Edit: Note that the OH2 Astro binding now contains event functionality that eliminates the need for this workaround! Whatâs below can be accomplished much more simply using the native Astro binding functionality.
There was some discussion here about sunrise & sunset events in OH2.
https://community.openhab.org/t/simply-turn-on-at-sunrise-turn-off-at-sunset-in-openhab2
Iâm sharing what I do in case anyone wants to use, critique, or extend.
ntp.items
DateTime CurrentTime "Date [%1$tA, %1$tm/%1$td/%1$tY %1$tT]" <calendar> { channel="ntp:ntp:local:dateTime" }
astro.items
// Times of Day
String TimePeriodOfDay "Time of Day [%s]"
DateTime DawnStart_Time "Dawn Start [%1$tH:%1$tM]" { channel="astro:sun:local:civilDawn#start" }
DateTime DawnStop_Time "Dawn Stop [%1$tH:%1$tM]" { channel="astro:sun:local:civilDawn#end" }
DateTime DayStart_Time "Day Start [%1$tH:%1$tM]" { channel="astro:sun:local:daylight#start" }
DateTime DayStop_Time "Day Stop [%1$tH:%1$tM]" { channel="astro:sun:local:daylight#end" }
DateTime DuskStart_Time "Dusk Start [%1$tH:%1$tM]" { channel="astro:sun:local:civilDusk#start" }
DateTime DuskStop_Time "Dusk Stop [%1$tH:%1$tM]" { channel="astro:sun:local:civilDusk#end" }
DateTime NightStart_Time "Night Start [%1$tH:%1$tM]" { channel="astro:sun:local:night#start" }
DateTime NightStop_Time "Night Stop[%1$tH:%1$tM]" { channel="astro:sun:local:night#end" }
DateTime MorningNightStart_Time "MorningNightStart [%1$tH:%1$tM]" { channel="astro:sun:local:morningNight#start" }
DateTime MorningNightStop_Time "MorningNightStop [%1$tH:%1$tM]" { channel="astro:sun:local:morningNight#end" }
DateTime EveningNightStart_Time "EveningNightStart [%1$tH:%1$tM]" { channel="astro:sun:local:eveningNight#start" }
DateTime EveningNightStop_Time "EveningNightStop [%1$tH:%1$tM]" { channel="astro:sun:local:eveningNight#end" }
// Events
Switch DawnStart_Event "Start of Dawn Event"
Switch DayStart_Event "Start of Day Event"
Switch DuskStart_Event "Start of Dusk Event"
Switch NightStart_Event "Start of Night Event"
// Items
Switch Dawn "Dawn [%s]" // After Dawn and before Day
Switch Day "Day [%s]" // After Day and before Dusk
Switch Dusk "Dusk [%s]" // After Dusk and before Night
Switch Night "Night [%s]" // After Night and before Dawn
Number SunAzimuth "Azimuth [%.0f °]" { channel="astro:sun:local:position#azimuth" }
Number SunElevation "Elevation [%.0f °]" { channel="astro:sun:local:position#elevation" }
String MoonPhase "MoonPhase [%s]" { channel="astro:moon:local:phase#name" }
time-of-day.rules
import java.util.Date
// Time of Day Rules
// Requires time update every 60 seconds
val String RFN = "time-of-day.rules"
rule "Get time period for right now"
when
System started
then
val now = new Date()
val dawn = new Date((DawnStart_Time.state as DateTimeType).calendar.timeInMillis)
val day = new Date((DayStart_Time.state as DateTimeType).calendar.timeInMillis)
val dusk = new Date((DuskStart_Time.state as DateTimeType).calendar.timeInMillis)
val night = new Date((NightStart_Time.state as DateTimeType).calendar.timeInMillis)
val String initStr = "Initializing time period. The time of day is "
if(now.after(dawn) && now.before(day)) {
logInfo(RFN, initStr + "Dawn: " + now)
Dawn.sendCommand(ON)
Day.sendCommand(OFF)
Dusk.sendCommand(OFF)
Night.sendCommand(OFF)
TimePeriodOfDay.postUpdate("Dawn")
}
else if(now.after(day) && now.before(dusk)) {
logInfo(RFN, initStr + "Day: " + now)
Dawn.sendCommand(OFF)
Day.sendCommand(ON)
Dusk.sendCommand(OFF)
Night.sendCommand(OFF)
TimePeriodOfDay.postUpdate("Day")
}
else if(now.after(dusk) && now.before(night)) {
logInfo(RFN, initStr + "Dusk: " + now)
Dawn.sendCommand(OFF)
Day.sendCommand(OFF)
Dusk.sendCommand(ON)
Night.sendCommand(OFF)
TimePeriodOfDay.postUpdate("Dusk")
}
else {
logInfo(RFN, initStr + "Night: " + now)
Dawn.sendCommand(OFF)
Day.sendCommand(OFF)
Dusk.sendCommand(OFF)
Night.sendCommand(ON)
TimePeriodOfDay.postUpdate("Night")
}
end
rule "Generate Time of Day Events"
when
Item CurrentTime received update
then
val now = new Date()
val dawn = new Date((DawnStart_Time.state as DateTimeType).calendar.timeInMillis)
val day = new Date((DayStart_Time.state as DateTimeType).calendar.timeInMillis)
val dusk = new Date((DuskStart_Time.state as DateTimeType).calendar.timeInMillis)
val night = new Date((NightStart_Time.state as DateTimeType).calendar.timeInMillis)
val sunset = new Date((SunsetStart_Time.state as DateTimeType).calendar.timeInMillis)
val sunrise = new Date((SunriseStart_Time.state as DateTimeType).calendar.timeInMillis)
if((now.getTime-(now.getTime%60000)) == (dawn.getTime-(dawn.getTime%60000))) {
logInfo(RFN, "Transitioning to Dawn!!!")
DawnStart_Event.postUpdate(ON)
}
else if((now.getTime-(now.getTime%60000)) == (day.getTime-(day.getTime%60000))) {
logInfo(RFN, "Transitioning to Day!!!")
DayStart_Event.postUpdate(ON)
}
else if((now.getTime-(now.getTime%60000)) == (dusk.getTime-(dusk.getTime%60000))) {
logInfo(RFN, "Transitioning to Dusk!!!")
DuskStart_Event.postUpdate(ON)
}
else if((now.getTime-(now.getTime%60000)) == (night.getTime-(night.getTime%60000))) {
logInfo(RFN, "Transitioning to Night!!!")
NightStart_Event.postUpdate(ON)
}
if((now.getTime-(now.getTime%60000)) == (sunrise.getTime-(sunrise.getTime%60000))) {
logInfo(RFN, "Start of Sunrise!")
SunriseStart_Event.postUpdate(ON)
}
else if((now.getTime-(now.getTime%60000)) == (sunset.getTime-(sunset.getTime%60000))) {
logInfo(RFN, "Start of Sunset!")
SunsetStart_Event.postUpdate(ON)
}
end
rule "Dawn Started"
when
Item DawnStart_Event received update ON
then
val now = new Date()
val dawn = new Date((DawnStart_Time.state as DateTimeType).calendar.timeInMillis)
val day = new Date((DayStart_Time.state as DateTimeType).calendar.timeInMillis)
if(now.after(dawn) && now.before(day)) {
logInfo(RFN, "Its Dawn: " + now)
Dawn.sendCommand(ON)
Day.sendCommand(OFF)
Dusk.sendCommand(OFF)
Night.sendCommand(OFF)
TimePeriodOfDay.postUpdate("Dawn")
}
end
rule "Day Started"
when
Item DayStart_Event received update ON
then
val now = new Date()
val day = new Date((DayStart_Time.state as DateTimeType).calendar.timeInMillis)
val dusk = new Date((DuskStart_Time.state as DateTimeType).calendar.timeInMillis)
if(now.after(day) && now.before(dusk)) {
logInfo(RFN, "Its Day: " + now)
Dawn.sendCommand(OFF)
Day.sendCommand(ON)
Dusk.sendCommand(OFF)
Night.sendCommand(OFF)
TimePeriodOfDay.postUpdate("Day")
}
end
rule "Dusk started"
when
Item DuskStart_Event received update ON
then
val now = new Date()
val dusk = new Date((DuskStart_Time.state as DateTimeType).calendar.timeInMillis)
val night = new Date((NightStart_Time.state as DateTimeType).calendar.timeInMillis)
if(now.after(dusk) && now.before(night)) {
logInfo(RFN, "Its Dusk: " + now)
Dawn.sendCommand(OFF)
Day.sendCommand(OFF)
Dusk.sendCommand(ON)
Night.sendCommand(OFF)
TimePeriodOfDay.postUpdate("Dusk")
}
end
rule "Night started"
when
Item NightStart_Event received update ON
then
val now = new Date()
val morningNightStart = new Date((MorningNightStart_Time.state as DateTimeType).calendar.timeInMillis)
val morningNightStop = new Date((MorningNightStop_Time.state as DateTimeType).calendar.timeInMillis)
val eveningNightStart = new Date((EveningNightStart_Time.state as DateTimeType).calendar.timeInMillis)
val eveningNightStop = new Date((EveningNightStop_Time.state as DateTimeType).calendar.timeInMillis)
if((now.after(morningNightStart) && now.before(morningNightStop)) ||
(now.after(eveningNightStart) && now.before(eveningNightStop))) {
logInfo(RFN, "Its Night: " + now)
Dawn.sendCommand(OFF)
Day.sendCommand(OFF)
Dusk.sendCommand(OFF)
Night.sendCommand(ON)
TimePeriodOfDay.postUpdate("Night")
}
end
rule "Sunrise started"
when
Item SunriseStart_Event received update ON
then
val now = new Date()
logInfo(RFN, "Its Sunrise : " + now)
end
rule "Sunset started"
when
Item SunsetStart_Event received update ON
then
val now = new Date()
logInfo(RFN, "Its Sunset : " + now)
end
sitemap fragment
Frame {
Text label="Time of Day Information" {
Frame label="Time Period of Day" {
Text item=TimePeriodOfDay label="Time of Day"
}
Frame label="Time Transition Events" {
Text item=SunriseStart_Time label="Sunrise Start Time"
Text item=SunsetStart_Time label="Sunset Start Time"
Text item=DawnStart_Time label="Dawn Start Time"
Text item=DayStart_Time label="Day Start Time"
Text item=DuskStart_Time label="Dusk Start Time"
Text item=NightStart_Time label="Night Start Time"
}
Frame label="Time of Day Status" {
Text item=Dawn label="Is Dawn"
Text item=Day label="Is Day"
Text item=Dusk label="Is Dusk"
Text item=Night label="Is Night"
}
Frame label="Sun" {
Text item=SunAzimuth label="Sun Azimuth" icon="sun"
Text item=SunElevation label="Sun Elevation" icon="sun"
}
Frame label="Moon" {
Text item=MoonPhase label="Moon Phase" icon="moon"
}
}
}