@switchbot/homebridge-switchbot 1.15.1-beta.8 → 2.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/.github/Old Releaser.zip +0 -0
  2. package/.github/npm-version-script.js +81 -0
  3. package/.github/workflows/beta-release.yml +31 -0
  4. package/.github/workflows/build.yml +18 -0
  5. package/.github/workflows/codeql-analysis.yml +5 -63
  6. package/.github/workflows/label.yml +2 -2
  7. package/.github/workflows/release-drafter.yml +14 -0
  8. package/.github/workflows/release.yml +24 -0
  9. package/.github/workflows/stale.yml +6 -22
  10. package/README.md +10 -3
  11. package/dist/device/bot.d.ts.map +1 -1
  12. package/dist/device/bot.js +33 -29
  13. package/dist/device/bot.js.map +1 -1
  14. package/dist/device/colorbulb.d.ts +1 -0
  15. package/dist/device/colorbulb.d.ts.map +1 -1
  16. package/dist/device/colorbulb.js +129 -97
  17. package/dist/device/colorbulb.js.map +1 -1
  18. package/dist/device/contact.js +1 -1
  19. package/dist/device/contact.js.map +1 -1
  20. package/dist/device/curtain.d.ts.map +1 -1
  21. package/dist/device/curtain.js +34 -26
  22. package/dist/device/curtain.js.map +1 -1
  23. package/dist/device/humidifier.d.ts.map +1 -1
  24. package/dist/device/humidifier.js +88 -92
  25. package/dist/device/humidifier.js.map +1 -1
  26. package/dist/device/lock.d.ts.map +1 -1
  27. package/dist/device/lock.js +29 -25
  28. package/dist/device/lock.js.map +1 -1
  29. package/dist/device/meter.js +1 -1
  30. package/dist/device/meter.js.map +1 -1
  31. package/dist/device/meterplus.js +1 -1
  32. package/dist/device/meterplus.js.map +1 -1
  33. package/dist/device/motion.js +1 -1
  34. package/dist/device/motion.js.map +1 -1
  35. package/dist/device/plug.d.ts.map +1 -1
  36. package/dist/device/plug.js +31 -27
  37. package/dist/device/plug.js.map +1 -1
  38. package/dist/device/striplight.d.ts.map +1 -1
  39. package/dist/device/striplight.js +81 -72
  40. package/dist/device/striplight.js.map +1 -1
  41. package/dist/irdevice/airconditioner.d.ts +2 -2
  42. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  43. package/dist/irdevice/airconditioner.js +35 -32
  44. package/dist/irdevice/airconditioner.js.map +1 -1
  45. package/dist/irdevice/airpurifier.d.ts +2 -2
  46. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  47. package/dist/irdevice/airpurifier.js +35 -32
  48. package/dist/irdevice/airpurifier.js.map +1 -1
  49. package/dist/irdevice/camera.d.ts +2 -2
  50. package/dist/irdevice/camera.d.ts.map +1 -1
  51. package/dist/irdevice/camera.js +28 -26
  52. package/dist/irdevice/camera.js.map +1 -1
  53. package/dist/irdevice/fan.d.ts +2 -2
  54. package/dist/irdevice/fan.d.ts.map +1 -1
  55. package/dist/irdevice/fan.js +47 -45
  56. package/dist/irdevice/fan.js.map +1 -1
  57. package/dist/irdevice/light.d.ts +2 -2
  58. package/dist/irdevice/light.d.ts.map +1 -1
  59. package/dist/irdevice/light.js +40 -38
  60. package/dist/irdevice/light.js.map +1 -1
  61. package/dist/irdevice/other.d.ts +2 -2
  62. package/dist/irdevice/other.d.ts.map +1 -1
  63. package/dist/irdevice/other.js +28 -26
  64. package/dist/irdevice/other.js.map +1 -1
  65. package/dist/irdevice/tv.d.ts +2 -2
  66. package/dist/irdevice/tv.d.ts.map +1 -1
  67. package/dist/irdevice/tv.js +82 -80
  68. package/dist/irdevice/tv.js.map +1 -1
  69. package/dist/irdevice/vacuumcleaner.d.ts +2 -2
  70. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  71. package/dist/irdevice/vacuumcleaner.js +24 -22
  72. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  73. package/dist/irdevice/waterheater.d.ts +2 -2
  74. package/dist/irdevice/waterheater.d.ts.map +1 -1
  75. package/dist/irdevice/waterheater.js +28 -26
  76. package/dist/irdevice/waterheater.js.map +1 -1
  77. package/dist/settings.d.ts +0 -5
  78. package/dist/settings.d.ts.map +1 -1
  79. package/dist/settings.js.map +1 -1
  80. package/package.json +79 -79
  81. package/src/device/bot.ts +34 -39
  82. package/src/device/colorbulb.ts +130 -119
  83. package/src/device/contact.ts +1 -1
  84. package/src/device/curtain.ts +35 -35
  85. package/src/device/humidifier.ts +89 -118
  86. package/src/device/lock.ts +29 -34
  87. package/src/device/meter.ts +1 -1
  88. package/src/device/meterplus.ts +1 -1
  89. package/src/device/motion.ts +1 -1
  90. package/src/device/plug.ts +32 -36
  91. package/src/device/striplight.ts +82 -98
  92. package/src/irdevice/airconditioner.ts +36 -41
  93. package/src/irdevice/airpurifier.ts +36 -43
  94. package/src/irdevice/camera.ts +29 -34
  95. package/src/irdevice/fan.ts +48 -53
  96. package/src/irdevice/light.ts +41 -46
  97. package/src/irdevice/other.ts +29 -34
  98. package/src/irdevice/tv.ts +83 -88
  99. package/src/irdevice/vacuumcleaner.ts +25 -30
  100. package/src/irdevice/waterheater.ts +29 -34
  101. package/src/settings.ts +0 -19
  102. package/.github/workflows/nodejs-beta.yml +0 -42
  103. package/.github/workflows/nodejs.yml +0 -47
  104. package/.github/workflows/prerelease-beta.js +0 -34
@@ -6,7 +6,7 @@ import { interval, Subject } from 'rxjs';
6
6
  import { SwitchBotPlatform } from '../platform';
7
7
  import { debounceTime, skipWhile, tap } from 'rxjs/operators';
8
8
  import { Service, PlatformAccessory, CharacteristicValue, ControllerConstructor, Controller, ControllerServiceMap } from 'homebridge';
9
- import { device, devicesConfig, deviceStatus, switchbot, payload, hs2rgb, rgb2hs, m2hs, serviceData, ad, HostDomain, DevicePath } from '../settings';
9
+ import { device, devicesConfig, deviceStatus, switchbot, hs2rgb, rgb2hs, m2hs, serviceData, ad, HostDomain, DevicePath } from '../settings';
10
10
 
11
11
  /**
12
12
  * Platform Accessory
@@ -34,7 +34,7 @@ export class ColorBulb {
34
34
  color: deviceStatus['color'];
35
35
  brightness: deviceStatus['brightness'];
36
36
  colorTemperature?: deviceStatus['colorTemperature'];
37
- deviceStatus!: any; //deviceStatusResponse;
37
+ deviceStatus!: any;
38
38
 
39
39
  // BLE Others
40
40
  connected?: boolean;
@@ -68,6 +68,7 @@ export class ColorBulb {
68
68
  constructor(private readonly platform: SwitchBotPlatform, private accessory: PlatformAccessory, public device: device & devicesConfig) {
69
69
  // default placeholders
70
70
  this.logs(device);
71
+ this.scan(device);
71
72
  this.refreshRate(device);
72
73
  this.adaptiveLighting(device);
73
74
  this.config(device);
@@ -316,7 +317,10 @@ export class ColorBulb {
316
317
  })
317
318
  .then(() => {
318
319
  // Set an event hander
320
+ this.errorLog(`Color Bulb: ${this.accessory.displayName} then switchbot: ${JSON.stringify(switchbot)}`);
319
321
  switchbot.onadvertisement = (ad: any) => {
322
+ this.errorLog(`Color Bulb: ${this.accessory.displayName} switchbot: ${JSON.stringify(switchbot.onadvertisement)}`);
323
+ this.errorLog(`Color Bulb: ${this.accessory.displayName} ad: ${JSON.stringify(ad)}`);
320
324
  this.address = ad.address;
321
325
  if (this.deviceLogging.includes('debug')) {
322
326
  this.infoLog(this.address);
@@ -325,19 +329,19 @@ export class ColorBulb {
325
329
  this.infoLog(`Color Bulb: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac}`);
326
330
  }
327
331
  this.serviceData = ad.serviceData;
328
- this.state = ad.serviceData.state;
329
- this.delay = ad.serviceData.delay;
332
+ //this.state = ad.serviceData.state;
333
+ //this.delay = ad.serviceData.delay;
330
334
  //this.timer = ad.serviceData.timer;
331
335
  //this.syncUtcTime = ad.serviceData.syncUtcTime;
332
- this.wifiRssi = ad.serviceData.wifiRssi;
336
+ //this.wifiRssi = ad.serviceData.wifiRssi;
333
337
  //this.overload = ad.serviceData.overload;
334
338
  //this.currentPower = ad.serviceData.currentPower;
335
339
  this.debugLog(`Color Bulb: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
336
- this.debugLog(
340
+ /*this.debugLog(
337
341
  `Color Bulb: ${this.accessory.displayName} state: ${ad.serviceData.state}, ` +
338
342
  `delay: ${ad.serviceData.delay}, timer: ${ad.serviceData.timer}, syncUtcTime: ${ad.serviceData.syncUtcTime} ` +
339
343
  `wifiRssi: ${ad.serviceData.wifiRssi}, overload: ${ad.serviceData.overload}, currentPower: ${ad.serviceData.currentPower}`,
340
- );
344
+ );*/
341
345
 
342
346
  if (this.serviceData) {
343
347
  this.connected = true;
@@ -351,13 +355,18 @@ export class ColorBulb {
351
355
  return switchbot.wait(this.scanDuration * 1000);
352
356
  })
353
357
  .then(async () => {
354
- // Stop to monitor
358
+ // Stop to monitor
355
359
  switchbot.stopScan();
356
360
  if (this.connected) {
357
361
  this.parseStatus();
358
362
  this.updateHomeKitCharacteristics();
359
363
  } else {
360
- await this.BLEconnection(switchbot);
364
+ this.errorLog(`Color Bulb: ${this.accessory.displayName} wasn't able to establish BLE Connection`);
365
+ if (this.platform.config.credentials?.token) {
366
+ this.warnLog(`Color Bulb: ${this.accessory.displayName} Using OpenAPI Connection`);
367
+ this.SwitchToOpenAPI = true;
368
+ await this.openAPIRefreshStatus();
369
+ }
361
370
  }
362
371
  })
363
372
  .catch(async (e: any) => {
@@ -381,6 +390,7 @@ export class ColorBulb {
381
390
 
382
391
  async getCustomBLEAddress(switchbot: any) {
383
392
  if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
393
+ this.debugLog(`Color Bulb: ${this.accessory.displayName} customBLEaddress: ${this.device.customBLEaddress}`);
384
394
  (async () => {
385
395
  // Start to monitor advertisement packets
386
396
  await switchbot.startScan({
@@ -388,7 +398,7 @@ export class ColorBulb {
388
398
  });
389
399
  // Set an event handler
390
400
  switchbot.onadvertisement = (ad: any) => {
391
- this.warnLog(JSON.stringify(ad, null, ' '));
401
+ this.warnLog(`Color Bulb: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
392
402
  };
393
403
  await switchbot.wait(10000);
394
404
  // Stop to monitor
@@ -478,68 +488,66 @@ export class ColorBulb {
478
488
  async pushChanges(): Promise<void> {
479
489
  try {
480
490
  if (this.On !== this.OnCached) {
481
- // Push On Update
482
- const payload = {
483
- commandType: 'command',
484
- parameter: 'default',
485
- } as payload;
486
-
487
- if (this.On) {
488
- payload.command = 'turnOn';
489
- } else {
490
- payload.command = 'turnOff';
491
- }
492
-
493
- this.infoLog(
494
- `Color Bulb: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},` +
495
- ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`,
496
- );
497
-
498
- // Make the API request
491
+ // Make Push On request to the API
499
492
  const t = Date.now();
500
493
  const nonce = 'requestID';
501
494
  const data = this.platform.config.credentials?.token + t + nonce;
502
- const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
495
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
496
+ .update(Buffer.from(data, 'utf-8'))
497
+ .digest();
503
498
  const sign = signTerm.toString('base64');
504
499
  this.debugLog(`Color Bulb: ${this.accessory.displayName} sign: ${sign}`);
500
+
501
+ let command = '';
502
+ if (this.On) {
503
+ command = 'turnOn';
504
+ } else {
505
+ command = 'turnOff';
506
+ }
507
+ const body = JSON.stringify({
508
+ 'command': `${command}`,
509
+ 'parameter': 'default',
510
+ 'commandType': 'command',
511
+ });
512
+ this.infoLog(`Color Bulb: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
505
513
  const options = {
506
514
  hostname: HostDomain,
507
515
  port: 443,
508
516
  path: `${DevicePath}/${this.device.deviceId}/commands`,
509
517
  method: 'POST',
510
518
  headers: {
511
- Authorization: this.platform.config.credentials?.token,
512
- sign: sign,
513
- nonce: nonce,
514
- t: t,
519
+ 'Authorization': this.platform.config.credentials?.token,
520
+ 'sign': sign,
521
+ 'nonce': nonce,
522
+ 't': t,
515
523
  'Content-Type': 'application/json',
524
+ 'Content-Length': body.length,
516
525
  },
517
526
  };
518
- const req = https.request(options, (res) => {
527
+ const req = https.request(options, res => {
519
528
  this.debugLog(`Color Bulb: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
520
529
  this.statusCode({ res });
521
- res.on('data', (d) => {
522
- this.debugLog(`d: ${d}`);
530
+ res.on('data', d => {
531
+ this.debugLog(`Color Bulb: ${this.accessory.displayName} d: ${d}`);
523
532
  });
524
533
  });
525
- req.on('error', (error) => {
526
- this.errorLog(`Color Bulb: ${this.accessory.displayName} error: ${error}`);
534
+ req.on('error', (e: any) => {
535
+ this.errorLog(`Color Bulb: ${this.accessory.displayName} error message: ${e.message}`);
527
536
  });
528
- req.write(payload);
537
+ req.write(body);
529
538
  req.end();
530
-
531
539
  this.debugLog(`Color Bulb: ${this.accessory.displayName} pushChanges: ${JSON.stringify(req)}`);
532
540
  this.OnCached = this.On;
533
541
  this.accessory.context.On = this.OnCached;
534
542
  }
535
543
  // Push Brightness Update
536
544
  if (this.On) {
537
- await this.pushBrightnessChanges();
545
+ //await this.pushBrightnessChanges();
538
546
  }
539
547
 
540
548
  // Push ColorTemperature Update
541
549
  if (this.On) {
542
- await this.pushColorTemperatureChanges();
550
+ //await this.pushColorTemperatureChanges();
543
551
  }
544
552
 
545
553
  // Push Hue & Saturation Update
@@ -566,51 +574,47 @@ export class ColorBulb {
566
574
  const [red, green, blue] = hs2rgb(Number(this.Hue), Number(this.Saturation));
567
575
  this.debugLog(`Color Bulb: ${this.accessory.displayName} rgb: ${JSON.stringify([red, green, blue])}`);
568
576
 
569
- const payload = {
570
- commandType: 'command',
571
- command: 'setColor',
572
- parameter: `${red}:${green}:${blue}`,
573
- } as payload;
574
-
575
- this.infoLog(
576
- `Color Bulb: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},` +
577
- ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`,
578
- );
579
-
580
- // Make the API request
577
+ // Make Push Hue/Saturation request to the API
581
578
  const t = Date.now();
582
579
  const nonce = 'requestID';
583
580
  const data = this.platform.config.credentials?.token + t + nonce;
584
- const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
581
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
582
+ .update(Buffer.from(data, 'utf-8'))
583
+ .digest();
585
584
  const sign = signTerm.toString('base64');
586
585
  this.debugLog(`Color Bulb: ${this.accessory.displayName} sign: ${sign}`);
586
+ const body = JSON.stringify({
587
+ 'command': 'setColor',
588
+ 'parameter': `${red}:${green}:${blue}`,
589
+ 'commandType': 'command',
590
+ });
591
+ this.infoLog(`Color Bulb: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
587
592
  const options = {
588
593
  hostname: HostDomain,
589
594
  port: 443,
590
595
  path: `${DevicePath}/${this.device.deviceId}/commands`,
591
596
  method: 'POST',
592
597
  headers: {
593
- Authorization: this.platform.config.credentials?.token,
594
- sign: sign,
595
- nonce: nonce,
596
- t: t,
598
+ 'Authorization': this.platform.config.credentials?.token,
599
+ 'sign': sign,
600
+ 'nonce': nonce,
601
+ 't': t,
597
602
  'Content-Type': 'application/json',
603
+ 'Content-Length': body.length,
598
604
  },
599
605
  };
600
- const req = https.request(options, (res) => {
606
+ const req = https.request(options, res => {
601
607
  this.debugLog(`Color Bulb: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
602
- this.statusCode({ res });
603
- res.on('data', (d) => {
604
- this.debugLog(`d: ${d}`);
608
+ res.on('data', d => {
609
+ this.debugLog(`Color Bulb: ${this.accessory.displayName} d: ${d}`);
605
610
  });
606
611
  });
607
- req.on('error', (error) => {
608
- this.errorLog(`Color Bulb: ${this.accessory.displayName} error: ${error}`);
612
+ req.on('error', (e: any) => {
613
+ this.errorLog(`Color Bulb: ${this.accessory.displayName} error message: ${e.message}`);
609
614
  });
610
- req.write(payload);
615
+ req.write(body);
611
616
  req.end();
612
-
613
- this.debugLog(`Color Bulb: ${this.accessory.displayName} pushChanges: ${JSON.stringify(req)}`);
617
+ this.debugLog(`Color Bulb: ${this.accessory.displayName} pushHueSaturationChanges: ${JSON.stringify(req)}`);
614
618
  this.HueCached = this.Hue;
615
619
  this.SaturationCached = this.Saturation;
616
620
  } else {
@@ -636,51 +640,48 @@ export class ColorBulb {
636
640
  const kelvin = Math.round(1000000 / Number(this.ColorTemperature));
637
641
  this.cacheKelvin = kelvin;
638
642
 
639
- const payload = {
640
- commandType: 'command',
641
- command: 'setColorTemperature',
642
- parameter: `${kelvin}`,
643
- } as payload;
644
-
645
- this.infoLog(
646
- `Color Bulb: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},` +
647
- ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`,
648
- );
649
-
650
- // Make the API request
643
+ // Make Push On request to the API
651
644
  const t = Date.now();
652
645
  const nonce = 'requestID';
653
646
  const data = this.platform.config.credentials?.token + t + nonce;
654
- const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
647
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
648
+ .update(Buffer.from(data, 'utf-8'))
649
+ .digest();
655
650
  const sign = signTerm.toString('base64');
656
651
  this.debugLog(`Color Bulb: ${this.accessory.displayName} sign: ${sign}`);
652
+ const body = JSON.stringify({
653
+ 'command': 'setColorTemperature',
654
+ 'parameter': `${kelvin}`,
655
+ 'commandType': 'command',
656
+ });
657
+ this.infoLog(`Color Bulb: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
657
658
  const options = {
658
659
  hostname: HostDomain,
659
660
  port: 443,
660
661
  path: `${DevicePath}/${this.device.deviceId}/commands`,
661
662
  method: 'POST',
662
663
  headers: {
663
- Authorization: this.platform.config.credentials?.token,
664
- sign: sign,
665
- nonce: nonce,
666
- t: t,
664
+ 'Authorization': this.platform.config.credentials?.token,
665
+ 'sign': sign,
666
+ 'nonce': nonce,
667
+ 't': t,
667
668
  'Content-Type': 'application/json',
669
+ 'Content-Length': body.length,
668
670
  },
669
671
  };
670
- const req = https.request(options, (res) => {
672
+ const req = https.request(options, res => {
671
673
  this.debugLog(`Color Bulb: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
672
- this.statusCode({ res });
673
- res.on('data', (d) => {
674
- this.debugLog(`d: ${d}`);
674
+ res.on('data', d => {
675
+ this.debugLog(`Color Bulb: ${this.accessory.displayName} d: ${d}`);
675
676
  });
676
677
  });
677
- req.on('error', (error) => {
678
- this.errorLog(`Color Bulb: ${this.accessory.displayName} error: ${error}`);
678
+ req.on('error', (e: any) => {
679
+ this.errorLog(`Color Bulb: ${this.accessory.displayName} error message: ${e.message}`);
679
680
  });
680
- req.write(payload);
681
+ req.write(body);
681
682
  req.end();
682
683
 
683
- this.debugLog(`Color Bulb: ${this.accessory.displayName} pushChanges: ${JSON.stringify(req)}`);
684
+ this.debugLog(`Color Bulb: ${this.accessory.displayName} pushColorTemperatureChanges: ${JSON.stringify(req)}`);
684
685
  this.ColorTemperatureCached = this.ColorTemperature;
685
686
  } else {
686
687
  this.debugLog(
@@ -702,51 +703,47 @@ export class ColorBulb {
702
703
  async pushBrightnessChanges(): Promise<void> {
703
704
  try {
704
705
  if (this.Brightness !== this.BrightnessCached) {
705
- const payload = {
706
- commandType: 'command',
707
- command: 'setBrightness',
708
- parameter: `${this.Brightness}`,
709
- } as payload;
710
-
711
- this.infoLog(
712
- `Color Bulb: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},` +
713
- ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`,
714
- );
715
-
716
- // Make the API request
706
+ // Make Push On request to the API
717
707
  const t = Date.now();
718
708
  const nonce = 'requestID';
719
709
  const data = this.platform.config.credentials?.token + t + nonce;
720
- const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
710
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
711
+ .update(Buffer.from(data, 'utf-8'))
712
+ .digest();
721
713
  const sign = signTerm.toString('base64');
722
714
  this.debugLog(`Color Bulb: ${this.accessory.displayName} sign: ${sign}`);
715
+ const body = JSON.stringify({
716
+ 'command': 'setBrightness',
717
+ 'parameter': `${this.Brightness}`,
718
+ 'commandType': 'command',
719
+ });
720
+ this.infoLog(`Color Bulb: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
723
721
  const options = {
724
722
  hostname: HostDomain,
725
723
  port: 443,
726
724
  path: `${DevicePath}/${this.device.deviceId}/commands`,
727
725
  method: 'POST',
728
726
  headers: {
729
- Authorization: this.platform.config.credentials?.token,
730
- sign: sign,
731
- nonce: nonce,
732
- t: t,
727
+ 'Authorization': this.platform.config.credentials?.token,
728
+ 'sign': sign,
729
+ 'nonce': nonce,
730
+ 't': t,
733
731
  'Content-Type': 'application/json',
732
+ 'Content-Length': body.length,
734
733
  },
735
734
  };
736
- const req = https.request(options, (res) => {
735
+ const req = https.request(options, res => {
737
736
  this.debugLog(`Color Bulb: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
738
- this.statusCode({ res });
739
- res.on('data', (d) => {
740
- this.debugLog(`d: ${d}`);
737
+ res.on('data', d => {
738
+ this.debugLog(`Color Bulb: ${this.accessory.displayName} d: ${d}`);
741
739
  });
742
740
  });
743
- req.on('error', (error) => {
744
- this.errorLog(`Color Bulb: ${this.accessory.displayName} error: ${error}`);
741
+ req.on('error', (e: any) => {
742
+ this.errorLog(`Color Bulb: ${this.accessory.displayName} error message: ${e.message}`);
745
743
  });
746
- req.write(payload);
744
+ req.write(body);
747
745
  req.end();
748
-
749
- this.debugLog(`Color Bulb: ${this.accessory.displayName} pushChanges: ${JSON.stringify(req)}`);
746
+ this.debugLog(`Color Bulb: ${this.accessory.displayName} pushBrightnessChanges: ${JSON.stringify(req)}`);
750
747
  this.BrightnessCached = this.Brightness;
751
748
  } else {
752
749
  this.debugLog(
@@ -954,6 +951,20 @@ export class ColorBulb {
954
951
  }
955
952
  }
956
953
 
954
+ async scan(device: device & devicesConfig): Promise<void> {
955
+ if (device.scanDuration) {
956
+ this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
957
+ if (device.ble) {
958
+ this.debugLog(`Bot: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
959
+ }
960
+ } else {
961
+ this.scanDuration = this.accessory.context.scanDuration = 1;
962
+ if (this.device.ble) {
963
+ this.debugLog(`Bot: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
964
+ }
965
+ }
966
+ }
967
+
957
968
  async logs(device: device & devicesConfig): Promise<void> {
958
969
  if (this.platform.debugMode) {
959
970
  this.deviceLogging = this.accessory.context.logging = 'debugMode';
@@ -354,7 +354,7 @@ export class Contact {
354
354
  });
355
355
  // Set an event handler
356
356
  switchbot.onadvertisement = (ad: any) => {
357
- this.warnLog(JSON.stringify(ad, null, ' '));
357
+ this.warnLog(`Contact Sensor: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
358
358
  };
359
359
  await switchbot.wait(10000);
360
360
  // Stop to monitor
@@ -8,7 +8,7 @@ import { connectAsync } from 'async-mqtt';
8
8
  import { SwitchBotPlatform } from '../platform';
9
9
  import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
10
10
  import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
11
- import { device, devicesConfig, serviceData, switchbot, payload, deviceStatus, ad, HostDomain, DevicePath } from '../settings';
11
+ import { device, devicesConfig, serviceData, switchbot, deviceStatus, ad, HostDomain, DevicePath } from '../settings';
12
12
 
13
13
  export class Curtain {
14
14
  // Services
@@ -436,6 +436,7 @@ export class Curtain {
436
436
  this.debugLog(`Curtain: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
437
437
  this.getCustomBLEAddress(switchbot);
438
438
  // Start to monitor advertisement packets
439
+ this.errorLog(`Color Bulb: ${this.accessory.displayName} switchbot: ${JSON.stringify(switchbot)}`);
439
440
  if (switchbot !== false) {
440
441
  switchbot
441
442
  .startScan({
@@ -481,7 +482,12 @@ export class Curtain {
481
482
  this.parseStatus();
482
483
  this.updateHomeKitCharacteristics();
483
484
  } else {
484
- await this.BLEconnection(switchbot);
485
+ this.errorLog(`Curtain: ${this.accessory.displayName} wasn't able to establish BLE Connection`);
486
+ if (this.platform.config.credentials?.token) {
487
+ this.warnLog(`Curtain: ${this.accessory.displayName} Using OpenAPI Connection`);
488
+ this.SwitchToOpenAPI = true;
489
+ await this.openAPIRefreshStatus();
490
+ }
485
491
  }
486
492
  })
487
493
  .catch(async (e: any) => {
@@ -512,7 +518,7 @@ export class Curtain {
512
518
  });
513
519
  // Set an event handler
514
520
  switchbot.onadvertisement = (ad: any) => {
515
- this.warnLog(JSON.stringify(ad, null, ' '));
521
+ this.warnLog(`Curtain: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
516
522
  };
517
523
  await switchbot.wait(10000);
518
524
  // Stop to monitor
@@ -679,6 +685,15 @@ export class Curtain {
679
685
  try {
680
686
  this.debugLog(`Curtain: ${this.accessory.displayName} OpenAPI pushChanges`);
681
687
  if (this.TargetPosition !== this.CurrentPosition) {
688
+ // Make Push On request to the API
689
+ const t = Date.now();
690
+ const nonce = 'requestID';
691
+ const data = this.platform.config.credentials?.token + t + nonce;
692
+ const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret)
693
+ .update(Buffer.from(data, 'utf-8'))
694
+ .digest();
695
+ const sign = signTerm.toString('base64');
696
+ this.debugLog(`Curtain: ${this.accessory.displayName} sign: ${sign}`);
682
697
  this.debugLog(`Pushing ${this.TargetPosition}`);
683
698
  const adjustedTargetPosition = 100 - Number(this.TargetPosition);
684
699
  if (this.TargetPosition > 50) {
@@ -695,54 +710,39 @@ export class Curtain {
695
710
  }
696
711
  this.debugLog(`${this.accessory.displayName} Mode: ${this.Mode}`);
697
712
  const adjustedMode = this.setPositionMode || 'ff';
698
- const payload = {
699
- commandType: 'command',
700
- command: 'setPosition',
701
- parameter: `0,${adjustedMode},${adjustedTargetPosition}`,
702
- } as payload;
703
-
704
- this.infoLog(
705
- `Curtain: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},` +
706
- ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`,
707
- );
708
-
709
- // Make the API request
710
- const t = Date.now();
711
- const nonce = 'requestID';
712
- const data = this.platform.config.credentials?.token + t + nonce;
713
- const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
714
- const sign = signTerm.toString('base64');
715
- this.debugLog(`Curtain: ${this.accessory.displayName} sign: ${sign}`);
713
+ const body = JSON.stringify({
714
+ 'command': 'setPosition',
715
+ 'parameter': `0,${adjustedMode},${adjustedTargetPosition}`,
716
+ 'commandType': 'command',
717
+ });
718
+ this.infoLog(`Curtain: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
716
719
  const options = {
717
720
  hostname: HostDomain,
718
721
  port: 443,
719
722
  path: `${DevicePath}/${this.device.deviceId}/commands`,
720
723
  method: 'POST',
721
724
  headers: {
722
- Authorization: this.platform.config.credentials?.token,
723
- sign: sign,
724
- nonce: nonce,
725
- t: t,
725
+ 'Authorization': this.platform.config.credentials?.token,
726
+ 'sign': sign,
727
+ 'nonce': nonce,
728
+ 't': t,
726
729
  'Content-Type': 'application/json',
730
+ 'Content-Length': body.length,
727
731
  },
728
732
  };
729
-
730
- const req = https.request(options, (res) => {
733
+ const req = https.request(options, res => {
731
734
  this.debugLog(`Curtain: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
732
735
  this.statusCode({ res });
733
- res.on('data', (d) => {
736
+ res.on('data', d => {
734
737
  this.debugLog(`Curtain: ${this.accessory.displayName} d: ${d}`);
735
738
  });
736
739
  });
737
-
738
- req.on('error', (error) => {
739
- this.errorLog(`Curtain: ${this.accessory.displayName} error: ${error}`);
740
+ req.on('error', (e: any) => {
741
+ this.errorLog(`Curtain: ${this.accessory.displayName} error message: ${e.message}`);
740
742
  });
741
-
742
- req.write(payload);
743
+ req.write(body);
743
744
  req.end();
744
-
745
- this.debugLog(`Curtain: ${this.accessory.displayName} pushchanges: ${JSON.stringify(req)}`);
745
+ this.debugLog(`Curtain: ${this.accessory.displayName} openAPIpushChanges: ${JSON.stringify(req)}`);
746
746
  } else {
747
747
  this.debugLog(
748
748
  `Curtain: ${this.accessory.displayName} No OpenAPI Changes, CurrentPosition & TargetPosition Are the Same.` +