openhab / openhab-core

Core framework of openHAB
https://www.openhab.org/
Eclipse Public License 2.0
917 stars 422 forks source link

Add ability to specify precision for items #1495

Closed robnielsen closed 1 year ago

robnielsen commented 4 years ago

This is a request to add a new feature to OH3 to specify precision for items that are represented by BigDecimal since it supports precision. This could be done either globally like the measurement system is set or individually on items. For example, when converting between Metric and Imperial Systems, items contain values that include false precision (https://en.wikipedia.org/wiki/False_precision). This can also occur with calculations such as heat index.

For example if events.log contains:

rain changed from 0.004212598455703164648821973425196850 in to 0.008425196911406329297643946850393701 in
pressure changed from 29.86663147914717687400262462541209 inHg to 29.87253603503017078964371477810576 inHg
temp changed from 62.960001373291015625 °F to 63.139998626708984375 °F

Currently, the display of the items in a UI can be converted using:

Number:Length      rain     "[%.03f in]"
Number:Pressure    pressure "[%.2f inHg]"
Number:Temperature temp     "[%.1f °F]" 

This is not user friendly and is confusing for non-technical people. Using the above example here's a way to possibly set the precision.

Number:Length(3)      rain 
Number:Pressure(2)    pressure
Number:Temperature(1) temp

Then the items in events.log would be:

rain changed from 0.004 in to 0.008 in
pressure changed from 29.87 inHg to 29.87 inHg
temp changed from 63.0 °F to 63.1 °F

As well as the same in the UI. Not only is this easier to use, but the actual item now represents what is displayed in the UI.

kaikreuzer commented 4 years ago

Adding it on item level is imho not the right place, because items only say that they are of a certain dimension. The precision can then highly depend on the unit you want it to be displayed in.

Ideally, the bindings should deliver the states with the precision they can provide. If we then have false precisions by automatic unit conversion, I would say that this should be addressed within the unit conversion logic. If the state carries the precision information, it should be possible to keep it through the transformation.

It might be a problem that atm no binding sets the precision. Best way to address this might be a system wide configurable default precision for each dimension.

robnielsen commented 4 years ago

Yes, I agree a system wide default precision would be best. I was trying to provide a couple of options.

BTW, the examples here are from Netatmo devices. It's precision is:

Temperature: Accuracy: ± 0.3°C / ± 0.54°F Barometer: Accuracy: ± 1 mbar / ± 0.03 inHg Rain: 0.1 mm / 0.004 in

ghys commented 4 years ago

Maybe that could be implemented as a rounding profile, with the number of decimals configured in the profile?

seime commented 4 years ago

@ghys #1204 & #779

J-N-K commented 2 years ago

IMO this should be closed. Intermediate results should never be rounded as that essentially leads to a loss of precision (This is also stated in the Wikipedia article linked above:

However, in contrast, it is good practice to retain more significant figures than this in the intermediate stages of a calculation, in order to avoid accumulated [rounding errors](https://en.wikipedia.org/wiki/Rounding_error).

I would consider the item state to be such an intermediate result because using them for calculating other quantities is a common use case. The precision should be set when displaying the value and that is already possible.

spacemanspiff2007 commented 2 years ago

I think keeping precision in openhab high is good. However I think there is a need to specify precision on either on

I've connected one set of LEDs to a Plug and look how it fills up the events.log and keeps spamming events over SSE. This makes it very hard to track down other issues.

2022-10-10 06:06:51.840 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'LEDs_Power' changed from 7.19 to 7.18
2022-10-10 06:07:00.295 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'LEDs_Power' changed from 7.18 to 7.20
2022-10-10 06:07:06.847 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'LEDs_Power' changed from 7.20 to 7.19
2022-10-10 06:07:09.405 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'LEDs_Power' changed from 7.19 to 7.20
2022-10-10 06:07:21.857 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'LEDs_Power' changed from 7.20 to 7.19
2022-10-10 06:07:24.565 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'LEDs_Power' changed from 7.19 to 7.18
2022-10-10 06:07:36.860 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'LEDs_Power' changed from 7.18 to 7.19
2022-10-10 06:07:39.716 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'LEDs_Power' changed from 7.19 to 7.18
2022-10-10 06:07:51.870 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'LEDs_Power' changed from 7.18 to 7.17
2022-10-10 06:07:54.871 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'LEDs_Power' changed from 7.17 to 7.21
2022-10-10 06:07:56.945 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Ping' changed from 10.6 ms to 11.6 ms
2022-10-10 06:08:01.017 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'LEDs_Power' changed from 7.21 to 7.18
2022-10-10 06:08:06.870 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'LEDs_Power' changed from 7.18 to 7.19
2022-10-10 06:08:09.291 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Sun_Azimuth' changed from 82.50040724792725 to 83.57393418506345
2022-10-10 06:08:09.292 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'Sun_Elevation' changed from -18.819870137597515 to -17.703338073964354
2022-10-10 06:08:21.876 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'LEDs_Power' changed from 7.19 to 7.21
2022-10-10 06:08:48.977 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'MyTemperature' changed from 23.8 °C to 23.9 °C
2022-10-10 06:08:51.883 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'LEDs_Power' changed from 7.21 to 7.18
2022-10-10 06:09:01.752 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'LEDs_Power' changed from 7.18 to 7.21
2022-10-10 06:09:06.886 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'LEDs_Power' changed from 7.21 to 7.19
2022-10-10 06:09:21.885 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'LEDs_Power' changed from 7.19 to 7.21
2022-10-10 06:09:36.885 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'LEDs_Power' changed from 7.21 to 7.20
2022-10-10 06:10:02.465 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'LEDs_Power' changed from 7.20 to 7.19
2022-10-10 06:10:02.466 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'LEDs_Energy' changed from 0.201 to 0.202
2022-10-10 06:10:06.887 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'LEDs_Power' changed from 7.19 to 7.17
2022-10-10 06:10:08.603 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'LEDs_Power' changed from 7.17 to 7.18
2022-10-10 06:10:23.765 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'LEDs_Power' changed from 7.18 to 7.19
2022-10-10 06:10:36.899 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'LEDs_Power' changed from 7.19 to 7.20
2022-10-10 06:10:38.914 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'LEDs_Power' changed from 7.20 to 7.19

I would have been perfectly happy if the power value would have been rounded to 7.2W. Differentiation between 7.2W and 7.18W has no benefit and since the plug measures up to 3000W the value 7.18W is probably just sensor jitter anyway.


Now imagine if I would have multiple LEDs (e.g. 10 or more) connected and active. The logs would eventually become useless because they fill up so fast and get rotated and it's unnecessary high load on the system.

rkoshak commented 2 years ago

My search skills are not sufficient or else my memory is failing me. At one point I thought someone was working on a profile that only forwards those updates that are a certain amount different from the current state of the Item. That could be a relatively painless way to filter out the sensor jitter like this.

Of course, if the Generic Scripting Profile get's merged, it wouldn't be too hard to implement something that way.

Though, for this to work, the profile will need access to the item's current state. You can't base the decision based on the last update because if there is a slow but gradual rise or fall it might get missed.

J-N-K commented 2 years ago

There is a 3rd party ROUND profile for the application of @spacemanspiff2007. A script like @rkoshak suggested is of course also fine (in JS it‘s already possible if the proper transformation add-on is installed).

The issue here however is different, it‘s not about the inbound precision (which should be applied before the state is applied to the item) but about the precision of a unit conversion takes place. And I still regard that as intermediate result which should not be rounded. The precision should be set for displaying the item in the state description.

spacemanspiff2007 commented 2 years ago

The issue here however is different

What do you mean by "here". Do you mean rounding of item values or do you mean item event reduction through rounding? My goal is the latter.

I've searched for js transformation and only found an entry which complains about problems with the "%.1f" format because the js transformation returns a string. But even if that would work it still wouldn't reduce the item update events ...

J-N-K commented 2 years ago

There are two different issues:

  1. An outside system (like your thing) reports values with a higher precision than needed. In this case a profile that reduces the precision (by rounding) would be the correct way to go, you would still receive the ItemStateUpdatedEvent, but not the ItemStateChangedEvent, because the value is the same. Rounding can be achieved by a specialized profile or a general purpose profile like the JavaScriptTransformation profile (https://www.openhab.org/addons/transformations/javascript/). If you create a script that does the correct rounding, it should work.
  2. The state of an item is set to 70 °F by a binding. The system unit is set to °C and without setting a state description the value is displayed as 21.1111 °C. Obviously 21.1111 is far more "precise" than the original value and this is the result of the mathematical operation used in the unit conversion. As stated in the first post this can be solved by state descriptions and I believe that rounding values that are the result of some unit conversion should not be done implicitly, as they are intermediate results.