@switchbot/homebridge-switchbot 1.15.1-beta.7 → 1.15.1-beta.9

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 +97 -21
  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 +221 -56
  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 +95 -21
  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 +180 -59
  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 +98 -22
  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 +96 -20
  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 +186 -47
  45. package/dist/device/striplight.js.map +1 -1
  46. package/dist/irdevice/airconditioner.d.ts +7 -6
  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 +7 -6
  51. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  52. package/dist/irdevice/airpurifier.js +46 -11
  53. package/dist/irdevice/airpurifier.js.map +1 -1
  54. package/dist/irdevice/camera.d.ts +7 -6
  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 +8 -7
  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 +7 -6
  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 +7 -6
  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 +8 -7
  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 +7 -6
  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 +7 -6
  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 +141 -95
  85. package/dist/platform.js.map +1 -1
  86. package/dist/settings.d.ts +2 -21
  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 +97 -30
  92. package/src/device/colorbulb.ts +225 -93
  93. package/src/device/contact.ts +49 -10
  94. package/src/device/curtain.ts +98 -31
  95. package/src/device/humidifier.ts +182 -77
  96. package/src/device/lock.ts +97 -30
  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 +97 -29
  101. package/src/device/striplight.ts +189 -68
  102. package/src/irdevice/airconditioner.ts +44 -9
  103. package/src/irdevice/airpurifier.ts +52 -17
  104. package/src/irdevice/camera.ts +46 -11
  105. package/src/irdevice/fan.ts +50 -15
  106. package/src/irdevice/light.ts +48 -13
  107. package/src/irdevice/other.ts +46 -11
  108. package/src/irdevice/tv.ts +56 -21
  109. package/src/irdevice/vacuumcleaner.ts +46 -11
  110. package/src/irdevice/waterheater.ts +46 -11
  111. package/src/platform.ts +154 -108
  112. package/src/settings.ts +2 -25
@@ -1,12 +1,14 @@
1
- import { AxiosResponse } from 'axios';
1
+ import https from 'https';
2
+ import crypto from 'crypto';
3
+ import { Context } from 'vm';
4
+ import { MqttClient } from 'mqtt';
5
+ import { IncomingMessage } from 'http';
2
6
  import { interval, Subject } from 'rxjs';
7
+ import { connectAsync } from 'async-mqtt';
3
8
  import { SwitchBotPlatform } from '../platform';
4
9
  import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
5
10
  import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
6
- import { DeviceURL, device, devicesConfig, serviceData, switchbot, deviceStatusResponse, payload, deviceStatus, ad } from '../settings';
7
- import { Context } from 'vm';
8
- import { MqttClient } from 'mqtt';
9
- import { connectAsync } from 'async-mqtt';
11
+ import { device, devicesConfig, serviceData, switchbot, deviceStatus, ad, HostDomain, DevicePath } from '../settings';
10
12
 
11
13
  export class Curtain {
12
14
  // Services
@@ -23,7 +25,7 @@ export class Curtain {
23
25
  StatusLowBattery?: CharacteristicValue;
24
26
 
25
27
  // OpenAPI Others
26
- deviceStatus!: deviceStatusResponse;
28
+ deviceStatus!: any; //deviceStatusResponse;
27
29
  slidePosition: deviceStatus['slidePosition'];
28
30
  moving: deviceStatus['moving'];
29
31
  brightness: deviceStatus['brightness'];
@@ -532,13 +534,51 @@ export class Curtain {
532
534
  if (this.platform.config.credentials?.token) {
533
535
  this.debugLog(`Curtain: ${this.accessory.displayName} OpenAPI refreshStatus`);
534
536
  try {
535
- this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
536
- this.debugLog(`Curtain: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
537
- this.slidePosition = this.deviceStatus.body.slidePosition;
538
- this.moving = this.deviceStatus.body.moving;
539
- this.brightness = this.deviceStatus.body.brightness;
540
- this.parseStatus();
541
- this.updateHomeKitCharacteristics();
537
+ const t = Date.now();
538
+ const nonce = 'requestID';
539
+ const data = this.platform.config.credentials?.token + t + nonce;
540
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
541
+ const sign = signTerm.toString('base64');
542
+ this.debugLog(`Curtain: ${this.accessory.displayName} sign: ${sign}`);
543
+ const options = {
544
+ hostname: HostDomain,
545
+ port: 443,
546
+ path: `${DevicePath}/${this.device.deviceId}/status`,
547
+ method: 'GET',
548
+ headers: {
549
+ Authorization: this.platform.config.credentials?.token,
550
+ sign: sign,
551
+ nonce: nonce,
552
+ t: t,
553
+ 'Content-Type': 'application/json',
554
+ },
555
+ };
556
+ const req = https.request(options, (res) => {
557
+ this.debugLog(`Curtain: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
558
+ let rawData = '';
559
+ res.on('data', (d) => {
560
+ rawData += d;
561
+ this.debugLog(`Curtain: ${this.accessory.displayName} d: ${d}`);
562
+ });
563
+
564
+ res.on('end', () => {
565
+ try {
566
+ this.deviceStatus = JSON.parse(rawData);
567
+ this.debugLog(`Curtain: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
568
+ this.slidePosition = this.deviceStatus.body.slidePosition;
569
+ this.moving = this.deviceStatus.body.moving;
570
+ this.brightness = this.deviceStatus.body.brightness;
571
+ this.parseStatus();
572
+ this.updateHomeKitCharacteristics();
573
+ } catch (e: any) {
574
+ this.errorLog(`Curtain: ${this.accessory.displayName} error message: ${e.message}`);
575
+ }
576
+ });
577
+ });
578
+ req.on('error', (e: any) => {
579
+ this.errorLog(`Curtain: ${this.accessory.displayName} error message: ${e.message}`);
580
+ });
581
+ req.end();
542
582
  } catch (e: any) {
543
583
  this.errorLog(`Curtain: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
544
584
  if (this.deviceLogging.includes('debug')) {
@@ -639,6 +679,15 @@ export class Curtain {
639
679
  try {
640
680
  this.debugLog(`Curtain: ${this.accessory.displayName} OpenAPI pushChanges`);
641
681
  if (this.TargetPosition !== this.CurrentPosition) {
682
+ // Make Push On request to the API
683
+ const t = Date.now();
684
+ const nonce = 'requestID';
685
+ const data = this.platform.config.credentials?.token + t + nonce;
686
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
687
+ .update(Buffer.from(data, 'utf-8'))
688
+ .digest();
689
+ const sign = signTerm.toString('base64');
690
+ this.debugLog(`Curtain: ${this.accessory.displayName} sign: ${sign}`);
642
691
  this.debugLog(`Pushing ${this.TargetPosition}`);
643
692
  const adjustedTargetPosition = 100 - Number(this.TargetPosition);
644
693
  if (this.TargetPosition > 50) {
@@ -655,21 +704,39 @@ export class Curtain {
655
704
  }
656
705
  this.debugLog(`${this.accessory.displayName} Mode: ${this.Mode}`);
657
706
  const adjustedMode = this.setPositionMode || 'ff';
658
- const payload = {
659
- commandType: 'command',
660
- command: 'setPosition',
661
- parameter: `0,${adjustedMode},${adjustedTargetPosition}`,
662
- } as payload;
663
-
664
- this.infoLog(
665
- `Curtain: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},` +
666
- ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`,
667
- );
668
-
669
- // Make the API request
670
- const push: any = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId!}/commands`, payload);
671
- this.debugLog(`Curtain: ${this.accessory.displayName} pushchanges: ${JSON.stringify(push.data)}`);
672
- this.statusCode(push);
707
+ const body = JSON.stringify({
708
+ 'command': 'setPosition',
709
+ 'parameter': `0,${adjustedMode},${adjustedTargetPosition}`,
710
+ 'commandType': 'command',
711
+ });
712
+ this.infoLog(`Curtain: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
713
+ const options = {
714
+ hostname: HostDomain,
715
+ port: 443,
716
+ path: `${DevicePath}/${this.device.deviceId}/commands`,
717
+ method: 'POST',
718
+ headers: {
719
+ 'Authorization': this.platform.config.credentials?.token,
720
+ 'sign': sign,
721
+ 'nonce': nonce,
722
+ 't': t,
723
+ 'Content-Type': 'application/json',
724
+ 'Content-Length': body.length,
725
+ },
726
+ };
727
+ const req = https.request(options, res => {
728
+ this.debugLog(`Curtain: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
729
+ this.statusCode({ res });
730
+ res.on('data', d => {
731
+ this.debugLog(`Curtain: ${this.accessory.displayName} d: ${d}`);
732
+ });
733
+ });
734
+ req.on('error', (e: any) => {
735
+ this.errorLog(`Curtain: ${this.accessory.displayName} error message: ${e.message}`);
736
+ });
737
+ req.write(body);
738
+ req.end();
739
+ this.debugLog(`Curtain: ${this.accessory.displayName} openAPIpushChanges: ${JSON.stringify(req)}`);
673
740
  } else {
674
741
  this.debugLog(
675
742
  `Curtain: ${this.accessory.displayName} No OpenAPI Changes, CurrentPosition & TargetPosition Are the Same.` +
@@ -752,8 +819,8 @@ export class Curtain {
752
819
  //throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
753
820
  }
754
821
 
755
- async statusCode(push: AxiosResponse<{ statusCode: number }>): Promise<void> {
756
- switch (push.data.statusCode) {
822
+ async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
823
+ switch (res.statusCode) {
757
824
  case 151:
758
825
  this.errorLog(`Curtain: ${this.accessory.displayName} Command not supported by this device type.`);
759
826
  break;
@@ -772,7 +839,7 @@ export class Curtain {
772
839
  case 190:
773
840
  this.errorLog(
774
841
  `Curtain: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
775
- ` Or command: ${JSON.stringify(push.data)} format is invalid`,
842
+ ` Or command: ${JSON.stringify(res)} format is invalid`,
776
843
  );
777
844
  break;
778
845
  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, serviceData, ad, deviceStatusResponse, payload, deviceStatus } from '../settings';
7
- import { Context } from 'vm';
9
+ import { device, devicesConfig, serviceData, ad, 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')) {
@@ -479,33 +514,49 @@ export class Humidifier {
479
514
  this.TargetHumidifierDehumidifierState === this.platform.Characteristic.TargetHumidifierDehumidifierState.HUMIDIFIER &&
480
515
  this.Active === this.platform.Characteristic.Active.ACTIVE
481
516
  ) {
482
- try {
483
- this.debugLog(`Pushing Manual: ${this.RelativeHumidityHumidifierThreshold}!`);
484
- const payload = {
485
- commandType: 'command',
486
- command: 'setMode',
487
- parameter: `${this.RelativeHumidityHumidifierThreshold}`,
488
- } as payload;
489
-
490
- this.infoLog(
491
- `Humidifier: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},` +
492
- ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`,
493
- );
494
-
495
- // 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);
499
- } catch (e: any) {
500
- this.errorLog(`Humidifier: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
501
- if (this.deviceLogging.includes('debug')) {
502
- this.errorLog(
503
- `Humidifier: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` +
504
- ` Error Message: ${JSON.stringify(e.message)}`,
505
- );
506
- }
517
+ // Make Push On request to the API
518
+ const t = Date.now();
519
+ const nonce = 'requestID';
520
+ const data = this.platform.config.credentials?.token + t + nonce;
521
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
522
+ .update(Buffer.from(data, 'utf-8'))
523
+ .digest();
524
+ const sign = signTerm.toString('base64');
525
+ this.debugLog(`Humidifier: ${this.accessory.displayName} sign: ${sign}`);
526
+ this.debugLog(`Pushing Manual: ${this.RelativeHumidityHumidifierThreshold}!`);
527
+ const body = JSON.stringify({
528
+ 'command': 'setMode',
529
+ 'parameter': `${this.RelativeHumidityHumidifierThreshold}`,
530
+ 'commandType': 'command',
531
+ });
532
+ this.infoLog(`Humidifier: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
533
+ const options = {
534
+ hostname: HostDomain,
535
+ port: 443,
536
+ path: `${DevicePath}/${this.device.deviceId}/commands`,
537
+ method: 'POST',
538
+ headers: {
539
+ 'Authorization': this.platform.config.credentials?.token,
540
+ 'sign': sign,
541
+ 'nonce': nonce,
542
+ 't': t,
543
+ 'Content-Type': 'application/json',
544
+ 'Content-Length': body.length,
545
+ },
546
+ };
547
+ const req = https.request(options, res => {
548
+ this.debugLog(`Humidifier: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
549
+ res.on('data', d => {
550
+ this.debugLog(`Humidifier: ${this.accessory.displayName} d: ${d}`);
551
+ });
552
+ });
553
+ req.on('error', (e: any) => {
554
+ this.errorLog(`Humidifier: ${this.accessory.displayName} error message: ${e.message}`);
507
555
  this.apiError(e);
508
- }
556
+ });
557
+ req.write(body);
558
+ req.end();
559
+ this.debugLog(`Humidifier: ${this.accessory.displayName} openAPIpushChanges: ${JSON.stringify(req)}`);
509
560
  } else if (
510
561
  this.TargetHumidifierDehumidifierState === this.platform.Characteristic.TargetHumidifierDehumidifierState.HUMIDIFIER_OR_DEHUMIDIFIER &&
511
562
  this.Active === this.platform.Characteristic.Active.ACTIVE
@@ -526,22 +577,49 @@ export class Humidifier {
526
577
  this.TargetHumidifierDehumidifierState === this.platform.Characteristic.TargetHumidifierDehumidifierState.HUMIDIFIER_OR_DEHUMIDIFIER &&
527
578
  this.Active === this.platform.Characteristic.Active.ACTIVE
528
579
  ) {
580
+ // Make Push On request to the API
581
+ const t = Date.now();
582
+ const nonce = 'requestID';
583
+ const data = this.platform.config.credentials?.token + t + nonce;
584
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
585
+ .update(Buffer.from(data, 'utf-8'))
586
+ .digest();
587
+ const sign = signTerm.toString('base64');
588
+ this.debugLog(`Humidifier: ${this.accessory.displayName} sign: ${sign}`);
529
589
  this.debugLog('Pushing Auto!');
530
- const payload = {
531
- commandType: 'command',
532
- command: 'setMode',
533
- parameter: 'auto',
534
- } as payload;
535
-
536
- this.infoLog(
537
- `Humidifier: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},` +
538
- ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`,
539
- );
540
-
541
- // 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);
590
+ const body = JSON.stringify({
591
+ 'command': 'setMode',
592
+ 'parameter': 'auto',
593
+ 'commandType': 'command',
594
+ });
595
+ this.infoLog(`Humidifier: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
596
+ const options = {
597
+ hostname: HostDomain,
598
+ port: 443,
599
+ path: `${DevicePath}/${this.device.deviceId}/commands`,
600
+ method: 'POST',
601
+ headers: {
602
+ 'Authorization': this.platform.config.credentials?.token,
603
+ 'sign': sign,
604
+ 'nonce': nonce,
605
+ 't': t,
606
+ 'Content-Type': 'application/json',
607
+ 'Content-Length': body.length,
608
+ },
609
+ };
610
+ const req = https.request(options, res => {
611
+ this.debugLog(`Humidifier: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
612
+ this.statusCode({ res });
613
+ res.on('data', d => {
614
+ this.debugLog(`Humidifier: ${this.accessory.displayName} d: ${d}`);
615
+ });
616
+ });
617
+ req.on('error', (e: any) => {
618
+ this.errorLog(`Humidifier: ${this.accessory.displayName} error message: ${e.message}`);
619
+ });
620
+ req.write(body);
621
+ req.end();
622
+ this.debugLog(`Humidifier: ${this.accessory.displayName} pushAutoChanges: ${JSON.stringify(req)}`);
545
623
  }
546
624
  } catch (e: any) {
547
625
  this.errorLog(`Humidifier: ${this.accessory.displayName} failed pushAutoChanges with OpenAPI Connection`);
@@ -561,22 +639,49 @@ export class Humidifier {
561
639
  async pushActiveChanges(): Promise<void> {
562
640
  try {
563
641
  if (this.Active === this.platform.Characteristic.Active.INACTIVE) {
642
+ // Make Push On request to the API
643
+ const t = Date.now();
644
+ const nonce = 'requestID';
645
+ const data = this.platform.config.credentials?.token + t + nonce;
646
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
647
+ .update(Buffer.from(data, 'utf-8'))
648
+ .digest();
649
+ const sign = signTerm.toString('base64');
650
+ this.debugLog(`Humidifier: ${this.accessory.displayName} sign: ${sign}`);
564
651
  this.debugLog('Pushing Off!');
565
- const payload = {
566
- commandType: 'command',
567
- command: 'turnOff',
568
- parameter: 'default',
569
- } as payload;
570
-
571
- this.infoLog(
572
- `Humidifier: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},` +
573
- ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`,
574
- );
575
-
576
- // 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);
652
+ const body = JSON.stringify({
653
+ 'command': 'turnOff',
654
+ 'parameter': 'default',
655
+ 'commandType': 'command',
656
+ });
657
+ this.infoLog(`Humidifier: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
658
+ const options = {
659
+ hostname: HostDomain,
660
+ port: 443,
661
+ path: `${DevicePath}/${this.device.deviceId}/commands`,
662
+ method: 'POST',
663
+ headers: {
664
+ 'Authorization': this.platform.config.credentials?.token,
665
+ 'sign': sign,
666
+ 'nonce': nonce,
667
+ 't': t,
668
+ 'Content-Type': 'application/json',
669
+ 'Content-Length': body.length,
670
+ },
671
+ };
672
+ const req = https.request(options, res => {
673
+ this.debugLog(`Humidifier: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
674
+ this.statusCode({ res });
675
+ res.on('data', d => {
676
+ this.debugLog(`Humidifier: ${this.accessory.displayName} d: ${d}`);
677
+ });
678
+ });
679
+ req.on('error', (e: any) => {
680
+ this.errorLog(`Humidifier: ${this.accessory.displayName} error message: ${e.message}`);
681
+ });
682
+ req.write(body);
683
+ req.end();
684
+ this.debugLog(`Humidifier: ${this.accessory.displayName} pushActiveChanges: ${JSON.stringify(req)}`);
580
685
  }
581
686
  } catch (e: any) {
582
687
  this.errorLog(`Humidifier: ${this.accessory.displayName} failed pushActiveChanges with OpenAPI Connection`);
@@ -677,8 +782,8 @@ export class Humidifier {
677
782
  //throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
678
783
  }
679
784
 
680
- async statusCode(push: AxiosResponse<{ statusCode: number }>): Promise<void> {
681
- switch (push.data.statusCode) {
785
+ async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
786
+ switch (res.statusCode) {
682
787
  case 151:
683
788
  this.errorLog(`Humidifier: ${this.accessory.displayName} Command not supported by this device type.`);
684
789
  break;
@@ -699,7 +804,7 @@ export class Humidifier {
699
804
  case 190:
700
805
  this.errorLog(
701
806
  `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`,
807
+ ` Or command: ${JSON.stringify(res)} format is invalid`,
703
808
  );
704
809
  break;
705
810
  case 100: