Open doors automation with variables question

I’m trying to improve an existing automation which alerts if any of 4 doors are open 30min after sunset and at 2215. If the house is Disarmed (ie we’re not away), and any of the 4 doors are not closed at the trigger times, a persistent alert is sent.

This works as expected. However, I’d like to include the name of the door that is not closed in the notification. I thought to create a variable, door, that would be set by the condition that allows the automation to continue. So, I added variables: into the conditions: section but I get an error Message malformed: extra keys not allowed @ data['conditions'][1]['conditions'][0]['variables'] Looks like variables can’t be defined inside conditions.

Alternatively, I know I can create a group helper for the 4 doors but I don’t know how to extract the door that’s not closed.

This works …

alias: Alert - Home Door(s) not closed
description: Alert if door(s) not closed sunset+30min and 2215
triggers:
  - trigger: sun
    event: sunset
    offset: "1800"
  - trigger: time
    at: "22:15:00"
conditions:
  - condition: state
    entity_id: input_select.arming
    state:
      - Disarm
  - condition: not
    conditions:
      - condition: state
        entity_id: sensor.sheddoor
        state:
          - closed
      - condition: state
        entity_id: sensor.garagepa
        state:
          - closed
      - condition: state
        entity_id: sensor.garageposition
        state:
          - closed
      - condition: state
        entity_id: sensor.frontgate
        state:
          - closed
actions:
  - action: notify.persistent_notification
    metadata: {}
    data:
      title: Warning !
      message: Door(s) open
mode: single

What doesn’t work is …

conditions:
  - condition: state
    entity_id: input_select.arming
    state:
      - Disarm
  - condition: not
    conditions:
      - condition: state
        variables:
          door: Shed door
        entity_id: sensor.sheddoor
        state:
          - closed
      - condition: state
        variables:
          door: Garage PA
        entity_id: sensor.garagepa
        state:
          - closed
... etcetera
actions:
  - action: notify.persistent_notification
    metadata: {}
    data:
      title: Warning !
      message: {{ door }} open
mode: single

That has never been supported.

alias: Alert - Home Door(s) not closed
description: Alert if door(s) not closed sunset+30min and 2215
triggers:
  - trigger: sun
    event: sunset
    offset: "1800"
  - trigger: time
    at: "22:15:00"
conditions:
  - condition: state
    entity_id: input_select.arming
    state:
      - Disarm
  - condition: not
    conditions:
      - condition: state
        entity_id: 
          - sensor.sheddoor
          - sensor.garagepa
          - sensor.garageposition
          - sensor.frontgate
        state:
          - closed
        match: all
actions:
  - variables:
      open_doors: |
        {% set doors =  ['sensor.sheddoor','sensor.garagepa','sensor.garageposition','sensor.frontgate'] %}
        {{  doors | reject('is_state', 'closed') | map('entity_name') | list | join(', ') }}
  - action: notify.persistent_notification
    metadata: {}
    data:
      title: Warning !
      message: |
        {{' and '.join(open_doors.rsplit(', ', 1))}} open
mode: single

Aaah, lovely. Thank you very much (yet again).

One tiny suggestion: the duplicated entities list can be removed by adding a variables section to the top level of the automation.

Thanks - I understand what you mean but am unsure of the syntax.

Maybe some tweaking needed.
I’m now seeing this error Message malformed: Entity sensor.sheddoor sensor.garagepa sensor.garageposition sensor.frontgate is neither a valid entity ID nor a valid UUID for dictionary value @ data['conditions'][1]['conditions'][0]['entity_id']

Each of the entities is a template sensor (defined in the templates.yaml file) - does that make a difference?

Updated automation

alias: Alert - Home Door(s) not closed
... etcetera
  - condition: not
    conditions:
      - condition: state
        entity_id: 
          sensor.sheddoor
          sensor.garagepa
          sensor.garageposition
          sensor.frontgate
        state:
          - closed
        match: all
actions:
  - variables:
      open_doors: |
        {% set doors =  ['sensor.sheddoor','sensor.garagepa','sensor.garageposition','sensor.frontgate'] %}
        {{  doors | reject('is_state', 'closed') | map('entity_name') | list | join(', ') }}
  - action: notify.persistent_notification
    metadata: {}
    data:
      title: Warning !
      message: |
        {{' and '.join(open_doors.rsplit(', ', 1))}} open
mode: single

and this is the template that creates sensor.sheddoor (the other 3 sensors are similar)

  - sensor:
    - name: sheddoor  # Shed door
      unique_id: 10240050
      state: >
        {% set shed1state = states('binary_sensor.shed1_input') %}
        {% if shed1state == "off" %} open
        {% elif shed1state == "on" %} closed
        {% else %} sensor error
        {% endif %}

Oops, fixed it. I omitted the dashes in front of the entities in the conditions

entity_id: 
  sensor.sheddoor
  sensor.garagepa
  sensor.garageposition
  sensor.frontgate

should be

entity_id: 
  - sensor.sheddoor
  - sensor.garagepa
  - sensor.garageposition
  - sensor.frontgate

One more complication. The entity_name is not quite what I want in the notification. The output is sheddoor, garagepa, garageposition and/or frontgate (depending on what’s not closed)

What I want is Shed door, Garage PA, Garage and/or Front gate. I have added an attribute to each template sensor, fullname, that contains the names I want.

Now I need to modify the map('entity_name') part to extract the attribute rather than the entity_name.
So, I tried this without success (no error - although one door open, the notification was blank)

{{  doors | reject('is_state', 'closed') | map(attribute='fullname') | list |
        join(', ') }}

Some further help would be most appreciated !

To get your custom attribute, you can use expand() on the list of entity ID to get a list of state objects.

{{  doors|reject('is_state', 'closed') | expand
| map(attribute= 'attributes.fullname') | list | join(', ') }}

or (probably the better way) map the state_attr():

{{  doors|reject('is_state', 'closed') | expand
| map('state_attr', 'fullname') | list | join(', ') }}

Yes, either entity ID contains a scalar value (e.g. entity_id: sensor.sheddoor) or it takes a list (that’s what the dashes denote).

Like this (using Drew’s original):

alias: Alert - Home Door(s) not closed
description: Alert if door(s) not closed sunset+30min and 2215
triggers:
  - trigger: sun
    event: sunset
    offset: "1800"
  - trigger: time
    at: "22:15:00"
variables:
  doors: 
    - sensor.sheddoor
    - sensor.garagepa
    - sensor.garageposition
    - sensor.frontgate
  # same as 
  # doors: ['sensor.sheddoor', 'sensor.garagepa', 'sensor.garageposition', 'sensor.frontgate']
conditions:
  - condition: state
    entity_id: input_select.arming
    state:
      - Disarm
  - condition: not
    conditions:
      - condition: state
        entity_id: "{{ entities }}"
        state:
          - closed
        match: all
actions:
  - variables:
      open_doors: |
        {{  doors | reject('is_state', 'closed') | map('entity_name') | list | join(', ') }}
  - action: notify.persistent_notification
    metadata: {}
    data:
      title: Warning !
      message: |
        {{' and '.join(open_doors.rsplit(', ', 1))}} open
mode: single

@Didgeridrew is better than me at this, so good if he double checked and agrees.

You can’t template in a State condition, so that would need to change to a Template condition.

alias: Alert - Home Door(s) not closed
description: Alert if door(s) not closed sunset+30min and 2215
triggers:
  - trigger: sun
    event: sunset
    offset: "1800"
  - trigger: time
    at: "22:15:00"
variables:
  doors: 
    - sensor.sheddoor
    - sensor.garagepa
    - sensor.garageposition
    - sensor.frontgate
conditions:
  - condition: state
    entity_id: input_select.arming
    state:
      - Disarm
  - alias: Check if any doors aren't closed
    condition: template
    value_template: |
      {{ doors | reject('is_state', 'closed') | list | count != 0 }}
actions:
  - action: notify.persistent_notification
    metadata: {}
    data:
      title: Warning !
      message: |
        {% set open_doors =  doors|reject('is_state', 'closed')
        |map('state_attr', 'fullname')|list|join(', ') %}
        {{' and '.join(open_doors.rsplit(', ', 1))}} open
mode: single

OK, thanks, easy when you know how :wink:

Well, I did not know that … and would never have worked out the solution - elegant :slight_smile:

Thank you to both of you - I really appreciate the time you guys devote to providing assistance.