SmartHome How to create a recursive Timer in OpenHab3's DSL Rule

I wanted a DSL Script to send a notification email if a door was still opened after several checks.

There are various options to achieve this purpose.

A simple option could have been to use a Switch Item with an Expire Property. When the door opens, set that Switch Item to 'ON' and initialize a Number Item to be count how many checks will be done. When the Switch Item expires, execute a script which checks if the door is still opened. If it is not, that script ends. Otherwise, it increases the Item Number. If that Item Number is lower than the maximum checks to be done (your threshold), Set back the Switch Item to 'ON'. Otherwise, send the notification email.

Another option (just for fun) relies on a DSL Script with a lamdba expression which creates a Timer calling itself recursively until the door is closed or your threshold is reached. That DLS Script must be called when the Door opens.

Here after a Number Item SensorGarageDoor_Duration is used to count the number of checks: The Item SensorGarageDoor_OpenClose is the state of the Sensor on the Door.


val int treshold = 3
var int attempt = 0

// Define a Lambda Expression to check if the Door is open and if not, call itself after 15 minutes to check again until a treshold of calls is reached
val Functions$Function1 Monitor = [ Functions$Function1 recursive |
    if (SensorGarageDoor_OpenClose.state == OPEN) {
    logInfo("default.rules", "Monitor Opened Door")
    createTimerWithArgument(now.plusMinutes(15), recursive, [ Functions$Function1 callMonitor |
      var int duration = (SensorGarageDoor_Duration.state as Number).intValue+1
      SensorGarageDoor_Duration.sendCommand(duration)
      logInfo("default.rules", "Garage Opened since "+duration.toString+" cycle(s)")
      if (duration == treshold) {
          logInfo("default.rules", "Notify by email that Garage still Opened after "+duration.toString+" cycles")
          val mailActions = getActions("mail","your smtp binding")
          val success = mailActions.sendMail("your from", "your subject", "your message")
      } else if (duration < treshold) {
          callMonitor.apply(callMonitor)
      }
    ])
} else {
    logInfo("default.rules", "Stop monitoring Door")
}
true
] 

if (SensorGarageDoor_Duration.state != NULL) {
  attempt = (SensorGarageDoor_Duration.state as Number).intValue
} else {
  attempt = treshold
}

if (attempt < treshold) {
  logInfo("default.rules", "Request for monitoring Opened Door")
  SensorGarageDoor_Duration.sendCommand(0)
  Monitor.apply(Monitor)
} else {
  logInfo("default.rules", "New request for monitoring Opened Door ignored")  
}

One of the trick is to pass the Lambda Expression as parameter to the Timer (Created with createTimerWithArgument). Indeed, a Timer may not call a "Global" Lambda Expression. To get a Lambda Expression as parameter, this parameter must be defined as Functions$FunctionX (where X is the amount of parameters of the Lambda Expression). In my sample above, my Lambda as one parameter which is itself, to be passed to the Trigger (So, it is typed Functions$Function1).

You must type explicitly the parameters as Functions$Function1 to be able to use the method "apply()".

Raspberry Pi Xiamo Aqara and Openhab on Raspberry Pi

A few notes on using Xiaomi Aqara Sensors and Switches with Openhab 3.

Click to Read More

I am using a Zigbee USB key Conbee II from Dresen Eletronik.

It is plugged into the Raspberry Pi with a USB cable extension to put it away from the other keys used on this RPi, like my Sigma Z-Wave controller.

I am sing OpenHab 3 (previously OpenHab 2).

Opposite to the Sigma Z-Wave USB key, there is not mount issue after a reboot due to the usb port id increasing... (See also a solution in French).

I am using the Phoscon App to connect and manage devices via the Conbee II key. The App is accessible on the http port 80 of the Raspberry.

To connect a new Xiaomi Aqara device,

  1. "Add a Sensor" or a "Add a Switch" within Phoscon. Pick the type "Other".
  2. Press the reset button for 5 sec. The blue led should turn on and start blinking after 5 sec. Release the button immediately when it starts blinking. The led will then turn on for 2 or 3 sec and then blink 3 times. It means that the connection is established.
  3. A few second later, the device will appear in Phoscon.

To get the Things into Openhab, Add the Binding "Dresen Eletronik DeCONZ Binding" and "Scan" for devices.

I am using with success:

  • Multi Sensors : with values for Temperature, Humidity and Pressure
  • Door and Window Sensors: with Status Opened / Closed
  • A Cube : with events Pushed (various direction), Rotation, Shacked
  • Wireless Mini Switch : One Button Control with 4 events: Single Press, Double Press, Long Press and Long Press Release

 

Notice: 

  • after a few month using the Door Sensors on my Garage Door, it stopped to send events... The problem was that the captor part was attached on a metal upright which ended to be magnetized by the magnet part moving around...