Hi, I have multiple zigbee devices (xiaomi ones). Running zigbee2mqtt addon. I noticed that all zigbee devices send messages even where there is no action (like button press or water leak). Just as “I am still here”. Like for example those water leak sensors. They send roughly once a hour simple message water_leak:false. I would like to have some kind of alert when some device stops sending messages - because I can imagine the battery fails or the electronics fails. And with those water leak or smoke alarms you will have only false sense of security while in reality the sensor could be dead.
So does anybody have some script that checks when the device sent last message and if this time period is longer than X minutes it will issue some alert? Thanks for replies
Thanks for the tip - didn’t hear about the zigbee2mqttassistant. Looks great. But the function to make alerts is not implemented there…so I guess I have to make some script to compare “last_seen” to current time
{%- macro GetDroppedZigbee() -%}
{% for state in states.sensor -%}
{%- if state.attributes.linkquality %}
{%- if "linkquality" in state.name and (as_timestamp(now()) - as_timestamp(state.last_updated) > (24 * 60 * 60) ) -%}
X
{%- endif -%}
{%- endif -%}
{%- endfor %}
{%- endmacro -%}
{%- if GetDroppedZigbee()[0] == "X" -%}
true
{%- else -%}
false
{%- endif -%}
As notification:
message: >
Some Zigbee devices haven't been seen lately... {% for state in states.sensor
-%}
{%- if state.attributes.linkquality %}
{%- if "linkquality" in state.name and (as_timestamp(now()) - as_timestamp(state.last_updated) > (24 * 60 * 60) ) %}
{{ relative_time(state.last_updated) }} ago for {{ state.name | lower }}
{%- endif -%}
{%- endif -%}
{%- endfor %}
I trigger it twice a day and get a push notification to my phone.
Note: credit goes to someone else in the community whose name slips my mind at the moment.
@Skye great piece of code. Was about to make a similar “call for help” topic with these assumptions:
I`m ok with triggering automation once in a day by time; - check
It should loop through all entities. - check
I would like to add condition that returns true only if there is more than 0 entities that have last_changed > X - check
So have changed every last_updated to last_changed in your code and I am lacking only one thing.
How to exclude multiple inside template so that I can add some device that I do not really care about (printer, SHP6 connected to ironing board etc.). Adding and not 'X' in 'state' is not good for keeping code clear. I do not have any idea how to pass by list inside if loop since it should be string.
Z2M already offers some functionality for this. Wired devices are pinged every x seconds as set in config under:
advanced:
availability_timeout: 60
Battery devices are marked as unavailable after 25 hours. I’d like to see this added per device so we can customise it. There’s an issue which needs reopening here
I just have an automation in HA to send an alert sent when the device is marked unavailable by Z2M.
I want to share my setup. I’m using Z2M and first I tried availability_timeout config. I didn’t like it because it generates additional network traffic and I have mostly battery powered devices which are not pinged. Also when Z2M mark device as unavailable then you are unable to control it any more via HA.
For me that was no go and I went for binary sensor which checks last seen field. For that I enabled last_seen in Z2M config:
advanced:
last_seen: ISO_8601_local
and then I created binary_sensor template like this:
binary_sensor:
- platform: template
sensors:
z2m_health:
friendly_name: 'Z2M Mesh health'
value_template: >-
{%- macro CheckDroppedZigbee() -%}
{% for state in states.sensor -%}
{%- if ("linkquality" in state.name and state_attr(state.entity_id, "last_seen") != None and (as_timestamp(now()) - as_timestamp(state_attr(state.entity_id, "last_seen")) > (24 * 60 * 60))) -%}
{{ state.name }}
{%- endif -%}
{%- endfor %}
{%- endmacro -%}
{% set output = CheckDroppedZigbee() %}
{% if output | trim == "" %}
false
{%- else -%}
true
{%- endif -%}
attribute_templates:
data: >-
{%- macro GetDroppedZigbee() -%}
{% for state in states.sensor -%}
{%- if ("linkquality" in state.name and state_attr(state.entity_id, "last_seen") != None and (as_timestamp(now()) - as_timestamp(state_attr(state.entity_id, "last_seen")) > (24 * 60 * 60))) -%}
{{ state.name | regex_replace(find=' linkquality', replace='', ignorecase=False) }} - {{ relative_time(strptime(state_attr(state.entity_id, "last_seen"), '%Y-%m-%dT%H:%M:%S%z')) }} ago {{- '\n' -}}
{%- endif -%}
{%- endfor %}
{%- endmacro -%}
{{ GetDroppedZigbee() }}
I wanted to store message into attributes so that I can use it in Lovelace also. I’m using only linkquality entities.
After that you have everything and you can use this binary sensor in automations like this:
alias: Zigbee unhealthy alert
description: ''
trigger:
- platform: state
entity_id: binary_sensor.z2m_health
to: 'on'
condition: []
action:
- data:
message: |-
❌ Zigbee last seen ❌️:
{{state_attr('binary_sensor.z2m_health', 'data')}}
service: notify.telegrambotme
mode: single
Thanks to @Skye and @Tinkerer for code which gave me idea and direction.
Thank you for sharing your automation script!
Sorry, i’m noob, i’m getting following result using your script:
Some Zigbee devices haven’t been seen lately…
8.8 hours ago for ikeae14bulbupdateavailable
8.8 hours ago for ikeae273updateavailable
8.8 hours ago for ikeae14bulb
8.8 hours ago for ikeae273
8.8 hours ago for ikeae14bulblinkquality
8.8 hours ago for ikeae14bulbpoweronbehavior
8.8 hours ago for ikeae14bulbupdatestate
8.8 hours ago for ikeae273linkquality
8.8 hours ago for ikeae273poweronbehavior
8.8 hours ago for ikeae273updatestate
Is it possible to fix this somehow? There is only 2 devices.
You will just have to experiment and change the words the regex is looking for to exclude the entries you don’t want. I could only guess at what they were based on your post, you need to look at the entity names. Hopefully you are using the template editor which will allow you to quickly test different ideas.
Hi!
Is the last-seen attribute possible with all zigbee devices?
To enable it, simply enter in the zigbee2mqtt advanced configuration:
last_seen: ISO_8601_local ?
@OzGav Did you only use one automation or did you have to create template sensors?
Not sure if all zigbee devices have the last_seen attribute but all mine do. Yes you can enter any valid option in the configuration I use last_seen: ISO_8601