Blinds by Time, Sun, and Temperature: Comfort Without Overheating the House
Blinds by Time, Sun, and Temperature: Comfort Without Overheating the House
Blind automation isn't meant to find the perfect temperature. It's meant to perform a handful of well-justified moves, defer to a person, and never move the mechanism when any safety condition is uncertain.
Lessons 7 and 12 gave you safety, cover entities, and the sun. Here: in summer, shade only on a window the sun actually hits; in winter, open only with real daylight; a manual override after STOP; a minimum interval between moves; an observation mode before the first real travel. Helpers from Lesson 7: blinds_automation_enabled, patio_blinds_lockout, window_cleaning_mode. You only turn on the global master at the very end. Further on I'll shorten Home Assistant to HA.
Plan on about 120 to 130 minutes. Syntax: triggers / conditions / actions.
This lesson's rule
A blind isn't a thermostat. Summer: shade before the heat arrives. Winter: light only when the sun is really shining. A manual STOP means: don't try again.
A real-life problem
The living room hits 82°F despite the AC. Or: an automation closes the patio blind while the door sensor reads unknown. Or: STOP at 70%, and five minutes later it's back to 50%. Or: the blind moves every fifteen minutes over a 1°F change. Or: a winter opening on an overcast day just because the outdoor temperature is "above the threshold."
Blind control priorities
- The drive's safeguards and the local STOP.
- Emergency opening and protecting the patio exit.
- Servicing mode, window cleaning, and ice protection.
- Protecting an awning or screen from wind.
- A household member's manual override.
- The minimum interval between moves.
- The room's and season's profile.
- The sun, temperature, and thermal comfort.
- The evening schedule.
Safety conditions depend on the direction of travel. A patio lockout prevents automatic lowering, but it shouldn't take away raising, STOP, or the local up button. Don't copy an identical set of conditions onto both opening and closing.
Closing safety
For the patio blind, closing requires an explicit binary_sensor.patio_door = off: not not on, since unknown/unavailable would pass that check. The door sensor still doesn't detect a person on the patio: opening the door turns on the lockout; closing the door doesn't turn it off: a household member turns it off deliberately (Lesson 7).
conditions:
- condition: state
entity_id: input_boolean.blinds_automation_enabled
state: "on"
- condition: state
entity_id: input_boolean.patio_blinds_lockout
state: "off"
- condition: state
entity_id: input_boolean.window_cleaning_mode
state: "off"
- condition: state
entity_id: binary_sensor.patio_door
state: "off"
- condition: template
value_template: >
{{ states('cover.living_room_patio_blind')
in ['open', 'closed', 'opening', 'closing'] }}
The condition set above is for the patio extension. The first full automation example in this lesson uses a plain window blind, cover.office_blind_west: no door sensor involved. Don't start with the patio as your first pilot blind. The last condition confirms the HA model is available: it isn't a mechanical safeguard. A global window_cleaning_mode blocks every blind; local helpers are more convenient but more work. Don't group the patio blind with plain windows. A cover group doesn't confirm every member entity: critical automation controls each one individually.
| Situation | Behavior |
|---|---|
| Strong wind, an extended awning | Manufacturer protection / protective retraction takes priority |
| Wind sensor unknown | Don't extend automatically |
| Comfort automation off | Doesn't block protective retraction |
| Icing / snow in the guide rails | Seasonal automation off; no retry after failed movement |
| Rain, a skylight / awning | Don't bypass the factory rain sensor |
An awning isn't a window blind. HA isn't the only layer of wind protection. When expected movement doesn't happen: send a notification, and don't automatically retry.
A manual STOP means: don't try again
If a household member stops or repositions a blind, comfort automation should defer for a while. Without an override, the system would just force its own position again a few minutes later.
input_select:
blinds_season:
name: Blinds profile
icon: mdi:blinds
options:
- off
- summer
- winter
- transitional
input_number:
office_blind_shade_position:
name: Office blind shade position
icon: mdi:blinds-horizontal
min: 20
max: 80
step: 10
unit_of_measurement: "%"
shade_temp_threshold:
name: "Temp. threshold: shading"
min: 68
max: 95
step: 1
unit_of_measurement: "°F"
open_temp_threshold:
name: "Temp. threshold: open after cooling"
min: 59
max: 86
step: 1
unit_of_measurement: "°F"
winter_open_lux_threshold:
name: "Lux threshold: winter opening"
min: 50
max: 5000
step: 50
unit_of_measurement: "lx"
timer:
office_blind_manual_override:
name: Office blind manual override
duration: "02:00:00"
restore: true
office_blind_move_interval:
name: Office blind minimum move interval
duration: "01:00:00"
restore: true
input_boolean:
blinds_observation_mode:
name: Blinds observation mode
icon: mdi:eye-outline
The profile: a deliberate human choice in input_select.blinds_season: summer / winter / transitional / off: no auto value. Transitional: no temperature-based shading; the evening routine can still run; most moves stay manual. Don't switch the season from a single reading. Fixed months (month in [5...9]) are just an illustration: a warm April and a cool May both happen. Two temperature thresholds plus for: plus a move-interval timer: for: alone isn't hysteresis. The move-interval timer doesn't block STOP, local opening, or an awning's protective retraction: it only applies to comfort automation.
Manual actions from HA go through a script that starts the timer; local remotes: separate automations. Don't base everything on the state's context at startup. Three to four position levels (open / shaded / closed): not a dozen percentages. 0 = closed, 100 = open (the HA model, often an estimate). Tolerance: a 50% target → roughly 45-55%. No position data → don't assume the move happened.
Compass direction and temperature
Don't group every blind together. East: protection in the morning; south: midday; west: afternoon; north: often no direct-sun shading needed at all. The hour is only an approximation: the sun's actual reach depends on azimuth and elevation. Outdoor temperature alone isn't enough: a window can be in shade at 82°F. A forecast gives you lead time; a local sensor gives you confirmation. An outdoor sensor: shield it from direct sun, ensure airflow, keep it off heated metal. Indoor temperature has thermal inertia: waiting until the living room hits 82°F can already be too late. Temperature unavailable means no new movement, not "safe to open." Check how fresh the reading is in the history.
In freezing weather, don't use a blanket "never open below 23°F" rule: test your own building. A blind reduces heat loss and air movement at the window, it doesn't replace a good window. Privacy: living room ≠ bedroom ≠ bathroom. Turn off manufacturer schedules, or record them on the map: two systems can fight each other.
After shading, Lesson 12's logic might turn on a light: choose deliberately between thermal comfort and energy savings. We're not controlling HVAC in this lesson; a blind is a passive step ahead of it.
Observation mode first, then one blind
Run a few days: a notification or the Logbook instead of actually calling cover.set_cover_position. Then: one blind that isn't the main patio exit, without a group. During testing: watch for the motor's thermal pauses: no movement after many travels can mean thermal protection, not a YAML bug. Turn off automation during calibration (blinds_automation_enabled = off).
| Time | Outdoor T | Sun | Door | Lockout | Decision |
|---|---|---|---|---|---|
| 10:00am | 75°F | no | off | off | none |
| 3:00pm | 82°F | yes | off | off | shade |
| 4:00pm | 82°F | yes | on | on | none |
Summer: shading and opening after cooling
Separate automations for cover.office_blind_west (a window, not the patio). The hours below are an example for a west-facing window: don't copy them onto an east-facing one. Before moving: require a position difference of at least 10%, and a state of open/closed (don't interrupt travel unnecessarily). For 2-3 comfort-driven travels per day, check the drive's documentation for duty-cycle limits and required pauses. You add the patio blind later, as an extension with the door condition and lockout from Lesson 7.
- id: office_summer_shading
alias: Office - summer blind shading
description: >
Lowers the blind to the shading position when high temperature
persists and safety conditions allow it.
mode: single
triggers:
- trigger: numeric_state
entity_id: sensor.outdoor_temperature
above: input_number.shade_temp_threshold
for: "00:20:00"
conditions:
- condition: state
entity_id: input_boolean.blinds_automation_enabled
state: "on"
- condition: state
entity_id: input_boolean.blinds_observation_mode
state: "off"
- condition: state
entity_id: input_select.blinds_season
state: "summer"
- condition: state
entity_id: input_boolean.window_cleaning_mode
state: "off"
- condition: state
entity_id: timer.office_blind_manual_override
state: "idle"
- condition: state
entity_id: timer.office_blind_move_interval
state: "idle"
- condition: template
value_template: >
{{ states('cover.office_blind_west') in ['open', 'closed'] }}
- condition: sun
after: sunrise
before: sunset
- condition: time
after: "12:00:00"
before: "19:30:00"
- condition: template
value_template: >
{% set current = state_attr('cover.office_blind_west', 'current_position') %}
{% set target = states('input_number.office_blind_shade_position') | int(50) %}
{{ current is number and (current - target) | abs >= 10 }}
actions:
- action: cover.set_cover_position
target:
entity_id: cover.office_blind_west
data:
position: "{{ states('input_number.office_blind_shade_position') | int(50) }}"
- action: timer.start
target:
entity_id: timer.office_blind_move_interval
- id: office_summer_open_after_cooling
alias: Office - open the blind after cooling
mode: single
triggers:
- trigger: numeric_state
entity_id: sensor.outdoor_temperature
below: input_number.open_temp_threshold
for: "00:30:00"
conditions:
- condition: state
entity_id: input_boolean.blinds_automation_enabled
state: "on"
- condition: state
entity_id: input_boolean.blinds_observation_mode
state: "off"
- condition: state
entity_id: input_select.blinds_season
state: "summer"
- condition: state
entity_id: input_boolean.window_cleaning_mode
state: "off"
- condition: state
entity_id: timer.office_blind_manual_override
state: "idle"
- condition: state
entity_id: timer.office_blind_move_interval
state: "idle"
- condition: template
value_template: >
{% set position = state_attr('cover.office_blind_west', 'current_position') %}
{{ position is number and position < 90 }}
actions:
- action: cover.open_cover
target:
entity_id: cover.office_blind_west
- action: timer.start
target:
entity_id: timer.office_blind_move_interval
Opening: no patio lockout against closing here, but cleaning and servicing modes can still block it. A numeric_state trigger reacts to crossing the threshold: after an HA restart, a value that's already past the threshold may not fire it. The fallback: a deliberate evaluation, not an immediate move right after startup.
Winter and evening
In winter, don't open just from outdoor temperature: you need a light indicator (outdoor lux, bright conditions). The office isn't the bedroom. Evening closing: full safety conditions plus the manual override. Summer and winter use different profiles. Turning on the master at 3pm could immediately lower a blind: it's safer to show a status and wait for the next scheduled point, or require the first activation to be manual. When outdoor lux is unavailable, automation doesn't open the blind: that's the safe choice, but add a diagnostic message (a notification or a dashboard status), so the blind doesn't stay closed for days without explanation. Test the position attribute in the Template tool: it can be an int or a float; is number usually works, but confirm it on your own system.
- id: office_winter_opening
alias: Office - winter blind opening
description: >
Opens the blind in winter when conditions indicate real sunlight.
mode: single
triggers:
- trigger: sun
event: sunrise
offset: "+01:00:00"
conditions:
- condition: state
entity_id: input_boolean.blinds_automation_enabled
state: "on"
- condition: state
entity_id: input_boolean.blinds_observation_mode
state: "off"
- condition: state
entity_id: input_select.blinds_season
state: "winter"
- condition: state
entity_id: input_boolean.window_cleaning_mode
state: "off"
- condition: state
entity_id: timer.office_blind_manual_override
state: "idle"
- condition: template
value_template: >
{{ states('cover.office_blind_west') in ['open', 'closed'] }}
- condition: numeric_state
entity_id: sensor.office_outdoor_lux
above: input_number.winter_open_lux_threshold
- condition: template
value_template: >
{% set position = state_attr('cover.office_blind_west', 'current_position') %}
{{ position is number and position < 90 }}
actions:
- action: cover.open_cover
target:
entity_id: cover.office_blind_west
- action: timer.start
target:
entity_id: timer.office_blind_move_interval
- id: office_blind_evening_closing
alias: Office - evening blind closing
description: >
Closes the blind after sunset only once safety is confirmed.
mode: single
triggers:
- trigger: sun
event: sunset
offset: "+00:45:00"
conditions:
- condition: state
entity_id: input_boolean.blinds_automation_enabled
state: "on"
- condition: state
entity_id: input_boolean.blinds_observation_mode
state: "off"
- condition: state
entity_id: input_boolean.window_cleaning_mode
state: "off"
- condition: state
entity_id: timer.office_blind_manual_override
state: "idle"
- condition: state
entity_id: timer.office_blind_move_interval
state: "idle"
- condition: template
value_template: >
{% set position = state_attr('cover.office_blind_west', 'current_position') %}
{{ position is number and position > 5 }}
actions:
- action: cover.close_cover
target:
entity_id: cover.office_blind_west
- action: timer.start
target:
entity_id: timer.office_blind_move_interval
After a restart or a power loss: wait, check the entities, and don't correct the position without every lockout in place. Internet, HA, the coordinator, and the module: test Plan B for each separately. A log: the Logbook plus traces (time, temperature, source). If there's a conflict, also check the manufacturer's own schedule.
Testing blind automation
☐ I test one blind, not a whole-house group.
☐ A manual STOP triggers a temporary override.
☐ The patio lockout blocks closing, not emergency opening.
☐ An open or unavailable door sensor blocks automatic closing.
☐ Window-cleaning mode blocks routine automatic movement.
☐ No movement occurs on
unknown / unavailable.☐ No command is sent when the blind is already close to the target position.
☐ The minimum interval between moves actually works.
☐ The closing and opening thresholds are different values.
☐ The time window matches the compass direction.
☐ Winter doesn't open on an overcast day.
☐ Summer doesn't shade a window the sun isn't hitting.
☐ An HA restart doesn't trigger a sudden movement.
☐ Missing expected movement leads to diagnostics, not a retry loop.
☐ Duty-cycle pauses are respected; a household member knows how to STOP and raise the blind.
Identical conditions for opening and closing.
Closing while the door sensor is unknown.
No override after STOP: a fight over 50%.
Winter: opening based on outdoor temperature alone.
Treating an awning like a window blind; comfort-off blocking wind protection.
Hands-on exercise
☐ Choose one pilot blind that's safer than the main patio exit.
☐ Add a season profile, two temperature thresholds, and one shading position.
☐ Add a manual-override timer and a minimum move-interval timer.
☐ Build observation mode first, with no physical movement.
☐ Watch it for several days, and count how many moves the logic would have triggered.
☐ Add automatic shading for just one compass direction.
☐ Add a separate opening-after-cooling automation with a lower threshold.
☐ Test an open door, the patio lockout, window cleaning, and unavailable entities.
☐ Test a manual STOP and a repeated temperature trigger.
☐ Test an HA restart and a module power loss.
☐ Test the winter logic in observation mode first.
☐ Don't use one group for blinds with different safety rules.
☐ Only turn on the global helper after checking every automation that uses it.
Key takeaways
- A blind isn't a thermostat and shouldn't react to every small temperature change.
- In summer, you only shade windows the sun is actually hitting.
- In winter, you only open a blind when you can genuinely use the light and solar gain.
- Outdoor temperature, indoor temperature, and the sun's position describe different parts of the situation.
- Two separate temperature thresholds, plus a minimum move interval, limit oscillation.
- A manual STOP or a repositioning has to temporarily disable comfort automation.
- A patio lockout protects against closing, but must never block emergency opening.
- A door sensor reading
unknownorunavailablemeans no permission for automatic closing. - A position of 0 means closed and 100 means open, but the reading can be just an estimate.
- You don't send a move command when the blind is already close to its target position.
- Missing expected movement should trigger diagnostics, not a retry loop.
- Awnings and screens need a separate, higher-priority wind protection.
- A cover group doesn't replace checking each blind and its own local lockouts.
- Observation mode first, then one pilot blind, and only at the end, the whole house.
In Lesson 14 you'll sort out conflicts between lighting and blinds, plus a checklist before handing the home over. Before moving on, one pilot blind should defer to STOP and stay still whenever the data is incomplete.