Researched from current Home Assistant documentation on October 7, 2026. The worked configuration is an illustrative design, not a tested Tara installation or a measurement of cooling savings. The cover is an AI-generated editorial illustration.

Start with one window and one shading position

A Home Assistant blinds automation based on sun position needs three decisions: which direction the window faces, when sunlight actually reaches it, and how far to lower the shade. The built-in Sun integration provides the first part of the calculation. Your observations in the room supply the useful limits.

Start with a shade-only routine: while enabled during your chosen daytime hours, lower an existing roller shade to a fixed position when the sun is in its troublesome direction. Leave it alone if it is already more closed. Reopen it yourself when you want the view back. This avoids a rule that unexpectedly opens a bedroom shade when a cloud passes or evening arrives.

Follow the steps below in order: check the existing controls, observe the sunlight, add a pause, then run a harmless preview. This guide assumes the shade is already connected. If you are still choosing a motor or control system, use the Home Assistant motorized-blinds buying guide first.

1. Confirm what your shade can actually control

Home Assistant calls a blind, shade or shutter control a cover entity—a named control such as cover.office_shade. Open its controls and check that it offers a position percentage. For the example, you also need a believable current_position attribute, the extra value shown with the entity in Developer tools → States. Read it there; do not change the state to pretend the motor moved.

Set cover position uses 0 for closed and 100 for open. Thus 35 means 35% open, not 35% closed. Confirm the physical direction and travel limits using the manufacturer's calibration instructions before enabling automation. Choose a target between 0 and 100. A numeric position can still be stale or estimated; compare it with the real shade before trusting it.

A slat-tilting blind is different. Set cover tilt position uses a separate action and tilt_position field. Do not paste this lift-position example into a tilt-only setup. An open/close-only device or one with unreliable position feedback also needs a different design; changing its icon does not add those capabilities.

Use an unobstructed interior window shade for this exercise. Keep children, pets and objects clear of its travel. Keep normal physical controls available. Do not reuse this code for a garage door, powered window, exit shutter or outdoor awning: those need their own access, obstruction or wind protections.

2. Find the sun angles that matter at this window

In Developer tools → States, find sun.sun and read its azimuth and elevation attributes. Check Home Assistant's configured home location if they do not match your surroundings. The Sun documentation defines azimuth as clockwise from north and elevation as height above the horizon.

  • Direction, or azimuth: north is 0°, east 90°, south 180° and west 270°. The window direction means looking straight outward through the glass, perpendicular to the wall.
  • Height, or elevation: 0° is the horizon; positive numbers put the sun above it. Nearby trees, roof overhangs and buildings can still block it.

On a day when glare is a problem, note the angles when it begins and ends. For an illustrative west-facing office, start with direction 270°, an angle allowance of 40° on each side, and a minimum elevation of 5°. That accepts directions from 230° through 310° while the sun is at least 5° high. These are example settings, not measurements of your window.

The code calculates the shortest distance around the compass. For a window facing 350° and sun at 10°, the difference is 20°, not 340°. It therefore also works across north. Keep the angle allowance between 0° and 90°, and adjust the minimum height to observations: a high minimum can miss low winter glare. Recheck the settings as seasons change.

3. Add the household's pause switch

Go to Settings → Devices & services → Helpers → Create helper → Toggle. Name it “Office sun shading” and keep it off during setup. Note its full entity ID; the code expects input_boolean.office_sun_shading. Add it to an Entities card on a dashboard the household uses, beside the normal shade control.

The Toggle helper normally restores its previous state after restart. Check any startup-state option your installed version offers. Off pauses this rule; it does not reopen the shade, stop a movement already sent, or pause other controllers. Turning it back on immediately checks the current conditions and can lower the shade once motor control is enabled.

Turn the toggle off before a manual adjustment. This example does not infer who moved the shade. A wall remote, voice command or vendor app can otherwise be followed by another shading command on the next check. For more elaborate pause/resume behavior, see manual overrides for Home Assistant automations.

4. Add the notification-only preview

Open Settings → Automations & scenes → Create automation → Create new automation. In the editor menu choose Edit in YAML, and paste the complete example below. YAML is the text form of the automation. Replace both entity IDs wherever they appear, set your window angles, and change the daytime hours to suit the room before saving.

The rule checks every five minutes, when Home Assistant starts, and when you turn the toggle on. Each check reads the current situation; it does not replay missed moves. Missing data, a moving shade, a paused routine or a position already close enough to the target stops the action list. The trigger documentation and action-list conditions describe these building blocks.

The code scrolls horizontally on a phone.

alias: Office sun shading - preview
description: Lower one shade for glare; preview first, no automatic reopening.
triggers:
  - trigger: time_pattern
    minutes: "/5"
  - trigger: homeassistant
    event: start
  - trigger: state
    entity_id: input_boolean.office_sun_shading
    to: "on"
conditions: []
actions:
  - condition: state
    entity_id: input_boolean.office_sun_shading
    state: "on"
  - condition: time
    after: "09:00:00"
    before: "17:30:00"
  - variables:
      window_direction: 270
      half_angle: 40
      minimum_elevation: 5
      shade_position: 35
      azimuth: "{{ state_attr('sun.sun', 'azimuth') }}"
      elevation: "{{ state_attr('sun.sun', 'elevation') }}"
      current_position: "{{ state_attr('cover.office_shade', 'current_position') }}"
  - condition: template
    value_template: >-
      {{ states('cover.office_shade') in ['open', 'closed']
         and states('sun.sun') in ['above_horizon', 'below_horizon']
         and is_number(azimuth) and is_number(elevation)
         and is_number(current_position) }}
  - condition: template
    value_template: >-
      {{ 0 <= (azimuth | float) <= 360
         and -90 <= (elevation | float) <= 90
         and 0 <= (current_position | float) <= 100 }}
  - condition: template
    value_template: >-
      {% set difference = (((azimuth | float) - window_direction + 180) % 360 - 180) | abs %}
      {{ difference <= half_angle
         and (elevation | float) >= minimum_elevation
         and (current_position | float) > shade_position + 10 }}
  - action: persistent_notification.create
    data:
      notification_id: office_sun_shading_preview
      title: "Office shade preview"
      message: >-
        At {{ now().strftime('%H:%M') }}, this rule would lower the shade
        from {{ current_position }}% to {{ shade_position }}% open.
        Sun direction: {{ azimuth }} degrees; height: {{ elevation }} degrees.
        Preview only: no motor command was sent.
mode: single

Turn “Office sun shading” on during the chosen hours. When all checks pass, Home Assistant's sidebar Notifications area should show “Office shade preview,” with a time, sun angles and proposed position. This is a notification inside Home Assistant, not a phone push alert. The fixed notification ID updates one message instead of creating a new item at every check. The message remains as the last qualifying decision; a later skipped check does not clear it.

If nothing appears, open the automation's Traces and find the condition that stopped it. That may be the correct result. Do not widen the real window settings simply to force a motor test.

5. Check the worked decisions before enabling movement

This table follows the example exactly. Unless stated otherwise, it is 14:00, the toggle is on, the west window settings are unchanged, and the shade is stationary with valid data. The results describe the configuration's logic, not observed hardware performance.

Scroll sideways on a phone to read all three columns.

SituationPreview resultReason
Sun 250°, elevation 20°; shade 100% open.Report a proposed move to 35% open.Direction difference is 20°; sunlight and position checks pass.
Same sun; shade already at 40% open.No new notification.The remaining difference is only five percentage points. The rule tolerates up to ten.
Same sun; you have closed the shade to 20% open.No new notification.The rule never opens a shade to reach its target.
Sun 315°, or elevation 4°.No new notification.Direction is outside the example range, or height is below its minimum.
It is 18:00, or the toggle is off.No new notification.The daytime or pause check stops the sequence.
The shade is unavailable, moving, or missing its position.No new notification.Missing feedback is not treated as an open shade.
A cloud passes while the sun remains at 250° and 20°.The basic rule can still qualify.It calculates direction, not brightness; see the optional sensor check below.
  1. Verify the pause harmlessly. Leave the code in preview mode, turn the toggle off, and choose Run actions. Its trace should stop at the first action-list condition, with no new notification or movement.
  2. Verify a qualifying decision. When sunlight reaches the window during the chosen hours, turn the toggle on and compare the notification's time and angles with the room. If the shade is already closed farther, a skipped result is expected.
  3. Check a later scheduled run. Read the trace after a five-minute clock boundary. Run actions alone does not test the triggers. An old preview message is not evidence that the latest check passed.

Run actions skips triggers and top-level conditions. Here the checks are deliberately inside the action list, so a whole-sequence manual run still respects them. Running an individual action separately can bypass earlier checks; keep the preview unchanged while rehearsing.

6. Enable movement for this one shade

After the preview makes sense, turn the toggle off. With the window clear and someone present, confirm the selected position using the shade's normal control. Then replace only the final persistent_notification.create action and its data block with this action, keeping all preceding checks:

  - action: cover.set_cover_position
    target:
      entity_id: cover.office_shade
    data:
      position: "{{ shade_position }}"

Replace the entity ID here too. Rename the automation “Office sun shading,” save it, and turn the toggle on when ready. A qualifying run should lower the shade to your target. Once it reports a position within ten percentage points above that target—or farther closed—later checks should send nothing. Read the trace and look at the shade; a completed action does not prove the motor reached its destination.

If movement fails or position feedback stays wrong, switch the toggle off. Otherwise the rule can retry on later five-minute checks. Repair the control path or calibration before resuming. Do not remove the position check to make an unresponsive motor keep trying.

This rule does not reopen the shade when the sun leaves, a cloud arrives, or the active hours end. For a manual reopening during the shading period, pause first. If you later add automatic reopening, give it explicit daytime/privacy conditions and honor the same pause switch. Do not reverse the shading condition and assume that “no glare” always means “open the window covering.”

Add a brightness check only if you need it

If cloudy afternoons make the shade close unnecessarily, add an illuminance sensor—a sensor that reports light level in lux. Observe readings during actual glare and under cloud before choosing a threshold. Place it where lowering this shade does not hide the light it is supposed to measure; check the sensor's environmental rating before placing it outdoors.

For example, insert this condition immediately before the final notification or motor action. Replace the entity ID and the illustrative 15,000 lux threshold with values appropriate to your sensor's placement:

  - condition: numeric_state
    entity_id: sensor.window_illuminance
    above: 15000

That means the reading must be strictly above the chosen threshold at the check; an unavailable or nonnumeric reading does not pass. This condition does not detect a sensor stuck on an old numeric reading. It only gates lowering. It does not reopen the shade under a cloud, so this version avoids cloud-driven open/close cycling. For the related problem of a lamp affecting its own sensor, see the guide to choosing room brightness thresholds.

When the result looks wrong

  • It moves when the room is already shaded: narrow the direction range using observations of trees and overhangs. Calculated sun position cannot see those obstructions.
  • It misses low winter glare: check the minimum elevation and active hours. Change them based on the room, not a universal “best” angle.
  • It fights a manual change: pause before using the remote. Also check vendor schedules and other automations; this toggle controls only this rule.
  • It never acts: find the stopped condition in Traces. Check exact entity IDs, local time, valid sun attributes and current_position. A tilt-only or open/close-only control does not meet the example's prerequisites.
  • It opens unexpectedly: this code never requests opening. Inspect other automations, vendor schedules and the motor's direction/calibration before enabling it again.

Frequently asked questions

Do I need a light sensor or weather service?

No. The starting rule uses calculated sun position and a fixed shade target. It may also lower the shade on cloudy days. A correctly placed light sensor adds a check for real brightness; it is optional, and its threshold is specific to that position.

Will this work without internet?

The Sun calculation and automation run in Home Assistant. Motor control also needs a working local integration to keep operating without internet. A cloud-dependent shade integration remains cloud-dependent. While Home Assistant itself is stopped, this rule cannot issue commands.

Does restarting Home Assistant reopen the shade?

No. Startup triggers a fresh check. If the toggle restores as on, the data is ready and the daytime shading conditions pass, the rule may lower the shade. If the data is not ready, a later five-minute check can try again. There is no reopening action.

For help combining shade controls, household pauses and other local routines, see Tara's home automation kit for coordinated local routines.