Ignore stale moving operational status for position aware Matter covers - #177571
Draft
agners wants to merge 2 commits into
Draft
Ignore stale moving operational status for position aware Matter covers#177571agners wants to merge 2 commits into
agners wants to merge 2 commits into
Conversation
Some devices report attribute changes which make up a single logical state change as separate attribute updates shortly after each other, e.g. Eve MotionBlinds report OperationalStatus stopped before the final CurrentPositionLiftPercent100ths value. Writing the entity state on each individual update publishes an intermittent state (e.g. stopped at 1% open followed by closed), causing state change automations to trigger twice. Add opt-in state write debouncing to the Matter entity base class and enable it for covers, which derive their state from both the operational status and the current position attributes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Some devices deliver a single Matter report containing a moving WindowCovering OperationalStatus together with the final positions (current position already at target), without a subsequent report clearing the moving state. The Matter Server WebSocket API additionally splits attribute updates from a single Matter report into separate per-attribute events, which the integration processes individually. As a result the cover entity can get stuck in an opening/closing state. Per the Matter specification, position aware covers must expose target position attributes which reflect the requested position, while the current position attributes always reflect the physical position. Use this to gate the moving state: a covering whose current position(s) match the target position(s) is not moving, regardless of what the operational status claims. When positions are unavailable or unknown (non position aware covers, null values), the operational status remains authoritative, as before. Also add debug logging stating which movement detection mode is in use. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
|
Hey there @home-assistant/matter, mind taking a look at this pull request as it has been labeled with an integration ( Code owner commandsCode owners of
|
Contributor
There was a problem hiding this comment.
Pull request overview
Prevents position-aware Matter covers from remaining stuck in a moving state when current and target positions match.
Changes:
- Ignores stale moving operational status at the target position.
- Debounces cover state writes to coalesce split updates.
- Adds coverage for stale, unknown, and split attribute updates.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
homeassistant/components/matter/entity.py |
Adds opt-in state-write debouncing. |
homeassistant/components/matter/cover.py |
Compares target/current positions and subscribes to target updates. |
tests/components/matter/test_cover.py |
Tests debouncing and movement-state handling. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Breaking change
Proposed change
Note: stacked on #177540, the first commit belongs to that PR.
Ignore a stale moving
OperationalStatusfor position aware Matter covers: a covering whose current position(s) match the target position(s) is not moving, regardless of what the operational status claims.Some devices deliver a single Matter report containing a moving
OperationalStatustogether with the final positions (current position already at target), without a subsequent report clearing the moving state. This has been observed with Rademacher shutters behind a Matter bridge (see home-assistant/addons#4724, server debug log analysis): the onlyOperationalStatusreports in a 2 hour debug log arrived together withTargetPositionLiftPercent100ths=CurrentPositionLiftPercent100ths= 10000, claiming "closing" while the device was provably stationary at its target. Since the integration derivesis_opening/is_closingsolely fromOperationalStatus, the cover entity remained stuck in a closing state until the Matter Server was restarted.The Matter specification provides the tools to detect this: for position aware covers the target position attributes are mandatory alongside the current position attributes (identical conformance,
LF & PA_LFresp.TL & PA_TL), the target position "SHALL reflect the requested position" (set upon command receipt, and set to the current position byStopMotion), and the current position "SHALL always reflect the physical position" (section 5.3.4.3). A covering resting at its target is therefore not moving.The check is deliberately asymmetric: position/target equality only ever forces the moving state off, a position/target mismatch never forces it on. Real-world target values cannot be fully trusted, e.g. the
mock_window_covering_pa_liftfixture (a diagnostics dump of a real Eliteu/Longan Link WNCV-DA01) rests withTargetPositionLiftPercent100ths= 0 whileCurrentPositionLiftPercent100ths= 4900. With this polarity a bogus target can at most fail to unstick a broken cover, but can never wedge a healthy one into a moving state.When the positions cannot be compared (non position aware covers, null values, missing target attribute), the operational status remains authoritative, as before. Debug logging now states which movement detection mode is in use for each update.
Minor behavior change for spec-compliant devices: when the final position report (current = target) arrives before the report clearing the operational status, the cover now shows the final state immediately instead of remaining in a moving state until the status clears (observed up to ~800 ms with Eve MotionBlinds).
The target position attributes are added as
optional_attributesto the position aware discovery schemas so the entities subscribe to their updates; discovery matching is unchanged.Type of change
Additional information
Checklist
ruff format homeassistant tests)If user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
Updated and included derived files by running:
python3 -m script.hassfest.requirements_all.txt.Updated by running
python3 -m script.gen_requirements_all.To help with the load of incoming pull requests: