Wrote this, and its working
But, I have problem. In case a BI_FC_Motion change to ON during running timer, the previous timer will turn of the lights before the new timer will.
So I need to reset the timer to X every time new movement happen (Movement is BI_FC_Motion=ON)
I saw I can reschedule a timer, but what if I didn’t have this timer ?
I can create timer and immediately reschedule it, but I think its not the right solution
rule “BI Motion FC”
when
Item BI_FC_Motion changed from OFF to ON
then
var boolean MovementLightsOn = false
logInfo(“home.rules”, "MovementLightOn Before State: " + MovementLightsOn )
logInfo(“home.rules”, "Sun State: " + sun )
if (sun == false && LS_FrontOutside.state == OFF) {
MovementLightsOn = true
logInfo(“home.rules”, "MovementLightOn During State: " + MovementLightsOn )
LS_FrontOutside.sendCommand(ON)
logInfo(“home.rules”, “Lights on for Camera”)
}
Thread::sleep(2500)
sendTelegramPhoto(“sec”, “http://xxx/image/Cam201”, “”)
Thread::sleep(1000)
sendTelegramPhoto(“sec”, “http://xxx/image/Cam201”, “”)
Thread::sleep(1000)
sendTelegramPhoto(“sec”, “http://xxx/image/Cam201”, “”)
Thread::sleep(2000)
sendTelegramPhoto(“sec”, “http://xxx/image/Cam201”, “”)
if (MovementLightsOn == true) {
createTimer(now.plusSeconds(20), [| LS_FrontOutside.sendCommand(OFF)])
MovementLightsOn = false
logInfo(“home.rules”, "MovementLightOn After State: " + MovementLightsOn )
}
end
Make sure you define a Timer variable globally within the rules file and cancel that every time before (re)setting the timer, like so:
var Timer MovementTimer = null
rule “BI Motion FC”
when
Item BI_FC_Motion changed from OFF to ON
then
....
if (MovementLightsOn == true) {
MovementTimer?.cancel
MovementTimer = createTimer(now.plusSeconds(20), [| LS_FrontOutside.sendCommand(OFF)])
...
}
end
Next to that, you are potentially creating an issue with those Thread::sleeps, see here:
That’s actually a good place to use fire-and-forget anonymous timers (no handle variable needed to cancel/reschedule later)
createTimer(now.plusMillis(2500), [|
sendTelegramPhoto(“sec”, “http://xxx/image/Cam201”, “”)
])
createTimer(now.plusMillis(3500), [|
sendTelegramPhoto(“sec”, “http://xxx/image/Cam201”, “”)
])
// etc
// this will set up a set of timers for later
// and not sit waiting in the rule
The question mark means that it will not try to perform the cancel method if MovementTimer is not defined. More practically: when MovementTimer has never been set with createTimer, there is nothing to cancel, and then it can just skip that line. If it has been set, it cancels that timer.