@switchbot/homebridge-switchbot 3.5.0-beta.5 → 3.5.0-beta.50

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 (168) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/config.schema.json +120 -17
  3. package/dist/device/blindtilt.d.ts +21 -94
  4. package/dist/device/blindtilt.d.ts.map +1 -1
  5. package/dist/device/blindtilt.js +351 -757
  6. package/dist/device/blindtilt.js.map +1 -1
  7. package/dist/device/bot.d.ts +25 -71
  8. package/dist/device/bot.d.ts.map +1 -1
  9. package/dist/device/bot.js +587 -761
  10. package/dist/device/bot.js.map +1 -1
  11. package/dist/device/ceilinglight.d.ts +13 -67
  12. package/dist/device/ceilinglight.d.ts.map +1 -1
  13. package/dist/device/ceilinglight.js +213 -588
  14. package/dist/device/ceilinglight.js.map +1 -1
  15. package/dist/device/colorbulb.d.ts +13 -74
  16. package/dist/device/colorbulb.d.ts.map +1 -1
  17. package/dist/device/colorbulb.js +255 -634
  18. package/dist/device/colorbulb.js.map +1 -1
  19. package/dist/device/contact.d.ts +14 -65
  20. package/dist/device/contact.d.ts.map +1 -1
  21. package/dist/device/contact.js +208 -532
  22. package/dist/device/contact.js.map +1 -1
  23. package/dist/device/curtain.d.ts +17 -86
  24. package/dist/device/curtain.d.ts.map +1 -1
  25. package/dist/device/curtain.js +339 -787
  26. package/dist/device/curtain.js.map +1 -1
  27. package/dist/device/device.d.ts +59 -0
  28. package/dist/device/device.d.ts.map +1 -0
  29. package/dist/device/device.js +681 -0
  30. package/dist/device/device.js.map +1 -0
  31. package/dist/device/fan.d.ts +51 -0
  32. package/dist/device/fan.d.ts.map +1 -0
  33. package/dist/device/fan.js +504 -0
  34. package/dist/device/fan.js.map +1 -0
  35. package/dist/device/hub.d.ts +15 -59
  36. package/dist/device/hub.d.ts.map +1 -1
  37. package/dist/device/hub.js +246 -597
  38. package/dist/device/hub.js.map +1 -1
  39. package/dist/device/humidifier.d.ts +10 -65
  40. package/dist/device/humidifier.d.ts.map +1 -1
  41. package/dist/device/humidifier.js +217 -579
  42. package/dist/device/humidifier.js.map +1 -1
  43. package/dist/device/iosensor.d.ts +11 -64
  44. package/dist/device/iosensor.d.ts.map +1 -1
  45. package/dist/device/iosensor.js +178 -585
  46. package/dist/device/iosensor.js.map +1 -1
  47. package/dist/device/lightstrip.d.ts +10 -68
  48. package/dist/device/lightstrip.d.ts.map +1 -1
  49. package/dist/device/lightstrip.js +256 -569
  50. package/dist/device/lightstrip.js.map +1 -1
  51. package/dist/device/lock.d.ts +15 -62
  52. package/dist/device/lock.d.ts.map +1 -1
  53. package/dist/device/lock.js +214 -543
  54. package/dist/device/lock.js.map +1 -1
  55. package/dist/device/meter.d.ts +13 -63
  56. package/dist/device/meter.d.ts.map +1 -1
  57. package/dist/device/meter.js +174 -578
  58. package/dist/device/meter.js.map +1 -1
  59. package/dist/device/meterplus.d.ts +13 -64
  60. package/dist/device/meterplus.d.ts.map +1 -1
  61. package/dist/device/meterplus.js +163 -578
  62. package/dist/device/meterplus.js.map +1 -1
  63. package/dist/device/motion.d.ts +13 -69
  64. package/dist/device/motion.d.ts.map +1 -1
  65. package/dist/device/motion.js +141 -520
  66. package/dist/device/motion.js.map +1 -1
  67. package/dist/device/plug.d.ts +9 -57
  68. package/dist/device/plug.d.ts.map +1 -1
  69. package/dist/device/plug.js +86 -453
  70. package/dist/device/plug.js.map +1 -1
  71. package/dist/device/robotvacuumcleaner.d.ts +11 -62
  72. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  73. package/dist/device/robotvacuumcleaner.js +144 -452
  74. package/dist/device/robotvacuumcleaner.js.map +1 -1
  75. package/dist/device/waterdetector.d.ts +9 -70
  76. package/dist/device/waterdetector.d.ts.map +1 -1
  77. package/dist/device/waterdetector.js +125 -665
  78. package/dist/device/waterdetector.js.map +1 -1
  79. package/dist/homebridge-ui/public/index.html +2 -2
  80. package/dist/index.js +1 -1
  81. package/dist/irdevice/airconditioner.d.ts +8 -48
  82. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  83. package/dist/irdevice/airconditioner.js +309 -419
  84. package/dist/irdevice/airconditioner.js.map +1 -1
  85. package/dist/irdevice/airpurifier.d.ts +7 -38
  86. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  87. package/dist/irdevice/airpurifier.js +72 -304
  88. package/dist/irdevice/airpurifier.js.map +1 -1
  89. package/dist/irdevice/camera.d.ts +6 -35
  90. package/dist/irdevice/camera.d.ts.map +1 -1
  91. package/dist/irdevice/camera.js +34 -278
  92. package/dist/irdevice/camera.js.map +1 -1
  93. package/dist/irdevice/fan.d.ts +6 -39
  94. package/dist/irdevice/fan.d.ts.map +1 -1
  95. package/dist/irdevice/fan.js +67 -311
  96. package/dist/irdevice/fan.js.map +1 -1
  97. package/dist/irdevice/irdevice.d.ts +40 -0
  98. package/dist/irdevice/irdevice.d.ts.map +1 -0
  99. package/dist/irdevice/irdevice.js +512 -0
  100. package/dist/irdevice/irdevice.js.map +1 -0
  101. package/dist/irdevice/light.d.ts +6 -34
  102. package/dist/irdevice/light.d.ts.map +1 -1
  103. package/dist/irdevice/light.js +23 -272
  104. package/dist/irdevice/light.js.map +1 -1
  105. package/dist/irdevice/other.d.ts +18 -47
  106. package/dist/irdevice/other.d.ts.map +1 -1
  107. package/dist/irdevice/other.js +352 -546
  108. package/dist/irdevice/other.js.map +1 -1
  109. package/dist/irdevice/tv.d.ts +7 -39
  110. package/dist/irdevice/tv.d.ts.map +1 -1
  111. package/dist/irdevice/tv.js +82 -321
  112. package/dist/irdevice/tv.js.map +1 -1
  113. package/dist/irdevice/vacuumcleaner.d.ts +6 -35
  114. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  115. package/dist/irdevice/vacuumcleaner.js +41 -284
  116. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  117. package/dist/irdevice/waterheater.d.ts +6 -35
  118. package/dist/irdevice/waterheater.d.ts.map +1 -1
  119. package/dist/irdevice/waterheater.js +42 -287
  120. package/dist/irdevice/waterheater.js.map +1 -1
  121. package/dist/platform.d.ts +14 -1
  122. package/dist/platform.d.ts.map +1 -1
  123. package/dist/platform.js +291 -147
  124. package/dist/platform.js.map +1 -1
  125. package/dist/settings.d.ts +41 -11
  126. package/dist/settings.d.ts.map +1 -1
  127. package/dist/settings.js +0 -552
  128. package/dist/settings.js.map +1 -1
  129. package/dist/utils.d.ts +77 -0
  130. package/dist/utils.d.ts.map +1 -1
  131. package/dist/utils.js +638 -1
  132. package/dist/utils.js.map +1 -1
  133. package/package.json +15 -14
  134. package/src/custom.d.ts +2 -1
  135. package/src/device/blindtilt.ts +377 -783
  136. package/src/device/bot.ts +620 -845
  137. package/src/device/ceilinglight.ts +226 -608
  138. package/src/device/colorbulb.ts +268 -657
  139. package/src/device/contact.ts +233 -554
  140. package/src/device/curtain.ts +359 -811
  141. package/src/device/device.ts +709 -0
  142. package/src/device/fan.ts +553 -0
  143. package/src/device/hub.ts +273 -625
  144. package/src/device/humidifier.ts +245 -624
  145. package/src/device/iosensor.ts +204 -611
  146. package/src/device/lightstrip.ts +277 -597
  147. package/src/device/lock.ts +251 -583
  148. package/src/device/meter.ts +199 -601
  149. package/src/device/meterplus.ts +188 -603
  150. package/src/device/motion.ts +160 -542
  151. package/src/device/plug.ts +96 -481
  152. package/src/device/robotvacuumcleaner.ts +165 -478
  153. package/src/device/waterdetector.ts +142 -689
  154. package/src/homebridge-ui/public/index.html +2 -2
  155. package/src/index.ts +1 -1
  156. package/src/irdevice/airconditioner.ts +330 -446
  157. package/src/irdevice/airpurifier.ts +89 -321
  158. package/src/irdevice/camera.ts +42 -293
  159. package/src/irdevice/fan.ts +78 -327
  160. package/src/irdevice/irdevice.ts +528 -0
  161. package/src/irdevice/light.ts +32 -287
  162. package/src/irdevice/other.ts +396 -615
  163. package/src/irdevice/tv.ts +100 -339
  164. package/src/irdevice/vacuumcleaner.ts +49 -305
  165. package/src/irdevice/waterheater.ts +50 -310
  166. package/src/platform.ts +301 -155
  167. package/src/settings.ts +57 -566
  168. package/src/utils.ts +642 -1
package/src/platform.ts CHANGED
@@ -1,4 +1,4 @@
1
- /* Copyright(C) 2017-2023, donavanbecker (https://github.com/donavanbecker). All rights reserved.
1
+ /* Copyright(C) 2017-2024, donavanbecker (https://github.com/donavanbecker). All rights reserved.
2
2
  *
3
3
  * platform.ts: @switchbot/homebridge-switchbot platform class.
4
4
  */
@@ -20,8 +20,9 @@ import { CeilingLight } from './device/ceilinglight.js';
20
20
  import { StripLight } from './device/lightstrip.js';
21
21
  import { Humidifier } from './device/humidifier.js';
22
22
  import { RobotVacuumCleaner } from './device/robotvacuumcleaner.js';
23
+ import { Fan } from './device/fan.js';
23
24
  import { TV } from './irdevice/tv.js';
24
- import { Fan } from './irdevice/fan.js';
25
+ import { IRFan } from './irdevice/fan.js';
25
26
  import { Light } from './irdevice/light.js';
26
27
  import { Others } from './irdevice/other.js';
27
28
  import { Camera } from './irdevice/camera.js';
@@ -32,16 +33,16 @@ import { VacuumCleaner } from './irdevice/vacuumcleaner.js';
32
33
  import { AirConditioner } from './irdevice/airconditioner.js';
33
34
  import * as http from 'http';
34
35
  import { Buffer } from 'buffer';
35
- import { request } from 'undici';
36
+ import { Dispatcher, request } from 'undici';
36
37
  import { MqttClient } from 'mqtt';
37
38
  import { queueScheduler } from 'rxjs';
38
39
  import fakegato from 'fakegato-history';
39
40
  import asyncmqtt from 'async-mqtt';
40
41
  import crypto, { randomUUID } from 'crypto';
41
42
  import { readFileSync, writeFileSync } from 'fs';
42
- import hbLib from 'homebridge-lib';
43
-
44
-
43
+ import { EveHomeKitTypes } from 'homebridge-lib/EveHomeKitTypes';
44
+ import { UrlObject } from 'url';
45
+ import { sleep } from './utils.js';
45
46
 
46
47
  /**
47
48
  * HomebridgePlatform
@@ -56,6 +57,8 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
56
57
  version!: string;
57
58
  Logging?: string;
58
59
  debugMode!: boolean;
60
+ maxRetries!: number;
61
+ delayBetweenRetries!: number;
59
62
  platformConfig!: SwitchBotPlatformConfig['options'];
60
63
  platformLogging!: SwitchBotPlatformConfig['logging'];
61
64
  config!: SwitchBotPlatformConfig;
@@ -104,7 +107,6 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
104
107
  }
105
108
 
106
109
  // import fakegato-history module and EVE characteristics
107
- const { EveHomeKitTypes } = hbLib;
108
110
  this.fakegatoAPI = fakegato(api);
109
111
  this.eve = new EveHomeKitTypes(api);
110
112
 
@@ -383,6 +385,21 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
383
385
  this.debugWarnLog('Using Default Push Rate.');
384
386
  }
385
387
 
388
+ if (!this.config.options.maxRetries) {
389
+ this.config.options.maxRetries = 5;
390
+ this.debugWarnLog('Using Default Max Retries.');
391
+ } else {
392
+ this.maxRetries = this.config.options.maxRetries;
393
+ }
394
+
395
+ if (!this.config.options.delayBetweenRetries) {
396
+ // default 3 seconds
397
+ this.config.options!.delayBetweenRetries! = 3000;
398
+ this.debugWarnLog('Using Default Delay Between Retries.');
399
+ } else {
400
+ this.delayBetweenRetries = this.config.options.delayBetweenRetries * 1000;
401
+ }
402
+
386
403
  if (!this.config.credentials && !this.config.options) {
387
404
  this.debugWarnLog('Missing Credentials');
388
405
  } else if (this.config.credentials && !this.config.credentials.notice) {
@@ -492,44 +509,98 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
492
509
  */
493
510
  async discoverDevices() {
494
511
  if (this.config.credentials?.token) {
495
- try {
496
- const { body, statusCode } = await request(Devices, {
497
- headers: this.generateHeaders(),
498
- });
499
- this.debugWarnLog(`statusCode: ${statusCode}`);
500
- const devicesAPI: any = await body.json();
501
- this.debugWarnLog(`devicesAPI: ${JSON.stringify(devicesAPI)}`);
502
- this.debugWarnLog(`devicesAPI Body: ${JSON.stringify(devicesAPI.body)}`);
503
- this.debugWarnLog(`devicesAPI StatusCode: ${devicesAPI.statusCode}`);
504
- if ((statusCode === 200 || statusCode === 100) && (devicesAPI.statusCode === 200 || devicesAPI.statusCode === 100)) {
505
- this.debugErrorLog(`statusCode: ${statusCode} & devicesAPI StatusCode: ${devicesAPI.statusCode}`);
506
- // SwitchBot Devices
507
- const deviceLists = devicesAPI.body.deviceList;
508
- this.debugWarnLog(`DeviceLists: ${JSON.stringify(deviceLists)}`);
509
- this.debugWarnLog(`DeviceLists Length: ${deviceLists.length}`);
510
- if (!this.config.options?.devices) {
511
- this.debugLog(`SwitchBot Device Config Not Set: ${JSON.stringify(this.config.options?.devices)}`);
512
- if (deviceLists.length === 0) {
513
- this.debugLog(`SwitchBot API Currently Doesn't Have Any Devices With Cloud Services Enabled: ${JSON.stringify(devicesAPI.body)}`);
514
- } else {
515
- const devices = deviceLists.map((v: any) => v);
516
- for (const device of devices) {
517
- if (device.deviceType) {
518
- if (device.configDeviceName) {
519
- device.deviceName = device.configDeviceName;
512
+ let retryCount = 0;
513
+ const maxRetries = this.maxRetries; // Maximum number of retries
514
+ const delayBetweenRetries = this.delayBetweenRetries; // Delay between retries in milliseconds
515
+ this.debugWarnLog(`Retry Count: ${retryCount}`);
516
+ this.debugWarnLog(`Max Retries: ${maxRetries}`);
517
+ this.debugWarnLog(`Delay Between Retries: ${delayBetweenRetries}`);
518
+ while (retryCount < maxRetries) {
519
+ try {
520
+ const { body, statusCode } = await request(Devices, {
521
+ headers: this.generateHeaders(),
522
+ });
523
+ this.debugWarnLog(`statusCode: ${statusCode}`);
524
+ const devicesAPI: any = await body.json();
525
+ this.debugWarnLog(`devicesAPI: ${JSON.stringify(devicesAPI)}`);
526
+ this.debugWarnLog(`devicesAPI Body: ${JSON.stringify(devicesAPI.body)}`);
527
+ this.debugWarnLog(`devicesAPI StatusCode: ${devicesAPI.statusCode}`);
528
+ if ((statusCode === 200 || statusCode === 100) && (devicesAPI.statusCode === 200 || devicesAPI.statusCode === 100)) {
529
+ this.debugErrorLog(`statusCode: ${statusCode} & devicesAPI StatusCode: ${devicesAPI.statusCode}`);
530
+ // SwitchBot Devices
531
+ const deviceLists = devicesAPI.body.deviceList;
532
+ this.debugWarnLog(`DeviceLists: ${JSON.stringify(deviceLists)}`);
533
+ this.debugWarnLog(`DeviceLists Length: ${deviceLists.length}`);
534
+ if (!this.config.options?.devices) {
535
+ this.debugLog(`SwitchBot Device Config Not Set: ${JSON.stringify(this.config.options?.devices)}`);
536
+ if (deviceLists.length === 0) {
537
+ this.debugLog(`SwitchBot API Currently Doesn't Have Any Devices With Cloud Services Enabled: ${JSON.stringify(devicesAPI.body)}`);
538
+ } else {
539
+ const devices = deviceLists.map((v: any) => v);
540
+ for (const device of devices) {
541
+ if (device.deviceType) {
542
+ if (device.configDeviceName) {
543
+ device.deviceName = device.configDeviceName;
544
+ }
545
+ this.createDevice(device);
520
546
  }
521
- this.createDevice(device);
522
547
  }
523
548
  }
549
+ } else if (this.config.credentials?.token && this.config.options.devices) {
550
+ this.debugLog(`SwitchBot Device Config Set: ${JSON.stringify(this.config.options?.devices)}`);
551
+ if (deviceLists.length === 0) {
552
+ this.debugLog(`SwitchBot API Currently Doesn't Have Any Devices With Cloud Services Enabled: ${JSON.stringify(devicesAPI.body)}`);
553
+ } else {
554
+ const deviceConfigs = this.config.options?.devices;
555
+
556
+ const mergeBydeviceId = (a1: { deviceId: string }[], a2: any[]) =>
557
+ a1.map((itm: { deviceId: string }) => ({
558
+ ...a2.find(
559
+ (item: { deviceId: string }) =>
560
+ item.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') === itm.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') && item,
561
+ ),
562
+ ...itm,
563
+ }));
564
+
565
+ const devices = mergeBydeviceId(deviceLists, deviceConfigs);
566
+ this.debugLog(`SwitchBot Devices: ${JSON.stringify(devices)}`);
567
+ for (const device of devices) {
568
+ if (!device.deviceType) {
569
+ device.deviceType = device.configDeviceType;
570
+ this.errorLog(`API has displaying no deviceType: ${device.deviceType}, So using configDeviceType: ${device.configDeviceType}`);
571
+ }
572
+ if (device.deviceType) {
573
+ if (device.configDeviceName) {
574
+ device.deviceName = device.configDeviceName;
575
+ }
576
+ this.createDevice(device);
577
+ }
578
+ }
579
+ }
580
+ } else {
581
+ this.errorLog('SwitchBot Token Supplied, Issue with Auth.');
524
582
  }
525
- } else if (this.config.credentials?.token && this.config.options.devices) {
526
- this.debugLog(`SwitchBot Device Config Set: ${JSON.stringify(this.config.options?.devices)}`);
527
- if (deviceLists.length === 0) {
528
- this.debugLog(`SwitchBot API Currently Doesn't Have Any Devices With Cloud Services Enabled: ${JSON.stringify(devicesAPI.body)}`);
583
+ if (devicesAPI.body.deviceList.length !== 0) {
584
+ this.infoLog(`Total SwitchBot Devices Found: ${devicesAPI.body.deviceList.length}`);
529
585
  } else {
530
- const deviceConfigs = this.config.options?.devices;
586
+ this.debugLog(`Total SwitchBot Devices Found: ${devicesAPI.body.deviceList.length}`);
587
+ }
531
588
 
532
- const mergeBydeviceId = (a1: { deviceId: string }[], a2: any[]) =>
589
+ // IR Devices
590
+ const irDeviceLists = devicesAPI.body.infraredRemoteList;
591
+ if (!this.config.options?.irdevices) {
592
+ this.debugLog(`IR Device Config Not Set: ${JSON.stringify(this.config.options?.irdevices)}`);
593
+ const devices = irDeviceLists.map((v: any) => v);
594
+ for (const device of devices) {
595
+ if (device.remoteType) {
596
+ this.createIRDevice(device);
597
+ }
598
+ }
599
+ } else {
600
+ this.debugLog(`IR Device Config Set: ${JSON.stringify(this.config.options?.irdevices)}`);
601
+ const irDeviceConfig = this.config.options?.irdevices;
602
+
603
+ const mergeIRBydeviceId = (a1: { deviceId: string }[], a2: any[]) =>
533
604
  a1.map((itm: { deviceId: string }) => ({
534
605
  ...a2.find(
535
606
  (item: { deviceId: string }) =>
@@ -538,73 +609,34 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
538
609
  ...itm,
539
610
  }));
540
611
 
541
- const devices = mergeBydeviceId(deviceLists, deviceConfigs);
542
- this.debugLog(`SwitchBot Devices: ${JSON.stringify(devices)}`);
612
+ const devices = mergeIRBydeviceId(irDeviceLists, irDeviceConfig);
613
+ this.debugLog(`IR Devices: ${JSON.stringify(devices)}`);
543
614
  for (const device of devices) {
544
- if (!device.deviceType) {
545
- device.deviceType = device.configDeviceType;
546
- this.errorLog(`API has displaying no deviceType: ${device.deviceType}, So using configDeviceType: ${device.configDeviceType}`);
547
- }
548
- if (device.deviceType) {
549
- if (device.configDeviceName) {
550
- device.deviceName = device.configDeviceName;
551
- }
552
- this.createDevice(device);
553
- }
554
- }
555
- }
556
- } else {
557
- this.errorLog('SwitchBot Token Supplied, Issue with Auth.');
558
- }
559
- if (devicesAPI.body.deviceList.length !== 0) {
560
- this.infoLog(`Total SwitchBot Devices Found: ${devicesAPI.body.deviceList.length}`);
561
- } else {
562
- this.debugLog(`Total SwitchBot Devices Found: ${devicesAPI.body.deviceList.length}`);
563
- }
564
-
565
- // IR Devices
566
- const irDeviceLists = devicesAPI.body.infraredRemoteList;
567
- if (!this.config.options?.irdevices) {
568
- this.debugLog(`IR Device Config Not Set: ${JSON.stringify(this.config.options?.irdevices)}`);
569
- const devices = irDeviceLists.map((v: any) => v);
570
- for (const device of devices) {
571
- if (device.remoteType) {
572
615
  this.createIRDevice(device);
573
616
  }
574
617
  }
575
- } else {
576
- this.debugLog(`IR Device Config Set: ${JSON.stringify(this.config.options?.irdevices)}`);
577
- const irDeviceConfig = this.config.options?.irdevices;
578
-
579
- const mergeIRBydeviceId = (a1: { deviceId: string }[], a2: any[]) =>
580
- a1.map((itm: { deviceId: string }) => ({
581
- ...a2.find(
582
- (item: { deviceId: string }) =>
583
- item.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') === itm.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') && item,
584
- ),
585
- ...itm,
586
- }));
587
-
588
- const devices = mergeIRBydeviceId(irDeviceLists, irDeviceConfig);
589
- this.debugLog(`IR Devices: ${JSON.stringify(devices)}`);
590
- for (const device of devices) {
591
- this.createIRDevice(device);
618
+ if (devicesAPI.body.infraredRemoteList.length !== 0) {
619
+ this.infoLog(`Total IR Devices Found: ${devicesAPI.body.infraredRemoteList.length}`);
620
+ } else {
621
+ this.debugLog(`Total IR Devices Found: ${devicesAPI.body.infraredRemoteList.length}`);
592
622
  }
593
- }
594
- if (devicesAPI.body.infraredRemoteList.length !== 0) {
595
- this.infoLog(`Total IR Devices Found: ${devicesAPI.body.infraredRemoteList.length}`);
623
+ break;
596
624
  } else {
597
- this.debugLog(`Total IR Devices Found: ${devicesAPI.body.infraredRemoteList.length}`);
625
+ this.statusCode(statusCode);
626
+ this.statusCode(devicesAPI.statusCode);
627
+ if (statusCode === 500) {
628
+ retryCount++;
629
+ this.infoLog(`statusCode: ${statusCode} Attempt ${retryCount} of ${maxRetries}`);
630
+ await sleep(delayBetweenRetries);
631
+ }
598
632
  }
599
- } else {
600
- this.statusCode(statusCode);
601
- this.statusCode(devicesAPI.statusCode);
633
+ } catch (e: any) {
634
+ retryCount++;
635
+ this.debugErrorLog(
636
+ `Failed to Discover Devices, Error Message: ${JSON.stringify(e.message)}, Submit Bugs Here: ` + 'https://tinyurl.com/SwitchBotBug',
637
+ );
638
+ this.debugErrorLog(`Failed to Discover Devices, Error: ${e}`);
602
639
  }
603
- } catch (e: any) {
604
- this.debugErrorLog(
605
- `Failed to Discover Devices, Error Message: ${JSON.stringify(e.message)}, Submit Bugs Here: ` + 'https://tinyurl.com/SwitchBotBug',
606
- );
607
- this.debugErrorLog(`Failed to Discover Devices, Error: ${e}`);
608
640
  }
609
641
  } else if (!this.config.credentials?.token && this.config.options?.devices) {
610
642
  this.debugLog(`SwitchBot Device Manual Config Set: ${JSON.stringify(this.config.options?.devices)}`);
@@ -696,6 +728,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
696
728
  case 'WoSweeperMini':
697
729
  case 'Robot Vacuum Cleaner S1':
698
730
  case 'Robot Vacuum Cleaner S1 Plus':
731
+ case 'Robot Vacuum Cleaner S10':
699
732
  this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
700
733
  this.createRobotVacuumCleaner(device);
701
734
  break;
@@ -713,8 +746,13 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
713
746
  this.warnLog(`Device: ${device.deviceName} with Device Type: ${device.deviceType}, is currently not supported.`);
714
747
  break;
715
748
  case 'Remote':
749
+ case 'remote with screen+':
716
750
  this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId} is Not Supported.`);
717
751
  break;
752
+ case 'Battery Circulator Fan':
753
+ this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
754
+ this.createFan(device);
755
+ break;
718
756
  default:
719
757
  this.warnLog(`Device: ${device.deviceName} with Device Type: ${device.deviceType}, is currently not supported.`);
720
758
  // eslint-disable-next-line max-len
@@ -750,7 +788,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
750
788
  case 'Fan':
751
789
  case 'DIY Fan':
752
790
  this.debugLog(`Discovered ${device.remoteType}: ${device.deviceId}`);
753
- this.createFan(device);
791
+ this.createIRFan(device);
754
792
  break;
755
793
  case 'Air Conditioner':
756
794
  case 'DIY Air Conditioner':
@@ -808,7 +846,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
808
846
  existingAccessory.context.deviceID = device.deviceId;
809
847
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
810
848
  if (device.firmware) {
811
- existingAccessory.context.FirmwareRevision = device.firmware;
849
+ existingAccessory.context.version = device.firmware;
812
850
  }
813
851
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
814
852
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -836,7 +874,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
836
874
  accessory.context.model = device.deviceType;
837
875
  accessory.context.deviceID = device.deviceId;
838
876
  if (device.firmware) {
839
- accessory.context.FirmwareRevision = device.firmware;
877
+ accessory.context.version = device.firmware;
840
878
  }
841
879
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
842
880
  accessory.context.connectionType = await this.connectionType(device);
@@ -868,7 +906,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
868
906
  existingAccessory.context.deviceID = device.deviceId;
869
907
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
870
908
  if (device.firmware) {
871
- existingAccessory.context.FirmwareRevision = device.firmware;
909
+ existingAccessory.context.version = device.firmware;
872
910
  }
873
911
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
874
912
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -896,11 +934,11 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
896
934
  accessory.context.model = device.deviceType;
897
935
  accessory.context.deviceID = device.deviceId;
898
936
  if (device.firmware) {
899
- accessory.context.FirmwareRevision = device.firmware;
937
+ accessory.context.version = device.firmware;
900
938
  }
901
939
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
902
940
  accessory.context.connectionType = await this.connectionType(device);
903
- // accessory.context.FirmwareRevision = findaccessories.accessoryAttribute.softwareRevision;
941
+ // accessory.context.version = findaccessories.accessoryAttribute.softwareRevision;
904
942
  // create the accessory handler for the newly create accessory
905
943
  // this is imported from `platformAccessory.ts`
906
944
  new Bot(this, accessory, device);
@@ -929,7 +967,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
929
967
  existingAccessory.context.deviceID = device.deviceId;
930
968
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
931
969
  if (device.firmware) {
932
- existingAccessory.context.FirmwareRevision = device.firmware;
970
+ existingAccessory.context.version = device.firmware;
933
971
  }
934
972
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
935
973
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -957,7 +995,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
957
995
  accessory.context.model = device.deviceType;
958
996
  accessory.context.deviceID = device.deviceId;
959
997
  if (device.firmware) {
960
- accessory.context.FirmwareRevision = device.firmware;
998
+ accessory.context.version = device.firmware;
961
999
  }
962
1000
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
963
1001
  accessory.context.connectionType = await this.connectionType(device);
@@ -990,7 +1028,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
990
1028
  existingAccessory.context.deviceID = device.deviceId;
991
1029
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
992
1030
  if (device.firmware) {
993
- existingAccessory.context.FirmwareRevision = device.firmware;
1031
+ existingAccessory.context.version = device.firmware;
994
1032
  }
995
1033
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
996
1034
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1018,7 +1056,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1018
1056
  accessory.context.model = device.deviceType;
1019
1057
  accessory.context.deviceID = device.deviceId;
1020
1058
  if (device.firmware) {
1021
- accessory.context.FirmwareRevision = device.firmware;
1059
+ accessory.context.version = device.firmware;
1022
1060
  }
1023
1061
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1024
1062
  accessory.context.connectionType = await this.connectionType(device);
@@ -1051,7 +1089,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1051
1089
  existingAccessory.context.deviceID = device.deviceId;
1052
1090
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1053
1091
  if (device.firmware) {
1054
- existingAccessory.context.FirmwareRevision = device.firmware;
1092
+ existingAccessory.context.version = device.firmware;
1055
1093
  }
1056
1094
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1057
1095
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1079,7 +1117,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1079
1117
  accessory.context.model = device.deviceType;
1080
1118
  accessory.context.deviceID = device.deviceId;
1081
1119
  if (device.firmware) {
1082
- accessory.context.FirmwareRevision = device.firmware;
1120
+ accessory.context.version = device.firmware;
1083
1121
  }
1084
1122
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1085
1123
  accessory.context.connectionType = await this.connectionType(device);
@@ -1111,7 +1149,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1111
1149
  existingAccessory.context.deviceID = device.deviceId;
1112
1150
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1113
1151
  if (device.firmware) {
1114
- existingAccessory.context.FirmwareRevision = device.firmware;
1152
+ existingAccessory.context.version = device.firmware;
1115
1153
  }
1116
1154
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1117
1155
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1139,7 +1177,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1139
1177
  accessory.context.model = device.deviceType;
1140
1178
  accessory.context.deviceID = device.deviceId;
1141
1179
  if (device.firmware) {
1142
- accessory.context.FirmwareRevision = device.firmware;
1180
+ accessory.context.version = device.firmware;
1143
1181
  }
1144
1182
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1145
1183
  accessory.context.connectionType = await this.connectionType(device);
@@ -1171,7 +1209,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1171
1209
  existingAccessory.context.deviceID = device.deviceId;
1172
1210
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1173
1211
  if (device.firmware) {
1174
- existingAccessory.context.FirmwareRevision = device.firmware;
1212
+ existingAccessory.context.version = device.firmware;
1175
1213
  }
1176
1214
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1177
1215
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1199,7 +1237,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1199
1237
  accessory.context.model = device.deviceType;
1200
1238
  accessory.context.deviceID = device.deviceId;
1201
1239
  if (device.firmware) {
1202
- accessory.context.FirmwareRevision = device.firmware;
1240
+ accessory.context.version = device.firmware;
1203
1241
  }
1204
1242
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1205
1243
  accessory.context.connectionType = await this.connectionType(device);
@@ -1231,7 +1269,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1231
1269
  existingAccessory.context.deviceID = device.deviceId;
1232
1270
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1233
1271
  if (device.firmware) {
1234
- existingAccessory.context.FirmwareRevision = device.firmware;
1272
+ existingAccessory.context.version = device.firmware;
1235
1273
  }
1236
1274
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1237
1275
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1259,7 +1297,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1259
1297
  accessory.context.model = device.deviceType;
1260
1298
  accessory.context.deviceID = device.deviceId;
1261
1299
  if (device.firmware) {
1262
- accessory.context.FirmwareRevision = device.firmware;
1300
+ accessory.context.version = device.firmware;
1263
1301
  }
1264
1302
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1265
1303
  accessory.context.connectionType = await this.connectionType(device);
@@ -1291,7 +1329,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1291
1329
  existingAccessory.context.deviceID = device.deviceId;
1292
1330
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1293
1331
  if (device.firmware) {
1294
- existingAccessory.context.FirmwareRevision = device.firmware;
1332
+ existingAccessory.context.version = device.firmware;
1295
1333
  }
1296
1334
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1297
1335
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1319,7 +1357,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1319
1357
  accessory.context.model = device.deviceType;
1320
1358
  accessory.context.deviceID = device.deviceId;
1321
1359
  if (device.firmware) {
1322
- accessory.context.FirmwareRevision = device.firmware;
1360
+ accessory.context.version = device.firmware;
1323
1361
  }
1324
1362
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1325
1363
  accessory.context.connectionType = await this.connectionType(device);
@@ -1351,7 +1389,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1351
1389
  existingAccessory.context.deviceID = device.deviceId;
1352
1390
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1353
1391
  if (device.firmware) {
1354
- existingAccessory.context.FirmwareRevision = device.firmware;
1392
+ existingAccessory.context.version = device.firmware;
1355
1393
  }
1356
1394
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1357
1395
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1392,7 +1430,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1392
1430
  accessory.context.model = device.deviceType;
1393
1431
  accessory.context.deviceID = device.deviceId;
1394
1432
  if (device.firmware) {
1395
- accessory.context.FirmwareRevision = device.firmware;
1433
+ accessory.context.version = device.firmware;
1396
1434
  }
1397
1435
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1398
1436
  accessory.context.connectionType = await this.connectionType(device);
@@ -1424,7 +1462,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1424
1462
  existingAccessory.context.deviceID = device.deviceId;
1425
1463
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1426
1464
  if (device.firmware) {
1427
- existingAccessory.context.FirmwareRevision = device.firmware;
1465
+ existingAccessory.context.version = device.firmware;
1428
1466
  }
1429
1467
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1430
1468
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1465,7 +1503,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1465
1503
  accessory.context.model = device.deviceType;
1466
1504
  accessory.context.deviceID = device.deviceId;
1467
1505
  if (device.firmware) {
1468
- accessory.context.FirmwareRevision = device.firmware;
1506
+ accessory.context.version = device.firmware;
1469
1507
  }
1470
1508
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1471
1509
  accessory.context.connectionType = await this.connectionType(device);
@@ -1497,7 +1535,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1497
1535
  existingAccessory.context.deviceID = device.deviceId;
1498
1536
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1499
1537
  if (device.firmware) {
1500
- existingAccessory.context.FirmwareRevision = device.firmware;
1538
+ existingAccessory.context.version = device.firmware;
1501
1539
  }
1502
1540
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1503
1541
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1525,7 +1563,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1525
1563
  accessory.context.model = device.deviceType;
1526
1564
  accessory.context.deviceID = device.deviceId;
1527
1565
  if (device.firmware) {
1528
- accessory.context.FirmwareRevision = device.firmware;
1566
+ accessory.context.version = device.firmware;
1529
1567
  }
1530
1568
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1531
1569
  accessory.context.connectionType = await this.connectionType(device);
@@ -1557,7 +1595,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1557
1595
  existingAccessory.context.deviceID = device.deviceId;
1558
1596
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1559
1597
  if (device.firmware) {
1560
- existingAccessory.context.FirmwareRevision = device.firmware;
1598
+ existingAccessory.context.version = device.firmware;
1561
1599
  }
1562
1600
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1563
1601
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1585,7 +1623,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1585
1623
  accessory.context.model = device.deviceType;
1586
1624
  accessory.context.deviceID = device.deviceId;
1587
1625
  if (device.firmware) {
1588
- accessory.context.FirmwareRevision = device.firmware;
1626
+ accessory.context.version = device.firmware;
1589
1627
  }
1590
1628
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1591
1629
  accessory.context.connectionType = await this.connectionType(device);
@@ -1617,7 +1655,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1617
1655
  existingAccessory.context.deviceID = device.deviceId;
1618
1656
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1619
1657
  if (device.firmware) {
1620
- existingAccessory.context.FirmwareRevision = device.firmware;
1658
+ existingAccessory.context.version = device.firmware;
1621
1659
  }
1622
1660
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1623
1661
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1645,7 +1683,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1645
1683
  accessory.context.model = device.deviceType;
1646
1684
  accessory.context.deviceID = device.deviceId;
1647
1685
  if (device.firmware) {
1648
- accessory.context.FirmwareRevision = device.firmware;
1686
+ accessory.context.version = device.firmware;
1649
1687
  }
1650
1688
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1651
1689
  accessory.context.connectionType = await this.connectionType(device);
@@ -1677,7 +1715,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1677
1715
  existingAccessory.context.deviceID = device.deviceId;
1678
1716
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1679
1717
  if (device.firmware) {
1680
- existingAccessory.context.FirmwareRevision = device.firmware;
1718
+ existingAccessory.context.version = device.firmware;
1681
1719
  }
1682
1720
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1683
1721
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1705,7 +1743,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1705
1743
  accessory.context.model = device.deviceType;
1706
1744
  accessory.context.deviceID = device.deviceId;
1707
1745
  if (device.firmware) {
1708
- accessory.context.FirmwareRevision = device.firmware;
1746
+ accessory.context.version = device.firmware;
1709
1747
  }
1710
1748
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1711
1749
  accessory.context.connectionType = await this.connectionType(device);
@@ -1737,7 +1775,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1737
1775
  existingAccessory.context.deviceID = device.deviceId;
1738
1776
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1739
1777
  if (device.firmware) {
1740
- existingAccessory.context.FirmwareRevision = device.firmware;
1778
+ existingAccessory.context.version = device.firmware;
1741
1779
  }
1742
1780
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1743
1781
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1765,7 +1803,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1765
1803
  accessory.context.model = device.deviceType;
1766
1804
  accessory.context.deviceID = device.deviceId;
1767
1805
  if (device.firmware) {
1768
- accessory.context.FirmwareRevision = device.firmware;
1806
+ accessory.context.version = device.firmware;
1769
1807
  }
1770
1808
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1771
1809
  accessory.context.connectionType = await this.connectionType(device);
@@ -1782,6 +1820,66 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1782
1820
  }
1783
1821
  }
1784
1822
 
1823
+ private async createFan(device: device & devicesConfig) {
1824
+ const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
1825
+
1826
+ // see if an accessory with the same uuid has already been registered and restored from
1827
+ // the cached devices we stored in the `configureAccessory` method above
1828
+ const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
1829
+
1830
+ if (existingAccessory) {
1831
+ // the accessory already exists
1832
+ if (await this.registerDevice(device)) {
1833
+ // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1834
+ existingAccessory.context.model = device.deviceType;
1835
+ existingAccessory.context.deviceID = device.deviceId;
1836
+ existingAccessory.displayName = device.configDeviceName || device.deviceName;
1837
+ if (device.firmware) {
1838
+ existingAccessory.context.version = device.firmware;
1839
+ }
1840
+ existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1841
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1842
+ existingAccessory.context.connectionType = await this.connectionType(device);
1843
+ this.api.updatePlatformAccessories([existingAccessory]);
1844
+ // create the accessory handler for the restored accessory
1845
+ // this is imported from `platformAccessory.ts`
1846
+ new Fan(this, existingAccessory, device);
1847
+ this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${existingAccessory.UUID})`);
1848
+ } else {
1849
+ this.unregisterPlatformAccessories(existingAccessory);
1850
+ }
1851
+ } else if (await this.registerDevice(device)) {
1852
+ // the accessory does not yet exist, so we need to create it
1853
+ if (!device.external) {
1854
+ this.infoLog(`Adding new accessory: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
1855
+ }
1856
+
1857
+ // create a new accessory
1858
+ const accessory = new this.api.platformAccessory(device.deviceName, uuid);
1859
+
1860
+ // store a copy of the device object in the `accessory.context`
1861
+ // the `context` property can be used to store any data about the accessory you may need
1862
+ accessory.context.device = device;
1863
+ accessory.context.model = device.deviceType;
1864
+ accessory.context.deviceID = device.deviceId;
1865
+ if (device.firmware) {
1866
+ accessory.context.version = device.firmware;
1867
+ }
1868
+ accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1869
+ accessory.context.connectionType = await this.connectionType(device);
1870
+ // create the accessory handler for the newly create accessory
1871
+ // this is imported from `platformAccessory.ts`
1872
+ new Fan(this, accessory, device);
1873
+ this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`);
1874
+
1875
+ // publish device externally or link the accessory to your platform
1876
+ this.externalOrPlatform(device, accessory);
1877
+ this.accessories.push(accessory);
1878
+ } else {
1879
+ this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
1880
+ }
1881
+ }
1882
+
1785
1883
  private async createRobotVacuumCleaner(device: device & devicesConfig) {
1786
1884
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
1787
1885
 
@@ -1797,7 +1895,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1797
1895
  existingAccessory.context.deviceID = device.deviceId;
1798
1896
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1799
1897
  if (device.firmware) {
1800
- existingAccessory.context.FirmwareRevision = device.firmware;
1898
+ existingAccessory.context.version = device.firmware;
1801
1899
  }
1802
1900
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1803
1901
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1825,7 +1923,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1825
1923
  accessory.context.model = device.deviceType;
1826
1924
  accessory.context.deviceID = device.deviceId;
1827
1925
  if (device.firmware) {
1828
- accessory.context.FirmwareRevision = device.firmware;
1926
+ accessory.context.version = device.firmware;
1829
1927
  }
1830
1928
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1831
1929
  accessory.context.connectionType = await this.connectionType(device);
@@ -1854,7 +1952,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1854
1952
  existingAccessory.context.model = device.remoteType;
1855
1953
  existingAccessory.context.deviceID = device.deviceId;
1856
1954
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1857
- existingAccessory.context.FirmwareRevision = device.firmware;
1955
+ if (device.version && !device.firmware) {
1956
+ existingAccessory.context.version = device.version;
1957
+ }
1858
1958
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1859
1959
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1860
1960
  existingAccessory.context.connectionType = device.connectionType;
@@ -1878,7 +1978,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1878
1978
  accessory.context.model = device.remoteType;
1879
1979
  accessory.context.deviceID = device.deviceId;
1880
1980
  if (device.firmware) {
1881
- accessory.context.FirmwareRevision = device.firmware;
1981
+ accessory.context.version = device.firmware;
1882
1982
  }
1883
1983
  accessory.context.deviceType = `IR: ${device.remoteType}`;
1884
1984
  accessory.context.connectionType = device.connectionType;
@@ -1894,7 +1994,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1894
1994
  }
1895
1995
  }
1896
1996
 
1897
- private async createFan(device: irdevice & devicesConfig) {
1997
+ private async createIRFan(device: irdevice & devicesConfig) {
1898
1998
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.remoteType}`);
1899
1999
 
1900
2000
  // see if an accessory with the same uuid has already been registered and restored from
@@ -1909,7 +2009,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1909
2009
  existingAccessory.context.deviceID = device.deviceId;
1910
2010
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1911
2011
  if (device.firmware) {
1912
- existingAccessory.context.FirmwareRevision = device.firmware;
2012
+ existingAccessory.context.version = device.firmware;
1913
2013
  }
1914
2014
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1915
2015
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1917,7 +2017,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1917
2017
  this.api.updatePlatformAccessories([existingAccessory]);
1918
2018
  // create the accessory handler for the restored accessory
1919
2019
  // this is imported from `platformAccessory.ts`
1920
- new Fan(this, existingAccessory, device);
2020
+ new IRFan(this, existingAccessory, device);
1921
2021
  this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${existingAccessory.UUID})`);
1922
2022
  } else {
1923
2023
  this.unregisterPlatformAccessories(existingAccessory);
@@ -1937,13 +2037,13 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1937
2037
  accessory.context.model = device.remoteType;
1938
2038
  accessory.context.deviceID = device.deviceId;
1939
2039
  if (device.firmware) {
1940
- accessory.context.FirmwareRevision = device.firmware;
2040
+ accessory.context.version = device.firmware;
1941
2041
  }
1942
2042
  accessory.context.deviceType = `IR: ${device.remoteType}`;
1943
2043
  accessory.context.connectionType = device.connectionType;
1944
2044
  // create the accessory handler for the newly create accessory
1945
2045
  // this is imported from `platformAccessory.ts`
1946
- new Fan(this, accessory, device);
2046
+ new IRFan(this, accessory, device);
1947
2047
  this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`);
1948
2048
 
1949
2049
  // publish device externally or link the accessory to your platform
@@ -1969,7 +2069,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1969
2069
  existingAccessory.context.deviceID = device.deviceId;
1970
2070
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1971
2071
  if (device.firmware) {
1972
- existingAccessory.context.FirmwareRevision = device.firmware;
2072
+ existingAccessory.context.version = device.firmware;
1973
2073
  }
1974
2074
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1975
2075
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1997,7 +2097,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1997
2097
  accessory.context.model = device.remoteType;
1998
2098
  accessory.context.deviceID = device.deviceId;
1999
2099
  if (device.firmware) {
2000
- accessory.context.FirmwareRevision = device.firmware;
2100
+ accessory.context.version = device.firmware;
2001
2101
  }
2002
2102
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2003
2103
  accessory.context.connectionType = device.connectionType;
@@ -2029,7 +2129,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2029
2129
  existingAccessory.context.deviceID = device.deviceId;
2030
2130
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
2031
2131
  if (device.firmware) {
2032
- existingAccessory.context.FirmwareRevision = device.firmware;
2132
+ existingAccessory.context.version = device.firmware;
2033
2133
  }
2034
2134
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2035
2135
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -2057,7 +2157,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2057
2157
  accessory.context.model = device.remoteType;
2058
2158
  accessory.context.deviceID = device.deviceId;
2059
2159
  if (device.firmware) {
2060
- accessory.context.FirmwareRevision = device.firmware;
2160
+ accessory.context.version = device.firmware;
2061
2161
  }
2062
2162
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2063
2163
  accessory.context.connectionType = device.connectionType;
@@ -2089,7 +2189,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2089
2189
  existingAccessory.context.deviceID = device.deviceId;
2090
2190
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
2091
2191
  if (device.firmware) {
2092
- existingAccessory.context.FirmwareRevision = device.firmware;
2192
+ existingAccessory.context.version = device.firmware;
2093
2193
  }
2094
2194
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2095
2195
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -2117,7 +2217,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2117
2217
  accessory.context.model = device.remoteType;
2118
2218
  accessory.context.deviceID = device.deviceId;
2119
2219
  if (device.firmware) {
2120
- accessory.context.FirmwareRevision = device.firmware;
2220
+ accessory.context.version = device.firmware;
2121
2221
  }
2122
2222
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2123
2223
  accessory.context.connectionType = device.connectionType;
@@ -2149,7 +2249,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2149
2249
  existingAccessory.context.deviceID = device.deviceId;
2150
2250
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
2151
2251
  if (device.firmware) {
2152
- existingAccessory.context.FirmwareRevision = device.firmware;
2252
+ existingAccessory.context.version = device.firmware;
2153
2253
  }
2154
2254
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2155
2255
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -2177,7 +2277,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2177
2277
  accessory.context.model = device.remoteType;
2178
2278
  accessory.context.deviceID = device.deviceId;
2179
2279
  if (device.firmware) {
2180
- accessory.context.FirmwareRevision = device.firmware;
2280
+ accessory.context.version = device.firmware;
2181
2281
  }
2182
2282
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2183
2283
  accessory.context.connectionType = device.connectionType;
@@ -2209,7 +2309,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2209
2309
  existingAccessory.context.deviceID = device.deviceId;
2210
2310
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
2211
2311
  if (device.firmware) {
2212
- existingAccessory.context.FirmwareRevision = device.firmware;
2312
+ existingAccessory.context.version = device.firmware;
2213
2313
  }
2214
2314
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2215
2315
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -2237,7 +2337,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2237
2337
  accessory.context.model = device.remoteType;
2238
2338
  accessory.context.deviceID = device.deviceId;
2239
2339
  if (device.firmware) {
2240
- accessory.context.FirmwareRevision = device.firmware;
2340
+ accessory.context.version = device.firmware;
2241
2341
  }
2242
2342
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2243
2343
  accessory.context.connectionType = device.connectionType;
@@ -2269,7 +2369,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2269
2369
  existingAccessory.context.deviceID = device.deviceId;
2270
2370
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
2271
2371
  if (device.firmware) {
2272
- existingAccessory.context.FirmwareRevision = device.firmware;
2372
+ existingAccessory.context.version = device.firmware;
2273
2373
  }
2274
2374
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2275
2375
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -2297,7 +2397,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2297
2397
  accessory.context.model = device.remoteType;
2298
2398
  accessory.context.deviceID = device.deviceId;
2299
2399
  if (device.firmware) {
2300
- accessory.context.FirmwareRevision = device.firmware;
2400
+ accessory.context.version = device.firmware;
2301
2401
  }
2302
2402
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2303
2403
  accessory.context.connectionType = device.connectionType;
@@ -2329,7 +2429,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2329
2429
  existingAccessory.context.deviceID = device.deviceId;
2330
2430
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
2331
2431
  if (device.firmware) {
2332
- existingAccessory.context.FirmwareRevision = device.firmware;
2432
+ existingAccessory.context.version = device.firmware;
2333
2433
  }
2334
2434
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2335
2435
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -2357,7 +2457,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2357
2457
  accessory.context.model = device.remoteType;
2358
2458
  accessory.context.deviceID = device.deviceId;
2359
2459
  if (device.firmware) {
2360
- accessory.context.FirmwareRevision = device.firmware;
2460
+ accessory.context.version = device.firmware;
2361
2461
  }
2362
2462
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2363
2463
  accessory.context.connectionType = device.connectionType;
@@ -2627,6 +2727,30 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2627
2727
  }
2628
2728
  }
2629
2729
 
2730
+ async retryRequest(deviceMaxRetries: number, deviceDelayBetweenRetries: number, url: string | URL | UrlObject,
2731
+ options?: { dispatcher?: Dispatcher } & Omit<Dispatcher.RequestOptions,
2732
+ 'origin' | 'path' | 'method'> & Partial<Pick<Dispatcher.RequestOptions, 'method'>>): Promise<{ body: any; statusCode: number }> {
2733
+ let retryCount = 0;
2734
+ const maxRetries = deviceMaxRetries;
2735
+ const delayBetweenRetries = deviceDelayBetweenRetries;
2736
+ while (retryCount < maxRetries) {
2737
+ try {
2738
+ const { body, statusCode } = await request(url, options);
2739
+ if (statusCode === 200 || statusCode === 100) {
2740
+ return { body, statusCode };
2741
+ } else {
2742
+ this.debugLog(`Received status code: ${statusCode}`);
2743
+ }
2744
+ } catch (error: any) {
2745
+ this.errorLog(`Error making request: ${error.message}`);
2746
+ }
2747
+ retryCount++;
2748
+ this.debugLog(`Retry attempt ${retryCount} of ${maxRetries}`);
2749
+ await sleep(delayBetweenRetries);
2750
+ }
2751
+ return { body: null, statusCode: -1 };
2752
+ }
2753
+
2630
2754
  // BLE Connection
2631
2755
  async connectBLE() {
2632
2756
  let switchbot: any;
@@ -2663,6 +2787,22 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2663
2787
  if (this.config.options.pushRate) {
2664
2788
  platformConfig.pushRate = this.config.options.pushRate;
2665
2789
  }
2790
+ if (this.config.options.maxRetries) {
2791
+ this.maxRetries = this.config.options.maxRetries;
2792
+ platformConfig.maxRetries = this.config.options.maxRetries;
2793
+ } else {
2794
+ this.maxRetries = 3;
2795
+ this.debugWarnLog('Using Default Max Retries');
2796
+ platformConfig.maxRetries = this.maxRetries;
2797
+ }
2798
+ if (this.config.options.delayBetweenRetries) {
2799
+ this.delayBetweenRetries = this.config.options.delayBetweenRetries * 1000;
2800
+ platformConfig.delayBetweenRetries = this.config.options.delayBetweenRetries;
2801
+ } else {
2802
+ this.delayBetweenRetries = 3000;
2803
+ this.debugWarnLog('Using Default Delay Between Retries');
2804
+ platformConfig.delayBetweenRetries = this.delayBetweenRetries / 1000;
2805
+ }
2666
2806
  if (Object.entries(platformConfig).length !== 0) {
2667
2807
  this.debugLog(`Platform Config: ${JSON.stringify(platformConfig)}`);
2668
2808
  }
@@ -2688,6 +2828,12 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2688
2828
  * If device level logging is turned on, log to log.warn
2689
2829
  * Otherwise send debug logs to log.debug
2690
2830
  */
2831
+ successLog(...log: any[]): void {
2832
+ if (this.enablingPlatformLogging()) {
2833
+ this.log.success(String(...log));
2834
+ }
2835
+ }
2836
+
2691
2837
  infoLog(...log: any[]): void {
2692
2838
  if (this.enablingPlatformLogging()) {
2693
2839
  this.log.info(String(...log));