You should avoid using {{ states | .....}}
as it reevaluates the template on every entity update. At a minimum use {{ states.binary_sensor | ...}}
but expand('group.contact_sensor_windows')
is the better way to go.
- id: "b8064a7b-6c95-4ec2-a665-c26a0a830cad"
alias: "Rain Alert Window Open"
trigger:
- platform: numeric_state
entity_id: sensor.5123_weather_event_rain
above: "0"
action:
- service: notify.telegram
data:
message: >
It is raining and
{% set ow = expand('group.contact_sensor_windows')
| selectattr('state', 'eq', 'on') | map(attribute='name') | list%}
{%- set qty = ow | count -%}
{%- if qty != 0 -%}
{{-' the '}}{{-' and '.join((ow|join(', ')).rsplit(', ', 1)) }}
{{-' is ' if qty==1 else ' are '}}open.
{% else %} all windows are closed. {% endif %}
title: Rain Alert Window Open
mode: single
FWIW, I preferred to have the areas for my notification instead of a long list of window entites.
Area-based template
{% set ow = expand('group.all_window_sensors')
|selectattr('state','eq','on') | map(attribute='entity_id') |
map('area_name') | unique | reject('eq',None) | sort | map('lower') | list %}
{% set qty = ow | count %}
{% if qty != 0 %}
There {{ 'is an' if qty==1 else 'are'}} open window{{' ' if qty==1 else 's '}}in the
{{' and '.join((ow|join(', ')).rsplit(', ', 1)) }}.
{% else %} All windows are closed. {% endif %}