[Ovmsdev] New Metric Units

Michael Geddes frog at bunyip.wheelycreek.net
Wed Nov 9 05:47:54 HKT 2022


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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openvehicles.com/pipermail/ovmsdev/attachments/20221109/53619e12/attachment-0001.htm>


More information about the OvmsDev mailing list