@switchbot/homebridge-switchbot 1.15.1-beta.6 → 1.15.1-beta.8
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/.prettierrc +1 -1
- package/dist/device/bot.d.ts +8 -7
- package/dist/device/bot.d.ts.map +1 -1
- package/dist/device/bot.js +83 -11
- package/dist/device/bot.js.map +1 -1
- package/dist/device/colorbulb.d.ts +8 -7
- package/dist/device/colorbulb.d.ts.map +1 -1
- package/dist/device/colorbulb.js +182 -23
- package/dist/device/colorbulb.js.map +1 -1
- package/dist/device/contact.d.ts +3 -3
- package/dist/device/contact.d.ts.map +1 -1
- package/dist/device/contact.js +50 -7
- package/dist/device/contact.js.map +1 -1
- package/dist/device/curtain.d.ts +9 -8
- package/dist/device/curtain.d.ts.map +1 -1
- package/dist/device/curtain.js +86 -14
- package/dist/device/curtain.js.map +1 -1
- package/dist/device/humidifier.d.ts +8 -7
- package/dist/device/humidifier.d.ts.map +1 -1
- package/dist/device/humidifier.js +152 -27
- package/dist/device/humidifier.js.map +1 -1
- package/dist/device/lock.d.ts +8 -7
- package/dist/device/lock.d.ts.map +1 -1
- package/dist/device/lock.js +84 -12
- package/dist/device/lock.js.map +1 -1
- package/dist/device/meter.d.ts +4 -4
- package/dist/device/meter.d.ts.map +1 -1
- package/dist/device/meter.js +51 -8
- package/dist/device/meter.js.map +1 -1
- package/dist/device/meterplus.d.ts +3 -3
- package/dist/device/meterplus.d.ts.map +1 -1
- package/dist/device/meterplus.js +49 -6
- package/dist/device/meterplus.js.map +1 -1
- package/dist/device/motion.d.ts +3 -3
- package/dist/device/motion.d.ts.map +1 -1
- package/dist/device/motion.js +49 -9
- package/dist/device/motion.js.map +1 -1
- package/dist/device/plug.d.ts +8 -7
- package/dist/device/plug.d.ts.map +1 -1
- package/dist/device/plug.js +83 -11
- package/dist/device/plug.js.map +1 -1
- package/dist/device/striplight.d.ts +8 -7
- package/dist/device/striplight.d.ts.map +1 -1
- package/dist/device/striplight.js +149 -19
- package/dist/device/striplight.js.map +1 -1
- package/dist/irdevice/airconditioner.d.ts +5 -4
- package/dist/irdevice/airconditioner.d.ts.map +1 -1
- package/dist/irdevice/airconditioner.js +40 -6
- package/dist/irdevice/airconditioner.js.map +1 -1
- package/dist/irdevice/airpurifier.d.ts +5 -4
- package/dist/irdevice/airpurifier.d.ts.map +1 -1
- package/dist/irdevice/airpurifier.js +40 -6
- package/dist/irdevice/airpurifier.js.map +1 -1
- package/dist/irdevice/camera.d.ts +5 -4
- package/dist/irdevice/camera.d.ts.map +1 -1
- package/dist/irdevice/camera.js +40 -6
- package/dist/irdevice/camera.js.map +1 -1
- package/dist/irdevice/fan.d.ts +7 -6
- package/dist/irdevice/fan.d.ts.map +1 -1
- package/dist/irdevice/fan.js +40 -6
- package/dist/irdevice/fan.js.map +1 -1
- package/dist/irdevice/light.d.ts +5 -4
- package/dist/irdevice/light.d.ts.map +1 -1
- package/dist/irdevice/light.js +40 -6
- package/dist/irdevice/light.js.map +1 -1
- package/dist/irdevice/other.d.ts +5 -4
- package/dist/irdevice/other.d.ts.map +1 -1
- package/dist/irdevice/other.js +40 -6
- package/dist/irdevice/other.js.map +1 -1
- package/dist/irdevice/tv.d.ts +7 -6
- package/dist/irdevice/tv.d.ts.map +1 -1
- package/dist/irdevice/tv.js +40 -6
- package/dist/irdevice/tv.js.map +1 -1
- package/dist/irdevice/vacuumcleaner.d.ts +5 -4
- package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
- package/dist/irdevice/vacuumcleaner.js +40 -6
- package/dist/irdevice/vacuumcleaner.js.map +1 -1
- package/dist/irdevice/waterheater.d.ts +5 -4
- package/dist/irdevice/waterheater.d.ts.map +1 -1
- package/dist/irdevice/waterheater.js +40 -6
- package/dist/irdevice/waterheater.js.map +1 -1
- package/dist/platform.d.ts +3 -5
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +142 -92
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +2 -16
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +3 -3
- package/dist/settings.js.map +1 -1
- package/package.json +6 -7
- package/src/device/bot.ts +87 -15
- package/src/device/colorbulb.ts +186 -41
- package/src/device/contact.ts +49 -10
- package/src/device/curtain.ts +92 -19
- package/src/device/humidifier.ts +164 -30
- package/src/device/lock.ts +88 -16
- package/src/device/meter.ts +51 -12
- package/src/device/meterplus.ts +48 -9
- package/src/device/motion.ts +48 -12
- package/src/device/plug.ts +87 -15
- package/src/device/striplight.ts +161 -24
- package/src/irdevice/airconditioner.ts +43 -8
- package/src/irdevice/airpurifier.ts +43 -8
- package/src/irdevice/camera.ts +43 -8
- package/src/irdevice/fan.ts +44 -9
- package/src/irdevice/light.ts +43 -8
- package/src/irdevice/other.ts +43 -8
- package/src/irdevice/tv.ts +44 -9
- package/src/irdevice/vacuumcleaner.ts +43 -8
- package/src/irdevice/waterheater.ts +43 -8
- package/src/platform.ts +155 -105
- package/src/settings.ts +6 -10
package/src/device/humidifier.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import
|
|
1
|
+
import https from 'https';
|
|
2
|
+
import crypto from 'crypto';
|
|
3
|
+
import { Context } from 'vm';
|
|
4
|
+
import { IncomingMessage } from 'http';
|
|
2
5
|
import { interval, Subject } from 'rxjs';
|
|
3
6
|
import { SwitchBotPlatform } from '../platform';
|
|
4
7
|
import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
|
|
5
8
|
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
6
|
-
import {
|
|
7
|
-
import { Context } from 'vm';
|
|
9
|
+
import { device, devicesConfig, serviceData, ad, payload, deviceStatus, HostDomain, DevicePath } from '../settings';
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
* Platform Accessory
|
|
@@ -32,7 +34,7 @@ export class Humidifier {
|
|
|
32
34
|
lackWater: deviceStatus['lackWater'];
|
|
33
35
|
temperature: deviceStatus['temperature'];
|
|
34
36
|
nebulizationEfficiency: deviceStatus['nebulizationEfficiency'];
|
|
35
|
-
deviceStatus!: deviceStatusResponse;
|
|
37
|
+
deviceStatus!: any; //deviceStatusResponse;
|
|
36
38
|
|
|
37
39
|
// BLE Others
|
|
38
40
|
connected?: boolean;
|
|
@@ -388,20 +390,53 @@ export class Humidifier {
|
|
|
388
390
|
if (this.platform.config.credentials?.token) {
|
|
389
391
|
this.debugLog(`Humidifier: ${this.accessory.displayName} OpenAPI refreshStatus`);
|
|
390
392
|
try {
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
this.
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
393
|
+
const t = Date.now();
|
|
394
|
+
const nonce = 'requestID';
|
|
395
|
+
const data = this.platform.config.credentials?.token + t + nonce;
|
|
396
|
+
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
397
|
+
const sign = signTerm.toString('base64');
|
|
398
|
+
this.debugLog(`Humidifier: ${this.accessory.displayName} sign: ${sign}`);
|
|
399
|
+
const options = {
|
|
400
|
+
hostname: HostDomain,
|
|
401
|
+
port: 443,
|
|
402
|
+
path: `${DevicePath}/${this.device.deviceId}/status`,
|
|
403
|
+
method: 'GET',
|
|
404
|
+
headers: {
|
|
405
|
+
Authorization: this.platform.config.credentials?.token,
|
|
406
|
+
sign: sign,
|
|
407
|
+
nonce: nonce,
|
|
408
|
+
t: t,
|
|
409
|
+
'Content-Type': 'application/json',
|
|
410
|
+
},
|
|
411
|
+
};
|
|
412
|
+
const req = https.request(options, (res) => {
|
|
413
|
+
this.debugLog(`Humidifier: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
414
|
+
let rawData = '';
|
|
415
|
+
res.on('data', (d) => {
|
|
416
|
+
rawData += d;
|
|
417
|
+
this.debugLog(`Humidifier: ${this.accessory.displayName} d: ${d}`);
|
|
418
|
+
});
|
|
419
|
+
res.on('end', () => {
|
|
420
|
+
try {
|
|
421
|
+
this.deviceStatus = JSON.parse(rawData);
|
|
422
|
+
this.debugLog(`Humidifier: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
423
|
+
this.auto = this.deviceStatus.body.auto;
|
|
424
|
+
this.power = this.deviceStatus.body.power;
|
|
425
|
+
this.lackWater = this.deviceStatus.body.lackWater;
|
|
426
|
+
this.humidity = this.deviceStatus.body.humidity;
|
|
427
|
+
this.temperature = this.deviceStatus.body.temperature;
|
|
428
|
+
this.nebulizationEfficiency = this.deviceStatus.body.nebulizationEfficiency;
|
|
429
|
+
this.parseStatus();
|
|
430
|
+
this.updateHomeKitCharacteristics();
|
|
431
|
+
} catch (e: any) {
|
|
432
|
+
this.errorLog(`Humidifier: ${this.accessory.displayName} error message: ${e.message}`);
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
});
|
|
436
|
+
req.on('error', (e: any) => {
|
|
437
|
+
this.errorLog(`Humidifier: ${this.accessory.displayName} error message: ${e.message}`);
|
|
438
|
+
});
|
|
439
|
+
req.end();
|
|
405
440
|
} catch (e: any) {
|
|
406
441
|
this.errorLog(`Humidifier: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
|
|
407
442
|
if (this.deviceLogging.includes('debug')) {
|
|
@@ -493,9 +528,42 @@ export class Humidifier {
|
|
|
493
528
|
);
|
|
494
529
|
|
|
495
530
|
// Make the API request
|
|
496
|
-
const
|
|
497
|
-
|
|
498
|
-
this.
|
|
531
|
+
const t = Date.now();
|
|
532
|
+
const nonce = 'requestID';
|
|
533
|
+
const data = this.platform.config.credentials?.token + t + nonce;
|
|
534
|
+
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
535
|
+
const sign = signTerm.toString('base64');
|
|
536
|
+
this.debugLog(`Humidifier: ${this.accessory.displayName} sign: ${sign}`);
|
|
537
|
+
const options = {
|
|
538
|
+
hostname: 'api.switch-bot.com',
|
|
539
|
+
port: 443,
|
|
540
|
+
path: `/v1.1/devices/${this.device.deviceId}/commands`,
|
|
541
|
+
method: 'POST',
|
|
542
|
+
headers: {
|
|
543
|
+
Authorization: this.platform.config.credentials?.token,
|
|
544
|
+
sign: sign,
|
|
545
|
+
nonce: nonce,
|
|
546
|
+
t: t,
|
|
547
|
+
'Content-Type': 'application/json',
|
|
548
|
+
},
|
|
549
|
+
};
|
|
550
|
+
|
|
551
|
+
const req = https.request(options, (res) => {
|
|
552
|
+
this.debugLog(`Humidifier: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
553
|
+
this.statusCode({ res });
|
|
554
|
+
res.on('data', (d) => {
|
|
555
|
+
this.debugLog(`Humidifier: ${this.accessory.displayName} d: ${d}`);
|
|
556
|
+
});
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
req.on('error', (error) => {
|
|
560
|
+
this.errorLog(`Humidifier: ${this.accessory.displayName} error: ${error}`);
|
|
561
|
+
});
|
|
562
|
+
|
|
563
|
+
req.write(payload);
|
|
564
|
+
req.end();
|
|
565
|
+
|
|
566
|
+
this.debugLog(`Humidifier: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
|
|
499
567
|
} catch (e: any) {
|
|
500
568
|
this.errorLog(`Humidifier: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
|
|
501
569
|
if (this.deviceLogging.includes('debug')) {
|
|
@@ -539,9 +607,42 @@ export class Humidifier {
|
|
|
539
607
|
);
|
|
540
608
|
|
|
541
609
|
// Make the API request
|
|
542
|
-
const
|
|
543
|
-
|
|
544
|
-
this.
|
|
610
|
+
const t = Date.now();
|
|
611
|
+
const nonce = 'requestID';
|
|
612
|
+
const data = this.platform.config.credentials?.token + t + nonce;
|
|
613
|
+
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
614
|
+
const sign = signTerm.toString('base64');
|
|
615
|
+
this.debugLog(`Humidifier: ${this.accessory.displayName} sign: ${sign}`);
|
|
616
|
+
const options = {
|
|
617
|
+
hostname: 'api.switch-bot.com',
|
|
618
|
+
port: 443,
|
|
619
|
+
path: `/v1.1/devices/${this.device.deviceId}/commands`,
|
|
620
|
+
method: 'POST',
|
|
621
|
+
headers: {
|
|
622
|
+
Authorization: this.platform.config.credentials?.token,
|
|
623
|
+
sign: sign,
|
|
624
|
+
nonce: nonce,
|
|
625
|
+
t: t,
|
|
626
|
+
'Content-Type': 'application/json',
|
|
627
|
+
},
|
|
628
|
+
};
|
|
629
|
+
|
|
630
|
+
const req = https.request(options, (res) => {
|
|
631
|
+
this.debugLog(`Humidifier: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
632
|
+
this.statusCode({ res });
|
|
633
|
+
res.on('data', (d) => {
|
|
634
|
+
this.debugLog(`Humidifier: ${this.accessory.displayName} d: ${d}`);
|
|
635
|
+
});
|
|
636
|
+
});
|
|
637
|
+
|
|
638
|
+
req.on('error', (error) => {
|
|
639
|
+
this.errorLog(`Humidifier: ${this.accessory.displayName} error: ${error}`);
|
|
640
|
+
});
|
|
641
|
+
|
|
642
|
+
req.write(payload);
|
|
643
|
+
req.end();
|
|
644
|
+
|
|
645
|
+
this.debugLog(`Humidifier: ${this.accessory.displayName} pushAutoChanges: ${JSON.stringify(req)}`);
|
|
545
646
|
}
|
|
546
647
|
} catch (e: any) {
|
|
547
648
|
this.errorLog(`Humidifier: ${this.accessory.displayName} failed pushAutoChanges with OpenAPI Connection`);
|
|
@@ -574,9 +675,42 @@ export class Humidifier {
|
|
|
574
675
|
);
|
|
575
676
|
|
|
576
677
|
// Make the API request
|
|
577
|
-
const
|
|
578
|
-
|
|
579
|
-
this.
|
|
678
|
+
const t = Date.now();
|
|
679
|
+
const nonce = 'requestID';
|
|
680
|
+
const data = this.platform.config.credentials?.token + t + nonce;
|
|
681
|
+
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
682
|
+
const sign = signTerm.toString('base64');
|
|
683
|
+
this.debugLog(`Humidifier: ${this.accessory.displayName} sign: ${sign}`);
|
|
684
|
+
const options = {
|
|
685
|
+
hostname: 'api.switch-bot.com',
|
|
686
|
+
port: 443,
|
|
687
|
+
path: `/v1.1/devices/${this.device.deviceId}/commands`,
|
|
688
|
+
method: 'POST',
|
|
689
|
+
headers: {
|
|
690
|
+
Authorization: this.platform.config.credentials?.token,
|
|
691
|
+
sign: sign,
|
|
692
|
+
nonce: nonce,
|
|
693
|
+
t: t,
|
|
694
|
+
'Content-Type': 'application/json',
|
|
695
|
+
},
|
|
696
|
+
};
|
|
697
|
+
|
|
698
|
+
const req = https.request(options, (res) => {
|
|
699
|
+
this.debugLog(`Humidifier: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
700
|
+
this.statusCode({ res });
|
|
701
|
+
res.on('data', (d) => {
|
|
702
|
+
this.debugLog(`Humidifier: ${this.accessory.displayName} d: ${d}`);
|
|
703
|
+
});
|
|
704
|
+
});
|
|
705
|
+
|
|
706
|
+
req.on('error', (error) => {
|
|
707
|
+
this.errorLog(`Humidifier: ${this.accessory.displayName} error: ${error}`);
|
|
708
|
+
});
|
|
709
|
+
|
|
710
|
+
req.write(payload);
|
|
711
|
+
req.end();
|
|
712
|
+
|
|
713
|
+
this.debugLog(`Humidifier: ${this.accessory.displayName} pushActiveChanges: ${JSON.stringify(req)}`);
|
|
580
714
|
}
|
|
581
715
|
} catch (e: any) {
|
|
582
716
|
this.errorLog(`Humidifier: ${this.accessory.displayName} failed pushActiveChanges with OpenAPI Connection`);
|
|
@@ -677,8 +811,8 @@ export class Humidifier {
|
|
|
677
811
|
//throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
678
812
|
}
|
|
679
813
|
|
|
680
|
-
async statusCode(
|
|
681
|
-
switch (
|
|
814
|
+
async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
|
|
815
|
+
switch (res.statusCode) {
|
|
682
816
|
case 151:
|
|
683
817
|
this.errorLog(`Humidifier: ${this.accessory.displayName} Command not supported by this device type.`);
|
|
684
818
|
break;
|
|
@@ -699,7 +833,7 @@ export class Humidifier {
|
|
|
699
833
|
case 190:
|
|
700
834
|
this.errorLog(
|
|
701
835
|
`Humidifier: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
702
|
-
` Or command: ${JSON.stringify(
|
|
836
|
+
` Or command: ${JSON.stringify(res)} format is invalid`,
|
|
703
837
|
);
|
|
704
838
|
break;
|
|
705
839
|
case 100:
|
package/src/device/lock.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import
|
|
1
|
+
import https from 'https';
|
|
2
|
+
import crypto from 'crypto';
|
|
3
|
+
import { Context } from 'vm';
|
|
4
|
+
import { IncomingMessage } from 'http';
|
|
2
5
|
import { interval, Subject } from 'rxjs';
|
|
3
6
|
import { SwitchBotPlatform } from '../platform';
|
|
4
7
|
import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
|
|
5
8
|
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
6
|
-
import {
|
|
7
|
-
import { Context } from 'vm';
|
|
9
|
+
import { device, devicesConfig, payload, deviceStatus, HostDomain, DevicePath } from '../settings';
|
|
8
10
|
|
|
9
11
|
export class Lock {
|
|
10
12
|
// Services
|
|
@@ -19,7 +21,7 @@ export class Lock {
|
|
|
19
21
|
// OpenAPI Others
|
|
20
22
|
doorState!: deviceStatus['doorState'];
|
|
21
23
|
lockState!: deviceStatus['lockState'];
|
|
22
|
-
deviceStatus!: deviceStatusResponse;
|
|
24
|
+
deviceStatus!: any; //deviceStatusResponse;
|
|
23
25
|
|
|
24
26
|
// Config
|
|
25
27
|
scanDuration!: number;
|
|
@@ -151,12 +153,49 @@ export class Lock {
|
|
|
151
153
|
|
|
152
154
|
async refreshStatus(): Promise<void> {
|
|
153
155
|
try {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
this.
|
|
156
|
+
const t = Date.now();
|
|
157
|
+
const nonce = 'requestID';
|
|
158
|
+
const data = this.platform.config.credentials?.token + t + nonce;
|
|
159
|
+
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
160
|
+
const sign = signTerm.toString('base64');
|
|
161
|
+
this.debugLog(`Lock: ${this.accessory.displayName} sign: ${sign}`);
|
|
162
|
+
const options = {
|
|
163
|
+
hostname: HostDomain,
|
|
164
|
+
port: 443,
|
|
165
|
+
path: `${DevicePath}/${this.device.deviceId}/status`,
|
|
166
|
+
method: 'GET',
|
|
167
|
+
headers: {
|
|
168
|
+
Authorization: this.platform.config.credentials?.token,
|
|
169
|
+
sign: sign,
|
|
170
|
+
nonce: nonce,
|
|
171
|
+
t: t,
|
|
172
|
+
'Content-Type': 'application/json',
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
const req = https.request(options, (res) => {
|
|
176
|
+
this.debugLog(`Lock: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
177
|
+
let rawData = '';
|
|
178
|
+
res.on('data', (d) => {
|
|
179
|
+
rawData += d;
|
|
180
|
+
this.debugLog(`Lock: ${this.accessory.displayName} d: ${d}`);
|
|
181
|
+
});
|
|
182
|
+
res.on('end', () => {
|
|
183
|
+
try {
|
|
184
|
+
this.deviceStatus = JSON.parse(rawData);
|
|
185
|
+
this.debugLog(`Lock: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
186
|
+
this.lockState = this.deviceStatus.body.lockState;
|
|
187
|
+
this.doorState = this.deviceStatus.body.doorState;
|
|
188
|
+
this.parseStatus();
|
|
189
|
+
this.updateHomeKitCharacteristics();
|
|
190
|
+
} catch (e: any) {
|
|
191
|
+
this.errorLog(`Lock: ${this.accessory.displayName} error message: ${e.message}`);
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
req.on('error', (e: any) => {
|
|
196
|
+
this.errorLog(`Lock: ${this.accessory.displayName} error message: ${e.message}`);
|
|
197
|
+
});
|
|
198
|
+
req.end();
|
|
160
199
|
} catch (e: any) {
|
|
161
200
|
this.errorLog(`Lock: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
|
|
162
201
|
if (this.deviceLogging.includes('debug')) {
|
|
@@ -192,9 +231,42 @@ export class Lock {
|
|
|
192
231
|
);
|
|
193
232
|
|
|
194
233
|
// Make the API request
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
this.
|
|
234
|
+
const t = Date.now();
|
|
235
|
+
const nonce = 'requestID';
|
|
236
|
+
const data = this.platform.config.credentials?.token + t + nonce;
|
|
237
|
+
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
238
|
+
const sign = signTerm.toString('base64');
|
|
239
|
+
this.debugLog(`Lock: ${this.accessory.displayName} sign: ${sign}`);
|
|
240
|
+
const options = {
|
|
241
|
+
hostname: 'api.switch-bot.com',
|
|
242
|
+
port: 443,
|
|
243
|
+
path: `/v1.1/devices/${this.device.deviceId}/commands`,
|
|
244
|
+
method: 'POST',
|
|
245
|
+
headers: {
|
|
246
|
+
Authorization: this.platform.config.credentials?.token,
|
|
247
|
+
sign: sign,
|
|
248
|
+
nonce: nonce,
|
|
249
|
+
t: t,
|
|
250
|
+
'Content-Type': 'application/json',
|
|
251
|
+
},
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
const req = https.request(options, (res) => {
|
|
255
|
+
this.debugLog(`Lock: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
256
|
+
this.statusCode({ res });
|
|
257
|
+
res.on('data', (d) => {
|
|
258
|
+
this.debugLog(`Lock: ${this.accessory.displayName} d: ${d}`);
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
req.on('error', (error) => {
|
|
263
|
+
this.errorLog(`Lock: ${this.accessory.displayName} error: ${error}`);
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
req.write(payload);
|
|
267
|
+
req.end();
|
|
268
|
+
|
|
269
|
+
this.debugLog(`Lock: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
|
|
198
270
|
this.accessory.context.On = this.LockTargetState;
|
|
199
271
|
interval(5000)
|
|
200
272
|
.pipe(take(1))
|
|
@@ -235,8 +307,8 @@ export class Lock {
|
|
|
235
307
|
//throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
236
308
|
}
|
|
237
309
|
|
|
238
|
-
async statusCode(
|
|
239
|
-
switch (
|
|
310
|
+
async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
|
|
311
|
+
switch (res.statusCode) {
|
|
240
312
|
case 151:
|
|
241
313
|
this.errorLog(`Lock: ${this.accessory.displayName} Command not supported by this device type.`);
|
|
242
314
|
break;
|
|
@@ -255,7 +327,7 @@ export class Lock {
|
|
|
255
327
|
case 190:
|
|
256
328
|
this.errorLog(
|
|
257
329
|
`Lock: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
258
|
-
` Or command: ${JSON.stringify(
|
|
330
|
+
` Or command: ${JSON.stringify(res)} format is invalid`,
|
|
259
331
|
);
|
|
260
332
|
break;
|
|
261
333
|
case 100:
|
package/src/device/meter.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
import https from 'https';
|
|
2
|
+
import crypto from 'crypto';
|
|
3
|
+
import { Context } from 'vm';
|
|
4
|
+
import { hostname } from 'os';
|
|
5
|
+
import { MqttClient } from 'mqtt';
|
|
6
|
+
import { connectAsync } from 'async-mqtt';
|
|
1
7
|
import { interval, Subject } from 'rxjs';
|
|
2
8
|
import { skipWhile } from 'rxjs/operators';
|
|
3
9
|
import { SwitchBotPlatform } from '../platform';
|
|
4
10
|
import { Service, PlatformAccessory, Units, CharacteristicValue } from 'homebridge';
|
|
5
|
-
import {
|
|
6
|
-
import { Context } from 'vm';
|
|
7
|
-
import { MqttClient } from 'mqtt';
|
|
8
|
-
import { connectAsync } from 'async-mqtt';
|
|
9
|
-
import { hostname } from 'os';
|
|
11
|
+
import { device, devicesConfig, serviceData, ad, switchbot, temperature, deviceStatus, HostDomain, DevicePath } from '../settings';
|
|
10
12
|
|
|
11
13
|
/**
|
|
12
14
|
* Platform Accessory
|
|
@@ -33,7 +35,7 @@ export class Meter {
|
|
|
33
35
|
// OpenAPI Others
|
|
34
36
|
Temperature: deviceStatus['temperature'];
|
|
35
37
|
Humidity: deviceStatus['humidity'];
|
|
36
|
-
deviceStatus!: deviceStatusResponse;
|
|
38
|
+
deviceStatus!: any; //deviceStatusResponse;
|
|
37
39
|
|
|
38
40
|
// BLE Others
|
|
39
41
|
connected?: boolean;
|
|
@@ -407,12 +409,49 @@ export class Meter {
|
|
|
407
409
|
if (this.platform.config.credentials?.token) {
|
|
408
410
|
this.debugLog(`Meter: ${this.accessory.displayName} OpenAPI RefreshStatus`);
|
|
409
411
|
try {
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
this.
|
|
412
|
+
const t = Date.now();
|
|
413
|
+
const nonce = 'requestID';
|
|
414
|
+
const data = this.platform.config.credentials?.token + t + nonce;
|
|
415
|
+
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
416
|
+
const sign = signTerm.toString('base64');
|
|
417
|
+
this.debugLog(`Meter: ${this.accessory.displayName} sign: ${sign}`);
|
|
418
|
+
const options = {
|
|
419
|
+
hostname: HostDomain,
|
|
420
|
+
port: 443,
|
|
421
|
+
path: `${DevicePath}/${this.device.deviceId}/status`,
|
|
422
|
+
method: 'GET',
|
|
423
|
+
headers: {
|
|
424
|
+
Authorization: this.platform.config.credentials?.token,
|
|
425
|
+
sign: sign,
|
|
426
|
+
nonce: nonce,
|
|
427
|
+
t: t,
|
|
428
|
+
'Content-Type': 'application/json',
|
|
429
|
+
},
|
|
430
|
+
};
|
|
431
|
+
const req = https.request(options, (res) => {
|
|
432
|
+
this.debugLog(`Meter: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
433
|
+
let rawData = '';
|
|
434
|
+
res.on('data', (d) => {
|
|
435
|
+
rawData += d;
|
|
436
|
+
this.debugLog(`Meter: ${this.accessory.displayName} d: ${d}`);
|
|
437
|
+
});
|
|
438
|
+
res.on('end', () => {
|
|
439
|
+
try {
|
|
440
|
+
this.deviceStatus = JSON.parse(rawData);
|
|
441
|
+
this.debugLog(`Meter: ${this.accessory.displayName} openAPIRefreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
442
|
+
this.Humidity = this.deviceStatus.body.humidity!;
|
|
443
|
+
this.Temperature = this.deviceStatus.body.temperature!;
|
|
444
|
+
this.parseStatus();
|
|
445
|
+
this.updateHomeKitCharacteristics();
|
|
446
|
+
} catch (e: any) {
|
|
447
|
+
this.errorLog(`Meter: ${this.accessory.displayName} error message: ${e.message}`);
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
});
|
|
451
|
+
req.on('error', (e: any) => {
|
|
452
|
+
this.errorLog(`Meter: ${this.accessory.displayName} error message: ${e.message}`);
|
|
453
|
+
});
|
|
454
|
+
req.end();
|
|
416
455
|
} catch (e: any) {
|
|
417
456
|
this.errorLog(`Meter: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
|
|
418
457
|
if (this.deviceLogging.includes('debug')) {
|
package/src/device/meterplus.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import https from 'https';
|
|
2
|
+
import crypto from 'crypto';
|
|
3
|
+
import { Context } from 'vm';
|
|
1
4
|
import { interval, Subject } from 'rxjs';
|
|
2
5
|
import { skipWhile } from 'rxjs/operators';
|
|
3
6
|
import { SwitchBotPlatform } from '../platform';
|
|
4
7
|
import { Service, PlatformAccessory, Units, CharacteristicValue } from 'homebridge';
|
|
5
|
-
import {
|
|
6
|
-
import { Context } from 'vm';
|
|
8
|
+
import { device, devicesConfig, serviceData, ad, switchbot, temperature, deviceStatus, HostDomain, DevicePath } from '../settings';
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* Platform Accessory
|
|
@@ -30,7 +32,7 @@ export class MeterPlus {
|
|
|
30
32
|
// OpenAPI Others
|
|
31
33
|
Temperature: deviceStatus['temperature'];
|
|
32
34
|
Humidity: deviceStatus['humidity'];
|
|
33
|
-
deviceStatus!: deviceStatusResponse;
|
|
35
|
+
deviceStatus!: any; //deviceStatusResponse;
|
|
34
36
|
|
|
35
37
|
// BLE Others
|
|
36
38
|
connected?: boolean;
|
|
@@ -344,12 +346,49 @@ export class MeterPlus {
|
|
|
344
346
|
if (this.platform.config.credentials?.token) {
|
|
345
347
|
this.debugLog(`Meter Plus: ${this.accessory.displayName} OpenAPI RefreshStatus`);
|
|
346
348
|
try {
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
this.
|
|
349
|
+
const t = Date.now();
|
|
350
|
+
const nonce = 'requestID';
|
|
351
|
+
const data = this.platform.config.credentials?.token + t + nonce;
|
|
352
|
+
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
353
|
+
const sign = signTerm.toString('base64');
|
|
354
|
+
this.debugLog(`Meter Plus: ${this.accessory.displayName} sign: ${sign}`);
|
|
355
|
+
const options = {
|
|
356
|
+
hostname: HostDomain,
|
|
357
|
+
port: 443,
|
|
358
|
+
path: `${DevicePath}/${this.device.deviceId}/status`,
|
|
359
|
+
method: 'GET',
|
|
360
|
+
headers: {
|
|
361
|
+
Authorization: this.platform.config.credentials?.token,
|
|
362
|
+
sign: sign,
|
|
363
|
+
nonce: nonce,
|
|
364
|
+
t: t,
|
|
365
|
+
'Content-Type': 'application/json',
|
|
366
|
+
},
|
|
367
|
+
};
|
|
368
|
+
const req = https.request(options, (res) => {
|
|
369
|
+
this.debugLog(`Meter Plus: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
370
|
+
let rawData = '';
|
|
371
|
+
res.on('data', (d) => {
|
|
372
|
+
rawData += d;
|
|
373
|
+
this.debugLog(`Meter Plus: ${this.accessory.displayName} d: ${d}`);
|
|
374
|
+
});
|
|
375
|
+
res.on('end', () => {
|
|
376
|
+
try {
|
|
377
|
+
this.deviceStatus = JSON.parse(rawData);
|
|
378
|
+
this.debugLog(`Meter Plus: ${this.accessory.displayName} openAPIRefreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
379
|
+
this.Humidity = this.deviceStatus.body.humidity!;
|
|
380
|
+
this.Temperature = this.deviceStatus.body.temperature!;
|
|
381
|
+
this.parseStatus();
|
|
382
|
+
this.updateHomeKitCharacteristics();
|
|
383
|
+
} catch (e: any) {
|
|
384
|
+
this.errorLog(`Meter Plus: ${this.accessory.displayName} error message: ${e.message}`);
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
});
|
|
388
|
+
req.on('error', (e: any) => {
|
|
389
|
+
this.errorLog(`Meter Plus: ${this.accessory.displayName} error message: ${e.message}`);
|
|
390
|
+
});
|
|
391
|
+
req.end();
|
|
353
392
|
} catch (e: any) {
|
|
354
393
|
this.errorLog(`Meter Plus: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
|
|
355
394
|
if (this.deviceLogging.includes('debug')) {
|
package/src/device/motion.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import https from 'https';
|
|
2
|
+
import crypto from 'crypto';
|
|
3
|
+
import { Context } from 'vm';
|
|
1
4
|
import { interval, Subject } from 'rxjs';
|
|
2
5
|
import { skipWhile } from 'rxjs/operators';
|
|
3
6
|
import { SwitchBotPlatform } from '../platform';
|
|
4
7
|
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
5
|
-
import {
|
|
6
|
-
import { Context } from 'vm';
|
|
8
|
+
import { device, devicesConfig, serviceData, switchbot, deviceStatus, ad, HostDomain, DevicePath } from '../settings';
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* Platform Accessory
|
|
@@ -23,7 +25,7 @@ export class Motion {
|
|
|
23
25
|
StatusLowBattery?: CharacteristicValue;
|
|
24
26
|
|
|
25
27
|
// OpenAPI Others
|
|
26
|
-
deviceStatus!: deviceStatusResponse;
|
|
28
|
+
deviceStatus!: any; //deviceStatusResponse;
|
|
27
29
|
moveDetected: deviceStatus['moveDetected'];
|
|
28
30
|
brightness: deviceStatus['brightness'];
|
|
29
31
|
|
|
@@ -326,15 +328,49 @@ export class Motion {
|
|
|
326
328
|
if (this.platform.config.credentials?.token) {
|
|
327
329
|
this.debugLog(`Motion Sensor: ${this.accessory.displayName} OpenAPI RefreshStatus`);
|
|
328
330
|
try {
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
this.
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
331
|
+
const t = Date.now();
|
|
332
|
+
const nonce = 'requestID';
|
|
333
|
+
const data = this.platform.config.credentials?.token + t + nonce;
|
|
334
|
+
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
335
|
+
const sign = signTerm.toString('base64');
|
|
336
|
+
this.debugLog(`Motion Sensor: ${this.accessory.displayName} sign: ${sign}`);
|
|
337
|
+
const options = {
|
|
338
|
+
hostname: HostDomain,
|
|
339
|
+
port: 443,
|
|
340
|
+
path: `${DevicePath}/${this.device.deviceId}/status`,
|
|
341
|
+
method: 'GET',
|
|
342
|
+
headers: {
|
|
343
|
+
Authorization: this.platform.config.credentials?.token,
|
|
344
|
+
sign: sign,
|
|
345
|
+
nonce: nonce,
|
|
346
|
+
t: t,
|
|
347
|
+
'Content-Type': 'application/json',
|
|
348
|
+
},
|
|
349
|
+
};
|
|
350
|
+
const req = https.request(options, (res) => {
|
|
351
|
+
this.debugLog(`Motion Sensor: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
352
|
+
let rawData = '';
|
|
353
|
+
res.on('data', (d) => {
|
|
354
|
+
rawData += d;
|
|
355
|
+
this.debugLog(`Motion Sensor: ${this.accessory.displayName} d: ${d}`);
|
|
356
|
+
});
|
|
357
|
+
res.on('end', () => {
|
|
358
|
+
try {
|
|
359
|
+
this.deviceStatus = JSON.parse(rawData);
|
|
360
|
+
this.debugLog(`Motion Sensor: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
361
|
+
this.moveDetected = this.deviceStatus.body.moveDetected;
|
|
362
|
+
this.brightness = this.deviceStatus.body.brightness;
|
|
363
|
+
this.parseStatus();
|
|
364
|
+
this.updateHomeKitCharacteristics();
|
|
365
|
+
} catch (e: any) {
|
|
366
|
+
this.errorLog(`Motion Sensor: ${this.accessory.displayName} error message: ${e.message}`);
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
req.on('error', (e: any) => {
|
|
371
|
+
this.errorLog(`Motion Sensor: ${this.accessory.displayName} error message: ${e.message}`);
|
|
372
|
+
});
|
|
373
|
+
req.end();
|
|
338
374
|
} catch (e: any) {
|
|
339
375
|
this.errorLog(`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
|
|
340
376
|
if (this.deviceLogging.includes('debug')) {
|