Notification of offline devices... changing from ZHA Toolkit

I used to use ZHA Toolkit to alert me when any of my ZHA devices went offline. This has worked fine, until a more recent HA release broke ZHA Toolkit, and its been playing catchup ever since.

So I thought I would investigate another way of doing this, which turns out to be pretty straight forward.

As a pre-requisite, you will need to enable the hidden LQI attribute of your zigbee devices that you want monitored.

Then simply use the script below. I’ve set mine on an hour timer, but you could trigger it how ever you want:

alias: ZHA and Wifi Offline Devices Check
description: ""
trigger:
  - platform: time_pattern
    hours: /1
condition:
  - condition: template
    value_template: >-
      {{ states.sensor | selectattr('state', 'in', ['unavailable', 'none']) |
      selectattr('entity_id', 'search', 'lqi') | rejectattr('name', 'search',
      'Tradfri Switch')  | list | count >0}}
action:
  - action: notify.mobile_app_YOUR_PHONE_HERE
    data:
      title: Devices Offline
      message: >-
        {{ states.sensor | selectattr('state', 'in', ['unavailable', 'none']) |
        selectattr('entity_id', 'search', 'lqi') | rejectattr('name', 'search',
        'Tradfri Switch') | map(attribute='name') | list | join(', ')}}
mode: single

The condition check simply counts the number of devices in the offline state. I’ve also added an additional check:

rejectattr('name', 'search',
      'Tradfri Switch')

to ignore any entities which have names including the words ‘Tradfri Switch’. This is because some of my devices present themselves as offline (when they are not, they are working fine) and I want to ignore these.

I reallt like your solution. I also differentiate between unknown vs unavailable (offline). I have four booleans (true if any unknown/unavailable, false otherwise) that are helpful for monitoring same (as well as a dashboard that shows only devices that are unavailable or unknown - the cards are hidden for items not unavailable or unknown) - so it’s handy to check that dashboard from time to time:

For Yolink and Shelly for instance:

#
# This binary sensor not only specifies if any entities in the integration are unavailable, but also if
# there are any unavailable, it will contain an attribute that is a list of the entities that are unavailable.
#
  - binary_sensor:
      - name: "Any Yolink Unavailable"
        state: "{{ integration_entities('yolink') | select('is_state', 'unavailable') | list | count > 0 }}"
        attributes:
          entity_id: "{{ integration_entities('yolink') | select('is_state', 'unavailable') | list }}"
        unique_id: any_yolink_unavailable

#
# This binary sensor not only specifies if any entities in the integration are known, but also if
# there are any unknown, it will contain an attribute that is a list of the entities that are unknown.
#
  - binary_sensor:
      - name: "Any Yolink Unknown"
        state: "{{ integration_entities('yolink') | select('is_state', 'unknown') | list | count > 0 }}"
        attributes:
          entity_id: "{{ integration_entities('yolink') | select('is_state', 'unknown') | list }}"
        unique_id: any_yolink_unknown
#
# This binary sensor not only specifies if any entities in the integration are unavailable, but also if
# there are any unavailable, it will contain an attribute that is a list of the entities that are unavailable.
#
  - binary_sensor:
      - name: "Any Shelly Unavailable"
        state: "{{ integration_entities('shelly') | select('is_state', 'unavailable') | list | count > 0 }}"
        attributes:
          entity_id: "{{ integration_entities('shelly') | select('is_state', 'unavailable') | list }}"
        unique_id: any_shelly_unavailable

#
# This binary sensor not only specifies if any entities in the integration are known, but also if
# there are any unknown, it will contain an attribute that is a list of the entities that are unknown.
#
  - binary_sensor:
      - name: "Any Shelly Unknown"
        state: "{{ integration_entities('shelly') | select('is_state', 'unknown') | list | count > 0 }}"
        attributes:
          entity_id: "{{ integration_entities('shelly') | select('is_state', 'unknown') | list }}"
        unique_id: any_shelly_unknown