A very frequent problem when writing rules is how to determine if it is currently DAY Time of NIGHT Time in order your rules to take different paths .
Many solutions have already been provided in the community forum, some more easy than others.
A very simple approach would be just to follow the daily events using the Astro binding. This is based on the fact the Sun Rise will ALWAYS follow Sun Set and vice versa.
The same logic applies for any event during the day. eg Night time will always come after Afternoon time.
The two extremely simple rules can be used to change the state of an item accordingly, which in turn can be used in other rules depending if the state is ON or OFF.
/======================================================/
rule âNight time ON at sun setâ
when
Channel âastro:sun:home:set#eventâ triggered START
then
Night_Time.sendCommand(ON)
end
/======================================================/
rule âNight time OFF at sun riseâ
when
Channel âastro:sun:home:rise#eventâ triggered START
then
Night_Time.sendCommand(OFF)
end
/======================================================/
The above will work perfectly as long as there is no openHAB server down time for a significant amount of time. If the server is down long enough for one of the events to be passed during the down time period then the state of the Night_Time item will be wrong until the execution of the next event. (assuming suitable persistence is used at start up).
A better and yet very easy to determine the time of the day is to calculate it. This rule can be used at start up or at any other time. The rule below is based on the fact that " If the current time is after Sunset OR before Sunrise it will always be night time (respectively if the current time is before or after midnight)"
/======================================================/
rule âCalculate time of day stateâ
when
System started // run at system start in case the state changed when OH was offline
then
val Number epochNow = now.millis
val Number epochSunrise = (astro_sun_home_rise_start.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli
val Number epochSunset = (astro_sun_home_set_start.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli
if ((epochNow > epochSunset) || (epochNow < epochSunrise)) {
Night_Time.sendCommand(ON) // If the current time is after Sunset OR before Sunrise it will always be night time (before or after midnight)
}
else
Night_Time.sendCommand(OFF)
end
/======================================================/
It would help to read if you placed your rules inside code fences. Itâs the paper icon to the left of gear icon when posting.
Example:
rule "Night time ON at sun set"
when
Channel 'astro:sun:home:set#event' triggered START
then
Night_Time.sendCommand(ON)
end
rule "Night time OFF at sun rise"
when
Channel 'astro:sun:home:rise#event' triggered START
then
Night_Time.sendCommand(OFF)
end
rule "Calculate time of day state"
when
System started // run at system start in case the state changed when OH was offline
then
val Number epochNow = now.millis
val Number epochSunrise = (astro_sun_home_rise_start.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli
val Number epochSunset = (astro_sun_home_set_start.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli
if ((epochNow > epochSunset) || (epochNow < epochSunrise)) {
Night_Time.sendCommand(ON) // If the current time is after Sunset OR before Sunrise it will always be night time (before or after midnight)
}
else
Night_Time.sendCommand(OFF)
end
@ancheta61. Hi my rules are were mend to provide to the system a way to know if it is currently day time or night time. Then how this information is further used in other rules to turn lights ON and OFF or take other actions is up to the individual user.
Having said the above, there are several ways to tackle your question.
The simplest way would be to have a simple rule with a CRON trigger that runs at specified intervals (letâs say every minute, to turn the light ON, after checking if it is night time. For example,
rule "check every minute"
when
Time cron "0 0/1 * 1/1 * ? *" // every 1 minute
then
if( Night_Time.state == ON ) {
myLightItem.sendCommand (ON)
} else {
myLightItem.sendCommand (OFF)
}
end
Another way would be to set up a timer that when a light is turned OFF, would turn it back ON after a specified time interval, after checking if it is day time or night time. For exampleâŠ
var Timer myTimer = null
rule "check with timer"
when
myLightItem changed to OFF
then
if (Night_Time.state == ON ) {
myTimer?.cancel
myTimer = createTimer(now.plusMinutes(30), [ | // You can have any number of Seconds, Minutes or Hours
myLightItem.sendCommand (ON)
])
}
end
Finally please donât forget that you can use my third rule âCalculate time of day stateâ at any moment, in order to find out if it is day time or night time. You can just Copy Paste the rule.
After re-checking my rules i found that I made a small mistake in my rule âcheck with timerâ above after the when line. Please find the corrected rule below.
var Timer myTimer = null
rule "check with timer"
when
Item myLightItem changed to OFF
then
if (Night_Time.state == ON ) {
myTimer?.cancel
myTimer = createTimer(now.plusMinutes(30), [ | // You can have any number of Seconds, Minutes or Hours
myLightItem.sendCommand (ON)
])
}
end
Please also note that it is better to have the
var Timer myTimer = null
line, at the top of your rules file before any rule in order to avoid parsing errors.
@gustav. So the Night_Time in Night_Time.sendCommand(ON) is not an item. Also can I put all the rules in one file. By the way thanks for helping out a newbie.
I think this bit is very helpful and crucial information. By creating switch items for nighttime (or even âawayâ, âsleepâ, âholidayâ etc) you can then use the state of these switches in other rules/automations. Advantage is that you have the actual logic for determining whether it is day or night in one single location. At first I would copy this in each separate rule which made changes cumbersome and prone to errors.
Got it all working now. Thanks for all your contribution. Some us just really need simple operations and your rules are pretty much all i need for this part of my project. Thanks again.