Contents

Automate Smart Blinds and Adaptive Lighting for Better Sleep

Your home’s lights are one of the best levers for better sleep, and you can set most of it on autopilot. Pair motorized blinds driven by Home Assistant solar elevation data with the Adaptive Lighting HACS integration. The combined setup shifts light and blind positions through the day, in step with your body clock. The result: a gentler wake-up, a calmer wind-down, and better sleep.

The Science of Circadian Lighting

The human circadian system is keenly sensitive to light. The intrinsically photosensitive retinal ganglion cells (ipRGCs) in the eye react strongly to short-wavelength blue light in the 470 to 490 nm range. Cool bluish light, typically in the 5000K to 6500K color range, blocks melatonin and tells the brain it’s daytime. Warm light in the 2200K to 2700K range mostly falls outside that band and won’t trigger the same response, so it’s safe (and even helpful) for evening use.

Lux levels carry just as much weight as color temperature. Studies show that more than 200 lux in the hour or two before bed delays sleep onset. Your brain reads the brightness as “daytime” and holds off on melatonin. The target for that pre-sleep window is below 10 lux, roughly candlelight. These numbers give you concrete, useful thresholds to build automations around.

The cleanest master variable in Home Assistant is solar elevation: the sun’s angle above the horizon in degrees. At solar noon in summer, elevation peaks above 60° at mid-latitudes, which lines up with bright daylight. At civil twilight (about minus 6°), useful daylight is gone. Solar elevation tracks the natural light your body evolved with, so using it as a trigger gives you a system that adapts to the seasons on its own. When winter days get shorter, the blinds and lights follow real solar geometry, not a fixed clock.

Studies on smart home lighting report 15 to 20% faster sleep onset in homes where circadian lighting is automated. The key point is that consistency beats perfection. A system that reliably dims and warms every evening trains the circadian system better than a manual one you skip when life gets busy.

Smart Blind Hardware Options

The motorized blind market has grown a lot. The right pick depends on your budget, the hardware you own, and how deep you want the Home Assistant tie-in to go.

Retrofit motors are the cheapest path if you own corded roller shades or venetian blinds. The SOMA Smart Shades 2 clips onto corded blinds and adds Wi-Fi or Bluetooth control. Zemismart sells a Zigbee retrofit motor that pairs with HA through Zigbee2MQTT or ZHA. Yoswit ships similar Zigbee retrofits with solid community support. Before you buy any retrofit motor, check the torque against the weight of your blinds. Heavy blackout shades need at least 1.5 N·m; light sheers may run on budget motors at 0.6 N·m.

Native smart blinds give you cleaner setup at a higher up-front cost. The IKEA KADRILJ and FYRTUR roller shades use Zigbee, stay cheap, and pair well with Home Assistant via ZHA or Zigbee2MQTT. Battery life runs 6 to 12 months. For a premium build, Lutron Serena shades use a closed radio (paired with the Lutron RA3 bridge) and earn praise for rock-solid uptime and near-silent motors.

Matter-ready options are the new standard. Eve MotionBlinds speaks Thread and Matter, so you only need a Thread border router (which modern HomePod mini and Apple TV 4K devices already provide). Home Assistant’s Matter integration gives you first-class control with almost no setup.

One spec people often miss: tilt vs. lift control. Roller shades give you only lift (how far open or closed). Venetian and slat blinds tilt to steer light without fully opening, which helps with the afternoon sun. If you want to block direct sun while keeping an outward view, pick blinds with tilt control.

Installing the Adaptive Lighting HACS Integration

You need HACS (Home Assistant Community Store) running before you can add Adaptive Lighting. Once HACS is up, open HACS → Integrations, search for “Adaptive Lighting,” install it, and restart Home Assistant. After the restart, go to Settings → Devices & Services → Add Integration, search for Adaptive Lighting, and add it.

Adaptive Lighting configuration panel in Home Assistant showing color temperature and brightness settings
The Adaptive Lighting integration provides granular control over color temperature curves, brightness, and sleep mode

The integration creates a switch.adaptive_lighting entity and a set of sensors that show the current color temperature and brightness. The key config knobs to know:

  • min_color_temp: Set to 2200K for a warm amber that sits well below the melatonin-blocking threshold.
  • max_color_temp: Set to 6500K for cool daylight at solar noon.
  • min_brightness: 1%. Adaptive Lighting dims lights to near-off at night.
  • max_brightness: 100%. Full brightness at solar noon.
  • sleep_mode: When you turn this on (via a companion input_boolean toggle), the integration drops to a red-tinted mode at about 800K and 1% brightness. It’s ideal for brief nighttime wake-ups.
  • only_once: When set to true, Adaptive Lighting sets the color temperature once on light activation and won’t re-apply it if you tweak the bulb. When false (the default), it keeps nudging the light back to the calculated value. For most people, false works best. Handle overrides through the sleep mode toggle or by turning the switch entity off for a while.

Any lights you add to the Adaptive Lighting config (including light groups) get managed for you. The integration works out the right color temperature and brightness from the current solar elevation every minute. It glides through the day with no extra automation code on your end.

Automating Blinds with Solar Elevation

Adaptive Lighting continuously adjusts color temperature and brightness based on solar position

Home Assistant’s sun.sun entity exposes elevation (degrees above the horizon) and azimuth as fields. They update every minute. These fields are the base of solar-aware blind control.

The trigger you want is numeric_state on sun.sun, watching the elevation attribute. Here’s a full automation set that covers the day:

# Morning: gentle dawn at 5° elevation
automation:
  - alias: "Blinds - Gentle Dawn Opening"
    trigger:
      - platform: numeric_state
        entity_id: sun.sun
        attribute: elevation
        above: 5
    condition:
      - condition: state
        entity_id: input_boolean.blinds_manual_override
        state: "off"
      - condition: time
        after: "05:00:00"
        before: "11:00:00"
    action:
      - service: cover.set_cover_position
        target:
          entity_id: cover.bedroom_blind
        data:
          position: 30

  # Afternoon: reduce solar heat gain on west windows above 60°
  - alias: "Blinds - Afternoon Solar Block"
    trigger:
      - platform: numeric_state
        entity_id: sun.sun
        attribute: elevation
        above: 60
    condition:
      - condition: state
        entity_id: input_boolean.blinds_manual_override
        state: "off"
    action:
      - service: cover.set_cover_position
        target:
          entity_id: cover.west_living_room_blind
        data:
          position: 50

  # Evening: close all blinds at civil twilight (-5°)
  - alias: "Blinds - Evening Close"
    trigger:
      - platform: numeric_state
        entity_id: sun.sun
        attribute: elevation
        below: -5
    condition:
      - condition: state
        entity_id: input_boolean.blinds_manual_override
        state: "off"
    action:
      - service: cover.set_cover_position
        target:
          entity_id:
            - cover.bedroom_blind
            - cover.west_living_room_blind
            - cover.office_blind
        data:
          position: 0

The input_boolean.blinds_manual_override helper is a key safety net. When someone moves a blind by hand, through the HA app or a physical remote, a second rule flips this boolean to on. That pauses all solar rules for the rest of the day. A time-based rule resets it to off at midnight, so auto control comes back the next morning. For a deeper take on targeting the triggering entity to stop unwanted rule firing, see the guide on Home Assistant guards.

# Reset override flag at midnight
automation:
  - alias: "Blinds - Reset Manual Override"
    trigger:
      - platform: time
        at: "00:00:00"
    action:
      - service: input_boolean.turn_off
        target:
          entity_id: input_boolean.blinds_manual_override

South-facing and north-facing rooms need their own rule paths. The sun’s azimuth (compass heading) decides which windows take direct light. Add an azimuth check with a template condition to fence a blind rule to the time of day when the sun is actually hitting that face of the house.

The Combined Morning Routine Automation

The morning routine builds a gradual wake-up that swaps the shock of an alarm for a simulated dawn. It leans on two input_datetime helpers, one for weekday wake time and one for weekend wake time, so the two schedules sort themselves out.

Create the helpers through Settings → Devices & Services → Helpers → Add Helper → Date and/or time. Name them input_datetime.wake_time_weekday and input_datetime.wake_time_weekend.

automation:
  - alias: "Morning Routine - Gradual Wake-Up"
    trigger:
      # Trigger 30 minutes before wake time on weekdays
      - platform: template
        value_template: >
          {% set wake = states('input_datetime.wake_time_weekday') %}
          {% set wake_dt = today_at(wake) %}
          {% set trigger_dt = wake_dt - timedelta(minutes=30) %}
          {{ now() >= trigger_dt and now() < wake_dt and
             now().weekday() < 5 }}
      # Trigger 30 minutes before wake time on weekends
      - platform: template
        value_template: >
          {% set wake = states('input_datetime.wake_time_weekend') %}
          {% set wake_dt = today_at(wake) %}
          {% set trigger_dt = wake_dt - timedelta(minutes=30) %}
          {{ now() >= trigger_dt and now() < wake_dt and
             now().weekday() >= 5 }}
    condition:
      - condition: state
        entity_id: input_boolean.sleep_mode
        state: "on"
    action:
      # T-30: Disable sleep mode, Adaptive Lighting warms up from 2200K/1%
      - service: switch.turn_off
        target:
          entity_id: switch.adaptive_lighting_sleep_mode
      - service: light.turn_on
        target:
          entity_id: light.bedroom_ceiling
        data:
          brightness_pct: 1
          color_temp_kelvin: 2200
          transition: 60

      # T-20: Open blinds to 10%, ramp lights to 10%
      - delay:
          minutes: 10
      - service: cover.set_cover_position
        target:
          entity_id: cover.bedroom_blind
        data:
          position: 10
      - service: light.turn_on
        target:
          entity_id: light.bedroom_ceiling
        data:
          brightness_pct: 10
          color_temp_kelvin: 2500
          transition: 120

      # T-10: Open blinds to 50%, lights at 3000K/40%
      - delay:
          minutes: 10
      - service: cover.set_cover_position
        target:
          entity_id: cover.bedroom_blind
        data:
          position: 50
      - service: light.turn_on
        target:
          entity_id: light.bedroom_ceiling
        data:
          brightness_pct: 40
          color_temp_kelvin: 3000
          transition: 120

      # Wake time: blinds fully open, daylight simulation
      - delay:
          minutes: 10
      - service: cover.set_cover_position
        target:
          entity_id: cover.bedroom_blind
        data:
          position: 100
      - service: light.turn_on
        target:
          entity_id: light.bedroom_ceiling
        data:
          brightness_pct: 80
          color_temp_kelvin: 5000
          transition: 120

      # Re-engage Adaptive Lighting to take over from here
      - service: switch.turn_on
        target:
          entity_id: switch.adaptive_lighting

After the routine ends, Adaptive Lighting takes over and keeps the natural daytime color curve going. If you set a preferred scene by hand earlier in the week, HA’s scene feature can save and restore it. Use scene.create with a snapshot_entities list to grab the current light state before the routine fires, then scene.turn_on afterward to put it back.

Evening Wind-Down Automation

The evening automation mirrors the morning routine in reverse. Ninety minutes before your target sleep time (stored in input_datetime.sleep_time), the sequence kicks off:

automation:
  - alias: "Evening Wind-Down"
    trigger:
      - platform: template
        value_template: >
          {% set sleep = states('input_datetime.sleep_time') %}
          {% set sleep_dt = today_at(sleep) %}
          {% set trigger_dt = sleep_dt - timedelta(minutes=90) %}
          {{ now() >= trigger_dt and now() < sleep_dt + timedelta(minutes=1) }}
    condition:
      - condition: state
        entity_id: input_boolean.guest_mode
        state: "off"
    action:
      # Adaptive Lighting handles the gradual 4000K → 2200K transition automatically.
      # Ensure it is active and sleep mode is off at this point.
      - service: switch.turn_on
        target:
          entity_id: switch.adaptive_lighting

      # At T-30, close all blinds except bedroom (leave 10% gap until lights-out)
      - delay:
          minutes: 60
      - service: cover.set_cover_position
        target:
          entity_id:
            - cover.west_living_room_blind
            - cover.office_blind
        data:
          position: 0
      - service: cover.set_cover_position
        target:
          entity_id: cover.bedroom_blind
        data:
          position: 10

      # At sleep time: activate sleep mode and close bedroom blind fully
      - delay:
          minutes: 30
      - service: switch.turn_on
        target:
          entity_id: switch.adaptive_lighting_sleep_mode_bedroom
      - service: cover.set_cover_position
        target:
          entity_id: cover.bedroom_blind
        data:
          position: 0
      - service: input_boolean.turn_on
        target:
          entity_id: input_boolean.sleep_mode

Adaptive Lighting handles the gradual color shift from 4000K at the start of the wind-down through 3000K to 2200K on its own. No manual light.turn_on calls needed. The automation just has to keep the integration active and stop sleep mode from kicking in too early.

Movie mode override lives in a script that pauses the wind-down when your TV turns on:

script:
  movie_mode:
    alias: "Movie Mode"
    sequence:
      - service: switch.turn_off
        target:
          entity_id: switch.adaptive_lighting
      - service: light.turn_on
        target:
          entity_id: light.living_room
        data:
          brightness_pct: 30
          color_temp_kelvin: 3000
      - service: cover.set_cover_position
        target:
          entity_id: cover.west_living_room_blind
        data:
          position: 0

Fire this script from an automation that watches media_player.living_room_tv for a playing state during the wind-down window. When the movie ends and the TV flips to idle or off, a paired automation turns Adaptive Lighting back on and picks up the normal wind-down again.

Sleep mode activation can fire in several ways: scan a bedside NFC tag (set up in the HA Companion App), have your phone connect to the bedroom Wi-Fi SSID (caught by a network scanner and device tracker), or tap an app widget by hand. All three should call the same script or set the same input_boolean.sleep_mode helper.

Tuning and Edge Cases

Overcast days expose the limit of solar-elevation-only logic. On an overcast December day, outdoor lux can sit below 500 even at noon. Midday feels as dim as dawn. A lux sensor fixes this. A BH1750 light sensor wired to an ESP32 via I2C and flashed with ESPHome costs about $3 and feeds live lux readings into your HA instance. Many Zigbee multisensors (such as the Aqara E1 or SONOFF SNZB-02P) also include a lux channel. With a lux sensor, you can layer extra checks on the blind rules: “only open blinds to 30% at 5° elevation if outdoor lux > 500, otherwise wait until lux > 1000.” That blocks early morning openings on rainy days, which would let in cold drafts with little light payoff.

Guest mode is a useful quality-of-life safety net. Create an input_boolean.guest_mode helper and add it as a check in every circadian rule. When guests stay over, flipping this boolean freezes all auto blind and lighting changes. You get full manual control without turning off each rule by hand. A dashboard button is enough. You can also add a time-limited version that flips guest mode off after 24 or 48 hours.

Seasonal shifts are where solar elevation truly beats a clock. At 45° latitude, the sun’s noon elevation is about 21° in December and 68° in June. A fixed clock rule that closes west-facing blinds at 3:00 PM year-round will close them too early in winter, when the sun is already low and you want the heat. In summer, the same rule closes too late. With elevation cutoffs, the same rule shifts its fire time by two or more hours between seasons. It tracks real solar geometry with no user input.

Multi-orientation rooms need their own rule paths per cover entity. A room with east-facing and west-facing windows needs two rules. East windows should be partly closed in the morning to block glare. West windows need closing in the afternoon. Well-named cover entities (cover.bedroom_east_blind, cover.bedroom_west_blind) with one rule each are cleaner than one big rule with branches.

Cost Breakdown: Budget vs. Premium Build

Knowing the cost picture helps you decide where to spend.

Budget build, IKEA FYRTUR plus Adaptive Lighting:

  • IKEA FYRTUR blackout blind (per window): $100-130 USD
  • IKEA DIRIGERA hub (required for Zigbee): $65 USD (or use existing Zigbee coordinator)
  • Adaptive Lighting integration: free (open source, HACS)
  • BH1750 lux sensor + ESP32: ~$8 USD
  • Typical 2-bedroom setup (4 blinds): ~$500-600 USD total

FYRTUR has solid Home Assistant support through Zigbee2MQTT or ZHA, and the blackout fabric is great for sleep. The catch is battery-only power and a fairly slow motor.

Premium build, Lutron Serena plus Lutron RA3 bridge:

  • Lutron Serena roller shades (per window): $350-500 USD
  • Lutron RA3 bridge: $200 USD
  • Lutron HA integration: free (official integration)
  • Typical 2-bedroom setup (4 blinds): ~$1,800-2,400 USD total

The Lutron stack gives you near-instant response, near-silent motors, wired power for heavy-use windows, and a closed radio (Clear Connect) that almost never sees noise. The official Home Assistant Lutron Caseta/RA3 integration gives you full cover control. For a home where blinds are the main privacy and light tool, and budget comes second, Lutron is the pro’s pick.

The middle ground is Eve MotionBlinds (Thread/Matter): about $200 to $250 per window, no hub needed, strong HA integration, and a clear future-proofing path as the Matter ecosystem grows.


Pairing solar elevation rules with Adaptive Lighting builds a home that works with your body, not against it. The morning routine cuts the shock of an alarm. The evening sequence builds a steady wind-down cue your body clock learns to expect. Once tuned, the setup runs on its own. It adjusts for the seasons, reacts to overcast days, and yields to manual overrides when guests show up or movie night runs long. The hardware bill runs from a few hundred dollars with IKEA blinds to a few thousand with Lutron, but the setup work is the same. The sleep gain is there at every price point. To stretch your Home Assistant setup further, pair this with home energy monitoring for a full view of how your blinds and lights hit your power bill.