Skip to content

fix(T2320): add X9 Pro mop controls and state decoding#467

Open
bdamokos wants to merge 16 commits into
damacus:mainfrom
bdamokos:fix/t2320-x9-pro-dps-mop-telemetry
Open

fix(T2320): add X9 Pro mop controls and state decoding#467
bdamokos wants to merge 16 commits into
damacus:mainfrom
bdamokos:fix/t2320-x9-pro-dps-mop-telemetry

Conversation

@bdamokos
Copy link
Copy Markdown
Contributor

@bdamokos bdamokos commented May 14, 2026

Summary

Adds focused support for the Eufy RoboVac X9 Pro / T2320 based on observed live DPS data.

This PR:

  • maps the observed T2320 DPS codes for battery, fan speed, status, mode, errors, locate, return/dock progress, and clean params
  • decodes X9 Pro base64/protobuf payloads for mode, dock/return progress, station status, clean params, errors, and warnings
  • exposes T2320 configuration entities for clean type, mop level, fan speed, and edge-hugging mopping
  • fixes HA activity reporting for dock prep, active cleaning, pause, return-to-dock, docked, washing, and drying states
  • keeps T2320 config entities scoped to T2320 only
  • avoids duplicating clean type as both a config entity and diagnostic sensor on T2320
  • adds a T2320 diagnostic warning sensor for non-fatal maintenance/station warnings from DPS 177
  • preserves clean-param state across partial DPS updates and avoids defaulting unread edge-mopping state
  • keeps DPS 168 out of room-clean handling and exposes it as T2320 consumable runtime diagnostics for side brush, rolling brush, filter, scraper/brush guard, sensor, and mop
  • adds T2320 room metadata support based on feat: Add T2320 room discovery from metadata DPS #419's DPS 165/cloud-fallback approach, plus selected-room support with the corrected DPS split: room commands are sent on DPS 152 and DPS 168 remains consumables
  • labels currently observed DPS 178 prompt codes 10, 12, and 17 generically; these prompts still need app-correlated semantic decoding

T2320 / X9 Pro DPS notes

Area Previous mapping/behavior X9 Pro behavior in this PR Notes
Battery DPS 172 DPS 163 X9 reports battery percentage on 163
Fan speed DPS 154 DPS 158 DPS 154 is clean/mop params on X9
Clean params Not exposed DPS 154 decoded and patched Clean type, mop level, edge-hugging mopping
Error DPS 169 DPS 177 field 2 DPS 169 is device info; DPS 177 carries errors/warnings
Warnings Not exposed separately DPS 177 field 3 diagnostic sensor Warning-only payloads do not force vacuum error
Locate DPS 153 DPS 160 DPS 153 is return/dock progress
Return/dock progress Not decoded DPS 153 decoded Distinguishes returning, dock prep, docked, and cleaning
Mode DPS 152 plain values DPS 152 base64/protobuf values X9 sends encoded mode payloads
Room metadata Not exposed on this PR branch DPS 165 decoded with cloud fallback Based on #419's room discovery approach
Selected-room commands Later follow-up room-clean experiments tried DPS 168+152 Commands sent as a DPS 152 ModeCtrlRequest Keeps DPS 168 reserved for consumables
Consumables Not exposed / previously confused with room clean on follow-up work DPS 168 diagnostic runtime sensors Values are consumed/used hours; dust bag omitted for T2320 because this model does not report it
Prompts Raw prompt_N fallback Observed DPS 178 codes 10/12/17 get generic labels Meanings still need decoding against app text
Station status DPS 173 raw DPS 173 decoded Includes washing/drying station states
Activity mapping Not set T2320-specific mapping Maps X9 states to HA vacuum activities

Exposed T2320 controls

Entity Values
Clean type select Sweep only, Mop only, Vacuum and mop
Mop level select Low, Middle, High
Fan speed select Quiet, Standard, Turbo, Max
Edge mopping switch On/off

Observed payloads

DPS 152 value Decoded mode
AA== standby
AggN pause
AggM stop
AggG return
BBoCCAE= auto
AggO auto / resume

Station status is decoded from DPS 173, including observed numeric station codes for washing and drying.

Edge-mopping writes use the app-observed DPS154 payload shape. App-side on/off changes and HA-side on/off writes were both verified against a live X9 Pro.

Testing

  • Focused T2320/DPS checks: 34 passed
  • flake8 custom_components tests
  • mypy --python-version 3.14 custom_components/robovac
  • Full pytest: 595 passed, plus the existing unrelated tests/test_config_flow.py::test_user_form_success teardown error from Tuya discovery opening blocked UDP sockets
  • Deployed to a live Home Assistant Docker instance with a T2320/X9 Pro
  • Verified start, dock prep, cleaning, pause, return-to-dock, docked state, mop level writes, edge mopping writes, app-side edge mopping changes, and warning decoding
  • Verified T2320 DPS 168 sensors populate from live data as used hours and that Dust Bag is not created for T2320

@bdamokos bdamokos force-pushed the fix/t2320-x9-pro-dps-mop-telemetry branch from a1e180c to e072078 Compare May 14, 2026 13:56
@bdamokos bdamokos marked this pull request as ready for review May 14, 2026 14:27
@bdamokos bdamokos force-pushed the fix/t2320-x9-pro-dps-mop-telemetry branch from a887f56 to 47239b6 Compare May 14, 2026 16:44
bdamokos added 3 commits May 14, 2026 18:50
DPS 168 is consumable telemetry on T2320, not room-clean metadata or commands. Add a focused regression assertion so future room work does not claim this DPS.
Based on damacus#419's DPS 165 room discovery and Tuya cloud fallback approach.

Adds selected-room support using DPS 152 ModeCtrlRequest payloads. Later room-clean experiments tried DPS 168 with DPS 152, but this branch keeps DPS 168 reserved for consumable telemetry.
@bdamokos bdamokos force-pushed the fix/t2320-x9-pro-dps-mop-telemetry branch from 47239b6 to 234a4ea Compare May 14, 2026 16:50
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds model-specific support for the Eufy RoboVac X9 Pro / T2320 by updating DPS mappings and introducing base64/protobuf decoding, plus new Home Assistant config entities to control mop/clean parameters and room targeting.

Changes:

  • Implement T2320 DPS remapping + base64/protobuf decoding for mode, station status, return/dock progress, errors/warnings, prompts, clean params, consumables, and room metadata.
  • Add T2320-specific configuration entities (selects + switch) for clean type, mop level, fan speed, edge-mopping, and a room selector; add warning + consumable diagnostics.
  • Update vacuum activity resolution to incorporate decoded mode/return-progress signals, and extend tests for the new behaviors/decoders.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
custom_components/robovac/init.py Enables the new SELECT and SWITCH platforms for config entities.
custom_components/robovac/proto_decode.py Adds protobuf encode/patch helpers; implements T2320 room-meta decode + room-clean mode payload build; enhances clean-param decode/merge.
custom_components/robovac/robovac.py Extends DPS-code extraction to include model-provided extra codes (e.g., room meta).
custom_components/robovac/vacuum.py Integrates new decoding/attributes (clean params, rooms); adds cloud room bootstrap; adjusts activity derivation; implements T2320 clean-param writes and room-clean payload handling.
custom_components/robovac/vacuums/T2320.py Defines T2320 DPS codes/commands, activity mapping, and model-specific DPS decoders for station/progress/errors/prompts.
custom_components/robovac/sensor.py Adds T2320 warning sensor and model-specific prompt decoding; makes consumables diagnostic and supports model-scoped consumable key sets; avoids duplicate clean-type sensor on config-entity models.
custom_components/robovac/select.py New config selects for fan speed, clean type, mop level, and room selection (T2320-scoped).
custom_components/robovac/switch.py New edge-mopping switch (T2320-scoped) that writes patched DPS 154.
tests/test_vacuum/test_config_entities.py Tests that T2320 exposes config entities and other models do not; ensures no duplicate clean-type sensor on T2320.
tests/test_vacuum/test_dps_command_mapping.py Updates T2320 DPS expectations (battery/error/fan/clean-param codes) and quiet-vs-pure display behavior.
tests/test_vacuum/test_proto_decode.py Adds coverage for clean-param merging/patching, T2320 consumables decode, room-meta decode, and room-clean payload building.
tests/test_vacuum/test_robovac.py Tests model-level extra DPS codes and T2320 consumables/room-clean code separation.
tests/test_vacuum/test_sensor.py Adds/updates tests for diagnostic categories, warning sensor behavior, and “No error” semantics.
tests/test_vacuum/test_t2320_command_mappings.py Updates/extends T2320 command mapping tests and adds decode tests for station/progress/errors/prompts.
tests/test_vacuum/test_vacuum_activity_lookup.py Adds tests for case-insensitive activity mapping lookup helper.
tests/test_vacuum/test_vacuum_commands.py Adds tests for T2320-specific pause/return payloads and clean-param patching behavior.
tests/test_vacuum/test_vacuum_entity.py Adds activity-resolution tests for mode-only/return-progress cases and fixes a fan-speed formatting expectation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread custom_components/robovac/vacuum.py
Comment thread custom_components/robovac/vacuums/T2320.py
Comment thread custom_components/robovac/switch.py Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 3 comments.

Comment thread custom_components/robovac/proto_decode.py Outdated
Comment thread custom_components/robovac/vacuum.py
Comment thread custom_components/robovac/select.py
@damacus damacus enabled auto-merge (squash) May 24, 2026 06:19
@damacus damacus disabled auto-merge May 24, 2026 06:19
@damacus damacus enabled auto-merge (squash) May 24, 2026 06:20
@bdamokos
Copy link
Copy Markdown
Contributor Author

Merging #484 should resolve the CI failure seen previously on this PR branch (tested locally)

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.

3 participants