[SOLVED] Alarm contacts, one with delay (to have time to switch off the alarm)

Hello,
I have three door contacts, for two contacts the alarm should begin immediately when the contact is going to “open”, for one contact there should be a delay from 5s so I can switch off the alarm button (before alarm-action was executed) (disarm).

Can this be done with “expire” option I found in oH (for switches) ?

Actuall the alarm-rule is this:

rule "AlarmAction"
when Item DoorTerrace changed from CLOSED to OPEN or Item DoorLivingroom changed from CLOSED to OPEN or Item DoorMain changed from CLOSED to OPEN
then
    if( AlarmCtrlLED.state == OFF )   // LED off=Alarm activated!
    { // ALARM-action ...

The DoorMain should get the delay from 5 seconds.

Yes it can and some would even say it’s the best way to do it. Check the documentation for examples and if you hit a snag were here to help.:wink:

Just trying, but unclear where to add the expire option.

Can it be “local” in the alarm-rule, or must it be in the (my) contact.items (were the contacts are defined) ?

And: When in contact.items -part, the delay is global, also for usage I always have a delay ?

I try this :wink:
… to OPEN or Item DoorMain (expire=“10s,state=OPEN”) changed from …

It’s in the item’s file and used so you don’t have to create a timer in your rule.

Yes, the expire time will be the same each time you use the item. You can have multiple items that use the binding.

Contact DoorMain "Your door contact" (expire=“10s,state=OPEN”)

Hi,
I use contacts, connected on the GPIO4 from the Raspberry.

So I add it here on this way, syntax seems fine. But the alarm is coming immediately, no delay !?

Contact DoorMain
  "Wohnzimmer Tür [%s]"
  <door>
  (GF_Livingroom, GF_Diningroom)
  { gpio="pin:4 debounce:500 activelow:no", expire="6s,state=OPEN" } 

Try removing the groups and see if that helps and make sure there is no rule that’s causing the alarm.

You should also be able to see whats occurring by watching the front tail log.

EDIT: Also make sure you have installed the expire binding via PaperUI.:wink:

1 Like

OK, expire-binding was not installed, thougt this was a build-in option, becasue also no error when using expire …

Delay seems now to work, thanks!

But how can I solve the problem, if I want / need to use this GPIO-Contact also without an delay?
I.e. to send signal to camera to make NOW a picture.

I try to duplicate the usage from GPIO 4 in the contact.items, but than the (correct) error “The pin with number ‘4’ is already registered” appaer.

You can’t do both with the same item using expire so you’ll need to use a rule or two contacts.

OK, if this a fact, I must see.
If anyone have an idea here, …

Thx to H102 !!

@Topsurfer Here’s a rule example to get you started.

var Timer stopMotionTimer = null
rule "Alarm"
when
    Item DoorMain changed from CLOSED to OPEN  // using this trigger you shouldn't need to check the DoorMain.state in the if statment
then
    if(stopMotionTimer === null && DoorMain.state == OPEN){  
        Camera_Item.sendCommand(ON)   // Take a picture when door is opened
            stopMotionTimer = createTimer(now.plusSeconds(6)) [|   // Create timer for 6 sec
                Alarm_item.sendCommand(ON)   // Sound alert or turn on light
                stopMotionTimer = null
            ]
    }
end

Create a few more proxy items.

Create an Switch Alarm_item to sound the horn or turn on a light 6 seconds after the door opens. The Switch Camera_Item can be used to take the picture as soon as the door is open.

You can also change the trigger if you like but you will then need to check the DoorMain.state otherwise everytime the door opens or closes the rule will run.

when
    Item DoorMain received update
then
    if(stopMotionTimer === null && DoorMain.state == OPEN){  // this part required if using received update as trigger
1 Like

Till now I have not test your last code, because I run in problems with the “solution” I thought it works …

After closing the door (at 17:56:17), the door is shown as “open” again and new alarm is generated immediatly !?!?
Is there a need from an “update” function?
I don’t now what happens, without the "expire -part the alarm is working as exepected (one door open => alarm)

2018-12-28 17:54:16.366 [vent.ItemStateChangedEvent] - DoorLivingroom changed from CLOSED to OPEN

==> /var/log/openhab2/openhab.log <==

2018-12-28 17:54:16.384 [INFO ] [e.smarthome.model.script.alarm.rules] - !!! ALARM !!! Wohnzimmer: OPEN; Terrassentür: CLOSED; Haustür: CLOSED

==> /var/log/openhab2/events.log <==

2018-12-28 17:56:17.102 [vent.ItemStateChangedEvent] - DoorLivingroom changed from OPEN to CLOSED

2018-12-28 17:56:25.387 [vent.ItemStateChangedEvent] - DoorLivingroom changed from CLOSED to OPEN

==> /var/log/openhab2/openhab.log <==

2018-12-28 17:56:25.403 [INFO ] [e.smarthome.model.script.alarm.rules] - !!! ALARM !!! Wohnzimmer: OPEN; Terrassentür: CLOSED; Haustür: CLOSED

For me still unclear what exactly the >" { gpio=“pin:4 debounce:500 activelow:no”, expire=“8s,state=OPEN” } " will do in the contact.items.
Will only delay a “OPEN” event with 8s, and “CLOSE” or initial will work as without an “expire …” -part?

Maybe the “problem” is, that the doorcontacts are not push-buttons?

Try removing the debounce:500 and see what happens.

Personally I would not use expire.

Contact RealDoor "description"  {real binding}
Contact DelayedDoor "description" 

DelayedDoor is the one to put in your “alarm” rules/group

// put this before any rules in file
// defines a global variable that rules can share
var Timer doorTimer = null

rule "start door delay"
when
   Item RealDoor changed to OPEN
then
   if (doorTimer == null) {
      // if no timer running yet
      // set up a timer for the future
      doorTimer = createTimer(now.plusSeconds(10) [ |
         // code to done in the future
         DelayedDoor.postUpdate(OPEN)
         doorTimer = null
      ] )
   }  // else if timer already running, let it run
end

rule "door closing"
when
   Item RealDoor changed to CLOSED
then
   if (doorTimer === null) {
      // timer is not running, mirror closing immediately
      DelayedDoor.postUpdate(CLOSED)
   } else {
      // timer is running,so - 
      // do NOT stop alarm happening just because door was closed quickly
      // but - we do want to mirror door closing later on
      // this anonymous timer will do that
      createTimer(now.plusSeconds(10) [ |
         if (RealDoor.state == CLOSED) {
            // if its still closed
            DelayedDoor.postUpdate(CLOSED)
         }
      ] )
   }

You’re going to need some other means to get out before alarm sets, a longer than 20 secs delay to arm it.

1 Like

Remove the expire part from the item and use the rule as it has the 6 seconds delay you were wanting. Add the extra items for the alarm and camera then test to see if it works as expected.

@rossko57
Try to understand your code, but where is the place to put the immediately action (camera picture) from the delayed door and where to put the action if timer reach the 10s (switch light and siren on) ?

@H102
Must test your code when finding time … and the code should work? :wink:

Actuall I think will be the best (and easiest form me) to create two different rules,
one for the simple alarm (with direct alarm, no delay: Door open=ALARM)
The other one with one contact and delay
Must be “only” ensure that both rules will not influence

Thanks to all!!

I don’t know what that means. I’ve shown a rule that runs when the real door is opened. Perhaps that’s a good place to do it, if you want it “immediate”.
The same also creates a timer that does something 10 seconds later. Perhaps that’s a good place to put it, if you want it “delayed”.

That’s your existing rule that gets triggered from this door or that door or this window or that window etc.
You want to change that existing rule so it it gets triggered by DelayedDoor and not by the real door.

So, fighting …

Trying the code from you (rossko57), think I understand little more now …

The DelayedDoor is a “virtuell” door, so I have created a new item (switch) for this (not to use /press, only to use this status later in an extra rule).
For testing purpose I use instead the (phys.) real-door contact a switch (“Switch_TV_Simulation”).

I change the OPEN/CLOSED to ON/OFF because these seems my TV-switch is sending (I see in log)
But when TV-switch send “ON” I get in this error in the log:

“[ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule ‘start door delay’: An error occurred during the script execution: index=1, size=1”

I don’t know what the error caused? Is it a bad postUpdate. ?

Here is the code (I add the “end” on the rule, I think you forget this):

var Timer doorTimer = null

rule "start door delay"
when
   Item Switch_TV_Simulation changed to ON
then
   if (doorTimer == null) {
      // logInfo("alarm.rules", "XXX 111 Door delay; Status Switch_TV_Simulation: {}",Switch_TV_Simulation.state )
      // if no timer running yet
      // set up a timer for the future
      doorTimer = createTimer(now.plusSeconds(3) [ |
         // code to done in the future
         logInfo("alarm.rules", "XXX 333 Door delay; Status Switch_TV_Simulation: {}",Switch_TV_Simulation.state )
         DelayedDoor.postUpdate(ON)
         doorTimer = null
      ] )
   }  // else if timer already running, let it run
end

rule "door closing"
when
   Item Switch_TV_Simulation changed to ON
then
   if (doorTimer === null)
   {
      // timer is not running, mirror closing immediately
      DelayedDoor.postUpdate(OFF)
      logInfo("alarm.rules", "XXX 555 Door delay; Status DelayedDoor: {}",DelayedDoor.state )
   }
   else
   {
      logInfo("alarm.rules", "XXX 777 Door delay; Status DelayedDoor: {}",DelayedDoor.state )   // timer is running,so - 
      // do NOT stop alarm happening just because door was closed quickly
      // but - we do want to mirror door closing later on
      // this anonymous timer will do that
      createTimer(now.plusSeconds(3) [ |
         if (Switch_TV_Simulation.state == ON) {
            // if its still closed
            logInfo("alarm.rules", "XXX 999 Door delay; Status DelayedDoor: {}",DelayedDoor.state )
            DelayedDoor.postUpdate(OFF)
         }
      ] )
   }
end

Well spotted.
I messed up the createTimer brackets as well; change both occurrences to this general form

createTimer(now.plusSeconds(nn)) [ |
       lots of code
   ]
1 Like

This was the problem, now the rule seems to work; I can use the “delayedDoor” as regular door in my alarm-rule (when this (virtual) door opens, alarm will executed …)

Thx ,also to H102 !

Check the “edge cases” as well, make sure the alarm still goes off if you open and close the door quickly. That part is harder to get right.