Skip to content

Commit d01287a

Browse files
authored
Improve library user documentation (#685)
* chore: Improve library user documentation Update the documentation to answer basic questions from a first time library user perspective. Given the deeper submodules, it may be harder to find so we add details so users can understand the bigger picture. Some existing documentation was focused more on design details for deeper implementation issues, so this clarifies what is lower level vs higher level. * chore: fix typo in README.md
1 parent c576d5f commit d01287a

File tree

7 files changed

+149
-37
lines changed

7 files changed

+149
-37
lines changed

README.md

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ Install this via pip (or your favourite package manager):
2020

2121
`pip install python-roborock`
2222

23-
## Functionality
23+
## Example Usage
2424

25-
You can see all of the commands supported [here](https://python-roborock.readthedocs.io/en/latest/api_commands.html)
25+
See [examples/example.py](examples/example.py) for a more full featured example,
26+
or the [API documentation](https://python-roborock.github.io/python-roborock/)
27+
for more details.
2628

27-
## Example Usage
29+
Here is a basic example:
2830

2931
```python
3032
import asyncio
@@ -34,38 +36,45 @@ from roborock.devices.device_manager import create_device_manager, UserParams
3436

3537

3638
async def main():
37-
web_api = RoborockApiClient(username="youremailhere")
38-
# Login via your password
39-
user_data = await web_api.pass_login(password="pass_here")
40-
# Or login via a code
39+
email_address = "youremailhere@example.com"
40+
web_api = RoborockApiClient(username=email_address)
41+
# Send a login code to the above email address
4142
await web_api.request_code()
43+
# Prompt the user to enter the code
4244
code = input("What is the code?")
4345
user_data = await web_api.code_login(code)
4446

4547
# Create a device manager that can discover devices.
46-
user_params = UserParams(
47-
username="youremailhere",
48-
user_data=user_data,
49-
)
48+
user_params = UserParams(username=email_address, user_data=user_data)
5049
device_manager = await create_device_manager(user_params)
5150
devices = await device_manager.get_devices()
5251

53-
# Get all vacuum devices that support the v1 PropertiesApi
52+
# Get all vacuum devices. Each device generation has different capabilities
53+
# and APIs available so to find vacuums we filter by the v1 PropertiesApi.
5454
for device in devices:
5555
if not device.v1_properties:
5656
continue
5757

58-
# Refresh the current device status
58+
# The PropertiesAPI has traits different device commands such as getting
59+
# status, sending clean commands, etc. For this example we send a
60+
# command to refresh the current device status.
5961
status_trait = device.v1_properties.status
6062
await status_trait.refresh()
6163
print(status_trait)
6264

6365
asyncio.run(main())
6466
```
6567

66-
See [examples/example.py](examples/example.py) for a more full featured example
67-
that has performance improvements to cache cloud information to prefer
68-
connections over the local network.
68+
69+
## Functionality
70+
71+
The library interacts with devices through specific API properties based on the device protocol:
72+
73+
* **Standard Vacuums (V1 Protocol)**: Most robot vacuums use this. Interaction is done through `device.v1_properties`, which contains traits like `status`, `consumables`, and `maps`. Use the `command` trait for actions like starting or stopping cleaning.
74+
* **Wet/Dry Vacuums & Washing Machines (A01 Protocol)**: Devices like the Dyad and Zeo use this. Interaction is done through `device.a01_properties` using `query_values()` and `set_value()`.
75+
76+
You can find detailed documentation for [Devices](https://python-roborock.github.io/python-roborock/roborock/devices/device.html) and [Traits](https://python-roborock.github.io/python-roborock/roborock/devices/traits.html).
77+
6978

7079
## Supported devices
7180

@@ -74,6 +83,7 @@ You can find what devices are supported
7483
Please note this may not immediately contain the latest devices.
7584

7685

77-
## Credits
86+
## Acknowledgements
7887

79-
Thanks @rovo89 for https://gist.github.com/rovo89/dff47ed19fca0dfdda77503e66c2b7c7 And thanks @PiotrMachowski for https://github.com/PiotrMachowski/Home-Assistant-custom-components-Xiaomi-Cloud-Map-Extractor
88+
* Thanks to [@rovo89](https://github.com/rovo89) for [Login APIs gist](https://gist.github.com/rovo89/dff47ed19fca0dfdda77503e66c2b7c7).
89+
* Thanks to [@PiotrMachowski](https://github.com/PiotrMachowski) for [Home-Assistant-custom-components-Xiaomi-Cloud-Map-Extractor](https://github.com/PiotrMachowski/Home-Assistant-custom-components-Xiaomi-Cloud-Map-Extractor).

roborock/devices/README.md

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,19 @@ The devices module provides functionality to discover Roborock devices on the
44
network. This section documents the full lifecycle of device discovery across
55
Cloud and Network.
66

7-
## Quick Start: Understanding Device Protocols
7+
## Usage TL;DR
8+
9+
* **Discovery**: Use `roborock.devices.device_manager.DeviceManager` to get device instances.
10+
* Call `create_device_manager(user_params)` then `await device_manager.get_devices()`.
11+
* **Control**:
12+
* **Vacuums (V1)**: Use `device.v1_properties` to access traits like `status` or `consumables`.
13+
* Call `await trait.refresh()` to update state.
14+
* Use `device.v1_properties.command.send()` for raw commands (start/stop).
15+
* **Washers (A01)**: Use `device.a01_properties` for Dyad/Zeo devices.
16+
* Use `await device.a01_properties.query_values([...])` to get state.
17+
* Use `await device.a01_properties.set_value(protocol, value)` to control.
18+
19+
## Background: Understanding Device Protocols
820

921
**The library supports three device protocol versions, each with different capabilities:**
1022

@@ -18,7 +30,7 @@ Cloud and Network.
1830

1931
**Key Point:** The `DeviceManager` automatically detects the protocol version and creates the appropriate channel type. You don't need to handle this manually.
2032

21-
## Architecture Overview
33+
## Internal Architecture
2234

2335
The library is organized into distinct layers, each with a specific responsibility. **Different device protocols use different channel implementations:**
2436

@@ -138,7 +150,7 @@ graph TB
138150
| **A01** (`pv=A01`) | `MqttChannel` + helpers | ❌ No | Direct MQTT | Dyad, Zeo washers |
139151
| **B01** (`pv=B01`) | `MqttChannel` + helpers | ❌ No | Direct MQTT | Some newer models |
140152

141-
## Init account setup
153+
## Account Setup Internals
142154

143155
### Login
144156

@@ -151,7 +163,7 @@ graph TB
151163
- This contains information used to connect to MQTT
152164
- You get an `-eu` suffix in the API URLs if you are in the eu and `-us` if you are in the us
153165

154-
## Home Data
166+
## Home Data Internals
155167

156168
The `HomeData` includes information about the various devices in the home. We use `v3`
157169
and it is notable that if devices don't show up in the `home_data` response it is likely
@@ -174,7 +186,7 @@ that a newer version of the API should be used.
174186
- There is another REST request `get_rooms` that will do the same thing.
175187
- Note: If we cache home_data, we likely need to use `get_rooms` to get rooms fresh
176188

177-
## Device Connections
189+
## Connection Implementation
178190

179191
### Connection Flow by Protocol
180192

@@ -343,7 +355,7 @@ graph LR
343355
3. **Timeout Handling**: Commands timeout after 10 seconds if no response is received
344356
4. **Multiple Strategies**: `V1Channel` tries local first, then falls back to MQTT if local fails
345357

346-
## Design
358+
## Class Design & Components
347359

348360
### Current Architecture
349361

roborock/devices/traits/__init__.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
1-
"""Module for device traits."""
1+
"""Module for device traits.
2+
3+
This package contains the trait definitions for different device protocols supported
4+
by Roborock devices.
5+
6+
Submodules
7+
----------
8+
* `v1`: Contains traits for standard Roborock vacuums (e.g., S-series, Q-series).
9+
These devices use the V1 protocol and have rich feature sets split into
10+
granular traits (e.g., `StatusTrait`, `ConsumableTrait`).
11+
* `a01`: Contains APIs for A01 protocol devices, such as the Dyad (wet/dry vacuum)
12+
and Zeo (washing machine). These devices use a different communication structure.
13+
* `b01`: Contains APIs for B01 protocol devices.
14+
"""
215

316
from abc import ABC
417

roborock/devices/traits/a01/__init__.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,24 @@
1+
"""Create traits for A01 devices.
2+
3+
This module provides the API implementations for A01 protocol devices, which include
4+
Dyad (Wet/Dry Vacuums) and Zeo (Washing Machines).
5+
6+
Using A01 APIs
7+
--------------
8+
A01 devices expose a single API object that handles all device interactions. This API is
9+
available on the device instance (typically via `device.a01_properties`).
10+
11+
The API provides two main methods:
12+
1. **query_values(protocols)**: Fetches current state for specific data points.
13+
You must pass a list of protocol enums (e.g. `RoborockDyadDataProtocol` or
14+
`RoborockZeoProtocol`) to request specific data.
15+
2. **set_value(protocol, value)**: Sends a command to the device to change a setting
16+
or perform an action.
17+
18+
Note that these APIs fetch data directly from the device upon request and do not
19+
cache state internally.
20+
"""
21+
122
import json
223
from collections.abc import Callable
324
from datetime import time

roborock/devices/traits/v1/__init__.py

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,33 @@
22
33
Traits are modular components that encapsulate specific features of a Roborock
44
device. This module provides a factory function to create and initialize the
5-
appropriate traits for V1 devices based on their capabilities. They can also
6-
be considered groups of commands and parsing logic for that command.
7-
8-
Traits have a `refresh()` method that can be called to update their state
9-
from the device. Some traits may also provide additional methods for modifying
10-
the device state.
11-
12-
The most common pattern for a trait is to subclass `V1TraitMixin` and a `RoborockBase`
13-
dataclass, and define a `command` class variable that specifies the `RoborockCommand`
14-
used to fetch the trait data from the device. See `common.py` for more details
15-
on common patterns used across traits.
5+
appropriate traits for V1 devices based on their capabilities.
6+
7+
Using Traits
8+
------------
9+
Traits are accessed via the `v1_properties` attribute on a device. Each trait
10+
represents a specific capability, such as `status`, `consumables`, or `rooms`.
11+
12+
Traits serve two main purposes:
13+
1. **State**: Traits are dataclasses that hold the current state of the device
14+
feature. You can access attributes directly (e.g., `device.v1_properties.status.battery`).
15+
2. **Commands**: Traits provide methods to control the device. For example,
16+
`device.v1_properties.volume.set_volume()`.
17+
18+
Additionally, the `command` trait provides a generic way to send any command to the
19+
device (e.g. `device.v1_properties.command.send("app_start")`). This is often used
20+
for basic cleaning operations like starting, stopping, or docking the vacuum.
21+
22+
Most traits have a `refresh()` method that must be called to update their state
23+
from the device. The state is not updated automatically in real-time unless
24+
specifically implemented by the trait or via polling.
25+
26+
Adding New Traits
27+
-----------------
28+
When adding a new trait, the most common pattern is to subclass `V1TraitMixin`
29+
and a `RoborockBase` dataclass. You must define a `command` class variable that
30+
specifies the `RoborockCommand` used to fetch the trait data from the device.
31+
See `common.py` for more details on common patterns used across traits.
1632
1733
There are some additional decorators in `common.py` that can be used to specify which
1834
RPC channel to use for the trait (standard, MQTT/cloud, or map-specific).
@@ -43,6 +59,29 @@
4359
from roborock.protocols.v1_protocol import V1RpcChannel
4460
from roborock.web_api import UserWebApiClient
4561

62+
from . import (
63+
child_lock,
64+
clean_summary,
65+
command,
66+
common,
67+
consumeable,
68+
device_features,
69+
do_not_disturb,
70+
dust_collection_mode,
71+
flow_led_status,
72+
home,
73+
led_status,
74+
map_content,
75+
maps,
76+
network_info,
77+
rooms,
78+
routines,
79+
smart_wash_params,
80+
status,
81+
valley_electricity_timer,
82+
volume,
83+
wash_towel_mode,
84+
)
4685
from .child_lock import ChildLockTrait
4786
from .clean_summary import CleanSummaryTrait
4887
from .command import CommandTrait
@@ -71,6 +110,7 @@
71110
"PropertiesApi",
72111
"child_lock",
73112
"clean_summary",
113+
"command",
74114
"common",
75115
"consumeable",
76116
"device_features",

roborock/devices/traits/v1/command.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,17 @@
55

66

77
class CommandTrait:
8-
"""Trait for sending commands to Roborock devices."""
8+
"""Trait for sending commands to Roborock devices.
9+
10+
This trait allows sending raw commands directly to the device. It is particularly
11+
useful for:
12+
1. **Cleaning Control**: Sending commands like `app_start`, `app_stop`, `app_pause`,
13+
or `app_charge` which don't belong to a specific state trait.
14+
2. **Unsupported Features**: Accessing device functionality that hasn't been
15+
mapped to a specific trait yet.
16+
17+
See `roborock.roborock_typing.RoborockCommand` for a list of available commands.
18+
"""
919

1020
def __post_init__(self) -> None:
1121
"""Post-initialization to set up the RPC channel.

roborock/roborock_typing.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@
1616

1717

1818
class RoborockCommand(str, Enum):
19+
"""Enum of all known Roborock V1 protocol commands.
20+
21+
These commands can be sent to a device using the `CommandTrait`.
22+
For example: `device.v1_properties.command.send(RoborockCommand.APP_START)`.
23+
"""
24+
1925
ADD_MOP_TEMPLATE_PARAMS = "add_mop_template_params"
2026
APP_AMETHYST_SELF_CHECK = "app_amethyst_self_check"
2127
APP_CHARGE = "app_charge"

0 commit comments

Comments
 (0)