Skip to content

Troubleshooting

Jason Rhubottom edited this page Jun 5, 2026 · 13 revisions

Troubleshooting

Update first. Many known issues are fixed in the latest release. Before diving into diagnostics, confirm you're on the latest version: Settings → Devices & Services → Adaptive Cover Pro → version.

When a cover is at an unexpected position, use the diagnostic sensors to trace exactly why.

For the per-sensor / per-attribute reference of every sensor mentioned below, see Diagnostic Sensors. For design-level constraints (open/close-only covers, dual-axis venetian setup, sensor-startup defaults), see Known Limitations.

Step 1: Check the Decision Trace

The sensor.{device_name}_decision_trace sensor is the starting point. Its state is the winning pipeline handler's identifier — solar, default, manual_override, force_override, summer, winter, glare_zone, weather_override, cloud_suppression, custom_position, motion_timeout. For the full state set with descriptions, see Diagnostic Sensors → decision_trace.

The trace attribute lists every handler evaluated in priority order — read it top to bottom to see why each one won or was skipped.

Step 2: Check the Target Position Attributes

The sensor.{device_name}_cover_position sensor (displayed as Target Position) exposes two attributes that answer "who won?" and "where did this number come from?":

  • reason: which pipeline rule claimed control and why (e.g. "no active condition — default position 100%")
  • position_explanation: where the final number came from after the pipeline decided (e.g. "Sun Tracking (67%) → Max Position Limit → 80%")

To check whether each cover has actually reached the target, see actual_positions and all_at_target on the same sensor — full attribute reference: Diagnostic Sensors → cover_position attributes.

Step 3: Cover Isn't Moving When You Expect It To

Check sensor.{device_name}_last_skipped_action. Its state encodes the suppression reason — delta_too_small, time_delta_too_small, manual_override, dry_run, cover_unavailable, etc. For the full state set with attribute hints, see Diagnostic Sensors → last_skipped_action.

If last_skipped_action shows nothing recent but the cover still isn't responding, the issue may be the time window rather than a skipped action; there's no skip code for "outside time window." Verify that the current time falls within your configured start/end window (integration options → Automation). Also check that the Automatic Control switch is on.

If the cover is commanded but never arrives at the target, see the Position Verification page for how the reconciliation retry loop works, its 3-retry give-up behavior, and the position_verification / retry_count diagnostic sensors.

Step 4: Climate Mode Behavior

If the decision trace shows summer, winter, or the cover is at an unexpected position while climate mode is enabled, check sensor.{device_name}_climate_status — its state (Summer Mode / Winter Mode / Intermediate) plus the active_temperature, is_presence, and is_sunny attributes explain the decision. Full attribute reference: Diagnostic Sensors → climate_status.

v2.18.0 (#231): when climate mode is on, presence is detected, and the sun is active, the glare_zone handler (priority 45) now runs; previously the climate handler's GLARE_CONTROL branch short-circuited to solar, blocking glare zones entirely. If a decision trace shows glare_zone where you used to see solar, this is the fix in action.

Glare zones and presence. If a presence sensor is configured, glare zones follow the same rule as regular glare control; they do not activate when nobody is home. If glare zones aren't triggering when expected, check that is_presence is true in the climate status sensor.

Step 5: Force Override Active

If the decision trace shows force_override, check sensor.{device_name}_force_override_triggers. The per_sensor attribute shows every configured binary sensor and its current state. Any sensor reporting on will override automatic control and move covers to the configured override position.

Minimum position mode not behaving as expected. If "Minimum position mode" is enabled for force override but covers are moving all the way to the override position instead of staying at their current (higher) position, check whether sun tracking is disabled; the minimum position mode calculation requires the correct base position and can behave unexpectedly when sun tracking is off. Ensure you're on the latest release and re-test.

Step 6: Motion Control Unexpected

If motion control is configured and behavior is unexpected, check sensor.{device_name}_motion_status — its state (motion_detected, timeout_pending, no_motion, waiting_for_data) plus motion_timeout_end_time and last_motion_time explain the current state. Full attribute reference: Diagnostic Sensors → motion_status.

Step 7: Position Doesn't Match the Calculation

If the cover moved but not to the expected position, check the sun_position and cover_position sensors. The gamma attribute on sun_position (angle of sun relative to window normal) and the raw_calculated_position attribute on cover_position (geometric position before limits, climate adjustments, or margins) are the key fields — full attribute reference: Diagnostic Sensors → sun_position and cover_position attributes. High gamma values (>45°) and low elevations (<10°) trigger automatic safety margins that extend the blind further.

Enable Sun Tracking and Glare Zones are independent. The "Enable Sun Tracking" switch gates only distance-based solar positioning; it does not affect glare zones. Glare zones are independently controlled by their own switch and remain active regardless of the sun tracking toggle. If you've disabled sun tracking and glare zones have stopped firing, check that the glare zones switch is still on.

Position calibration direction. Calibration maps calculated position (input) → actual command sent (output). The left column is what the engine outputs; the right column is what gets sent to the cover. For example, mapping calculated 25% → actual 11% means a 25% engine result sends an 11% command. If covers are consistently stopping too low or too high after calibration, verify the direction isn't inverted.

Blind spot reference frame. Blind spot angles are measured from the left FOV boundary (fov_left), not from the window normal / azimuth center. If a blind spot is blocking the wrong part of the FOV or not triggering where expected, verify that the angles are counted from fov_left rather than from center.

Tilt-only covers (v2.18.0, #234). Some covers, common with Z-Wave venetian blinds and certain KNX actuators, support SET_TILT_POSITION but not SET_POSITION. Earlier versions mis-routed these through open_cover/close_cover because routing relied on the configured sensor_type rather than per-entity capabilities; the result was a two-minute reconciliation retry loop where the integration kept sending position commands the motor couldn't acknowledge. Cover Pro now inspects each cover's supported_features and auto-routes tilt-only covers through set_cover_tilt_position. If you still see routing oddities, confirm the cover's supported_features bitmask exposes SET_TILT_POSITION. Covers that temporarily report STATE_UNKNOWN (common on Z-Wave after restart) now still pass the capability check as long as supported_features is populated.

Debug toggles without the UI. Most debug-relevant options (enable/disable integration, motion/climate/cloud toggles, delta thresholds, custom position slots) can be flipped from an automation using the Runtime Configuration Services instead of the options flow; useful when reproducing an issue on a live install.

Card shows the cover inverted (open/closed swapped). If the cover bars, tile, or Sky Compass draw the cover open when it's physically closed (or the reverse), the cover is reporting its position backwards (0 = open / 100 = closed). Fix it at the source — the integration's Inverse State toggle or a normalising template cover — not per-card. Full walkthrough: Dashboard Cards → inverted cover display.

Step 8: Manual Override Triggered Unexpectedly

If the decision trace shows manual_override and you didn't actually touch the cover, the integration is reading a state change that didn't come from its own commands. Common causes:

  • Slow covers or covers that report only a final position. The transit window expires mid-move and the next intermediate update looks like a manual change. See "Slow Covers and Covers That Don't Report Movement" below for the full fix.
  • Venetian dual-axis blinds (Somfy IO via Tahoma, KNX, Shelly 2PM, Fibaro). After a position command the motor back-rotates the slats and — on slower bus protocols — republishes the post-move position seconds to minutes later. The integration classifies both as motor side-effects within a 45 s window after settle. From v2.23.4 the window is exposed as Geometry → Publish-lag window (s) (default 45 s, range 15–180 s) and covers both axes; before v2.23.4 it protected only the tilt axis, so a slow current_position republish could trip manual_override_set 30–90 s after a commanded move (issue #33). If your hardware sits on a slow KNX line or you see overrides fire right when the sun leaves the FOV and the cover commands itself open, widen the window to 60–120 s. The Publish-lag window tuning section on the Venetian Blinds page covers the diagnostic counter (primary_axis_suppression_last_24h) and the WARN log line that tells you whether the window is actually doing work for your hardware. The Timeouts and Manual-Override Detection section covers all three layered timeouts and what each one protects against.
  • Anything else. Enable Debug Mode → Manual Override category (see "Collecting a Bug Report" below) and reproduce. The manual_override_history block in the diagnostics download shows every decision with position values, threshold, and reason.

In every case, the Reset Manual Override button on the integration's device page forces ADP to disengage immediately and resume automatic control.

Workaround — stop unexpected manual overrides entirely

If overrides keep firing when you didn't touch the cover — on slow Zigbee/battery shades, covers that report a stale position mid-move, or anything driven by an external source (other automations, the default HA cover card, physical or RF remotes) — you can take ACP's external-state detection out of the loop completely. This is the recommended fix when increasing the transit timeout doesn't stop the false overrides.

  1. Enable "Only engage manual override from Adaptive Cover Pro commands" under Automation → Manual Override. With this on, ACP ignores all external state changes — the three detection paths that ingest them (user-context fast-path, numeric position diff, and the user stop_cover path) are skipped. Only a command routed through ACP itself engages manual override, so a stale or noisy position report can no longer trip a false override.

  2. Drive the cover through ACP instead of the physical entity so your intentional adjustments are still recognised. Pick either:

    • Turn on the Proxy Cover Entity and point your dashboard cards at the …_managed proxy instead of the physical cover, or
    • Use the companion Adaptive Cover Pro Card — its position bars, more-info dialog, and custom-position controls already drive covers through ACP.

    Both route through ACP, so your manual moves engage override normally while external noise is filtered out. While this option is on, use the adaptive_cover_pro.stop service instead of cover.stop_cover (the native stop is an external command and will now be ignored).

Full walkthrough, including how the ACP Card behaves with this enabled: Tips and Tricks → ACP-only manual override.

Slow Covers and Covers That Don't Report Movement

Some covers take longer than the default 45-second transit window to complete a full traverse: large motorized blinds, heavy outdoor awnings, or covers on older radio-protocol motors are common examples. Others complete their transit silently, reporting only their final position when they arrive (no intermediate updates). Both can trigger a false manual override if the integration's transit-protection window closes before the cover finishes moving.

Symptom: a cover enters manual override shortly after an automatic sunset close, a default-position reset, or any slow automatic command, even though you didn't touch the cover.

Why it happens: the integration protects covers in transit from false override detection. By default this protection window resets whenever the cover reports it moved closer to its target and times out after 45 seconds of no observed progress. For a slow cover, the 45-second window may expire mid-transit, causing the next intermediate position report to look like a manual move. Covers that don't report intermediate positions fall back to measuring elapsed time from when the command was sent.

Fix: raise the Transit Timeout setting to at least 1.5× your longest full-traverse time. That page documents the setting, its range, how the timer resets on progress, and how to measure your cover's traverse time end-to-end.

If increasing the timeout doesn't help or the false override happens at other times (not during transit), enable Debug Mode + Manual Override category and reproduce the issue. The log will show exactly why the override was triggered: position delta, direction check result, and which backstop fired. Download a Diagnostics snapshot after reproducing and attach it to a GitHub issue.

Enable Debug Logging (YAML)

For the deepest detail when the UI debug categories aren't enough, enable debug logging in configuration.yaml:

logger:
  default: warning
  logs:
    custom_components.adaptive_cover_pro: debug

Restart Home Assistant and check Settings → System → Logs. With debug logging active you will see detailed entries such as:

Position explanation changed: Sun tracking (45%) → Climate: Winter Heating → 100%
Skipping cover.living_room_blind: position delta too small
Vertical calc: elev=32.5°, gamma=18.3°, dist=2.500→2.500, base=1.234, margin=1.000, clipped=1.234
Sun visibility transition detected: ON → OFF (sun left field of view)

Each log entry is prefixed with the device name so you can filter by device in multi-instance setups.

Most users prefer the no-YAML UI route — see Debug Mode setting, which promotes specific categories from DEBUG to INFO without touching configuration.yaml.

Collecting a Bug Report

For targeted troubleshooting — especially manual-override detection issues — enable Debug Mode and the relevant log categories from Debug & Diagnostics, then:

  1. Reproduce the issue (move the cover manually, wait for incorrect behavior).
  2. Go to Settings → Devices & Services → Adaptive Cover Pro → select the affected cover → Download Diagnostics.
  3. Attach the downloaded JSON to the GitHub issue.

The most useful sections in the diagnostics JSON for triage:

  • manual_override_history — every override decision (set / reset / rejected) with position values, threshold, and reason
  • cover_command_state — per-entity snapshot of target_call, wait_for_target, retry count, safety target, and last command time

Turn Debug Mode off after collecting data; INFO-level logs are persistent and the ring buffer uses a small amount of memory per event.

Privacy: Diagnostics contain entity IDs and position history but no credentials or location data; safe to attach to public GitHub issues.

Clone this wiki locally