@switchbot/homebridge-switchbot 1.3.1-beta.7 → 1.4.1-beta.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 +3 -1
- package/dist/devices/bots.d.ts.map +1 -1
- package/dist/devices/bots.js +114 -97
- package/dist/devices/bots.js.map +1 -1
- package/dist/devices/colorbulb.d.ts +2 -1
- package/dist/devices/colorbulb.d.ts.map +1 -1
- package/dist/devices/colorbulb.js +26 -16
- package/dist/devices/colorbulb.js.map +1 -1
- package/dist/devices/contact.d.ts +1 -1
- package/dist/devices/contact.d.ts.map +1 -1
- package/dist/devices/contact.js +5 -15
- package/dist/devices/contact.js.map +1 -1
- package/dist/devices/curtains.d.ts +1 -1
- package/dist/devices/curtains.d.ts.map +1 -1
- package/dist/devices/curtains.js +7 -16
- package/dist/devices/curtains.js.map +1 -1
- package/dist/devices/humidifiers.d.ts +2 -1
- package/dist/devices/humidifiers.d.ts.map +1 -1
- package/dist/devices/humidifiers.js +18 -20
- package/dist/devices/humidifiers.js.map +1 -1
- package/dist/devices/indoorcam.d.ts +1 -1
- package/dist/devices/indoorcam.d.ts.map +1 -1
- package/dist/devices/indoorcam.js +11 -5
- package/dist/devices/indoorcam.js.map +1 -1
- package/dist/devices/meters.d.ts +6 -12
- package/dist/devices/meters.d.ts.map +1 -1
- package/dist/devices/meters.js +58 -62
- package/dist/devices/meters.js.map +1 -1
- package/dist/devices/motion.d.ts +1 -1
- package/dist/devices/motion.d.ts.map +1 -1
- package/dist/devices/motion.js +4 -9
- package/dist/devices/motion.js.map +1 -1
- package/dist/devices/plugs.d.ts +3 -1
- package/dist/devices/plugs.d.ts.map +1 -1
- package/dist/devices/plugs.js +39 -20
- package/dist/devices/plugs.js.map +1 -1
- package/dist/irdevices/airconditioners.d.ts +3 -1
- package/dist/irdevices/airconditioners.d.ts.map +1 -1
- package/dist/irdevices/airconditioners.js +20 -9
- package/dist/irdevices/airconditioners.js.map +1 -1
- package/dist/irdevices/airpurifiers.d.ts +3 -1
- package/dist/irdevices/airpurifiers.d.ts.map +1 -1
- package/dist/irdevices/airpurifiers.js +20 -6
- package/dist/irdevices/airpurifiers.js.map +1 -1
- package/dist/irdevices/cameras.d.ts +2 -1
- package/dist/irdevices/cameras.d.ts.map +1 -1
- package/dist/irdevices/cameras.js +12 -3
- package/dist/irdevices/cameras.js.map +1 -1
- package/dist/irdevices/fans.d.ts +2 -1
- package/dist/irdevices/fans.d.ts.map +1 -1
- package/dist/irdevices/fans.js +12 -5
- package/dist/irdevices/fans.js.map +1 -1
- package/dist/irdevices/lights.d.ts +2 -1
- package/dist/irdevices/lights.d.ts.map +1 -1
- package/dist/irdevices/lights.js +12 -3
- package/dist/irdevices/lights.js.map +1 -1
- package/dist/irdevices/others.d.ts +2 -1
- package/dist/irdevices/others.d.ts.map +1 -1
- package/dist/irdevices/others.js +12 -3
- package/dist/irdevices/others.js.map +1 -1
- package/dist/irdevices/tvs.d.ts +2 -1
- package/dist/irdevices/tvs.d.ts.map +1 -1
- package/dist/irdevices/tvs.js +12 -4
- package/dist/irdevices/tvs.js.map +1 -1
- package/dist/irdevices/vacuumcleaners.d.ts +2 -1
- package/dist/irdevices/vacuumcleaners.d.ts.map +1 -1
- package/dist/irdevices/vacuumcleaners.js +12 -3
- package/dist/irdevices/vacuumcleaners.js.map +1 -1
- package/dist/irdevices/waterheaters.d.ts +2 -1
- package/dist/irdevices/waterheaters.d.ts.map +1 -1
- package/dist/irdevices/waterheaters.js +12 -3
- 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 +7 -7
- package/src/devices/bots.ts +95 -77
- package/src/devices/colorbulb.ts +27 -17
- package/src/devices/contact.ts +6 -16
- package/src/devices/curtains.ts +8 -17
- package/src/devices/humidifiers.ts +20 -21
- package/src/devices/indoorcam.ts +12 -6
- package/src/devices/meters.ts +60 -64
- package/src/devices/motion.ts +5 -10
- package/src/devices/plugs.ts +43 -22
- package/src/irdevices/airconditioners.ts +21 -10
- package/src/irdevices/airpurifiers.ts +22 -7
- package/src/irdevices/cameras.ts +14 -4
- package/src/irdevices/fans.ts +14 -6
- package/src/irdevices/lights.ts +14 -4
- package/src/irdevices/others.ts +14 -4
- package/src/irdevices/tvs.ts +14 -5
- package/src/irdevices/vacuumcleaners.ts +14 -4
- package/src/irdevices/waterheaters.ts +14 -4
- package/src/platform.ts +37 -2
- package/src/settings.ts +7 -5
|
@@ -3,7 +3,7 @@ import Switchbot from 'node-switchbot';
|
|
|
3
3
|
import { interval, Subject } from 'rxjs';
|
|
4
4
|
import { SwitchBotPlatform } from '../platform';
|
|
5
5
|
import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
|
|
6
|
-
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
6
|
+
import { Service, PlatformAccessory, CharacteristicValue, HAPStatus } from 'homebridge';
|
|
7
7
|
import { DeviceURL, device, devicesConfig, serviceData, ad, deviceStatusResponse, payload } from '../settings';
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -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
|
|
@@ -184,7 +184,7 @@ export class Humidifier {
|
|
|
184
184
|
this.platform.log.error(`Humidifier: ${this.accessory.displayName} failed pushChanges,`
|
|
185
185
|
+ ` Error: ${JSON.stringify(e)}`);
|
|
186
186
|
}
|
|
187
|
-
this.apiError(
|
|
187
|
+
this.apiError();
|
|
188
188
|
}
|
|
189
189
|
this.humidifierUpdateInProgress = false;
|
|
190
190
|
});
|
|
@@ -354,7 +354,7 @@ export class Humidifier {
|
|
|
354
354
|
this.platform.log.warn(`Humidifier: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
355
355
|
await this.openAPIRefreshStatus();
|
|
356
356
|
}
|
|
357
|
-
this.apiError(
|
|
357
|
+
this.apiError();
|
|
358
358
|
});
|
|
359
359
|
}
|
|
360
360
|
|
|
@@ -380,7 +380,7 @@ export class Humidifier {
|
|
|
380
380
|
this.platform.log.error(`Humidifier: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,`
|
|
381
381
|
+ ` Error: ${JSON.stringify(e)}`);
|
|
382
382
|
}
|
|
383
|
-
this.apiError(
|
|
383
|
+
this.apiError();
|
|
384
384
|
}
|
|
385
385
|
}
|
|
386
386
|
}
|
|
@@ -424,7 +424,7 @@ export class Humidifier {
|
|
|
424
424
|
this.platform.log.warn(`Humidifier: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
425
425
|
await this.OpenAPIpushChanges();
|
|
426
426
|
}
|
|
427
|
-
this.apiError(
|
|
427
|
+
this.apiError();
|
|
428
428
|
});
|
|
429
429
|
}
|
|
430
430
|
|
|
@@ -461,7 +461,7 @@ export class Humidifier {
|
|
|
461
461
|
this.platform.log.error(`Humidifier: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
|
|
462
462
|
+ ` Error: ${JSON.stringify(e)}`);
|
|
463
463
|
}
|
|
464
|
-
this.apiError(
|
|
464
|
+
this.apiError();
|
|
465
465
|
}
|
|
466
466
|
} else if (
|
|
467
467
|
this.TargetHumidifierDehumidifierState ===
|
|
@@ -510,7 +510,7 @@ export class Humidifier {
|
|
|
510
510
|
this.platform.log.error(`Humidifier: ${this.accessory.displayName} failed pushAutoChanges with OpenAPI Connection,`
|
|
511
511
|
+ ` Error: ${JSON.stringify(e)}`);
|
|
512
512
|
}
|
|
513
|
-
this.apiError(
|
|
513
|
+
this.apiError();
|
|
514
514
|
}
|
|
515
515
|
}
|
|
516
516
|
|
|
@@ -545,7 +545,7 @@ export class Humidifier {
|
|
|
545
545
|
this.platform.log.error(`Humidifier: ${this.accessory.displayName} failed pushActiveChanges with OpenAPI Connection,`
|
|
546
546
|
+ ` Error: ${JSON.stringify(e)}`);
|
|
547
547
|
}
|
|
548
|
-
this.apiError(
|
|
548
|
+
this.apiError();
|
|
549
549
|
}
|
|
550
550
|
}
|
|
551
551
|
|
|
@@ -606,18 +606,8 @@ export class Humidifier {
|
|
|
606
606
|
}
|
|
607
607
|
}
|
|
608
608
|
|
|
609
|
-
public apiError(
|
|
610
|
-
this.
|
|
611
|
-
if (!this.device.ble) {
|
|
612
|
-
this.service.updateCharacteristic(this.platform.Characteristic.WaterLevel, e);
|
|
613
|
-
}
|
|
614
|
-
this.service.updateCharacteristic(this.platform.Characteristic.CurrentHumidifierDehumidifierState, e);
|
|
615
|
-
this.service.updateCharacteristic(this.platform.Characteristic.TargetHumidifierDehumidifierState, e);
|
|
616
|
-
this.service.updateCharacteristic(this.platform.Characteristic.Active, e);
|
|
617
|
-
this.service.updateCharacteristic(this.platform.Characteristic.RelativeHumidityHumidifierThreshold, e);
|
|
618
|
-
if (!this.device.humidifier?.hide_temperature && !this.device.ble) {
|
|
619
|
-
this.temperatureservice?.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, e);
|
|
620
|
-
}
|
|
609
|
+
public apiError() {
|
|
610
|
+
throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
621
611
|
}
|
|
622
612
|
|
|
623
613
|
private statusCode(push: AxiosResponse<{ statusCode: number; }>) {
|
|
@@ -633,9 +623,11 @@ export class Humidifier {
|
|
|
633
623
|
break;
|
|
634
624
|
case 161:
|
|
635
625
|
this.platform.log.error(`Humidifier: ${this.accessory.displayName} Device is offline.`);
|
|
626
|
+
this.offlineOff();
|
|
636
627
|
break;
|
|
637
628
|
case 171:
|
|
638
629
|
this.platform.log.error(`Humidifier: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
|
|
630
|
+
this.offlineOff();
|
|
639
631
|
break;
|
|
640
632
|
case 190:
|
|
641
633
|
this.platform.log.error(`Humidifier: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,`
|
|
@@ -649,6 +641,13 @@ export class Humidifier {
|
|
|
649
641
|
}
|
|
650
642
|
}
|
|
651
643
|
|
|
644
|
+
private offlineOff() {
|
|
645
|
+
if (this.device.offline) {
|
|
646
|
+
this.Active = this.platform.Characteristic.Active.INACTIVE;
|
|
647
|
+
this.service.getCharacteristic(this.platform.Characteristic.Active).updateValue(this.Active);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
|
|
652
651
|
/**
|
|
653
652
|
* Handle requests to set the "Target Humidifier Dehumidifier State" characteristic
|
|
654
653
|
*/
|
package/src/devices/indoorcam.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { AxiosResponse } from 'axios';
|
|
|
2
2
|
import { interval, Subject } from 'rxjs';
|
|
3
3
|
import { SwitchBotPlatform } from '../platform';
|
|
4
4
|
import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
|
|
5
|
-
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
5
|
+
import { Service, PlatformAccessory, CharacteristicValue, HAPStatus } from 'homebridge';
|
|
6
6
|
import { DeviceURL, device, devicesConfig, deviceStatusResponse, payload } from '../settings';
|
|
7
7
|
|
|
8
8
|
export class IndoorCam {
|
|
@@ -126,7 +126,7 @@ export class IndoorCam {
|
|
|
126
126
|
this.platform.log.error(`Indoor Cam: ${this.accessory.displayName} failed pushChanges,`
|
|
127
127
|
+ ` Error: ${JSON.stringify(e)}`);
|
|
128
128
|
}
|
|
129
|
-
this.apiError(
|
|
129
|
+
this.apiError();
|
|
130
130
|
}
|
|
131
131
|
this.cameraUpdateInProgress = false;
|
|
132
132
|
});
|
|
@@ -139,7 +139,7 @@ export class IndoorCam {
|
|
|
139
139
|
|
|
140
140
|
private async refreshStatus() {
|
|
141
141
|
try {
|
|
142
|
-
this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
|
|
142
|
+
//this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
|
|
143
143
|
this.platform.device(`Indoor Cam: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
144
144
|
this.parseStatus();
|
|
145
145
|
this.updateHomeKitCharacteristics();
|
|
@@ -153,7 +153,7 @@ export class IndoorCam {
|
|
|
153
153
|
this.platform.log.error(`Indoor Cam: ${this.accessory.displayName} failed refreshStatus with BLE Connection,`
|
|
154
154
|
+ ` Error: ${JSON.stringify(e)}`);
|
|
155
155
|
}
|
|
156
|
-
this.apiError(
|
|
156
|
+
this.apiError();
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
159
|
|
|
@@ -198,8 +198,8 @@ export class IndoorCam {
|
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
-
public apiError(
|
|
202
|
-
this.
|
|
201
|
+
public apiError() {
|
|
202
|
+
throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
203
203
|
}
|
|
204
204
|
|
|
205
205
|
private statusCode(push: AxiosResponse<{ statusCode: number; }>) {
|
|
@@ -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
|
@@ -2,8 +2,8 @@ import Switchbot from 'node-switchbot';
|
|
|
2
2
|
import { interval, Subject } from 'rxjs';
|
|
3
3
|
import { skipWhile } from 'rxjs/operators';
|
|
4
4
|
import { SwitchBotPlatform } from '../platform';
|
|
5
|
-
import { Service, PlatformAccessory, Units, CharacteristicValue } from 'homebridge';
|
|
6
|
-
import { DeviceURL, device, devicesConfig, serviceData, ad, switchbot, deviceStatusResponse } from '../settings';
|
|
5
|
+
import { Service, PlatformAccessory, Units, CharacteristicValue, HAPStatus } from 'homebridge';
|
|
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
|
}
|
|
@@ -240,9 +247,9 @@ export class Meter {
|
|
|
240
247
|
*/
|
|
241
248
|
async refreshStatus() {
|
|
242
249
|
if (this.device.ble) {
|
|
243
|
-
|
|
250
|
+
this.BLErefreshStatus();
|
|
244
251
|
} else {
|
|
245
|
-
|
|
252
|
+
this.openAPIRefreshStatus();
|
|
246
253
|
}
|
|
247
254
|
}
|
|
248
255
|
|
|
@@ -253,7 +260,7 @@ export class Meter {
|
|
|
253
260
|
return switchbot;
|
|
254
261
|
}
|
|
255
262
|
|
|
256
|
-
private
|
|
263
|
+
private BLErefreshStatus() {
|
|
257
264
|
this.platform.debug(`Meter: ${this.accessory.displayName} BLE RefreshStatus`);
|
|
258
265
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
259
266
|
const switchbot = this.connectBLE();
|
|
@@ -265,14 +272,13 @@ export class Meter {
|
|
|
265
272
|
// Set an event hander
|
|
266
273
|
switchbot.onadvertisement = (ad: ad) => {
|
|
267
274
|
this.serviceData = ad.serviceData;
|
|
268
|
-
this.temperature = ad.serviceData.temperature;
|
|
269
|
-
this.fahrenheit = ad.serviceData.fahrenheit;
|
|
275
|
+
this.temperature = ad.serviceData.temperature!.c;
|
|
270
276
|
this.humidity = ad.serviceData.humidity;
|
|
271
277
|
this.battery = ad.serviceData.battery;
|
|
272
278
|
this.platform.device(`Meter: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
273
279
|
this.platform.device(`Meter: ${this.accessory.displayName} model: ${ad.serviceData.model}, modelName: ${ad.serviceData.modelName}, `
|
|
274
|
-
+ `temperature: ${JSON.stringify(ad.serviceData.temperature)},
|
|
275
|
-
+ `
|
|
280
|
+
+ `temperature: ${JSON.stringify(ad.serviceData.temperature?.c)}, humidity: ${ad.serviceData.humidity}, `
|
|
281
|
+
+ `battery: ${ad.serviceData.battery}`);
|
|
276
282
|
|
|
277
283
|
if (this.serviceData) {
|
|
278
284
|
this.connected = true;
|
|
@@ -288,13 +294,19 @@ export class Meter {
|
|
|
288
294
|
// Stop to monitor
|
|
289
295
|
switchbot.stopScan();
|
|
290
296
|
if (this.connected) {
|
|
297
|
+
this.CurrentTemperatureCached = this.temperature;
|
|
298
|
+
this.accessory.context.CurrentTemperature = this.CurrentTemperatureCached;
|
|
299
|
+
this.CurrentRelativeHumidityCached = this.humidity!;
|
|
300
|
+
this.accessory.context.CurrentRelativeHumidity = this.CurrentRelativeHumidityCached;
|
|
301
|
+
this.BatteryLevelCached = this.battery!;
|
|
302
|
+
this.accessory.context.BatteryLevel = this.BatteryLevelCached;
|
|
291
303
|
this.parseStatus();
|
|
292
304
|
this.updateHomeKitCharacteristics();
|
|
293
305
|
} else {
|
|
294
306
|
this.platform.log.error(`Meter: ${this.accessory.displayName} wasn't able to establish BLE Connection`);
|
|
295
307
|
if (this.platform.config.credentials?.openToken) {
|
|
296
308
|
this.platform.log.warn(`Meter: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
297
|
-
|
|
309
|
+
this.openAPIRefreshStatus();
|
|
298
310
|
}
|
|
299
311
|
}
|
|
300
312
|
}).catch(async (e: any) => {
|
|
@@ -309,9 +321,9 @@ export class Meter {
|
|
|
309
321
|
}
|
|
310
322
|
if (this.platform.config.credentials?.openToken) {
|
|
311
323
|
this.platform.log.warn(`Meter: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
312
|
-
|
|
324
|
+
this.openAPIRefreshStatus();
|
|
313
325
|
}
|
|
314
|
-
this.apiError(
|
|
326
|
+
this.apiError();
|
|
315
327
|
});
|
|
316
328
|
}
|
|
317
329
|
|
|
@@ -321,6 +333,12 @@ export class Meter {
|
|
|
321
333
|
try {
|
|
322
334
|
this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
|
|
323
335
|
this.platform.debug(`Meter: ${this.accessory.displayName} openAPIRefreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
336
|
+
this.CurrentTemperatureCached = this.deviceStatus.body.humidity!;
|
|
337
|
+
this.accessory.context.CurrentTemperature = this.CurrentTemperatureCached;
|
|
338
|
+
this.CurrentRelativeHumidityCached = this.deviceStatus.body.humidity!;
|
|
339
|
+
this.accessory.context.CurrentRelativeHumidity = this.CurrentRelativeHumidityCached;
|
|
340
|
+
this.BatteryLevelCached = 100;
|
|
341
|
+
this.accessory.context.BatteryLevel = this.BatteryLevelCached;
|
|
324
342
|
this.parseStatus();
|
|
325
343
|
this.updateHomeKitCharacteristics();
|
|
326
344
|
} catch (e: any) {
|
|
@@ -333,7 +351,7 @@ export class Meter {
|
|
|
333
351
|
this.platform.log.error(`Meter: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,`
|
|
334
352
|
+ ` Error: ${JSON.stringify(e)}`);
|
|
335
353
|
}
|
|
336
|
-
this.apiError(
|
|
354
|
+
this.apiError();
|
|
337
355
|
}
|
|
338
356
|
}
|
|
339
357
|
}
|
|
@@ -372,29 +390,7 @@ export class Meter {
|
|
|
372
390
|
}
|
|
373
391
|
}
|
|
374
392
|
|
|
375
|
-
public apiError(
|
|
376
|
-
this.
|
|
377
|
-
this.service.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
|
|
378
|
-
if (!this.device.meter?.hide_humidity) {
|
|
379
|
-
this.humidityservice?.updateCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity, e);
|
|
380
|
-
}
|
|
381
|
-
if (!this.device.meter?.hide_temperature) {
|
|
382
|
-
this.temperatureservice?.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, e);
|
|
383
|
-
}
|
|
384
|
-
}
|
|
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);
|
|
393
|
+
public apiError() {
|
|
394
|
+
throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
399
395
|
}
|
|
400
396
|
}
|
package/src/devices/motion.ts
CHANGED
|
@@ -2,7 +2,7 @@ import Switchbot from 'node-switchbot';
|
|
|
2
2
|
import { interval, Subject } from 'rxjs';
|
|
3
3
|
import { skipWhile } from 'rxjs/operators';
|
|
4
4
|
import { SwitchBotPlatform } from '../platform';
|
|
5
|
-
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
5
|
+
import { Service, PlatformAccessory, CharacteristicValue, HAPStatus } from 'homebridge';
|
|
6
6
|
import { DeviceURL, device, devicesConfig, serviceData, switchbot, deviceStatusResponse } from '../settings';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -224,7 +224,7 @@ export class Motion {
|
|
|
224
224
|
this.platform.log.warn(`Motion Sensor: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
225
225
|
await this.openAPIRefreshStatus();
|
|
226
226
|
}
|
|
227
|
-
this.apiError(
|
|
227
|
+
this.apiError();
|
|
228
228
|
});
|
|
229
229
|
}
|
|
230
230
|
|
|
@@ -246,7 +246,7 @@ export class Motion {
|
|
|
246
246
|
this.platform.log.error(`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,`
|
|
247
247
|
+ ` Error: ${JSON.stringify(e)}`);
|
|
248
248
|
}
|
|
249
|
-
this.apiError(
|
|
249
|
+
this.apiError();
|
|
250
250
|
}
|
|
251
251
|
}
|
|
252
252
|
}
|
|
@@ -284,12 +284,7 @@ export class Motion {
|
|
|
284
284
|
}
|
|
285
285
|
}
|
|
286
286
|
|
|
287
|
-
public apiError(
|
|
288
|
-
this.
|
|
289
|
-
if (this.device.ble) {
|
|
290
|
-
this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
|
|
291
|
-
this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
|
|
292
|
-
this.lightSensorService?.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, e);
|
|
293
|
-
}
|
|
287
|
+
public apiError() {
|
|
288
|
+
throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
294
289
|
}
|
|
295
290
|
}
|
package/src/devices/plugs.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { AxiosResponse } from 'axios';
|
|
|
3
3
|
import { interval, Subject } from 'rxjs';
|
|
4
4
|
import { SwitchBotPlatform } from '../platform';
|
|
5
5
|
import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
|
|
6
|
-
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
6
|
+
import { Service, PlatformAccessory, CharacteristicValue, HAPStatus } from 'homebridge';
|
|
7
7
|
import { DeviceURL, device, devicesConfig, deviceStatusResponse, payload } from '../settings';
|
|
8
8
|
|
|
9
9
|
export class Plug {
|
|
@@ -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();
|
|
@@ -98,7 +106,7 @@ export class Plug {
|
|
|
98
106
|
this.platform.log.error(`Plug: ${this.accessory.displayName} failed pushChanges,`
|
|
99
107
|
+ ` Error: ${JSON.stringify(e)}`);
|
|
100
108
|
}
|
|
101
|
-
this.apiError(
|
|
109
|
+
this.apiError();
|
|
102
110
|
}
|
|
103
111
|
this.plugUpdateInProgress = false;
|
|
104
112
|
});
|
|
@@ -131,7 +139,7 @@ export class Plug {
|
|
|
131
139
|
this.platform.log.error(`Plug: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,`
|
|
132
140
|
+ ` Error: ${JSON.stringify(e)}`);
|
|
133
141
|
}
|
|
134
|
-
this.apiError(
|
|
142
|
+
this.apiError();
|
|
135
143
|
}
|
|
136
144
|
}
|
|
137
145
|
|
|
@@ -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))
|
|
@@ -177,8 +189,8 @@ export class Plug {
|
|
|
177
189
|
}
|
|
178
190
|
}
|
|
179
191
|
|
|
180
|
-
public apiError(
|
|
181
|
-
this.
|
|
192
|
+
public apiError() {
|
|
193
|
+
throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
182
194
|
}
|
|
183
195
|
|
|
184
196
|
private statusCode(push: AxiosResponse<{ statusCode: number; }>) {
|
|
@@ -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
|
*/
|