Automation: trigger state to 'open', but only after time condition?

Hello,

I am working to create an automation that closes a garage door after 8pm if it has been open for more than 5 minutes.

All of the payload etc. are functioning, if I trigger it manually it works as expected. However, the trigger/condition is not quite working correctly, and I get the sense that part of the issue is the “for” trigger. If I’m understanding correctly, the condition will be met if the door has been open for any cumulative 5 minutes as reported from throughout the entire day.

What I’m actually trying to achieve is: “if the door state is ‘open’ for any 5 contiguous minute window only after 8PM, then fire the action”.

I looked at the trigger docs here, but as far as I understand, that “to” state “for” reads from the entire day, and could read true if the door has ever been open for more than 5 minutes. Am I overthinking this?

Here’s the automation so far:

- id: '1561920307144'
  alias: Garage Door Reminder - Tommy
  trigger:
    platform: state
    entity_id: cover.sonoff_sv_garage
    to: 'open'
    for:
      hours: 0
      minutes: 5
      seconds: 0
  condition:
  - after: '20:00:00'
    condition: time
  action:
  - data:
      message: Garage door was closed after being left open
      title: 'Glasgow Bay:'
    service: notify.ios_tommys_iphone
  - data:
      payload: 'ON'
      topic: sonoff/cmnd/POWER1
    service: mqtt.publish

Any help is much appreciated, thank you!

You are over thinking it, kind of.

The “for” of a trigger works if it’s been in that state continuously for the length of time you’ve requested. So, in that way, this automation works.

The issue with it is, if your door opens at 19:00:00 and never closes, at 20:00:00 this won’t fire. You need to add the 20:00:00 time as a trigger as well. And, because you have two triggers, you need to add the door open for 5 minutes as a condition. So you’ll have two triggers, and, basically, the exact same two conditions. Then, if it’s been open for 5 minutes continuously, and it’s after 20:00:00 it’ll close.

And to clarify a bit more…

the trigger will be “instantaneously” true if the door has been open fort 5 minutes. once the trigger becomes true for that one instant in time it will no longer be true and will never be true again until the trigger definition becomes untrue then becomes true again (the door closes and then reopens for 56 minutes). The trigger doesn’t wait around staying true waiting for the condition to be satisfied.

So, to expand on the example above, if you open the door at 19:00:00.00 and it stays open for 5 minutes then the trigger becomes true at 19:05:00.00 and it will immediately become not true again (at say 19:05:00.01). then if the door stays open until after 20:00:00 the condition becomes satisfied but the trigger is no longer satisfied because it has already come and gone 55 minutes earlier.

That’s why you need to add another trigger at 20:00:00 with the condition that the door also needs to have been open for at least 5 minutes.

The over all idea here is correct, but the implementation is not.

Triggers don’t “become true”. They are instantaneous moments in time that say “this thing happened”. And every time that thing happens they will trigger again.

So in the case of a “open for 5 minutes” trigger… it triggers when the door is open for five minutes. It does not trigger again when the door is open for 5 minutes and 1 second. If it did, the automation would trigger every second, until the trigger values were no longer met, which, in the case of closing a door might make sense. But, in the case of just about anything else it makes no sense. Imagine if I have a trigger that says “when motion is detected” and an action of “turn on the lights”. The system would keep turning on the lights every second (or whatever) for the entire time I was in the room. If I turned off a light manually, it would turn right back on.

You have to think of triggers as “things that happen” not as “conditions that are present”. That’s what conditions are for. Which is why I have automations that look like this:

- trigger:
    - platform: state
      entity_id: binary_sensor.living_occupied
      to: 'on'
      from: 'off'
    - platform: state
      entity_id: input_select.living_mode
      to: 'normal'
    - platform: state
      entity_id: input_select.house_mode
      to: 'sleep'
  condition:
    - condition: template
      value_template: >-
        {{
          is_state('binary_sensor.living_occupied', 'on') and
          is_state('input_select.living_mode', 'normal') and
          is_state('input_select.house_mode', 'sleep')
        }}

Any of those triggers can happen, and then the condition is evaluated.

There’s a miss conception here.

For triggers trigger exactly when the state changes. In @ThomasPatrick’s post, it will trigger as soon as the state changes to ‘open’. At this point it checks the condition and if it passes, creates a listener. This listener will watch the state. If the state stays ‘open’ the entire duration of the for, it executes the action. If it does not, it cancels the listener. It will not trigger again until the state changes to ‘open’.

1 Like

I’m not really sure where the disconnect in communication is but I’m pretty sure I said exactly that in my post above.

In summary my post was ssying “The trigger becomes true at exactly the moment the door has been open for 5 minutes and then it instantaneously becomes not true again. And it won’t become true again until the state changes from open to some other state then back to open again for 5 minutes.”

And in a logic driven system the triggers must be thought of as becoming “true” to make sense of what is happening whether it is an event happening causing the underlying logic to become an instaneous “1” or some other thing.

EDIT: see post 9.

And @petro thanks for clarifying the underlying mechanism that the system uses to determine when the automation trigger becomes “true”.

If I understand what you are saying then for example if we had a “for: 6 hours” statement in the trigger then st the moment the door opens it checks that the conditions are true then waits 6 hours and if the door never becomes not open then the actions occur no matter what the current state of the conditions are? The conditions are only checked at the instant the state of the trigger changes to open not when the “for:” statement is satisfied?

1 Like

Yep, they are only checked at the start. This has burned a few people in other threads.

If you want the condition to be checked for the entire duration of the for. Use a template trigger with the conditions built into the trigger. This is new functionality, @pnbruckner added the for ability to template triggers in 95 or 96.

If you want the condition to be checked right after the for duration. Place the condition in the list of actions.

1 Like

WOW! I had no idea. Obviously, I don’t use “for” triggers very often or this would have bitten me already. Good to know, though. Thank you!

Um, no, that’s not true. A trigger with a for specified does not actually “trigger” until the for requirement has been satisfied. Only at that time (i.e., after the for period has expired, where the trigger specification has been met for the whole period) will the condition be evaluated.

As a concrete example, the condition in the OP will only be evaluated after the cover has been open for 5 minutes. So if the cover opens at 19:55:00, and stays open until 20:00:00 (i.e., for 5 minutes), the actions will run.

1 Like

Last time I debugged into it, the condition was checked prior to creating the listener. Unless that was a bug. This was maybe 2 months ago, prior to your for template changes. Hell, I think you responded in that thread too.

The code is definitely a bit difficult to follow. But I just did a test with a state trigger. The condition was definitely not tested until the for period expired.

I’m pretty sure the condition is tested here. This is in a common function (async_trigger) that is called whenever a trigger fires, no matter what the trigger type is, or whether or not the trigger’s for option is used/satisfied.

I have no clue where I was looking before. Maybe the fire event bus. Either way, it does appear as if the condition is checked after the listener.

Looks like some posts above need editing to minimize future confusion.