Repository navigation
Saros 10R: set_clean_motor_mode generates invalid Mop payload (-10005 Param error) #930
Description
Description
python-roborock appears to generate an incorrect set_clean_motor_mode payload when selecting Mop mode on a Roborock Saros 10R.
The generated command is rejected by the robot with:
code: -10005
message: Param error
I captured the command generated through the Home Assistant Roborock integration, compared it with the command sent by the official Roborock iOS app, and then independently tested the official-app parameters through vacuum.send_command.
The official-app parameters work successfully.
Environment
- Robot: Roborock Saros 10R
- Model:
roborock.vacuum.a144 - Firmware:
02.50.56 - Home Assistant:
2026.8.3 - Integration: Home Assistant Roborock integration /
python-roborock
Reproduction
Using the Home Assistant Roborock integration, the cleaning mode entity exposes:
vacuum
vac_and_mop
mop
Selecting mop results in SET_CLEAN_MOTOR_MODE being sent with:
[
{
"fan_power": 109,
"water_box_mode": 202,
"mop_mode": 300
}
]The Saros 10R rejects this payload:
{'code': -10005, 'message': 'Param error'}
This occurs both through the local connection and MQTT.
Official Roborock app behavior
I captured the RPC sent by the official Roborock iOS app when selecting Mop on the same robot.
The official app sends:
{
"method": "set_clean_motor_mode",
"params": [
{
"fan_power": 105,
"mop_mode": 300,
"water_box_mode": 225
}
]
}The robot accepts this command.
Independent verification
I then sent the official-app parameters directly through Home Assistant:
action: vacuum.send_command
target:
entity_id: vacuum.saros_10r
data:
command: set_clean_motor_mode
params:
- fan_power: 105
mop_mode: 300
water_box_mode: 225This succeeds.
The robot changes to Mop mode, and the official Roborock iOS app subsequently reflects Mop as the active cleaning mode.
This appears to rule out the robot, MQTT/local transport, and Home Assistant service call itself as the cause. The Saros 10R accepts set_clean_motor_mode; the issue appears to be the model-specific values being generated for that command.
Additional mode captures
For comparison, I captured the following commands from the official Roborock app on this Saros 10R:
| Mode | fan_power | mop_mode | water_box_mode |
|---|---|---|---|
| Vacuum | 102 | 300 | 200 |
| Vac + Mop | 102 | 300 | 225 |
| Mop | 105 | 300 | 225 |
Therefore the official app uses:
Vacuum
{
"fan_power": 102,
"mop_mode": 300,
"water_box_mode": 200
}Vacuum + Mop
{
"fan_power": 102,
"mop_mode": 300,
"water_box_mode": 225
}Mop
{
"fan_power": 105,
"mop_mode": 300,
"water_box_mode": 225
}All three were accepted when tested against the robot.
Cleaning mode state also becomes unknown
There appears to be a related state-decoding issue.
After sending the valid Mop command above, the robot is demonstrably in Mop mode and the official Roborock app displays Mop, but Home Assistant's:
select.saros_10r_cleaning_mode
reports:
unknown
So there may be two Saros 10R-specific problems:
- The library generates incorrect
set_clean_motor_modeparameters for Mop. - The resulting/actual Saros 10R cleaning-mode state is not correctly decoded back into the cleaning mode enum.
Related fourth cleaning mode
The Saros 10R also supports "Vacuum followed by Mop" / "Clean then mop."
That is being discussed separately in #914.
I captured that mode using a different RPC:
app_set_clean_sequence_type
and I added the protocol details to #914 rather than duplicate them here.
Expected behavior
Selecting Mop should cause the Saros 10R to receive the correct model-specific set_clean_motor_mode parameters and the cleaning-mode entity should subsequently report mop.
Actual behavior
python-roborock/Home Assistant sends:
{
"fan_power": 109,
"water_box_mode": 202,
"mop_mode": 300
}and the Saros 10R responds:
-10005 Param error
The official app instead sends:
{
"fan_power": 105,
"mop_mode": 300,
"water_box_mode": 225
}which the same robot accepts.
I can provide the full debug/local-server traces or perform additional command/state tests if useful.
Activity
liborplisek commentedon Aug 28, 2026
The
water_box_mode: 202part has a root cause, filed as #931.Four
WaterModesmembers share a value string with an earlier member, andStrEnumde-duplicates by value, so they silently become aliases carrying the earlier member's code:_get_default_mopping_water_mode()returnsPURE_WATER_FLOW_MIDDLEspecifically to avoid 202 (its comment says water-slide devices don't accept it), but the alias resolves toMEDIUM, whose code is 202.Two notes on your report, checked against a clean install of 7.1.1:
The
fan_power: 109looks already fixed. On 7.1.1get_mop_only_vacuum_mode()returnsVacuumModes.OFF(105), matching your app capture, so the payload is now{'fan_power': 105, 'water_box_mode': 202, 'mop_mode': 300}. The 109 in your report suggests an older version. The water code is still wrong.The
unknowncleaning-mode state has the same root cause.get_current_cleaning_mode()resolves the reported water code throughWaterModes.from_code_optional(), which returnsNonefor 225, 235, 248 and 250 — exactly the four collapsed codes — and the function then returnsNone:So after your successful manual command with
water_box_mode: 225, the state genuinely cannot be classified. That is not a separate Saros 10R decoding problem, it is the same aliasing.#931 has a reproduction and a patch that keeps the user-facing option strings unchanged.
BlackRockCity commentedon Aug 28, 2026
Thanks, this explains the behavior very clearly.
One clarification on my original report: I am currently on Home Assistant 2026.8.3. Since Home Assistant pins
python-roborock==7.1.1, thewater_box_modebehavior I am seeing is consistent with the aliasing bug described in #931.The earlier
fan_power: 109capture appears to be a separate historical difference. As you noted, a clean 7.1.1 install now producesfan_power: 105, which matches the official Roborock app capture on my Saros 10R.For the Saros 10R, the official app sends Mop as:
{ "fan_power": 105, "mop_mode": 300, "water_box_mode": 225 }and I independently verified that this payload succeeds.
The #931 explanation also accounts for the
unknowncleaning-mode state I observed after manually sending that valid command, becauseWaterModes.from_code_optional(225)cannot currently resolve the collapsed slide-water code.So I agree that the bad outgoing water mode and the
unknowndecoded state are manifestations of the sameWaterModesaliasing issue rather than two separate Saros 10R bugs.I also noted the Home Assistant follow-up in #931: once the enum members use unique internal values plus
display_name, HA's water select will need to usemode.display_namerather thanmode.value.Happy to retest the Saros 10R against the fix once it is available.