Skip to content

Commit b7322c0

Browse files
committed
Add docking contact sensor
1 parent 6945cbd commit b7322c0

File tree

4 files changed

+52
-0
lines changed

4 files changed

+52
-0
lines changed

.changeset/nasty-camels-hammer.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"homebridge-roomba2": minor
3+
---
4+
5+
Add docking contact sensor

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ configure your accessory using JSON:
7979
|`dockContactSensor`|Add a contact sensor to HomeKit that's _closed_ when Roomba is docked|
8080
|`runningContactSensor`|Add a contact sensor to HomeKit that's _closed_ when Roomba is running|
8181
|`binContactSensor`|Add a contact sensor to HomeKit that's _open_ when Roomba's bin is full|
82+
|`dockingContactSensor`|Add a contact sensor to HomeKit that's _open_ when Roomba is docking|
8283

8384
### Deprecated configuration
8485

config.schema.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@
4444
"type": "boolean",
4545
"title": "Show if bin is full as a contact sensor",
4646
"required": false
47+
},
48+
"dockingContactSensor": {
49+
"type": "boolean",
50+
"title": "Show docking status as a contact sensor",
51+
"required": false
4752
}
4853
}
4954
}

src/accessory.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const STATUS_COALLESCE_WINDOW_MILLIS = 5_000;
99
interface Status {
1010
error: null
1111
running: boolean
12+
docking: boolean
1213
charging: boolean
1314
batteryLevel: number | null
1415
binFull: boolean
@@ -41,6 +42,7 @@ export default class RoombaAccessory implements AccessoryPlugin {
4142
private dockService?: Service
4243
private runningService?: Service
4344
private binService?: Service
45+
private dockingService?: Service
4446

4547
/**
4648
* The last known state from Roomba, if any.
@@ -71,6 +73,7 @@ export default class RoombaAccessory implements AccessoryPlugin {
7173
const showDockAsContactSensor = config.dockContactSensor === undefined ? true : config.dockContactSensor;
7274
const showRunningAsContactSensor = config.runningContactSensor;
7375
const showBinStatusAsContactSensor = config.binContactSensor;
76+
const showDockingAsContactSensor = config.dockingContactSensor;
7477

7578
const Service = api.hap.Service;
7679

@@ -87,6 +90,9 @@ export default class RoombaAccessory implements AccessoryPlugin {
8790
if (showBinStatusAsContactSensor) {
8891
this.binService = new Service.ContactSensor(this.name + " Bin Full", "Full");
8992
}
93+
if (showDockingAsContactSensor) {
94+
this.dockingService = new Service.ContactSensor(this.name + " Docking", "docking");
95+
}
9096

9197
this.pendingStatusRequests = [];
9298
}
@@ -150,6 +156,12 @@ export default class RoombaAccessory implements AccessoryPlugin {
150156
.on("get", this.createCharacteristicGetter("Bin status", this.binStatus));
151157
services.push(this.binService);
152158
}
159+
if (this.dockingService) {
160+
this.dockingService
161+
.getCharacteristic(Characteristic.ContactSensorState)
162+
.on("get", this.createCharacteristicGetter("Docking status", this.dockingStatus));
163+
services.push(this.dockingService);
164+
}
153165

154166
return services;
155167
}
@@ -182,6 +194,7 @@ export default class RoombaAccessory implements AccessoryPlugin {
182194
this.mergeStatus({
183195
running: true,
184196
charging: false,
197+
docking: false,
185198
});
186199

187200
this.log("Roomba is running");
@@ -209,6 +222,7 @@ export default class RoombaAccessory implements AccessoryPlugin {
209222
this.mergeStatus({
210223
running: false,
211224
charging: false,
225+
docking: false,
212226
});
213227

214228
this.log("Roomba paused, returning to Dock");
@@ -245,6 +259,7 @@ export default class RoombaAccessory implements AccessoryPlugin {
245259
this.mergeStatus({
246260
running: false,
247261
charging: false,
262+
docking: true,
248263
});
249264

250265
break;
@@ -373,6 +388,7 @@ export default class RoombaAccessory implements AccessoryPlugin {
373388
const status: Status = {
374389
error: null,
375390
running: false,
391+
docking: false,
376392
charging: false,
377393
batteryLevel: null,
378394
binFull: false,
@@ -385,16 +401,33 @@ export default class RoombaAccessory implements AccessoryPlugin {
385401
case "run":
386402
status.running = true;
387403
status.charging = false;
404+
status.docking = false;
388405

389406
break;
390407
case "charge":
391408
status.running = false;
392409
status.charging = true;
410+
status.docking = false;
411+
412+
break;
413+
case "hmUsrDock":
414+
status.running = false;
415+
status.charging = false;
416+
status.docking = true;
417+
418+
break;
419+
case "stop":
420+
status.running = false;
421+
status.charging = true;
422+
status.docking = false;
393423

394424
break;
395425
default:
426+
this.log.info(`Unsupported phase: ${state.cleanMissionStatus!.phase}`);
427+
396428
status.running = false;
397429
status.charging = false;
430+
status.docking = false;
398431

399432
break;
400433
}
@@ -434,6 +467,11 @@ export default class RoombaAccessory implements AccessoryPlugin {
434467
.getCharacteristic(Characteristic.ContactSensorState)
435468
.updateValue(this.binStatus(status));
436469
}
470+
if (this.dockingService) {
471+
this.dockingService
472+
.getCharacteristic(Characteristic.ContactSensorState)
473+
.updateValue(this.dockingStatus(status));
474+
}
437475
}
438476

439477
private runningStatus = (status: Status) => status.running
@@ -442,6 +480,9 @@ export default class RoombaAccessory implements AccessoryPlugin {
442480
private chargingStatus = (status: Status) => status.charging
443481
? this.api.hap.Characteristic.ChargingState.CHARGING
444482
: this.api.hap.Characteristic.ChargingState.NOT_CHARGING;
483+
private dockingStatus = (status: Status) => status.docking
484+
? this.api.hap.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED
485+
: this.api.hap.Characteristic.ContactSensorState.CONTACT_DETECTED;
445486
private dockedStatus = (status: Status) => status.charging
446487
? this.api.hap.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED
447488
: this.api.hap.Characteristic.ContactSensorState.CONTACT_DETECTED;

0 commit comments

Comments
 (0)