Need help with heating rule

Hi all,

i have a problem with a rule and i don’t get the error.

I try to change the Setpoint of two thermostats with a “Selection” Item in my sitemap. Here is my configuration:

Item:

Number	temp_WZ		"Temperatur WZ"		<heating>	(gHaus)

Sitemap:

Selection	item=temp_WZ mappings=[1="Auto", 2="Manuell", 3="Komfort"]

Rule:

rule "Heizen Wohnzimmer"
when 
	Time cron "0/15 * * * * ?"
then
	if(temp_WZ.state == 2){
		eg_wz_hz_sp.sendCommand(14)
		wz_hz_fritz_sp.sendCommand(14)
	}
	else if(temp_WZ.state == 3){
		eg_wz_hz_sp.sendCommand(21)
		wz_hz_fritz_sp.sendCommand(21)
	}
	else if{
		if(temp_WZ.state == 1 && wTemperature.state < 10){
			eg_wz_hz_sp.sendCommand(22)
			wz_hz_fritz_sp.sendCommand(22)
		}
		else if(temp_WZ.state == 1 && wTemperature > 10) {
			eg_wz_hz_sp.sendCommand(14)
			wz_hz_fritz_sp.sendCommand(14)
		}
	}
end

Eventlog when changeing state:

2018-11-02 15:54:21.786 [vent.ItemStateChangedEvent] - temp_WZ changed from 1 to 2

My problem now is that the state changes but my rule don’t do anything.

Where is my Error

Thanks
Nils

  • Platform information:
    • Hardware: Raspberry Pi 3
    • OS: openHABian 2.4 m5

I would add some logging to find out where he is going

logInfo(“rule check”, “Inside rule”)

logInfo(“rule check”, “Inside temp_WZ.state == 2”)

etc

it also feel strange that you use a cron to see of a state is changed

why are you doing that?

can’t you have one rule per state change of temp_WZ ?
something like

rule " temp_WZ changed to 1"
when Item temp_WZ changed to 2 then
eg_wz_hz_sp.sendCommand(14)
wz_hz_fritz_sp.sendCommand(14)
end

I thought it would be easyer if all is in one rule. I try one rule for each state.

Edit:
But what do i do if in rule “Received Command 1” (the automatic rule with outside temperature) the outside temperature changed?
The cron gives me the ability to check this.

1 Like

Have you looked in openhab.log? I bet you will see an error saying something about not being able to call operator > on null or something like that. You are missing the .state on your last else if.

else if(temp_WZ.state == 1 && wTemperature.state > 10) {

I highly recommend VSCode for editing Rules. It catches errors like this.

Cron triggered Rules for something like this is somewhat of an anti-pattern. OH is an event driven system so Rules should be written to respond to those events. In this case you have two events that may change your heating, temp_WZ changing or wTemperature changing. So trigger your Rule based on those changes instead of running it every 15 seconds wasting resources doing nothing.

rule "Heizen Wohnzimmer"
when
    Item temp_WZ changed or
    Item wTemperature changed
then
...

As for the body, definitely add some logging as yves suggests.

  • first line of the Rule to see that it is being triggered
  • in each if statement
  • last line of the Rule to see that it is exiting

It’s kind of a matter of style, but I prefer to side on fewer Rules with centralized logic over lots of different Rules.

Finally, @NilsAcht, I recommend Design Pattern: How to Structure a Rule which will let you separate the logic a bit and avoid duplicated code and perhaps make it easier to debug.

rule "Heizen Wohnzimmer"
when
    Item temp_WZ changed or
    Item wTemperature changed
then
    // 1. determine if we need to run the Rule at all
    if(temp_WZ.state == 1 && wTemperature.state == 10) return;

    // 2. Calculate what needs to be done
    var newTemp = 14 // covers temp_WZ.state == 2 and temp_WZ.state == 1 && wTemperature.state > 10

    if(temp_WZ.state == 3) newTemp = 21
    else if(temp_WZ.state == 1 && wTemperature.state < 10) newTemp = 22

    // 3. Do it
    logInfo("heating", "Changing target temp to " + newTemp)
    eg_wz_hz_sp.sendCommand(newTemp)
    wz_hz_fritz_sp.sendCommand(newTemp)
end
1 Like

It’s kind of a matter of style, but I prefer to side on fewer Rules with centralized logic over lots of >different Rules.
I basically ment, not use cron to do this. As like you said, this looks like an anti-pattern.

Sorry ich dont quiet get it.

Can you please add some more information to your example rule?

what lines don’t you understand?

I have three states.

First then Line:
If temp_wz state ist 1 and Temperatur equals 10 then nothing Happens?

What happened in step two?

What is with state number 2?

If temp_wz state ist 1 and Temperatur equals 10 then nothing Happens?

In your rule, this happens also.
You only have an action
when temp_wz state ist 1 and Temperatur > 10
when temp_wz state ist 1 and Temperatur < 10
nothing happens when temp_wz state ist 1 and Temperatur equal 10
hence the return

What happened in step two?
What is with state number 2?

newTemp is set to 14 and at the end
eg_wz_hz_sp.sendCommand(newTemp)
wz_hz_fritz_sp.sendCommand(newTemp)

this is why I prefer one rule for one action. independant, simplier and easier to read.

Ok thanks. I now ended up with three rules for each state.

rule "Heizen Automatisch"
when
	Item temp_WZ changed or
	Item wTemperature changed
then
	if(temp_WZ.state == 1){
		if(wTemperature.state < 11){
			eg_wz_hz_sp.sendCommand(22)
			wz_hz_fritz_sp.sendCommand(22)
		}
		else {
			eg_wz_hz_sp.sendCommand(15)
			wz_hz_fritz_sp.sendCommand(15)
		}
	}
end

rule "Heizen Komfort"
when
	Item temp_WZ received command 3 or
	Item eg_wz_hz_sp changed or
	Item wz_hz_fritz_sp changed
then
	if(temp_WZ.state == 3){
		eg_wz_hz_sp.sendCommand(21)
		wz_hz_fritz_sp.sendCommand(21)
	}
end

rule "Heizen Manuell"
when
	Item temp_WZ received command 2
then
	eg_wz_hz_sp.sendCommand(14)
	wz_hz_fritz_sp.sendCommand(14)
end

Now I can play with the item temp_WZ (Change it to string for better Google Home / IFTTT Integration).

Thank you.

I think the second one is too complex
sound the same as

rule “Heizen Komfort”
when
Item temp_WZ received command 3
then
eg_wz_hz_sp.sendCommand(21)
wz_hz_fritz_sp.sendCommand(21)
end

Except if you always want eg_wz_hz_sp to be 21 temp_WZ is 3

That is what I want to do. The thermostats should bei 21 when temp_WZ is 3

so when someone changes the thermostat, you change it back?
I’m afraid people will not understand that…
yet your house, so then it’s correct…

All in all i want to have 4 or 5 modes. Automatic mode, Night mode, Comfort mode, manuell mode.

In Automatic openHAB does all the heating Settings alone. In manuell mode i want to manually Change the temperature with no interfearing. In Comfort mode I want openHAB to hold one Temperature ( in this case 21).

Night mode is not implemented yet.

ah, now I get it

This discussion made me realize what I miss in the code:

Constanst that have a name of what you want to do, instead of magic numbers

var Number WZ_AUTO= 1
var Number WZ_MANUELL= 2
var Number WZ_KOMFORT= 3

var KOMFORT_TEMPERATURE= 21
var MANUAL_TEMPERATURE= 14

when you then do eg_wz_hz_sp.sendCommand(KOMFORT_TEMPERATURE)
it’s much clearer to understand

I have this in the mappings in my Sitemap.

Selection	item=temp_WZ mappings=[automatisch="Auto", Manuell="Manuell", Komfort="Komfort", Nacht="Nacht"]

My Item temp_WZ is now a String-Item. With this I am able to give Google Home the command “Set Livingroom to Comfort” and my Comfort-Rule gets started.

Is it better to do this in a seperate tranformation file?

Now is the only Problem to get this function to the Google Home App. But thats an other story.

I have this in the mappings in my Sitemap.

yes I saw that when I originally saw your question, and then later I forgot it.
That is one of the many reasons why I like to have all info in my rules.

In general I don’t like to use magic numbers in my code. I prefer constants that explain what the number means…

You could just use a String Item that gets set to “Auto” etc. Then you don’t need the mappings or transforms or constants at all.