Thanks for this post! I found it very helpful.
For anyone interested, here is how it is implemented in my setup. It’s pretty much the same, but I filtered out more types of things in my query out of necessity.
- trigger:
- platform: time_pattern
minutes: "*"
sensor:
- name: Unavailable Entities
icon: mdi:help-circle-outline
state: "{{ states | selectattr('state', 'in', ['unavailable', 'unknown', 'none']) | rejectattr('domain', '==', 'button') | rejectattr('entity_id', 'search', '_device_temperature$') | rejectattr('domain', 'in', ['device_tracker', 'person']) | rejectattr('entity_id', 'search', '_charger_type$') | map(attribute='entity_id') | reject('==', 'sensor.unavailable_entities') | list | length }}"
unit_of_measurement: entities
state_class: measurement
attributes:
unavailable: "{{ states | selectattr('state', 'in', ['unavailable']) | rejectattr('domain', '==', 'button') | rejectattr('entity_id', 'search', '_device_temperature$') | rejectattr('domain', 'in', ['device_tracker', 'person']) | rejectattr('entity_id', 'search', '_charger_type$') | map(attribute='entity_id') | reject('==', 'sensor.unavailable_entities') | list }}"
unknown: "{{ states | selectattr('state', 'in', ['unknown']) | rejectattr('domain', '==', 'button') | rejectattr('entity_id', 'search', '_device_temperature$') | rejectattr('domain', 'in', ['device_tracker', 'person']) | rejectattr('entity_id', 'search', '_charger_type$') | map(attribute='entity_id') | reject('==', 'sensor.unavailable_entities') | list }}"
none: "{{ states | selectattr('state', 'in', ['none']) | rejectattr('domain', '==', 'button') | rejectattr('entity_id', 'search', '_device_temperature$') | rejectattr('domain', 'in', ['device_tracker', 'person']) | rejectattr('entity_id', 'search', '_charger_type$') | map(attribute='entity_id') | reject('==', 'sensor.unavailable_entities') | list }}"