Some hardware links on this page are affiliate links. As an Amazon Associate I earn from qualifying purchases. We may earn a commission if you buy through them, at no extra cost to you. See the affiliate disclosure.
A fixed “window open for 10 minutes” timer is wrong twice. On a freezing morning you wanted the nudge in five. On a mild afternoon a half-hour of air is fine. This pack starts when a door or window contact opens, measures how much warmer the room is than outside, and waits a matching number of minutes before the first action. A bigger gap shortens the wait. Outdoor air above a ceiling you set (pack default 18 °C) skips the reminder entirely. Closing the contact can clear the notification.
Entity ids are blueprint inputs. Do not publish which sash belongs to which room.
An immediate open/close log with a snapshot is door and window open notify. Turning heat or cool off is window-open climate pause. Advice to open a window for cooling is passive-cooling window advisory. This one only nags you to close something that is already open, and only when the outdoor air is the colder one.
What problem it solves
You want a close-the-window reminder whose patience matches the temperature gap, without a page on a warm day and without a second push after the contact is already shut.
How it works
For a contact with device_class: door or window, on is open and off is closed. Fix an inverted sensor before you trust the wait.
- Open starts the clock — the contact goes
on. One automation per room. Several sashes in that room belong in one binary-sensor group shown as a window, with an area, so the message can name the area. - Warm outdoor air stops it — if the outdoor sensor is at or above the ceiling (default 18 °C), the run stops. No wait, no message.
- Gap sets the wait — indoor minus outdoor. Below the minimum gap (default 5 °C) the run stops. At that minimum gap the wait is the longest (default 30 minutes). At or above the maximum gap (default 17.5 °C) the wait is the shortest (default 5 minutes). Between those two gaps the wait falls in a straight line.
- Still open — the automation waits for the contact to close, or for the computed minutes. If it is still
on, the first action runs. Variables available to that action are the area name, the wait in minutes, indoor temperature, outdoor temperature, and the gap. - Second action — optional. After another slice of the same wait (default 80 percent), if the contact is still open, a second action runs. The default is a louder follow-up. Turn it off when one message is enough.
- Close clears — optional close actions run when the contact goes
off. The default clear uses the same notification tag as the area name, so the phone drops the reminder. A service that cannot clear by tag will not.
mode: queued so a second opening is not dropped while the first wait is running. The wait is computed once, from the temperatures at the moment the contact opened. A later swing in the weather does not rewrite that wait.
Needs Home Assistant 2024.6 or newer.
Hardware notes
- Contact. Any binary sensor that is
onwhen the opening is open, device class door or window. Group the ones that should share a timer. The area name is what the message prints, so name the area after the room. - Indoor temperature. A sensor in that room. The ESP32-C6 climate sensor is the build when the room does not have one. A weather entity is a poor stand-in for the room.
- Outdoor temperature. A shaded outdoor sensor, or a
weatherentity that exposes temperature as a sensor you can select. The blueprint wants asensorwith device class temperature, not the weather entity itself. - Notify. Companion, or any notify service. Clearing on close needs a tag the service understands. The token stays in the integration. Never paste it into the blueprint.
Snippet
The pack ships a blueprint. Inputs replace real entity ids. This is the wait, not the action blocks:
trigger:
- platform: state
entity_id: !input window_contact
to: "on"
id: opened
condition:
- condition: template
value_template: "{{ states(outdoor_temp) | float < outdoor_ceiling }}"
action:
- variables:
gap: "{{ (states(indoor_temp) | float - states(outdoor_temp) | float) | round(2) }}"
wait_minutes: >
{% set span = max_gap - min_gap %}
{% if gap >= max_gap %}
{{ min_minutes }}
{% else %}
{{ max_minutes - ((gap - min_gap) * (max_minutes - min_minutes) / span) }}
{% endif %}
- if:
- condition: template
value_template: "{{ gap >= min_gap }}"
then:
- wait_template: "{{ is_state(window_contact, 'off') }}"
timeout:
minutes: "{{ wait_minutes }}"
- if:
- condition: template
value_template: "{{ is_state(window_contact, 'on') }}"
then:
- service: !input notify_service
data:
title: "Window still open"
message: >
Open for {{ wait_minutes | round(0, 'floor') }} minutes.
Outside {{ states(outdoor_temp) }} °C.
data:
tag: "{{ area_name(window_contact) }}"
min_gap, max_gap, min_minutes, max_minutes, and outdoor_ceiling are the blueprint number inputs (defaults 5 °C, 17.5 °C, 5 min, 30 min, and 18 °C). The condition stops the run when outdoor air is at or above that ceiling. The real blueprint also has the second-action wait and the close-to-clear branch.
Setup outline
- Import the blueprint. Create one automation for one room. Point it at that room’s contact (or group), indoor temperature, and outdoor temperature.
- Leave the defaults for a first week: outdoor ceiling 18 °C, gaps 5 °C and 17.5 °C, waits 5 and 30 minutes.
- Keep the demo notification, including the tag, if you want close to clear it. Replace the action when you want a different service.
- Open the contact on a cool day and confirm the trace shows a wait between 5 and 30 minutes, then a message only if it is still open. Close it and confirm the clear. Repeat with outdoor temperature above the ceiling and confirm the run stops immediately.
Troubleshooting
- No message on a cold open. The gap was under 5 °C, the outdoor sensor was at or above 18 °C, or the contact closed before the wait ended. Read the trace variables.
- Message is immediate. Minimum wait is 1 minute only if you dragged that slider down. The default short end is 5 minutes, and only at a gap of 17.5 °C or more.
- Wait ignores a sudden cold front. The minutes are fixed when the contact opens. Close and reopen if you want a new calculation.
- Close does not clear the phone. The notify service ignores tags, or the close action’s tag does not match the open action’s tag. Both have to be the area name.
- Two sashes, one message for the wrong room. They are not in a group, or the group has no area. The area name comes from the entity that triggered.
- Second page after you already shut it. The second action is still enabled and the contact bounced back to
on. Turn the second action off, or increase the contact’s debounce in the sensor itself.
Credits
Based on the community blueprint Open Window Notifications (forum thread). This write-up is an original overview of the temperature-scaled wait: a straight line between a short delay and a long one, a warm-outdoor skip, and a clear when the contact closes.