Skip to content

feat(v1): expose clean-then-mop status from the device - #959

Open
klowdo wants to merge 1 commit into
Python-roborock:mainfrom
klowdo:feat/status-seq-type
Open

klowdo wants to merge 1 commit into
Python-roborock:mainfrom
klowdo:feat/status-seq-type

Conversation

@klowdo

@klowdo klowdo commented Sep 15, 2026

Copy link
Copy Markdown

Summary

The device reports seq_type in its get_status payload, but StatusV2 did not model it, so RoborockBase.from_dict discarded it along with every other unmatched key.

This adds seq_type to StatusV2 and a clean_then_mop property on StatusTrait reporting whether the current configuration vacuums each room fully before mopping it ("clean then mop" / "vacuum then mop").

Why it is get_status

The vendor Android app derives its own clean-then-mop state from the same field on the same payload. In the cloud-downloaded device plugin for roborock.vacuum.a288, parseCleanModeStatus does:

r6 = r1.seq_type;
r6 = 1 == r6;
r2['cleanThenMop'] = r6;

and its caller passes the status object — the same one it parses charge_status, wash_ready and kct from.

Verification

Tested against a Roborock Saros 20 (roborock.vacuum.a288). Raw get_status excerpt:

{"state": 8, "fan_power": 102, "water_box_mode": 235, "mop_mode": 300,
 "repeat": 1, "kct": 0, "subdivision_sets": 0, "seq_type": 0, ...}

Toggling "vacuum then mop" in the Roborock app, with the robot docked and idle (state: 8, in_cleaning: 0), flips the field and the new property follows it:

app setting seq_type clean_then_mop
vacuum and mop 0 False
vacuum then mop 1 True

So this is a persisted device setting that tracks the app, not merely a per-run artifact.

uv run pytest (1037 passed) and uv run pre-commit run --all-files both pass. One syrupy snapshot updated for the new field.

Notes and open questions

  • Read only, deliberately. I could not find a command that writes the global value. set_clean_motor_mode accepts seq_type and silently ignores it — sending seq_type: 0 returns ["ok"] while the device continues to report 1. If a maintainer knows the setter I am happy to add it.
  • There is also a per-room layer. get_customize_clean_mode returns seq_type and repeat per segment, e.g. [{"segment": 4, "fan_power": 102, "water_box_mode": 235, "mop_mode": 300, "repeat": 1, "seq_type": 0}]. This PR models only the global value from get_status; the per-room layer is left alone.
  • Single device. Verified on one Saros 20 only. The field is gated for reporting on is_clean_then_mop_mode_supported, so devices without the feature are unaffected, but I cannot confirm behaviour on other models.
  • get_status carries several other keys this library still drops (distance_off, cleaning_info, extra_time, monitor_status, exit_dock, pet_reminding, sub_error_code, sub_zone). Out of scope here, but happy to follow up if wanted.

Motivation

Downstream this lets Home Assistant expose clean-then-mop as real device state rather than guessing. Deliberately not folded into CleaningMode: the axes are independent — toggling clean-then-mop on the test device left current_cleaning_mode at vac_and_mop — and with no setter available a CleaningMode member would be readable but not selectable.

The device reports seq_type in its get_status payload, but StatusV2 did not
model it, so RoborockBase.from_dict discarded it along with every other
unmatched key. The vendor app reads the same field off the same payload to
derive its "clean then mop" state.

Add seq_type to StatusV2 and a clean_then_mop property on StatusTrait that
reports whether the current run vacuums each room fully before mopping it.
It describes the run in progress rather than a persisted setting, and the
device offers no setter, so it is read only here; the value travels outbound
as a parameter of the cleaning command instead.

Gated for reporting on is_clean_then_mop_mode_supported.

Verified against a Roborock Saros 20 (roborock.vacuum.a288).
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