Help making a sensor that returns "name" of open doors

I am trying to make a senor sensor.open_doors that returns a sentence containing the doors that are open.

I started by making a sensor

sensor:
  - platform: template
    sensors:
      open_doors:
        value_template: >
          {% set open_doors = states | selectattr('entity_id', 'in', state_attr('group.doors', 'entity_id')) | selectattr('state', 'in', ['on', 'open']) | map(attribute='name') | list %}
          {% if open_doors|length == 0 %}
             The exterior doors are closed.
          {% elif open_doors|length == 1 %}
             The {{ open_doors[0] }} is open.
          {% else  %}
             The {{ open_doors[:-1]|join(', ') }}{{ ', ' if open_doors|length > 2 else ' ' }}and {{ open_doors[-1] }}{{ 's are open.' if open_doors|length > 2 else ' is open.' }}
          {% endif %}

I also made a group in group.yaml

doors:
  name: Doors
  entities:
    - binary_sensor.back_door_access_control
    - binary_sensor.front_door_access_control

I also gave them custom names Front Door & Back Door.

I tried using the template (from value_template:) in develepor tools - template
It returns answers “The exterior doors are closed” when all the doors are closed. It returnd “The Front Door is open” or “The Back Door is open” when one of the doors is open. When both doors are open it returns, “The Back Door and Front Door is open”

Problem is when I pole
{{ states('sensor.open_doors') }} it returns corect answers until both doors are open. When the front and back doors are open, it returns either “The exterior doors are closed”, “The Front Door is open” and “The Back Door is open”. It seems like it might be data from a previous state but sometimes it seems random.

Does anyone have an idea why the template works, but the sensor state that displays the template doesnt?

Probably because your template is too complicated for home assistant to work out what to monitor for changes. See: entity_id

If you have a group, you can use that to simplify your template. Also, binary_sensor entities are only 'on', they’re never 'open' (they only look that way in the frontend.)

sensor:
  - platform: template
    sensors:
      open_doors:
        value_template: >
          {% set open_doors = expand('group.doors') | selectattr('state','eq','on')
                              | map(attribute='name') | list %}
          {% if open_doors|length == 0 %}
             The exterior doors are closed.
          {% elif open_doors|length == 1 %}
             The {{ open_doors[0] }} is open.
          {% else  %}
             The {{ open_doors[:-1]|join(', ') }}{{ ', ' if open_doors|length > 2 else ' ' }}and {{ open_doors[-1] }}{{ 's are open.' if open_doors|length > 2 else ' is open.' }}
          {% endif %}

I know there was some work being done to extract entity ID’s from expressions using the expand() function, but I haven’t checked the status of that yet. So it’s possible this will not only simplify your template, but it may solve your problem as well. (If not, then use the entity_id config option as @tom_l suggested.)

Here are two suggestions.

The first one handles any number of doors.

  - platform: template
    sensors:
      open_doors:
        value_template: >
          {% set doors =
            [ states.binary_sensor.back_door_access_control,
              states.binary_sensor.front_door_access_control ]
            | selectattr('state', 'eq', 'on')
            | map(attribute='name') | list %}
          {% set qty = doors | count %}
          {% if qty == 0 %}
            All exterior doors are closed.
          {% else %}
            The following door{{ 's are' if qty > 1 else ' is' }} open: {{doors | join(', ')}}
          {% endif %}

The second one is designed to handle only two doors. It also strips out the word “Door” from the entity’s friendly_name so it can produce a phrase like “The Back and Front doors are open.” as opposed to “The Back Door and Front Door are open.”

  - platform: template
    sensors:
      open_doors:
        value_template: >
          {% set doors =
            [ states.binary_sensor.back_door_access_control,
              states.binary_sensor.front_door_access_control ]
            | selectattr('state', 'eq', 'on')
            | map(attribute='name') 
            | map('replace', ' Door', '') | list %}
          {% set qty = doors | count %}
          {% if qty == 0 %}
            All exterior doors are closed.
          {% elif qty == 1 %}
            The {{doors[0]}} door is open.
          {% else %}
            The {{doors[0]}} and {{doors[1]}} doors are open.
          {% endif %}

Ideally, we could use the expand function with a group in this Template Sensor. However, on startup, Home Assistant doesn’t expand the group to monitor each group member’s state but simply monitors the group’s state. I had posted it as a Feature Request.

There was an enhancement introduced in 0.110 to make it monitor each group member’s state but, unfortunately, it failed to work. I reported it as an Issue and the developer continues to work on correcting it. The complication he encountered is that, on startup, groups must be defined before Template Sensors and that sequence is not guaranteed.


EDIT
Correction. Forgot to copy-paste this very important line: value_template: >

1 Like

Does your suggestions need a value_template: > before the {% starts?

Also, and I can’t seem to find an answer to this, why is it sometimes value_template: > and sometimes value_template: >-

Thanks for the help!

The difference is the removal of white space, usually not necessary

Yes! I had worked on the template exclusively and then, at the last moment, copy-pasted the first few lines from your example but overlooked to include the line containing value_template. It definitely won’t pass the configuration-check without it! I’ve corrected my previous post.

The greater-than symbol (>) represents a line-continuation character (i.e. the template begins on the next line). The addition of a hyphen (-) is to control whitespace (suppress it) but, in practice, it rarely makes a difference when used with value_template.

Jinja 2 Whitespace Control

Hauhawee (ninja noise ! )
:rofl:

Edit: Having said that I use jinja2 to write some sections of my ui-lovelace.yaml
And judiciously placed “-” can clean some lines up considerably