I’ve switched almost entirely to using the EXPIRE binding to deal with what were previously timers issues.
Works well, gets you separation between your core automation logic and the mechanics of maintaining timers “in-line”.
Mechanics —
- Define a couple of timers as a virtual items like this, like this----
Switch SW_u_01_LIGHT_Kitchen_TIMER_5m_OFF { expire="5m,command=OFF" }
Switch SW_u_01_LIGHT_Kitchen_TIMER_10s_OFF { expire="10s,command=OFF" }
- In your rules file, on occurrence of some event, use sendCommand to turn this virtual switch ON, like this…
rule "Kitchen motion sensor fires"
when
Item MO_u_01_MOTION_Kitchen changed to OPEN or
Item MO_u_01_MOTION_Kitchen changed to ON
then
SW_u_01_LIGHT_Kitchen_PXY_MOTION.sendCommand(ON)
SW_u_01_LIGHT_Kitchen_TIMER_5m_OFF.sendCommand(ON)
end
This rule’s THEN clause first does a sendCommand to the entry point of the proxy-chain I have defined (long story, but gist is tracing back the source of a command for a switch to a particular type of trigger), and then turns the virtual switch for the 5minute timer (ON) in the second part of the THEN clause.
If the virtual switch for the 5m_OFF is triggered by the EXPIRE binding (ie 5 minutes pass without a countermanding instruction, this rule cascade gets hit----
rule "SW_u_01_LIGHT_Kitchen_TIMER_5m_OFF changed to OFF"
when
Item SW_u_01_LIGHT_Kitchen_TIMER_5m_OFF changed to OFF
then
logDebug("APARTMENT","META_TIMER_3: Timer 5m OFF received command OFF")
logDebug("APARTMENT","META_TIMER_3: MO_u_01_MOTION_Kitchen.state is: " + MO_u_01_MOTION_Kitchen.state)
logInfo("APARTMENT","META_TIMER_3: SW_u_01_LIGHT_Kitchen_TIMER_5m_OFF is OFF: Motion detector OFF, sending ON to TIMER_10s_OFF")
SW_u_01_LIGHT_Kitchen_TIMER_10s_OFF.sendCommand(ON)
end
//.....
rule "SW_u_01_LIGHT_Kitchen_TIMER_10s_OFF changed to OFF"
when
Item SW_u_01_LIGHT_Kitchen_TIMER_10s_OFF changed to OFF
then
if (MO_u_01_MOTION_Kitchen.state == OPEN) {
SW_u_01_LIGHT_Kitchen_TIMER_10s_OFF.sendCommand(ON)
} else {
SW_u_01_LIGHT_Kitchen_PXY_MOTION.sendCommand(OFF)
}
end
So, in essence, if the 5m_OFF timer expires, the rules go into a tight loop checking to see if the motion detector is OPEN or not — IF OPEN it resets the the 10s_OFF “tight loop”.
This illustrates both one of the drawbacks of EXPIRE binding and how to deal with it. You cannot change the time length of an item with an EXPIRE binding. You can start it (with defined time length), stop it (with a sendCommand(OFF), or reset it to its defined length by a sendCommand(ON). You cannot have variable-length timers using EXPIRE binding, but I have found the overhead of the multiple virtual timer definitions to be well-worth the savings in mechanics of timer create, reset, cancel, cleanup operations inline in rules.