Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
487778a
feat(q7): add b01 map_content support
arduano Mar 15, 2026
68f41a4
refactor: make q7 scmap parsing declarative
arduano Mar 15, 2026
f8c069c
refactor: trim q7 map parser scope
arduano Mar 15, 2026
2d73fd1
refactor: restore declarative q7 scmap fields
arduano Mar 15, 2026
bedf379
feat: define checked-in proto for q7 scmap
arduano Mar 16, 2026
d638f6e
fix: pass q7 scmap lint checks
arduano Mar 16, 2026
34cebbd
fix: avoid extra mypy surface from protobuf stubs
arduano Mar 16, 2026
96c42ab
fix: scope mypy protobuf ignore to generated module
arduano Mar 16, 2026
1010ddb
fix: add protobuf stubs to mypy hook
arduano Mar 16, 2026
9f9c1b4
feat: Separate trait response handling logic from refresh logic and m…
allenporter Mar 16, 2026
b0fc1c7
4.23.0
Mar 16, 2026
08ca9aa
feat: Rename and reorder `YXFanLevel` enum members (#787)
allenporter Mar 16, 2026
312b7ac
4.24.0
Mar 16, 2026
19d7674
feat: Add `from_any_optional` method to `RoborockModeEnum` (#788)
allenporter Mar 16, 2026
a36a956
4.25.0
Mar 16, 2026
13170e2
Merge branch 'main' into leo/q7-map-content-followup
arduano Mar 17, 2026
91efb3b
feat: Q7 Get battery level (#790)
RaddedMC Mar 19, 2026
1ac5913
4.26.0
Mar 19, 2026
741fca6
refactor(q7): address maintainer review follow-ups
arduano Mar 19, 2026
2e5ede7
docs(q7): refresh protobuf regeneration note
arduano Mar 19, 2026
1bfc839
fix(ci): stop passing duplicate ruff exclude flag
arduano Mar 19, 2026
3259338
Merge branch 'main' into leo/q7-map-content-followup
arduano Mar 19, 2026
711f49e
chore: increase commit header maximum length to 200 (#789)
allenporter Mar 20, 2026
526da01
fix: add missing DPS fields to Q10Status and fix CLEAN_PROGRESS mappi…
lboue Mar 21, 2026
042fbed
4.26.1
Mar 21, 2026
66d76fc
fix(q10): add missing fault field to Q10Status (#792)
lboue Mar 21, 2026
dca91a0
4.26.2
Mar 21, 2026
dce00a2
Harmonizes Q10 status names in `python-roborock` to canonical values …
lboue Mar 22, 2026
0c2c781
4.26.3
Mar 22, 2026
c630022
feat(api)!: rename `YXWaterLevel` enum values to mirror v1 values (#796)
allenporter Mar 22, 2026
ad3ceea
feat(api)!: Again rename `YXDeviceState` enum members to have consist…
allenporter Mar 22, 2026
7baeb65
Q10: use readable YXCleanType values (vac_and_mop / vacuum / mop) (#794)
lboue Mar 22, 2026
44ee75e
5.0.0
Mar 22, 2026
d762649
chore: Migrate to typing.Self and remove __future__ annotations. (#798)
allenporter Mar 23, 2026
99a63e6
refactor(q7): use generated protobuf message types
arduano Mar 23, 2026
8611c2b
Merge branch 'main' into leo/q7-map-content-followup
arduano Mar 23, 2026
f9efa68
refactor(q7): remove intermediate SCMap mapping layer
arduano Mar 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
exclude: "CHANGELOG.md"
exclude: >
(?x)^(
CHANGELOG\.md|
roborock/map/proto/.*_pb2\.py
)$
default_stages: [ pre-commit ]

repos:
Expand Down Expand Up @@ -42,7 +46,7 @@ repos:
hooks:
- id: mypy
exclude: cli.py
additional_dependencies: [ "types-paho-mqtt" ]
additional_dependencies: [ "types-paho-mqtt", "types-protobuf" ]
- repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook
rev: v9.23.0
hooks:
Expand Down
200 changes: 200 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,206 @@

<!-- version list -->

## v5.0.0 (2026-03-22)

### Bug Fixes

- **cli**: Make clean mode option case insensitive
([#794](https://github.com/Python-roborock/python-roborock/pull/794),
[`7baeb65`](https://github.com/Python-roborock/python-roborock/commit/7baeb658fd80b40bfb631dc250b899e659e20210))

- **q10**: Restrict clean mode cli choices
([#794](https://github.com/Python-roborock/python-roborock/pull/794),
[`7baeb65`](https://github.com/Python-roborock/python-roborock/commit/7baeb658fd80b40bfb631dc250b899e659e20210))

### Features

- **api**: Again rename `YXDeviceState` enum members to have consistency with V1 state values
([#795](https://github.com/Python-roborock/python-roborock/pull/795),
[`ad3ceea`](https://github.com/Python-roborock/python-roborock/commit/ad3ceeaea6f1b12dc51513c48476bcdf2756392b))

- **api**: Rename `YXWaterLevel` enum values to mirror v1 values
([#796](https://github.com/Python-roborock/python-roborock/pull/796),
[`c630022`](https://github.com/Python-roborock/python-roborock/commit/c63002264e40beb0f6e51281afd90e10e7b731cc))

### Refactoring

- **q10**: Use readable YXCleanType values with legacy aliases
([#794](https://github.com/Python-roborock/python-roborock/pull/794),
[`7baeb65`](https://github.com/Python-roborock/python-roborock/commit/7baeb658fd80b40bfb631dc250b899e659e20210))

- **YXCleanType**: Move legacy values to a separate dictionary and update from_value method
([#794](https://github.com/Python-roborock/python-roborock/pull/794),
[`7baeb65`](https://github.com/Python-roborock/python-roborock/commit/7baeb658fd80b40bfb631dc250b899e659e20210))

- **YXCleanType**: Remove legacy test for readable public values
([#794](https://github.com/Python-roborock/python-roborock/pull/794),
[`7baeb65`](https://github.com/Python-roborock/python-roborock/commit/7baeb658fd80b40bfb631dc250b899e659e20210))

- **YXCleanType**: Simplify clean type definitions and remove legacy alias support
([#794](https://github.com/Python-roborock/python-roborock/pull/794),
[`7baeb65`](https://github.com/Python-roborock/python-roborock/commit/7baeb658fd80b40bfb631dc250b899e659e20210))


## v4.26.3 (2026-03-22)

### Bug Fixes

- **q10**: Add tests for Q10 status values and code mappings
([#793](https://github.com/Python-roborock/python-roborock/pull/793),
[`dce00a2`](https://github.com/Python-roborock/python-roborock/commit/dce00a2499c3976f1cd25239bc4f81d996d51a79))

- **q10**: Normalize status names to canonical values
([#793](https://github.com/Python-roborock/python-roborock/pull/793),
[`dce00a2`](https://github.com/Python-roborock/python-roborock/commit/dce00a2499c3976f1cd25239bc4f81d996d51a79))

- **q10**: Normalize YXDeviceState status names to canonical values
([#793](https://github.com/Python-roborock/python-roborock/pull/793),
[`dce00a2`](https://github.com/Python-roborock/python-roborock/commit/dce00a2499c3976f1cd25239bc4f81d996d51a79))

- **q10**: Refactor test for canonical status names using a dictionary
([#793](https://github.com/Python-roborock/python-roborock/pull/793),
[`dce00a2`](https://github.com/Python-roborock/python-roborock/commit/dce00a2499c3976f1cd25239bc4f81d996d51a79))


## v4.26.2 (2026-03-21)

### Bug Fixes

- **q10**: Add missing fault field to Q10Status
([#792](https://github.com/Python-roborock/python-roborock/pull/792),
[`66d76fc`](https://github.com/Python-roborock/python-roborock/commit/66d76fc9b3cd6d6d15f5883bfa8a22c688d9b960))


## v4.26.1 (2026-03-21)

### Bug Fixes

- Add missing DPS fields to Q10Status and fix CLEAN_PROGRESS mapping
([#791](https://github.com/Python-roborock/python-roborock/pull/791),
[`526da01`](https://github.com/Python-roborock/python-roborock/commit/526da01d02f6b52cab3674145273448eb602620e))

- Correct comment for fan level in test_status_trait_refresh
([#791](https://github.com/Python-roborock/python-roborock/pull/791),
[`526da01`](https://github.com/Python-roborock/python-roborock/commit/526da01d02f6b52cab3674145273448eb602620e))

### Chores

- Disable commitlint rules for header max length and header full stop.
([#789](https://github.com/Python-roborock/python-roborock/pull/789),
[`711f49e`](https://github.com/Python-roborock/python-roborock/commit/711f49e9a6e4d7fc964b164c7f23265979aa166b))

- Increase commit header maximum length to 200
([#789](https://github.com/Python-roborock/python-roborock/pull/789),
[`711f49e`](https://github.com/Python-roborock/python-roborock/commit/711f49e9a6e4d7fc964b164c7f23265979aa166b))

- Increase commit header maximum length to 200 in commitlint configuration.
([#789](https://github.com/Python-roborock/python-roborock/pull/789),
[`711f49e`](https://github.com/Python-roborock/python-roborock/commit/711f49e9a6e4d7fc964b164c7f23265979aa166b))


## v4.26.0 (2026-03-19)

### Features

- Q7 Get battery level ([#790](https://github.com/Python-roborock/python-roborock/pull/790),
[`91efb3b`](https://github.com/Python-roborock/python-roborock/commit/91efb3b0be3122490c362a8e2ecc1192bb98bee6))


## v4.25.0 (2026-03-16)

### Chores

- Apply suggestions from code review
([#788](https://github.com/Python-roborock/python-roborock/pull/788),
[`19d7674`](https://github.com/Python-roborock/python-roborock/commit/19d7674cbf98dcf1ba591d1bf71f87b370a90a55))

### Features

- Add `from_any_optional` method to `CodeMapping` for flexible enum resolution with corresponding
tests. ([#788](https://github.com/Python-roborock/python-roborock/pull/788),
[`19d7674`](https://github.com/Python-roborock/python-roborock/commit/19d7674cbf98dcf1ba591d1bf71f87b370a90a55))

- Add `from_any_optional` method to `RoborockModeEnum`
([#788](https://github.com/Python-roborock/python-roborock/pull/788),
[`19d7674`](https://github.com/Python-roborock/python-roborock/commit/19d7674cbf98dcf1ba591d1bf71f87b370a90a55))

### Refactoring

- Simplify B01_Q10 command parsing by removing a helper function and utilizing `from_any_optional`.
([#788](https://github.com/Python-roborock/python-roborock/pull/788),
[`19d7674`](https://github.com/Python-roborock/python-roborock/commit/19d7674cbf98dcf1ba591d1bf71f87b370a90a55))


## v4.24.0 (2026-03-16)

### Chores

- Fix lint. ([#787](https://github.com/Python-roborock/python-roborock/pull/787),
[`08ca9aa`](https://github.com/Python-roborock/python-roborock/commit/08ca9aa2f9dfb85f41e427d62c3ef189d3a48727))

- Fix MAX_PLUS enum value ([#787](https://github.com/Python-roborock/python-roborock/pull/787),
[`08ca9aa`](https://github.com/Python-roborock/python-roborock/commit/08ca9aa2f9dfb85f41e427d62c3ef189d3a48727))

- Rename and reorder `YXFanLevel` enum members
([#787](https://github.com/Python-roborock/python-roborock/pull/787),
[`08ca9aa`](https://github.com/Python-roborock/python-roborock/commit/08ca9aa2f9dfb85f41e427d62c3ef189d3a48727))

### Documentation

- Add docstring and alias comments to the YXFanLevel enum.
([#787](https://github.com/Python-roborock/python-roborock/pull/787),
[`08ca9aa`](https://github.com/Python-roborock/python-roborock/commit/08ca9aa2f9dfb85f41e427d62c3ef189d3a48727))

### Features

- Rename and reorder `YXFanLevel` enum members
([#787](https://github.com/Python-roborock/python-roborock/pull/787),
[`08ca9aa`](https://github.com/Python-roborock/python-roborock/commit/08ca9aa2f9dfb85f41e427d62c3ef189d3a48727))


## v4.23.0 (2026-03-16)

### Chores

- Remove duplicate V1TraitDataConverter
([#783](https://github.com/Python-roborock/python-roborock/pull/783),
[`9f9c1b4`](https://github.com/Python-roborock/python-roborock/commit/9f9c1b4b9271a6a63a0dbe6afd21216b13a15648))

- Remove unused `typing.Self` import.
([#783](https://github.com/Python-roborock/python-roborock/pull/783),
[`9f9c1b4`](https://github.com/Python-roborock/python-roborock/commit/9f9c1b4b9271a6a63a0dbe6afd21216b13a15648))

### Documentation

- Clarify internal usage of V1TraitDataConverter and V1TraitMixin attributes.
([#783](https://github.com/Python-roborock/python-roborock/pull/783),
[`9f9c1b4`](https://github.com/Python-roborock/python-roborock/commit/9f9c1b4b9271a6a63a0dbe6afd21216b13a15648))

### Features

- Separate trait response handling logic from refresh logic and merge
([#783](https://github.com/Python-roborock/python-roborock/pull/783),
[`9f9c1b4`](https://github.com/Python-roborock/python-roborock/commit/9f9c1b4b9271a6a63a0dbe6afd21216b13a15648))

- Simplify V1 trait handling ([#783](https://github.com/Python-roborock/python-roborock/pull/783),
[`9f9c1b4`](https://github.com/Python-roborock/python-roborock/commit/9f9c1b4b9271a6a63a0dbe6afd21216b13a15648))

### Refactoring

- Make V1TraitDataConverter an abstract base class, use a dedicated LedStatusConverter, and fix a
typo in Rooms. ([#783](https://github.com/Python-roborock/python-roborock/pull/783),
[`9f9c1b4`](https://github.com/Python-roborock/python-roborock/commit/9f9c1b4b9271a6a63a0dbe6afd21216b13a15648))

- Remove trait update listeners and centralize data conversion into dedicated converter classes
([#783](https://github.com/Python-roborock/python-roborock/pull/783),
[`9f9c1b4`](https://github.com/Python-roborock/python-roborock/commit/9f9c1b4b9271a6a63a0dbe6afd21216b13a15648))

- Standardize trait data merging to `merge_trait_values` and remove direct `_parse_response` methods
from traits. ([#783](https://github.com/Python-roborock/python-roborock/pull/783),
[`9f9c1b4`](https://github.com/Python-roborock/python-roborock/commit/9f9c1b4b9271a6a63a0dbe6afd21216b13a15648))


## v4.22.0 (2026-03-14)

### Features
Expand Down
6 changes: 5 additions & 1 deletion commitlint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ export default {
// Disable the rule that enforces lowercase in subject
"subject-case": [0], // 0 = disable, 1 = warn, 2 = error
// Disable the rule that enforces a maximum line length in the body
"body-max-line-length": [0, "always"]
"body-max-line-length": [0, "always"],
// Disable header max length for AI-generated commits
"header-max-length": [0],
// Disable the rule that prevents periods at the end of subjects
"header-full-stop": [0]
},

};
9 changes: 8 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "python-roborock"
version = "4.22.0"
version = "5.0.0"
description = "A package to control Roborock vacuums."
authors = [{ name = "humbertogontijo", email = "humbertogontijo@users.noreply.github.com" }, {name="Lash-L"}, {name="allenporter"}]
requires-python = ">=3.11, <4"
Expand All @@ -25,6 +25,7 @@ dependencies = [
"pycryptodomex~=3.18 ; sys_platform == 'darwin'",
"paho-mqtt>=1.6.1,<3.0.0",
"construct>=2.10.57,<3",
"protobuf>=5,<7",
"vacuum-map-parser-roborock",
"pyrate-limiter>=4.0.0,<5",
"aiomqtt>=2.5.0,<3",
Expand Down Expand Up @@ -97,9 +98,15 @@ major_tags= ["refactor"]
lint.ignore = ["F403", "E741"]
lint.select=["E", "F", "UP", "I"]
line-length = 120
extend-exclude = ["roborock/map/proto/*_pb2.py"]

[tool.ruff.lint.per-file-ignores]
"*/__init__.py" = ["F401"]
"roborock/map/proto/*_pb2.py" = ["E501", "I001", "UP009"]

[[tool.mypy.overrides]]
module = ["roborock.map.proto.*"]
ignore_errors = true

[tool.pytest.ini_options]
asyncio_mode = "auto"
Expand Down
2 changes: 0 additions & 2 deletions roborock/broadcast_protocol.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from __future__ import annotations

import asyncio
import hashlib
import json
Expand Down
25 changes: 8 additions & 17 deletions roborock/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -764,21 +764,6 @@ async def network_info(ctx, device_id: str):
await _display_v1_trait(context, device_id, lambda v1: v1.network_info)


def _parse_b01_q10_command(cmd: str) -> B01_Q10_DP:
"""Parse B01_Q10 command from either enum name or value."""
try:
return B01_Q10_DP(int(cmd))
except ValueError:
try:
return B01_Q10_DP.from_name(cmd)
except ValueError:
try:
return B01_Q10_DP.from_value(cmd)
except ValueError:
pass
raise RoborockException(f"Invalid command {cmd} for B01_Q10 device")


@click.command()
@click.option("--device_id", required=True)
@click.option("--cmd", required=True)
Expand All @@ -795,7 +780,8 @@ async def command(ctx, cmd, device_id, params):
if result:
click.echo(dump_json(result))
elif device.b01_q10_properties is not None:
cmd_value = _parse_b01_q10_command(cmd)
if cmd_value := B01_Q10_DP.from_any_optional(cmd) is None:
raise RoborockException(f"Invalid command {cmd} for B01_Q10 device")
command_trait: Trait = device.b01_q10_properties.command
await command_trait.send(cmd_value, json.loads(params) if params is not None else None)
click.echo("Command sent successfully; Enable debug logging (-d) to see responses.")
Expand Down Expand Up @@ -1289,7 +1275,12 @@ async def q10_empty_dustbin(ctx: click.Context, device_id: str) -> None:

@session.command()
@click.option("--device_id", required=True, help="Device ID")
@click.option("--mode", required=True, type=click.Choice(["bothwork", "onlysweep", "onlymop"]), help="Clean mode")
@click.option(
"--mode",
required=True,
type=click.Choice(["vac_and_mop", "vacuum", "mop"], case_sensitive=False),
help='Clean mode (preferred: "vac_and_mop", "vacuum", "mop")',
)
@click.pass_context
@async_command
async def q10_set_clean_mode(ctx: click.Context, device_id: str, mode: str) -> None:
Expand Down
Loading