Rule Timer help!

Please take a closer look at your rule: :wink:

var Timer timer = null 

rule "Presence Wohnzimmer"
when
    Item alarm_multisensor_3 received update or
    Item sw_tv_wohnzimmer changed
then
    if (timer != null) {
        timer.cancel
        timer = null
    }
    Thread::sleep(10000)
    presence_wohnzimmer = 1
    timer = createTimer(now.plusMinutes(20)) [|
        presence_wohnzimmer = 0
    ]
end

The rule is triggered from item alarm_multisensor_3 (I guess it’s a motion sensor). If timer is not null, timer will be cancelled and set to null, after that, the thread will going to sleep, and after 10 seconds, presence_wohnzimmer will be set to 1. there is no condition not to set it to 1, and timer is created without any conditions, too. The only thing is, if motion is detected after 20 minutes, there will be (potentially) 1 minute darkness, because of switching off lights (through timer) and delayed switching on (next minute).

Hi Udo,

thanks for you reply. Yes, alarm_multisensor_3 is a motion sensor and yes, there are no conditions preventing presence_wohnzimmer from switching to 1, because that motion sensor (and switching tv on/off) are the only conditions for presence_wohnzimmer.

Yes, the rule should work as you described it, and yes, there may be a dark minute with bad timing, as you have to decide a timeout in every light automatic, else the light will stay on forever.

But all that is not the point, i had the lights turning off, although there was an event of alarm_multisensor_3 three minutes before that - and that should not have happened with theese rules, right?

Greets,
Stefan

Edit: Is there a possibility to see the timers remaining time?

Yes, this should not happen. have no idea beyond the point, that @rlkoshak made (timer name duplication through rule files).
Does this happen often?

Some logInfo would be helpful (at least for timer.cancel, createTimer and timer execution, just like that:

   if (timer != null) {
        timer.cancel
        timer = null
        logInfo("pres_wohn","timer cancelled!")
    }
    presence_wohnzimmer = 1
    logInfo("pres_wohn","timer created! Executes @ {}",now.plusMinutes(20))
    timer = createTimer(now.plusMinutes(20)) [|
        presence_wohnzimmer = 0
        logInfo("pres_wohn","timer executed!")
    ]

just to ensure, that every part is done well. You will find those logs in openhab.log. (I’m not sure if the time stamp in 2nd logInfo will be parsed correctly but this could be enforced)

i did that and directly found something that is not good :wink:

2016-10-16 12:27:43.444 [INFO ] [openhab.model.script.pres_wohn] - timer created! Executes @ 2016-10-16T12:47:43.442+02:00
2016-10-16 12:27:44.059 [INFO ] [openhab.model.script.pres_wohn] - timer created! Executes @ 2016-10-16T12:47:44.058+02:00
2016-10-16 12:27:44.276 [INFO ] [openhab.model.script.pres_wohn] - timer created! Executes @ 2016-10-16T12:47:44.275+02:00
2016-10-16 12:29:42.121 [INFO ] [openhab.model.script.pres_wohn] - timer cancelled!
2016-10-16 12:29:52.123 [INFO ] [openhab.model.script.pres_wohn] - timer created! Executes @ 2016-10-16T12:49:52.122+02:00
2016-10-16 12:30:52.742 [INFO ] [openhab.model.script.pres_wohn] - timer cancelled!
2016-10-16 12:31:02.744 [INFO ] [openhab.model.script.pres_wohn] - timer created! Executes @ 2016-10-16T12:51:02.743+02:00
2016-10-16 12:31:05.420 [INFO ] [openhab.model.script.pres_wohn] - timer cancelled!
2016-10-16 12:31:15.422 [INFO ] [openhab.model.script.pres_wohn] - timer created! Executes @ 2016-10-16T12:51:15.421+02:00
2016-10-16 12:33:02.276 [INFO ] [openhab.model.script.pres_wohn] - timer cancelled!
2016-10-16 12:33:12.277 [INFO ] [openhab.model.script.pres_wohn] - timer created! Executes @ 2016-10-16T12:53:12.277+02:00
2016-10-16 12:33:22.516 [INFO ] [openhab.model.script.pres_wohn] - timer cancelled!
2016-10-16 12:33:32.518 [INFO ] [openhab.model.script.pres_wohn] - timer created! Executes @ 2016-10-16T12:53:32.518+02:00
2016-10-16 12:34:33.279 [INFO ] [openhab.model.script.pres_wohn] - timer cancelled!
2016-10-16 12:34:43.281 [INFO ] [openhab.model.script.pres_wohn] - timer created! Executes @ 2016-10-16T12:54:43.280+02:00
2016-10-16 12:37:52.137 [INFO ] [openhab.model.script.pres_wohn] - timer cancelled!
2016-10-16 12:38:02.139 [INFO ] [openhab.model.script.pres_wohn] - timer created! Executes @ 2016-10-16T12:58:02.138+02:00
2016-10-16 12:39:02.817 [INFO ] [openhab.model.script.pres_wohn] - timer cancelled!
2016-10-16 12:39:12.818 [INFO ] [openhab.model.script.pres_wohn] - timer created! Executes @ 2016-10-16T12:59:12.818+02:00
2016-10-16 12:41:19.819 [INFO ] [openhab.model.script.pres_wohn] - timer cancelled!
2016-10-16 12:41:29.820 [INFO ] [openhab.model.script.pres_wohn] - timer created! Executes @ 2016-10-16T13:01:29.820+02:00
2016-10-16 12:43:12.357 [INFO ] [openhab.model.script.pres_wohn] - timer cancelled!
2016-10-16 12:43:22.358 [INFO ] [openhab.model.script.pres_wohn] - timer created! Executes @ 2016-10-16T13:03:22.357+02:00
2016-10-16 12:47:43.479 [INFO ] [openhab.model.script.pres_wohn] - timer executed!
2016-10-16 12:47:44.060 [INFO ] [openhab.model.script.pres_wohn] - timer executed!

So here is what it looks like… the motion sensor reported 3 times the movement at 12:27:

2016-10-16 12:27:33 - alarm_multisensor_3 state updated to 0
2016-10-16 12:27:34 - alarm_multisensor_3 state updated to 0
2016-10-16 12:27:34 - alarm_multisensor_3 state updated to 0

so three timer (with the same name) were created but only one was cancelled? So 20minutes later a get 2 executed timers and my presence_wohnzimmer would switch to off and so the lights could.

Shall i try:

if (timer == null) {
        logInfo("pres_wohn","timer created! Executes @ {}",now.plusMinutes(20))
        timer = createTimer(now.plusMinutes(20)) [|
            presence_wohnzimmer = 0
            logInfo("pres_wohn","timer executed!")
        ]
}

instead of:

logInfo("pres_wohn","timer created! Executes @ {}",now.plusMinutes(20))
timer = createTimer(now.plusMinutes(20)) [|
        presence_wohnzimmer = 0
        logInfo("pres_wohn","timer executed!")
]

or what are your suggestions?

Testing to see if the timer is null is how I usually deal with these situations. However, make the last line of your Timer body setting timer to null so once the timer goes off it gets reset and the next time the rule runs a new timer is created.

Okay, here is what i did:

rule "Presence Wohnzimmer"
when
    Item alarm_multisensor_3 received update or
    Item sw_tv_wohnzimmer changed
then
    if (timer != null) {
        timer.cancel()
        timer = null
        logInfo("pres_wohn","timer cancelled!")
    }
    Thread::sleep(10000)
    presence_wohnzimmer = 1
    if (timer == null) {
        logInfo("pres_wohn","timer created! Executes @ {}",now.plusMinutes(20))
        timer = createTimer(now.plusMinutes(20)) [|
            presence_wohnzimmer = 0
            timer = null
            logInfo("pres_wohn","timer executed!")
        ]
    }
end

Let’s see what we get! Thanks so far!