This comprehensive FAQ covers the most common questions about Cover Control Automation. For additional support, visit the CCA Community Thread, check out the Trace Analyzer for debugging, or report issues on GitHub.
A: CCA is a comprehensive Home Assistant blueprint that automatically manages window coverings (roller shutters, blinds, awnings) based on time, sun position, weather conditions, and your preferences. It largely eliminates the need for manual adjustments.
A: Create one automation per cover for reliable results. While cover groups are technically possible, position detection becomes inaccurate when covers are at different positions simultaneously.
Why one automation per cover?
Example: If one cover in a group is at 100% and another at 0%, the group shows 50% - making position detection unreliable.
A: In principle, you can use a group here. But please note that there are problems with position detection for a group of covers! For example, one cover may be at position 100% and the other cover at position 0%. This results in a wrong group-value of 50%.
My clear recommendation is to create one automation for each cover.
A:
A: ⚠️ Not directly - The automation runs on time triggers and sensor changes. However, force triggers allow manual override of automatic behavior when needed.
Why not manual triggering?
A:
current_position attribute (or alternative position source)sun.sun) enabled and working correctly (for sun-based features)A: The helper is required for sun shading and ventilation features. Time-based opening/closing works with basic position detection alone, but you lose:
How to create a helper:
A: No special hardware required! CCA works with:
A:
https://github.com/hvorragend/ha-blueprints/blob/main/blueprints/automation/cover_control_automation.yaml
A: For Blinds/Roller Shutters (Standard):
Cover Type: Blind / Roller Shutter
Open Position: 100% # Fully up
Shading Position: 25% # Partially down for sun protection
Ventilate Position: 30% # Slightly down for air flow
Close Position: 0% # Fully down
Position Tolerance: 5% # Acceptable variance
For Awnings/Sunshades (Inverted):
Cover Type: Awning / Sunshade
Open Position: 0% # Retracted
Shading Position: 75% # Extended for sun protection
Close Position: 100% # Fully extended
A:
Time Settings:
time_up_early must be earlier than time_up_latetime_up_early_non_workday must be earlier than time_up_late_non_workdaytime_down_early must be earlier than time_down_latetime_down_early_non_workday must be earlier than time_down_late_non_workdayPosition Values (for Blinds):
open_position > shading_position > ventilate_position > close_positionPosition Values (for Awnings):
close_position > shading_position > open_positionShading Thresholds:
shading_azimuth_start < shading_azimuth_endshading_elevation_min < shading_elevation_maxshading_sun_brightness_start > shading_sun_brightness_endBinary Sensors:
resident_sensor must be on/off/true/false (binary)A: All feature toggles are centralized in the Automation Options section (parameter auto_options).
Instead of hunting through multiple sections, a single checklist controls what CCA manages:
auto_options:
- auto_up_enabled # Morning opening
- auto_down_enabled # Evening closing
- time_control_enabled # Time-based triggers
- auto_brightness_enabled # Brightness-based opening/closing
- auto_sun_enabled # Sun elevation-based opening/closing
- auto_ventilate_enabled # Ventilation mode
- auto_shading_enabled # Sun protection / shading
Backward compatibility:
time_control_enabled keep working — the legacy time_control: time_control_disabled selector is still honored.time_control_enabled is present in auto_options, it takes precedence.brightness_sun_operator parameter (AND/OR link between brightness and sun conditions) has moved to this section as well. Its value is preserved; only the UI location changed.When to update: Only when you reconfigure the automation in the UI. No forced migration.
A: Drive Time is the duration your cover needs to move from fully closed to fully open (or vice versa).
How to configure:
Why it matters:
Recommendation: Rather round up than be too precise!
A: Yes! Since version 2025.12.22, CCA supports alternative position sources:
Position Source Options:
current_position (default) - Most covers use thisposition attribute - Some integrations use this insteadWhen to use alternatives:
Configuration: Navigate to “Cover Position Settings” → “Position Source Type”
A: Common causes:
1. Once-per-day restrictions:
2. Manual override active:
3. Incomplete configuration:
4. Entity states:
A: Early Time (time_up_early / time_down_early):
Late Time (time_up_late / time_down_late):
Special Case - Identical Times (NEW in 2025.12.22): Set both to the same time for guaranteed execution:
time_up_early: "07:00:00"
time_up_late: "07:00:00" # Opens exactly at 07:00, no environmental checks
Migration Guide:
A: Calendar mode replaces traditional time inputs with visual, family-friendly scheduling:
Setup:
How to use:
Example Schedule:
Monday-Friday: "Open Cover" 06:00-20:00
Saturday-Sunday: "Open Cover" 08:00-22:00
Vacation Week: "Close Cover" all day (keeps closed)
Benefits:
A: No, choose one mode:
Switching modes: Go to “Time Control Configuration” and select your preferred option.
A: Workday sensors enable different schedules for workdays vs. non-workdays (weekends, holidays):
Configuration:
Why Workday Tomorrow?
Recommendation: Use the Workday Integration
Example:
# Monday-Friday (workday)
time_up_early: 06:00
time_up_late: 07:00
# Saturday-Sunday (non-workday)
time_up_early_non_workday: 08:00
time_up_late_non_workday: 09:00
A: Position Tolerance is the acceptable variance when comparing cover positions.
Purpose:
Recommended Values:
Important: All position values must remain unique even with tolerance applied!
Example with 5% tolerance:
Open Position: 100% # Range: 95-100%
Shading Position: 25% # Range: 20-30%
Close Position: 0% # Range: 0-5%
# All ranges non-overlapping ✅
A: Overlapping positions cause ambiguous state detection:
Problem scenario:
Ventilate Position: 30%
Close Position: 25%
Position Tolerance: 10%
# Ventilate range: 20-40%
# Close range: 15-35%
# OVERLAP at 20-35%! ❌
Result: CCA can’t determine if cover is ventilating or closing!
Solution: Keep positions clearly separated considering tolerance:
Ventilate Position: 30%
Close Position: 0%
Position Tolerance: 5%
# Ventilate range: 25-35%
# Close range: 0-5%
# No overlap! ✅
Use the validator: Configuration Validator checks for overlaps!
A: For Ventilation Position:
For Shading Position:
A:
Blinds/Roller Shutters (Traditional):
Awnings/Sunshades (Inverted):
CCA automatically adapts: Just select your cover type, and all position logic adjusts automatically!
A: Yes! Full awning support since version 2025.12.22:
What’s supported:
Not supported for awnings:
Configuration:
Cover Type: Awning / Sunshade
Open Position: 0% # Retracted
Shading Position: 75% # Extended for shade
Close Position: 100% # Fully extended
A: Create separate automations:
A: These are two completely different features:
Sun Elevation (☀️):
Sun Protection/Shading (🥵):
Example of a summer day:
06:00 - Sun Elevation triggers opening (sun rose)
07:00 - Time-based opening (but already open)
12:00 - Sun Protection activates (sun hits window → partial close)
18:00 - Sun Protection ends (sun moved away → opens again)
21:00 - Sun Elevation triggers closing (sun set)
A: Since version 2025.12.22, CCA uses flexible AND/OR logic:
AND Conditions (Required):
OR Conditions (Optional Boosters):
Example Configurations:
Conservative (all must be perfect):
AND: Azimuth, Elevation, Brightness, Temp1, Temp2
OR: (none)
Result: Shading only when everything is perfect
Flexible (sun position + temperature):
AND: Azimuth, Elevation
OR: Brightness, Temp1, Temp2
Result: Sun must be in range + (bright OR warm)
Aggressive (sun only, temperature optional):
AND: Azimuth
OR: Elevation, Brightness, Temp1, Forecast
Result: Sun in range + at least one other condition
A: Available shading conditions:
Each condition can be:
A: “Pending” means conditions are actively being evaluated:
Shading Start Pending:
Shading End Pending:
Why pending?
Adjust if needed:
A: Hysteresis prevents rapid on/off cycling near threshold values by creating two different thresholds:
Example with Temperature:
Threshold: 25°C
Hysteresis: 2°C
Activation threshold: 25°C + 2°C = 27°C
Deactivation threshold: 25°C - 2°C = 23°C
Behavior:
- Temperature rises to 27°C → Shading starts
- Temperature drops to 26°C → Shading continues (still above 23°C)
- Temperature drops to 25°C → Shading continues (still above 23°C)
- Temperature drops to 22°C → Shading ends
Benefits:
Recommended Values:
A: Common issues:
1. Inaccurate Weather Forecast:
2. Incorrect Azimuth/Elevation:
shading_azimuth_start must be < shading_azimuth_end3. Waiting Time Too Long:
4. Missing Sensors:
sun.sun must be enabled5. Time Window:
time_up_early to time_down_late range6. Manual Override Active:
Debugging: Use Traces to see exactly why conditions aren’t met!
A: Yes! Since version 2025.12.22, “Independent Shading via Temperature Comparison” allows this:
Enable in “Sun Shading - Configuration”:
☑ Independent Shading via Temperature Comparison
How it works:
Example:
06:00 - Forecast shows 35°C max today
06:00 - Shading activates immediately (forecast > threshold)
- Cover stays in shading position all day
- No need to wait for sun to hit window
Use cases:
A: Two methods available:
Method 1: Weather Entity (Recommended)
Forecast Weather Entity: weather.home
Forecast Source: Use the daily weather forecast service
Forecast Temperature Value: 30°C
Method 2: Direct Temperature Sensor (Alternative)
Direct Temperature Sensor: sensor.forecast_temperature_max
Forecast Temperature Value: 30°C
Priority: Temperature sensor takes priority if both configured
Benefits of sensors:
Benefits of weather entity:
A: Ventilation mode reacts to window/door contacts:
Tilted Window (Partial Ventilation):
Fully Opened Window:
Window Closed:
Configuration:
Contact Sensor For Open Window: binary_sensor.window_opened
Contact Sensor For Tilted Window: binary_sensor.window_tilted
Important: Don’t use the same sensor for both!
A: Lockout protection prevents covers from closing while windows are open, avoiding:
When it’s active:
Configurable for tilted windows:
Lockout Protection Options:
☑ When closing the cover
☑ When starting sun shading
☑ When sun shading ends
Behavior with lockout:
A: To differentiate between tilted (partial ventilation) and fully opened (full ventilation + lockout):
Tilted sensor:
Opened sensor:
Can’t I use one sensor?
A: contact_window_opened (window fully open) always has higher priority than contact_window_tilted (window tilted). If both sensors are on at the same time, CCA treats the window as fully open and acts accordingly — the cover never moves to the ventilation position in this case.
Priority Table:
contact_window_opened |
contact_window_tilted |
CCA Behavior |
|---|---|---|
off |
off |
Normal operation |
off |
on |
Partial ventilation → ventilate_position |
on |
off |
Full ventilation + lockout → open_position |
on |
on |
Full ventilation + lockout → open_position (opened wins!) |
How the priority is enforced per event:
| Event / Trigger | Only opened = on |
Only tilted = on |
Both = on |
|---|---|---|---|
Contact sensor changes (t_contact_*) |
→ open_position |
→ ventilate_position |
→ open_position |
Evening closing (t_close_*) |
Lockout — no movement | → ventilate_position (if lockout for tilted disabled) |
Lockout — no movement |
Shading start (t_shading_start_*) |
Shading blocked (lockout) | Shading blocked (if lockout for tilted enabled) | Shading blocked |
Shading end (t_shading_end_*) |
Lockout skip | → ventilate_position (if configured) |
Lockout skip |
Force disabled — recovery (t_force_disabled_*) |
→ open_position |
→ ventilate_position |
→ open_position |
Resident leaves (t_resident_update) |
→ open_position |
→ ventilate_position |
→ open_position |
Resident arrives (t_resident_update) |
Helper updated only (no movement) | → ventilate_position (if resident_allow_ventilation) |
Helper updated only (no movement) |
Implementation details:
CCA enforces this priority in two ways:
tilted explicitly require contact_window_opened = off (e.g. evening closing, shading end, contact sensor change handler).choose block ordering: In sections where both window states are evaluated (e.g. resident leaving), the opened case is always placed before the tilted case in the choose block — the first matching branch wins.Why this matters in practice:
ventilate_position during the transitionventilate_position (50%) while the window is fully open, verify that contact_window_opened correctly reports on for the fully open stateA: Contact Trigger Delay prevents race conditions when multiple sensors change simultaneously:
The Problem:
00:00.000 - Window sensor: off → on
00:00.005 - Lock sensor: off → on (5ms later)
00:00.002 - First trigger fires
00:00.005 - Second trigger blocked (mode: queued)
Result: Lockout sensor change lost! ❌
The Solution (Delay = 2 seconds):
00:00.000 - Window sensor: off → on
00:00.005 - Lock sensor: off → on
00:02.000 - Trigger fires with both sensors in final state
Result: All changes captured! ✅
Symptoms of race conditions:
Recommendation:
Fixed in version 2025.12.22: Switched to mode: queued for better handling
A: Yes, lockout protection is optional for tilted windows:
Disable for tilted position:
Lockout Protection Options:
☐ When closing the cover (unchecked)
Behavior without lockout:
Use case: Small bathroom window where lockout isn’t critical
Note: Lockout for fully opened windows is always active and cannot be disabled!
A: CCA detects when you manually adjust the cover (via switch, UI, voice control):
Detection triggers:
What happens:
Why respect manual changes?
A: Yes! Configure which actions can override manual changes:
Options in “Manual Override” section:
Ignore/override next automatic opening after manual changes
Ignore/override next automatic closing after manual changes
Ignore/override next automatic ventilation after manual changes
Ignore/override next automatic sun shading after manual changes
Example scenario:
A: Three options:
1. Automatic timeout (default):
Reset Configuration: Reset after a timeout in minutes
Number of minutes: 60 (default)
2. Fixed time reset:
Reset Configuration: Reset at a specified time
Time to reset: 00:01:00 (resets at midnight)
3. No automatic reset:
Reset Configuration: No timed reset for manual override
Manual override persists until:
A: Possible causes:
1. Drive Time too short:
2. Manual override not enabled:
3. Override timeout expired:
4. Position within tolerance:
5. Force function active:
A: Resident mode keeps covers closed when someone is sleeping:
Purpose:
How it works:
Behavior:
A:
1. Create or select sensor:
# Examples:
binary_sensor.bedroom_occupied
input_boolean.guest_sleeping
binary_sensor.motion_bedroom (inverted logic)
2. Configure in CCA:
Resident Sensor: binary_sensor.bedroom_occupied
Resident Configuration:
☑ Enable automatic opening when resident wakes up
☑ Enable automatic closing when resident goes to sleep
☑ Allow sun protection when resident is still present
☑ Allow opening the cover when resident is still present
☐ Allow ventilation when resident is still present
A: Fixed in version 2025.12.22! Previous versions had this bug (#174).
Current behavior (correct):
time_down_early)Example:
Morning scenario:
07:00 - Resident wakes up
07:00 - Time window: 06:00-08:00 ✅
07:00 - Sun is up ✅
Result: Cover opens
Evening scenario:
22:00 - Resident wakes up
22:00 - Time window: closed (after 20:00) ❌
Result: Cover stays closed (correct!)
A: Yes! Resident mode doesn’t prevent manual control:
Manual control always works:
What resident mode does:
Optional override:
☑ Allow opening the cover when resident is still present
Enables automatic opening even if resident sensor is “on”
A: Force functions provide immediate manual override for emergency scenarios:
Available force functions:
How to use:
A:
Basic Behavior (Without Background State Tracking):
Advanced: Automatic Return to Target (With Background State Tracking)
Important Constraints:
A: NEW in 2025.12.22! Automatic recovery after emergency:
How it works:
Example scenario:
10:00 - Normal: Cover open
12:00 - Shading active
14:00 - Heavy rain → Force Close activated
14:00 - Cover closes immediately
14:00 - Helper tracks: "Should be shading"
15:00 - Rain stops → Force Close disabled
15:00 - Cover automatically returns to shading position
18:00 - Evening close time
18:00 - Cover closes normally
Configuration:
Return to Target State After Force Disable:
✅ Enable Automatic Return to Target State
Use cases:
A: No! Only ONE force function can be active at a time:
What happens with conflicts:
Recommendation:
Example automation for prioritized forces:
# Rain protection takes priority over wind protection
trigger:
- platform: state
entity_id: input_boolean.force_close_rain
to: 'on'
action:
- service: input_boolean.turn_off
entity_id: input_boolean.force_open_wind
- service: input_boolean.turn_on
entity_id: input_boolean.force_close_rain
A: Force Pause is a dedicated input (force_pause, accepts input_boolean or switch) that suspends all automatic cover movements while keeping the background state fully up to date.
While paused (force_pause = on):
On resume (force_pause = off):
effective_state.Why not just put the same entity into the global condition? The global condition blocks the entire action block — including helper state updates. When you re-enable automation that way, the helper is stale and the cover only catches up on the next trigger. Force Pause only blocks movement, not state tracking, so resume is instant and accurate.
Typical use case: A manual/automatic toggle in your dashboard. Flip it to pause during a party, cleaning, or filming; flip it back on and the cover jumps straight to where it should be.
Note: Force Pause is not a force function — it does not override state (lockout, shading, etc.), it only freezes cover movement. Regular force functions (Force Open/Close/Shade/Ventilate) continue to take the absolute highest priority when active.
A: Force functions stay active until manually disabled:
Duration:
Why no timeout?
Recommendation:
trigger:
A: The helper stores comprehensive state information in a highly compact JSON format to save space:
Main Keys:
| Key | State | Example Values | Description |
|---|---|---|---|
bas |
Base | opn, cls |
The main time-based position (open or close) |
shd |
Shading | 0, 1 |
Shading flag (0=off, 1=active) |
win |
Window | cls, tlt, opn |
Window sensor state (closed, tilted, fully open) |
frc |
Force | non, opn, cls, shd, vnt |
Overriding force state (none/open/close/shade/vent) |
res |
Resident | 0, 1 |
Resident presence (1=present, 0=away) |
man |
Manual | 0, 1 |
Manual operation detected (1=active) |
ts |
Timestamps | Object | Dictionary of when each state was last changed |
v |
Version | Number | Helper schema version (current: 6) |
t |
Global Time | Timestamp | Last overall helper update timestamp |
Top-level field — pending phase:
| Field | Values | Meaning |
|---|---|---|
pnd |
non / beg / end |
Shading pending phase (none / start armed / end armed) |
Timestamp sub-keys (ts):
| Key | Meaning |
|---|---|
opn |
Timestamp of last automatic opening |
cls |
Timestamp of last automatic closing |
shd |
Timestamp when shading became active |
due |
Fire time of the armed pending (0 when pnd == "non") |
arm |
First-arming timestamp of the current pending retry sequence (0 when pnd == "non") |
man |
Timestamp of last manual intervention |
Common State Scenarios:
| Scenario | bas | shd | pnd | win | frc | man | Description |
|---|---|---|---|---|---|---|---|
| Cover is open | opn | 0 | non | cls | non | 0 | Normal daytime state |
| Cover is closed | cls | 0 | non | cls | non | 0 | Normal nighttime state |
| Shading active | opn | 1 | non | cls | non | 0 | Sun protection engaged |
| Shading start pending | opn | 0 | beg | cls | non | 0 | Waiting for start conditions to stabilize |
| Shading end pending | opn | 1 | end | cls | non | 0 | Waiting for end conditions to stabilize |
| Window tilted (ventilation) | opn | 0 | non | tlt | non | 0 | Partial opening for air flow |
| Window fully open (lockout) | opn | 0 | non | opn | non | 0 | Lockout: prevents closing |
| Force close active | cls | 0 | non | cls | cls | 0 | Forced closed via external entity |
| Manual override | * | * | * | * | * | 1 | Physical push button used |
A: Yes, in Developer Tools:
Method 1: States Tab
input_text.cca_status_living_room)Method 2: Template Tab
{{ states('input_text.cca_status_living_room') }}
Example content:
{
"bas": "opn",
"shd": 0,
"pnd": "non",
"win": "cls",
"frc": "non",
"res": 0,
"man": 0,
"ts": {
"opn": 1703250600,
"cls": 1703164200,
"shd": 1703237000,
"due": 0,
"arm": 0,
"man": 1703150600
},
"v": 6,
"t": 1703250600
}
A:
Problem: Helper length too short
Error: JSON content truncated
Symptom: Automation doesn't work, helper shows incomplete data
Solution: Recreate helper with max: 254 characters
Problem: Can I use 255 characters?
Answer: Yes, 254 or 255 both work
CCA requires minimum 254
Problem: Helper empty after creating automation
Cause: Helper created with wrong length
Solution:
1. Delete and recreate helper with correct length
2. Wait for next trigger to refill
3. Or restart automation
Problem: Can I share one helper between multiple covers?
Answer: NO!
Each cover automation MUST have its own unique helper
Sharing breaks functionality completely
A: Not recommended, but possible for debugging:
When it might be useful:
How to edit:
Risks:
Better alternatives:
A: Use the custom:flex-table-card to create a comprehensive multi-column status table:
Requirements:
Dashboard Card Configuration:
📄 examples/cover-status-flex-table.yaml
What you see:
Customization:
modify: x.replace('Cover Status ', '')modify: x.replace('Your Prefix ', '')modify: x.substring(0, 8)modify: x.slice(-8)modify line completelytoLocaleDateString and toLocaleTimeStringA: Traces show exactly what happened during automation execution:
Enable more traces (optional):
# In automation YAML
trace:
stored_traces: 20 # Default: 5
Viewing traces:
What to look for:
Navigation:
A: For support requests:
Download trace:
Share trace (forum doesn’t allow JSON):
| Service | URL | Account Required? |
|---|---|---|
| Pastebin | ✅ For “Unlisted” | Syntax highlighting |
| GitHub Gist | Optional | Public or secret |
| Hastebin | No | Fast & simple |
| 0bin | No | Encrypted |
Pastebin example:
jsonUnlistedA: Understanding Home Assistant threshold concepts:
The Threshold Rule:
Example:
Current brightness: 50 lux
Threshold: 75 lux
Trigger: "above 75"
Changes that DON'T fire:
- 50 → 60 (still below)
- 50 → 74 (still below)
- 60 → 70 (still below)
Changes that DO fire:
- 50 → 76 (crossed threshold!)
- 74 → 76 (crossed threshold!)
Common causes:
Solutions:
A: Check these common issues:
1. Environmental conditions not met:
# You configured:
time_up_early: 06:00
time_up_late: 08:00
Brightness: Enabled (threshold: 10000 lux)
# Current situation:
Time: 07:00 ✅
Brightness: 8000 lux ❌
Result: Cover won't move until 08:00 (late time)
Solution: Disable brightness/sun elevation for guaranteed time-based movement, OR adjust thresholds
2. Identical Early and Late times (NEW behavior):
time_up_early: 07:00
time_up_late: 07:00
Result: Opens exactly at 07:00, ignores environmental conditions
3. Resident sensor blocking:
Resident sensor: on (sleeping)
Resident Configuration: Opening NOT enabled
Result: Cover won't open automatically
4. Manual override active:
5. Once-per-day restriction:
A: Use the online validator BEFORE deploying:
What it checks:
How to use:
input: sectionBenefits:
A: For efficient support, include:
Essential:
Helpful:
Tips:
Template:
**Issue:** Cover doesn't close at configured evening time
**Expected:** Cover closes at 22:00
**Actual:** Cover stays open
**Configuration:**
- CCA Version: 2026.01.25
- HA Version: 2024.10.0
- Cover: cover.living_room_blind (Shelly integration)
**YAML:** [Link to Pastebin]
**Trace:** [Link to Pastebin]
**Recent changes:** Updated CCA from 2025.08.15 yesterday
A: CCA uses a 7-layer state hierarchy where higher layers override lower layers. This ensures that critical functions (like window protection) always take priority over convenience features (like schedules).
State Hierarchy (Priority Order):
┌─────────────────────────────────────────────────────────────────┐
│ Layer 1: FORCE │
│ ├─ force != "none" → return force state │
│ ├─ Examples: Rain protection, wind protection, frost │
│ └─ Variable: state_force │
├─────────────────────────────────────────────────────────────────┤
│ Layer 2: LOCKOUT │
│ ├─ window == "open" → return "lock" (100% open) │
│ ├─ Purpose: Prevent closing on open windows │
│ └─ Variable: state_window == "open" │
├─────────────────────────────────────────────────────────────────┤
│ Layer 3: BASE=OPEN │
│ ├─ base == "open" AND no shading/privacy/restriction → "open" │
│ ├─ Purpose: When the schedule says open, opening wins — │
│ │ a fully open cover gives maximum airflow when │
│ │ the window is tilted │
│ └─ Variable: state_base == "open" + allow_open │
├─────────────────────────────────────────────────────────────────┤
│ Layer 4: VENTILATION (floor) │
│ ├─ window == "tilted" AND allow_ventilate AND base would │
│ │ close/shade/privacy-close → return "vent" │
│ ├─ Purpose: Floor that keeps the cover at vent position when │
│ │ anything below would lower it further │
│ └─ Variable: state_window == "tilted" + resident_allow_vent │
├─────────────────────────────────────────────────────────────────┤
│ Layer 5: PRIVACY │
│ ├─ resident == 1 AND closing_trigger → return "close" │
│ ├─ Purpose: Privacy / darkness when resident is sleeping │
│ └─ Variable: state_resident + resident_closing_enabled │
├─────────────────────────────────────────────────────────────────┤
│ Layer 6: SHADING │
│ ├─ shade == true AND allow_shade → return "shade" │
│ ├─ Purpose: Sun protection during hot periods │
│ └─ Variable: state_shade + resident_allow_shading │
├─────────────────────────────────────────────────────────────────┤
│ Layer 7: BASE=CLOSE │
│ ├─ return base ("close") │
│ ├─ Purpose: Time-based schedule (evening) │
│ └─ Variable: state_base │
└─────────────────────────────────────────────────────────────────┘
Decision Flow:
┌─────────────────┐
│ 1. FORCE │
│ (emergency) │
└────────┬────────┘
│ force = "none"
┌──────────────────┴──────────────────┐
▼ │
┌─────────────────┐ │
│ window="open" │──────────────────────────────┤
│ 2. LOCKOUT │ → 100% open (protect) │
└────────┬────────┘ │
│ window != "open" │
▼ │
┌─────────────────┐ │
│ base="open" │ │
│ AND no shading │──────────────────────────────┤
│ AND allow_open │ │
│ 3. BASE=OPEN │ → 100% open │
└────────┬────────┘ │
│ base would close/shade/privacy │
▼ │
┌─────────────────┐ │
│window="tilted" │──────────────────────────────┤
│ AND allow_vent │ │
│ 4. VENTILATION │ → 30% open (floor) │
└────────┬────────┘ │
│ window = "closed" / vent blocked │
▼ │
┌─────────────────┐ │
│ resident==1 │──────────────────────────────┤
│AND closing_trig │ │
│ 5. PRIVACY │ → 100% closed (privacy) │
└────────┬────────┘ │
│ no resident / trigger disabled │
▼ │
┌─────────────────┐ │
│shade=true AND │──────────────────────────────┤
│ allow_shade │ │
│ 6. SHADING │ → 25% closed (shade) │
└────────┬────────┘ │
│ shade = false / shade blocked │
▼ │
┌─────────────────┐ │
│ 7. BASE=CLOSE │◄─────────────────────────────┘
│ │ → Scheduled close position
└─────────────────┘
Examples:
| Scenario | Layer Active | Result | Reason |
|---|---|---|---|
| Heavy rain | Layer 1 (Force) | Close completely | Emergency protection |
| Window fully open | Layer 2 (Lockout) | Stay 100% open | Prevent damage |
| Window tilted, daytime (base=open) | Layer 3 (Base=Open) | Move to 100% | Open beats vent — more airflow |
| Window tilted at night (base=close) | Layer 4 (Ventilation) | Move to 30% | Vent floor over close |
| Window tilted during shading hours | Layer 4 (Ventilation) | Move to 30% | Vent floor over shade |
| Window tilted, resident sleeping, vent blocked | Layer 5 (Privacy) | Close completely | Privacy overrides ventilation |
| Resident sleeping | Layer 5 (Privacy) | Close completely | Privacy / darkness |
| Hot summer, resident absent, window closed | Layer 6 (Shading) | Move to 25% | Sun protection |
| Normal evening, window closed | Layer 7 (Base=Close) | Close | Time schedule |
| Window open + rain | Layer 1 (Force) | Close completely | Force overrides lockout! |
Key Points:
allow_ventilate, allow_shade, allow_open gate their respective layers directlyTechnical Details (State Machine v6 variables):
effective_state: Computed final state via priority cascade (open/close/shade/vent/lock/force-*)state_force: Current force state from helper (“none”, “open”, “close”, “shade”, “vent”)state_window: Window sensor state from helper (“closed”, “tilted”, “open”)state_resident: Boolean flag for resident presence (from helper res field)state_shade: Boolean flag for active shading (from helper shd field)state_base: Time-based ground state (“open” or “close”, from helper bas field)state_manual: Boolean flag for active manual override (from helper man field)A: Automatically adapts sun elevation thresholds to seasons:
The Problem:
The Solution:
Benefits:
Setup Guide: 📚 Dynamic Sun Elevation Guide
A: Dynamic control based on external factors:
Use cases:
Vacation Mode:
Additional Condition For Opening:
condition: state
entity_id: input_boolean.vacation_mode
state: 'off'
Result: Covers stay closed during vacation
Party Mode:
Additional Condition For Closing:
condition: state
entity_id: input_boolean.party_mode
state: 'off'
Result: Covers don't close during party
Maintenance Mode:
Additional Condition (Global):
condition: state
entity_id: input_boolean.maintenance_mode
state: 'off'
Result: All automation disabled during maintenance
Season-based shading:
Additional Condition For Shading:
condition: template
value_template: "{{ now().month in [6, 7, 8] }}"
Result: Shading only in summer months
A: Yes! “Additional Actions” allow custom behavior:
Available hooks:
Use cases:
Example 1: Notifications
Additional Actions After Opening:
- service: notify.mobile_app
data:
message: "Living room cover opened"
Example 2: Scene activation
Additional Actions After Closing:
- service: scene.turn_on
target:
entity_id: scene.evening_lights
Example 3: Custom devices
Additional Actions Before Shading:
- service: light.turn_on
target:
entity_id: light.window_plants
data:
brightness: 255
A: Disables CCA’s built-in cover commands:
When to use:
Configuration:
Behavior Customization:
☑ Use custom actions only
Additional Actions After Opening:
- service: script.my_custom_cover_open
data:
entity_id: cover.living_room
Examples:
Shelly combined position+tilt:
Additional Actions After Shading:
- service: script.cover_position_tilt
data:
entity_id: cover.living_room
position: 25
tilt: 20
Homematic combined positioning:
Additional Actions After Shading:
- service: homematicip_local.set_cover_combined_position
data:
entity_id: cover.living_room
position: 25
tilt_position: 20
A: NEW in 2025.12.22! For Z-Wave and timing-sensitive devices:
The Problem:
The Solution:
Configuration:
Tilt Wait Mode: Wait Until Idle (Z-Wave devices)
Tilt Wait Timeout: 30 seconds
Benefits:
When to use:
A: Fine-tune automation behavior:
Position Management:
☑ Don't raise cover when closing for the evening
Prevents opening if cover is already lower than close position
☑ Keep shading position during evening close
If shading, don’t lower further when closing time arrives
Feature Control:
☑ Stay shaded: Don't open cover when sun shading ends
Keeps cover in shading position instead of opening
☑ Keep closed: Don't open cover when ventilation ends
Useful for bedrooms - stays closed after ventilation
Frequency Limits:
☑ Open cover only once per day
☑ Close cover only once per day
☑ Shade cover only once per day
Prevents repeated actions, useful during testing/debugging
Hardware Compatibility:
☑ Use custom actions only
Disables default cover commands for custom integrations
A:
| Trigger ID | Function | Description |
|---|---|---|
t_open_1 - t_open_2 |
Cover Opening | Time-based (early/late time reached) |
t_open_4 - t_open_5 |
Cover Opening | Condition-based (brightness / sun elevation) |
t_close_1 - t_close_2 |
Cover Closing | Time-based (early/late time reached) |
t_close_4 - t_close_5 |
Cover Closing | Condition-based (brightness / sun elevation) |
t_resident_update |
Resident | Resident sensor changed (arriving or leaving) |
t_calendar_event_start |
Calendar Event Start | Calendar event becomes active |
t_calendar_event_end |
Calendar Event End | Calendar event ends |
t_contact_tilted_changed |
Ventilation - Tilted | Window tilted sensor change |
t_contact_opened_changed |
Ventilation - Opened | Window opened sensor change |
t_shading_start_pending_1 - _7 |
Shading Pending | Checks azimuth/elevation, brightness, temp1/2, weather, forecast |
t_shading_start_execution |
Shading Executed | Pending time elapsed, conditions met |
t_shading_tilt_1 - _4 |
Shading Tilt | Elevation-based tilt adjustment |
t_shading_end_pending_1 - _6 |
Shading End Pending | End conditions detected |
t_shading_end_execution |
Shading End Executed | End pending time elapsed |
t_shading_reset |
Shading Reset | Midnight reset of shading status |
t_manual_position |
Manual Position Detection | Position changed manually |
t_manual_tilt |
Manual Tilt Detection | Tilt changed manually |
t_reset_fixedtime |
Reset Override - Fixed Time | Manual override reset at configured time |
t_reset_timeout |
Reset Override - Timeout | Manual override timeout expired |
t_force_enabled_* |
Force Enabled | Force function activated |
t_force_disabled_* |
Force Disabled | Force function deactivated |
Debugging tips:
t_manual_* triggers are rarely the issue - look at trigger before itA: Multiple support channels:
Community Forum:
GitHub:
Documentation:
Tools:
A: Several ways to help:
Financial Support:
Community Contributions:
Testing:
Before posting for support, verify these essential points:
current_position attribute (or alternative source configured)sun.sun) is enabled and workingPosition Logic:
Position Hierarchy:
100% (Open)
↓
25% (Shading)
↓
30% (Ventilate)
↓
0% (Close)
Example Configuration:
Cover Type: Blind / Roller Shutter
Open Position: 100%
Shading Position: 25%
Ventilate Position: 30%
Close Position: 0%
Position Tolerance: 5%
Real-World Examples:
Position Logic:
Position Hierarchy:
100% (Close)
↓
75% (Shading)
↓
0% (Open)
Example Configuration:
Cover Type: Awning / Sunshade
Open Position: 0%
Shading Position: 75%
Close Position: 100%
Real-World Examples:
How CCA Adapts: The blueprint automatically:
You simply set positions intuitively and CCA handles the rest!
All triggers available in CCA and their purposes:
| Trigger ID | Category | Description |
|---|---|---|
t_open_1 |
Opening | Early opening time reached |
t_open_2 |
Opening | Late opening time reached (guaranteed if conditions didn’t trigger early) |
t_close_1 |
Closing | Early closing time reached |
t_close_2 |
Closing | Late closing time reached (guaranteed if conditions didn’t trigger early) |
| Trigger ID | Category | Description |
|---|---|---|
t_open_4 |
Opening | Brightness above threshold maintained for configured duration |
t_open_5 |
Opening | Sun elevation above threshold maintained for configured duration |
t_close_4 |
Closing | Brightness below threshold maintained for configured duration |
t_close_5 |
Closing | Sun elevation below threshold maintained for configured duration |
| Trigger ID | Category | Description |
|---|---|---|
t_resident_update |
Resident | Resident sensor changed state — handles both arriving and leaving |
| Trigger ID | Category | Description |
|---|---|---|
t_calendar_event_start |
Calendar | Calendar event becomes active (cover configured action starts) |
t_calendar_event_end |
Calendar | Calendar event ends (cover configured action ends) |
| Trigger ID | Category | Description |
|---|---|---|
t_contact_tilted_changed |
Ventilation | Window/door tilted state changed |
t_contact_opened_changed |
Ventilation | Window/door fully opened state changed |
| Trigger ID | Category | Description |
|---|---|---|
t_shading_start_pending_1 |
Shading | Sun azimuth/elevation entered shading range |
t_shading_start_pending_2 |
Shading | Brightness exceeded shading threshold |
t_shading_start_pending_3 |
Shading | Temperature Sensor 1 exceeded threshold |
t_shading_start_pending_4 |
Shading | Temperature Sensor 2 exceeded threshold |
t_shading_start_pending_5 |
Shading | Weather condition matched |
t_shading_start_pending_6 |
Shading | Forecast temperature sensor value changed |
t_shading_start_pending_7 |
Shading | Pre-opening forecast check (triggered ~1h before opening time) |
t_shading_start_execution |
Shading | Start pending time elapsed + conditions confirmed → execute shading |
| Trigger ID | Category | Description |
|---|---|---|
t_shading_tilt_1 |
Shading | Sun elevation < tilt threshold 1 |
t_shading_tilt_2 |
Shading | Sun elevation < tilt threshold 2 |
t_shading_tilt_3 |
Shading | Sun elevation < tilt threshold 3 |
t_shading_tilt_4 |
Shading | Sun elevation < tilt threshold 4 |
| Trigger ID | Category | Description |
|---|---|---|
t_shading_end_pending_1 |
Shading | Temperature Sensor 1 dropped below threshold |
t_shading_end_pending_2 |
Shading | Temperature Sensor 2 dropped below threshold |
t_shading_end_pending_3 |
Shading | Brightness dropped below shading threshold |
t_shading_end_pending_4 |
Shading | Weather condition no longer met |
t_shading_end_pending_5 |
Shading | Sun position left shading range (azimuth/elevation) |
t_shading_end_pending_6 |
Shading | Forecast temperature sensor value changed (end condition) |
t_shading_end_execution |
Shading | End pending time elapsed + conditions confirmed → end shading |
t_shading_reset |
Shading | Midnight reset of daily shading counter |
| Trigger ID | Category | Description |
|---|---|---|
t_manual_position |
Manual | Manual cover position change detected |
t_manual_tilt |
Manual | Manual tilt position change detected |
| Trigger ID | Category | Description |
|---|---|---|
t_reset_fixedtime |
Override Reset | Manual override timeout reset at configured time (midnight or specified time) |
t_reset_timeout |
Override Reset | Manual override timeout expired (duration-based) |
| Trigger ID | Category | Description |
|---|---|---|
t_force_enabled_open |
Force | Force-Open activated |
t_force_enabled_close |
Force | Force-Close activated |
t_force_enabled_shade |
Force | Force-Shade activated |
t_force_enabled_ventilate |
Force | Force-Ventilate activated |
t_force_disabled_open |
Force | Force-Open deactivated → return to target |
t_force_disabled_close |
Force | Force-Close deactivated → return to target |
t_force_disabled_shade |
Force | Force-Shade deactivated → return to target |
t_force_disabled_ventilate |
Force | Force-Ventilate deactivated → return to target |
What to look for:
Example debugging:
Problem: "Covers don't open at 07:00"
Check trace:
- ❌ t_open_1 didn't fire
- ❌ t_open_2 didn't fire
- ❌ t_open_4 didn't fire
- ❌ t_open_5 didn't fire
Likely causes: Manual override active OR time values incorrect
A: CCA uses a priority-based state machine where the cover can be in one of 6 states. Each transition is handled by a specific action branch:
| From ↓ \ To → | OPEN | CLOSE | SHADE | VENT | LOCK | FORCE |
|---|---|---|---|---|---|---|
| OPEN | – | Branch 1 | Branch 2 | Branch 5 | Branch 5 | Branch 7 |
| CLOSE | Branch 0 | – | Branch 2* | Branch 5 | Branch 5 | Branch 7 |
| SHADE | Branch 4 | Branch 1 | – | Branch 5 | Branch 5 | Branch 7 |
| VENT | Branch 5 | Branch 5 | Branch 5 | – | Branch 5 | Branch 7 |
| LOCK | Branch 5 | – ⚠️ | Branch 5 | Branch 5 | – | Branch 7 |
| FORCE | Branch 8 | Branch 8 | Branch 8 | Branch 8 | – | Branch 7 |
Legend:
* = Branch 2 saves shading intent when the cover is closed (base state preserved, no movement)⚠️ = LOCK → CLOSE has no direct transition. The window must first be closed (LOCK → VENT/OPEN → CLOSE)Branch Overview:
| Branch | Name | Primary Trigger |
|---|---|---|
| 0 | Opening | t_open_* |
| 1 | Closing | t_close_* |
| 2 | Shading Start | t_shading_start_pending_*, t_shading_start_execution |
| 3 | Shading Tilt | t_shading_tilt_* |
| 4 | Shading End | t_shading_end_pending_*, t_shading_end_execution |
| 5 | Contact Sensor | t_contact_* |
| 6 | Resident Update | t_resident_update |
| 7 | Force Functions | t_force_enabled_* |
| 8 | Return After Force | t_force_disabled_* |
| 9 | Manual Detection | t_manual_* |
| 10 | Reset Override | t_reset_* |
| 11 | Midnight Reset | t_shading_reset |
Priority Cascade (highest first):
force != "none" → Force positionwindow == "open" → Open position (lockout protection)base == "open" AND no shading/privacy/restriction → Open positionwindow == "tilted" AND base would close/shade/privacy → Ventilate position (floor)resident == 1 AND closing trigger → Close positionshade == 1 → Shading positionbase == "close" → Close positionA tilted window expresses ventilation intent — and a fully open cover gives maximum airflow. So when the schedule says “open” and nothing else lowers the cover, opening wins over the tilted-vent floor. VENT acts as a floor only when the cover would otherwise close, shade, or privacy-close.
A: CCA uses a two-phase approach to ensure stable conditions before activating or ending sun shading:
Trigger → Pending (timestamp set) → Execution Trigger → Re-evaluation → Start/Retry/Abort
Phase 1 - Pending (Condition Detection):
pnd to "beg" (start) or "end" (end), writing the fire time into ts.due and the retry anchor into ts.armnow() + waiting_time (configurable delay)Phase 2 - Execution (Verification & Action):
now() reaches ts.due, the execution trigger fires| Outcome | Conditions still met? | Timeout reached? | Action |
|---|---|---|---|
| ✅ Execute | Yes | – | Start/end shading, clear pending timestamp |
| 🔄 Retry | No | No | Set new pending timestamp, wait again |
| ❌ Abort | No | Yes | Clear pending timestamp, no action |
Why this approach?
Official Documentation:
Tools:
Community: