Unavailable / Unknown Entity Monitoring - Template Sensor

There is something new in 0.104 that might influence the way you detect unavailable sensors:

Entity handling
Draft: One major change: we’re restoring all entity registry entities on Home Assistant startup this allows Homekit/Google/Alexa to always find all entities to expose and Lovelace will no longer show yellow/red boxes. All entities are being restored as “unavailable” they can be differentiated from normal unavailable entities by the “restored” state attribute


Now officially part of release version 0.104.
Improved entity handling on startup.

2 Likes

After going through this thread and then looking at the changes for 0.104 I think this will render the whole whitelist concept unnecessary? Am I interpreting that correctly? I’ve updated to 0.104 now and my original sensors were not affected by the change. They function as they did before but I never utilized the whitelist concept that @anon43302295 came up with.

I was able to scoop a couple techniques from this thread to simplify my own templates and make them a little more robust so thanks guys!

1 Like

Can confirm that whitelist is unnecessary in 104 - will post my revised sensor when I get chance.

I think it basically boils down to this…

    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.ignored_sensors', 'entity_id'))
          |rejectattr('domain', 'eq', 'group')
          |map(attribute='entity_id')|list|length %}
        {{ count }}
      attribute_templates:
        entities: >
          {% set entities = states|selectattr('state', 'in', ['unavailable', 'unknown', 'none'])
            |rejectattr('entity_id', 'in', state_attr('group.ignored_sensors', 'entity_id'))
            |rejectattr('domain', 'eq', 'group')
            |map(attribute='entity_id')|list|join(', ') %}
          {{- entities -}} 

This is how unavailable entities show up in lovelace now!

image

Indeed - I ended up with:

sensor:
  - platform: template
    sensors:
      unavailable_entities:
        friendly_name: Unavailable Entities
        value_template: "{{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')
            |map(attribute='entity_id')|list|length }}"
        attribute_templates:
          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')
              |map(attribute='entity_id')|list|join(', ') }}"
        unit_of_measurement: items

…And using an automation to update the sensor every second. Works well :slight_smile:

I never did get around to resolving the duplicates. However, it looks like procrastination paid off because 0.104 has obviated the need for it. Nevertheless, I don’t wish to appear as a slacker so I offer you some minor streamlining.

According to my tests, you can replace this:

            |rejectattr('entity_id', 'in', state_attr('group.entity_blacklist', 'entity_id'))
            |rejectattr('entity_id', 'eq' , 'group.entity_blacklist')

with this:

            |reject('in', expand('group.entity_blacklist'))
            |reject('eq', states.group.entity_blacklist)

You can also remove this filter from the value_template:

map(attribute='entity_id')

Here’s the streamlined version:

sensor:
  - platform: template
    sensors:
      unavailable_entities:
        friendly_name: Unavailable Entities
        value_template: >
          {{states|selectattr('state', 'in', ['unavailable', 'unknown', 'none'])
            |reject('in', expand('group.entity_blacklist'))
            |reject('eq', states.group.entity_blacklist)
            |list|length}}
        attribute_templates:
          entities: >
            {{states|selectattr('state', 'in', ['unavailable', 'unknown', 'none'])
              |reject('in', expand('group.entity_blacklist'))
              |reject('eq' , states.group.entity_blacklist)
              |map(attribute='entity_id')|list|join(', ')}}
        unit_of_measurement: items
4 Likes

Thanks for putting this together, so does this streamlined version just replace the sensor section of @jazzyisj unavail_sensor.yaml? I’m not really certain what to change?

Where does this card get generated from? I don’t see anything in the github code for a lovelace card?

image

That is just one of my basic lovelace entities cards in my config. I’d have to go back through the thread to remember why it was referenced here. It has nothing to do with the unavailable entities sensor.

Not sure who you’re replying to but I think this was the final revised version of the sensor we came up with. Is this what you’re looking for?

EDIT: Updated version is always on the gist.

sensor:
  - platform: template
    sensors:
      unavailable_entities:
        entity_id: sensor.time
        friendly_name: Unavailable Entities
        unit_of_measurement: items
        icon_template: >
          {% if states('sensor.unavailable_entities')|int == 0 %} mdi:check-circle
          {% else %} mdi:alert-circle
          {% endif %}
        value_template: >
          {% set count = states|selectattr('state','in',['unavailable','unknown','none'])
            |rejectattr('entity_id','in',state_attr('group.ignored_sensors', 'entity_id'))
            |rejectattr('domain','eq','group')|list|length %}
          {{ count }}
        attribute_templates:
          entities: >
            {% set entities = states|selectattr('state','in',['unavailable','unknown','none'])
              |rejectattr('entity_id', 'in', state_attr('group.ignored_sensors', 'entity_id'))
              |rejectattr('domain','eq','group')|list|join(', ') %}
            {{- entities -}}
7 Likes

@jazzyisj, thanks for providing the latest sensor for detecting unavailable entities! I’m trying to use this as a way of detecting when I’ve lost power and shut my instance of HA down gracefully to avoid data corruption. The problem I’m having is that the majority of my sensors are Z-wave dimmers (JASCO 28167) and even after 18 mins (and counting) after unplugging one of these devices, it’s still not showing as unavailable. It’s not in my ignored_sensors group. Any ideas on how to improve status reporting of the Z-wave hub (I’m using a GoControls HUSBZB-1)?

Using something like @ptdalen as shown below with polling intensity = 1 at least gets the device entity to show that the device is “Dead” pretty soon after unplugging it, but the status of the entity still shows blank as if the device is still available.

zwave:
  usb_path: /dev/ttyACM0
  config_path: /srv/homeassistant/src/python-openzwave/openzwave/config
  polling_interval: 10000
  customize:

    light.office_level_3_0: 
      polling_intensity: 1
      refresh_value: 2
      delay: 3

Okay… I think I found the solution. Along with the polling intensity set to 1 as shown above, add the status of ‘dead’ to the states being checked for in to the sensor code @jazzisj provided directly above my remarks.

I’ve been trying to get this to work for 2 weeks with no success. I have Zigbee contact sensors that report as unavailable but the script never notify’s me. Can you test it with a zigbee device?

@mboarman: when you say that your zigbee contact sensors “report as unavailable”, do you mean that you are using the sensor provided by jazzyisj and the the sensor is reporting your zigbee contact sensors as unavailable? If so, not sure how my testing is going to help. I’ve got a zigbee contact sensor, so I can test for you in the next day or so, but need you to confirm what you mean by yours is “reporting as unavailable.”

@chad01 Sorry I should have been more specific, I have a couple sensors that the battery has died and are reporting as unavailable to HA. I assumed when I installed this script I was hoping it would give me feedback on any sensors that went missing from the network or the battery has died. So far it hasn’t done either. Appreciate any help! Thanks!

I don’t know what you’re doing wrong, but that’s exactly what this sensor does.

That’s what I figured…I drop the following in as a package.The group is created, the automation are listed, and the sensors appear. So I’m not sure why it isn’t sending any notifications. Below is my package file:

#######################################################################################################################
## Sensor - Unavailable Sensors
## - state: number of unavailable sensors
## - attribute: sensor_names - comma separated list of unavailable sensor names
## - attribute: sensor_entities: - comma separated list of unavailable sensor entity id's
## - updates every minute (sensor.time)
## - sensor entity_id's in ignored_sensors are filtered from this sensor
## - group.ignored_sensors MUST exist even if empty for sensor template to render
#######################################################################################################################

sensor:
  - platform: template
    sensors:
      unavailable_entities:
        entity_id: sensor.time
        friendly_name: Unavailable Entities
        unit_of_measurement: items
        icon_template: >
          {% if states('sensor.unavailable_entities')|int == 0 %} mdi:check-circle
          {% else %} mdi:alert-circle
          {% endif %}
        value_template: >
          {% set count = states|selectattr('state','in',['unavailable','unknown','none'])
            |rejectattr('entity_id','in',state_attr('group.ignored_sensors', 'entity_id'))
            |rejectattr('domain','eq','group')|list|length %}
          {{ count }}
        attribute_templates:
          entities: >
            {% set entities = states|selectattr('state','in',['unavailable','unknown','none'])
              |rejectattr('entity_id', 'in', state_attr('group.ignored_sensors', 'entity_id'))
              |rejectattr('domain','eq','group')|list|join(', ') %}
            {{- entities -}}


group:
  ignored_sensors:
    entities:
      - sensor.ssl_certificate_expiry


automation:
  - id: sensor_unavailable_notification
    alias: "Sensor Unavailable Notification"
    description: "Send notification when sensor goes offline."

    trigger:
      # run whenever unavailable sensors sensor state changes
      - platform: state
        entity_id: sensor.unavailable_entities

    condition:
      # 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 }}"

    action:
      # wait 30 seconds before rechecking sensor state
      - delay:
          seconds: 30
          
      # make sure the sensor is updated before we check the state
      - service: homeassistant.update_entity
        entity_id: sensor.unavailable_entities
        
      # only continue if current number of sensors is equal or more than the number when triggered
      - condition: template
        value_template: "{{ states('sensor.unavailable_entities') | int >= trigger.to_state.state | int }} "

      # create a persistent notification
      - service: persistent_notification.create
        data_template:
          title: "Sensor Unavailable"
          message: "### Unavailable Sensors: {{ '\n' + state_attr('sensor.unavailable_entities','sensor_names').split(', ') | join('\n') }}"
          notification_id: 'sensor_alert'
          
      - data_template:
          message: "### Unavailable Sensors: {{ '\n' + state_attr('sensor.unavailable_entities','sensor_names').split(', ') | join('\n') }}"
        service: notify.pushover

  - id: dismiss_sensor_unavailable_notification
    alias: "Dismiss Sensor Unavailable Notification"
    description: "Send notification when sensor goes offline."

    trigger:
      # run when there are no more unavailable
      - platform: numeric_state
        entity_id: sensor.unavailable_entities
        below: 1

    action:
      # dismiss the persistent notification
      - service: persistent_notification.dismiss
        data:
          notification_id: 'sensor_alert'

I take it you do have a time sensor defined somewhere?

Well that’s an interesting question. I’m still new to the HA world. I figured this was a plug and play implementation. What am I missing? lol