How to list all sensors with state = 'unavailable', 'none' or 'unknown'

I did something like this with my ZWave devices and ran into the 255 character limit. I simply changed the value_template to be on or off and used attribute_templates to record the actual list:

    attribute_templates:
      entities: >-
          {% compute the list here %}

I coded the logic of value_template so that if entities is going to contain devices then the value of the sensor is on, otherwise it is off. I also had to change some of my automation logic: where I previously would use last_changed to know whether my list of entities changed I had to switch to last_updated because last_changed ignores attributes and if the list changes from 2 to 3 devices or there’s any other change to it, that matters to me.

1 Like
{{ states | selectattr('state', 'in', ['unavailable', 'unknown', 'none']) | list | join(', ') }}

EDIT: I didn’t fully read your question. The above template removes all whitespace. Thought that’s what you wanted.

Anyways, attributes don’t have a limit, so place the provided template into an attribute.

Something like:

sensor:
- platform: template
  sensors:
    unknown_entities:
      friendly_name: Unknown Entities
      value_template: >
        {{ states | selectattr('state', 'in', ['unavailable', 'unknown', 'none']) | list | length }}
      attribute_templates:
        entities: >
          {{ states | selectattr('state', 'in', ['unavailable', 'unknown', 'none']) | list | join(', ') }}

The main state will be a total number of unknown entities and it will contain an attribute that displays all of the entity_ids.

5 Likes

Thanks, both of you!

I tried the @petro solution, and it works fine. At first I thought something was wrong since it listed 95 devices after restart, but it just needed an update after the startup phase.

However, now I’d like some help formatting the output. It lists all information about each entity. I only want the entity name and the state

Like:

light.belysning_poolomrade_5=unavailable; sensor.latest_alarm_change=unavailable; ; sensor.unavailable=unknown; sensor.zxp_qr_code=unknown

While it now list like this (which is good, but hard to read)…

    <template state light.belysning_poolomrade_5=unavailable; friendly_name=Belysning poolområde (5), supported_features=41, icon=mdi:lightbulb, assumed_state=False @ 2019-12-12T15:54:43.056278+01:00>, <template state sensor.latest_alarm_change=unavailable; friendly_name=Senaste förändring, icon=mdi:clock @ 2019-12-12T15:55:06.426483+01:00>, <template state sensor.unavailable=unknown; friendly_name=Sensorer utan data @ 2019-12-12T15:54:42.381244+01:00>, <template state sensor.zxp_qr_code=unknown; friendly_name=zxp QR Code @ 2019-12-12T15:54:42.617662+01:00>

Thanks again!

Oh, that’s an error on my part. Sorry!

Change the template for the attribute to

{{ states | selectattr('state', 'in', ['unavailable', 'unknown', 'none']) | map(attribute='entity_id') | list | join(', ') }}
7 Likes

Thanks so much! Now it works like a charm.

For others reading and wanting the same thing:

The sensor:

    unavailable:
      friendly_name: 'Sensors that need attention'
      value_template: >
        {{ states | selectattr('state', 'in', ['unavailable', 'unknown', 'none']) | list | length }}
      attribute_templates:
        entities: >
          {{ states | selectattr('state', 'in', ['unavailable', 'unknown', 'none']) | map(attribute='entity_id') | list | join('\n') }}

…and the automation that updates the sensor:

alias: "System - Refresh sensor.unavailable"
trigger:
  platform: time_pattern
  minutes: '/1'
action:
  service: homeassistant.update_entity
  data:
    entity_id: sensor.unavailable
5 Likes

to prevent needing to use an automation to trigger a refresh every minute you could set up the “Time & Date Sensor” then use the “sensor.time” in the config for the “unavailable” sensor you created.

That will cause the sensor to refresh whenever the sensor.time updates (which is every minute0. So you will get the same result as using the automation without the extra code.

3 Likes

building on this, it would be even cooler if we could have the listing show both the entity and its state (because the selection is for 3 possible states now), and even better, list per attribute unavailable, unknown and none.

If been fiddling with groupby but havent found the correct syntax yet…

a bit like this, the loaded components, grouped by integration:

07

You know you aren’t allowed to show nice pictures without the code that produced it :stuck_out_tongue_winking_eye:

haha its a python script…

##############################################################################################################
# python script to show the loaded components on a  Hassio instance, and order them alphabetically, grouping
# components that have sub components (attributes)
# this script gets its data from the rest_sensor:
#   - platform: rest
#     name: Hassio Main config
#     resource: !secret resource_hassio_main_config
#     authentication: basic
#     value_template: >
#       {{ value_json.version }}
#     json_attributes:
#       - components
#       - unit_system
#       - config_dir
#     headers:
#       Content-Type: application/json
#       Authorization: !secret api_bearer_token
#       User-Agent: Home Assistant REST sensor
#
##########################################################################################
# Codes for text_colors declared in 
# Custom card: /custom_ui/state-card-value_only.html
# changed to use below customizing options:
##########################################################################################
#
#      case "*": return "bold";
#      case "/": return "italic";
#      case "!": return "red";
#      case "+": return "green";
#      case "=": return "yellow";
#      case "%": return "grey";
#      case "$": return "brown";
#      case "#": return "blue";
#      default:  return "normal";
#
# https://community.home-assistant.io/t/template-to-display-loaded-components-on-ha-instance/114402/59
# @123 and @apop pointed to the rest sensor, and made that availabe in Lovelace
# @petro had a great hand in creating the script
# thanks for joining in on a great HA community!
# @mariusthvdb 20190504
##############################################################################################################
attributes = {}
components = hass.states.get('sensor.hassio_rpi4_config').attributes['components']
cnt = len(components)
components.sort()

# Make a dictionary of all main domains, add each sub domain to the main domain list.
compdict = {}
for component in components:
    if component.count('.') == 0 and component not in compdict:
        compdict[component] = []
    if component.count('.') == 1:
        domain, subdomain = component.split('.')
        compdict[domain].append(subdomain)
        
# Make the dictionary into a flat list of strings.

complist = []

for key, value in compdict.items():
    if value:
        value.sort()
        # Adding a domain & series of sub domains
        complist.append('- {}: \n --> {}'.format(key, ', '.join(value)))
    else:
        complist.append('- {}'.format(key))

# join each component with a carriage return
complist = '\n'.join(complist)

text = '{} Loaded Components:\n' \
       '{}'.format(cnt, complist)

attributes['friendly_name'] = 'Components'
attributes['icon'] = 'mdi:format-list-bulleted-type'
attributes['Components'] = cnt
attributes['---------------'] = '--------'

attributes['text'] = text

hass.states.set('sensor.overview_components', cnt, attributes)

# hass.states.set('sensor.overview_components', cnt, {
#     'icon': 'mdi:format-list-bulleted-type',
#     'friendly_name': 'Components',
#     'text': text
#     })
##############################################################################################################
# first attempt, simply creating an unordered list of components
# components = hass.states.get('sensor.hassio_main_config').attributes['components']
# count = len(components)
# components.sort()
# list = ', '.join(components)
# 
# text = '*========== {} Loaded Components ========\n' \
#         '+{}' \
#           .format(count,
#                   list)
# 
# 
# hass.states.set('sensor.hassio_main_components', count, {
#         'custom_ui_state_card': 'state-card-value_only',
#         'text': text
#     })

I’m not sure I follow what you want. You want to group by in the attributes or do you want separate attributes?

id like to be able to group them by the selected attributes:

unavailable (2) :
  - sensor.123
  - group.456
unknown (2):
  - sensor.789
  - group.abc
none (1): 
  - nobody.knows

or something like that :wink:

btw, check this:

I’ve made this domains sensor:

  - platform: template
    sensors:
      domains_in_use:
        friendly_name_template: >
          Domains in use:
        value_template: >
          {{ states|groupby('domain')|count }}
        attribute_templates:
          domains: >-
            {% set ns = namespace(domains=[]) %}
            {% for d in states | groupby('domain') %}
              {% set ns.domains = ns.domains + [d[0]] %}
            {% endfor %}
            {% set list = ns.domains | join('\n') %}
              {{list}}

which in the developer template page shows fine:

but does this in real life:

16

what am I missing in the formatting?

1 Like

Whitespace is removed for display in the attributes tab. It may be removed all together. Only way to tell is to look at the attribute in the template editor.

{% set grouped = states | selectattr('state', 'in', ['unavailable', 'unknown', 'none'])| map(attribute='entity_id') | groupby('state') %}

thats what I tried also, but it errors out with:

Error rendering template: UndefinedError: 'str object' has no attribute 'state'

this:

{% set grouped = states | selectattr('state', 'in', ['unavailable', 'unknown', 'none'])| groupby('state') %}

{{grouped}}

works, but shows all attributes again. No way to add the | map(attribute='entity_id') filter…

as a followup and not to duplicate posts: Sensor - Unavailable/Offline Detection

This is what I do, now updated to exclude the new button entities:

template:
  - trigger:
      - platform: time_pattern
        minutes: "*"
    sensor:
      - name: Unavailable Entities
        icon: mdi:help-circle-outline
        state: "{{ states | selectattr('state', 'in',['unavailable', 'unknown', 'none']) | map(attribute='entity_id') | reject('==', 'sensor.unavailable_entities') | reject('match', 'button') | list | length }}"
        unit_of_measurement: entities
        state_class: measurement
        attributes:
          # buttons don't have state – we don't care about buttons here
          unavailable: "{{ states | selectattr('state', 'in', ['unavailable']) | map(attribute='entity_id') | reject('==', 'sensor.unavailable_entities') | reject('match', 'button') | list }}"
          unknown: "{{ states | selectattr('state', 'in', ['unknown']) | map(attribute='entity_id') | reject('==', 'sensor.unavailable_entities') | reject('match', 'button') | list }}"
          none: "{{ states | selectattr('state', 'in', ['none']) | map(attribute='entity_id') | reject('==', 'sensor.unavailable_entities') | reject('match', 'button') | list }}"

This post helped me.

EDIT: As was wisely pointed out by someone else, you can also reject by domain (which I too think is cleaner and more robust):

rejectattr('domain','eq','button')
2 Likes

I’d like to use something similar to have a list of binary sensors of a certain gropus, whan I’m leaving home, listed by they’re firendly name is it possible to make a template like this?

I made something like this, starting from your suggestion:

{{ states.binary_sensor | selectattr('state', 'in', ['on']) | map(attribute='attributes.friendly_name' ) | list | join(', ') }}

But I’d like to list only the binary sensors that are ON and belong to a specific group

you want to expand('group.your_group') that group, instead of using all states.binary_sensor

really another topic ofc, so search the community for expand() and you’ll find many examples

this is a good place to start: Unleash the power of 'expand' for Template Sensors

1 Like

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 }}"
3 Likes