homebridge-roborock-matter 3.19.0 → 3.19.1

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,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.19.1
4
+
5
+ **The live-room loop was polling a Q10 for a map it cannot answer, and counting each refusal as a failure. Same defect 3.19.0 fixed in the status loop, one loop over.**
6
+
7
+ 3.19.0 stopped the dedicated B01 status loop asking a Q10 (`ss*`) for `get_status`. The live-room loop has the same shape and was missed. It sends `get_map_list`, which has no Q10 translation and is not answered neutrally, so the send choke point refuses it by name and throws — correctly. The catch then counted that refusal as a failure and logged `Live-room map fetch has failed N times in a row` at warn level every fifth one.
8
+
9
+ It reached a Q10 because `refreshLiveRoomForDevice` gates on `pv === "B01"`, and `pv === "B01"` is both dialects — which is the entire premise of [#19](https://github.com/mathiashornbek/homebridge-roborock-matter/issues/19). The Matter accessory drives it whenever the robot is in a cleaning run and `enableMatterServiceArea` is not false, and that setting defaults to on.
10
+
11
+ **That timing is what makes it worth a release on its own: the live-room loop only runs while the robot is actively cleaning.** The first two attempts are 10 seconds apart before the backoff widens, so the first warning lands roughly two and a half minutes into a clean — during the exact operation [#14](https://github.com/mathiashornbek/homebridge-roborock-matter/issues/14)'s reporter had just confirmed working on the only Q10 in the field. A fourth round of chasing this plugin's own designed refusal was one clean away.
12
+
13
+ A Q10 is now skipped before the request is built, and says once per robot that the dialect sends no reply to a map read, so no room is reported during a clean. No state entry is allocated and `null` is returned — the same answer the disabled-tracking branch already gives, so every caller already handles it. The gate sits at the loop's entry rather than at its two call sites, because one of those call sites is the `pv === "B01"` test that caused this.
14
+
15
+ A Q7 is unchanged and pinned as such: it is still fetched, an unrecognised B01 model is still treated as a Q7, and a Q7 that genuinely stops answering still raises the warning. The warning is kept off a robot that cannot answer by design, not removed.
16
+
17
+ The 6-hourly room-name refresh also sends `get_map_list` and is also refused on a Q10, but it logs at debug and is left alone. It wastes a request; it does not tell anyone their robot is failing.
18
+
3
19
  ## 3.19.0
4
20
 
5
21
  **The B01 Q10 command dialect has now been run on a Q10, and it works. That measurement is the whole reason this goes to `latest`.**
package/README.md CHANGED
@@ -37,7 +37,7 @@ This is the most feature-packed, most thoroughly engineered Roborock plugin for
37
37
  - 📍 **See where it's cleaning — live.** Apple Home shows _"Cleaning — Kitchen"_ with the room the robot is actually inside, updating as it moves from room to room. Works even for cleans started from the robot's button or the Roborock app. No other Homebridge plugin does this.
38
38
  - 🧭 **One robot, one tile — and as many robots as you own.** Sign in once and your whole fleet comes along: every vacuum on your account appears as its own clean, native accessory in Apple Home. No clutter of fake fans and helper switches, and rooms appear with the names you gave them in the Roborock app.
39
39
  - ⚡ **Fast and reliable.** Commands go directly to the robot over your own network whenever possible, with the Roborock cloud as automatic backup — and built-in diagnostics in the settings if you ever want to look under the hood.
40
- - 🛡️ **Verified by Homebridge.** Reviewed and endorsed by the Homebridge team. 1602 automated tests, zero known vulnerabilities, no analytics, and a startup designed to never crash your Homebridge — even when your Wi-Fi or the Roborock cloud has a bad day.
40
+ - 🛡️ **Verified by Homebridge.** Reviewed and endorsed by the Homebridge team. 1611 automated tests, zero known vulnerabilities, no analytics, and a startup designed to never crash your Homebridge — even when your Wi-Fi or the Roborock cloud has a bad day.
41
41
 
42
42
  ## Features
43
43
 
@@ -252,7 +252,7 @@ The complete path — robot → plugin → Homebridge → matter.js store — wa
252
252
 
253
253
  ## Contributing
254
254
 
255
- Model reports, diagnostics exports, and pull requests are very welcome. The codebase ships with 1602 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.
255
+ Model reports, diagnostics exports, and pull requests are very welcome. The codebase ships with 1611 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.
256
256
 
257
257
  ## Support the project
258
258
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "homebridge-roborock-matter",
3
- "version": "3.19.0",
3
+ "version": "3.19.1",
4
4
  "description": "The most complete Roborock plugin for Apple Home. Supports the entire Roborock lineup — from the classic S-series to the new 2025 Q7 series that no other plugin can control. Sign in with your Roborock account and get native start/stop, room cleaning, suction levels, battery, and live 'cleaning in the kitchen' room tracking. Verified by Homebridge.",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -4752,6 +4752,29 @@ class Roborock {
4752
4752
  return promise;
4753
4753
  }
4754
4754
 
4755
+ /**
4756
+ * Say once per Q10 robot that its live room does not come from this loop.
4757
+ *
4758
+ * Once per robot for the same reason the status loop says it once: during a
4759
+ * clean this is reached every ten seconds, and a line repeated that often
4760
+ * stops being read.
4761
+ *
4762
+ * @param {string} duid
4763
+ * @returns {void}
4764
+ */
4765
+ noteB01Q10LiveRoomNotAttempted(duid) {
4766
+ if (!this._b01Q10LiveRoomNoticed) {
4767
+ this._b01Q10LiveRoomNoticed = new Set();
4768
+ }
4769
+ if (this._b01Q10LiveRoomNoticed.has(duid)) {
4770
+ return;
4771
+ }
4772
+ this._b01Q10LiveRoomNoticed.add(duid);
4773
+ this.log.info(
4774
+ `${this.describeDevice(duid)} speaks the B01 Q10 dialect, which sends no reply to a map read, so its live-room position is not fetched and no room is reported during a clean. This is a property of the dialect and not a fault; reading state from the datapoint updates the robot pushes is tracked in issue #19.`
4775
+ );
4776
+ }
4777
+
4755
4778
  /**
4756
4779
  * Fetch the current SCMap and derive which room the robot is physically
4757
4780
  * inside (currentPose ray-cast against the per-room boundary chains).
@@ -4772,6 +4795,37 @@ class Roborock {
4772
4795
  if (this.config.enableLiveRoomTracking === false) {
4773
4796
  return null;
4774
4797
  }
4798
+
4799
+ // A Q10 (`ss*`) IS NOT FETCHED AT ALL, for the same reason the status loop
4800
+ // does not poll one — and this is the second loop with that shape, missed
4801
+ // when the first was fixed in 3.19.0.
4802
+ //
4803
+ // `get_map_list` is not in NEUTRAL_RESPONSES and has no Q10 translation,
4804
+ // so the send choke point refuses it by name and throws. The catch below
4805
+ // then counts that refusal as a failure and warns "Live-room map fetch has
4806
+ // failed N times in a row" every fifth one. The refusal is correct; the
4807
+ // failure count is not, because a request whose refusal is certain before
4808
+ // it is asked is not a diagnostic.
4809
+ //
4810
+ // It matters more here than the cadence alone suggests: the live-room loop
4811
+ // runs only while the robot is actively cleaning, so the warning lands in
4812
+ // the log precisely during the operation #14's reporter confirmed working
4813
+ // on the only Q10 in the field.
4814
+ //
4815
+ // Gated at the entry rather than at the call sites because there are two
4816
+ // of them, and the one in `refreshLiveRoomForDevice` gates on `pv ===
4817
+ // "B01"` — which is BOTH dialects, the premise of #19. Returning null is
4818
+ // what the disabled-tracking branch above already returns, so every caller
4819
+ // handles it, and no state entry is allocated.
4820
+ if (
4821
+ b01Q7Adapter.b01FamilyForModel(
4822
+ this.getProductAttribute(duid, "model")
4823
+ ) === b01Q7Adapter.B01_FAMILY.Q10
4824
+ ) {
4825
+ this.noteB01Q10LiveRoomNotAttempted(duid);
4826
+ return null;
4827
+ }
4828
+
4775
4829
  if (!this._b01LiveRoomState) {
4776
4830
  this._b01LiveRoomState = new Map();
4777
4831
  }