@cecnic1989/homebridge-roborock-mower 0.1.1 → 0.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/README.md +32 -20
- package/config.schema.json +67 -12
- package/dist/mower/accessory.d.ts +37 -0
- package/dist/mower/accessory.js +134 -0
- package/dist/mower/accessory.js.map +1 -0
- package/dist/mower/state.d.ts +29 -0
- package/dist/mower/state.js +73 -0
- package/dist/mower/state.js.map +1 -0
- package/dist/platform.d.ts +32 -2
- package/dist/platform.js +157 -5
- package/dist/platform.js.map +1 -1
- package/dist/roborock/crypto.d.ts +11 -0
- package/dist/roborock/crypto.js +29 -0
- package/dist/roborock/crypto.js.map +1 -0
- package/dist/roborock/mower.d.ts +8 -0
- package/dist/roborock/mower.js +12 -0
- package/dist/roborock/mower.js.map +1 -0
- package/dist/roborock/mqtt-client.d.ts +34 -0
- package/dist/roborock/mqtt-client.js +102 -0
- package/dist/roborock/mqtt-client.js.map +1 -0
- package/dist/roborock/rate-limiter.d.ts +14 -0
- package/dist/roborock/rate-limiter.js +35 -0
- package/dist/roborock/rate-limiter.js.map +1 -0
- package/dist/roborock/session-store.d.ts +5 -0
- package/dist/roborock/session-store.js +40 -0
- package/dist/roborock/session-store.js.map +1 -0
- package/dist/roborock/types.d.ts +61 -0
- package/dist/roborock/types.js +9 -0
- package/dist/roborock/types.js.map +1 -0
- package/dist/roborock/v1-protocol.d.ts +10 -0
- package/dist/roborock/v1-protocol.js +76 -0
- package/dist/roborock/v1-protocol.js.map +1 -0
- package/dist/roborock/web-api.d.ts +49 -0
- package/dist/roborock/web-api.js +220 -0
- package/dist/roborock/web-api.js.map +1 -0
- package/dist/ui/server.d.ts +1 -0
- package/dist/ui/server.js +65 -0
- package/dist/ui/server.js.map +1 -0
- package/homebridge-ui/public/index.html +30 -0
- package/homebridge-ui/public/index.js +133 -0
- package/homebridge-ui/server.js +2 -0
- package/package.json +14 -2
package/README.md
CHANGED
|
@@ -9,15 +9,31 @@
|
|
|
9
9
|
|
|
10
10
|
Homebridge plugin for Roborock RockMow robot lawn mowers. Exposes your mower to Apple Home.
|
|
11
11
|
|
|
12
|
-
> **Early development.**
|
|
12
|
+
> **Early development.** Status sensors and battery work (tested on a RockMow Z1 / X120H). Controls are next.
|
|
13
13
|
|
|
14
14
|
## Features
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
- **State sensors** for Home-app automations: Docked, Leaving, Mowing, Returning (each a contact sensor, live via Roborock's cloud push)
|
|
17
|
+
- **Battery** level, charging state, low-battery flag
|
|
18
|
+
- **Fault indicator** on every sensor when the mower reports an error
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
Planned: start / pause / return-to-dock controls.
|
|
21
|
+
|
|
22
|
+
## Automations
|
|
23
|
+
|
|
24
|
+
Each state is a contact sensor so the Home app can trigger on it ("A Sensor Detects Something"):
|
|
25
|
+
|
|
26
|
+
| Sensor | Opens when | Closes when |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| **Docked** | it leaves the dock | it is back on the dock (charging or charged) |
|
|
29
|
+
| **Leaving** | a job starts (initializing / undocking) | it begins cutting |
|
|
30
|
+
| **Mowing** | it starts cutting or driving to a zone | cutting stops |
|
|
31
|
+
| **Returning** | it heads back to the dock | it reaches the dock |
|
|
32
|
+
|
|
33
|
+
Example for a dock inside a garage: *Leaving opens → open garage*, *Mowing opens → close garage*, *Returning opens → open garage*, *Docked closes → close garage*.
|
|
34
|
+
Note: the mower starts driving ~1.5 s after "Leaving" opens, so for the outbound trip pair it with a time-based automation on the mowing schedule if the door needs longer.
|
|
35
|
+
|
|
36
|
+
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.
|
|
21
37
|
|
|
22
38
|
## Requirements
|
|
23
39
|
|
|
@@ -31,26 +47,22 @@ Homebridge UI: **Plugins** → search `@cecnic1989/homebridge-roborock-mower`.
|
|
|
31
47
|
|
|
32
48
|
## Configuration
|
|
33
49
|
|
|
34
|
-
|
|
50
|
+
1. Homebridge UI → **Plugins** → **Roborock Mower** → **Settings**.
|
|
51
|
+
2. Enter your Roborock account email and press **Send code**.
|
|
52
|
+
3. Enter the verification code Roborock emails you and press **Verify & save**.
|
|
53
|
+
4. Restart Homebridge.
|
|
35
54
|
|
|
36
|
-
|
|
37
|
-
{
|
|
38
|
-
"platforms": [
|
|
39
|
-
{
|
|
40
|
-
"platform": "RoborockMower",
|
|
41
|
-
"name": "Roborock Mower"
|
|
42
|
-
}
|
|
43
|
-
]
|
|
44
|
-
}
|
|
45
|
-
```
|
|
55
|
+
Sign-in stores the cloud token in `<homebridge storage>/roborock-mower/session.json` (owner-only permissions); treat it like a password. Use **Sign out** in the settings page to remove it.
|
|
46
56
|
|
|
47
|
-
|
|
57
|
+
Optional fields:
|
|
48
58
|
|
|
49
59
|
| Field | Default | Description |
|
|
50
60
|
|---|---|---|
|
|
51
|
-
| `
|
|
52
|
-
|
|
53
|
-
|
|
61
|
+
| `exposeDocked`, `exposeLeaving`, `exposeMowing`, `exposeReturning` | `true` | Which state sensors to create |
|
|
62
|
+
| `exposeBattery` | `true` | Battery service |
|
|
63
|
+
| `faultIndicator` | `true` | Set StatusFault on the sensors when the mower reports an error |
|
|
64
|
+
| `sensorDebounceSeconds` | `3` | How long a state must hold before its sensor flips (0–60) |
|
|
65
|
+
| `pollInterval` | `3600` | Cloud re-sync interval in seconds (min 900). Live state comes by push; Roborock rate-limits this call, so keep it high |
|
|
54
66
|
|
|
55
67
|
## Support
|
|
56
68
|
|
package/config.schema.json
CHANGED
|
@@ -3,27 +3,82 @@
|
|
|
3
3
|
"pluginType": "platform",
|
|
4
4
|
"singular": true,
|
|
5
5
|
"strictValidation": false,
|
|
6
|
+
"customUi": true,
|
|
6
7
|
"headerDisplay": "Homebridge plugin for Roborock RockMow robot lawn mowers.",
|
|
7
8
|
"schema": {
|
|
8
9
|
"type": "object",
|
|
9
10
|
"properties": {
|
|
10
|
-
"name": {
|
|
11
|
-
"title": "Name",
|
|
12
|
-
"type": "string",
|
|
13
|
-
"default": "Roborock Mower"
|
|
14
|
-
},
|
|
15
11
|
"pollInterval": {
|
|
16
|
-
"title": "
|
|
12
|
+
"title": "Cloud refresh interval (seconds)",
|
|
13
|
+
"type": "integer",
|
|
14
|
+
"default": 3600,
|
|
15
|
+
"minimum": 900,
|
|
16
|
+
"maximum": 86400,
|
|
17
|
+
"description": "Live state arrives by push; this only re-syncs with the Roborock cloud as a safety net. Roborock limits this call, keep it at an hour or more."
|
|
18
|
+
},
|
|
19
|
+
"exposeDocked": {
|
|
20
|
+
"title": "Docked sensor",
|
|
21
|
+
"type": "boolean",
|
|
22
|
+
"default": true
|
|
23
|
+
},
|
|
24
|
+
"exposeLeaving": {
|
|
25
|
+
"title": "Leaving sensor",
|
|
26
|
+
"type": "boolean",
|
|
27
|
+
"default": true
|
|
28
|
+
},
|
|
29
|
+
"exposeMowing": {
|
|
30
|
+
"title": "Mowing sensor",
|
|
31
|
+
"type": "boolean",
|
|
32
|
+
"default": true
|
|
33
|
+
},
|
|
34
|
+
"exposeReturning": {
|
|
35
|
+
"title": "Returning sensor",
|
|
36
|
+
"type": "boolean",
|
|
37
|
+
"default": true
|
|
38
|
+
},
|
|
39
|
+
"exposeBattery": {
|
|
40
|
+
"title": "Battery",
|
|
41
|
+
"type": "boolean",
|
|
42
|
+
"default": true
|
|
43
|
+
},
|
|
44
|
+
"faultIndicator": {
|
|
45
|
+
"title": "Fault indicator",
|
|
46
|
+
"type": "boolean",
|
|
47
|
+
"default": true
|
|
48
|
+
},
|
|
49
|
+
"sensorDebounceSeconds": {
|
|
50
|
+
"title": "Sensor debounce (seconds)",
|
|
17
51
|
"type": "integer",
|
|
18
|
-
"default":
|
|
19
|
-
"minimum":
|
|
20
|
-
"maximum":
|
|
21
|
-
"description": "How
|
|
52
|
+
"default": 3,
|
|
53
|
+
"minimum": 0,
|
|
54
|
+
"maximum": 60,
|
|
55
|
+
"description": "How long a state must hold before its sensor flips. Faults and battery are reported immediately."
|
|
22
56
|
}
|
|
23
57
|
}
|
|
24
58
|
},
|
|
25
59
|
"layout": [
|
|
26
|
-
|
|
27
|
-
|
|
60
|
+
{
|
|
61
|
+
"type": "fieldset",
|
|
62
|
+
"title": "HomeKit sensors",
|
|
63
|
+
"expandable": false,
|
|
64
|
+
"items": [
|
|
65
|
+
"exposeDocked",
|
|
66
|
+
"exposeLeaving",
|
|
67
|
+
"exposeMowing",
|
|
68
|
+
"exposeReturning",
|
|
69
|
+
"exposeBattery",
|
|
70
|
+
"faultIndicator",
|
|
71
|
+
"sensorDebounceSeconds"
|
|
72
|
+
]
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"type": "fieldset",
|
|
76
|
+
"title": "Advanced",
|
|
77
|
+
"expandable": true,
|
|
78
|
+
"expanded": false,
|
|
79
|
+
"items": [
|
|
80
|
+
"pollInterval"
|
|
81
|
+
]
|
|
82
|
+
}
|
|
28
83
|
]
|
|
29
84
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { API, Logging, PlatformAccessory } from 'homebridge';
|
|
2
|
+
import type { DerivedState } from './state.js';
|
|
3
|
+
export interface SensorOptions {
|
|
4
|
+
docked: boolean;
|
|
5
|
+
leaving: boolean;
|
|
6
|
+
mowing: boolean;
|
|
7
|
+
returning: boolean;
|
|
8
|
+
battery: boolean;
|
|
9
|
+
faultIndicator: boolean;
|
|
10
|
+
debounceSeconds: number;
|
|
11
|
+
}
|
|
12
|
+
export interface DeviceInformation {
|
|
13
|
+
model: string;
|
|
14
|
+
serial?: string;
|
|
15
|
+
firmware?: string;
|
|
16
|
+
}
|
|
17
|
+
type Hap = Pick<API['hap'], 'Service' | 'Characteristic'>;
|
|
18
|
+
export declare class MowerAccessory {
|
|
19
|
+
private readonly hap;
|
|
20
|
+
readonly accessory: PlatformAccessory;
|
|
21
|
+
private readonly log;
|
|
22
|
+
private readonly options;
|
|
23
|
+
private readonly sensors;
|
|
24
|
+
private readonly battery?;
|
|
25
|
+
private readonly applied;
|
|
26
|
+
private readonly pending;
|
|
27
|
+
private last;
|
|
28
|
+
constructor(hap: Hap, accessory: PlatformAccessory, log: Logging, options: SensorOptions);
|
|
29
|
+
setInformation(info: DeviceInformation): void;
|
|
30
|
+
update(state: DerivedState): void;
|
|
31
|
+
setOnline(online: boolean): void;
|
|
32
|
+
private schedule;
|
|
33
|
+
private apply;
|
|
34
|
+
private pushFault;
|
|
35
|
+
private pushBattery;
|
|
36
|
+
}
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
const SENSOR_LABELS = { docked: 'Docked', leaving: 'Leaving', mowing: 'Mowing', returning: 'Returning' };
|
|
2
|
+
const SENSOR_KEYS = Object.keys(SENSOR_LABELS);
|
|
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 "Leaving opens → open the garage" reads naturally.
|
|
5
|
+
function contactValue(key, active, c) {
|
|
6
|
+
const detected = c.ContactSensorState.CONTACT_DETECTED;
|
|
7
|
+
const notDetected = c.ContactSensorState.CONTACT_NOT_DETECTED;
|
|
8
|
+
if (key === 'docked') {
|
|
9
|
+
return active ? detected : notDetected;
|
|
10
|
+
}
|
|
11
|
+
return active ? notDetected : detected;
|
|
12
|
+
}
|
|
13
|
+
export class MowerAccessory {
|
|
14
|
+
hap;
|
|
15
|
+
accessory;
|
|
16
|
+
log;
|
|
17
|
+
options;
|
|
18
|
+
sensors = new Map();
|
|
19
|
+
battery;
|
|
20
|
+
applied = new Map();
|
|
21
|
+
pending = new Map();
|
|
22
|
+
last = {};
|
|
23
|
+
constructor(hap, accessory, log, options) {
|
|
24
|
+
this.hap = hap;
|
|
25
|
+
this.accessory = accessory;
|
|
26
|
+
this.log = log;
|
|
27
|
+
this.options = options;
|
|
28
|
+
const { Service, Characteristic } = hap;
|
|
29
|
+
if (!accessory.getService(Service.AccessoryInformation)) {
|
|
30
|
+
accessory.addService(Service.AccessoryInformation);
|
|
31
|
+
}
|
|
32
|
+
for (const key of SENSOR_KEYS) {
|
|
33
|
+
const existing = accessory.getServiceById(Service.ContactSensor, key);
|
|
34
|
+
if (!options[key]) {
|
|
35
|
+
if (existing) {
|
|
36
|
+
accessory.removeService(existing);
|
|
37
|
+
}
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
const name = `${accessory.displayName} ${SENSOR_LABELS[key]}`;
|
|
41
|
+
const service = existing ?? accessory.addService(Service.ContactSensor, name, key);
|
|
42
|
+
service.setCharacteristic(Characteristic.Name, name);
|
|
43
|
+
service.setCharacteristic(Characteristic.ConfiguredName, name);
|
|
44
|
+
this.sensors.set(key, service);
|
|
45
|
+
}
|
|
46
|
+
const existingBattery = accessory.getService(Service.Battery);
|
|
47
|
+
if (options.battery) {
|
|
48
|
+
this.battery = existingBattery ?? accessory.addService(Service.Battery, `${accessory.displayName} Battery`);
|
|
49
|
+
}
|
|
50
|
+
else if (existingBattery) {
|
|
51
|
+
accessory.removeService(existingBattery);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
setInformation(info) {
|
|
55
|
+
const { Service, Characteristic } = this.hap;
|
|
56
|
+
this.accessory.getService(Service.AccessoryInformation)
|
|
57
|
+
?.setCharacteristic(Characteristic.Manufacturer, 'Roborock')
|
|
58
|
+
.setCharacteristic(Characteristic.Model, info.model)
|
|
59
|
+
.setCharacteristic(Characteristic.SerialNumber, info.serial ?? this.accessory.UUID)
|
|
60
|
+
.setCharacteristic(Characteristic.FirmwareRevision, info.firmware ?? '0');
|
|
61
|
+
}
|
|
62
|
+
update(state) {
|
|
63
|
+
for (const key of this.sensors.keys()) {
|
|
64
|
+
this.schedule(key, state[key]);
|
|
65
|
+
}
|
|
66
|
+
this.pushFault(state.fault);
|
|
67
|
+
this.pushBattery(state);
|
|
68
|
+
}
|
|
69
|
+
setOnline(online) {
|
|
70
|
+
for (const service of this.sensors.values()) {
|
|
71
|
+
service.updateCharacteristic(this.hap.Characteristic.StatusActive, online);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Activity flags must hold for debounceSeconds before HomeKit sees them; the first value is applied immediately.
|
|
75
|
+
schedule(key, value) {
|
|
76
|
+
const pending = this.pending.get(key);
|
|
77
|
+
if (this.applied.get(key) === value) {
|
|
78
|
+
if (pending) {
|
|
79
|
+
clearTimeout(pending.timer);
|
|
80
|
+
this.pending.delete(key);
|
|
81
|
+
}
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (pending?.value === value) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (pending) {
|
|
88
|
+
clearTimeout(pending.timer);
|
|
89
|
+
}
|
|
90
|
+
if (!this.applied.has(key) || this.options.debounceSeconds <= 0) {
|
|
91
|
+
this.apply(key, value);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const timer = setTimeout(() => {
|
|
95
|
+
this.pending.delete(key);
|
|
96
|
+
this.apply(key, value);
|
|
97
|
+
}, this.options.debounceSeconds * 1000);
|
|
98
|
+
this.pending.set(key, { value, timer });
|
|
99
|
+
}
|
|
100
|
+
apply(key, value) {
|
|
101
|
+
this.applied.set(key, value);
|
|
102
|
+
this.sensors.get(key)?.updateCharacteristic(this.hap.Characteristic.ContactSensorState, contactValue(key, value, this.hap.Characteristic));
|
|
103
|
+
this.log.debug(`${this.accessory.displayName}: ${SENSOR_LABELS[key]} ${value ? 'on' : 'off'}`);
|
|
104
|
+
}
|
|
105
|
+
pushFault(fault) {
|
|
106
|
+
if (!this.options.faultIndicator || this.last.fault === fault) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
this.last.fault = fault;
|
|
110
|
+
const c = this.hap.Characteristic;
|
|
111
|
+
for (const service of this.sensors.values()) {
|
|
112
|
+
service.updateCharacteristic(c.StatusFault, fault ? c.StatusFault.GENERAL_FAULT : c.StatusFault.NO_FAULT);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
pushBattery(state) {
|
|
116
|
+
if (!this.battery) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const c = this.hap.Characteristic;
|
|
120
|
+
if (state.battery !== undefined && state.battery !== this.last.battery) {
|
|
121
|
+
this.last.battery = state.battery;
|
|
122
|
+
this.battery.updateCharacteristic(c.BatteryLevel, state.battery);
|
|
123
|
+
}
|
|
124
|
+
if (state.lowBattery !== this.last.lowBattery) {
|
|
125
|
+
this.last.lowBattery = state.lowBattery;
|
|
126
|
+
this.battery.updateCharacteristic(c.StatusLowBattery, state.lowBattery ? c.StatusLowBattery.BATTERY_LEVEL_LOW : c.StatusLowBattery.BATTERY_LEVEL_NORMAL);
|
|
127
|
+
}
|
|
128
|
+
if (state.charging !== this.last.charging) {
|
|
129
|
+
this.last.charging = state.charging;
|
|
130
|
+
this.battery.updateCharacteristic(c.ChargingState, state.charging ? c.ChargingState.CHARGING : c.ChargingState.NOT_CHARGING);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=accessory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accessory.js","sourceRoot":"","sources":["../../src/mower/accessory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export declare const DPS: {
|
|
2
|
+
readonly ERROR_CODE: 120;
|
|
3
|
+
readonly BATTERY: 121;
|
|
4
|
+
readonly MOW_TYPE: 122;
|
|
5
|
+
readonly MOW_STATE: 123;
|
|
6
|
+
readonly CHARGE_STATE: 127;
|
|
7
|
+
readonly DOCK_STATE: 128;
|
|
8
|
+
readonly CHARGE_TYPE: 129;
|
|
9
|
+
readonly MOW_START_TYPE: 132;
|
|
10
|
+
readonly MOW_PROGRESS: 139;
|
|
11
|
+
readonly OFF_DOCK_NO_TASK_STATUS: 143;
|
|
12
|
+
};
|
|
13
|
+
export declare const MOW_STATE_NAMES: Record<number, string>;
|
|
14
|
+
export interface DerivedState {
|
|
15
|
+
docked: boolean;
|
|
16
|
+
leaving: boolean;
|
|
17
|
+
mowing: boolean;
|
|
18
|
+
returning: boolean;
|
|
19
|
+
charging: boolean;
|
|
20
|
+
paused: boolean;
|
|
21
|
+
fault: boolean;
|
|
22
|
+
battery?: number;
|
|
23
|
+
lowBattery: boolean;
|
|
24
|
+
mowState?: number;
|
|
25
|
+
errorCode: number;
|
|
26
|
+
}
|
|
27
|
+
export type Dps = Record<number, unknown>;
|
|
28
|
+
export declare function deriveMowerState(dps: Dps): DerivedState;
|
|
29
|
+
export declare function describeMowState(code: number | undefined): string;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// DPS ids and state codes from python-roborock (RoborockMowerDataProtocol / RoborockMowerStateCode),
|
|
2
|
+
// cross-checked against a RockMow a282 capture (test/fixtures/dps-sequence.json).
|
|
3
|
+
export const DPS = {
|
|
4
|
+
ERROR_CODE: 120,
|
|
5
|
+
BATTERY: 121,
|
|
6
|
+
MOW_TYPE: 122,
|
|
7
|
+
MOW_STATE: 123,
|
|
8
|
+
CHARGE_STATE: 127,
|
|
9
|
+
DOCK_STATE: 128,
|
|
10
|
+
CHARGE_TYPE: 129,
|
|
11
|
+
MOW_START_TYPE: 132,
|
|
12
|
+
MOW_PROGRESS: 139,
|
|
13
|
+
OFF_DOCK_NO_TASK_STATUS: 143,
|
|
14
|
+
};
|
|
15
|
+
export const MOW_STATE_NAMES = {
|
|
16
|
+
0: 'idle',
|
|
17
|
+
1: 'map_initializing', 2: 'map_undocking', 3: 'map_undock_fault', 4: 'map_locating', 5: 'map_prepare_boundary',
|
|
18
|
+
6: 'map_prepare_island', 7: 'map_prepare_path', 8: 'map_boundary', 9: 'map_island', 10: 'map_path',
|
|
19
|
+
11: 'map_boundary_auto', 12: 'map_erasing', 13: 'map_save', 14: 'map_wait', 15: 'map_recoverable_fault',
|
|
20
|
+
16: 'map_fault', 17: 'map_emergency_stop', 18: 'map_waiting_fault',
|
|
21
|
+
51: 'mow_initializing', 52: 'mow_undocking', 53: 'mow_locating', 54: 'mow_adjust_cutter', 55: 'mow_zig_zag',
|
|
22
|
+
56: 'mow_edge', 57: 'mow_goto', 58: 'mow_suspend', 59: 'mow_recoverable_fault', 60: 'mow_fault',
|
|
23
|
+
61: 'mow_docked_rainfall', 62: 'mow_docked_do_not_disturb', 63: 'mow_docked_low_battery', 64: 'mow_wait',
|
|
24
|
+
65: 'mow_prepare_remote', 66: 'mow_remote', 67: 'mow_emergency_stop', 68: 'mow_docked_manual', 69: 'mow_dock_fault',
|
|
25
|
+
70: 'mow_remote_undocking', 71: 'mow_to_dock_initializing', 72: 'mow_to_dock_locating', 73: 'mow_to_dock_recoverable_fault',
|
|
26
|
+
74: 'mow_to_dock_fault', 75: 'mow_to_dock_emergency_stop', 76: 'mow_to_dock_charging', 77: 'mow_to_dock_charge_completed',
|
|
27
|
+
101: 'free', 102: 'free_initializing', 103: 'free_locating', 104: 'free_docked_manual', 105: 'free_docked_mow_end',
|
|
28
|
+
106: 'free_docked_plan_end', 107: 'free_emergency_stop', 108: 'free_recoverable_fault', 109: 'free_fault',
|
|
29
|
+
151: 'charge_charging', 152: 'charge_completed', 153: 'charge_waiting', 154: 'charge_fault',
|
|
30
|
+
};
|
|
31
|
+
const LEAVING_STATES = new Set([51, 52, 53, 54]);
|
|
32
|
+
const MOWING_STATES = new Set([55, 56, 57, 64, 65, 66, 70]);
|
|
33
|
+
const RETURNING_STATES = new Set([71, 72, 73, 74, 75]);
|
|
34
|
+
// Bare idle (0) is deliberately not here: the mower reports 0 off the dock between a task ending and 143 being set.
|
|
35
|
+
const DOCKED_STATES = new Set([61, 62, 63, 68, 76, 77, 104, 105, 106, 151, 152, 153]);
|
|
36
|
+
const CHARGING_STATES = new Set([76, 151]);
|
|
37
|
+
const PAUSED_STATES = new Set([17, 58, 67, 75, 107]);
|
|
38
|
+
const FAULT_STATES = new Set([3, 15, 16, 59, 60, 69, 73, 74, 108, 109, 154]);
|
|
39
|
+
const CHARGE_STATE_ON_DOCK = new Set([1, 2, 3]); // charging, completed, waiting
|
|
40
|
+
const LOW_BATTERY_PERCENT = 20;
|
|
41
|
+
function num(value) {
|
|
42
|
+
const n = typeof value === 'number' ? value : Number(value);
|
|
43
|
+
return value === undefined || value === null || Number.isNaN(n) ? undefined : n;
|
|
44
|
+
}
|
|
45
|
+
export function deriveMowerState(dps) {
|
|
46
|
+
const mowState = num(dps[DPS.MOW_STATE]);
|
|
47
|
+
const chargeState = num(dps[DPS.CHARGE_STATE]);
|
|
48
|
+
const offDock = num(dps[DPS.OFF_DOCK_NO_TASK_STATUS]) ?? 0;
|
|
49
|
+
const battery = num(dps[DPS.BATTERY]);
|
|
50
|
+
const errorCode = num(dps[DPS.ERROR_CODE]) ?? 0;
|
|
51
|
+
const state = mowState ?? -1;
|
|
52
|
+
const docked = (chargeState !== undefined && CHARGE_STATE_ON_DOCK.has(chargeState)) || DOCKED_STATES.has(state);
|
|
53
|
+
return {
|
|
54
|
+
docked,
|
|
55
|
+
leaving: LEAVING_STATES.has(state),
|
|
56
|
+
mowing: MOWING_STATES.has(state),
|
|
57
|
+
returning: !docked && (RETURNING_STATES.has(state) || offDock !== 0),
|
|
58
|
+
charging: chargeState === 1 || CHARGING_STATES.has(state),
|
|
59
|
+
paused: PAUSED_STATES.has(state),
|
|
60
|
+
fault: errorCode !== 0 || FAULT_STATES.has(state),
|
|
61
|
+
battery,
|
|
62
|
+
lowBattery: battery !== undefined && battery <= LOW_BATTERY_PERCENT,
|
|
63
|
+
mowState,
|
|
64
|
+
errorCode,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
export function describeMowState(code) {
|
|
68
|
+
if (code === undefined) {
|
|
69
|
+
return 'unknown';
|
|
70
|
+
}
|
|
71
|
+
return MOW_STATE_NAMES[code] ?? `unknown(${code})`;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/mower/state.ts"],"names":[],"mappings":"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"}
|
package/dist/platform.d.ts
CHANGED
|
@@ -1,16 +1,46 @@
|
|
|
1
1
|
import type { API, Characteristic, DynamicPlatformPlugin, Logging, PlatformAccessory, PlatformConfig, Service } from 'homebridge';
|
|
2
|
+
import type mqtt from 'mqtt';
|
|
3
|
+
import type { StoredSession } from './roborock/types.js';
|
|
2
4
|
export interface RoborockMowerConfig extends PlatformConfig {
|
|
3
5
|
pollInterval?: number;
|
|
6
|
+
exposeDocked?: boolean;
|
|
7
|
+
exposeLeaving?: boolean;
|
|
8
|
+
exposeMowing?: boolean;
|
|
9
|
+
exposeReturning?: boolean;
|
|
10
|
+
exposeBattery?: boolean;
|
|
11
|
+
faultIndicator?: boolean;
|
|
12
|
+
sensorDebounceSeconds?: number;
|
|
13
|
+
}
|
|
14
|
+
export interface PlatformDeps {
|
|
15
|
+
fetch?: typeof globalThis.fetch;
|
|
16
|
+
readSession?: (storagePath: string) => Promise<StoredSession | undefined>;
|
|
17
|
+
connectMqtt?: typeof mqtt.connect;
|
|
18
|
+
now?: () => number;
|
|
4
19
|
}
|
|
5
20
|
export declare class RoborockMowerPlatform implements DynamicPlatformPlugin {
|
|
6
21
|
readonly log: Logging;
|
|
7
22
|
readonly config: PlatformConfig;
|
|
8
23
|
readonly api: API;
|
|
24
|
+
private readonly deps;
|
|
9
25
|
readonly Service: typeof Service;
|
|
10
26
|
readonly Characteristic: typeof Characteristic;
|
|
11
27
|
readonly accessories: Map<string, PlatformAccessory>;
|
|
12
28
|
readonly pluginConfig: RoborockMowerConfig;
|
|
13
|
-
|
|
29
|
+
private webApi?;
|
|
30
|
+
private mqtt?;
|
|
31
|
+
private homeId?;
|
|
32
|
+
private session?;
|
|
33
|
+
private reconcileTimer?;
|
|
34
|
+
private readonly mowers;
|
|
35
|
+
constructor(log: Logging, config: PlatformConfig, api: API, deps?: PlatformDeps);
|
|
14
36
|
configureAccessory(accessory: PlatformAccessory): void;
|
|
15
|
-
private
|
|
37
|
+
private sensorOptions;
|
|
38
|
+
private start;
|
|
39
|
+
private stop;
|
|
40
|
+
private syncMowers;
|
|
41
|
+
private applyDps;
|
|
42
|
+
private startMqtt;
|
|
43
|
+
private pollSeconds;
|
|
44
|
+
private scheduleReconcile;
|
|
45
|
+
private reconcile;
|
|
16
46
|
}
|