Weather + Windows + Safety: Rain, Wind, Frost, Heat, and Open Windows
Weather + Windows + Safety: Rain, Wind, Frost, Heat, and Open Windows
In Lesson 6 you built the opening logic and home mode. Now we're adding weather: an open window means one thing in the rain, something else in strong wind, and something else again during a frost or a heat wave.
This lesson is about practically limiting everyday damage and discomfort. Home Assistant doesn't control the weather and doesn't replace common sense. It's meant to remind you at the right moment: close the window, it's started to rain; check the skylight, the wind has passed a safe threshold.
Plan on about 90 to 105 minutes. Start with one window and one rain automation. Then add wind, frost, and heat.
The rule for this lesson
An open window isn't always an alarm.
Weather and home mode decide whether you send a reminder, an urgent alert, or nothing at all.
A real-life problem: rain and a cracked-open window
You leave in the morning and crack open the living room window. It starts raining and gets windy in the afternoon. You come home to a wet windowsill and floor. It's a common, simple scenario that a single good automation can prevent.
The most important scenario in this lesson isn't "it's raining and you're home." It's "it's raining and the house is in Away mode." Nobody will spot the wet windowsill right away then, so the alert should be more urgent.
Where Home Assistant gets its weather data
This lesson uses example entity names. Yours might come from a weather integration, a local weather station, a rain sensor, an outdoor temperature sensor, or online data. What matters most is understanding the difference between a forecast and current conditions.
| Data source | Good for | Risk |
|---|---|---|
| Weather forecast | An early warning, e.g. "rain possible in an hour." | May not hold true locally. |
| Current weather condition | An alert when the integration shows rain, wind, or a temperature right now. | May be delayed or from a different location. |
| A local rain sensor | The best signal that it's raining on your own property. | Needs hardware, power, and a good mounting spot. |
| A local weather station | Wind, temperature, rain, sometimes humidity and pressure. | A bad mounting spot gives bad data. |
A forecast isn't the same as rain outside your window
A forecast might say it'll rain in your area, but that doesn't guarantee rain is falling on your property right now. That's why, for the first version of the automation, it's better to rely on the current condition or a local rain sensor. You can add the forecast later as an early warning, but not as the only reason to alert.
Weather from the internet doesn't always match weather at your house
A weather integration might use a station several miles away. It could already be raining in one part of town while it's still dry at your place. That's why, for critical windows like skylights, a local rain sensor or your own weather station is the best option.
What's actually the risk
One automation for every kind of weather: rain, wind, and frost need different thresholds.
Using the forecast alone as a trigger: the forecast says "rain possible," but it's still dry at your place: an easy way to spam alerts.
A one-directional automation: you catch rain starting, but not a window opening once it's already raining.
The wrong wind unit: a 45 threshold with a sensor in m/s will either never trigger, or trigger far too soon.
No separation for skylights: ordinary windows and skylights don't share the same wind sensitivity.
No mute helper: notifications get in the way during intentional airing.
Three levels of weather response
Weather doesn't always call for a life-safety alarm. In Lesson 6, we distinguished a reminder, an urgent alert, and a full alarm. Here, we mainly use the first two: rain against an open window in Home mode is a reminder, strong wind against a skylight at night can be an urgent alert.
| Situation | Response | Script |
|---|---|---|
| Home mode, light rain, window open | A calm reminder | script.notify_household |
| Away mode, rain, window open | An urgent alert | script.notify_household_urgent |
| Strong wind, skylight open | An urgent alert, since the risk of damage is higher | script.notify_household_urgent |
In this lesson we deliberately don't default to the full security-alarm escalation. Weather and open windows are, most of the time, a reminder or an urgent alert, not a life-safety alarm. With weather, not every alert needs to wake the household: rain and a window in Home mode is a reminder. Strong wind and a skylight at night can be an urgent alert.
Which entities we're watching
| Entity | Meaning |
|---|---|
binary_sensor.living_room_window |
A regular window |
binary_sensor.attic_skylight |
Attic skylight |
binary_sensor.rain_now |
Current rain condition |
sensor.wind_speed |
Wind, in km/h |
sensor.outdoor_temperature |
Outdoor temperature |
input_select.home_mode |
Context from Lesson 6 |
Entity names are examples
Your rain sensor might have a different name, e.g. binary_sensor.rain, or it might not exist at all. Wind might be reported in m/s instead of km/h. Before pasting in an automation, check the units, entity names, and whether the values actually change.
Cracked open and fully open are often the same to HA
A regular contact sensor usually only reports open/closed. It doesn't always know whether a window is cracked open or fully open. For weather purposes that's good enough for a reminder, but don't treat it as a precise measurement of window position.
Units matter
Before setting a wind threshold, check the entity's unit. If the sensor reports m/s and you enter a threshold meant for km/h, the automation will behave incorrectly. The conversion is simple: 1 m/s equals 3.6 km/h.
# Example:
# 10 m/s = 36 km/h
# 12.5 m/s = 45 km/h
# 15 m/s = 54 km/h
To start, we hard-code thresholds or use input_number helpers. Once the system is up and running, it's worth keeping thresholds in helpers so you can change them from the dashboard without editing YAML.
Wind speed units
numeric_state compares raw numbers. If the sensor reports m/s and the helper is in km/h, comparing 12 to 45 is wrong (12 m/s is about 43 km/h). Use matching units, or a template sensor:
template:
- sensor:
- name: "Wind speed km/h"
unique_id: wind_speed_kmh
unit_of_measurement: "km/h"
device_class: wind_speed
state: >
{% set value = states('sensor.wind_speed') | float(0) %}
{% set unit = state_attr('sensor.wind_speed', 'unit_of_measurement') %}
{% if unit == 'm/s' %}
{{ (value * 3.6) | round(1) }}
{% elif unit == 'mph' %}
{{ (value * 1.60934) | round(1) }}
{% else %}
{{ value }}
{% endif %}
In your wind automations, use sensor.wind_speed_kmh (or your own entity name) instead of the raw sensor with a different unit.
Helpers and groups
input_boolean:
weather_alerts_windows:
name: "Weather alerts for windows"
icon: mdi:weather-partly-rainy
initial: true
weather_alert_test:
name: "Weather alert test"
icon: mdi:weather-lightning-rainy
airing_in_progress:
name: "Airing in progress"
icon: mdi:window-open-variant
input_number:
wind_threshold_skylights:
name: "Wind threshold for skylights"
min: 20
max: 100
step: 5
initial: 45
unit_of_measurement: "km/h"
icon: mdi:weather-windy
frost_threshold_windows:
name: "Frost threshold for open windows"
min: -20
max: 10
step: 1
initial: 0
unit_of_measurement: "°C"
icon: mdi:snowflake
heat_threshold_windows:
name: "Heat threshold for open windows"
min: 20
max: 40
step: 1
initial: 30
unit_of_measurement: "°C"
icon: mdi:thermometer-high
group:
weather_critical_windows:
name: "Weather-critical windows"
entities:
- binary_sensor.living_room_window
- binary_sensor.attic_skylight
skylights:
name: "Skylights"
entities:
- binary_sensor.attic_skylight
A threshold can be a number or a helper
In simple automations you can hard-code a threshold, e.g. above: 45. In this lesson we use input_number helpers, e.g. above: input_number.wind_threshold_skylights. That way you change the threshold from the dashboard, with no YAML editing.
Airing out the house is normal, not a mistake. That's why it's worth having an airing_in_progress helper that mutes weather reminders for a short time. It's important that the mute ends on its own, e.g. after 30 minutes.
automation:
- alias: "Security: mute weather alerts while airing"
description: "Mutes weather alerts for 30 minutes"
mode: restart
triggers:
- trigger: state
entity_id: input_boolean.airing_in_progress
to: "on"
actions:
- delay:
minutes: 30
- action: input_boolean.turn_off
target:
entity_id: input_boolean.airing_in_progress
Airing can mute mild reminders (e.g. heat plus an open window). It shouldn't mute rain against a skylight or strong wind: you can adjust the urgency if you like, but keep the warning.
Don't start with automatic window closing
In this lesson we send notifications, not control window actuators. Automatic closing can be risky: someone's hand might be in the window, the mechanism could jam, or a sensor could misread the weather. Build good alerts first. Add window control only once you have safe hardware, limit switches, safeguards, and manual override.
Automation 1: rain and an open window
The automation should catch both directions: a window was open and it started raining, and it was already raining and someone opened a window. The message names which windows are open: the household doesn't have to guess. We use mode: restart, because with rain and windows changing fast, the latest state matters more than an old queued alert.
The weather alert test uses the exact same path as a real alert. If the house is in Away mode, the test will also go out as urgent. That's deliberate: you're testing exactly the logic that has to work while you're away.
automation:
- alias: "Security: rain and an open window"
description: "Alerts when it's raining and critical windows are open"
mode: restart
triggers:
- trigger: state
entity_id: binary_sensor.rain_now
to: "on"
- trigger: state
entity_id: input_boolean.weather_alert_test
to: "on"
- trigger: state
entity_id:
- binary_sensor.living_room_window
- binary_sensor.attic_skylight
to: "on"
conditions:
- condition: state
entity_id: input_boolean.weather_alerts_windows
state: "on"
# airing doesn't mute rain
- condition: or
conditions:
- condition: template
value_template: "{{ trigger.entity_id == 'input_boolean.weather_alert_test' }}"
- condition: and
conditions:
- condition: state
entity_id: binary_sensor.rain_now
state: "on"
- condition: template
value_template: "{{ expand('group.weather_critical_windows') | selectattr('state', 'eq', 'on') | list | count > 0 }}"
actions:
- choose:
- conditions:
- condition: state
entity_id: input_select.home_mode
state: "Away"
sequence:
- action: script.notify_household_urgent
data:
title: "Rain and an open window"
message: >
{% set open_items = expand('group.weather_critical_windows')
| selectattr('state', 'eq', 'on')
| map(attribute='name') | list %}
{% if trigger.entity_id == 'input_boolean.weather_alert_test' %}
This is a weather alert test. Check that the notification arrives.
{% elif open_items | length > 0 %}
It's raining, and open: {{ open_items | join(', ') }}.
{% else %}
It's raining, but no open windows were found in the group.
{% endif %}
default:
- action: script.notify_household
data:
title: "It's raining and a window is open"
message: >
{% set open_items = expand('group.weather_critical_windows')
| selectattr('state', 'eq', 'on')
| map(attribute='name') | list %}
{% if trigger.entity_id == 'input_boolean.weather_alert_test' %}
This is a weather alert test. Check that the notification arrives.
{% elif open_items | length > 0 %}
It's raining, and open: {{ open_items | join(', ') }}.
{% else %}
It's raining, but no open windows were found in the group.
{% endif %}
- choose:
- conditions:
- condition: template
value_template: "{{ trigger.entity_id == 'input_boolean.weather_alert_test' }}"
sequence:
- delay:
seconds: 2
- action: input_boolean.turn_off
target:
entity_id: input_boolean.weather_alert_test
Automation 2: strong wind and a skylight
Wind also responds in two directions: a skylight was already open and the wind crossed the threshold, or the wind is already strong and someone opens a skylight. We keep the threshold in a helper: if your sensor reports m/s, set it to about 12.5 instead of 45.
A gust of wind versus sustained wind
A single gust doesn't necessarily mean a real problem. That's why the wind automation uses for: 3 minutes. The alert only fires once the threshold has been exceeded for a while, not after a single spike in the reading.
automation:
- alias: "Security: strong wind and a skylight"
description: "An urgent alert for strong wind with an open skylight"
mode: single
triggers:
- trigger: numeric_state
entity_id: sensor.wind_speed_kmh
above: input_number.wind_threshold_skylights
for:
minutes: 3
- trigger: state
entity_id: binary_sensor.attic_skylight
to: "on"
conditions:
- condition: state
entity_id: input_boolean.weather_alerts_windows
state: "on"
# airing doesn't mute strong wind
- condition: template
value_template: "{{ expand('group.skylights') | selectattr('state', 'eq', 'on') | list | count > 0 }}"
- condition: numeric_state
entity_id: sensor.wind_speed_kmh
above: input_number.wind_threshold_skylights
actions:
- action: script.notify_household_urgent
data:
title: "Strong wind and an open skylight"
message: >
{% set open_items = expand('group.skylights')
| selectattr('state', 'eq', 'on')
| map(attribute='name') | list %}
The wind has crossed the threshold, and open: {{ open_items | join(', ') }}. Check and close the window.
Automation 3: frost and an open window
Frost works the same way in two directions: the temperature dropped below the threshold while the window was open, or someone opened the window once it was already freezing outside.
automation:
- alias: "Security: frost and an open window"
description: "A reminder to close the window during a frost"
mode: single
triggers:
- trigger: numeric_state
entity_id: sensor.outdoor_temperature
below: input_number.frost_threshold_windows
for:
minutes: 10
- trigger: state
entity_id: binary_sensor.living_room_window
to: "on"
conditions:
- condition: state
entity_id: input_boolean.weather_alerts_windows
state: "on"
- condition: state
entity_id: input_boolean.airing_in_progress
state: "off"
- condition: state
entity_id: binary_sensor.living_room_window
state: "on"
- condition: numeric_state
entity_id: sensor.outdoor_temperature
below: input_number.frost_threshold_windows
actions:
- action: script.notify_household
data:
title: "Frost and an open window"
message: "The temperature has dropped below the threshold, and a window is open. Check it and close it most of the way."
Automation 4: heat and an open window
Heat is a reminder, not a life-safety alarm. We limit it to Home mode: in Away mode, nobody's airing out windows fully open anyway.
automation:
- alias: "Security: heat and an open window"
description: "A reminder to close the window during high heat"
mode: single
triggers:
- trigger: numeric_state
entity_id: sensor.outdoor_temperature
above: input_number.heat_threshold_windows
for:
minutes: 15
- trigger: state
entity_id: binary_sensor.living_room_window
to: "on"
conditions:
- condition: state
entity_id: input_boolean.weather_alerts_windows
state: "on"
- condition: state
entity_id: input_boolean.airing_in_progress
state: "off"
- condition: state
entity_id: binary_sensor.living_room_window
state: "on"
- condition: state
entity_id: input_select.home_mode
state: "Home"
- condition: numeric_state
entity_id: sensor.outdoor_temperature
above: input_number.heat_threshold_windows
actions:
- action: script.notify_household
data:
title: "Heat and an open window"
message: >
The outdoor temperature has crossed the heat threshold, and a window is open.
If you're cooling the house, close it most of the way. If you're intentionally airing it out, turn on the airing_in_progress helper.
An open window at 86°F isn't always a mistake: what matters is the indoor temperature, the outdoor temperature, the time of day, air conditioning, and sun exposure. A simple outdoor threshold is a starting point, not full logic.
Resetting the test when an alert can't run
If you turn on weather_alert_test while alerts are disabled or airing is in progress, the main rain automation won't run: and the test helper will stay on. We solved the same problem in Lesson 6. Add a separate reset automation:
automation:
- alias: "Security: reset weather alert test when alerts are muted"
description: "Turns off the test helper if weather alerts are disabled or airing is in progress"
mode: single
triggers:
- trigger: state
entity_id: input_boolean.weather_alert_test
to: "on"
conditions:
- condition: or
conditions:
- condition: state
entity_id: input_boolean.weather_alerts_windows
state: "off"
- condition: state
entity_id: input_boolean.airing_in_progress
state: "on"
actions:
- delay:
seconds: 2
- action: input_boolean.turn_off
target:
entity_id: input_boolean.weather_alert_test
- action: script.notify_household
data:
title: "Weather alert test canceled"
message: >
The test didn't run because weather alerts are disabled or airing is in progress.
Enable alerts and turn off airing if you want to test the notification.
Dashboard: weather and windows
type: entities
title: Weather and windows
entities:
- input_select.home_mode
- input_boolean.weather_alerts_windows
- input_boolean.airing_in_progress
- group.weather_critical_windows
- binary_sensor.rain_now
- sensor.wind_speed
- sensor.outdoor_temperature
- input_number.wind_threshold_skylights
- input_number.frost_threshold_windows
- input_number.heat_threshold_windows
- input_boolean.weather_alert_test
How to test, step by step
1. Check where the weather data comes from and whether the entities really change, in Developer Tools.
2. Open a test window and check that the entity's state changes.
3. Run weather_alert_test and check that the message clearly says it's a test.
4. Test both directions: first an open window followed by a weather change, then bad weather followed by opening a window.
5. Turn off the alerts helper, or turn on airing, and confirm the test resets with a cancellation message.
6. Turn on airing_in_progress and check that mild reminders (e.g. heat) get muted while rain/wind still alert.
7. Test the wind threshold and restore the target value afterward.
Don't copy the thresholds one-to-one
Choose wind speed and temperature ranges to match your local climate and your home's construction. After a week of testing, tune the thresholds so alerts are rare but accurate.
Common mistakes
A forecast with no confirmation from current conditions: alert spam.
A one-directional automation: you catch rain starting, but not a window opening while it's already raining.
No separation for skylights: too weak a response during strong wind.
The wrong wind unit: a threshold of 45 with an m/s sensor disables the alert permanently.
Thresholds set too low: the household starts ignoring the alerts.
The test helper stays on: no reset when weather alerts are disabled.
No automatic end to airing: the helper stays on all day and weather alerts stay silent.
Assignment: weather and windows
To do
☐ Check where your weather data comes from: forecast, current condition, a local sensor, or a weather station.
☐ Check the wind units: km/h or m/s.
☐ Add one test window to the weather_critical_windows group.
☐ Create the alert, threshold, and airing helpers.
☐ Paste in the rain, wind, frost, and heat automations.
☐ Test both directions: first an open window followed by a weather change, then bad weather followed by opening a window.
☐ Test the airing_in_progress helper: turn it on, run the alert test, and check the notification is muted.
☐ Check that airing_in_progress returns to off on its own after 30 minutes.
☐ After a week, check how many alerts were accurate, and only then adjust the thresholds.
☐ Update the risk map from Lesson 1 with weather-critical windows.
Key takeaways
Weather changes what an open window means: airing out on a sunny day is normal, rain against an open window is a problem.
A forecast and current conditions are two different things: it's better to respond to actual rain, wind, and temperature to start.
Alerts need to work both ways: when weather changes with a window open, and when someone opens a window in bad weather.
You tailor thresholds to your house: a skylight, a regular window, and a covered patio each need different values.
What's next
In Lesson 8 we move on to presence and automatically switching home mode. That closes the loop on the logic from Lessons 6 and 7: less manual clicking, more context.
After this lesson, your system no longer just sees that a window is open. It's starting to understand when that's actually a problem.