<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
Michael,<br>
<br>
yes, while async getters seem to be possible by some JS voodoo, they
probably won't work without changes to the applications.<br>
<br>
I also don't think they would form an application code pattern we
should encourage, as they would try to hide asynchronous operations
and would lead to each individual metric needing to be requested (at
least initially) by a separate async call.<br>
<br>
Instead, please reconsider:<br>
<br>
<blockquote type="cite"> Btw, in case you didn't see this already: I
implemented an auto subscription scheme for the 'stream'
notifications -- these are by default very transmission intense
and can cause substantial load on the module side as well. These
subscriptions are managed automatically for all components and
plugins by the framework (which btw also takes care of
initializing all fragments added in the '#' container).</blockquote>
<br>
I designed this subscription scheme to follow the MQTT topic
subscription scheme and be usable for any kind of subscription.
Different data sources can be identified by the root topic. For
notifications, it's `notify/`, for metrics, we can naturally assign
`metrics/`. A subscription pattern `metrics/v/p/#` would for example
subscribe to all `v.p.*` metrics.<br>
<br>
Auto subscribing & unsubscribing is managed by the framework via
the `data-subscriptions` attribute of a `.receiver`.<br>
<br>
Examples:<br>
<ul>
<li><a class="moz-txt-link-freetext" href="https://docs.openvehicles.com/en/latest/components/ovms_webserver/docs/notifications.html">https://docs.openvehicles.com/en/latest/components/ovms_webserver/docs/notifications.html</a></li>
<li><a class="moz-txt-link-freetext" href="https://github.com/openvehicles/Open-Vehicle-Monitoring-System-3/tree/master/plugins/retools">https://github.com/openvehicles/Open-Vehicle-Monitoring-System-3/tree/master/plugins/retools</a><br>
</li>
</ul>
<br>
Btw, if (!) we keep the units dictionary subscription necessity,
that could be a subscription to `units/#`.<br>
<br>
Regards,<br>
Michael<br>
<br>
<br>
<div class="moz-cite-prefix">Am 08.12.22 um 04:29 schrieb Michael
Geddes:<br>
</div>
<blockquote type="cite"
cite="mid:CAH0p7u+TDSae=u8xyLdRnVapX+Q8FX=bDoYN3mMn4OgJm5mGww@mail.gmail.com">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<div dir="ltr">
<div>I've implemented a way of having user units of metrics come
through (I have metrics_user[] metrics_label[] and
metrics_all[] implemented).. </div>
<div><b>however as far as dynamic subscription to metrics goes,
I now believe I can't do what I want in a backwards
compatible way.</b><br>
</div>
<div><br>
</div>
<div>This is where I'm at:</div>
<div><br>
</div>
<div>I<span
style="background-color:rgb(255,255,255);font-family:Arial,Helvetica,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;color:rgb(34,34,34);display:inline!important;float:none"> haven't
used Promises before or async/wait etc, so in my </span>naivity,
I had (mistakenly it seems) thought I could define a function
taking a <i>metric code</i> that</div>
<div>* Sends a command to the websocket eg <i>metric
fetchsub 1234 v.p.trip</i></div>
<div>* Waits for the result coming in over the web-socket or
times out</div>
<div>* Returns the result to the user <b>directly</b></div>
<div>so <i>metric['</i>
<i>v.p.trip</i><i>'] </i> (or whatever) could have an
accessor function that (for unsubscribed metrics) silently
fetched and subscribed to the metric over the websocket and
returned the value.</div>
<div><br>
</div>
<div>I have actually implemented the fetching bit mostly .. (a
Promise resolve call-back is put in a collection against a
random id and when the event comes back it uses the id to grab
the promise function and resolve with the result - and yes it
has a timeout) ... except that in the end, the javascript
still requires a Promise to be created that needs to execute
its result as a call-back. <span
style="background-color:rgb(255,255,255);font-family:Arial,Helvetica,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;color:rgb(34,34,34);display:inline!important;float:none">I
also believe I now understand why that is not possible, and
that </span>fundamentally the only way of doing async stuff
at all ends up in some kind of call back (via a Promise
directly or an async function Promise)... and that the only
exceptions to this are within an async function (which in the
end still returns a Promise).</div>
<div><br>
</div>
<div>This makes blocking on a metric['v.p.trip'] proxy get;
function not possible afaict. Unless somebody knows a
mechansim that I could use? (outside of an async function, of
course)</div>
<div><br>
</div>
<div>I have implement the subscription model for metrics[]
(which supports, for example, v.p.* ) .. but without the
auto-subscription it is going to be less useful for plugins as
far as backwards compatibility goes! </div>
<div><br>
</div>
<div>you could have a call like this:</div>
<div> applyMetric('v.p.trip', (value) => { ... put the
value somewhere } )</div>
<div><br>
</div>
<div><br>
</div>
<div><br>
</div>
<div>//.ichael</div>
<div><br>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Sat, 3 Dec 2022 at 02:29,
Michael Balzer <<a href="mailto:dexter@expeedo.de"
target="_blank" moz-do-not-send="true"
class="moz-txt-link-freetext">dexter@expeedo.de</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div> Michael,<br>
<br>
the unit conversion JS code scheme is fine. Btw, you can
optimize convert to…<br>
<br>
<font face="monospace"> convert = function (from, to,
value) {<br>
return (</font><font face="monospace"><font
face="monospace"><font face="monospace">unit_conversions[from
+ ">" + to] || </font></font><font
face="monospace"><font face="monospace"><font
face="monospace">unit_conversions.native</font></font></font>)(value);<br>
}<br>
</font></div>
</blockquote>
<div>Yeah - I'm assuming that the gain from not looking up
unnecessarily is lost from all the checking. Got it.</div>
<div><br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div><font face="monospace"> </font>
<div><br>
</div>
<blockquote type="cite">I knew we had to keep the default
webstream as it was. I was thinking of having a
different websocket Uri to trigger filtered mode
(starting without sending all units).<br>
</blockquote>
<blockquote type="cite">Especially, I was also considering
the plugins that run from the '#' container that may not
know the container had switched to user units! (so I'm
not sure about option a.), so from what I can tell, the
base metrics[] needs to maintain native units imho. This
is also why I was looking at the 'auto-subscribe' idea
since the outside container doesn't know which metrics a
plugin might use, and a plugin wouldn't know to
subscribe to the messages.</blockquote>
<br>
I think plugins will need to be updated anyway, as will
all our standard pages & components, as up to now all
units have been fixed in the UI.<br>
<br>
In both approaches, all metrics displays (simple markup,
tables, charts) will need to be reworked to use the user
units. Only the basic markup type displays could partially
be modified automatically (by walking through their
'.unit' elements), but any extended use, even the range
& energy displays in the dashboard's speed gauge, will
need a config-aware approach.<br>
<br>
Charts will need to fully reconfigure, as unit labels are
used within different chart features, and axis limits
& plotbands will need to be adjusted. For this,
scripts can subscribe to a new 'msg:units' event sent when
a (re-)configuration of units is received.<br>
</div>
</blockquote>
<div>Yeah - I've got some classes so that different cars can
specify all the ranges in native units and it will generate
code for the current user units. I've already put this into
use for all vehicle classes that return a custom guage
configuration.</div>
<div><br>
</div>
<div> At the moment it is still static code and we'll need to
sink on a (not yet implmeneted) untits changed event to
reload it.. but it would be simple enough to change the code
generated to be dynamic (especially that we now have that
conversion function). Even just having the user refresh the
page is better than nothing at the moment (it's not like the
user is going to be changing the units all the time).</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div> <br>
Btw, in case you didn't see this already: I implemented an
auto subscription scheme for the 'stream' notifications --
these are by default very transmission intense and can
cause substantial load on the module side as well. These
subscriptions are managed automatically for all components
and plugins by the framework (which btw also takes care of
initializing all fragments added in the '#' container).<br>
<br>
<blockquote type="cite">
<div>We could maintain a units collection exactly as
above with some proxy arrays to get at values without
exceptions. For eg: </div>
<div>m.label["v.p.speed"] could look up the units_
collection being maintained and return blank if the
entry doesn't exist. Then</div>
<div>m.value["v.p.speed"] would give the user unit and
m.nativevalue["v.p.speed"] the native value. The
latter two would use the metrics[] array or whatever
mechanism we had. We could add m.text["v.p.speed"]
that would give a text version with the value and unit
if it had one.</div>
</blockquote>
<br>
That leads us to another option: we could keep the metrics
transmission in native values, add the units dictionary
and provide all conversions in Javascript using this proxy
getter scheme.<br>
</div>
</blockquote>
<div><br>
</div>
<div>Yep - already decided to do that. It makes more sense.
At the moment I'm also implementing a way of starting off
with no metrics supplied and then adding in which ones we
need. Probably the JS is the bit I need to work out on
that.</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div> <br>
That would keep the current metrics[] access scheme intact
and unchanged, so all current frontend code & plugins
would continue to work, using the native values as before.<br>
<br>
The new proxy getters then can be used as the new way to
access metrics by anyone interested in using user units,
and we can go ahead by applying this to the standard pages
and components.<br>
<br>
This in combination with the 'msg:units' event to signal
reconfiguration should provide all we need.<br>
<br>
We can even easily combine this with providing a command
or socket URL / parameter to switch the metrics into user
mode. The standard web frontend won't need this then, but
it would make using user units easy for devices without
Javascript support.<br>
<br>
Regards,<br>
Michael<br>
<br>
<br>
<div>Am 28.11.22 um 00:36 schrieb Michael Geddes:<br>
</div>
<blockquote type="cite">
<div dir="ltr">Solved a couple of things.
<div>I have a 'unit conversion' code - which I current
have put into a separate cpp file along with the two
other C++ conversion functions.</div>
<div>I wanted to do it this way so they are all in
there together. (Does this make sense to do?).</div>
<div><br>
</div>
<div> <font face="monospace"> mi_to_km = function(mi)
{ return mi * 1.609347; }<br>
km_to_mi = function(km) { return km * 0.6213700;
}<br>
pkm_to_pmi = function(pkm) { return pkm *
1.609347; }<br>
pmi_to_pkm = function(pmi) { return pmi *
0.6213700; }<br>
const feet_per_mile = 5280;<br>
var unit_conversions = {<br>
"native": function (value) {
return value;},<br>
"km>miles": km_to_mi,<br>
"km>meters": function (value)
{ return value*1000; },<br>
"km>feet": function (value)
{ return km_to_mi(value) * feet_per_mile; },<br>
......<br>
"percent>permille": function (value)
{ return value*10.0; },<br>
"percent>percent": function (value)
{ return value*0.10; }<br>
}<br>
convert_function = function (from, to) {<br>
var fn = undefined;<br>
if (from !== to && to !== "")<br>
fn = unit_conversions[from + ">" + to];<br>
if (fn == undefined)<br>
fn = unit_conversions.native;<br>
return fn;<br>
}<br>
convert = function (from, to, value) {<br>
var fn = convert_function(from, to);<br>
return fn(value);<br>
}<br>
</font></div>
<div><br>
</div>
<div>The other problem of looking at the uri of the
websocket I have solved by creating a
'SocketCreator' MgHandler class in
the MG_EV_WEBSOCKET_HANDSHAKE_REQUEST event (and
looks at the uri)... that waits for the</div>
<div>MG_EV_WEBSOCKET_HANDSHAKE_DONE and deletes
itself.</div>
<br>
int OvmsSocketCreator::HandleEvent(int ev, void *p)<br>
{<br>
if ( ev != MG_EV_WEBSOCKET_HANDSHAKE_DONE)<br>
return ev;<br>
// new websocket connection<br>
MyWebServer.CreateWebSocketHandler(m_nc,
m_socket_type );<br>
m_nc = NULL;<br>
delete this;<br>
return 0;<br>
}<br>
<div><br>
</div>
<div>Thoughts?</div>
<div><br>
</div>
<div>//.ichael</div>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Sun, 27 Nov 2022
at 07:18, Michael Geddes <<a
href="mailto:frog@bunyip.wheelycreek.net"
target="_blank" moz-do-not-send="true"
class="moz-txt-link-freetext">frog@bunyip.wheelycreek.net</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px
0px 0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div dir="ltr">
<div dir="auto">
<div dir="auto">I knew we had to keep the
default webstream as it was. I was thinking
of having a different websocket Uri to trigger
filtered mode (starting without sending all
units).. Though I am struggling with how to
get and then pass the Uri information into the
web socket constructor! The event that
currently creates it doesn't seem to have
access to the Uri. (see below - p is NULL for
HANDSHAKE_DONE).</div>
<div dir="auto">
<div style="color:rgb(212,212,212);background-color:rgb(30,30,30);font-family:Consolas,"Courier New",monospace;line-height:19px;white-space:pre-wrap"><div> <span style="color:rgb(197,134,192)">case</span> <span style="color:rgb(86,156,214)">MG_EV_WEBSOCKET_HANDSHAKE_REQUEST</span>:</div><div> {</div><div> <span style="color:rgb(86,156,214)">struct</span> <span style="color:rgb(78,201,176)">http_message</span> <span style="color:rgb(86,156,214)">*</span><span style="color:rgb(156,220,254)">hm</span> = (<span style="color:rgb(86,156,214)">struct</span> <span style="color:rgb(78,201,176)">http_message</span> <span style="color:rgb(86,156,214)">*</span>) <span style="color:rgb(156,220,254)">p</span>; // how to pass uri info to the event below!?</div><div> }</div><div> <span style="color:rgb(197,134,192)">break</span>;</div><div> <span style="color:rgb(197,134,192)">case</span> <span style="color:rgb(86,156,214)">MG_EV_WEBSOCKET_HANDSHAKE_DONE</span>:<span style="color:rgb(106,153,85)"> // new websocket connection</span></div><div> {</div><div> <span style="color:rgb(156,220,254)">MyWebServer</span>.<span style="color:rgb(220,220,170)">CreateWebSocketHandler</span>(<span style="color:rgb(156,220,254)">nc</span>);</div><div> }</div><div> <span style="color:rgb(197,134,192)">break</span>;</div>
</div>
</div>
<div dir="auto"><br>
</div>
<div dir="auto"><br>
</div>
<div dir="auto">Especially, I was also
considering the plugins that run from the '#'
container that may not know the container had
switched to user units! (so I'm not sure about
option a.), so from what I can tell, the base
metrics[] needs to maintain native units imho.
This is also why I was looking at the
'auto-subscribe' idea since the outside
container doesn't know which metrics a plugin
might use, and a plugin wouldn't know to
subscribe to the messages.</div>
<div dir="auto"><br>
</div>
<div>I do like the separate units description
message - though we would probably need to add
the 'native' if we want to do conversions.</div>
<font face="monospace"><font face="monospace"><br>
{ units: {<br>
"v.p.speed": { </font></font><font
face="monospace"><font face="monospace"><font
face="monospace"><font face="monospace">code:
"kmph", <b>native "kmph",</b> </font></font>label:
"km/h" }, …</font></font><br>
<div><br>
</div>
<div>We could maintain a units collection
exactly as above with some proxy arrays to get
at values without exceptions. For eg: </div>
<div>m.label["v.p.speed"] could look up the
units_ collection being maintained and return
blank if the entry doesn't exist. Then</div>
<div>m.value["v.p.speed"] would give the user
unit and m.nativevalue["v.p.speed"] the native
value. The latter two would use the metrics[]
array or whatever mechanism we had. We could
add m.text["v.p.speed"] that would give a text
version with the value and unit if it had one.</div>
<div dir="auto"><br>
</div>
<div>I had contemplated the idea of providing a
JavaScript unit conversion and was working
around it. Downside is it's a third set of
conversion functions to maintain... On the
other hand using that we could just keep the
metrics being sent as it is now, have the
groups sent as you proposed (along with the
native unit code) , and have the above
m.value[] proxy collection use a 'touser'
function assigned to the units_ collection
above that provided native to user conversion.</div>
<div>
<div dir="auto"> </div>
<div>We could send a javascript library
constructed with just the necessary
functions for the required conversions of
native to user (or the whole lot..
whichever). .</div>
<div>--</div>
<font face="monospace">var conversions = {</font></div>
<div><font face="monospace"> unit: function (
value) { return value }<br>
km_miles: function (value) { return
value * 0.6213700; }</font></div>
<div><font face="monospace"> }</font>
<div>We could perform the lookup when
constructing the units and assign the touser
property. (And have a 'unit' function that
does no conversion).</div>
</div>
<div dir="auto"><br>
//.ichael <br>
<br>
<div class="gmail_quote" dir="auto">
<div dir="ltr" class="gmail_attr">On Sat, 26
Nov 2022, 10:43 pm Michael Balzer, <<a
href="mailto:dexter@expeedo.de"
target="_blank" moz-do-not-send="true"
class="moz-txt-link-freetext">dexter@expeedo.de</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote"
style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div> The metrics subscription scheme is
an option, and the auto-subscribe
feature via a getter is a nice idea. But
I wouldn't apply that to metrics value
conversions and units.<br>
<br>
Also we would still need the current set
of metrics to be subscribed by default,
as there are also non Javascript devices
(e.g. smart buttons, Wifi displays)
reading the WebSocket stream.<br>
<br>
My thoughts on this so far:<br>
<br>
Basically the web UI, as any frontend,
should adapt to unit configurations
seamlessly. The web UI includes many
command outputs, which already
automatically switch units as
configured.<br>
<br>
For all practical purposes, the web UI
needs to interact with users in their
preferred units. Only some plugins and
functions will need certain values in
metric (native) units for calculations,
and these will also need a simple way to
convert calculation results back to user
units for displaying. So I think we need
to provide the unit configuration and
value conversion tools in the web
framework as well.<br>
<br>
Proposal:<br>
<br>
a) We provide a config option and a
WebSocket command to switch the
WebSocket metrics transmission mode to
user / native units. To keep plugin
compatibility, the default is 'native'.<br>
<br>
b) We introduce a separate units
dictionary object containing the user
units for both metrics and the unit
groups in their code & label
representation. The units dictionary
only needs to be sent initially, when
new metrics are registered, when the
metrics mode is changed for the current
connection, and when some user unit
configuration is changed, keeping the
bandwidth and processing requirements
low.<br>
<br>
The units dictionary can combine both
metrics and group units, as the unit
group names are fully distinct from the
metrics namespace. The transport scheme
could be:<br>
<br>
<font face="monospace"><font
face="monospace">{ units: {<br>
"v.p.speed": { </font></font><font
face="monospace"><font
face="monospace"><font
face="monospace"><font
face="monospace">code: "kmph", </font></font>label:
"km/h" }, …<br>
"</font></font><font
face="monospace"><font
face="monospace"><font
face="monospace">units.distance":
{ </font></font></font><font
face="monospace"><font
face="monospace"><font
face="monospace"><font
face="monospace"><font
face="monospace"><font
face="monospace"><font
face="monospace">code: "</font></font></font></font></font></font></font><font
face="monospace"><font
face="monospace"><font
face="monospace"><font
face="monospace"><font
face="monospace"><font
face="monospace"><font
face="monospace"><font
face="monospace">miles</font>",
</font></font>label: "M" },
…<br>
}<br>
</font></font></font><br>
</font></font>c) In the web framework,
accessing units should be as simple as
possible and avoid throwing exceptions
for undefined entries, so we could e.g.
split these into separate code &
label objects:<br>
<font face="monospace"><font
face="monospace"><br>
units["v.p.speed"] =
"km/h" // consistently
accompanies metrics["v.p.speed"]<br>
</font></font><font face="monospace"><font
face="monospace"><font
face="monospace">unit</font></font></font><font
face="monospace"><font
face="monospace"><font
face="monospace"><font
face="monospace"><font
face="monospace"><font
face="monospace">codes</font></font></font>["v.p.speed"]
= "kmph"<br>
<br>
</font></font></font><font
face="monospace">units["units.distance"]
= "M"</font><br>
<font face="monospace">unitcodes["units.distance"]
= "miles"</font><br>
<br>
…or provide a getter that tests for the
key existence and returns an object with
empty fields as necessary.<br>
<br>
With this, all metrics displays can
easily be changed to display the actual
unit labels instead of using fixed
strings.<br>
<br>
d) To provide value conversion we
implement UnitConvert() in Javascript
plus some wrappers that automatically
look up the unit for a given
metrics/group name and do the conversion
to/from native units, something like…<br>
<br>
<font face="monospace">var speed_kph
= toNativeValue("v.p.speed"); //
optional second arg to convert any
data<br>
</font><font face="monospace"><font
face="monospace"><font
face="monospace">var speed_kph
= metrics_native["v.p.speed"]; //
using a getter<br>
<br>
</font></font>var trip_display =
toUserValue("units.distance", 1234);<br>
<br>
</font><br>
Plugins for scientific/technical
applications that depend on native
(metric) units can use the new metrics
transmission mode control command to
force native mode. Or they can choose to
migrate from "metrics[]" to
"metrics_native[]".<br>
<br>
The metrics mode config option can come
with a note informing users that there
may be some old plugins not compatible
with non-native units. They can then
check their plugins for this and make an
informed decision on wether to enable
user units and/or wether to install a
specific plugin.<br>
<br>
Thoughts, comments?<br>
<br>
Regards,<br>
Michael<br>
<br>
<br>
<div>Am 25.11.22 um 03:13 schrieb
Michael Geddes:<br>
</div>
<blockquote type="cite">
<div dir="ltr">
<div dir="ltr">I have an idea which
might reduce traffic for
maintaining the metrics[] array in
the browser and cope with the user
units.</div>
<div dir="ltr">I'll start by saying
I'm not a JS developer per se.. so
a newb in JS really. Still, it's
mainly just another language so ..
we'll give it a go. <br>
<div><br>
</div>
<div>Firstly:</div>
<div>* Implement the 'changed'
filters as below for the
web-socket.. for both normal and
'user' values.</div>
<div>* Add a function that
subscribes to a value (and
returns the current value of
it)..including to 'user'
value/unitlabel.</div>
<div><br>
</div>
<div>Subscribing the normal way to
the metrics over the websocket
would have the normal effect..
but we would have a new way that
would subscribe in a filtered
way.</div>
<div><br>
</div>
<div>I've had a little play with
the Proxy object .. so at least
I know this should work:</div>
<div><br>
</div>
<div>Have a metrics_ array that is
the real associative array for
metrics[] and then define a
Proxy that has (at the least)
'get' and 'has' defined (giving
us the ability to overload <i>metrics['prop']</i>
and <i>"prop" in metrics
operations</i>).</div>
<div><br>
</div>
<div>The <i>get </i>function
would return the underlying
value if it exists in the <i>metrics_ </i>array
(which is maintained through
the websocket from currently
subscribed values in the current
manner). </div>
<div>If the value is not in the <i>metrics_</i> array
- it would then do a
subscribe+query on the websocket
getting the current value and
adding it into the <i>metrics_</i> container.
If it was unavailable then it
would put <i>undefined</i> into
the array.<br>
</div>
<div>The 'has' would do the get()
and return true if the value was
not == <i>undefined</i>. </div>
<div><br>
<div>For the 'query
the websocket' bit, I'm
assuming I would be working
with promises or futures or
some such: I'll do the
research and do it properly
unless somebody can help me
out with it. That's the bit I
was going to work on next for
the proof-of-concept.</div>
<div><br>
</div>
<div>Any immediate thoughts?
Dangers?</div>
<div><br>
</div>
<div>I also noticed there was a
bit that went through html
element properties and looked
for metrics .. this could be
used to bulk subscribe to any
metric values required there.</div>
<div><br>
</div>
<div>//.ichael</div>
<div><br>
</div>
</div>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On
Thu, 17 Nov 2022 at 07:52,
Michael Geddes <<a
href="mailto:frog@bunyip.wheelycreek.net"
rel="noreferrer"
target="_blank"
moz-do-not-send="true"
class="moz-txt-link-freetext">frog@bunyip.wheelycreek.net</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote"
style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div dir="ltr">
<div dir="ltr">Yeah, ok.<br>
</div>
<div dir="ltr"><br>
</div>
<div>I will get all the other
'user unit' stuff done as a
line in the sand, and then
move to working out the web
stuff. I'm still finding my
way though all the client
side javascript, which looks
very cool.. but I've not
really done jQuery before
(just enough to recognise
it).</div>
<div><br>
</div>
<div>Subscribing to metrics
with/without user units
makes a lot of sense.
Obviously the default needs
to be 'Subscribe to all
metrics but not user units'
to maintain compatibility...
but I was also thinking it
might be nice if we could
filter down even the normal
subscribed events.</div>
<div>We could have:</div>
<div>* Web socket command to
filter units (flag on
websocket to say 'filtered'
+ flag bitset on each
metric similar to 'dirty')<br>
</div>
<div>Then either:</div>
<div>* Web socket command to
turn on user units (single
flag on that websocket)</div>
<div>or </div>
<div>* Web socket command to
turn on user units for
specific metrics (flag
bitset on each metric)</div>
<div><br>
</div>
<div>A parameter to the URI
for the websocket could
start the socket in
'filtered' mode to avoid the
initial rush of metrics.</div>
<div><br>
</div>
<div>This could drastically
reduce traffic and time for
the metrics command to
execute. It would be
possible to also check (on a
'filtered' websocket) for
any changes to metrics for
that websocket slot before
queueing the 'metric update'
socket command.</div>
<div><br>
</div>
<div>//.ichael</div>
<div><br>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr"
class="gmail_attr">On Thu,
17 Nov 2022 at 00:35,
Michael Balzer <<a
href="mailto:dexter@expeedo.de"
rel="noreferrer"
target="_blank"
moz-do-not-send="true"
class="moz-txt-link-freetext">dexter@expeedo.de</a>>
wrote:<br>
</div>
<blockquote
class="gmail_quote"
style="margin:0px 0px 0px
0.8ex;border-left:1px
solid
rgb(204,204,204);padding-left:1ex">
<div> Michael,<br>
<br>
I don't have much spare
time currently, just
some quick first
comments: it's important
to implement this as
lightweight as possible,
both in terms of network
load and client CPU
& memory
requirements. Some
devices already have
issues, which can be
seen by the "websocket
overflow" messages. The
web UI also should stay
usable via cellular.<br>
<br>
My impression is the new
scheme, while only
slightly raising the
client requirements,
adds substantially to
the network
requirements.<br>
<br>
An option could be to
separate the units -- or
more, back when
implementing this I
thought about separating
the names later on.
Another question is if
we normally generally
need both the native and
the converted values in
the web UI. We maybe
could provide an option
to switch to converted
values, or add an option
to retreive or subscribe
to a set of converted
metrics on demand.<br>
<br>
Standard plugins like
ABRP and PwrMon rely on
getting metric (native)
units, and there
probably are non-public
plugins, e.g. for
engineering &
scientific projects,
that depend on metric
units to do their
calculations and don't
need anything else. We
shouldn't make life
harder for these
applications without
good reason.<br>
<br>
Regards,<br>
Michael<br>
<br>
<br>
<div>Am 15.11.22 um
01:26 schrieb Michael
Geddes:<br>
</div>
<blockquote type="cite">
<div dir="ltr">
<div dir="ltr">If
you're ok with the
[default] option
I'll stick with
that. I mean in
some ways it would
be nice to have a
button choice</div>
<div dir="ltr">metric
| usa | europe |
asia | custom
etc and I kind of
considered
something like
that but figured
it's only a
handful of
choices.. and it's
an embedded
device.. so
simpler is better.</div>
<div dir="ltr"><br>
</div>
<div>On a related
note - I was
thinking how it
would be nice if
the dashboard
(etc) had access
to the 'user'
units, so went
hunting down that
little rabbit
hole. Quite a nice
mechanism with the
web socket
updating the
"metrics" object
in the UI. </div>
<div>This is a
snippet of one
idea, which is
that for any
metric that has
the possibility of
a user unit, we
set the extra
values of the
metric with
'#unit' and
'#user' appended -
see below. (I've
chosen '#'
arbitrarily.. but
it could be '/' or
':' or '>' but
maybe not '.' )</div>
<br>
v.p.odometer#unit:
"M"<br>
v.p.odometer#user:
6754.91<br>
v.p.satcount: 13<br>
v.p.speed: 0<br>
v.p.speed#unit:
"km/h"<br>
v.p.speed#user: null<br>
<b>v.p.trip: 28</b><br>
<b>v.p.trip#unit:
"M"<br>
v.p.trip#user:
17.3984</b>
<div><br>
</div>
<div>Then we can use
this in the dials
to populate the
values and
captions! (not
that I like
Miles).</div>
<div>I</div>
<div>
<div><br>
</div>
<div><img
alt="image.png"
moz-do-not-send="true" width="217" height="136"><br>
</div>
<div><br>
</div>
<div>The other
(similar) way
was to have
something like
the following:</div>
<div>"v.p.trip#user"
: { "value":
17.3984, "unit":
"M" }</div>
<div>It wouldn't
make the total
message any
shorter.. soo..
dunno.</div>
<div><br>
</div>
<div>There's also
some
complications
with setting up
the dials (for
min/max values)
- like for the
speed.</div>
<div><br>
</div>
<div>Notice also
that I'm
returning null
for undefined
values. It's
nice - but I'm
not sure how
javascript
handles null
when used /
printed etc.</div>
<div><br>
</div>
<div>//.ichael</div>
<div><br>
</div>
<div>
<div
class="gmail_quote">
<div dir="ltr"
class="gmail_attr">On Sun, 13 Nov 2022 at 21:06, Michael Balzer <<a
href="mailto:dexter@expeedo.de"
rel="noreferrer" target="_blank" moz-do-not-send="true"
class="moz-txt-link-freetext">dexter@expeedo.de</a>>
wrote:<br>
</div>
<blockquote
class="gmail_quote"
style="margin:0px 0px 0px 0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div> Michael,<br>
<br>
looks good.<br>
<br>
I think having
an explicit
'default'
option is
better than
taking the
'Metric'
equivalent for
that, as in
your example
you already
show unit
alternatives
within the
metric system
to support
different
scalings (kW /
W, kWh / Wh).
(Btw… waiting
for someone to
miss
Horsepower
& BTU here
;-))<br>
<br>
@Patrick, I
think that
also answers
your implicit
question:<br>
<blockquote
type="cite">
<pre>The default button makes it unclear what the actual setting is.
</pre>
</blockquote>
<br>
The default
(native unit)
is always
metric, but
you may have a
mix of
scalings, as
we try to find
the one that
fits best for
the given
application
when defining
a metric. For
example the
current
driving energy
consumption is
stored
natively in
Wh/km, while
the energy
used or
regenerated is
in kWh, and
the odometer
& trip
counters are
in km, while
the altitude
ist in m.<br>
<br>
Regards,<br>
Michael<br>
<br>
<br>
<div>Am
13.11.22 um
08:42 schrieb
Michael
Geddes:<br>
</div>
<blockquote
type="cite">
<div dir="ltr">Greetings,<br>
<div>so this
is my idea of
being able to
select which
units various
groups use (in
addition to
Distance).</div>
<div>This can
be then
accessed by
the special
'user' unit
code. (or
'metrics list
-u ' )</div>
<div>The idea
of [Default]
selection
below simply
means storing
the value to
blank -
meaning use
whatever unit
the particular
metric uses.
The other idea
I had was to
actually
default it to
the equivalent
of 'Metric'
special unit
code and not
have the
[Default]
button.</div>
<div><br>
</div>
<div><br>
</div>
<img
alt="image.png"
moz-do-not-send="true" width="472" height="395"><br>
<div><br>
</div>
<div>Currently
I've made it
so that if
there are more
than 3 choices
other than
[default] that
it uses the
choice/combo
box rather
than the Radio
buttons. (ie
this list is
auto-generated
from the
Metric Units
table and the
Metric Groups
table).</div>
<div><br>
</div>
<div>Thoughts
/ comments?</div>
<div><br>
</div>
<div>//.ichael </div>
</div>
<br>
<div
class="gmail_quote">
<div dir="ltr"
class="gmail_attr">On Sat, 12 Nov 2022 at 17:35, Michael Geddes <<a
href="mailto:frog@bunyip.wheelycreek.net"
rel="noreferrer" target="_blank" moz-do-not-send="true"
class="moz-txt-link-freetext">frog@bunyip.wheelycreek.net</a>>
wrote:<br>
</div>
<blockquote
class="gmail_quote"
style="margin:0px 0px 0px 0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div dir="ltr">
<div dir="ltr"><a
href="https://github.com/openvehicles/Open-Vehicle-Monitoring-System-3/pull/771"
rel="noreferrer" target="_blank" moz-do-not-send="true"
class="moz-txt-link-freetext">https://github.com/openvehicles/Open-Vehicle-Monitoring-System-3/pull/771</a><br>
<div><br>
</div>
<div>I'm
hoping this
P/R is ok in
this form
(made of 5
separate commits).</div>
<div><br>
</div>
<div>I will
have a look at
implementing
the "user"
unit code.
The base for
how it
would work is
already a part
of the above
pull request.
I'll just look
at the module
configuration
for distance.</div>
<div><br>
</div>
<div>The
'power
consumption'
is one where
it's not just
a check-box..
there're 5
possible
choice!</div>
<div><br>
</div>
<div>I should
also add 'bar'
for pressure
given that for
some reason
that's still a
thing people
want.</div>
<div><br>
</div>
<div>//.ichael</div>
</div>
<br>
<div
class="gmail_quote">
<div dir="ltr"
class="gmail_attr">On Sat, 12 Nov 2022 at 16:24, Michael Balzer <<a
href="mailto:dexter@expeedo.de"
rel="noreferrer" target="_blank" moz-do-not-send="true"
class="moz-txt-link-freetext">dexter@expeedo.de</a>>
wrote:<br>
</div>
<blockquote
class="gmail_quote"
style="margin:0px 0px 0px 0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div> I think
this is pretty
decent &
complete now.<br>
<br>
I also like
the approach
of the 'user'
unit code.
Moving all
user unit
prefs into the
module
configuration
is an old
todo.
Currently only
the distance
unit is
defined at the
module side,
temperature
and pressure
are App prefs.<br>
<br>
Regards,<br>
Michael<br>
<br>
<br>
<div>Am
11.11.22 um
09:54 schrieb
Michael
Geddes:<br>
</div>
<blockquote
type="cite">
<div dir="ltr">Ok
- so here's
what I have
implemented
for Duktape
and Metrics.
(I added
IsDefined() as
well).
<div>Any
thoughts on
this?<br>
<div><br>
<div>Noting</div>
<div>
OvmsMetrics.Float(
{metric} )
-> Outputs
metric as
float (same)</div>
<div>
OvmsMetrics.Float(
{metric},
{unit}) ->
Outputs metric
as float
converted to
given unit
(new)</div>
<div>
OvmsMetrics.Value(
{metric} )
-> Outputs
Metric in
native value
(same)</div>
<div>
OvmsMetrics.Value(
{metric} ,
false) ->
Outputs Metric
as string and
no units
(same) </div>
OvmsMetrics.Value(
{metric} ,
{unit}) ->
Outputs Metric
converted to
given unit as
native value.
(new)
<div>
OvmsMetrics.Value(
{metric} ,
{unit}, false
) ->
Outputs Metric
converted to
given unit as
string
including any
unit
specifier.
(new)
<div>also
OvmsMetric.GetValues(
{metric}
[,{unit}] [,
{converted} ]
) Adds
similar
behaviour to
Value() above.</div>
<div>also the
special units
'<b>imperial</b>'
and '<b>metric</b>'
will convert
to the
associated
imperial /
metric version
of the units
as
appropriate.</div>
<div><br>
<div><font
face="monospace">(function()
{<br>
dump =
function
(metric) {
print( metric+
" ["+(typeof
metric)+"]\n"
); }<br>
dump_obj =
function (obj
) {<br>
print('---
Object
----\n')<br>
for (var
k in obj) {<br>
xk =
obj[k];<br>
print(
k+':'+ xk + '
['+typeof xk+
"]\n");<br>
}<br>
}<br>
dump(OvmsMetrics.Value("xiq.v.trip.consumption"));<br>
dump(OvmsMetrics.Value("xiq.v.trip.consumption",
false));<br>
dump(OvmsMetrics.Value("xiq.v.trip.consumption","kmpkwh"));<br>
dump(OvmsMetrics.Value("xiq.v.trip.consumption",
"mipkwh",
false));<br>
dump(OvmsMetrics.AsFloat("xiq.v.trip.consumption"));<br>
dump(OvmsMetrics.AsFloat("xiq.v.trip.consumption","kmpkwh"));<br>
dump(OvmsMetrics.Value("xiq.v.trip.consumption","imperial"))<br>
dump(OvmsMetrics.Value("xiq.v.trip.consumption","imperial",
false))<br>
dump_obj(OvmsMetrics.GetValues("trip",
"metric"))<br>
dump_obj(OvmsMetrics.GetValues("trip",
"imperial",
false))<br>
})();<br>
</font></div>
<div><br>
</div>
<div>With this
output:</div>
<div>
<div>
<pre id="m_-6437764485757861817m_1446710767644746708m_3389478097269637711m_-3595551468962657953m_-358274377416053507m_-7644593744426345619m_-5441616086226233372m_8405494616978842232m_-5904723395924573806m_1733173679174480992m_-138117451584655546m_5484224439251412587gmail-output" style="box-sizing:border-box;overflow:auto;font-family:ui-monospace,"Cascadia Mono","Segoe UI Mono",Hack,"Source Code Pro","Roboto Mono",Menlo,Monaco,Consolas,monospace;font-size:13px;padding:9.5px;margin-top:0px;margin-bottom:10px;line-height:1.42857;color:rgb(0,34,0);word-break:break-all;background-color:rgb(245,245,245);border:1px solid rgb(204,204,204);border-radius:4px;height:406px;white-space:pre-wrap">19.2308 [number]
19.2308 [string]
5.2 [number]
3.23112mi/kWh [string]
19.2308 [number]
5.2 [number]
309.49 [number]
309.49Wh/mi [string]
--- Object ----
v.p.trip:13 [number]
xiq.e.trip:0 [number]
xiq.e.trip.energy.recuperated:0 [number]
xiq.e.trip.energy.used:0 [number]
xiq.v.trip.consumption:19.2308 [number]
--- Object ----
v.p.trip:8.07781M [string]
xiq.e.trip:0M [string]
xiq.e.trip.energy.recuperated:0kWh [string]
xiq.e.trip.energy.used:0kWh [string]
xiq.v.trip.consumption:309.49Wh/mi [string]</pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<br>
<div
class="gmail_quote">
<div dir="ltr"
class="gmail_attr">On Wed, 9 Nov 2022 at 05:47, Michael Geddes <<a
href="mailto:frog@bunyip.wheelycreek.net"
rel="noreferrer" target="_blank" moz-do-not-send="true"
class="moz-txt-link-freetext">frog@bunyip.wheelycreek.net</a>>
wrote:<br>
</div>
<blockquote
class="gmail_quote"
style="margin:0px 0px 0px 0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div dir="ltr">Yeah
- I like
HasValue. I
implemented
IsDefined()
but I will
rename it..
that's a much
clearer name.
<div><br>
</div>
<div>Another
thought. How
about if we
did this (but
also with
GetValues() as
well - see the
special values
below) </div>
<div><br>
<div>OvmsMetrics.Value("xiq.v.trip.consumption",
true) -> <span style="background-color:rgb(245,245,245);color:rgb(0,34,0);font-family:ui-monospace,"Cascadia Mono","Segoe UI Mono",Hack,"Source Code Pro","Roboto Mono",Menlo,Monaco,Consolas,monospace;font-size:13px;white-space:pre-wrap">17.0582</span><span style="background-color:rgb(245,245,245);color:rgb(0,34,0);font-family:ui-monospace,"Cascadia Mono","Segoe UI Mono",Hack,"Source Code Pro","Roboto Mono",Menlo,Monaco,Consolas,monospace;font-size:13px;white-space:pre-wrap"> (Number)</span><br>
</div>
<div>
<div>OvmsMetrics.Value("xiq.v.trip.consumption",
false)
-> <span style="background-color:rgb(245,245,245);color:rgb(0,34,0);font-family:ui-monospace,"Cascadia Mono","Segoe UI Mono",Hack,"Source Code Pro","Roboto Mono",Menlo,Monaco,Consolas,monospace;font-size:13px;white-space:pre-wrap">17.0582</span><span style="background-color:rgb(245,245,245);color:rgb(0,34,0);font-family:ui-monospace,"Cascadia Mono","Segoe UI Mono",Hack,"Source Code Pro","Roboto Mono",Menlo,Monaco,Consolas,monospace;font-size:13px;white-space:pre-wrap"> (String)</span></div>
</div>
</div>
<div>OvmsMetrics.Value("xiq.v.trip.consumption",
"mipkwh",
true) -> <span style="background-color:rgb(245,245,245);color:rgb(0,34,0);font-family:ui-monospace,"Cascadia Mono","Segoe UI Mono",Hack,"Source Code Pro","Roboto Mono",Menlo,Monaco,Consolas,monospace;font-size:13px;white-space:pre-wrap">3.64264</span><span style="background-color:rgb(245,245,245);color:rgb(0,34,0);font-family:ui-monospace,"Cascadia Mono","Segoe UI Mono",Hack,"Source Code Pro","Roboto Mono",Menlo,Monaco,Consolas,monospace;font-size:13px;white-space:pre-wrap"> (Number)</span><br>
</div>
<div>OvmsMetrics.Value("xiq.v.trip.consumption",
"mipkwh",
false) -> <span style="background-color:rgb(245,245,245);color:rgb(0,34,0);font-family:ui-monospace,"Cascadia Mono","Segoe UI Mono",Hack,"Source Code Pro","Roboto Mono",Menlo,Monaco,Consolas,monospace;font-size:13px;white-space:pre-wrap">3.64264Mi/kWh</span><span style="background-color:rgb(245,245,245);color:rgb(0,34,0);font-family:ui-monospace,"Cascadia Mono","Segoe UI Mono",Hack,"Source Code Pro","Roboto Mono",Menlo,Monaco,Consolas,monospace;font-size:13px;white-space:pre-wrap"> (String)</span><br>
</div>
<div> OvmsMetrics.Value("xiq.v.trip.consumption",
"native",
false) -> <span style="font-size:13px;background-color:rgb(245,245,245);color:rgb(0,34,0);font-family:ui-monospace,"Cascadia Mono","Segoe UI Mono",Hack,"Source Code Pro","Roboto Mono",Menlo,Monaco,Consolas,monospace;white-space:pre-wrap">17.0582km/kWh</span><span style="font-size:13px;background-color:rgb(245,245,245);color:rgb(0,34,0);font-family:ui-monospace,"Cascadia Mono","Segoe UI Mono",Hack,"Source Code Pro","Roboto Mono",Menlo,Monaco,Consolas,monospace;white-space:pre-wrap"> (String)</span> </div>
<div><br>
</div>
<div>and</div>
<div>
<div>OvmsMetrics.Value("xiq.v.trip.consumption",
"imperial",
false) -> <span style="background-color:rgb(245,245,245);color:rgb(0,34,0);font-family:ui-monospace,"Cascadia Mono","Segoe UI Mono",Hack,"Source Code Pro","Roboto Mono",Menlo,Monaco,Consolas,monospace;font-size:13px;white-space:pre-wrap">3.64264Mi/kWh</span><span style="background-color:rgb(245,245,245);color:rgb(0,34,0);font-family:ui-monospace,"Cascadia Mono","Segoe UI Mono",Hack,"Source Code Pro","Roboto Mono",Menlo,Monaco,Consolas,monospace;font-size:13px;white-space:pre-wrap"> (String)</span><br>
</div>
</div>
<div><br>
</div>
<div>I have
already
implemented
the special
values
'native'
(existing),
'imperial' and
'metric'. </div>
<div><br>
</div>
<div>I was
also thinking
that in the
future you
could have
'user'. Where
for each group
of values:</div>
<div>'temperature',
'distance',
'shortdistance',
'power' etc..
you could have
a user
preference. I
probably won't
implement it
now,.but it
could be cool
that any UI
could just ask
for the user
defined units
(rather than
having a
separate
choice).</div>
<div><br>
</div>
<div><br>
</div>
<div><br>
</div>
<div>//.ichael</div>
</div>
<br>
<div
class="gmail_quote">
<div dir="ltr"
class="gmail_attr">On Tue, 8 Nov 2022 at 21:57, Mark Webb-Johnson <<a
href="mailto:mark@webb-johnson.net" rel="noreferrer" target="_blank"
moz-do-not-send="true"
class="moz-txt-link-freetext">mark@webb-johnson.net</a>> wrote:<br>
</div>
<blockquote
class="gmail_quote"
style="margin:0px 0px 0px 0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div>
<div dir="ltr"
style="color:rgb(0,0,0)">Or perhaps something more specific?</div>
<div dir="ltr"
style="color:rgb(0,0,0)"><br>
</div>
<div dir="ltr"
style="color:rgb(0,0,0)"> HasValue()</div>
<div dir="ltr"
style="color:rgb(0,0,0)"><br>
</div>
<div dir="ltr"
style="color:rgb(0,0,0)">Mark</div>
<div><br>
<blockquote
type="cite">
<div>On 8 Nov
2022, at 9:01
PM, Michael
Balzer <<a
href="mailto:dexter@expeedo.de" rel="noreferrer" target="_blank"
moz-do-not-send="true"
class="moz-txt-link-freetext">dexter@expeedo.de</a>> wrote:</div>
<br>
<div>
<div>
<div>
<div>Signed
PGP part</div>
<div>
<div> That's
basically a
good approach,
but be aware
'IsDefined()'
has an
ambiguous
meaning here,
as with the
API stem
"OvmsMetrics"
it would
naturally be
expected to
mean "is this
metric
defined", not
"does this
metric have a
defined
value".<br>
<br>
An undefined
metric
currently can
be derived
from
'Values()'
returning
undefined, but
that's more an
undocumented
side effect
than intended.<br>
<br>
Maybe
'GetDefined()'
could be a
better name,
leveraging
this
behaviour,
i.e. returning
'undefined'
for an
actually
undefined
metric, and
'null' for a
defined metric
without a
value.<br>
<br>
Regards,<br>
Michael<br>
<br>
<br>
<div>Am
08.11.22 um
13:46 schrieb
Michael
Geddes:<br>
</div>
<blockquote
type="cite">
<div dir="ltr">
<div>Ah yes.
Arrays - will
check those.
Yeah, how
about we add a
'IsDefined'
method to
metrics
instead of the
null thing (it
does sound
like it will
upset too many
applecarts).</div>
<div><br>
</div>
<div>//.</div>
<br>
<div
class="gmail_quote">
<div dir="ltr"
class="gmail_attr">On Tue, 8 Nov 2022 at 20:35, Michael Balzer <<a
href="mailto:dexter@expeedo.de"
rel="noreferrer" target="_blank" moz-do-not-send="true"
class="moz-txt-link-freetext">dexter@expeedo.de</a>>
wrote:<br>
</div>
<blockquote
class="gmail_quote"
style="margin:0px 0px 0px 0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div> Michael,<br>
<br>
looks all good
to me, once
again nice
find with the
decode
argument.
Adding decode
to the Value()
call was only
for symmetry
IIRC, the main
use was with
GetValues() (<a
href="https://docs.openvehicles.com/en/latest/userguide/scripting.html#ovmsmetrics"
rel="noreferrer" target="_blank" moz-do-not-send="true"
class="moz-txt-link-freetext">https://docs.openvehicles.com/en/latest/userguide/scripting.html#ovmsmetrics</a>).<br>
<br>
Don't forget
to test
arrays, e.g.
"v.t.pressure"
&
"v.t.temp".<br>
<br>
Returning null
for an
undefined
metric seems
like a natural
choice, but is
a rather deep
change, as for
consistency
not only the
Duktape
metrics API
but also the
Web UI metrics
API would need
to be changed
accordingly.
Unless you've
got a real use
case that
needs that, we
should be
careful.<br>
<br>
Regards,<br>
Michael<br>
<br>
<br>
<div>Am
07.11.22 um
15:00 schrieb
Michael
Geddes:<br>
</div>
<blockquote
type="cite">
<div dir="ltr">
<div dir="ltr">I
have figured
out a bunch of
stuff and have
implemented
the following:
(having done
away with
needing
AsFloatUnit)
<div><br>
</div>
<div>OvmsMetrics.Value(
{metric} [,
{decode}])</div>
<div>OvmsMetrics.Value(
{metric},
{unit}
[,{decode}])</div>
<div><br>
</div>
<div>It turns
out that the
[decode] flag
wasn't working
anyway (since
the function
was being
registered as
only having 1
param)...</div>
<div>This way
it is still
really 1
function.. but
I check it the
second
parameter is a
'boolean', and
if not.. try
the second
form. </div>
<div><br>
</div>
<div>OvmsMetrics.AsFloat(
{metric}
[,{unit}] )</div>
<div><br>
</div>
<div>and add
the function</div>
<div><br>
</div>
<div>Ovms.Metrics.ValueUnit(
{metric}
[,{unit}]) </div>
<div>This
prints the
value and the
unit.</div>
<div><br>
</div>
<div>Here's a
sample
function and
the output!
This also
shows the
types of the
output.</div>
<div><br>
</div>
<div><font
face="monospace">(function()
{<br>
x =
OvmsMetrics.Value("xiq.v.trip.consumption");<br>
print(
(typeof x) +
": "+ x+"\n"
);<br>
x =
OvmsMetrics.Value("xiq.v.trip.consumption",
false);<br>
print(
(typeof x) +
": "+ x +"\n"
);<br>
x =
OvmsMetrics.Value("xiq.v.trip.consumption","kmpkwh")<br>
print(
(typeof x) +
": "+ x
+"\n");<br>
x =
OvmsMetrics.Value("xiq.v.trip.consumption",
"mipkwh",
false) <br>
print(
(typeof x) +
": "+ x
+"\n");<br>
x =
OvmsMetrics.ValueUnit("xiq.v.trip.consumption")<br>
print(
(typeof x) +
": "+ x
+"\n");<br>
x =
OvmsMetrics.ValueUnit("xiq.v.trip.consumption","mipkwh")<br>
print(
(typeof x) +
": "+ x
+"\n");<br>
x =
OvmsMetrics.AsFloat("xiq.v.trip.consumption")<br>
print(
(typeof x) +
": "+ x
+"\n");<br>
x =
OvmsMetrics.AsFloat("xiq.v.trip.consumption","kmpkwh")<br>
print(
(typeof x) +
": "+ x
+"\n");<br>
})();</font><br>
</div>
<div><br>
</div>
<div>
<pre id="m_-6437764485757861817m_1446710767644746708m_3389478097269637711m_-3595551468962657953m_-358274377416053507m_-7644593744426345619m_-5441616086226233372m_8405494616978842232m_-5904723395924573806m_1733173679174480992m_-138117451584655546m_5484224439251412587m_-6783916119872647666m_7514939671383041717m_-2249740601380801512gmail-output" style="box-sizing:border-box;overflow:auto;font-family:ui-monospace,"Cascadia Mono","Segoe UI Mono",Hack,"Source Code Pro","Roboto Mono",Menlo,Monaco,Consolas,monospace;font-size:13px;padding:9.5px;margin-top:0px;margin-bottom:10px;line-height:1.42857;color:rgb(0,34,0);word-break:break-all;background-color:rgb(245,245,245);border:1px solid rgb(204,204,204);border-radius:4px;height:165px;white-space:pre-wrap">number: 17.0582
string: 17.0582
number: 5.86227
string: 3.64264
string: 17.0582kWh/100km
string: 3.64264mi/kWh
number: 17.0582
number: 5.86227</pre>
</div>
<div><br>
</div>
<div><br>
</div>
<div>It still
might be an
idea to use
'null' as a
return value
if the metrics
is<font
face="monospace">
!IsDefined() </font><font
face="arial,
sans-serif">but
that would be
changing the
existing
behaviour
slightly.</font></div>
<div><font
face="arial,
sans-serif"><br>
</font></div>
<div><font
face="arial,
sans-serif">//.ichael</font></div>
<div><br>
</div>
</div>
<div
class="gmail_quote">
<div dir="ltr"
class="gmail_attr">On Mon, 7 Nov 2022 at 08:12, Michael Geddes <<a
href="mailto:frog@bunyip.wheelycreek.net"
rel="noreferrer" target="_blank" moz-do-not-send="true"
class="moz-txt-link-freetext">frog@bunyip.wheelycreek.net</a>>
wrote:<br>
</div>
<blockquote
class="gmail_quote"
style="margin:0px 0px 0px 0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div dir="ltr">I've
worked out
what the
decode flag is
for and how it
works, and I
think how
optional
params work. <br>
<div>I'm
pretty sure I
won't need
the
'AsFloatUnit'
function; the
unit would be
an option to
AsFloat();
I'll know that
soon.</div>
<div><br>
</div>
<div>The
'Value'
function is
more
complicated
because of the
optional
decode bool. I
guess I could
add the Unit
to the end of
that.</div>
<div><br>
</div>
<div>ValueUnit
could be still
useful then to
provide a
'Value +
Unit'.</div>
<div><br>
</div>
<div>Question:
Is there a
reason we
shouldn't be
returning
with <span style="color:rgb(220,220,170);background-color:rgb(30,30,30);font-family:Consolas,"Courier New",monospace;font-size:14px;white-space:pre-wrap">duk_push_null</span>
if the
metric
!IsDefined()
in both
AsFloat() and
Value(metric,true) cases?</div>
<div><br>
</div>
<div>//.ichael</div>
</div>
<br>
<div
class="gmail_quote">
<div dir="ltr"
class="gmail_attr">On Sun, 6 Nov 2022 at 11:22, Michael Geddes <<a
href="mailto:frog@bunyip.wheelycreek.net"
rel="noreferrer" target="_blank" moz-do-not-send="true"
class="moz-txt-link-freetext">frog@bunyip.wheelycreek.net</a>>
wrote:<br>
</div>
<blockquote
class="gmail_quote"
style="margin:0px 0px 0px 0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div dir="ltr">
<div>Right, so
I've
implemented
some stuff
that seems to
work quite
well. <br>
</div>
<div><br>
</div>
<div><a
href="https://github.com/openvehicles/Open-Vehicle-Monitoring-System-3/pull/764"
rel="noreferrer" target="_blank" moz-do-not-send="true"
class="moz-txt-link-freetext">https://github.com/openvehicles/Open-Vehicle-Monitoring-System-3/pull/764</a>
should be
ready now
after a couple
of stupid
mistakes
slipped
through.
This
absolutely
needs somebody
to review it
please!
(There's a
reason why
I've converted
some if()'s to
switch() -
which is that
it will be
used in the
follow-up
commit).</div>
<div><br>
</div>
<div>The
commit that
will follow on
from that it
implements the
new Units:
kWh/100km,
km/kWh and
mi/kWh.</div>
<div><br>
</div>
<div>This is a
summary of
what I've
implemented
for scripting
- including
showing the
unit codes I
have so far.
I've
considered a
few things:</div>
<div> *
Should some of
the longer
unit codes be
shortened (eg
mi, mins, m,
ft, deg, perc)</div>
<div> * The
unit codes
could be much
more re<font
face="arial,
sans-serif">gular
and separated
by dots eg: </font></div>
<div><font
face="arial,
sans-serif">
watthours
-> w.h</font></div>
<div><font
face="arial,
sans-serif">
kwhp100km
->
kw.h_100km or
kw.h/100km</font></div>
<div><font
face="arial,
sans-serif">
miph
-> mi_h or
mi/h (or
should it be
mph).</font></div>
<div><font
face="arial,
sans-serif">
psi
-> <a
href="http://p_in.in/"
rel="noreferrer" target="_blank" moz-do-not-send="true">p_in.in</a> or
p/<a
href="http://in.in/"
rel="noreferrer" target="_blank" moz-do-not-send="true">in.in</a> or <a
href="http://lb_in.in/" rel="noreferrer" target="_blank"
moz-do-not-send="true">lb_in.in</a>
(yes, slightly
weird, but
predictable)</font></div>
<div><font
face="arial,
sans-serif"> </font><br>
</div>
<b
style="font-family:monospace">OVMS#
metric units</b><br>
<font
face="monospace">
km :
km</font><br>
<font
face="monospace">
miles : M</font><br>
<font
face="monospace">
meters : m</font><br>
<font
face="monospace">
feet :
ft</font><br>
<font
face="monospace">
celcius :
°C</font><br>
<font
face="monospace">
fahrenheit :
°F</font><br>
<font
face="monospace">
kpa :
kPa</font><br>
<font
face="monospace">
pa :
Pa</font><br>
<font
face="monospace">
psi :
psi</font><br>
<font
face="monospace">
volts : V</font><br>
<font
face="monospace">
amps : A</font><br>
<font
face="monospace">
</font>amphours<font
face="monospace"> : Ah</font><br>
<font
face="monospace">
kw :
kW</font><br>
<font
face="monospace">
kwh :
kWh</font><br>
<font
face="monospace">
watts : W</font><br>
<font
face="monospace">
</font>watthours<font
face="monospace"> : Wh</font><br>
<font
face="monospace">
seconds :
Sec</font><br>
<font
face="monospace">
minutes :
Min </font><br>
<font
face="monospace">
hours :
Hour</font><br>
<font
face="monospace">
utc :
UTC</font><br>
<font
face="monospace">
degrees : °</font><br>
<font
face="monospace">
kmph :
km/h</font><br>
<font
face="monospace">
</font>miph<font
face="monospace"> : Mph</font><br>
<font
face="monospace">
</font>kmphps<font
face="monospace"> : km/h/s</font><br>
<font
face="monospace">
</font>miphps<font
face="monospace"> : Mph/s</font><br>
<font
face="monospace">
mpss :
m/s²</font><br>
<font
face="monospace">
dbm :
dBm</font><br>
<font
face="monospace">
sq :
sq</font><br>
<font
face="monospace">
percent : %</font><br>
<font
face="monospace">
whpkm :
Wh/km</font><br>
<font
face="monospace">
</font>whpmi<font
face="monospace"> : Wh/mi</font><br>
<font
face="monospace">
kwhp100km :
kWh/100km</font><br>
<font
face="monospace">
</font>kmpkwh<font
face="monospace"> : km/kWh</font><br>
<font
face="monospace">
</font>mipkwh<font
face="monospace"> : mi/kWh</font><br>
<font
face="monospace">
nm :
Nm</font><br>
<font
face="monospace"><br>
<b>OVMS#
metric unit mi</b><br>
miles :
M<br>
</font></div>
</blockquote>
</div>
</blockquote>
</div>
</div>
</blockquote>
</div>
</blockquote>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</blockquote>
</div>
</blockquote>
</div>
</blockquote>
</div>
</blockquote>
</div>
</div>
</blockquote>
</div>
</blockquote>
</div>
</blockquote>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</blockquote>
</div>
</div>
</blockquote>
</div>
</div>
</blockquote>
</div>
</blockquote>
</div>
</div>
</div>
</div>
</blockquote>
</div>
<br>
<fieldset></fieldset>
<pre>_______________________________________________
OvmsDev mailing list
<a href="mailto:OvmsDev@lists.openvehicles.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">OvmsDev@lists.openvehicles.com</a>
<a href="http://lists.openvehicles.com/mailman/listinfo/ovmsdev" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">http://lists.openvehicles.com/mailman/listinfo/ovmsdev</a>
</pre>
</blockquote>
<br>
<pre cols="72">--
Michael Balzer * Helkenberger Weg 9 * D-58256 Ennepetal
Fon 02333 / 833 5735 * Handy 0176 / 206 989 26</pre>
</div>
_______________________________________________<br>
OvmsDev mailing list<br>
<a href="mailto:OvmsDev@lists.openvehicles.com"
target="_blank" moz-do-not-send="true"
class="moz-txt-link-freetext">OvmsDev@lists.openvehicles.com</a><br>
<a
href="http://lists.openvehicles.com/mailman/listinfo/ovmsdev"
rel="noreferrer" target="_blank" moz-do-not-send="true"
class="moz-txt-link-freetext">http://lists.openvehicles.com/mailman/listinfo/ovmsdev</a><br>
</blockquote>
</div>
</div>
<br>
<fieldset class="moz-mime-attachment-header"></fieldset>
<pre class="moz-quote-pre" wrap="">_______________________________________________
OvmsDev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:OvmsDev@lists.openvehicles.com">OvmsDev@lists.openvehicles.com</a>
<a class="moz-txt-link-freetext" href="http://lists.openvehicles.com/mailman/listinfo/ovmsdev">http://lists.openvehicles.com/mailman/listinfo/ovmsdev</a>
</pre>
</blockquote>
<br>
<pre class="moz-signature" cols="72">--
Michael Balzer * Helkenberger Weg 9 * D-58256 Ennepetal
Fon 02333 / 833 5735 * Handy 0176 / 206 989 26</pre>
</body>
</html>