Physical entities "lost in space"

My Smart Home has 30 shelly entities of Gen1 and 18 zigbee entities. Everything runs well, but sometimes a lamp is no longer controlled, a contact sensor doesn’t update or reported temperature is stable over hours.

Result of investigations:

  • zigbee entities are fast asleep
  • shelly entities lost wifi connection

My solution for zigbee2mqtt:

  • Configure “availabilty” in zigbee2mqtt. Now entities are shown “ONLINE” or “OFFLINE” in dashboard/entities.
  • mqtt-explorer shows additional path /availability with state ONLINE/OFFLINE.
  • Copying this path in the mqtt-explorer let define a channel “availability” for each zigbee thing.
  • Link this information to an item.
  • Put all these items in a son sematic group i.e. “availability” and create a rule notifying changes of availability.

My Solution for shellies:

  • Create “raw”-item switches availability for each shelly thing
  • Create a rule triggered by changes of shelly thing states. (state=“ONLINE” and statusInfo=“ONLINE” true, false otherwise). Associate thingID (event.thingUID.toString()) to the matching “raw”-item.
  • Unfortunately these items are frequently changed if entity is disconnected. A solution of this problem is described in the “debounce” design pattern.
  • openHAB has 2 implementations of this design pattern:
    debounce profile (install “basic profiles”) for channel triggered items
    debounce add on (install this add on) otherwise
  • As I have no channel triggered, I have installed “debounce add on” which lets you add special meta data to your “raw”-item and define a rule handling these items from a template. This template is a new option when creating a rule in the UI.
  • Follow the documention of the “add on” to define so called “raw”-items changed by item state and “debounced” items, showing the stable state.
  • As this mechanism is event driven all items are not initialized after creation.

This doesn’t fix network faults nor prevent zigbees to fall in sleep, but your are notified.

Assuming that zigbee2mqtt publishes something when the device comes online and doesn’t just publish when the device goes offline and, like many, you are using Generic MQTT Things, on the MQTT Thing, you can configure this topic and those messages for the LWT on the Thing and the Thing itself will go to OFFLINE when the device goes OFFLINE.

There is a widget on the marketplace to show status Items like this.

It will show those Items which are OFF which have one of the tags you choose when configuring the widget (e.g. “status”). It can be useful with this approach.

An alternative approach which might be less effort for some could be to use the Threshold Alert and Open Door rule template which is installed same as Debounce. Threshold Alert and Open Reminder [4.0.0.0;4.9.9.9]

This template does the debouncing for you and it lets you do stuff like setting a do not disturb period (who wants to be woken up because some thermometer has stopped reporting) and schedule reminders.

Create a Group and add at least one senor Item from the devices which report periodically.

Configure Expire on those Item so they go UNDEF when no update is received for an appropriate amount of time. This is how we detect when a sensor stops reporting.

I use the following settings for my sensor status alerting rule which reports when a sensor stops reporting for too long (if a property is not mentioned, I’ve left it as the default).

  • Triggering Group : the Group defined above
  • Threshold State: UnDefType // matches both NULL and UNDEF
  • Comparison Operator: ==
  • Invert Operator: true
  • Alert Delay PT15M. // five minutes
  • Reminder Period: PT12H // twelve hours
  • Reschedule: true
  • Alert Rule: [UID of rule that gets called when an Item remains in any state but NULL or UNDEF for 15 minutes] // this means the sensor is reporting
  • Initial Alert Rule: [UID of rule that gets called when an Item was previously alerted but is now UNDEF or NULL] // this means the sensor is no longer reporting
  • Do Not Disturb Start: 11:00 PM
  • Do Not Disturb End: 8:00 AM // I don’t need alerts when I’m sleeping, if it goes offline over night and remains offline I’ll get that alert at 8 the next morning

I add the status Items as a member of the semantic model Equipment and use that fact in my alerting rule. My alerting rule is as follows:

configuration: {}
triggers: []
conditions:
  - inputs: {}
    id: "2"
    configuration:
      type: application/javascript
      script: >
        var equipment = actions.Semantics.getEquipment(items[alertItem]);

        var statusItem = items[equipment.name+'_Status'];

        if(equipment === null || statusItem === null) {
          console.warn(alertItem + ' does not belong to an equipment or equipment doesn\'t have a Status Item!');
          false;
        }

        else {
          var statusItem = items[equipment.name+'_Status'];
          console.info('Sensor status reporting called for ' + alertItem + ', equipment ' + equipment.label + ', is alerting ' + isAlerting + ', and is initial alert ' + isInitialAlert 
                       + ', current equipment state is ' + statusItem.state);
          // Sensor is offline                         Sensor back online
          (isAlerting && statusItem.state != 'OFF') || (!isAlerting && statusItem.state != 'ON');
        }
    type: script.ScriptCondition
actions:
  - inputs: {}
    id: "1"
    configuration:
      type: application/javascript
      script: >
        var {alerting} = require('rlk_personal');

        var logger = log('Sensor Alert');

        var equipment = actions.Semantics.getEquipment(items[alertItem]);

        var statusItem = items[equipment.name+'_Status'];


        if(isAlerting && statusItem.state != 'OFF') {
          statusItem.postUpdate('OFF');
          alerting.sendAlert('Offline: ' + equipment.label + ' has stopped reporting', logger);
        }

        else if(!isAlerting && statusItem.state != 'ON') {
          statusItem.postUpdate('ON');
          alerting.sendAlert('Online: ' + equipment.label + ' is back', logger);
        }

        else {
          console.info('Sensor status update alerting ' + isAlerting + ' initial ' + isInitialAlert + ' equipment ' + equipment.label + ' status ' + statusItem.state);
        }
    type: script.ScriptAction

The above rule’s gets the parent Equipment in order to find the status Item for the equipment and skips the rule if one doesn’t exist. If the status Item exists it checks to see if the status Item’s state matches the new alerting state.

To make it easier to read the condition by itself is:

var equipment = actions.Semantics.getEquipment(items[alertItem]);
var statusItem = items[equipment.name+'_Status'];
if(equipment === null || statusItem === null) {
  console.warn(alertItem + ' does not belong to an equipment or equipment doesn\'t have a Status Item!');
  false;
}
else {
  var statusItem = items[equipment.name+'_Status'];
  console.info('Sensor status reporting called for ' + alertItem + ', equipment ' + equipment.label + ', is alerting ' + isAlerting + ', and is initial alert ' + isInitialAlert 
               + ', current equipment state is ' + statusItem.state);
  // Sensor is offline                         Sensor back online
  (isAlerting && statusItem.state != 'OFF') || (!isAlerting && statusItem.state != 'ON');
}

The action imports my alerting library and alerts that the sensor has gone offline or come back online and updates the status Item accordingly.

Now that OH notifications are more capable I need to rework this to cancel the alert instead of sending a new alert when it comes back online.

var {alerting} = require('rlk_personal');
var logger = log('Sensor Alert');
var equipment = actions.Semantics.getEquipment(items[alertItem]);
var statusItem = items[equipment.name+'_Status'];

if(isAlerting && statusItem.state != 'OFF') {
  statusItem.postUpdate('OFF');
  alerting.sendAlert('Offline: ' + equipment.label + ' has stopped reporting', logger);
}
else if(!isAlerting && statusItem.state != 'ON') {
  statusItem.postUpdate('ON');
  alerting.sendAlert('Online: ' + equipment.label + ' is back', logger);
}
else {
  console.info('Sensor status update alerting ' + isAlerting + ' initial ' + isInitialAlert + ' equipment ' + equipment.label + ' status ' + statusItem.state);
}

Oh, great :grinning: I didn’t know about, because it’s hidden. Configuration is similar to my channel availability. BTW: Currently zigbee2mqtt posts “availability” not “LWT”.

“LWT” is a technical term for MQTT. That stands for “last will and testament” and it usually represents a message sent to an LWT topic (which can be anything including “availability”) when the connected client stops responding to heartbeat messages. The LWT topic can be published too outside of that specific use case as well.

A well designed MQTT client would publish something to that topic when it comes online (with retained set to true) and register with the broker to publish something else to that topic (again with retained set to true). But that doesn’t stop the client (zigbee2mqtt in this case) from publishing online/offline messages in other situations too.

LWT is a concept, not the name of an actual topic. The “availability” topic is the LWT topic for that device. Or at least it can be used as such.

Thank you for the detailed informations. :grinning:

Great!

Offline Things Display is another option. But I’m missing debounce.

Lately I’m using Thing Status Reporting [4.0.0.0;4.9.9.9] to trigger a script, based on the ideas of Offline Things Display but enhanced by the ability to use [ Debounce [4.0.0.0;4.9.9.9]

The groupItem of Offline Things Display gets metadata “deboundUIDs”

 value: <name of Debounce group>
  config:
    <uid of debounced thing>: <timeout>
    <uid of debounced thing>: <timeout>
    ...
    state: ON,OFF
    command: false

All items are created on demand.
Thanks to the authors of the used add ons.