<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
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><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>
<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>
<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 class="moz-cite-prefix">Am 28.11.22 um 00:36 schrieb Michael
Geddes:<br>
</div>
<blockquote type="cite"
cite="mid:CAH0p7uJp9cczE0gWwHBuXhdoDa7FFzqrE4bsUUTLF_4ve70spA@mail.gmail.com">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<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"
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_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_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 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>