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

_______________________________________________<br>
OvmsDev mailing list<br>
<a href="mailto:OvmsDev@lists.openvehicles.com" target="_blank">OvmsDev@lists.openvehicles.com</a><br>
<a href="http://lists.openvehicles.com/mailman/listinfo/ovmsdev" rel="noreferrer" target="_blank">http://lists.openvehicles.com/mailman/listinfo/ovmsdev</a><br>
</blockquote></div></div>