Inactivity of items // no updates // automatically tracking

Guys,
I’m having quite a complex setup with OH2, some RasPis with self written java programs that send sensor values through MQTT etc. I was wondering what the best way would be to check if a “datasource” is still active and delivers sensor values. My first idea was to update a timestamp as often as a new value comes in and check manually in the UI. But that is “manual” so :point_down:
What would be cool if an item could have something like a “listener” with a configured timeout. And if that timeout is reached do somehting, e.g. send an eMail that something is wrong.
I could also think of a rule for each item that should be supervised. Create a timer within that rule that fires an action. But if you have many items that would be a huge amount of rules and timers.(causes OH2 to slow down?)
I was also thinking of a new “timeout”-binding. The possible actions could be configured in the .cfg and timeout and action can be added to the item config, e.g.
timeout.cfg:
mail.to=my@email
mail.from=OH@email
items.:

Number Humidity_Room_Parents	"Luftfeuchtigkeit [%.1f %%]"	<humidity> (room_Parents, climate) {homematic="address=JEQXXXX457, channel=1, parameter=HUMIDITY", timeout="timeout=60, action=mail}

Any other ideas? How do you track automatically that a datasource is still there?

Thanks,
Michael

Expire binding (your timeout binding already exists). Since you are using MQTT it is pretty simple. Create an “online” Item for each device. Configure your remote sensors with a LWT. Then you can use an Item definition like the following (from my setup):

Switch vHydra_SensorReporter_Online "Hydra sensorReporter [MAP(admin.map):%s]"
    <network> (gSensorStatus, gResetExpire)
    { mqtt="<[mosquitto:status/sensor-reporters:command:OFF:.*hydra sensorReporter is dead.*],<[mosquitto:status/hydra/heartbeat/string:command:ON]", expire="10m,command=OFF" }

You will see several important parts.

  1. <[mosquitto:status/sensor-reporters:command:OFF:.*hydra sensorReporter is dead.*]: This will send an OFF command to vHydra_SensorReporter_Online when the LWT message is sent by the broker indicating the sensor went offline. The last part of the binding is a regular expression that matches against the specific LWT message from this host/sensor. I publish all the LWT messages to the same topic and match on the message to determine which device went offline.

  2. <[mosquitto:status/hydra/heartbeat/string:command:ON]: This will send an ON command to vHydra_SensorReporter_Online when ANY message is received on that topic. I have a heartbeat topic but you can subscribe to the same topic that you publish the sensor readings to. The contents of the message do not matter.

  3. expire="10m,command=OFF": Ten minutes after the last time vHydra_SensorReporter_Online gets commanded or updated to ON, the expire binding will sendCommand(OFF) to vHydra_SensorReporter_Online.

  4. gResetExpire: I add the Item to this Group because when OH restarts I want to reset the Expire timers so I can catch those Items that died while OH was down. The rule I have is:

rule "Reset Expire binding at startup"
when
  System started
then
  logInfo("Startup", "Restarting Expire binding Timers")
  gResetExpire.members.forEach[ i | i.postUpdate(i.state)]
end

Note that I use restoreOnStartup on these Items. The above updates the Expire binding Items with whatever their state was that was restored from persistence which will cause the Expire binding to start running again for those that were not OFF when OH went down.

  1. gSensorStatus: I added the Item(s) to this Group so I can centralize my alerting logic (you never have to write a separate Rule for every Item). This is the “something like a “listener”” part of your problem. I have the following Rule to alert me when a sensor goes offline or comes back online (note this uses Design Pattern: Associated Items, Design Pattern: Human Readable Names in Messages, and Design Pattern: Separation of Behaviors).
rule "A sensor changed its online state"
when
    // Member of gSensorStatus changed
    Item  vHydra_SensorReporter_Online changed or
    ... // list all the members of gSensorStatus as individual triggers until running on 2.3 then switch to use the Member of trigger
then
  if(previousState == NULL) return; // we don't care about changes from NULL

  val alerted = gOfflineAlerted.members.findFirst[ a | a.name == triggeringItem.name+"_Alerted"] as SwitchItem
  if(alerted === null) {
          logError("admin", "Cannot find Item " + triggeringItem.name+"_Alerted")
          aInfo.sendCommand(triggeringItem.name + " doesn't have an alerted flag, it is now " + transform("MAP", "admin.map", triggeringItem.state.toString) + "!")
          return;
  }

  if(alerted.state == triggeringItem.state && timers.get(triggeringItem.name) === null) {
          val currState = triggeringItem.state
          timers.put(triggeringItem.name, createTimer(now.plusSeconds(15), [ |
              if(triggeringItem.state == currState) {
                          var name = transform("MAP", "admin.map", triggeringItem.name)
                          if(name == "") name = triggeringItem.name
                          aInfo.sendCommand(name + " is now " + transform("MAP", "admin.map", triggeringItem.state.toString) + "!")
                          alerted.postUpdate(if(triggeringItem.state == ON) OFF else ON)
                  }
                  timers.put(triggeringItem.name, null)
          ]))
  }
end

The above rule triggers whenever any member of gSensorStatus changes state. It grabs an associated Alerted Item to determine whether the change has been reported in the past (i.e. the sensor is flapping between online and offline). Then it sets a 15 second timer before alerting and only sends the alert if after 15 seconds the Item is still in the changed state so we don’t get barraged by alerts if the sensor is flapping. This is an example of one way to handle reporting when a device goes online or offline. You can do your own.

The above works very well with MQTT and devices that report online/offline (e.g. Network Binding). However, if you have other devices that do not I’ve written up a design pattern for how to handle it in a more generic fashion: Design Patterns: Generic Is Alive which needs some more Rules logic to populate the Online Items for devices that periodically report a reading but do not have an online status you can get at directly. Note that I wrote this a long time ago and it needs a rewrite to take advantage of triggeringItem and other new features of OH.

2 Likes

Thanks. That seems exactly what I’ve been looking for.