Help wanted to control Raspberry pi output with Maxcube thermostates and rules

I am new to openhab and at the moment i am stuck with the creation of some rules. What i would like to do is to read the current temperature of a Maxcube thermostat and compare its value against the setpoint temperature. If the current temperature is lower then the setpoint a output on the Raspberry should go High and this would control a heater.

Until now i managed to install Openhab2 on a Raspberry pi, and i have been able to make the MAX! Binding and the GPIO Binding. I have all the Things visible and online, all the Thermostats, valves and contacts which are connected to the MAX! Cube Lan Gateway.

From the livingroom wall thermostat i have added to items,
Current Temperature: WallmountedThermostatWoonkamerThermostaat_CurrentTemperature
Setpoint Temperature: WallmountedThermostatWoonkamerThermostaat_SetpointTemperature

Both are a Number of the type Temperature

For the output to control the heater i used GPIO pin 7 of the Raspberry pi. I have added a LED to this output and i can control this LED on GPIO pin 7 via the BASIC UI.

I configured this Switch by editing the following files:

Home.items:

Switch KETEL “CV ketel”{gpio=”pin:7 activelow:no initialValue:low”}


Home.sitemap:
sitemap home label=“RVD-SmartHouse”
{
Frame label=“CVKetel”
{
Switch item=KETEL
}
}

The file home.things is empty and i tried to get the required functionality by changing the home.rules file. (/etc/openhab2/rules/home.rules) but i cannot work out what the right syntax is, hope that someone can point me in the right direction.

Or maybe someone can explain to me why the following piece of code doesn’t work (this is one of the examples i have tried):

Home.rules:
rule “CV-Ketel Aansturing”
when
item WallmountedThermostatWoonkamerThermostaat_SetpointTemperature > WallmountedThermostatWoonkamerThermostaat_CurrentTemperature

then
sendCommand(KETEL,ON)
end

You should read up a bit more on rules first.

Don’t know where you found that but it’s wrong.
You cannot use conditions but need to use triggers in “when” lines. See

so it would need to be something like

when
    Item WallmountedThermostatWoonkamerThermostaat_CurrentTemperature changed
    or
    Item WallmountedThermostatWoonkamerThermostaat_SetpointTemperature changed
then
    if (WallmountedThermostatWoonkamerThermostaat_SetpointTemperature.state >
    WallmountedThermostatWoonkamerThermostaat_CurrentTemperature.state)
         sendCommand(KETEL,ON)
end

But that’s just the basic most point. You’ll better use groups.
Check out this thread

mstormi thank you for the reply and the links. I will read the info in the links, thanks.

I have tried the proposed coded, it is not working (yet) but it is giving the following warning in the log file. Any idea what could be the cause (home.rules is not empty)

2019-02-13 21:11:48.211 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model ‘home.rules’

2019-02-13 21:11:48.297 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model ‘home.rules’ is either empty or cannot be parsed correctly!

That wasn’t a complete rule suggestion. Read up on rules; each must have a rule 'title' and an end, as well as when and then sections.

Managed to solve some of it, the remaining error is:
2019-02-13 22:19:55.903 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model ‘home.rules’ has errors, therefore ignoring it: [4,5]: no viable alternative at input ‘item’

I have used the item name from the Paper UI (Configuration and items, then copy this name to the clipboard). Is this not the right item name? Do i need to set these thermostats up in the home.items file as well.
I have read these links (had found these last week also) but i cannot seem to find the info on the right item names to use in the rules.

Your rule is a secret, so we’ll have to guess.

In the ‘when’ part of the rule, you need to tell it to trigger on an Item not an item.

1 Like

I have modified the proposal from mstormi slightly and the code looks like this now:

rule “CV-Ketel Aansturing”
when
    item WallmountedThermostatWoonkamerThermostaat_CurrentTemperature changed
then
    sendCommand(KETEL,ON)
end

This piece of code gave the error Configuration model ‘home.rules’ has errors, therefore ignoring it: [4,5]: no viable alternative at input ‘item.
This error message made me wonder if i am using the right item name? I have used the item name from the Paper UI (Configuration and items, then copy this name to the clipboard).

So were can i find the right item name to use in these rules? Or do i have to define these items somewhere else also before i can use them in a rules file?

openHAB rules are (very) case sensitive.

Thanks for your reply. I am at work at the moment but will try this when i get home. Thanks again

@RvD as mentioned, OH rules are case sensitive so I won’t spoil the hint given by @rossko57 as I really like the way he provides help. Usually I go straight for trying to provide the answer and leave the OP with no thinking to do. But learning from rossko57 you are likly to not forget the small stuff in future rules.:+1:

One thing I will point out is to change the command from sendCommand(KETEL,ON) to KETEL.sendCommand(ON). See the doc’s section “MyItem.sendCommand(“new state”) versus sendCommand(MyItem, “new state”)” for reason why:

if you read closely it tells you line and column So it’s because of item instead of Item. Sorry I didn’t spot that when copying your lines, now I corrected that.

I want to thank all of you for the tips and helping me out here. The last error was indeed the letter i which needed to be a capital.

It is working at the moment for the Livingroom thermostat. I have several more thermostats in the house so the next part will be to integrate these as well. I am currently reading how to get the syntax right for an OR statement and multiple variables.

Below i will post the working code as it is now, thanks again to you all.

rule "Ketel aan"

when

Item WallmountedThermostatWoonkamerThermostaat_CurrentTemperature changed or Item WallmountedThermostatWoonkamerThermostaat_SetpointTemperature changed

then

if (WallmountedThermostatWoonkamerThermostaat_SetpointTemperature.state > WallmountedThermostatWoonkamerThermostaat_CurrentTemperature.state)

KETEL.sendCommand(ON)

if (WallmountedThermostatWoonkamerThermostaat_SetpointTemperature.state < WallmountedThermostatWoonkamerThermostaat_CurrentTemperature.state)

KETEL.sendCommand(OFF)

end

Here’s a link to help with Logical Operators such as AND, OR, and NOT.
https://www.w3schools.com/js/js_comparisons.asp

Hope you find it helpful.

With the help and tips i have been able to add all my thermostats. I have replaced my home.rules files for two separates files. One file for the ground floor (ground.rules) and one file for the first floor (first.rules).
Besides the heater output i have also added an additional output to control the floor heating pump.

I got the OR statements to work, probably not the most efficient way, but i am still trying to work out the difference between “or” and “||”. Sometimes “or” doesn’t work and you have to use “||”.

I will share my ground.rules code below, maybe it is of any help to someone, or maybe someone can give me tips to improve this further.

rule "Ketel aan"
when
Item WallmountedThermostatWoonkamerThermostaat_CurrentTemperature changed or 
Item WallmountedThermostatWoonkamerThermostaat_SetpointTemperature changed or 

Item WallmountedThermostatGangThermostaat_SetpointTemperature changed or
Item WallmountedThermostatGangThermostaat_CurrentTemperature changed or

Item WallmountedThermostatKeukenWand_CurrentTemperature changed or 
Item WallmountedThermostatKeukenWand_SetpointTemperature changed

then

if (WallmountedThermostatWoonkamerThermostaat_SetpointTemperature.state < WallmountedThermostatWoonkamerThermostaat_CurrentTemperature.state 
|| WallmountedThermostatGangThermostaat_SetpointTemperature.state < WallmountedThermostatGangThermostaat_CurrentTemperature.state
|| WallmountedThermostatKeukenWand_SetpointTemperature.state < WallmountedThermostatKeukenWand_CurrentTemperature.state)
{
	KETEL.sendCommand(OFF)
	POMP.sendCommand(OFF)
}
if (WallmountedThermostatWoonkamerThermostaat_SetpointTemperature.state > WallmountedThermostatWoonkamerThermostaat_CurrentTemperature.state 
|| WallmountedThermostatGangThermostaat_SetpointTemperature.state > WallmountedThermostatGangThermostaat_CurrentTemperature.state
|| WallmountedThermostatKeukenWand_SetpointTemperature.state > WallmountedThermostatKeukenWand_CurrentTemperature.state)
{
	KETEL.sendCommand(ON)
	POMP.sendCommand(ON)
}
end

As already mentioned, consider using groups. You can then shorten your code to
if (group) changed

I definitely will look into how to setup groups, thanks.

In the meantime i discovered an other problem i have to solve first. I have connected a 12 V relay to the output to switch on the heater and pump. This is working with a small problem. The status of the output is changed according the result of the equations. Because i have several equations (multiple room temperatures to check) it can happen that the temperature in 1 room is oke but in the next room it is to cold.
If the heating was already ON the output then goes from OFF to directly ON again. The result is that the relay switches also from OFF to ON again in a short interval. The heater should not be switch OFF and ON again but should just remain ON all the time and should only switch OFF when all rooms are warm enough.

So my solution is to set a variable (TRUE or FALSE) as a result of the equations and only at the end set the output according this variable. So i first have to do some reading on how to store the outcome in a variable (Boolean).

Solved the unwanted switching off the output.

var boolean Heating = false

rule "Ketel aan"
when
Item WallmountedThermostatWoonkamerThermostaat_CurrentTemperature changed or 
Item WallmountedThermostatWoonkamerThermostaat_SetpointTemperature changed or 

Item WallmountedThermostatGangThermostaat_SetpointTemperature changed or
Item WallmountedThermostatGangThermostaat_CurrentTemperature changed or

Item WallmountedThermostatKeukenWand_CurrentTemperature changed or 
Item WallmountedThermostatKeukenWand_SetpointTemperature changed

then

if (WallmountedThermostatWoonkamerThermostaat_SetpointTemperature.state < WallmountedThermostatWoonkamerThermostaat_CurrentTemperature.state 
|| WallmountedThermostatGangThermostaat_SetpointTemperature.state < WallmountedThermostatGangThermostaat_CurrentTemperature.state
|| WallmountedThermostatKeukenWand_SetpointTemperature.state < WallmountedThermostatKeukenWand_CurrentTemperature.state)
{
Heating = false	
}
if (WallmountedThermostatWoonkamerThermostaat_SetpointTemperature.state > WallmountedThermostatWoonkamerThermostaat_CurrentTemperature.state 
|| WallmountedThermostatGangThermostaat_SetpointTemperature.state > WallmountedThermostatGangThermostaat_CurrentTemperature.state
|| WallmountedThermostatKeukenWand_SetpointTemperature.state > WallmountedThermostatKeukenWand_CurrentTemperature.state)
{
Heating = true	
}

EDIT: BOLD part is not correct, see below
if (Heating){
KETEL.sendCommand(ON)
POMP.sendCommand(ON)
}else{
KETEL.sendCommand(OFF)
POMP.sendCommand(OFF)
}

end

It seems to me that you could use if-else here.

if (conditions) {
turn things on
} else if (conditions) {
turn things off
}

Only one path is followed. If neither condition is satisfied, nothing is done.

I just did some more testing and i found out this didn’t work as i originally expected. I will implement your proposal. Thanks

Did some first testing and seems to work now. Thanks

if (Heating==true){
KETEL.sendCommand(ON)
POMP.sendCommand(ON)
}else if(Heating==false){
KETEL.sendCommand(OFF)
POMP.sendCommand(OFF)
}