I want to make a user-friendly list of devices that are offline so that a householder who is not particularly technically minded can find them and check that they are plugged in and connected to WiFi or ZigBee as applicable.
I found several postings on this forum and elsewhere, mostly focused on entities that are unavailable. That is not what I want because
a) Each device typically has several entities and I don’t want the duplicates
b) Sometimes some entities are unavailable for a device that is actually working, probably due to an obscure device configuration (quirk) error.
c) Entities can include items like automations that are not devices at all. I only want the real devices (what the householder can see).
I don’t really know what I am doing (!) but by experimentation and borrowing from all over (thanks) I have cobbled together a sensor that delivers in attributes (because the state cannot exceed 255 characters) a list of entity ids, a list of entity friendly names and a list of devices by user-defined device name.
All three work to the extent that they produce a list using the correct name. However, if I then look at the listed devices or entities in the UI, I find that they are not all unavailable. Apparently the filtering is not yet correct.
template:
- sensor:
- name: "Unavailable Entities"
unique_id: unavailable_entities
icon: "{{ iif(states(this.entity_id)|int(-1) > 0,'mdi:alert-circle','mdi:check-circle') }}"
state_class: measurement
unit_of_measurement: entities
state: >
{% set entities_list = state_attr(this.entity_id,'entity_id_list') %}
{{ entities_list | count if entities_list != none else none }}
# these results have to be attributes because the state cannot contain more than 255 characters
attributes:
entity_id_list: >-
{% set entities_list = states
|rejectattr('domain','in',['button','event','group','input_button','input_text','scene'])
|rejectattr('last_changed','ge',ignore_ts) %}
{% set entities_list = entities_list | rejectattr('entity_id','in',ignored) if ignored != none else entities_list %}
{% set entities_list = entities_list | map(attribute='entity_id')|reject('has_value')|list|sort %}
{{ entities_list }}
entity_name_list: >-
{% set entities_list = states
|rejectattr('domain','in',['button','event','group','input_button','input_text','scene'])
|rejectattr('last_changed','ge',ignore_ts) %}
{% set entities_list = entities_list | rejectattr('entity_id','in',ignored) if ignored != none else entities_list %}
{% set entities_list = entities_list | map(attribute='entity_id')|reject('has_value')|list|sort %}
{% set data = namespace(enamelist=[]) %}
{% for entity_id in entities_list %}
{% set entity_name = state_attr(entity_id,'friendly_name') | string %}
{% if not entity_name in data.enamelist %}
{% set data.enamelist = data.enamelist + [ entity_name ] %}
{% endif %}
{% endfor %}
{{ data.enamelist | sort | replace("'","") | replace("[","") | replace("]","") | replace(", ","\n") }}
device_name_list: >-
{% set device_list = states
| selectattr('state', 'in', ['unavailable', 'unknown'])
| map(attribute='entity_id')
| map("device_id")
| map("string")
| unique
| list
| sort
%}
{% set data = namespace(dnamelist=[]) %}
{% for device_id in device_list %}
{% set device_name = device_attr(device_id, 'name_by_user') | string %}
{% if device_name == "None" %}
{% elif device_name in data.dnamelist %}
{% else %}
{% set data.dnamelist = data.dnamelist + [ device_name ] %}
{% endif %}
{% endfor %}
{{ data.dnamelist | sort | replace("'","") | replace("[","") | replace("]","") | replace(", ","\n") }}
I would like to know
- How to distinguish the main entity for a device (the device itself)?
- How to list all the DEVICES on the system?
- How to filter on unavailability of the device itself, not just some of its entities?
- What exactly the ‘map’ function does?