@switchbot/homebridge-switchbot 1.3.1-beta.6 → 1.4.0
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 +12 -1
- package/config.schema.json +9 -22
- package/dist/devices/bots.d.ts +2 -0
- package/dist/devices/bots.d.ts.map +1 -1
- package/dist/devices/bots.js +109 -84
- package/dist/devices/bots.js.map +1 -1
- package/dist/devices/colorbulb.d.ts +1 -0
- package/dist/devices/colorbulb.d.ts.map +1 -1
- package/dist/devices/colorbulb.js +18 -4
- package/dist/devices/colorbulb.js.map +1 -1
- package/dist/devices/contact.js +1 -1
- package/dist/devices/contact.js.map +1 -1
- package/dist/devices/humidifiers.d.ts +1 -0
- package/dist/devices/humidifiers.d.ts.map +1 -1
- package/dist/devices/humidifiers.js +9 -1
- package/dist/devices/humidifiers.js.map +1 -1
- package/dist/devices/indoorcam.d.ts.map +1 -1
- package/dist/devices/indoorcam.js +6 -0
- package/dist/devices/indoorcam.js.map +1 -1
- package/dist/devices/meters.d.ts +5 -11
- package/dist/devices/meters.d.ts.map +1 -1
- package/dist/devices/meters.js +49 -47
- package/dist/devices/meters.js.map +1 -1
- package/dist/devices/plugs.d.ts +2 -0
- package/dist/devices/plugs.d.ts.map +1 -1
- package/dist/devices/plugs.js +35 -16
- package/dist/devices/plugs.js.map +1 -1
- package/dist/irdevices/airconditioners.d.ts +2 -0
- package/dist/irdevices/airconditioners.d.ts.map +1 -1
- package/dist/irdevices/airconditioners.js +17 -1
- package/dist/irdevices/airconditioners.js.map +1 -1
- package/dist/irdevices/airpurifiers.d.ts +2 -0
- package/dist/irdevices/airpurifiers.d.ts.map +1 -1
- package/dist/irdevices/airpurifiers.js +17 -0
- package/dist/irdevices/airpurifiers.js.map +1 -1
- package/dist/irdevices/cameras.d.ts +1 -0
- package/dist/irdevices/cameras.d.ts.map +1 -1
- package/dist/irdevices/cameras.js +9 -0
- package/dist/irdevices/cameras.js.map +1 -1
- package/dist/irdevices/fans.d.ts +1 -0
- package/dist/irdevices/fans.d.ts.map +1 -1
- package/dist/irdevices/fans.js +9 -0
- package/dist/irdevices/fans.js.map +1 -1
- package/dist/irdevices/lights.d.ts +1 -0
- package/dist/irdevices/lights.d.ts.map +1 -1
- package/dist/irdevices/lights.js +9 -0
- package/dist/irdevices/lights.js.map +1 -1
- package/dist/irdevices/others.d.ts +1 -0
- package/dist/irdevices/others.d.ts.map +1 -1
- package/dist/irdevices/others.js +9 -0
- package/dist/irdevices/others.js.map +1 -1
- package/dist/irdevices/tvs.d.ts +1 -0
- package/dist/irdevices/tvs.d.ts.map +1 -1
- package/dist/irdevices/tvs.js +9 -0
- package/dist/irdevices/tvs.js.map +1 -1
- package/dist/irdevices/vacuumcleaners.d.ts +1 -0
- package/dist/irdevices/vacuumcleaners.d.ts.map +1 -1
- package/dist/irdevices/vacuumcleaners.js +9 -0
- package/dist/irdevices/vacuumcleaners.js.map +1 -1
- package/dist/irdevices/waterheaters.d.ts +1 -0
- package/dist/irdevices/waterheaters.d.ts.map +1 -1
- package/dist/irdevices/waterheaters.js +9 -0
- package/dist/irdevices/waterheaters.js.map +1 -1
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +46 -2
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +6 -5
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js.map +1 -1
- package/package.json +66 -66
- package/src/devices/bots.ts +88 -63
- package/src/devices/colorbulb.ts +18 -4
- package/src/devices/contact.ts +1 -1
- package/src/devices/humidifiers.ts +10 -1
- package/src/devices/indoorcam.ts +6 -0
- package/src/devices/meters.ts +50 -48
- package/src/devices/plugs.ts +38 -17
- package/src/irdevices/airconditioners.ts +17 -1
- package/src/irdevices/airpurifiers.ts +18 -0
- package/src/irdevices/cameras.ts +10 -0
- package/src/irdevices/fans.ts +10 -0
- package/src/irdevices/lights.ts +10 -0
- package/src/irdevices/others.ts +10 -0
- package/src/irdevices/tvs.ts +10 -0
- package/src/irdevices/vacuumcleaners.ts +10 -0
- package/src/irdevices/waterheaters.ts +10 -0
- package/src/platform.ts +37 -2
- package/src/settings.ts +7 -5
package/src/devices/bots.ts
CHANGED
|
@@ -20,6 +20,7 @@ export class Bot {
|
|
|
20
20
|
|
|
21
21
|
// Characteristic Values
|
|
22
22
|
On!: CharacteristicValue;
|
|
23
|
+
OnCached!: CharacteristicValue;
|
|
23
24
|
BatteryLevel!: CharacteristicValue;
|
|
24
25
|
StatusLowBattery!: CharacteristicValue;
|
|
25
26
|
|
|
@@ -48,11 +49,15 @@ export class Bot {
|
|
|
48
49
|
public device: device & devicesConfig,
|
|
49
50
|
) {
|
|
50
51
|
// Bot Config
|
|
51
|
-
this.platform.device(`Bot: ${this.accessory.displayName} Config: (ble: ${device.ble}, mode: ${device.bot?.mode},`
|
|
52
|
+
this.platform.device(`Bot: ${this.accessory.displayName} Config: (ble: ${device.ble}, offline: ${device.offline}, mode: ${device.bot?.mode},`
|
|
52
53
|
+ ` deviceType: ${device.bot?.deviceType})`);
|
|
53
54
|
|
|
54
55
|
// default placeholders
|
|
55
|
-
this.On
|
|
56
|
+
if (this.On === undefined) {
|
|
57
|
+
this.On = false;
|
|
58
|
+
} else {
|
|
59
|
+
this.On = this.accessory.context.On;
|
|
60
|
+
}
|
|
56
61
|
this.BatteryLevel = 100;
|
|
57
62
|
this.StatusLowBattery = 1;
|
|
58
63
|
|
|
@@ -122,7 +127,6 @@ export class Bot {
|
|
|
122
127
|
}
|
|
123
128
|
|
|
124
129
|
// Retrieve initial values and updateHomekit
|
|
125
|
-
this.parseStatus();
|
|
126
130
|
this.updateHomeKitCharacteristics();
|
|
127
131
|
|
|
128
132
|
// Start an update interval
|
|
@@ -341,14 +345,38 @@ export class Bot {
|
|
|
341
345
|
}
|
|
342
346
|
|
|
343
347
|
private async BLEpushChanges() {
|
|
344
|
-
this.
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
.
|
|
350
|
-
|
|
351
|
-
|
|
348
|
+
if (this.On !== this.OnCached) {
|
|
349
|
+
this.platform.debug(`Bot: ${this.accessory.displayName} BLE pushChanges`);
|
|
350
|
+
const switchbot = this.connectBLE();
|
|
351
|
+
if (this.device.bot?.mode === 'press') {
|
|
352
|
+
this.platform.device(`Bot: ${this.accessory.displayName} Press Mode: ${this.device.bot?.mode}`);
|
|
353
|
+
switchbot.discover({ model: 'H', quick: true, id: this.device.bleMac })
|
|
354
|
+
.then((device_list: { press: (arg0: { id: string | undefined; }) => any; }[]) => {
|
|
355
|
+
this.platform.log.info(`Bot: ${this.accessory.displayName}, On: ${this.On}`);
|
|
356
|
+
return device_list[0].press({ id: this.device.bleMac });
|
|
357
|
+
}).then(() => {
|
|
358
|
+
this.platform.device(`Bot: ${this.accessory.displayName} Done.`);
|
|
359
|
+
}).catch(async (e: any) => {
|
|
360
|
+
this.platform.log.error(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection`);
|
|
361
|
+
if (this.deviceDebug) {
|
|
362
|
+
this.platform.log.error(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection,`
|
|
363
|
+
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
364
|
+
}
|
|
365
|
+
if (this.debugDebug) {
|
|
366
|
+
this.platform.log.error(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection,`
|
|
367
|
+
+ ` Error: ${JSON.stringify(e)}`);
|
|
368
|
+
}
|
|
369
|
+
if (this.platform.config.credentials?.openToken) {
|
|
370
|
+
this.platform.log.warn(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
371
|
+
await this.openAPIpushChanges();
|
|
372
|
+
}
|
|
373
|
+
this.apiError(e);
|
|
374
|
+
});
|
|
375
|
+
} else if (this.device.bot?.mode === 'switch') {
|
|
376
|
+
this.platform.device(`Bot: ${this.accessory.displayName} Press Mode: ${this.device.bot?.mode}`);
|
|
377
|
+
switchbot.discover({ model: 'H', quick: true, id: this.device.bleMac }).then((device_list: any) => {
|
|
378
|
+
this.platform.log.info(`Bot: ${this.accessory.displayName} On: ${this.On}`);
|
|
379
|
+
return this.turnOnOff(device_list);
|
|
352
380
|
}).then(() => {
|
|
353
381
|
this.platform.device(`Bot: ${this.accessory.displayName} Done.`);
|
|
354
382
|
}).catch(async (e: any) => {
|
|
@@ -367,32 +395,12 @@ export class Bot {
|
|
|
367
395
|
}
|
|
368
396
|
this.apiError(e);
|
|
369
397
|
});
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
this.platform.log.info(`Bot: ${this.accessory.displayName} On: ${this.On}`);
|
|
374
|
-
return this.turnOnOff(device_list);
|
|
375
|
-
}).then(() => {
|
|
376
|
-
this.platform.device(`Bot: ${this.accessory.displayName} Done.`);
|
|
377
|
-
}).catch(async (e: any) => {
|
|
378
|
-
this.platform.log.error(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection`);
|
|
379
|
-
if (this.deviceDebug) {
|
|
380
|
-
this.platform.log.error(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection,`
|
|
381
|
-
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
382
|
-
}
|
|
383
|
-
if (this.debugDebug) {
|
|
384
|
-
this.platform.log.error(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection,`
|
|
385
|
-
+ ` Error: ${JSON.stringify(e)}`);
|
|
386
|
-
}
|
|
387
|
-
if (this.platform.config.credentials?.openToken) {
|
|
388
|
-
this.platform.log.warn(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
389
|
-
await this.openAPIpushChanges();
|
|
390
|
-
}
|
|
391
|
-
this.apiError(e);
|
|
392
|
-
});
|
|
393
|
-
} else {
|
|
394
|
-
this.platform.log.error(`Bot: ${this.accessory.displayName} Mode Not Set, mode: ${this.device.bot?.mode}`);
|
|
398
|
+
} else {
|
|
399
|
+
this.platform.log.error(`Bot: ${this.accessory.displayName} Mode Not Set, mode: ${this.device.bot?.mode}`);
|
|
400
|
+
}
|
|
395
401
|
}
|
|
402
|
+
this.OnCached = this.On;
|
|
403
|
+
this.accessory.context.On = this.OnCached;
|
|
396
404
|
}
|
|
397
405
|
|
|
398
406
|
private turnOnOff(device_list: any) {
|
|
@@ -406,35 +414,39 @@ export class Bot {
|
|
|
406
414
|
private async openAPIpushChanges() {
|
|
407
415
|
if (this.platform.config.credentials?.openToken) {
|
|
408
416
|
try {
|
|
409
|
-
this.
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
417
|
+
if (this.On !== this.OnCached) {
|
|
418
|
+
this.platform.debug(`Bot: ${this.accessory.displayName} OpenAPI pushChanges`);
|
|
419
|
+
const payload = {
|
|
420
|
+
commandType: 'command',
|
|
421
|
+
parameter: 'default',
|
|
422
|
+
} as payload;
|
|
423
|
+
|
|
424
|
+
if (this.device.bot?.mode === 'switch' && this.On) {
|
|
425
|
+
payload.command = 'turnOn';
|
|
426
|
+
this.On = true;
|
|
427
|
+
this.platform.debug(`Bot: ${this.accessory.displayName} Switch Mode, Turning ${this.On}`);
|
|
428
|
+
} else if (this.device.bot?.mode === 'switch' && !this.On) {
|
|
429
|
+
payload.command = 'turnOff';
|
|
430
|
+
this.On = false;
|
|
431
|
+
this.platform.debug(`Bot: ${this.accessory.displayName} Switch Mode, Turning ${this.On}`);
|
|
432
|
+
} else if (this.device.bot?.mode === 'press') {
|
|
433
|
+
payload.command = 'press';
|
|
434
|
+
this.platform.debug(`Bot: ${this.accessory.displayName} Press Mode`);
|
|
435
|
+
this.On = false;
|
|
436
|
+
} else {
|
|
437
|
+
throw new Error(`Bot: ${this.accessory.displayName} Device Paramters not set for this Bot.`);
|
|
438
|
+
}
|
|
430
439
|
|
|
431
|
-
|
|
432
|
-
|
|
440
|
+
this.platform.log.info(`Bot: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},`
|
|
441
|
+
+ ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`);
|
|
433
442
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
443
|
+
// Make the API request
|
|
444
|
+
const push: any = (await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload));
|
|
445
|
+
this.platform.debug(`Bot ${this.accessory.displayName} pushchanges: ${JSON.stringify(push.data)}`);
|
|
446
|
+
this.statusCode(push);
|
|
447
|
+
this.OnCached = this.On;
|
|
448
|
+
this.accessory.context.On = this.OnCached;
|
|
449
|
+
}
|
|
438
450
|
} catch (e: any) {
|
|
439
451
|
this.platform.log.error(`Bot: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
|
|
440
452
|
if (this.deviceDebug) {
|
|
@@ -505,9 +517,11 @@ export class Bot {
|
|
|
505
517
|
break;
|
|
506
518
|
case 161:
|
|
507
519
|
this.platform.log.error(`Bot: ${this.accessory.displayName} Device is offline.`);
|
|
520
|
+
this.offlineOff();
|
|
508
521
|
break;
|
|
509
522
|
case 171:
|
|
510
523
|
this.platform.log.error(`Bot: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
|
|
524
|
+
this.offlineOff();
|
|
511
525
|
break;
|
|
512
526
|
case 190:
|
|
513
527
|
this.platform.log.error(`Bot: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,`
|
|
@@ -521,6 +535,17 @@ export class Bot {
|
|
|
521
535
|
}
|
|
522
536
|
}
|
|
523
537
|
|
|
538
|
+
private offlineOff() {
|
|
539
|
+
if (this.device.offline) {
|
|
540
|
+
this.On = false;
|
|
541
|
+
if (this.device.bot?.deviceType === 'switch') {
|
|
542
|
+
this.switchService?.getCharacteristic(this.platform.Characteristic.On).updateValue(this.On);
|
|
543
|
+
} else {
|
|
544
|
+
this.outletService?.getCharacteristic(this.platform.Characteristic.On).updateValue(this.On);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
|
|
524
549
|
/**
|
|
525
550
|
* Handle requests to set the "On" characteristic
|
|
526
551
|
*/
|
package/src/devices/colorbulb.ts
CHANGED
|
@@ -56,13 +56,17 @@ export class ColorBulb {
|
|
|
56
56
|
this.platform.device(`Color Bulb: ${this.accessory.displayName} Config: (ble: ${device.ble}, set_minStep: ${device.colorbulb?.set_minStep}`);
|
|
57
57
|
|
|
58
58
|
// default placeholders
|
|
59
|
-
this.
|
|
60
|
-
|
|
59
|
+
if (this.On === undefined) {
|
|
60
|
+
this.On = false;
|
|
61
|
+
} else {
|
|
62
|
+
this.On = this.accessory.context.On;
|
|
63
|
+
}
|
|
61
64
|
this.Hue = 0;
|
|
62
|
-
this.On = false;
|
|
63
65
|
this.Brightness = 0;
|
|
64
66
|
this.Saturation = 0;
|
|
65
67
|
this.ColorTemperature = 140;
|
|
68
|
+
this.minKelvin = 2000;
|
|
69
|
+
this.maxKelvin = 9000;
|
|
66
70
|
|
|
67
71
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
68
72
|
this.doColorBulbUpdate = new Subject();
|
|
@@ -299,6 +303,7 @@ export class ColorBulb {
|
|
|
299
303
|
this.platform.debug(`Color Bulb: ${this.accessory.displayName} pushChanges: ${JSON.stringify(push.data)}`);
|
|
300
304
|
this.statusCode(push);
|
|
301
305
|
this.OnCached = this.On;
|
|
306
|
+
this.accessory.context.On = this.OnCached;
|
|
302
307
|
}
|
|
303
308
|
// Push Brightness Update
|
|
304
309
|
if (this.On) {
|
|
@@ -498,9 +503,11 @@ export class ColorBulb {
|
|
|
498
503
|
break;
|
|
499
504
|
case 161:
|
|
500
505
|
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} Device is offline.`);
|
|
506
|
+
this.offlineOff();
|
|
501
507
|
break;
|
|
502
508
|
case 171:
|
|
503
|
-
this.platform.log.error(`Color Bulb: ${this.accessory.displayName}
|
|
509
|
+
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} is offline. Hub: ${this.device.hubDeviceId}`);
|
|
510
|
+
this.offlineOff();
|
|
504
511
|
break;
|
|
505
512
|
case 190:
|
|
506
513
|
this.platform.log.error(`Color Bulb: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,`
|
|
@@ -514,6 +521,13 @@ export class ColorBulb {
|
|
|
514
521
|
}
|
|
515
522
|
}
|
|
516
523
|
|
|
524
|
+
private offlineOff() {
|
|
525
|
+
if (this.device.offline) {
|
|
526
|
+
this.On = false;
|
|
527
|
+
this.service.getCharacteristic(this.platform.Characteristic.On).updateValue(this.On);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
|
|
517
531
|
/**
|
|
518
532
|
* Handle requests to set the value of the "On" characteristic
|
|
519
533
|
*/
|
package/src/devices/contact.ts
CHANGED
|
@@ -50,7 +50,7 @@ export class Contact {
|
|
|
50
50
|
public device: device & devicesConfig,
|
|
51
51
|
) {
|
|
52
52
|
// Contact Config
|
|
53
|
-
this.platform.device(`Contact Sensor: ${this.accessory.displayName} Config: (ble: ${device.ble},`
|
|
53
|
+
this.platform.device(`Contact Sensor: ${this.accessory.displayName} Config: (ble: ${device.ble}, offline: ${device.offline},`
|
|
54
54
|
+ ` hide_lightsensor: ${device.contact?.hide_lightsensor}, hide_motionsensor: ${device.contact?.hide_motionsensor})`);
|
|
55
55
|
|
|
56
56
|
|
|
@@ -50,7 +50,7 @@ export class Humidifier {
|
|
|
50
50
|
public device: device & devicesConfig,
|
|
51
51
|
) {
|
|
52
52
|
// Humidifiers Config
|
|
53
|
-
this.platform.device(`Humidifier: ${this.accessory.displayName} Config: (ble: ${device.ble}, hide_temperature: `
|
|
53
|
+
this.platform.device(`Humidifier: ${this.accessory.displayName} Config: (ble: ${device.ble}, offline: ${device.offline}, hide_temperature: `
|
|
54
54
|
+ `${device.humidifier?.hide_temperature}, set_minStep: ${device.humidifier?.set_minStep})`);
|
|
55
55
|
|
|
56
56
|
// default placeholders
|
|
@@ -633,9 +633,11 @@ export class Humidifier {
|
|
|
633
633
|
break;
|
|
634
634
|
case 161:
|
|
635
635
|
this.platform.log.error(`Humidifier: ${this.accessory.displayName} Device is offline.`);
|
|
636
|
+
this.offlineOff();
|
|
636
637
|
break;
|
|
637
638
|
case 171:
|
|
638
639
|
this.platform.log.error(`Humidifier: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
|
|
640
|
+
this.offlineOff();
|
|
639
641
|
break;
|
|
640
642
|
case 190:
|
|
641
643
|
this.platform.log.error(`Humidifier: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,`
|
|
@@ -649,6 +651,13 @@ export class Humidifier {
|
|
|
649
651
|
}
|
|
650
652
|
}
|
|
651
653
|
|
|
654
|
+
private offlineOff() {
|
|
655
|
+
if (this.device.offline) {
|
|
656
|
+
this.Active = this.platform.Characteristic.Active.INACTIVE;
|
|
657
|
+
this.service.getCharacteristic(this.platform.Characteristic.Active).updateValue(this.Active);
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
|
|
652
661
|
/**
|
|
653
662
|
* Handle requests to set the "Target Humidifier Dehumidifier State" characteristic
|
|
654
663
|
*/
|
package/src/devices/indoorcam.ts
CHANGED
|
@@ -215,9 +215,15 @@ export class IndoorCam {
|
|
|
215
215
|
break;
|
|
216
216
|
case 161:
|
|
217
217
|
this.platform.log.error(`Indoor Cam: ${this.accessory.displayName} Device is offline.`);
|
|
218
|
+
if (this.device.offline) {
|
|
219
|
+
this.Active = false;
|
|
220
|
+
}
|
|
218
221
|
break;
|
|
219
222
|
case 171:
|
|
220
223
|
this.platform.log.error(`Indoor Cam: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
|
|
224
|
+
if (this.device.offline) {
|
|
225
|
+
this.Active = false;
|
|
226
|
+
}
|
|
221
227
|
break;
|
|
222
228
|
case 190:
|
|
223
229
|
this.platform.log.error(`Indoor Cam: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,`
|
package/src/devices/meters.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { interval, Subject } from 'rxjs';
|
|
|
3
3
|
import { skipWhile } from 'rxjs/operators';
|
|
4
4
|
import { SwitchBotPlatform } from '../platform';
|
|
5
5
|
import { Service, PlatformAccessory, Units, CharacteristicValue } from 'homebridge';
|
|
6
|
-
import { DeviceURL, device, devicesConfig, serviceData, ad, switchbot, deviceStatusResponse } from '../settings';
|
|
6
|
+
import { DeviceURL, device, devicesConfig, serviceData, ad, switchbot, deviceStatusResponse, temperature } from '../settings';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Platform Accessory
|
|
@@ -18,8 +18,11 @@ export class Meter {
|
|
|
18
18
|
|
|
19
19
|
// Characteristic Values
|
|
20
20
|
CurrentRelativeHumidity!: CharacteristicValue;
|
|
21
|
+
CurrentRelativeHumidityCached!: CharacteristicValue;
|
|
21
22
|
CurrentTemperature!: CharacteristicValue;
|
|
23
|
+
CurrentTemperatureCached!: CharacteristicValue;
|
|
22
24
|
BatteryLevel!: CharacteristicValue;
|
|
25
|
+
BatteryLevelCached!: CharacteristicValue;
|
|
23
26
|
ChargingState!: CharacteristicValue;
|
|
24
27
|
StatusLowBattery!: CharacteristicValue;
|
|
25
28
|
Active!: CharacteristicValue;
|
|
@@ -32,10 +35,9 @@ export class Meter {
|
|
|
32
35
|
connected?: boolean;
|
|
33
36
|
switchbot!: switchbot;
|
|
34
37
|
serviceData!: serviceData;
|
|
38
|
+
temperature!: temperature['c'];
|
|
35
39
|
battery!: serviceData['battery'];
|
|
36
40
|
humidity!: serviceData['humidity'];
|
|
37
|
-
fahrenheit!: serviceData['fahrenheit'];
|
|
38
|
-
temperature!: serviceData['temperature'];
|
|
39
41
|
|
|
40
42
|
// Config
|
|
41
43
|
private readonly deviceDebug = this.platform.config.options?.debug === 'device' || this.platform.debugMode;
|
|
@@ -51,15 +53,31 @@ export class Meter {
|
|
|
51
53
|
public device: device & devicesConfig,
|
|
52
54
|
) {
|
|
53
55
|
// Meter Config
|
|
54
|
-
this.platform.device(`Meter: ${this.accessory.displayName} Config: (ble: ${device.ble},
|
|
55
|
-
+ `
|
|
56
|
+
this.platform.device(`Meter: ${this.accessory.displayName} Config: (ble: ${device.ble}, hide_temperature: ${device.meter?.hide_temperature},`
|
|
57
|
+
+ ` hide_humidity: ${device.meter?.hide_humidity})`);
|
|
56
58
|
|
|
57
59
|
// default placeholders
|
|
58
|
-
this.BatteryLevel
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
if (this.BatteryLevel === undefined) {
|
|
61
|
+
this.BatteryLevel = 100;
|
|
62
|
+
} else {
|
|
63
|
+
this.BatteryLevel = this.accessory.context.BatteryLevel;
|
|
64
|
+
}
|
|
65
|
+
if (this.BatteryLevel < 15) {
|
|
66
|
+
this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
67
|
+
} else {
|
|
68
|
+
this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
69
|
+
}
|
|
70
|
+
this.ChargingState = this.platform.Characteristic.ChargingState.NOT_CHARGEABLE;
|
|
71
|
+
if (this.CurrentRelativeHumidity === undefined) {
|
|
72
|
+
this.CurrentRelativeHumidity = 0;
|
|
73
|
+
} else {
|
|
74
|
+
this.CurrentRelativeHumidity = this.accessory.context.CurrentRelativeHumidity;
|
|
75
|
+
}
|
|
76
|
+
if (this.CurrentTemperature === undefined) {
|
|
77
|
+
this.CurrentTemperature = 0;
|
|
78
|
+
} else {
|
|
79
|
+
this.CurrentTemperature = this.accessory.context.CurrentTemperature;
|
|
80
|
+
}
|
|
63
81
|
|
|
64
82
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
65
83
|
this.doMeterUpdate = new Subject();
|
|
@@ -177,9 +195,9 @@ export class Meter {
|
|
|
177
195
|
// Battery
|
|
178
196
|
this.BatteryLevel = Number(this.battery);
|
|
179
197
|
if (this.BatteryLevel < 15) {
|
|
180
|
-
this.StatusLowBattery =
|
|
198
|
+
this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
181
199
|
} else {
|
|
182
|
-
this.StatusLowBattery =
|
|
200
|
+
this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
183
201
|
}
|
|
184
202
|
this.platform.debug(`${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}, StatusLowBattery: ${this.StatusLowBattery}`);
|
|
185
203
|
|
|
@@ -191,13 +209,8 @@ export class Meter {
|
|
|
191
209
|
|
|
192
210
|
// Current Temperature
|
|
193
211
|
if (!this.device.meter?.hide_temperature) {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
} else if (this.device.meter?.unit === 0) {
|
|
197
|
-
this.CurrentTemperature = this.toCelsius(this.temperature!.c);
|
|
198
|
-
} else {
|
|
199
|
-
this.CurrentTemperature = Number(this.temperature?.c);
|
|
200
|
-
}
|
|
212
|
+
this.temperature < 0 ? 0 : this.temperature > 100 ? 100 : this.temperature;
|
|
213
|
+
this.CurrentTemperature = this.temperature;
|
|
201
214
|
this.platform.debug(`Meter: ${this.accessory.displayName} Temperature: ${this.CurrentTemperature}°c`);
|
|
202
215
|
}
|
|
203
216
|
}
|
|
@@ -211,9 +224,9 @@ export class Meter {
|
|
|
211
224
|
this.BatteryLevel = 10;
|
|
212
225
|
}
|
|
213
226
|
if (this.BatteryLevel < 15) {
|
|
214
|
-
this.StatusLowBattery =
|
|
227
|
+
this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
215
228
|
} else {
|
|
216
|
-
this.StatusLowBattery =
|
|
229
|
+
this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
217
230
|
}
|
|
218
231
|
// Current Relative Humidity
|
|
219
232
|
if (!this.device.meter?.hide_humidity) {
|
|
@@ -223,13 +236,7 @@ export class Meter {
|
|
|
223
236
|
|
|
224
237
|
// Current Temperature
|
|
225
238
|
if (!this.device.meter?.hide_temperature) {
|
|
226
|
-
|
|
227
|
-
this.CurrentTemperature = this.toFahrenheit(this.deviceStatus.body.temperature!);
|
|
228
|
-
} else if (this.device.meter?.unit === 0) {
|
|
229
|
-
this.CurrentTemperature = this.toCelsius(this.deviceStatus.body.temperature!);
|
|
230
|
-
} else {
|
|
231
|
-
this.CurrentTemperature = Number(this.deviceStatus.body.temperature);
|
|
232
|
-
}
|
|
239
|
+
this.CurrentTemperature = Number(this.deviceStatus.body.temperature);
|
|
233
240
|
this.platform.debug(`Meter: ${this.accessory.displayName} Temperature: ${this.CurrentTemperature}°c`);
|
|
234
241
|
}
|
|
235
242
|
}
|
|
@@ -259,20 +266,18 @@ export class Meter {
|
|
|
259
266
|
const switchbot = this.connectBLE();
|
|
260
267
|
// Start to monitor advertisement packets
|
|
261
268
|
switchbot.startScan({
|
|
262
|
-
model: 'T',
|
|
263
269
|
id: this.device.bleMac,
|
|
264
270
|
}).then(() => {
|
|
265
271
|
// Set an event hander
|
|
266
272
|
switchbot.onadvertisement = (ad: ad) => {
|
|
267
273
|
this.serviceData = ad.serviceData;
|
|
268
|
-
this.temperature = ad.serviceData.temperature;
|
|
269
|
-
this.fahrenheit = ad.serviceData.fahrenheit;
|
|
274
|
+
this.temperature = ad.serviceData.temperature!.c;
|
|
270
275
|
this.humidity = ad.serviceData.humidity;
|
|
271
276
|
this.battery = ad.serviceData.battery;
|
|
272
277
|
this.platform.device(`Meter: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
273
278
|
this.platform.device(`Meter: ${this.accessory.displayName} model: ${ad.serviceData.model}, modelName: ${ad.serviceData.modelName}, `
|
|
274
|
-
+ `temperature: ${JSON.stringify(ad.serviceData.temperature)},
|
|
275
|
-
+ `
|
|
279
|
+
+ `temperature: ${JSON.stringify(ad.serviceData.temperature?.c)}, humidity: ${ad.serviceData.humidity}, `
|
|
280
|
+
+ `battery: ${ad.serviceData.battery}`);
|
|
276
281
|
|
|
277
282
|
if (this.serviceData) {
|
|
278
283
|
this.connected = true;
|
|
@@ -288,6 +293,12 @@ export class Meter {
|
|
|
288
293
|
// Stop to monitor
|
|
289
294
|
switchbot.stopScan();
|
|
290
295
|
if (this.connected) {
|
|
296
|
+
this.CurrentTemperatureCached = this.temperature;
|
|
297
|
+
this.accessory.context.CurrentTemperature = this.CurrentTemperatureCached;
|
|
298
|
+
this.CurrentRelativeHumidityCached = this.humidity!;
|
|
299
|
+
this.accessory.context.CurrentRelativeHumidity = this.CurrentRelativeHumidityCached;
|
|
300
|
+
this.BatteryLevelCached = this.battery!;
|
|
301
|
+
this.accessory.context.BatteryLevel = this.BatteryLevelCached;
|
|
291
302
|
this.parseStatus();
|
|
292
303
|
this.updateHomeKitCharacteristics();
|
|
293
304
|
} else {
|
|
@@ -321,6 +332,12 @@ export class Meter {
|
|
|
321
332
|
try {
|
|
322
333
|
this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
|
|
323
334
|
this.platform.debug(`Meter: ${this.accessory.displayName} openAPIRefreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
335
|
+
this.CurrentTemperatureCached = this.deviceStatus.body.humidity!;
|
|
336
|
+
this.accessory.context.CurrentTemperature = this.CurrentTemperatureCached;
|
|
337
|
+
this.CurrentRelativeHumidityCached = this.deviceStatus.body.humidity!;
|
|
338
|
+
this.accessory.context.CurrentRelativeHumidity = this.CurrentRelativeHumidityCached;
|
|
339
|
+
this.BatteryLevelCached = 100;
|
|
340
|
+
this.accessory.context.BatteryLevel = this.BatteryLevelCached;
|
|
324
341
|
this.parseStatus();
|
|
325
342
|
this.updateHomeKitCharacteristics();
|
|
326
343
|
} catch (e: any) {
|
|
@@ -382,19 +399,4 @@ export class Meter {
|
|
|
382
399
|
this.temperatureservice?.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, e);
|
|
383
400
|
}
|
|
384
401
|
}
|
|
385
|
-
|
|
386
|
-
/**
|
|
387
|
-
* Converts the value to celsius if the temperature units are in Fahrenheit
|
|
388
|
-
*/
|
|
389
|
-
toCelsius(value: number) {
|
|
390
|
-
// celsius should be to the nearest 0.5 degree
|
|
391
|
-
return Math.round((5 / 9) * (value - 32) * 2) / 2;
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
/**
|
|
395
|
-
* Converts the value to fahrenheit if the temperature units are in Fahrenheit
|
|
396
|
-
*/
|
|
397
|
-
toFahrenheit(value: number) {
|
|
398
|
-
return Math.round((value * 9) / 5 + 32);
|
|
399
|
-
}
|
|
400
402
|
}
|
package/src/devices/plugs.ts
CHANGED
|
@@ -12,6 +12,7 @@ export class Plug {
|
|
|
12
12
|
|
|
13
13
|
// Characteristic Values
|
|
14
14
|
On!: CharacteristicValue;
|
|
15
|
+
OnCached!: CharacteristicValue;
|
|
15
16
|
|
|
16
17
|
// OpenAPI Others
|
|
17
18
|
deviceStatus!: deviceStatusResponse;
|
|
@@ -29,8 +30,15 @@ export class Plug {
|
|
|
29
30
|
private accessory: PlatformAccessory,
|
|
30
31
|
public device: device & devicesConfig,
|
|
31
32
|
) {
|
|
33
|
+
// Bot Config
|
|
34
|
+
this.platform.device(`Plug: ${this.accessory.displayName} Config: (offline: ${device.offline})`);
|
|
35
|
+
|
|
32
36
|
// default placeholders
|
|
33
|
-
this.On
|
|
37
|
+
if (this.On === undefined) {
|
|
38
|
+
this.On = false;
|
|
39
|
+
} else {
|
|
40
|
+
this.On = this.accessory.context.On;
|
|
41
|
+
}
|
|
34
42
|
|
|
35
43
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
36
44
|
this.doPlugUpdate = new Subject();
|
|
@@ -142,24 +150,28 @@ export class Plug {
|
|
|
142
150
|
* Plug - "command" "turnOn" "default" = set to ON state
|
|
143
151
|
*/
|
|
144
152
|
async pushChanges() {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
153
|
+
if (this.On !== this.OnCached) {
|
|
154
|
+
const payload = {
|
|
155
|
+
commandType: 'command',
|
|
156
|
+
parameter: 'default',
|
|
157
|
+
} as payload;
|
|
158
|
+
|
|
159
|
+
if (this.On) {
|
|
160
|
+
payload.command = 'turnOn';
|
|
161
|
+
} else {
|
|
162
|
+
payload.command = 'turnOff';
|
|
163
|
+
}
|
|
155
164
|
|
|
156
|
-
|
|
157
|
-
|
|
165
|
+
this.platform.log.info(`Plug: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},`
|
|
166
|
+
+ ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`);
|
|
158
167
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
168
|
+
// Make the API request
|
|
169
|
+
const push: any = (await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload));
|
|
170
|
+
this.platform.debug(`Plug: ${this.accessory.displayName} pushchanges: ${JSON.stringify(push.data)}`);
|
|
171
|
+
this.statusCode(push);
|
|
172
|
+
this.OnCached = this.On;
|
|
173
|
+
this.accessory.context.On = this.OnCached;
|
|
174
|
+
}
|
|
163
175
|
interval(5000)
|
|
164
176
|
.pipe(skipWhile(() => this.plugUpdateInProgress))
|
|
165
177
|
.pipe(take(1))
|
|
@@ -194,9 +206,11 @@ export class Plug {
|
|
|
194
206
|
break;
|
|
195
207
|
case 161:
|
|
196
208
|
this.platform.log.error(`Plug: ${this.accessory.displayName} Device is offline.`);
|
|
209
|
+
this.offlineOff();
|
|
197
210
|
break;
|
|
198
211
|
case 171:
|
|
199
212
|
this.platform.log.error(`Plug: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
|
|
213
|
+
this.offlineOff();
|
|
200
214
|
break;
|
|
201
215
|
case 190:
|
|
202
216
|
this.platform.log.error(`Plug: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,`
|
|
@@ -210,6 +224,13 @@ export class Plug {
|
|
|
210
224
|
}
|
|
211
225
|
}
|
|
212
226
|
|
|
227
|
+
private offlineOff() {
|
|
228
|
+
if (this.device.offline) {
|
|
229
|
+
this.On = false;
|
|
230
|
+
this.service.getCharacteristic(this.platform.Characteristic.On).updateValue(this.On);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
213
234
|
/**
|
|
214
235
|
* Handle requests to set the value of the "On" characteristic
|
|
215
236
|
*/
|