Trouble with entity_id

Complete newbie here. I am trying to create a template binary_sensor that turns “on” or “true” when any of my leak detectors detect a leak. I am planning to use it to send an alert.

All of my leak detectors have the string “leak” in the entity_id.

This code fails the configuration check:

binary_sensor:
  - platform: template
    sensors: 
      wet_somewhere:
        friendly_name: "Its wet somewhere"
        entity_id: >
          {%- for state in states.binary_sensor if("leak" in state.entity_id)-%}
          {{state.entity_id}}{%- if not loop.last -%},{%- endif -%}
          {%- endfor -%}
        value_template: >-
            {% set ns = namespace(flag = 'off') %}
            {% for state in states.binary_sensor if("leak" in state.entity_id)-%}
            {% if state.state == 'on' -%}
            {% set ns.flag = 'on' -%}
            {% endif -%}
            {% endfor -%}
            {{ns.flag == 'on'}}

It complains about the entity_id. The frontend does not update without the entity_id. I did make this work using entity_id: sensor.time, but it is annoying to wait a minute and seems wasteful to check if an update is necessary every minute. I don’t understand why my code fails.

Both templates (for entity_id and value_template) seem to be correct using the template editor in developer tools. This is the error message from the configuration check:

                          Invalid config for [binary_sensor.template]: Entity ID {%- for state in states.binary_sensor if("leak" in state.entity_id) -%} {{state.entity_id}}{%- if not loop.last -%} is an invalid entity id for dictionary value @ data['sensors']['wet_somewhere']['entity_id']. Got '{%- for state in states.binary_sensor if("leak" in state.entity_id) -%} {{state.entity_id}}{%- if not loop.last -%},{%- endif -%} {%- endfor -%}\n'. (See ?, line ?). 

Also, it would be helpful if you could help me clean up the code, or make it more idiomatic.

Thanks in advance for any help you provide. Much appreciated.

Unless you regularly add and remove water leak sensors, this sound like a perfect fit for a “group”.

By default when any member of a group is on then the group will also be on .

1 Like

First of all, I second @Olen’s advice.

Secondly - I don’t think the entity_id parameter can use a template. It requires an actual list of valid entity id’s.

binary_sensor:
  - platform: template
    sensors:
      wet_somewhere:
        friendly_name: "Its wet somewhere"
        entity_id: group.leak_sensors
        value_template: "{{ states('group.leak_sensors') }}"
group:
  leak_sensors:
    entities:
      - sensor.leak_sensor1
      - sensor.leak_sensor2
      etc.

Thanks for the responses. Can the group be created automatically by searching for entities with the “leak” substring? I hate to type the same thing twice. I would easily forget to add a new leak sensor to the group.

It’s odd that the entity_id parameter can’t use a template. I had searched the forums and got the idea to do so from some of the postings.

You can template the entity id in a service call, but not in an entity definition.

First, thanks to everyone for their responses. I just wanted to post what I have working for me in case it helps anyone else.

In input_booleans.yaml:

restart_completed:
  name: Home Assistant restart completed
  initial: false

In automations.yaml:

- alias: Set restart completed to true after 30 seconds
  trigger:
    platform: homeassistant
    event: start
  action:
    - delay: 
        seconds: 30
    - service: input_boolean.turn_on
      entity_id: input_boolean.restart_completed

The delay after restart is needed so that I don’t get false leak alerts.

In groups.yaml:

all_leak_sensors:
  name: All leak sensors
  entities:
    - binary_sensor.ecolink_leak_sensor_1_sensor
    - binary_sensor.ecolink_leak_sensor_2_sensor
    - binary_sensor.ecolink_leak_sensor_3_sensor
    - binary_sensor.ecolink_leak_sensor_4_sensor

In binary_sensor.yaml

- platform: template
  sensors: 
    wet_somewhere:
        friendly_name: "Its wet somewhere"
        entity_id: input_boolean.restart_completed, group.all_leak_sensors
        value_template: >-
            {% set ns = namespace(flag = false) %}
            {% for entity_id in states.group.all_leak_sensors.attributes.entity_id 
               if is_state('input_boolean.restart_completed','on') and is_state(entity_id,'on')  %}
            {%- if loop.first -%}
            {% set ns.flag = true %}
            {%- endif -%}
            {% endfor %}
            {{ ns.flag }}

In alerts.yaml:

leak_sensor_wet:
  name: Leak sensor alert
  message: >
    Leak detected by:
    {% for entity_id in states.group.all_leak_sensors.attributes.entity_id 
    if is_state(entity_id,'on')  %}
    {{state_attr(entity_id,'friendly_name')}} 
    {% endfor %} 
  done_message: All leak sensors are *dry*
  entity_id: binary_sensor.wet_somewhere
  state: 'on'
  repeat:
    - 30
    - 60
    - 120
    - 1440
  can_acknowledge: true
  skip_first: false
  notifiers:
    - text_to_user1

In notifications.yaml:

  - name: text_to_user1
    platform: smtp
    server: smtp.gmail.com
    port: 587
    timeout: 15
    sender: !secret ha_email_address
    encryption: starttls
    username: !secret ha_email_address
    password: !secret ha_email_password
    recipient:
      - !secret user1_text
    sender_name: !secret ha_name