I am desperately trying to create a template sensor that looks for unavailable entities and then looks up the corresponding devices. I have also created an automation that monitors state changes of this sensor and then notifies me when a device goes offline. I know it’s not perfect and it’s still a work in progress, but at least I got a little closer to my goal.
You’ll find the template sensor below, and here’s the problem: I’m seeing some behavior that I can’t really explain. The template sensor seems to work, but the automation always runs twice. The first time, a new device is added to the attribute list of unavailable devices, but the state remains the same. The second time, only the state changes, but the attributes list doesn’t. I don’t really understand how this is possible, since the logic for getting the state and the attribute is exactly the same. Perhaps someone here has an idea?
Here is the template sensor:
template:
- sensor:
- name: "Unavailable Devices"
unique_id: unavailable_devices
icon: "mdi:lan-disconnect"
state_class: measurement
unit_of_measurement: entities
state: >
{% set ignore_seconds = 60 %}
{% set ignore_ts = (now().timestamp() - ignore_seconds)|as_datetime %}
{% set entities = states
|rejectattr('domain','in',['button','event','group','input_button','input_text','scene'])
|rejectattr('last_changed','ge',ignore_ts) %}
{% set unavailable = entities|map(attribute='entity_id')|reject('has_value')|list|sort %}
{%- set ns = namespace(list = []) %}
{%- for entity in unavailable %}
{%- if device_id(entity) %}
{%- set name = device_attr(device_id(entity), 'name_by_user') %}
{%- if name and name not in ns.list|join %}
{%- set ns.list = ns.list + [name] %}
{%- endif %}
{%- endif %}
{%- endfor %}
{{ ns.list|count }}
attributes:
device_id: >
{% set ignore_seconds = 60 %}
{% set ignore_ts = (now().timestamp() - ignore_seconds)|as_datetime %}
{% set entities = states
|rejectattr('domain','in',['button','event','group','input_button','input_text','scene'])
|rejectattr('last_changed','ge',ignore_ts) %}
{% set unavailable = entities|map(attribute='entity_id')|reject('has_value')|list|sort %}
{%- set ns = namespace(list = []) %}
{%- for entity in unavailable %}
{%- if device_id(entity) %}
{%- set name = device_attr(device_id(entity), 'name_by_user') %}
{%- if name and name not in ns.list|join %}
{%- set ns.list = ns.list + [name] %}
{%- endif %}
{%- endif %}
{%- endfor %}
{{ ns.list | sort}}
And here are the state changes the last time it triggered twice:
First run:
from_state:
entity_id: sensor.unavailable_devices
state: '9'
attributes:
state_class: measurement
device_id:
- Eglo RGB 8
- Galaxy Watch
- Paulmann CT 6
- Nous Steckdose 3
- Nous Steckdose 4
- Aqara Cube
- Ikea Rodret 1
- Galaxy
- Xiaomi Lumi 2
The device “Sonoff Temperature Sensor” got added to the attributes:
to_state:
entity_id: sensor.unavailable_devices
state: '9'
attributes:
state_class: measurement
device_id:
- Eglo RGB 8
- Galaxy Watch
- Paulmann CT 6
- Nous Steckdose 3
- Nous Steckdose 4
- Aqara Cube
- Ikea Rodret 1
- Galaxy
- Sonoff Temperature Sensor
- Xiaomi Lumi 2
Second run:
from_state:
entity_id: sensor.unavailable_devices
state: '9'
attributes:
state_class: measurement
device_id:
- Eglo RGB 8
- Galaxy Watch
- Paulmann CT 6
- Nous Steckdose 3
- Nous Steckdose 4
- Aqara Cube
- Ikea Rodret 1
- Galaxy
- Sonoff Temperature Sensor
- Xiaomi Lumi 2
The state changes from 9 to 10:
from_state:
entity_id: sensor.unavailable_devices
state: '10'
attributes:
state_class: measurement
device_id:
- Eglo RGB 8
- Galaxy Watch
- Paulmann CT 6
- Nous Steckdose 3
- Nous Steckdose 4
- Aqara Cube
- Ikea Rodret 1
- Galaxy
- Sonoff Temperature Sensor
- Xiaomi Lumi 2