[Ovmsdev] New Metric Units
Michael Geddes
frog at bunyip.wheelycreek.net
Fri Nov 11 16:54:33 HKT 2022
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
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openvehicles.com/pipermail/ovmsdev/attachments/20221111/13e29e5f/attachment-0001.htm>
More information about the OvmsDev
mailing list