If thatâs not the whole rule, may we see it all?
If it is the whole thing, you are missing rule name, when trigger then section, and an end.
You would most likely trigger the rule to run whenever the temperature changes.
rule "Heater Control"
when
Item Temperature_GF_Bath changed
then
if (Temperature_GF_Bath.state <= Temperature_Setpoint.state)
{
Heating_GF_Bath.sendCommand(ON)
}
else
{
Heating_GF_Bath.sendCommand(OFF)
}
end
Try this wayâŠ
and even set up some logging to the ruel, e.g. when the rule is triggered (above the if-clause) and in the if and else partâŠ
If it is turning on and off correctly you should set up a hysteresis for the setpoint value.
If the temperature is at the setpoint, the heater will turn on and off very quickly. You should allow a difference of 1 or 0.5 K for thisâŠ
Modified rule accordingly as per your suggestion above and seems to be working now
I can start and stop heater by increasing or decreasing temperature setpoint.
I will need to test it well over the next few days to see if this setup is reliable.
Looking in the log I can see the following warning stating NULL valueâŠ
2019-01-31 22:17:27.445 [WARN ] [b.core.events.EventPublisherDelegate] - given new state is NULL, couldn't post update for 'Temperature_Setpoint'
2019-01-31 22:18:27.520 [WARN ] [b.core.events.EventPublisherDelegate] - given new state is NULL, couldn't post update for 'Temperature_Setpoint'
2019-01-31 22:19:27.420 [WARN ] [b.core.events.EventPublisherDelegate] - given new state is NULL, couldn't post update for 'Temperature_Setpoint'
2019-01-31 22:20:27.439 [WARN ] [b.core.events.EventPublisherDelegate] - given new state is NULL, couldn't post update for 'Temperature_Setpoint'
2019-01-31 22:21:27.534 [WARN ] [b.core.events.EventPublisherDelegate] - given new state is NULL, couldn't post update for 'Temperature_Setpoint'
2019-01-31 22:22:27.504 [WARN ] [b.core.events.EventPublisherDelegate] - given new state is NULL, couldn't post update for 'Temperature_Setpoint'
2019-01-31 22:23:27.538 [WARN ] [b.core.events.EventPublisherDelegate] - given new state is NULL, couldn't post update for 'Temperature_Setpoint'
2019-01-31 22:24:27.533 [WARN ] [b.core.events.EventPublisherDelegate] - given new state is NULL, couldn't post update for 'Temperature_Setpoint'
2019-01-31 22:25:27.619 [WARN ] [b.core.events.EventPublisherDelegate] - given new state is NULL, couldn't post update for 'Temperature_Setpoint'
This Item is not updated in the rule that you have shown us, so the source of the warning is elsewhere.
Perhaps another rule, perhaps your UI, perhaps a binding.
How are you expecting that Item to get updated?
@rossko57 You are right - I had another âTemperature_Setpointâ in my demo code which was causing this error - removed now.
I need to improve my rule slightly to prevent some failure scenarios.
I noticed that when my temperature sensor gets disconnected from the system (for any reason) it showing reading -5C. If that ever happens my heater will be continuously working. So would like to add condition to my rule to only execute when temperature reading is above 0C. Temperature in the bath never drops below 13C when heating is off.
Would this work ?
rule "Heater Control"
when
Item Temperature_GF_Bath changed
(Temperature_GF_Bath >0)
then
if (Temperature_GF_Bath.state <= Temperature_Setpoint.state)
{
Heating_GF_Bath.sendCommand(ON)
}
else
{
Heating_GF_Bath.sendCommand(OFF)
}
end
Additionally I would like to add switch to sitemap in order to enable/disable (ON?OFF) temperature setpoint control. At the moment my system doesnt know if Im at home (presence is not implemented yet - on the list to do). So when I`m not at home this rule should be disabled.
Just a warning! If for some reason your sensor will fail or doesnât give the correct you value (like always give the same value back) you might still have the heater continuously working. So be careful what you implement and add some extra safeguards. For example donât run the heater for longer than x or donât run the heater when the temperature doesnât change even while the heater is on. But these are far more complex rules than a simple on/off.
Thanks, yes my scenario number 1 should cover the event of failure the temperature sensor at any time.
I like the idea of limiting heater run to x minutes or if the heater is running for x minutes and temperature hasn`t changed. How would you implement these conditions into working rule please?
Also modified the rule above to include this switch which woulld be used to enable/disable heater control. Third mode âShowerâ will be used when there is request to warm up bathroom to certain fixed temperature - lets say 24C for younger generation.
But some reason when flicking switch from OFF to ON position heater is not starting anymore.
Any ideas where is the mistake ?
rule "Bathroom Heater Control"
when
Item Temperature_Setpoint_Mode changed from OFF to ON
(Temperature_GF_Bath >0)
then
if (Temperature_GF_Bath.state <= Temperature_Setpoint_Bath.state)
{
Heating_GF_Bath.sendCommand(ON)
}
else
{
Heating_GF_Bath.sendCommand(OFF)
}
end
Tried the following rule but there seems to be a problem switching on heater after adding these news conditions (Temperature_GF_Bath>0 & Temperature_Setpoint_Mode)
rule "Bathroom Heater Control ON"
when
Item Temperature_GF_Bath changed
(Temperature_GF_Bath >0)
(Temperature_Setpoint_Mode changed to ON)
then
if (Temperature_GF_Bath.state <= Temperature_Setpoint_Bath.state)
{
Heating_GF_Bath.sendCommand(ON)
}
else
{
Heating_GF_Bath.sendCommand(OFF)
}
end
You should be seeing error report for your rules file in openhab.log
You canât have conditions in rule triggers. Theyâre not suggested in the documentation already pointed to. Rule triggers are just events.
If you want to evaluate conditions, you do it inside the rule body.
rule "Bathroom Heater Control ON"
when
Item Temperature_GF_Bath changed or
Item Temperature_Setpoint_Mode changed to ON
then
if ( (Temperature_GF_Bath.state as Number) > 0) {
if (Temperature_GF_Bath.state <= Temperature_Setpoint_Bath.state) {
Heating_GF_Bath.sendCommand(ON)
} else {
Heating_GF_Bath.sendCommand(OFF)
}
}
end
Iâm not sure if you wanted Temperature_Setpoint_Mode as a trigger, a condition, or both.
Thanks @rossko57 I prefer to set Temperature_Setpoint_Mode as trigger (when set to 1=Heat).
Temperature_Setpoint_Mode generally will be switched ON during day when someone is at home to maintain requested temperature in the bathroom.
I have removed the temperature change condition from rule leaving only setpoint_mode as trigger.
But it works to the degree. When Temperature_Setpoint_Mode is set to 1, heater is turning ON but not stopping after reaching requested temperature - it`s constantly running till heater is switched off manually.
rule "Bathroom Heater Control ON"
when
Item Temperature_Setpoint_Mode changed to 1
then
if ( (Temperature_GF_Bath.state as Number) > 0) {
if (Temperature_GF_Bath.state <= Temperature_Setpoint_Bath.state) {
Heating_GF_Bath.sendCommand(ON)
} else {
Heating_GF_Bath.sendCommand(OFF)
}
}
end
Not sure why is not stopping after hitting requested temperature ?
All I really want is to turn on this setpoint_mode in the morning and let it run to maintain temperature as per setpoint.
Why would it? Itâs doing just what you told it to. Triggers are events. The rule in its last iteration runs once only, when you change Temperature_Setpoint_Mode to 1. The rule then exits, and thatâs the end of that.
Itâs like a script. âWhen I say Go, read the scriptâ. Youâd only read it once and then put it back on the table.
I think what you want to do is trigger the rule whenever the temperature changes, so that you can do the comparison/thermostat action.
If you only want it to do that when the mode is 1, then you need to do the mode comparison within the rule. The rule will still run at every temperature change, but you set it up so that it does nothing useful if the mode is wrong.
If you do only that much, then changing the mode wonât have any immediate effect. Itâll get taken into account the next time the temperature changes and causes the rule to run.
If you want something to happen immediately you change mode, then you will need to trigger on a mode change as well.
You probably want to think about what you want to happen if you set the mode âoffâ while heater is on. That could determine where you do comparisons and what you have in âelseâ parts.
Fair point my friend, its probably better to trigger on temperature change if I can add Temperature_Setpoint_Mode to then section.Modified the following rule so now have three if conditions before heater can be started:
rule "Bathroom Heater Control ON"
when
Item Temperature_GF_Bath changed
then
if ( (Temperature_GF_Bath.state as Number) > 0) {
if (Temperature_GF_Bath.state <= Temperature_Setpoint_Bath.state) {
} if (Temperature_Setpoint_Mode changed to 1) {
Heating_GF_Bath.sendCommand(ON)
}
} else {
Heating_GF_Bath.sendCommand(OFF)
}
end
As a result of the above modification heater is starting as expected but again is just carry on running exceeding setup temperature till heater is manually switched off. What am I doing wrong again?
You still should be seeing errors in your openhab.log for this rules file.
Thatâs a nonsense condition, looking for an event to happen just as you test it in the middle of a rule.
Because this rule is broken as it stands, I suspect youâve got something else hanging around that also switches the heater on.
I do not like âwriting code for peopleâ because you donât learn from it, but offer up a solution in the hope you can figure out why it is this way. Itâs not the only way, or the most elegant way.
rule "Bathroom Heater Control"
when
Item Temperature_GF_Bath changed or
// triggers whenever temp changes
Item Temperature_Setpoint_Mode changed
// also triggers when mode changes for immediate action
// else nothing would happen until temp changed, if it ever did
then
// first we check if the temp reading is valid
if ( Temperature_GF_Bath.state != NULL &&
Temperature_GF_Bath.state != UNDEF &&
Temperature_GF_Bath.state > 0) {
// that != means "not equal" in an if(condition)
// while the && means "and"
// temp sensor is valid, so
// let's set up a target temperature
var Number tempMax = 0
if (Temperature_Setpoint_Mode.state == 2) {
// shower mode
tempMax = 24
} else if (Temperature_Setpoint_Mode.state == 1) {
// normal mode
tempMax = Temperature_Setpoint_Bath.state
}
// if the mode is anything else, the target stays 0 i.e. off
// now let's check against upper limit
if (Temperature_GF_Bath.state < (tempMax - 1)) {
// we allow 1 degree hysteresis
// It's colder than target
// so turn heater on if it isn't already
if (Heating_GF_Bath.state != ON) {
Heating_GF_Bath.sendCommand(ON)
}
// else lets check if we're at the target
} else if (Temperature_GF_Bath.state > tempMax) {
// reached target temp
// (our target could be 0 if mode is off)
// so turn heater off if it isn't already
if (Heating_GF_Bath.state != OFF) {
Heating_GF_Bath.sendCommand(OFF)
}
} // else we do nothing here
// temp could be within 1 degree of target
// and the heater will continue doing what it is doing
// That's the hysteresis
} else { // this else belongs to the valid temp reading check
Heating_GF_Bath.sendCommand(OFF)
// temp sensor broken, turn off heater for safety
}
end