Thanks for posting! Great example.
Great example.
I have set up mine with nodered and bigtimer for now. (Was a quick n dirty set up I did in one hour)
I thought about starting jsr223/experimental rule engine for this usecase.
It isn’t needed that urgent, but has some logic to play around with.
I’ve got the rules engine installed but honestly, as a programmer, I like writing them…even when they get ugly like this one.
Cheers!
=C=
Do you need any import
for the temporalAdjuster
and ChronoUnit
?
Gah!
I can’t believe I forgot the imports. Sorry. . Yes, you do need the following import statements in your rules file.
import java.time.Year
import java.time.Month
import java.time.temporal.TemporalAdjusters
import java.time.temporal.ChronoUnit
import java.time.DayOfWeek
import java.time.LocalDate
Cheers!
=C=
Could you add them to your original post, please?
Thanks
I did.
Cheers!
=C=
Thanks, These imports are going to come in useful.
Learned something new today!!
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.
WOW!
Compares to my code that is dang near elegant. Thanks again.
Cheers!
=C=
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.
Great point. I’ll update my code accordingly.
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.
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
Best, Jay
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 “Settings” sitemap
sitemap settings label="Settings"
{
Setpoint item=BedtimeTimer minValue=1 maxValue=10 step=1
Setpoint item=BarrelCount step=1
Setpoint item=MasterBedroomLightSleepTime minValue=10 maxValue=250 step=5
Setpoint item=MasterBedroomLightNumReadings minValue=10 maxValue=500 step=5
Switch item=ChristmasTime
}
My living room menu only shows christmas lights option if “Christmas time” switch is on.
sitemap home label="Main Menu"
{
Frame {
Switch item=Bedtime_Scene
Text label="Living Room" icon="firstfloor" {
Switch item=LivingRoomLights mappings=[OFF="All Off", ON="All On"]
Switch item=ChristmasLights visibility=[ChristmasTime==ON] mappings=[OFF="All Off", ON="All On"]
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.
Group gchristmaslights
Switch ChristmasLights "Christmas Lights"
Switch Switch_LivingRoom_Light "Living Room Light" <light> (gchristmaslights,gLivingRoomLights,gDashboard)
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.
I will post my rules as well since you can never have enough examples. My crons are less engine driven and more explicit to my kids and my own vacations. Feedback is very much welcome, I hope this helps other as well. Merry Christmas everyone!!!
rule "Outside Christmas Lights On at Dusk"
when
Channel 'astro:sun:48320974:set#event' triggered START
then
seasonal_christmas_lights_front.sendCommand(ON)
end
rule "Outside Christmas Lights Off at Dawn"
when
Channel 'astro:sun:48320974:rise#event' triggered START
then
seasonal_christmas_lights_front.sendCommand(OFF)
end
rule "Inside Christmas Lights on"
when
Time cron "0 30 15 ? NOV,DEC MON,TUE,WED,THU,FRI *" or Time cron "0 30 6 ? NOV,DEC SAT,SUN *" or Time cron "0 30 6 20,21,22,23 DEC ? *"
then
seasonal_christmas_banisters.sendCommand(ON)
seasonal_christmas_mantel.sendCommand(ON)
seasonal_christmas_tree.sendCommand(ON)
seasonal_christmas_table_runner.sendCommand(ON)
end
rule "Inside Christmas Lights off Bedtime Weekday"
when
Time cron "0 0 1 ? NOV,DEC SUN,MON,TUE,WED,THU *"
then
seasonal_christmas_banisters.sendCommand(OFF)
seasonal_christmas_mantel.sendCommand(OFF)
seasonal_christmas_tree.sendCommand(OFF)
seasonal_christmas_table_runner.sendCommand(OFF)
end
rule "Inside Christmas Lights off Bedtime Weekend"
when
Time cron "0 30 2 ? NOV,DEC FRI,SAT *"
then
seasonal_christmas_banisters.sendCommand(OFF)
seasonal_christmas_mantel.sendCommand(OFF)
seasonal_christmas_tree.sendCommand(OFF)
seasonal_christmas_table_runner.sendCommand(OFF)
end