<div dir="ltr"><div>Oooh.. I can now see this might actually happen.</div><div><br></div><div>Btw, one of the nice things about the async subscriptions is that the form (like the dashboard) doesn't freeze when loading up.. so the page loads and renders and then the metrics kinda of just slide on in. I don't believe it takes as long as loading all metrics - but also it feels from a UI perspective even shorter because the UI loads quicker.</div><div><br></div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, 14 Dec 2022 at 05:42, Michael Balzer <<a href="mailto:dexter@expeedo.de">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>
    <div>Am 13.12.22 um 00:00 schrieb Michael
      Geddes:<br>
    </div>
    <blockquote type="cite">
      
      <div dir="ltr">I'll go back and revise the topic subscriptions
        stuff wrt metrics etc. with the stuff I have done.
        <div><br>
        </div>
        <div>I have implemented metric subscriptions and also
          implemented async getters in the dashboard just to see what
          the burden is, and tbh it's not too bad!  I had no real
          expectation that this would end up in the final code and it
          was more just to further my understanding.   What I've done
          does require a 'get and subscribe' function added to the
          websocket.</div>
        <div><br>
        </div>
        <div><b>unit getsub  <i>CallID</i>  m<i>etricName</i></b></div>
        <div>Which subscribes to the metric, but also returns a result
          something like</div>
        <div>{ result : {  ID: <i>CallID</i>, Metric: <i>metricName</i>,
          Value: <i>metricValue</i>, Units : { native: <i>unitcode</i>,
          unit: <i>userunitcode</i>, label: <i>label</i>} }}</div>
        <div><br>
        </div>
        <div>So I can create a Promise and put the Accept function
          agains the (random) <i>CallID</i> on an object, (and a timeout
          that calls reject) -so when the result comes in I can call the
          accept. <br>
        </div>
      </div>
    </blockquote>
    <br>
    If the asynchronous nature isn't hidden (i.e. caller needs to use
    async/await tags) and using the async getters is an alternative to
    the pattern subscription scheme, that would be OK for inclusion. It
    adds another way to subscribe, that may be better for some
    applications. Keep in mind a page/fragment's getter subscriptions
    then also need to be unsubscribed on unloading the page/fragment.<br></div></blockquote><div><br></div><div>Yep - definitely worked out that the async nature can't be hidden, it seems it's just not an option.  </div><div>Hmm.. unsubscribe - ouch - this might be 'fun'.  Will see how it goes.  The values need to be cleared from the metrics[] array indicating they need to be subscribed again.</div><div> </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>
    <blockquote type="cite">
      <div dir="ltr">
        <div>It still doesn't get over the need for plugins to either
          subscribe to the metrics they want to access through
          metrics[]... or use the ametrics[] collection in an async
          function.  Having a tag (as you mentioned) that says which
          metrics to subscribe to would be at least backwards
          compatible.  I guess we could make it so that if a plugin was
          searched for such a tag and none existed, we could subscribe
          all?</div>
      </div>
    </blockquote>
    <br>
    Yes, and we could add an API version attribute, to be able to
    identify receivers that expect to have direct access to all metrics.
    That way we still enable a new receiver to be created that really
    doesn't need metrics (or does all subscriptions through the async
    getters). Something like…<br>
    <br>
    <font face="monospace"><div class="receiver"><br>
        → auto subscription to "metrics/#" if no explicit "metrics/…"
      subscriptions present<br>
      <br>
      <div class="receiver" data-apiversion="2"><br>
        → only process explicit subscriptions</font></div></blockquote><div>I very much like the apiversion idea: Easy to check for.</div><div><br></div><div>Also, I've been looking at the current subscription scheme - with a tag lookup. The way I currently implement subscriptions for the metrics is that I use a 'slot' per connection like the 'modified' flag which indicates that a metric is subscribed.  I'm wondering if it would be ok if when the particular metrics/* namespace comes in, if I could divert that to using the same method I have now then it would keep things working quite quickly... would that work for you?</div><div> <br></div><div>//.ichael</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>
    <br>
    Regards,<br>
    Michael<br>
    <br>
    <br>
    <blockquote type="cite">
      <div dir="ltr">
        <div><br>
        </div>
        <div>//.ichael</div>
        <div><br>
        </div>
        <div class="gmail_quote">
          <div dir="ltr" class="gmail_attr">On Sun, 11 Dec 2022 at
            19:54, Michael Balzer <<a href="mailto:dexter@expeedo.de" target="_blank">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>
              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 href="https://docs.openvehicles.com/en/latest/components/ovms_webserver/docs/notifications.html" target="_blank">https://docs.openvehicles.com/en/latest/components/ovms_webserver/docs/notifications.html</a></li>
                <li><a href="https://github.com/openvehicles/Open-Vehicle-Monitoring-System-3/tree/master/plugins/retools" target="_blank">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>Am 08.12.22 um 04:29 schrieb Michael Geddes:<br>
              </div>
              <blockquote type="cite">
                <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);float:none;display:inline"> 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);float:none;display:inline">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">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">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">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">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">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" 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">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" 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">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">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">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_4886991932006770610m_1082575795986022020m_-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">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">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">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">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">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_4886991932006770610m_1082575795986022020m_-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">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">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">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">p_in.in</a> or
                                                          p/<a href="http://in.in/" rel="noreferrer" target="_blank">in.in</a> or <a href="http://lb_in.in/" rel="noreferrer" target="_blank">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">OvmsDev@lists.openvehicles.com</a>
<a href="http://lists.openvehicles.com/mailman/listinfo/ovmsdev" target="_blank">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">OvmsDev@lists.openvehicles.com</a><br>
                      <a href="http://lists.openvehicles.com/mailman/listinfo/ovmsdev" rel="noreferrer" target="_blank">http://lists.openvehicles.com/mailman/listinfo/ovmsdev</a><br>
                    </blockquote>
                  </div>
                </div>
                <br>
                <fieldset></fieldset>
                <pre>_______________________________________________
OvmsDev mailing list
<a href="mailto:OvmsDev@lists.openvehicles.com" target="_blank">OvmsDev@lists.openvehicles.com</a>
<a href="http://lists.openvehicles.com/mailman/listinfo/ovmsdev" target="_blank">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">OvmsDev@lists.openvehicles.com</a><br>
            <a href="http://lists.openvehicles.com/mailman/listinfo/ovmsdev" rel="noreferrer" target="_blank">http://lists.openvehicles.com/mailman/listinfo/ovmsdev</a><br>
          </blockquote>
        </div>
      </div>
      <br>
      <fieldset></fieldset>
      <pre>_______________________________________________
OvmsDev mailing list
<a href="mailto:OvmsDev@lists.openvehicles.com" target="_blank">OvmsDev@lists.openvehicles.com</a>
<a href="http://lists.openvehicles.com/mailman/listinfo/ovmsdev" target="_blank">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">OvmsDev@lists.openvehicles.com</a><br>
<a href="http://lists.openvehicles.com/mailman/listinfo/ovmsdev" rel="noreferrer" target="_blank">http://lists.openvehicles.com/mailman/listinfo/ovmsdev</a><br>
</blockquote></div></div>