Hi all. After getting my rule working, I'd like to share it in the hope of:
- learning tips/tricks for improving it
- sharing some of the tricks I cooked up.
I realize this rule is similar to the lights app but I wanted to set things up myself and because I wanted some unsupported differences.
Design goals:
- Use a variable ("Family Room Lights - Pending") to structure the code in function-like blocks.
- Have all the triggers in one place so I can easily see how things interact.
- Have wait delays resume were they left off.
- Door triggers lights upon return home and not presence so that way I can see the lights turn on.
- Play nicely with manual overrides.
Things I wish RM supported:
- An enum for the trigger; this would prevent the clunky storing/reading as a string.
-
wait
which can easily takeFalse
- The ability to set a boolean variable to a condition; this would turn five lines into one. (Note: I didn't need that in this rule but I have in others.)
- Triggers supported "first" rather than "all"; eg, rather than trigger on every
illuminance<60
I wish it could be made to trigger only on the first. (I achieved this by creating a Virtual Illuminance sensor.) - A version of
wait for event
which short-circuited if the event was already true; this would mitigate needing a conditional "guard." - The ability to move multiple lines up or down.
- The ability to have multiple numeric operations and all in an assignment, eg,
set variable to 60*max(0,30-other_variable )
. This would mean I dont have to create excess variables for what otherwise could be an inline operation.
Well, I hope you find the following useful. Looking forward to hearing you thoughts.
Triggers:
Family Room Lights - Pending reports variable *changed*
Family Room Motion motion *changed*
Front Door contact open
Illuminance of Virtual Illuminance reports <= 60
Someone departs
Variables:
datetime_current DateTime 2022-10-18 11:30 PM
datetime_motion DateTime 2022-10-19 8:22 PM
datetime_pending DateTime 2022-10-19 5:06 PM
seen_door_trigger Boolean true
trigger String Family Room Motion
wait_delay Number 300
was_evening_time Boolean true
Rule:
IF (Variable Family Room Lights - Pending = 'Turn Off') THEN
IF (NOT Couch Lamp 1, Torch Lamp, Couch Lamp 2 any is on) THEN
Set Family Room Lights - Pending to 'Manual Off'
END-IF
IF (NOT Couch Lamp 1, Torch Lamp, Couch Lamp 2 all on) THEN
Set Family Room Lights - Pending to 'Manual On'
END-IF
Off: Couch Lamp 1, Couch Lamps, Torch Lamp, Couch Lamp 2
Set Family Room Lights - Pending to 'None'
END-IF
IF (NOT Couch Lamp 1, Torch Lamp, Couch Lamp 2 any is on AND
Variable Family Room Lights - Pending = 'Manual On') THEN
Set Family Room Lights - Pending to 'None'
END-IF
Set trigger to '%device%'
IF (Variable trigger *contains* 'Motion' AND
NOT Family Room Motion motion active) THEN
Set datetime_motion to current date and time
END-IF
IF (Variable trigger *contains* 'Pending') THEN
Set datetime_pending to current date and time
Set datetime_motion to datetime_pending
Set was_evening_time to false
IF (Variable Family Room Lights - Pending = 'None') THEN
Exit Rule
END-IF
END-IF
IF (Variable trigger = 'Someone') THEN
Set seen_door_trigger to false
Off: Couch Lamps, Torch Lamp
Wait for event: Couch Lamp 1, Torch Lamp, Couch Lamp 2 all turn off --> timeout: 0:00:01
Set Family Room Lights - Pending to 'None'
END-IF
IF (Variable Family Room Lights - Pending = 'None' AND
Couch Lamp 1, Torch Lamp, Couch Lamp 2 any is on) THEN
Set Family Room Lights - Pending to 'Manual On'
END-IF
IF (Variable Family Room Lights - Pending = 'None' AND
Someone present AND
Illuminance of Family Room Illuminance is <= 60 AND
( ( Variable trigger *contains* 'Door' AND
NOT Variable seen_door_trigger = true
) OR
( Variable trigger *contains* 'Illuminance' AND
Mode is Evening AND
Variable seen_door_trigger = true
) OR
( Variable trigger *contains* 'Motion' AND
Family Room Motion motion active AND
Variable seen_door_trigger = true
)
)) THEN
On: Couch Lamps, Torch Lamp
Set Family Room Lights - Pending to '%trigger%'
END-IF
IF (Variable trigger *contains* 'Door' OR
Variable Family Room Lights - Pending *contains* 'Door') THEN
Set seen_door_trigger to true
END-IF
IF (Variable Family Room Lights - Pending *contains* 'Manual') THEN
Wait for event: Mode becomes *changed*
IF (Couch Lamp 1, Torch Lamp, Couch Lamp 2 any is on) THEN
Set Family Room Lights - Pending to 'Family Room Motion'
ELSE
Set Family Room Lights - Pending to 'None'
END-IF
END-IF
IF (Variable Family Room Lights - Pending = 'None' OR
Family Room Motion motion active) THEN
Exit Rule
END-IF
IF (Mode is Evening) THEN
Set was_evening_time to true
Wait for event: Mode becomes *changed*
Set datetime_motion to current date and time
END-IF
IF (Mode is Night) THEN
Set datetime_current to current date and time
set wait_delay to minutes of difference between datetime_current) and datetime_motion
IF (Variable Family Room Lights - Pending *contains* 'Door' AND
NOT Variable was_evening_time = true) THEN
Set wait_delay to (30 - wait_delay)
ELSE
Set wait_delay to (5 - wait_delay)
END-IF
Set wait_delay to (60 * wait_delay)
Wait for Expression: --> timeout: wait_delaynull
ELSE-IF (Illuminance of Family Room Illuminance is <= 60) THEN
Wait for event: Illuminance of Family Room Illuminance is > 60 --> timeout: 12:00:00
END-IF
Set Family Room Lights - Pending to 'Turn Off'
Fwiw, here's the "Virtual Illuminance"
Triggers:
Illuminance of Family Room Illuminance *changed*
Code:
IF (Illuminance of Family Room Illuminance is < 60 XOR
Illuminance of Virtual Illuminance is < 60) THEN
setLux(%value%) on Virtual Illuminance
END-IF
I don't actually need to use this sensor but I thought it seemed like a good idea to have the big rule above triggered less often. (Either way it seems to be very fast; I guess this was just playing around more than anything.)