I want to build a simple automation that runs a 10 pm and, if one of my binary sensors (xiaomi doors sensors) are open, trigger a notification on telegram.
I’ve built the trigger and condition part but I’m unable to build the action part.
I “feel” that I have to use the loop function but how can I select only a specific range of sensor and not a generic category (exclude others binary sensors).
Thank you for your feedback. I’ve already set up the automation this way. What I would like to achieve is the chance to see which one is open without have to check on the frontend.
First make a group with all your door sensors in it. Also, make sure the state of all your door sensors will always be ‘on’ or ‘open’ when the door is ajar.
For this example, i will use the group: group.all_doors. Also, note this will only message you if doors are open at 10pm. Otherwise, you won’t get a message.
automation:
alias: "check all doors at 10PM"
trigger:
- platform: time
at: '22:00:00'
condition:
condition: template
value_template: >
# this counts the doors that are open and if we have any that are open, the notify will occur
{{ states | selectattr('entity_id', 'in', state_attr('group.all_doors','entity_id')) | selectattr('state','in',['on','open']) | list | length >= 1 }}
action:
- service: notify.notify
data_template:
title: "Doors Open!"
message: >
{% set open_doors = {{ states | selectattr('entity_id', 'in', state_attr('group.all_doors','entity_id')) | selectattr('state','in',['on','open']) | list | map(attribute='name') | join(', ') }}
The following doors are open: {{ open_doors }}
here’s an example of it working with doors that are closed ( i did this cause my doors are closed atm).
automation:
alias: "check all doors at 10PM"
trigger:
- platform: time
at: '22:00:00'
condition:
condition: template
value_template: >
# this counts the doors that are open and if we have any that are open, the notify will occur
{{ states | selectattr('entity_id', 'in', state_attr('group.all_doors','entity_id')) | selectattr('state','in',['on','open']) | list | length >= 1 }}
action:
- service: notify.notify
data_template:
title: "Doors Open!"
message: >
{% set open_doors = states | selectattr('entity_id', 'in', state_attr('group.all_doors','entity_id')) | selectattr('state','in',['on','open']) | map(attribute='name') | list %}
{% if open_doors | length == 1 %}
The {{ open_doors[0] }} door is open.
{% else %}
The {{ open_doors[:-1] | join(' door, ') }}{{' door,' if open_doors | length > 2 else ' door'}} and {{ open_doors[-1]}} door are open.
{% endif %}
single door sentance:
The front door is open.
double door sentance:
The front door and side door are open.
more than 2 doors sentance:
The front door, side door, and back door are open.
EDIT: I placed the word door behind the name because “Door Front” doesn’t make sense.
EDIT 2: The reason you can’t use the loop that you keep referencing is because the way jinja works. Jinja can only return 1 result. When iterating around a loop, it would return multiple items. This would cause your message to only output the last loop item instead of segmenting the message together.
Found this topic, even if is an old one I thought it would be useful to share my ideas:
what I wanted to achieve was to ask Google if there were open doors/windows and, if yes, which ones.
I decided to go for a python script:
cur_state = hass.states.get('group.aperture')
if (cur_state.state == "off") :
hass.services.call('tts', 'google_say', {"entity_id":"media_player.spione","message":"all is closed"})
else :
i = 0
openings = []
for a in cur_state.attributes["entity_id"]:
temp_state = hass.states.get(a)
if (temp_state.state == "on") :
i = i + 1
openings.append(a)
if (i == 1) :
message = "there is one opening that's not closed"
hass.services.call('tts', 'google_say', {"entity_id":"media_player.spione","message":message})
else :
message = "there are " + str(i) + " openings not closed"
hass.services.call('tts', 'google_say', {"entity_id":"media_player.spione","message":message})
for b in openings :
time.sleep(3)
temp_state = hass.states.get(b)
hass.services.call('tts', 'google_say', {"entity_id":"media_player.spione","message":temp_state.attributes["friendly_name"]})
basically, I have a group in which I put all the door sensors, check if off and, if not, cycle all the entities to find how many are open; contextually I put in an array which ones. Later I cycle again to make google say the friendly name of everyone that is open.
I cant for the life of me get this working. Both template statements work in the editor, but will not work in my automations. Gives this error
Invalid config for [automation]: invalid template (TemplateSyntaxError: expected token ‘:’, got ‘}’) for dictionary value @ data[‘action’][0][‘data_template’][‘message’]. Got “{% set open_doors = {{ states | selectattr(‘entity_id’, ‘in’, state_attr(‘group.doors’,‘entity_id’)) | selectattr(‘state’,‘in’,[‘on’,‘open’]) | list | map(attribute=‘name’) | join(', ')}} The following doors are open: {{ open_doors }}”.
id: ‘1234321234532’
alias: Door Status
trigger:
- platform: time
at: ‘22:00:00’
condition:
condition: template
value_template: >
# this counts the doors that are open and if we have any that are open, the notify will occur
{{ states | selectattr(‘entity_id’, ‘in’, state_attr(‘group.doors’,‘entity_id’)) | selectattr(‘state’,‘in’,[‘on’,‘open’]) | list | length >= 1 }}
action:
- service: notify.alexa_media
data_template:
title: Doors Open
message: >
{% set open_doors = {{ states | selectattr(‘entity_id’, ‘in’, state_attr(‘group.doors’,‘entity_id’)) | selectattr(‘state’,‘in’,[‘on’,‘open’]) | list | map(attribute=‘name’) | join(', ')}}
The following doors are open: {{ open_doors }}
your last emplate is wrong. you can’t embed templates in templates.
{% set open_doors = ( states | selectattr('entity_id', 'in', state_attr('group.doors','entity_id')) | selectattr('state','in',['on','open']) | list | map(attribute='name') | join(', ') ) %}
The following doors are open: {{ open_doors }}
I haven’t checked it for the right ( ) pairings since there are bunch of them nested so you’ll have to double check those. But it will be close.
I also just noticed I used the wrong style of quotation marks in the template. I used the “fancy” style instead of the standard text ones because I just did a copy/paste of your post. You probably noticed that if you have it working but I edited the post for the sake of completeness.
gotten this to work when manually executing but it wont trigger the automation on its own…
automation:
- id: Door Check
alias: Door Check
trigger:
- platform: state
entity_id: group.life360
from: home
to: not_home
- platform: time
at: '15:24:00'
condition:
condition: template
value_template: >
# this counts the doors that are open and if we have any that are open, the notify will occur
{{ states | selectattr('entity_id', 'in', state_attr('group.all_doors','entity_id')) | selectattr('state','in',['on','open']) | list | length >= 1 }}
action:
- service: notify.ios_marks_iphone_xr
data_template:
title: "Caution!"
message: >
{% set open_doors = states | selectattr('entity_id', 'in', state_attr('group.all_doors','entity_id')) | selectattr('state','in',['on','open']) | map(attribute='name') | list %}
{% if open_doors | length == 1 %}
The {{ open_doors[0] }} door is open.
{% else %}
The {{ open_doors[:-1] | join(', ') }}{{',' if open_doors | length > 2 else ' door'}} and {{ open_doors[-1]}} door are open.
{% endif %}