Home Assistant: Notifying offline states of Z-Wave devices
It’s essential thing to keep all security devices online 24/7 in order them to function properly in every case. Thinking of that I got an idea that I should get notification immediately if ANY critical security device drops off from my Z-Wave network. I already have setup device linking between Z-Wave devices (see Setting up a reliable fire protections using Z-Wave), but I also want to know immediately if something breaks.
There are of course multiple ways this can be implements. In this post I’m describing my approach by using Home Assistant Alerts with template sensors and some UI code as well. Even though I’m using this on Z-Wave devices, some of the approaches can easily be used with other type of implementations as well.
Detecting offline devices
How do we detect devices that went offline then? When using Z-Wave JS integration with Home Assistant, every device has a node status entity that can contains state of the current node. We are interested about alive, awake and asleep statuses and everything else basically means faulty state. Alive describes that the node is online and actively communicating with the Z-Wave coordinator. Asleep is commonly used with battery powered devices and describes that everything is ok and the device is in sleep to save battery. Awake describes that the node is awaken from sleep and is currently active.
By including devices using these node status entities we can easily make a templated sensor that spots if anything has gone offline.
sensor:
# Template to track specific Z-Wave device node statuses
- platform: template
sensors:
zwave_security_offline_nodes:
value_template: >
{{ this.attributes.devices | count | int(default=0) }}
attribute_templates:
devices: >
{% set devices = [
states.sensor.co_sensor_node_status,
states.sensor.kitchen_siren_node_status,
states.sensor.garage_smoke_detector_node_status,
states.sensor.corridor_smoke_detector_node_status,
states.sensor.walk_in_closet_smoke_detector_node_status,
states.sensor.living_room_smoke_detector_node_status,
states.sensor.utility_room_leak_detector_node_status
] %}
{{ devices | rejectattr('state', 'in', ['alive', 'asleep', 'awake']) | list | map(attribute='name') | list }}
In above example I’ve listed all my critical Z-wave devices and use the template value to list the count of faulty states. In addition to that, attribute ‘devices’ contains the list of offline devices that can be used to notify the user which specific devices are not functional properly.
So now we have the ‘system fault‘ state known and can move on with the actual notifications.
Using Alerts
Previously I used Home Assistant alert system on my garage door notifications and it’s been working great ever since implementing it, so why not to use alerts again? There are couple of improvements that could be made on Home Assistant alert framework, but once you know the flaws (complex alert criteria), it’s easy to overcome those issues.
When using an alert, we need to have a boolean helper to transform our previously made templated sensor count to boolean type. This will change from false to true every time count of offline devices is greater than zero and of course vice versa. The alert entity will then trigger by the binary status and do all actions to inform the user with the offline devices information.
In the automation part I’ve added the delay of one minute to ensure no events are send when Home Assistant reboots. On reboot, before Z-Wave is initialised, the state of the Z-Wave device is unknown and for that specific boot time I don’t want to have unnecessary notifications. So the alert will only appear when devices has been offline for more than one minute!
alert:
zwave_security_offline_warn_alert_active:
name: One or more Z-Wave security devices offline!
message: Z-Wave security devices has gone offline ({{ states.sensor.zwave_security_offline_nodes.attributes.devices }})
done_message: All Z-Wave security devices are back online!
entity_id: input_boolean.zwave_security_offline_alert
state: "on"
repeat: 60
can_acknowledge: true
skip_first: false
notifiers:
- STD_Warning # Use the warning notifier (not included in this package)
# Helper triggered by the automation
input_boolean:
zwave_security_offline_alert:
name: ZWave devices offline notify
icon: mdi:alert
automation:
# Turn on the alert once template sensor count increases
- id: zwave_security_devices_gone_offline
alias: 'Security: ZWave security devices gone offline'
trigger:
- platform: numeric_state
entity_id: sensor.zwave_security_offline_nodes
for: 0:01:00
above: 0
action:
- service: input_boolean.turn_on
target:
entity_id: input_boolean.zwave_security_offline_alert
mode: single
# Turn off the alert once there are no offline devices
- id: zwave_security_devices_came_online
alias: 'Security: ZWave security devices came back online'
trigger:
- platform: numeric_state
entity_id: sensor.zwave_security_offline_nodes
for: 0:01:00
below: 1
action:
- service: input_boolean.turn_off
target:
entity_id: input_boolean.zwave_security_offline_alert
Setting up the UI
Now that the alerts and notifications are in place it’s time to add the results into the Home Assistant UI.
It’s easy to setup the alert entity directly to the UI (just add a new entity entity card including created alert), but even better is to show the alert only when needed. That’s where auto entity card comes in handy. It automatically makes an entity card visible when certain conditions matches (filters).
I’m also making the alerts visibility (color) a bit more noticeable by using card mod.
The following code displays ALL alerts currently active in the system. Unfortunately I’ve not yet found a way to display detailed information about offline devices through the Alert system directly from UI so it’s only showing basic name of the alert instead of list of devices. I will get back to this issue as soon as I find a way to overcome this.
type: vertical-stack
cards:
- type: custom:auto-entities
show_empty: false
card:
type: entities
title: Active Alerts
card_mod:
style: |
ha-card {
background-color: rgba(232, 222, 211,1);
border-radius: 5px;
--card-mod-icon-color: red;
--primary-color: white;
--paper-item-icon-color: white;
--secondary-text-color: gray;
}
filter:
include:
- entity_id: /^alert(.).*/
options:
secondary_info: last-changed
exclude:
- state: idle
sort:
method: last_changed
reverse: true