- alias: 'Garage: Notify Open'
id: b4dddc0a-1212-42ac-aba5-75236ed4c498
trigger:
- platform: state
entity_id: cover.small_garage_door_homekit
to: open
for: "00:00:10"
action:
- repeat:
until: "{{ is_state('cover.small_garage_door_homekit', 'closed') }}"
sequence:
- service: notify.alexa_media
data:
data: { type: announce }
message: 'Small garage door is open'
target: media_player.everywhere
- delay: "00:00:30"
The goal is to announce on all echos in the house when my garage door has been open for a certain period of time. That announcement should be repeated (with a delay) for as long as that door remains open.
The above YAML works fine for a single garage door, but I have two doors. I could simply copy & paste this for the 2nd entity, but I’m worried about two announcements happening at the same time, assuming both doors are opened simultaneously.
Is there a clever way to combine both entities into this logic? I’d be OK with 1 interval/timer to handle 2+ doors, and the message just changes depending on the combination:
Both doors open: “Big and small garage doors are open”
Only small garage door open: “Small garage door is open”
Only big garage door open: “Big garage door is open”
This is just a thought; I am open to whatever is easiest / most reasonable.
One issue with this compared to the first is that the notification will give the names of @voidpointer 's non-garage covers that are open as well.
I know it’s closer to what OP asked for, but I fail to see the point… it’s just as many lines and I’m pretty sure it would actually increase the amount of processing needed to render the template.
I thought that this might be a case where you could use the trigger_variables key, but that doesn’t seem to work either.
That is true but I don’t have any other covers and made the assumption that they might not have any either.
If so then a different solution will need to be used or just revert to the original.
I guess you could use the device class attribute as another filter to only select garage doors.
{% set open = (states.cover
| selectattr('attributes.device_class', 'defined')
| selectattr('attributes.device_class', 'eq', 'garage_door')
| selectattr('state', 'eq', 'open')
| map(attribute='name')
| list)
%}
{% set count = open | count %}
{% if count == 1 %}
The {{ open | join(',') }} is open.
{% elif count == 2 %}
The {{ open | join(',') | replace(',' , " and ") }} are open.
{% elif count > 2 %}
The {%- for item in open -%}
{{item}}{% if not loop.last %}, {% endif %}{% if loop.revindex == 2 %} and {% endif %}
{%- endfor %} are open.
{% else %}
no doors are open
{% endif %}
I did some more tinkering and eventually got this to work nicely in a clean way. @finity was an absolute huge help in pushing me in the right direction. I’ve learned a lot. I ended up using a Group to define the list of garage doors I care about and have the automation operate on that. The group is a great way to make this automation scalable. If I want to add more covers, all I need to do is update the group. I don’t need to touch the automation.
In the automation itself, in addition to cleaning this up with a group, I also cleaned up the if/elseif conditions to use a more generic way of joining the entity names for more than 1 entity. It works for both 2 and >2 scenarios.
Automation:
- alias: "Garage: Notify Open"
id: b4dddc0a-1212-42ac-aba5-75236ed4c498
trigger:
- platform: state
entity_id: group.garage_doors
to: open
for: "00:30:00"
action:
- repeat:
until:
- condition: state
entity_id: group.garage_doors
state: closed
sequence:
- service: notify.alexa_media
data:
data: { type: announce }
target: media_player.everywhere
message: >
{% set open = (expand('group.garage_doors')
| selectattr('state', 'eq', 'open')
| map(attribute='name')
| list)
%}
{% set count = open | count %}
{% if count == 1 %}
The {{ open[0] }} is open.
{% elif count > 1 %}
The {{ open[:-1] | join(', ') }} and {{ open[-1] }} are open.
{% else %}
No doors are open.
{% endif %}
- delay: "00:05:00"
I hope this gives back a little bit for all the help. Thanks to you all.