@switchbot/homebridge-switchbot 1.7.1-beta.1 → 1.7.1-beta.10
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 +7 -2
- package/config.schema.json +46 -33
- package/dist/devices/bots.d.ts +4 -2
- package/dist/devices/bots.d.ts.map +1 -1
- package/dist/devices/bots.js +40 -40
- package/dist/devices/bots.js.map +1 -1
- package/dist/devices/colorbulb.d.ts +6 -1
- package/dist/devices/colorbulb.d.ts.map +1 -1
- package/dist/devices/colorbulb.js +18 -11
- package/dist/devices/colorbulb.js.map +1 -1
- package/dist/devices/contact.d.ts +6 -7
- package/dist/devices/contact.d.ts.map +1 -1
- package/dist/devices/contact.js +69 -107
- package/dist/devices/contact.js.map +1 -1
- package/dist/devices/curtains.d.ts +10 -3
- package/dist/devices/curtains.d.ts.map +1 -1
- package/dist/devices/curtains.js +52 -34
- package/dist/devices/curtains.js.map +1 -1
- package/dist/devices/humidifiers.d.ts +8 -2
- package/dist/devices/humidifiers.d.ts.map +1 -1
- package/dist/devices/humidifiers.js +28 -35
- package/dist/devices/humidifiers.js.map +1 -1
- package/dist/devices/meters.d.ts +14 -12
- package/dist/devices/meters.d.ts.map +1 -1
- package/dist/devices/meters.js +63 -103
- package/dist/devices/meters.js.map +1 -1
- package/dist/devices/motion.d.ts +5 -6
- package/dist/devices/motion.d.ts.map +1 -1
- package/dist/devices/motion.js +61 -90
- 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 +8 -1
- package/dist/devices/plugs.js.map +1 -1
- package/dist/irdevices/airconditioners.d.ts +1 -0
- package/dist/irdevices/airconditioners.d.ts.map +1 -1
- package/dist/irdevices/airconditioners.js +6 -0
- package/dist/irdevices/airconditioners.js.map +1 -1
- package/dist/irdevices/airpurifiers.d.ts +1 -0
- package/dist/irdevices/airpurifiers.d.ts.map +1 -1
- package/dist/irdevices/airpurifiers.js +6 -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 +6 -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 +6 -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 +6 -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 +6 -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 +6 -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 +6 -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 +6 -0
- package/dist/irdevices/waterheaters.js.map +1 -1
- package/dist/platform.d.ts +2 -1
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +14 -1
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +6 -0
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js.map +1 -1
- package/package.json +5 -5
- package/src/devices/bots.ts +43 -44
- package/src/devices/colorbulb.ts +24 -14
- package/src/devices/contact.ts +72 -108
- package/src/devices/curtains.ts +60 -36
- package/src/devices/humidifiers.ts +36 -36
- package/src/devices/meters.ts +79 -113
- package/src/devices/motion.ts +66 -91
- package/src/devices/plugs.ts +11 -2
- package/src/irdevices/airconditioners.ts +7 -0
- package/src/irdevices/airpurifiers.ts +7 -0
- package/src/irdevices/cameras.ts +7 -0
- package/src/irdevices/fans.ts +7 -0
- package/src/irdevices/lights.ts +7 -0
- package/src/irdevices/others.ts +7 -0
- package/src/irdevices/tvs.ts +7 -0
- package/src/irdevices/vacuumcleaners.ts +7 -0
- package/src/irdevices/waterheaters.ts +7 -0
- package/src/platform.ts +14 -1
- package/src/settings.ts +6 -0
package/src/devices/meters.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { interval, Subject } from 'rxjs';
|
|
|
2
2
|
import { skipWhile } from 'rxjs/operators';
|
|
3
3
|
import { SwitchBotPlatform } from '../platform';
|
|
4
4
|
import { Service, PlatformAccessory, Units, CharacteristicValue } from 'homebridge';
|
|
5
|
-
import { DeviceURL, device, devicesConfig, serviceData, ad, switchbot, deviceStatusResponse, temperature } from '../settings';
|
|
5
|
+
import { DeviceURL, device, devicesConfig, serviceData, ad, switchbot, deviceStatusResponse, temperature, deviceStatus } from '../settings';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Platform Accessory
|
|
@@ -11,28 +11,30 @@ import { DeviceURL, device, devicesConfig, serviceData, ad, switchbot, deviceSta
|
|
|
11
11
|
*/
|
|
12
12
|
export class Meter {
|
|
13
13
|
// Services
|
|
14
|
-
private
|
|
15
|
-
temperatureservice?: Service;
|
|
16
|
-
humidityservice?: Service;
|
|
14
|
+
private batteryService?: Service;
|
|
15
|
+
private temperatureservice?: Service;
|
|
16
|
+
private humidityservice?: Service;
|
|
17
17
|
|
|
18
18
|
// Characteristic Values
|
|
19
19
|
CurrentRelativeHumidity!: CharacteristicValue;
|
|
20
20
|
CurrentRelativeHumidityCached!: CharacteristicValue;
|
|
21
|
-
CurrentTemperature
|
|
22
|
-
CurrentTemperatureCached
|
|
23
|
-
BatteryLevel
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
StatusLowBattery!: CharacteristicValue;
|
|
21
|
+
CurrentTemperature?: CharacteristicValue;
|
|
22
|
+
CurrentTemperatureCached?: CharacteristicValue;
|
|
23
|
+
BatteryLevel?: CharacteristicValue;
|
|
24
|
+
ChargingState?: CharacteristicValue;
|
|
25
|
+
StatusLowBattery?: CharacteristicValue;
|
|
27
26
|
Active!: CharacteristicValue;
|
|
28
27
|
WaterLevel!: CharacteristicValue;
|
|
29
28
|
|
|
30
29
|
// OpenAPI Others
|
|
30
|
+
Temperature: deviceStatus['temperature'];
|
|
31
|
+
Humidity: deviceStatus['humidity'];
|
|
31
32
|
deviceStatus!: deviceStatusResponse;
|
|
32
33
|
|
|
33
34
|
// BLE Others
|
|
34
35
|
connected?: boolean;
|
|
35
36
|
switchbot!: switchbot;
|
|
37
|
+
SwitchToOpenAPI?: boolean;
|
|
36
38
|
serviceData!: serviceData;
|
|
37
39
|
temperature!: temperature['c'];
|
|
38
40
|
battery!: serviceData['battery'];
|
|
@@ -56,17 +58,7 @@ export class Meter {
|
|
|
56
58
|
this.logs();
|
|
57
59
|
this.scan();
|
|
58
60
|
this.refreshRate();
|
|
59
|
-
|
|
60
|
-
this.BatteryLevel = 100;
|
|
61
|
-
} else {
|
|
62
|
-
this.BatteryLevel = this.accessory.context.BatteryLevel;
|
|
63
|
-
}
|
|
64
|
-
if (this.BatteryLevel < 15) {
|
|
65
|
-
this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
66
|
-
} else {
|
|
67
|
-
this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
68
|
-
}
|
|
69
|
-
this.ChargingState = this.platform.Characteristic.ChargingState.NOT_CHARGEABLE;
|
|
61
|
+
this.config(device);
|
|
70
62
|
if (this.CurrentRelativeHumidity === undefined) {
|
|
71
63
|
this.CurrentRelativeHumidity = 0;
|
|
72
64
|
} else {
|
|
@@ -96,26 +88,6 @@ export class Meter {
|
|
|
96
88
|
.setCharacteristic(this.platform.Characteristic.Model, 'SWITCHBOT-METERTH-S1')
|
|
97
89
|
.setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!);
|
|
98
90
|
|
|
99
|
-
// get the Battery service if it exists, otherwise create a new Battery service
|
|
100
|
-
// you can create multiple services for each accessory
|
|
101
|
-
(this.service =
|
|
102
|
-
accessory.getService(this.platform.Service.Battery) ||
|
|
103
|
-
accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
|
|
104
|
-
|
|
105
|
-
// To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
|
|
106
|
-
// when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
|
|
107
|
-
// accessory.getService('NAME') ?? accessory.addService(this.platform.Service.Battery, 'NAME', 'USER_DEFINED_SUBTYPE');
|
|
108
|
-
|
|
109
|
-
// set the service name, this is what is displayed as the default name on the Home app
|
|
110
|
-
// in this example we are using the name we stored in the `accessory.context` in the `discoverDevices` method.
|
|
111
|
-
this.service.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
|
|
112
|
-
|
|
113
|
-
// each service must implement at-minimum the "required characteristics" for the given service type
|
|
114
|
-
// see https://developers.homebridge.io/#/service/Battery
|
|
115
|
-
|
|
116
|
-
// create handlers for required characteristics
|
|
117
|
-
this.service.setCharacteristic(this.platform.Characteristic.ChargingState, 2);
|
|
118
|
-
|
|
119
91
|
// Temperature Sensor Service
|
|
120
92
|
if (device.meter?.hide_temperature) {
|
|
121
93
|
this.debugLog(`Meter: ${accessory.displayName} Removing Temperature Sensor Service`);
|
|
@@ -127,7 +99,7 @@ export class Meter {
|
|
|
127
99
|
this.accessory.getService(this.platform.Service.TemperatureSensor) ||
|
|
128
100
|
this.accessory.addService(this.platform.Service.TemperatureSensor)), `${accessory.displayName} Temperature Sensor`;
|
|
129
101
|
|
|
130
|
-
this.
|
|
102
|
+
this.temperatureservice.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Temperature Sensor`);
|
|
131
103
|
|
|
132
104
|
this.temperatureservice
|
|
133
105
|
.getCharacteristic(this.platform.Characteristic.CurrentTemperature)
|
|
@@ -139,7 +111,7 @@ export class Meter {
|
|
|
139
111
|
minStep: 0.1,
|
|
140
112
|
})
|
|
141
113
|
.onGet(() => {
|
|
142
|
-
return this.CurrentTemperature
|
|
114
|
+
return this.CurrentTemperature!;
|
|
143
115
|
});
|
|
144
116
|
} else {
|
|
145
117
|
this.debugLog(`Meter: ${accessory.displayName} Temperature Sensor Service Not Added`);
|
|
@@ -156,7 +128,7 @@ export class Meter {
|
|
|
156
128
|
this.accessory.getService(this.platform.Service.HumiditySensor) ||
|
|
157
129
|
this.accessory.addService(this.platform.Service.HumiditySensor)), `${accessory.displayName} Humidity Sensor`;
|
|
158
130
|
|
|
159
|
-
this.
|
|
131
|
+
this.humidityservice.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Humidity Sensor`);
|
|
160
132
|
|
|
161
133
|
this.humidityservice
|
|
162
134
|
.getCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity)
|
|
@@ -170,6 +142,27 @@ export class Meter {
|
|
|
170
142
|
this.debugLog(`Meter: ${accessory.displayName} Humidity Sensor Service Not Added`);
|
|
171
143
|
}
|
|
172
144
|
|
|
145
|
+
// Battery Service
|
|
146
|
+
if (!device.ble) {
|
|
147
|
+
this.debugLog(`Meter: ${accessory.displayName} Removing Battery Service`);
|
|
148
|
+
this.batteryService = this.accessory.getService(this.platform.Service.Battery);
|
|
149
|
+
accessory.removeService(this.batteryService!);
|
|
150
|
+
} else if (device.ble && !this.batteryService) {
|
|
151
|
+
this.debugLog(`Meter: ${accessory.displayName} Add Battery Service`);
|
|
152
|
+
(this.batteryService =
|
|
153
|
+
this.accessory.getService(this.platform.Service.Battery) ||
|
|
154
|
+
this.accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
|
|
155
|
+
|
|
156
|
+
this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Battery`);
|
|
157
|
+
|
|
158
|
+
this.batteryService.setCharacteristic(this.platform.Characteristic.ChargingState, this.platform.Characteristic.ChargingState.NOT_CHARGEABLE);
|
|
159
|
+
|
|
160
|
+
} else {
|
|
161
|
+
this.debugLog(`Meter: ${accessory.displayName} Battery Service Not Added`);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
|
|
173
166
|
// Retrieve initial values and updateHomekit
|
|
174
167
|
this.updateHomeKitCharacteristics();
|
|
175
168
|
|
|
@@ -181,6 +174,12 @@ export class Meter {
|
|
|
181
174
|
});
|
|
182
175
|
}
|
|
183
176
|
|
|
177
|
+
config(device: device & devicesConfig) {
|
|
178
|
+
if (device.meter !== undefined || device.ble !== undefined) {
|
|
179
|
+
this.warnLog(`Meter: ${this.accessory.displayName} Config: ${JSON.stringify(device.meter)}, BLE: ${device.ble}`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
184
183
|
refreshRate() {
|
|
185
184
|
if (this.device.refreshRate) {
|
|
186
185
|
this.deviceRefreshRate = this.accessory.context.refreshRate = this.device.refreshRate;
|
|
@@ -232,10 +231,10 @@ export class Meter {
|
|
|
232
231
|
* Parse the device status from the SwitchBot api
|
|
233
232
|
*/
|
|
234
233
|
async parseStatus() {
|
|
235
|
-
if (this.device.ble) {
|
|
236
|
-
await this.BLEparseStatus();
|
|
237
|
-
} else {
|
|
234
|
+
if (this.SwitchToOpenAPI || !this.device.ble) {
|
|
238
235
|
await this.openAPIparseStatus();
|
|
236
|
+
} else {
|
|
237
|
+
await this.BLEparseStatus();
|
|
239
238
|
}
|
|
240
239
|
}
|
|
241
240
|
|
|
@@ -251,9 +250,9 @@ export class Meter {
|
|
|
251
250
|
}
|
|
252
251
|
this.debugLog(`${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}, StatusLowBattery: ${this.StatusLowBattery}`);
|
|
253
252
|
|
|
253
|
+
// Humidity
|
|
254
254
|
if (!this.device.meter?.hide_humidity) {
|
|
255
|
-
|
|
256
|
-
this.CurrentRelativeHumidity = Number(this.humidity);
|
|
255
|
+
this.CurrentRelativeHumidity = this.humidity!;
|
|
257
256
|
this.debugLog(`Meter: ${this.accessory.displayName} Humidity: ${this.CurrentRelativeHumidity}%`);
|
|
258
257
|
}
|
|
259
258
|
|
|
@@ -266,27 +265,20 @@ export class Meter {
|
|
|
266
265
|
}
|
|
267
266
|
|
|
268
267
|
private async openAPIparseStatus() {
|
|
268
|
+
if (this.device.ble) {
|
|
269
|
+
this.SwitchToOpenAPI = false;
|
|
270
|
+
}
|
|
269
271
|
if (this.platform.config.credentials?.openToken) {
|
|
270
272
|
this.debugLog(`Meter: ${this.accessory.displayName} OpenAPI parseStatus`);
|
|
271
|
-
if (this.deviceStatus.body) {
|
|
272
|
-
this.BatteryLevel = 100;
|
|
273
|
-
} else {
|
|
274
|
-
this.BatteryLevel = 10;
|
|
275
|
-
}
|
|
276
|
-
if (this.BatteryLevel < 15) {
|
|
277
|
-
this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
278
|
-
} else {
|
|
279
|
-
this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
280
|
-
}
|
|
281
273
|
// Current Relative Humidity
|
|
282
274
|
if (!this.device.meter?.hide_humidity) {
|
|
283
|
-
this.CurrentRelativeHumidity = this.
|
|
275
|
+
this.CurrentRelativeHumidity = this.Humidity!;
|
|
284
276
|
this.debugLog(`Meter: ${this.accessory.displayName} Humidity: ${this.CurrentRelativeHumidity}%`);
|
|
285
277
|
}
|
|
286
278
|
|
|
287
279
|
// Current Temperature
|
|
288
280
|
if (!this.device.meter?.hide_temperature) {
|
|
289
|
-
this.CurrentTemperature =
|
|
281
|
+
this.CurrentTemperature = this.Temperature!;
|
|
290
282
|
this.debugLog(`Meter: ${this.accessory.displayName} Temperature: ${this.CurrentTemperature}°c`);
|
|
291
283
|
}
|
|
292
284
|
}
|
|
@@ -303,34 +295,12 @@ export class Meter {
|
|
|
303
295
|
}
|
|
304
296
|
}
|
|
305
297
|
|
|
306
|
-
private async connectBLE() {
|
|
307
|
-
let switchbot: any;
|
|
308
|
-
try {
|
|
309
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
310
|
-
const Switchbot = require('node-switchbot');
|
|
311
|
-
switchbot = new Switchbot();
|
|
312
|
-
// Convert to BLE Address
|
|
313
|
-
this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
|
|
314
|
-
this.debugLog(`Meter: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
315
|
-
} catch (e: any) {
|
|
316
|
-
switchbot = false;
|
|
317
|
-
this.errorLog(`Meter: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot}`);
|
|
318
|
-
if (this.deviceLogging === 'debug') {
|
|
319
|
-
this.errorLog(`Meter: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot},`
|
|
320
|
-
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
321
|
-
}
|
|
322
|
-
if (this.platform.debugMode) {
|
|
323
|
-
this.errorLog(`Meter: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot},`
|
|
324
|
-
+ ` Error: ${JSON.stringify(e)}`);
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
return switchbot;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
298
|
private async BLErefreshStatus() {
|
|
331
299
|
this.debugLog(`Meter: ${this.accessory.displayName} BLE RefreshStatus`);
|
|
332
|
-
|
|
333
|
-
|
|
300
|
+
const switchbot = await this.platform.connectBLE();
|
|
301
|
+
// Convert to BLE Address
|
|
302
|
+
this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
|
|
303
|
+
this.debugLog(`Curtain: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
334
304
|
// Start to monitor advertisement packets
|
|
335
305
|
if (switchbot !== false) {
|
|
336
306
|
switchbot.startScan({
|
|
@@ -362,12 +332,6 @@ export class Meter {
|
|
|
362
332
|
// Stop to monitor
|
|
363
333
|
switchbot.stopScan();
|
|
364
334
|
if (this.connected) {
|
|
365
|
-
this.CurrentTemperatureCached = this.temperature;
|
|
366
|
-
this.accessory.context.CurrentTemperature = this.CurrentTemperatureCached;
|
|
367
|
-
this.CurrentRelativeHumidityCached = this.humidity!;
|
|
368
|
-
this.accessory.context.CurrentRelativeHumidity = this.CurrentRelativeHumidityCached;
|
|
369
|
-
this.BatteryLevelCached = this.battery!;
|
|
370
|
-
this.accessory.context.BatteryLevel = this.BatteryLevelCached;
|
|
371
335
|
this.parseStatus();
|
|
372
336
|
this.updateHomeKitCharacteristics();
|
|
373
337
|
} else {
|
|
@@ -385,6 +349,7 @@ export class Meter {
|
|
|
385
349
|
}
|
|
386
350
|
if (this.platform.config.credentials?.openToken) {
|
|
387
351
|
this.warnLog(`Meter: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
352
|
+
this.SwitchToOpenAPI = true;
|
|
388
353
|
this.openAPIRefreshStatus();
|
|
389
354
|
}
|
|
390
355
|
this.apiError(e);
|
|
@@ -398,6 +363,7 @@ export class Meter {
|
|
|
398
363
|
this.errorLog(`Meter: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
|
|
399
364
|
if (this.platform.config.credentials?.openToken) {
|
|
400
365
|
this.warnLog(`Meter: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
366
|
+
this.SwitchToOpenAPI = true;
|
|
401
367
|
await this.openAPIRefreshStatus();
|
|
402
368
|
}
|
|
403
369
|
}
|
|
@@ -408,12 +374,8 @@ export class Meter {
|
|
|
408
374
|
try {
|
|
409
375
|
this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
|
|
410
376
|
this.debugLog(`Meter: ${this.accessory.displayName} openAPIRefreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
411
|
-
this.
|
|
412
|
-
this.
|
|
413
|
-
this.CurrentRelativeHumidityCached = this.deviceStatus.body.humidity!;
|
|
414
|
-
this.accessory.context.CurrentRelativeHumidity = this.CurrentRelativeHumidityCached;
|
|
415
|
-
this.BatteryLevelCached = 100;
|
|
416
|
-
this.accessory.context.BatteryLevel = this.BatteryLevelCached;
|
|
377
|
+
this.Humidity = this.deviceStatus.body.humidity!;
|
|
378
|
+
this.Temperature = this.deviceStatus.body.temperature!;
|
|
417
379
|
this.parseStatus();
|
|
418
380
|
this.updateHomeKitCharacteristics();
|
|
419
381
|
} catch (e: any) {
|
|
@@ -435,18 +397,6 @@ export class Meter {
|
|
|
435
397
|
* Updates the status for each of the HomeKit Characteristics
|
|
436
398
|
*/
|
|
437
399
|
updateHomeKitCharacteristics() {
|
|
438
|
-
if (this.StatusLowBattery === undefined) {
|
|
439
|
-
this.debugLog(`Meter: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
|
|
440
|
-
} else {
|
|
441
|
-
this.service.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.StatusLowBattery);
|
|
442
|
-
this.debugLog(`Meter: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
|
|
443
|
-
}
|
|
444
|
-
if (this.BatteryLevel === undefined) {
|
|
445
|
-
this.debugLog(`Meter: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
|
|
446
|
-
} else {
|
|
447
|
-
this.service.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.BatteryLevel);
|
|
448
|
-
this.debugLog(`Meter: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
|
|
449
|
-
}
|
|
450
400
|
if (!this.device.meter?.hide_humidity) {
|
|
451
401
|
if (this.CurrentRelativeHumidity === undefined) {
|
|
452
402
|
this.debugLog(`Meter: ${this.accessory.displayName} CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
|
|
@@ -463,17 +413,33 @@ export class Meter {
|
|
|
463
413
|
this.debugLog(`Meter: ${this.accessory.displayName} updateCharacteristic CurrentTemperature: ${this.CurrentTemperature}`);
|
|
464
414
|
}
|
|
465
415
|
}
|
|
416
|
+
if (this.device.ble) {
|
|
417
|
+
if (this.BatteryLevel === undefined) {
|
|
418
|
+
this.debugLog(`Bot: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
|
|
419
|
+
} else {
|
|
420
|
+
this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.BatteryLevel);
|
|
421
|
+
this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
|
|
422
|
+
}
|
|
423
|
+
if (this.StatusLowBattery === undefined) {
|
|
424
|
+
this.debugLog(`Bot: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
|
|
425
|
+
} else {
|
|
426
|
+
this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.StatusLowBattery);
|
|
427
|
+
this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
466
430
|
}
|
|
467
431
|
|
|
468
432
|
public apiError(e: any) {
|
|
469
|
-
this.service.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
|
|
470
|
-
this.service.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
|
|
471
433
|
if (!this.device.meter?.hide_humidity) {
|
|
472
434
|
this.humidityservice?.updateCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity, e);
|
|
473
435
|
}
|
|
474
436
|
if (!this.device.meter?.hide_temperature) {
|
|
475
437
|
this.temperatureservice?.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, e);
|
|
476
438
|
}
|
|
439
|
+
if (this.device.ble) {
|
|
440
|
+
this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
|
|
441
|
+
this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
|
|
442
|
+
}
|
|
477
443
|
//throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
478
444
|
}
|
|
479
445
|
|
package/src/devices/motion.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { interval, Subject } from 'rxjs';
|
|
|
2
2
|
import { skipWhile } from 'rxjs/operators';
|
|
3
3
|
import { SwitchBotPlatform } from '../platform';
|
|
4
4
|
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
5
|
-
import { DeviceURL, device, devicesConfig, serviceData, switchbot, deviceStatusResponse } from '../settings';
|
|
5
|
+
import { DeviceURL, device, devicesConfig, serviceData, switchbot, deviceStatusResponse, deviceStatus } from '../settings';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Platform Accessory
|
|
@@ -23,10 +23,13 @@ export class Motion {
|
|
|
23
23
|
|
|
24
24
|
// OpenAPI Others
|
|
25
25
|
deviceStatus!: deviceStatusResponse;
|
|
26
|
+
moveDetected: deviceStatus['moveDetected'];
|
|
27
|
+
brightness: deviceStatus['brightness'];
|
|
26
28
|
|
|
27
29
|
// BLE Others
|
|
28
30
|
connected?: boolean;
|
|
29
31
|
switchbot!: switchbot;
|
|
32
|
+
SwitchToOpenAPI?: boolean;
|
|
30
33
|
serviceData!: serviceData;
|
|
31
34
|
battery!: serviceData['battery'];
|
|
32
35
|
movement!: serviceData['movement'];
|
|
@@ -52,6 +55,7 @@ export class Motion {
|
|
|
52
55
|
this.logs();
|
|
53
56
|
this.scan();
|
|
54
57
|
this.refreshRate();
|
|
58
|
+
this.config(device);
|
|
55
59
|
this.MotionDetected = false;
|
|
56
60
|
|
|
57
61
|
// Motion Config
|
|
@@ -108,12 +112,20 @@ export class Motion {
|
|
|
108
112
|
}
|
|
109
113
|
|
|
110
114
|
// Battery Service
|
|
111
|
-
if (device.ble) {
|
|
115
|
+
if (!device.ble) {
|
|
116
|
+
this.debugLog(`Motion Sensor: ${accessory.displayName} Removing Battery Service`);
|
|
117
|
+
this.batteryService = this.accessory.getService(this.platform.Service.Battery);
|
|
118
|
+
accessory.removeService(this.batteryService!);
|
|
119
|
+
} else if (device.ble && !this.batteryService) {
|
|
120
|
+
this.debugLog(`Motion Sensor: ${accessory.displayName} Add Battery Service`);
|
|
112
121
|
(this.batteryService =
|
|
113
|
-
accessory.getService(this.platform.Service.Battery) ||
|
|
114
|
-
accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
|
|
122
|
+
this.accessory.getService(this.platform.Service.Battery) ||
|
|
123
|
+
this.accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
|
|
115
124
|
|
|
116
125
|
this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Battery`);
|
|
126
|
+
|
|
127
|
+
} else {
|
|
128
|
+
this.debugLog(`Motion Sensor: ${accessory.displayName} Battery Service Not Added`);
|
|
117
129
|
}
|
|
118
130
|
|
|
119
131
|
// Retrieve initial values and updateHomekit
|
|
@@ -127,6 +139,12 @@ export class Motion {
|
|
|
127
139
|
});
|
|
128
140
|
}
|
|
129
141
|
|
|
142
|
+
config(device: device & devicesConfig) {
|
|
143
|
+
if (device.motion !== undefined) {
|
|
144
|
+
this.warnLog(`Motion Sensor: ${this.accessory.displayName} Config: ${JSON.stringify(device.motion)}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
130
148
|
refreshRate() {
|
|
131
149
|
if (this.device.refreshRate) {
|
|
132
150
|
this.deviceRefreshRate = this.accessory.context.refreshRate = this.device.refreshRate;
|
|
@@ -196,42 +214,38 @@ export class Motion {
|
|
|
196
214
|
* Parse the device status from the SwitchBot api
|
|
197
215
|
*/
|
|
198
216
|
async parseStatus() {
|
|
199
|
-
if (this.device.ble) {
|
|
200
|
-
await this.BLEparseStatus();
|
|
201
|
-
} else {
|
|
217
|
+
if (this.SwitchToOpenAPI || !this.device.ble) {
|
|
202
218
|
await this.openAPIparseStatus();
|
|
219
|
+
} else {
|
|
220
|
+
await this.BLEparseStatus();
|
|
203
221
|
}
|
|
204
222
|
}
|
|
205
223
|
|
|
206
224
|
private async BLEparseStatus() {
|
|
207
225
|
this.debugLog(`Motion Sensor: ${this.accessory.displayName} BLE parseStatus`);
|
|
208
226
|
// Movement
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
} else if (this.movement === undefined) {
|
|
212
|
-
this.movement = false;
|
|
213
|
-
this.BLEmotion();
|
|
214
|
-
} else {
|
|
215
|
-
this.BLEmotion();
|
|
216
|
-
}
|
|
227
|
+
this.MotionDetected = this.movement!;
|
|
228
|
+
this.debugLog(`Motion Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
|
|
217
229
|
// Light Level
|
|
218
230
|
if (!this.device.motion?.hide_lightsensor) {
|
|
219
231
|
this.set_minLux = this.minLux();
|
|
220
232
|
this.set_maxLux = this.maxLux();
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
233
|
+
switch (this.lightLevel) {
|
|
234
|
+
case 'dark':
|
|
235
|
+
case 1:
|
|
236
|
+
this.CurrentAmbientLightLevel = this.set_minLux;
|
|
237
|
+
break;
|
|
238
|
+
default:
|
|
239
|
+
this.CurrentAmbientLightLevel = this.set_maxLux;
|
|
228
240
|
}
|
|
241
|
+
this.debugLog(`Motion Sensor: ${this.accessory.displayName} LightLevel: ${this.lightLevel},`
|
|
242
|
+
+ ` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
229
243
|
}
|
|
230
244
|
// Battery
|
|
231
245
|
if (this.battery === undefined) {
|
|
232
246
|
this.battery = 100;
|
|
233
247
|
}
|
|
234
|
-
this.BatteryLevel =
|
|
248
|
+
this.BatteryLevel = this.battery!;
|
|
235
249
|
if (this.BatteryLevel < 10) {
|
|
236
250
|
this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
237
251
|
} else {
|
|
@@ -240,55 +254,31 @@ export class Motion {
|
|
|
240
254
|
this.debugLog(`Motion Sensor: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}, StatusLowBattery: ${this.StatusLowBattery}`);
|
|
241
255
|
}
|
|
242
256
|
|
|
243
|
-
private BLEmotion() {
|
|
244
|
-
this.MotionDetected = Boolean(this.movement);
|
|
245
|
-
this.debugLog(`Motion Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
private BLElux() {
|
|
249
|
-
switch (this.lightLevel) {
|
|
250
|
-
case 'dark':
|
|
251
|
-
case 1:
|
|
252
|
-
this.CurrentAmbientLightLevel = this.set_minLux;
|
|
253
|
-
break;
|
|
254
|
-
default:
|
|
255
|
-
this.CurrentAmbientLightLevel = this.set_maxLux;
|
|
256
|
-
}
|
|
257
|
-
this.debugLog(`Motion Sensor: ${this.accessory.displayName} LightLevel: ${this.lightLevel},`
|
|
258
|
-
+ ` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
257
|
private async openAPIparseStatus() {
|
|
258
|
+
if (this.device.ble) {
|
|
259
|
+
this.SwitchToOpenAPI = false;
|
|
260
|
+
}
|
|
262
261
|
if (this.platform.config.credentials?.openToken) {
|
|
263
262
|
this.debugLog(`Motion Sensor: ${this.accessory.displayName} OpenAPI parseStatus`);
|
|
264
263
|
// Motion State
|
|
265
|
-
this.
|
|
264
|
+
this.MotionDetected = this.moveDetected!;
|
|
265
|
+
this.debugLog(`Motion Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
|
|
266
266
|
// Light Level
|
|
267
267
|
if (!this.device.motion?.hide_lightsensor) {
|
|
268
|
-
this.
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
268
|
+
this.set_minLux = this.minLux();
|
|
269
|
+
this.set_maxLux = this.maxLux();
|
|
270
|
+
switch (this.brightness) {
|
|
271
|
+
case 'dim':
|
|
272
|
+
this.CurrentAmbientLightLevel = this.set_minLux;
|
|
273
|
+
break;
|
|
274
|
+
case 'bright':
|
|
275
|
+
default:
|
|
276
|
+
this.CurrentAmbientLightLevel = this.set_maxLux;
|
|
277
|
+
}
|
|
278
|
+
this.debugLog(`Motion Sensor: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
279
279
|
|
|
280
|
-
|
|
281
|
-
this.set_minLux = this.minLux();
|
|
282
|
-
this.set_maxLux = this.maxLux();
|
|
283
|
-
switch (this.deviceStatus.body.brightness) {
|
|
284
|
-
case 'dim':
|
|
285
|
-
this.CurrentAmbientLightLevel = this.set_minLux;
|
|
286
|
-
break;
|
|
287
|
-
case 'bright':
|
|
288
|
-
default:
|
|
289
|
-
this.CurrentAmbientLightLevel = this.set_maxLux;
|
|
280
|
+
}
|
|
290
281
|
}
|
|
291
|
-
this.debugLog(`Motion Sensor: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
292
282
|
}
|
|
293
283
|
|
|
294
284
|
/**
|
|
@@ -302,38 +292,16 @@ export class Motion {
|
|
|
302
292
|
}
|
|
303
293
|
}
|
|
304
294
|
|
|
305
|
-
public async connectBLE() {
|
|
306
|
-
let switchbot: any;
|
|
307
|
-
try {
|
|
308
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
309
|
-
const Switchbot = require('node-switchbot');
|
|
310
|
-
switchbot = new Switchbot();
|
|
311
|
-
// Convert to BLE Address
|
|
312
|
-
this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
|
|
313
|
-
this.debugLog(`Motion Sensor: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
314
|
-
} catch (e: any) {
|
|
315
|
-
switchbot = false;
|
|
316
|
-
this.errorLog(`Motion Sensor: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot}`);
|
|
317
|
-
if (this.deviceLogging === 'debug') {
|
|
318
|
-
this.errorLog(`Motion Sensor: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot},`
|
|
319
|
-
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
320
|
-
}
|
|
321
|
-
if (this.platform.debugMode) {
|
|
322
|
-
this.errorLog(`Motion Sensor: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot},`
|
|
323
|
-
+ ` Error: ${JSON.stringify(e)}`);
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
return switchbot;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
295
|
private async BLERefreshStatus() {
|
|
330
296
|
this.debugLog(`Motion Sensor: ${this.accessory.displayName} BLE RefreshStatus`);
|
|
331
|
-
|
|
332
|
-
|
|
297
|
+
const switchbot = await this.platform.connectBLE();
|
|
298
|
+
// Convert to BLE Address
|
|
299
|
+
this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
|
|
300
|
+
this.debugLog(`Curtain: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
333
301
|
// Start to monitor advertisement packets
|
|
334
302
|
if (switchbot !== false) {
|
|
335
303
|
switchbot.startScan({
|
|
336
|
-
|
|
304
|
+
model: 's',
|
|
337
305
|
id: this.device.bleMac,
|
|
338
306
|
}).then(() => {
|
|
339
307
|
// Set an event hander
|
|
@@ -377,6 +345,7 @@ export class Motion {
|
|
|
377
345
|
}
|
|
378
346
|
if (this.platform.config.credentials?.openToken) {
|
|
379
347
|
this.warnLog(`Motion Sensor: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
348
|
+
this.SwitchToOpenAPI = true;
|
|
380
349
|
await this.openAPIRefreshStatus();
|
|
381
350
|
}
|
|
382
351
|
this.apiError(e);
|
|
@@ -390,6 +359,7 @@ export class Motion {
|
|
|
390
359
|
this.errorLog(`Motion Sensor: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
|
|
391
360
|
if (this.platform.config.credentials?.openToken) {
|
|
392
361
|
this.warnLog(`Motion Sensor: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
362
|
+
this.SwitchToOpenAPI = true;
|
|
393
363
|
await this.openAPIRefreshStatus();
|
|
394
364
|
}
|
|
395
365
|
}
|
|
@@ -400,6 +370,11 @@ export class Motion {
|
|
|
400
370
|
try {
|
|
401
371
|
this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
|
|
402
372
|
this.debugLog(`Motion Sensor: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
373
|
+
if (this.deviceStatus.body.moveDetected === undefined) {
|
|
374
|
+
this.errorLog(`Motion Sensor: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
375
|
+
}
|
|
376
|
+
this.moveDetected = this.deviceStatus.body.moveDetected;
|
|
377
|
+
this.brightness = this.deviceStatus.body.brightness;
|
|
403
378
|
this.parseStatus();
|
|
404
379
|
this.updateHomeKitCharacteristics();
|
|
405
380
|
} catch (e: any) {
|
package/src/devices/plugs.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { interval, Subject } from 'rxjs';
|
|
|
4
4
|
import { SwitchBotPlatform } from '../platform';
|
|
5
5
|
import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
|
|
6
6
|
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
7
|
-
import { DeviceURL, device, devicesConfig, deviceStatusResponse, payload } from '../settings';
|
|
7
|
+
import { DeviceURL, device, devicesConfig, deviceStatusResponse, payload, deviceStatus } from '../settings';
|
|
8
8
|
|
|
9
9
|
export class Plug {
|
|
10
10
|
// Services
|
|
@@ -15,6 +15,7 @@ export class Plug {
|
|
|
15
15
|
OnCached!: CharacteristicValue;
|
|
16
16
|
|
|
17
17
|
// OpenAPI Others
|
|
18
|
+
power: deviceStatus['power'];
|
|
18
19
|
deviceStatus!: deviceStatusResponse;
|
|
19
20
|
|
|
20
21
|
// Config
|
|
@@ -35,6 +36,7 @@ export class Plug {
|
|
|
35
36
|
this.logs();
|
|
36
37
|
this.scan();
|
|
37
38
|
this.refreshRate();
|
|
39
|
+
this.config(device);
|
|
38
40
|
if (this.On === undefined) {
|
|
39
41
|
this.On = false;
|
|
40
42
|
} else {
|
|
@@ -116,6 +118,12 @@ export class Plug {
|
|
|
116
118
|
});
|
|
117
119
|
}
|
|
118
120
|
|
|
121
|
+
config(device: device & devicesConfig) {
|
|
122
|
+
if (device.plug !== undefined) {
|
|
123
|
+
this.warnLog(`Plug: ${this.accessory.displayName} Config: ${JSON.stringify(device.plug)}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
119
127
|
refreshRate() {
|
|
120
128
|
if (this.device.refreshRate) {
|
|
121
129
|
this.deviceRefreshRate = this.accessory.context.refreshRate = this.device.refreshRate;
|
|
@@ -164,7 +172,7 @@ export class Plug {
|
|
|
164
172
|
}
|
|
165
173
|
|
|
166
174
|
parseStatus() {
|
|
167
|
-
switch (this.
|
|
175
|
+
switch (this.power) {
|
|
168
176
|
case 'on':
|
|
169
177
|
this.On = true;
|
|
170
178
|
break;
|
|
@@ -178,6 +186,7 @@ export class Plug {
|
|
|
178
186
|
try {
|
|
179
187
|
this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
|
|
180
188
|
this.debugLog(`Plug: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
189
|
+
this.power = this.deviceStatus.body.power;
|
|
181
190
|
this.parseStatus();
|
|
182
191
|
this.updateHomeKitCharacteristics();
|
|
183
192
|
} catch (e: any) {
|