Skip to content

fix: preserve water-slide codes in cleaning-mode commands and status - #961

Open
xiaoyaner0201 wants to merge 1 commit into
Python-roborock:mainfrom
xiaoyaner0201:fix/water-slide-cleaning-mode
Open

xiaoyaner0201 wants to merge 1 commit into
Python-roborock:mainfrom
xiaoyaner0201:fix/water-slide-cleaning-mode

Conversation

@xiaoyaner0201

Copy link
Copy Markdown

Summary

Refs #931 and #930. Thanks to @liborplisek for identifying the enum-alias root cause and @BlackRockCity for the command/status captures.

Bring the combined cleaning-mode paths into line with the existing feature-aware water-mode mapping:

  • Encode water-slide cleaning-mode commands using the device mapping's wire code, so vac_and_mop and mop emit 235 instead of the aliased member's legacy 202.
  • Resolve reported slide water codes through WATER_SLIDE_MODE_MAPPING when classifying cleaning mode. Keep the existing legacy-code fallback and direct enum-input behavior.
  • Correct existing tests that compared against PURE_WATER_FLOW_MIDDLE.code on both sides: those tests were passing with the same incorrect 202. Expected wire values now use explicit protocol integers.
  • Add public StatusTrait read/write regressions for all currently mapped slide intensities, vacuum/mop selection, optional mop-route fields, legacy codes, enum inputs, and incomplete/unknown status.

Compatibility and scope

This deliberately keeps the public enum values and user-facing option strings unchanged, so existing consumers using mode.value do not need a coordinated migration. It fixes the demonstrated combined-mode command/classification paths, not the standalone enum-alias representation: WaterModes.PURE_WATER_FLOW_MIDDLE.code and generic WaterModes.from_code_optional(235) are still affected. A broader unique-value/display-name migration remains separate, so this PR references rather than closes #931.

The water-flow range/label changes discussed in #801, other protocol families, Home Assistant automation policies, and login fixes are outside this PR.

Reproduction and hardware evidence

On a G30S Ultra with Home Assistant 2026.9.1 and python-roborock 7.2.3, a real status payload contained fan_power=102, water_box_mode=235, mop_mode=303. Individual settings decoded as balanced/medium/deep_plus, while the combined mode was None (HA unknown). An automation waiting for confirmed vac_and_mop stopped before sending its start command.

After applying the same feature-mapping read/write fix locally, the combined mode reported vac_and_mop, the outgoing combined-mode payload used 235, and the automation passed its setting check and started real cleaning. Direct device readback showed cleaning active, no error, and the expected motor settings; cleaning counters increased. The upstream change is tested independently against current main, not just the deployed library version.

Validation

Base: eac001c9d0a5eb45cd20e49033c37ff00054617f.

  • Regression RED on unchanged production behavior: 19 assertion failures / 79 tests, no collection errors. Failures include 202 != 235 and mode None versus mop/vac_and_mop.
  • GREEN: uv run pytest tests/devices/traits/v1/test_status.py -q79 passed.
  • uv run pre-commit run --all-files — passed, including Ruff, Mypy and Codespell.
  • uv build — source distribution and wheel built successfully.
  • Full candidate suite: 1355 passed, 53 xfailed, 1 failed; 92 snapshots passed.
  • The full suite also fails on the exact clean base with identical dependencies: 1317 passed, 53 xfailed, 1 failed. The failing test name and assertion message match exactly: tests/conformance/test_model_conformance.py::test_data_model_subclasses_roborock_base[roborock.data.b01_q10.b01_q10_containers.Q10RoborockPoint]. This pre-existing Q10 conformance failure is not changed, suppressed, or marked xfail by this PR.

No device/account credentials, raw diagnostic dumps, or deployment scripts are included.

@Lash-L

Lash-L commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

Hi thanks for the fix! Can we take it a step further? Right now, this will still fail for say 223. Can we resolve the value via the range? When the user selects a value - we can set it to an exact value. But if the user changes it in the app to one of the inbetween slider values, we could still display the closest category.

e.g.

Add a small feature-gated range resolver

Preserve the raw value 223.

Resolve its range (221–223) to "slight".

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.

WaterModes pure-water members collapse into StrEnum aliases, sending water code 202 to water-slide devices (-10005 Param error)

2 participants