[SOLVED] Mixed Data Types in Rules Arithmetic

@vzorglub Vincent,


Number room_sensor_Temperature
Number:Temperature Nest_AmbientTemperature
Number:Temperature Nest_TargetTemperatureMax
Number:Temperature Nest_TargetTemperatureMin

The sensor temperatures come in via MQTT and I use JSONPath to set the Item value. They are floating point values with two decimal places.

var TargetMax = (Nest_TargetTemperatureMax.state as QuantityType<Number>).doubleValue
var TargetMin = (Nest_TargetTemperatureMin.state as QuantityType<Number>).doubleValue
val currTemp  = (Nest_AmbientTemperature.state as QuantityType<Number>).doubleValue
val denTemp   = room_sensor_Temperature.state

I’ve tried different permutations of typing to perform some arithmetic with these two Items… and can’t figure it out.

TargetMax = TargetMax + (currTemp - denTemp)
TargetMin = TargetMin + (currTemp - denTemp)

Thanks in advance!


You didn’t tell us what the problem is?

As three of your values are doubles, maybe the other one needs to be as well?

val denTemp = (room_sensor_Temperature.state as Number).doubleValue


You nailed it! I have a horrible time with data typing!

I was either getting syntax errors when I used improper typing or I getting runtime errors because the thermostat Items and the sensor Item could not be properly cast.




Now that the arithmetic works, I want to compare only the whole number (i.e., integer) portions of the new target value against the target value that is currently set. How do I cast:

Nest_TargetTemperatureMax as integer
TargetMax as integer



Replace that with intValue.

It’s a mirror of the double palaver to get “just a number” out of the temperature Items

var TargetMax = (Nest_TargetTemperatureMax.state as QuantityType<Number>).intValue

I believe intValue truncates, not round, so 21.9 -> 21

Handling these UoM item states is bit clumsy, isn’t it.

Thanks @rlkoshak & @rossko57

Of course, intValue. Not integerValue. Not integer. Not int.

Thanks for the truncation heads up. I’ll add .5 and then convert to get it to round.

And the award for understatement goes to … :wink:

@rlkoshak @rossko57

I’m certain that this can be simplified - but none of my trials have succeeded other than this convoluted mess:

var TargetTemp = (Nest_TargetTemperatureMax.state as QuantityType<Number>).doubleValue
logInfo("myLog", "Target {}", (TargetTemp + ROUNDING_ADJUST).intValue)

Basically I want to compare the value of my temperature Item as an integer… but I need to add the fraction so that when it gets truncated it gets rounded properly. As it is, since I have the actual temperature, the min target, and the max target, I have to repeat this dance three times. Surely there’s a much more concise method to do this than what I have done.



If you just need the rounded value for your logging:

var TargetTemp = (Nest_TargetTemperatureMax.state as QuantitiyType<Number>) as BigDecimal
logInfo("myLog", "Target %1$d", TargetTemp)

All those formatting % strings you use in Item labels can be used in log statements too. In the above %1$d means “Insert the first argument here and format it as an integer.” The formatting as an integer will round it.

If you need a rounded value for doing math use the Math::round() method. Though I highly recommend not rounding values when doing math. Over just a very few operations the error will build up to unacceptable levels.

var rounded = Math::round((Nest_Target_TemperatureMax.state as QuantityType<Number>).floatValue)

Thanks Rich.

It’s not just for logging. I was trying to “distill” the code for readability.

The issue is that the Nest actually provides Fahrenheit readings in whole number values but as floating point. My sensors provide two decimal places. I need to “shift” my calculated delta values based on my sensors to then adjust the Nest’s targets (as whole numbers). I don’t want to send an update to the Nest API (it tracks the number of transactions I make). That is why I want to do a comparison of the values (rounded whole/integer against rounded whole/integer) and, if different, then set the Nest’s target.