Presence rule with reed switch state & time

I use the following Rule. Note this is made generic for all my doors.

rule "Keep track of the last time a door was opened or closed"
when
  Member of gDoorSensors changed
then
  if(previousState == NULL) return;

  val name = triggeringItem.name
  val state = triggeringItem.state

  // Update the time stamp
  postUpdate(name+"_LastUpdate", now.toString)

  // Set the timer if the door is open, cancel if it is closed
  if(state == OPEN) sendCommand(name+"_Timer", "ON")
  else postUpdate(name+"_Timer", "OFF")

  // Set the message
  val msg = new StringBuilder
  msg.append(transform("MAP", "en.map", name) + " was ")
  msg.append(if(state == OPEN) "opened" else "closed")

  var alert = false
  if(vTimeOfDay.state.toString == "NIGHT" || vTimeOfDay.state.toString == "BED") {
    msg.append(" and it is night")
    alert = true
  }
  if(vPresent.state == OFF) {
    msg.append(" and no one is home")
    alert = true
  }
  msg.append("!")

  // Alert if necessary
  if(alert){
    aAlert.sendCommand(msg.toString)
  }
  // Log the message if we didn't alert
  else {
    logInfo(logName, msg.toString)
  }
end

rule "Timer expired for a door"
when
  Member of gDoorsTimers received command OFF
then
  val doorName = transform("MAP", "en.map", triggeringItem.name)

  aAlert.sendCommand(doorName + " has been open for over an hour")

  if(vTimeOfDay.state.toString == "NIGHT" || vTimeOfDay.state.toString == "BED") {
        triggeringItem.sendCommand(ON) // reschedule the timer
  }
end

See [Deprecated] Design Pattern: Time Of Day (vTimeOfDay), Generic Presence Detection (naming scheme of Items so I can update and command related Items based on triggeringItem.name), Design Pattern: Separation of Behaviors (centralized alerting), Design Pattern: Human Readable Names in Messages (converting Item names to more human friendly names for use in alerts and logs) and Design Pattern: Expire Binding Based Timers (door open timers). These tow Rules are a great example showing how DPs are not intended to be used in isolation.

All of my doors are a member of gDoorSensors. Any time one of them changes the first Rule triggers.

First I update a DateTime Item to record when the door opened/closed.

If the door opened I start a Timer. If the door closed I cancel the Timer.

Finally, I generate a message to log and potentially alert. I will generate an alert immediately if it is night or bed time or no one is home.

The second Rule triggers when a door Timer expires and generates an alert. If it is night or bed time I reschedule the timer.

The one thing the Rules above don’t show is how to handle OH restarts. All of my door sensors are DIY and will respond with the door’s current state when I send a certain message. So I have a System started Rule that publishes that message which causes the sensors to publish their current states and if those states differ from what was restoreOnStartup the Rules above run.

Remember, Rules are event triggered, not state triggered. When you set up a cron trigger, you are scheduling events based on time. So if you do something like

0 0 20-23,0-6 ? * * * // I don't know if this is correct but the intent is to be between 20:00 and 06:100:

what you are doing is scheduling an event to occur at 20:00, 21:00, 22:00 and so on.

2 Likes