homebridge-roborock-matter 2.9.2 → 2.9.4

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 CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.9.4
4
+
5
+ Startup-cost cleanup release (also refreshes the npm README with the Donate button and the prominent Verified badge).
6
+
7
+ - **Two fewer RSA-2048 key generations at every startup.** The MQTT connector generated a protocol keypair that nothing ever read (removed), and the message layer generated its keypair eagerly even though it is only needed for the rare photo request path on camera-equipped models (now created lazily on first use). Measured ~50 ms per keygen on fast hardware — substantially more on a Raspberry Pi.
8
+ - Removed dead code: the never-called `decryptWithPrivateKey` helper and the unused `scenesData` field (both HomeKit-era leftovers).
9
+
10
+ ## 2.9.3
11
+
12
+ **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.
13
+
14
+ - Verified badge added to the README.
15
+ - **Donate button enabled** on the plugin's Homebridge UI tile via the standard `funding` field (PayPal), plus a Support section in the README.
16
+ - 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.
17
+
3
18
  ## 2.9.2
4
19
 
5
20
  - **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).
package/README.md CHANGED
@@ -17,6 +17,14 @@
17
17
  <a href="./LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT license"></a>
18
18
  </p>
19
19
 
20
+ <p align="center">
21
+ <a href="https://paypal.me/MathiasHornbek"><img src="https://img.shields.io/badge/PayPal-Donate-00457C?logo=paypal&logoColor=white" alt="Donate via PayPal"></a>
22
+ </p>
23
+
24
+ <p align="center">
25
+ <a href="https://github.com/homebridge/homebridge/wiki/Verified-Plugins"><img src="https://img.shields.io/badge/homebridge-verified-blueviolet?color=%23491F59&style=for-the-badge&logoColor=%23FFFFFF&logo=homebridge" alt="Verified by Homebridge"></a>
26
+ </p>
27
+
20
28
  ---
21
29
 
22
30
  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.
@@ -27,7 +35,7 @@ Log in with your **Roborock app account** — no token extraction, no rooted app
27
35
  - 📍 **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
36
  - 🧭 **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
37
  - 🔌 **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.** 256 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.
38
+ - 🛡️ **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
39
 
32
40
  ## Features
33
41
 
@@ -116,6 +124,10 @@ The complete path — robot → plugin → Homebridge → matter.js store — wa
116
124
 
117
125
  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
126
 
127
+ ## Support the project
128
+
129
+ 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!
130
+
119
131
  ## Attribution
120
132
 
121
133
  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).
package/package.json CHANGED
@@ -1,11 +1,15 @@
1
1
  {
2
2
  "name": "homebridge-roborock-matter",
3
- "version": "2.9.2",
3
+ "version": "2.9.4",
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",
@@ -32,7 +32,18 @@ class message {
32
32
  this.adapter = adapter;
33
33
  this.missingLocalKeyWarnings = new Set();
34
34
 
35
- this.keys = roborockCrypto.generateRsaKeyPair();
35
+ // The protocol RSA keypair is only needed for the rare photo request
36
+ // path (camera-equipped models). Generate it lazily on first use
37
+ // instead of paying a full RSA-2048 keygen (~50 ms on fast hardware,
38
+ // substantially more on a Raspberry Pi) at every startup.
39
+ this._keys = null;
40
+ }
41
+
42
+ get keys() {
43
+ if (!this._keys) {
44
+ this._keys = roborockCrypto.generateRsaKeyPair();
45
+ }
46
+ return this._keys;
36
47
  }
37
48
 
38
49
  async buildPayload(
@@ -77,7 +77,10 @@ class roborock_mqtt_connector {
77
77
 
78
78
  this.connected = false;
79
79
 
80
- this.keys = roborockCrypto.generateRsaKeyPair();
80
+ // NOTE: this class previously generated its own RSA-2048 keypair here,
81
+ // but nothing ever read it — the protocol keypair lives in message.js
82
+ // (lazily created for the rare photo path). Removed: one full RSA
83
+ // keygen less at every startup.
81
84
  }
82
85
 
83
86
  async initUser(userdata) {
@@ -524,24 +527,6 @@ class roborock_mqtt_connector {
524
527
 
525
528
  return false;
526
529
  }
527
-
528
- decryptWithPrivateKey(privateKeyPem, encryptedData) {
529
- const privateKey = crypto.createPrivateKey({
530
- key: privateKeyPem,
531
- format: "pem",
532
- type: "pkcs8",
533
- });
534
-
535
- const decryptedData = crypto.privateDecrypt(
536
- {
537
- key: privateKey,
538
- padding: crypto.constants.RSA_PKCS1_PADDING,
539
- },
540
- encryptedData
541
- );
542
-
543
- return decryptedData;
544
- }
545
530
  }
546
531
 
547
532
  /**
@@ -122,8 +122,6 @@ class Roborock {
122
122
  this.localDevices = {};
123
123
  this.remoteDevices = new Set();
124
124
 
125
- this.scenesData = null; // Store scenes data locally
126
-
127
125
  this.name = "roborock";
128
126
  this.deviceNotify = null;
129
127
  this.serviceAreaRoomMapRefreshAttempts = new Map();