Rule with a grace period before running incase user changes mind?

I have a very simple rule that is triggered based on the “Armed” led of my alarm system as below…
I want it to turn the house ventilation to FULL when we arm the alarm meaning we have left the house.

Problem is that sometimes the young children can arm the alarm by mistake if they play with the remote and so it is quickly disarmed again by an adult…

How could I cater for this in a rule so that the actions in the rule will not run if the LED is set back to it’s previous state within 15 seconds or something like that? At the moment the entire rule fires twice…

I’m thinking of some sort of logic like like comparing the LED’s state with what it was 15 seconds ago and only then if it’s changed run the rule… Could something like that be possible?

Rule "Actions based on DSC Alarm"
when
    Item KEYPAD_ARMED_LED received update
then
    if (KEYPAD_ARMED_LED.state == 1) {
        // Turn ventilation fan to HIGH
	LNR801a.sendCommand(ON)
        LNR801e.sendCommand(OFF)
        LNR801h.sendCommand(OFF)
    }

    if (KEYPAD_ARMED_LED.state == 0) {
        // Turn ventilation fan to LOW
	LNR801a.sendCommand(OFF)
        LNR801e.sendCommand(OFF)
        LNR801h.sendCommand(ON)
    }
end

I found this in the rules samples using a “timer” but I suspect that this will still result in the action being run when the adult disarms the alarm again…

import org.openhab.model.script.actions.Timer
    var Timer timer
    
    rule "do something if item state is 0 for more than 10 seconds"
    when
    	Item MyItem changed
    then
    	if(MyItem.state==0) {
    		timer = createTimer(now.plusSeconds(10)) [|
    			// do something! 
    		]
    	} else {
    		if(timer!=null) {
    			timer.cancel
    			timer = null
    		}
    	}
    end

Why? The rule starts a timer if some item changes to X. If the item changes to anything else, it cancels the timer (if running)

You don’t need the import in OH2, careful with old postings.

Thanks for the reply!
I think that when the LED status is set back to 0 the rule will do the action because it’s changed to 0 and stays there for long enough for the timer to fire…

If it’s change from 0 to 1 and then back to 0 again within 15 seconds I don’t want anything to happen.

The code within the timer brackets is run only if the scheduled time hast come up AND if the timer isn’t canceled.

The timer is not a delay, don’t interpret it that way.

It’s a scheduler - “perform this task in 15 seconds time”.
Having set up this schedule, the rule carries on and exits.

If you cancel the schedule before the due time, the task is not done.

I still don’t see how it will work…

  • Alarm is current disabled
  • Someone enables the alarm by mistake… The timer is set for 15 seconds…
  • After 5 seconds someone disables the alarm again which cancels the timer but sets a new timer for 15 seconds.
  • After the 15 seconds the timer has been met and so the actions for “disarming” the alarm are run…

Ideally in this situation I’d like no actions to run at all…

Maybe I’m still not understanding it?

That’s not correct, the example you posted would work as follows:

  • Somebody arms the alarm by mistake, a timer is started and will execute the actions in its brackets after 15 seconds
  • Before the 15 seconds are up, somebody disarms the alarm
  • The rule fires a second time, but this time it won’t create a timer with actions, it will go to the else statement, check if there is a timer set and then cancel it (timer.cancel)
  • No actions are performed after this
3 Likes