Automation that will trigger if any entity becomes unavailable

I’m trying to set up an automation that will trigger if any entity becomes unavailable, the automation works when HA starts and sends the notifications as intended. I just can’t get it to trigger when an entity becomes unavailable.

This is what I have at the moment, but I have tried lots of different trigger approaches and none have worked.

alias: Notify on entity unavailable - test
description: >-
  Notify when the specified entity becomes unavailable and list the unavailable
  entities.
trigger:
  - platform: homeassistant
    event: start
  - platform: template
    value_template: |-
      {% set result = false %} {% for state in states %}
        {% if state.state == 'unavailable' %}
          {% set result = true %}
          {% break %}
        {% endif %}
      {% endfor %} {{ result }}
action:
  - delay:
      minutes: 1
  - variables:
      unavailable_entities: >-
        {{ states | selectattr('state', 'eq', 'unavailable') |
        map(attribute='name') | sort | map('regex_replace', '^(.*)$', '- \\1') |
        join('\n') }}
      recent_unavailable_entities: |-
        {{ unavailable_entities.split('
        ')[:5] | join('
        ') }}
  - service: persistent_notification.create
    data:
      title: Test Unavailable Entities
      message: |
        Total unavailable enabled entities: {{ unavailable_entities.split('\n')
        | length }}

        Unavailable entities:

        {{ unavailable_entities }}
      notification_id: unavailable_entities_{{ now().strftime('%Y%m%d%H%M%S') }}
  - service: notify.mobile_app_p30_pro
    data:
      title: Unavailable Entities
      message: >
        Total unavailable enabled entities: {{ unavailable_entities.split('\n')
        | length }}

        {{ '\n' }} 5 most recent unavailable entities:

        {{ recent_unavailable_entities }}
mode: single

You are running into variable scope issues. I don’t have time to get into it right now. But, that might be a good search for the forum.

A Template Trigger triggers when its template’s result changes from false to true. In order to trigger again, it must first change back to false. If it doesn’t do that, it doesn’t matter how many times its template reports true afterwards, it won’t trigger (until the template first reports false then true).

For example, let’s assume there no unavailable entities. That means the template reports false.

Now one of the entities becomes unavailable. That causes the template to report true. The change from false to true serves to trigger the Template Trigger.

Now another one of the entities becomes unavailable. The template still reports true. However, there’s no change from false to true so the Template Trigger is not triggered.

All this to say that the Template Trigger will trigger when the very first entity becomes unavailable but unless that entity becomes available again, the Template Trigger will not trigger again for any additional entities that become unavailable.

Restarting Home Assistant serves to trigger the Homeassistant Start trigger and it proceeds to execute its actions.

BTW, the use of states in the Template Trigger’s template means it’s subject to Rate Limiting (throttled to once a minute).

I’ve had a quick search for variable scope and can’t really get my head around it, and if the trigger doesn’t change back to false, it’s not going to do what I need.

Is there another way to get a trigger to look at all entities and trigger if any become unavailable? I was hoping that I could use a wildcard and list all the domains, but I have read that wildcards won’t work in triggers.

For me it looks like you don’t want to track if any device is unavailable, but that the unavailable device count does not change. You want to store the count of unavailable devices (or maybe directly the list of un/available devices) and track this for changes. If you react on increase, you can do something if a device becomes unavailable. If you react on decrease, you can also do something if a device becomes available.

If you want/need to trigger on a boolean, you can store the boolean “count of available devices is an odd number”. But this sounds not like a good idea, because the purpose is not directly clear and it is more difficult to follow.