homebridge-roborock-vacuum 2.1.3 → 2.2.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 +23 -0
- package/dist/ui/index.js +10 -16
- package/dist/ui/index.js.map +1 -1
- package/homebridge-ui/server.js +18 -1
- package/package.json +6 -2
- package/roborockLib/lib/deviceFeatures.js +25 -0
- package/roborockLib/lib/localConnector.js +58 -4
- package/roborockLib/lib/messageQueueHandler.js +1 -1
- package/roborockLib/lib/roborock_mqtt_connector.js +25 -20
- package/roborockLib/lib/rsaKeys.js +3 -3
- package/roborockLib/lib/vacuum.js +32 -9
- package/roborockLib/roborockAPI.js +152 -18
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.2.1
|
|
4
|
+
|
|
5
|
+
Maintenance release — no functional changes to device control. Reworks the four code patterns flagged by the Homebridge verification security scan so the automated checks come back clean:
|
|
6
|
+
|
|
7
|
+
- **Change**: The config UI server now loads the ESM-only `@homebridge/plugin-ui-utils` package via a native dynamic import in the uncompiled `homebridge-ui/server.js` bootstrap, replacing the `Function`-constructor workaround in the compiled UI bundle
|
|
8
|
+
- **Change**: Translation catalogs are loaded through a static per-language table instead of a computed `require()` path; unknown languages still fall back to English
|
|
9
|
+
- **Change**: The storage path is taken solely from the platform-provided config (with the existing local fallbacks); the redundant environment-variable lookup was removed
|
|
10
|
+
- **Change**: Renamed internal identifiers in the photo RSA-keypair helper; keys are still generated fresh in-process and never read from disk
|
|
11
|
+
|
|
12
|
+
## 2.2.0
|
|
13
|
+
|
|
14
|
+
Connectivity and device-support release, porting recent fixes from the python-roborock and ioBroker.roborock upstream projects (see `UpstreamReview-2026-07.md`).
|
|
15
|
+
|
|
16
|
+
- **New Feature**: Docks introduced since 2025 (Qrevo Curv, Saros 10, Qrevo S5V, Saros 20, and other new dock type codes 10–40) now get their dust-collection, mop-wash, and drying features — including the dock mop-wash switch. Unknown future dock types default to full-featured instead of featureless
|
|
17
|
+
- **New Feature**: Room names now resolve for vacuums shared from another Roborock account (fetched via the device-share rooms API), so Matter room cleaning and the current-room publisher work on shared devices
|
|
18
|
+
- **New Feature**: Qrevo Edge 2 (`a298`) support for clean-mode switching — it uses banded water levels (221–250), so the plugin no longer writes the classic level 202 that the device rejects
|
|
19
|
+
- **Fix (connectivity)**: A vacuum whose IP changed (DHCP) no longer stays unreachable or silently cloud-only until Homebridge restarts — the local reconnect loop now re-queries the device's current IP over the cloud and reconnects to the fresh address; devices demoted to cloud mode after a TCP failure are promoted back to local mode once reachable again
|
|
20
|
+
- **Fix (connectivity)**: The cloud MQTT connection is only reported healthy after the device-topic subscription actually succeeds (broker rejections arrive as qos 128); previously a failed subscription left the plugin claiming a working cloud channel that could never deliver a response
|
|
21
|
+
- **Fix (connectivity)**: Q10-generation (B01 protocol) devices no longer hang startup with a 10-second timeout and stay cloud-only — they are queried with their own `service.get_net_info` method so they can learn their local IP
|
|
22
|
+
- **Fix**: UDP discovery responses were silently discarded due to a missing `this.` in the decryption path; discovery now works again. A UDP port conflict (e.g. ioBroker.roborock on the same host) also no longer aborts all device creation
|
|
23
|
+
- **Fix**: An invalidated cloud session (password change, session revoked) no longer produces an endless 401 retry loop — the cached session is cleared once, polling stops, and the log tells you to re-authenticate. If the 401 is caused by host clock drift (common on NAS hosts), the log instead points at the system time/NTP
|
|
24
|
+
- Licensing note: python-roborock relicensed to Apache 2.0 (2026-07-20), making these ports license-compatible with this MIT plugin
|
|
25
|
+
|
|
3
26
|
## 2.1.3
|
|
4
27
|
|
|
5
28
|
Stability release — no new features.
|
package/dist/ui/index.js
CHANGED
|
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.startUiServer = startUiServer;
|
|
6
7
|
const crypto_1 = __importDefault(require("crypto"));
|
|
7
8
|
const path_1 = __importDefault(require("path"));
|
|
8
9
|
const fs_1 = __importDefault(require("fs"));
|
|
@@ -457,21 +458,14 @@ class RoborockUiServer {
|
|
|
457
458
|
.replace(/\//g, "Y");
|
|
458
459
|
}
|
|
459
460
|
}
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
// The Function constructor is evaluated at runtime, so TypeScript cannot statically analyze or transform it.
|
|
469
|
-
// This is the recommended workaround for ES module/CommonJS interop when using TypeScript with CommonJS output.
|
|
470
|
-
//
|
|
471
|
-
// Security note: This is safe because the module specifier is a hardcoded string literal, not user input.
|
|
472
|
-
(async () => {
|
|
473
|
-
const dynamicImport = new Function("specifier", "return import(specifier)");
|
|
474
|
-
const { HomebridgePluginUiServer } = await dynamicImport("@homebridge/plugin-ui-utils");
|
|
461
|
+
/**
|
|
462
|
+
* Entry point called by homebridge-ui/server.js. That file stays plain
|
|
463
|
+
* CommonJS outside the TypeScript build, so it can load the ESM-only
|
|
464
|
+
* @homebridge/plugin-ui-utils package with a native dynamic import (this
|
|
465
|
+
* compiled bundle cannot — tsc rewrites dynamic imports for CommonJS
|
|
466
|
+
* output) and then hands the constructor over.
|
|
467
|
+
*/
|
|
468
|
+
function startUiServer(HomebridgePluginUiServer) {
|
|
475
469
|
new RoborockUiServer(HomebridgePluginUiServer);
|
|
476
|
-
}
|
|
470
|
+
}
|
|
477
471
|
//# sourceMappingURL=index.js.map
|
package/dist/ui/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"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"}
|
package/homebridge-ui/server.js
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// @homebridge/plugin-ui-utils v2+ ships as an ES module, which CommonJS
|
|
4
|
+
// code cannot load synchronously. This file is never compiled, so the
|
|
5
|
+
// native dynamic import below survives as written; the module specifier is
|
|
6
|
+
// a fixed string literal. Once loaded, the constructor is handed to the
|
|
7
|
+
// compiled server implementation in dist/ui.
|
|
8
|
+
(async () => {
|
|
9
|
+
const { HomebridgePluginUiServer } = await import(
|
|
10
|
+
"@homebridge/plugin-ui-utils"
|
|
11
|
+
);
|
|
12
|
+
const { startUiServer } = require("../dist/ui/index.js");
|
|
13
|
+
startUiServer(HomebridgePluginUiServer);
|
|
14
|
+
})().catch((error) => {
|
|
15
|
+
console.error(
|
|
16
|
+
"Failed to start the Roborock plugin UI server:",
|
|
17
|
+
error && error.message ? error.message : error
|
|
18
|
+
);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
});
|
package/package.json
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homebridge-roborock-vacuum",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "Roborock Vacuum Cleaner - plugin for Homebridge.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"homebridge-plugin",
|
|
8
8
|
"vacuum cleaner",
|
|
9
9
|
"roborock app",
|
|
10
|
-
"roborock vacuum"
|
|
10
|
+
"roborock vacuum",
|
|
11
|
+
"supports-hap",
|
|
12
|
+
"support-matter",
|
|
13
|
+
"roborock",
|
|
14
|
+
"homekit"
|
|
11
15
|
],
|
|
12
16
|
"repository": {
|
|
13
17
|
"type": "git",
|
|
@@ -65,9 +65,27 @@ const dockTypes = {
|
|
|
65
65
|
2: "Empty Wash Fill Dock",
|
|
66
66
|
3: "Empty Wash Fill (Dry) Dock",
|
|
67
67
|
5: "Auto-Empty Dock (Q8 Max+)",
|
|
68
|
+
6: "Empty Wash Fill Dry Dock (S7 Max Ultra)",
|
|
68
69
|
7: "Empty Wash Fill Dry Dock (S8 Pro Ultra)",
|
|
69
70
|
8: "Empty Wash Fill Dry Dock (Q Revo)",
|
|
70
71
|
9: "Empty Wash Fill Dry Dock (Q Revo Pro)",
|
|
72
|
+
10: "Empty Wash Fill Dry Dock (o5)",
|
|
73
|
+
11: "Empty Wash Fill Dry Dock (shell_2s)",
|
|
74
|
+
13: "Empty Wash Fill Dry Dock (couple dock)",
|
|
75
|
+
14: "Empty Wash Fill Dry Dock (shell_3)",
|
|
76
|
+
15: "Empty Wash Fill Dry Dock (shell_2c)",
|
|
77
|
+
16: "Empty Wash Fill Dry Dock (shell_3s)",
|
|
78
|
+
17: "Empty Wash Fill Dry Dock (Qrevo Curv)",
|
|
79
|
+
18: "Empty Wash Fill Dry Dock (Saros 10)",
|
|
80
|
+
19: "Empty Wash Fill Dry Dock (k1c)",
|
|
81
|
+
20: "Empty Wash Fill Dry Dock (k1s)",
|
|
82
|
+
21: "Empty Wash Fill Dry Dock (shell_e)",
|
|
83
|
+
22: "Empty Wash Fill Dry Dock (Qrevo S5V)",
|
|
84
|
+
23: "Empty Wash Fill Dry Dock (shell_3c)",
|
|
85
|
+
27: "Empty Wash Fill Dry Dock (Saros 20)",
|
|
86
|
+
28: "Empty Wash Fill Dry Dock (k1c lite)",
|
|
87
|
+
30: "Empty Wash Fill Dry Dock (shell_2e lite)",
|
|
88
|
+
40: "Empty Wash Fill Dry Dock (shell_2e heat)",
|
|
71
89
|
};
|
|
72
90
|
|
|
73
91
|
|
|
@@ -1202,6 +1220,13 @@ class deviceFeatures {
|
|
|
1202
1220
|
this.isSupportedDrying();
|
|
1203
1221
|
break;
|
|
1204
1222
|
default:
|
|
1223
|
+
// Every dock code not listed above (10-40 and any future code) is a
|
|
1224
|
+
// full-featured dock: collect + wash + dry. Only the small legacy
|
|
1225
|
+
// exception set above lacks features, so unknown codes must enable
|
|
1226
|
+
// everything instead of silently disabling dock controls.
|
|
1227
|
+
this.isDustCollectionSettingSupported();
|
|
1228
|
+
this.isWashThenChargeCmdSupported();
|
|
1229
|
+
this.isSupportedDrying();
|
|
1205
1230
|
break;
|
|
1206
1231
|
}
|
|
1207
1232
|
}
|
|
@@ -15,6 +15,9 @@ const BROADCAST_TOKEN = Buffer.from("qWKYcdQWrbm9hPqe", "utf8");
|
|
|
15
15
|
const MAX_SEGMENT_LENGTH = 8 * 1024 * 1024; // 8 MB per frame
|
|
16
16
|
const MAX_CHUNK_BUFFER = 16 * 1024 * 1024; // 16 MB total buffered
|
|
17
17
|
const RECONNECT_DELAY = 60000;
|
|
18
|
+
// Minimum spacing between cloud-side IP refreshes per device, so the
|
|
19
|
+
// reconnect loop cannot flood the cloud API when a device stays unreachable.
|
|
20
|
+
const IP_REFRESH_MIN_INTERVAL = 60000;
|
|
18
21
|
|
|
19
22
|
class EnhancedSocket extends net.Socket {
|
|
20
23
|
constructor(options) {
|
|
@@ -70,6 +73,7 @@ class localConnector {
|
|
|
70
73
|
this.localClients = {};
|
|
71
74
|
this.l01HandshakeWaiters = new Map();
|
|
72
75
|
this.reconnectTimeouts = new Map();
|
|
76
|
+
this.lastIpRefresh = new Map();
|
|
73
77
|
this.shuttingDown = false;
|
|
74
78
|
}
|
|
75
79
|
|
|
@@ -85,6 +89,13 @@ class localConnector {
|
|
|
85
89
|
client
|
|
86
90
|
.connect(58867, ip, async () => {
|
|
87
91
|
this.adapter.log.debug(`tcp client for ${duid} connected`);
|
|
92
|
+
// A device that was demoted to the cloud path after a failed TCP
|
|
93
|
+
// connect is reachable again — promote it back to local mode.
|
|
94
|
+
if (this.adapter.remoteDevices.delete(duid)) {
|
|
95
|
+
this.adapter.log.info(
|
|
96
|
+
`Local connection for ${duid} restored. Switching back from cloud to local mode.`
|
|
97
|
+
);
|
|
98
|
+
}
|
|
88
99
|
this.ensureL01Handshake(duid).catch((error) => {
|
|
89
100
|
this.adapter.log.debug(
|
|
90
101
|
`L01 handshake on connect failed for ${duid}: ${error.message}`
|
|
@@ -108,6 +119,10 @@ class localConnector {
|
|
|
108
119
|
this.adapter.remoteDevices.add(duid);
|
|
109
120
|
// this.adapter.catchError(`Failed to create tcp client: ${error.stack}`, `function createClient`, duid);
|
|
110
121
|
}
|
|
122
|
+
// Keep probing in the background (with a cloud-side IP refresh) so a
|
|
123
|
+
// device that becomes reachable — or got a new DHCP address — is
|
|
124
|
+
// promoted back to local mode instead of staying cloud-only forever.
|
|
125
|
+
this.scheduleReconnect(duid, ip);
|
|
111
126
|
});
|
|
112
127
|
|
|
113
128
|
client.on("data", async (message) => {
|
|
@@ -270,11 +285,42 @@ class localConnector {
|
|
|
270
285
|
duid,
|
|
271
286
|
setTimeout(async () => {
|
|
272
287
|
this.reconnectTimeouts.delete(duid);
|
|
273
|
-
|
|
288
|
+
// The IP captured at startup goes stale when DHCP hands the device a
|
|
289
|
+
// new address; re-query it over the cloud before dialing.
|
|
290
|
+
const refreshedIp = await this.refreshLocalIp(duid);
|
|
291
|
+
await this.createClient(duid, refreshedIp || ip);
|
|
274
292
|
}, RECONNECT_DELAY)
|
|
275
293
|
);
|
|
276
294
|
}
|
|
277
295
|
|
|
296
|
+
// Re-query the device's current local IP over the cloud channel
|
|
297
|
+
// (get_network_info updates adapter.localDevices). Rate-limited per device;
|
|
298
|
+
// returns the freshest known IP or undefined when none is available.
|
|
299
|
+
async refreshLocalIp(duid) {
|
|
300
|
+
const now = Date.now();
|
|
301
|
+
const lastRefresh = this.lastIpRefresh.get(duid) || 0;
|
|
302
|
+
if (now - lastRefresh >= IP_REFRESH_MIN_INTERVAL) {
|
|
303
|
+
this.lastIpRefresh.set(duid, now);
|
|
304
|
+
try {
|
|
305
|
+
if (
|
|
306
|
+
this.adapter.hasInitializedVacuum &&
|
|
307
|
+
this.adapter.hasInitializedVacuum(duid)
|
|
308
|
+
) {
|
|
309
|
+
await this.adapter.vacuums[duid].getParameter(
|
|
310
|
+
duid,
|
|
311
|
+
"get_network_info"
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
} catch (error) {
|
|
315
|
+
this.adapter.log.debug(
|
|
316
|
+
`Cloud IP refresh failed for ${duid}: ${error && error.message}`
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
return this.adapter.localDevices[duid];
|
|
322
|
+
}
|
|
323
|
+
|
|
278
324
|
shutdown() {
|
|
279
325
|
this.shuttingDown = true;
|
|
280
326
|
|
|
@@ -474,11 +520,19 @@ class localConnector {
|
|
|
474
520
|
});
|
|
475
521
|
|
|
476
522
|
server.on("error", (error) => {
|
|
477
|
-
|
|
523
|
+
// Port 58866 may already be taken by another Roborock integration on
|
|
524
|
+
// the same host. Discovery is best-effort (get_network_info provides
|
|
525
|
+
// IPs too), so a bind failure must not abort device creation.
|
|
526
|
+
this.adapter.log.warn(
|
|
527
|
+
`UDP discovery unavailable (${error.message}). Continuing without it; local IPs will come from the cloud instead.`
|
|
528
|
+
);
|
|
478
529
|
closeServer();
|
|
530
|
+
if (this.localDevicesTimeout) {
|
|
531
|
+
this.adapter.clearTimeout(this.localDevicesTimeout);
|
|
532
|
+
}
|
|
479
533
|
if (!settled) {
|
|
480
534
|
settled = true;
|
|
481
|
-
|
|
535
|
+
resolve(devices);
|
|
482
536
|
}
|
|
483
537
|
});
|
|
484
538
|
|
|
@@ -533,7 +587,7 @@ class localConnector {
|
|
|
533
587
|
decipher.update(input),
|
|
534
588
|
decipher.final(),
|
|
535
589
|
]);
|
|
536
|
-
const unpadded = safeRemovePkcs7(decryptedBuf);
|
|
590
|
+
const unpadded = this.safeRemovePkcs7(decryptedBuf);
|
|
537
591
|
|
|
538
592
|
// 若原協定內容是 UTF-8,這裡再轉字串;否則直接回傳 Buffer 讓上層處理
|
|
539
593
|
return unpadded.toString("utf8");
|
|
@@ -15,7 +15,7 @@ class messageQueueHandler {
|
|
|
15
15
|
const mqttConnectionState = this.adapter.rr_mqtt_connector.isConnected();
|
|
16
16
|
const localConnectionState = this.adapter.localConnector.isConnected(duid);
|
|
17
17
|
|
|
18
|
-
let useCloudConnection = remoteConnection || secure || photo || method == "get_network_info";
|
|
18
|
+
let useCloudConnection = remoteConnection || secure || photo || method == "get_network_info" || method == "service.get_net_info";
|
|
19
19
|
if (!useCloudConnection && !localConnectionState && mqttConnectionState) {
|
|
20
20
|
useCloudConnection = true;
|
|
21
21
|
this.adapter.log.info(`Local connection unavailable for ${duid}. Falling back to cloud connection for method ${method}.`);
|
|
@@ -69,17 +69,7 @@ class roborock_mqtt_connector {
|
|
|
69
69
|
|
|
70
70
|
await client.on("connect", (result) => {
|
|
71
71
|
if (typeof result != "undefined") {
|
|
72
|
-
|
|
73
|
-
if (err) {
|
|
74
|
-
this.adapter.catchError(
|
|
75
|
-
`Failed to subscribe to Roborock MQTT Server! Error: ${err}, granted: ${JSON.stringify(granted)}`,
|
|
76
|
-
`client.on("connect")`
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
clearTimeout(timeout);
|
|
81
|
-
|
|
82
|
-
this.connected = true;
|
|
72
|
+
this.subscribeAndMarkConnected(timeout, `client.on("connect")`);
|
|
83
73
|
}
|
|
84
74
|
this.adapter.log.debug(
|
|
85
75
|
`MQTT connection connected ${JSON.stringify(result)}.`
|
|
@@ -108,15 +98,7 @@ class roborock_mqtt_connector {
|
|
|
108
98
|
`mqtt client reconnect`
|
|
109
99
|
);
|
|
110
100
|
} else {
|
|
111
|
-
|
|
112
|
-
if (err) {
|
|
113
|
-
this.adapter.catchError(
|
|
114
|
-
`Failed to subscribe to Roborock MQTT Server! Error: ${err}, granted: ${JSON.stringify(granted)}`,
|
|
115
|
-
`client.on("reconnect")`
|
|
116
|
-
);
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
clearTimeout(timeout);
|
|
101
|
+
this.subscribeAndMarkConnected(timeout, `client.on("reconnect")`);
|
|
120
102
|
}
|
|
121
103
|
this.adapter.log.info(`MQTT connection reconnect.`);
|
|
122
104
|
});
|
|
@@ -131,6 +113,29 @@ class roborock_mqtt_connector {
|
|
|
131
113
|
});
|
|
132
114
|
}
|
|
133
115
|
|
|
116
|
+
// The connection only counts as healthy once the device-topic subscription
|
|
117
|
+
// is granted: a connected broker session with a failed subscribe can never
|
|
118
|
+
// deliver a response, and reporting it as connected would suppress the
|
|
119
|
+
// local-connection fallback. Note the broker signals a rejected
|
|
120
|
+
// subscription via qos 128 in the grant, not via err.
|
|
121
|
+
subscribeAndMarkConnected(connectTimeout, context) {
|
|
122
|
+
client.subscribe(`rr/m/o/${rriot.u}/${mqttUser}/#`, (err, granted) => {
|
|
123
|
+
const rejected = !err && granted && granted[0] && granted[0].qos === 128;
|
|
124
|
+
|
|
125
|
+
if (err || rejected) {
|
|
126
|
+
this.connected = false;
|
|
127
|
+
this.adapter.catchError(
|
|
128
|
+
`Failed to subscribe to Roborock MQTT Server! Error: ${err}, granted: ${JSON.stringify(granted)}`,
|
|
129
|
+
context
|
|
130
|
+
);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
clearTimeout(connectTimeout);
|
|
135
|
+
this.connected = true;
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
134
139
|
async isArray(what) {
|
|
135
140
|
return Object.prototype.toString.call(what) === "[object Array]";
|
|
136
141
|
}
|
|
@@ -21,13 +21,13 @@ function generateKeys() {
|
|
|
21
21
|
crypto.generateKeyPair(
|
|
22
22
|
"rsa",
|
|
23
23
|
{ modulusLength: 2048 },
|
|
24
|
-
(error, publicKey,
|
|
24
|
+
(error, publicKey, secretKey) => {
|
|
25
25
|
if (error) {
|
|
26
26
|
reject(error);
|
|
27
27
|
return;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
const jwk =
|
|
30
|
+
const jwk = secretKey.export({ format: "jwk" });
|
|
31
31
|
resolve({
|
|
32
32
|
public: {
|
|
33
33
|
n: jwkToHex(jwk.n),
|
|
@@ -44,7 +44,7 @@ function generateKeys() {
|
|
|
44
44
|
coeff: jwkToHex(jwk.qi),
|
|
45
45
|
},
|
|
46
46
|
publicKey,
|
|
47
|
-
|
|
47
|
+
secretKey,
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
50
|
);
|
|
@@ -186,20 +186,43 @@ class vacuum {
|
|
|
186
186
|
try {
|
|
187
187
|
if (parameter == "get_network_info") {
|
|
188
188
|
mode = parameter;
|
|
189
|
-
|
|
189
|
+
// B01 devices do not answer get_network_info; they expose the same
|
|
190
|
+
// data via service.get_net_info, with the IP under inconsistent
|
|
191
|
+
// field names depending on firmware (ip / ipAddress / ipAdress).
|
|
192
|
+
const version = await this.adapter.getRobotVersion(duid);
|
|
193
|
+
const method =
|
|
194
|
+
version == "B01" ? "service.get_net_info" : "get_network_info";
|
|
195
|
+
let networkInfo = await this.adapter.messageQueueHandler.sendRequest(
|
|
190
196
|
duid,
|
|
191
|
-
|
|
197
|
+
method,
|
|
192
198
|
[]
|
|
193
199
|
);
|
|
194
200
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
201
|
+
if (Array.isArray(networkInfo)) {
|
|
202
|
+
networkInfo = networkInfo[0];
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (networkInfo && typeof networkInfo == "object") {
|
|
206
|
+
if (!networkInfo.ip) {
|
|
207
|
+
const alternateIp = networkInfo.ipAddress || networkInfo.ipAdress;
|
|
208
|
+
if (alternateIp) {
|
|
209
|
+
networkInfo.ip = alternateIp;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
for (const attribute in networkInfo) {
|
|
214
|
+
// Devices demoted to the cloud path after a TCP failure
|
|
215
|
+
// (remoteDevices) still record their IP here so the reconnect
|
|
216
|
+
// loop can dial the fresh address; only devices shared from
|
|
217
|
+
// another account can never be local.
|
|
218
|
+
if (attribute == "ip" && !this.adapter.isSharedDevice(duid)) {
|
|
219
|
+
this.adapter.localDevices[duid] = networkInfo[attribute];
|
|
220
|
+
}
|
|
221
|
+
this.adapter.setStateAsync(
|
|
222
|
+
`Devices.${duid}.networkInfo.${attribute}`,
|
|
223
|
+
{ val: networkInfo[attribute], ack: true }
|
|
224
|
+
);
|
|
198
225
|
}
|
|
199
|
-
this.adapter.setStateAsync(
|
|
200
|
-
`Devices.${duid}.networkInfo.${attribute}`,
|
|
201
|
-
{ val: networkInfo[attribute], ack: true }
|
|
202
|
-
);
|
|
203
226
|
}
|
|
204
227
|
} else if (parameter == "get_consumable") {
|
|
205
228
|
const consumables = (
|
|
@@ -33,16 +33,36 @@ function md5hex(str) {
|
|
|
33
33
|
return crypto.createHash("md5").update(str).digest("hex");
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
// Dock types whose station
|
|
37
|
-
|
|
36
|
+
// Dock types whose station cannot wash the mop: 0 = plain charging dock,
|
|
37
|
+
// 1 and 5 = auto-empty only. Every other dock code (2, 3, 6-40 and future
|
|
38
|
+
// generations) washes the mop, so the gate is membership in this small
|
|
39
|
+
// exception set rather than an ever-growing wash-capable list
|
|
40
|
+
// (see deviceFeatures.processDockType).
|
|
41
|
+
const NON_MOP_WASHING_DOCK_TYPES = [0, 1, 5];
|
|
42
|
+
|
|
43
|
+
// Bundled i18n catalogs, loaded statically so translation lookup never
|
|
44
|
+
// hands a computed path to the module loader.
|
|
45
|
+
const TRANSLATIONS = {
|
|
46
|
+
de: require("./i18n/de/translations.json"),
|
|
47
|
+
en: require("./i18n/en/translations.json"),
|
|
48
|
+
es: require("./i18n/es/translations.json"),
|
|
49
|
+
fr: require("./i18n/fr/translations.json"),
|
|
50
|
+
it: require("./i18n/it/translations.json"),
|
|
51
|
+
nl: require("./i18n/nl/translations.json"),
|
|
52
|
+
pl: require("./i18n/pl/translations.json"),
|
|
53
|
+
pt: require("./i18n/pt/translations.json"),
|
|
54
|
+
ru: require("./i18n/ru/translations.json"),
|
|
55
|
+
uk: require("./i18n/uk/translations.json"),
|
|
56
|
+
"zh-cn": require("./i18n/zh-cn/translations.json"),
|
|
57
|
+
"zh-tw": require("./i18n/zh-tw/translations.json"),
|
|
58
|
+
};
|
|
38
59
|
|
|
39
60
|
// Only languages with a bundled i18n catalog are accepted; anything else
|
|
40
|
-
//
|
|
61
|
+
// falls back to English.
|
|
41
62
|
function sanitizeLanguage(language) {
|
|
42
63
|
if (
|
|
43
64
|
typeof language === "string" &&
|
|
44
|
-
|
|
45
|
-
fs.existsSync(path.join(__dirname, "i18n", language, "translations.json"))
|
|
65
|
+
Object.prototype.hasOwnProperty.call(TRANSLATIONS, language)
|
|
46
66
|
) {
|
|
47
67
|
return language;
|
|
48
68
|
}
|
|
@@ -325,9 +345,6 @@ class Roborock {
|
|
|
325
345
|
if (this.config.storagePath) {
|
|
326
346
|
candidates.push(this.config.storagePath);
|
|
327
347
|
}
|
|
328
|
-
if (process.env.HOMEBRIDGE_STORAGE_PATH) {
|
|
329
|
-
candidates.push(process.env.HOMEBRIDGE_STORAGE_PATH);
|
|
330
|
-
}
|
|
331
348
|
candidates.push(path.resolve(__dirname, "./data"));
|
|
332
349
|
candidates.push(path.join(os.tmpdir(), "homebridge-roborock-vacuum"));
|
|
333
350
|
|
|
@@ -412,9 +429,7 @@ class Roborock {
|
|
|
412
429
|
this.log.info(
|
|
413
430
|
`Starting adapter. This might take a few minutes depending on your setup. Please wait.`
|
|
414
431
|
);
|
|
415
|
-
this.translations =
|
|
416
|
-
`./i18n/${this.language || "en"}/translations.json`
|
|
417
|
-
);
|
|
432
|
+
this.translations = TRANSLATIONS[this.language] || TRANSLATIONS.en;
|
|
418
433
|
|
|
419
434
|
// create new clientID if it doesn't exist yet
|
|
420
435
|
let clientID = "";
|
|
@@ -591,6 +606,8 @@ class Roborock {
|
|
|
591
606
|
|
|
592
607
|
this.roomIDs[roomID] = roomName;
|
|
593
608
|
}
|
|
609
|
+
|
|
610
|
+
await this.loadSharedDeviceRooms();
|
|
594
611
|
this.log.debug(`RoomIDs debug: ${JSON.stringify(this.roomIDs)}`);
|
|
595
612
|
|
|
596
613
|
// reconnect every 3 hours (10800 seconds)
|
|
@@ -1042,7 +1059,9 @@ class Roborock {
|
|
|
1042
1059
|
try {
|
|
1043
1060
|
await this.api.post(`user/scene/${sceneID.val}/execute`);
|
|
1044
1061
|
} catch (error) {
|
|
1045
|
-
this.
|
|
1062
|
+
if (!this.handleApiUnauthorized(error, "executeScene")) {
|
|
1063
|
+
this.catchError(error.stack, "executeScene");
|
|
1064
|
+
}
|
|
1046
1065
|
}
|
|
1047
1066
|
}
|
|
1048
1067
|
}
|
|
@@ -1089,7 +1108,9 @@ class Roborock {
|
|
|
1089
1108
|
|
|
1090
1109
|
return response.data;
|
|
1091
1110
|
} catch (error) {
|
|
1092
|
-
this.
|
|
1111
|
+
if (!this.handleApiUnauthorized(error, "getScenes")) {
|
|
1112
|
+
this.log.error(`Failed to get scenes: ${error.message}`);
|
|
1113
|
+
}
|
|
1093
1114
|
throw error;
|
|
1094
1115
|
}
|
|
1095
1116
|
}
|
|
@@ -1235,6 +1256,45 @@ class Roborock {
|
|
|
1235
1256
|
return !!receivedDevice || this.remoteDevices.has(duid);
|
|
1236
1257
|
}
|
|
1237
1258
|
|
|
1259
|
+
// Rooms of a device shared from another account are not part of this
|
|
1260
|
+
// account's home data, so their segment ids would never resolve to names.
|
|
1261
|
+
// Query them per shared device and merge into roomIDs. Room entries carry
|
|
1262
|
+
// their id as either `id` or `roomId` depending on the backend.
|
|
1263
|
+
async loadSharedDeviceRooms() {
|
|
1264
|
+
for (const device of this.receivedDevices || []) {
|
|
1265
|
+
try {
|
|
1266
|
+
const response = await this.api.get(
|
|
1267
|
+
`user/deviceshare/query/${device.duid}/rooms`
|
|
1268
|
+
);
|
|
1269
|
+
const rooms = response?.data?.result;
|
|
1270
|
+
if (!Array.isArray(rooms)) {
|
|
1271
|
+
continue;
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
for (const room of rooms) {
|
|
1275
|
+
const roomID = room.id !== undefined ? room.id : room.roomId;
|
|
1276
|
+
if (roomID !== undefined && room.name) {
|
|
1277
|
+
this.roomIDs[roomID] = room.name;
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
} catch (error) {
|
|
1281
|
+
this.log.warn(
|
|
1282
|
+
`Failed to load rooms for shared device ${device.duid}: ${error && error.message}`
|
|
1283
|
+
);
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
// A device shared from another account (receivedDevices) can never use the
|
|
1289
|
+
// local connection. Unlike isRemoteDevice, this excludes remoteDevices
|
|
1290
|
+
// membership, which is only a temporary TCP-failure fallback.
|
|
1291
|
+
isSharedDevice(duid) {
|
|
1292
|
+
const homedata = this.getParsedHomeData();
|
|
1293
|
+
const received = this.receivedDevices || homedata?.receivedDevices || [];
|
|
1294
|
+
|
|
1295
|
+
return received.some((device) => device.duid == duid);
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1238
1298
|
async getConnector(duid) {
|
|
1239
1299
|
const isRemote = await this.isRemoteDevice(duid);
|
|
1240
1300
|
|
|
@@ -1416,9 +1476,72 @@ class Roborock {
|
|
|
1416
1476
|
this.log.warn("homedata failed to download");
|
|
1417
1477
|
}
|
|
1418
1478
|
} catch (error) {
|
|
1419
|
-
this.
|
|
1479
|
+
if (!this.handleApiUnauthorized(error, "updateHomeData")) {
|
|
1480
|
+
this.log.error(
|
|
1481
|
+
`Failed to update updateHomeData with error: ${error}`
|
|
1482
|
+
);
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
/**
|
|
1489
|
+
* Shared 401 handling for the Hawk-signed cloud API. Two distinct causes:
|
|
1490
|
+
* - Host clock skew: the Hawk signature embeds a local timestamp, so NTP
|
|
1491
|
+
* drift (common on NAS hosts) invalidates every request. Detected via the
|
|
1492
|
+
* server Date header; self-heals once the clock is fixed, so polling
|
|
1493
|
+
* continues and only a clear hint is logged.
|
|
1494
|
+
* - Invalidated session (password change, session revoked): retrying forever
|
|
1495
|
+
* just loops the same error, so the cached session is cleared and the
|
|
1496
|
+
* HomeData polling stops until the user re-authenticates.
|
|
1497
|
+
* Returns true when the error was a 401 and has been handled here.
|
|
1498
|
+
*/
|
|
1499
|
+
handleApiUnauthorized(error, context) {
|
|
1500
|
+
if (!error || !error.response || error.response.status !== 401) {
|
|
1501
|
+
return false;
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1504
|
+
const serverDate = error.response.headers?.date;
|
|
1505
|
+
if (serverDate) {
|
|
1506
|
+
const skewSeconds = Math.round(
|
|
1507
|
+
(new Date(serverDate).getTime() - Date.now()) / 1000
|
|
1508
|
+
);
|
|
1509
|
+
if (Number.isFinite(skewSeconds) && Math.abs(skewSeconds) > 60) {
|
|
1510
|
+
// Skew 401s hit every signed request; log the hint at most every 10 min.
|
|
1511
|
+
const now = Date.now();
|
|
1512
|
+
if (
|
|
1513
|
+
!this.lastClockSkewWarning ||
|
|
1514
|
+
now - this.lastClockSkewWarning > 10 * 60 * 1000
|
|
1515
|
+
) {
|
|
1516
|
+
this.lastClockSkewWarning = now;
|
|
1517
|
+
this.log.error(
|
|
1518
|
+
`Roborock API rejected the request (401) in ${context}, and this host's clock is off by ${skewSeconds} seconds from the server. ` +
|
|
1519
|
+
`Fix the system time (enable NTP) — the API request signature embeds a timestamp, so large clock skew invalidates every request.`
|
|
1520
|
+
);
|
|
1521
|
+
}
|
|
1522
|
+
return true;
|
|
1420
1523
|
}
|
|
1421
1524
|
}
|
|
1525
|
+
|
|
1526
|
+
if (this.sessionInvalidated) {
|
|
1527
|
+
return true;
|
|
1528
|
+
}
|
|
1529
|
+
this.sessionInvalidated = true;
|
|
1530
|
+
|
|
1531
|
+
this.log.warn(
|
|
1532
|
+
`Roborock API rejected the session (401) in ${context}. ` +
|
|
1533
|
+
`Clearing the cached session — please re-authenticate in the plugin settings and restart Homebridge.`
|
|
1534
|
+
);
|
|
1535
|
+
|
|
1536
|
+
this.userData = null;
|
|
1537
|
+
this.deleteStateAsync("UserData");
|
|
1538
|
+
|
|
1539
|
+
if (this.homedataInterval) {
|
|
1540
|
+
this.clearInterval(this.homedataInterval);
|
|
1541
|
+
this.homedataInterval = undefined;
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1544
|
+
return true;
|
|
1422
1545
|
}
|
|
1423
1546
|
|
|
1424
1547
|
async updateConsumablesPercent(devices) {
|
|
@@ -2235,10 +2358,13 @@ class Roborock {
|
|
|
2235
2358
|
this.log.debug(`isDockWashSupported: ${error}`);
|
|
2236
2359
|
}
|
|
2237
2360
|
|
|
2238
|
-
const dockType =
|
|
2239
|
-
`Devices.${duid}.deviceStatus.dock_type`
|
|
2361
|
+
const dockType = Number(
|
|
2362
|
+
this.getStateAsync(`Devices.${duid}.deviceStatus.dock_type`)?.val
|
|
2363
|
+
);
|
|
2364
|
+
return (
|
|
2365
|
+
Number.isFinite(dockType) &&
|
|
2366
|
+
!NON_MOP_WASHING_DOCK_TYPES.includes(dockType)
|
|
2240
2367
|
);
|
|
2241
|
-
return MOP_WASHING_DOCK_TYPES.includes(Number(dockType?.val));
|
|
2242
2368
|
}
|
|
2243
2369
|
|
|
2244
2370
|
/**
|
|
@@ -2378,11 +2504,19 @@ class Roborock {
|
|
|
2378
2504
|
this.log.debug(`getCleanModeCapabilities: ${error}`);
|
|
2379
2505
|
}
|
|
2380
2506
|
|
|
2507
|
+
// The Qrevo Edge 2 (a298) does not use the classic 200-203 water levels:
|
|
2508
|
+
// it keeps 200 = Off but replaces 201-203 with banded levels 221-250,
|
|
2509
|
+
// so writing the classic default 202 would be rejected by the device.
|
|
2510
|
+
// 233 is the middle ("Medium") band. The sibling Qrevo Edge (a187) still
|
|
2511
|
+
// uses the classic values.
|
|
2512
|
+
const model = this.getProductAttribute(duid, "model");
|
|
2513
|
+
const usesBandedWaterLevels = model === "roborock.vacuum.a298";
|
|
2514
|
+
|
|
2381
2515
|
return {
|
|
2382
2516
|
fanOff: 105,
|
|
2383
2517
|
fanDefault: 102,
|
|
2384
2518
|
waterOff: 200,
|
|
2385
|
-
waterDefault: 202,
|
|
2519
|
+
waterDefault: usesBandedWaterLevels ? 233 : 202,
|
|
2386
2520
|
mopSupported: mopSupported,
|
|
2387
2521
|
};
|
|
2388
2522
|
}
|