Filtering in templates

Please could someone help me work out how to refine the following template. It’s sent as a notification when the house alarm is triggered but as I’ve added more sensors to the house the notification is now too long and clouded by irrelevant sensors.

When I first started out I had just 4 door sensors so when the notification was triggered the notification would say which door was opened - perfect!. I now have 3 times as many binary sensors (including doorbells and updaters etc etc) so I need to filter out all the irrelevant sensors but I’m struggling to do that.

I’ve tried to create a group of the relevant sensors and iterate through that, but that seems to be a dead end.

So I decided to filter on the sensor names in the template as all the relevant sensors contain “…contact…” in their name but this isn’t respected - all the sensors are still returned. Anyone know why?

I’ve tried using, state.name, state.entity_id and state.friendly_name with no joy.

{% for state in states.binary_sensor %} 
{% if state.state == "on" and 'contact' in state.name %} 
        {{ state.name }}: open
        {% else %}
        {{ state.name }}: closed 
        {% endif %}
        {% endfor %}

In fact the if and endif lines in the above can be removed completely and I get the same result.

The closest I’ve come to finding a previous post that helps is the following link but I can’t quite get there:

https://community.home-assistant.io/t/counting-matching-states/12464/22

because your logic is flawed. You only want to output the states that have contact in the name. Right now you’re outputting everything because your if statement checks for contact in the name but then you have an else statement that returns if contact is not in the name.

short hand

{% for state in states.binary_sensor %}
{% if 'contact' in state.name.lower() %}
  {{ state.name }}: {{ 'open' if state.state == 'on' else 'closed' }}
{% endif %}
{% endfor %}

long hand

{% for state in states.binary_sensor %}
  {% if 'contact' in state.name.lower() %}
    {% if state.state == 'on' %}
      {{ state.name }}: open
    {% else %}
      {{ state.name }}: closed
    {% endif %}
  {% endif %}
{% endfor %}
1 Like

Excellent, many thanks. I’ve only been staring at this bit of logic all morning :crazy_face:

So I modified this slightly in the template editor to the following and it works fine (if I set to == off I get all the required sensors and only the open door when it’s open - great!):

{% for state in states.binary_sensor %}
{% if 'contact' in state.name.lower() and state.state == 'on' %}
  "The following door is open: " {{ state.name }}
{% endif %}
{% endfor %}

However try as I might in either an automation or script I get the following error:

Configuration invalid
Error loading /config/configuration.yaml: while parsing a block mapping
  in "/config/scripts.yaml", line 6, column 9
expected <block end>, but found '<scalar>'
  in "/config/scripts.yaml", line 7, column 26

e.g. from a script:

notify_test:
  sequence:
    - service: notify.notify_bob 
      data_template:
        title: 'House Alarm Triggered!'
        message: '{% for state in states.binary_sensor %}
                  {% if 'contact' in state.name.lower() and state.state == 'on' %}
                  {{ state.name }}
                  {% endif %}
                  {% endfor %}'

What’s wrong with that? Driving me nuts!

you need to use mutliline templates or encapsolate your string in opposite quotes. You can’t use single quotes on the outside and inside of your templates. you need to escape the quotes or use different quotes.

multiline (No outside quotes needed)

foo: >
  {{ 'my template' }}
  {{ 'my template' }}

multliline with quotes 1

foo: "{{ 'my template' }}
      {{ 'my template' }}"

multliline with quotes 2

foo: '{{ "my template" }}
      {{ "my template" }}'

multliline with quote escaping 1

foo: '{{ ''my template'' }}
      {{ ''my template'' }}'

multliline with quote escaping 2

foo: '{{ \'my template\' }}
      {{ \'my template\' }}'

multliline with quote escaping 3

foo: "{{ \"my template\" }}
      {{ \"my template\" }}"

Many thanks, strange that the template editor doesn’t expect this as well - leads you into a false sense of security

because the template editor is always in multiline template mode. It doesn’t require quotes before and after the template. Yaml does, unless you use the multiline template carrot (>).