Polling Devices to Avoid Silent Failure

I use HA and also have a SmartThings Hub with a range of zwave and zigbee sensors. The ST hub will report if a device indicates a low battery signal. But it does not seem to proactively poll devices or report when a device has failed to phone home for a set period of time (e.g., 1 hour or even 24).

Is there a way to tell HA to run through all the devices in my system at some interval and report any that fail to respond?

This is probably not a very scalable (or elegant) solution, but I have this automation set up to alert me every 3 hours if the temperature sensors in my freezers haven’t updated recently. It’s proven to be quite useful when batteries die unexpectedly (but also covers other failure cases as well, such as internet or SmartThings cloud outages).

- id: '1625968420204'
  alias: Alert - Freezer - Old Data
  description: ''
  trigger:
  - platform: time_pattern
    hours: /3
  condition:
  - condition: or
    conditions:
    - condition: template
      value_template: '{{ ( as_timestamp(now()) - as_timestamp(states.sensor.deep_freeze_temperature_measurement.last_changed)
        ) | int > 10800 }}'
    - condition: template
      value_template: '{{ ( as_timestamp(now()) - as_timestamp(states.sensor.kitchen_freezer_temperature_measurement.last_changed)
        ) | int > 10800 }}'
  action:
  - service: notify.mobile_app_pixel_3_xl
    data:
      message: Freezer Temps outdated!
      data:
        channel: Alerts
        group: Alerts
  mode: single
1 Like

Paste this template into the Template Editor. It will list all sensors whose states have not changed in the past hour (3600 seconds, change it to whatever duration you prefer).

{{ states.sensor 
   | selectattr('last_changed', 'lt', now()-timedelta(seconds=3600)) 
   | map(attribute='entity_id') | join(', ') }}

You can use that as a starting point to create a template that checks for ‘stale’ entities. If you want it to check sensors and binary_sensors, use expand().

{{ expand(states.sensor, states.binary_sensor)
   | selectattr('last_changed', 'lt', now()-timedelta(seconds=3600))
   | map(attribute='entity_id') | join(', ') }}

If you already have a group containing all of the entities you wish to check then the template changes to this:

{{ expand('group.check')
   | selectattr('last_changed', 'lt', now()-timedelta(seconds=3600)) 
   | map(attribute='entity_id') | join(', ') }}

You can implement the template in an automation that periodically checks the desired entities (much like iridris is doing).

- alias: Stale Entities
  trigger:
  - platform: time_pattern
    hours: '/4'
  action:
  - variables:
      stale: >
        {{ expand(states.sensor, states.binary_sensor)
           | selectattr('last_changed', 'lt', now()-timedelta(seconds=14400))
           | map(attribute='entity_id') | list }}
  - condition: template
    value_template: "{{ stale | count > 0 }}"
  - service: notify.persistent_notification
    data:
      title: 'Stale Entities Found'
      message: "{{ stale | join(', ') }}"

16 Likes

Hello, I am not good at yaml templating. May I please ask how this automation needs to be configured just for one particular sensor, not for all? Thanks very much, Jan