Door sensor notification help

Thanks 123, makes a lot of sense to use a state variable. I’ll try this out later tonight and see how it goes.

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.

Another good one to experiment with I think.

I’ll give this a try as well and post my results. Thanks everyone for the suggestions so far.

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.

It’s the same contradiction.

  • Trigger: Door is closed for X seconds.
  • Condition: Door is open for X minutes.

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 %}

That’s my fault. A little too fast on the keyboard …

In data_template, there are two instance of the word triggered. Replace them with trigger.

I’ve corrected the example in my original post (above).

Thank you! All is working normally now. You’d think the “undefined” would have given me a clue. :roll_eyes:

Hi Petro,

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.

Yes but the trigger still occurs before the condition is checked. Actions occur after the time is hit, the action is in the callback.

My experience is a bit different, please see this thread for an example:

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.

Thanks, that clarifies it for me.

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.

Yes. But you can add a condition in the action section to have it check when the action fires.

Yep, but only the triggers state affects this, not the condition.

@jwelter
Can you amend your linked post? Either explain the original theory was incorrect (about conditions allegedly being evaluated before triggers) and/or include a link to Petro’s excellent explanation above.

The reason for my suggestion is because I’ve had this conversation in the past, with finity, and that linked post was supplied as evidence of ‘spooky behavior’. It didn’t take me long to refute it (I even included the results of experiments disproving the alleged behavior) but it would be best if others didn’t continue to use it to support this mistaken theory.

Yes, but the issue is this behavior is not documented anywhere in the docs.

They clearly state that a condition applies after the trigger. But what none of the documents states that if you use a “for” as part of a trigger it is not assumed to be part of the trigger.

I know many people who have spent much time struggling on this…

It may be a foreign concept to you but it’s pretty normal in software. The trigger occurs, the condition is there to basically ask “should i fire this trigger or not”. If the trigger is getting fired… then perform the duration (or action if there is no for loop).

I’ve carried out the following experiment twice with identical results. I encourage others to try it for themselves.

The automation uses both for and condition:
Trigger: the input_boolean must be on for 4 minutes (a 4-minute timer).
Condition: only within a specific 10-minute time span (08:20 - 08:30).
Action: toggle a light.

- alias: 'for and condition tester'
  trigger:
    platform: state
    entity_id: input_boolean.toggler
    for: '00:04:00'
  condition:
    condition: time
    after: '08:20:00'
    before: '08:30:00'
  action:
    - service: light.toggle
      entity_id: light.family

To understand the interaction between for and condition it is instructive to observe the automation’s behavior at the condition’s boundaries (see ‘period A’ and ‘period B’ in the chart below). In other words, how does it behave when we trigger it just before 08:20 and 08:30?

The test begins at 08:18 which means the 4-minute period spans the start of the condition (at 08:20). Four minutes later, the light changes state to on.

  • 08:18 input_boolean set to on
  • 08:22 light turns on

A minute later, we toggle the input_boolean in order to restart the 4-minute timer. Four minutes later, the light changes state to off.

  • 08:23 input_boolean set to off then on
  • 08:27 light turns off

A minute later, we toggle the input_boolean in order to restart the 4-minute timer. Four minutes later, the light remains off.

  • 08:28 input_boolean set to off then on
  • 08:32 light remains off
input_boolean:   off/on              off/on              off/on
        light:    off          on      |          off      |          off
    condition:     |   08:20===|=======|===========|=======|===08:30   |
                   |-----|-----|-------|-----------|-------|-----|-----|
         time:   08:18       08:22   08:23       08:27   08:28       08:32
      periods:     |=====A=====|                           |=====B=====|
  • For period A, spanning 08:20, the light is turned on at 08:22 because the end of period A is within the condition’s time span (08:20 - 08:30).

  • For period B, spanning 08:30, the light remains off at 08:32 because the end of period B is not within the condition’s time span (08:20 - 08:30).

The results of this experiment show the condition is evaluated after for's time period has expired.

1 Like