I thought I had this fixed but maybe HA was supressing the errors and now I am seeing them. The issue is I need to check all the zigbee entities to see if they have gone offline. I am using the following and I am trying to check if the attribute exists first before doing the math on it but it appears it is not working because I keep getting this error
Template variable warning: ‘homeassistant.util.read_only_dict.ReadOnlyDict object’ has no attribute ‘last_seen’ when rendering
- alias: Zigbee Device Missing Alert
id: zigbee_device_missing_alert
trigger:
- platform: time
at: '10:00'
- platform: time
at: '20:00'
condition:
- condition: template
value_template: >
{% set ns = namespace(break = false) %}
{% for state in states -%}
{%- if state.attributes.last_seen | default(false) %}
{%- if (as_timestamp(now()) - as_timestamp(state.attributes.last_seen) > (60 * 60 * 8) ) and ns.break == false %}
{%- set ns.break = true %}
true
{%- endif -%}
{%- endif -%}
{%- endfor %}
action:
- service: notify.mobile_app_Pixel_XL
data_template:
message: >
Some Zigbee devices haven't been seen lately...
{% for state in states -%}
{%- if (state.attributes.last_seen) and not (state.name | regex_search('linkquality|button_fan|update state|voltage|temperature|battery'))%}
{%- if (as_timestamp(now()) - as_timestamp(state.attributes.last_seen) > (60 * 60 * 8) ) %}
{{ ((as_timestamp(now()) - as_timestamp(state.attributes.last_seen)) / (3600)) | round(1) }} hours ago for {{ state.name }}
{%- endif -%}
{%- endif -%}
{%- endfor %}
means it checks every entity you have (automations, scripts, scenes, lights, switches, sensors, etc).
It’s quite clear that most entities in your system do not have a last_seen attribute so why design a Template Trigger to monitor every entity? Why not restrict it to just the entities (or at least the domains) that have it?
My suggestion was to reduce the amount of work performed by Home Assistant to just the minimum needed to get the job done. Then you need to select only the entities that have a defined lasr_seen attribute. Petro’s post shows how to do that with the selectattr filter and defined test.
For another example, you can refer to this one that rejects entities having a particular attribute defined:
Thanks this is what I have now. I am thinking the regex can probably be incorporated as a filter but it is working as far as I can tell. Thanks for the help!
- alias: Zigbee Device Missing Alert
id: zigbee_device_missing_alert
trigger:
- platform: time
at: '10:00'
- platform: time
at: '20:00'
condition:
- condition: template
value_template: >
{% set ns = namespace(break = false) %}
{% for state in (expand(states.sensor, states.binary_sensor, states.light, states.switch) | selectattr('attributes.last_seen', 'defined')) -%}
{%- if (as_timestamp(now()) - as_timestamp(state.attributes.last_seen) > (60 * 60 * 8) ) and ns.break == false %}
{%- set ns.break = true %}
true
{%- endif -%}
{%- endfor %}
action:
- service: notify.mobile_app_Pixel_XL
data_template:
message: >
Some Zigbee devices haven't been seen lately...
{% for state in (expand(states.sensor, states.binary_sensor, states.light, states.switch) | selectattr('attributes.last_seen', 'defined')) -%}
{%- if not (state.name | regex_search('linkquality|button_fan|update state|voltage|temperature|battery|illuminance')) %}
{%- if (as_timestamp(now()) - as_timestamp(state.attributes.last_seen) > (60 * 60 * 8) ) %}
{{ ((as_timestamp(now()) - as_timestamp(state.attributes.last_seen)) / (3600)) | round(1) }} hours ago for {{ state.name }}
{%- endif -%}
{%- endif -%}
{%- endfor %}