Hi,
I tried for several months to have my heating change values related to the time but depending that on my presence.
So, I searched and read rules and defs over and over but can’t find what’s wrong with this rule:
rule "Flur Heizung"
when
Time cron "0 0 * * * ?"
or
Item Presence changed
then
var Number hour_Corridor = now.getHourOfDay
//22-6
if ((Presence.state == ON) && (hour_Corridor >= 22) && (hour_Corridor <=6))
{ sendCommand(Heating_GF_Corridor, 5.0)
}
//6-12
else if ((Presence.state == ON) && (hour_Corridor >= 6) && (hour_Corridor <=12))
{ sendCommand(Heating_GF_Corridor, 16.0)
}
//12-18
else if ((Presence.state == ON) && (hour_Corridor >= 12) && (hour_Corridor <=18))
{ sendCommand(Heating_GF_Corridor, 12.0)
}
//18-22
else if ((Presence.state == ON) && (hour_Corridor >= 18) && (hour_Corridor <=22))
{ sendCommand(Heating_GF_Corridor, 16.0)
}
end
I am surely no rules specialist, but how can a value be greater than 22 AND at the same time lower than 6? Shouldn’t it be an OR relation instead of an AND relation?
If you will have other rules that may need to do different things based on time of day I recommend the following:
I’m pretty certain that @KjetilA has the solution. You can never have an hour that is both >=22 and <=6.
Assuming you didn’t apply the design pattern above, I think you can make this code a little easier to understand the following way:
if(Presence.state == ON){
var Number hour = now.getHourOfDay
var heat = 16.0
if (hour > 22 || hour <= 6) heat = 5.0
else if(hour > 12 && hour <= 18) heat = 12.0
Heating_GF_Corridor.sendCommand(heat)
}
In the above we have just one if statement at the top to see if Presence.state == ON. If not then all the code is skipped. Now we don’t need to worry about presence in the rest of the rule.
Next I notice that the heating value passed for two of your time periods are the same. So I initialize a var to 16.0 and now only need to check for the other two time periods, reducing the number of conditionals by half.
You are right. I overseen this, whole life with IFs and such mistake! If you know that clock is limited to 24 hours then this if could be flipped to IF (hour <= 6 || hour => 22). @rlkoshak pattern is also fine since it allows to use same signs for comparision.
@rlkoshak Wow, way shorter. strongly believe that this is what I searched for.
One problem I had so far is that when coming home at 5:50 am the heating is at 5.0, but it’s not set to 16.0 at 6:01 am because nothing does change.
But if I use your IF construction under a cron expression, that should work, right?
Yes. The problem is you were using <= for all of your comparisons. So, for example, your system wouldn’t go to heating 16.0 until 7 am because at 6 am your first conditional will evaluate to True. The conditionals are evaluated in order.