homebridge-roborock-matter 2.9.1 ā 2.9.3
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 +13 -0
- package/README.md +7 -2
- package/docs/issue-3958-reply.md +29 -0
- package/docs/matter-battery-issue-draft.md +57 -66
- package/package.json +5 -1
- package/roborockLib/lib/deviceFeatures.js +16 -0
- package/roborockLib/roborockAPI.js +8 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.9.3
|
|
4
|
+
|
|
5
|
+
**The plugin is now Verified by Homebridge!** š Reviewed and endorsed by the Homebridge team (homebridge/plugins#1124), with specific praise for the encrypted at-rest session storage, the preserved fork attribution, and the per-release notes.
|
|
6
|
+
|
|
7
|
+
- Verified badge added to the README.
|
|
8
|
+
- **Donate button enabled** on the plugin's Homebridge UI tile via the standard `funding` field (PayPal), plus a Support section in the README.
|
|
9
|
+
- Verified plugins are bumped in Homebridge UI search results and distributed via the pre-bundled tarball pipeline for faster, more reliable installs on low-power devices.
|
|
10
|
+
|
|
11
|
+
## 2.9.2
|
|
12
|
+
|
|
13
|
+
- **Max+ ("Grundig"/"Deep Clean") suction mode now announced on the S8 Pro Ultra.** Field report from a re-paired fleet: the S8 Pro Ultra only showed four suction levels because Max+ was gated to B01/Q7. The classic gate now uses the upstream-vetted per-model feature data (`set_custom_mode_max_plus` in the model's action list) ā currently confirming the S8 Pro Ultra (`a70`); further models are added as feature data or field reports with diagnostics exports confirm the level. NOTE: the robot must be re-paired once for the new mode to appear (Matter locks the mode list at commissioning).
|
|
14
|
+
- Battery documentation corrected after upstream verification on homebridge#3958: `batPercentRemaining` is quality **Q (quieter)** as of Matter 1.4 (reports ARE sent via subscription, 10 s throttle) ā a spec-compliant controller applies them; Apple Home in steady state does not. No plugin architecture change needed; the bridge already does the right thing.
|
|
15
|
+
|
|
3
16
|
## 2.9.1
|
|
4
17
|
|
|
5
18
|
Deep performance pass over the live-room hot paths, with honest before/after measurements.
|
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
12
|
+
<a href="https://github.com/homebridge/homebridge/wiki/Verified-Plugins"><img src="https://img.shields.io/badge/homebridge-verified-blueviolet?color=%23491F59&style=flat" alt="verified-by-homebridge"></a>
|
|
12
13
|
<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
14
|
<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
15
|
<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>
|
|
@@ -27,7 +28,7 @@ Log in with your **Roborock app account** ā no token extraction, no rooted app
|
|
|
27
28
|
- š **Live room tracking ā on every robot.** While the robot works, its position is read from the map channel (encrypted SCMap on B01/Q7, classic RRMap on S/Q-series), matched against your room geometry, 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
29
|
- š§ **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
30
|
- š **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.**
|
|
31
|
+
- š”ļø **Hardened and boring where it counts.** 260 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 by Homebridge** after review by the Homebridge team.
|
|
31
32
|
|
|
32
33
|
## Features
|
|
33
34
|
|
|
@@ -96,7 +97,7 @@ Everything is configurable from the Homebridge UI. The essentials:
|
|
|
96
97
|
|
|
97
98
|
## Battery percentage in Apple Home
|
|
98
99
|
|
|
99
|
-
Apple Home renders the battery percentage from pairing time and
|
|
100
|
+
Apple Home renders the battery percentage from pairing time and refreshes it only on a fresh read (commissioning, hub restart) ā while charging state on the very same cluster updates live. This is a controller-side limitation, not a plugin bug, and it is being investigated upstream with the Homebridge team ([homebridge#3958](https://github.com/homebridge/homebridge/issues/3958)). Current state of knowledge: as of Matter 1.4 the attribute carries the **"quieter" (Q)** reporting quality ā reports ARE sent over the subscription (rate-limited to one per 10 s), a Homebridge maintainer verified that a spec-compliant matter.js controller receives and applies them, yet Apple Home in steady state does not. The likely permanent fix is on Apple's side (Apple Feedback).
|
|
100
101
|
|
|
101
102
|
<details>
|
|
102
103
|
<summary>The full evidence chain and workarounds</summary>
|
|
@@ -116,6 +117,10 @@ The complete path ā robot ā plugin ā Homebridge ā matter.js store ā wa
|
|
|
116
117
|
|
|
117
118
|
Model reports, diagnostics exports, and pull requests are very welcome. The codebase ships with 256 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.
|
|
118
119
|
|
|
120
|
+
## Support the project
|
|
121
|
+
|
|
122
|
+
If this plugin makes your home a little smarter, you can support its development via [PayPal](https://paypal.me/MathiasHornbek) ā or through the ā¤ļø **Donate** button on the plugin's tile in the Homebridge UI. Model reports and diagnostics exports are just as valuable!
|
|
123
|
+
|
|
119
124
|
## Attribution
|
|
120
125
|
|
|
121
126
|
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).
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Svar til bwp91 pĆ„ homebridge#3958 ā klar til at poste
|
|
2
|
+
|
|
3
|
+
```markdown
|
|
4
|
+
Thank you ā this is exactly the kind of verification I was hoping for, and
|
|
5
|
+
the C ā Q correction is a genuinely important update. You're right that my
|
|
6
|
+
analysis was written against the older changes-omitted reading of the
|
|
7
|
+
attribute; I've already corrected the plugin's documentation to reflect the
|
|
8
|
+
Matter 1.4 Q (quieter) quality and your subscription trace
|
|
9
|
+
(mathiashornbek/homebridge-roborock-matter@main, README + docs).
|
|
10
|
+
|
|
11
|
+
Your controller log also explains two things I had observed but couldn't
|
|
12
|
+
fully reconcile: the resync nudge's null ā value transition "working" at the
|
|
13
|
+
wire level while Apple still never converged, and `batChargeState` updating
|
|
14
|
+
live throughout. Both are consistent with the reports leaving the bridge and
|
|
15
|
+
Apple simply not applying Q-quality percentage reports in steady state.
|
|
16
|
+
|
|
17
|
+
I'll run the verification you suggested on my production setup (three
|
|
18
|
+
robots: one V1, two B01) ā Homebridge with matter.js debug logging through a
|
|
19
|
+
full charge cycle, watching for the subscription flushes carrying
|
|
20
|
+
`batPercentRemaining` ā and post the log excerpts here. If I can get
|
|
21
|
+
chip-tool set up on the same network I'll add a subscription trace from that
|
|
22
|
+
side too.
|
|
23
|
+
|
|
24
|
+
Assuming both confirm what your trace already shows, I'll file the Apple
|
|
25
|
+
Feedback report about the controller's handling of Q-quality PowerSource
|
|
26
|
+
attributes and link it here so others can dupe it. Thanks again for digging
|
|
27
|
+
in ā happy to test any builds if something changes in the Homebridge Matter
|
|
28
|
+
layer down the road.
|
|
29
|
+
```
|
|
@@ -1,66 +1,57 @@
|
|
|
1
|
-
# Matter PowerSource `batPercentRemaining`
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
Matter
|
|
11
|
-
matter.js store
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
##
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
Consider a device-side mitigation in the Homebridge Matter layer for bridged
|
|
60
|
-
accessories ā for example bumping the cluster data version or scheduling a
|
|
61
|
-
periodic re-announce for changes-omitted attributes whose value has drifted ā
|
|
62
|
-
so controllers that rely purely on subscriptions eventually converge. This
|
|
63
|
-
would fix frozen battery percentages for every bridged plugin at once, in one
|
|
64
|
-
place.
|
|
65
|
-
|
|
66
|
-
Happy to provide full logs, store dumps, and to test builds.
|
|
1
|
+
# Matter PowerSource `batPercentRemaining` ā investigation record
|
|
2
|
+
|
|
3
|
+
Filed upstream as
|
|
4
|
+
[homebridge/homebridge#3958](https://github.com/homebridge/homebridge/issues/3958)
|
|
5
|
+
on 2026-07-15. This document tracks the current state of knowledge; the
|
|
6
|
+
original report text lives in the issue.
|
|
7
|
+
|
|
8
|
+
## Symptom
|
|
9
|
+
|
|
10
|
+
A Matter RVC bridged through Homebridge 2's Matter API publishes battery
|
|
11
|
+
updates continuously; the matter.js store verifiably carries the live value;
|
|
12
|
+
`batChargeState` on the same PowerSource cluster updates live in Apple Home ā
|
|
13
|
+
but the rendered battery **percentage** stays at its commissioning-time value
|
|
14
|
+
until a fresh read (re-pair or Matter hub restart).
|
|
15
|
+
|
|
16
|
+
## Corrected analysis (per Homebridge maintainer verification, 2026-07-15)
|
|
17
|
+
|
|
18
|
+
The original analysis assumed the attribute carries the Matter reporting
|
|
19
|
+
quality **C (changes omitted)** ā never reported via subscription, controllers
|
|
20
|
+
must poll. That was true of older spec revisions, **but as of Matter 1.4 the
|
|
21
|
+
attribute is quality Q (quieter)** , and matter.js 0.17.x (shipped with every
|
|
22
|
+
Homebridge 2.1.x release) models it accordingly:
|
|
23
|
+
|
|
24
|
+
- **Q (quieter):** reported via subscription, rate-limited to at most one
|
|
25
|
+
report per 10 seconds, plus an immediate report on any null ā value
|
|
26
|
+
transition.
|
|
27
|
+
|
|
28
|
+
A Homebridge maintainer (bwp91) commissioned a matter.js controller against a
|
|
29
|
+
bridge exposing `PowerSource(Battery, Rechargeable)` ā the same setup
|
|
30
|
+
Homebridge builds ā and logged the subscription: percentage changes propagate
|
|
31
|
+
exactly as Q prescribes (immediate first report, deferred follow-up inside the
|
|
32
|
+
10 s window, correct application after an interleaved `batChargeState` bump).
|
|
33
|
+
The "stale cluster data version" theory does not hold on the controller side.
|
|
34
|
+
|
|
35
|
+
## Where that leaves things
|
|
36
|
+
|
|
37
|
+
- The bridge **emits** the reports; a spec-compliant controller **applies**
|
|
38
|
+
them. Apple Home in steady state does not ā consistent with Apple's
|
|
39
|
+
controller still treating the attribute under the older changes-omitted
|
|
40
|
+
rules and refreshing only on a fresh read.
|
|
41
|
+
- The plugin's boot-time resync nudge (null ā value transition) does hit the
|
|
42
|
+
wire immediately (maintainer-confirmed) and remains useful for controllers
|
|
43
|
+
that re-prime their subscriptions; Apple still does not converge.
|
|
44
|
+
- **No device-side fix exists**: bumping the data version or re-announcing
|
|
45
|
+
only produces more of the reports Apple already receives and ignores.
|
|
46
|
+
|
|
47
|
+
## Next verification steps (requested upstream)
|
|
48
|
+
|
|
49
|
+
1. Run Homebridge with matter.js debug logging during a battery change and
|
|
50
|
+
capture the subscription flushes carrying `batPercentRemaining` ā proves
|
|
51
|
+
the reports leave THIS bridge specifically.
|
|
52
|
+
2. Optionally subscribe with `chip-tool` and confirm it sees (and applies)
|
|
53
|
+
the live values.
|
|
54
|
+
|
|
55
|
+
If both confirm reports going out, the permanent fix belongs with Apple
|
|
56
|
+
(Apple Feedback report about the controller's handling of Q-quality
|
|
57
|
+
PowerSource attributes). The upstream issue stays open in the meantime.
|
package/package.json
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homebridge-roborock-matter",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.3",
|
|
4
4
|
"description": "Matter-only Homebridge plugin publishing Roborock robot vacuums (including 2025 B01/Q7-series) as native Matter accessories for Apple Home. Fork of homebridge-roborock-vacuum2.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Mathias Hornbek"
|
|
8
8
|
},
|
|
9
|
+
"funding": {
|
|
10
|
+
"type": "paypal",
|
|
11
|
+
"url": "https://paypal.me/MathiasHornbek"
|
|
12
|
+
},
|
|
9
13
|
"keywords": [
|
|
10
14
|
"apple-home",
|
|
11
15
|
"homebridge-plugin",
|
|
@@ -1345,7 +1345,23 @@ class deviceFeatures {
|
|
|
1345
1345
|
}
|
|
1346
1346
|
}
|
|
1347
1347
|
|
|
1348
|
+
// Classic v1 models whose upstream-vetted per-model action list includes
|
|
1349
|
+
// `set_custom_mode_max_plus` ā the verified signal that the robot's firmware
|
|
1350
|
+
// accepts the Max+ suction level (v1 fan power 108). Keep this in sync with
|
|
1351
|
+
// the modelConfig action lists in processSupportedFeatures above; models are
|
|
1352
|
+
// only added here once the upstream feature data (or a field report with a
|
|
1353
|
+
// diagnostics export) confirms the level.
|
|
1354
|
+
const MAX_PLUS_FAN_POWER_MODELS = new Set([
|
|
1355
|
+
"roborock.vacuum.a70", // S8 Pro Ultra
|
|
1356
|
+
]);
|
|
1357
|
+
|
|
1358
|
+
/** @param {string} model */
|
|
1359
|
+
function supportsMaxPlusFanPower(model) {
|
|
1360
|
+
return MAX_PLUS_FAN_POWER_MODELS.has(model);
|
|
1361
|
+
}
|
|
1362
|
+
|
|
1348
1363
|
module.exports = {
|
|
1349
1364
|
deviceFeatures,
|
|
1350
1365
|
stateCodes,
|
|
1366
|
+
supportsMaxPlusFanPower,
|
|
1351
1367
|
};
|
|
@@ -14,6 +14,8 @@ const roborock_mqtt_connector =
|
|
|
14
14
|
const rrMessage = require("./lib/message").message;
|
|
15
15
|
const vacuum_class = require("./lib/vacuum").vacuum;
|
|
16
16
|
const deviceFeatures = require("./lib/deviceFeatures").deviceFeatures;
|
|
17
|
+
const supportsMaxPlusFanPower =
|
|
18
|
+
require("./lib/deviceFeatures").supportsMaxPlusFanPower;
|
|
17
19
|
const RRMapParser = require("./lib/RRMapParser");
|
|
18
20
|
const messageQueueHandler =
|
|
19
21
|
require("./lib/messageQueueHandler").messageQueueHandler;
|
|
@@ -1944,6 +1946,12 @@ class Roborock {
|
|
|
1944
1946
|
canVacuum: true,
|
|
1945
1947
|
canMop: hasWaterModeSchema || hasMopSchema || hasMopFeature,
|
|
1946
1948
|
canControlFanPower,
|
|
1949
|
+
// Max+ (fan power 108) only where the upstream-vetted per-model
|
|
1950
|
+
// feature data confirms the level (e.g. S8 Pro Ultra) ā field
|
|
1951
|
+
// reports with diagnostics exports extend the list.
|
|
1952
|
+
canMaxPlusFanPower: supportsMaxPlusFanPower(
|
|
1953
|
+
this.getProductAttribute(duid, "model")
|
|
1954
|
+
),
|
|
1947
1955
|
canControlWater:
|
|
1948
1956
|
hasWaterModeSchema ||
|
|
1949
1957
|
this.hasVacuumFeature(duid, [
|