Skip to content

Add StationErrorEvent for base station errors - #1854

Open
nau-tic wants to merge 1 commit into
DeebotUniverse:devfrom
nau-tic:feat/station-error-event
Open

nau-tic wants to merge 1 commit into
DeebotUniverse:devfrom
nau-tic:feat/station-error-event

Conversation

@nau-tic

@nau-tic nau-tic commented Oct 4, 2026

Copy link
Copy Markdown

Some docks report water-tank and other base-station faults on the station's own error channel rather than through ErrorEvent/getError. The library currently drops that field (OnStationState reads only state/content.type/content.motionState), so the signal is invisible to consumers.

This adds a dedicated StationErrorEvent carrying the error-code tuple, notified from the existing OnStationState handler. GetStationState subclasses it, so one event covers both the push and the poll. ErrorEvent is left untouched, so the two sources cannot clobber each other.

Details:

  • StationErrorEvent(errors: tuple[int, ...]); an empty tuple means the station reported an empty error list.
  • Emitted before the activity-state parse, so an unrecognised type/motionState cannot swallow a fault.
  • An absent, non-list, or wholly unusable error field is ignored (the last known value is preserved) rather than read as an all-clear; non-integer entries inside a list are skipped.
  • Optional CapabilityStation.error: CapabilityEvent[StationErrorEvent] | None, so a profile can declare its own refresh command. No profile is wired here — that follows separately, per the split-PR convention.

Evidence — DEEBOT X1 OMNI, class 1vxt52, model EINSTEIN_INT, UILogicId t10_ww_n_omni. While the clean tank was low, the robot error channel read 0 while the station channel reported 301 ("FreshWaterBox empty"); 314 is the expected "water/silver module not installed" on this container-based model, not a fault:

onStationState   "content":{"error":[301,314],"type":0},"state":0
getStationState  "content":{"error":[314],...}
getError         {"code":[0]}

Tests cover push and poll: [301,314], an empty list, an omitted field, an unrecognised activity state carrying errors, string codes, and non-list / all-unusable lists. tests/test_capabilities.py checks the new capability field is extractable as a refresh command.

Caveat: the poll path is unproven for this device — every captured getStationState returned [314], and the only 301 arrived on a push. Since the event is a replacement snapshot, a poll taken while the tank is low may be less informative; that needs a live capture before a consumer relies on polling. Nothing here wires a profile.

Related: #1808, home-assistant/core#181667.

Surface the base station's error codes (content.error on onStationState, shared by the getStationState poll) as a dedicated event. It is emitted before the activity-state parse so an unrecognised frame cannot swallow a fault, and an absent or unusable error field is ignored rather than treated as an all-clear.

Add an optional CapabilityStation.error field so a profile can declare the refresh command. Tests cover push and poll, an empty list, an omitted field, an unrecognised activity state, and mixed/unusable entries.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant