Skip to content

Manual Override

Jason Rhubottom edited this page Aug 12, 2026 · 2 revisions

Manual Override

Manual override is how Adaptive Cover Pro gets out of your way. When you move a cover yourself, the integration stops driving it, holds it where you left it, and hands control back after a while.

Everything on this page is in v2026.8.2.

The first half is what you need to use the feature. The second half, after the divider, is the detection machinery β€” read it when an override fires and you don't know why.

What it is

An override is per cover and has exactly three things in it: a flag, the moment you touched it, and the moment it ends. While it is held, the sun-tracking pipeline still runs and still calculates a position β€” it just doesn't send it.

graph TD
  AUTO["Automatic control\nACP sends calculated positions"]
  TOUCH{"Something moves\nthe cover"}
  ARMED["Override armed\nstart time recorded"]
  HELD["Cover held where you left it\npipeline keeps calculating, sends nothing"]
  END{"End reached, or\ncleared by hand?"}

  AUTO --> TOUCH
  TOUCH -->|"ACP decides it was you"| ARMED
  TOUCH -->|"ACP decides it was itself"| AUTO
  ARMED --> HELD
  HELD --> END
  END -->|"Not yet"| HELD
  END -->|"Yes"| RESUME["Override dropped\nACP sends the current calculated position"]
  RESUME --> AUTO

  classDef engage fill:#f59e0b,stroke:#b45309,stroke-width:2px,color:#111827
  classDef hold fill:#fdba74,stroke:#ea580c,color:#111827
  classDef auto fill:#86efac,stroke:#16a34a,color:#111827
  class ARMED engage
  class HELD hold
  class AUTO,RESUME auto
Loading

The whole feature turns on one question: was that move you, or was it me? Almost every complaint about manual override β€” it fires when you didn't touch anything, or it doesn't fire when you did β€” is that question being answered wrongly. How detection actually decides is the answer in full.

What engages it

Five independent paths, plus a service. Any one of them arms the override.

# Path What triggers it Notes
1 Position delta The cover reports a position that differs from what ACP last commanded, by more than the threshold The default path, and the only one that can be fooled. Everything in the second half of this page is about this one
2 User context A state change carrying a Home Assistant user_id that isn't ACP's own Someone used the HA cover card, an app, or a voice assistant. Fast path β€” skips the delta ladder entirely
3 Stop button cover.stop_cover called from outside ACP Only works if My Position is configured; without it an external stop is ignored. See My Position Support
4 Input sensor / template A configured binary sensor goes off→on, or a configured template renders truthy Nothing to do with cover position — this is a wall switch telling ACP directly. Engages on every cover in the instance
5 ACP's own user commands The proxy cover entity, the set_position / set_tilt / set_axes / stop services, the card's sliders, the My Position button Marked as yours before the command is even sent, so the resulting movement can never be misread
graph TD
  P1["Cover reports a new position"]
  P2["State change carries a\nHome Assistant user_id"]
  P3["cover.stop_cover called\nfrom outside ACP"]
  P4["Input sensor goes off to on,\nor input template renders truthy"]
  P5["Proxy entity, ACP card, or\nset_position / set_tilt / set_axes / stop"]
  SVC["engage_manual_override service"]

  P1 --> LADDER{"Detection ladder\nsays it was you?"}
  LADDER -->|No| IGNORE(["Ignored β€” automatic control continues"])
  LADDER -->|Yes| ARM

  P2 -->|"not ACP's own context"| ARM
  P3 -->|"My Position configured"| ARM
  P3 -->|"My Position not set"| IGNORE
  P4 -->|"rising edge only"| ARM
  P5 -->|"force: true"| NOARM["Cover moves,\nno override armed"]
  P5 -->|"force: false"| PRE{"Is a handler that outranks\nmanual override winning\nright now?"}
  PRE -->|"Yes"| REFUSE["Move refused\nrecorded as preempted_by_..."]
  PRE -->|No| ARM
  SVC --> ARM

  ARM["Override armed\non this cover"]

  classDef engage fill:#f59e0b,stroke:#b45309,stroke-width:2px,color:#111827
  classDef reject fill:#cbd5e1,stroke:#64748b,color:#111827
  class ARM engage
  class IGNORE,REFUSE,NOARM reject
Loading

Paths 4 and 5 never guess. They know a human acted because a human action routed through them. Path 1 is the only one doing inference, and it is the one to take out of the loop if you get false overrides β€” see Stopping unwanted overrides.

⚠️ An ACP-routed move can be refused outright. If a handler that outranks manual override β€” weather safety, a safety-priority custom slot, a group lock β€” is winning at that moment, your slider drag or set_position call is not sent and no override is engaged. It is recorded as skipped with the reason preempted_by_<handler>. This is why the card sometimes appears to ignore you during a wind retract: the safety override is refusing the move, not losing it. Pass force: true to override that, which also skips engaging the override.

Input sensors and templates

These two settings let a physical wall switch engage the override directly, instead of ACP inferring your intent from a position report. Wire a switch to a Shelly 2PM input, point the setting at binary_sensor.*_cover_input_0, and pressing it pauses automatic control on every cover in the instance.

  • Input sensors that trigger manual override β€” one or more binary sensors, switches, or input_boolean helpers. Only the offβ†’on edge engages. A sensor that restores already-on at startup does nothing, and neither does onβ†’on.
  • Input template that triggers manual override β€” a Jinja template; a truthy render engages. Same rising-edge behaviour, no combine mode, and it works on its own with no companion sensor. A falsy, empty, or broken template does nothing.

Neither one ever releases an override. The configured duration does that.

Pair these with "Only engage manual override from ACP commands" for a completely deterministic setup. Position inference off, wall switch on: the only things that can pause automatic control are the switch and ACP's own services.

What it holds

While an override is active, the decision trace shows a position the cover is not moving to. That is intentional and it confuses everyone once.

Value What it is
Held position Where the cover physically sits. This is what the override is protecting
Position (in the trace) What sun tracking would have commanded right now. Published for diagnostics so you can see what you're overriding β€” never sent

So the Tile Card showing "Target 62%" while the cover sits at 100% is not a bug: 62% is the shadow, 100% is the hold.

Two different skip labels show up in last_skipped_action, and they mean different things:

  • manual_override_hold β€” the pipeline decided to hold; no command was generated.
  • manual_override β€” a command was generated but the dispatch gate blocked it for this specific cover.

⚠️ A cover that never reports a numeric position cannot be held. The hold needs a physical position to protect. With no position feedback the handler falls through and the cover keeps tracking β€” open/close-only motors without My Position behave this way.

On a multi-cover instance, one overridden cover makes the handler win for the whole entry. The per-cover filtering happens later, at dispatch: covers that aren't overridden still get their commands. What you lose is the instance-level sensors, which report the override state for the entry as a whole. binary_sensor.<device>_manual_override has a manual_controlled attribute listing exactly which covers are held.

When it ends

The end time

Four rules, checked in order. The first one that produces an answer wins.

graph TD
  Q1{"Is an override\nactually held?"}
  Q1 -->|No| NONE(["No end time"])
  Q1 -->|Yes| Q2{"Was an absolute end pinned?\n(engage_manual_override, or\nrestored after a restart)"}
  Q2 -->|Yes| PIN["Use that exact time"]
  Q2 -->|No| Q3{"Duration mode"}

  Q3 -->|"Fixed duration"| FIX["start + Override Duration"]
  Q3 -->|"Until the next sunset"| SS["first sunset after the start"]
  Q3 -->|"Until the next sunrise"| SR["first sunrise after the start"]
  Q3 -->|"Until the next sunrise or sunset"| SE["whichever comes first\nafter the start"]
  Q3 -->|"Until the time window ends"| WE["first End Time after the start"]

  SS --> RESOLVE{"Could that boundary\nbe worked out?"}
  SR --> RESOLVE
  SE --> RESOLVE
  WE --> RESOLVE
  RESOLVE -->|Yes| USE["Use the boundary"]
  RESOLVE -->|"No β€” e.g. no End Time set"| FIX

  classDef engage fill:#f59e0b,stroke:#b45309,stroke-width:2px,color:#111827
  classDef reject fill:#cbd5e1,stroke:#64748b,color:#111827
  class PIN,FIX,USE engage
  class NONE reject
Loading

Two rules that are easy to get wrong:

  • The anchor is the moment you touched the cover, never "now". "Until the next sunset" means the first sunset after you moved it β€” not the first sunset after each refresh, which would keep receding.
  • The boundary must fall strictly after the anchor. Touch a cover exactly at sunset with "Until the next sunset" and you get tomorrow's sunset, not a zero-length hold.

An override can never hold forever. If the boundary can't be worked out β€” "Until the time window ends" with no End Time configured, or a sun mode before the first calculation cycle β€” the fixed Override Duration is used as the fallback. The Configuration Summary flags this shape with a ⚠️ so you can see it before it bites.

The sun-relative modes exist for the close-the-blind-at-dusk case: with "Fixed duration" set to 2 hours, a blind you close at 20:00 reopens at 22:00. With "Until the next sunrise" it stays closed all night.

What clears it

graph TD
  HELD["Override held"]

  HELD --> C1["End time passes"]
  HELD --> C2["Reset Manual Override button"]
  HELD --> C3["group_clear_overrides service\nor Clear Member Overrides button"]
  HELD --> C4["Manual Override Detection\nswitch turned OFF"]
  HELD --> C5["Automatic Control\nswitch turned OFF"]
  HELD --> C6["Restart, and the stored end time\nhad already passed"]

  C1 --> GONE
  C2 --> GONE
  C3 --> GONE
  C4 --> GONE
  C5 --> GONE
  C6 --> GONE
  GONE["Override cleared\nACP sends the current calculated position"]

  HELD -.-> N1(["Cover reaches the position ACP wanted"])
  HELD -.-> N2(["Cover fully opened or closed"])
  HELD -.-> N3(["Sunset, or the end of the time window"])
  HELD -.-> N4(["A new day starts"])

  classDef hold fill:#fdba74,stroke:#ea580c,color:#111827
  classDef auto fill:#86efac,stroke:#16a34a,color:#111827
  classDef reject fill:#cbd5e1,stroke:#64748b,color:#111827
  class HELD hold
  class GONE auto
  class N1,N2,N3,N4 reject
Loading

The dotted branches are the things people expect to clear an override that deliberately do not. There is no "the cover matched the calculated position again, so release" rule and no end-of-day reset. Sunset and the end-of-window reposition skip an overridden cover rather than clearing it β€” that is the point of the feature.

Turning off Automatic Control clears every override, but does not stop detection. Detection is governed only by the Manual Override Detection switch. With Automatic Control off and detection on, ACP still tracks that you moved a cover β€” it just isn't driving anything.

Across restarts

Overrides survive a Home Assistant restart and an integration reload. The mechanism is sensor.<device>_manual_override_end_time: its per_entity attribute stores each cover's end time, and Home Assistant restores it on startup.

What that means in practice:

  • Only the end time is stored. The start time is reconstructed from it, so "started at" after a restart is an approximation.
  • Overrides whose end time has already passed are dropped, not resurrected.
  • Covers no longer configured on the entry are dropped.
  • Position verification restores its command target too, so the first state report after a restart runs the fully-guarded detection path instead of the weaker no-target one.

Fixed in v2026.8.2: before that release, every restart wiped restored overrides. The Manual Override switch had not finished restoring when the first refresh ran, and its unset state was read as "detection disabled", which cleared everything. (#1232)

Where it sits in the pipeline

Manual override runs at priority 80 by default β€” below the safety overrides, above everything that calculates a position.

graph TD
  IN[("Cover decision cycle")] --> PIPE

  subgraph PIPE ["Override Pipeline (highest priority wins)"]
    direction TB
    H100["Custom-position safety slot,\nor group lock (100)"] -->|"No result"| H90
    H90["Weather override (90)"] -->|"No result"| H85
    H85["Group scene (85)"] -->|"No result"| H80
    H80{"Manual override (80)\nany cover held?"}
    H80 -->|Yes| HOLD["Hold each held cover\nwhere it sits"]
    H80 -->|No| H77
    H77["Custom position slots (77 default)"] -->|"No result"| H75
    H75["Motion timeout (75)"] -->|"No result"| H60
    H60["Cloud suppression (60)"] -->|"No result"| H50
    H50["Climate (50)"] -->|"No result"| H45
    H45["Glare zone (45)"] -->|"No result"| H40
    H40["Solar (40)"] -->|"No result"| H0
    H0["Default (0)"]
  end

  classDef engage fill:#f59e0b,stroke:#b45309,stroke-width:2px,color:#111827
  classDef hold fill:#fdba74,stroke:#ea580c,color:#111827
  class H80 engage
  class HOLD hold
Loading

Weather safety and safety-priority custom slots go through an override. They dispatch with force, which bypasses the per-cover gate entirely. That is deliberate: a wind retract must not be blocked because someone nudged the blind an hour ago.

Minimum and maximum position floors only move a held cover when they outrank it. A floor whose priority is strictly above manual override's effective priority will clamp a manually-placed cover back up to it; at or below β€” including the default 77 for custom slots β€” the manual position is left alone for the whole window. Full treatment: Custom Position β†’ Priority and manual moves.

⚠️ 80 is a default, not a constant. Every built-in handler's priority is configurable per cover (range 1–99) in the πŸ”€ Handler Priorities step. If you have re-ordered the chain, compare against your configured value, not against 80. See Reordering the built-in handlers.

Settings

Options flow β†’ βœ‹ Manual Override.

Setting Default Range What it does
Duration of manual override 2 hours β€” How long the hold lasts in "Fixed duration" mode, and the fallback for every other mode
What the override duration is measured against Fixed duration 5 modes Fixed, or until the next sunset / sunrise / sun event / end of the time window
Reset manual override duration off β€” Extends the hold on every touch. With it off, only the first touch sets the end time and later adjustments don't push it out
Manual override threshold unset 0–99 % Position change that counts as a manual move. Always floored at 3 % β€” setting 0 or 1 does not make detection more sensitive than 3 %
Ignore intermediate positions off β€” Drop opening / closing state changes. Turn on for covers that report many positions mid-travel
Only engage manual override from ACP commands off β€” Ignore all external state changes. Paths 1–3 above stop working; paths 4–5 still do
Input sensors that trigger manual override none — Binary sensors whose off→on edge engages the override on every cover
Input template that triggers manual override none β€” Jinja template whose truthy render does the same
Transit timeout 45 s 15–600 s How long a cover may travel without reporting progress before its next position report is read as intentional. Raise to 1.5Γ— your longest full traverse for slow covers

Three settings that live elsewhere but change detection:

Setting Where Effect
Position match tolerance Automation The 3 % floor on the threshold, and the dead-band for "already at target"
Enable position matching Behaviour Off by default. With it off, a cover that settles past tolerance becomes an override instead of being re-commanded. See Position Matching
My position Cover setup Required for the external-stop path. Unset means cover.stop_cover from outside ACP is ignored
Publish-lag window Geometry Venetian only β€” how long a late position report is tolerated before it counts as a touch. See Venetian Blinds

Fixed and not configurable: the 5 second command grace after every command ACP sends, the 30 second startup grace after Home Assistant restarts, and the 30 % venetian back-rotation geometry cap.

Entities, services and cards

Entity Purpose
binary_sensor.<device>_manual_override On when any cover is held. Attribute manual_controlled lists which ones
switch.<device>_manual_override Manual Override Detection. Turning it off clears every active override and stops all detection
sensor.<device>_manual_override_end_time The latest end time across covers. Attribute per_entity gives each cover's own. This is also what persists overrides across restarts
button.<device>_reset_manual_override Clear every override on this entry and resume immediately
button.<group>_clear_member_overrides The same, across a cover group
sensor.<device>_control_status Reads manual_override while held; attribute manual_covers names them
sensor.<device>_decision_trace Shows which handler won and why
sensor.<device>_last_skipped_action Shows manual_override or manual_override_hold when a command was suppressed
Service Purpose
engage_manual_override Pause control without moving the cover. Optional end_time (absolute) or duration
set_manual_override Change the settings above from an automation
group_clear_overrides Clear overrides across a group's members
set_position / set_tilt / set_axes Move a cover through ACP. Engages the override unless force: true
stop Stop a cover through ACP. Always engages

⚠️ engage_manual_override reads a naive end_time as UTC, not your local time. 2026-07-04T22:00:00 means 22:00 UTC. For local time, include the offset (2026-07-04T22:00:00+02:00) or use a template like {{ (now() + timedelta(hours=2)).isoformat() }}.

duration extends, it does not restart. On a cover already held, duration: {hours: 1} adds an hour to the current end time. On a cover not held, it engages fresh for an hour. And if you pass both, end_time wins.

On the Tile Card, a held cover shows an orange Manual Β· HH:MM badge; tap it to resume, or use its clock button to push the end time out. The Panel Card has an Overrides section with the countdown and a reset button, and the History Card draws overlay bands for past overrides.

Stopping unwanted overrides

If overrides fire when you didn't touch anything, the fix is to stop ACP inferring your intent from position reports:

  1. Turn on Only engage manual override from ACP commands. Paths 1–3 stop working entirely.
  2. Drive covers through ACP so your real adjustments still register β€” the Proxy Cover Entity or the companion card. Use adaptive_cover_pro.stop rather than cover.stop_cover.
  3. Optionally add an input sensor so a physical wall switch still engages the override directly.

Symptom-by-symptom diagnosis, including the slow-cover and venetian cases, is on Troubleshooting β†’ Manual override triggered unexpectedly, and the full walkthrough is at Tips and Tricks β†’ ACP-only manual override.


You don't need anything below this line to use manual override. It's here for when an override fires and the reason isn't obvious.

How detection actually decides

This is path 1 β€” position-delta detection β€” in full. Every rejection has a name, and that name appears in the debug log and in the manual_override_history block of a diagnostics download. Find the name, find your branch.

A state change runs three stages in order. It has to survive all three to become an override.

Stage 1 β€” instance gates

Checked once for the whole entry. Nothing here is about a particular cover.

graph TD
  EV[("Cover reports a state change")] --> G0
  G0{"Was the cover previously\nunavailable or unknown?"}
  G0 -->|Yes| X0["Ignored β€” a reconnection,\nnot a move"]
  G0 -->|No| G1{"Manual Override Detection\nswitch on?"}
  G1 -->|No| X1["Ignored\nmanual_override_gate_closed"]
  G1 -->|Yes| G2{"More than 30 s\nsince HA started?"}
  G2 -->|No| X2["Ignored β€” startup grace"]
  G2 -->|Yes| G3{"'Only engage from ACP\ncommands' turned on?"}
  G3 -->|Yes| X3["Ignored β€” external change"]
  G3 -->|No| G4{"Change carries a HA user_id\nthat isn't ACP's?"}
  G4 -->|Yes| SET1["OVERRIDE SET\nuser context"]
  G4 -->|No| G5{"Cover just arrived at\nthe commanded target?"}
  G5 -->|Yes| X4["Ignored β€” target reached"]
  G5 -->|No| NEXT(["Continue to Stage 2"])

  classDef engage fill:#f59e0b,stroke:#b45309,stroke-width:2px,color:#111827
  classDef reject fill:#cbd5e1,stroke:#64748b,color:#111827
  classDef defer fill:#e0e7ff,stroke:#6366f1,color:#111827
  class SET1 engage
  class X0,X1,X2,X3,X4 reject
  class NEXT defer
Loading

Stage 2 β€” per-cover gates

Now it matters which cover reported.

graph TD
  IN(["From Stage 1"]) --> C1
  C1{"Is this cover\nmanaged by ACP?"}
  C1 -->|No| X5["Ignored β€” not tracked"]
  C1 -->|Yes| C2{"Still waiting for this cover\nto reach its target?"}
  C2 -->|Yes| X6["Ignored\nrejected_wait_for_target"]
  C2 -->|No| C3{"Within 5 s of a command\nACP sent?"}
  C3 -->|Yes| X7["Ignored\nrejected_command_grace"]
  C3 -->|No| C4{"Did the tilt axis\nclaim this event?"}
  C4 -->|Yes| TILT(["Handled by the tilt tree below β€”\nthe position axis never runs"])
  C4 -->|No| NEXT(["Continue to Stage 3"])

  classDef reject fill:#cbd5e1,stroke:#64748b,color:#111827
  classDef defer fill:#e0e7ff,stroke:#6366f1,color:#111827
  class X5,X6,X7 reject
  class IN,TILT,NEXT defer
Loading

Stage 3 β€” the position-delta ladder

Where the decision is actually made. The threshold here is the larger of your configured Manual Override Threshold and 3 %.

graph TD
  IN(["From Stage 2"]) --> D1
  D1{"Has ACP ever commanded\nthis cover?"}
  D1 -->|No| D1a{"Did the position actually\nmove past the threshold?"}
  D1a -->|No| X8["Ignored\nrejected_no_command_target"]
  D1a -->|Yes| SET2["OVERRIDE SET\ncontext-less move"]
  D1 -->|Yes| D2{"Did it report\na position at all?"}
  D2 -->|No| X9["Ignored\nrejected_position_unavailable"]
  D2 -->|Yes| D3{"Does the cover say\nit is still moving?"}
  D3 -->|Yes| X10["Ignored\nrejected_in_transit"]
  D3 -->|No| D4{"Is this a known late\nrepublish? (venetian)"}
  D4 -->|Yes| X11["Ignored\nrejected_primary_axis_suppression"]
  D4 -->|No| D5{"Position exactly matches\nwhat ACP commanded?"}
  D5 -->|Yes| X12["Ignored β€” no change"]
  D5 -->|No| D6{"Difference bigger than\nthe threshold?"}
  D6 -->|No| X13["Ignored\nrejected_within_threshold"]
  D6 -->|Yes| SET3["OVERRIDE SET\nmanual_override_set"]

  classDef engage fill:#f59e0b,stroke:#b45309,stroke-width:2px,color:#111827
  classDef reject fill:#cbd5e1,stroke:#64748b,color:#111827
  classDef defer fill:#e0e7ff,stroke:#6366f1,color:#111827
  class SET2,SET3 engage
  class X8,X9,X10,X11,X12,X13 reject
  class IN defer
Loading

Three branches that surprise people:

  • The user-context branch skips the whole ladder. A move from the HA cover card carries a user_id, so it engages immediately β€” no threshold, no transit check. That is why an app move always registers and a remote-control move sometimes doesn't.
  • "Has ACP ever commanded this cover?" matters more than it looks. With no command on record, ACP has nothing meaningful to compare against, so it falls back to asking whether the position changed between reports. That is the weaker test, and it is the one running right after a restart if the command target wasn't restored.
  • The threshold floor is 3 %, always. Setting the threshold to 0 or 1 does not make detection more sensitive; motor rounding would trip it constantly.

Tilt and second-axis detection

On venetian and other dual-axis covers, the tilt axis is checked before the position axis and can claim the event outright.

graph TD
  T0["State change on a dual-axis cover"] --> T1{"Did it report\na tilt position?"}
  T1 -->|No| POS(["Fall through to the position tree"])
  T1 -->|Yes| T2{"Part of a drift-reset\nout-and-back trip?"}
  T2 -->|Yes| Y1["Claimed and ignored\nrejected_tilt_suppression"]
  T2 -->|No| T3{"Has ACP dispatched a tilt\ntarget to compare against?"}
  T3 -->|No| POS
  T3 -->|Yes| T4{"Inside the back-rotation or\npublish-lag window?"}
  T4 -->|Yes| Y2["Claimed and ignored\nrejected_tilt_suppression"]
  T4 -->|No| T5{"Tilt matches\nthe commanded angle?"}
  T5 -->|Yes| POS
  T5 -->|No| T6{"Difference past\nthe threshold?"}
  T6 -->|No| POS
  T6 -->|Yes| Y3["OVERRIDE SET\nmanual_override_set"]

  classDef engage fill:#f59e0b,stroke:#b45309,stroke-width:2px,color:#111827
  classDef reject fill:#cbd5e1,stroke:#64748b,color:#111827
  classDef defer fill:#e0e7ff,stroke:#6366f1,color:#111827
  class Y3 engage
  class Y1,Y2 reject
  class POS defer
Loading

Venetian motors back-rotate their slats after a position move, and slow buses republish the post-move position long afterwards. Both look exactly like a user touch. Three layered windows suppress them: the carriage being mid-travel, a 5 second tail after the slats settle, and the configurable publish-lag window (default 45 s, range 15–180 s). Outside all three, a back-rotation larger than 30 % is treated as real.

If your hardware sits on a slow KNX line or a Somfy IO/Tahoma bridge and overrides fire 30–90 seconds after a commanded move, widen that window. Full detail, including the diagnostic counter that tells you whether it is doing any work: Venetian Blinds β†’ Timeouts and manual-override detection.

Reading the diagnostics

Turn on Debug Mode β†’ Manual Override (Debug & Diagnostics) and reproduce. Every decision above is logged with its position values, threshold, and reason.

Event Meaning Usual fix
manual_override_set Override engaged. The reason field says which branch β€”
manual_override_gate_closed The Manual Override Detection switch is off Turn it on if you wanted detection
..._rejected_wait_for_target ACP is still waiting for the cover to arrive Normal during a commanded move
..._rejected_command_grace Within 5 s of an ACP command Normal
..._rejected_no_command_target No command on record and the position didn't move Normal after a restart
..._rejected_position_unavailable The cover reported no position Normal mid-transition
..._rejected_in_transit The cover says it is still moving Normal
..._rejected_primary_axis_suppression A late position republish was absorbed Widen the publish-lag window if genuine touches are being eaten
..._rejected_within_threshold The move was smaller than the threshold Lower the threshold if real moves are being missed
..._rejected_tilt_suppression A slat back-rotation was absorbed As above

A diagnostics download carries a manual_override_state block with the tracked covers and, for each held one, its start, end, and remaining seconds β€” plus manual_override_history, the full event timeline. primary_axis_suppression_last_24h counts how often the publish-lag guard fired, which is the fastest way to tell whether it is protecting you or hiding your touches.

Two overrides that never fire, and how to spot them. If detection seems dead, check the Manual Override Detection switch first (manual_override_gate_closed in the log) and "Only engage from ACP commands" second β€” the second one logs nothing at all, because the event is dropped before any decision is recorded.

Related pages

🏠 Home Β· ✨ Features Β· πŸ“° What's New

Buy Me A Coffee

πŸš€ Getting Started

🧠 Core Concepts

πŸ“ Cover Types

βš™οΈ Configuration

πŸ”Œ Entities & Services

πŸ› οΈ Operations

πŸ”§ Advanced Use Cases

🎨 Dashboard

πŸ§ͺ Testing & Simulation

πŸ“š Reference

πŸ‘©β€πŸ’» For Developers

Clone this wiki locally