Home Assistant Guide

Simple tutorials for powerful automations

Door & Window “Left Open” Alert Blueprint for Home Assistant

This Home Assistant blueprint monitors any selected doors, windows, or covers and alerts you if one stays open too long. It works with binary sensors (device class opening, door, window, garage_door) and covers (e.g., garage doors or smart windows). You can also enable repeating alerts that remind you every few minutes until the entity is closed.

What Does This Blueprint Do?

This automation watches for a door, window, or cover that remains open beyond a time you choose. If triggered, it sends a notification to your selected mobile device and can optionally keep sending reminders until the item is closed.

  • Detects if any selected sensor has been open for too long
  • Sends a mobile notification after the specified time
  • Optionally repeats the notification every few minutes until closed
  • Works independently for each selected entity

How to Add This Blueprint to Home Assistant

  1. Import the Blueprint
    Click the Import Blueprint button or link at the top of this article.
    If prompted in Home Assistant, review the YAML and click Import.
    Alternative: Go to Settings > Automations & Scenes > Blueprints, click Import Blueprint, paste this blueprint’s raw YAML URL, then click Preview > Import.
  2. Create an Automation from the Blueprint
    After import, find “Left Open Alert (doors/windows & covers)” under Settings > Automations & Scenes > Blueprints and click Create Automation.
  3. Fill in the Inputs
    • Sensors / Covers: Select one or more entities (door, window, or cover).
    • Open for at least: How long it must stay open before you’re notified (default: 10 minutes).
    • Device to notify: Choose your mobile app device (e.g., your phone).
    • Repeat until closed? Turn on if you want reminders until the entity closes.
    • Repeat every: The interval between reminders (default: 5 minutes).
  4. Save & Test
    Click Save to enable the automation. Open a door or window for longer than your chosen duration to test the notification.

Example Uses

  • Warn if the front door is left open more than 5 minutes
  • Remind you when the garage door has been open too long
  • Notify if a window is still open at night
  • Alert if the balcony door is open while you’re away

How It Works

The automation triggers whenever any selected entity remains open for the specified time. It immediately sends a notification to your chosen mobile device. If repeat notifications are enabled, it waits for the chosen interval, checks if the entity is still open, and repeats until it’s closed.

The blueprint supports both binary sensors (state on/off) and covers (state open/closed) and runs independently for each monitored entity.

Tips & Customization

  • Notification Customization: You can edit the notify.notify action in the YAML if you prefer to use a specific notification service.
  • Multiple Sensors: Each open entity triggers its own timer, so alerts won’t interfere with one another.
  • Extended Use: You can adapt this blueprint for covers, gates, or even moisture sensors (e.g., "tap left on" warnings).

Troubleshooting

  • Sensor never triggers? Check that your entity actually changes to on (for binary sensors) or open (for covers) when opened.
  • Notification not received? Ensure the selected device has the Home Assistant Companion App installed and notifications enabled.
  • Repeats too quickly? Increase the “Repeat every” duration to a larger interval.

Blueprint YAML

blueprint:
  name: "Left Open Alert (doors/windows & covers) — duration + optional repeat"
  description: >
    Warn if any selected door/window/contact sensor or cover stays open for a set
    duration. Sends a mobile-app notification to the chosen device, and can repeat
    on an interval until the entity is closed.
  domain: automation

  input:
    entities:
      name: "Sensors / Covers to monitor"
      description: >
        Pick one or more entities:
        - binary_sensor with device_class: opening, door, window, garage_door
        - cover (door/garage/gate/window/shutter/blind/etc.)
      selector:
        entity:
          multiple: true
          filter:
            - domain: binary_sensor
              device_class:
                - opening
                - door
                - window
                - garage_door
            - domain: cover

    open_duration:
      name: "Open for at least"
      description: "Only alert if it stays open continuously for this duration."
      default:
        hours: 0
        minutes: 10
        seconds: 0
      selector:
        duration: {}

    notify_device:
      name: "Device to notify"
      description: "Send alerts to this mobile app device."
      selector:
        device:
          multiple: false
          filter:
            - integration: mobile_app

    repeat_enabled:
      name: "Repeat until closed?"
      description: "If enabled, keep notifying at the interval below until the entity closes."
      default: false
      selector:
        boolean: {}

    repeat_delay:
      name: "Repeat every"
      description: "Used only if repeat is enabled."
      default:
        hours: 0
        minutes: 5
        seconds: 0
      selector:
        duration: {}

mode: parallel
max: 20
trace:
  stored_traces: 20

variables:
  v_repeat_enabled: !input repeat_enabled
  v_repeat_delay: !input repeat_delay
  v_open_duration: !input open_duration

trigger:
  # binary_sensor goes 'on' when open
  - platform: state
    id: bin_open
    entity_id: !input entities
    to: "on"
    for: !input open_duration

  # cover goes 'open' when open
  - platform: state
    id: cover_open
    entity_id: !input entities
    to: "open"
    for: !input open_duration

action:
  - variables:
      trig_entity: "{{ trigger.entity_id }}"
      trig_name: "{{ state_attr(trigger.entity_id, 'friendly_name') or trigger.to_state.name or trigger.entity_id }}"
      # Duration pretty-printer (no as_timedelta on dicts)
      dur_h: "{{ (v_open_duration.hours | default(0)) | int }}"
      dur_m: "{{ (v_open_duration.minutes | default(0)) | int }}"
      dur_s: "{{ (v_open_duration.seconds | default(0)) | int }}"
      pretty_duration: >-
        {%- set parts = [] -%}
        {%- if dur_h > 0 -%}{%- set _ = parts.append(dur_h ~ 'h') -%}{%- endif -%}
        {%- if dur_m > 0 -%}{%- set _ = parts.append(dur_m ~ 'm') -%}{%- endif -%}
        {%- if dur_s > 0 and parts|length == 0 -%}{%- set _ = parts.append(dur_s ~ 's') -%}{%- endif -%}
        {{ parts|join(' ') if parts|length > 0 else 'the set duration' }}

  - alias: "Send initial alert"
    action: notify.notify
    target:
      device_id: !input notify_device
    data:
      title: "Left Open"
      message: >-
        {{ trig_name }} has been open for {{ pretty_duration }}.
      data:
        url: "entity://{{ trig_entity }}"

  - choose:
      - conditions: "{{ v_repeat_enabled }}"
        sequence:
          - repeat:
              while:
                - condition: template
                  value_template: "{{ states(trig_entity) in ['on','open'] }}"
              sequence:
                - delay: !input repeat_delay
                - if:
                    - condition: template
                      value_template: "{{ states(trig_entity) in ['on','open'] }}"
                  then:
                    - action: notify.notify
                      target:
                        device_id: !input notify_device
                      data:
                        title: "Still Open"
                        message: >-
                          {{ trig_name }} is still open ({{ pretty_duration }}+). Please close it.
                        data:
                          url: "entity://{{ trig_entity }}"
    default: []