Offline detection for Z2M devices with last_seen

Some recent z2m upgrade introduced hiding linkquality entities by default. You must enable each linkquality entity manually in devices

I agree. Is it possible to specify multiple times for automation to run or set an intervall like every three hours?

Is anyone else seeing this error? (I’m on 2021.12.9)

2022-01-29 18:56:48 WARNING (MainThread) [homeassistant.helpers.template] Template warning: 'strptime' got invalid input '2022-01-29T17:30:49.295Z' when rendering template '{% set result = namespace(sensors=[]) %}
{% for state in states.sensor | selectattr('attributes.unit_of_measurement', '==', 'lqi') %}
{% if state_attr(state.entity_id, 'last_seen') != None and (as_timestamp(now()) - as_timestamp(state_attr(state.entity_id, 'last_seen'))) > ((1 | int) * 60 * 60) %}
{% set result.sensors = result.sensors + [state.name | regex_replace(find=' linkquality', replace='') ~ ' (' ~ relative_time(strptime(state_attr(state.entity_id, 'last_seen'), '%Y-%m-%dT%H:%M:%S%z')) ~ ')'] %}
{% endif %}
{% endfor %}
{{ result.sensors | join(', ') }}' but no default was specified. Currently 'strptime' will return '2022-01-29T17:30:49.295Z', however this template will fail to render in Home Assistant core 2022.1

Notification does not show the sensor name


If you have the blueprint and other YAML code in the main message, the myBlueprints tool does not work.
I would suggest putting the other 2 yaml code segments onto a reply, or using a screenshot of those, or adding them as just text. Otherwise people will have problems importing the blueprint. (That or remove the myBlueprints thing completely.)
Before I moved my blueprint code to GitHub, I would load the main message with the blueprint code, then comment on it immediately if there were ‘helper’ yaml code segments that were needed.

The warning part, read this…
{{ result.sensors | join(', ') }}' but no default was specified. Currently 'strptime' will return '2022-01-29T17:30:49.295Z', however this template will fail to render in Home Assistant core 2022.1

@Mr_Groch

It’s a deprecated thing that will, I assume, become a breaking change…

Yeah, this blueprint no longer works for me on 2022.3.x

I’ve been trying to figure out where the issue is without much knowledge of templating, so hopefully the info below is correct.
At the moment I think the fault seems to be with this part of the template:

{{ strptime(state_attr('binary_sensor.door_front_contact', 'last_seen'), '%Y-%m-%dT%H:%M:%S%z', 0) }}

Running this in the template editor returns a 0 due to it failing. Remove the “,0” (as it is in the blueprint template) returns the timestamp string, e.g. 2022-04-14T17:56:31.029Z. This is why relative_time doesn’t work because strptime can’t convert the string to a datetime object.

# returns time @ 10 am, if fails returns 0
{{ strptime("10:00", "%H:%M", 0) }}

strptime(string, format) 
parses a string based on a format and returns a datetime object. 
If that fails, returns the default value, or if omitted the unprocessed input value.

What I can’t figure out is why strptime isn’t able to parse the date string. I suspect its something to do with the seconds and UTC offset that it can’t convert:

:%S%z
:31.029Z

According to this page, it says the following:

In fact, if I test the following template by removing “.029Z” from the timestamp, it successfully converts to a datetime object:

{{ strptime("2022-04-14T19:08:50", '%Y-%m-%dT%H:%M:%S', 0) }}
Result:
2022-04-14 19:08:50

My zigbee2mqtt configuration.yaml has last_seen set to ISO_8601 which might be related. An alternative is ISO_8601_local which I might try as well.

For reference, the full template (line wraps removed from the blueprint) is below:

{% set result = namespace(sensors=[]) %} 
{% for state in states.sensor | selectattr('attributes.unit_of_measurement', '==', 'lqi') %}
{% if state_attr(state.entity_id, 'last_seen') != None and (as_timestamp(now()) - as_timestamp(state_attr(state.entity_id, 'last_seen'))) > ((1 | int) * 60 * 60) %}
{% set result.sensors = result.sensors + [state.name | regex_replace(find=' linkquality', replace='') ~ ' (' ~ relative_time(strptime(state_attr(state.entity_id, 'last_seen'), '%Y-%m-%dT%H:%M:%S%z')) ~ ')'] %}
{% endif %}
{% endfor %}
{{ result.sensors | join(', ') }}

doh, I really should RTFM. Changing to ISO_8601_local did the trick (as it tells me to do in the first post in this thread!!!). The last_seen timestamp is now 2022-04-14T20:37:02+01:00 which of course works… :expressionless:

1 Like

Hi all!

Lot happens in Zigbee2MQTT and Home Assistant, so I’ve updated this blueprint! Device attributes are now legacy in Z2M and ‘last seen’ sesnors are now exposed as sensors with ‘timestamp’ device_class in Home Assstant by Z2M - so I’ve decided to drop checking for ‘lqi’ sensors - I’m checking all ‘last seen’ sensors with ‘timestamp’ device_class instead…

So all you need is to enable ‘last seen’ sensors in device page if it is disabled, and also modify excluded sensors if you are using it…

That is breaking change…

PS. I’m also checking now for ‘unavailable’ state :wink:

1 Like

Hmm, I’ve been trying to figure out how an easier way to do this:

The problem is I have 125 Z2M devices, so enabling the last_seen entity for each device within HA will take far too long! I’ve not been able to find an easy way to enable this from within Z2M either, with comments near the end of this issue describing the same problem: last seen not showing up · Issue #9398 · Koenkk/zigbee2mqtt · GitHub

This is not documented, and I can’t test it now, but try adding this into your Z2M configuration, it should enable all last_seen sensors by default in HA:

device_options:
  homeassistant:
    last_seen:
      enabled_by_default: true

EDIT: You need to restart Z2M and HA to refresh discovery for all devices

Great find, thank you for the tip!

I was able to find this related Discussion based on your suggestion:

However, having just tried it myself it doesn’t appear to work for me.

I copied the options into Z2M configuration.yaml, restarted Z2M, checked HA entities to find last_seen still disabled, so restarted HA as well, but unfortunately no change.

I raised this issue just before your reply and so I’ve now updated it with my results in case there’s another fix.

We are on the same page here. Added both:

advanced:
  last_seen: ISO_8601_local
device_options:
  homeassistant:
    last_seen:
      enabled_by_default: true

And there are no attributes or entities present.
Controary to this issue i cannot find any “last_seen” value in states. How about You ?

I’ve enabled all my ‘last seen’ sensors earlier, but I’ve added this to my Z2M configuration:

device_options:
  homeassistant:
    last_seen:
      enabled_by_default: true

Restarted Z2M and HA, and checked with MQTT Explorer discovery topics for ‘last_seen’ sensors:

As you can see - enabled_by_default is true, so it works…

Try manually set Home Assistant status topic to offline and online few times (default is hass/status for Z2M)

Thanks @Mr_Groch that’s useful to see - I’ll check mine when back home later today.

Unfortunetly I`m still stuck.
My config:

data_path: /share/zigbee2mqtt
socat:
  enabled: false
  master: pty,raw,echo=0,link=/tmp/ttyZ2M,mode=777
  slave: tcp-listen:8485,keepalive,nodelay,reuseaddr,keepidle=1,keepintvl=1,keepcnt=5
  options: '-d -d'
  log: false
mqtt:
  server: mqtt://192.168.0.111:1883
  user: mqtt
  password: '!secret mqttpwd'
serial:
  port: /dev/serial/by-path/pci-0000:00:07.0-usb-0:2.2:1.0-port0
external_converters: []
devices: devices.yaml
groups: groups.yaml
homeassistant: true
permit_join: false
advanced:
  last_seen: ISO_8601_local
  log_level: info
  pan_id: 6756
  channel: XX
  network_key:
    - XX 
  availability_blocklist: []
  availability_passlist: []
  ikea_ota_use_test_url: true
device_options:
  homeassistant:
    last_seen:
      enabled_by_default: true
blocklist: []
passlist: []
queue: {}
frontend:
  port: 8099
experimental: {}
availability: true
zigbee_herdsman_debug: false

This config beside entries from my previous post was running quite long.
I have no clue what I am doing wrong. I have compered everything with z2m docs, restarted HA , server few times and was manually putting offline value for homeassistant/status (according to docs). Weird thing is that there is no such message by itself in that topic.

Ok, so I also see the same enabled_by_default message within MQTT explorer from home assistant:

Along with the hidden last_seen entity within HA:

The last_seen attribute is there as usual:

I rebooted HA and Z2M a few times again, as well as publishing manual offline/online message, but last_seen remains firmly hidden.

I see that Koenkk responded to my issue and suggested we use the availability feature for this instead: Device-Availability | Zigbee2MQTT

I guess this would just mean monitoring the offline / online state of a device?

So in your HA states, you don’t see the last_seen attribute like this?

Or are you just finding that the last_seen entity remains hidden like mine?

You are lucky I do not have attribute or hidden entity “last_seen”.
If You have that attribute this all that blueprint is about.
Avaiabilty is not just that good since this is presented in documentation.
My colegue also tested this settings and has last_seen in debug for devices that are out of network.