@switchbot/homebridge-switchbot 3.5.0-beta.7 → 3.5.0-beta.70

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 (177) hide show
  1. package/.vscode/settings.json +4 -1
  2. package/CHANGELOG.md +4 -1
  3. package/config.schema.json +120 -17
  4. package/dist/device/blindtilt.d.ts +23 -96
  5. package/dist/device/blindtilt.d.ts.map +1 -1
  6. package/dist/device/blindtilt.js +425 -778
  7. package/dist/device/blindtilt.js.map +1 -1
  8. package/dist/device/bot.d.ts +26 -72
  9. package/dist/device/bot.d.ts.map +1 -1
  10. package/dist/device/bot.js +803 -837
  11. package/dist/device/bot.js.map +1 -1
  12. package/dist/device/ceilinglight.d.ts +14 -68
  13. package/dist/device/ceilinglight.d.ts.map +1 -1
  14. package/dist/device/ceilinglight.js +241 -606
  15. package/dist/device/ceilinglight.js.map +1 -1
  16. package/dist/device/colorbulb.d.ts +14 -75
  17. package/dist/device/colorbulb.d.ts.map +1 -1
  18. package/dist/device/colorbulb.js +283 -658
  19. package/dist/device/colorbulb.js.map +1 -1
  20. package/dist/device/contact.d.ts +15 -66
  21. package/dist/device/contact.d.ts.map +1 -1
  22. package/dist/device/contact.js +254 -545
  23. package/dist/device/contact.js.map +1 -1
  24. package/dist/device/curtain.d.ts +19 -88
  25. package/dist/device/curtain.d.ts.map +1 -1
  26. package/dist/device/curtain.js +412 -806
  27. package/dist/device/curtain.js.map +1 -1
  28. package/dist/device/device.d.ts +59 -0
  29. package/dist/device/device.d.ts.map +1 -0
  30. package/dist/device/device.js +711 -0
  31. package/dist/device/device.js.map +1 -0
  32. package/dist/device/fan.d.ts +51 -0
  33. package/dist/device/fan.d.ts.map +1 -0
  34. package/dist/device/fan.js +540 -0
  35. package/dist/device/fan.js.map +1 -0
  36. package/dist/device/hub.d.ts +16 -60
  37. package/dist/device/hub.d.ts.map +1 -1
  38. package/dist/device/hub.js +261 -616
  39. package/dist/device/hub.js.map +1 -1
  40. package/dist/device/humidifier.d.ts +11 -66
  41. package/dist/device/humidifier.d.ts.map +1 -1
  42. package/dist/device/humidifier.js +240 -594
  43. package/dist/device/humidifier.js.map +1 -1
  44. package/dist/device/iosensor.d.ts +11 -64
  45. package/dist/device/iosensor.d.ts.map +1 -1
  46. package/dist/device/iosensor.js +196 -600
  47. package/dist/device/iosensor.js.map +1 -1
  48. package/dist/device/lightstrip.d.ts +11 -69
  49. package/dist/device/lightstrip.d.ts.map +1 -1
  50. package/dist/device/lightstrip.js +281 -586
  51. package/dist/device/lightstrip.js.map +1 -1
  52. package/dist/device/lock.d.ts +16 -63
  53. package/dist/device/lock.d.ts.map +1 -1
  54. package/dist/device/lock.js +252 -560
  55. package/dist/device/lock.js.map +1 -1
  56. package/dist/device/meter.d.ts +14 -64
  57. package/dist/device/meter.d.ts.map +1 -1
  58. package/dist/device/meter.js +191 -593
  59. package/dist/device/meter.js.map +1 -1
  60. package/dist/device/meterplus.d.ts +14 -65
  61. package/dist/device/meterplus.d.ts.map +1 -1
  62. package/dist/device/meterplus.js +180 -593
  63. package/dist/device/meterplus.js.map +1 -1
  64. package/dist/device/motion.d.ts +13 -69
  65. package/dist/device/motion.d.ts.map +1 -1
  66. package/dist/device/motion.js +188 -532
  67. package/dist/device/motion.js.map +1 -1
  68. package/dist/device/plug.d.ts +9 -57
  69. package/dist/device/plug.d.ts.map +1 -1
  70. package/dist/device/plug.js +96 -458
  71. package/dist/device/plug.js.map +1 -1
  72. package/dist/device/robotvacuumcleaner.d.ts +12 -63
  73. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  74. package/dist/device/robotvacuumcleaner.js +202 -521
  75. package/dist/device/robotvacuumcleaner.js.map +1 -1
  76. package/dist/device/waterdetector.d.ts +10 -63
  77. package/dist/device/waterdetector.d.ts.map +1 -1
  78. package/dist/device/waterdetector.js +146 -475
  79. package/dist/device/waterdetector.js.map +1 -1
  80. package/dist/homebridge-ui/public/index.html +22 -16
  81. package/dist/homebridge-ui/server.js +1 -1
  82. package/dist/homebridge-ui/server.js.map +1 -1
  83. package/dist/index.d.ts +1 -1
  84. package/dist/index.d.ts.map +1 -1
  85. package/dist/index.js +2 -2
  86. package/dist/index.js.map +1 -1
  87. package/dist/irdevice/airconditioner.d.ts +10 -50
  88. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  89. package/dist/irdevice/airconditioner.js +324 -452
  90. package/dist/irdevice/airconditioner.js.map +1 -1
  91. package/dist/irdevice/airpurifier.d.ts +8 -39
  92. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  93. package/dist/irdevice/airpurifier.js +93 -307
  94. package/dist/irdevice/airpurifier.js.map +1 -1
  95. package/dist/irdevice/camera.d.ts +7 -36
  96. package/dist/irdevice/camera.d.ts.map +1 -1
  97. package/dist/irdevice/camera.js +39 -281
  98. package/dist/irdevice/camera.js.map +1 -1
  99. package/dist/irdevice/fan.d.ts +10 -43
  100. package/dist/irdevice/fan.d.ts.map +1 -1
  101. package/dist/irdevice/fan.js +113 -341
  102. package/dist/irdevice/fan.js.map +1 -1
  103. package/dist/irdevice/irdevice.d.ts +40 -0
  104. package/dist/irdevice/irdevice.d.ts.map +1 -0
  105. package/dist/irdevice/irdevice.js +330 -0
  106. package/dist/irdevice/irdevice.js.map +1 -0
  107. package/dist/irdevice/light.d.ts +12 -45
  108. package/dist/irdevice/light.d.ts.map +1 -1
  109. package/dist/irdevice/light.js +118 -362
  110. package/dist/irdevice/light.js.map +1 -1
  111. package/dist/irdevice/other.d.ts +19 -48
  112. package/dist/irdevice/other.d.ts.map +1 -1
  113. package/dist/irdevice/other.js +438 -570
  114. package/dist/irdevice/other.js.map +1 -1
  115. package/dist/irdevice/tv.d.ts +8 -40
  116. package/dist/irdevice/tv.d.ts.map +1 -1
  117. package/dist/irdevice/tv.js +87 -335
  118. package/dist/irdevice/tv.js.map +1 -1
  119. package/dist/irdevice/vacuumcleaner.d.ts +7 -36
  120. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  121. package/dist/irdevice/vacuumcleaner.js +45 -285
  122. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  123. package/dist/irdevice/waterheater.d.ts +7 -36
  124. package/dist/irdevice/waterheater.d.ts.map +1 -1
  125. package/dist/irdevice/waterheater.js +47 -291
  126. package/dist/irdevice/waterheater.js.map +1 -1
  127. package/dist/platform.d.ts +19 -6
  128. package/dist/platform.d.ts.map +1 -1
  129. package/dist/platform.js +310 -172
  130. package/dist/platform.js.map +1 -1
  131. package/dist/settings.d.ts +62 -19
  132. package/dist/settings.d.ts.map +1 -1
  133. package/dist/settings.js +16 -552
  134. package/dist/settings.js.map +1 -1
  135. package/dist/utils.d.ts +77 -0
  136. package/dist/utils.d.ts.map +1 -1
  137. package/dist/utils.js +638 -1
  138. package/dist/utils.js.map +1 -1
  139. package/eslint.config.js +96 -0
  140. package/package.json +19 -15
  141. package/src/custom.d.ts +2 -1
  142. package/src/device/blindtilt.ts +462 -817
  143. package/src/device/bot.ts +862 -931
  144. package/src/device/ceilinglight.ts +259 -633
  145. package/src/device/colorbulb.ts +300 -688
  146. package/src/device/contact.ts +288 -571
  147. package/src/device/curtain.ts +441 -838
  148. package/src/device/device.ts +734 -0
  149. package/src/device/fan.ts +596 -0
  150. package/src/device/hub.ts +299 -645
  151. package/src/device/humidifier.ts +274 -647
  152. package/src/device/iosensor.ts +233 -626
  153. package/src/device/lightstrip.ts +309 -620
  154. package/src/device/lock.ts +292 -601
  155. package/src/device/meter.ts +228 -619
  156. package/src/device/meterplus.ts +216 -619
  157. package/src/device/motion.ts +218 -559
  158. package/src/device/plug.ts +111 -490
  159. package/src/device/robotvacuumcleaner.ts +228 -550
  160. package/src/device/waterdetector.ts +169 -501
  161. package/src/homebridge-ui/public/index.html +22 -16
  162. package/src/homebridge-ui/server.ts +1 -1
  163. package/src/index.ts +4 -3
  164. package/src/irdevice/airconditioner.ts +350 -477
  165. package/src/irdevice/airpurifier.ts +120 -330
  166. package/src/irdevice/camera.ts +53 -301
  167. package/src/irdevice/fan.ts +130 -360
  168. package/src/irdevice/irdevice.ts +346 -0
  169. package/src/irdevice/light.ts +157 -412
  170. package/src/irdevice/other.ts +507 -648
  171. package/src/irdevice/tv.ts +117 -367
  172. package/src/irdevice/vacuumcleaner.ts +59 -311
  173. package/src/irdevice/waterheater.ts +61 -320
  174. package/src/platform.ts +355 -219
  175. package/src/settings.ts +116 -611
  176. package/src/utils.ts +642 -1
  177. package/src/device/waterdetector.json +0 -11
package/src/platform.ts CHANGED
@@ -1,27 +1,27 @@
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
  */
5
- import { API, DynamicPlatformPlugin, Logging, PlatformAccessory } from 'homebridge';
6
- import { PLATFORM_NAME, PLUGIN_NAME, irdevice, device, SwitchBotPlatformConfig, devicesConfig, irDevicesConfig, Devices } from './settings.js';
5
+ import { Hub } from './device/hub.js';
7
6
  import { Bot } from './device/bot.js';
8
7
  import { Plug } from './device/plug.js';
9
8
  import { Lock } from './device/lock.js';
10
9
  import { Meter } from './device/meter.js';
11
10
  import { Motion } from './device/motion.js';
12
- import { Hub } from './device/hub.js';
13
11
  import { Contact } from './device/contact.js';
14
12
  import { Curtain } from './device/curtain.js';
15
13
  import { IOSensor } from './device/iosensor.js';
16
- import { WaterDetector } from './device/waterdetector.js';
17
14
  import { MeterPlus } from './device/meterplus.js';
18
15
  import { ColorBulb } from './device/colorbulb.js';
19
- import { CeilingLight } from './device/ceilinglight.js';
20
16
  import { StripLight } from './device/lightstrip.js';
21
17
  import { Humidifier } from './device/humidifier.js';
18
+ import { CeilingLight } from './device/ceilinglight.js';
19
+ import { WaterDetector } from './device/waterdetector.js';
22
20
  import { RobotVacuumCleaner } from './device/robotvacuumcleaner.js';
21
+
22
+ import { Fan } from './device/fan.js';
23
23
  import { TV } from './irdevice/tv.js';
24
- import { Fan } from './irdevice/fan.js';
24
+ import { IRFan } from './irdevice/fan.js';
25
25
  import { Light } from './irdevice/light.js';
26
26
  import { Others } from './irdevice/other.js';
27
27
  import { Camera } from './irdevice/camera.js';
@@ -30,18 +30,25 @@ import { AirPurifier } from './irdevice/airpurifier.js';
30
30
  import { WaterHeater } from './irdevice/waterheater.js';
31
31
  import { VacuumCleaner } from './irdevice/vacuumcleaner.js';
32
32
  import { AirConditioner } from './irdevice/airconditioner.js';
33
- import * as http from 'http';
33
+
34
34
  import { Buffer } from 'buffer';
35
35
  import { request } from 'undici';
36
- import { MqttClient } from 'mqtt';
36
+ import asyncmqtt from 'async-mqtt';
37
+ import { sleep } from './utils.js';
38
+ import { createServer } from 'http';
37
39
  import { queueScheduler } from 'rxjs';
38
40
  import fakegato from 'fakegato-history';
39
- 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
-
43
+ import { EveHomeKitTypes } from 'homebridge-lib/EveHomeKitTypes';
44
+ import { PLATFORM_NAME, PLUGIN_NAME, Devices, setupWebhook, updateWebhook, deleteWebhook, queryWebhook } from './settings.js';
44
45
 
46
+ import type { UrlObject } from 'url';
47
+ import type { MqttClient } from 'mqtt';
48
+ import type { Dispatcher } from 'undici';
49
+ import type { Server, IncomingMessage, ServerResponse } from 'http';
50
+ import type { API, DynamicPlatformPlugin, Logging, PlatformAccessory } from 'homebridge';
51
+ import type { irdevice, device, SwitchBotPlatformConfig, devicesConfig, irDevicesConfig } from './settings.js';
45
52
 
46
53
  /**
47
54
  * HomebridgePlatform
@@ -56,11 +63,13 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
56
63
  version!: string;
57
64
  Logging?: string;
58
65
  debugMode!: boolean;
66
+ maxRetries!: number;
67
+ delayBetweenRetries!: number;
59
68
  platformConfig!: SwitchBotPlatformConfig['options'];
60
69
  platformLogging!: SwitchBotPlatformConfig['logging'];
61
70
  config!: SwitchBotPlatformConfig;
62
71
 
63
- webhookEventListener: http.Server | null = null;
72
+ webhookEventListener: Server | null = null;
64
73
  mqttClient: MqttClient | null = null;
65
74
 
66
75
  public readonly fakegatoAPI: any;
@@ -104,7 +113,6 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
104
113
  }
105
114
 
106
115
  // import fakegato-history module and EVE characteristics
107
- const { EveHomeKitTypes } = hbLib;
108
116
  this.fakegatoAPI = fakegato(api);
109
117
  this.eve = new EveHomeKitTypes(api);
110
118
 
@@ -119,7 +127,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
119
127
  if (this.config.credentials?.openToken && !this.config.credentials.token) {
120
128
  await this.updateToken();
121
129
  } else if (this.config.credentials?.token && !this.config.credentials?.secret) {
122
- // eslint-disable-next-line no-useless-escape
130
+
123
131
  this.errorLog('"secret" config is not populated, you must populate then please restart Homebridge.');
124
132
  } else {
125
133
  this.discoverDevices();
@@ -173,7 +181,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
173
181
  const xurl = new URL(url);
174
182
  const port = Number(xurl.port);
175
183
  const path = xurl.pathname;
176
- this.webhookEventListener = http.createServer((request: http.IncomingMessage, response: http.ServerResponse) => {
184
+ this.webhookEventListener = createServer((request: IncomingMessage, response: ServerResponse) => {
177
185
  try {
178
186
  if (request.url === path && request.method === 'POST') {
179
187
  request.on('data', async (data) => {
@@ -210,16 +218,15 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
210
218
  }
211
219
 
212
220
  try {
213
- const { body, statusCode } = await request(
214
- 'https://api.switch-bot.com/v1.1/webhook/setupWebhook', {
215
- method: 'POST',
216
- headers: this.generateHeaders(),
217
- body: JSON.stringify({
218
- 'action': 'setupWebhook',
219
- 'url': url,
220
- 'deviceList': 'ALL',
221
- }),
222
- });
221
+ const { body, statusCode } = await request(setupWebhook, {
222
+ method: 'POST',
223
+ headers: this.generateHeaders(),
224
+ body: JSON.stringify({
225
+ 'action': 'setupWebhook',
226
+ 'url': url,
227
+ 'deviceList': 'ALL',
228
+ }),
229
+ });
223
230
  const response: any = await body.json();
224
231
  this.debugLog(`setupWebhook: url:${url}`);
225
232
  this.debugLog(`setupWebhook: body:${JSON.stringify(response)}`);
@@ -233,18 +240,15 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
233
240
  }
234
241
 
235
242
  try {
236
- const { body, statusCode } = await request(
237
- 'https://api.switch-bot.com/v1.1/webhook/updateWebhook', {
238
- method: 'POST',
239
- headers: this.generateHeaders(),
240
- body: JSON.stringify({
241
- 'action': 'updateWebhook',
242
- 'config': {
243
- 'url': url,
244
- 'enable': true,
245
- },
246
- }),
247
- });
243
+ const { body, statusCode } = await request(updateWebhook, {
244
+ method: 'POST', headers: this.generateHeaders(), body: JSON.stringify({
245
+ 'action': 'updateWebhook',
246
+ 'config': {
247
+ 'url': url,
248
+ 'enable': true,
249
+ },
250
+ }),
251
+ });
248
252
  const response: any = await body.json();
249
253
  this.debugLog(`updateWebhook: url:${url}`);
250
254
  this.debugLog(`updateWebhook: body:${JSON.stringify(response)}`);
@@ -257,14 +261,13 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
257
261
  }
258
262
 
259
263
  try {
260
- const { body, statusCode } = await request(
261
- 'https://api.switch-bot.com/v1.1/webhook/queryWebhook', {
262
- method: 'POST',
263
- headers: this.generateHeaders(),
264
- body: JSON.stringify({
265
- 'action': 'queryUrl',
266
- }),
267
- });
264
+ const { body, statusCode } = await request(queryWebhook, {
265
+ method: 'POST',
266
+ headers: this.generateHeaders(),
267
+ body: JSON.stringify({
268
+ 'action': 'queryUrl',
269
+ }),
270
+ });
268
271
  const response: any = await body.json();
269
272
  this.debugLog(`queryWebhook: body:${JSON.stringify(response)}`);
270
273
  this.debugLog(`queryWebhook: statusCode:${statusCode}`);
@@ -279,15 +282,14 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
279
282
 
280
283
  this.api.on('shutdown', async () => {
281
284
  try {
282
- const { body, statusCode } = await request(
283
- 'https://api.switch-bot.com/v1.1/webhook/deleteWebhook', {
284
- method: 'POST',
285
- headers: this.generateHeaders(),
286
- body: JSON.stringify({
287
- 'action': 'deleteWebhook',
288
- 'url': url,
289
- }),
290
- });
285
+ const { body, statusCode } = await request(deleteWebhook, {
286
+ method: 'POST',
287
+ headers: this.generateHeaders(),
288
+ body: JSON.stringify({
289
+ 'action': 'deleteWebhook',
290
+ 'url': url,
291
+ }),
292
+ });
291
293
  const response: any = await body.json();
292
294
  this.debugLog(`deleteWebhook: url:${url}`);
293
295
  this.debugLog(`deleteWebhook: body:${JSON.stringify(response)}`);
@@ -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) {
@@ -432,18 +449,12 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
432
449
  }
433
450
  // Move openToken to token
434
451
  if (!this.config.credentials.secret) {
435
- // eslint-disable-next-line no-useless-escape, max-len
436
- this.warnLog(
437
- 'This plugin has been updated to use OpenAPI v1.1, config is set with openToken, "openToken" cconfig has been moved to the "token" config',
438
- );
439
- // eslint-disable-next-line no-useless-escape
452
+ this.warnLog('This plugin has been updated to use OpenAPI v1.1, config is set with openToken,'
453
+ + ' "openToken" cconfig has been moved to the "token" config');
440
454
  this.errorLog('"secret" config is not populated, you must populate then please restart Homebridge.');
441
455
  } else {
442
- // eslint-disable-next-line no-useless-escape, max-len
443
- this.warnLog(
444
- 'This plugin has been updated to use OpenAPI v1.1, config is set with openToken, '
445
- + '"openToken" config has been moved to the "token" config, please restart Homebridge.',
446
- );
456
+ this.warnLog('This plugin has been updated to use OpenAPI v1.1, config is set with openToken, '
457
+ + '"openToken" config has been moved to the "token" config, please restart Homebridge.');
447
458
  }
448
459
 
449
460
  // set the refresh token
@@ -492,44 +503,98 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
492
503
  */
493
504
  async discoverDevices() {
494
505
  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;
506
+ let retryCount = 0;
507
+ const maxRetries = this.maxRetries; // Maximum number of retries
508
+ const delayBetweenRetries = this.delayBetweenRetries; // Delay between retries in milliseconds
509
+ this.debugWarnLog(`Retry Count: ${retryCount}`);
510
+ this.debugWarnLog(`Max Retries: ${maxRetries}`);
511
+ this.debugWarnLog(`Delay Between Retries: ${delayBetweenRetries}`);
512
+ while (retryCount < maxRetries) {
513
+ try {
514
+ const { body, statusCode } = await request(Devices, {
515
+ headers: this.generateHeaders(),
516
+ });
517
+ this.debugWarnLog(`statusCode: ${statusCode}`);
518
+ const devicesAPI: any = await body.json();
519
+ this.debugWarnLog(`devicesAPI: ${JSON.stringify(devicesAPI)}`);
520
+ this.debugWarnLog(`devicesAPI Body: ${JSON.stringify(devicesAPI.body)}`);
521
+ this.debugWarnLog(`devicesAPI StatusCode: ${devicesAPI.statusCode}`);
522
+ if ((statusCode === 200 || statusCode === 100) && (devicesAPI.statusCode === 200 || devicesAPI.statusCode === 100)) {
523
+ this.debugErrorLog(`statusCode: ${statusCode} & devicesAPI StatusCode: ${devicesAPI.statusCode}`);
524
+ // SwitchBot Devices
525
+ const deviceLists = devicesAPI.body.deviceList;
526
+ this.debugWarnLog(`DeviceLists: ${JSON.stringify(deviceLists)}`);
527
+ this.debugWarnLog(`DeviceLists Length: ${deviceLists.length}`);
528
+ if (!this.config.options?.devices) {
529
+ this.debugLog(`SwitchBot Device Config Not Set: ${JSON.stringify(this.config.options?.devices)}`);
530
+ if (deviceLists.length === 0) {
531
+ this.debugLog(`SwitchBot API Currently Doesn't Have Any Devices With Cloud Services Enabled: ${JSON.stringify(devicesAPI.body)}`);
532
+ } else {
533
+ const devices = deviceLists.map((v: any) => v);
534
+ for (const device of devices) {
535
+ if (device.deviceType) {
536
+ if (device.configDeviceName) {
537
+ device.deviceName = device.configDeviceName;
538
+ }
539
+ this.createDevice(device);
540
+ }
541
+ }
542
+ }
543
+ } else if (this.config.credentials?.token && this.config.options.devices) {
544
+ this.debugLog(`SwitchBot Device Config Set: ${JSON.stringify(this.config.options?.devices)}`);
545
+ if (deviceLists.length === 0) {
546
+ this.debugLog(`SwitchBot API Currently Doesn't Have Any Devices With Cloud Services Enabled: ${JSON.stringify(devicesAPI.body)}`);
547
+ } else {
548
+ const deviceConfigs = this.config.options?.devices;
549
+
550
+ const mergeBydeviceId = (a1: { deviceId: string }[], a2: any[]) =>
551
+ a1.map((itm: { deviceId: string }) => ({
552
+ ...a2.find(
553
+ (item: { deviceId: string }) =>
554
+ item.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') === itm.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') && item,
555
+ ),
556
+ ...itm,
557
+ }));
558
+
559
+ const devices = mergeBydeviceId(deviceLists, deviceConfigs);
560
+ this.debugLog(`SwitchBot Devices: ${JSON.stringify(devices)}`);
561
+ for (const device of devices) {
562
+ if (!device.deviceType) {
563
+ device.deviceType = device.configDeviceType;
564
+ this.errorLog(`API has displaying no deviceType: ${device.deviceType}, So using configDeviceType: ${device.configDeviceType}`);
565
+ }
566
+ if (device.deviceType) {
567
+ if (device.configDeviceName) {
568
+ device.deviceName = device.configDeviceName;
569
+ }
570
+ this.createDevice(device);
520
571
  }
521
- this.createDevice(device);
522
572
  }
523
573
  }
574
+ } else {
575
+ this.errorLog('SwitchBot Token Supplied, Issue with Auth.');
524
576
  }
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)}`);
577
+ if (devicesAPI.body.deviceList.length !== 0) {
578
+ this.infoLog(`Total SwitchBot Devices Found: ${devicesAPI.body.deviceList.length}`);
529
579
  } else {
530
- const deviceConfigs = this.config.options?.devices;
580
+ this.debugLog(`Total SwitchBot Devices Found: ${devicesAPI.body.deviceList.length}`);
581
+ }
531
582
 
532
- const mergeBydeviceId = (a1: { deviceId: string }[], a2: any[]) =>
583
+ // IR Devices
584
+ const irDeviceLists = devicesAPI.body.infraredRemoteList;
585
+ if (!this.config.options?.irdevices) {
586
+ this.debugLog(`IR Device Config Not Set: ${JSON.stringify(this.config.options?.irdevices)}`);
587
+ const devices = irDeviceLists.map((v: any) => v);
588
+ for (const device of devices) {
589
+ if (device.remoteType) {
590
+ this.createIRDevice(device);
591
+ }
592
+ }
593
+ } else {
594
+ this.debugLog(`IR Device Config Set: ${JSON.stringify(this.config.options?.irdevices)}`);
595
+ const irDeviceConfig = this.config.options?.irdevices;
596
+
597
+ const mergeIRBydeviceId = (a1: { deviceId: string }[], a2: any[]) =>
533
598
  a1.map((itm: { deviceId: string }) => ({
534
599
  ...a2.find(
535
600
  (item: { deviceId: string }) =>
@@ -538,73 +603,34 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
538
603
  ...itm,
539
604
  }));
540
605
 
541
- const devices = mergeBydeviceId(deviceLists, deviceConfigs);
542
- this.debugLog(`SwitchBot Devices: ${JSON.stringify(devices)}`);
606
+ const devices = mergeIRBydeviceId(irDeviceLists, irDeviceConfig);
607
+ this.debugLog(`IR Devices: ${JSON.stringify(devices)}`);
543
608
  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
609
  this.createIRDevice(device);
573
610
  }
574
611
  }
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);
612
+ if (devicesAPI.body.infraredRemoteList.length !== 0) {
613
+ this.infoLog(`Total IR Devices Found: ${devicesAPI.body.infraredRemoteList.length}`);
614
+ } else {
615
+ this.debugLog(`Total IR Devices Found: ${devicesAPI.body.infraredRemoteList.length}`);
592
616
  }
593
- }
594
- if (devicesAPI.body.infraredRemoteList.length !== 0) {
595
- this.infoLog(`Total IR Devices Found: ${devicesAPI.body.infraredRemoteList.length}`);
617
+ break;
596
618
  } else {
597
- this.debugLog(`Total IR Devices Found: ${devicesAPI.body.infraredRemoteList.length}`);
619
+ this.statusCode(statusCode);
620
+ this.statusCode(devicesAPI.statusCode);
621
+ if (statusCode === 500) {
622
+ retryCount++;
623
+ this.infoLog(`statusCode: ${statusCode} Attempt ${retryCount} of ${maxRetries}`);
624
+ await sleep(delayBetweenRetries);
625
+ }
598
626
  }
599
- } else {
600
- this.statusCode(statusCode);
601
- this.statusCode(devicesAPI.statusCode);
627
+ } catch (e: any) {
628
+ retryCount++;
629
+ this.debugErrorLog(
630
+ `Failed to Discover Devices, Error Message: ${JSON.stringify(e.message)}, Submit Bugs Here: ` + 'https://tinyurl.com/SwitchBotBug',
631
+ );
632
+ this.debugErrorLog(`Failed to Discover Devices, Error: ${e}`);
602
633
  }
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
634
  }
609
635
  } else if (!this.config.credentials?.token && this.config.options?.devices) {
610
636
  this.debugLog(`SwitchBot Device Manual Config Set: ${JSON.stringify(this.config.options?.devices)}`);
@@ -696,6 +722,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
696
722
  case 'WoSweeperMini':
697
723
  case 'Robot Vacuum Cleaner S1':
698
724
  case 'Robot Vacuum Cleaner S1 Plus':
725
+ case 'Robot Vacuum Cleaner S10':
699
726
  this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
700
727
  this.createRobotVacuumCleaner(device);
701
728
  break;
@@ -708,17 +735,18 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
708
735
  this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
709
736
  this.createStripLight(device);
710
737
  break;
711
- case 'Indoor Cam':
738
+ case 'Battery Circulator Fan':
712
739
  this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
713
- this.warnLog(`Device: ${device.deviceName} with Device Type: ${device.deviceType}, is currently not supported.`);
740
+ this.createFan(device);
714
741
  break;
715
742
  case 'Remote':
716
- this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId} is Not Supported.`);
743
+ case 'Indoor Cam':
744
+ case 'remote with screen+':
745
+ this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}, is currently not supported, device: ${JSON.stringify(device)}`);
717
746
  break;
718
747
  default:
719
- this.warnLog(`Device: ${device.deviceName} with Device Type: ${device.deviceType}, is currently not supported.`);
720
- // eslint-disable-next-line max-len
721
- this.warnLog('Submit Feature Requests Here: ' + 'https://tinyurl.com/SwitchBotFeatureRequest');
748
+ this.warnLog(`Device: ${device.deviceName} with Device Type: ${device.deviceType}, is currently not supported.`,
749
+ + `Submit Feature Requests Here: https://tinyurl.com/SwitchBotFeatureRequest, device: ${JSON.stringify(device)}` );
722
750
  }
723
751
  }
724
752
 
@@ -750,7 +778,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
750
778
  case 'Fan':
751
779
  case 'DIY Fan':
752
780
  this.debugLog(`Discovered ${device.remoteType}: ${device.deviceId}`);
753
- this.createFan(device);
781
+ this.createIRFan(device);
754
782
  break;
755
783
  case 'Air Conditioner':
756
784
  case 'DIY Air Conditioner':
@@ -808,7 +836,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
808
836
  existingAccessory.context.deviceID = device.deviceId;
809
837
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
810
838
  if (device.firmware) {
811
- existingAccessory.context.FirmwareRevision = device.firmware;
839
+ existingAccessory.context.version = device.firmware;
812
840
  }
813
841
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
814
842
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -836,7 +864,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
836
864
  accessory.context.model = device.deviceType;
837
865
  accessory.context.deviceID = device.deviceId;
838
866
  if (device.firmware) {
839
- accessory.context.FirmwareRevision = device.firmware;
867
+ accessory.context.version = device.firmware;
840
868
  }
841
869
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
842
870
  accessory.context.connectionType = await this.connectionType(device);
@@ -868,7 +896,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
868
896
  existingAccessory.context.deviceID = device.deviceId;
869
897
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
870
898
  if (device.firmware) {
871
- existingAccessory.context.FirmwareRevision = device.firmware;
899
+ existingAccessory.context.version = device.firmware;
872
900
  }
873
901
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
874
902
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -896,11 +924,11 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
896
924
  accessory.context.model = device.deviceType;
897
925
  accessory.context.deviceID = device.deviceId;
898
926
  if (device.firmware) {
899
- accessory.context.FirmwareRevision = device.firmware;
927
+ accessory.context.version = device.firmware;
900
928
  }
901
929
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
902
930
  accessory.context.connectionType = await this.connectionType(device);
903
- // accessory.context.FirmwareRevision = findaccessories.accessoryAttribute.softwareRevision;
931
+ // accessory.context.version = findaccessories.accessoryAttribute.softwareRevision;
904
932
  // create the accessory handler for the newly create accessory
905
933
  // this is imported from `platformAccessory.ts`
906
934
  new Bot(this, accessory, device);
@@ -929,7 +957,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
929
957
  existingAccessory.context.deviceID = device.deviceId;
930
958
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
931
959
  if (device.firmware) {
932
- existingAccessory.context.FirmwareRevision = device.firmware;
960
+ existingAccessory.context.version = device.firmware;
933
961
  }
934
962
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
935
963
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -957,7 +985,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
957
985
  accessory.context.model = device.deviceType;
958
986
  accessory.context.deviceID = device.deviceId;
959
987
  if (device.firmware) {
960
- accessory.context.FirmwareRevision = device.firmware;
988
+ accessory.context.version = device.firmware;
961
989
  }
962
990
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
963
991
  accessory.context.connectionType = await this.connectionType(device);
@@ -990,7 +1018,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
990
1018
  existingAccessory.context.deviceID = device.deviceId;
991
1019
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
992
1020
  if (device.firmware) {
993
- existingAccessory.context.FirmwareRevision = device.firmware;
1021
+ existingAccessory.context.version = device.firmware;
994
1022
  }
995
1023
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
996
1024
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1018,7 +1046,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1018
1046
  accessory.context.model = device.deviceType;
1019
1047
  accessory.context.deviceID = device.deviceId;
1020
1048
  if (device.firmware) {
1021
- accessory.context.FirmwareRevision = device.firmware;
1049
+ accessory.context.version = device.firmware;
1022
1050
  }
1023
1051
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1024
1052
  accessory.context.connectionType = await this.connectionType(device);
@@ -1051,7 +1079,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1051
1079
  existingAccessory.context.deviceID = device.deviceId;
1052
1080
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1053
1081
  if (device.firmware) {
1054
- existingAccessory.context.FirmwareRevision = device.firmware;
1082
+ existingAccessory.context.version = device.firmware;
1055
1083
  }
1056
1084
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1057
1085
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1079,7 +1107,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1079
1107
  accessory.context.model = device.deviceType;
1080
1108
  accessory.context.deviceID = device.deviceId;
1081
1109
  if (device.firmware) {
1082
- accessory.context.FirmwareRevision = device.firmware;
1110
+ accessory.context.version = device.firmware;
1083
1111
  }
1084
1112
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1085
1113
  accessory.context.connectionType = await this.connectionType(device);
@@ -1111,7 +1139,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1111
1139
  existingAccessory.context.deviceID = device.deviceId;
1112
1140
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1113
1141
  if (device.firmware) {
1114
- existingAccessory.context.FirmwareRevision = device.firmware;
1142
+ existingAccessory.context.version = device.firmware;
1115
1143
  }
1116
1144
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1117
1145
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1139,7 +1167,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1139
1167
  accessory.context.model = device.deviceType;
1140
1168
  accessory.context.deviceID = device.deviceId;
1141
1169
  if (device.firmware) {
1142
- accessory.context.FirmwareRevision = device.firmware;
1170
+ accessory.context.version = device.firmware;
1143
1171
  }
1144
1172
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1145
1173
  accessory.context.connectionType = await this.connectionType(device);
@@ -1171,7 +1199,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1171
1199
  existingAccessory.context.deviceID = device.deviceId;
1172
1200
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1173
1201
  if (device.firmware) {
1174
- existingAccessory.context.FirmwareRevision = device.firmware;
1202
+ existingAccessory.context.version = device.firmware;
1175
1203
  }
1176
1204
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1177
1205
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1199,7 +1227,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1199
1227
  accessory.context.model = device.deviceType;
1200
1228
  accessory.context.deviceID = device.deviceId;
1201
1229
  if (device.firmware) {
1202
- accessory.context.FirmwareRevision = device.firmware;
1230
+ accessory.context.version = device.firmware;
1203
1231
  }
1204
1232
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1205
1233
  accessory.context.connectionType = await this.connectionType(device);
@@ -1231,7 +1259,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1231
1259
  existingAccessory.context.deviceID = device.deviceId;
1232
1260
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1233
1261
  if (device.firmware) {
1234
- existingAccessory.context.FirmwareRevision = device.firmware;
1262
+ existingAccessory.context.version = device.firmware;
1235
1263
  }
1236
1264
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1237
1265
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1259,7 +1287,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1259
1287
  accessory.context.model = device.deviceType;
1260
1288
  accessory.context.deviceID = device.deviceId;
1261
1289
  if (device.firmware) {
1262
- accessory.context.FirmwareRevision = device.firmware;
1290
+ accessory.context.version = device.firmware;
1263
1291
  }
1264
1292
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1265
1293
  accessory.context.connectionType = await this.connectionType(device);
@@ -1291,7 +1319,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1291
1319
  existingAccessory.context.deviceID = device.deviceId;
1292
1320
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1293
1321
  if (device.firmware) {
1294
- existingAccessory.context.FirmwareRevision = device.firmware;
1322
+ existingAccessory.context.version = device.firmware;
1295
1323
  }
1296
1324
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1297
1325
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1319,7 +1347,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1319
1347
  accessory.context.model = device.deviceType;
1320
1348
  accessory.context.deviceID = device.deviceId;
1321
1349
  if (device.firmware) {
1322
- accessory.context.FirmwareRevision = device.firmware;
1350
+ accessory.context.version = device.firmware;
1323
1351
  }
1324
1352
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1325
1353
  accessory.context.connectionType = await this.connectionType(device);
@@ -1351,7 +1379,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1351
1379
  existingAccessory.context.deviceID = device.deviceId;
1352
1380
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1353
1381
  if (device.firmware) {
1354
- existingAccessory.context.FirmwareRevision = device.firmware;
1382
+ existingAccessory.context.version = device.firmware;
1355
1383
  }
1356
1384
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1357
1385
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1392,7 +1420,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1392
1420
  accessory.context.model = device.deviceType;
1393
1421
  accessory.context.deviceID = device.deviceId;
1394
1422
  if (device.firmware) {
1395
- accessory.context.FirmwareRevision = device.firmware;
1423
+ accessory.context.version = device.firmware;
1396
1424
  }
1397
1425
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1398
1426
  accessory.context.connectionType = await this.connectionType(device);
@@ -1424,7 +1452,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1424
1452
  existingAccessory.context.deviceID = device.deviceId;
1425
1453
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1426
1454
  if (device.firmware) {
1427
- existingAccessory.context.FirmwareRevision = device.firmware;
1455
+ existingAccessory.context.version = device.firmware;
1428
1456
  }
1429
1457
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1430
1458
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1465,7 +1493,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1465
1493
  accessory.context.model = device.deviceType;
1466
1494
  accessory.context.deviceID = device.deviceId;
1467
1495
  if (device.firmware) {
1468
- accessory.context.FirmwareRevision = device.firmware;
1496
+ accessory.context.version = device.firmware;
1469
1497
  }
1470
1498
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1471
1499
  accessory.context.connectionType = await this.connectionType(device);
@@ -1497,7 +1525,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1497
1525
  existingAccessory.context.deviceID = device.deviceId;
1498
1526
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1499
1527
  if (device.firmware) {
1500
- existingAccessory.context.FirmwareRevision = device.firmware;
1528
+ existingAccessory.context.version = device.firmware;
1501
1529
  }
1502
1530
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1503
1531
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1525,7 +1553,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1525
1553
  accessory.context.model = device.deviceType;
1526
1554
  accessory.context.deviceID = device.deviceId;
1527
1555
  if (device.firmware) {
1528
- accessory.context.FirmwareRevision = device.firmware;
1556
+ accessory.context.version = device.firmware;
1529
1557
  }
1530
1558
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1531
1559
  accessory.context.connectionType = await this.connectionType(device);
@@ -1557,7 +1585,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1557
1585
  existingAccessory.context.deviceID = device.deviceId;
1558
1586
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1559
1587
  if (device.firmware) {
1560
- existingAccessory.context.FirmwareRevision = device.firmware;
1588
+ existingAccessory.context.version = device.firmware;
1561
1589
  }
1562
1590
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1563
1591
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1585,7 +1613,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1585
1613
  accessory.context.model = device.deviceType;
1586
1614
  accessory.context.deviceID = device.deviceId;
1587
1615
  if (device.firmware) {
1588
- accessory.context.FirmwareRevision = device.firmware;
1616
+ accessory.context.version = device.firmware;
1589
1617
  }
1590
1618
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1591
1619
  accessory.context.connectionType = await this.connectionType(device);
@@ -1617,7 +1645,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1617
1645
  existingAccessory.context.deviceID = device.deviceId;
1618
1646
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1619
1647
  if (device.firmware) {
1620
- existingAccessory.context.FirmwareRevision = device.firmware;
1648
+ existingAccessory.context.version = device.firmware;
1621
1649
  }
1622
1650
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1623
1651
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1645,7 +1673,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1645
1673
  accessory.context.model = device.deviceType;
1646
1674
  accessory.context.deviceID = device.deviceId;
1647
1675
  if (device.firmware) {
1648
- accessory.context.FirmwareRevision = device.firmware;
1676
+ accessory.context.version = device.firmware;
1649
1677
  }
1650
1678
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1651
1679
  accessory.context.connectionType = await this.connectionType(device);
@@ -1677,7 +1705,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1677
1705
  existingAccessory.context.deviceID = device.deviceId;
1678
1706
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1679
1707
  if (device.firmware) {
1680
- existingAccessory.context.FirmwareRevision = device.firmware;
1708
+ existingAccessory.context.version = device.firmware;
1681
1709
  }
1682
1710
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1683
1711
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1705,7 +1733,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1705
1733
  accessory.context.model = device.deviceType;
1706
1734
  accessory.context.deviceID = device.deviceId;
1707
1735
  if (device.firmware) {
1708
- accessory.context.FirmwareRevision = device.firmware;
1736
+ accessory.context.version = device.firmware;
1709
1737
  }
1710
1738
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1711
1739
  accessory.context.connectionType = await this.connectionType(device);
@@ -1737,7 +1765,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1737
1765
  existingAccessory.context.deviceID = device.deviceId;
1738
1766
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1739
1767
  if (device.firmware) {
1740
- existingAccessory.context.FirmwareRevision = device.firmware;
1768
+ existingAccessory.context.version = device.firmware;
1741
1769
  }
1742
1770
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1743
1771
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1765,7 +1793,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1765
1793
  accessory.context.model = device.deviceType;
1766
1794
  accessory.context.deviceID = device.deviceId;
1767
1795
  if (device.firmware) {
1768
- accessory.context.FirmwareRevision = device.firmware;
1796
+ accessory.context.version = device.firmware;
1769
1797
  }
1770
1798
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1771
1799
  accessory.context.connectionType = await this.connectionType(device);
@@ -1782,6 +1810,66 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1782
1810
  }
1783
1811
  }
1784
1812
 
1813
+ private async createFan(device: device & devicesConfig) {
1814
+ const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
1815
+
1816
+ // see if an accessory with the same uuid has already been registered and restored from
1817
+ // the cached devices we stored in the `configureAccessory` method above
1818
+ const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
1819
+
1820
+ if (existingAccessory) {
1821
+ // the accessory already exists
1822
+ if (await this.registerDevice(device)) {
1823
+ // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1824
+ existingAccessory.context.model = device.deviceType;
1825
+ existingAccessory.context.deviceID = device.deviceId;
1826
+ existingAccessory.displayName = device.configDeviceName || device.deviceName;
1827
+ if (device.firmware) {
1828
+ existingAccessory.context.version = device.firmware;
1829
+ }
1830
+ existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1831
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1832
+ existingAccessory.context.connectionType = await this.connectionType(device);
1833
+ this.api.updatePlatformAccessories([existingAccessory]);
1834
+ // create the accessory handler for the restored accessory
1835
+ // this is imported from `platformAccessory.ts`
1836
+ new Fan(this, existingAccessory, device);
1837
+ this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${existingAccessory.UUID})`);
1838
+ } else {
1839
+ this.unregisterPlatformAccessories(existingAccessory);
1840
+ }
1841
+ } else if (await this.registerDevice(device)) {
1842
+ // the accessory does not yet exist, so we need to create it
1843
+ if (!device.external) {
1844
+ this.infoLog(`Adding new accessory: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
1845
+ }
1846
+
1847
+ // create a new accessory
1848
+ const accessory = new this.api.platformAccessory(device.deviceName, uuid);
1849
+
1850
+ // store a copy of the device object in the `accessory.context`
1851
+ // the `context` property can be used to store any data about the accessory you may need
1852
+ accessory.context.device = device;
1853
+ accessory.context.model = device.deviceType;
1854
+ accessory.context.deviceID = device.deviceId;
1855
+ if (device.firmware) {
1856
+ accessory.context.version = device.firmware;
1857
+ }
1858
+ accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1859
+ accessory.context.connectionType = await this.connectionType(device);
1860
+ // create the accessory handler for the newly create accessory
1861
+ // this is imported from `platformAccessory.ts`
1862
+ new Fan(this, accessory, device);
1863
+ this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`);
1864
+
1865
+ // publish device externally or link the accessory to your platform
1866
+ this.externalOrPlatform(device, accessory);
1867
+ this.accessories.push(accessory);
1868
+ } else {
1869
+ this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
1870
+ }
1871
+ }
1872
+
1785
1873
  private async createRobotVacuumCleaner(device: device & devicesConfig) {
1786
1874
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
1787
1875
 
@@ -1797,7 +1885,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1797
1885
  existingAccessory.context.deviceID = device.deviceId;
1798
1886
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1799
1887
  if (device.firmware) {
1800
- existingAccessory.context.FirmwareRevision = device.firmware;
1888
+ existingAccessory.context.version = device.firmware;
1801
1889
  }
1802
1890
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1803
1891
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1825,7 +1913,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1825
1913
  accessory.context.model = device.deviceType;
1826
1914
  accessory.context.deviceID = device.deviceId;
1827
1915
  if (device.firmware) {
1828
- accessory.context.FirmwareRevision = device.firmware;
1916
+ accessory.context.version = device.firmware;
1829
1917
  }
1830
1918
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1831
1919
  accessory.context.connectionType = await this.connectionType(device);
@@ -1854,7 +1942,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1854
1942
  existingAccessory.context.model = device.remoteType;
1855
1943
  existingAccessory.context.deviceID = device.deviceId;
1856
1944
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1857
- existingAccessory.context.FirmwareRevision = device.firmware;
1945
+ if (device.version && !device.firmware) {
1946
+ existingAccessory.context.version = device.version;
1947
+ }
1858
1948
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1859
1949
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1860
1950
  existingAccessory.context.connectionType = device.connectionType;
@@ -1878,7 +1968,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1878
1968
  accessory.context.model = device.remoteType;
1879
1969
  accessory.context.deviceID = device.deviceId;
1880
1970
  if (device.firmware) {
1881
- accessory.context.FirmwareRevision = device.firmware;
1971
+ accessory.context.version = device.firmware;
1882
1972
  }
1883
1973
  accessory.context.deviceType = `IR: ${device.remoteType}`;
1884
1974
  accessory.context.connectionType = device.connectionType;
@@ -1894,7 +1984,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1894
1984
  }
1895
1985
  }
1896
1986
 
1897
- private async createFan(device: irdevice & devicesConfig) {
1987
+ private async createIRFan(device: irdevice & devicesConfig) {
1898
1988
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.remoteType}`);
1899
1989
 
1900
1990
  // see if an accessory with the same uuid has already been registered and restored from
@@ -1909,7 +1999,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1909
1999
  existingAccessory.context.deviceID = device.deviceId;
1910
2000
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1911
2001
  if (device.firmware) {
1912
- existingAccessory.context.FirmwareRevision = device.firmware;
2002
+ existingAccessory.context.version = device.firmware;
1913
2003
  }
1914
2004
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1915
2005
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1917,7 +2007,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1917
2007
  this.api.updatePlatformAccessories([existingAccessory]);
1918
2008
  // create the accessory handler for the restored accessory
1919
2009
  // this is imported from `platformAccessory.ts`
1920
- new Fan(this, existingAccessory, device);
2010
+ new IRFan(this, existingAccessory, device);
1921
2011
  this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${existingAccessory.UUID})`);
1922
2012
  } else {
1923
2013
  this.unregisterPlatformAccessories(existingAccessory);
@@ -1937,13 +2027,13 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1937
2027
  accessory.context.model = device.remoteType;
1938
2028
  accessory.context.deviceID = device.deviceId;
1939
2029
  if (device.firmware) {
1940
- accessory.context.FirmwareRevision = device.firmware;
2030
+ accessory.context.version = device.firmware;
1941
2031
  }
1942
2032
  accessory.context.deviceType = `IR: ${device.remoteType}`;
1943
2033
  accessory.context.connectionType = device.connectionType;
1944
2034
  // create the accessory handler for the newly create accessory
1945
2035
  // this is imported from `platformAccessory.ts`
1946
- new Fan(this, accessory, device);
2036
+ new IRFan(this, accessory, device);
1947
2037
  this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`);
1948
2038
 
1949
2039
  // publish device externally or link the accessory to your platform
@@ -1969,7 +2059,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1969
2059
  existingAccessory.context.deviceID = device.deviceId;
1970
2060
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1971
2061
  if (device.firmware) {
1972
- existingAccessory.context.FirmwareRevision = device.firmware;
2062
+ existingAccessory.context.version = device.firmware;
1973
2063
  }
1974
2064
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1975
2065
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1997,7 +2087,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1997
2087
  accessory.context.model = device.remoteType;
1998
2088
  accessory.context.deviceID = device.deviceId;
1999
2089
  if (device.firmware) {
2000
- accessory.context.FirmwareRevision = device.firmware;
2090
+ accessory.context.version = device.firmware;
2001
2091
  }
2002
2092
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2003
2093
  accessory.context.connectionType = device.connectionType;
@@ -2029,7 +2119,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2029
2119
  existingAccessory.context.deviceID = device.deviceId;
2030
2120
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
2031
2121
  if (device.firmware) {
2032
- existingAccessory.context.FirmwareRevision = device.firmware;
2122
+ existingAccessory.context.version = device.firmware;
2033
2123
  }
2034
2124
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2035
2125
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -2057,7 +2147,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2057
2147
  accessory.context.model = device.remoteType;
2058
2148
  accessory.context.deviceID = device.deviceId;
2059
2149
  if (device.firmware) {
2060
- accessory.context.FirmwareRevision = device.firmware;
2150
+ accessory.context.version = device.firmware;
2061
2151
  }
2062
2152
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2063
2153
  accessory.context.connectionType = device.connectionType;
@@ -2089,7 +2179,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2089
2179
  existingAccessory.context.deviceID = device.deviceId;
2090
2180
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
2091
2181
  if (device.firmware) {
2092
- existingAccessory.context.FirmwareRevision = device.firmware;
2182
+ existingAccessory.context.version = device.firmware;
2093
2183
  }
2094
2184
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2095
2185
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -2117,7 +2207,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2117
2207
  accessory.context.model = device.remoteType;
2118
2208
  accessory.context.deviceID = device.deviceId;
2119
2209
  if (device.firmware) {
2120
- accessory.context.FirmwareRevision = device.firmware;
2210
+ accessory.context.version = device.firmware;
2121
2211
  }
2122
2212
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2123
2213
  accessory.context.connectionType = device.connectionType;
@@ -2149,7 +2239,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2149
2239
  existingAccessory.context.deviceID = device.deviceId;
2150
2240
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
2151
2241
  if (device.firmware) {
2152
- existingAccessory.context.FirmwareRevision = device.firmware;
2242
+ existingAccessory.context.version = device.firmware;
2153
2243
  }
2154
2244
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2155
2245
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -2177,7 +2267,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2177
2267
  accessory.context.model = device.remoteType;
2178
2268
  accessory.context.deviceID = device.deviceId;
2179
2269
  if (device.firmware) {
2180
- accessory.context.FirmwareRevision = device.firmware;
2270
+ accessory.context.version = device.firmware;
2181
2271
  }
2182
2272
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2183
2273
  accessory.context.connectionType = device.connectionType;
@@ -2209,7 +2299,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2209
2299
  existingAccessory.context.deviceID = device.deviceId;
2210
2300
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
2211
2301
  if (device.firmware) {
2212
- existingAccessory.context.FirmwareRevision = device.firmware;
2302
+ existingAccessory.context.version = device.firmware;
2213
2303
  }
2214
2304
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2215
2305
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -2237,7 +2327,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2237
2327
  accessory.context.model = device.remoteType;
2238
2328
  accessory.context.deviceID = device.deviceId;
2239
2329
  if (device.firmware) {
2240
- accessory.context.FirmwareRevision = device.firmware;
2330
+ accessory.context.version = device.firmware;
2241
2331
  }
2242
2332
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2243
2333
  accessory.context.connectionType = device.connectionType;
@@ -2269,7 +2359,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2269
2359
  existingAccessory.context.deviceID = device.deviceId;
2270
2360
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
2271
2361
  if (device.firmware) {
2272
- existingAccessory.context.FirmwareRevision = device.firmware;
2362
+ existingAccessory.context.version = device.firmware;
2273
2363
  }
2274
2364
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2275
2365
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -2297,7 +2387,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2297
2387
  accessory.context.model = device.remoteType;
2298
2388
  accessory.context.deviceID = device.deviceId;
2299
2389
  if (device.firmware) {
2300
- accessory.context.FirmwareRevision = device.firmware;
2390
+ accessory.context.version = device.firmware;
2301
2391
  }
2302
2392
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2303
2393
  accessory.context.connectionType = device.connectionType;
@@ -2329,7 +2419,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2329
2419
  existingAccessory.context.deviceID = device.deviceId;
2330
2420
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
2331
2421
  if (device.firmware) {
2332
- existingAccessory.context.FirmwareRevision = device.firmware;
2422
+ existingAccessory.context.version = device.firmware;
2333
2423
  }
2334
2424
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2335
2425
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -2357,7 +2447,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2357
2447
  accessory.context.model = device.remoteType;
2358
2448
  accessory.context.deviceID = device.deviceId;
2359
2449
  if (device.firmware) {
2360
- accessory.context.FirmwareRevision = device.firmware;
2450
+ accessory.context.version = device.firmware;
2361
2451
  }
2362
2452
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2363
2453
  accessory.context.connectionType = device.connectionType;
@@ -2627,6 +2717,30 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2627
2717
  }
2628
2718
  }
2629
2719
 
2720
+ async retryRequest(deviceMaxRetries: number, deviceDelayBetweenRetries: number, url: string | URL | UrlObject,
2721
+ options?: { dispatcher?: Dispatcher } & Omit<Dispatcher.RequestOptions,
2722
+ 'origin' | 'path' | 'method'> & Partial<Pick<Dispatcher.RequestOptions, 'method'>>): Promise<{ body: any; statusCode: number }> {
2723
+ let retryCount = 0;
2724
+ const maxRetries = deviceMaxRetries;
2725
+ const delayBetweenRetries = deviceDelayBetweenRetries;
2726
+ while (retryCount < maxRetries) {
2727
+ try {
2728
+ const { body, statusCode } = await request(url, options);
2729
+ if (statusCode === 200 || statusCode === 100) {
2730
+ return { body, statusCode };
2731
+ } else {
2732
+ this.debugLog(`Received status code: ${statusCode}`);
2733
+ }
2734
+ } catch (error: any) {
2735
+ this.errorLog(`Error making request: ${error.message}`);
2736
+ }
2737
+ retryCount++;
2738
+ this.debugLog(`Retry attempt ${retryCount} of ${maxRetries}`);
2739
+ await sleep(delayBetweenRetries);
2740
+ }
2741
+ return { body: null, statusCode: -1 };
2742
+ }
2743
+
2630
2744
  // BLE Connection
2631
2745
  async connectBLE() {
2632
2746
  let switchbot: any;
@@ -2663,6 +2777,22 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2663
2777
  if (this.config.options.pushRate) {
2664
2778
  platformConfig.pushRate = this.config.options.pushRate;
2665
2779
  }
2780
+ if (this.config.options.maxRetries) {
2781
+ this.maxRetries = this.config.options.maxRetries;
2782
+ platformConfig.maxRetries = this.config.options.maxRetries;
2783
+ } else {
2784
+ this.maxRetries = 3;
2785
+ this.debugWarnLog('Using Default Max Retries');
2786
+ platformConfig.maxRetries = this.maxRetries;
2787
+ }
2788
+ if (this.config.options.delayBetweenRetries) {
2789
+ this.delayBetweenRetries = this.config.options.delayBetweenRetries * 1000;
2790
+ platformConfig.delayBetweenRetries = this.config.options.delayBetweenRetries;
2791
+ } else {
2792
+ this.delayBetweenRetries = 3000;
2793
+ this.debugWarnLog('Using Default Delay Between Retries');
2794
+ platformConfig.delayBetweenRetries = this.delayBetweenRetries / 1000;
2795
+ }
2666
2796
  if (Object.entries(platformConfig).length !== 0) {
2667
2797
  this.debugLog(`Platform Config: ${JSON.stringify(platformConfig)}`);
2668
2798
  }
@@ -2688,6 +2818,12 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2688
2818
  * If device level logging is turned on, log to log.warn
2689
2819
  * Otherwise send debug logs to log.debug
2690
2820
  */
2821
+ successLog(...log: any[]): void {
2822
+ if (this.enablingPlatformLogging()) {
2823
+ this.log.success(String(...log));
2824
+ }
2825
+ }
2826
+
2691
2827
  infoLog(...log: any[]): void {
2692
2828
  if (this.enablingPlatformLogging()) {
2693
2829
  this.log.info(String(...log));