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