I just posted “My OpenHab Christmas Rule” over on my blog. However, I know what a pain it it to search all over the code you are looking for, so here is the Items and Rules. If you know a little about OpenHab, you can figure this out. If you want the why, visit my blog.
That’s it. I included the plug in my network, setup the Items and Groups - the last group is so that I can have Alexa turn the lights off when I ask - and I put the rules in my Dusk_till_Dawn.rules file.
I hope this helps you get your seasonal lighting automated.
OH! After I wrote this, I got " Design Pattern: Time Of Day by @rlkoshak working. Wonderful tutorial. I may update my rules for next year using some of his concepts. Thank you Rich.
If you do please post how you did it. We will need lots and lots of examples.
So, if you want to make the code a little cleaner you can take advantage of cron triggers and perhaps Astro season events to populate a TimeOfYear state. Then you can use a few very simple Rules instead of the complicated date math.
Let’s make it even simpler and have a ChristmasTime Switch.
Switch ChristmasTime "Tis the season"
rule "Christmas Time"
when
Time cron "45 0 0 ? NOV 5#4 *" or // 4th Thursday of November
Time cron "45 0 0 31 DEC ? *" // Last day of the year
then
ChristmasTime.sendCommand(if(now.getMonthOfYear == 11) ON else OFF)
end
rule "Christmas Lights ON"
when
Channel "astro:sun:local:civilDusk#event" triggered START
then
if(ChristmasTime.state == OFF) return;
logInfo("LIGHTS", "Light the Christmas tree")
christmasLights.sendCommand(ON)
end
rule "Christmas Lights OFF"
when
Time cron "0 0 23 1/1 NOV,DEC ? *"
then
christmasLights.sendCommand(OFF)
logInfo("LIGHTS","Christmas, Lights Off")
end
Of course you lose the nice logInfo calculation of the number of days until the tree is lit. For that I don’t think there is any alternative that is any cleaner than what you have. Working with Dates is always ugly.
And I too learned something. I’m not familiar with those classes. I guess I’ve been away from Java too long.
Just one little bit:
I would change the cron triggers in the first rule so as not to conflict with other “midnight” jobs
rule "Christmas Time"
when
Time cron "45 0 0 ? NOV 5#4 *" or // 4th Thursday of November
Time cron "45 0 0 31 DEC ? *" // Last day of the year
then
ChristmasTime.sendCommand(if(now.getMonthOfYear == 11) ON else OFF)
end
I’ve been at this awhile and have taken it upon myself to figure out how to code in Rules DSL well. Now that I’m really good at it the NGRE is coming down the line.
I fully agree and this is one reason i didn’t try to switch yet.
If i do so it will definetely be a combination of experimental engine combined with JSR223 (i think javascript will be my choice then), which uses the script area.
I am waiting/hoping for your tutorial to get started.
Maybe i can use it as a starting point and help out improving the threads before we add them to the docs.
What I have so far start’s here. There are five posts in the series (see the little navigation links at the bottom of each post).
I have a good start. I have the basics, installation, importing libraries, what implicit variables are available, and started on Actions. I still need to cover “but only if…” , templates, creating your own libraries, and lots of examples. I think there is enough there to get started. But the time based triggers are one thing that is somewhat lacking which would make my approach challenging.
Sounds really promising already.
Maybe i can start with that soon.
Current priority topic is the vscode extension, which need a bit love after this long time without updates.
3 Likes
jwiseman
(Mr. Wiseman (OH 4.2 Snapshot on Pi4))
18
My xMas Tree Plug (WeMo & Hue Motion) Rules:
//
// xMas Tree Plug
//
rule "xMas Tree turn ON when a phone is ON and Dec and Weekend "
when
Item Kitchen_Motion_Sensor changed to ON
then
currMonth = now.getMonthOfYear
currHour = now.getHourOfDay
currDayofWeek = now.getDayOfWeek
if (Wallplug_xMas_Tree.state == OFF && currMonth == 12 && currHour >= 7 && currHour <= 21 && Home_Away.state == ON && (JsAndriodUnifi.state == ON || TsiPhoneUnifi.state == ON)) {
if (currDayofWeek == 6 || currDayofWeek == 7) {
// Turn ON xMas Tree
Wallplug_xMas_Tree.sendCommand(ON)
Thread::sleep(3000) // 3 second wait
Wallplug_xMas_Tree.sendCommand(ON)
Thread::sleep(3000) // 3 second wait
logInfo("WeMo", "Turned ON xMas Tree Plug based on motion, phones, hour, day and month.")
}
}
end
rule "xMas Tree Plug turn OFF when both phones are off the network"
when
Item JsAndriodUnifi changed to OFF or
Item TsiPhoneUnifi changed to OFF
then
if (JsAndriodUnifi.state == OFF && TsiPhoneUnifi.state == OFF) {
// Shut off xMas Tree
Wallplug_xMas_Tree.sendCommand(OFF)
Thread::sleep(3000) // 3 second wait
Wallplug_xMas_Tree.sendCommand(OFF)
Thread::sleep(3000) // 3 second wait
logInfo("WeMo", "Turned OFF xMas Tree Plug because both Cell Phones are gone.")
}
end
It is advisable not to use Thread::sleep for more than 500ms
You can use timers instead:
Why are you sending the command twice to turn ON and OFF the Xmas tree?
rule "xMas Tree turn ON when a phone is ON and Dec and Weekend "
when
Item Kitchen_Motion_Sensor changed to ON
then
currMonth = now.getMonthOfYear
currHour = now.getHourOfDay
currDayofWeek = now.getDayOfWeek
if (Wallplug_xMas_Tree.state == OFF && currMonth == 12 && currHour >= 7 && currHour <= 21 && Home_Away.state == ON && (JsAndriodUnifi.state == ON || TsiPhoneUnifi.state == ON)) {
if (currDayofWeek == 6 || currDayofWeek == 7) {
// Turn ON xMas Tree
Wallplug_xMas_Tree.sendCommand(ON)
createTimer(now.plusSeconds(3), [ | Wallplug_xMas_Tree.sendCommand(ON) ])
createTimer(now.plusSeconds(6), [ | logInfo("WeMo", "Turned ON xMas Tree Plug based on motion, phones, hour, day and month.") ])
}
}
end
rule "xMas Tree Plug turn OFF when both phones are off the network"
when
Item JsAndriodUnifi changed to OFF or
Item TsiPhoneUnifi changed to OFF
then
if (JsAndriodUnifi.state == OFF && TsiPhoneUnifi.state == OFF) {
// Shut off xMas Tree
Wallplug_xMas_Tree.sendCommand(OFF)
createTimer(now.plusSeconds(3), [ | Wallplug_xMas_Tree.sendCommand(OFF) ])
createTimer(now.plusSeconds(6), [ | logInfo("WeMo", "Turned OFF xMas Tree Plug because both Cell Phones are gone.") ])
logInfo("WeMo", "Turned OFF xMas Tree Plug because both Cell Phones are gone.")
}
end
My setup is a little different as we don’t always get to put up the tree and lights at the same time. I have my outside lights on this too. I have a switch that says it’s christmas time to cover this since we sometime are late getting the stuff setup.
My items have the virtual switch for all my xmas lights. the group and my one living room light is also where the christmas tree goes. so it’s part of that group too.
rule "Christmas Lights"
when
Item ChristmasLights changed
then
if(ChristmasLights.state==ON)
{
gchristmaslights.send(ON)
logInfo("All xmas Lights","ON")
sendCommand(gchristmaslights,ON)
}
else
{
logInfo("All xmas Lights","OFF")
gchristmaslights.send(OFF)
}
end
rule "xmas morning lights"
when
Time cron "0 30 6 * * ?"
then
if (ChristmasTime.state == ON)
{
gchristmaslights.send(ON)
logInfo("All xmas Lights","ON")
}
end
Each morning, if it’s christmas time the lights turn on. This way the tree is lit each morning when the kids get up. The christmas inflatables are up and saying hi to everyone as they are off to work/school.