My Christmas Rule

Thanks for posting! Great example.

1 Like

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.

2 Likes

I’ve got the rules engine installed but honestly, as a programmer, I like writing them…even when they get ugly like this one. :slight_smile:

Cheers!
=C=

Do you need any import for the temporalAdjuster and ChronoUnit?

Gah!

I can’t believe I forgot the imports. Sorry. :slight_smile: . 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! :slight_smile:
=C=

1 Like

Could you add them to your original post, please?
Thanks

I did. :slight_smile:

Cheers!
=C=

Thanks, These imports are going to come in useful.
Learned something new today!!

1 Like

If you do please post how you did it. We will need lots and lots of examples. :slight_smile:

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.

2 Likes

WOW!

Compares to my code that is dang near elegant. Thanks again. :slight_smile:

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

1 Like

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.

image

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.

1 Like

I am waiting/hoping for your tutorial to get started. :smile:
Maybe i can use it as a starting point and help out improving the threads before we add them to the docs.

1 Like

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.

1 Like

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

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

1 Like

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.

1 Like

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
1 Like