Skip to content

Nickduino/adaptive-cover-pro

 
 

Repository files navigation

Version Tests Hassfest HACS Coverage

logo logo

Adaptive Cover Pro

This Custom-Integration provides sensors for vertical and horizontal blinds based on the sun's position by calculating the position to filter out direct sunlight.

This integration builds upon the template sensor from this forum post Automatic Blinds

Credits

Adaptive Cover Pro is a fork of the original Adaptive Cover integration created by Bas Brussee (@basbruss).

This fork includes enhancements and modifications, but the core functionality and architecture are based on Bas Brussee's excellent work. Please visit the original repository to see the upstream project and consider supporting the original author.

For Developers

If you're interested in contributing to this project, please see the Development Guide (docs/DEVELOPMENT.md) for comprehensive documentation on:

  • Setting up your development environment
  • Project structure and architecture
  • Development workflow and scripts
  • Testing strategies
  • Release process (automated with ./scripts/release)
  • Code standards and best practices

Testing the Algorithms

Want to visualize how the blinds will behave before installing? The Jupyter notebook (notebooks/test_env.ipynb) lets you test and visualize the position calculation algorithms without needing Home Assistant or physical covers.

Quick Start

1. Install Jupyter:

pip install jupyter matplotlib pandas pvlib

2. Run the notebook:

# From the repository root
jupyter notebook notebooks/test_env.ipynb

Or open in VS Code with the Jupyter extension installed.

3. Configure and run:

  • Modify the configuration variables (location, window dimensions, orientation)
  • Run all cells (Cell → Run All)
  • Review the plots showing cover positions throughout the day

What You'll See

The notebook generates two plots:

  • Vertical Cover Plot - Shows blind position based on sun position for up/down blinds
  • Horizontal Cover Plot - Shows awning extension for in/out awnings

Each plot displays:

  • Sun elevation and azimuth over 24 hours
  • Calculated cover position overlaid
  • Sunrise/sunset times (red lines)
  • When sun enters/exits your window's field of view (yellow lines)

Example Configuration

# Location (modify for your testing location)
timezone = "America/New_York"  # Your timezone
lat = 40.7128                  # Your latitude
lon = -74.0060                 # Your longitude

# Window properties
windown_azimuth = 180          # 180 = South-facing
window_fov_left = 90           # Field of view (degrees)
window_fov_right = 90
window_height = 3              # meters
window_distance = 0.5          # Distance from window to blind (meters)

Perfect for:

  • Testing different window orientations before configuration
  • Experimenting with field of view angles
  • Validating behavior for your specific location
  • Understanding how the algorithm responds to sun position

For detailed documentation, see the Manual Testing section in CLAUDE.md.

Table of Contents

Features

  • Individual service devices for vertical, horizontal and tilted covers

  • Two mode approach with multiple strategies Modes(basic,climate)

  • Binary Sensor to track when the sun is in front of the window

  • Sensors for start and end time

  • Auto manual override detection

  • Smart device naming - automatically suggests device names based on your cover entities

  • Support for both position-capable and open/close-only covers

    • Automatic detection of cover capabilities at runtime
    • Configurable threshold for open/close decision (default 50%)
  • Climate Mode

    • Weather condition based operation
    • Presence based operation
    • Switch to toggle climate mode
    • Sensor for displaying the operation modus (winter,intermediate,summer)
  • Adaptive Control

    • Turn control on/off
    • Control multiple covers
    • Optional return to default position when automatic control is disabled
    • Set start time to prevent opening blinds while you are asleep
    • Set minimum interval time between position changes
    • Set minimum percentage change
    • Force Override Sensors - Weather safety protection
      • Configure binary sensors (rain, wind, etc.) that override automatic control
      • When ANY sensor is active, ALL covers move to a configured safe position
      • Default position: 0% (fully retracted/closed) for rain/wind protection
      • Customizable position: Set to 100% for security sensors (emergency access)
      • Manual control still works during force override
    • Motion-Based Automatic Control - Occupancy-based automation
      • Configure motion sensors to enable/disable sun positioning based on room occupancy
      • When ANY sensor detects motion, covers use automatic sun-based positioning
      • When ALL sensors show no motion for configured timeout, covers return to default position
      • Debouncing prevents position flapping from rapid sensor toggling (30-3600 seconds, default 300)
      • OR logic for multiple sensors - ANY room with motion enables automatic positioning
      • Use cases: Glare control when present, energy savings when away, privacy when unoccupied
      • Optional feature - leave sensor list empty to disable
    • Automatic Position Verification (built-in reliability feature)
      • Periodically verifies covers reached the positions we sent them to (every 2 minutes)
      • Automatically retries failed position commands (up to 3 attempts)
      • Detects position mismatches between target and actual position (3% tolerance)
      • Respects manual override detection and skips during active moves
      • Separate from normal position updates - only retries failed commands, doesn't chase sun movement
      • No configuration required - works automatically when automatic control is enabled
      • Diagnostic sensors available for troubleshooting cover movement issues
  • Diagnostic Sensors (Optional, enable in automation settings)

    • Real-time troubleshooting sensors to understand integration behavior
    • All sensors use diagnostic entity category
    • Priority 0 sensors (enabled by default when diagnostics are on):
      • Sun position (azimuth, elevation, gamma)
      • Control status (why covers aren't moving)
      • Control state reason (human-readable explanation of current cover position)
      • Calculated position (before adjustments)
      • Last cover action (tracks most recent cover action with full details)
      • Manual override end time (when automatic control will resume)
    • Priority 1 sensors (disabled by default, enable individually):
      • Position verification tracking (last check time, retry counts, mismatch detection)
      • Active temperature (climate mode only)
      • Climate conditions (climate mode only)
      • Time window status
      • Sun validity status
  • Enhanced Geometric Accuracy (automatic improvements)

    • Angle-dependent safety margins for better sun blocking at extreme angles
    • Automatic edge case handling for very low/high sun elevations
    • Smooth transitions across all sun angles using interpolation
    • Optional window depth parameter for advanced precision
    • No configuration required - works automatically
    • Backward compatible - existing installations benefit immediately

Known Limitations & Best Practices

Temperature Unit Consistency

IMPORTANT: All temperature sensors used in Climate mode must use the same unit system. The integration currently does not perform automatic unit conversion between Fahrenheit and Celsius.

  • If your Indoor Temperature Entity reports in Celsius, your Outdoor Temperature Entity must also report in Celsius
  • The Minimum Comfort Temperature and Maximum Comfort Temperature values should match your sensor units
  • Mixing °F and °C will result in incorrect calculations

Workaround: Ensure all climate entities report in the same units, or use template sensors to convert them to a consistent unit.

Future: Automatic unit system support is planned (see Features Planned)

Start with Basic Mode

If you're new to Adaptive Cover Pro, we strongly recommend:

  1. Start with Basic Mode - Configure and test basic sun position-based control first
  2. Understand the calculations - Observe how your covers respond to sun position throughout the day
  3. Add Climate Mode gradually - Once comfortable with Basic Mode, enable Climate Mode and add temperature/presence features incrementally

Climate Mode introduces additional complexity with temperature thresholds, presence detection, and weather conditions. Understanding Basic Mode operation first will help you troubleshoot issues more effectively.

Venetian Blinds (Dual Control)

Home Assistant cover entities can only control a single dimension (position OR tilt angle, not both simultaneously). For venetian blinds that support both vertical movement and slat tilting:

You must create TWO separate Adaptive Cover Pro instances:

  1. Vertical instance - Controls up/down position using the same cover entity
  2. Tilt instance - Controls slat angle using the same cover entity

Example:

  • Instance 1: "Adaptive Office Blind Vertical" → Controls cover.office_blind position (0-100%)
  • Instance 2: "Adaptive Office Blind Tilt" → Controls cover.office_blind tilt angle (0-100%)

Both instances monitor the sun independently and send appropriate commands to the same physical device.

Weather Entity Reliability

Weather entities in Home Assistant may not always reflect real-time conditions accurately, which can affect Climate Mode operation:

  • Weather forecasts may lag actual conditions
  • Some integrations update infrequently (e.g., hourly)
  • Not all weather services distinguish between types of cloud cover

Recommendations:

  • Consider using lux sensors or irradiance sensors for more accurate real-time light level detection
  • The integration supports both Lux Entity and Irradiance Entity for direct sunlight measurement
  • If using weather entities, verify they update frequently enough for your needs (every 5-15 minutes is ideal)

Sensor Startup Reliability

The integration gracefully handles sensors that are unavailable during Home Assistant startup (common with Zigbee2MQTT, Z-Wave, and other hub-based devices):

  • Automatic recovery: If temperature, lux, or irradiance sensors report unavailable or None during startup, the integration uses safe defaults and continues operating
  • Typical startup time: Zigbee2MQTT devices often take 20-60 seconds to initialize after Home Assistant starts
  • No manual intervention required: Once sensors become available, the integration automatically uses their values

What happens during startup:

  • Missing lux/irradiance sensors → Defaults to "light available" (continues with weather-based operation)
  • Missing temperature sensors → Defaults to "comfortable" range (uses basic glare calculations)
  • Missing weather sensors → Uses sun position calculations only

This ensures your covers operate correctly even during brief sensor outages or Home Assistant restarts.

Open/Close-Only Covers

Covers that only support OPEN and CLOSE commands (no position control) are supported with threshold-based control:

  • The integration calculates position as normal (0-100%)
  • If calculated position ≥ threshold → cover opens
  • If calculated position < threshold → cover closes
  • Default threshold is 50% (adjustable in Automation settings, 1-99%)

Limitations:

  • Granular position control is not possible
  • Intermediate positions are not available
  • Tilt covers must support SET_TILT_POSITION (open/close mode not supported)

Example Use Cases:

  • Simple roller shutters with only up/down buttons
  • Garage doors with open/close only
  • Budget blinds without position feedback

Inverse State with Open/Close-Only Covers:

The "Inverse the state" option works with open/close-only covers by inverting the calculated position before comparing to the threshold:

  • Without inverse: Position 30% → 30% < 50% → CLOSE command
  • With inverse: Position 30% → inverted to 70% → 70% ≥ 50% → OPEN command

This allows the integration to support covers with non-standard OPEN/CLOSE behavior that don't follow Home Assistant guidelines. Enable this option if your cover's OPEN and CLOSE commands appear to work backwards.

Response Time and Control Delays

The integration uses periodic checks to balance responsiveness with system performance. Understanding these timing behaviors helps set appropriate expectations:

Time Window Transitions (Start/End Times):

  • When start time or end time is reached, covers will respond within 1 minute
  • The integration checks time window state every minute and triggers immediate action when transitions occur
  • Log messages will indicate: "Time window state changed: inactive → active" (or vice versa)

Sun Position Changes:

  • Sun position changes trigger updates immediately
  • Temperature, weather, and presence sensor changes also trigger immediate updates
  • Delta position and delta time settings control how frequently covers actually move

After Home Assistant Restart:

  • Covers are automatically repositioned during first refresh (typically within 30 seconds)
  • Target positions are calculated and stored even if covers don't need to move
  • Position verification begins immediately after first refresh

Position Verification:

  • Every minute, the integration verifies covers reached their target positions
  • If a mismatch is detected (e.g., cover failed to move), automatic retry occurs
  • Up to 3 retry attempts before logging a warning

Why Not Instant?

  • Periodic checks balance responsiveness with Home Assistant performance
  • Prevents excessive processor usage from continuous monitoring
  • 1-minute intervals are imperceptible for sun-based automation (sun moves slowly)
  • Immediate triggers still available for sun position, temperature, and sensor changes

Recommendation:

  • For time-critical automations at specific times, consider using Home Assistant automations that trigger on time patterns instead of relying on start/end times
  • Start/end times are designed for daily operational windows, not precision timing

Enhanced Geometric Accuracy

Adaptive Cover Pro includes sophisticated geometric calculations to ensure accurate sun blocking even at extreme sun angles. These improvements work automatically - no configuration required.

Angle-Dependent Safety Margins

Safety margins automatically increase blind extension at extreme angles to compensate for geometric uncertainties:

  • Horizontal angles (gamma): Up to 20% increase when sun is at extreme side angles (>45° from direct front)
  • Low elevations: Up to 15% increase when sun is near the horizon (<10° elevation)
  • High elevations: Up to 10% increase when sun is nearly overhead (>75° elevation)
  • Combined extremes: Margins multiply together (e.g., 85° gamma + 8° elevation ≈ 27% total increase)

Margins activate automatically, use smoothstep interpolation for smooth transitions, and are zero at normal angles (gamma < 45°, 10° < elevation < 75°). Check the "Control Status" diagnostic sensor to see when margins are active.

Edge Case Handling

Automatic fallback positions for extreme conditions where standard calculations become unreliable:

Condition Behavior Reason
Elevation < 2° Full window coverage Sun nearly horizontal, precise calculation unreliable
|Gamma| > 85° Full window coverage Sun perpendicular to window, standard formula unstable
Elevation > 88° Simplified calculation Sun nearly overhead, path length correction minimal

Optional Window Depth

For users who want maximum precision, the Window Depth parameter accounts for window reveals/frames creating additional shadow at angled sun positions.

Configuration

Located in the vertical blind configuration screen:

Parameter: Window Depth (Reveal) Range: 0.0 - 0.5 meters (0 - 50cm) Default: 0.0 (disabled) Unit: meters

Typical values:

  • 0.0m - Disabled (default)
  • 0.05m (2 inches) - Flush-mounted windows
  • 0.10m (4 inches) - Standard window frames
  • 0.15m (6 inches) - Deep reveals or thick walls

How to measure:

  1. Stand outside your building
  2. Measure from the outer wall surface to the inner edge of the window frame
  3. Convert to meters (1 inch ≈ 0.025m, 1 foot ≈ 0.30m)

How It Works

Window depth creates an additional horizontal offset at angled sun positions:

Outer wall surface
    |
    |<-- Window Depth -->|
    |                    Window glass
                         |
                         Sun at angle

At angled sun positions (gamma > 10°), the window depth effectively extends the glare zone, requiring the blind to extend further to block sunlight.

Effect magnitude:

  • Zero effect at gamma < 10° (sun directly in front)
  • Minimal effect at gamma 10-30° (1-3cm additional extension)
  • Moderate effect at gamma 30-60° (3-8cm additional extension)
  • Significant effect at gamma > 60° (8-15cm additional extension)

Example:

  • Window depth: 0.10m (4 inches)
  • Sun angle: gamma = 45° from window normal
  • Additional blind extension: ≈7cm
  • Result: Tighter sun blocking at angled positions

When to Use Window Depth

Enable window depth (set > 0) if:

  • You notice sun "leaking" around the blind at extreme angles
  • Your windows have deep reveals (thick walls, recessed frames)
  • You want maximum precision for critical applications (art preservation, glare-sensitive workspaces)
  • You're willing to measure window depth accurately

Leave at default (0.0) if:

  • Your windows are flush-mounted or nearly flush
  • Current sun blocking is satisfactory
  • You prefer simpler configuration

Backward Compatibility

  • Existing installations: Unaffected — window_depth defaults to 0.0
  • Optional enhancement: Set window_depth > 0 only if needed
  • No performance impact: Adds minimal computational cost

Technical Details

Safety Margin Formula

The integration calculates safety margins using smoothstep interpolation for smooth transitions:

# Gamma margin (horizontal angles)
if gamma_abs > 45°:
    t = (gamma_abs - 45°) / 45°  # 0 at 45°, 1 at 90°
    smooth_t = t² × (3 - 2t)     # Smoothstep
    margin += 0.2 × smooth_t     # Up to 20%

# Elevation margins
if elevation < 10°:
    t = (10° - elevation) / 10°
    margin += 0.15 × t  # Up to 15%
elif elevation > 75°:
    t = (elevation - 75°) / 15°
    margin += 0.10 × t  # Up to 10%

Window Depth Contribution

if window_depth > 0 and |gamma| > 10°:
    depth_contribution = window_depth × sin(|gamma|)
    effective_distance = base_distance + depth_contribution

Regression Testing

All enhancements are verified to:

  • Maintain <5% deviation from baseline at normal angles
  • Never reduce protection (always ≥ baseline position)
  • Produce no NaN, infinity, or numerical errors
  • Provide smooth transitions across all angle ranges

Test Coverage

  • 34 dedicated tests for geometric accuracy
  • 214 total integration tests (all passing)
  • 92% code coverage on calculation engine

Diagnostic Sensors

Enable diagnostic sensors to monitor enhanced geometric accuracy:

Key sensors:

  • Calculated Position - Raw calculated position before adjustments
  • Sun Gamma - Horizontal angle from window normal
  • Sun Elevation - Vertical angle above horizon
  • Control Status - Shows active safety margins and adjustments

Compare "Calculated Position" to actual cover position to see safety margin effects.

Troubleshooting

Q: My blinds extend more than before at extreme angles A: This is expected behavior. Safety margins automatically increase extension at challenging angles to ensure effective sun blocking. You can check the diagnostic sensor "Control Status" to see when margins are applied.

Q: Should I enable window depth? A: Only if you notice sun leaking at extreme angles or have deep window reveals (>10cm). Most users don't need this.

Q: Can I disable the safety margins? A: No, safety margins are automatic and cannot be disabled. They're essential for reliable sun blocking at extreme angles. However, margins are zero at normal angles (gamma < 45°, 10° < elevation < 75°).

Q: How do I measure window depth accurately? A: Use a tape measure or ruler to measure from the outer wall surface (outside your home) to the inner edge of the window frame. If you're unsure, leave at the default (0.0) — the automatic safety margins work well without it.

Installation

HACS (Recommended)

Add https://github.com/jrhubott/adaptive-cover-pro as custom repository to HACS. Search and download Adaptive Cover Pro within HACS.

Restart Home-Assistant and add the integration.

Manual

Download the adaptive_cover_pro folder from this github. Add the folder to config/custom_components/.

Restart Home-Assistant and add the integration.

Migrating from Adaptive Cover

Adaptive Cover Pro includes an automatic import tool to migrate your existing Adaptive Cover configurations seamlessly. This allows you to preserve all your settings without manual reconfiguration.

How to Import

  1. Install Adaptive Cover Pro from HACS (see Installation above)
  2. Restart Home Assistant
  3. Go to SettingsDevices & ServicesAdd Integration
  4. Search for "Adaptive Cover Pro"
  5. If you have existing Adaptive Cover installations, you'll see a menu with two options:
    • Create new configuration - Set up a fresh configuration
    • Import from Adaptive Cover (X found) - Import existing configurations
  6. Select Import from Adaptive Cover
  7. Choose which configurations to import (you can select multiple)
  8. Review the configuration summary
  9. Confirm the import

The import process will detect all your loaded Adaptive Cover entries and guide you through migrating them.

What Gets Imported

All configuration settings are preserved during import:

  • Window Parameters: Azimuth, field of view, height, distance, elevation limits
  • Cover Entities: All associated cover entities
  • Position Settings: Default position, min/max positions, sunset position
  • Automation Settings:
    • Delta position and delta time thresholds
    • Start and end times (fixed times and entity-based)
    • Manual override settings (duration, threshold, reset behavior)
    • Return to sunset position option
  • Climate Mode Settings:
    • Temperature entities and thresholds
    • Presence detection entities
    • Weather entities and sunny state definitions
    • Outside temperature thresholds
  • Advanced Features:
    • Blind spot configurations
    • Interpolation settings
    • Transparent blind mode
    • Light sensors (lux and irradiance thresholds)

All 50+ configuration fields are mapped 1:1 from the original integration.

After Import

Once the import completes successfully:

  1. Verify the imported configurations work correctly
    • Check that entities are created properly
    • Verify the position calculations match your expectations
  2. Test cover movements to ensure automation works as expected
  3. Review and adjust any settings if needed through the Configure options
  4. When you're confident everything works correctly:
    • Disable the old Adaptive Cover integration entries in Settings → Devices & Services
    • Optional: Remove the old Adaptive Cover from HACS if you no longer need it

Important Notes:

  • Both integrations can run simultaneously during the transition period
  • Your original Adaptive Cover entries remain completely unchanged
  • If anything goes wrong, you can simply disable Adaptive Cover Pro and continue using the original
  • Entity IDs will be different between the two integrations, so you may need to update automations and dashboards

Import from Options Menu

You can also import additional configurations later if you add more Adaptive Cover entries:

  1. Go to SettingsDevices & Services
  2. Find your Adaptive Cover Pro integration
  3. Click Configure
  4. Select Import another Adaptive Cover configuration from the menu
  5. Follow the same import process

This is useful if you want to migrate your configurations gradually or if you add new Adaptive Cover entries after the initial migration.

Setup

Adaptive Cover Pro supports (for now) three types of covers/blinds; Vertical and Horizontal and Venetian (Tilted) blinds. Each type has its own specific parameters to setup a sensor. To setup the sensor you first need to find out the azimuth of the window(s). This can be done by finding your location on Open Street Map Compass.

During setup, the integration will automatically suggest a device name based on the first cover entity you select, prefixed with "Adaptive" (e.g., "Living Room Blind" becomes "Adaptive Living Room Blind"). You can modify this suggested name if desired.

Enhanced Configuration UI: The setup flow includes comprehensive descriptions for every configuration field, with practical examples, recommended values, and explanations of technical terms. Each field now provides context about why it matters and how it affects cover behavior, making configuration easier for both new and experienced users.

Cover Types

Vertical Horizontal Tilted
alt text alt text alt text
Movement Up/Down In/Out Tilting
variables variables variables
Note For venetian blinds with both vertical and tilt capabilities, see Known Limitations

Modes

This component supports two strategy modes: A basic mode and a climate comfort/energy saving mode that works with presence and temperature detection.

  graph TD

  A[("fa:fa-sun Sundata")]
  A --> B["Basic Mode"]
  A --> C["Climate Mode"]

  subgraph "Basic Mode"
      B --> BA("Sun within field of view")

      BA --> |No| BC{{Default}}
      BC --> BE("Time between sunset and sunrise?")
      BE --> |Yes| BF["Return default"]
      BE --> |No| BG["Return Sunset default"]

      BA --> |Yes| BD("Elevation above 0?")
      BD --> |Yes| BH{{"Calculated Position"}}
      BD --> |No| BC
  end

  subgraph "Climate Mode"
      C --> CA("Check Presence")
  end

  subgraph "Occupants"
      CA --> |True| CB("Temperature above maximum comfort (summer)?")

      CB --> |Yes| CD("Transparent blind?")
      CB --> |No| CE("Lux/Irradiance below threshold or Weather is not sunny?")

      CD --> |Yes| CF["Return fully closed (0%)"]
      CD --> |No| B

      CE --> |Yes| CG("Temperature below minimum comfort (winter) and sun infront of window and elevation > 0?")
      CE --> |No| B

      CG --> |Yes| CH["Return fully open (100%)"]
      CG --> |No| BC
  end

  subgraph "No Occupants"
      CA --> |False| CC("Sun infront of window and elevation > 0?")
      CC --> |No| BC
      CC --> |Yes| CI("Temperature above maximum comfort (summer)?")
      CI --> |Yes| CF
      CI --> |No| CJ("Temperature below minimum comfort (winter)")
      CJ --> |Yes| CH
      CJ --> |No| BC
  end
Loading

Basic mode

This mode uses the calculated position when the sun is within the specified azimuth range of the window. Else it defaults to the default value or after sunset value depending on the time of day.

Climate mode

⚠️ Start with Basic Mode First Climate mode adds significant complexity with temperature thresholds, presence detection, and weather conditions. We recommend configuring Basic mode first and ensuring it works correctly before enabling Climate mode features.

Temperature Unit Consistency Required: All temperature sensors must use the same unit system (°C or °F). The integration does not automatically convert between units. See Known Limitations for details.

This mode calculates the position based on extra parameters for presence, indoor temperature, minimal comfort temperature, maximum comfort temperature and weather (optional). This mode is split up in two types of strategies; Presence and No Presence.

Climate strategies

Climate mode uses a priority-based decision system to balance comfort, energy efficiency, and glare reduction:

  • No Presence: Providing daylight to the room is no objective if there is no presence.

    • Below minimal comfort temperature (Winter Mode): If the sun is above the horizon and the indoor temperature is below the minimal comfort temperature it opens the blind fully or tilt the slats to be parallel with the sun rays to allow for maximum solar radiation to heat up the room.

    • Above maximum comfort temperature (Summer Mode): The objective is to not heat up the room any further by blocking out all possible radiation. All blinds close fully to block out light.

      If the indoor temperature is between both thresholds the position defaults to the set default value based on the time of day.

  • Presence (or no Presence Entity set): The objective is to reduce glare while providing daylight to the room. The system uses the following priority order:

    1. Winter Mode (Priority 1): When indoor temperature is below the minimal comfort threshold and the sun is in front of the window, blinds open to 100% for solar heating. This takes priority over all other conditions including light sensors and weather state.

    2. Low Light Conditions (Priority 2): When it's not summer and light levels are low (lux/irradiance below threshold) or weather is not sunny, the position defaults to the configured default value to allow more sunlight while minimizing glare.

    3. Summer Mode (Priority 3): When indoor temperature is above the maximum comfort threshold with transparent blinds, blinds close to 0% to block heat.

    4. Normal Glare Calculation (Priority 4): In all other conditions (comfortable temperature on sunny days), uses the basic sun-tracking calculation to reduce glare while providing daylight.

    Weather Integration: If you configure a weather entity, the system checks if the current weather state indicates direct sunlight (default states: sunny, windy, partlycloudy, cloudy - customizable in weather options). However, winter mode (Priority 1) activates regardless of weather or light conditions when temperature thresholds are met.

    Tilted Blinds: Follow the same priority system, but in summer mode (when inside temperature exceeds maximum comfort), slats are positioned at 45 degrees as this is found optimal for heat blocking while maintaining some light.

Variables

Common

Field of View and Blind Spot diagram

Variables Default Range Description
Entities [] Denotes entities controllable by the integration
Window Azimuth 180 0-359 The compass direction of the window, discoverable via Open Street Map Compass
Default Position 60 0-100 Initial position of the cover in the absence of sunlight glare detection
Minimal Position 100 0-99 Minimal opening position for the cover, suitable for partially closing certain cover types
Maximum Position 100 1-100 Maximum opening position for the cover, suitable for partially opening certain cover types
Field of view Left 90 0-180 Unobstructed viewing angle from window center to the left, in degrees
Field of view Right 90 0-180 Unobstructed viewing angle from window center to the right, in degrees
Minimal Elevation None 0-90 Minimal elevation degree of the sun to be considered
Maximum Elevation None 1-90 Maximum elevation degree of the sun to be considered
Default position after Sunset 0 0-100 Cover's default position from sunset to sunrise
Offset Sunset time 0 Additional minutes before/after sunset
Offset Sunrise time 0 Additional minutes before/after sunrise
Inverse State False Calculates inverse state for covers fully closed at 100%

Position Limits: Min and Max Position

The Minimal Position and Maximum Position settings create boundaries for automatic cover control. Each limit has an associated toggle that controls when the limit applies:

Apply min/max only during sun tracking (toggles):

  • Unchecked (default, recommended): The position limit applies ALL THE TIME - during sun tracking, default position, climate modes, and all other states. The cover will never go below the minimum or above the maximum value.
  • Checked (advanced): The position limit ONLY applies when the sun is directly in front of the window during active sun tracking. During default/fallback states (sun behind window, outside tracking hours, etc.), the cover can go below minimum or above maximum values.

Most users should leave these toggles UNCHECKED for consistent protection and predictable behavior. The "checked" option is for advanced users who want limits to apply only during active sun tracking, allowing more flexibility during other times.

Common use cases:

  • Minimum Position (e.g., 20%): Prevents cover from fully closing, maintains some natural light, protects from jamming at bottom
  • Maximum Position (e.g., 80%): Prevents cover from fully opening, maintains some privacy/shade, protects from jamming at top

Position Interpolation (Range Adjustment)

Position Interpolation allows you to adjust how calculated positions (0-100%) map to actual cover positions sent to your devices. This is useful for covers with non-standard behavior or limited operating ranges.

When to use:

  • Covers that don't respond across the full 0-100% range
  • Covers that need inverted operation (alternative to inverse_state)
  • Covers requiring non-linear position mapping

Simple Mode (Start/End values):

Configure two values to linearly map the 0-100% calculated range to a custom output range.

Use Case Configuration Result
Limited Range Cover Start: 10%, End: 90% 0% calculated → 10% sent
100% calculated → 90% sent
50% calculated → 50% sent
Inverted Operation Start: 100%, End: 0% 0% calculated → 100% sent
100% calculated → 0% sent
50% calculated → 50% sent
Offset Range Start: 20%, End: 80% 0% calculated → 20% sent
100% calculated → 80% sent
50% calculated → 50% sent

Advanced Mode (Point Lists):

For non-linear mappings, define custom control points. Useful for covers with aggressive closing behavior or custom position curves.

Example - Aggressive Closing:

Normal List:     [0, 25, 50, 75, 100]
Interpolated List: [0, 15, 35, 60, 100]

This mapping causes the cover to close more aggressively:

  • 0% calc → 0% sent (no change)
  • 25% calc → 15% sent (closes more)
  • 50% calc → 35% sent (closes more)
  • 75% calc → 60% sent (closes more)
  • 100% calc → 100% sent (no change)

Example - Inverted with Custom Curve:

Normal List:     [0, 25, 50, 75, 100]
Interpolated List: [100, 75, 50, 25, 0]

Important Notes:

  • Interpolation is applied AFTER position calculation and BEFORE sending to cover
  • Works with both position-capable and open/close-only covers
  • Cannot be used together with inverse_state (choose one or the other)
  • List mode requires at least 2 points, values must be sorted ascending in Normal List

Vertical

Vertical blind measurement diagram

Variables Default Range Description
Window Height 2.1 0.1-6 Length of fully extended cover/window
Sill Height 0.0 0.0-3.0 Height from floor to bottom of window glass (meters). Set for windows not starting at floor level. Allows the blind to open more, as the sill already blocks low-angle sun. Range: 0.0–3.0m.
Glare Zone 0.5 0.1-5 Objects within this distance of the cover recieve direct sunlight. Measured horizontally from the bottom of the cover when fully extended

Horizontal

Horizontal awning measurement diagram

Variables Default Range Description
Awning Height 2 0.1-6 Height from work area to awning mounting point
Awning Length (horizontal) 2.1 0.3-6 Length of the awning when fully extended
Awning Angle 0 0-45 Angle of the awning from the wall
Glare Zone 0.5 0.1-5 Objects within this distance of the cover recieve direct sunlight

Tilt

Venetian slat measurement diagram

Variables Default Range Description
Slat Depth 3 cm 0.1-15 cm Width of each slat (measure one slat front to back)
Slat Distance 2 cm 0.1-15 cm Vertical distance between slat centers
Tilt Mode Bi-directional Mode1: 0-90°, Mode2: 0-180° slat rotation

Automation

Variables Default Range Description
Minimum Delta Position 1 1-90 Minimum position change required before another change can occur
Minimum Delta Time 2 Minimum time gap between position change
Start Time "00:00:00" Earliest time a cover can be adjusted after midnight
Start Time Entity None The earliest moment a cover may be changed after midnight. Overrides the start_time value
Manual Override Duration 15 min Minimum duration for manual control status to remain active
Manual Override reset Timer False Resets duration timer each time the position changes while the manual control status is active
Manual Override Threshold None 1-99 Minimal position change to be recognized as manual change
Manual Override ignore intermediate states False Ignore StateChangedEvents that have state opening or closing
End Time "00:00:00" Latest time a cover can be adjusted each day
End Time Entity None The latest moment a cover may be changed . Overrides the end_time value
Adjust at end time False Make sure to always update the position to the default setting at the end time.
Motion Sensors (Occupancy-based control)
Motion Sensors for Occupancy Control None (empty) List of binary sensors that control sun positioning based on room occupancy. When ANY sensor detects motion, covers use automatic positioning. When ALL sensors show no motion for the timeout duration, covers return to default position. Leave empty to disable feature.
Motion Timeout Duration 300 30-3600 Duration (in seconds) to wait after last motion before returning covers to default position. Prevents rapid position changes when motion sensors toggle frequently. Default: 300 seconds (5 minutes).

Climate

Variables Default Range Example Description
Indoor Temperature Entity None climate.living_room | sensor.indoor_temp
Minimum Comfort Temperature 21 0-86
Maximum Comfort Temperature 25 0-86
Outdoor Temperature Entity None sensor.outdoor_temp
Outdoor Temperature Threshold None If the minimum outside temperature for summer mode is set and the outside temperature falls below this threshold, summer mode will not be activated.
Presence Entity None
Weather Entity None weather.home Can also serve as outdoor temperature sensor
Lux Entity None sensor.lux Returns measured lux
Lux Threshold 1000 "In non-summer, above threshold, use optimal position. Otherwise, default position or fully open in winter."
Irradiance Entity None sensor.irradiance Returns measured irradiance
Irradiance Threshold 300 "In non-summer, above threshold, use optimal position. Otherwise, default position or fully open in winter."

Blindspot

The blind spot is shown as an orange shaded area within the FOV in the diagram above (see Common section). It represents an angular range within the field of view where obstructions (trees, buildings) block direct sunlight.

Variables Default Range Example Description
Blind Spot Left None 0-max(fov_right, 180) Start point of the blind spot on the predefined field of view, where 0 is equal to the window azimuth - fov left.
Blind Spot Right None 1-max(fov_right, 180) End point of the blind spot on the predefined field of view, where 1 is equal to the window azimuth - fov left + 1 .
Blind Spot Elevation None 0-90 Minimal elevation of the sun for the blindspot area.

Entities

The integration dynamically adds multiple entities based on the used features.

Note on Entity Naming:

Entity IDs follow the pattern: {domain}.{device_name}_{entity_name}

Where {device_name} is the slugified version of the device name you configured during setup.

Example: For a device named "Adaptive Living Room Blind":

  • sensor.adaptive_living_room_blind_cover_position
  • switch.adaptive_living_room_blind_automatic_control
  • binary_sensor.adaptive_living_room_blind_sun_infront

These entities are always available:

Entities Default Description
sensor.{device_name}_cover_position Reflects the current state determined by predefined settings and factors such as sun position, weather, and temperature
sensor.{device_name}_control_method solar Cover Position Driver: Shows what is currently controlling the cover position. Values (in priority order): force_override — a safety binary sensor is active; cover moves to the override position. motion_timeout — no occupancy detected after the configured timeout; cover returns to its default position. manual_override — you manually moved the cover; automatic control is paused. summer — climate mode active and temperature is above the max threshold; cover closes to block heat. winter — climate mode active and temperature is below the min threshold; cover opens to maximise solar heat gain. solar — sun is within the field of view; cover follows the calculated sun-position. default — sun is outside the field of view, elevation limits, blind spot, or the sunrise/sunset offset window; cover holds the default position.
sensor.{device_name}_start_sun Shows the starting time when the sun enters the window's view, with an interval of every 5 minutes.
sensor.{device_name}_end_sun Indicates the ending time when the sun exits the window's view, with an interval of every 5 minutes.
binary_sensor.{device_name}_manual_override off Indicates if manual override is engaged for any blinds.
binary_sensor.{device_name}_sun_infront off Indicates whether the sun is in front of the window within the designated field of view.
switch.{device_name}_automatic_control on Activates the adaptive control feature. When enabled, blinds adjust based on calculated position, unless manually overridden.
switch.{device_name}_manual_override on Manual Override Detection Switch: Enables automatic detection of manual position changes. When enabled, the integration monitors your covers and pauses automatic control if you manually adjust a cover's position (via physical controls, app, or automation). The cover remains in manual mode for the configured duration (default: 15 minutes), after which automatic control resumes. This allows you to temporarily take control without disabling automation entirely. Turn this switch off to disable manual override detection and always apply calculated positions.
switch.{device_name}_return_to_default_when_disabled (vertical & horizontal only) off When enabled, covers automatically return to their default position when automatic control is turned off. Useful for retracting awnings or setting blinds to a safe position.
button.{device_name}_reset_manual_override on Resets manual override tags for all covers; if switch.{device_name}_automatic_control is on, it also restores blinds to their correct positions.

When climate mode is setup you will also get these entities:

Entities Default Description
switch.{device_name}_climate_mode on Enables climate mode strategy; otherwise, defaults to the standard strategy.
switch.{device_name}_outside_temperature on Switches between inside and outside temperatures as the basis for determining the climate control strategy.

Diagnostic Sensors (Optional):

These sensors are created when diagnostics are enabled in automation settings. They help troubleshoot and monitor integration behavior.

Entity Default Description
sensor.{device_name}_sun_azimuth Enabled Current sun azimuth angle in degrees (0–360°). Use to verify window azimuth configuration. Attributes: window_azimuth, fov_left, fov_right, azimuth_min, azimuth_max, in_fov (bool — whether the sun is currently within the field of view).
sensor.{device_name}_sun_elevation Enabled Current sun elevation angle in degrees. Compare against configured limits to debug why the sun is considered out of range. Attributes: min_elevation and max_elevation (shown only when configured). For validity status and blind spot detection, see sensor.{device_name}_sun_validity.
sensor.{device_name}_gamma Enabled Surface solar azimuth — the sun's angle relative to the window normal. Most critical sensor for troubleshooting shadow accuracy. Attributes: interpretation (nearly perpendicular / oblique angle / steep angle / nearly parallel), absolute_angle, direction (left/right/center); blind_spot_range when blind spot is enabled.
sensor.{device_name}_control_status Enabled Shows current automation status. Possible values: active (running normally), automatic_control_off (Automatic Control switch is off), manual_override (cover was manually moved), outside_time_window (outside configured schedule), sun_not_visible (sun not shining on window). Attributes: automatic_control_enabled (always present); after_start_time/before_end_time when outside_time_window; valid_elevation/in_blind_spot when sun_not_visible; manual_covers list when manual_override.
sensor.{device_name}_control_state_reason Enabled Human-readable explanation of why the cover is in its current position. Coordinator-level reasons (checked first): Force Override (a force override sensor is active), Motion Timeout (no motion detected for timeout duration), Manual Override (cover was manually moved). Cover-level sun position reasons: Direct Sun (tracking the sun to block glare), Default: Sunset Offset (past sunset offset time), Default: Elevation Limit (sun outside elevation limits), Default: FOV Exit (sun outside field of view), Default: Blind Spot (sun in a configured blind spot), Default (using default position). No attributes.
sensor.{device_name}_calculated_position Enabled Raw calculated position (%) before interpolation or inversion adjustments. Compare to the final Cover Position to see the effect of limits, inversion, or climate mode. Attributes: final_position (position actually sent to the cover), direct_sun_valid (bool); min_limit_applied/max_limit_applied and limited_by when a position limit was enforced; inverse_state_enabled when inverse state is active; interpolation_enabled when interpolation is active; climate_position when climate mode overrides the geometric calculation.
sensor.{device_name}_last_cover_action Enabled Tracks the most recent cover command: service called, entity controlled, and timestamp formatted as HH:MM:SS. Attributes: entity_id, service, position (sent), calculated_position, inverse_state_applied, timestamp, covers_controlled; threshold_used and threshold_comparison for open/close-only covers.
sensor.{device_name}_manual_override_end_time Enabled Timestamp of when the current manual override will expire and automatic control will resume. Returns unavailable when no manual override is active. Attributes: per_entity dict mapping each cover entity ID to its expiry timestamp (ISO 8601).
sensor.{device_name}_motion_timeout_end_time Enabled Timestamp of when the motion timeout will fire (i.e., when covers switch to default position after no motion). Only created when motion sensors are configured. Returns unavailable when no timeout is pending. Attributes: motion_timeout_seconds (configured duration), last_motion_detected (ISO 8601 timestamp).
sensor.{device_name}_last_position_verification Disabled Timestamp of the most recent position verification check across all controlled covers. Attributes: per_entity dict mapping each cover entity ID to its last verification timestamp (ISO 8601).
sensor.{device_name}_force_override_triggers Disabled Count of currently active force override sensors (0–N). Only created when force override sensors are configured. Attributes: per_sensor dict mapping each sensor entity ID to its state (on/off/unavailable), total_configured.
sensor.{device_name}_last_motion_time Disabled Timestamp of the last motion detection event. Only created when motion sensors are configured. Returns unavailable if motion has never been detected. No attributes.
sensor.{device_name}_position_verification_retries Disabled Current retry count for position verification (0–3). Attributes: max_retries, retries_remaining, per_entity dict of retry counts per cover entity. Helps identify covers that repeatedly fail to reach their target positions.
binary_sensor.{device_name}_position_mismatch Disabled Indicates position mismatch between target and actual position (problem class). Attributes show target position sent, actual position per entity, position delta, and retry counts. Useful for troubleshooting cover movement issues.
sensor.{device_name}_active_temperature Disabled Currently active temperature value used for climate mode decisions. Only created when climate mode is configured. Attributes: inside_temperature, outside_temperature, temp_switch (bool — whether outside temperature is selected).
sensor.{device_name}_climate_conditions Disabled Climate mode state: Summer Mode, Winter Mode, or Intermediate. Only created when climate mode is configured. Attributes: is_summer, is_winter, is_presence (bool flags).
sensor.{device_name}_time_window Disabled Time window status: Active or Outside Window. Attributes: check_adaptive_time (bool — within window?), after_start_time, before_end_time, start_time, end_time.
sensor.{device_name}_sun_validity Disabled Sun validity status: Valid, In Blind Spot, or Invalid Elevation. Attributes: valid (bool), valid_elevation (bool), in_blind_spot (bool or null when blind spot is not configured).

Note: Priority 1 sensors (disabled by default) reduce entity overhead. Enable them individually in the entity list if needed for troubleshooting. Motion and force override sensors are only created when the corresponding features are configured.

Features Planned

  • Manual override controls

    • Time to revert back to adaptive control
    • Reset button
    • Wait until next manual/none adaptive change
  • Support Home Assistant unit system (automatic conversion between °F/°C, meters/feet, etc.)

    • This will resolve the current requirement for all temperature sensors to use matching units
    • Will automatically handle conversions based on your Home Assistant unit system preference
  • Algorithm to control radiation and/or illumination

About

An Adaptive Cover component for HomeAsisstant to control covers based on the sun's position

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Python 92.3%
  • Shell 5.0%
  • Jupyter Notebook 2.7%