@switchbot/homebridge-switchbot 3.5.0-beta.6 → 3.5.0-beta.61

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 +408 -779
  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 +696 -822
  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 +237 -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 +280 -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 +242 -544
  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 +402 -805
  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 +684 -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 +535 -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 +246 -613
  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 +232 -593
  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 +185 -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 +277 -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 +241 -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 +181 -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 +170 -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 +178 -531
  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 +92 -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 +197 -521
  75. package/dist/device/robotvacuumcleaner.js.map +1 -1
  76. package/dist/device/waterdetector.d.ts +10 -65
  77. package/dist/device/waterdetector.d.ts.map +1 -1
  78. package/dist/device/waterdetector.js +139 -495
  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 +9 -49
  88. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  89. package/dist/irdevice/airconditioner.js +309 -419
  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 +72 -304
  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 +34 -278
  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 +100 -338
  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 +87 -357
  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 +352 -546
  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 +82 -321
  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 +41 -284
  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 +42 -287
  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 -169
  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 +442 -814
  143. package/src/device/bot.ts +754 -915
  144. package/src/device/ceilinglight.ts +255 -633
  145. package/src/device/colorbulb.ts +295 -685
  146. package/src/device/contact.ts +277 -571
  147. package/src/device/curtain.ts +431 -835
  148. package/src/device/device.ts +709 -0
  149. package/src/device/fan.ts +591 -0
  150. package/src/device/hub.ts +286 -644
  151. package/src/device/humidifier.ts +266 -646
  152. package/src/device/iosensor.ts +220 -625
  153. package/src/device/lightstrip.ts +305 -620
  154. package/src/device/lock.ts +280 -600
  155. package/src/device/meter.ts +216 -617
  156. package/src/device/meterplus.ts +205 -619
  157. package/src/device/motion.ts +206 -556
  158. package/src/device/plug.ts +107 -490
  159. package/src/device/robotvacuumcleaner.ts +223 -550
  160. package/src/device/waterdetector.ts +160 -519
  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 +333 -447
  165. package/src/irdevice/airpurifier.ts +92 -322
  166. package/src/irdevice/camera.ts +45 -294
  167. package/src/irdevice/fan.ts +115 -353
  168. package/src/irdevice/irdevice.ts +346 -0
  169. package/src/irdevice/light.ts +110 -385
  170. package/src/irdevice/other.ts +399 -616
  171. package/src/irdevice/tv.ts +103 -340
  172. package/src/irdevice/vacuumcleaner.ts +52 -306
  173. package/src/irdevice/waterheater.ts +53 -311
  174. package/src/platform.ts +355 -216
  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;
@@ -713,12 +740,16 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
713
740
  this.warnLog(`Device: ${device.deviceName} with Device Type: ${device.deviceType}, is currently not supported.`);
714
741
  break;
715
742
  case 'Remote':
743
+ case 'remote with screen+':
716
744
  this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId} is Not Supported.`);
717
745
  break;
746
+ case 'Battery Circulator Fan':
747
+ this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
748
+ this.createFan(device);
749
+ break;
718
750
  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');
751
+ this.warnLog(`Device: ${device.deviceName} with Device Type: ${device.deviceType}, is currently not supported.`,
752
+ + 'Submit Feature Requests Here: https://tinyurl.com/SwitchBotFeatureRequest');
722
753
  }
723
754
  }
724
755
 
@@ -750,7 +781,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
750
781
  case 'Fan':
751
782
  case 'DIY Fan':
752
783
  this.debugLog(`Discovered ${device.remoteType}: ${device.deviceId}`);
753
- this.createFan(device);
784
+ this.createIRFan(device);
754
785
  break;
755
786
  case 'Air Conditioner':
756
787
  case 'DIY Air Conditioner':
@@ -808,7 +839,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
808
839
  existingAccessory.context.deviceID = device.deviceId;
809
840
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
810
841
  if (device.firmware) {
811
- existingAccessory.context.FirmwareRevision = device.firmware;
842
+ existingAccessory.context.version = device.firmware;
812
843
  }
813
844
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
814
845
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -836,7 +867,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
836
867
  accessory.context.model = device.deviceType;
837
868
  accessory.context.deviceID = device.deviceId;
838
869
  if (device.firmware) {
839
- accessory.context.FirmwareRevision = device.firmware;
870
+ accessory.context.version = device.firmware;
840
871
  }
841
872
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
842
873
  accessory.context.connectionType = await this.connectionType(device);
@@ -868,7 +899,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
868
899
  existingAccessory.context.deviceID = device.deviceId;
869
900
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
870
901
  if (device.firmware) {
871
- existingAccessory.context.FirmwareRevision = device.firmware;
902
+ existingAccessory.context.version = device.firmware;
872
903
  }
873
904
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
874
905
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -896,11 +927,11 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
896
927
  accessory.context.model = device.deviceType;
897
928
  accessory.context.deviceID = device.deviceId;
898
929
  if (device.firmware) {
899
- accessory.context.FirmwareRevision = device.firmware;
930
+ accessory.context.version = device.firmware;
900
931
  }
901
932
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
902
933
  accessory.context.connectionType = await this.connectionType(device);
903
- // accessory.context.FirmwareRevision = findaccessories.accessoryAttribute.softwareRevision;
934
+ // accessory.context.version = findaccessories.accessoryAttribute.softwareRevision;
904
935
  // create the accessory handler for the newly create accessory
905
936
  // this is imported from `platformAccessory.ts`
906
937
  new Bot(this, accessory, device);
@@ -929,7 +960,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
929
960
  existingAccessory.context.deviceID = device.deviceId;
930
961
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
931
962
  if (device.firmware) {
932
- existingAccessory.context.FirmwareRevision = device.firmware;
963
+ existingAccessory.context.version = device.firmware;
933
964
  }
934
965
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
935
966
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -957,7 +988,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
957
988
  accessory.context.model = device.deviceType;
958
989
  accessory.context.deviceID = device.deviceId;
959
990
  if (device.firmware) {
960
- accessory.context.FirmwareRevision = device.firmware;
991
+ accessory.context.version = device.firmware;
961
992
  }
962
993
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
963
994
  accessory.context.connectionType = await this.connectionType(device);
@@ -990,7 +1021,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
990
1021
  existingAccessory.context.deviceID = device.deviceId;
991
1022
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
992
1023
  if (device.firmware) {
993
- existingAccessory.context.FirmwareRevision = device.firmware;
1024
+ existingAccessory.context.version = device.firmware;
994
1025
  }
995
1026
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
996
1027
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1018,7 +1049,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1018
1049
  accessory.context.model = device.deviceType;
1019
1050
  accessory.context.deviceID = device.deviceId;
1020
1051
  if (device.firmware) {
1021
- accessory.context.FirmwareRevision = device.firmware;
1052
+ accessory.context.version = device.firmware;
1022
1053
  }
1023
1054
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1024
1055
  accessory.context.connectionType = await this.connectionType(device);
@@ -1051,7 +1082,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1051
1082
  existingAccessory.context.deviceID = device.deviceId;
1052
1083
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1053
1084
  if (device.firmware) {
1054
- existingAccessory.context.FirmwareRevision = device.firmware;
1085
+ existingAccessory.context.version = device.firmware;
1055
1086
  }
1056
1087
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1057
1088
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1079,7 +1110,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1079
1110
  accessory.context.model = device.deviceType;
1080
1111
  accessory.context.deviceID = device.deviceId;
1081
1112
  if (device.firmware) {
1082
- accessory.context.FirmwareRevision = device.firmware;
1113
+ accessory.context.version = device.firmware;
1083
1114
  }
1084
1115
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1085
1116
  accessory.context.connectionType = await this.connectionType(device);
@@ -1111,7 +1142,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1111
1142
  existingAccessory.context.deviceID = device.deviceId;
1112
1143
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1113
1144
  if (device.firmware) {
1114
- existingAccessory.context.FirmwareRevision = device.firmware;
1145
+ existingAccessory.context.version = device.firmware;
1115
1146
  }
1116
1147
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1117
1148
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1139,7 +1170,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1139
1170
  accessory.context.model = device.deviceType;
1140
1171
  accessory.context.deviceID = device.deviceId;
1141
1172
  if (device.firmware) {
1142
- accessory.context.FirmwareRevision = device.firmware;
1173
+ accessory.context.version = device.firmware;
1143
1174
  }
1144
1175
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1145
1176
  accessory.context.connectionType = await this.connectionType(device);
@@ -1171,7 +1202,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1171
1202
  existingAccessory.context.deviceID = device.deviceId;
1172
1203
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1173
1204
  if (device.firmware) {
1174
- existingAccessory.context.FirmwareRevision = device.firmware;
1205
+ existingAccessory.context.version = device.firmware;
1175
1206
  }
1176
1207
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1177
1208
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1199,7 +1230,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1199
1230
  accessory.context.model = device.deviceType;
1200
1231
  accessory.context.deviceID = device.deviceId;
1201
1232
  if (device.firmware) {
1202
- accessory.context.FirmwareRevision = device.firmware;
1233
+ accessory.context.version = device.firmware;
1203
1234
  }
1204
1235
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1205
1236
  accessory.context.connectionType = await this.connectionType(device);
@@ -1231,7 +1262,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1231
1262
  existingAccessory.context.deviceID = device.deviceId;
1232
1263
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1233
1264
  if (device.firmware) {
1234
- existingAccessory.context.FirmwareRevision = device.firmware;
1265
+ existingAccessory.context.version = device.firmware;
1235
1266
  }
1236
1267
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1237
1268
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1259,7 +1290,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1259
1290
  accessory.context.model = device.deviceType;
1260
1291
  accessory.context.deviceID = device.deviceId;
1261
1292
  if (device.firmware) {
1262
- accessory.context.FirmwareRevision = device.firmware;
1293
+ accessory.context.version = device.firmware;
1263
1294
  }
1264
1295
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1265
1296
  accessory.context.connectionType = await this.connectionType(device);
@@ -1291,7 +1322,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1291
1322
  existingAccessory.context.deviceID = device.deviceId;
1292
1323
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1293
1324
  if (device.firmware) {
1294
- existingAccessory.context.FirmwareRevision = device.firmware;
1325
+ existingAccessory.context.version = device.firmware;
1295
1326
  }
1296
1327
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1297
1328
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1319,7 +1350,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1319
1350
  accessory.context.model = device.deviceType;
1320
1351
  accessory.context.deviceID = device.deviceId;
1321
1352
  if (device.firmware) {
1322
- accessory.context.FirmwareRevision = device.firmware;
1353
+ accessory.context.version = device.firmware;
1323
1354
  }
1324
1355
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1325
1356
  accessory.context.connectionType = await this.connectionType(device);
@@ -1351,7 +1382,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1351
1382
  existingAccessory.context.deviceID = device.deviceId;
1352
1383
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1353
1384
  if (device.firmware) {
1354
- existingAccessory.context.FirmwareRevision = device.firmware;
1385
+ existingAccessory.context.version = device.firmware;
1355
1386
  }
1356
1387
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1357
1388
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1392,7 +1423,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1392
1423
  accessory.context.model = device.deviceType;
1393
1424
  accessory.context.deviceID = device.deviceId;
1394
1425
  if (device.firmware) {
1395
- accessory.context.FirmwareRevision = device.firmware;
1426
+ accessory.context.version = device.firmware;
1396
1427
  }
1397
1428
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1398
1429
  accessory.context.connectionType = await this.connectionType(device);
@@ -1424,7 +1455,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1424
1455
  existingAccessory.context.deviceID = device.deviceId;
1425
1456
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1426
1457
  if (device.firmware) {
1427
- existingAccessory.context.FirmwareRevision = device.firmware;
1458
+ existingAccessory.context.version = device.firmware;
1428
1459
  }
1429
1460
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1430
1461
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1465,7 +1496,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1465
1496
  accessory.context.model = device.deviceType;
1466
1497
  accessory.context.deviceID = device.deviceId;
1467
1498
  if (device.firmware) {
1468
- accessory.context.FirmwareRevision = device.firmware;
1499
+ accessory.context.version = device.firmware;
1469
1500
  }
1470
1501
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1471
1502
  accessory.context.connectionType = await this.connectionType(device);
@@ -1497,7 +1528,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1497
1528
  existingAccessory.context.deviceID = device.deviceId;
1498
1529
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1499
1530
  if (device.firmware) {
1500
- existingAccessory.context.FirmwareRevision = device.firmware;
1531
+ existingAccessory.context.version = device.firmware;
1501
1532
  }
1502
1533
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1503
1534
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1525,7 +1556,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1525
1556
  accessory.context.model = device.deviceType;
1526
1557
  accessory.context.deviceID = device.deviceId;
1527
1558
  if (device.firmware) {
1528
- accessory.context.FirmwareRevision = device.firmware;
1559
+ accessory.context.version = device.firmware;
1529
1560
  }
1530
1561
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1531
1562
  accessory.context.connectionType = await this.connectionType(device);
@@ -1557,7 +1588,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1557
1588
  existingAccessory.context.deviceID = device.deviceId;
1558
1589
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1559
1590
  if (device.firmware) {
1560
- existingAccessory.context.FirmwareRevision = device.firmware;
1591
+ existingAccessory.context.version = device.firmware;
1561
1592
  }
1562
1593
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1563
1594
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1585,7 +1616,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1585
1616
  accessory.context.model = device.deviceType;
1586
1617
  accessory.context.deviceID = device.deviceId;
1587
1618
  if (device.firmware) {
1588
- accessory.context.FirmwareRevision = device.firmware;
1619
+ accessory.context.version = device.firmware;
1589
1620
  }
1590
1621
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1591
1622
  accessory.context.connectionType = await this.connectionType(device);
@@ -1617,7 +1648,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1617
1648
  existingAccessory.context.deviceID = device.deviceId;
1618
1649
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1619
1650
  if (device.firmware) {
1620
- existingAccessory.context.FirmwareRevision = device.firmware;
1651
+ existingAccessory.context.version = device.firmware;
1621
1652
  }
1622
1653
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1623
1654
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1645,7 +1676,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1645
1676
  accessory.context.model = device.deviceType;
1646
1677
  accessory.context.deviceID = device.deviceId;
1647
1678
  if (device.firmware) {
1648
- accessory.context.FirmwareRevision = device.firmware;
1679
+ accessory.context.version = device.firmware;
1649
1680
  }
1650
1681
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1651
1682
  accessory.context.connectionType = await this.connectionType(device);
@@ -1677,7 +1708,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1677
1708
  existingAccessory.context.deviceID = device.deviceId;
1678
1709
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1679
1710
  if (device.firmware) {
1680
- existingAccessory.context.FirmwareRevision = device.firmware;
1711
+ existingAccessory.context.version = device.firmware;
1681
1712
  }
1682
1713
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1683
1714
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1705,7 +1736,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1705
1736
  accessory.context.model = device.deviceType;
1706
1737
  accessory.context.deviceID = device.deviceId;
1707
1738
  if (device.firmware) {
1708
- accessory.context.FirmwareRevision = device.firmware;
1739
+ accessory.context.version = device.firmware;
1709
1740
  }
1710
1741
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1711
1742
  accessory.context.connectionType = await this.connectionType(device);
@@ -1737,7 +1768,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1737
1768
  existingAccessory.context.deviceID = device.deviceId;
1738
1769
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1739
1770
  if (device.firmware) {
1740
- existingAccessory.context.FirmwareRevision = device.firmware;
1771
+ existingAccessory.context.version = device.firmware;
1741
1772
  }
1742
1773
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1743
1774
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1765,7 +1796,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1765
1796
  accessory.context.model = device.deviceType;
1766
1797
  accessory.context.deviceID = device.deviceId;
1767
1798
  if (device.firmware) {
1768
- accessory.context.FirmwareRevision = device.firmware;
1799
+ accessory.context.version = device.firmware;
1769
1800
  }
1770
1801
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1771
1802
  accessory.context.connectionType = await this.connectionType(device);
@@ -1782,6 +1813,66 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1782
1813
  }
1783
1814
  }
1784
1815
 
1816
+ private async createFan(device: device & devicesConfig) {
1817
+ const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
1818
+
1819
+ // see if an accessory with the same uuid has already been registered and restored from
1820
+ // the cached devices we stored in the `configureAccessory` method above
1821
+ const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
1822
+
1823
+ if (existingAccessory) {
1824
+ // the accessory already exists
1825
+ if (await this.registerDevice(device)) {
1826
+ // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1827
+ existingAccessory.context.model = device.deviceType;
1828
+ existingAccessory.context.deviceID = device.deviceId;
1829
+ existingAccessory.displayName = device.configDeviceName || device.deviceName;
1830
+ if (device.firmware) {
1831
+ existingAccessory.context.version = device.firmware;
1832
+ }
1833
+ existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1834
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1835
+ existingAccessory.context.connectionType = await this.connectionType(device);
1836
+ this.api.updatePlatformAccessories([existingAccessory]);
1837
+ // create the accessory handler for the restored accessory
1838
+ // this is imported from `platformAccessory.ts`
1839
+ new Fan(this, existingAccessory, device);
1840
+ this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${existingAccessory.UUID})`);
1841
+ } else {
1842
+ this.unregisterPlatformAccessories(existingAccessory);
1843
+ }
1844
+ } else if (await this.registerDevice(device)) {
1845
+ // the accessory does not yet exist, so we need to create it
1846
+ if (!device.external) {
1847
+ this.infoLog(`Adding new accessory: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
1848
+ }
1849
+
1850
+ // create a new accessory
1851
+ const accessory = new this.api.platformAccessory(device.deviceName, uuid);
1852
+
1853
+ // store a copy of the device object in the `accessory.context`
1854
+ // the `context` property can be used to store any data about the accessory you may need
1855
+ accessory.context.device = device;
1856
+ accessory.context.model = device.deviceType;
1857
+ accessory.context.deviceID = device.deviceId;
1858
+ if (device.firmware) {
1859
+ accessory.context.version = device.firmware;
1860
+ }
1861
+ accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1862
+ accessory.context.connectionType = await this.connectionType(device);
1863
+ // create the accessory handler for the newly create accessory
1864
+ // this is imported from `platformAccessory.ts`
1865
+ new Fan(this, accessory, device);
1866
+ this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`);
1867
+
1868
+ // publish device externally or link the accessory to your platform
1869
+ this.externalOrPlatform(device, accessory);
1870
+ this.accessories.push(accessory);
1871
+ } else {
1872
+ this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
1873
+ }
1874
+ }
1875
+
1785
1876
  private async createRobotVacuumCleaner(device: device & devicesConfig) {
1786
1877
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
1787
1878
 
@@ -1797,7 +1888,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1797
1888
  existingAccessory.context.deviceID = device.deviceId;
1798
1889
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1799
1890
  if (device.firmware) {
1800
- existingAccessory.context.FirmwareRevision = device.firmware;
1891
+ existingAccessory.context.version = device.firmware;
1801
1892
  }
1802
1893
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1803
1894
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1825,7 +1916,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1825
1916
  accessory.context.model = device.deviceType;
1826
1917
  accessory.context.deviceID = device.deviceId;
1827
1918
  if (device.firmware) {
1828
- accessory.context.FirmwareRevision = device.firmware;
1919
+ accessory.context.version = device.firmware;
1829
1920
  }
1830
1921
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1831
1922
  accessory.context.connectionType = await this.connectionType(device);
@@ -1854,7 +1945,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1854
1945
  existingAccessory.context.model = device.remoteType;
1855
1946
  existingAccessory.context.deviceID = device.deviceId;
1856
1947
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1857
- existingAccessory.context.FirmwareRevision = device.firmware;
1948
+ if (device.version && !device.firmware) {
1949
+ existingAccessory.context.version = device.version;
1950
+ }
1858
1951
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1859
1952
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1860
1953
  existingAccessory.context.connectionType = device.connectionType;
@@ -1878,7 +1971,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1878
1971
  accessory.context.model = device.remoteType;
1879
1972
  accessory.context.deviceID = device.deviceId;
1880
1973
  if (device.firmware) {
1881
- accessory.context.FirmwareRevision = device.firmware;
1974
+ accessory.context.version = device.firmware;
1882
1975
  }
1883
1976
  accessory.context.deviceType = `IR: ${device.remoteType}`;
1884
1977
  accessory.context.connectionType = device.connectionType;
@@ -1894,7 +1987,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1894
1987
  }
1895
1988
  }
1896
1989
 
1897
- private async createFan(device: irdevice & devicesConfig) {
1990
+ private async createIRFan(device: irdevice & devicesConfig) {
1898
1991
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.remoteType}`);
1899
1992
 
1900
1993
  // see if an accessory with the same uuid has already been registered and restored from
@@ -1909,7 +2002,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1909
2002
  existingAccessory.context.deviceID = device.deviceId;
1910
2003
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1911
2004
  if (device.firmware) {
1912
- existingAccessory.context.FirmwareRevision = device.firmware;
2005
+ existingAccessory.context.version = device.firmware;
1913
2006
  }
1914
2007
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1915
2008
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1917,7 +2010,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1917
2010
  this.api.updatePlatformAccessories([existingAccessory]);
1918
2011
  // create the accessory handler for the restored accessory
1919
2012
  // this is imported from `platformAccessory.ts`
1920
- new Fan(this, existingAccessory, device);
2013
+ new IRFan(this, existingAccessory, device);
1921
2014
  this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${existingAccessory.UUID})`);
1922
2015
  } else {
1923
2016
  this.unregisterPlatformAccessories(existingAccessory);
@@ -1937,13 +2030,13 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1937
2030
  accessory.context.model = device.remoteType;
1938
2031
  accessory.context.deviceID = device.deviceId;
1939
2032
  if (device.firmware) {
1940
- accessory.context.FirmwareRevision = device.firmware;
2033
+ accessory.context.version = device.firmware;
1941
2034
  }
1942
2035
  accessory.context.deviceType = `IR: ${device.remoteType}`;
1943
2036
  accessory.context.connectionType = device.connectionType;
1944
2037
  // create the accessory handler for the newly create accessory
1945
2038
  // this is imported from `platformAccessory.ts`
1946
- new Fan(this, accessory, device);
2039
+ new IRFan(this, accessory, device);
1947
2040
  this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`);
1948
2041
 
1949
2042
  // publish device externally or link the accessory to your platform
@@ -1969,7 +2062,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1969
2062
  existingAccessory.context.deviceID = device.deviceId;
1970
2063
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1971
2064
  if (device.firmware) {
1972
- existingAccessory.context.FirmwareRevision = device.firmware;
2065
+ existingAccessory.context.version = device.firmware;
1973
2066
  }
1974
2067
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1975
2068
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1997,7 +2090,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1997
2090
  accessory.context.model = device.remoteType;
1998
2091
  accessory.context.deviceID = device.deviceId;
1999
2092
  if (device.firmware) {
2000
- accessory.context.FirmwareRevision = device.firmware;
2093
+ accessory.context.version = device.firmware;
2001
2094
  }
2002
2095
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2003
2096
  accessory.context.connectionType = device.connectionType;
@@ -2029,7 +2122,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2029
2122
  existingAccessory.context.deviceID = device.deviceId;
2030
2123
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
2031
2124
  if (device.firmware) {
2032
- existingAccessory.context.FirmwareRevision = device.firmware;
2125
+ existingAccessory.context.version = device.firmware;
2033
2126
  }
2034
2127
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2035
2128
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -2057,7 +2150,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2057
2150
  accessory.context.model = device.remoteType;
2058
2151
  accessory.context.deviceID = device.deviceId;
2059
2152
  if (device.firmware) {
2060
- accessory.context.FirmwareRevision = device.firmware;
2153
+ accessory.context.version = device.firmware;
2061
2154
  }
2062
2155
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2063
2156
  accessory.context.connectionType = device.connectionType;
@@ -2089,7 +2182,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2089
2182
  existingAccessory.context.deviceID = device.deviceId;
2090
2183
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
2091
2184
  if (device.firmware) {
2092
- existingAccessory.context.FirmwareRevision = device.firmware;
2185
+ existingAccessory.context.version = device.firmware;
2093
2186
  }
2094
2187
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2095
2188
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -2117,7 +2210,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2117
2210
  accessory.context.model = device.remoteType;
2118
2211
  accessory.context.deviceID = device.deviceId;
2119
2212
  if (device.firmware) {
2120
- accessory.context.FirmwareRevision = device.firmware;
2213
+ accessory.context.version = device.firmware;
2121
2214
  }
2122
2215
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2123
2216
  accessory.context.connectionType = device.connectionType;
@@ -2149,7 +2242,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2149
2242
  existingAccessory.context.deviceID = device.deviceId;
2150
2243
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
2151
2244
  if (device.firmware) {
2152
- existingAccessory.context.FirmwareRevision = device.firmware;
2245
+ existingAccessory.context.version = device.firmware;
2153
2246
  }
2154
2247
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2155
2248
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -2177,7 +2270,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2177
2270
  accessory.context.model = device.remoteType;
2178
2271
  accessory.context.deviceID = device.deviceId;
2179
2272
  if (device.firmware) {
2180
- accessory.context.FirmwareRevision = device.firmware;
2273
+ accessory.context.version = device.firmware;
2181
2274
  }
2182
2275
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2183
2276
  accessory.context.connectionType = device.connectionType;
@@ -2209,7 +2302,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2209
2302
  existingAccessory.context.deviceID = device.deviceId;
2210
2303
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
2211
2304
  if (device.firmware) {
2212
- existingAccessory.context.FirmwareRevision = device.firmware;
2305
+ existingAccessory.context.version = device.firmware;
2213
2306
  }
2214
2307
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2215
2308
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -2237,7 +2330,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2237
2330
  accessory.context.model = device.remoteType;
2238
2331
  accessory.context.deviceID = device.deviceId;
2239
2332
  if (device.firmware) {
2240
- accessory.context.FirmwareRevision = device.firmware;
2333
+ accessory.context.version = device.firmware;
2241
2334
  }
2242
2335
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2243
2336
  accessory.context.connectionType = device.connectionType;
@@ -2269,7 +2362,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2269
2362
  existingAccessory.context.deviceID = device.deviceId;
2270
2363
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
2271
2364
  if (device.firmware) {
2272
- existingAccessory.context.FirmwareRevision = device.firmware;
2365
+ existingAccessory.context.version = device.firmware;
2273
2366
  }
2274
2367
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2275
2368
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -2297,7 +2390,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2297
2390
  accessory.context.model = device.remoteType;
2298
2391
  accessory.context.deviceID = device.deviceId;
2299
2392
  if (device.firmware) {
2300
- accessory.context.FirmwareRevision = device.firmware;
2393
+ accessory.context.version = device.firmware;
2301
2394
  }
2302
2395
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2303
2396
  accessory.context.connectionType = device.connectionType;
@@ -2329,7 +2422,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2329
2422
  existingAccessory.context.deviceID = device.deviceId;
2330
2423
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
2331
2424
  if (device.firmware) {
2332
- existingAccessory.context.FirmwareRevision = device.firmware;
2425
+ existingAccessory.context.version = device.firmware;
2333
2426
  }
2334
2427
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2335
2428
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -2357,7 +2450,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2357
2450
  accessory.context.model = device.remoteType;
2358
2451
  accessory.context.deviceID = device.deviceId;
2359
2452
  if (device.firmware) {
2360
- accessory.context.FirmwareRevision = device.firmware;
2453
+ accessory.context.version = device.firmware;
2361
2454
  }
2362
2455
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2363
2456
  accessory.context.connectionType = device.connectionType;
@@ -2627,6 +2720,30 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2627
2720
  }
2628
2721
  }
2629
2722
 
2723
+ async retryRequest(deviceMaxRetries: number, deviceDelayBetweenRetries: number, url: string | URL | UrlObject,
2724
+ options?: { dispatcher?: Dispatcher } & Omit<Dispatcher.RequestOptions,
2725
+ 'origin' | 'path' | 'method'> & Partial<Pick<Dispatcher.RequestOptions, 'method'>>): Promise<{ body: any; statusCode: number }> {
2726
+ let retryCount = 0;
2727
+ const maxRetries = deviceMaxRetries;
2728
+ const delayBetweenRetries = deviceDelayBetweenRetries;
2729
+ while (retryCount < maxRetries) {
2730
+ try {
2731
+ const { body, statusCode } = await request(url, options);
2732
+ if (statusCode === 200 || statusCode === 100) {
2733
+ return { body, statusCode };
2734
+ } else {
2735
+ this.debugLog(`Received status code: ${statusCode}`);
2736
+ }
2737
+ } catch (error: any) {
2738
+ this.errorLog(`Error making request: ${error.message}`);
2739
+ }
2740
+ retryCount++;
2741
+ this.debugLog(`Retry attempt ${retryCount} of ${maxRetries}`);
2742
+ await sleep(delayBetweenRetries);
2743
+ }
2744
+ return { body: null, statusCode: -1 };
2745
+ }
2746
+
2630
2747
  // BLE Connection
2631
2748
  async connectBLE() {
2632
2749
  let switchbot: any;
@@ -2663,6 +2780,22 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2663
2780
  if (this.config.options.pushRate) {
2664
2781
  platformConfig.pushRate = this.config.options.pushRate;
2665
2782
  }
2783
+ if (this.config.options.maxRetries) {
2784
+ this.maxRetries = this.config.options.maxRetries;
2785
+ platformConfig.maxRetries = this.config.options.maxRetries;
2786
+ } else {
2787
+ this.maxRetries = 3;
2788
+ this.debugWarnLog('Using Default Max Retries');
2789
+ platformConfig.maxRetries = this.maxRetries;
2790
+ }
2791
+ if (this.config.options.delayBetweenRetries) {
2792
+ this.delayBetweenRetries = this.config.options.delayBetweenRetries * 1000;
2793
+ platformConfig.delayBetweenRetries = this.config.options.delayBetweenRetries;
2794
+ } else {
2795
+ this.delayBetweenRetries = 3000;
2796
+ this.debugWarnLog('Using Default Delay Between Retries');
2797
+ platformConfig.delayBetweenRetries = this.delayBetweenRetries / 1000;
2798
+ }
2666
2799
  if (Object.entries(platformConfig).length !== 0) {
2667
2800
  this.debugLog(`Platform Config: ${JSON.stringify(platformConfig)}`);
2668
2801
  }
@@ -2688,6 +2821,12 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
2688
2821
  * If device level logging is turned on, log to log.warn
2689
2822
  * Otherwise send debug logs to log.debug
2690
2823
  */
2824
+ successLog(...log: any[]): void {
2825
+ if (this.enablingPlatformLogging()) {
2826
+ this.log.success(String(...log));
2827
+ }
2828
+ }
2829
+
2691
2830
  infoLog(...log: any[]): void {
2692
2831
  if (this.enablingPlatformLogging()) {
2693
2832
  this.log.info(String(...log));