Mimic unsupported sensor group

Hi

I just want to share how I managed to mimic a sensor group using a template sensor.
Kudos to @petro who offered a nice solution to use anchors in templates.
I used that to only define the group entities once in the template sensor.

Use case:
Group alerts into a binary group. These alerts have 3 states (idle, on, off) and I want to define a template to calculate the group state as a binary sensor (on, off).
By adding the attribute entity_id, the sensor can be used as a group to populate for example the auto entities card.

The template sensor:

# mimic a binary sensor group for Alerts
# the variables and anchors are used to define
# the group entities only once
- trigger:
  - platform: state
    variables: &my_variables 
      entities: &triggered_by
       - alert.mgeups_alert
       - alert.battery_alert
       - alert.koelkast_keuken
       - alert.koelkast_bijkeuken
       - alert.koelkast_serre
    entity_id: *triggered_by
  - platform: homeassistant
    event: start
    variables: *my_variables
  - platform: event
    event_type: event_template_reloaded
    variables: *my_variables
  binary_sensor:
  - unique_id: myalerts
    name: MyAlerts
    state: >
       {% set ns = namespace(counter=0) %} 
       {% for entity in entities %}     
         {% if states(entity) != 'idle' %}
           {% set ns.counter = ns.counter + 1 %} 
         {% endif %} 
       {% endfor %}    
       {{ 'on' if ns.counter else 'off' }}
    attributes:
      entity_id: "{{ entities }}"
    state: >
      {{ expand(entities) | rejectattr('state', 'eq', 'idle')
        | list | count > 0 }}

EDIT

Why does this Trigger-based Template Binary Sensor need to be triggered on startup and on template-reload?

You are right, reload template seems indeed not needed. Trigger at startup can be useful the first time, in case the sensor didn’t get triggered yet (state unknown)

Ps I know the one liner for state. Did this just for readability of the example.

I must have misunderstood your reply because it sounds like you’re saying seven lines of Jinja2, containing a namespace variable, for-loop, and two if statements, offers better readability.


EDIT

Another way to do the same thing:

    state: >
      {{ entities | map('states') | reject('eq', 'idle')
        | list | count > 0 }}

Thanks, I’m not that familiar with filters, but I adopted your code :blush: