[SOLVED] Rule broke with latest Nest Binding

@wborn

openHAB 2.4.0~20181105174706-1 (Build #1413)
Linux openHABianPi 4.14.71-v7+ #1145 SMP Fri Sep 21 15:38:35 BST 2018 armv7l
Release = Raspbian GNU/Linux 9 (stretch)
Kernel = Linux 4.14.71-v7+
Platform = Raspberry Pi 3 Model B Rev 1.2

This crude rule “widens” the target temperature windows. It used to do what I intended. It ran yesterday but failed. Now that the Item types for the Nest binding have changed, it appears that my calculation logic now has mismatched data types. The target values are OK, but when I adjust them with a local constant, they are out of whack and of course way out of limits for the API.

rule "Adjust Nest Thermostat Targets"
    when
        Item gInTown changed
    then
        val Number TARGET_ADJUST = 3.0
        logInfo("my_log", "Adjust Nest Thermostat Targets - Nest max = {}", TargetTemperatureMax.state)
        logInfo("my_log", "Adjust Nest Thermostat Targets - Nest min = {}", TargetTemperatureMin.state)
        var TargetMax = TargetTemperatureMax.state as Number
        var TargetMin = TargetTemperatureMin.state as Number
        logInfo("my_log", "Adjust Nest Thermostat Targets - TargetMax = {}", TargetMax)
        logInfo("my_log", "Adjust Nest Thermostat Targets - TargetMin = {}", TargetMin)

        if (nestStructureAway.state == "HOME")
        {
            if (gInTown.state == OFF)
            {
                TargetMax = TargetMax + TARGET_ADJUST
                TargetMin = TargetMin - TARGET_ADJUST
            }
            else
            {
                if ((TargetMax - TargetMin) >= (3.0 + (2 * TARGET_ADJUST)))
                {
                    TargetMax = TargetMax - TARGET_ADJUST
                    TargetMin = TargetMin + TARGET_ADJUST
                }
            }

            logInfo("my_log", "Adjust Nest Thermostat Targets - Adj. TargetMax = {}", TargetMax)
            logInfo("my_log", "Adjust Nest Thermostat Targets - Adj. TargetMin = {}", TargetMin)

            if (TargetTemperatureMax.state != TargetMax)
                TargetTemperatureMax.sendCommand(TargetMax)
            if (TargetTemperatureMin.state != TargetMin)
                TargetTemperatureMin.sendCommand(TargetMin)
        }
end
[INFO ] [pse.smarthome.model.script.SPT_house] - Running rule Away Lights Off - out of Town region.
[INFO ] [pse.smarthome.model.script.SPT_house] - Adjust Nest Thermostat Targets - Nest max = 76.0 °F
[INFO ] [pse.smarthome.model.script.SPT_house] - Adjust Nest Thermostat Targets - Nest min = 72.0 °F
[INFO ] [pse.smarthome.model.script.SPT_house] - Adjust Nest Thermostat Targets - TargetMax = 76.0 °F
[INFO ] [pse.smarthome.model.script.SPT_house] - Adjust Nest Thermostat Targets - TargetMin = 72.0 °F
[INFO ] [pse.smarthome.model.script.SPT_house] - Adjust Nest Thermostat Targets - Out of town temperatures
[INFO ] [pse.smarthome.model.script.SPT_house] - Adjust Nest Thermostat Targets - Adj. TargetMax = 300.5944444444444444444444444444444
[INFO ] [pse.smarthome.model.script.SPT_house] - Adjust Nest Thermostat Targets - Adj. TargetMin = 292.3722222222222222222222222222222
[INFO ] [pse.smarthome.model.script.SPT_house] - Running rule Back Bedroom Ceiling Fan Send Speed.
[ome.event.ItemCommandEvent] - Item 'SPT_house_FF_hallway_wall_sensor_thermostat_TargetTemperatureMax' received command 300.5944444444444444444444444444444
[ome.event.ItemCommandEvent] - Item 'SPT_house_FF_hallway_wall_sensor_thermostat_TargetTemperatureMin' received command 292.3722222222222222222222222222222
[nt.ItemStatePredictedEvent] - SPT_house_FF_hallway_wall_sensor_thermostat_TargetTemperatureMax predicted to become 300.5944444444444444444444444444444
[nt.ItemStatePredictedEvent] - SPT_house_FF_hallway_wall_sensor_thermostat_TargetTemperatureMin predicted to become 292.3722222222222222222222222222222
[WARN ] [t.internal.handler.NestBridgeHandler] - Nest API error: Temperature F value is too high: 301.0
[WARN ] [t.internal.handler.NestBridgeHandler] - Nest API error: Cannot set target low temperature '292.0' higher than target high temperature '76.0'

Regards.

Mike

I don’t think it has to do with the binding but with how addition/subtraction of such units is handled by Eclipse SmartHome. See also this RfC:

Wouter,

Thanks for the prompt response. Indeed it seems that is the issue I’m encountering.

After reading that Eclipse thread, I unfortunately have no idea how to implement a fix to my rule. My situation is definitely the T plus delta T scenario. I tried defining my constant as Number:Temperature but that syntax is not valid for val nor var declarations. I could declare an actual Item to hold the delta T (3 degrees). In any case (val/var/Item) I don’t know how to properly define my 3 degree delta T to have the same UOM as my Nest target temperature (i.e., Fahrenheit in my case). What is the appropriate solution?

Thanks.

Mike

@rlkoshak

You’re my goto when it comes to casting data types (and lots of other OH coding topics too, of course). Any ideas on data typing delta “constants” for temperature value addition/subtraction?

Mike

In your rule:

        var TargetMax = TargetTemperatureMax.state as Number
        var TargetMin = TargetTemperatureMin.state as Number

Will now be Number Quantity Types
You will need to convert them to raw decimal types before doing operations on/with them

val TargetMax = (TargetTemperatureMax.state as QuantityType<Number>).doubleValue
1 Like

I use a constant in my automated lighting rules like this:

val lxThreshold = 30 | lx

So I would assume your temperature delta would look something like:

val delta = 3 | F

1 Like

@vzorglub - the data typing as doubleValue did the trick… although, @danielwalters86, for documenting the “trick” for my future reference, I set the offset constant as Fahrenheit.

rule "Adjust Nest Thermostat Targets"
    when
        Item gInTown changed
    then
        val Number TARGET_ADJUST = 3.0 | F
        var TargetMax = (TargetTemperatureMax.state as QuantityType<Number>).doubleValue
        var TargetMin = (TargetTemperatureMin.state as QuantityType<Number>).doubleValue

        if (nestStructureAway.state == "HOME")
        {
            if (gInTown.state == OFF)
            {
                TargetMax = TargetMax + TARGET_ADJUST
                TargetMin = TargetMin - TARGET_ADJUST
            }
            else
            {
                if ((TargetMax - TargetMin) >= (3.0 + (2 * TARGET_ADJUST)))
                {
                    TargetMax = TargetMax - TARGET_ADJUST
                    TargetMin = TargetMin + TARGET_ADJUST
                }
            }

            if ((TargetTemperatureMax.state as QuantityType<Number>).doubleValue != TargetMax)
                TargetTemperatureMax.sendCommand(TargetMax)
            if ((TargetTemperatureMin.state as QuantityType<Number>).doubleValue != TargetMin)
                TargetTemperatureMin.sendCommand(TargetMin)
        }
end

Thanks

Mike

@vzorglub is the man when it comes to working with Quantity types.

2 Likes

Hi guys, I need some help.

I have the following rule

rule “living area off”
when
item Thermostat_Mode changed
then
if (Thermostat_Mode.state == “ECO”)
{
LED_Power.sendCommand(OFF)
glight.sendCommand(OFF)
}
end

For some reason my rule is unable to obtain the Thermostat_Mode.state as “ECO” value. However, the Item Thermostat_Mode is a String and it can accept (HEAT, COOL, HEAT_COOL, ECO, OFF) as values and it has R/W access on this String.

I have also tried with Thermostat_Mode.state.toString.contains (“ECO”) but that also doesn’t work.

The conditions after the IF statement works fine as I’ve tested those with other rules.
Also when I display the Thermostat_Mode as dummy on the HABpanel then I can see values such as HEAT, ECO, OFF etc. Not sure what is wrong.

Add a couple of logInfo statements to print out the values as the change to make sure they are what you believe them to be. I’ve been bitten by this… not only the case but also the actual string.