Got an arithmetic exception converting value

Hi, I have been using Danfoss living Thermostats LC13 for more than a year without issues.
But lately (possible after updating OH2, i now recives these error messages:

2017-10-05 19:10:00.158 [ERROR] [.ZWaveThermostatSetpointCommandClass] - NODE 6: Got an arithmetic exception converting value 21.400000000000002 to a valid Z-Wave value. Ignoring THERMOSTAT_SETPOINT_SET message.
2017-10-05 19:10:00.159 [WARN ] [ter.ZWaveThermostatSetpointConverter] - NODE 6: Generating message failed for command class = THERMOSTAT_SETPOINT, endpoint = 0
2017-10-05 19:10:00.160 [WARN ] [ding.zwave.handler.ZWaveThingHandler] - NODE 6: No messages returned from converter

and

2017-10-04 22:30:00.160 [ERROR] [.ZWaveThermostatSetpointCommandClass] - NODE 10: Got an arithmetic exception converting value 19.400000000000002 to a valid Z-Wave value. Ignoring THERMOSTAT_SETPOINT_SET message.
2017-10-04 22:30:00.161 [WARN ] [ter.ZWaveThermostatSetpointConverter] - NODE 10: Generating message failed for command class = THERMOSTAT_SETPOINT, endpoint = 0
2017-10-04 22:30:00.162 [WARN ] [ding.zwave.handler.ZWaveThingHandler] - NODE 10: No messages returned from converter

I have checked previous posts and understand that the Zwave binding does not handle so many digits. Simple rounding is suggested, but despite clear examples, it has onlly partly solved my issues.
I’m using Math::round command, both via .floatValue and .intValue format. The strange thing and what i do not understand at all is, that the error is not consistent. It’s only an issue with node 6 and 10 (and not at the same time). And it comes and go…seems to be linked with update of Rad_TEMP_SP.

I have tried many things but is stuck. Hope somebody have a hint for me.

My installation: OH 2.0.0-1

My rule:

rule "temperature control" // det er denne kontrol som opdaterer de enkelte radiatorers setpunkter
when
    Time cron "0 0/5 * 1/1 * ? *"
then
   if (Heat_auto.state == ON) //setpunkterne bliver kun opdateret hvis automatikken er ON
   {
   TempDiff.postUpdate(2*(Rad_TEMP_SP.state as DecimalType - Temperature_GF_Living2.state as DecimalType))		
	if(TempDiff.state > 1)
		{
		TempDiff.postUpdate(1.0)
		}
	if(TempDiff.state < -1)
		{
		TempDiff.postUpdate(-1.0)
		}
	TempDiff.postUpdate(Math::round((TempDiff.state as DecimalType).intValue*100.0)*0.01)
   sendCommand(GF_Kitchen_setpoint, Math::round(((Rad_TEMP_SP.state as DecimalType + GF_Kitchen_offset.state as DecimalType + TempDiff.state as DecimalType)*100.0).intValue)*0.01)    
   sendCommand(GF_Living_east_setpoint, Math::round(((Rad_TEMP_SP.state as DecimalType + GF_Living_east_offset.state as DecimalType + TempDiff.state as DecimalType)*100.0).intValue)*0.01)
   sendCommand(GF_Living_south_setpoint, Math::round(((Rad_TEMP_SP.state as DecimalType + GF_Living_south_offset.state as DecimalType + TempDiff.state as DecimalType)*100.0).intValue)*0.01)
   sendCommand(GF_Corridor_setpoint, Math::round(((Rad_TEMP_SP.state as DecimalType + GF_Corridor_offset.state as DecimalType)*100.0).floatValue)*0.01)
   sendCommand(GF_Jonas_setpoint, Math::round(((Rad_TEMP_SP.state as DecimalType + GF_Jonas_offset.state as DecimalType)*100.0).intValue)*0.01)
   sendCommand(FF_Living_east_setpoint, Math::round(((Rad_TEMP_SP.state as DecimalType + FF_Living_east_offset.state as DecimalType)*100.0).intValue)*0.01)
   sendCommand(FF_Living_west_setpoint, Math::round(((Rad_TEMP_SP.state as DecimalType + FF_Living_west_offset.state as DecimalType)*100.0).intValue)*0.01)
   }
end	

My items:

Number          GF_Kitchen_setpoint     "Køkken SP [%.1f C]" 					<temperature>	(GF_Kitchen, Radiators)	{ channel="zwave:device:129234db:node7:thermostat_setpoint_heating" }
Number          GF_Living_east_setpoint "Stue øst SP [%.1f C]" 					<temperature>	(GF_Living, Radiators)	{ channel="zwave:device:129234db:node3:thermostat_setpoint_heating" }
Number          GF_Living_south_setpoint"Stue syd SP [%.1f C]" 					<temperature>	(GF_Living, Radiators)	{ channel="zwave:device:129234db:node4:thermostat_setpoint_heating" }
Number          GF_Corridor_setpoint 	"Hall SP [%.1f C]" 						<temperature>	(GF_Corridor, Radiators){ channel="zwave:device:129234db:node5:thermostat_setpoint_heating" }
Number          GF_Jonas_setpoint	 	"Jonas værelse SP [%.1f C]" 			<temperature>	(GF_Corridor, Radiators){ channel="zwave:device:129234db:node10:thermostat_setpoint_heating" }
Number          FF_Living_east_setpoint "Stue loft øst SP [%.1f C]" 			<temperature>	(FF_Living, Radiators)	{ channel="zwave:device:129234db:node6:thermostat_setpoint_heating" }
Number          FF_Living_west_setpoint "Stue loft vest SP [%.1f C]" 			<temperature>	(FF_Living, Radiators)	{ channel="zwave:device:129234db:node9:thermostat_setpoint_heating" }
Number          Rad_TEMP_SP				"Radiator SP automatik [%.1f C]"		<temperature>	(Radiators, Temperature, Persist, status)
Number			TempDiff				"Offset Temp stue [%.1f C]" 			<temperature>	(Radiators, Persist)
Number			GF_Kitchen_offset		"Køkken, offset Temp [%.1f C]"			<temperature>	(Radiators, Persist)
Number			GF_Living_east_offset	"Stue øst, offset Temp [%.1f C]"		<temperature>	(Radiators, Persist)
Number			GF_Living_south_offset	"Stue syd, offset Temp [%.1f C]"		<temperature>	(Radiators, Persist)
Number			GF_Corridor_offset		"Hall, offset Temp [%.1f C]"			<temperature>	(Radiators, Persist)
Number			GF_Jonas_offset			"Jonas værelse, offset Temp [%.1f C]"	<temperature>	(Radiators, Persist)
Number			FF_Living_east_offset	"Stue loft øst, offset Temp [%.1f C]"	<temperature>	(Radiators, Persist)
Number			FF_Living_west_offset	"Stue loft vest, offset Temp [%.1f C]"	<temperature>	(Radiators, Persist)

Number Temperature_GF_Living2    "Temperature Stue IOT [%.1f °C]" <temperature>   (Temperature,GF_Living) {mqtt="<[mymosquitto:/IOT_Stue/TEMP/Temperature:state:default]"}

Added the zwave tag as this looks a whole lot like a zwave binding issue.

Finally got it to work, had to divide my arithmetic operations into two to make it work. Don’t now why it is like this, but it works :-).

I also found out that there is a difference between /100 and * 0.01. /100 throws a lot of decimals, whereas * 0.01 only throws 2.

My working rule:

rule "temperature control" // det er denne kontrol som opdaterer de enkelte radiatorers setpunkter
when
    Time cron "0 0/5 * 1/1 * ? *"
then
   if (Heat_auto.state == ON) //setpunkterne bliver kun opdateret hvis automatikken er ON
   {
   TempDiff.postUpdate(3*(Rad_TEMP_SP.state as DecimalType - Temperature_GF_Living2.state as DecimalType))		
	if(TempDiff.state > 1.5)
		{
		TempDiff.postUpdate(1.5)
		}
	if(TempDiff.state < -1.5)
		{
		TempDiff.postUpdate(-1.5)
		}
   var Number setPointDec = Math::round(100*(Rad_TEMP_SP.state as DecimalType + GF_Kitchen_offset.state as DecimalType + TempDiff.state as DecimalType).floatValue())
   sendCommand(GF_Kitchen_setpoint, setPointDec*0.01)    
   setPointDec = Math::round(100*(Rad_TEMP_SP.state as DecimalType + GF_Living_east_offset.state as DecimalType + TempDiff.state as DecimalType).floatValue())
   sendCommand(GF_Living_east_setpoint, setPointDec*0.01) 
   setPointDec = Math::round(100*(Rad_TEMP_SP.state as DecimalType + GF_Living_south_offset.state as DecimalType + TempDiff.state as DecimalType).floatValue())
   sendCommand(GF_Living_south_setpoint, setPointDec*0.01)
   setPointDec = Math::round(100*(Rad_TEMP_SP.state as DecimalType + GF_Corridor_offset.state as DecimalType).floatValue())
   sendCommand(GF_Corridor_setpoint, setPointDec*0.01)
   setPointDec = Math::round(100*(Rad_TEMP_SP.state as DecimalType + GF_Jonas_offset.state as DecimalType).floatValue())
   sendCommand(GF_Jonas_setpoint, setPointDec*0.01) 
   setPointDec = Math::round(100*(Rad_TEMP_SP.state as DecimalType + FF_Living_east_offset.state as DecimalType).floatValue())
   sendCommand(FF_Living_east_setpoint, setPointDec*0.01)
   setPointDec = Math::round(100*(Rad_TEMP_SP.state as DecimalType + FF_Living_west_offset.state as DecimalType).floatValue())
   sendCommand(FF_Living_west_setpoint, setPointDec*0.01)
   }
end	
1 Like

There was a discussion about this on another thread. Computers are pretty bad at floating point math. Most of the time the CPU will give you a number that is really really close to the exact answer but not exact. This problem gets exacerbated by how division is implemented in the CPU. So this is not wholly unexpected behavior.

I’m not sure why this caused problems. Perhaps the binding can only have so many decimal places.