@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.
Files changed (112) hide show
  1. package/.prettierrc +1 -1
  2. package/dist/device/bot.d.ts +8 -7
  3. package/dist/device/bot.d.ts.map +1 -1
  4. package/dist/device/bot.js +83 -11
  5. package/dist/device/bot.js.map +1 -1
  6. package/dist/device/colorbulb.d.ts +8 -7
  7. package/dist/device/colorbulb.d.ts.map +1 -1
  8. package/dist/device/colorbulb.js +182 -23
  9. package/dist/device/colorbulb.js.map +1 -1
  10. package/dist/device/contact.d.ts +3 -3
  11. package/dist/device/contact.d.ts.map +1 -1
  12. package/dist/device/contact.js +50 -7
  13. package/dist/device/contact.js.map +1 -1
  14. package/dist/device/curtain.d.ts +9 -8
  15. package/dist/device/curtain.d.ts.map +1 -1
  16. package/dist/device/curtain.js +86 -14
  17. package/dist/device/curtain.js.map +1 -1
  18. package/dist/device/humidifier.d.ts +8 -7
  19. package/dist/device/humidifier.d.ts.map +1 -1
  20. package/dist/device/humidifier.js +152 -27
  21. package/dist/device/humidifier.js.map +1 -1
  22. package/dist/device/lock.d.ts +8 -7
  23. package/dist/device/lock.d.ts.map +1 -1
  24. package/dist/device/lock.js +84 -12
  25. package/dist/device/lock.js.map +1 -1
  26. package/dist/device/meter.d.ts +4 -4
  27. package/dist/device/meter.d.ts.map +1 -1
  28. package/dist/device/meter.js +51 -8
  29. package/dist/device/meter.js.map +1 -1
  30. package/dist/device/meterplus.d.ts +3 -3
  31. package/dist/device/meterplus.d.ts.map +1 -1
  32. package/dist/device/meterplus.js +49 -6
  33. package/dist/device/meterplus.js.map +1 -1
  34. package/dist/device/motion.d.ts +3 -3
  35. package/dist/device/motion.d.ts.map +1 -1
  36. package/dist/device/motion.js +49 -9
  37. package/dist/device/motion.js.map +1 -1
  38. package/dist/device/plug.d.ts +8 -7
  39. package/dist/device/plug.d.ts.map +1 -1
  40. package/dist/device/plug.js +83 -11
  41. package/dist/device/plug.js.map +1 -1
  42. package/dist/device/striplight.d.ts +8 -7
  43. package/dist/device/striplight.d.ts.map +1 -1
  44. package/dist/device/striplight.js +149 -19
  45. package/dist/device/striplight.js.map +1 -1
  46. package/dist/irdevice/airconditioner.d.ts +5 -4
  47. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  48. package/dist/irdevice/airconditioner.js +40 -6
  49. package/dist/irdevice/airconditioner.js.map +1 -1
  50. package/dist/irdevice/airpurifier.d.ts +5 -4
  51. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  52. package/dist/irdevice/airpurifier.js +40 -6
  53. package/dist/irdevice/airpurifier.js.map +1 -1
  54. package/dist/irdevice/camera.d.ts +5 -4
  55. package/dist/irdevice/camera.d.ts.map +1 -1
  56. package/dist/irdevice/camera.js +40 -6
  57. package/dist/irdevice/camera.js.map +1 -1
  58. package/dist/irdevice/fan.d.ts +7 -6
  59. package/dist/irdevice/fan.d.ts.map +1 -1
  60. package/dist/irdevice/fan.js +40 -6
  61. package/dist/irdevice/fan.js.map +1 -1
  62. package/dist/irdevice/light.d.ts +5 -4
  63. package/dist/irdevice/light.d.ts.map +1 -1
  64. package/dist/irdevice/light.js +40 -6
  65. package/dist/irdevice/light.js.map +1 -1
  66. package/dist/irdevice/other.d.ts +5 -4
  67. package/dist/irdevice/other.d.ts.map +1 -1
  68. package/dist/irdevice/other.js +40 -6
  69. package/dist/irdevice/other.js.map +1 -1
  70. package/dist/irdevice/tv.d.ts +7 -6
  71. package/dist/irdevice/tv.d.ts.map +1 -1
  72. package/dist/irdevice/tv.js +40 -6
  73. package/dist/irdevice/tv.js.map +1 -1
  74. package/dist/irdevice/vacuumcleaner.d.ts +5 -4
  75. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  76. package/dist/irdevice/vacuumcleaner.js +40 -6
  77. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  78. package/dist/irdevice/waterheater.d.ts +5 -4
  79. package/dist/irdevice/waterheater.d.ts.map +1 -1
  80. package/dist/irdevice/waterheater.js +40 -6
  81. package/dist/irdevice/waterheater.js.map +1 -1
  82. package/dist/platform.d.ts +3 -5
  83. package/dist/platform.d.ts.map +1 -1
  84. package/dist/platform.js +142 -92
  85. package/dist/platform.js.map +1 -1
  86. package/dist/settings.d.ts +2 -16
  87. package/dist/settings.d.ts.map +1 -1
  88. package/dist/settings.js +3 -3
  89. package/dist/settings.js.map +1 -1
  90. package/package.json +6 -7
  91. package/src/device/bot.ts +87 -15
  92. package/src/device/colorbulb.ts +186 -41
  93. package/src/device/contact.ts +49 -10
  94. package/src/device/curtain.ts +92 -19
  95. package/src/device/humidifier.ts +164 -30
  96. package/src/device/lock.ts +88 -16
  97. package/src/device/meter.ts +51 -12
  98. package/src/device/meterplus.ts +48 -9
  99. package/src/device/motion.ts +48 -12
  100. package/src/device/plug.ts +87 -15
  101. package/src/device/striplight.ts +161 -24
  102. package/src/irdevice/airconditioner.ts +43 -8
  103. package/src/irdevice/airpurifier.ts +43 -8
  104. package/src/irdevice/camera.ts +43 -8
  105. package/src/irdevice/fan.ts +44 -9
  106. package/src/irdevice/light.ts +43 -8
  107. package/src/irdevice/other.ts +43 -8
  108. package/src/irdevice/tv.ts +44 -9
  109. package/src/irdevice/vacuumcleaner.ts +43 -8
  110. package/src/irdevice/waterheater.ts +43 -8
  111. package/src/platform.ts +155 -105
  112. package/src/settings.ts +6 -10
@@ -1,10 +1,12 @@
1
- import { AxiosResponse } from 'axios';
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 { DeviceURL, device, devicesConfig, serviceData, ad, deviceStatusResponse, payload, deviceStatus } from '../settings';
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
- this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
392
- if (this.deviceStatus.message === 'success') {
393
- this.debugLog(`Humidifier: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
394
- this.auto = this.deviceStatus.body.auto;
395
- this.power = this.deviceStatus.body.power;
396
- this.lackWater = this.deviceStatus.body.lackWater;
397
- this.humidity = this.deviceStatus.body.humidity;
398
- this.temperature = this.deviceStatus.body.temperature;
399
- this.nebulizationEfficiency = this.deviceStatus.body.nebulizationEfficiency;
400
- this.parseStatus();
401
- this.updateHomeKitCharacteristics();
402
- } else {
403
- this.errorLog(`Humidifier: ${this.accessory.displayName} message: ${JSON.stringify(this.deviceStatus.message)}`);
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 push: any = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
497
- this.debugLog(`Humidifier: ${this.accessory.displayName} pushChanges: ${JSON.stringify(push.data)}`);
498
- this.statusCode(push);
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 push: any = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
543
- this.debugLog(`Humidifier: ${this.accessory.displayName} pushAutoChanges: ${JSON.stringify(push.data)}`);
544
- this.statusCode(push);
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 push: any = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
578
- this.debugLog(`Humidifier: ${this.accessory.displayName} pushActiveChanges: ${JSON.stringify(push.data)}`);
579
- this.statusCode(push);
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(push: AxiosResponse<{ statusCode: number }>): Promise<void> {
681
- switch (push.data.statusCode) {
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(push.data)} format is invalid`,
836
+ ` Or command: ${JSON.stringify(res)} format is invalid`,
703
837
  );
704
838
  break;
705
839
  case 100:
@@ -1,10 +1,12 @@
1
- import { AxiosResponse } from 'axios';
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 { DeviceURL, device, devicesConfig, deviceStatusResponse, payload, deviceStatus } from '../settings';
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
- this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
155
- this.debugLog(`Lock: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
156
- this.lockState = this.deviceStatus.body.lockState;
157
- this.doorState = this.deviceStatus.body.doorState;
158
- this.parseStatus();
159
- this.updateHomeKitCharacteristics();
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 push: any = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
196
- this.debugLog(`Lock: ${this.accessory.displayName} pushchanges: ${JSON.stringify(push.data)}`);
197
- this.statusCode(push);
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(push: AxiosResponse<{ statusCode: number }>): Promise<void> {
239
- switch (push.data.statusCode) {
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(push.data)} format is invalid`,
330
+ ` Or command: ${JSON.stringify(res)} format is invalid`,
259
331
  );
260
332
  break;
261
333
  case 100:
@@ -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 { DeviceURL, device, devicesConfig, serviceData, ad, switchbot, deviceStatusResponse, temperature, deviceStatus } from '../settings';
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
- this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
411
- this.debugLog(`Meter: ${this.accessory.displayName} openAPIRefreshStatus: ${JSON.stringify(this.deviceStatus)}`);
412
- this.Humidity = this.deviceStatus.body.humidity!;
413
- this.Temperature = this.deviceStatus.body.temperature!;
414
- this.parseStatus();
415
- this.updateHomeKitCharacteristics();
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')) {
@@ -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 { DeviceURL, device, devicesConfig, serviceData, ad, switchbot, deviceStatusResponse, temperature, deviceStatus } from '../settings';
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
- this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
348
- this.debugLog(`Meter Plus: ${this.accessory.displayName} openAPIRefreshStatus: ${JSON.stringify(this.deviceStatus)}`);
349
- this.Humidity = this.deviceStatus.body.humidity!;
350
- this.Temperature = this.deviceStatus.body.temperature!;
351
- this.parseStatus();
352
- this.updateHomeKitCharacteristics();
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')) {
@@ -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 { DeviceURL, device, devicesConfig, serviceData, switchbot, deviceStatusResponse, deviceStatus, ad } from '../settings';
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
- this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
330
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
331
- if (this.deviceStatus.body.moveDetected === undefined) {
332
- this.errorLog(`Motion Sensor: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
333
- }
334
- this.moveDetected = this.deviceStatus.body.moveDetected;
335
- this.brightness = this.deviceStatus.body.brightness;
336
- this.parseStatus();
337
- this.updateHomeKitCharacteristics();
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')) {