[SOLVED] Help with thermostat rule

Hi,

I’m using latest version of Openhab2 on a Raspberry Pi3 (latest OS). I’m having a simple heating solution:
Danboss thermostat on the wall and Fibaro smart plug between electric heater and a wall plug. The logic is that when thermostat sees the room is cold, it turns on the smartplug, which turns on the heater and if thermostat sees the room is in set temperature, it turns off the plug again.

I’m not experienced coder so I found a suitable rule somewhere from this forum, which works for me but there’s something that annoys me and I need help solving it. The rule itself is as follows:

ElutoaSetpoint = Thermostat Setpoint
ElutoaTemp = Current room temperature
ElutoaRadikas = Fibaro smart plug

rule "Elutoa temperatuur"
when
                Item ElutoaSetpoint changed or
                Item ElutoaTemp changed
        then

        var Number cur_temp = ElutoaTemp.state
        var Number setpoint = ElutoaSetpoint.state
        val  hysteresis = 0.5

        if ((cur_temp).floatValue < ((setpoint).floatValue - hysteresis)) {
                        if (ElutoaRadikas == OFF) {
                                sendCommand(ElutoaRadikas, ON)
                                }
                        }
                else {
                        sendCommand(ElutoaRadikas, OFF)
                        }
end

The system sees the temperature with two decimal places (example 22,25). So every time the temperature changes 0,01 degrees, the thermostat sends the “OFF” command.

2018-08-30 14:48:32.877 [vent.ItemStateChangedEvent] - ElutoaTemp changed from 24.27 to 24.23
2018-08-30 14:48:32.909 [me.event.ThingUpdatedEvent] - Thing 'zwave:device:6675270d:node3' has been updated.
2018-08-30 14:48:33.343 [ome.event.ItemCommandEvent] - Item 'ElutoaRadikas' received command OFF
2018-08-30 14:53:33.876 [vent.ItemStateChangedEvent] - ElutoaTemp changed from 24.23 to 24.19
2018-08-30 14:53:33.899 [ome.event.ItemCommandEvent] - Item 'ElutoaRadikas' received command OFF
2018-08-30 14:53:33.934 [me.event.ThingUpdatedEvent] - Thing 'zwave:device:6675270d:node3' has been updated.
2018-08-30 14:58:34.865 [vent.ItemStateChangedEvent] - ElutoaTemp changed from 24.19 to 24.13
2018-08-30 14:58:34.904 [me.event.ThingUpdatedEvent] - Thing 'zwave:device:6675270d:node3' has been updated.
2018-08-30 14:58:34.920 [ome.event.ItemCommandEvent] - Item 'ElutoaRadikas' received command OFF

How can I modify the code so that the “OFF” command is sent only when the change is 0,5 degrees (hysteresis)?

    if ((cur_temp).floatValue < ((setpoint).floatValue - hysteresis)) {
        if (ElutoaRadikas.state != ON) {ElutoaRadikas.sendCommand(ON)}}
    else if((cur_temp).floatValue > (setpoint).floatValue) {
        if (ElutoaRadikas.state != OFF) {ElutoaRadikas.sendCommand(OFF)}}
1 Like

Have you tried moving the var’s and val’s to the top, make them global and use two rules without the “else”?

Wouldn’t the else sendCommand part of the rule still give the OFF each time it ran?

@hr3 code is more elegant than two rules. :grin: You may want to add + hysteresis to the else if. That way you have a larger hysteresis to prevent short cycling.

Hi,
Moving the var’s to the top (right before “when”) for some reason gave me some kind of error so I moved them back.
But I used your suggestion to use two rules, without the “else” and it works. I’ll test some time, when the weather gets colder and see how it performs and if the cycles get too short then I’ll have a look of the @hr3 suggestion.

Thanks to both of you!

Change the hysteresis to a Number val
As your variable and hysteresis are now all numbers you won’t need the floatValue anymore

rule "Elutoa temperatuur"
when
    Item ElutoaSetpoint changed or
    Item ElutoaTemp changed
then
    var Number cur_temp = ElutoaTemp.state as Number
    var Number setpoint = ElutoaSetpoint.state as Number
    val  Number hysteresis = 0.5

    if (cur_temp < (setpoint - hysteresis)) {
        if (ElutoaRadikas.state != ON) {ElutoaRadikas.sendCommand(ON)}
    }
    else if(cur_temp > setpoint + hysteresis) {
        if (ElutoaRadikas.state != OFF) {ElutoaRadikas.sendCommand(OFF)}
    }
end
3 Likes

Would there be a way to implement a switch to decide wether this rule activated or not? I’m planning to run my boiler using a general wireless thermostat to control schedules and so forth and then have valves on every radiator and sensors to determine a certain room temperature. With the rule set out as it is if the boiler was off and the room Setpoint was say 21 but the actual room temperature was 17 the valve would be open using electric and opening the valve unnecessarily. I would read the boiler state and then use a switch item to control wether the rule would run or not. Or would it just be a case of adding a when Boiler_State is on carry on rule if off wait till Boiler_State changed to on? Can anybody help?

Create a proxy item for the switch and add it to the “if statement” in the rule so it checks the state of the switch and runs only if it’s on.

ive got a sensor connected to my boiler. Boiler_Status
this is the rule i came up with but its coming up with errors.

rule “Kids Bedroom heating”

when

Item Boiler_Status changed to ON then 

Item Kids_Bedroom_Temp_Setpoint changed or

Item Bed_Temperature changed

then

var Number cur_temp = Bed_Temperature.state as Number

var Number setpoint = Kids_Bedroom_Temp_Setpoint.state as Number

val  Number hysteresis = 0.5

if (cur_temp < (setpoint - hysteresis)) {

    if (Bed_Heater.state != ON) {Bed_Heater.sendCommand(ON)}

}

else if(cur_temp > setpoint + hysteresis) {

    if (Bed_Heater.state != OFF) {Bed_Heater.sendCommand(OFF)}

}

end

Some items are just demo items at the minute
this is the error i get

2020-05-10 16:16:16.755 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model ‘heating.rules’ has errors, therefore ignoring it: [4,5]: mismatched input ‘Item’ expecting ‘end’

You can not use then in the when part, only or.

Is Boiler_Status the switch you want to use for allowing the rule to run?

yes i would like the rule to run once the boiler updates with on

Move Boiler_Status to the then section and check the condition.

rule "Elutoa temperatuur"
when
    Item ElutoaSetpoint changed or
    Item ElutoaTemp changed
then
    var Number cur_temp = ElutoaTemp.state as Number
    var Number setpoint = ElutoaSetpoint.state as Number
    val  Number hysteresis = 0.5

    if (cur_temp < (setpoint - hysteresis) && Boiler_Status.state == ON) {
        if (ElutoaRadikas.state != ON) {ElutoaRadikas.sendCommand(ON)}
    }
    else if(cur_temp > setpoint + hysteresis) {
        if (ElutoaRadikas.state != OFF) {ElutoaRadikas.sendCommand(OFF)}
    }
end

Or just check if the switch is off and do nothing with:

if (Boiler_Status.state == OFF) return; 

Put this at the first part of the then part of rule. If the switch is off the rule will do nothing.

i have just run the rule and it works perfectly apart from the Bed_Heater is still on when the boiler status changes to off because the setpoint temp is not met, could i implement a or Bed_Heater.state OFF, on the else if line?

I replied to your other post. Please post the rule you have working there and I will have a look at what to change for the Bed_Heater.