@switchbot/homebridge-switchbot 3.5.0-beta.17 → 3.5.0-beta.19

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 (96) hide show
  1. package/CHANGELOG.md +1 -0
  2. package/config.schema.json +18 -0
  3. package/dist/device/blindtilt.d.ts +3 -0
  4. package/dist/device/blindtilt.d.ts.map +1 -1
  5. package/dist/device/blindtilt.js +28 -1
  6. package/dist/device/blindtilt.js.map +1 -1
  7. package/dist/device/bot.d.ts +3 -0
  8. package/dist/device/bot.d.ts.map +1 -1
  9. package/dist/device/bot.js +22 -1
  10. package/dist/device/bot.js.map +1 -1
  11. package/dist/device/ceilinglight.d.ts +3 -0
  12. package/dist/device/ceilinglight.d.ts.map +1 -1
  13. package/dist/device/ceilinglight.js +22 -1
  14. package/dist/device/ceilinglight.js.map +1 -1
  15. package/dist/device/colorbulb.d.ts +3 -0
  16. package/dist/device/colorbulb.d.ts.map +1 -1
  17. package/dist/device/colorbulb.js +22 -1
  18. package/dist/device/colorbulb.js.map +1 -1
  19. package/dist/device/contact.d.ts +3 -0
  20. package/dist/device/contact.d.ts.map +1 -1
  21. package/dist/device/contact.js +22 -2
  22. package/dist/device/contact.js.map +1 -1
  23. package/dist/device/curtain.d.ts +3 -0
  24. package/dist/device/curtain.d.ts.map +1 -1
  25. package/dist/device/curtain.js +22 -1
  26. package/dist/device/curtain.js.map +1 -1
  27. package/dist/device/hub.d.ts +3 -0
  28. package/dist/device/hub.d.ts.map +1 -1
  29. package/dist/device/hub.js +22 -2
  30. package/dist/device/hub.js.map +1 -1
  31. package/dist/device/humidifier.d.ts +3 -0
  32. package/dist/device/humidifier.d.ts.map +1 -1
  33. package/dist/device/humidifier.js +22 -1
  34. package/dist/device/humidifier.js.map +1 -1
  35. package/dist/device/iosensor.d.ts +3 -0
  36. package/dist/device/iosensor.d.ts.map +1 -1
  37. package/dist/device/iosensor.js +22 -2
  38. package/dist/device/iosensor.js.map +1 -1
  39. package/dist/device/lightstrip.d.ts +3 -0
  40. package/dist/device/lightstrip.d.ts.map +1 -1
  41. package/dist/device/lightstrip.js +22 -1
  42. package/dist/device/lightstrip.js.map +1 -1
  43. package/dist/device/lock.d.ts +3 -0
  44. package/dist/device/lock.d.ts.map +1 -1
  45. package/dist/device/lock.js +22 -1
  46. package/dist/device/lock.js.map +1 -1
  47. package/dist/device/meter.d.ts +3 -0
  48. package/dist/device/meter.d.ts.map +1 -1
  49. package/dist/device/meter.js +22 -2
  50. package/dist/device/meter.js.map +1 -1
  51. package/dist/device/meterplus.d.ts +3 -0
  52. package/dist/device/meterplus.d.ts.map +1 -1
  53. package/dist/device/meterplus.js +22 -2
  54. package/dist/device/meterplus.js.map +1 -1
  55. package/dist/device/motion.d.ts +3 -0
  56. package/dist/device/motion.d.ts.map +1 -1
  57. package/dist/device/motion.js +22 -2
  58. package/dist/device/motion.js.map +1 -1
  59. package/dist/device/plug.d.ts +3 -0
  60. package/dist/device/plug.d.ts.map +1 -1
  61. package/dist/device/plug.js +22 -1
  62. package/dist/device/plug.js.map +1 -1
  63. package/dist/device/robotvacuumcleaner.d.ts +3 -0
  64. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  65. package/dist/device/robotvacuumcleaner.js +22 -1
  66. package/dist/device/robotvacuumcleaner.js.map +1 -1
  67. package/dist/device/waterdetector.d.ts +3 -0
  68. package/dist/device/waterdetector.d.ts.map +1 -1
  69. package/dist/device/waterdetector.js +22 -2
  70. package/dist/device/waterdetector.js.map +1 -1
  71. package/dist/platform.d.ts +9 -0
  72. package/dist/platform.d.ts.map +1 -1
  73. package/dist/platform.js +24 -1
  74. package/dist/platform.js.map +1 -1
  75. package/dist/settings.d.ts +2 -0
  76. package/dist/settings.d.ts.map +1 -1
  77. package/package.json +9 -9
  78. package/src/device/blindtilt.ts +30 -3
  79. package/src/device/bot.ts +24 -3
  80. package/src/device/ceilinglight.ts +24 -3
  81. package/src/device/colorbulb.ts +24 -3
  82. package/src/device/contact.ts +24 -4
  83. package/src/device/curtain.ts +24 -3
  84. package/src/device/hub.ts +24 -4
  85. package/src/device/humidifier.ts +24 -3
  86. package/src/device/iosensor.ts +24 -4
  87. package/src/device/lightstrip.ts +24 -3
  88. package/src/device/lock.ts +24 -3
  89. package/src/device/meter.ts +24 -4
  90. package/src/device/meterplus.ts +24 -4
  91. package/src/device/motion.ts +24 -4
  92. package/src/device/plug.ts +24 -3
  93. package/src/device/robotvacuumcleaner.ts +24 -3
  94. package/src/device/waterdetector.ts +24 -4
  95. package/src/platform.ts +27 -2
  96. package/src/settings.ts +2 -0
@@ -79,6 +79,8 @@ export class BlindTilt {
79
79
  deviceRefreshRate!: number;
80
80
  setCloseMode!: string;
81
81
  setOpenMode!: string;
82
+ maxRetries!: number;
83
+ delayBetweenRetries!: number;
82
84
 
83
85
  // Updates
84
86
  blindTiltUpdateInProgress!: boolean;
@@ -106,6 +108,7 @@ export class BlindTilt {
106
108
  this.scan(device);
107
109
  this.setupMqtt(device);
108
110
  this.deviceContext();
111
+ this.deviceRetry(device);
109
112
  this.deviceConfig(device);
110
113
 
111
114
  this.mappingMode = (device.blindTilt?.mode as BlindTiltMappingMode) ?? BlindTiltMappingMode.OnlyUp;
@@ -594,9 +597,10 @@ export class BlindTilt {
594
597
  async openAPIRefreshStatus(): Promise<void> {
595
598
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
596
599
  try {
597
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/status`, {
598
- headers: this.platform.generateHeaders(),
599
- });
600
+ const { body, statusCode } = await this.platform.retryRequest(this.maxRetries, this.delayBetweenRetries,
601
+ `${Devices}/${this.device.deviceId}/status`, {
602
+ headers: this.platform.generateHeaders(),
603
+ });
600
604
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
601
605
  const deviceStatus: any = await body.json();
602
606
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
@@ -1382,6 +1386,23 @@ export class BlindTilt {
1382
1386
  }
1383
1387
  }
1384
1388
 
1389
+ async deviceRetry(device: device & devicesConfig): Promise<void> {
1390
+ if (device.maxRetries === undefined) {
1391
+ this.maxRetries = 5; // Maximum number of retries
1392
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Max Retries Not Set, Using: ${this.maxRetries}`);
1393
+ } else {
1394
+ this.maxRetries = device.maxRetries;
1395
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Max Retries: ${this.maxRetries}`);
1396
+ }
1397
+ if (device.delayBetweenRetries === undefined) {
1398
+ this.delayBetweenRetries = 3000; // Delay between retries in milliseconds
1399
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Delay Between Retries Not Set, Using: ${this.delayBetweenRetries}`);
1400
+ } else {
1401
+ this.delayBetweenRetries = device.delayBetweenRetries;
1402
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Delay Between Retries: ${this.delayBetweenRetries}`);
1403
+ }
1404
+ }
1405
+
1385
1406
  async deviceConfig(device: device & devicesConfig): Promise<void> {
1386
1407
  let config = {};
1387
1408
  if (device.blindTilt) {
@@ -1411,6 +1432,12 @@ export class BlindTilt {
1411
1432
  if (device.webhook !== undefined) {
1412
1433
  config['webhook'] = device.webhook;
1413
1434
  }
1435
+ if (device.maxRetries !== undefined) {
1436
+ config['maxRetries'] = device.maxRetries;
1437
+ }
1438
+ if (device.delayBetweenRetries !== undefined) {
1439
+ config['delayBetweenRetries'] = device.delayBetweenRetries;
1440
+ }
1414
1441
  if (device.blindTilt?.mode === undefined) {
1415
1442
  config['mode'] = BlindTiltMappingMode.OnlyUp;
1416
1443
  } else {
package/src/device/bot.ts CHANGED
@@ -58,6 +58,8 @@ export class Bot {
58
58
  deviceLogging!: string;
59
59
  multiPressCount!: number;
60
60
  deviceRefreshRate!: number;
61
+ maxRetries!: number;
62
+ delayBetweenRetries!: number;
61
63
 
62
64
  // Updates
63
65
  botUpdateInProgress!: boolean;
@@ -88,6 +90,7 @@ export class Bot {
88
90
  this.allowPushChanges(device);
89
91
  this.deviceContext();
90
92
  this.DoublePress(device);
93
+ this.deviceRetry(device);
91
94
  this.deviceConfig(device);
92
95
 
93
96
  this.multiPressCount = 0;
@@ -623,9 +626,10 @@ export class Bot {
623
626
  async openAPIRefreshStatus(): Promise<void> {
624
627
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
625
628
  try {
626
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/status`, {
627
- headers: this.platform.generateHeaders(),
628
- });
629
+ const { body, statusCode } = await this.platform.retryRequest(this.maxRetries, this.delayBetweenRetries,
630
+ `${Devices}/${this.device.deviceId}/status`, {
631
+ headers: this.platform.generateHeaders(),
632
+ });
629
633
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
630
634
  const deviceStatus: any = await body.json();
631
635
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
@@ -1483,6 +1487,23 @@ export class Bot {
1483
1487
  }
1484
1488
  }
1485
1489
 
1490
+ async deviceRetry(device: device & devicesConfig): Promise<void> {
1491
+ if (device.maxRetries === undefined) {
1492
+ this.maxRetries = 5; // Maximum number of retries
1493
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Max Retries Not Set, Using: ${this.maxRetries}`);
1494
+ } else {
1495
+ this.maxRetries = device.maxRetries;
1496
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Max Retries: ${this.maxRetries}`);
1497
+ }
1498
+ if (device.delayBetweenRetries === undefined) {
1499
+ this.delayBetweenRetries = 3000; // Delay between retries in milliseconds
1500
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Delay Between Retries Not Set, Using: ${this.delayBetweenRetries}`);
1501
+ } else {
1502
+ this.delayBetweenRetries = device.delayBetweenRetries;
1503
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Delay Between Retries: ${this.delayBetweenRetries}`);
1504
+ }
1505
+ }
1506
+
1486
1507
  async deviceConfig(device: device & devicesConfig): Promise<void> {
1487
1508
  let config = {};
1488
1509
  if (device.bot) {
@@ -50,6 +50,8 @@ export class CeilingLight {
50
50
  deviceLogging!: string;
51
51
  deviceRefreshRate!: number;
52
52
  adaptiveLightingShift?: number;
53
+ maxRetries!: number;
54
+ delayBetweenRetries!: number;
53
55
 
54
56
  // Adaptive Lighting
55
57
  AdaptiveLightingController?: ControllerConstructor | Controller<ControllerServiceMap>;
@@ -85,6 +87,7 @@ export class CeilingLight {
85
87
  this.refreshRate(device);
86
88
  this.adaptiveLighting(device);
87
89
  this.deviceContext();
90
+ this.deviceRetry(device);
88
91
  this.deviceConfig(device);
89
92
 
90
93
  // this is subject we use to track when we need to POST changes to the SwitchBot API
@@ -461,9 +464,10 @@ export class CeilingLight {
461
464
  async openAPIRefreshStatus() {
462
465
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
463
466
  try {
464
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/status`, {
465
- headers: this.platform.generateHeaders(),
466
- });
467
+ const { body, statusCode } = await this.platform.retryRequest(this.maxRetries, this.delayBetweenRetries,
468
+ `${Devices}/${this.device.deviceId}/status`, {
469
+ headers: this.platform.generateHeaders(),
470
+ });
467
471
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
468
472
  const deviceStatus: any = await body.json();
469
473
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
@@ -1144,6 +1148,23 @@ export class CeilingLight {
1144
1148
  }
1145
1149
  }
1146
1150
 
1151
+ async deviceRetry(device: device & devicesConfig): Promise<void> {
1152
+ if (device.maxRetries === undefined) {
1153
+ this.maxRetries = 5; // Maximum number of retries
1154
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Max Retries Not Set, Using: ${this.maxRetries}`);
1155
+ } else {
1156
+ this.maxRetries = device.maxRetries;
1157
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Max Retries: ${this.maxRetries}`);
1158
+ }
1159
+ if (device.delayBetweenRetries === undefined) {
1160
+ this.delayBetweenRetries = 3000; // Delay between retries in milliseconds
1161
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Delay Between Retries Not Set, Using: ${this.delayBetweenRetries}`);
1162
+ } else {
1163
+ this.delayBetweenRetries = device.delayBetweenRetries;
1164
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Delay Between Retries: ${this.delayBetweenRetries}`);
1165
+ }
1166
+ }
1167
+
1147
1168
  async deviceConfig(device: device & devicesConfig): Promise<void> {
1148
1169
  let config = {};
1149
1170
  if (device.ceilinglight) {
@@ -58,6 +58,8 @@ export class ColorBulb {
58
58
  deviceLogging!: string;
59
59
  deviceRefreshRate!: number;
60
60
  adaptiveLightingShift?: number;
61
+ maxRetries!: number;
62
+ delayBetweenRetries!: number;
61
63
 
62
64
  // Adaptive Lighting
63
65
  AdaptiveLightingController?: ControllerConstructor | Controller<ControllerServiceMap>;
@@ -93,6 +95,7 @@ export class ColorBulb {
93
95
  this.refreshRate(device);
94
96
  this.adaptiveLighting(device);
95
97
  this.deviceContext();
98
+ this.deviceRetry(device);
96
99
  this.deviceConfig(device);
97
100
 
98
101
  // this is subject we use to track when we need to POST changes to the SwitchBot API
@@ -527,9 +530,10 @@ export class ColorBulb {
527
530
  async openAPIRefreshStatus() {
528
531
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
529
532
  try {
530
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/status`, {
531
- headers: this.platform.generateHeaders(),
532
- });
533
+ const { body, statusCode } = await this.platform.retryRequest(this.maxRetries, this.delayBetweenRetries,
534
+ `${Devices}/${this.device.deviceId}/status`, {
535
+ headers: this.platform.generateHeaders(),
536
+ });
533
537
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
534
538
  const deviceStatus: any = await body.json();
535
539
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
@@ -1353,6 +1357,23 @@ export class ColorBulb {
1353
1357
  }
1354
1358
  }
1355
1359
 
1360
+ async deviceRetry(device: device & devicesConfig): Promise<void> {
1361
+ if (device.maxRetries === undefined) {
1362
+ this.maxRetries = 5; // Maximum number of retries
1363
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Max Retries Not Set, Using: ${this.maxRetries}`);
1364
+ } else {
1365
+ this.maxRetries = device.maxRetries;
1366
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Max Retries: ${this.maxRetries}`);
1367
+ }
1368
+ if (device.delayBetweenRetries === undefined) {
1369
+ this.delayBetweenRetries = 3000; // Delay between retries in milliseconds
1370
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Delay Between Retries Not Set, Using: ${this.delayBetweenRetries}`);
1371
+ } else {
1372
+ this.delayBetweenRetries = device.delayBetweenRetries;
1373
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Delay Between Retries: ${this.delayBetweenRetries}`);
1374
+ }
1375
+ }
1376
+
1356
1377
  async deviceConfig(device: device & devicesConfig): Promise<void> {
1357
1378
  let config = {};
1358
1379
  if (device.colorbulb) {
@@ -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';
@@ -53,6 +52,8 @@ export class Contact {
53
52
  scanDuration!: number;
54
53
  deviceLogging!: string;
55
54
  deviceRefreshRate!: number;
55
+ maxRetries!: number;
56
+ delayBetweenRetries!: number;
56
57
 
57
58
  // Updates
58
59
  contactUbpdateInProgress!: boolean;
@@ -79,6 +80,7 @@ export class Contact {
79
80
  this.scan(device);
80
81
  this.refreshRate(device);
81
82
  this.deviceContext();
83
+ this.deviceRetry(device);
82
84
  this.deviceConfig(device);
83
85
 
84
86
  // this is subject we use to track when we need to POST changes to the SwitchBot API
@@ -437,9 +439,10 @@ export class Contact {
437
439
  async openAPIRefreshStatus(): Promise<void> {
438
440
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
439
441
  try {
440
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/status`, {
441
- headers: this.platform.generateHeaders(),
442
- });
442
+ const { body, statusCode } = await this.platform.retryRequest(this.maxRetries, this.delayBetweenRetries,
443
+ `${Devices}/${this.device.deviceId}/status`, {
444
+ headers: this.platform.generateHeaders(),
445
+ });
443
446
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
444
447
  const deviceStatus: any = await body.json();
445
448
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
@@ -708,6 +711,23 @@ export class Contact {
708
711
  }
709
712
  }
710
713
 
714
+ async deviceRetry(device: device & devicesConfig): Promise<void> {
715
+ if (device.maxRetries === undefined) {
716
+ this.maxRetries = 5; // Maximum number of retries
717
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Max Retries Not Set, Using: ${this.maxRetries}`);
718
+ } else {
719
+ this.maxRetries = device.maxRetries;
720
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Max Retries: ${this.maxRetries}`);
721
+ }
722
+ if (device.delayBetweenRetries === undefined) {
723
+ this.delayBetweenRetries = 3000; // Delay between retries in milliseconds
724
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Delay Between Retries Not Set, Using: ${this.delayBetweenRetries}`);
725
+ } else {
726
+ this.delayBetweenRetries = device.delayBetweenRetries;
727
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Delay Between Retries: ${this.delayBetweenRetries}`);
728
+ }
729
+ }
730
+
711
731
  async deviceConfig(device: device & devicesConfig): Promise<void> {
712
732
  let config = {};
713
733
  if (device.contact) {
@@ -68,6 +68,8 @@ export class Curtain {
68
68
  scanDuration!: number;
69
69
  deviceLogging!: string;
70
70
  deviceRefreshRate!: number;
71
+ maxRetries!: number;
72
+ delayBetweenRetries!: number;
71
73
 
72
74
  // Updates
73
75
  curtainUpdateInProgress!: boolean;
@@ -98,6 +100,7 @@ export class Curtain {
98
100
  this.scan(device);
99
101
  this.setupMqtt(device);
100
102
  this.deviceContext();
103
+ this.deviceRetry(device);
101
104
  this.deviceConfig(device);
102
105
 
103
106
  // this is subject we use to track when we need to POST changes to the SwitchBot API
@@ -634,9 +637,10 @@ export class Curtain {
634
637
  async openAPIRefreshStatus(): Promise<void> {
635
638
  this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
636
639
  try {
637
- const { body, statusCode } = await request(`${Devices}/${this.device.deviceId}/status`, {
638
- headers: this.platform.generateHeaders(),
639
- });
640
+ const { body, statusCode } = await this.platform.retryRequest(this.maxRetries, this.delayBetweenRetries,
641
+ `${Devices}/${this.device.deviceId}/status`, {
642
+ headers: this.platform.generateHeaders(),
643
+ });
640
644
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
641
645
  const deviceStatus: any = await body.json();
642
646
  this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus: ${JSON.stringify(deviceStatus)}`);
@@ -1310,6 +1314,23 @@ export class Curtain {
1310
1314
  }
1311
1315
  }
1312
1316
 
1317
+ async deviceRetry(device: device & devicesConfig): Promise<void> {
1318
+ if (device.maxRetries === undefined) {
1319
+ this.maxRetries = 5; // Maximum number of retries
1320
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Max Retries Not Set, Using: ${this.maxRetries}`);
1321
+ } else {
1322
+ this.maxRetries = device.maxRetries;
1323
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Max Retries: ${this.maxRetries}`);
1324
+ }
1325
+ if (device.delayBetweenRetries === undefined) {
1326
+ this.delayBetweenRetries = 3000; // Delay between retries in milliseconds
1327
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Delay Between Retries Not Set, Using: ${this.delayBetweenRetries}`);
1328
+ } else {
1329
+ this.delayBetweenRetries = device.delayBetweenRetries;
1330
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Delay Between Retries: ${this.delayBetweenRetries}`);
1331
+ }
1332
+ }
1333
+
1313
1334
  async deviceConfig(device: device & devicesConfig): Promise<void> {
1314
1335
  let config = {};
1315
1336
  if (device.curtain) {
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 === undefined) {
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 === undefined) {
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;
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) {
@@ -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)}`);
@@ -1023,6 +1027,23 @@ export class Humidifier {
1023
1027
  }
1024
1028
  }
1025
1029
 
1030
+ async deviceRetry(device: device & devicesConfig): Promise<void> {
1031
+ if (device.maxRetries === undefined) {
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 === undefined) {
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;
1043
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Delay Between Retries: ${this.delayBetweenRetries}`);
1044
+ }
1045
+ }
1046
+
1026
1047
  async deviceConfig(device: device & devicesConfig): Promise<void> {
1027
1048
  let config = {};
1028
1049
  if (device.humidifier) {
@@ -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 === undefined) {
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 === undefined) {
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;
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) {
@@ -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)}`);
@@ -1172,6 +1176,23 @@ export class StripLight {
1172
1176
  }
1173
1177
  }
1174
1178
 
1179
+ async deviceRetry(device: device & devicesConfig): Promise<void> {
1180
+ if (device.maxRetries === undefined) {
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 === undefined) {
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;
1192
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Delay Between Retries: ${this.delayBetweenRetries}`);
1193
+ }
1194
+ }
1195
+
1175
1196
  async deviceConfig(device: device & devicesConfig): Promise<void> {
1176
1197
  let config = {};
1177
1198
  if (device.striplight) {
@@ -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)}`);
@@ -847,6 +851,23 @@ export class Lock {
847
851
  }
848
852
  }
849
853
 
854
+ async deviceRetry(device: device & devicesConfig): Promise<void> {
855
+ if (device.maxRetries === undefined) {
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 === undefined) {
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;
867
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Delay Between Retries: ${this.delayBetweenRetries}`);
868
+ }
869
+ }
870
+
850
871
  async deviceConfig(device: device & devicesConfig): Promise<void> {
851
872
  let config = {};
852
873
  if (device.lock) {