Unavailable / Unknown Entity Monitoring - Template Sensor

Nice, I’ll try it.

Whilst you’re on format, can you think of a solution to this…

The whitelist is important because it checks for devices that are not online yet, therefore don’t have the entity_id registered in homeassistant yet.

Problem being the say 3 hours later if they go unavailable they now are in the entity list, so the sensor gets the same entity from the whitelist and the states loop causing duplicates.

Any ‘easy’ way to the final count number and entity list to ignore the duplicates?

I thought you might ask that and … I’ll be honest … I only focused on that one for-loop and didn’t take a holistic view of its operation. In other words, I dunno.

However, your invention intrigues me so I’ll have a look at in depth when I have more time to experiment with it.

1 Like

Excellent, I’ll await your thoughts :slightly_smiling_face:

in the meantime… :wink:

please could you explain this:

    # only continue if current number of sensors is equal or more than the number when triggered
      - condition: template
        value_template: >
          {{ states('sensor.entities_uun')|int >= trigger.to_state.state|int }}

I am having a hard time understanding why these aren’t equal… I mean, the current state is also the to_state? hence we always check for the from_state < to_state ?

iow, why would this template be necessary, if you already use

      - condition: template
        value_template: >
          {{ trigger.to_state.state|int > trigger.from_state.state|int }}

in the automation?

if Id change it to:

  - alias: 'Unavailable Notification'
    id: 'Unavailable Notification'
    description: 'Send notification when entities go.'
    trigger:
    # run whenever unavailable sensors sensor state changes
      platform: state
      entity_id: sensor.entities_uun
    condition: []
    action:
    # wait 30 seconds before rechecking sensor state
      - delay:
         seconds: 30
    # make sure the sensor is updated before we check the state
      - service: script.update_entities_uun
    # only continue if current number of sensors is equal or more than the number when triggered = 
    # only run if the number of unavailable sensors had gone up
      - condition: template
        value_template: >
          {{ trigger.to_state.state|int > trigger.from_state.state|int }}    # create a persistent notification
      - service: persistent_notification.create
        data_template:
          title: 'Entities Unavailable!'
          message: >
            ### Unavailable entities: {{ '\n' + state_attr('sensor.entities_uun','Unavailable').split(', ') 
                                         | join('\n') }}
          notification_id: 'entities_uun_alert'

would this do the following:

upon state change, update the sensor,
if to_state<from_state, do nothing else,
if to_state>from_state, create notification?

added this to keep checking when needed:

  - alias: 'Check for unavailabe entities'
    id: 'Check for unavailabe entities'
    trigger:
      platform: time_pattern
      minutes: "/5"
    condition:
      condition: template
      value_template: >
        {{is_state('persistent_notification.entities_uun_alert','notifying')}}
    action:
      service: script.update_entities_uun

I have a question: why is there a need for both a whitelist and a blacklist?

I would have thought only a whitelist is needed; just monitor the availability of desired entities and all others are ignored.

Or is having white and black lists meant to be a convenience? If I need to monitor 97 out of 100 entities, then it’s more convenient to blacklist 3 of them than whitelist 97 entities. But that implies using one or the other but I see in your example that you are using both. So if an entity is not whitelisted or blacklisted how is it handled?

  • It’s not on the whitelist so it should be rejected.
  • It’s not on the blacklist so it should be accepted.

How is this conflicting situation handled?

yes, my thoughts too.

I’m only using the blacklist option, (and an ignore list inside the sensors) and playing with the results, end up adding more to the blacklist. Seems no need for a whitelist is necessary.

I guess it could depend on the amount of entities one has and needs to check for state. Still, one of either would suffice?

have an additional request:
can we somehow add * to the ex/inclusions?

explain: I noticed the SolarEdge sensor is quite unreliable at the moment, and seems to go offline every now and then.
No need for the sensors to monitor, so Id like to exclude the set of solardedge sensors completely.

I could add them individually to the blacklist option. They are not of a dedicated domain, so can’t use that technique.

checking the available options on the states, I’d need something in the lines of
|rejectattr('object_id','startswith','solaredge')

doesnt work in Jinja though…

{{ trigger.event.data.object_id.startswith(‘solaredge.’)}}
{{ trigger.event.data.entity_id.split(’.’)[1].startswith(‘solaredge’)}}

would probably do it in an automation, but I need it in the sensor…

Blacklist is entities that you are expecting to be unavailable so should not appear in the list. For example - the Alexa Media Player component creates several sensors that are unavailable a lot of the time, and I don’t want them to be monitored.

Whitelist is for entities that might not be in the states list on startup, for example - homeassistant reboots and the Hue hub isn’t ready when it does. Since hue became configured via ‘integration’ this means that my lights would not appear in the states list until they are dynamically added when the Hue hub becomes ready. If that isn’t for 10 minutes, then the ‘normal’ bit of the sensor that goes through the states list won’t know that I should have multiple lights and sensors from the Hue hub so will return 0 unavailable entities when in fact there are around 20. Whitelist makes the sensor look for devices that should be in the states list even if they’re not.

Entities that are not on either list should be monitored as well.

It works perfectly, except for the duplication.

Possibly a more concise way to put it:

Sensor should ignore anything on the blacklist.

Should report anything in states that is unavailable.

Should also report anything that is in the Whitelist but not in the states list yet.

I see; there’s another layer to this onion.

Moments after startup, there are:

  1. Entities whose state might be unavailable (we can check their state)
  2. Entities that haven’t even been created yet (we cannot check their state)

Whitelist contains entities from the second category. Entities from the first category will be monitored by default (i.e. no need to add them to the whitelist), unless they are in the black list. Is that correct?

Exactly that :slightly_smiling_face:

Would it be fair to say that entities comprising the second category exist because of checking for their presence too soon after startup?

In other words, if I allowed a full minute to pass (after startup) I’d encounter fewer “2nd category entities” than if I checked a mere 15 seconds after startup?


This situation reminds me of the guidance provided for the Homekit integration (Disable auto-start). It suggests there may be a need to delay the start of the HomeKit integration until all dependent entities become available. The instructions suggest disabling the integration’s auto-start option, then creating an automation to enable it at the appropriate time. The automation’s trigger can be an event (if the dependent integration or entities can issue one) or simply after a fixed delay (a full five minutes in the documentation’s example!). So the simplest strategy is to give dependent entities sufficient time to establish themselves before checking on them.

FWIW, in my case, I use an automation with a fixed delay of merely 5 seconds since all dependent entities are MQTT-based. They’re discovered very quickly because it’s only a matter of subscribing to the MQTT broker and receiving all the retained values. In contrast, a longer delay may be needed for integrations that have to poll all related devices.

The problem there being - what if they never come online?

So imagine the reason my homeassistant is being restarted is because of a power cut. Unbeknown to me this event has also killed my esphome device that controls my heating (seen as switch.heater in my whitelist). Homeassistant boots, waits one minute for everything to settle down and then does the check. Switch.heater has never come online, so it never makes it in to the states list, but I still need to know its not there so I can take action to fix the problem.

1 Like

I haven’t had a chance read the rest of the thread yet but this is exactly why I did my offline device sensor the way I did with the group. Now I’m going to read the rest of the thread and realize you know this and you’re talking about something else. :slightly_smiling_face:

1 Like

OK, thanks for the explanation, it makes sense to me now. What I had not considered are entities that exist only after they are (re)discovered by their associated integration. So if the integration fails to instantiate them, they don’t exist as far the state machine and templates are concerned. So the whitelist serves as a ‘master entity reference’.

1 Like

Without wishing to appear lazy (no point reinventing the wheel :wink: ) did anyone come up with the ‘definitive solution’ to this?

Aside from duplicates between whitelist and states list I have a one that works well. It’s refined a little bit from the one I posted up there :arrow_double_up: somewhere, but @123 's idea to reduce the code by using expand doesn’t work for whitelisted entities that don’t yet exist, so it’s still fairly big.

Still interested in knowing (and hoping!) if there’s a way to remove duplicates from the final number and list.

Will post my latest version of the sensor when I’m at the computer.

1 Like

really small nudge

Ha, yeah, I haven’t picked up my computer in days - tomorrow morning though I’m all over it :slightly_smiling_face:

1 Like

OK - the sensor -

sensor:
  - platform: template
    sensors:
      unavailable_entities:
        entity_id: sensor.time
        friendly_name: Unavailable Entities
        value_template: >
          {% set count = states|selectattr('state', 'in', ['unavailable', 'unknown', 'none'])
            |rejectattr('entity_id', 'in', state_attr('group.entity_blacklist', 'entity_id'))
            |rejectattr('entity_id', 'eq' , 'group.entity_blacklist')
            |rejectattr('entity_id', 'eq' , 'group.entity_whitelist')
            |map(attribute='entity_id')|list|length %}
          {%- set devices = state_attr('group.entity_whitelist', 'entity_id') -%}
          {%- set dev = namespace(value=0) -%}
            {%- for entity_id in devices -%}
              {%- if states(entity_id) in ['unavailable', 'unknown', 'none'] -%}
              {%- set dev.value = dev.value + 1 -%}
              {%- endif -%}
            {%- endfor -%}
          {{ count + dev.value }}
        attribute_templates:
          entities: >
            {% set entities = states|selectattr('state', 'in', ['unavailable', 'unknown', 'none'])
              |rejectattr('entity_id', 'in', state_attr('group.entity_blacklist', 'entity_id'))
              |rejectattr('entity_id', 'eq' , 'group.entity_blacklist')
              |rejectattr('entity_id', 'eq' , 'group.entity_whitelist')
              |map(attribute='entity_id')|list|join(', ') %}
            {%- set whitelisted = state_attr('group.entity_whitelist', 'entity_id') -%}
            {%- set dev = namespace(value=0) -%}
              {%- for entity_id in whitelisted -%}
                {% if states(entity_id) in ['unavailable', 'unknown', 'none'] %}
                  {%- if not dev.value == 0 %}{{- ', ' -}}
                {% endif %}
                {%- set dev.value = dev.value + 1 -%}
                {{- entity_id -}}
              {% endif -%}
            {% endfor %}
            {%- if not dev.value == 0 %}{{- ', ' -}}{% endif %}
            {{- entities -}}

It currently updates every minute (with sensor.time) but I’m thinking of refreshing it with an automation that runs every second instead just to be sure it captures straight away when things go offline.

Obviously you’ll want

group:
  entity_whitelist:
    # Entities you want to check are there that might not be in the states list at startrup
  entity_blacklist:
    - sensor.unavailable_entities
    # any other entities that you don't mind being unavailable/unknown/none

As I say, aside from the duplication of whitelisted items that get in to the states list and then go offline, it’s pretty ticketyboo.

2 Likes

:rofl:

I have no idea what that means (but I can make an educated guess…) but for some reason I found that hilarious.

1 Like

Lol - hopefully you guessed right…

:slightly_smiling_face: