Here is a way to trigger an automation based on state change of any entity in a dynamically generated list - without extra helper entities. My original motivation was to create a notification whenever any door, window, or lock is opened. I don't want to list them manually in the automation because I'm slowly but steadily adding new devices and I don't want to constantly update multiple places with every new device.
I have group entities aggregating each device class, but the group doesn't change state when e.g. the third window is opened - so a state trigger doesn't work. A Template Trigger can do the job of watching each individual entity by expanding the groups, but it's not obvious how to get a False->True edge on every state change. The trick I found is to extract the last_changed attribute and compare to the automation last_triggered time:
- alias: Dynamic Entity Test
triggers:
- trigger: template
value_template: >
{% set doors_windows = (
expand("binary_sensor.all_doors")
+ expand("binary_sensor.all_windows")
) | list %}
{% set last_changed_time = (doors_windows + (states.lock | list))
| map(attribute="last_changed") | max %}
{% set this_auto = states.automation.dynamic_entity_test %}
{% set last_triggered_time = this_auto.attributes.last_triggered
| default(as_datetime(0), true) %}
{% set effective_trigger_time = max([
last_triggered_time,
this_auto.last_changed + timedelta(seconds=10)]) %}
{{ last_changed_time > effective_trigger_time }}
actions:
- action: persistent_notification.create
...
The use of effective_trigger_time is a kludge to account for HA restarts, in order to force the template to evaluate false initially. The timedelta should essentially be set to the maximum variation between the last_changed values of all sensors and the automation itself after a restart. And consequently, it won't trigger in that timedelta after a restart and after editing/saving the automation.