Automation help: Notification if door is closed after being open for 20 seconds or more

Hello everyone

I am trying to set up an automation that will notify me when the front door has been closed after being open for 20 seconds or more.
I already have the automation to get a notification when it’s open for 20 seconds set up, but it would be very handy to know if it actually gets closed later.

I’ve tried a few things like the History Statistics Sensor and conditions in an automation triggered by state change, but I am simply not clever enough to figure this out on my own.

Perhaps it would work if I’d make a input_boolean that gets turned on when the front door has been open for 20 seconds, and make another automation that runs when the door is closed, with a condition checking if the input boolean is on.
However this does not look like the most efficient way of doing this.

Any input would be greatly appreciated!

I disagree. With the current limitations of the automations in home assisstant, this is probably the easiest and most robust implementation. I’d add the input_boolean.

I’d agree, input_boolean is probably the best way to do it.

My only other suggestion would apply if you’re interested in exploring AppDaemon. You could migrate your listener there to check whether the door’s been open for 20 seconds and notify, and then along with notifying set up a one-off listener to notify you when the door’s been closed. If you’re interested, @nickjedl, I can walk you through it in more detail.

Here’s one I use for my garage door

- id: GarageDoorOpen
  alias: Garage Door Open
  trigger:
    platform: state
    entity_id: sensor.garage_status
    to: Open
    for:
      minutes: 5
  action:
  - service: notify.google_broadcast
    data_template:
      message: The garage has been open for over 5 minutes

I don’t have AppDaemon set up yet, so I’ll probably go with the input_boolean method. Thanks anyway!

1 Like

That’s what I already had set up, thank you anyway!

You could replace what you currently have with the alert component.

# Alert for Garage Door having been open for 5 minutes
alert:
  garage_door_open_long:
    name: Garage Door is still open!
    entity_id: binary_sensor.garage_door_sensor
    state: 'off'   # Optional, 'on' is the default value
    repeat: 5
    can_acknowledge: true  # Optional, default is true
    skip_first: false # Optional, false is the default
    notifiers:
      - mypushbullet

and the alert will stop once the door has been closed.

Not sure, though, if it fits with what you’re trying to achieve, especially if it can be set it up to send the first alert after less than a minute.

Just coming back/resurrecting this - given the various changes since April 2019, is the use of an input_boolean and two trigger automations still seen as the best way to handle this?

Here is my full block of automations to tackle this

#######################################################################
#  Notify if doors open for more than 5 minutes                       #
#######################################################################
- id: detect_if_doors_open_for_long
  alias: Detect if doors open for more than 5 minutes
  mode: single
  initial_state: 'on'
  trigger:
    - platform: state
      entity_id:
        - binary_sensor.front_door
        - binary_sensor.back_door
      from: 'off'
      to: 'on'
      for:
        minutes: 5
  action:
    - service: input_text.set_value
      data_template:
        entity_id: input_text.last_door_open_long
        value: '{{ trigger.to_state.attributes.friendly_name }}'  

- id: notify_if_doors_open_for_long
  alias: Notify if doors open for more than 5 minutes
  mode: single
  initial_state: 'on'
  trigger:
    - platform: time_pattern
      seconds: '/30' #check every 30 seconds
  condition:
    condition: or
    conditions:
      - condition: and
        conditions:
          - condition: state
            entity_id: binary_sensor.front_door
            state: 'on'
          - condition: template
            value_template: '{{ ((as_timestamp(now()) - as_timestamp(states.binary_sensor.front_door.last_changed) | default(0)) | int) > 300 }}' #300= 5 minutes
          - condition: state
            entity_id: input_boolean.notify_about_doors_ajar
            state: 'on'
      - condition: and
        conditions:
          - condition: state
            entity_id: binary_sensor.back_door
            state: 'on'
          - condition: template
            value_template: '{{ ((as_timestamp(now()) - as_timestamp(states.binary_sensor.back_door.last_changed) | default(0)) | int) > 300 }}' #300= 5 minutes
          - condition: state
            entity_id: input_boolean.notify_about_doors_ajar
            state: 'on'
  action:
    - service: script.notification
      data_template:
        message_text: "Warning, the {{ states.input_text.last_door_open_long.state }} has been left open for more than 5 minutes. Please close."

The requirements in the first post can now be fulfilled with a single automation (and no input_boolean).

Any more detail on how?

(In my use case I want to do a notification when a door closes after being open 2 hours, based on the door sensor changing state to “off”)

Not the bit I’m interested in - I’ve got a reminder to close the door after 15 minutes that I’m happy with.

(BTW - does the notification in your code actually go off every 30 seconds??)

State Trigger when door changes from on to off followed by a State Template Condition subtracting the door’s last_changed from now(). If the difference exceeds 2 hours, the condition is met and it proceeds to execute the action (containing the notification).

1 Like

Yep… I want the doors closed quickly. And my Telegram has a ton of messages. I want to know that something or someone is trying to get to me every 30 seconds… I have a good ear for evenly spaced out notifications :slight_smile:

1 Like

So this is the code I wrote:

alias: 'NOTE: reminder to turn off flyspray if door open for at least 2 hours'
id: note__turn_off_fly_spray
initial_state: true
trigger:
  platform: state
  entity_id: binary_sensor.door_window_sensor_158d0001ef33b1
  to: 'off'
condition: >-
  {{ as_timestamp( now() ) - as_timestamp(
  states.binary_sensor.door_window_sensor_158d0001ef33b1.last_changed ) >= 7200
  }}
action:
  service: notify.google_assistant
  data:
    message: Don't forget to turn off the flyspray

But despite it being 2+ hours between open and close, the condition parses as false (according to the the automation trace).

I suspect by the time the trigger fires, the last_changed is already updated. And the intiial variable change dump from the trace suggests this too…

this:
  entity_id: >-
    automation.note_reminder_to_turn_off_flyspray_if_door_open_for_at_least_2_hours
  state: 'on'
  attributes:
    last_triggered: '2021-10-05T05:50:23.835748+00:00'
    mode: single
    current: 0
    id: note__turn_off_fly_spray
    friendly_name: 'NOTE: reminder to turn off flyspray if door open for at least 2 hours'
    hide_attributes:
      - templates
  last_changed: '2021-10-05T06:04:13.196372+00:00'
  last_updated: '2021-10-05T06:04:13.196372+00:00'
  context:
    id: 2ce2416cb0b96bffd56ab8e3908d7b99
    parent_id: null
    user_id: null
trigger:
  id: '0'
  idx: '0'
  platform: state
  entity_id: binary_sensor.door_window_sensor_158d0001ef33b1
  from_state:
    entity_id: binary_sensor.door_window_sensor_158d0001ef33b1
    state: 'on'
    attributes:
      Open since: '300'
      voltage: 3
      battery_level: 39
      friendly_name: Stacker Doors
      device_class: door
      hide_attributes:
        - templates
      templates:
        icon_color: >-
          if (state === 'on') return 'red'; else if (state === 'off') return
          'green'; else return 'blue';
    last_changed: '2021-10-05T23:10:46.005747+00:00'
    last_updated: '2021-10-05T23:15:45.528820+00:00'
    context:
      id: 2d412e95c83dc1cbf7cb8ecf517dc812
      parent_id: null
      user_id: null
  to_state:
    entity_id: binary_sensor.door_window_sensor_158d0001ef33b1
    state: 'off'
    attributes:
      Open since: 0
      voltage: 3
      battery_level: 39
      friendly_name: Stacker Doors
      device_class: door
      hide_attributes:
        - templates
      templates:
        icon_color: >-
          if (state === 'on') return 'red'; else if (state === 'off') return
          'green'; else return 'blue';
    last_changed: '2021-10-06T02:34:19.741573+00:00'
    last_updated: '2021-10-06T02:34:19.741573+00:00'
    context:
      id: 75cea1f9f68566e3620c1a9aa719d279
      parent_id: null
      user_id: null
  for: null
  attribute: null
  description: state of binary_sensor.door_window_sensor_158d0001ef33b1

I presume I should actually be using something like last_triggered instead?
nope - last_triggered will only show when the full trigger ran including the condition.

SO - how to access the last_changed before it changed?

You want to know the time when the binary_sensor changed to on (before it changed to off). That’s in last_changed but not the one in the entity (because it got updated the instant the binary_sensor changed state to off). The last_changed you want is in the trigger variable. Look at the trace dump. It’s in trigger.from_state.last_updated

from_state contains information about the entity’s previous state.

1 Like

thanks - appreciate the help.