@switchbot/homebridge-switchbot 2.6.0-beta.4 → 2.6.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/.vscode/tasks.json +13 -0
- package/CHANGELOG.md +4 -2
- package/README.md +18 -9
- package/dist/device/blindtilt.d.ts +1 -5
- package/dist/device/blindtilt.d.ts.map +1 -1
- package/dist/device/blindtilt.js +80 -140
- package/dist/device/blindtilt.js.map +1 -1
- package/dist/device/bot.d.ts +1 -5
- package/dist/device/bot.d.ts.map +1 -1
- package/dist/device/bot.js +79 -138
- package/dist/device/bot.js.map +1 -1
- package/dist/device/ceilinglight.d.ts +2 -6
- package/dist/device/ceilinglight.d.ts.map +1 -1
- package/dist/device/ceilinglight.js +157 -304
- package/dist/device/ceilinglight.js.map +1 -1
- package/dist/device/colorbulb.d.ts +2 -6
- package/dist/device/colorbulb.d.ts.map +1 -1
- package/dist/device/colorbulb.js +164 -311
- package/dist/device/colorbulb.js.map +1 -1
- package/dist/device/contact.d.ts +1 -5
- package/dist/device/contact.d.ts.map +1 -1
- package/dist/device/contact.js +36 -72
- package/dist/device/contact.js.map +1 -1
- package/dist/device/curtain.d.ts +1 -5
- package/dist/device/curtain.d.ts.map +1 -1
- package/dist/device/curtain.js +78 -138
- package/dist/device/curtain.js.map +1 -1
- package/dist/device/hub.d.ts +2 -6
- package/dist/device/hub.d.ts.map +1 -1
- package/dist/device/hub.js +30 -63
- package/dist/device/hub.js.map +1 -1
- package/dist/device/humidifier.d.ts +1 -5
- package/dist/device/humidifier.d.ts.map +1 -1
- package/dist/device/humidifier.js +115 -228
- package/dist/device/humidifier.js.map +1 -1
- package/dist/device/iosensor.d.ts +1 -5
- package/dist/device/iosensor.d.ts.map +1 -1
- package/dist/device/iosensor.js +38 -74
- package/dist/device/iosensor.js.map +1 -1
- package/dist/device/{striplight.d.ts → lightstrip.d.ts} +2 -10
- package/dist/device/lightstrip.d.ts.map +1 -0
- package/dist/device/{striplight.js → lightstrip.js} +138 -194
- package/dist/device/lightstrip.js.map +1 -0
- package/dist/device/lock.d.ts +1 -5
- package/dist/device/lock.d.ts.map +1 -1
- package/dist/device/lock.js +66 -126
- package/dist/device/lock.js.map +1 -1
- package/dist/device/meter.d.ts +1 -5
- package/dist/device/meter.d.ts.map +1 -1
- package/dist/device/meter.js +38 -74
- package/dist/device/meter.js.map +1 -1
- package/dist/device/meterplus.d.ts +1 -5
- package/dist/device/meterplus.d.ts.map +1 -1
- package/dist/device/meterplus.js +39 -75
- package/dist/device/meterplus.js.map +1 -1
- package/dist/device/motion.d.ts +1 -5
- package/dist/device/motion.d.ts.map +1 -1
- package/dist/device/motion.js +35 -72
- package/dist/device/motion.js.map +1 -1
- package/dist/device/plug.d.ts +1 -5
- package/dist/device/plug.d.ts.map +1 -1
- package/dist/device/plug.js +65 -126
- package/dist/device/plug.js.map +1 -1
- package/dist/device/robotvacuumcleaner.d.ts +1 -5
- package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
- package/dist/device/robotvacuumcleaner.js +79 -151
- package/dist/device/robotvacuumcleaner.js.map +1 -1
- package/dist/irdevice/airconditioner.d.ts +3 -7
- package/dist/irdevice/airconditioner.d.ts.map +1 -1
- package/dist/irdevice/airconditioner.js +34 -62
- package/dist/irdevice/airconditioner.js.map +1 -1
- package/dist/irdevice/airpurifier.d.ts +3 -7
- package/dist/irdevice/airpurifier.d.ts.map +1 -1
- package/dist/irdevice/airpurifier.js +31 -59
- package/dist/irdevice/airpurifier.js.map +1 -1
- package/dist/irdevice/camera.d.ts +1 -5
- package/dist/irdevice/camera.d.ts.map +1 -1
- package/dist/irdevice/camera.js +30 -57
- package/dist/irdevice/camera.js.map +1 -1
- package/dist/irdevice/fan.d.ts +2 -6
- package/dist/irdevice/fan.d.ts.map +1 -1
- package/dist/irdevice/fan.js +39 -66
- package/dist/irdevice/fan.js.map +1 -1
- package/dist/irdevice/light.d.ts +1 -5
- package/dist/irdevice/light.d.ts.map +1 -1
- package/dist/irdevice/light.js +32 -59
- package/dist/irdevice/light.js.map +1 -1
- package/dist/irdevice/other.d.ts +1 -5
- package/dist/irdevice/other.d.ts.map +1 -1
- package/dist/irdevice/other.js +30 -57
- package/dist/irdevice/other.js.map +1 -1
- package/dist/irdevice/tv.d.ts +3 -7
- package/dist/irdevice/tv.d.ts.map +1 -1
- package/dist/irdevice/tv.js +46 -76
- package/dist/irdevice/tv.js.map +1 -1
- package/dist/irdevice/vacuumcleaner.d.ts +2 -6
- package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
- package/dist/irdevice/vacuumcleaner.js +30 -58
- package/dist/irdevice/vacuumcleaner.js.map +1 -1
- package/dist/irdevice/waterheater.d.ts +7 -23
- package/dist/irdevice/waterheater.d.ts.map +1 -1
- package/dist/irdevice/waterheater.js +41 -74
- package/dist/irdevice/waterheater.js.map +1 -1
- package/dist/platform.d.ts +14 -5
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +156 -149
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +4 -0
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +5 -1
- package/dist/settings.js.map +1 -1
- package/nodemon.json +1 -1
- package/package.json +10 -10
- package/src/device/blindtilt.ts +122 -181
- package/src/device/bot.ts +96 -149
- package/src/device/ceilinglight.ts +172 -315
- package/src/device/colorbulb.ts +178 -324
- package/src/device/contact.ts +48 -78
- package/src/device/curtain.ts +93 -148
- package/src/device/hub.ts +34 -63
- package/src/device/humidifier.ts +135 -243
- package/src/device/iosensor.ts +49 -79
- package/src/device/{striplight.ts → lightstrip.ts} +148 -200
- package/src/device/lock.ts +78 -134
- package/src/device/meter.ts +48 -78
- package/src/device/meterplus.ts +50 -80
- package/src/device/motion.ts +46 -77
- package/src/device/plug.ts +76 -134
- package/src/device/robotvacuumcleaner.ts +91 -159
- package/src/irdevice/airconditioner.ts +56 -81
- package/src/irdevice/airpurifier.ts +41 -67
- package/src/irdevice/camera.ts +35 -60
- package/src/irdevice/fan.ts +46 -71
- package/src/irdevice/light.ts +38 -63
- package/src/irdevice/other.ts +35 -60
- package/src/irdevice/tv.ts +52 -80
- package/src/irdevice/vacuumcleaner.ts +36 -62
- package/src/irdevice/waterheater.ts +46 -76
- package/src/platform.ts +144 -158
- package/src/settings.ts +5 -0
- package/.github/npm-version-script.js +0 -81
- package/dist/device/striplight.d.ts.map +0 -1
- package/dist/device/striplight.js.map +0 -1
package/src/device/meterplus.ts
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
import https from 'https';
|
|
2
|
-
import crypto from 'crypto';
|
|
3
1
|
import { Context } from 'vm';
|
|
4
2
|
import { hostname } from 'os';
|
|
3
|
+
import { request } from 'undici';
|
|
4
|
+
import { sleep } from '../utils';
|
|
5
5
|
import { MqttClient } from 'mqtt';
|
|
6
|
-
import { connectAsync } from 'async-mqtt';
|
|
7
6
|
import { interval, Subject } from 'rxjs';
|
|
7
|
+
import { connectAsync } from 'async-mqtt';
|
|
8
8
|
import { skipWhile } from 'rxjs/operators';
|
|
9
|
-
import superStringify from 'super-stringify';
|
|
10
9
|
import { SwitchBotPlatform } from '../platform';
|
|
11
10
|
import { Service, PlatformAccessory, Units, CharacteristicValue } from 'homebridge';
|
|
12
|
-
import { device, devicesConfig, serviceData, ad, switchbot, temperature, deviceStatus,
|
|
13
|
-
import { IncomingMessage } from 'http';
|
|
14
|
-
import { sleep } from '../utils';
|
|
11
|
+
import { device, devicesConfig, serviceData, ad, switchbot, temperature, deviceStatus, Devices } from '../settings';
|
|
15
12
|
|
|
16
13
|
/**
|
|
17
14
|
* Platform Accessory
|
|
@@ -195,7 +192,7 @@ export class MeterPlus {
|
|
|
195
192
|
} else {
|
|
196
193
|
await this.offlineOff();
|
|
197
194
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
198
|
-
|
|
195
|
+
+ ` ${this.device.connectionType}, parseStatus will not happen.`);
|
|
199
196
|
}
|
|
200
197
|
}
|
|
201
198
|
|
|
@@ -254,7 +251,7 @@ export class MeterPlus {
|
|
|
254
251
|
} else {
|
|
255
252
|
await this.offlineOff();
|
|
256
253
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
257
|
-
|
|
254
|
+
+ ` ${this.device.connectionType}, refreshStatus will not happen.`);
|
|
258
255
|
}
|
|
259
256
|
}
|
|
260
257
|
|
|
@@ -280,7 +277,7 @@ export class MeterPlus {
|
|
|
280
277
|
switchbot.onadvertisement = async (ad: ad) => {
|
|
281
278
|
this.address = ad.address;
|
|
282
279
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},`
|
|
283
|
-
|
|
280
|
+
+ ` BLE Address Found: ${this.address}`);
|
|
284
281
|
if (ad.serviceData.humidity! > 0) {
|
|
285
282
|
// reject unreliable data
|
|
286
283
|
this.humidity = ad.serviceData.humidity;
|
|
@@ -290,11 +287,11 @@ export class MeterPlus {
|
|
|
290
287
|
this.celsius = ad.serviceData.temperature!.c;
|
|
291
288
|
this.fahrenheit = ad.serviceData.temperature!.f;
|
|
292
289
|
this.battery = ad.serviceData.battery;
|
|
293
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${
|
|
290
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
294
291
|
this.debugLog(
|
|
295
292
|
`${this.device.deviceType}: ${this.accessory.displayName} model: ${ad.serviceData.model}, modelName: ${ad.serviceData.modelName}, ` +
|
|
296
|
-
|
|
297
|
-
|
|
293
|
+
`temperature: ${JSON.stringify(ad.serviceData.temperature?.c)}, humidity: ${ad.serviceData.humidity}, ` +
|
|
294
|
+
`battery: ${ad.serviceData.battery}`,
|
|
298
295
|
);
|
|
299
296
|
|
|
300
297
|
if (this.serviceData) {
|
|
@@ -316,7 +313,7 @@ export class MeterPlus {
|
|
|
316
313
|
.catch(async (e: any) => {
|
|
317
314
|
this.apiError(e);
|
|
318
315
|
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}`
|
|
319
|
-
|
|
316
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
320
317
|
await this.BLERefreshConnection(switchbot);
|
|
321
318
|
});
|
|
322
319
|
} else {
|
|
@@ -327,54 +324,26 @@ export class MeterPlus {
|
|
|
327
324
|
async openAPIRefreshStatus(): Promise<void> {
|
|
328
325
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
|
|
329
326
|
try {
|
|
330
|
-
const
|
|
331
|
-
|
|
332
|
-
const data = this.platform.config.credentials?.token + t + nonce;
|
|
333
|
-
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
334
|
-
const sign = signTerm.toString('base64');
|
|
335
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
|
|
336
|
-
const options = {
|
|
337
|
-
hostname: HostDomain,
|
|
338
|
-
port: 443,
|
|
339
|
-
path: `${DevicePath}/${this.device.deviceId}/status`,
|
|
340
|
-
method: 'GET',
|
|
341
|
-
headers: {
|
|
342
|
-
Authorization: this.platform.config.credentials?.token,
|
|
343
|
-
sign: sign,
|
|
344
|
-
nonce: nonce,
|
|
345
|
-
t: t,
|
|
346
|
-
'Content-Type': 'application/json',
|
|
347
|
-
},
|
|
348
|
-
};
|
|
349
|
-
const req = https.request(options, (res) => {
|
|
350
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus statusCode: ${res.statusCode}`);
|
|
351
|
-
let rawData = '';
|
|
352
|
-
res.on('data', (d) => {
|
|
353
|
-
rawData += d;
|
|
354
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
|
|
355
|
-
});
|
|
356
|
-
res.on('end', () => {
|
|
357
|
-
try {
|
|
358
|
-
this.deviceStatus = JSON.parse(rawData);
|
|
359
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus: ${superStringify(this.deviceStatus)}`);
|
|
360
|
-
this.Humidity = this.deviceStatus.body.humidity!;
|
|
361
|
-
this.Temperature = this.deviceStatus.body.temperature!;
|
|
362
|
-
this.Battery = this.deviceStatus.body.battery!;
|
|
363
|
-
this.parseStatus();
|
|
364
|
-
this.updateHomeKitCharacteristics();
|
|
365
|
-
} catch (e: any) {
|
|
366
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
367
|
-
}
|
|
368
|
-
});
|
|
327
|
+
const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/status`, {
|
|
328
|
+
headers: this.platform.generateHeaders(),
|
|
369
329
|
});
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
330
|
+
const deviceStatus = await body.json();
|
|
331
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Devices: ${JSON.stringify(deviceStatus.body)}`);
|
|
332
|
+
this.statusCode(statusCode);
|
|
333
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Headers: ${JSON.stringify(headers)}`);
|
|
334
|
+
this.debugLog(
|
|
335
|
+
`${this.device.deviceType}: ${this.accessory.displayName
|
|
336
|
+
} refreshStatus: ${JSON.stringify(deviceStatus)}`,
|
|
337
|
+
);
|
|
338
|
+
this.Humidity = deviceStatus.body.humidity!;
|
|
339
|
+
this.Temperature = deviceStatus.body.temperature!;
|
|
340
|
+
this.Battery = deviceStatus.body.battery!;
|
|
341
|
+
this.openAPIparseStatus();
|
|
342
|
+
this.updateHomeKitCharacteristics();
|
|
374
343
|
} catch (e: any) {
|
|
375
344
|
this.apiError(e);
|
|
376
345
|
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
|
|
377
|
-
|
|
346
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
378
347
|
}
|
|
379
348
|
}
|
|
380
349
|
|
|
@@ -391,7 +360,7 @@ export class MeterPlus {
|
|
|
391
360
|
this.accessory.context.CurrentRelativeHumidity = this.CurrentRelativeHumidity;
|
|
392
361
|
this.humidityservice?.updateCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity, this.CurrentRelativeHumidity);
|
|
393
362
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
394
|
-
|
|
363
|
+
+ ` updateCharacteristic CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
|
|
395
364
|
if (this.device.mqttURL) {
|
|
396
365
|
mqttmessage.push(`"humidity": ${this.CurrentRelativeHumidity}`);
|
|
397
366
|
}
|
|
@@ -407,7 +376,7 @@ export class MeterPlus {
|
|
|
407
376
|
if (this.device.mqttURL) {
|
|
408
377
|
mqttmessage.push(`"temperature": ${this.CurrentTemperature}`);
|
|
409
378
|
}
|
|
410
|
-
if (this.device.history){
|
|
379
|
+
if (this.device.history) {
|
|
411
380
|
entry['temp'] = this.CurrentTemperature;
|
|
412
381
|
}
|
|
413
382
|
this.accessory.context.CurrentTemperature = this.CurrentTemperature;
|
|
@@ -459,7 +428,7 @@ export class MeterPlus {
|
|
|
459
428
|
?.join(':');
|
|
460
429
|
const options = this.device.mqttPubOptions || {};
|
|
461
430
|
this.mqttClient?.publish(`homebridge-switchbot/meter/${mac}`, `${message}`, options);
|
|
462
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT message: ${message} options:${
|
|
431
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT message: ${message} options:${JSON.stringify(options)}`);
|
|
463
432
|
}
|
|
464
433
|
|
|
465
434
|
/*
|
|
@@ -516,7 +485,7 @@ export class MeterPlus {
|
|
|
516
485
|
});
|
|
517
486
|
// Set an event handler
|
|
518
487
|
switchbot.onadvertisement = (ad: any) => {
|
|
519
|
-
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${
|
|
488
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
|
|
520
489
|
};
|
|
521
490
|
await sleep(10000);
|
|
522
491
|
// Stop to monitor
|
|
@@ -557,40 +526,41 @@ export class MeterPlus {
|
|
|
557
526
|
}
|
|
558
527
|
}
|
|
559
528
|
|
|
560
|
-
async statusCode(
|
|
561
|
-
switch (
|
|
529
|
+
async statusCode(statusCode: number): Promise<void> {
|
|
530
|
+
switch (statusCode) {
|
|
562
531
|
case 151:
|
|
563
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this
|
|
532
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
|
|
564
533
|
break;
|
|
565
534
|
case 152:
|
|
566
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found
|
|
535
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
|
|
567
536
|
break;
|
|
568
537
|
case 160:
|
|
569
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported
|
|
538
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
|
|
570
539
|
break;
|
|
571
540
|
case 161:
|
|
572
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline
|
|
573
|
-
|
|
541
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
|
|
542
|
+
this.offlineOff();
|
|
574
543
|
break;
|
|
575
544
|
case 171:
|
|
576
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} is offline
|
|
577
|
-
|
|
545
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. `
|
|
546
|
+
+ `Hub: ${this.device.hubDeviceId}`);
|
|
547
|
+
this.offlineOff();
|
|
578
548
|
break;
|
|
579
549
|
case 190:
|
|
580
550
|
this.errorLog(
|
|
581
551
|
`${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
582
|
-
|
|
552
|
+
` Or command format is invalid, statusCode: ${statusCode}`,
|
|
583
553
|
);
|
|
584
554
|
break;
|
|
585
555
|
case 100:
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
556
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
|
|
557
|
+
break;
|
|
558
|
+
case 200:
|
|
559
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
|
|
589
560
|
break;
|
|
590
561
|
default:
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
}
|
|
562
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: `
|
|
563
|
+
+ `${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
|
|
594
564
|
}
|
|
595
565
|
}
|
|
596
566
|
|
|
@@ -617,7 +587,7 @@ export class MeterPlus {
|
|
|
617
587
|
FirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
|
|
618
588
|
let FirmwareRevision: string;
|
|
619
589
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
620
|
-
|
|
590
|
+
+ ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
|
|
621
591
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
|
|
622
592
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
|
|
623
593
|
if (accessory.context.FirmwareRevision) {
|
|
@@ -690,7 +660,7 @@ export class MeterPlus {
|
|
|
690
660
|
config['scanDuration'] = device.scanDuration;
|
|
691
661
|
}
|
|
692
662
|
if (Object.entries(config).length !== 0) {
|
|
693
|
-
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${
|
|
663
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
|
|
694
664
|
}
|
|
695
665
|
}
|
|
696
666
|
|
package/src/device/motion.ts
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import https from 'https';
|
|
2
|
-
import crypto from 'crypto';
|
|
3
1
|
import { Context } from 'vm';
|
|
2
|
+
import { request } from 'undici';
|
|
3
|
+
import { sleep } from '../utils';
|
|
4
4
|
import { interval, Subject } from 'rxjs';
|
|
5
5
|
import { skipWhile } from 'rxjs/operators';
|
|
6
|
-
import superStringify from 'super-stringify';
|
|
7
6
|
import { SwitchBotPlatform } from '../platform';
|
|
8
7
|
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
9
|
-
import { device, devicesConfig, serviceData, switchbot, deviceStatus, ad,
|
|
10
|
-
import { IncomingMessage } from 'http';
|
|
11
|
-
import { sleep } from '../utils';
|
|
8
|
+
import { device, devicesConfig, serviceData, switchbot, deviceStatus, ad, Devices } from '../settings';
|
|
12
9
|
|
|
13
10
|
/**
|
|
14
11
|
* Platform Accessory
|
|
@@ -162,7 +159,7 @@ export class Motion {
|
|
|
162
159
|
} else {
|
|
163
160
|
await this.offlineOff();
|
|
164
161
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
165
|
-
|
|
162
|
+
+ ` ${this.device.connectionType}, parseStatus will not happen.`);
|
|
166
163
|
}
|
|
167
164
|
}
|
|
168
165
|
|
|
@@ -187,7 +184,7 @@ export class Motion {
|
|
|
187
184
|
this.CurrentAmbientLightLevel = this.set_maxLux;
|
|
188
185
|
}
|
|
189
186
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.lightLevel},` +
|
|
190
|
-
|
|
187
|
+
` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
191
188
|
if (this.CurrentAmbientLightLevel !== this.accessory.context.CurrentAmbientLightLevel) {
|
|
192
189
|
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
193
190
|
}
|
|
@@ -203,7 +200,7 @@ export class Motion {
|
|
|
203
200
|
this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
204
201
|
}
|
|
205
202
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel},`
|
|
206
|
-
|
|
203
|
+
+ ` StatusLowBattery: ${this.StatusLowBattery}`);
|
|
207
204
|
}
|
|
208
205
|
|
|
209
206
|
async openAPIparseStatus(): Promise<void> {
|
|
@@ -240,7 +237,7 @@ export class Motion {
|
|
|
240
237
|
} else {
|
|
241
238
|
await this.offlineOff();
|
|
242
239
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
243
|
-
|
|
240
|
+
+ ` ${this.device.connectionType}, refreshStatus will not happen.`);
|
|
244
241
|
}
|
|
245
242
|
}
|
|
246
243
|
|
|
@@ -272,7 +269,7 @@ export class Motion {
|
|
|
272
269
|
switchbot.onadvertisement = async (ad: any) => {
|
|
273
270
|
this.address = ad.address;
|
|
274
271
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},`
|
|
275
|
-
|
|
272
|
+
+ ` BLE Address Found: ${this.address}`);
|
|
276
273
|
this.serviceData = ad.serviceData;
|
|
277
274
|
this.movement = ad.serviceData.movement;
|
|
278
275
|
this.tested = ad.serviceData.tested;
|
|
@@ -282,10 +279,10 @@ export class Motion {
|
|
|
282
279
|
this.sense_distance = ad.serviceData.sense_distance;
|
|
283
280
|
this.lightLevel = ad.serviceData.lightLevel;
|
|
284
281
|
this.is_light = ad.serviceData.is_light;
|
|
285
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${
|
|
282
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
286
283
|
this.debugLog(
|
|
287
284
|
`${this.device.deviceType}: ${this.accessory.displayName} movement: ${ad.serviceData.movement}, is_light: ` +
|
|
288
|
-
|
|
285
|
+
`${ad.serviceData.is_light}, lightLevel: ${ad.serviceData.lightLevel}, battery: ${ad.serviceData.battery}`,
|
|
289
286
|
);
|
|
290
287
|
|
|
291
288
|
if (this.serviceData) {
|
|
@@ -316,7 +313,7 @@ export class Motion {
|
|
|
316
313
|
.catch(async (e: any) => {
|
|
317
314
|
this.apiError(e);
|
|
318
315
|
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}`
|
|
319
|
-
|
|
316
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
320
317
|
this.debugErrorLog('3');
|
|
321
318
|
await this.BLERefreshConnection(switchbot);
|
|
322
319
|
});
|
|
@@ -329,54 +326,25 @@ export class Motion {
|
|
|
329
326
|
async openAPIRefreshStatus(): Promise<void> {
|
|
330
327
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
|
|
331
328
|
try {
|
|
332
|
-
const
|
|
333
|
-
|
|
334
|
-
const data = this.platform.config.credentials?.token + t + nonce;
|
|
335
|
-
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
336
|
-
const sign = signTerm.toString('base64');
|
|
337
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
|
|
338
|
-
const options = {
|
|
339
|
-
hostname: HostDomain,
|
|
340
|
-
port: 443,
|
|
341
|
-
path: `${DevicePath}/${this.device.deviceId}/status`,
|
|
342
|
-
method: 'GET',
|
|
343
|
-
headers: {
|
|
344
|
-
Authorization: this.platform.config.credentials?.token,
|
|
345
|
-
sign: sign,
|
|
346
|
-
nonce: nonce,
|
|
347
|
-
t: t,
|
|
348
|
-
'Content-Type': 'application/json',
|
|
349
|
-
},
|
|
350
|
-
};
|
|
351
|
-
const req = https.request(options, (res) => {
|
|
352
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus statusCode: ${res.statusCode}`);
|
|
353
|
-
this.statusCode({ res });
|
|
354
|
-
let rawData = '';
|
|
355
|
-
res.on('data', (d) => {
|
|
356
|
-
rawData += d;
|
|
357
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
|
|
358
|
-
});
|
|
359
|
-
res.on('end', () => {
|
|
360
|
-
try {
|
|
361
|
-
this.deviceStatus = JSON.parse(rawData);
|
|
362
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus: ${superStringify(this.deviceStatus)}`);
|
|
363
|
-
this.moveDetected = this.deviceStatus.body.moveDetected;
|
|
364
|
-
this.brightness = this.deviceStatus.body.brightness;
|
|
365
|
-
this.openAPIparseStatus();
|
|
366
|
-
this.updateHomeKitCharacteristics();
|
|
367
|
-
} catch (e: any) {
|
|
368
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
369
|
-
}
|
|
370
|
-
});
|
|
371
|
-
});
|
|
372
|
-
req.on('error', (e: any) => {
|
|
373
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
329
|
+
const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/status`, {
|
|
330
|
+
headers: this.platform.generateHeaders(),
|
|
374
331
|
});
|
|
375
|
-
|
|
332
|
+
const deviceStatus = await body.json();
|
|
333
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Devices: ${JSON.stringify(deviceStatus.body)}`);
|
|
334
|
+
this.statusCode(statusCode);
|
|
335
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Headers: ${JSON.stringify(headers)}`);
|
|
336
|
+
this.debugLog(
|
|
337
|
+
`${this.device.deviceType}: ${this.accessory.displayName
|
|
338
|
+
} refreshStatus: ${JSON.stringify(deviceStatus)}`,
|
|
339
|
+
);
|
|
340
|
+
this.moveDetected = deviceStatus.body.moveDetected;
|
|
341
|
+
this.brightness = deviceStatus.body.brightness;
|
|
342
|
+
this.openAPIparseStatus();
|
|
343
|
+
this.updateHomeKitCharacteristics();
|
|
376
344
|
} catch (e: any) {
|
|
377
345
|
this.apiError(e);
|
|
378
346
|
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
|
|
379
|
-
|
|
347
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
380
348
|
}
|
|
381
349
|
}
|
|
382
350
|
|
|
@@ -438,7 +406,7 @@ export class Motion {
|
|
|
438
406
|
});
|
|
439
407
|
// Set an event handler
|
|
440
408
|
switchbot.onadvertisement = (ad: any) => {
|
|
441
|
-
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${
|
|
409
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
|
|
442
410
|
};
|
|
443
411
|
await sleep(10000);
|
|
444
412
|
// Stop to monitor
|
|
@@ -507,40 +475,41 @@ export class Motion {
|
|
|
507
475
|
}
|
|
508
476
|
}
|
|
509
477
|
|
|
510
|
-
async statusCode(
|
|
511
|
-
switch (
|
|
478
|
+
async statusCode(statusCode: number): Promise<void> {
|
|
479
|
+
switch (statusCode) {
|
|
512
480
|
case 151:
|
|
513
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this
|
|
481
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
|
|
514
482
|
break;
|
|
515
483
|
case 152:
|
|
516
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found
|
|
484
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
|
|
517
485
|
break;
|
|
518
486
|
case 160:
|
|
519
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported
|
|
487
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
|
|
520
488
|
break;
|
|
521
489
|
case 161:
|
|
522
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline
|
|
523
|
-
|
|
490
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
|
|
491
|
+
this.offlineOff();
|
|
524
492
|
break;
|
|
525
493
|
case 171:
|
|
526
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} is offline
|
|
527
|
-
|
|
494
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. `
|
|
495
|
+
+ `Hub: ${this.device.hubDeviceId}`);
|
|
496
|
+
this.offlineOff();
|
|
528
497
|
break;
|
|
529
498
|
case 190:
|
|
530
499
|
this.errorLog(
|
|
531
500
|
`${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
532
|
-
|
|
501
|
+
` Or command format is invalid, statusCode: ${statusCode}`,
|
|
533
502
|
);
|
|
534
503
|
break;
|
|
535
504
|
case 100:
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
505
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
|
|
506
|
+
break;
|
|
507
|
+
case 200:
|
|
508
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
|
|
539
509
|
break;
|
|
540
510
|
default:
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
}
|
|
511
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: `
|
|
512
|
+
+ `${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
|
|
544
513
|
}
|
|
545
514
|
}
|
|
546
515
|
|
|
@@ -563,7 +532,7 @@ export class Motion {
|
|
|
563
532
|
FirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
|
|
564
533
|
let FirmwareRevision: string;
|
|
565
534
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
566
|
-
|
|
535
|
+
+ ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
|
|
567
536
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
|
|
568
537
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
|
|
569
538
|
if (accessory.context.FirmwareRevision) {
|
|
@@ -618,7 +587,7 @@ export class Motion {
|
|
|
618
587
|
config['offline'] = device.offline;
|
|
619
588
|
}
|
|
620
589
|
if (Object.entries(config).length !== 0) {
|
|
621
|
-
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${
|
|
590
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
|
|
622
591
|
}
|
|
623
592
|
}
|
|
624
593
|
|