@switchbot/homebridge-switchbot 3.5.0-beta.2 → 3.5.0-beta.21

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 (151) hide show
  1. package/CHANGELOG.md +4 -1
  2. package/config.schema.json +57 -6
  3. package/dist/device/blindtilt.d.ts +4 -0
  4. package/dist/device/blindtilt.d.ts.map +1 -1
  5. package/dist/device/blindtilt.js +37 -1
  6. package/dist/device/blindtilt.js.map +1 -1
  7. package/dist/device/bot.d.ts +4 -0
  8. package/dist/device/bot.d.ts.map +1 -1
  9. package/dist/device/bot.js +31 -1
  10. package/dist/device/bot.js.map +1 -1
  11. package/dist/device/ceilinglight.d.ts +4 -0
  12. package/dist/device/ceilinglight.d.ts.map +1 -1
  13. package/dist/device/ceilinglight.js +37 -3
  14. package/dist/device/ceilinglight.js.map +1 -1
  15. package/dist/device/colorbulb.d.ts +4 -0
  16. package/dist/device/colorbulb.d.ts.map +1 -1
  17. package/dist/device/colorbulb.js +39 -3
  18. package/dist/device/colorbulb.js.map +1 -1
  19. package/dist/device/contact.d.ts +4 -0
  20. package/dist/device/contact.d.ts.map +1 -1
  21. package/dist/device/contact.js +27 -2
  22. package/dist/device/contact.js.map +1 -1
  23. package/dist/device/curtain.d.ts +4 -0
  24. package/dist/device/curtain.d.ts.map +1 -1
  25. package/dist/device/curtain.js +31 -1
  26. package/dist/device/curtain.js.map +1 -1
  27. package/dist/device/hub.d.ts +4 -0
  28. package/dist/device/hub.d.ts.map +1 -1
  29. package/dist/device/hub.js +27 -2
  30. package/dist/device/hub.js.map +1 -1
  31. package/dist/device/humidifier.d.ts +4 -0
  32. package/dist/device/humidifier.d.ts.map +1 -1
  33. package/dist/device/humidifier.js +36 -2
  34. package/dist/device/humidifier.js.map +1 -1
  35. package/dist/device/iosensor.d.ts +4 -0
  36. package/dist/device/iosensor.d.ts.map +1 -1
  37. package/dist/device/iosensor.js +27 -2
  38. package/dist/device/iosensor.js.map +1 -1
  39. package/dist/device/lightstrip.d.ts +4 -0
  40. package/dist/device/lightstrip.d.ts.map +1 -1
  41. package/dist/device/lightstrip.js +37 -3
  42. package/dist/device/lightstrip.js.map +1 -1
  43. package/dist/device/lock.d.ts +4 -0
  44. package/dist/device/lock.d.ts.map +1 -1
  45. package/dist/device/lock.js +31 -1
  46. package/dist/device/lock.js.map +1 -1
  47. package/dist/device/meter.d.ts +4 -0
  48. package/dist/device/meter.d.ts.map +1 -1
  49. package/dist/device/meter.js +27 -2
  50. package/dist/device/meter.js.map +1 -1
  51. package/dist/device/meterplus.d.ts +4 -0
  52. package/dist/device/meterplus.d.ts.map +1 -1
  53. package/dist/device/meterplus.js +27 -2
  54. package/dist/device/meterplus.js.map +1 -1
  55. package/dist/device/motion.d.ts +4 -0
  56. package/dist/device/motion.d.ts.map +1 -1
  57. package/dist/device/motion.js +27 -2
  58. package/dist/device/motion.js.map +1 -1
  59. package/dist/device/plug.d.ts +4 -0
  60. package/dist/device/plug.d.ts.map +1 -1
  61. package/dist/device/plug.js +31 -1
  62. package/dist/device/plug.js.map +1 -1
  63. package/dist/device/robotvacuumcleaner.d.ts +4 -0
  64. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  65. package/dist/device/robotvacuumcleaner.js +38 -5
  66. package/dist/device/robotvacuumcleaner.js.map +1 -1
  67. package/dist/device/waterdetector.d.ts +7 -11
  68. package/dist/device/waterdetector.d.ts.map +1 -1
  69. package/dist/device/waterdetector.js +54 -224
  70. package/dist/device/waterdetector.js.map +1 -1
  71. package/dist/index.js +1 -1
  72. package/dist/irdevice/airconditioner.d.ts +1 -0
  73. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  74. package/dist/irdevice/airconditioner.js +6 -0
  75. package/dist/irdevice/airconditioner.js.map +1 -1
  76. package/dist/irdevice/airpurifier.d.ts +1 -0
  77. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  78. package/dist/irdevice/airpurifier.js +6 -0
  79. package/dist/irdevice/airpurifier.js.map +1 -1
  80. package/dist/irdevice/camera.d.ts +1 -0
  81. package/dist/irdevice/camera.d.ts.map +1 -1
  82. package/dist/irdevice/camera.js +6 -0
  83. package/dist/irdevice/camera.js.map +1 -1
  84. package/dist/irdevice/fan.d.ts +1 -0
  85. package/dist/irdevice/fan.d.ts.map +1 -1
  86. package/dist/irdevice/fan.js +6 -0
  87. package/dist/irdevice/fan.js.map +1 -1
  88. package/dist/irdevice/light.d.ts +1 -0
  89. package/dist/irdevice/light.d.ts.map +1 -1
  90. package/dist/irdevice/light.js +6 -0
  91. package/dist/irdevice/light.js.map +1 -1
  92. package/dist/irdevice/other.d.ts +1 -0
  93. package/dist/irdevice/other.d.ts.map +1 -1
  94. package/dist/irdevice/other.js +6 -0
  95. package/dist/irdevice/other.js.map +1 -1
  96. package/dist/irdevice/tv.d.ts +1 -0
  97. package/dist/irdevice/tv.d.ts.map +1 -1
  98. package/dist/irdevice/tv.js +6 -0
  99. package/dist/irdevice/tv.js.map +1 -1
  100. package/dist/irdevice/vacuumcleaner.d.ts +1 -0
  101. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  102. package/dist/irdevice/vacuumcleaner.js +6 -0
  103. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  104. package/dist/irdevice/waterheater.d.ts +1 -0
  105. package/dist/irdevice/waterheater.d.ts.map +1 -1
  106. package/dist/irdevice/waterheater.js +6 -0
  107. package/dist/irdevice/waterheater.js.map +1 -1
  108. package/dist/platform.d.ts +12 -0
  109. package/dist/platform.d.ts.map +1 -1
  110. package/dist/platform.js +148 -89
  111. package/dist/platform.js.map +1 -1
  112. package/dist/settings.d.ts +5 -6
  113. package/dist/settings.d.ts.map +1 -1
  114. package/dist/settings.js +0 -552
  115. package/dist/settings.js.map +1 -1
  116. package/dist/utils.d.ts +4 -0
  117. package/dist/utils.d.ts.map +1 -1
  118. package/dist/utils.js +553 -1
  119. package/dist/utils.js.map +1 -1
  120. package/package.json +16 -15
  121. package/src/custom.d.ts +1 -1
  122. package/src/device/blindtilt.ts +49 -12
  123. package/src/device/bot.ts +34 -3
  124. package/src/device/ceilinglight.ts +40 -5
  125. package/src/device/colorbulb.ts +42 -5
  126. package/src/device/contact.ts +30 -4
  127. package/src/device/curtain.ts +34 -3
  128. package/src/device/hub.ts +30 -4
  129. package/src/device/humidifier.ts +39 -4
  130. package/src/device/iosensor.ts +30 -4
  131. package/src/device/lightstrip.ts +40 -5
  132. package/src/device/lock.ts +34 -3
  133. package/src/device/meter.ts +30 -4
  134. package/src/device/meterplus.ts +30 -4
  135. package/src/device/motion.ts +30 -4
  136. package/src/device/plug.ts +34 -3
  137. package/src/device/robotvacuumcleaner.ts +41 -7
  138. package/src/device/waterdetector.ts +60 -229
  139. package/src/index.ts +1 -1
  140. package/src/irdevice/airconditioner.ts +7 -0
  141. package/src/irdevice/airpurifier.ts +7 -0
  142. package/src/irdevice/camera.ts +7 -0
  143. package/src/irdevice/fan.ts +7 -0
  144. package/src/irdevice/light.ts +7 -0
  145. package/src/irdevice/other.ts +7 -0
  146. package/src/irdevice/tv.ts +7 -0
  147. package/src/irdevice/vacuumcleaner.ts +7 -0
  148. package/src/irdevice/waterheater.ts +7 -0
  149. package/src/platform.ts +157 -95
  150. package/src/settings.ts +6 -557
  151. package/src/utils.ts +556 -1
package/src/device/hub.ts CHANGED
@@ -3,7 +3,6 @@ import { CharacteristicValue, PlatformAccessory, Service, Units, API, Logging, H
3
3
  import { MqttClient } from 'mqtt';
4
4
  import { hostname } from 'os';
5
5
  import { interval } from 'rxjs';
6
- import { request } from 'undici';
7
6
  import { SwitchBotPlatform } from '../platform.js';
8
7
  import { Devices, device, deviceStatus, devicesConfig, SwitchBotPlatformConfig } from '../settings.js';
9
8
 
@@ -46,6 +45,8 @@ export class Hub {
46
45
  scanDuration!: number;
47
46
  deviceLogging!: string;
48
47
  deviceRefreshRate!: number;
48
+ maxRetries!: number;
49
+ delayBetweenRetries!: number;
49
50
 
50
51
  // Connection
51
52
  private readonly OpenAPI: boolean;
@@ -69,6 +70,7 @@ export class Hub {
69
70
  this.deviceContext();
70
71
  this.setupHistoryService(device);
71
72
  this.setupMqtt(device);
73
+ this.deviceRetry(device);
72
74
  this.deviceConfig(device);
73
75
 
74
76
  this.CurrentRelativeHumidity = accessory.context.CurrentRelativeHumidity;
@@ -432,9 +434,10 @@ export class Hub {
432
434
  async openAPIRefreshStatus(): Promise<void> {
433
435
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
434
436
  try {
435
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/status`, {
436
- headers: this.platform.generateHeaders(),
437
- });
437
+ const { body, statusCode } = await this.platform.retryRequest(this.maxRetries, this.delayBetweenRetries,
438
+ `${Devices}/${this.device.deviceId}/status`, {
439
+ headers: this.platform.generateHeaders(),
440
+ });
438
441
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
439
442
  const deviceStatus: any = await body.json();
440
443
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
@@ -742,6 +745,23 @@ export class Hub {
742
745
  }
743
746
  }
744
747
 
748
+ async deviceRetry(device: device & devicesConfig): Promise<void> {
749
+ if (!device.maxRetries) {
750
+ this.maxRetries = 5; // Maximum number of retries
751
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Max Retries Not Set, Using: ${this.maxRetries}`);
752
+ } else {
753
+ this.maxRetries = device.maxRetries;
754
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Max Retries: ${this.maxRetries}`);
755
+ }
756
+ if (!device.delayBetweenRetries) {
757
+ this.delayBetweenRetries = 3000; // Delay between retries in milliseconds
758
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Delay Between Retries Not Set, Using: ${this.delayBetweenRetries}`);
759
+ } else {
760
+ this.delayBetweenRetries = device.delayBetweenRetries * 1000;
761
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Delay Between Retries: ${this.delayBetweenRetries}`);
762
+ }
763
+ }
764
+
745
765
  async deviceConfig(device: device & devicesConfig): Promise<void> {
746
766
  let config = {};
747
767
  if (device.hub) {
@@ -786,6 +806,12 @@ export class Hub {
786
806
  /**
787
807
  * Logging for Device
788
808
  */
809
+ successLog(...log: any[]): void {
810
+ if (this.enablingDeviceLogging()) {
811
+ this.platform.log.success(String(...log));
812
+ }
813
+ }
814
+
789
815
  infoLog(...log: any[]): void {
790
816
  if (this.enablingDeviceLogging()) {
791
817
  this.platform.log.info(String(...log));
@@ -50,6 +50,8 @@ export class Humidifier {
50
50
  scanDuration!: number;
51
51
  deviceLogging!: string;
52
52
  deviceRefreshRate!: number;
53
+ maxRetries!: number;
54
+ delayBetweenRetries!: number;
53
55
 
54
56
  // Updates
55
57
  humidifierUpdateInProgress!: boolean;
@@ -76,6 +78,7 @@ export class Humidifier {
76
78
  this.scan(device);
77
79
  this.refreshRate(device);
78
80
  this.deviceContext();
81
+ this.deviceRetry(device);
79
82
  this.deviceConfig(device);
80
83
 
81
84
  // this is subject we use to track when we need to POST changes to the SwitchBot API
@@ -429,9 +432,10 @@ export class Humidifier {
429
432
  async openAPIRefreshStatus(): Promise<void> {
430
433
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
431
434
  try {
432
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/status`, {
433
- headers: this.platform.generateHeaders(),
434
- });
435
+ const { body, statusCode } = await this.platform.retryRequest(this.maxRetries, this.delayBetweenRetries,
436
+ `${Devices}/${this.device.deviceId}/status`, {
437
+ headers: this.platform.generateHeaders(),
438
+ });
435
439
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
436
440
  const deviceStatus: any = await body.json();
437
441
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
@@ -500,11 +504,13 @@ export class Humidifier {
500
504
  id: this.device.bleMac,
501
505
  })
502
506
  .then(async (device_list: any) => {
503
- this.infoLog(`${this.accessory.displayName} Target Position: ${this.Active}`);
507
+ this.infoLog(`${this.accessory.displayName} Active: ${this.Active}`);
504
508
  return await device_list[0].percentage(this.RelativeHumidityHumidifierThreshold);
505
509
  })
506
510
  .then(() => {
507
511
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
512
+ this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
513
+ + `Active: ${this.Active} sent over BLE, sent successfully`);
508
514
  })
509
515
  .catch(async (e: any) => {
510
516
  this.apiError(e);
@@ -543,6 +549,8 @@ export class Humidifier {
543
549
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
544
550
  this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
545
551
  + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
552
+ this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
553
+ + `request to SwitchBot API, body: ${deviceStatus} sent successfully`);
546
554
  } else {
547
555
  this.statusCode(statusCode);
548
556
  this.statusCode(deviceStatus.statusCode);
@@ -594,6 +602,8 @@ export class Humidifier {
594
602
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
595
603
  this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
596
604
  + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
605
+ this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
606
+ + `request to SwitchBot API, body: ${deviceStatus} sent successfully`);
597
607
  } else {
598
608
  this.statusCode(statusCode);
599
609
  this.statusCode(deviceStatus.statusCode);
@@ -640,6 +650,8 @@ export class Humidifier {
640
650
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
641
651
  this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
642
652
  + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
653
+ this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
654
+ + `request to SwitchBot API, body: ${deviceStatus} sent successfully`);
643
655
  } else {
644
656
  this.statusCode(statusCode);
645
657
  this.statusCode(deviceStatus.statusCode);
@@ -1015,6 +1027,23 @@ export class Humidifier {
1015
1027
  }
1016
1028
  }
1017
1029
 
1030
+ async deviceRetry(device: device & devicesConfig): Promise<void> {
1031
+ if (!device.maxRetries) {
1032
+ this.maxRetries = 5; // Maximum number of retries
1033
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Max Retries Not Set, Using: ${this.maxRetries}`);
1034
+ } else {
1035
+ this.maxRetries = device.maxRetries;
1036
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Max Retries: ${this.maxRetries}`);
1037
+ }
1038
+ if (!device.delayBetweenRetries) {
1039
+ this.delayBetweenRetries = 3000; // Delay between retries in milliseconds
1040
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Delay Between Retries Not Set, Using: ${this.delayBetweenRetries}`);
1041
+ } else {
1042
+ this.delayBetweenRetries = device.delayBetweenRetries * 1000;
1043
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Delay Between Retries: ${this.delayBetweenRetries}`);
1044
+ }
1045
+ }
1046
+
1018
1047
  async deviceConfig(device: device & devicesConfig): Promise<void> {
1019
1048
  let config = {};
1020
1049
  if (device.humidifier) {
@@ -1065,6 +1094,12 @@ export class Humidifier {
1065
1094
  /**
1066
1095
  * Logging for Device
1067
1096
  */
1097
+ successLog(...log: any[]): void {
1098
+ if (this.enablingDeviceLogging()) {
1099
+ this.platform.log.success(String(...log));
1100
+ }
1101
+ }
1102
+
1068
1103
  async infoLog(...log: any[]): Promise<void> {
1069
1104
  if (this.enablingDeviceLogging()) {
1070
1105
  this.platform.log.info(String(...log));
@@ -1,5 +1,4 @@
1
1
  import { hostname } from 'os';
2
- import { request } from 'undici';
3
2
  import { sleep } from '../utils.js';
4
3
  import { MqttClient } from 'mqtt';
5
4
  import asyncmqtt from 'async-mqtt';
@@ -57,6 +56,8 @@ export class IOSensor {
57
56
  scanDuration!: number;
58
57
  deviceLogging!: string;
59
58
  deviceRefreshRate!: number;
59
+ maxRetries!: number;
60
+ delayBetweenRetries!: number;
60
61
 
61
62
  // Updates
62
63
  ioSensorUpdateInProgress!: boolean;
@@ -85,6 +86,7 @@ export class IOSensor {
85
86
  this.deviceContext();
86
87
  this.setupHistoryService(device);
87
88
  this.setupMqtt(device);
89
+ this.deviceRetry(device);
88
90
  this.deviceConfig(device);
89
91
 
90
92
  // this is subject we use to track when we need to POST changes to the SwitchBot API
@@ -409,9 +411,10 @@ export class IOSensor {
409
411
  async openAPIRefreshStatus(): Promise<void> {
410
412
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
411
413
  try {
412
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/status`, {
413
- headers: this.platform.generateHeaders(),
414
- });
414
+ const { body, statusCode } = await this.platform.retryRequest(this.maxRetries, this.delayBetweenRetries,
415
+ `${Devices}/${this.device.deviceId}/status`, {
416
+ headers: this.platform.generateHeaders(),
417
+ });
415
418
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
416
419
  const deviceStatus: any = await body.json();
417
420
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
@@ -743,6 +746,23 @@ export class IOSensor {
743
746
  }
744
747
  }
745
748
 
749
+ async deviceRetry(device: device & devicesConfig): Promise<void> {
750
+ if (!device.maxRetries) {
751
+ this.maxRetries = 5; // Maximum number of retries
752
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Max Retries Not Set, Using: ${this.maxRetries}`);
753
+ } else {
754
+ this.maxRetries = device.maxRetries;
755
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Max Retries: ${this.maxRetries}`);
756
+ }
757
+ if (!device.delayBetweenRetries) {
758
+ this.delayBetweenRetries = 3000; // Delay between retries in milliseconds
759
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Delay Between Retries Not Set, Using: ${this.delayBetweenRetries}`);
760
+ } else {
761
+ this.delayBetweenRetries = device.delayBetweenRetries * 1000;
762
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Delay Between Retries: ${this.delayBetweenRetries}`);
763
+ }
764
+ }
765
+
746
766
  async deviceConfig(device: device & devicesConfig): Promise<void> {
747
767
  let config = {};
748
768
  if (device.meter) {
@@ -793,6 +813,12 @@ export class IOSensor {
793
813
  /**
794
814
  * Logging for Device
795
815
  */
816
+ successLog(...log: any[]): void {
817
+ if (this.enablingDeviceLogging()) {
818
+ this.platform.log.success(String(...log));
819
+ }
820
+ }
821
+
796
822
  infoLog(...log: any[]): void {
797
823
  if (this.enablingDeviceLogging()) {
798
824
  this.platform.log.info(String(...log));
@@ -1,12 +1,12 @@
1
1
  import { request } from 'undici';
2
- import { sleep } from '../utils.js';
2
+ import { hs2rgb, rgb2hs, m2hs, sleep } from '../utils.js';
3
3
  import { interval, Subject } from 'rxjs';
4
4
  import { SwitchBotPlatform } from '../platform.js';
5
5
  import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
6
6
  import {
7
7
  Service, PlatformAccessory, CharacteristicValue, ControllerConstructor, Controller, ControllerServiceMap, API, Logging, HAP,
8
8
  } from 'homebridge';
9
- import { device, devicesConfig, hs2rgb, rgb2hs, deviceStatus, serviceData, m2hs, Devices, SwitchBotPlatformConfig } from '../settings.js';
9
+ import { device, devicesConfig, deviceStatus, serviceData, Devices, SwitchBotPlatformConfig } from '../settings.js';
10
10
 
11
11
  /**
12
12
  * Platform Accessory
@@ -48,6 +48,8 @@ export class StripLight {
48
48
  deviceLogging!: string;
49
49
  deviceRefreshRate!: number;
50
50
  adaptiveLightingShift?: number;
51
+ maxRetries!: number;
52
+ delayBetweenRetries!: number;
51
53
 
52
54
  // Adaptive Lighting
53
55
  AdaptiveLightingController?: ControllerConstructor | Controller<ControllerServiceMap>;
@@ -83,6 +85,7 @@ export class StripLight {
83
85
  this.scan(device);
84
86
  this.refreshRate(device);
85
87
  this.deviceContext();
88
+ this.deviceRetry(device);
86
89
  this.deviceConfig(device);
87
90
 
88
91
  // this is subject we use to track when we need to POST changes to the SwitchBot API
@@ -441,9 +444,10 @@ export class StripLight {
441
444
  async openAPIRefreshStatus(): Promise<void> {
442
445
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
443
446
  try {
444
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/status`, {
445
- headers: this.platform.generateHeaders(),
446
- });
447
+ const { body, statusCode } = await this.platform.retryRequest(this.maxRetries, this.delayBetweenRetries,
448
+ `${Devices}/${this.device.deviceId}/status`, {
449
+ headers: this.platform.generateHeaders(),
450
+ });
447
451
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
448
452
  const deviceStatus: any = await body.json();
449
453
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
@@ -533,6 +537,8 @@ export class StripLight {
533
537
  })
534
538
  .then(() => {
535
539
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
540
+ this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
541
+ + `On: ${this.On} sent over BLE, sent successfully`);
536
542
  this.On = false;
537
543
  })
538
544
  .catch(async (e: any) => {
@@ -672,6 +678,8 @@ export class StripLight {
672
678
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
673
679
  this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
674
680
  + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
681
+ this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
682
+ + `request to SwitchBot API, body: ${deviceStatus} sent successfully`);
675
683
  } else {
676
684
  this.statusCode(statusCode);
677
685
  this.statusCode(deviceStatus.statusCode);
@@ -728,6 +736,8 @@ export class StripLight {
728
736
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
729
737
  this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
730
738
  + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
739
+ this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
740
+ + `request to SwitchBot API, body: ${deviceStatus} sent successfully`);
731
741
  } else {
732
742
  this.statusCode(statusCode);
733
743
  this.statusCode(deviceStatus.statusCode);
@@ -770,6 +780,8 @@ export class StripLight {
770
780
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
771
781
  this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
772
782
  + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
783
+ this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
784
+ + `request to SwitchBot API, body: ${deviceStatus} sent successfully`);
773
785
  } else {
774
786
  this.statusCode(statusCode);
775
787
  this.statusCode(deviceStatus.statusCode);
@@ -1164,6 +1176,23 @@ export class StripLight {
1164
1176
  }
1165
1177
  }
1166
1178
 
1179
+ async deviceRetry(device: device & devicesConfig): Promise<void> {
1180
+ if (!device.maxRetries) {
1181
+ this.maxRetries = 5; // Maximum number of retries
1182
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Max Retries Not Set, Using: ${this.maxRetries}`);
1183
+ } else {
1184
+ this.maxRetries = device.maxRetries;
1185
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Max Retries: ${this.maxRetries}`);
1186
+ }
1187
+ if (!device.delayBetweenRetries) {
1188
+ this.delayBetweenRetries = 3000; // Delay between retries in milliseconds
1189
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Delay Between Retries Not Set, Using: ${this.delayBetweenRetries}`);
1190
+ } else {
1191
+ this.delayBetweenRetries = device.delayBetweenRetries * 1000;
1192
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Delay Between Retries: ${this.delayBetweenRetries}`);
1193
+ }
1194
+ }
1195
+
1167
1196
  async deviceConfig(device: device & devicesConfig): Promise<void> {
1168
1197
  let config = {};
1169
1198
  if (device.striplight) {
@@ -1217,6 +1246,12 @@ export class StripLight {
1217
1246
  /**
1218
1247
  * Logging for Device
1219
1248
  */
1249
+ successLog(...log: any[]): void {
1250
+ if (this.enablingDeviceLogging()) {
1251
+ this.platform.log.success(String(...log));
1252
+ }
1253
+ }
1254
+
1220
1255
  infoLog(...log: any[]): void {
1221
1256
  if (this.enablingDeviceLogging()) {
1222
1257
  this.platform.log.info(String(...log));
@@ -44,6 +44,8 @@ export class Lock {
44
44
  scanDuration!: number;
45
45
  deviceLogging!: string;
46
46
  deviceRefreshRate!: number;
47
+ maxRetries!: number;
48
+ delayBetweenRetries!: number;
47
49
 
48
50
  // Updates
49
51
  lockUpdateInProgress!: boolean;
@@ -70,6 +72,7 @@ export class Lock {
70
72
  this.scan(device);
71
73
  this.refreshRate(device);
72
74
  this.deviceContext();
75
+ this.deviceRetry(device);
73
76
  this.deviceConfig(device);
74
77
 
75
78
  // this is subject we use to track when we need to POST changes to the SwitchBot API
@@ -468,9 +471,10 @@ export class Lock {
468
471
  async openAPIRefreshStatus(): Promise<void> {
469
472
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
470
473
  try {
471
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/status`, {
472
- headers: this.platform.generateHeaders(),
473
- });
474
+ const { body, statusCode } = await this.platform.retryRequest(this.maxRetries, this.delayBetweenRetries,
475
+ `${Devices}/${this.device.deviceId}/status`, {
476
+ headers: this.platform.generateHeaders(),
477
+ });
474
478
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
475
479
  const deviceStatus: any = await body.json();
476
480
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
@@ -546,6 +550,8 @@ export class Lock {
546
550
  })
547
551
  .then(() => {
548
552
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
553
+ this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
554
+ + `LockTargetState: ${this.LockTargetState} sent over BLE, sent successfully`);
549
555
  this.LockTargetState = this.hap.Characteristic.LockTargetState.SECURED;
550
556
  })
551
557
  .catch(async (e: any) => {
@@ -596,6 +602,8 @@ export class Lock {
596
602
  if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
597
603
  this.debugErrorLog(`${this.device.deviceType}: ${this.accessory.displayName} `
598
604
  + `statusCode: ${statusCode} & deviceStatus StatusCode: ${deviceStatus.statusCode}`);
605
+ this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
606
+ + `request to SwitchBot API, body: ${deviceStatus} sent successfully`);
599
607
  } else {
600
608
  this.statusCode(statusCode);
601
609
  this.statusCode(deviceStatus.statusCode);
@@ -843,6 +851,23 @@ export class Lock {
843
851
  }
844
852
  }
845
853
 
854
+ async deviceRetry(device: device & devicesConfig): Promise<void> {
855
+ if (!device.maxRetries) {
856
+ this.maxRetries = 5; // Maximum number of retries
857
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Max Retries Not Set, Using: ${this.maxRetries}`);
858
+ } else {
859
+ this.maxRetries = device.maxRetries;
860
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Max Retries: ${this.maxRetries}`);
861
+ }
862
+ if (!device.delayBetweenRetries) {
863
+ this.delayBetweenRetries = 3000; // Delay between retries in milliseconds
864
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Delay Between Retries Not Set, Using: ${this.delayBetweenRetries}`);
865
+ } else {
866
+ this.delayBetweenRetries = device.delayBetweenRetries * 1000;
867
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Delay Between Retries: ${this.delayBetweenRetries}`);
868
+ }
869
+ }
870
+
846
871
  async deviceConfig(device: device & devicesConfig): Promise<void> {
847
872
  let config = {};
848
873
  if (device.lock) {
@@ -890,6 +915,12 @@ export class Lock {
890
915
  /**
891
916
  * Logging for Device
892
917
  */
918
+ successLog(...log: any[]): void {
919
+ if (this.enablingDeviceLogging()) {
920
+ this.platform.log.success(String(...log));
921
+ }
922
+ }
923
+
893
924
  infoLog(...log: any[]): void {
894
925
  if (this.enablingDeviceLogging()) {
895
926
  this.platform.log.info(String(...log));
@@ -3,7 +3,6 @@ import { CharacteristicValue, PlatformAccessory, Service, Units, API, Logging, H
3
3
  import { MqttClient } from 'mqtt';
4
4
  import { hostname } from 'os';
5
5
  import { interval } from 'rxjs';
6
- import { request } from 'undici';
7
6
  import { SwitchBotPlatform } from '../platform.js';
8
7
  import { Devices, device, deviceStatus, devicesConfig, serviceData, temperature, SwitchBotPlatformConfig } from '../settings.js';
9
8
  import { sleep } from '../utils.js';
@@ -51,6 +50,8 @@ export class Meter {
51
50
  scanDuration!: number;
52
51
  deviceLogging!: string;
53
52
  deviceRefreshRate!: number;
53
+ maxRetries!: number;
54
+ delayBetweenRetries!: number;
54
55
 
55
56
  // Connection
56
57
  private readonly OpenAPI: boolean;
@@ -75,6 +76,7 @@ export class Meter {
75
76
  this.deviceContext();
76
77
  this.setupHistoryService(device);
77
78
  this.setupMqtt(device);
79
+ this.deviceRetry(device);
78
80
  this.deviceConfig(device);
79
81
 
80
82
  this.CurrentRelativeHumidity = accessory.context.CurrentRelativeHumidity;
@@ -398,9 +400,10 @@ export class Meter {
398
400
  async openAPIRefreshStatus(): Promise<void> {
399
401
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
400
402
  try {
401
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/status`, {
402
- headers: this.platform.generateHeaders(),
403
- });
403
+ const { body, statusCode } = await this.platform.retryRequest(this.maxRetries, this.delayBetweenRetries,
404
+ `${Devices}/${this.device.deviceId}/status`, {
405
+ headers: this.platform.generateHeaders(),
406
+ });
404
407
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
405
408
  const deviceStatus: any = await body.json();
406
409
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
@@ -736,6 +739,23 @@ export class Meter {
736
739
  }
737
740
  }
738
741
 
742
+ async deviceRetry(device: device & devicesConfig): Promise<void> {
743
+ if (!device.maxRetries) {
744
+ this.maxRetries = 5; // Maximum number of retries
745
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Max Retries Not Set, Using: ${this.maxRetries}`);
746
+ } else {
747
+ this.maxRetries = device.maxRetries;
748
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Max Retries: ${this.maxRetries}`);
749
+ }
750
+ if (!device.delayBetweenRetries) {
751
+ this.delayBetweenRetries = 3000; // Delay between retries in milliseconds
752
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Delay Between Retries Not Set, Using: ${this.delayBetweenRetries}`);
753
+ } else {
754
+ this.delayBetweenRetries = device.delayBetweenRetries * 1000;
755
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Delay Between Retries: ${this.delayBetweenRetries}`);
756
+ }
757
+ }
758
+
739
759
  async deviceConfig(device: device & devicesConfig): Promise<void> {
740
760
  let config = {};
741
761
  if (device.meter) {
@@ -786,6 +806,12 @@ export class Meter {
786
806
  /**
787
807
  * Logging for Device
788
808
  */
809
+ successLog(...log: any[]): void {
810
+ if (this.enablingDeviceLogging()) {
811
+ this.platform.log.success(String(...log));
812
+ }
813
+ }
814
+
789
815
  infoLog(...log: any[]): void {
790
816
  if (this.enablingDeviceLogging()) {
791
817
  this.platform.log.info(String(...log));
@@ -3,7 +3,6 @@ import { CharacteristicValue, PlatformAccessory, Service, Units, API, Logging, H
3
3
  import { MqttClient } from 'mqtt';
4
4
  import { hostname } from 'os';
5
5
  import { interval } from 'rxjs';
6
- import { request } from 'undici';
7
6
  import { SwitchBotPlatform } from '../platform.js';
8
7
  import { Devices, device, deviceStatus, devicesConfig, serviceData, temperature, SwitchBotPlatformConfig } from '../settings.js';
9
8
  import { sleep } from '../utils.js';
@@ -56,6 +55,8 @@ export class MeterPlus {
56
55
  scanDuration!: number;
57
56
  deviceLogging!: string;
58
57
  deviceRefreshRate!: number;
58
+ maxRetries!: number;
59
+ delayBetweenRetries!: number;
59
60
 
60
61
  // Connection
61
62
  private readonly OpenAPI: boolean;
@@ -80,6 +81,7 @@ export class MeterPlus {
80
81
  this.deviceContext();
81
82
  this.setupHistoryService(device);
82
83
  this.setupMqtt(device);
84
+ this.deviceRetry(device);
83
85
  this.deviceConfig(device);
84
86
 
85
87
  // Retrieve initial values and updateHomekit
@@ -400,9 +402,10 @@ export class MeterPlus {
400
402
  async openAPIRefreshStatus(): Promise<void> {
401
403
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
402
404
  try {
403
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/status`, {
404
- headers: this.platform.generateHeaders(),
405
- });
405
+ const { body, statusCode } = await this.platform.retryRequest(this.maxRetries, this.delayBetweenRetries,
406
+ `${Devices}/${this.device.deviceId}/status`, {
407
+ headers: this.platform.generateHeaders(),
408
+ });
406
409
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
407
410
  const deviceStatus: any = await body.json();
408
411
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
@@ -751,6 +754,23 @@ export class MeterPlus {
751
754
  }
752
755
  }
753
756
 
757
+ async deviceRetry(device: device & devicesConfig): Promise<void> {
758
+ if (!device.maxRetries) {
759
+ this.maxRetries = 5; // Maximum number of retries
760
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Max Retries Not Set, Using: ${this.maxRetries}`);
761
+ } else {
762
+ this.maxRetries = device.maxRetries;
763
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Max Retries: ${this.maxRetries}`);
764
+ }
765
+ if (!device.delayBetweenRetries) {
766
+ this.delayBetweenRetries = 3000; // Delay between retries in milliseconds
767
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Delay Between Retries Not Set, Using: ${this.delayBetweenRetries}`);
768
+ } else {
769
+ this.delayBetweenRetries = device.delayBetweenRetries * 1000;
770
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Delay Between Retries: ${this.delayBetweenRetries}`);
771
+ }
772
+ }
773
+
754
774
  async deviceConfig(device: device & devicesConfig): Promise<void> {
755
775
  let config = {};
756
776
  if (device.meter) {
@@ -801,6 +821,12 @@ export class MeterPlus {
801
821
  /**
802
822
  * Logging for Device
803
823
  */
824
+ successLog(...log: any[]): void {
825
+ if (this.enablingDeviceLogging()) {
826
+ this.platform.log.success(String(...log));
827
+ }
828
+ }
829
+
804
830
  infoLog(...log: any[]): void {
805
831
  if (this.enablingDeviceLogging()) {
806
832
  this.platform.log.info(String(...log));
@@ -1,4 +1,3 @@
1
- import { request } from 'undici';
2
1
  import { sleep } from '../utils.js';
3
2
  import { interval, Subject } from 'rxjs';
4
3
  import { skipWhile } from 'rxjs/operators';
@@ -49,6 +48,8 @@ export class Motion {
49
48
  scanDuration!: number;
50
49
  deviceLogging!: string;
51
50
  deviceRefreshRate!: number;
51
+ maxRetries!: number;
52
+ delayBetweenRetries!: number;
52
53
 
53
54
  // Updates
54
55
  motionUbpdateInProgress!: boolean;
@@ -75,6 +76,7 @@ export class Motion {
75
76
  this.scan(device);
76
77
  this.refreshRate(device);
77
78
  this.deviceContext();
79
+ this.deviceRetry(device);
78
80
  this.deviceConfig(device);
79
81
 
80
82
  // this is subject we use to track when we need to POST changes to the SwitchBot API
@@ -392,9 +394,10 @@ export class Motion {
392
394
  async openAPIRefreshStatus(): Promise<void> {
393
395
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
394
396
  try {
395
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/status`, {
396
- headers: this.platform.generateHeaders(),
397
- });
397
+ const { body, statusCode } = await this.platform.retryRequest(this.maxRetries, this.delayBetweenRetries,
398
+ `${Devices}/${this.device.deviceId}/status`, {
399
+ headers: this.platform.generateHeaders(),
400
+ });
398
401
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
399
402
  const deviceStatus: any = await body.json();
400
403
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
@@ -665,6 +668,23 @@ export class Motion {
665
668
  }
666
669
  }
667
670
 
671
+ async deviceRetry(device: device & devicesConfig): Promise<void> {
672
+ if (!device.maxRetries) {
673
+ this.maxRetries = 5; // Maximum number of retries
674
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Max Retries Not Set, Using: ${this.maxRetries}`);
675
+ } else {
676
+ this.maxRetries = device.maxRetries;
677
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Max Retries: ${this.maxRetries}`);
678
+ }
679
+ if (!device.delayBetweenRetries) {
680
+ this.delayBetweenRetries = 3000; // Delay between retries in milliseconds
681
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Delay Between Retries Not Set, Using: ${this.delayBetweenRetries}`);
682
+ } else {
683
+ this.delayBetweenRetries = device.delayBetweenRetries * 1000;
684
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Delay Between Retries: ${this.delayBetweenRetries}`);
685
+ }
686
+ }
687
+
668
688
  async deviceConfig(device: device & devicesConfig): Promise<void> {
669
689
  let config = {};
670
690
  if (device.motion) {
@@ -715,6 +735,12 @@ export class Motion {
715
735
  /**
716
736
  * Logging for Device
717
737
  */
738
+ successLog(...log: any[]): void {
739
+ if (this.enablingDeviceLogging()) {
740
+ this.platform.log.success(String(...log));
741
+ }
742
+ }
743
+
718
744
  infoLog(...log: any[]): void {
719
745
  if (this.enablingDeviceLogging()) {
720
746
  this.platform.log.info(String(...log));