Getting Notified About Stale Sensors in Home Assistant

Quick one to share a little useful automation.

I have a ton of ZigBee devices spread around the house, several of which are temperature and humidity sensors, and I make use of these sensors in Home Assistant to calculate the average temperature in the house, which is then fed into a DIYLESS OpenTherm Thermostat 3 via MQTT to control the heating. So in summary, it's pretty important to make sure these sensors are always working, specially during winter.

While my ZigBee network is rock solid, there are always happy little surprises when it comes to battery-powered wireless devices. For instance, I have an automation that notifies me about devices that are low on battery, but there is a very annoying case where some devices will report battery level just above the threshold for the notification, then suddenly die because that value was inaccurate. And since they are dead, Z2M never receives any updates, and continues to display the previous values indefinitely (for both battery and temperature/humidity). The result is a temperature sensor in HA stuck on the same value since the sensor went down.

To work around that, I created an automation that instead checks the last_updated timestamp all my sensors matching some specific keywords, and notifies me in case they have not been updated in the last 6 hours (which is almost impossible if everything is working as intended):

alias: Alert about stale temperature sensors
description: ''
triggers:
  - trigger: time
    at: '10:00:00'
conditions:
  - condition: template
    value_template: >-
      {% set ns = namespace(affected=[]) %}

      {% for sensor_id in (states.sensor | selectattr('entity_id', 'match',
      '.*temperature*') | selectattr('entity_id', 'match', '.*thermometer.*') |
      map(attribute='entity_id') | list) %}
        {% if (now() - states[sensor_id].last_updated >= timedelta(minutes=360)) %}
          {% set ns.affected = ns.affected + [sensor_id] %}
        {% endif %}
      {% endfor %}

      {{ (ns.affected | length) > 0 }}
actions:
  - action: notify.send_message
    metadata: {}
    target:
      entity_id: notify.my_mobile_phone
    data:
      message: >-
        The following sensors have not updated in the last six hours. Check
        their batteries:


        {% set ns = namespace(affected=[]) %}

        {% for sensor_id in (states.sensor | selectattr('entity_id', 'match',
        '.*temperature*') | selectattr('entity_id', 'match', '.*thermometer.*')
        | map(attribute='entity_id') | list) %}
            {% if (now() - states[sensor_id].last_updated >= timedelta(minutes=360)) %}
              {% set ns.affected = ns.affected + [sensor_id] %}
            {% endif %}
        {% endfor %}


        {% for sensor_id in ns.affected %}
          • {{ entity_name(sensor_id) }}
        {% endfor %}
      title: Stale Sensors
mode: single

The result is a little notification like this every day at 10 AM if a sensor is stuck:

A Home Assistant notification on Android with the text: "Stale Sensors - The following sensors have not updated in the last six hours. Check their batteries: Office Temperature, Living Room Temperature, Bedroom Temperature".
antsu

antsu

Some dude who likes computers
UK