homebridge-roborock-matter 2.4.2 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/README.md +100 -47
- package/config.schema.json +6 -0
- package/dist/matter_vacuum_accessory.js +78 -5
- package/dist/matter_vacuum_accessory.js.map +1 -1
- package/dist/ui/index.js +2 -17
- package/dist/ui/index.js.map +1 -1
- package/homebridge-ui/package.json +5 -0
- package/homebridge-ui/server.js +11 -2
- package/package.json +1 -2
- package/roborockLib/lib/vacuum.js +8 -0
- package/roborockLib/roborockAPI.js +59 -8
- package/.gitattributes +0 -13
- package/__tests__/testdata/b01_q7_get_prop_response.json +0 -6
- package/__tests__/testdata/b01_q7_map_fixture.json +0 -16
- package/homebridge-roborock-vacuum.code-workspace +0 -7
- package/roborockLib/lib/map/map.html +0 -137
- package/roborockLib/lib/map/zones.js +0 -851
- package/roborockLib/lib/roborockPackageHelper.js +0 -142
- package/roborockLib/lib/sniffing/mitmproxy_roborock.py +0 -300
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.6.0
|
|
4
|
+
|
|
5
|
+
- **New: opt-in suction-level cleaning modes.** With `enableFanPowerCleanModes` (default off), the Matter cleaning mode list gains **Quiet / Balanced / Turbo / Max Vacuum** variants with proper Matter mode tags (Vacuum + Quiet/Max), so suction can be chosen directly from Apple Home's mode picker. Selecting a variant pins the robot's fan power (v1 codes 101-104; the B01/Q7 adapter translates to wind levels 1-4) while behaving as a vacuum-family mode everywhere else (water box handling, mop rules). Off by default because Matter fixes an accessory's mode list at commissioning: toggling the option requires removing and re-pairing the robot once — this ships as a deliberate opt-in rather than a forced re-pair for everyone.
|
|
6
|
+
- **README rebuilt from scratch** around what makes the plugin unique (2025 B01/Q7 support, live room tracking, Matter-only design), with a feature matrix, configuration reference, honest limitation notes, and the plugin icon.
|
|
7
|
+
- Full suite: 247 passing (6 new clean-mode tests). No changes to default behavior anywhere.
|
|
8
|
+
|
|
9
|
+
## 2.5.0
|
|
10
|
+
|
|
11
|
+
Supply-chain, robustness and capability-detection release. Every Socket.dev alert with a code-level source is eliminated at the source, and the plugin now adapts itself to unknown robot models instead of guessing silently.
|
|
12
|
+
|
|
13
|
+
- **Custom UI server moved to native ESM loading — no more dynamic code evaluation.** The `homebridge-ui` directory is now marked `"type": "module"`, so `server.js` imports the pure-ESM `@homebridge/plugin-ui-utils` natively and instantiates the exported (side-effect-free) server class from the compiled output. The `new Function("return import(...)")` interop shim is gone, and with it the Socket.dev "uses eval" alert.
|
|
14
|
+
- **Removed the dead ioBroker-era package/image downloader** (`roborockPackageHelper`) and its `jszip` dependency (12 packages out of the tree). The helper was never called by this fork, wrote to relative paths, and was the source of Socket.dev's AI-detected ZIP-slip/path-traversal alert. Deleting it removes the entire alert surface rather than patching around it.
|
|
15
|
+
- **Self-healing capability detection.** Any periodic poll request a robot definitively answers with an unsupported-method error is now remembered per device and skipped until the next restart (firmware updates get a fresh probe) — exotic and brand-new models stop generating repeated warnings for requests they will never answer. Timeouts and transport errors never count as unsupported.
|
|
16
|
+
- **Capability-derived poll profiles for unknown models.** Models without a dedicated poll profile (e.g. newly released Saros 10 / Q5 Max+ / QX Revo Plus-class devices) now derive their polls from the robot's own capability bitmask where available (carpet support), announce the chosen profile once in the log, and point to the model-report issue template. Known models keep their verified profiles unchanged.
|
|
17
|
+
- **Clearer model lookup mismatch logs:** a device whose HomeData model string does not look like a Roborock vacuum now logs exactly what was reported and how to file a useful report, instead of a generic "unsupported model" line.
|
|
18
|
+
- **Leaner npm package:** the mitmproxy sniffing script, the ioBroker map viewer, test files, and editor metadata no longer ship in the tarball.
|
|
19
|
+
- ROADMAP refreshed against live upstream status: applemanj#12 (pause/dock) confirmed fixed and closed upstream; applemanj#4 (S8 local timeouts) still awaiting reporter retest; homebridge#3951 stable with no recurrence since June. The legacy "HomeKit scene/room controls" item is superseded by the Matter-only design.
|
|
20
|
+
- Full suite: 241 passing (6 new capability-detection tests). Verified end to end under Homebridge 1.8.3 and 2.1.2-beta.3, including the plugin-verification harness's crash scenarios (invalid credentials, unreachable cloud).
|
|
21
|
+
|
|
3
22
|
## 2.4.2
|
|
4
23
|
|
|
5
24
|
Robustness and supply-chain release (Homebridge verification runtime checks + Socket.dev scan).
|
package/README.md
CHANGED
|
@@ -1,68 +1,121 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/mathiashornbek/homebridge-roborock-matter/main/assets/icon.png" width="140" alt="homebridge-roborock-matter icon">
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
<h1 align="center">homebridge-roborock-matter</h1>
|
|
4
6
|
|
|
5
|
-
>
|
|
7
|
+
<p align="center">
|
|
8
|
+
<b>Your Roborock vacuum as a native Matter robot in Apple Home — with live "cleaning in the kitchen" room tracking.</b>
|
|
9
|
+
</p>
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://www.npmjs.com/package/homebridge-roborock-matter"><img src="https://img.shields.io/npm/v/homebridge-roborock-matter?label=npm&color=cb3837" alt="npm version"></a>
|
|
13
|
+
<a href="https://www.npmjs.com/package/homebridge-roborock-matter"><img src="https://img.shields.io/npm/dt/homebridge-roborock-matter?label=downloads&color=8a5cf5" alt="npm downloads"></a>
|
|
14
|
+
<a href="https://github.com/mathiashornbek/homebridge-roborock-matter/actions"><img src="https://img.shields.io/github/actions/workflow/status/mathiashornbek/homebridge-roborock-matter/nodejs.yml?label=CI" alt="CI status"></a>
|
|
15
|
+
<img src="https://img.shields.io/badge/node-22%20%7C%2024-brightgreen" alt="Node 22/24">
|
|
16
|
+
<img src="https://img.shields.io/badge/homebridge-1.11%20%7C%202.x-purple" alt="Homebridge 1.11/2.x">
|
|
17
|
+
<a href="./LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT license"></a>
|
|
18
|
+
</p>
|
|
8
19
|
|
|
9
|
-
|
|
10
|
-
- **B01/Q7-series protocol support.** The 2025 Q-series robots speak a different RPC dialect that upstream does not implement. This fork adds a full B01 adapter — commands (start/stop/pause/dock/locate/segment cleaning), status, battery, charging state, mop/vacuum mode switching, and room selection via the encrypted B01 map channel — implemented against the [python-roborock](https://github.com/Python-roborock/python-roborock) reference and verified with fixture-driven tests.
|
|
11
|
-
- **Live room tracking (B01/Q7).** While the robot is actively cleaning, the plugin periodically reads the robot's position from the encrypted map channel, resolves which room outline contains it, and publishes that room as the current Matter Service Area — so Apple Home can show "cleaning in \<room\>" with the room the robot is physically inside, the way the vendor app does. Room progress stays honest: only rooms the robot was actually detected in are marked completed when it moves on. Opt out with the **Enable Live Room Tracking** setting.
|
|
12
|
-
- **Robustness hardening.** Startup guards, self-healing status polling with a dedicated B01 loop, per-cluster Matter publish isolation, interval-lifecycle fixes, and a light, accessible settings UI with per-device enable/disable.
|
|
20
|
+
---
|
|
13
21
|
|
|
14
|
-
|
|
22
|
+
Log in with your **Roborock app account** — no token extraction, no rooted apps, no packet sniffing — and every robot appears in Apple Home as a first-class **Matter Robotic Vacuum Cleaner**: start, pause, dock, pick rooms, choose cleaning modes, and watch the status pill name the room the robot is _actually inside_, live.
|
|
15
23
|
|
|
16
|
-
|
|
17
|
-
reporting quality **"changes omitted"**: value changes are not pushed to
|
|
18
|
-
subscribed controllers, by design. matter.js implements this faithfully on
|
|
19
|
-
the device side, and its own controller documents the consequence ("Always
|
|
20
|
-
read attributes that do not report changes via subscriptions"). Apple Home
|
|
21
|
-
performs no such re-reads, so the vacuum tile's battery percentage freezes
|
|
22
|
-
at whatever it was when the accessory was paired — while the charging state
|
|
23
|
-
on the very same cluster updates live.
|
|
24
|
+
## Why this plugin
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
device-side write can force a changes-omitted attribute to report. Known
|
|
31
|
-
refresh paths today: re-establishing the controller subscription (Matter
|
|
32
|
-
hub restart) and re-pairing. The permanent fix belongs in the controller
|
|
33
|
-
ecosystem — `docs/matter-battery-issue-draft.md` contains a ready-to-file
|
|
34
|
-
upstream report with the complete evidence chain.
|
|
26
|
+
- 🗣️ **The only plugin that speaks 2025 Roborock.** The B01/Q7-series (`roborock.vacuum.sc05`, Q7 M5 / M5+) exists solely in the Roborock app ecosystem — a new RPC dialect with an encrypted protobuf map channel that miio-based plugins cannot talk to at all. Fully implemented here: commands, status, battery, suction levels, room cleaning, and the map channel.
|
|
27
|
+
- 📍 **Live room tracking.** While the robot works, its position is read from the encrypted map, matched against your room outlines, and published as the current Matter Service Area. Apple Home shows _"Cleaning — Kitchen"_ — including runs started from the robot's button or the Roborock app. No other Homebridge plugin does this.
|
|
28
|
+
- 🧭 **Matter-only, by design.** No legacy fan tiles, no helper-switch clutter. One robot, one native accessory, on Homebridge 2's built-in Matter bridge — including room/map selection sourced from your Roborock account's named rooms.
|
|
29
|
+
- 🔌 **Cloud + local, automatically.** Commands prefer a direct local TCP connection to the robot and fall back to the Roborock cloud transparently, with per-device connection diagnostics in the settings UI when you want to see exactly what happened.
|
|
30
|
+
- 🛡️ **Hardened and boring where it counts.** 247 automated tests, CI on Node 22/24 against Homebridge 1.11 and 2.x, zero known vulnerabilities, no analytics, no post-install scripts, and a startup that retries with backoff instead of ever crash-looping Homebridge — verified against the Homebridge plugin-verification harness.
|
|
35
31
|
|
|
36
|
-
##
|
|
32
|
+
## Features
|
|
37
33
|
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
| | |
|
|
35
|
+
| ------------------------------------ | -------------------------------------------------------------------------------------------------------------------- |
|
|
36
|
+
| 🤖 **Native Matter RVC** | Start / stop / pause / return-to-dock, run modes, operational state, error reporting |
|
|
37
|
+
| 🚪 **Room cleaning from Apple Home** | Matter Service Area selection with your real room names, multi-map homes included |
|
|
38
|
+
| 📍 **Live room tracking** | The room the robot is physically inside, updated every ~20 s while cleaning ([details](#live-room-tracking)) |
|
|
39
|
+
| 📊 **Honest cleaning progress** | Per-room pending → operating → completed, only claiming rooms the robot was actually detected in |
|
|
40
|
+
| 🌀 **Cleaning modes** | Vacuum / Mop / Vacuum + Mop, capability-gated per robot — plus optional Quiet / Balanced / Turbo / Max suction modes |
|
|
41
|
+
| 🔋 **Battery & charging** | Live percentage and charge state via Matter PowerSource ([one Apple-side caveat](#battery-percentage-in-apple-home)) |
|
|
42
|
+
| 🧠 **Self-adapting model support** | Unknown models get capability-derived polling; requests a robot reports as unsupported are disabled automatically |
|
|
43
|
+
| 🩺 **Built-in diagnostics** | Connection state, transport history, live LAN probe, and a redacted report generator for bug reports |
|
|
44
|
+
| 🔐 **2FA-friendly login** | Roborock account two-factor authentication handled entirely in the settings UI |
|
|
45
|
+
|
|
46
|
+
## Quick start
|
|
47
|
+
|
|
48
|
+
1. Install through the Homebridge UI (search for **`homebridge-roborock-matter`**) or:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npm install -g homebridge-roborock-matter
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
2. Open the plugin settings, sign in with your **Roborock app account** (2FA supported), and pick which robots to manage.
|
|
55
|
+
3. Enable **Matter** for the plugin's child bridge, restart Homebridge, and add each robot to Apple Home with the pairing code from the **Matter Pairing** section of the settings.
|
|
56
|
+
|
|
57
|
+
For B01/Q7 robots, room selection appears once the map has been fetched (watch for a `B01 rooms for ...` log line). Robots paired _before_ rooms were available need one remove/re-pair in Apple Home — Matter fixes an accessory's capabilities at commissioning time.
|
|
58
|
+
|
|
59
|
+
## Live room tracking
|
|
60
|
+
|
|
61
|
+
While a robot is actively cleaning, the plugin fetches its live position from Roborock's encrypted SCMap channel (throttled to ~20 s, active runs only, nothing while docked), ray-casts it against the per-room boundary outlines, and publishes the result as the Matter Service Area `currentArea`:
|
|
62
|
+
|
|
63
|
+
- Apple Home's status pill names the room the robot is **physically inside** — the way the vendor app does it.
|
|
64
|
+
- Works for full-home cleans and for runs started from the robot's button or the Roborock app, which previously had no room to show at all.
|
|
65
|
+
- Progress stays honest: a room is only marked _completed_ once the robot was actually detected inside it and has moved on. The plugin never invents data the robot didn't report.
|
|
66
|
+
|
|
67
|
+
Enabled by default; opt out with `enableLiveRoomTracking: false`.
|
|
40
68
|
|
|
41
69
|
## Supported robots
|
|
42
70
|
|
|
43
|
-
-
|
|
44
|
-
- **
|
|
71
|
+
- **B01/Q7-series (2025):** `roborock.vacuum.sc05` and compatible (Q7 M5 / M5+), including manual-tank mopping with vacuum/mop mode switching.
|
|
72
|
+
- **Classic app-account Roborock vacuums** supported by the upstream lineage (S-series, Q-series, Saros — S5 through S8 Pro Ultra, Q5/Q7/Q8/Q Revo families and newer), published as Matter accessories.
|
|
73
|
+
- Brand-new models get capability-derived defaults automatically. If something looks off, [open a model report](https://github.com/mathiashornbek/homebridge-roborock-matter/issues) with a diagnostics export — that's exactly what it's for.
|
|
45
74
|
|
|
46
|
-
##
|
|
75
|
+
## Configuration
|
|
47
76
|
|
|
48
|
-
|
|
49
|
-
2. Enter your Roborock app account credentials in the plugin settings.
|
|
50
|
-
3. Enable Matter for the Roborock child bridge, restart, and add each robot to Apple Home using the codes shown in the **Matter Pairing** section of the plugin settings.
|
|
51
|
-
4. Use the **Devices** section to choose which robots the plugin manages.
|
|
77
|
+
Everything is configurable from the Homebridge UI. The essentials:
|
|
52
78
|
|
|
53
|
-
|
|
79
|
+
| Option | Default | What it does |
|
|
80
|
+
| ------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
81
|
+
| `email` / password | — | Your Roborock app account (2FA handled in the UI; the session token is stored encrypted) |
|
|
82
|
+
| `skipDevices` | — | Comma-separated device IDs the plugin should ignore |
|
|
83
|
+
| `enableMatterServiceArea` | `true` | Room/map selection in Apple Home |
|
|
84
|
+
| `enableLiveRoomTracking` | `true` | Live current-room from the robot's map position while cleaning |
|
|
85
|
+
| `enableMatterCleanMode` | `true` | Vacuum / Mop / Vacuum + Mop mode selection |
|
|
86
|
+
| `enableFanPowerCleanModes` | `false` | Adds Quiet / Balanced / Turbo / Max suction modes to the Matter mode list. **Re-pair the robot once after toggling** — Matter locks the mode list at pairing |
|
|
87
|
+
| `enableMatterPowerSource` | `true` | Battery cluster |
|
|
88
|
+
| `cloudOnlyMode` | `false` | Skip local TCP entirely and use the cloud for everything |
|
|
89
|
+
| `transientWarningThrottleHours` | `6` | How often recurring transient-timeout warnings may repeat (0 = only in debug) |
|
|
54
90
|
|
|
55
|
-
##
|
|
91
|
+
## Battery percentage in Apple Home
|
|
92
|
+
|
|
93
|
+
Apple Home renders the battery percentage from pairing time and never re-reads it — the Matter attribute carries the spec's "changes omitted" reporting quality, so value changes are not pushed to controllers _by design_ (charging state on the very same cluster updates live). This is a controller-side limitation verified end-to-end, not a plugin bug.
|
|
94
|
+
|
|
95
|
+
<details>
|
|
96
|
+
<summary>The full evidence chain and workarounds</summary>
|
|
97
|
+
|
|
98
|
+
The complete path — robot → plugin → Homebridge → matter.js store — was verified to carry the live value in real time while Apple kept rendering the pairing-day percentage. matter.js's own controller documents the consequence ("always read attributes that do not report changes via subscriptions"); Apple's controller performs no such re-reads. The plugin performs a one-time battery resync each boot so controllers that re-prime their subscriptions pick up a fresh value. Known refresh paths: restarting the Matter hub (HomePod/Apple TV) or re-pairing. A ready-to-file upstream report with the full evidence lives in [`docs/matter-battery-issue-draft.md`](./docs/matter-battery-issue-draft.md).
|
|
99
|
+
|
|
100
|
+
</details>
|
|
56
101
|
|
|
57
|
-
|
|
102
|
+
## Troubleshooting
|
|
58
103
|
|
|
59
|
-
- **
|
|
60
|
-
- **
|
|
61
|
-
- **
|
|
62
|
-
- **
|
|
104
|
+
- **Diagnostics first:** the plugin settings include per-device connection state, the last cloud/local transport used, a live **Test Local Connection** probe, and a **redacted diagnostics report** you can paste straight into a GitHub issue.
|
|
105
|
+
- **Robot shows "Updating…" in Apple Home:** remove the robot from Apple Home and pair it again — a stale controller cache from an earlier pairing is the usual cause (tracked upstream in homebridge/homebridge#3951).
|
|
106
|
+
- **Rooms missing for a Q7/B01 robot:** wait for the `B01 rooms for ...` log line, then re-pair once so the Service Area cluster is announced with room data.
|
|
107
|
+
- **Startup without network:** the plugin retries the Roborock cloud with increasing backoff (up to 10 attempts) and never crash-loops Homebridge; wrong credentials stop cleanly with a clear log message.
|
|
108
|
+
|
|
109
|
+
## Contributing
|
|
110
|
+
|
|
111
|
+
Model reports, diagnostics exports, and pull requests are very welcome. The codebase ships with 247 tests (protocol fixtures verified against the [python-roborock](https://github.com/Python-roborock/python-roborock) reference), strict TypeScript checking, and CI across Node 22/24 × Homebridge 1.11/2.x — `npm test` before you push and you're set.
|
|
112
|
+
|
|
113
|
+
## Attribution
|
|
63
114
|
|
|
64
|
-
|
|
115
|
+
A Matter-only fork of [`homebridge-roborock-vacuum2`](https://github.com/applemanj/homebridge-roborock-vacuum2) by **Joshua Appleman**, itself adapted from [ioBroker.roborock](https://github.com/copystring/ioBroker.roborock) by **copystring**, with original work by **Nico Hartung**. B01/Q7 protocol work is implemented against the [python-roborock](https://github.com/Python-roborock/python-roborock) reference. All original copyright is preserved under the [MIT license](./LICENSE).
|
|
65
116
|
|
|
66
|
-
|
|
117
|
+
---
|
|
67
118
|
|
|
68
|
-
|
|
119
|
+
<p align="center">
|
|
120
|
+
<sub>Not affiliated with or endorsed by Roborock, Apple, or the Connectivity Standards Alliance. Roborock is a trademark of Beijing Roborock Technology Co., Ltd.</sub>
|
|
121
|
+
</p>
|
package/config.schema.json
CHANGED
|
@@ -92,6 +92,12 @@
|
|
|
92
92
|
"type": "boolean",
|
|
93
93
|
"default": true
|
|
94
94
|
},
|
|
95
|
+
"enableFanPowerCleanModes": {
|
|
96
|
+
"title": "Enable Suction-Level Cleaning Modes",
|
|
97
|
+
"description": "Adds Quiet / Balanced / Turbo / Max vacuum modes to the Matter cleaning mode list, so suction can be chosen directly from Apple Home. IMPORTANT: Matter fixes the mode list when the robot is paired, so after enabling or disabling this you must remove the robot from Apple Home and re-pair it once. Requires Matter Cleaning Mode Selection.",
|
|
98
|
+
"type": "boolean",
|
|
99
|
+
"default": false
|
|
100
|
+
},
|
|
95
101
|
"enableMatterExtendedOperationalStates": {
|
|
96
102
|
"title": "Enable Matter Returning Status",
|
|
97
103
|
"description": "Opt in to the extended Matter Returning status while the vacuum is heading back to the dock. Unless Charging/Docked status is also enabled below, docked and charging still report as Ready for Apple Home compatibility.",
|
|
@@ -28,6 +28,45 @@ const LIVE_STATUS_STALENESS_MS = 15 * 60 * 1000;
|
|
|
28
28
|
const CLEAN_MODE_VACUUM = 0;
|
|
29
29
|
const CLEAN_MODE_MOP = 1;
|
|
30
30
|
const CLEAN_MODE_VACUUM_AND_MOP = 2;
|
|
31
|
+
// Opt-in fan-power clean modes (enableFanPowerCleanModes, default off since
|
|
32
|
+
// Matter locks the announced mode set at commissioning — enabling requires
|
|
33
|
+
// one re-pair). Mode ids are stable and appended after the base modes.
|
|
34
|
+
// Fan power values are Roborock v1 codes (101-104); the B01/Q7 adapter
|
|
35
|
+
// translates them to its wind levels 1-4 transparently.
|
|
36
|
+
const CLEAN_MODE_VACUUM_QUIET = 3;
|
|
37
|
+
const CLEAN_MODE_VACUUM_BALANCED = 4;
|
|
38
|
+
const CLEAN_MODE_VACUUM_TURBO = 5;
|
|
39
|
+
const CLEAN_MODE_VACUUM_MAX = 6;
|
|
40
|
+
// Matter ModeBase common mode tags (Quiet/Max) — combined with the RVC
|
|
41
|
+
// Vacuum tag so controllers can render semantic labels where supported.
|
|
42
|
+
const RVC_CLEAN_MODE_TAG_QUIET = 2;
|
|
43
|
+
const RVC_CLEAN_MODE_TAG_MAX = 7;
|
|
44
|
+
const FAN_POWER_CLEAN_MODES = [
|
|
45
|
+
{
|
|
46
|
+
mode: CLEAN_MODE_VACUUM_QUIET,
|
|
47
|
+
label: "Quiet Vacuum",
|
|
48
|
+
fanPower: 101,
|
|
49
|
+
extraTags: [RVC_CLEAN_MODE_TAG_QUIET],
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
mode: CLEAN_MODE_VACUUM_BALANCED,
|
|
53
|
+
label: "Balanced Vacuum",
|
|
54
|
+
fanPower: 102,
|
|
55
|
+
extraTags: [],
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
mode: CLEAN_MODE_VACUUM_TURBO,
|
|
59
|
+
label: "Turbo Vacuum",
|
|
60
|
+
fanPower: 103,
|
|
61
|
+
extraTags: [],
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
mode: CLEAN_MODE_VACUUM_MAX,
|
|
65
|
+
label: "Max Vacuum",
|
|
66
|
+
fanPower: 104,
|
|
67
|
+
extraTags: [RVC_CLEAN_MODE_TAG_MAX],
|
|
68
|
+
},
|
|
69
|
+
];
|
|
31
70
|
const RVC_RUN_MODE_TAG_IDLE = 16384;
|
|
32
71
|
const RVC_RUN_MODE_TAG_CLEANING = 16385;
|
|
33
72
|
const RVC_CLEAN_MODE_TAG_VACUUM = 16385;
|
|
@@ -848,7 +887,8 @@ class RoborockMatterVacuumAccessory {
|
|
|
848
887
|
modeTags: [{ value: RVC_CLEAN_MODE_TAG_VACUUM }],
|
|
849
888
|
},
|
|
850
889
|
];
|
|
851
|
-
|
|
890
|
+
const capabilities = this.getMatterCleanModeCapabilities();
|
|
891
|
+
if (capabilities.canMop) {
|
|
852
892
|
supportedModes.push({
|
|
853
893
|
label: "Mop",
|
|
854
894
|
mode: CLEAN_MODE_MOP,
|
|
@@ -864,8 +904,31 @@ class RoborockMatterVacuumAccessory {
|
|
|
864
904
|
],
|
|
865
905
|
});
|
|
866
906
|
}
|
|
907
|
+
// Opt-in suction-level variants, only when the robot actually exposes
|
|
908
|
+
// fan-power control. NOTE: Matter fixes the announced mode set at
|
|
909
|
+
// commissioning — toggling this option requires re-pairing the robot.
|
|
910
|
+
if (this.isFanPowerCleanModesEnabled() &&
|
|
911
|
+
capabilities.canControlFanPower === true) {
|
|
912
|
+
for (const powerMode of FAN_POWER_CLEAN_MODES) {
|
|
913
|
+
supportedModes.push({
|
|
914
|
+
label: powerMode.label,
|
|
915
|
+
mode: powerMode.mode,
|
|
916
|
+
modeTags: [
|
|
917
|
+
{ value: RVC_CLEAN_MODE_TAG_VACUUM },
|
|
918
|
+
...powerMode.extraTags.map((value) => ({ value })),
|
|
919
|
+
],
|
|
920
|
+
});
|
|
921
|
+
}
|
|
922
|
+
}
|
|
867
923
|
return supportedModes;
|
|
868
924
|
}
|
|
925
|
+
isFanPowerCleanModesEnabled() {
|
|
926
|
+
return this.platform.platformConfig.enableFanPowerCleanModes === true;
|
|
927
|
+
}
|
|
928
|
+
getFanPowerCleanMode(cleanMode) {
|
|
929
|
+
var _a;
|
|
930
|
+
return ((_a = FAN_POWER_CLEAN_MODES.find((powerMode) => powerMode.mode === cleanMode)) !== null && _a !== void 0 ? _a : null);
|
|
931
|
+
}
|
|
869
932
|
getCurrentCleanMode() {
|
|
870
933
|
return this.isSupportedCleanMode(this.selectedCleanMode)
|
|
871
934
|
? this.selectedCleanMode
|
|
@@ -928,19 +991,25 @@ class RoborockMatterVacuumAccessory {
|
|
|
928
991
|
}
|
|
929
992
|
getRoborockCleanModeSettings(cleanMode) {
|
|
930
993
|
const capabilities = this.getMatterCleanModeCapabilities();
|
|
994
|
+
// Fan-power variants are vacuum-family modes with a pinned suction
|
|
995
|
+
// level: protocol layers only understand the three base clean types, so
|
|
996
|
+
// translate before handing over.
|
|
997
|
+
const fanPowerMode = this.getFanPowerCleanMode(cleanMode);
|
|
998
|
+
const baseCleanMode = fanPowerMode ? CLEAN_MODE_VACUUM : cleanMode;
|
|
931
999
|
// Always carry the selected Matter clean mode; protocol layers that have
|
|
932
1000
|
// a native clean-type concept (B01/Q7) apply it directly and ignore the
|
|
933
1001
|
// v1-style fan/water workarounds below.
|
|
934
|
-
const settings = { cleanMode };
|
|
1002
|
+
const settings = { cleanMode: baseCleanMode };
|
|
935
1003
|
if (capabilities.canControlFanPower) {
|
|
936
|
-
settings.fanPower =
|
|
937
|
-
|
|
1004
|
+
settings.fanPower = fanPowerMode
|
|
1005
|
+
? fanPowerMode.fanPower
|
|
1006
|
+
: baseCleanMode === CLEAN_MODE_MOP
|
|
938
1007
|
? ROBOROCK_FAN_POWER_OFF
|
|
939
1008
|
: this.getPreferredVacuumFanPower();
|
|
940
1009
|
}
|
|
941
1010
|
if (capabilities.canControlWater) {
|
|
942
1011
|
settings.waterBoxMode =
|
|
943
|
-
|
|
1012
|
+
baseCleanMode === CLEAN_MODE_VACUUM
|
|
944
1013
|
? ROBOROCK_WATER_BOX_OFF
|
|
945
1014
|
: this.getPreferredWaterBoxMode();
|
|
946
1015
|
}
|
|
@@ -981,6 +1050,10 @@ class RoborockMatterVacuumAccessory {
|
|
|
981
1050
|
return (_a = this.lastWaterBoxMode) !== null && _a !== void 0 ? _a : ROBOROCK_WATER_BOX_MILD;
|
|
982
1051
|
}
|
|
983
1052
|
getCleanModeLabel(cleanMode) {
|
|
1053
|
+
const fanPowerMode = this.getFanPowerCleanMode(cleanMode);
|
|
1054
|
+
if (fanPowerMode) {
|
|
1055
|
+
return fanPowerMode.label;
|
|
1056
|
+
}
|
|
984
1057
|
switch (cleanMode) {
|
|
985
1058
|
case CLEAN_MODE_MOP:
|
|
986
1059
|
return "Mop";
|