Hello everyone. I’m pretty new the HA and I’m looking for a little assistance in setting up an automation for a door sensor. I’ve successfully setup the automation to notify me if the door has been open for more than 5 minutes. Is there a way to then be notified when this door that has been opened for more than 5 minutes is now closed?
id: door1_open_notification
alias: ‘Door 1 is open’
trigger:
platform: state
entity_id: sensor.door1
to: ‘Open’
for:
minutes: 5
condition:
action:
service: notify.door_notify
data_template:
title: ‘Door1 left open!’
message: ‘Door 1 has been open since {{states.zwave.ecolink_door_window_sensor.attributes.receivedTS}}.’
Creating an automation to announce the door is now closed is a simple task but wouldn’t be ideal. It would notify you every time the door was closed, even if it wasn’t left open for more than 5 minutes.
We can’t simply use a ‘for 5 minutes’ in the door-closure automation because we aren’t looking for the door to be closed for 5 minutes.
We want an automation that reports door-closure but only if the door was previously left open for more than 5 minutes.
Start by creating an input_boolean:
input_boolean:
door1_left_open:
name: Door1 Left Open
Modify your existing ‘Door Open’ automation so it turns on the input_boolean when the door opens. I assume the states you are using for sensor.door1 are correct? (‘Open’ and ‘Closed’) It’s usually ‘on’ and ‘off’.
- id: door1_open
alias: 'Door 1 is open'
trigger:
platform: state
entity_id: sensor.door1
to: 'Open'
for:
minutes: 5
condition: []
action:
- service: input_boolean.turn_on
entity_id: input_boolean.door1_left_open
Create a second automation for handling door closure. It turns off the input_boolean but only if it is already on.
- id: door1_closed
alias: 'Door 1 is closed'
trigger:
platform: state
entity_id: sensor.door1
to: 'Closed'
condition:
condition: state
entity_id: input_boolean.door1_left_open
state: 'on'
action:
- service: input_boolean.turn_off
entity_id: input_boolean.door1_left_open
Create one more automation that is triggered by the input_boolean. This automation is responsible for announcing Door1 is ‘left open’ or ‘is now closed’.
- id: door1_notifier
alias: 'Door 1 Notifier'
trigger:
platform: state
entity_id: input_boolean.door1_left_open
condition: []
action:
- service: notify.door_notify
data_template:
title: "{{ 'Door1 left open!' if trigger.to_state.state == 'on' else 'Door1 closed' }}"
message: >-
{% if trigger.to_state.state == 'on' %}
Door 1 has been open since {{states.zwave.ecolink_door_window_sensor.attributes.receivedTS}}.
{% else %}
Door1 has been closed.
{% endif %}
I haven’t tested it so it may require additional refinements. However, it should get you started down the right path. You can easily test the notification portion by manually toggling the input_boolean.
EDIT
Fixed typo. Replaced triggered.to_state with trigger.to_state in two places.
I think it depends on when the conditions are checked.
If the conditions are checked before the trigger is processed it will work. If not then it won’t.
I was in a thread a while ago in which we mostly determined from the functioning of an automation that the conditions are evaluated before the trigger. So in that case it should work.
I always thought the triggers were evaluated and then the conditions until that thread showed that it’s not that straight forward.
I’d really appreciate a link to that thread because the theory it proposes contradicts the basic operation of an automation.
The trigger is what Home Assistant monitors (creates ‘listeners’). When the listener detects an appropriate change, it executes the balance of the automation and proceeds to evaluate the conditions (if any). It’s the trigger that gets the ball rolling.
For the condition to be evaluated before the trigger, implies the automation was not activated by its trigger but by its condition. The implication is that Home Assistant has also created listeners for the condition. That’s unlikely. If you create an automation with a condition but no trigger, Home Assistant will force the automation to be off because it’s not a functional arrangement; it has no listener(s).
FWIW, I recall discussing this topic about ~3 weeks ago and I posted an example demonstrating the condition is evaluated after the automation is triggered. If you know of examples where the condition is evaluated before the trigger, I would very much like to see them.
Not sure what you guys were testing but triggers are what home assistant listens to and reacts from. conditions are evaluated after the trigger occurs. Otherwise passing the trigger object to conditions wouldn’t be possible. You get yourself into a what came first, chicken or the egg. Conditions use the trigger object, therefore the trigger had to occur prior to the condition. Also, I’ve looked at the code.
However, re-reading the thread, it didn’t evaluate the conditions first before the entire trigger. It seemed to evaluate the conditions before the “for:” part of the trigger. I remember doing some testing at the time and I think I got the same results as him.
but now looking at that then the above proposed code wouldn’t work. unless you put a “for:” in the trigger then it might still work.
to clarify, test to see if the door goes closed for a few seconds in the trigger and keep the condition as the door open for 5 minutes to see if the automation fires.
i’m not saying in any of this that it definitely works that way and as i said i was surprised to see that result too since it contradicted my understanding at the time. however, it seemed to have been tested and confirmed at least in that scenario.
OTOH, as shown in the recent thread about the two light scenario in which the OP was trying to get either light to follow the state of the other and it didn’t work as expected for both you and the OP and it worked exactly as it should for me that here are definitely some little unexplainable glitches in the system at times.
The condition can never be true. The event that led to the condition’s evaluation is the exact opposite state of what the condition requires.
I concur there may be glitches but that lighting issue had the earmarks of a timing problem (possibly related to propagation delays in the lighting protocols used). In this case, it’s a matter of the order of execution, namely trigger before condition and not the other way around (see Petro’s post).
Finally got around to trying this out. I’m getting an error stating “Error rendering data template: UndefinedError: ‘triggered’ is undefined”. I’m pretty sure it’s referring to the trigger on the door1_notifier automation but I can’t figure out the issue.
FYI, no difference if I manually toggle the boolean or let the door sensor toggle it.
- id: door1_open
alias: 'Door 1 is open'
trigger:
platform: state
entity_id: sensor.door1
to: 'Open'
for:
minutes: 1
condition: []
action:
- service: input_boolean.turn_on
entity_id: input_boolean.door1_left_open
- id: door1_closed
alias: 'Door 1 is closed'
trigger:
platform: state
entity_id: sensor.door1
to: 'Closed'
condition:
condition: state
entity_id: input_boolean.door1_left_open
state: 'on'
action:
- service: input_boolean.turn_off
entity_id: input_boolean.door1_left_open
- id: door1_notifier
alias: 'Door 1 Notifier'
trigger:
platform: state
entity_id: input_boolean.door1_left_open
condition: []
action:
- service: notify.door_notify
data_template:
title: "{{ 'Door1 left open!' if triggered.to_state.state == 'on' else 'Door1 closed' }}"
message: >-
{% if triggered.to_state.state == 'on' %}
Door1 has been open since {{states.zwave.ecolink_door_window_sensor.attributes.receivedTS}}.
{% else %}
Door1 was closed at {{states.zwave.ecolink_door_window_sensor.attributes.receivedTS}}.
{% endif %}
I think that if you use a trigger with a “for” to specify a time the condition is only evaluated at the start; and not re-evaluated at the end of the for wait time. So if the condition changes during the “for” it does not impact the trigger.
I have proved this with several automations; and the fix is to duplicate the condition at the start of the action section as this will get evaluated once the trigger is triggered.
I’ve not dug into the code to find this; but presume a “for” sets up a callback timer and the condition is checked then that occurs; and not when the timer expires.
Let me lay it out to you so you understand better:
non-for trigger flow:
trigger -> condition -> action
for trigger flow:
trigger -> condition -> wait for duration -> action
Your experience is exactly what I’m describing. Conditions are always after triggers. No matter what. You for some reason are lumping the for duration into the trigger, that’s not the case.
I was assuming the “wait” was part of the trigger and not evaluated after the condition.
So this means as long as the condition is valid when the trigger is valid we pass to the wait; and if the condition changes during that wait it is irrelevant to the action being performed once wait is passed.
I do assume the trigger continues to be evaluated during the wait so that if it state changes so the wait duration is not met; then it exits and the entire cycle starts again.