@cecnic1989/homebridge-roborock-mower 0.2.0 → 0.2.2
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/README.md +4 -2
- package/dist/mower/accessory.d.ts +5 -0
- package/dist/mower/accessory.js +41 -8
- package/dist/mower/accessory.js.map +1 -1
- package/dist/platform.d.ts +16 -5
- package/dist/platform.js +218 -77
- package/dist/platform.js.map +1 -1
- package/dist/roborock/mqtt-client.d.ts +1 -0
- package/dist/roborock/mqtt-client.js +8 -0
- package/dist/roborock/mqtt-client.js.map +1 -1
- package/dist/roborock/session-store.d.ts +19 -0
- package/dist/roborock/session-store.js +33 -9
- package/dist/roborock/session-store.js.map +1 -1
- package/dist/roborock/web-api.js +5 -0
- package/dist/roborock/web-api.js.map +1 -1
- package/dist/ui/server.js +42 -10
- package/dist/ui/server.js.map +1 -1
- package/homebridge-ui/public/index.html +2 -0
- package/homebridge-ui/public/index.js +50 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -30,8 +30,10 @@ Each state is a contact sensor so the Home app can trigger on it ("A Sensor Dete
|
|
|
30
30
|
| **Mowing** | it starts cutting or driving to a zone | cutting stops |
|
|
31
31
|
| **Returning** | it heads back to the dock | it reaches the dock |
|
|
32
32
|
|
|
33
|
-
Example for a dock inside a garage: *
|
|
34
|
-
|
|
33
|
+
Example for a dock inside a garage: *Docked opens → open garage*, *Mowing opens → close garage*, *Returning opens → open garage*, *Docked closes → close garage*.
|
|
34
|
+
Prefer **Docked opens** over *Leaving opens* for the departure trigger: both fire on the same push, but Docked can only open once per trip. The mower starts driving ~1.5 s after that push, so if the door needs longer, add a time-based automation on the mowing schedule as well.
|
|
35
|
+
|
|
36
|
+
Accessories take the name you gave the mower in the Roborock app (renames follow on the next sync); names you set in the Home app are kept.
|
|
35
37
|
|
|
36
38
|
Sensors flip only after a state holds for `sensorDebounceSeconds` (default 3 s); faults and battery update immediately. While the cloud connection is down, sensors show as inactive rather than stale.
|
|
37
39
|
|
|
@@ -25,10 +25,15 @@ export declare class MowerAccessory {
|
|
|
25
25
|
private readonly applied;
|
|
26
26
|
private readonly pending;
|
|
27
27
|
private last;
|
|
28
|
+
private baseName;
|
|
29
|
+
private readonly debounceMs;
|
|
28
30
|
constructor(hap: Hap, accessory: PlatformAccessory, log: Logging, options: SensorOptions);
|
|
29
31
|
setInformation(info: DeviceInformation): void;
|
|
32
|
+
rename(displayName: string): void;
|
|
30
33
|
update(state: DerivedState): void;
|
|
31
34
|
setOnline(online: boolean): void;
|
|
35
|
+
dispose(): void;
|
|
36
|
+
private sensorName;
|
|
32
37
|
private schedule;
|
|
33
38
|
private apply;
|
|
34
39
|
private pushFault;
|
package/dist/mower/accessory.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const SENSOR_LABELS = { docked: 'Docked', leaving: 'Leaving', mowing: 'Mowing', returning: 'Returning' };
|
|
2
2
|
const SENSOR_KEYS = Object.keys(SENSOR_LABELS);
|
|
3
3
|
// Home-app automations trigger on "opens"/"closes". Docked closes when the mower is home;
|
|
4
|
-
// the activity sensors open when their activity starts, so "
|
|
4
|
+
// the activity sensors open when their activity starts, so "Docked opens → open the garage" reads naturally.
|
|
5
5
|
function contactValue(key, active, c) {
|
|
6
6
|
const detected = c.ContactSensorState.CONTACT_DETECTED;
|
|
7
7
|
const notDetected = c.ContactSensorState.CONTACT_NOT_DETECTED;
|
|
@@ -20,12 +20,16 @@ export class MowerAccessory {
|
|
|
20
20
|
applied = new Map();
|
|
21
21
|
pending = new Map();
|
|
22
22
|
last = {};
|
|
23
|
+
baseName;
|
|
24
|
+
debounceMs;
|
|
23
25
|
constructor(hap, accessory, log, options) {
|
|
24
26
|
this.hap = hap;
|
|
25
27
|
this.accessory = accessory;
|
|
26
28
|
this.log = log;
|
|
27
29
|
this.options = options;
|
|
28
30
|
const { Service, Characteristic } = hap;
|
|
31
|
+
this.baseName = accessory.displayName;
|
|
32
|
+
this.debounceMs = Number.isFinite(options.debounceSeconds) && options.debounceSeconds > 0 ? options.debounceSeconds * 1000 : 0;
|
|
29
33
|
if (!accessory.getService(Service.AccessoryInformation)) {
|
|
30
34
|
accessory.addService(Service.AccessoryInformation);
|
|
31
35
|
}
|
|
@@ -37,15 +41,20 @@ export class MowerAccessory {
|
|
|
37
41
|
}
|
|
38
42
|
continue;
|
|
39
43
|
}
|
|
40
|
-
|
|
41
|
-
|
|
44
|
+
if (existing) {
|
|
45
|
+
// Restored from cache: leave Name/ConfiguredName alone so renames made in the Home app survive restarts.
|
|
46
|
+
this.sensors.set(key, existing);
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
const name = this.sensorName(key);
|
|
50
|
+
const service = accessory.addService(Service.ContactSensor, name, key);
|
|
42
51
|
service.setCharacteristic(Characteristic.Name, name);
|
|
43
52
|
service.setCharacteristic(Characteristic.ConfiguredName, name);
|
|
44
53
|
this.sensors.set(key, service);
|
|
45
54
|
}
|
|
46
55
|
const existingBattery = accessory.getService(Service.Battery);
|
|
47
56
|
if (options.battery) {
|
|
48
|
-
this.battery = existingBattery ?? accessory.addService(Service.Battery, `${
|
|
57
|
+
this.battery = existingBattery ?? accessory.addService(Service.Battery, `${this.baseName} Battery`);
|
|
49
58
|
}
|
|
50
59
|
else if (existingBattery) {
|
|
51
60
|
accessory.removeService(existingBattery);
|
|
@@ -59,6 +68,21 @@ export class MowerAccessory {
|
|
|
59
68
|
.setCharacteristic(Characteristic.SerialNumber, info.serial ?? this.accessory.UUID)
|
|
60
69
|
.setCharacteristic(Characteristic.FirmwareRevision, info.firmware ?? '0');
|
|
61
70
|
}
|
|
71
|
+
// Follows a rename made in the Roborock app. ConfiguredName is only touched if the user never changed it in Home.
|
|
72
|
+
rename(displayName) {
|
|
73
|
+
const c = this.hap.Characteristic;
|
|
74
|
+
const previousBase = this.baseName;
|
|
75
|
+
this.baseName = displayName;
|
|
76
|
+
for (const [key, service] of this.sensors) {
|
|
77
|
+
const previous = `${previousBase} ${SENSOR_LABELS[key]}`;
|
|
78
|
+
const next = this.sensorName(key);
|
|
79
|
+
service.updateCharacteristic(c.Name, next);
|
|
80
|
+
if (service.getCharacteristic(c.ConfiguredName).value === previous) {
|
|
81
|
+
service.updateCharacteristic(c.ConfiguredName, next);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
this.battery?.updateCharacteristic(c.Name, `${displayName} Battery`);
|
|
85
|
+
}
|
|
62
86
|
update(state) {
|
|
63
87
|
for (const key of this.sensors.keys()) {
|
|
64
88
|
this.schedule(key, state[key]);
|
|
@@ -71,7 +95,16 @@ export class MowerAccessory {
|
|
|
71
95
|
service.updateCharacteristic(this.hap.Characteristic.StatusActive, online);
|
|
72
96
|
}
|
|
73
97
|
}
|
|
74
|
-
|
|
98
|
+
dispose() {
|
|
99
|
+
for (const pending of this.pending.values()) {
|
|
100
|
+
clearTimeout(pending.timer);
|
|
101
|
+
}
|
|
102
|
+
this.pending.clear();
|
|
103
|
+
}
|
|
104
|
+
sensorName(key) {
|
|
105
|
+
return `${this.baseName} ${SENSOR_LABELS[key]}`;
|
|
106
|
+
}
|
|
107
|
+
// Activity flags must hold for the debounce period before HomeKit sees them; the first value is applied immediately.
|
|
75
108
|
schedule(key, value) {
|
|
76
109
|
const pending = this.pending.get(key);
|
|
77
110
|
if (this.applied.get(key) === value) {
|
|
@@ -87,20 +120,20 @@ export class MowerAccessory {
|
|
|
87
120
|
if (pending) {
|
|
88
121
|
clearTimeout(pending.timer);
|
|
89
122
|
}
|
|
90
|
-
if (!this.applied.has(key) || this.
|
|
123
|
+
if (!this.applied.has(key) || this.debounceMs === 0) {
|
|
91
124
|
this.apply(key, value);
|
|
92
125
|
return;
|
|
93
126
|
}
|
|
94
127
|
const timer = setTimeout(() => {
|
|
95
128
|
this.pending.delete(key);
|
|
96
129
|
this.apply(key, value);
|
|
97
|
-
}, this.
|
|
130
|
+
}, this.debounceMs);
|
|
98
131
|
this.pending.set(key, { value, timer });
|
|
99
132
|
}
|
|
100
133
|
apply(key, value) {
|
|
101
134
|
this.applied.set(key, value);
|
|
102
135
|
this.sensors.get(key)?.updateCharacteristic(this.hap.Characteristic.ContactSensorState, contactValue(key, value, this.hap.Characteristic));
|
|
103
|
-
this.log.debug(`${this.
|
|
136
|
+
this.log.debug(`${this.baseName}: ${SENSOR_LABELS[key]} ${value ? 'on' : 'off'}`);
|
|
104
137
|
}
|
|
105
138
|
pushFault(fault) {
|
|
106
139
|
if (!this.options.faultIndicator || this.last.fault === fault) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accessory.js","sourceRoot":"","sources":["../../src/mower/accessory.ts"],"names":[],"mappings":"AAuBA,MAAM,aAAa,GAA8B,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC;AACpI,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,CAAgB,CAAC;AAE9D,0FAA0F;AAC1F,
|
|
1
|
+
{"version":3,"file":"accessory.js","sourceRoot":"","sources":["../../src/mower/accessory.ts"],"names":[],"mappings":"AAuBA,MAAM,aAAa,GAA8B,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC;AACpI,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,CAAgB,CAAC;AAE9D,0FAA0F;AAC1F,6GAA6G;AAC7G,SAAS,YAAY,CAAC,GAAc,EAAE,MAAe,EAAE,CAAwB;IAC7E,MAAM,QAAQ,GAAG,CAAC,CAAC,kBAAkB,CAAC,gBAAgB,CAAC;IACvD,MAAM,WAAW,GAAG,CAAC,CAAC,kBAAkB,CAAC,oBAAoB,CAAC;IAC9D,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;QACrB,OAAO,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC;IACzC,CAAC;IACD,OAAO,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC;AACzC,CAAC;AAED,MAAM,OAAO,cAAc;IAUN;IACR;IACQ;IACA;IAZF,OAAO,GAAG,IAAI,GAAG,EAAsB,CAAC;IACxC,OAAO,CAAW;IAClB,OAAO,GAAG,IAAI,GAAG,EAAsB,CAAC;IACxC,OAAO,GAAG,IAAI,GAAG,EAAwD,CAAC;IACnF,IAAI,GAAiF,EAAE,CAAC;IACxF,QAAQ,CAAS;IACR,UAAU,CAAS;IAEpC,YACmB,GAAQ,EAChB,SAA4B,EACpB,GAAY,EACZ,OAAsB;QAHtB,QAAG,GAAH,GAAG,CAAK;QAChB,cAAS,GAAT,SAAS,CAAmB;QACpB,QAAG,GAAH,GAAG,CAAS;QACZ,YAAO,GAAP,OAAO,CAAe;QAEvC,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,GAAG,CAAC;QACxC,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC,WAAW,CAAC;QACtC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,OAAO,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/H,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE,CAAC;YACxD,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QACrD,CAAC;QAED,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;YAC9B,MAAM,QAAQ,GAAG,SAAS,CAAC,cAAc,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;YACtE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBAClB,IAAI,QAAQ,EAAE,CAAC;oBACb,SAAS,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;gBACpC,CAAC;gBACD,SAAS;YACX,CAAC;YACD,IAAI,QAAQ,EAAE,CAAC;gBACb,yGAAyG;gBACzG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;gBAChC,SAAS;YACX,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YAClC,MAAM,OAAO,GAAG,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;YACvE,OAAO,CAAC,iBAAiB,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACrD,OAAO,CAAC,iBAAiB,CAAC,cAAc,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;YAC/D,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACjC,CAAC;QAED,MAAM,eAAe,GAAG,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC9D,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,IAAI,CAAC,OAAO,GAAG,eAAe,IAAI,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,QAAQ,UAAU,CAAC,CAAC;QACtG,CAAC;aAAM,IAAI,eAAe,EAAE,CAAC;YAC3B,SAAS,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,cAAc,CAAC,IAAuB;QACpC,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC;QAC7C,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,oBAAoB,CAAC;YACrD,EAAE,iBAAiB,CAAC,cAAc,CAAC,YAAY,EAAE,UAAU,CAAC;aAC3D,iBAAiB,CAAC,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC;aACnD,iBAAiB,CAAC,cAAc,CAAC,YAAY,EAAE,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;aAClF,iBAAiB,CAAC,cAAc,CAAC,gBAAgB,EAAE,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC,CAAC;IAC9E,CAAC;IAED,kHAAkH;IAClH,MAAM,CAAC,WAAmB;QACxB,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC;QAClC,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC;QACnC,IAAI,CAAC,QAAQ,GAAG,WAAW,CAAC;QAC5B,KAAK,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAC1C,MAAM,QAAQ,GAAG,GAAG,YAAY,IAAI,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;YACzD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YAClC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC3C,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACnE,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;YACvD,CAAC;QACH,CAAC;QACD,IAAI,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,WAAW,UAAU,CAAC,CAAC;IACvE,CAAC;IAED,MAAM,CAAC,KAAmB;QACxB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YACtC,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QACjC,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC5B,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED,SAAS,CAAC,MAAe;QACvB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YAC5C,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YAC5C,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAEO,UAAU,CAAC,GAAc;QAC/B,OAAO,GAAG,IAAI,CAAC,QAAQ,IAAI,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;IAClD,CAAC;IAED,qHAAqH;IAC7G,QAAQ,CAAC,GAAc,EAAE,KAAc;QAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC;YACpC,IAAI,OAAO,EAAE,CAAC;gBACZ,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBAC5B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC3B,CAAC;YACD,OAAO;QACT,CAAC;QACD,IAAI,OAAO,EAAE,KAAK,KAAK,KAAK,EAAE,CAAC;YAC7B,OAAO;QACT,CAAC;QACD,IAAI,OAAO,EAAE,CAAC;YACZ,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,KAAK,CAAC,EAAE,CAAC;YACpD,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACvB,OAAO;QACT,CAAC;QACD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACzB,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACzB,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACpB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1C,CAAC;IAEO,KAAK,CAAC,GAAc,EAAE,KAAc;QAC1C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC7B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,kBAAkB,EAAE,YAAY,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC;QAC3I,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,QAAQ,KAAK,aAAa,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;IACpF,CAAC;IAEO,SAAS,CAAC,KAAc;QAC9B,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;YAC9D,OAAO;QACT,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACxB,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC;QAClC,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YAC5C,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAC5G,CAAC;IACH,CAAC;IAEO,WAAW,CAAC,KAAmB;QACrC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QACD,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC;QAClC,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACvE,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;YAClC,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACnE,CAAC;QACD,IAAI,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YAC9C,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;YACxC,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,gBAAgB,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,CAAC;QAC3J,CAAC;QACD,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1C,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;YACpC,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,aAAa,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;QAC/H,CAAC;IACH,CAAC;CACF"}
|
package/dist/platform.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { API, Characteristic, DynamicPlatformPlugin, Logging, PlatformAccessory, PlatformConfig, Service } from 'homebridge';
|
|
2
2
|
import type mqtt from 'mqtt';
|
|
3
|
-
import type
|
|
3
|
+
import { type StoredSession } from './roborock/types.js';
|
|
4
4
|
export interface RoborockMowerConfig extends PlatformConfig {
|
|
5
5
|
pollInterval?: number;
|
|
6
6
|
exposeDocked?: boolean;
|
|
@@ -31,16 +31,27 @@ export declare class RoborockMowerPlatform implements DynamicPlatformPlugin {
|
|
|
31
31
|
private homeId?;
|
|
32
32
|
private session?;
|
|
33
33
|
private reconcileTimer?;
|
|
34
|
+
private retryTimer?;
|
|
35
|
+
private startPromise?;
|
|
36
|
+
private stopped;
|
|
37
|
+
private sessionExpiredLogged;
|
|
34
38
|
private readonly mowers;
|
|
35
39
|
constructor(log: Logging, config: PlatformConfig, api: API, deps?: PlatformDeps);
|
|
36
40
|
configureAccessory(accessory: PlatformAccessory): void;
|
|
41
|
+
whenStarted(): Promise<void>;
|
|
42
|
+
pollSeconds(): number;
|
|
43
|
+
reconcile(): Promise<void>;
|
|
37
44
|
private sensorOptions;
|
|
45
|
+
private now;
|
|
38
46
|
private start;
|
|
39
47
|
private stop;
|
|
48
|
+
private startMqtt;
|
|
49
|
+
private restoreFromCache;
|
|
50
|
+
private track;
|
|
51
|
+
private subscribeMqtt;
|
|
52
|
+
private syncFromCloud;
|
|
40
53
|
private syncMowers;
|
|
54
|
+
private remove;
|
|
41
55
|
private applyDps;
|
|
42
|
-
private
|
|
43
|
-
private pollSeconds;
|
|
44
|
-
private scheduleReconcile;
|
|
45
|
-
private reconcile;
|
|
56
|
+
private saveStatus;
|
|
46
57
|
}
|
package/dist/platform.js
CHANGED
|
@@ -1,15 +1,35 @@
|
|
|
1
1
|
import { MowerAccessory } from './mower/accessory.js';
|
|
2
|
-
import { deriveMowerState, describeMowState
|
|
2
|
+
import { deriveMowerState, describeMowState } from './mower/state.js';
|
|
3
3
|
import { findMowers } from './roborock/mower.js';
|
|
4
4
|
import { RoborockMqtt } from './roborock/mqtt-client.js';
|
|
5
|
-
import { readSession } from './roborock/session-store.js';
|
|
5
|
+
import { readSession, writeStatus } from './roborock/session-store.js';
|
|
6
|
+
import { RoborockApiError } from './roborock/types.js';
|
|
6
7
|
import { RoborockWebApi } from './roborock/web-api.js';
|
|
7
8
|
import { PLATFORM_NAME, PLUGIN_NAME } from './settings.js';
|
|
8
9
|
const MIN_POLL_SECONDS = 900; // Roborock rate-limits home data; python-roborock budgets 5/hour.
|
|
10
|
+
const MAX_POLL_SECONDS = 86_400;
|
|
9
11
|
const DEFAULT_POLL_SECONDS = 3600;
|
|
12
|
+
const STARTUP_RETRY_MS = 5 * 60_000;
|
|
13
|
+
const MISSES_BEFORE_REMOVAL = 3;
|
|
14
|
+
const SESSION_EXPIRED = 'session-expired';
|
|
10
15
|
function message(error) {
|
|
11
16
|
return error instanceof Error ? error.message : String(error);
|
|
12
17
|
}
|
|
18
|
+
// Config edited by hand bypasses the schema; never let a bad value become NaN timers.
|
|
19
|
+
function numberOption(value, fallback, min, max) {
|
|
20
|
+
const n = typeof value === 'number' ? value : Number(value);
|
|
21
|
+
if (value === undefined || value === null || value === '' || !Number.isFinite(n)) {
|
|
22
|
+
return fallback;
|
|
23
|
+
}
|
|
24
|
+
return Math.min(max, Math.max(min, n));
|
|
25
|
+
}
|
|
26
|
+
function toCached(device) {
|
|
27
|
+
const { duid, name, model, productName, localKey, sn, fv, pv } = device;
|
|
28
|
+
return { duid, name, model, productName, localKey, sn, fv, pv };
|
|
29
|
+
}
|
|
30
|
+
function isSessionExpired(error) {
|
|
31
|
+
return error instanceof RoborockApiError && (error.code === 2010 || error.code === 401);
|
|
32
|
+
}
|
|
13
33
|
export class RoborockMowerPlatform {
|
|
14
34
|
log;
|
|
15
35
|
config;
|
|
@@ -24,6 +44,10 @@ export class RoborockMowerPlatform {
|
|
|
24
44
|
homeId;
|
|
25
45
|
session;
|
|
26
46
|
reconcileTimer;
|
|
47
|
+
retryTimer;
|
|
48
|
+
startPromise;
|
|
49
|
+
stopped = false;
|
|
50
|
+
sessionExpiredLogged = false;
|
|
27
51
|
mowers = new Map();
|
|
28
52
|
constructor(log, config, api, deps = {}) {
|
|
29
53
|
this.log = log;
|
|
@@ -33,7 +57,9 @@ export class RoborockMowerPlatform {
|
|
|
33
57
|
this.Service = api.hap.Service;
|
|
34
58
|
this.Characteristic = api.hap.Characteristic;
|
|
35
59
|
this.pluginConfig = config;
|
|
36
|
-
this.api.on('didFinishLaunching', () =>
|
|
60
|
+
this.api.on('didFinishLaunching', () => {
|
|
61
|
+
this.startPromise = this.start();
|
|
62
|
+
});
|
|
37
63
|
this.api.on('shutdown', () => this.stop());
|
|
38
64
|
}
|
|
39
65
|
// Called by Homebridge for each accessory restored from cache, before didFinishLaunching.
|
|
@@ -41,6 +67,16 @@ export class RoborockMowerPlatform {
|
|
|
41
67
|
this.log.info(`Loading accessory from cache: ${accessory.displayName}`);
|
|
42
68
|
this.accessories.set(accessory.UUID, accessory);
|
|
43
69
|
}
|
|
70
|
+
whenStarted() {
|
|
71
|
+
return this.startPromise ?? Promise.resolve();
|
|
72
|
+
}
|
|
73
|
+
pollSeconds() {
|
|
74
|
+
return numberOption(this.pluginConfig.pollInterval, DEFAULT_POLL_SECONDS, MIN_POLL_SECONDS, MAX_POLL_SECONDS);
|
|
75
|
+
}
|
|
76
|
+
// Safety net only: re-reads home data so a missed push, a rename, or a new device is picked up eventually.
|
|
77
|
+
async reconcile() {
|
|
78
|
+
await this.syncFromCloud('re-sync');
|
|
79
|
+
}
|
|
44
80
|
sensorOptions() {
|
|
45
81
|
const c = this.pluginConfig;
|
|
46
82
|
return {
|
|
@@ -50,130 +86,235 @@ export class RoborockMowerPlatform {
|
|
|
50
86
|
returning: c.exposeReturning ?? true,
|
|
51
87
|
battery: c.exposeBattery ?? true,
|
|
52
88
|
faultIndicator: c.faultIndicator ?? true,
|
|
53
|
-
debounceSeconds: c.sensorDebounceSeconds
|
|
89
|
+
debounceSeconds: numberOption(c.sensorDebounceSeconds, 3, 0, 60),
|
|
54
90
|
};
|
|
55
91
|
}
|
|
92
|
+
now() {
|
|
93
|
+
return this.deps.now?.() ?? Date.now();
|
|
94
|
+
}
|
|
56
95
|
async start() {
|
|
57
96
|
const session = await (this.deps.readSession ?? readSession)(this.api.user.storagePath());
|
|
58
97
|
if (!session) {
|
|
59
98
|
this.log.warn(`${PLATFORM_NAME}: not signed in. Open the plugin settings in the Homebridge UI to sign in.`);
|
|
60
99
|
return;
|
|
61
100
|
}
|
|
101
|
+
if (this.stopped) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
62
104
|
this.session = session;
|
|
63
105
|
this.webApi = new RoborockWebApi({
|
|
64
106
|
email: session.email, clientId: session.clientId, region: session.region, fetch: this.deps.fetch, now: this.deps.now,
|
|
65
107
|
});
|
|
66
|
-
|
|
108
|
+
// MQTT first: it only needs the session, so cached mowers get live updates even if the cloud is unreachable right now.
|
|
109
|
+
this.startMqtt(session);
|
|
110
|
+
const synced = await this.syncFromCloud('startup');
|
|
111
|
+
if (this.stopped) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (!synced) {
|
|
115
|
+
this.log.warn(`Roborock cloud sync will be retried in ${STARTUP_RETRY_MS / 60_000} minutes.`);
|
|
116
|
+
this.retryTimer = setTimeout(() => void this.reconcile(), STARTUP_RETRY_MS);
|
|
117
|
+
this.retryTimer.unref?.();
|
|
118
|
+
}
|
|
119
|
+
this.reconcileTimer = setInterval(() => void this.reconcile(), this.pollSeconds() * 1000);
|
|
120
|
+
this.reconcileTimer.unref?.();
|
|
121
|
+
}
|
|
122
|
+
stop() {
|
|
123
|
+
this.stopped = true;
|
|
124
|
+
this.mqtt?.stop();
|
|
125
|
+
clearInterval(this.reconcileTimer);
|
|
126
|
+
clearTimeout(this.retryTimer);
|
|
127
|
+
for (const tracked of this.mowers.values()) {
|
|
128
|
+
tracked.accessory.dispose();
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
startMqtt(session) {
|
|
67
132
|
try {
|
|
68
|
-
this.
|
|
69
|
-
|
|
133
|
+
this.mqtt = new RoborockMqtt(session.userData.rriot, this.log, this.deps.connectMqtt);
|
|
134
|
+
this.mqtt.onConnectionChange((connected) => {
|
|
135
|
+
for (const tracked of this.mowers.values()) {
|
|
136
|
+
tracked.accessory.setOnline(connected && tracked.online);
|
|
137
|
+
}
|
|
138
|
+
if (!connected) {
|
|
139
|
+
this.log.warn('Roborock MQTT disconnected; sensors marked inactive until it reconnects.');
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
this.restoreFromCache();
|
|
143
|
+
this.mqtt.start();
|
|
70
144
|
}
|
|
71
145
|
catch (error) {
|
|
72
|
-
this.log.error(`Roborock
|
|
73
|
-
this.
|
|
146
|
+
this.log.error(`Roborock MQTT could not start: ${message(error)}. State will only refresh every ${this.pollSeconds()}s.`);
|
|
147
|
+
this.restoreFromCache();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Accessories Homebridge restored carry the device identity in their context, so they can be tracked before any cloud call.
|
|
151
|
+
restoreFromCache() {
|
|
152
|
+
for (const platformAccessory of this.accessories.values()) {
|
|
153
|
+
const device = platformAccessory.context.device;
|
|
154
|
+
if (device?.duid && !this.mowers.has(device.duid)) {
|
|
155
|
+
this.track(platformAccessory, device);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
track(platformAccessory, device) {
|
|
160
|
+
const accessory = new MowerAccessory(this.api.hap, platformAccessory, this.log, this.sensorOptions());
|
|
161
|
+
accessory.setInformation({ model: device.model, serial: device.sn, firmware: device.fv });
|
|
162
|
+
const tracked = { device, online: true, platformAccessory, accessory, dps: {} };
|
|
163
|
+
this.mowers.set(device.duid, tracked);
|
|
164
|
+
accessory.setOnline(this.mqtt?.connected ?? false);
|
|
165
|
+
this.subscribeMqtt(tracked);
|
|
166
|
+
return tracked;
|
|
167
|
+
}
|
|
168
|
+
subscribeMqtt(tracked) {
|
|
169
|
+
if (!this.mqtt) {
|
|
74
170
|
return;
|
|
75
171
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
172
|
+
if (!tracked.device.localKey) {
|
|
173
|
+
this.log.error(`${tracked.device.name}: no localKey in home data; live updates unavailable.`);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
this.mqtt.subscribe(tracked.device.duid, tracked.device.localKey, (dps) => this.applyDps(tracked, dps, 'push'));
|
|
79
177
|
}
|
|
80
|
-
|
|
81
|
-
this.
|
|
82
|
-
|
|
83
|
-
clearInterval(this.reconcileTimer);
|
|
178
|
+
async syncFromCloud(reason) {
|
|
179
|
+
if (!this.webApi || !this.session) {
|
|
180
|
+
return false;
|
|
84
181
|
}
|
|
182
|
+
let home;
|
|
183
|
+
try {
|
|
184
|
+
this.homeId ??= await this.webApi.getHomeId(this.session.userData);
|
|
185
|
+
home = await this.webApi.getHomeData(this.session.userData, this.homeId);
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
if (isSessionExpired(error)) {
|
|
189
|
+
if (!this.sessionExpiredLogged) {
|
|
190
|
+
this.sessionExpiredLogged = true;
|
|
191
|
+
this.log.error('Roborock session is no longer valid. Sign in again in the plugin settings.');
|
|
192
|
+
}
|
|
193
|
+
await this.saveStatus(SESSION_EXPIRED);
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
this.log.warn(`Roborock cloud ${reason} failed: ${message(error)}`);
|
|
197
|
+
}
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
if (this.stopped) {
|
|
201
|
+
return true;
|
|
202
|
+
}
|
|
203
|
+
this.sessionExpiredLogged = false;
|
|
204
|
+
this.syncMowers(home);
|
|
205
|
+
await this.saveStatus();
|
|
206
|
+
return true;
|
|
85
207
|
}
|
|
86
|
-
// Creates/updates one accessory per mower on the account
|
|
208
|
+
// Creates/updates one accessory per mower on the account; removal needs several consecutive confirmed absences.
|
|
87
209
|
syncMowers(home) {
|
|
88
210
|
const devices = findMowers(home);
|
|
211
|
+
const listed = (home.devices?.length ?? 0) + (home.receivedDevices?.length ?? 0);
|
|
89
212
|
if (devices.length === 0) {
|
|
90
|
-
|
|
91
|
-
|
|
213
|
+
this.log.warn(listed === 0
|
|
214
|
+
? 'Roborock returned an empty device list; keeping the cached mower(s).'
|
|
215
|
+
: `No mower found on this Roborock account (${listed} other device(s)).`);
|
|
92
216
|
}
|
|
93
217
|
const seen = new Set();
|
|
94
218
|
for (const device of devices) {
|
|
95
|
-
|
|
96
|
-
|
|
219
|
+
seen.add(device.duid);
|
|
220
|
+
const cached = toCached(device);
|
|
97
221
|
let tracked = this.mowers.get(device.duid);
|
|
98
222
|
if (!tracked) {
|
|
223
|
+
const uuid = this.api.hap.uuid.generate(device.duid);
|
|
99
224
|
let platformAccessory = this.accessories.get(uuid);
|
|
100
225
|
if (!platformAccessory) {
|
|
101
226
|
platformAccessory = new this.api.platformAccessory(device.name, uuid);
|
|
102
227
|
this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [platformAccessory]);
|
|
103
228
|
this.accessories.set(uuid, platformAccessory);
|
|
104
229
|
}
|
|
105
|
-
|
|
106
|
-
accessory.setInformation({ model: device.model, serial: device.sn, firmware: device.fv });
|
|
107
|
-
tracked = { device, accessory, dps: {} };
|
|
108
|
-
this.mowers.set(device.duid, tracked);
|
|
230
|
+
tracked = this.track(platformAccessory, cached);
|
|
109
231
|
this.log.info(`Found mower "${device.name}" (model=${device.model}, pv=${device.pv}, online=${device.online})`);
|
|
110
232
|
}
|
|
111
|
-
tracked.device
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
233
|
+
else if (!tracked.device.localKey && cached.localKey) {
|
|
234
|
+
tracked.device = cached;
|
|
235
|
+
this.subscribeMqtt(tracked);
|
|
236
|
+
}
|
|
237
|
+
tracked.device = cached;
|
|
238
|
+
const context = tracked.platformAccessory.context;
|
|
239
|
+
context.device = cached;
|
|
240
|
+
context.missedSyncs = 0;
|
|
241
|
+
context.lastSeenAt = this.now();
|
|
242
|
+
if (tracked.platformAccessory.displayName !== device.name) {
|
|
243
|
+
this.log.info(`Renaming "${tracked.platformAccessory.displayName}" to "${device.name}" (changed in the Roborock app)`);
|
|
244
|
+
tracked.platformAccessory.displayName = device.name;
|
|
245
|
+
tracked.accessory.rename(device.name);
|
|
246
|
+
}
|
|
247
|
+
this.api.updatePlatformAccessories([tracked.platformAccessory]);
|
|
248
|
+
// The cloud snapshot can lag the live pushes; only use it when we have nothing fresher.
|
|
249
|
+
const connected = this.mqtt?.connected ?? false;
|
|
250
|
+
if (tracked.lastPushAt === undefined || !connected) {
|
|
251
|
+
this.applyDps(tracked, device.deviceStatus ?? {}, 'cloud');
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
this.log.debug(`${device.name}: cloud snapshot ignored in favour of live state: ${JSON.stringify(device.deviceStatus)}`);
|
|
255
|
+
}
|
|
256
|
+
tracked.online = device.online !== false;
|
|
257
|
+
tracked.accessory.setOnline(tracked.online && connected);
|
|
258
|
+
}
|
|
259
|
+
if (listed === 0) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
for (const [duid, tracked] of [...this.mowers]) {
|
|
263
|
+
if (seen.has(duid)) {
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
const context = tracked.platformAccessory.context;
|
|
267
|
+
const missed = (context.missedSyncs ?? 0) + 1;
|
|
268
|
+
context.missedSyncs = missed;
|
|
269
|
+
if (missed >= MISSES_BEFORE_REMOVAL) {
|
|
270
|
+
this.remove(tracked);
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
this.log.warn(`${tracked.device.name} missing from the account (${missed}/${MISSES_BEFORE_REMOVAL} syncs); removed after ${MISSES_BEFORE_REMOVAL}.`);
|
|
274
|
+
this.api.updatePlatformAccessories([tracked.platformAccessory]);
|
|
120
275
|
}
|
|
121
276
|
}
|
|
122
277
|
}
|
|
123
|
-
|
|
124
|
-
|
|
278
|
+
remove(tracked) {
|
|
279
|
+
this.log.info(`Removing accessory no longer on the account: ${tracked.platformAccessory.displayName}`);
|
|
280
|
+
tracked.accessory.dispose();
|
|
281
|
+
this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [tracked.platformAccessory]);
|
|
282
|
+
this.accessories.delete(tracked.platformAccessory.UUID);
|
|
283
|
+
this.mowers.delete(tracked.device.duid);
|
|
284
|
+
}
|
|
285
|
+
applyDps(tracked, update, source) {
|
|
125
286
|
for (const [key, value] of Object.entries(update)) {
|
|
126
287
|
tracked.dps[Number(key)] = value;
|
|
127
288
|
}
|
|
289
|
+
if (source === 'push') {
|
|
290
|
+
tracked.lastPushAt = this.now();
|
|
291
|
+
}
|
|
128
292
|
const state = deriveMowerState(tracked.dps);
|
|
129
|
-
if (state.mowState !==
|
|
293
|
+
if (state.mowState !== tracked.last?.mowState) {
|
|
130
294
|
this.log.info(`${tracked.device.name}: ${describeMowState(state.mowState)} (battery ${state.battery ?? '?'}%)`);
|
|
131
295
|
}
|
|
132
|
-
this.log.debug(`${tracked.device.name} dps: ${JSON.stringify(update)}`);
|
|
296
|
+
this.log.debug(`${tracked.device.name} ${source} dps: ${JSON.stringify(update)}`);
|
|
297
|
+
tracked.last = state;
|
|
133
298
|
tracked.accessory.update(state);
|
|
134
299
|
}
|
|
135
|
-
|
|
300
|
+
async saveStatus(lastError) {
|
|
301
|
+
const devices = [...this.mowers.values()].map((tracked) => ({
|
|
302
|
+
duid: tracked.device.duid,
|
|
303
|
+
name: tracked.device.name,
|
|
304
|
+
model: tracked.device.model,
|
|
305
|
+
productName: tracked.device.productName,
|
|
306
|
+
online: tracked.online,
|
|
307
|
+
fv: tracked.device.fv,
|
|
308
|
+
mowState: tracked.last?.mowState,
|
|
309
|
+
mowStateName: tracked.last ? describeMowState(tracked.last.mowState) : undefined,
|
|
310
|
+
battery: tracked.last?.battery,
|
|
311
|
+
}));
|
|
312
|
+
const status = { updatedAt: this.now(), devices, ...(lastError ? { lastError } : {}) };
|
|
136
313
|
try {
|
|
137
|
-
|
|
138
|
-
this.mqtt.onConnectionChange((connected) => {
|
|
139
|
-
for (const tracked of this.mowers.values()) {
|
|
140
|
-
tracked.accessory.setOnline(connected && tracked.device.online !== false);
|
|
141
|
-
}
|
|
142
|
-
if (!connected) {
|
|
143
|
-
this.log.warn('Roborock MQTT disconnected; sensors marked inactive until it reconnects.');
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
for (const tracked of this.mowers.values()) {
|
|
147
|
-
if (!tracked.device.localKey) {
|
|
148
|
-
this.log.error(`${tracked.device.name}: no localKey in home data; live updates unavailable.`);
|
|
149
|
-
continue;
|
|
150
|
-
}
|
|
151
|
-
this.mqtt.subscribe(tracked.device.duid, tracked.device.localKey, (dps) => this.applyDps(tracked, dps));
|
|
152
|
-
}
|
|
153
|
-
this.mqtt.start();
|
|
154
|
-
}
|
|
155
|
-
catch (error) {
|
|
156
|
-
this.log.error(`Roborock MQTT could not start: ${message(error)}. State will only refresh every ${this.pollSeconds()}s.`);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
pollSeconds() {
|
|
160
|
-
return Math.max(MIN_POLL_SECONDS, this.pluginConfig.pollInterval ?? DEFAULT_POLL_SECONDS);
|
|
161
|
-
}
|
|
162
|
-
// Safety net only: re-reads home data so a missed push or a new device is picked up eventually.
|
|
163
|
-
scheduleReconcile() {
|
|
164
|
-
this.reconcileTimer = setInterval(() => void this.reconcile(), this.pollSeconds() * 1000);
|
|
165
|
-
this.reconcileTimer.unref?.();
|
|
166
|
-
}
|
|
167
|
-
async reconcile() {
|
|
168
|
-
if (!this.webApi || !this.session) {
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
try {
|
|
172
|
-
this.homeId ??= await this.webApi.getHomeId(this.session.userData);
|
|
173
|
-
this.syncMowers(await this.webApi.getHomeData(this.session.userData, this.homeId));
|
|
314
|
+
await writeStatus(this.api.user.storagePath(), status);
|
|
174
315
|
}
|
|
175
316
|
catch (error) {
|
|
176
|
-
this.log.
|
|
317
|
+
this.log.debug(`Could not write status file: ${message(error)}`);
|
|
177
318
|
}
|
|
178
319
|
}
|
|
179
320
|
}
|
package/dist/platform.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,6 +21,7 @@ export declare class RoborockMqtt {
|
|
|
21
21
|
private client?;
|
|
22
22
|
private readonly subscriptions;
|
|
23
23
|
private readonly connectionListeners;
|
|
24
|
+
private lastConnected;
|
|
24
25
|
constructor(rriot: RRiot, log: MqttLogger, connect?: typeof mqtt.connect);
|
|
25
26
|
start(): void;
|
|
26
27
|
get connected(): boolean;
|
|
@@ -19,6 +19,7 @@ export class RoborockMqtt {
|
|
|
19
19
|
client;
|
|
20
20
|
subscriptions = new Map();
|
|
21
21
|
connectionListeners = [];
|
|
22
|
+
lastConnected = false;
|
|
22
23
|
constructor(rriot, log, connect = mqtt.connect) {
|
|
23
24
|
this.rriot = rriot;
|
|
24
25
|
this.log = log;
|
|
@@ -44,6 +45,7 @@ export class RoborockMqtt {
|
|
|
44
45
|
this.emitConnection(true);
|
|
45
46
|
});
|
|
46
47
|
this.client.on('close', () => this.emitConnection(false));
|
|
48
|
+
this.client.on('offline', () => this.emitConnection(false));
|
|
47
49
|
this.client.on('reconnect', () => this.log.debug('Roborock MQTT reconnecting'));
|
|
48
50
|
this.client.on('error', (error) => this.log.warn(`Roborock MQTT error: ${error.message}`));
|
|
49
51
|
this.client.on('message', (topic, payload) => this.onMessage(topic, payload));
|
|
@@ -54,6 +56,7 @@ export class RoborockMqtt {
|
|
|
54
56
|
stop() {
|
|
55
57
|
const client = this.client;
|
|
56
58
|
this.client = undefined;
|
|
59
|
+
this.lastConnected = false;
|
|
57
60
|
client?.removeAllListeners();
|
|
58
61
|
client?.end(true);
|
|
59
62
|
}
|
|
@@ -93,7 +96,12 @@ export class RoborockMqtt {
|
|
|
93
96
|
}
|
|
94
97
|
}
|
|
95
98
|
}
|
|
99
|
+
// mqtt.js emits close after every failed reconnect attempt; listeners only want the transitions.
|
|
96
100
|
emitConnection(connected) {
|
|
101
|
+
if (connected === this.lastConnected) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
this.lastConnected = connected;
|
|
97
105
|
for (const listener of this.connectionListeners) {
|
|
98
106
|
listener(connected);
|
|
99
107
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mqtt-client.js","sourceRoot":"","sources":["../../src/roborock/mqtt-client.ts"],"names":[],"mappings":"AAAA,OAAO,IAAyB,MAAM,MAAM,CAAC;AAE7C,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEzD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAgBjF,wEAAwE;AACxE,MAAM,UAAU,eAAe,CAAC,KAAkE;IAChG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO;QACL,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;QACtD,QAAQ,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;KACpD,CAAC;AACJ,CAAC;AAOD,MAAM,OAAO,YAAY;
|
|
1
|
+
{"version":3,"file":"mqtt-client.js","sourceRoot":"","sources":["../../src/roborock/mqtt-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
import type { StoredSession } from './types.js';
|
|
2
2
|
export declare function sessionPath(storagePath: string): string;
|
|
3
|
+
export declare function statusPath(storagePath: string): string;
|
|
4
|
+
export interface StatusDevice {
|
|
5
|
+
duid: string;
|
|
6
|
+
name: string;
|
|
7
|
+
model: string;
|
|
8
|
+
productName?: string;
|
|
9
|
+
online: boolean;
|
|
10
|
+
fv?: string;
|
|
11
|
+
mowState?: number;
|
|
12
|
+
mowStateName?: string;
|
|
13
|
+
battery?: number;
|
|
14
|
+
}
|
|
15
|
+
export interface PlatformStatus {
|
|
16
|
+
updatedAt: number;
|
|
17
|
+
devices: StatusDevice[];
|
|
18
|
+
lastError?: string;
|
|
19
|
+
}
|
|
3
20
|
export declare function readSession(storagePath: string): Promise<StoredSession | undefined>;
|
|
4
21
|
export declare function writeSession(storagePath: string, session: StoredSession): Promise<void>;
|
|
5
22
|
export declare function clearSession(storagePath: string): Promise<void>;
|
|
23
|
+
export declare function readStatus(storagePath: string): Promise<PlatformStatus | undefined>;
|
|
24
|
+
export declare function writeStatus(storagePath: string, status: PlatformStatus): Promise<void>;
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import { chmod, mkdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
1
|
+
import { chmod, mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
3
|
// Lives outside config.json so the Homebridge UI's schema form can never overwrite it.
|
|
4
4
|
export function sessionPath(storagePath) {
|
|
5
5
|
return join(storagePath, 'roborock-mower', 'session.json');
|
|
6
6
|
}
|
|
7
|
+
export function statusPath(storagePath) {
|
|
8
|
+
return join(storagePath, 'roborock-mower', 'status.json');
|
|
9
|
+
}
|
|
7
10
|
function isSession(value) {
|
|
8
11
|
const candidate = value;
|
|
9
12
|
return typeof candidate?.email === 'string'
|
|
@@ -12,29 +15,50 @@ function isSession(value) {
|
|
|
12
15
|
&& typeof candidate.userData?.token === 'string'
|
|
13
16
|
&& typeof candidate.userData.rriot === 'object';
|
|
14
17
|
}
|
|
15
|
-
|
|
18
|
+
async function readJson(path) {
|
|
16
19
|
let raw;
|
|
17
20
|
try {
|
|
18
|
-
raw = await readFile(
|
|
21
|
+
raw = await readFile(path, 'utf8');
|
|
19
22
|
}
|
|
20
23
|
catch {
|
|
21
24
|
return undefined;
|
|
22
25
|
}
|
|
23
26
|
try {
|
|
24
|
-
|
|
25
|
-
return isSession(parsed) ? parsed : undefined;
|
|
27
|
+
return JSON.parse(raw);
|
|
26
28
|
}
|
|
27
29
|
catch {
|
|
28
30
|
return undefined;
|
|
29
31
|
}
|
|
30
32
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
// Write to a sibling temp file and rename so a crash mid-write never leaves a truncated file behind.
|
|
34
|
+
async function writeFileAtomic(path, data, mode) {
|
|
33
35
|
await mkdir(dirname(path), { recursive: true });
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
const tmp = `${path}.${process.pid}.tmp`;
|
|
37
|
+
try {
|
|
38
|
+
await writeFile(tmp, data, { mode });
|
|
39
|
+
await chmod(tmp, mode);
|
|
40
|
+
await rename(tmp, path);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
await rm(tmp, { force: true }).catch(() => undefined);
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export async function readSession(storagePath) {
|
|
48
|
+
const parsed = await readJson(sessionPath(storagePath));
|
|
49
|
+
return isSession(parsed) ? parsed : undefined;
|
|
50
|
+
}
|
|
51
|
+
export async function writeSession(storagePath, session) {
|
|
52
|
+
await writeFileAtomic(sessionPath(storagePath), JSON.stringify(session, null, 2), 0o600);
|
|
36
53
|
}
|
|
37
54
|
export async function clearSession(storagePath) {
|
|
38
55
|
await rm(sessionPath(storagePath), { force: true });
|
|
39
56
|
}
|
|
57
|
+
export async function readStatus(storagePath) {
|
|
58
|
+
const parsed = await readJson(statusPath(storagePath));
|
|
59
|
+
return typeof parsed?.updatedAt === 'number' && Array.isArray(parsed.devices) ? parsed : undefined;
|
|
60
|
+
}
|
|
61
|
+
export async function writeStatus(storagePath, status) {
|
|
62
|
+
await writeFileAtomic(statusPath(storagePath), JSON.stringify(status, null, 2), 0o600);
|
|
63
|
+
}
|
|
40
64
|
//# sourceMappingURL=session-store.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-store.js","sourceRoot":"","sources":["../../src/roborock/session-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"session-store.js","sourceRoot":"","sources":["../../src/roborock/session-store.ts"],"names":[],"mappings":"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"}
|
package/dist/roborock/web-api.js
CHANGED
|
@@ -80,6 +80,7 @@ export class RoborockWebApi {
|
|
|
80
80
|
}
|
|
81
81
|
// Asks each regional host whether it knows the account; the answer also carries the country values the login needs.
|
|
82
82
|
async resolveRegion() {
|
|
83
|
+
let unreachable = 0;
|
|
83
84
|
for (const baseUrl of this.candidates) {
|
|
84
85
|
const url = new URL('/api/v1/getUrlByEmail', baseUrl);
|
|
85
86
|
url.searchParams.set('email', this.email);
|
|
@@ -89,6 +90,7 @@ export class RoborockWebApi {
|
|
|
89
90
|
envelope = await this.call(url, { method: 'POST', headers: this.loginHeaders() });
|
|
90
91
|
}
|
|
91
92
|
catch {
|
|
93
|
+
unreachable++;
|
|
92
94
|
continue;
|
|
93
95
|
}
|
|
94
96
|
if (envelope.code === 2003 || envelope.code === 1001) {
|
|
@@ -100,6 +102,9 @@ export class RoborockWebApi {
|
|
|
100
102
|
return this.region;
|
|
101
103
|
}
|
|
102
104
|
}
|
|
105
|
+
if (unreachable === this.candidates.length) {
|
|
106
|
+
throw new RoborockApiError('Could not reach the Roborock servers (network or DNS). Check connectivity and try again.');
|
|
107
|
+
}
|
|
103
108
|
throw new RoborockApiError('Could not find a Roborock region for this account. Check the email address.');
|
|
104
109
|
}
|
|
105
110
|
requestEmailCode() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-api.js","sourceRoot":"","sources":["../../src/roborock/web-api.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"web-api.js","sourceRoot":"","sources":["../../src/roborock/web-api.ts"],"names":[],"mappings":"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"}
|
package/dist/ui/server.js
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import { HomebridgePluginUiServer, RequestError } from '@homebridge/plugin-ui-utils';
|
|
3
|
+
import { describeMowState, deriveMowerState } from '../mower/state.js';
|
|
3
4
|
import { findMowers } from '../roborock/mower.js';
|
|
4
|
-
import { clearSession, readSession, writeSession } from '../roborock/session-store.js';
|
|
5
|
+
import { clearSession, readSession, readStatus, writeSession, writeStatus } from '../roborock/session-store.js';
|
|
5
6
|
import { RoborockWebApi } from '../roborock/web-api.js';
|
|
7
|
+
const STALE_AFTER_MS = 2 * 60 * 60_000;
|
|
6
8
|
class RoborockMowerUiServer extends HomebridgePluginUiServer {
|
|
9
|
+
// One cloud client per account for the life of this UI process, so the send/verify pair shares its rate limiter.
|
|
10
|
+
current;
|
|
7
11
|
constructor() {
|
|
8
12
|
super();
|
|
9
13
|
this.onRequest('/session', () => this.guard(() => this.session()));
|
|
@@ -19,36 +23,64 @@ class RoborockMowerUiServer extends HomebridgePluginUiServer {
|
|
|
19
23
|
}
|
|
20
24
|
return this.homebridgeStoragePath;
|
|
21
25
|
}
|
|
26
|
+
apiFor(email, clientId, region) {
|
|
27
|
+
if (this.current?.email !== email || this.current.clientId !== clientId) {
|
|
28
|
+
this.current = { email, clientId, api: new RoborockWebApi({ email, clientId, region }) };
|
|
29
|
+
}
|
|
30
|
+
return this.current.api;
|
|
31
|
+
}
|
|
22
32
|
async session() {
|
|
23
33
|
const session = await readSession(this.storagePath);
|
|
24
|
-
|
|
34
|
+
const status = await readStatus(this.storagePath);
|
|
35
|
+
return { email: session?.email ?? null, lastError: status?.lastError };
|
|
25
36
|
}
|
|
26
37
|
async sendCode({ email }) {
|
|
27
38
|
const clientId = randomUUID();
|
|
28
|
-
const
|
|
29
|
-
const region = await api.requestEmailCode();
|
|
39
|
+
const region = await this.apiFor(email, clientId).requestEmailCode();
|
|
30
40
|
return { clientId, region };
|
|
31
41
|
}
|
|
32
42
|
async verifyCode({ email, clientId, region, code }) {
|
|
33
|
-
const
|
|
34
|
-
const userData = await api.loginWithCode(code.trim());
|
|
43
|
+
const userData = await this.apiFor(email, clientId, region).loginWithCode(code.trim());
|
|
35
44
|
await writeSession(this.storagePath, { email, clientId, region, userData });
|
|
45
|
+
await writeStatus(this.storagePath, { updatedAt: 0, devices: [] }); // clears any session-expired flag
|
|
36
46
|
return { email };
|
|
37
47
|
}
|
|
38
48
|
async signOut() {
|
|
39
49
|
await clearSession(this.storagePath);
|
|
40
50
|
}
|
|
51
|
+
// Serves the platform's status file; only a freshly signed-in account (no status yet) costs a cloud call.
|
|
41
52
|
async devices() {
|
|
53
|
+
const status = await readStatus(this.storagePath);
|
|
54
|
+
if (status && status.updatedAt > 0) {
|
|
55
|
+
return { ...status, stale: Date.now() - status.updatedAt > STALE_AFTER_MS };
|
|
56
|
+
}
|
|
42
57
|
const session = await readSession(this.storagePath);
|
|
43
58
|
if (!session) {
|
|
44
59
|
throw new Error('Not signed in.');
|
|
45
60
|
}
|
|
46
|
-
const
|
|
61
|
+
const fresh = await this.fetchStatus(session);
|
|
62
|
+
await writeStatus(this.storagePath, fresh);
|
|
63
|
+
return { ...fresh, stale: false };
|
|
64
|
+
}
|
|
65
|
+
async fetchStatus(session) {
|
|
66
|
+
const api = this.apiFor(session.email, session.clientId, session.region);
|
|
47
67
|
const homeId = await api.getHomeId(session.userData);
|
|
48
68
|
const home = await api.getHomeData(session.userData, homeId);
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
69
|
+
const devices = findMowers(home).map((mower) => {
|
|
70
|
+
const state = deriveMowerState(Object.fromEntries(Object.entries(mower.deviceStatus ?? {}).map(([k, v]) => [Number(k), v])));
|
|
71
|
+
return {
|
|
72
|
+
duid: mower.duid,
|
|
73
|
+
name: mower.name,
|
|
74
|
+
model: mower.model,
|
|
75
|
+
productName: mower.productName,
|
|
76
|
+
online: mower.online !== false,
|
|
77
|
+
fv: mower.fv,
|
|
78
|
+
mowState: state.mowState,
|
|
79
|
+
mowStateName: describeMowState(state.mowState),
|
|
80
|
+
battery: state.battery,
|
|
81
|
+
};
|
|
82
|
+
});
|
|
83
|
+
return { updatedAt: Date.now(), devices };
|
|
52
84
|
}
|
|
53
85
|
async guard(run) {
|
|
54
86
|
try {
|
package/dist/ui/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/ui/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,wBAAwB,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAErF,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/ui/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
</div>
|
|
20
20
|
</div>
|
|
21
21
|
|
|
22
|
+
<div id="session-expired" class="alert alert-warning d-none">Roborock session expired — sign out and sign in again.</div>
|
|
23
|
+
|
|
22
24
|
<div id="signed-in" class="d-none">
|
|
23
25
|
<p>Signed in as <strong id="signed-in-email"></strong></p>
|
|
24
26
|
<button id="sign-out" type="button" class="btn btn-outline-danger btn-sm">Sign out</button>
|
|
@@ -20,37 +20,72 @@
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
function renderDevices({
|
|
23
|
+
function renderDevices({ devices, updatedAt, stale }) {
|
|
24
24
|
const container = $('devices');
|
|
25
25
|
container.replaceChildren();
|
|
26
|
-
if (
|
|
26
|
+
if (devices.length === 0) {
|
|
27
27
|
const p = document.createElement('p');
|
|
28
28
|
p.className = 'text-warning';
|
|
29
|
-
p.textContent =
|
|
29
|
+
p.textContent = 'No mower found on this account. Restart Homebridge after adding one in the Roborock app.';
|
|
30
30
|
container.appendChild(p);
|
|
31
31
|
return;
|
|
32
32
|
}
|
|
33
|
-
for (const
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
33
|
+
for (const device of devices) {
|
|
34
|
+
const row = document.createElement('div');
|
|
35
|
+
row.className = 'mb-2';
|
|
36
|
+
const title = document.createElement('strong');
|
|
37
|
+
title.textContent = device.name;
|
|
38
|
+
const detail = document.createElement('div');
|
|
39
|
+
detail.className = 'small';
|
|
40
|
+
const bits = [device.model, device.online ? (device.mowStateName ?? 'state unknown') : 'offline'];
|
|
41
|
+
if (device.battery !== undefined) {
|
|
42
|
+
bits.push(`battery ${device.battery}%`);
|
|
43
|
+
}
|
|
44
|
+
if (device.fv) {
|
|
45
|
+
bits.push(`firmware ${device.fv}`);
|
|
46
|
+
}
|
|
47
|
+
detail.textContent = bits.join(' · ');
|
|
48
|
+
row.append(title, detail);
|
|
49
|
+
container.appendChild(row);
|
|
42
50
|
}
|
|
51
|
+
const when = document.createElement('p');
|
|
52
|
+
when.className = 'small mt-2';
|
|
53
|
+
const minutes = Math.max(0, Math.round((Date.now() - updatedAt) / 60_000));
|
|
54
|
+
when.textContent = `Last synced ${minutes} min ago${stale ? ' — is Homebridge running?' : ''}.`;
|
|
55
|
+
container.appendChild(when);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// A freshly installed plugin has no platform block yet; without one Homebridge never starts the platform.
|
|
59
|
+
let platformBlockUnsaved = false;
|
|
60
|
+
|
|
61
|
+
async function ensurePlatformBlock() {
|
|
62
|
+
const configs = await homebridge.getPluginConfig();
|
|
63
|
+
if (configs.length > 0) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
await homebridge.updatePluginConfig([{ platform: 'RoborockMower' }]);
|
|
67
|
+
platformBlockUnsaved = true;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async function savePlatformBlockIfNew() {
|
|
71
|
+
if (!platformBlockUnsaved) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
await homebridge.savePluginConfig();
|
|
75
|
+
platformBlockUnsaved = false;
|
|
43
76
|
}
|
|
44
77
|
|
|
45
78
|
async function render() {
|
|
46
79
|
let email = null;
|
|
80
|
+
let lastError;
|
|
47
81
|
try {
|
|
48
|
-
({ email } = await request('/session'));
|
|
82
|
+
({ email, lastError } = await request('/session'));
|
|
49
83
|
} catch (error) {
|
|
50
84
|
homebridge.toast.error(error.message, 'Could not read sign-in state');
|
|
51
85
|
}
|
|
52
86
|
show($('signed-out'), !email);
|
|
53
87
|
show($('signed-in'), Boolean(email));
|
|
88
|
+
show($('session-expired'), lastError === 'session-expired');
|
|
54
89
|
if (!email) {
|
|
55
90
|
return;
|
|
56
91
|
}
|
|
@@ -89,6 +124,7 @@
|
|
|
89
124
|
try {
|
|
90
125
|
await request('/auth/verify-code', { email: $('email').value.trim(), code, ...pending });
|
|
91
126
|
pending = null;
|
|
127
|
+
await savePlatformBlockIfNew();
|
|
92
128
|
homebridge.toast.success('Signed in. Restart Homebridge to apply.');
|
|
93
129
|
await render();
|
|
94
130
|
} catch (error) {
|
|
@@ -106,6 +142,7 @@
|
|
|
106
142
|
await render();
|
|
107
143
|
});
|
|
108
144
|
|
|
145
|
+
await ensurePlatformBlock();
|
|
109
146
|
homebridge.showSchemaForm();
|
|
110
147
|
await render();
|
|
111
148
|
})();
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@cecnic1989/homebridge-roborock-mower",
|
|
3
3
|
"displayName": "Homebridge Roborock Mower",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "0.2.
|
|
5
|
+
"version": "0.2.2",
|
|
6
6
|
"description": "Homebridge plugin for Roborock RockMow robot lawn mowers",
|
|
7
7
|
"author": "cecnic1989",
|
|
8
8
|
"license": "Apache-2.0",
|