Managing Offline Devices in Zigbee2MQTT
Zigbee is great, and it’s my favourite Smart Home Protocol… until one of my devices stops working.
In the past, I wouldn’t even know that the device was offline until it stopped working, meaning I’d have to turn on the lights manually with a switch using my hands, like some sort of caveman. It was very frustrating.
There are many reasons why a Zigbee device might go offline, perhaps the battery in it has discharged, or perhaps the device has dropped off the Zigbee network and needs to be re-paired. There are several steps you can take to improve your Zigbee network reliability, but despite all your best intentions, there will still be a day when a device disappears from the network.
My goal was to get notified when a device went offline so I could tend to it before it became a frustrating problem.
Enabling Device Availability in Zigbee2MQTT
The first step was to turn on Device Availability in Zigbee2MQTT. When this is enabled it will report on when a device was last seen and it works differently for active and passive devices.
Active devices (routers or mains powered end devices): by default they have to check-in every 10 minutes. If they don't, they will be pinged, if that fails the device will be marked as
offline
.Passive devices (everything that is not an active device, mostly battery powered devices): these devices need to check-in every 25 hours, they cannot be pinged so if they don't they will be marked as
offline
.
You will then see the devices marked as Online or Offline in the Availability column in the Zigbee2MQTT devices list, as well as when they were Last Seen.
You can turn this on by either editing the Zigbee2MQTT configuration file, or in the User Interface under Settings and Availability.
I also set the Last Seen timestamp type to ISO_8601 in the Settings -> Advanced area of Zigbee2MQTT.
I have over 100 Zigbee devices in my network, so I changed the Timeout value for Active devices to 30 minutes, and it’s been working well for me. This prevents each device from getting pinged every 10 minutes, which is the default, and does it every half an hour instead. This reduces the load on my Zigbee network, leaving the bandwidth free for more useful data.
You’ll now be able to use the Zigbee2MQTT user interface to tell when devices were last seen by Zigbee2MQTT, and if it deems them to be Online or Offline.
Send a notification when a device is offline
Whilst seeing if a device’s Online or Offline state inside Zigbee2MQTT is useful, I’m hardly going to log into that user interface every day to check what’s online and what isn’t. My house normally goes weeks or months without a device going offline, so I wanted Home Assistant to tell me when something needed my attention.
This Last Seen value is actually brought over from Zigbee2MQTT into Home Assistant, but it’s part of a diagnostic entity that is disabled by default. To make use of it you need to enable it.
You can either manually go into each device you want to monitor, click on the disabled Last seen entity, and enable it. Or you can have Zigbee2MQTT automatically enable this attribute for every Zigbee device - which is what I have done.
To do this you need to add the following parts to your Zigbee2MQTT configuration.yaml file.
device_options:
homeassistant:
last_seen:
enabled_by_default: true
You’ll then probably need to restart Zigbee2MQTT to make it take effect, and you should soon see the last seen attribute populated for each of your Zigbee devices.
Using a Blueprint to notify you of offline Zigbee devices
A smart person called Mr_Groch has created a Home Assistant Blueprint that you can use to easily create an automation which runs at a certain time each day and sends your mobile phone a push notification with any offline Zigbee devices.
Once you add the Blueprint to your Home Assistant you can create an automation with it that runs at a specific time and notifies you of any devices that need help.
In this example you can see how it’s configured to run at 8pm every day, and send a notification to my Home Assistant app on my Pixel 6 phone. I’ve also excluded a couple of devices from this, because I often turn them off at the switch when I’m not in the room so I’m OK with them being offline.
Using a Template Sensor to be immediately notified when a device is offline
The Blueprint is great, and makes it really easy to set up these notifications, but not being notified that a device is offline until a specific time each day wasn’t cutting it for me. A device could be offline for 10 hours or more before I knew about it, and that might cause problems in my smart home. I wanted a way to be notified immediately when a device went offline so I could choose whether or not to fix it right then or wait until later.
I hacked apart Mr_Groch’s blueprint and created a Template Sensor using their code as a starting point which shows all the devices that are currently offline.
To create a template sensor go to Home Assistants settings page, and Helpers. Create a Helper, which is a Template sensor. Give it a name and paste this code into the state template area:
{% set result = namespace(sensors=[]) %}
{% for state in states.sensor | rejectattr('attributes.device_class', 'undefined') | selectattr('attributes.device_class', '==', 'timestamp') %}
{% if 'last_seen' in state.entity_id and (states(state.entity_id) == 'unavailable' or ((as_timestamp(now()) - as_timestamp(states(state.entity_id))) > ((24 | int) * 60 * 60))) %}
{% set result.sensors = result.sensors + [state.name | regex_replace(find=' last seen', replace='') ~ ' (' ~ relative_time(strptime(states(state.entity_id), '%Y-%m-%dT%H:%M:%S%z', 'unavailable')) ~ ')'] %}
{% endif %}
{% endfor %}
{{ result.sensors | join('\n') | truncate(254, True) }}
You will see a preview of the sensor at the bottom of the dialog box listing out any Offline devices, or ones that have not been seen for over 24 hours.
Props to @DavidGeorge4 for helping me improve this template sensor in the comments of my YouTube video 🙏
You could now add this sensor to a Home Assistant dashboard.
Or you can use it in an automation to immediately tell you when a Zigbee device changes.
This automation is triggered when the sensor changes state - meaning a new device has gone offline (or back online).
It then uses the Home Assistant notification service to send almost the same push notification as the Blueprint to my Pixel 6 pro.
You’ll need to select the right service from the list for your Home Assistant mobile app notification service and you’ll need to make sure you edit the {{ states("sensor.z2m_offline_devices") }} part to use the sensor you created earlier.
Final Thoughts
Now, when I get a push notification, I can immediately go and check that device to either replace the battery or re-pair it to my Zigbee network if that’s required. Or, I can ignore it if I’m busy.
Then at 8pm, when my work day is finished, I get the scheduled push notification reminding me of any devices that are still offline and I can deal with them then if I prefer. The push notification only gets sent if there are indeed offline devices, so I don’t get spammed if there’s nothing to do.