xiaomi-vacuum-sdk
Async Python SDK for Xiaomi MIoT robot vacuums: local control over the encrypted MIoT UDP protocol, and rendering of the cloud map blob to PNG.
Built as a focused replacement for python-miio + vacuum-map-parser-xiaomi
covering exactly the surface a vacuum integration needs — no legacy miIO
protocol, no CLI, no device discovery. Reference models are the Xiaomi Robot
Vacuum X20 Max (xiaomi.vacuum.d109gl) and S20+ (xiaomi.vacuum.b108gl);
the API is model-agnostic and takes MIoT property/action addresses as input.
Install
pip install xiaomi-vacuum-sdk
Requires Python >= 3.13. Runtime dependencies: cryptography, pillow.
Local control
from xiaomi_vacuum_sdk import ActionAddress, MiotClient, PropertyAddress
client = MiotClient(host="192.168.1.50", token="ffffffffffffffffffffffffffffffff")
try:
info = await client.info()
print(info.model, info.firmware_version)
state = await client.get_properties(
{
"status": PropertyAddress(siid=2, piid=1),
"battery_level": PropertyAddress(siid=3, piid=1),
}
)
print(state)
await client.call_action(ActionAddress(siid=2, aiid=1))
await client.set_property(PropertyAddress(siid=7, piid=4), 1)
finally:
await client.close()
All calls are async-native (asyncio UDP transport, no threads). Errors form
a typed hierarchy rooted at MiotError:
MiotConnectionError— network failure or response timeout.MiotDeviceError— the device answered with a non-zero error code (code,messageattributes).MiotAckTimeoutError— the device accepted the command but never sent the ack (Xiaomi vacuums do this routinely while busy); a distinct type so callers can choose optimistic handling.
Map rendering
from xiaomi_vacuum_sdk import MapRenderer, RenderOptions
renderer = MapRenderer(RenderOptions())
png = renderer.render(blob, model="xiaomi.vacuum.d109gl", device_id="412345678")
blob is the encrypted map exactly as downloaded from the Xiaomi cloud
(get_file_url object storage). The renderer absorbs the format quirks —
model-derived AES key, optional {"data": "<base64>"} envelope, zlib
inflate — and returns finished PNG bytes. Rendering is CPU-bound and sync;
wrap it in an executor inside async applications.
RenderOptions controls palette, room colors, drawn layers, scale and
element sizes; every field has a sensible default.
When the caller also needs the map behind the image — to place overlays, or
to translate a click on the PNG back into device coordinates — use
render_map, which parses the blob once and hands back the geometry it drew
from:
rendered = renderer.render_map(blob, model="xiaomi.vacuum.d109gl", device_id="412345678")
rendered.png # the same bytes render() returns
rendered.map_data # the parsed MapData: grid size, origin, resolution, features
rendered.coordinates # the CoordinateSystem that projection used
x, y = rendered.coordinates.to_image(rendered.map_data.vacuum)
device_point = rendered.coordinates.to_device(x, y) # a MapPoint, in millimeters
CoordinateSystem.to_device is the exact inverse of to_image, so consumers
never have to reimplement the scale, border and Y-flip the renderer applied.
Support
This SDK is built and maintained on personal time, on hardware bought for the purpose. If it is useful to you, consider sponsoring the work — it keeps the devices, the testing and the releases coming.
License
MIT.
Metadata
Release files for xiaomi-vacuum-sdk 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| xiaomi_vacuum_sdk-0.1.1.tar.gz | 82.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| xiaomi_vacuum_sdk-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 114.1 kB
Release files / xiaomi_vacuum_sdk-0.1.1.tar.gz
| Download URL | xiaomi_vacuum_sdk-0.1.1.tar.gz |
|---|---|
| Size | 82.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dc9e73ec5f6dce0847bdbae814b14ee72949b8084538a3fb896249c3b27379cd
|
|
BLAKE2b-256 checksum How to use checksums |
de0cd2090151ec236f51437e172073c3ff60b3dada0bdac3370e97054a603efd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / xiaomi_vacuum_sdk-0.1.1-py3-none-any.whl
| Download URL | xiaomi_vacuum_sdk-0.1.1-py3-none-any.whl |
|---|---|
| Size | 31.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5f736acf6bb3e3ee28fa9a13ad372ea3afbd29808d28d8bb653eca2df6ce06b0
|
|
BLAKE2b-256 checksum How to use checksums |
37408bded22a48098d0361fbfd402d14ee25137205a0411575262b0787e6866f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|