[Ovmsdev] New Metric Units

Michael Geddes frog at bunyip.wheelycreek.net
Wed Nov 16 12:11:13 HKT 2022


I've got the Dials on the Dashboard displaying in user units using the
unit#code  and unit#user method described previously.
  There are two small issues at the moment:
* Changing the Unit for a group doesn't trigger all that groups (otherwise
unchanged) values to be sent. So it would be waiting for them to change
value.
* All the configuration for the dials/charts need to be reloaded - since
the ranges and captions need really to be set up in GetDashboardConfig().
Presumably ok, those settings will be rather static - so not a big deal.

The problem with GetDashboardConfig() is that it is set up by each vehicle
so that it can modify ranges.
I have implemented a helper class.. but for this to work at all, then any
car overriding GetDashboardConfig() would have
to be converted to something like this (which I'm ok to do..).

This is my current implementation of the Ioniq5 version of that method - I
think it's more readable anyway.. but thoughts?
The helper will convert all those bands / min/max to the 'user setting'
units.


/**
 * GetDashboardConfig: Hyundai Ioniq specific dashboard setup
 */
void OvmsHyundaiIoniqEv::GetDashboardConfig(DashboardConfig &cfg)
{
  // Speed:
  dash_guage_t speed_dash(NULL, Kph);
  speed_dash.SetMinMax(0, 170, 5);
  speed_dash.AddBand("green", 0, 70, 5);
  speed_dash.AddBand("yellow", 70, 120, 5);
  speed_dash.AddBand("red", 120, 170, 5);

  // Voltage:
  dash_guage_t voltage_dash(NULL, Volts);
  voltage_dash.SetMinMax(300, 810);
  voltage_dash.AddBand("red", 350, 450);
  voltage_dash.AddBand("yellow", 450, 500);
  voltage_dash.AddBand("green", 500, 800);

  // SOC:
  dash_guage_t soc_dash("SOC ", Percentage);
  soc_dash.SetMinMax(0, 100);
  soc_dash.AddBand("red", 0, 12.5);
  soc_dash.AddBand("yellow", 12.5, 25);
  soc_dash.AddBand("green",  25,  100);

  // Efficiency:
  dash_guage_t eff_dash(NULL, WattHoursPK);
  // Efficency has some inverse relationships .. so choose values that work
either way first
  eff_dash.SetMinMax(50, 300);
  // Then force the minimum to zero (whichever way round);
  eff_dash.ZeroMin();
  eff_dash.AddBand("green", 50, 150);
  eff_dash.AddBand("yellow", 150, 250);
  eff_dash.AddBand("red", 250, 300);

  // Power:
  dash_guage_t power_dash(NULL, kW);
  power_dash.SetMinMax(-30, 30);
  power_dash.AddBand("violet", -10, 0);
  power_dash.AddBand("green", 0, 15);
  power_dash.AddBand("yellow", 15, 25);
  power_dash.AddBand("red", 25, 30);

  // Charger temperature:
  dash_guage_t charget_dash("CHG ", Celcius);
  charget_dash.SetMinMax(10, 80);
  charget_dash.SetTick(20, 5);
  charget_dash.AddBand("normal", 10, 65);
  charget_dash.AddBand("red", 65, 80);

  // Battery temperature:
  dash_guage_t batteryt_dash("BAT ", Celcius);
  batteryt_dash.SetMinMax(-15, 65);
  batteryt_dash.SetTick(25, 5);
  batteryt_dash.AddBand("red", -15, 0);
  batteryt_dash.AddBand("normal", 0, 50);
  batteryt_dash.AddBand("red", 50, 65);

  // Inverter temperature:
  dash_guage_t invertert_dash("PEM ", Celcius);
  invertert_dash.SetMinMax(20, 80);
  invertert_dash.SetTick(20, 5);
  invertert_dash.AddBand("normal", 20, 70);
  invertert_dash.AddBand("red", 70, 80);

  // Motor temperature:
  dash_guage_t motort_dash("MOT ", Celcius);
  motort_dash.SetMinMax(10, 100);
  motort_dash.SetTick(25, 5);
  motort_dash.AddBand("normal", 10, 70);
  motort_dash.AddBand("red", 70, 100);

  std::ostringstream str;
  str << "yAxis: ["
      << speed_dash << ","
      << voltage_dash << ","
      << soc_dash << ","
      << eff_dash << ","
      << power_dash << ","
      << charget_dash << ","
      << batteryt_dash << ","
      << invertert_dash << ","
      << motort_dash
      << "]";
  cfg.gaugeset1 = str.str();
}



On Tue, 15 Nov 2022 at 15:27, Michael Geddes <frog at bunyip.wheelycreek.net>
wrote:

> Also, all the command status displays should probably be in user units.
> There is already stuff there to check for miles/km... But that becomes
> simpler.
>
> For example:
>
> Not charging
> SOC: 895.0‰
> Ideal range: 245M
> Est. range: 253M
> ODO: 6754.9M
> CAC: 974.7Ah
> SOH: 1000‰
>
> I mean not my choice of units... But you can!
>
> Michael
>
>
>
> On Tue, 15 Nov 2022, 8:26 am Michael Geddes, <frog at bunyip.wheelycreek.net>
> wrote:
>
>> 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
>> 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.
>>
>> 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.
>> 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 '.' )
>>
>> v.p.odometer#unit: "M"
>> v.p.odometer#user: 6754.91
>> v.p.satcount: 13
>> v.p.speed: 0
>> v.p.speed#unit: "km/h"
>> v.p.speed#user: null
>> *v.p.trip: 28*
>>
>> *v.p.trip#unit: "M"v.p.trip#user: 17.3984*
>>
>> Then we can use this in the dials to populate the values and captions!
>> (not that I like Miles).
>> I
>>
>> [image: image.png]
>>
>> The other (similar) way was to have something like the following:
>> "v.p.trip#user" : { "value": 17.3984, "unit": "M" }
>> It wouldn't make the total message any shorter.. soo.. dunno.
>>
>> There's also some complications with setting up the dials (for min/max
>> values) - like for the speed.
>>
>> 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.
>>
>> //.ichael
>>
>> On Sun, 13 Nov 2022 at 21:06, Michael Balzer <dexter at expeedo.de> wrote:
>>
>>> Michael,
>>>
>>> looks good.
>>>
>>> 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 ;-))
>>>
>>> @Patrick, I think that also answers your implicit question:
>>>
>>> The default button makes it unclear what the actual setting is.
>>>
>>>
>>> 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.
>>>
>>> Regards,
>>> Michael
>>>
>>>
>>> Am 13.11.22 um 08:42 schrieb Michael Geddes:
>>>
>>> Greetings,
>>> so this is my idea of being able to select which units various groups
>>> use (in addition to Distance).
>>> This can be then accessed by the special 'user' unit code.  (or
>>> 'metrics list -u ' )
>>> 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.
>>>
>>>
>>> [image: image.png]
>>>
>>> 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).
>>>
>>> Thoughts / comments?
>>>
>>> //.ichael
>>>
>>> On Sat, 12 Nov 2022 at 17:35, Michael Geddes <
>>> frog at bunyip.wheelycreek.net> wrote:
>>>
>>>>
>>>> https://github.com/openvehicles/Open-Vehicle-Monitoring-System-3/pull/771
>>>>
>>>> I'm hoping this P/R is ok in this form (made of 5 separate commits).
>>>>
>>>> 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.
>>>>
>>>> The 'power consumption' is one where it's not just a check-box..
>>>> there're 5 possible choice!
>>>>
>>>> I should also add 'bar' for pressure given that for some reason that's
>>>> still a thing people want.
>>>>
>>>> //.ichael
>>>>
>>>> On Sat, 12 Nov 2022 at 16:24, Michael Balzer <dexter at expeedo.de> wrote:
>>>>
>>>>> I think this is pretty decent & complete now.
>>>>>
>>>>> 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.
>>>>>
>>>>> Regards,
>>>>> Michael
>>>>>
>>>>>
>>>>> Am 11.11.22 um 09:54 schrieb Michael Geddes:
>>>>>
>>>>> Ok - so here's what I have implemented for Duktape and Metrics. (I
>>>>> added IsDefined() as well).
>>>>> Any thoughts on this?
>>>>>
>>>>> Noting
>>>>>    OvmsMetrics.Float( {metric} ) -> Outputs metric as float (same)
>>>>>    OvmsMetrics.Float( {metric}, {unit}) -> Outputs metric as float
>>>>> converted to given unit  (new)
>>>>>    OvmsMetrics.Value( {metric} )   -> Outputs Metric in native value
>>>>> (same)
>>>>>    OvmsMetrics.Value( {metric} , false)   -> Outputs Metric as string
>>>>> and no units (same)
>>>>>    OvmsMetrics.Value( {metric} ,  {unit})  -> Outputs Metric converted
>>>>> to given unit as native value. (new)
>>>>>   OvmsMetrics.Value( {metric} ,  {unit}, false )  -> Outputs Metric
>>>>> converted to given unit as string including any unit specifier. (new)
>>>>> also  OvmsMetric.GetValues( {metric} [,{unit}] [, {converted} ] )
>>>>> Adds similar behaviour to Value() above.
>>>>> also the special units '*imperial*' and '*metric*' will convert to
>>>>> the associated imperial / metric version of the units as appropriate.
>>>>>
>>>>> (function() {
>>>>>    dump = function (metric) { print( metric+ " ["+(typeof
>>>>> metric)+"]\n"  ); }
>>>>>    dump_obj = function (obj )  {
>>>>>      print('--- Object ----\n')
>>>>>      for (var k in obj) {
>>>>>        xk = obj[k];
>>>>>        print( k+':'+ xk + ' ['+typeof xk+ "]\n");
>>>>>      }
>>>>>    }
>>>>>    dump(OvmsMetrics.Value("xiq.v.trip.consumption"));
>>>>>    dump(OvmsMetrics.Value("xiq.v.trip.consumption", false));
>>>>>    dump(OvmsMetrics.Value("xiq.v.trip.consumption","kmpkwh"));
>>>>>    dump(OvmsMetrics.Value("xiq.v.trip.consumption", "mipkwh", false));
>>>>>    dump(OvmsMetrics.AsFloat("xiq.v.trip.consumption"));
>>>>>    dump(OvmsMetrics.AsFloat("xiq.v.trip.consumption","kmpkwh"));
>>>>>    dump(OvmsMetrics.Value("xiq.v.trip.consumption","imperial"))
>>>>>    dump(OvmsMetrics.Value("xiq.v.trip.consumption","imperial", false))
>>>>>    dump_obj(OvmsMetrics.GetValues("trip", "metric"))
>>>>>    dump_obj(OvmsMetrics.GetValues("trip", "imperial", false))
>>>>> })();
>>>>>
>>>>> With this output:
>>>>>
>>>>> 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]
>>>>>
>>>>>
>>>>> On Wed, 9 Nov 2022 at 05:47, Michael Geddes <
>>>>> frog at bunyip.wheelycreek.net> wrote:
>>>>>
>>>>>> Yeah - I like HasValue.  I implemented IsDefined() but I will rename
>>>>>> it.. that's a much clearer name.
>>>>>>
>>>>>> Another thought. How about if we did this (but also with GetValues()
>>>>>> as well - see the special values below)
>>>>>>
>>>>>> OvmsMetrics.Value("xiq.v.trip.consumption",  true)  -> 17.0582
>>>>>> (Number)
>>>>>> OvmsMetrics.Value("xiq.v.trip.consumption",  false)  -> 17.0582
>>>>>> (String)
>>>>>> OvmsMetrics.Value("xiq.v.trip.consumption", "mipkwh", true)  ->
>>>>>> 3.64264  (Number)
>>>>>> OvmsMetrics.Value("xiq.v.trip.consumption", "mipkwh", false)  ->
>>>>>> 3.64264Mi/kWh  (String)
>>>>>>  OvmsMetrics.Value("xiq.v.trip.consumption", "native", false)  ->
>>>>>> 17.0582km/kWh  (String)
>>>>>>
>>>>>> and
>>>>>> OvmsMetrics.Value("xiq.v.trip.consumption", "imperial", false)  ->
>>>>>> 3.64264Mi/kWh  (String)
>>>>>>
>>>>>> I have already implemented the special values 'native' (existing),
>>>>>> 'imperial' and 'metric'.
>>>>>>
>>>>>> I was also thinking that in the future you could have 'user'. Where
>>>>>> for each group of values:
>>>>>> '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).
>>>>>>
>>>>>>
>>>>>>
>>>>>> //.ichael
>>>>>>
>>>>>> On Tue, 8 Nov 2022 at 21:57, Mark Webb-Johnson <mark at webb-johnson.net>
>>>>>> wrote:
>>>>>>
>>>>>>> Or perhaps something more specific?
>>>>>>>
>>>>>>>     HasValue()
>>>>>>>
>>>>>>> Mark
>>>>>>>
>>>>>>> On 8 Nov 2022, at 9:01 PM, Michael Balzer <dexter at expeedo.de> wrote:
>>>>>>>
>>>>>>> Signed PGP part
>>>>>>> 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".
>>>>>>>
>>>>>>> An undefined metric currently can be derived from 'Values()'
>>>>>>> returning undefined, but that's more an undocumented side effect than
>>>>>>> intended.
>>>>>>>
>>>>>>> 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.
>>>>>>>
>>>>>>> Regards,
>>>>>>> Michael
>>>>>>>
>>>>>>>
>>>>>>> Am 08.11.22 um 13:46 schrieb Michael Geddes:
>>>>>>>
>>>>>>> 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).
>>>>>>>
>>>>>>> //.
>>>>>>>
>>>>>>> On Tue, 8 Nov 2022 at 20:35, Michael Balzer <dexter at expeedo.de>
>>>>>>> wrote:
>>>>>>>
>>>>>>>> Michael,
>>>>>>>>
>>>>>>>> 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() (
>>>>>>>> https://docs.openvehicles.com/en/latest/userguide/scripting.html#ovmsmetrics
>>>>>>>> ).
>>>>>>>>
>>>>>>>> Don't forget to test arrays, e.g. "v.t.pressure" & "v.t.temp".
>>>>>>>>
>>>>>>>> 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.
>>>>>>>>
>>>>>>>> Regards,
>>>>>>>> Michael
>>>>>>>>
>>>>>>>>
>>>>>>>> Am 07.11.22 um 15:00 schrieb Michael Geddes:
>>>>>>>>
>>>>>>>> I have figured out a bunch of stuff and have implemented the
>>>>>>>> following: (having done away with needing AsFloatUnit)
>>>>>>>>
>>>>>>>> OvmsMetrics.Value( {metric} [, {decode}])
>>>>>>>> OvmsMetrics.Value( {metric}, {unit} [,{decode}])
>>>>>>>>
>>>>>>>> It turns out that the [decode] flag wasn't working anyway (since
>>>>>>>> the function was being registered as only having 1 param)...
>>>>>>>> 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.
>>>>>>>>
>>>>>>>> OvmsMetrics.AsFloat( {metric} [,{unit}] )
>>>>>>>>
>>>>>>>> and add the function
>>>>>>>>
>>>>>>>> Ovms.Metrics.ValueUnit( {metric} [,{unit}])
>>>>>>>> This prints the value and the unit.
>>>>>>>>
>>>>>>>> Here's a sample function and the output! This also shows the types
>>>>>>>> of the output.
>>>>>>>>
>>>>>>>> (function() {
>>>>>>>>    x = OvmsMetrics.Value("xiq.v.trip.consumption");
>>>>>>>>    print( (typeof x) + ": "+  x+"\n"  );
>>>>>>>>    x = OvmsMetrics.Value("xiq.v.trip.consumption", false);
>>>>>>>>    print( (typeof x) + ": "+  x +"\n" );
>>>>>>>>    x =  OvmsMetrics.Value("xiq.v.trip.consumption","kmpkwh")
>>>>>>>>    print( (typeof x) + ": "+ x +"\n");
>>>>>>>>    x =  OvmsMetrics.Value("xiq.v.trip.consumption", "mipkwh",
>>>>>>>> false)
>>>>>>>>    print( (typeof x) + ": "+ x +"\n");
>>>>>>>>    x =  OvmsMetrics.ValueUnit("xiq.v.trip.consumption")
>>>>>>>>    print( (typeof x) + ": "+ x +"\n");
>>>>>>>>    x =  OvmsMetrics.ValueUnit("xiq.v.trip.consumption","mipkwh")
>>>>>>>>    print( (typeof x) + ": "+ x +"\n");
>>>>>>>>    x =  OvmsMetrics.AsFloat("xiq.v.trip.consumption")
>>>>>>>>    print( (typeof x) + ": "+ x +"\n");
>>>>>>>>    x =  OvmsMetrics.AsFloat("xiq.v.trip.consumption","kmpkwh")
>>>>>>>>    print( (typeof x) + ": "+ x +"\n");
>>>>>>>> })();
>>>>>>>>
>>>>>>>> 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
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> It still might be an idea to use 'null' as a return value if the
>>>>>>>> metrics is !IsDefined() but that would be changing the existing
>>>>>>>> behaviour slightly.
>>>>>>>>
>>>>>>>> //.ichael
>>>>>>>>
>>>>>>>> On Mon, 7 Nov 2022 at 08:12, Michael Geddes <
>>>>>>>> frog at bunyip.wheelycreek.net> wrote:
>>>>>>>>
>>>>>>>>> I've worked out what the decode flag is for and how it works, and
>>>>>>>>> I think how optional params work.
>>>>>>>>> I'm pretty sure I won't  need the 'AsFloatUnit' function; the unit
>>>>>>>>> would be an option to AsFloat(); I'll know that soon.
>>>>>>>>>
>>>>>>>>> The 'Value' function is more complicated because of the optional
>>>>>>>>> decode bool. I guess I could add the Unit to the end of that.
>>>>>>>>>
>>>>>>>>> ValueUnit could be still useful then to provide a 'Value + Unit'.
>>>>>>>>>
>>>>>>>>> Question:  Is there a reason we shouldn't be returning with
>>>>>>>>> duk_push_null    if the metric !IsDefined()  in both AsFloat()
>>>>>>>>> and Value(metric,true) cases?
>>>>>>>>>
>>>>>>>>> //.ichael
>>>>>>>>>
>>>>>>>>> On Sun, 6 Nov 2022 at 11:22, Michael Geddes <
>>>>>>>>> frog at bunyip.wheelycreek.net> wrote:
>>>>>>>>>
>>>>>>>>>> Right, so I've implemented some stuff that seems to work quite
>>>>>>>>>> well.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> https://github.com/openvehicles/Open-Vehicle-Monitoring-System-3/pull/764
>>>>>>>>>> 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).
>>>>>>>>>>
>>>>>>>>>> The commit that will follow on from that it implements the new
>>>>>>>>>> Units: kWh/100km, km/kWh  and  mi/kWh.
>>>>>>>>>>
>>>>>>>>>> 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:
>>>>>>>>>>   * Should some of the longer unit codes be shortened  (eg mi,
>>>>>>>>>> mins, m, ft, deg, perc)
>>>>>>>>>>   * The unit codes could be much more regular and separated by
>>>>>>>>>> dots  eg:
>>>>>>>>>>         watthours -> w.h
>>>>>>>>>>         kwhp100km -> kw.h_100km or kw.h/100km
>>>>>>>>>>         miph ->  mi_h or mi/h  (or should it be mph).
>>>>>>>>>>         psi -> p_in.in or p/in.in or lb_in.in (yes, slightly
>>>>>>>>>> weird, but predictable)
>>>>>>>>>>
>>>>>>>>>> *OVMS# metric units*
>>>>>>>>>>           km : km
>>>>>>>>>>        miles : M
>>>>>>>>>>       meters : m
>>>>>>>>>>         feet : ft
>>>>>>>>>>      celcius : °C
>>>>>>>>>>   fahrenheit : °F
>>>>>>>>>>          kpa : kPa
>>>>>>>>>>           pa : Pa
>>>>>>>>>>          psi : psi
>>>>>>>>>>        volts : V
>>>>>>>>>>         amps : A
>>>>>>>>>>     amphours : Ah
>>>>>>>>>>           kw : kW
>>>>>>>>>>          kwh : kWh
>>>>>>>>>>        watts : W
>>>>>>>>>>    watthours : Wh
>>>>>>>>>>      seconds : Sec
>>>>>>>>>>      minutes : Min
>>>>>>>>>>        hours : Hour
>>>>>>>>>>          utc : UTC
>>>>>>>>>>      degrees : °
>>>>>>>>>>         kmph : km/h
>>>>>>>>>>         miph : Mph
>>>>>>>>>>       kmphps : km/h/s
>>>>>>>>>>       miphps : Mph/s
>>>>>>>>>>         mpss : m/s²
>>>>>>>>>>          dbm : dBm
>>>>>>>>>>           sq : sq
>>>>>>>>>>      percent : %
>>>>>>>>>>        whpkm : Wh/km
>>>>>>>>>>        whpmi : Wh/mi
>>>>>>>>>>    kwhp100km : kWh/100km
>>>>>>>>>>       kmpkwh : km/kWh
>>>>>>>>>>       mipkwh : mi/kWh
>>>>>>>>>>           nm : Nm
>>>>>>>>>>
>>>>>>>>>> *OVMS# metric unit mi*
>>>>>>>>>>        miles : M
>>>>>>>>>>      minutes : Min
>>>>>>>>>>         miph : Mph
>>>>>>>>>>       miphps : Mph/s
>>>>>>>>>>        whpmi : Wh/mi
>>>>>>>>>>       mipkwh : mi/kWh
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> *OVMS# metric get xiq.v.trip.consumption *17.0597kWh/100km
>>>>>>>>>>
>>>>>>>>>> *OVMS# metric get xiq.v.trip.consumption kpkwh *5.86177km/kWh
>>>>>>>>>>
>>>>>>>>>> *OVMS# metric get xiq.v.trip.consumption mpkwh *3.64233mi/kWh
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> *OVMS# metric set xiq.c.speed 5 miph *Metric set
>>>>>>>>>>
>>>>>>>>>> *OVMS# metric get xiq.c.speed *8.04673km/h
>>>>>>>>>>
>>>>>>>>>> *OVMS# metric get xiq.c.speed miph *5Mph
>>>>>>>>>>
>>>>>>>>>> And then in DukTape - there are some questions I have about the
>>>>>>>>>> implementation:
>>>>>>>>>> * Names of functions? Better ideas?
>>>>>>>>>> * Should ValueUnit output the units?
>>>>>>>>>> * In Value() there is the line    bool decode =
>>>>>>>>>> duk_opt_boolean(ctx, 1, true);
>>>>>>>>>>     * What does 'decode' mean here?
>>>>>>>>>>     * Do I need it for ValueUnit() ?
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> * (function() {    print(
>>>>>>>>>> OvmsMetrics.Value("xiq.v.trip.consumption"));    print("\n")    print(
>>>>>>>>>> OvmsMetrics.ValueUnit("xiq.v.trip.consumption",""));    print("\n")
>>>>>>>>>>  print( OvmsMetrics.ValueUnit("xiq.v.trip.consumption","mipkwh"));
>>>>>>>>>>  print("\n")    print(
>>>>>>>>>> OvmsMetrics.AsFloatUnit("xiq.v.trip.consumption","kmpkwh")); })();*
>>>>>>>>>> --- Output ---
>>>>>>>>>> 17.0597
>>>>>>>>>> 17.0597kWh/100km
>>>>>>>>>> 3.64233mi/kWh
>>>>>>>>>> 5.86177
>>>>>>>>>> ------
>>>>>>>>>>
>>>>>>>>>> The basic stuff all works - it's just quibbling over the
>>>>>>>>>> details.. but let's get them right!
>>>>>>>>>>
>>>>>>>>>> //.ichael
>>>>>>>>>>
>>>>>>>>>> On Sat, 5 Nov 2022 at 20:09, Michael Geddes <
>>>>>>>>>> frog at bunyip.wheelycreek.net> wrote:
>>>>>>>>>>
>>>>>>>>>>> Yeah - this was copied code from kia/kona and is what triggered
>>>>>>>>>>> these ideas; I totally agree this shouldn't be doubled up on.
>>>>>>>>>>>
>>>>>>>>>>> I've got some commits centred round Metrics that I'll just check
>>>>>>>>>>> over and push up ... and then I'll just have the single xiq.v.
>>>>>>>>>>> trip.consumption metric (unless you have some ideas for the
>>>>>>>>>>> namespace) which will be much neater.
>>>>>>>>>>>
>>>>>>>>>>> If it's ok with you then I might do that unit conversion
>>>>>>>>>>> proposal.
>>>>>>>>>>> Would it ok if the unit specifications were the same as to the
>>>>>>>>>>> programatic codes in ovms_metrics.h?
>>>>>>>>>>> (kWh,   WattHours , MetersPSS )
>>>>>>>>>>> I would probably add a command
>>>>>>>>>>> metric units <spec>
>>>>>>>>>>> to list all (matching) units and their associated Labels.
>>>>>>>>>>>
>>>>>>>>>>> //.ichael
>>>>>>>>>>>
>>>>>>>>>>> On Sat, 5 Nov 2022 at 18:48, Michael Balzer <dexter at expeedo.de>
>>>>>>>>>>> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> Michael,
>>>>>>>>>>>>
>>>>>>>>>>>> adding unit conversion support to the shell and Duktape
>>>>>>>>>>>> commands is a good idea.
>>>>>>>>>>>>
>>>>>>>>>>>> Metrics are not meant to provide a user interface, they should
>>>>>>>>>>>> be defined to be efficient and non-redundant.
>>>>>>>>>>>>
>>>>>>>>>>>> Btw, metrics names also shall not use upper case characters,
>>>>>>>>>>>> and shall only use "." as a separator.
>>>>>>>>>>>>
>>>>>>>>>>>> Regards,
>>>>>>>>>>>> Michael
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Am 05.11.22 um 11:22 schrieb Michael Geddes:
>>>>>>>>>>>>
>>>>>>>>>>>> Hi all,
>>>>>>>>>>>> Some of the code I copied from Kona/Kia code had both kwh/100km
>>>>>>>>>>>> and km/kwh metrics in the code as 'Other'.
>>>>>>>>>>>> Adding the various power consumption Units is not particularly
>>>>>>>>>>>> hard (I will have a pull-request soon) - though the conversions between
>>>>>>>>>>>> them all required some thought!
>>>>>>>>>>>> ... but it also made me think these two metrics that are (with
>>>>>>>>>>>> the consumption units added) defined like this:
>>>>>>>>>>>> m_v_trip_consumption1 =
>>>>>>>>>>>> MyMetrics.InitFloat("xiq.v.trip.consumption.KWh/100km", 10, 0, kWHP100K);
>>>>>>>>>>>> m_v_trip_consumption2 = MyMetrics.InitFloat("
>>>>>>>>>>>> xiq.v.trip.consumption.km/kWh", 10, 0, kPkWH);
>>>>>>>>>>>>
>>>>>>>>>>>> These are effectively the same metric but in different units!
>>>>>>>>>>>> I'm wondering if we would be better to have scripting and
>>>>>>>>>>>> Duktape support for converting metrics to different unit!  This might be
>>>>>>>>>>>> also quite useful for those strange countries that insist on using miles as
>>>>>>>>>>>> a measurement.
>>>>>>>>>>>>
>>>>>>>>>>>> On top of the 'metric list' and 'metric set' we could add a
>>>>>>>>>>>> 'metric get' which gets a single value.. and add unit support for get/set.
>>>>>>>>>>>>
>>>>>>>>>>>> I've also got a pull request that improves the precision of the
>>>>>>>>>>>> km<->mi conversions and factors it out.
>>>>>>>>>>>>
>>>>>>>>>>>> //.ichael
>>>>>>>>>>>>
>>>>>>>>>>>> _______________________________________________
>>>>>>>>>>>> OvmsDev mailing listOvmsDev at lists.openvehicles.comhttp://lists.openvehicles.com/mailman/listinfo/ovmsdev
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> --
>>>>>>>>>>>> Michael Balzer * Helkenberger Weg 9 * D-58256 Ennepetal
>>>>>>>>>>>> Fon 02333 / 833 5735 * Handy 0176 / 206 989 26
>>>>>>>>>>>>
>>>>>>>>>>>> _______________________________________________
>>>>>>>>>>>> OvmsDev mailing list
>>>>>>>>>>>> OvmsDev at lists.openvehicles.com
>>>>>>>>>>>> http://lists.openvehicles.com/mailman/listinfo/ovmsdev
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>> _______________________________________________
>>>>>>>> OvmsDev mailing listOvmsDev at lists.openvehicles.comhttp://lists.openvehicles.com/mailman/listinfo/ovmsdev
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Michael Balzer * Helkenberger Weg 9 * D-58256 Ennepetal
>>>>>>>> Fon 02333 / 833 5735 * Handy 0176 / 206 989 26
>>>>>>>>
>>>>>>>> _______________________________________________
>>>>>>>> OvmsDev mailing list
>>>>>>>> OvmsDev at lists.openvehicles.com
>>>>>>>> http://lists.openvehicles.com/mailman/listinfo/ovmsdev
>>>>>>>>
>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> OvmsDev mailing listOvmsDev at lists.openvehicles.comhttp://lists.openvehicles.com/mailman/listinfo/ovmsdev
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Michael Balzer * Helkenberger Weg 9 * D-58256 Ennepetal
>>>>>>> Fon 02333 / 833 5735 * Handy 0176 / 206 989 26
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> OvmsDev mailing list
>>>>>>> OvmsDev at lists.openvehicles.com
>>>>>>> http://lists.openvehicles.com/mailman/listinfo/ovmsdev
>>>>>>>
>>>>>>
>>>>> _______________________________________________
>>>>> OvmsDev mailing listOvmsDev at lists.openvehicles.comhttp://lists.openvehicles.com/mailman/listinfo/ovmsdev
>>>>>
>>>>>
>>>>> --
>>>>> Michael Balzer * Helkenberger Weg 9 * D-58256 Ennepetal
>>>>> Fon 02333 / 833 5735 * Handy 0176 / 206 989 26
>>>>>
>>>>> _______________________________________________
>>>>> OvmsDev mailing list
>>>>> OvmsDev at lists.openvehicles.com
>>>>> http://lists.openvehicles.com/mailman/listinfo/ovmsdev
>>>>>
>>>>
>>> _______________________________________________
>>> OvmsDev mailing listOvmsDev at lists.openvehicles.comhttp://lists.openvehicles.com/mailman/listinfo/ovmsdev
>>>
>>>
>>> --
>>> Michael Balzer * Helkenberger Weg 9 * D-58256 Ennepetal
>>> Fon 02333 / 833 5735 * Handy 0176 / 206 989 26
>>>
>>> _______________________________________________
>>> OvmsDev mailing list
>>> OvmsDev at lists.openvehicles.com
>>> http://lists.openvehicles.com/mailman/listinfo/ovmsdev
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openvehicles.com/pipermail/ovmsdev/attachments/20221116/ccf67115/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image.png
Type: image/png
Size: 62641 bytes
Desc: not available
URL: <http://lists.openvehicles.com/pipermail/ovmsdev/attachments/20221116/ccf67115/attachment-0002.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image.png
Type: image/png
Size: 11857 bytes
Desc: not available
URL: <http://lists.openvehicles.com/pipermail/ovmsdev/attachments/20221116/ccf67115/attachment-0003.png>


More information about the OvmsDev mailing list