@switchbot/homebridge-switchbot 2.0.0-beta.19 → 2.0.0-beta.20
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 +6 -1
- package/README.md +1 -2
- package/config.schema.json +51 -32
- package/dist/device/bot.d.ts +32 -29
- package/dist/device/bot.d.ts.map +1 -1
- package/dist/device/bot.js +549 -575
- package/dist/device/bot.js.map +1 -1
- package/dist/device/colorbulb.d.ts +33 -15
- package/dist/device/colorbulb.d.ts.map +1 -1
- package/dist/device/colorbulb.js +426 -341
- package/dist/device/colorbulb.js.map +1 -1
- package/dist/device/contact.d.ts +16 -9
- package/dist/device/contact.d.ts.map +1 -1
- package/dist/device/contact.js +246 -208
- package/dist/device/contact.js.map +1 -1
- package/dist/device/curtain.d.ts +21 -18
- package/dist/device/curtain.d.ts.map +1 -1
- package/dist/device/curtain.js +449 -449
- package/dist/device/curtain.js.map +1 -1
- package/dist/device/humidifier.d.ts +22 -20
- package/dist/device/humidifier.d.ts.map +1 -1
- package/dist/device/humidifier.js +346 -324
- package/dist/device/humidifier.js.map +1 -1
- package/dist/device/lock.d.ts +22 -10
- package/dist/device/lock.d.ts.map +1 -1
- package/dist/device/lock.js +257 -178
- package/dist/device/lock.js.map +1 -1
- package/dist/device/meter.d.ts +21 -14
- package/dist/device/meter.d.ts.map +1 -1
- package/dist/device/meter.js +287 -239
- package/dist/device/meter.js.map +1 -1
- package/dist/device/meterplus.d.ts +23 -10
- package/dist/device/meterplus.d.ts.map +1 -1
- package/dist/device/meterplus.js +308 -190
- package/dist/device/meterplus.js.map +1 -1
- package/dist/device/motion.d.ts +17 -10
- package/dist/device/motion.d.ts.map +1 -1
- package/dist/device/motion.js +225 -193
- package/dist/device/motion.js.map +1 -1
- package/dist/device/plug.d.ts +24 -17
- package/dist/device/plug.d.ts.map +1 -1
- package/dist/device/plug.js +270 -267
- package/dist/device/plug.js.map +1 -1
- package/dist/device/striplight.d.ts +36 -14
- package/dist/device/striplight.d.ts.map +1 -1
- package/dist/device/striplight.js +447 -299
- package/dist/device/striplight.js.map +1 -1
- package/dist/irdevice/airconditioner.d.ts +7 -14
- package/dist/irdevice/airconditioner.d.ts.map +1 -1
- package/dist/irdevice/airconditioner.js +177 -169
- package/dist/irdevice/airconditioner.js.map +1 -1
- package/dist/irdevice/airpurifier.d.ts +3 -5
- package/dist/irdevice/airpurifier.d.ts.map +1 -1
- package/dist/irdevice/airpurifier.js +72 -57
- package/dist/irdevice/airpurifier.js.map +1 -1
- package/dist/irdevice/camera.d.ts +3 -4
- package/dist/irdevice/camera.d.ts.map +1 -1
- package/dist/irdevice/camera.js +47 -33
- package/dist/irdevice/camera.js.map +1 -1
- package/dist/irdevice/fan.d.ts +3 -4
- package/dist/irdevice/fan.d.ts.map +1 -1
- package/dist/irdevice/fan.js +66 -48
- package/dist/irdevice/fan.js.map +1 -1
- package/dist/irdevice/light.d.ts +3 -4
- package/dist/irdevice/light.d.ts.map +1 -1
- package/dist/irdevice/light.js +48 -47
- package/dist/irdevice/light.js.map +1 -1
- package/dist/irdevice/other.d.ts +3 -4
- package/dist/irdevice/other.d.ts.map +1 -1
- package/dist/irdevice/other.js +47 -33
- package/dist/irdevice/other.js.map +1 -1
- package/dist/irdevice/tv.d.ts +10 -11
- package/dist/irdevice/tv.d.ts.map +1 -1
- package/dist/irdevice/tv.js +64 -48
- package/dist/irdevice/tv.js.map +1 -1
- package/dist/irdevice/vacuumcleaner.d.ts +7 -12
- package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
- package/dist/irdevice/vacuumcleaner.js +52 -41
- package/dist/irdevice/vacuumcleaner.js.map +1 -1
- package/dist/irdevice/waterheater.d.ts +6 -11
- package/dist/irdevice/waterheater.d.ts.map +1 -1
- package/dist/irdevice/waterheater.js +52 -42
- package/dist/irdevice/waterheater.js.map +1 -1
- package/dist/platform.d.ts +0 -4
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +44 -66
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +3 -3
- package/dist/settings.d.ts.map +1 -1
- package/package.json +7 -6
- package/src/device/bot.ts +551 -589
- package/src/device/colorbulb.ts +441 -375
- package/src/device/contact.ts +249 -213
- package/src/device/curtain.ts +452 -461
- package/src/device/humidifier.ts +358 -365
- package/src/device/lock.ts +263 -179
- package/src/device/meter.ts +302 -253
- package/src/device/meterplus.ts +319 -194
- package/src/device/motion.ts +230 -199
- package/src/device/plug.ts +273 -274
- package/src/device/striplight.ts +460 -316
- package/src/irdevice/airconditioner.ts +181 -183
- package/src/irdevice/airpurifier.ts +70 -60
- package/src/irdevice/camera.ts +46 -36
- package/src/irdevice/fan.ts +64 -49
- package/src/irdevice/light.ts +47 -51
- package/src/irdevice/other.ts +46 -36
- package/src/irdevice/tv.ts +64 -51
- package/src/irdevice/vacuumcleaner.ts +52 -45
- package/src/irdevice/waterheater.ts +50 -45
- package/src/platform.ts +44 -68
- package/src/settings.ts +3 -3
package/src/device/motion.ts
CHANGED
|
@@ -7,6 +7,7 @@ import superStringify from 'super-stringify';
|
|
|
7
7
|
import { SwitchBotPlatform } from '../platform';
|
|
8
8
|
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
9
9
|
import { device, devicesConfig, serviceData, switchbot, deviceStatus, ad, HostDomain, DevicePath } from '../settings';
|
|
10
|
+
import { IncomingMessage } from 'http';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Platform Accessory
|
|
@@ -33,15 +34,14 @@ export class Motion {
|
|
|
33
34
|
// BLE Others
|
|
34
35
|
connected?: boolean;
|
|
35
36
|
switchbot!: switchbot;
|
|
36
|
-
SwitchToOpenAPI?: boolean;
|
|
37
37
|
serviceData!: serviceData;
|
|
38
38
|
address!: ad['address'];
|
|
39
|
+
SwitchToOpenAPI?: boolean;
|
|
39
40
|
battery!: serviceData['battery'];
|
|
40
41
|
movement!: serviceData['movement'];
|
|
41
42
|
lightLevel!: serviceData['lightLevel'];
|
|
42
43
|
|
|
43
44
|
// Config
|
|
44
|
-
OpenAPI?: boolean;
|
|
45
45
|
set_minLux!: number;
|
|
46
46
|
set_maxLux!: number;
|
|
47
47
|
scanDuration!: number;
|
|
@@ -52,14 +52,17 @@ export class Motion {
|
|
|
52
52
|
motionUbpdateInProgress!: boolean;
|
|
53
53
|
doMotionUpdate!: Subject<void>;
|
|
54
54
|
|
|
55
|
+
// Connection
|
|
56
|
+
private readonly BLE = (this.device.connectionType === 'BLE' || this.device.connectionType === 'Both');
|
|
57
|
+
private readonly OpenAPI = (this.device.connectionType === 'OpenAPI' || this.device.connectionType === 'Both');
|
|
58
|
+
|
|
55
59
|
constructor(private readonly platform: SwitchBotPlatform, private accessory: PlatformAccessory, public device: device & devicesConfig) {
|
|
56
60
|
// default placeholders
|
|
57
61
|
this.logs(device);
|
|
58
|
-
this.openAPI();
|
|
59
62
|
this.scan(device);
|
|
60
63
|
this.refreshRate(device);
|
|
61
64
|
this.config(device);
|
|
62
|
-
this.
|
|
65
|
+
this.context();
|
|
63
66
|
|
|
64
67
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
65
68
|
this.doMotionUpdate = new Subject();
|
|
@@ -111,11 +114,11 @@ export class Motion {
|
|
|
111
114
|
}
|
|
112
115
|
|
|
113
116
|
// Battery Service
|
|
114
|
-
if (!
|
|
117
|
+
if (!this.BLE) {
|
|
115
118
|
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Battery Service`);
|
|
116
119
|
this.batteryService = this.accessory.getService(this.platform.Service.Battery);
|
|
117
120
|
accessory.removeService(this.batteryService!);
|
|
118
|
-
} else if (
|
|
121
|
+
} else if (this.BLE && !this.batteryService) {
|
|
119
122
|
this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Battery Service`);
|
|
120
123
|
(this.batteryService = this.accessory.getService(this.platform.Service.Battery) || this.accessory.addService(this.platform.Service.Battery)),
|
|
121
124
|
`${accessory.displayName} Battery`;
|
|
@@ -140,15 +143,19 @@ export class Motion {
|
|
|
140
143
|
* Parse the device status from the SwitchBot api
|
|
141
144
|
*/
|
|
142
145
|
async parseStatus(): Promise<void> {
|
|
143
|
-
if (this.
|
|
146
|
+
if (this.BLE && !this.SwitchToOpenAPI) {
|
|
147
|
+
await this.BLEparseStatus();
|
|
148
|
+
} else if (this.OpenAPI && this.platform.config.credentials?.token) {
|
|
149
|
+
this.SwitchToOpenAPI = false;
|
|
144
150
|
await this.openAPIparseStatus();
|
|
145
151
|
} else {
|
|
146
|
-
|
|
152
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
153
|
+
+ ` ${this.device.connectionType}, parseStatus will not happen.`);
|
|
147
154
|
}
|
|
148
155
|
}
|
|
149
156
|
|
|
150
157
|
async BLEparseStatus(): Promise<void> {
|
|
151
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
158
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
|
|
152
159
|
// Movement
|
|
153
160
|
this.MotionDetected = this.movement!;
|
|
154
161
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
|
|
@@ -184,28 +191,23 @@ export class Motion {
|
|
|
184
191
|
}
|
|
185
192
|
|
|
186
193
|
async openAPIparseStatus(): Promise<void> {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
this.
|
|
194
|
-
this.
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
break;
|
|
203
|
-
case 'bright':
|
|
204
|
-
default:
|
|
205
|
-
this.CurrentAmbientLightLevel = this.set_maxLux;
|
|
206
|
-
}
|
|
207
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
194
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
|
|
195
|
+
// Motion State
|
|
196
|
+
this.MotionDetected = this.moveDetected!;
|
|
197
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
|
|
198
|
+
// Light Level
|
|
199
|
+
if (!this.device.motion?.hide_lightsensor) {
|
|
200
|
+
this.set_minLux = this.minLux();
|
|
201
|
+
this.set_maxLux = this.maxLux();
|
|
202
|
+
switch (this.brightness) {
|
|
203
|
+
case 'dim':
|
|
204
|
+
this.CurrentAmbientLightLevel = this.set_minLux;
|
|
205
|
+
break;
|
|
206
|
+
case 'bright':
|
|
207
|
+
default:
|
|
208
|
+
this.CurrentAmbientLightLevel = this.set_maxLux;
|
|
208
209
|
}
|
|
210
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
209
211
|
}
|
|
210
212
|
}
|
|
211
213
|
|
|
@@ -213,15 +215,18 @@ export class Motion {
|
|
|
213
215
|
* Asks the SwitchBot API for the latest device information
|
|
214
216
|
*/
|
|
215
217
|
async refreshStatus(): Promise<void> {
|
|
216
|
-
if (this.
|
|
218
|
+
if (this.BLE) {
|
|
217
219
|
await this.BLERefreshStatus();
|
|
218
|
-
} else {
|
|
220
|
+
} else if (this.OpenAPI && this.platform.config.credentials?.token) {
|
|
219
221
|
await this.openAPIRefreshStatus();
|
|
222
|
+
} else {
|
|
223
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
224
|
+
+ ` ${this.device.connectionType}, refreshStatus will not happen.`);
|
|
220
225
|
}
|
|
221
226
|
}
|
|
222
227
|
|
|
223
228
|
async BLERefreshStatus(): Promise<void> {
|
|
224
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
229
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
|
|
225
230
|
const switchbot = await this.platform.connectBLE();
|
|
226
231
|
// Convert to BLE Address
|
|
227
232
|
this.device.bleMac =
|
|
@@ -231,7 +236,6 @@ export class Motion {
|
|
|
231
236
|
.join(':')
|
|
232
237
|
.toLowerCase();
|
|
233
238
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
234
|
-
|
|
235
239
|
this.getCustomBLEAddress(switchbot);
|
|
236
240
|
// Start to monitor advertisement packets
|
|
237
241
|
if (switchbot !== false) {
|
|
@@ -282,111 +286,67 @@ export class Motion {
|
|
|
282
286
|
}
|
|
283
287
|
})
|
|
284
288
|
.catch(async (e: any) => {
|
|
285
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed refreshStatus with BLE Connection`);
|
|
286
|
-
if (this.deviceLogging.includes('debug')) {
|
|
287
|
-
this.errorLog(
|
|
288
|
-
`${this.device.deviceType}: ${this.accessory.displayName} failed refreshStatus with BLE Connection,` +
|
|
289
|
-
` Error Message: ${superStringify(e.message)}`,
|
|
290
|
-
);
|
|
291
|
-
}
|
|
292
|
-
if (this.platform.config.credentials?.token) {
|
|
293
|
-
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
294
|
-
this.SwitchToOpenAPI = true;
|
|
295
|
-
await this.openAPIRefreshStatus();
|
|
296
|
-
}
|
|
297
289
|
this.apiError(e);
|
|
290
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}`
|
|
291
|
+
+ ` Connection, Error Message: ${superStringify(e.message)}`);
|
|
292
|
+
await this.BLEconnection(switchbot);
|
|
298
293
|
});
|
|
299
294
|
} else {
|
|
300
295
|
await this.BLEconnection(switchbot);
|
|
301
296
|
}
|
|
302
297
|
}
|
|
303
298
|
|
|
304
|
-
async getCustomBLEAddress(switchbot: any) {
|
|
305
|
-
if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
|
|
306
|
-
(async () => {
|
|
307
|
-
// Start to monitor advertisement packets
|
|
308
|
-
await switchbot.startScan({
|
|
309
|
-
model: 's',
|
|
310
|
-
});
|
|
311
|
-
// Set an event handler
|
|
312
|
-
switchbot.onadvertisement = (ad: any) => {
|
|
313
|
-
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${superStringify(ad, null, ' ')}`);
|
|
314
|
-
};
|
|
315
|
-
await switchbot.wait(10000);
|
|
316
|
-
// Stop to monitor
|
|
317
|
-
switchbot.stopScan();
|
|
318
|
-
})();
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
async BLEconnection(switchbot: any): Promise<void> {
|
|
323
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
|
|
324
|
-
if (this.platform.config.credentials?.token) {
|
|
325
|
-
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
326
|
-
this.SwitchToOpenAPI = true;
|
|
327
|
-
await this.openAPIRefreshStatus();
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
299
|
async openAPIRefreshStatus(): Promise<void> {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
});
|
|
361
|
-
res.on('end', () => {
|
|
362
|
-
try {
|
|
363
|
-
this.deviceStatus = JSON.parse(rawData);
|
|
364
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} refreshStatus: ${superStringify(this.deviceStatus)}`);
|
|
365
|
-
this.moveDetected = this.deviceStatus.body.moveDetected;
|
|
366
|
-
this.brightness = this.deviceStatus.body.brightness;
|
|
367
|
-
this.parseStatus();
|
|
368
|
-
this.updateHomeKitCharacteristics();
|
|
369
|
-
} catch (e: any) {
|
|
370
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
371
|
-
}
|
|
372
|
-
});
|
|
300
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
|
|
301
|
+
try {
|
|
302
|
+
const t = Date.now();
|
|
303
|
+
const nonce = 'requestID';
|
|
304
|
+
const data = this.platform.config.credentials?.token + t + nonce;
|
|
305
|
+
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
306
|
+
const sign = signTerm.toString('base64');
|
|
307
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
|
|
308
|
+
const options = {
|
|
309
|
+
hostname: HostDomain,
|
|
310
|
+
port: 443,
|
|
311
|
+
path: `${DevicePath}/${this.device.deviceId}/status`,
|
|
312
|
+
method: 'GET',
|
|
313
|
+
headers: {
|
|
314
|
+
Authorization: this.platform.config.credentials?.token,
|
|
315
|
+
sign: sign,
|
|
316
|
+
nonce: nonce,
|
|
317
|
+
t: t,
|
|
318
|
+
'Content-Type': 'application/json',
|
|
319
|
+
},
|
|
320
|
+
};
|
|
321
|
+
const req = https.request(options, (res) => {
|
|
322
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus statusCode: ${res.statusCode}`);
|
|
323
|
+
this.statusCode({ res });
|
|
324
|
+
let rawData = '';
|
|
325
|
+
res.on('data', (d) => {
|
|
326
|
+
rawData += d;
|
|
327
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
|
|
373
328
|
});
|
|
374
|
-
|
|
375
|
-
|
|
329
|
+
res.on('end', () => {
|
|
330
|
+
try {
|
|
331
|
+
this.deviceStatus = JSON.parse(rawData);
|
|
332
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus: ${superStringify(this.deviceStatus)}`);
|
|
333
|
+
this.moveDetected = this.deviceStatus.body.moveDetected;
|
|
334
|
+
this.brightness = this.deviceStatus.body.brightness;
|
|
335
|
+
this.parseStatus();
|
|
336
|
+
this.updateHomeKitCharacteristics();
|
|
337
|
+
} catch (e: any) {
|
|
338
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
339
|
+
}
|
|
376
340
|
});
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
this.apiError(e);
|
|
387
|
-
}
|
|
388
|
-
} else {
|
|
389
|
-
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} OpenAPI is disabled, commands will not be sent.`);
|
|
341
|
+
});
|
|
342
|
+
req.on('error', (e: any) => {
|
|
343
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
344
|
+
});
|
|
345
|
+
req.end();
|
|
346
|
+
} catch (e: any) {
|
|
347
|
+
this.apiError(e);
|
|
348
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
|
|
349
|
+
+ ` Connection, Error Message: ${superStringify(e.message)}`);
|
|
390
350
|
}
|
|
391
351
|
}
|
|
392
352
|
|
|
@@ -397,25 +357,29 @@ export class Motion {
|
|
|
397
357
|
if (this.MotionDetected === undefined) {
|
|
398
358
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
|
|
399
359
|
} else {
|
|
360
|
+
this.accessory.context.MotionDetected = this.MotionDetected;
|
|
400
361
|
this.motionSensorService.updateCharacteristic(this.platform.Characteristic.MotionDetected, this.MotionDetected);
|
|
401
362
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic MotionDetected: ${this.MotionDetected}`);
|
|
402
363
|
}
|
|
403
|
-
if (this.
|
|
364
|
+
if (this.BLE) {
|
|
404
365
|
if (this.BatteryLevel === undefined) {
|
|
405
366
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
|
|
406
367
|
} else {
|
|
368
|
+
this.accessory.context.BatteryLevel = this.BatteryLevel;
|
|
407
369
|
this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.BatteryLevel);
|
|
408
370
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
|
|
409
371
|
}
|
|
410
372
|
if (this.StatusLowBattery === undefined) {
|
|
411
373
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
|
|
412
374
|
} else {
|
|
375
|
+
this.accessory.context.StatusLowBattery = this.StatusLowBattery;
|
|
413
376
|
this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.StatusLowBattery);
|
|
414
377
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
|
|
415
378
|
}
|
|
416
379
|
if (this.CurrentAmbientLightLevel === undefined) {
|
|
417
380
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
418
381
|
} else {
|
|
382
|
+
this.accessory.context.CurrentAmbientLightLevel = this.CurrentAmbientLightLevel;
|
|
419
383
|
this.lightSensorService?.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, this.CurrentAmbientLightLevel);
|
|
420
384
|
this.debugLog(
|
|
421
385
|
`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
@@ -425,90 +389,116 @@ export class Motion {
|
|
|
425
389
|
}
|
|
426
390
|
}
|
|
427
391
|
|
|
428
|
-
async
|
|
429
|
-
this.
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
392
|
+
async getCustomBLEAddress(switchbot: any) {
|
|
393
|
+
if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
|
|
394
|
+
(async () => {
|
|
395
|
+
// Start to monitor advertisement packets
|
|
396
|
+
await switchbot.startScan({
|
|
397
|
+
model: 's',
|
|
398
|
+
});
|
|
399
|
+
// Set an event handler
|
|
400
|
+
switchbot.onadvertisement = (ad: any) => {
|
|
401
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${superStringify(ad, null, ' ')}`);
|
|
402
|
+
};
|
|
403
|
+
await switchbot.wait(10000);
|
|
404
|
+
// Stop to monitor
|
|
405
|
+
switchbot.stopScan();
|
|
406
|
+
})();
|
|
434
407
|
}
|
|
435
|
-
//throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
436
408
|
}
|
|
437
409
|
|
|
438
|
-
async
|
|
439
|
-
|
|
440
|
-
if (device.
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
config['ble'] = device.ble;
|
|
445
|
-
}
|
|
446
|
-
if (device.openAPI !== undefined) {
|
|
447
|
-
config['openAPI'] = device.openAPI;
|
|
448
|
-
}
|
|
449
|
-
if (device.logging !== undefined) {
|
|
450
|
-
config['logging'] = device.logging;
|
|
451
|
-
}
|
|
452
|
-
if (device.refreshRate !== undefined) {
|
|
453
|
-
config['refreshRate'] = device.refreshRate;
|
|
454
|
-
}
|
|
455
|
-
if (device.scanDuration !== undefined) {
|
|
456
|
-
config['scanDuration'] = device.scanDuration;
|
|
457
|
-
}
|
|
458
|
-
if (device.offline !== undefined) {
|
|
459
|
-
config['offline'] = device.offline;
|
|
460
|
-
}
|
|
461
|
-
if (Object.entries(config).length !== 0) {
|
|
462
|
-
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${superStringify(config)}`);
|
|
410
|
+
async BLEconnection(switchbot: any): Promise<void> {
|
|
411
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
|
|
412
|
+
if (this.platform.config.credentials?.token && this.device.connectionType !== 'Both') {
|
|
413
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
414
|
+
this.SwitchToOpenAPI = true;
|
|
415
|
+
await this.openAPIRefreshStatus();
|
|
463
416
|
}
|
|
464
417
|
}
|
|
465
418
|
|
|
466
|
-
|
|
467
|
-
if (device.
|
|
468
|
-
this.
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
|
|
472
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
|
|
419
|
+
minLux(): number {
|
|
420
|
+
if (this.device.motion?.set_minLux) {
|
|
421
|
+
this.set_minLux = this.device.motion!.set_minLux!;
|
|
422
|
+
} else {
|
|
423
|
+
this.set_minLux = 1;
|
|
473
424
|
}
|
|
425
|
+
return this.set_minLux;
|
|
474
426
|
}
|
|
475
427
|
|
|
476
|
-
|
|
477
|
-
if (
|
|
478
|
-
this.
|
|
428
|
+
maxLux(): number {
|
|
429
|
+
if (this.device.motion?.set_maxLux) {
|
|
430
|
+
this.set_maxLux = this.device.motion!.set_maxLux!;
|
|
479
431
|
} else {
|
|
480
|
-
this.
|
|
432
|
+
this.set_maxLux = 6001;
|
|
481
433
|
}
|
|
482
|
-
|
|
434
|
+
return this.set_maxLux;
|
|
483
435
|
}
|
|
484
436
|
|
|
485
437
|
async scan(device: device & devicesConfig): Promise<void> {
|
|
486
438
|
if (device.scanDuration) {
|
|
487
439
|
this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
|
|
488
|
-
if (
|
|
440
|
+
if (this.BLE) {
|
|
489
441
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
|
|
490
442
|
}
|
|
491
443
|
} else {
|
|
492
444
|
this.scanDuration = this.accessory.context.scanDuration = 1;
|
|
493
|
-
if (this.
|
|
445
|
+
if (this.BLE) {
|
|
494
446
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
|
|
495
447
|
}
|
|
496
448
|
}
|
|
497
449
|
}
|
|
498
450
|
|
|
499
|
-
async
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
451
|
+
async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
|
|
452
|
+
switch (res.statusCode) {
|
|
453
|
+
case 151:
|
|
454
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this device type.`);
|
|
455
|
+
break;
|
|
456
|
+
case 152:
|
|
457
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found.`);
|
|
458
|
+
break;
|
|
459
|
+
case 160:
|
|
460
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported.`);
|
|
461
|
+
break;
|
|
462
|
+
case 161:
|
|
463
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline.`);
|
|
464
|
+
this.offlineOff();
|
|
465
|
+
break;
|
|
466
|
+
case 171:
|
|
467
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} is offline. Hub: ${this.device.hubDeviceId}`);
|
|
468
|
+
this.offlineOff();
|
|
469
|
+
break;
|
|
470
|
+
case 190:
|
|
471
|
+
this.errorLog(
|
|
472
|
+
`${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
473
|
+
` Or command: ${superStringify(res)} format is invalid`,
|
|
474
|
+
);
|
|
475
|
+
break;
|
|
476
|
+
case 100:
|
|
477
|
+
if (this.platform.debugMode) {
|
|
478
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent.`);
|
|
479
|
+
}
|
|
480
|
+
break;
|
|
481
|
+
default:
|
|
482
|
+
if (this.platform.debugMode) {
|
|
483
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode.`);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
async offlineOff(): Promise<void> {
|
|
489
|
+
if (this.device.offline) {
|
|
490
|
+
this.MotionDetected = false;
|
|
491
|
+
this.motionSensorService.getCharacteristic(this.platform.Characteristic.MotionDetected).updateValue(this.MotionDetected);
|
|
492
|
+
await this.updateHomeKitCharacteristics();
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
async apiError(e: any): Promise<void> {
|
|
497
|
+
this.motionSensorService.updateCharacteristic(this.platform.Characteristic.MotionDetected, e);
|
|
498
|
+
if (this.BLE) {
|
|
499
|
+
this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
|
|
500
|
+
this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
|
|
501
|
+
this.lightSensorService?.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, e);
|
|
512
502
|
}
|
|
513
503
|
}
|
|
514
504
|
|
|
@@ -528,22 +518,63 @@ export class Motion {
|
|
|
528
518
|
return FirmwareRevision;
|
|
529
519
|
}
|
|
530
520
|
|
|
531
|
-
|
|
532
|
-
if (this.
|
|
533
|
-
this.
|
|
521
|
+
async context() {
|
|
522
|
+
if (this.MotionDetected === undefined) {
|
|
523
|
+
this.MotionDetected = false;
|
|
534
524
|
} else {
|
|
535
|
-
this.
|
|
525
|
+
this.MotionDetected = this.accessory.context.MotionDetected;
|
|
536
526
|
}
|
|
537
|
-
return this.set_minLux;
|
|
538
527
|
}
|
|
539
528
|
|
|
540
|
-
|
|
541
|
-
if (
|
|
542
|
-
this.
|
|
529
|
+
async refreshRate(device: device & devicesConfig): Promise<void> {
|
|
530
|
+
if (device.refreshRate) {
|
|
531
|
+
this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
|
|
532
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
|
|
533
|
+
} else if (this.platform.config.options!.refreshRate) {
|
|
534
|
+
this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
|
|
535
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
async config(device: device & devicesConfig): Promise<void> {
|
|
540
|
+
let config = {};
|
|
541
|
+
if (device.motion) {
|
|
542
|
+
config = device.motion;
|
|
543
|
+
}
|
|
544
|
+
if (device.connectionType !== undefined) {
|
|
545
|
+
config['connectionType'] = device.connectionType;
|
|
546
|
+
}
|
|
547
|
+
if (device.logging !== undefined) {
|
|
548
|
+
config['logging'] = device.logging;
|
|
549
|
+
}
|
|
550
|
+
if (device.refreshRate !== undefined) {
|
|
551
|
+
config['refreshRate'] = device.refreshRate;
|
|
552
|
+
}
|
|
553
|
+
if (device.scanDuration !== undefined) {
|
|
554
|
+
config['scanDuration'] = device.scanDuration;
|
|
555
|
+
}
|
|
556
|
+
if (device.offline !== undefined) {
|
|
557
|
+
config['offline'] = device.offline;
|
|
558
|
+
}
|
|
559
|
+
if (Object.entries(config).length !== 0) {
|
|
560
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${superStringify(config)}`);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
async logs(device: device & devicesConfig): Promise<void> {
|
|
565
|
+
if (this.platform.debugMode) {
|
|
566
|
+
this.deviceLogging = this.accessory.context.logging = 'debugMode';
|
|
567
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
|
|
568
|
+
} else if (device.logging) {
|
|
569
|
+
this.deviceLogging = this.accessory.context.logging = device.logging;
|
|
570
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
|
|
571
|
+
} else if (this.platform.config.options?.logging) {
|
|
572
|
+
this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
|
|
573
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
|
|
543
574
|
} else {
|
|
544
|
-
this.
|
|
575
|
+
this.deviceLogging = this.accessory.context.logging = 'standard';
|
|
576
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
|
|
545
577
|
}
|
|
546
|
-
return this.set_maxLux;
|
|
547
578
|
}
|
|
548
579
|
|
|
549
580
|
/**
|