Setpoint problem with decimal places in sitemap?

Hey,

I have this in my sitemap;
Setpoint item=Termostat_Dag minValue=5 maxValue=28 step=0.1

Problem is that if I change the setting up and down a bit it does this;
2016-01-11 22:22:47 - Termostat_Dag received command 22.9
2016-01-11 22:22:48 - Termostat_Dag received command 22.8
2016-01-11 22:22:49 - Termostat_Dag received command 22.9
2016-01-11 22:22:51 - Termostat_Dag received command 22.8
2016-01-11 22:22:51 - Termostat_Dag received command 22.699999
2016-01-11 22:22:53 - Termostat_Dag received command 22.599998
2016-01-11 22:22:54 - Termostat_Dag received command 22.499998
2016-01-11 22:22:58 - Termostat_Dag received command 22.399998

This was a problem about a year ago, and still is… (I’ve been using step=0.5 and that actually worked, but I’d like to be able to adjust the temperature with more precision)

Anyone know what can be done to solve it?

There isn’t much you can do about it without going to a WHOLE lot of extra trouble which, at the end of the day, will not change how your system works. From a practical perspective there is no difference between 22.7 and 22.6999999.

The problem is that computers are really quite horrible at doing math with floating point numbers. What usually happens, as you are seeing, is that the computer gets pretty close (within a hundredths) of the “true” answer but rarely hits the exact answer exactly. It is just a fact of life in programming and something you have to work around. Most programmers work around it by rounding the value before showing it to a user and never ever use “==” when trying to compare something to the result of some floating point math.

For a Setpoint that moves by 0.1, there is no practical difference between 22.7 and 22.699999 so really you should just live with it. In fact your thermostat is likely converting the 22.699999 to 22.7 anyway. If you are displaying this number on your sitemap use the formatting characters to round to the tens place. That is what every other program that uses floating point numbers do: hide the error by rounding to the nearest tens or hundredths place.

In Java there is a class called BigDecimal, which is what is used to hold numeric item states in the server, and it does not suffer from the issues of the float and double native types that Rich describes. I am guessing the client is not using a similar solution that avoids this kind of problem.

I doubt (but I could be wrong) that this issue would be fixed in openHAB 1.x, but there are workarounds using proxy items and rounding if needed. A solution could be needed if the binding that’s receiving the commands can’t cope with a number like 22.699999 when sent to the Termostat_Dag item.

Interesting.

Yes, I do see errors from this time to time as well.

09:50:40.622 ERROR o.o.b.z.i.p.c.ZWaveThermostatSetpointCommandClass[:348]- NODE 4: Got an arithmetic exception converting value 22.11111111111111071636514679994434118$
09:50:40.624 WARN  o.o.b.z.i.c.ZWaveThermostatSetpointConverter[:147]- NODE 4: Generating message failed for command class = THERMOSTAT_SETPOINT, endpoint = 0`

I was assuming that the new value calculated when dragging the slider is calculated on the UI so it would be JavaScript in the web so it wouldn’t have access to BigDecimal.

Well, if it is causing errors you will need to work around it. Remove the binding from the Dimmer item, create a new Number Item bound to your thermostat, create a rule that triggers on updates to the Dimmer Item which gets the value, rounds it to the nearest tenths place and sendCommand() that rounded value to your new Number Item.

I meant similar to Java’s BigDecimal, not that the client could actually use BigDecimal (unless it was an Android app written in Java).

the $ at the end of the long decimal number is concerning. That would lead to a conversion error for sure if it was part of the number. So this might be yet a separate issue.

The $ is just truncated text from my editor.

Full message is:

 09:50:40.622 ERROR o.o.b.z.i.p.c.ZWaveThermostatSetpointCommandClass[:348]- NODE 4: Got an arithmetic exception converting value 22.111111111111110716365146799944341182708740234375 to a valid Z-Wave value. Ignoring THERMOSTAT_SETPOINT_SET message.

Is it the setpoint steps implemented by the UI? I see the same behavior with bot the classic UI and android UI

That is the theory that @watou and I are believing is the case. The clients are doing the decimal point math using a means less capable than BigDecimal causing the result to be a little off. And it looks like your Z-wave device has a limit to the number of decimal places it can accept so to fix this you need to either abandon decimal steps or implement a rule to round what the UI is calculating before sending it to the Z-wave device.

This one may present a challenge to track down. When I update my device with lets say 22.0, the device gets updated to 22.0, then it updates back to 22.1… The zwave setpoint conversion looks correct on the binding side, I’m wondering if the error is coming from my device.
Update: if I change the units to F, I do not see this behavior.

A bit off topic;
I’m using a bash script to adjust my thermostats (Danfoss Zwave which are placed on the radiator, right next to the heat source), since I find it hard to keep a stable room temperature in my apartment if they are on a fixed setting - old windows + very unstable temperature in the pipes.

I set a target temperature, eg. 22.5c for daytime and 22.0 for nighttime, and then the script adjusts the thermostat setpoint every 10 minutes to try and keep the target temperature, measured by temperature sensors.

My “fix” for this problem for now is to round the number in my bash script and return it to openhab… A bit primitive but it works.

I see two problems:

  1. Inexact arithmetic in the client because it’s not using an exact arithmetic class like BigDecimal (or similar).
  2. Inflexibility in the Z-Wave binding in converting BigDecimal values whose unscaled values are outside Integer.MIN_VALUE and Integer.MAX_VALUE.

I think there is an argument to be made that this line in the Z-Wave binding code is a cause of the problem as described above, with the following thinking:

Number items in openHAB can be sent DecimalType commands that can contain any decimal value, with any scale (number of digits to the right of the decimal point). It should be up to the binding to convert the underlying BigDecimal number, on a best-effort basis, into a protocol-compliant format, which may include loss of digits, instead of throwing the ArithmeticException referenced above.

@chris, does this make sense to you?

Please see issue #3794.

This appears to still be an issue in the ZWave binding 3.2.0-SNAPSHOT. Did it never get fixed?

2021-10-10 21:50:45.133 [ERROR] [.ZWaveThermostatSetpointCommandClass] - NODE 25: Got an arithmetic exception converting value 23.38888888888889 to a valid Z-Wave value. Ignoring THERMOSTAT_SETPOINT_SET message.
2021-10-10 21:50:45.134 [WARN ] [ter.ZWaveThermostatSetpointConverter] - NODE 25: Generating message failed for command class = COMMAND_CLASS_THERMOSTAT_SETPOINT, endpoint = 0