@switchbot/homebridge-switchbot 1.7.1-beta.0 → 1.7.1-beta.4
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 +8 -2
- package/config.schema.json +31 -0
- package/dist/devices/bots.d.ts +1 -0
- package/dist/devices/bots.d.ts.map +1 -1
- package/dist/devices/bots.js +21 -6
- package/dist/devices/bots.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 +46 -76
- package/dist/devices/contact.js.map +1 -1
- package/dist/devices/curtains.d.ts +5 -2
- package/dist/devices/curtains.d.ts.map +1 -1
- package/dist/devices/curtains.js +36 -29
- package/dist/devices/curtains.js.map +1 -1
- package/dist/devices/meters.d.ts +1 -0
- package/dist/devices/meters.d.ts.map +1 -1
- package/dist/devices/meters.js +8 -3
- package/dist/devices/meters.js.map +1 -1
- package/dist/devices/motion.d.ts +8 -1
- package/dist/devices/motion.d.ts.map +1 -1
- package/dist/devices/motion.js +104 -42
- package/dist/devices/motion.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 +21 -6
- package/src/devices/contact.ts +43 -79
- package/src/devices/curtains.ts +39 -30
- package/src/devices/meters.ts +9 -3
- package/src/devices/motion.ts +113 -47
- package/src/platform.ts +14 -1
- package/src/settings.ts +7 -0
package/src/devices/motion.ts
CHANGED
|
@@ -17,9 +17,9 @@ export class Motion {
|
|
|
17
17
|
|
|
18
18
|
// Characteristic Values
|
|
19
19
|
MotionDetected!: CharacteristicValue;
|
|
20
|
+
CurrentAmbientLightLevel!: CharacteristicValue;
|
|
20
21
|
BatteryLevel?: CharacteristicValue;
|
|
21
22
|
StatusLowBattery?: CharacteristicValue;
|
|
22
|
-
CurrentAmbientLightLevel?: CharacteristicValue;
|
|
23
23
|
|
|
24
24
|
// OpenAPI Others
|
|
25
25
|
deviceStatus!: deviceStatusResponse;
|
|
@@ -27,12 +27,15 @@ export class Motion {
|
|
|
27
27
|
// BLE Others
|
|
28
28
|
connected?: boolean;
|
|
29
29
|
switchbot!: switchbot;
|
|
30
|
+
SwitchToOpenAPI?: boolean;
|
|
30
31
|
serviceData!: serviceData;
|
|
31
32
|
battery!: serviceData['battery'];
|
|
32
33
|
movement!: serviceData['movement'];
|
|
33
34
|
lightLevel!: serviceData['lightLevel'];
|
|
34
35
|
|
|
35
36
|
// Config
|
|
37
|
+
set_minLux!: number;
|
|
38
|
+
set_maxLux!: number;
|
|
36
39
|
scanDuration!: number;
|
|
37
40
|
deviceLogging!: string;
|
|
38
41
|
deviceRefreshRate!: number;
|
|
@@ -40,6 +43,8 @@ export class Motion {
|
|
|
40
43
|
// Updates
|
|
41
44
|
motionUbpdateInProgress!: boolean;
|
|
42
45
|
doMotionUpdate!: Subject<void>;
|
|
46
|
+
moveDetected: boolean | undefined;
|
|
47
|
+
brightness: string | number | undefined;
|
|
43
48
|
|
|
44
49
|
constructor(
|
|
45
50
|
private readonly platform: SwitchBotPlatform,
|
|
@@ -52,6 +57,11 @@ export class Motion {
|
|
|
52
57
|
this.refreshRate();
|
|
53
58
|
this.MotionDetected = false;
|
|
54
59
|
|
|
60
|
+
// Motion Config
|
|
61
|
+
this.debugLog(`Motion Sensor: ${this.accessory.displayName} Config: (ble: ${device.ble}, offline: ${device.offline},`
|
|
62
|
+
+ ` hide_lightsensor: ${device.motion?.hide_lightsensor},`
|
|
63
|
+
+ ` set_minLux: ${this.device.motion?.set_minLux}, set_maxLux: ${this.device.motion?.set_maxLux})`);
|
|
64
|
+
|
|
55
65
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
56
66
|
this.doMotionUpdate = new Subject();
|
|
57
67
|
this.motionUbpdateInProgress = false;
|
|
@@ -72,21 +82,6 @@ export class Motion {
|
|
|
72
82
|
accessory.getService(this.platform.Service.MotionSensor) ||
|
|
73
83
|
accessory.addService(this.platform.Service.MotionSensor)), `${accessory.displayName} Motion Sensor`;
|
|
74
84
|
|
|
75
|
-
if (device.ble) {
|
|
76
|
-
(this.lightSensorService =
|
|
77
|
-
accessory.getService(this.platform.Service.LightSensor) ||
|
|
78
|
-
accessory.addService(this.platform.Service.LightSensor)), `${accessory.displayName} Light Sensor`;
|
|
79
|
-
|
|
80
|
-
this.lightSensorService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Light Sensor`);
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
(this.batteryService =
|
|
84
|
-
accessory.getService(this.platform.Service.Battery) ||
|
|
85
|
-
accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
|
|
86
|
-
|
|
87
|
-
this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Battery`);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
85
|
// To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
|
|
91
86
|
// when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
|
|
92
87
|
// accessory.getService('NAME') ?? accessory.addService(this.platform.Service.Motion, 'NAME', 'USER_DEFINED_SUBTYPE');
|
|
@@ -98,8 +93,39 @@ export class Motion {
|
|
|
98
93
|
// each service must implement at-minimum the "required characteristics" for the given service type
|
|
99
94
|
// see https://developers.homebridge.io/#/service/MotionSensor
|
|
100
95
|
|
|
101
|
-
//
|
|
102
|
-
|
|
96
|
+
// Light Sensor Service
|
|
97
|
+
if (device.motion?.hide_lightsensor) {
|
|
98
|
+
this.debugLog(`Motion Sensor: ${accessory.displayName} Removing Light Sensor Service`);
|
|
99
|
+
this.lightSensorService = this.accessory.getService(this.platform.Service.LightSensor);
|
|
100
|
+
accessory.removeService(this.lightSensorService!);
|
|
101
|
+
} else if (!this.lightSensorService) {
|
|
102
|
+
this.debugLog(`Motion Sensor: ${accessory.displayName} Add Light Sensor Service`);
|
|
103
|
+
(this.lightSensorService =
|
|
104
|
+
this.accessory.getService(this.platform.Service.LightSensor) ||
|
|
105
|
+
this.accessory.addService(this.platform.Service.LightSensor)), `${accessory.displayName} Light Sensor`;
|
|
106
|
+
|
|
107
|
+
this.lightSensorService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Light Sensor`);
|
|
108
|
+
|
|
109
|
+
} else {
|
|
110
|
+
this.debugLog(`Motion Sensor: ${accessory.displayName} Light Sensor Service Not Added`);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Battery Service
|
|
114
|
+
if (!device.ble) {
|
|
115
|
+
this.debugLog(`Motion Sensor: ${accessory.displayName} Removing Battery Service`);
|
|
116
|
+
this.batteryService = this.accessory.getService(this.platform.Service.Battery);
|
|
117
|
+
accessory.removeService(this.batteryService!);
|
|
118
|
+
} else if (!this.batteryService) {
|
|
119
|
+
this.debugLog(`Motion Sensor: ${accessory.displayName} Add Battery Service`);
|
|
120
|
+
(this.batteryService =
|
|
121
|
+
this.accessory.getService(this.platform.Service.Battery) ||
|
|
122
|
+
this.accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
|
|
123
|
+
|
|
124
|
+
this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Battery`);
|
|
125
|
+
|
|
126
|
+
} else {
|
|
127
|
+
this.debugLog(`Motion Sensor: ${accessory.displayName} Battery Service Not Added`);
|
|
128
|
+
}
|
|
103
129
|
|
|
104
130
|
// Retrieve initial values and updateHomekit
|
|
105
131
|
this.updateHomeKitCharacteristics();
|
|
@@ -159,59 +185,92 @@ export class Motion {
|
|
|
159
185
|
}
|
|
160
186
|
}
|
|
161
187
|
|
|
188
|
+
private minLux(): number {
|
|
189
|
+
if (this.device.motion?.set_minLux) {
|
|
190
|
+
this.set_minLux = this.device.motion!.set_minLux!;
|
|
191
|
+
} else {
|
|
192
|
+
this.set_minLux = 1;
|
|
193
|
+
}
|
|
194
|
+
return this.set_minLux;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
private maxLux(): number {
|
|
198
|
+
if (this.device.motion?.set_maxLux) {
|
|
199
|
+
this.set_maxLux = this.device.motion!.set_maxLux!;
|
|
200
|
+
} else {
|
|
201
|
+
this.set_maxLux = 6001;
|
|
202
|
+
}
|
|
203
|
+
return this.set_maxLux;
|
|
204
|
+
}
|
|
205
|
+
|
|
162
206
|
/**
|
|
163
207
|
* Parse the device status from the SwitchBot api
|
|
164
208
|
*/
|
|
165
209
|
async parseStatus() {
|
|
166
|
-
if (this.device.ble) {
|
|
167
|
-
await this.BLEparseStatus();
|
|
168
|
-
} else {
|
|
210
|
+
if (this.SwitchToOpenAPI || !this.device.ble) {
|
|
169
211
|
await this.openAPIparseStatus();
|
|
212
|
+
} else {
|
|
213
|
+
await this.BLEparseStatus();
|
|
170
214
|
}
|
|
171
215
|
}
|
|
172
216
|
|
|
173
217
|
private async BLEparseStatus() {
|
|
174
218
|
this.debugLog(`Motion Sensor: ${this.accessory.displayName} BLE parseStatus`);
|
|
175
|
-
|
|
219
|
+
// Movement
|
|
220
|
+
this.MotionDetected = this.movement!;
|
|
176
221
|
this.debugLog(`Motion Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
|
|
177
222
|
// Light Level
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
223
|
+
if (!this.device.motion?.hide_lightsensor) {
|
|
224
|
+
this.set_minLux = this.minLux();
|
|
225
|
+
this.set_maxLux = this.maxLux();
|
|
226
|
+
switch (this.lightLevel) {
|
|
227
|
+
case 'dark':
|
|
228
|
+
case 1:
|
|
229
|
+
this.CurrentAmbientLightLevel = this.set_minLux;
|
|
230
|
+
break;
|
|
231
|
+
default:
|
|
232
|
+
this.CurrentAmbientLightLevel = this.set_maxLux;
|
|
233
|
+
}
|
|
234
|
+
this.debugLog(`Motion Sensor: ${this.accessory.displayName} LightLevel: ${this.lightLevel},`
|
|
235
|
+
+ ` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
185
236
|
}
|
|
186
237
|
// Battery
|
|
187
|
-
|
|
238
|
+
if (this.battery === undefined) {
|
|
239
|
+
this.battery = 100;
|
|
240
|
+
}
|
|
241
|
+
this.BatteryLevel = this.battery!;
|
|
188
242
|
if (this.BatteryLevel < 10) {
|
|
189
243
|
this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
|
|
190
244
|
} else {
|
|
191
245
|
this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
192
246
|
}
|
|
247
|
+
this.debugLog(`Motion Sensor: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}, StatusLowBattery: ${this.StatusLowBattery}`);
|
|
193
248
|
}
|
|
194
249
|
|
|
195
250
|
private async openAPIparseStatus() {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
251
|
+
if (this.device.ble) {
|
|
252
|
+
this.SwitchToOpenAPI = false;
|
|
253
|
+
}
|
|
254
|
+
if (this.platform.config.credentials?.openToken) {
|
|
255
|
+
this.debugLog(`Motion Sensor: ${this.accessory.displayName} OpenAPI parseStatus`);
|
|
256
|
+
// Motion State
|
|
257
|
+
this.MotionDetected = this.moveDetected!;
|
|
258
|
+
this.debugLog(`Motion Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
|
|
259
|
+
// Light Level
|
|
260
|
+
if (!this.device.motion?.hide_lightsensor) {
|
|
261
|
+
this.set_minLux = this.minLux();
|
|
262
|
+
this.set_maxLux = this.maxLux();
|
|
263
|
+
switch (this.brightness) {
|
|
264
|
+
case 'dim':
|
|
265
|
+
this.CurrentAmbientLightLevel = this.set_minLux;
|
|
266
|
+
break;
|
|
267
|
+
case 'bright':
|
|
268
|
+
default:
|
|
269
|
+
this.CurrentAmbientLightLevel = this.set_maxLux;
|
|
201
270
|
}
|
|
202
|
-
this.debugLog(`Motion Sensor: ${this.accessory.displayName}
|
|
203
|
-
|
|
204
|
-
} catch (e: any) {
|
|
205
|
-
this.errorLog(`Motion Sensor: ${this.accessory.displayName} failed parseStatus with OpenAPI Connection`);
|
|
206
|
-
if (this.deviceLogging === 'debug') {
|
|
207
|
-
this.errorLog(`Motion Sensor: ${this.accessory.displayName} failed parseStatus with OpenAPI Connection,`
|
|
208
|
-
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
209
|
-
}
|
|
210
|
-
if (this.platform.debugMode) {
|
|
211
|
-
this.errorLog(`Motion Sensor: ${this.accessory.displayName} failed parseStatus with OpenAPI Connection,`
|
|
212
|
-
+ ` Error: ${JSON.stringify(e)}`);
|
|
271
|
+
this.debugLog(`Motion Sensor: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
272
|
+
|
|
213
273
|
}
|
|
214
|
-
this.apiError(e);
|
|
215
274
|
}
|
|
216
275
|
}
|
|
217
276
|
|
|
@@ -301,6 +360,7 @@ export class Motion {
|
|
|
301
360
|
}
|
|
302
361
|
if (this.platform.config.credentials?.openToken) {
|
|
303
362
|
this.warnLog(`Motion Sensor: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
363
|
+
this.SwitchToOpenAPI = true;
|
|
304
364
|
await this.openAPIRefreshStatus();
|
|
305
365
|
}
|
|
306
366
|
this.apiError(e);
|
|
@@ -314,6 +374,7 @@ export class Motion {
|
|
|
314
374
|
this.errorLog(`Motion Sensor: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
|
|
315
375
|
if (this.platform.config.credentials?.openToken) {
|
|
316
376
|
this.warnLog(`Motion Sensor: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
377
|
+
this.SwitchToOpenAPI = true;
|
|
317
378
|
await this.openAPIRefreshStatus();
|
|
318
379
|
}
|
|
319
380
|
}
|
|
@@ -324,6 +385,11 @@ export class Motion {
|
|
|
324
385
|
try {
|
|
325
386
|
this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
|
|
326
387
|
this.debugLog(`Motion Sensor: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
388
|
+
if (this.deviceStatus.body.moveDetected === undefined) {
|
|
389
|
+
this.errorLog(`Motion Sensor: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
390
|
+
}
|
|
391
|
+
this.moveDetected = this.deviceStatus.body.moveDetected;
|
|
392
|
+
this.brightness = this.deviceStatus.body.brightness;
|
|
327
393
|
this.parseStatus();
|
|
328
394
|
this.updateHomeKitCharacteristics();
|
|
329
395
|
} catch (e: any) {
|
package/src/platform.ts
CHANGED
|
@@ -192,8 +192,21 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
|
|
|
192
192
|
}
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
+
connectBLE() {
|
|
196
|
+
let Switchbot: new () => any;
|
|
197
|
+
let switchbot: any;
|
|
198
|
+
try {
|
|
199
|
+
Switchbot = require('node-switchbot');
|
|
200
|
+
switchbot = new Switchbot();
|
|
201
|
+
} catch (e) {
|
|
202
|
+
switchbot = false;
|
|
203
|
+
this.errorLog(`Was 'node-switchbot' found: ${switchbot}`);
|
|
204
|
+
}
|
|
205
|
+
return switchbot;
|
|
206
|
+
}
|
|
207
|
+
|
|
195
208
|
/**
|
|
196
|
-
* this method discovers
|
|
209
|
+
* this method discovers devices
|
|
197
210
|
*/
|
|
198
211
|
async discoverDevices() {
|
|
199
212
|
try {
|
package/src/settings.ts
CHANGED
|
@@ -48,6 +48,7 @@ export interface devicesConfig extends device {
|
|
|
48
48
|
humidifier?: humidifier;
|
|
49
49
|
curtain?: curtain;
|
|
50
50
|
contact?: contact;
|
|
51
|
+
motion?: motion;
|
|
51
52
|
colorbulb?: colorbulb;
|
|
52
53
|
ble?: string;
|
|
53
54
|
scanDuration?: number;
|
|
@@ -89,6 +90,12 @@ export type contact = {
|
|
|
89
90
|
hide_motionsensor?: boolean;
|
|
90
91
|
};
|
|
91
92
|
|
|
93
|
+
export type motion = {
|
|
94
|
+
hide_lightsensor?: boolean;
|
|
95
|
+
set_minLux?: number;
|
|
96
|
+
set_maxLux?: number;
|
|
97
|
+
};
|
|
98
|
+
|
|
92
99
|
export type colorbulb = {
|
|
93
100
|
set_minStep?: number;
|
|
94
101
|
adaptiveLightingShift?: number;
|