Martin-Gleiss/smartvisu

basic.print: Colorizing sometimes not working as expected

Closed this issue · 4 comments

{{
basic.print('', 'heizung.sensoren.af1', '%d °C', '',
[-15,15,25], ['blue','lightblue','green','orange'])
}}

This has been working well during summertime, and still is for values of 10°C and above:
image

As soon temperature goes down to 9°C and below, the color is displayed in orange instead of light blue:
image

The effect is reproducable, not just a one-time error. There is also a second item with 3 thresholds and the same strange effect. All other basic.print's with just 2 thresholds are working fine and as expected.

Possibly found the reason for this behaviour.

This only seems to happen if the source item of the value contains digits (like the yellow 7°C above - the corresponding shNG item held actually the value 7.2 at the time of reading). The item itself is correctly defined as 'num'.

@smaiLee: Is it possible that the comparison doesn't recognise numbers with digits and is using strings instead when it finds a '.' ? This would explain why the item turns orange below 10°C, because in string comparison '9.9' > '25', while '10.0' < '15' (see threshold definitions in the post above).

Also, this would explain why the color turns back to light blue again below 2°C:
String '1.9' < '15' (=light blue), and '2.0' > '15' (=orange) ...

/tom

Unfortunately I can't reproduce this issue.
Your theory sounds reasonable, but I can't confirm it. When both, the threshold an the received value (after applying the formula but before formatting) are numeric, then they are compared as numbers:

if((isNaN(value) || isNaN(threshold)) ? (threshold > value) : (parseFloat(threshold) > parseFloat(value)))

Found the cause. If a format is added to a num value, the whole thing is considered as a string. At 7.3 °C outside right now, I am getting the following results from the num item heizung.sensoren.af1 with a value of 7.3:

{{ basic.print('', 'heizung.sensoren.af1', '%d °C', '', [0,15,25], ['blue','lightblue','green','orange']) }}
Results in an orange-colored 7°C (erratic behaviour). The display string is formatted, and the result of "7 °C" is used for comparison.

{{ basic.print('', 'heizung.sensoren.af1', '', '', [0,15,25], ['blue','lightblue','green','orange']) }}
Results in a light-blue colored 7.3 (expected behaviour, but without rounding nor unit). The original num value 7.3 is used for comparison.

Seems I can only work around this with helper items that do a proper rounding for each temperature (having a lot of them meanwhile).

/tom

p.s. To fix this, it is probably the easiest way to add the same formatting string to the threshold value(s) as well before comparison is done.

p.p.s. Nope, won't work - comparison needs to be done before formatting is applied.

It seems that once a manual formatting or a unit is added (no matter if manually like "%d °C", or "°" from the language file), a string comparison is done. Also the following try didn't give the expected results:

{{ basic.print('', 'heizung.sensoren.af1', '°C', 'Math.round(VAR)', [0,15,25], ['blue','lightblue','green','orange']) }} --> orange 7 °C

While this is working fine again, but the result of course doesn't contain a colorized unit:

{{ basic.print('', 'heizung.sensoren.af1', '', 'Math.round(VAR)', [0,15,25], ['blue','lightblue','green','orange']) }} °C --> light-blue 7 with white °C

Conclusion: The paramter 'format' seems incompatible to the parameter threshold for numeric values.

For some odd reason, it seems that I was running on an elder version of basic.js, compared to the one quoted by @smaiLee above. No clue why.

After replacing it with the latest develop version, quite some code in threshold comparison has changed, and an additional/new variable 'value' is used for comparison (insted of the variable 'calc' in the elder version). So, in the develop, the issue seems to be fixed, and comparison is working properly, even along with formats:

Example for 9° outside:

{{ basic.print('', 'heizung.sensoren.af1', '°C', 'Math.round(VAR)', [0,15,25], ['blue','lightblue','green','orange']) }}

Result is now light blue, as expected:

image

Issue closed, apologies for the confusion.

/tom