Blinds by Time, Sun, and Temperature: Comfort Without Overheating the House

Module 20 · Lesson 13

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

  1. The drive's safeguards and the local STOP.
  2. Emergency opening and protecting the patio exit.
  3. Servicing mode, window cleaning, and ice protection.
  4. Protecting an awning or screen from wind.
  5. A household member's manual override.
  6. The minimum interval between moves.
  7. The room's and season's profile.
  8. The sun, temperature, and thermal comfort.
  9. The evening schedule.
A closing lockout must never block emergency opening

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:00am75°Fnooffoffnone
3:00pm82°Fyesoffoffshade
4:00pm82°Fyesononnone

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

☐ Observation mode first, with no actual blind movement.
☐ 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

☐ For every blind, record the compass direction, the room type, and the patio risk.
☐ 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 unknown or unavailable means 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.

Finished this lesson?