@switchbot/homebridge-switchbot 3.5.0-beta.9 → 3.5.0

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 (178) hide show
  1. package/.vscode/settings.json +4 -1
  2. package/CHANGELOG.md +4 -1
  3. package/config.schema.json +166 -24
  4. package/dist/device/blindtilt.d.ts +21 -96
  5. package/dist/device/blindtilt.d.ts.map +1 -1
  6. package/dist/device/blindtilt.js +439 -817
  7. package/dist/device/blindtilt.js.map +1 -1
  8. package/dist/device/bot.d.ts +27 -72
  9. package/dist/device/bot.d.ts.map +1 -1
  10. package/dist/device/bot.js +835 -865
  11. package/dist/device/bot.js.map +1 -1
  12. package/dist/device/ceilinglight.d.ts +15 -69
  13. package/dist/device/ceilinglight.d.ts.map +1 -1
  14. package/dist/device/ceilinglight.js +287 -653
  15. package/dist/device/ceilinglight.js.map +1 -1
  16. package/dist/device/colorbulb.d.ts +15 -76
  17. package/dist/device/colorbulb.d.ts.map +1 -1
  18. package/dist/device/colorbulb.js +354 -732
  19. package/dist/device/colorbulb.js.map +1 -1
  20. package/dist/device/contact.d.ts +14 -66
  21. package/dist/device/contact.d.ts.map +1 -1
  22. package/dist/device/contact.js +268 -576
  23. package/dist/device/contact.js.map +1 -1
  24. package/dist/device/curtain.d.ts +18 -89
  25. package/dist/device/curtain.d.ts.map +1 -1
  26. package/dist/device/curtain.js +431 -851
  27. package/dist/device/curtain.js.map +1 -1
  28. package/dist/device/device.d.ts +60 -0
  29. package/dist/device/device.d.ts.map +1 -0
  30. package/dist/device/device.js +739 -0
  31. package/dist/device/device.js.map +1 -0
  32. package/dist/device/fan.d.ts +63 -0
  33. package/dist/device/fan.d.ts.map +1 -0
  34. package/dist/device/fan.js +698 -0
  35. package/dist/device/fan.js.map +1 -0
  36. package/dist/device/hub.d.ts +15 -60
  37. package/dist/device/hub.d.ts.map +1 -1
  38. package/dist/device/hub.js +257 -631
  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 +266 -629
  43. package/dist/device/humidifier.js.map +1 -1
  44. package/dist/device/iosensor.d.ts +12 -64
  45. package/dist/device/iosensor.d.ts.map +1 -1
  46. package/dist/device/iosensor.js +215 -615
  47. package/dist/device/iosensor.js.map +1 -1
  48. package/dist/device/lightstrip.d.ts +12 -70
  49. package/dist/device/lightstrip.d.ts.map +1 -1
  50. package/dist/device/lightstrip.js +336 -645
  51. package/dist/device/lightstrip.js.map +1 -1
  52. package/dist/device/lock.d.ts +17 -63
  53. package/dist/device/lock.d.ts.map +1 -1
  54. package/dist/device/lock.js +290 -595
  55. package/dist/device/lock.js.map +1 -1
  56. package/dist/device/meter.d.ts +15 -64
  57. package/dist/device/meter.d.ts.map +1 -1
  58. package/dist/device/meter.js +211 -608
  59. package/dist/device/meter.js.map +1 -1
  60. package/dist/device/meterplus.d.ts +15 -65
  61. package/dist/device/meterplus.d.ts.map +1 -1
  62. package/dist/device/meterplus.js +205 -615
  63. package/dist/device/meterplus.js.map +1 -1
  64. package/dist/device/motion.d.ts +12 -69
  65. package/dist/device/motion.d.ts.map +1 -1
  66. package/dist/device/motion.js +202 -563
  67. package/dist/device/motion.js.map +1 -1
  68. package/dist/device/plug.d.ts +10 -57
  69. package/dist/device/plug.d.ts.map +1 -1
  70. package/dist/device/plug.js +125 -484
  71. package/dist/device/plug.js.map +1 -1
  72. package/dist/device/robotvacuumcleaner.d.ts +13 -63
  73. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  74. package/dist/device/robotvacuumcleaner.js +233 -549
  75. package/dist/device/robotvacuumcleaner.js.map +1 -1
  76. package/dist/device/waterdetector.d.ts +11 -63
  77. package/dist/device/waterdetector.d.ts.map +1 -1
  78. package/dist/device/waterdetector.js +170 -493
  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 +340 -468
  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 +105 -319
  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 +44 -285
  98. package/dist/irdevice/camera.js.map +1 -1
  99. package/dist/irdevice/fan.d.ts +7 -43
  100. package/dist/irdevice/fan.d.ts.map +1 -1
  101. package/dist/irdevice/fan.js +92 -350
  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 +369 -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 +91 -339
  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 +22 -8
  128. package/dist/platform.d.ts.map +1 -1
  129. package/dist/platform.js +342 -191
  130. package/dist/platform.js.map +1 -1
  131. package/dist/settings.d.ts +64 -17
  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 +20 -16
  141. package/src/custom.d.ts +2 -1
  142. package/src/device/blindtilt.ts +472 -888
  143. package/src/device/bot.ts +893 -968
  144. package/src/device/ceilinglight.ts +304 -709
  145. package/src/device/colorbulb.ts +370 -803
  146. package/src/device/contact.ts +301 -611
  147. package/src/device/curtain.ts +460 -908
  148. package/src/device/device.ts +755 -0
  149. package/src/device/fan.ts +749 -0
  150. package/src/device/hub.ts +294 -664
  151. package/src/device/humidifier.ts +299 -696
  152. package/src/device/iosensor.ts +251 -644
  153. package/src/device/lightstrip.ts +362 -712
  154. package/src/device/lock.ts +328 -653
  155. package/src/device/meter.ts +247 -637
  156. package/src/device/meterplus.ts +240 -644
  157. package/src/device/motion.ts +230 -598
  158. package/src/device/plug.ts +139 -525
  159. package/src/device/robotvacuumcleaner.ts +258 -593
  160. package/src/device/waterdetector.ts +191 -522
  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 +370 -527
  165. package/src/irdevice/airpurifier.ts +132 -356
  166. package/src/irdevice/camera.ts +58 -311
  167. package/src/irdevice/fan.ts +109 -379
  168. package/src/irdevice/irdevice.ts +382 -0
  169. package/src/irdevice/light.ts +157 -412
  170. package/src/irdevice/other.ts +507 -648
  171. package/src/irdevice/tv.ts +121 -375
  172. package/src/irdevice/vacuumcleaner.ts +59 -311
  173. package/src/irdevice/waterheater.ts +61 -320
  174. package/src/platform.ts +395 -259
  175. package/src/settings.ts +118 -609
  176. package/src/utils.ts +642 -1
  177. package/.github/npm-version-script.cjs +0 -81
  178. package/src/device/waterdetector.json +0 -11
package/dist/platform.js CHANGED
@@ -1,22 +1,26 @@
1
- import { PLATFORM_NAME, PLUGIN_NAME, Devices } from './settings.js';
1
+ /* Copyright(C) 2017-2024, donavanbecker (https://github.com/donavanbecker). All rights reserved.
2
+ *
3
+ * platform.ts: @switchbot/homebridge-switchbot platform class.
4
+ */
5
+ import { Hub } from './device/hub.js';
2
6
  import { Bot } from './device/bot.js';
3
7
  import { Plug } from './device/plug.js';
4
8
  import { Lock } from './device/lock.js';
5
9
  import { Meter } from './device/meter.js';
6
10
  import { Motion } from './device/motion.js';
7
- import { Hub } from './device/hub.js';
8
11
  import { Contact } from './device/contact.js';
9
12
  import { Curtain } from './device/curtain.js';
10
13
  import { IOSensor } from './device/iosensor.js';
11
- import { WaterDetector } from './device/waterdetector.js';
12
14
  import { MeterPlus } from './device/meterplus.js';
13
15
  import { ColorBulb } from './device/colorbulb.js';
14
- import { CeilingLight } from './device/ceilinglight.js';
15
16
  import { StripLight } from './device/lightstrip.js';
16
17
  import { Humidifier } from './device/humidifier.js';
18
+ import { CeilingLight } from './device/ceilinglight.js';
19
+ import { WaterDetector } from './device/waterdetector.js';
17
20
  import { RobotVacuumCleaner } from './device/robotvacuumcleaner.js';
21
+ import { Fan } from './device/fan.js';
18
22
  import { TV } from './irdevice/tv.js';
19
- import { Fan } from './irdevice/fan.js';
23
+ import { IRFan } from './irdevice/fan.js';
20
24
  import { Light } from './irdevice/light.js';
21
25
  import { Others } from './irdevice/other.js';
22
26
  import { Camera } from './irdevice/camera.js';
@@ -25,15 +29,17 @@ import { AirPurifier } from './irdevice/airpurifier.js';
25
29
  import { WaterHeater } from './irdevice/waterheater.js';
26
30
  import { VacuumCleaner } from './irdevice/vacuumcleaner.js';
27
31
  import { AirConditioner } from './irdevice/airconditioner.js';
28
- import * as http from 'http';
29
32
  import { Buffer } from 'buffer';
30
33
  import { request } from 'undici';
34
+ import asyncmqtt from 'async-mqtt';
35
+ import { sleep } from './utils.js';
36
+ import { createServer } from 'http';
31
37
  import { queueScheduler } from 'rxjs';
32
38
  import fakegato from 'fakegato-history';
33
- import asyncmqtt from 'async-mqtt';
34
39
  import crypto, { randomUUID } from 'crypto';
35
40
  import { readFileSync, writeFileSync } from 'fs';
36
- import hbLib from 'homebridge-lib';
41
+ import { EveHomeKitTypes } from 'homebridge-lib/EveHomeKitTypes';
42
+ import { PLATFORM_NAME, PLUGIN_NAME, Devices, setupWebhook, updateWebhook, deleteWebhook, queryWebhook } from './settings.js';
37
43
  /**
38
44
  * HomebridgePlatform
39
45
  * This class is the main constructor for your plugin, this is where you should
@@ -46,6 +52,8 @@ export class SwitchBotPlatform {
46
52
  version;
47
53
  Logging;
48
54
  debugMode;
55
+ maxRetries;
56
+ delayBetweenRetries;
49
57
  platformConfig;
50
58
  platformLogging;
51
59
  config;
@@ -55,6 +63,7 @@ export class SwitchBotPlatform {
55
63
  eve;
56
64
  webhookEventHandler = {};
57
65
  constructor(log, config, api) {
66
+ // initialize
58
67
  this.accessories = [];
59
68
  this.api = api;
60
69
  this.log = log;
@@ -69,10 +78,11 @@ export class SwitchBotPlatform {
69
78
  credentials: config.credentials,
70
79
  options: config.options,
71
80
  };
72
- this.platformLogging = this.config.options?.logging ?? 'standard';
73
- this.platformConfigOptions();
74
- this.platformLogs();
81
+ // Plugin Configuration
82
+ this.getPlatformConfigSettings();
83
+ this.getPlatformLogSettings();
75
84
  this.getVersion();
85
+ // Finish initializing the platform
76
86
  this.debugLog(`Finished initializing platform: ${config.name}`);
77
87
  // verify the config
78
88
  try {
@@ -85,7 +95,6 @@ export class SwitchBotPlatform {
85
95
  return;
86
96
  }
87
97
  // import fakegato-history module and EVE characteristics
88
- const { EveHomeKitTypes } = hbLib;
89
98
  this.fakegatoAPI = fakegato(api);
90
99
  this.eve = new EveHomeKitTypes(api);
91
100
  // When this event is fired it means Homebridge has restored all cached accessories from disk.
@@ -100,7 +109,6 @@ export class SwitchBotPlatform {
100
109
  await this.updateToken();
101
110
  }
102
111
  else if (this.config.credentials?.token && !this.config.credentials?.secret) {
103
- // eslint-disable-next-line no-useless-escape
104
112
  this.errorLog('"secret" config is not populated, you must populate then please restart Homebridge.');
105
113
  }
106
114
  else {
@@ -154,7 +162,7 @@ export class SwitchBotPlatform {
154
162
  const xurl = new URL(url);
155
163
  const port = Number(xurl.port);
156
164
  const path = xurl.pathname;
157
- this.webhookEventListener = http.createServer((request, response) => {
165
+ this.webhookEventListener = createServer((request, response) => {
158
166
  try {
159
167
  if (request.url === path && request.method === 'POST') {
160
168
  request.on('data', async (data) => {
@@ -193,7 +201,7 @@ export class SwitchBotPlatform {
193
201
  return;
194
202
  }
195
203
  try {
196
- const { body, statusCode } = await request('https://api.switch-bot.com/v1.1/webhook/setupWebhook', {
204
+ const { body, statusCode } = await request(setupWebhook, {
197
205
  method: 'POST',
198
206
  headers: this.generateHeaders(),
199
207
  body: JSON.stringify({
@@ -215,10 +223,8 @@ export class SwitchBotPlatform {
215
223
  this.errorLog(`Failed to configure webhook. Error: ${e.message}`);
216
224
  }
217
225
  try {
218
- const { body, statusCode } = await request('https://api.switch-bot.com/v1.1/webhook/updateWebhook', {
219
- method: 'POST',
220
- headers: this.generateHeaders(),
221
- body: JSON.stringify({
226
+ const { body, statusCode } = await request(updateWebhook, {
227
+ method: 'POST', headers: this.generateHeaders(), body: JSON.stringify({
222
228
  'action': 'updateWebhook',
223
229
  'config': {
224
230
  'url': url,
@@ -238,7 +244,7 @@ export class SwitchBotPlatform {
238
244
  this.errorLog(`Failed to update webhook. Error:${e.message}`);
239
245
  }
240
246
  try {
241
- const { body, statusCode } = await request('https://api.switch-bot.com/v1.1/webhook/queryWebhook', {
247
+ const { body, statusCode } = await request(queryWebhook, {
242
248
  method: 'POST',
243
249
  headers: this.generateHeaders(),
244
250
  body: JSON.stringify({
@@ -260,7 +266,7 @@ export class SwitchBotPlatform {
260
266
  }
261
267
  this.api.on('shutdown', async () => {
262
268
  try {
263
- const { body, statusCode } = await request('https://api.switch-bot.com/v1.1/webhook/deleteWebhook', {
269
+ const { body, statusCode } = await request(deleteWebhook, {
264
270
  method: 'POST',
265
271
  headers: this.generateHeaders(),
266
272
  body: JSON.stringify({
@@ -355,6 +361,21 @@ export class SwitchBotPlatform {
355
361
  this.config.options.pushRate = 0.1;
356
362
  this.debugWarnLog('Using Default Push Rate.');
357
363
  }
364
+ if (!this.config.options.maxRetries) {
365
+ this.config.options.maxRetries = 5;
366
+ this.debugWarnLog('Using Default Max Retries.');
367
+ }
368
+ else {
369
+ this.maxRetries = this.config.options.maxRetries;
370
+ }
371
+ if (!this.config.options.delayBetweenRetries) {
372
+ // default 3 seconds
373
+ this.config.options.delayBetweenRetries = 3000;
374
+ this.debugWarnLog('Using Default Delay Between Retries.');
375
+ }
376
+ else {
377
+ this.delayBetweenRetries = this.config.options.delayBetweenRetries * 1000;
378
+ }
358
379
  if (!this.config.credentials && !this.config.options) {
359
380
  this.debugWarnLog('Missing Credentials');
360
381
  }
@@ -399,13 +420,11 @@ export class SwitchBotPlatform {
399
420
  }
400
421
  // Move openToken to token
401
422
  if (!this.config.credentials.secret) {
402
- // eslint-disable-next-line no-useless-escape, max-len
403
- this.warnLog('This plugin has been updated to use OpenAPI v1.1, config is set with openToken, "openToken" cconfig has been moved to the "token" config');
404
- // eslint-disable-next-line no-useless-escape
423
+ this.warnLog('This plugin has been updated to use OpenAPI v1.1, config is set with openToken,'
424
+ + ' "openToken" cconfig has been moved to the "token" config');
405
425
  this.errorLog('"secret" config is not populated, you must populate then please restart Homebridge.');
406
426
  }
407
427
  else {
408
- // eslint-disable-next-line no-useless-escape, max-len
409
428
  this.warnLog('This plugin has been updated to use OpenAPI v1.1, config is set with openToken, '
410
429
  + '"openToken" config has been moved to the "token" config, please restart Homebridge.');
411
430
  }
@@ -451,114 +470,129 @@ export class SwitchBotPlatform {
451
470
  */
452
471
  async discoverDevices() {
453
472
  if (this.config.credentials?.token) {
454
- try {
455
- const { body, statusCode } = await request(Devices, {
456
- headers: this.generateHeaders(),
457
- });
458
- this.debugWarnLog(`statusCode: ${statusCode}`);
459
- const devicesAPI = await body.json();
460
- this.debugWarnLog(`devicesAPI: ${JSON.stringify(devicesAPI)}`);
461
- this.debugWarnLog(`devicesAPI Body: ${JSON.stringify(devicesAPI.body)}`);
462
- this.debugWarnLog(`devicesAPI StatusCode: ${devicesAPI.statusCode}`);
463
- if ((statusCode === 200 || statusCode === 100) && (devicesAPI.statusCode === 200 || devicesAPI.statusCode === 100)) {
464
- this.debugErrorLog(`statusCode: ${statusCode} & devicesAPI StatusCode: ${devicesAPI.statusCode}`);
465
- // SwitchBot Devices
466
- const deviceLists = devicesAPI.body.deviceList;
467
- this.debugWarnLog(`DeviceLists: ${JSON.stringify(deviceLists)}`);
468
- this.debugWarnLog(`DeviceLists Length: ${deviceLists.length}`);
469
- if (!this.config.options?.devices) {
470
- this.debugLog(`SwitchBot Device Config Not Set: ${JSON.stringify(this.config.options?.devices)}`);
471
- if (deviceLists.length === 0) {
472
- this.debugLog(`SwitchBot API Currently Doesn't Have Any Devices With Cloud Services Enabled: ${JSON.stringify(devicesAPI.body)}`);
473
+ let retryCount = 0;
474
+ const maxRetries = this.maxRetries; // Maximum number of retries
475
+ const delayBetweenRetries = this.delayBetweenRetries; // Delay between retries in milliseconds
476
+ this.debugWarnLog(`Retry Count: ${retryCount}`);
477
+ this.debugWarnLog(`Max Retries: ${maxRetries}`);
478
+ this.debugWarnLog(`Delay Between Retries: ${delayBetweenRetries}`);
479
+ while (retryCount < maxRetries) {
480
+ try {
481
+ const { body, statusCode } = await request(Devices, {
482
+ headers: this.generateHeaders(),
483
+ });
484
+ this.debugWarnLog(`statusCode: ${statusCode}`);
485
+ const devicesAPI = await body.json();
486
+ this.debugWarnLog(`devicesAPI: ${JSON.stringify(devicesAPI)}`);
487
+ this.debugWarnLog(`devicesAPI Body: ${JSON.stringify(devicesAPI.body)}`);
488
+ this.debugWarnLog(`devicesAPI StatusCode: ${devicesAPI.statusCode}`);
489
+ if ((statusCode === 200 || statusCode === 100) && (devicesAPI.statusCode === 200 || devicesAPI.statusCode === 100)) {
490
+ this.debugErrorLog(`statusCode: ${statusCode} & devicesAPI StatusCode: ${devicesAPI.statusCode}`);
491
+ // SwitchBot Devices
492
+ const deviceLists = devicesAPI.body.deviceList;
493
+ this.debugWarnLog(`DeviceLists: ${JSON.stringify(deviceLists)}`);
494
+ this.debugWarnLog(`DeviceLists Length: ${deviceLists.length}`);
495
+ if (!this.config.options?.devices) {
496
+ this.debugLog(`SwitchBot Device Config Not Set: ${JSON.stringify(this.config.options?.devices)}`);
497
+ if (deviceLists.length === 0) {
498
+ this.debugLog(`SwitchBot API Currently Doesn't Have Any Devices With Cloud Services Enabled: ${JSON.stringify(devicesAPI.body)}`);
499
+ }
500
+ else {
501
+ const devices = deviceLists.map((v) => v);
502
+ for (const device of devices) {
503
+ if (device.deviceType) {
504
+ if (device.configDeviceName) {
505
+ device.deviceName = device.configDeviceName;
506
+ }
507
+ this.createDevice(device);
508
+ }
509
+ }
510
+ }
473
511
  }
474
- else {
475
- const devices = deviceLists.map((v) => v);
476
- for (const device of devices) {
477
- if (device.deviceType) {
478
- if (device.configDeviceName) {
479
- device.deviceName = device.configDeviceName;
512
+ else if (this.config.credentials?.token && this.config.options.devices) {
513
+ this.debugLog(`SwitchBot Device Config Set: ${JSON.stringify(this.config.options?.devices)}`);
514
+ if (deviceLists.length === 0) {
515
+ this.debugLog(`SwitchBot API Currently Doesn't Have Any Devices With Cloud Services Enabled: ${JSON.stringify(devicesAPI.body)}`);
516
+ }
517
+ else {
518
+ const deviceConfigs = this.config.options?.devices;
519
+ const mergeBydeviceId = (a1, a2) => a1.map((itm) => ({
520
+ ...a2.find((item) => item.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') === itm.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') && item),
521
+ ...itm,
522
+ }));
523
+ const devices = mergeBydeviceId(deviceLists, deviceConfigs);
524
+ this.debugLog(`SwitchBot Devices: ${JSON.stringify(devices)}`);
525
+ for (const device of devices) {
526
+ if (!device.deviceType) {
527
+ device.deviceType = device.configDeviceType;
528
+ this.errorLog(`API has displaying no deviceType: ${device.deviceType}, So using configDeviceType: ${device.configDeviceType}`);
529
+ }
530
+ if (device.deviceType) {
531
+ if (device.configDeviceName) {
532
+ device.deviceName = device.configDeviceName;
533
+ }
534
+ this.createDevice(device);
480
535
  }
481
- this.createDevice(device);
482
536
  }
483
537
  }
484
538
  }
485
- }
486
- else if (this.config.credentials?.token && this.config.options.devices) {
487
- this.debugLog(`SwitchBot Device Config Set: ${JSON.stringify(this.config.options?.devices)}`);
488
- if (deviceLists.length === 0) {
489
- this.debugLog(`SwitchBot API Currently Doesn't Have Any Devices With Cloud Services Enabled: ${JSON.stringify(devicesAPI.body)}`);
539
+ else {
540
+ this.errorLog('SwitchBot Token Supplied, Issue with Auth.');
541
+ }
542
+ if (devicesAPI.body.deviceList.length !== 0) {
543
+ this.infoLog(`Total SwitchBot Devices Found: ${devicesAPI.body.deviceList.length}`);
490
544
  }
491
545
  else {
492
- const deviceConfigs = this.config.options?.devices;
493
- const mergeBydeviceId = (a1, a2) => a1.map((itm) => ({
494
- ...a2.find((item) => item.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') === itm.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') && item),
495
- ...itm,
496
- }));
497
- const devices = mergeBydeviceId(deviceLists, deviceConfigs);
498
- this.debugLog(`SwitchBot Devices: ${JSON.stringify(devices)}`);
546
+ this.debugLog(`Total SwitchBot Devices Found: ${devicesAPI.body.deviceList.length}`);
547
+ }
548
+ // IR Devices
549
+ const irDeviceLists = devicesAPI.body.infraredRemoteList;
550
+ if (!this.config.options?.irdevices) {
551
+ this.debugLog(`IR Device Config Not Set: ${JSON.stringify(this.config.options?.irdevices)}`);
552
+ const devices = irDeviceLists.map((v) => v);
499
553
  for (const device of devices) {
500
- if (!device.deviceType) {
501
- device.deviceType = device.configDeviceType;
502
- this.errorLog(`API has displaying no deviceType: ${device.deviceType}, So using configDeviceType: ${device.configDeviceType}`);
503
- }
504
- if (device.deviceType) {
505
- if (device.configDeviceName) {
506
- device.deviceName = device.configDeviceName;
507
- }
508
- this.createDevice(device);
554
+ if (device.remoteType) {
555
+ this.createIRDevice(device);
509
556
  }
510
557
  }
511
558
  }
512
- }
513
- else {
514
- this.errorLog('SwitchBot Token Supplied, Issue with Auth.');
515
- }
516
- if (devicesAPI.body.deviceList.length !== 0) {
517
- this.infoLog(`Total SwitchBot Devices Found: ${devicesAPI.body.deviceList.length}`);
518
- }
519
- else {
520
- this.debugLog(`Total SwitchBot Devices Found: ${devicesAPI.body.deviceList.length}`);
521
- }
522
- // IR Devices
523
- const irDeviceLists = devicesAPI.body.infraredRemoteList;
524
- if (!this.config.options?.irdevices) {
525
- this.debugLog(`IR Device Config Not Set: ${JSON.stringify(this.config.options?.irdevices)}`);
526
- const devices = irDeviceLists.map((v) => v);
527
- for (const device of devices) {
528
- if (device.remoteType) {
559
+ else {
560
+ this.debugLog(`IR Device Config Set: ${JSON.stringify(this.config.options?.irdevices)}`);
561
+ const irDeviceConfig = this.config.options?.irdevices;
562
+ const mergeIRBydeviceId = (a1, a2) => a1.map((itm) => ({
563
+ ...a2.find((item) => item.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') === itm.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') && item),
564
+ ...itm,
565
+ }));
566
+ const devices = mergeIRBydeviceId(irDeviceLists, irDeviceConfig);
567
+ this.debugLog(`IR Devices: ${JSON.stringify(devices)}`);
568
+ for (const device of devices) {
529
569
  this.createIRDevice(device);
530
570
  }
531
571
  }
532
- }
533
- else {
534
- this.debugLog(`IR Device Config Set: ${JSON.stringify(this.config.options?.irdevices)}`);
535
- const irDeviceConfig = this.config.options?.irdevices;
536
- const mergeIRBydeviceId = (a1, a2) => a1.map((itm) => ({
537
- ...a2.find((item) => item.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') === itm.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') && item),
538
- ...itm,
539
- }));
540
- const devices = mergeIRBydeviceId(irDeviceLists, irDeviceConfig);
541
- this.debugLog(`IR Devices: ${JSON.stringify(devices)}`);
542
- for (const device of devices) {
543
- this.createIRDevice(device);
572
+ if (devicesAPI.body.infraredRemoteList.length !== 0) {
573
+ this.infoLog(`Total IR Devices Found: ${devicesAPI.body.infraredRemoteList.length}`);
544
574
  }
545
- }
546
- if (devicesAPI.body.infraredRemoteList.length !== 0) {
547
- this.infoLog(`Total IR Devices Found: ${devicesAPI.body.infraredRemoteList.length}`);
575
+ else {
576
+ this.debugLog(`Total IR Devices Found: ${devicesAPI.body.infraredRemoteList.length}`);
577
+ }
578
+ break;
548
579
  }
549
580
  else {
550
- this.debugLog(`Total IR Devices Found: ${devicesAPI.body.infraredRemoteList.length}`);
581
+ this.statusCode(statusCode);
582
+ this.statusCode(devicesAPI.statusCode);
583
+ if (statusCode === 500) {
584
+ retryCount++;
585
+ this.infoLog(`statusCode: ${statusCode} Attempt ${retryCount} of ${maxRetries}`);
586
+ await sleep(delayBetweenRetries);
587
+ }
551
588
  }
552
589
  }
553
- else {
554
- this.statusCode(statusCode);
555
- this.statusCode(devicesAPI.statusCode);
590
+ catch (e) {
591
+ retryCount++;
592
+ this.debugErrorLog(`Failed to Discover Devices, Error Message: ${JSON.stringify(e.message)}, Submit Bugs Here: ` + 'https://tinyurl.com/SwitchBotBug');
593
+ this.debugErrorLog(`Failed to Discover Devices, Error: ${e}`);
556
594
  }
557
595
  }
558
- catch (e) {
559
- this.debugErrorLog(`Failed to Discover Devices, Error Message: ${JSON.stringify(e.message)}, Submit Bugs Here: ` + 'https://tinyurl.com/SwitchBotBug');
560
- this.debugErrorLog(`Failed to Discover Devices, Error: ${e}`);
561
- }
562
596
  }
563
597
  else if (!this.config.credentials?.token && this.config.options?.devices) {
564
598
  this.debugLog(`SwitchBot Device Manual Config Set: ${JSON.stringify(this.config.options?.devices)}`);
@@ -650,6 +684,7 @@ export class SwitchBotPlatform {
650
684
  case 'WoSweeperMini':
651
685
  case 'Robot Vacuum Cleaner S1':
652
686
  case 'Robot Vacuum Cleaner S1 Plus':
687
+ case 'Robot Vacuum Cleaner S10':
653
688
  this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
654
689
  this.createRobotVacuumCleaner(device);
655
690
  break;
@@ -662,17 +697,17 @@ export class SwitchBotPlatform {
662
697
  this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
663
698
  this.createStripLight(device);
664
699
  break;
665
- case 'Indoor Cam':
700
+ case 'Battery Circulator Fan':
666
701
  this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
667
- this.warnLog(`Device: ${device.deviceName} with Device Type: ${device.deviceType}, is currently not supported.`);
702
+ this.createFan(device);
668
703
  break;
669
704
  case 'Remote':
670
- this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId} is Not Supported.`);
705
+ case 'Indoor Cam':
706
+ case 'remote with screen+':
707
+ this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}, is currently not supported, device: ${JSON.stringify(device)}`);
671
708
  break;
672
709
  default:
673
- this.warnLog(`Device: ${device.deviceName} with Device Type: ${device.deviceType}, is currently not supported.`);
674
- // eslint-disable-next-line max-len
675
- this.warnLog('Submit Feature Requests Here: ' + 'https://tinyurl.com/SwitchBotFeatureRequest');
710
+ this.warnLog(`Device: ${device.deviceName} with Device Type: ${device.deviceType}, is currently not supported.`, +`Submit Feature Requests Here: https://tinyurl.com/SwitchBotFeatureRequest, device: ${JSON.stringify(device)}`);
676
711
  }
677
712
  }
678
713
  createIRDevice(device) {
@@ -704,7 +739,7 @@ export class SwitchBotPlatform {
704
739
  case 'Fan':
705
740
  case 'DIY Fan':
706
741
  this.debugLog(`Discovered ${device.remoteType}: ${device.deviceId}`);
707
- this.createFan(device);
742
+ this.createIRFan(device);
708
743
  break;
709
744
  case 'Air Conditioner':
710
745
  case 'DIY Air Conditioner':
@@ -759,7 +794,7 @@ export class SwitchBotPlatform {
759
794
  existingAccessory.context.deviceID = device.deviceId;
760
795
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
761
796
  if (device.firmware) {
762
- existingAccessory.context.FirmwareRevision = device.firmware;
797
+ existingAccessory.context.version = device.firmware;
763
798
  }
764
799
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
765
800
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -787,7 +822,7 @@ export class SwitchBotPlatform {
787
822
  accessory.context.model = device.deviceType;
788
823
  accessory.context.deviceID = device.deviceId;
789
824
  if (device.firmware) {
790
- accessory.context.FirmwareRevision = device.firmware;
825
+ accessory.context.version = device.firmware;
791
826
  }
792
827
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
793
828
  accessory.context.connectionType = await this.connectionType(device);
@@ -816,7 +851,7 @@ export class SwitchBotPlatform {
816
851
  existingAccessory.context.deviceID = device.deviceId;
817
852
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
818
853
  if (device.firmware) {
819
- existingAccessory.context.FirmwareRevision = device.firmware;
854
+ existingAccessory.context.version = device.firmware;
820
855
  }
821
856
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
822
857
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -844,11 +879,11 @@ export class SwitchBotPlatform {
844
879
  accessory.context.model = device.deviceType;
845
880
  accessory.context.deviceID = device.deviceId;
846
881
  if (device.firmware) {
847
- accessory.context.FirmwareRevision = device.firmware;
882
+ accessory.context.version = device.firmware;
848
883
  }
849
884
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
850
885
  accessory.context.connectionType = await this.connectionType(device);
851
- // accessory.context.FirmwareRevision = findaccessories.accessoryAttribute.softwareRevision;
886
+ // accessory.context.version = findaccessories.accessoryAttribute.softwareRevision;
852
887
  // create the accessory handler for the newly create accessory
853
888
  // this is imported from `platformAccessory.ts`
854
889
  new Bot(this, accessory, device);
@@ -874,7 +909,7 @@ export class SwitchBotPlatform {
874
909
  existingAccessory.context.deviceID = device.deviceId;
875
910
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
876
911
  if (device.firmware) {
877
- existingAccessory.context.FirmwareRevision = device.firmware;
912
+ existingAccessory.context.version = device.firmware;
878
913
  }
879
914
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
880
915
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -902,7 +937,7 @@ export class SwitchBotPlatform {
902
937
  accessory.context.model = device.deviceType;
903
938
  accessory.context.deviceID = device.deviceId;
904
939
  if (device.firmware) {
905
- accessory.context.FirmwareRevision = device.firmware;
940
+ accessory.context.version = device.firmware;
906
941
  }
907
942
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
908
943
  accessory.context.connectionType = await this.connectionType(device);
@@ -932,7 +967,7 @@ export class SwitchBotPlatform {
932
967
  existingAccessory.context.deviceID = device.deviceId;
933
968
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
934
969
  if (device.firmware) {
935
- existingAccessory.context.FirmwareRevision = device.firmware;
970
+ existingAccessory.context.version = device.firmware;
936
971
  }
937
972
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
938
973
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -960,7 +995,7 @@ export class SwitchBotPlatform {
960
995
  accessory.context.model = device.deviceType;
961
996
  accessory.context.deviceID = device.deviceId;
962
997
  if (device.firmware) {
963
- accessory.context.FirmwareRevision = device.firmware;
998
+ accessory.context.version = device.firmware;
964
999
  }
965
1000
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
966
1001
  accessory.context.connectionType = await this.connectionType(device);
@@ -990,7 +1025,7 @@ export class SwitchBotPlatform {
990
1025
  existingAccessory.context.deviceID = device.deviceId;
991
1026
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
992
1027
  if (device.firmware) {
993
- existingAccessory.context.FirmwareRevision = device.firmware;
1028
+ existingAccessory.context.version = device.firmware;
994
1029
  }
995
1030
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
996
1031
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1018,7 +1053,7 @@ export class SwitchBotPlatform {
1018
1053
  accessory.context.model = device.deviceType;
1019
1054
  accessory.context.deviceID = device.deviceId;
1020
1055
  if (device.firmware) {
1021
- accessory.context.FirmwareRevision = device.firmware;
1056
+ accessory.context.version = device.firmware;
1022
1057
  }
1023
1058
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1024
1059
  accessory.context.connectionType = await this.connectionType(device);
@@ -1047,7 +1082,7 @@ export class SwitchBotPlatform {
1047
1082
  existingAccessory.context.deviceID = device.deviceId;
1048
1083
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1049
1084
  if (device.firmware) {
1050
- existingAccessory.context.FirmwareRevision = device.firmware;
1085
+ existingAccessory.context.version = device.firmware;
1051
1086
  }
1052
1087
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1053
1088
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1075,7 +1110,7 @@ export class SwitchBotPlatform {
1075
1110
  accessory.context.model = device.deviceType;
1076
1111
  accessory.context.deviceID = device.deviceId;
1077
1112
  if (device.firmware) {
1078
- accessory.context.FirmwareRevision = device.firmware;
1113
+ accessory.context.version = device.firmware;
1079
1114
  }
1080
1115
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1081
1116
  accessory.context.connectionType = await this.connectionType(device);
@@ -1104,7 +1139,7 @@ export class SwitchBotPlatform {
1104
1139
  existingAccessory.context.deviceID = device.deviceId;
1105
1140
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1106
1141
  if (device.firmware) {
1107
- existingAccessory.context.FirmwareRevision = device.firmware;
1142
+ existingAccessory.context.version = device.firmware;
1108
1143
  }
1109
1144
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1110
1145
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1132,7 +1167,7 @@ export class SwitchBotPlatform {
1132
1167
  accessory.context.model = device.deviceType;
1133
1168
  accessory.context.deviceID = device.deviceId;
1134
1169
  if (device.firmware) {
1135
- accessory.context.FirmwareRevision = device.firmware;
1170
+ accessory.context.version = device.firmware;
1136
1171
  }
1137
1172
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1138
1173
  accessory.context.connectionType = await this.connectionType(device);
@@ -1161,7 +1196,7 @@ export class SwitchBotPlatform {
1161
1196
  existingAccessory.context.deviceID = device.deviceId;
1162
1197
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1163
1198
  if (device.firmware) {
1164
- existingAccessory.context.FirmwareRevision = device.firmware;
1199
+ existingAccessory.context.version = device.firmware;
1165
1200
  }
1166
1201
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1167
1202
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1189,7 +1224,7 @@ export class SwitchBotPlatform {
1189
1224
  accessory.context.model = device.deviceType;
1190
1225
  accessory.context.deviceID = device.deviceId;
1191
1226
  if (device.firmware) {
1192
- accessory.context.FirmwareRevision = device.firmware;
1227
+ accessory.context.version = device.firmware;
1193
1228
  }
1194
1229
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1195
1230
  accessory.context.connectionType = await this.connectionType(device);
@@ -1218,7 +1253,7 @@ export class SwitchBotPlatform {
1218
1253
  existingAccessory.context.deviceID = device.deviceId;
1219
1254
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1220
1255
  if (device.firmware) {
1221
- existingAccessory.context.FirmwareRevision = device.firmware;
1256
+ existingAccessory.context.version = device.firmware;
1222
1257
  }
1223
1258
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1224
1259
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1246,7 +1281,7 @@ export class SwitchBotPlatform {
1246
1281
  accessory.context.model = device.deviceType;
1247
1282
  accessory.context.deviceID = device.deviceId;
1248
1283
  if (device.firmware) {
1249
- accessory.context.FirmwareRevision = device.firmware;
1284
+ accessory.context.version = device.firmware;
1250
1285
  }
1251
1286
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1252
1287
  accessory.context.connectionType = await this.connectionType(device);
@@ -1275,7 +1310,7 @@ export class SwitchBotPlatform {
1275
1310
  existingAccessory.context.deviceID = device.deviceId;
1276
1311
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1277
1312
  if (device.firmware) {
1278
- existingAccessory.context.FirmwareRevision = device.firmware;
1313
+ existingAccessory.context.version = device.firmware;
1279
1314
  }
1280
1315
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1281
1316
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1315,7 +1350,7 @@ export class SwitchBotPlatform {
1315
1350
  accessory.context.model = device.deviceType;
1316
1351
  accessory.context.deviceID = device.deviceId;
1317
1352
  if (device.firmware) {
1318
- accessory.context.FirmwareRevision = device.firmware;
1353
+ accessory.context.version = device.firmware;
1319
1354
  }
1320
1355
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1321
1356
  accessory.context.connectionType = await this.connectionType(device);
@@ -1344,7 +1379,7 @@ export class SwitchBotPlatform {
1344
1379
  existingAccessory.context.deviceID = device.deviceId;
1345
1380
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1346
1381
  if (device.firmware) {
1347
- existingAccessory.context.FirmwareRevision = device.firmware;
1382
+ existingAccessory.context.version = device.firmware;
1348
1383
  }
1349
1384
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1350
1385
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1384,7 +1419,7 @@ export class SwitchBotPlatform {
1384
1419
  accessory.context.model = device.deviceType;
1385
1420
  accessory.context.deviceID = device.deviceId;
1386
1421
  if (device.firmware) {
1387
- accessory.context.FirmwareRevision = device.firmware;
1422
+ accessory.context.version = device.firmware;
1388
1423
  }
1389
1424
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1390
1425
  accessory.context.connectionType = await this.connectionType(device);
@@ -1413,7 +1448,7 @@ export class SwitchBotPlatform {
1413
1448
  existingAccessory.context.deviceID = device.deviceId;
1414
1449
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1415
1450
  if (device.firmware) {
1416
- existingAccessory.context.FirmwareRevision = device.firmware;
1451
+ existingAccessory.context.version = device.firmware;
1417
1452
  }
1418
1453
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1419
1454
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1441,7 +1476,7 @@ export class SwitchBotPlatform {
1441
1476
  accessory.context.model = device.deviceType;
1442
1477
  accessory.context.deviceID = device.deviceId;
1443
1478
  if (device.firmware) {
1444
- accessory.context.FirmwareRevision = device.firmware;
1479
+ accessory.context.version = device.firmware;
1445
1480
  }
1446
1481
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1447
1482
  accessory.context.connectionType = await this.connectionType(device);
@@ -1470,7 +1505,7 @@ export class SwitchBotPlatform {
1470
1505
  existingAccessory.context.deviceID = device.deviceId;
1471
1506
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1472
1507
  if (device.firmware) {
1473
- existingAccessory.context.FirmwareRevision = device.firmware;
1508
+ existingAccessory.context.version = device.firmware;
1474
1509
  }
1475
1510
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1476
1511
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1498,7 +1533,7 @@ export class SwitchBotPlatform {
1498
1533
  accessory.context.model = device.deviceType;
1499
1534
  accessory.context.deviceID = device.deviceId;
1500
1535
  if (device.firmware) {
1501
- accessory.context.FirmwareRevision = device.firmware;
1536
+ accessory.context.version = device.firmware;
1502
1537
  }
1503
1538
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1504
1539
  accessory.context.connectionType = await this.connectionType(device);
@@ -1527,7 +1562,7 @@ export class SwitchBotPlatform {
1527
1562
  existingAccessory.context.deviceID = device.deviceId;
1528
1563
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1529
1564
  if (device.firmware) {
1530
- existingAccessory.context.FirmwareRevision = device.firmware;
1565
+ existingAccessory.context.version = device.firmware;
1531
1566
  }
1532
1567
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1533
1568
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1555,7 +1590,7 @@ export class SwitchBotPlatform {
1555
1590
  accessory.context.model = device.deviceType;
1556
1591
  accessory.context.deviceID = device.deviceId;
1557
1592
  if (device.firmware) {
1558
- accessory.context.FirmwareRevision = device.firmware;
1593
+ accessory.context.version = device.firmware;
1559
1594
  }
1560
1595
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1561
1596
  accessory.context.connectionType = await this.connectionType(device);
@@ -1584,7 +1619,7 @@ export class SwitchBotPlatform {
1584
1619
  existingAccessory.context.deviceID = device.deviceId;
1585
1620
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1586
1621
  if (device.firmware) {
1587
- existingAccessory.context.FirmwareRevision = device.firmware;
1622
+ existingAccessory.context.version = device.firmware;
1588
1623
  }
1589
1624
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1590
1625
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1612,7 +1647,7 @@ export class SwitchBotPlatform {
1612
1647
  accessory.context.model = device.deviceType;
1613
1648
  accessory.context.deviceID = device.deviceId;
1614
1649
  if (device.firmware) {
1615
- accessory.context.FirmwareRevision = device.firmware;
1650
+ accessory.context.version = device.firmware;
1616
1651
  }
1617
1652
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1618
1653
  accessory.context.connectionType = await this.connectionType(device);
@@ -1641,7 +1676,7 @@ export class SwitchBotPlatform {
1641
1676
  existingAccessory.context.deviceID = device.deviceId;
1642
1677
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1643
1678
  if (device.firmware) {
1644
- existingAccessory.context.FirmwareRevision = device.firmware;
1679
+ existingAccessory.context.version = device.firmware;
1645
1680
  }
1646
1681
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1647
1682
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1669,7 +1704,7 @@ export class SwitchBotPlatform {
1669
1704
  accessory.context.model = device.deviceType;
1670
1705
  accessory.context.deviceID = device.deviceId;
1671
1706
  if (device.firmware) {
1672
- accessory.context.FirmwareRevision = device.firmware;
1707
+ accessory.context.version = device.firmware;
1673
1708
  }
1674
1709
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1675
1710
  accessory.context.connectionType = await this.connectionType(device);
@@ -1685,6 +1720,63 @@ export class SwitchBotPlatform {
1685
1720
  this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
1686
1721
  }
1687
1722
  }
1723
+ async createFan(device) {
1724
+ const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
1725
+ // see if an accessory with the same uuid has already been registered and restored from
1726
+ // the cached devices we stored in the `configureAccessory` method above
1727
+ const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
1728
+ if (existingAccessory) {
1729
+ // the accessory already exists
1730
+ if (await this.registerDevice(device)) {
1731
+ // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1732
+ existingAccessory.context.model = device.deviceType;
1733
+ existingAccessory.context.deviceID = device.deviceId;
1734
+ existingAccessory.displayName = device.configDeviceName || device.deviceName;
1735
+ if (device.firmware) {
1736
+ existingAccessory.context.version = device.firmware;
1737
+ }
1738
+ existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1739
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1740
+ existingAccessory.context.connectionType = await this.connectionType(device);
1741
+ this.api.updatePlatformAccessories([existingAccessory]);
1742
+ // create the accessory handler for the restored accessory
1743
+ // this is imported from `platformAccessory.ts`
1744
+ new Fan(this, existingAccessory, device);
1745
+ this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${existingAccessory.UUID})`);
1746
+ }
1747
+ else {
1748
+ this.unregisterPlatformAccessories(existingAccessory);
1749
+ }
1750
+ }
1751
+ else if (await this.registerDevice(device)) {
1752
+ // the accessory does not yet exist, so we need to create it
1753
+ if (!device.external) {
1754
+ this.infoLog(`Adding new accessory: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
1755
+ }
1756
+ // create a new accessory
1757
+ const accessory = new this.api.platformAccessory(device.deviceName, uuid);
1758
+ // store a copy of the device object in the `accessory.context`
1759
+ // the `context` property can be used to store any data about the accessory you may need
1760
+ accessory.context.device = device;
1761
+ accessory.context.model = device.deviceType;
1762
+ accessory.context.deviceID = device.deviceId;
1763
+ if (device.firmware) {
1764
+ accessory.context.version = device.firmware;
1765
+ }
1766
+ accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1767
+ accessory.context.connectionType = await this.connectionType(device);
1768
+ // create the accessory handler for the newly create accessory
1769
+ // this is imported from `platformAccessory.ts`
1770
+ new Fan(this, accessory, device);
1771
+ this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`);
1772
+ // publish device externally or link the accessory to your platform
1773
+ this.externalOrPlatform(device, accessory);
1774
+ this.accessories.push(accessory);
1775
+ }
1776
+ else {
1777
+ this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
1778
+ }
1779
+ }
1688
1780
  async createRobotVacuumCleaner(device) {
1689
1781
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
1690
1782
  // see if an accessory with the same uuid has already been registered and restored from
@@ -1698,7 +1790,7 @@ export class SwitchBotPlatform {
1698
1790
  existingAccessory.context.deviceID = device.deviceId;
1699
1791
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1700
1792
  if (device.firmware) {
1701
- existingAccessory.context.FirmwareRevision = device.firmware;
1793
+ existingAccessory.context.version = device.firmware;
1702
1794
  }
1703
1795
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1704
1796
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1726,7 +1818,7 @@ export class SwitchBotPlatform {
1726
1818
  accessory.context.model = device.deviceType;
1727
1819
  accessory.context.deviceID = device.deviceId;
1728
1820
  if (device.firmware) {
1729
- accessory.context.FirmwareRevision = device.firmware;
1821
+ accessory.context.version = device.firmware;
1730
1822
  }
1731
1823
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1732
1824
  accessory.context.connectionType = await this.connectionType(device);
@@ -1752,7 +1844,9 @@ export class SwitchBotPlatform {
1752
1844
  existingAccessory.context.model = device.remoteType;
1753
1845
  existingAccessory.context.deviceID = device.deviceId;
1754
1846
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1755
- existingAccessory.context.FirmwareRevision = device.firmware;
1847
+ if (device.version && !device.firmware) {
1848
+ existingAccessory.context.version = device.version;
1849
+ }
1756
1850
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1757
1851
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1758
1852
  existingAccessory.context.connectionType = device.connectionType;
@@ -1775,7 +1869,7 @@ export class SwitchBotPlatform {
1775
1869
  accessory.context.model = device.remoteType;
1776
1870
  accessory.context.deviceID = device.deviceId;
1777
1871
  if (device.firmware) {
1778
- accessory.context.FirmwareRevision = device.firmware;
1872
+ accessory.context.version = device.firmware;
1779
1873
  }
1780
1874
  accessory.context.deviceType = `IR: ${device.remoteType}`;
1781
1875
  accessory.context.connectionType = device.connectionType;
@@ -1790,7 +1884,7 @@ export class SwitchBotPlatform {
1790
1884
  this.debugLog(`Device not registered: ${device.deviceName} ${device.remoteType} DeviceID: ${device.deviceId}`);
1791
1885
  }
1792
1886
  }
1793
- async createFan(device) {
1887
+ async createIRFan(device) {
1794
1888
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.remoteType}`);
1795
1889
  // see if an accessory with the same uuid has already been registered and restored from
1796
1890
  // the cached devices we stored in the `configureAccessory` method above
@@ -1803,7 +1897,7 @@ export class SwitchBotPlatform {
1803
1897
  existingAccessory.context.deviceID = device.deviceId;
1804
1898
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1805
1899
  if (device.firmware) {
1806
- existingAccessory.context.FirmwareRevision = device.firmware;
1900
+ existingAccessory.context.version = device.firmware;
1807
1901
  }
1808
1902
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1809
1903
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1811,7 +1905,7 @@ export class SwitchBotPlatform {
1811
1905
  this.api.updatePlatformAccessories([existingAccessory]);
1812
1906
  // create the accessory handler for the restored accessory
1813
1907
  // this is imported from `platformAccessory.ts`
1814
- new Fan(this, existingAccessory, device);
1908
+ new IRFan(this, existingAccessory, device);
1815
1909
  this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${existingAccessory.UUID})`);
1816
1910
  }
1817
1911
  else {
@@ -1831,13 +1925,13 @@ export class SwitchBotPlatform {
1831
1925
  accessory.context.model = device.remoteType;
1832
1926
  accessory.context.deviceID = device.deviceId;
1833
1927
  if (device.firmware) {
1834
- accessory.context.FirmwareRevision = device.firmware;
1928
+ accessory.context.version = device.firmware;
1835
1929
  }
1836
1930
  accessory.context.deviceType = `IR: ${device.remoteType}`;
1837
1931
  accessory.context.connectionType = device.connectionType;
1838
1932
  // create the accessory handler for the newly create accessory
1839
1933
  // this is imported from `platformAccessory.ts`
1840
- new Fan(this, accessory, device);
1934
+ new IRFan(this, accessory, device);
1841
1935
  this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`);
1842
1936
  // publish device externally or link the accessory to your platform
1843
1937
  this.externalOrPlatformIR(device, accessory);
@@ -1860,7 +1954,7 @@ export class SwitchBotPlatform {
1860
1954
  existingAccessory.context.deviceID = device.deviceId;
1861
1955
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1862
1956
  if (device.firmware) {
1863
- existingAccessory.context.FirmwareRevision = device.firmware;
1957
+ existingAccessory.context.version = device.firmware;
1864
1958
  }
1865
1959
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1866
1960
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1888,7 +1982,7 @@ export class SwitchBotPlatform {
1888
1982
  accessory.context.model = device.remoteType;
1889
1983
  accessory.context.deviceID = device.deviceId;
1890
1984
  if (device.firmware) {
1891
- accessory.context.FirmwareRevision = device.firmware;
1985
+ accessory.context.version = device.firmware;
1892
1986
  }
1893
1987
  accessory.context.deviceType = `IR: ${device.remoteType}`;
1894
1988
  accessory.context.connectionType = device.connectionType;
@@ -1917,7 +2011,7 @@ export class SwitchBotPlatform {
1917
2011
  existingAccessory.context.deviceID = device.deviceId;
1918
2012
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1919
2013
  if (device.firmware) {
1920
- existingAccessory.context.FirmwareRevision = device.firmware;
2014
+ existingAccessory.context.version = device.firmware;
1921
2015
  }
1922
2016
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1923
2017
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -1945,7 +2039,7 @@ export class SwitchBotPlatform {
1945
2039
  accessory.context.model = device.remoteType;
1946
2040
  accessory.context.deviceID = device.deviceId;
1947
2041
  if (device.firmware) {
1948
- accessory.context.FirmwareRevision = device.firmware;
2042
+ accessory.context.version = device.firmware;
1949
2043
  }
1950
2044
  accessory.context.deviceType = `IR: ${device.remoteType}`;
1951
2045
  accessory.context.connectionType = device.connectionType;
@@ -1974,7 +2068,7 @@ export class SwitchBotPlatform {
1974
2068
  existingAccessory.context.deviceID = device.deviceId;
1975
2069
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
1976
2070
  if (device.firmware) {
1977
- existingAccessory.context.FirmwareRevision = device.firmware;
2071
+ existingAccessory.context.version = device.firmware;
1978
2072
  }
1979
2073
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1980
2074
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -2002,7 +2096,7 @@ export class SwitchBotPlatform {
2002
2096
  accessory.context.model = device.remoteType;
2003
2097
  accessory.context.deviceID = device.deviceId;
2004
2098
  if (device.firmware) {
2005
- accessory.context.FirmwareRevision = device.firmware;
2099
+ accessory.context.version = device.firmware;
2006
2100
  }
2007
2101
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2008
2102
  accessory.context.connectionType = device.connectionType;
@@ -2031,7 +2125,7 @@ export class SwitchBotPlatform {
2031
2125
  existingAccessory.context.deviceID = device.deviceId;
2032
2126
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
2033
2127
  if (device.firmware) {
2034
- existingAccessory.context.FirmwareRevision = device.firmware;
2128
+ existingAccessory.context.version = device.firmware;
2035
2129
  }
2036
2130
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2037
2131
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -2059,7 +2153,7 @@ export class SwitchBotPlatform {
2059
2153
  accessory.context.model = device.remoteType;
2060
2154
  accessory.context.deviceID = device.deviceId;
2061
2155
  if (device.firmware) {
2062
- accessory.context.FirmwareRevision = device.firmware;
2156
+ accessory.context.version = device.firmware;
2063
2157
  }
2064
2158
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2065
2159
  accessory.context.connectionType = device.connectionType;
@@ -2088,7 +2182,7 @@ export class SwitchBotPlatform {
2088
2182
  existingAccessory.context.deviceID = device.deviceId;
2089
2183
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
2090
2184
  if (device.firmware) {
2091
- existingAccessory.context.FirmwareRevision = device.firmware;
2185
+ existingAccessory.context.version = device.firmware;
2092
2186
  }
2093
2187
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2094
2188
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -2116,7 +2210,7 @@ export class SwitchBotPlatform {
2116
2210
  accessory.context.model = device.remoteType;
2117
2211
  accessory.context.deviceID = device.deviceId;
2118
2212
  if (device.firmware) {
2119
- accessory.context.FirmwareRevision = device.firmware;
2213
+ accessory.context.version = device.firmware;
2120
2214
  }
2121
2215
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2122
2216
  accessory.context.connectionType = device.connectionType;
@@ -2145,7 +2239,7 @@ export class SwitchBotPlatform {
2145
2239
  existingAccessory.context.deviceID = device.deviceId;
2146
2240
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
2147
2241
  if (device.firmware) {
2148
- existingAccessory.context.FirmwareRevision = device.firmware;
2242
+ existingAccessory.context.version = device.firmware;
2149
2243
  }
2150
2244
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2151
2245
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -2173,7 +2267,7 @@ export class SwitchBotPlatform {
2173
2267
  accessory.context.model = device.remoteType;
2174
2268
  accessory.context.deviceID = device.deviceId;
2175
2269
  if (device.firmware) {
2176
- accessory.context.FirmwareRevision = device.firmware;
2270
+ accessory.context.version = device.firmware;
2177
2271
  }
2178
2272
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2179
2273
  accessory.context.connectionType = device.connectionType;
@@ -2202,7 +2296,7 @@ export class SwitchBotPlatform {
2202
2296
  existingAccessory.context.deviceID = device.deviceId;
2203
2297
  existingAccessory.displayName = device.configDeviceName || device.deviceName;
2204
2298
  if (device.firmware) {
2205
- existingAccessory.context.FirmwareRevision = device.firmware;
2299
+ existingAccessory.context.version = device.firmware;
2206
2300
  }
2207
2301
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
2208
2302
  this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
@@ -2230,7 +2324,7 @@ export class SwitchBotPlatform {
2230
2324
  accessory.context.model = device.remoteType;
2231
2325
  accessory.context.deviceID = device.deviceId;
2232
2326
  if (device.firmware) {
2233
- accessory.context.FirmwareRevision = device.firmware;
2327
+ accessory.context.version = device.firmware;
2234
2328
  }
2235
2329
  accessory.context.deviceType = `IR: ${device.remoteType}`;
2236
2330
  accessory.context.connectionType = device.connectionType;
@@ -2250,8 +2344,8 @@ export class SwitchBotPlatform {
2250
2344
  switch (device.deviceType) {
2251
2345
  case 'Curtain':
2252
2346
  case 'Curtain3':
2253
- this.debugWarnLog(`deviceName: ${device.deviceName} deviceId: ${device.deviceId}, curtainDevicesIds: ${device.curtainDevicesIds}, master: ` +
2254
- `${device.master}, group: ${device.group}, disable_group: ${device.curtain?.disable_group}, connectionType: ${device.connectionType}`);
2347
+ this.debugWarnLog(`deviceName: ${device.deviceName} deviceId: ${device.deviceId}, curtainDevicesIds: ${device.curtainDevicesIds}, master: `
2348
+ + `${device.master}, group: ${device.group}, disable_group: ${device.curtain?.disable_group}, connectionType: ${device.connectionType}`);
2255
2349
  break;
2256
2350
  default:
2257
2351
  this.debugWarnLog(`deviceName: ${device.deviceName} deviceId: ${device.deviceId}, blindTiltDevicesIds: ${device.blindTiltDevicesIds}, master:`
@@ -2261,35 +2355,36 @@ export class SwitchBotPlatform {
2261
2355
  if (device.master && device.group) {
2262
2356
  // OpenAPI: Master Curtains/Blind Tilt in Group
2263
2357
  registerCurtain = true;
2264
- this.debugLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] device.master: ${device.master}, device.group: ${device.group}` +
2265
- ` connectionType; ${device.connectionType}`);
2358
+ this.debugLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] device.master: ${device.master}, device.group: ${device.group}`
2359
+ + ` connectionType; ${device.connectionType}`);
2266
2360
  this.debugWarnLog(`Device: ${device.deviceName} registerCurtains: ${registerCurtain}`);
2267
2361
  }
2268
2362
  else if (!device.master && device.curtain?.disable_group) {
2269
2363
  //!device.group && device.connectionType === 'BLE'
2270
2364
  // OpenAPI: Non-Master Curtains/Blind Tilts that has Disable Grouping Checked
2271
2365
  registerCurtain = true;
2272
- this.debugLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] device.master: ${device.master}, disable_group: ` +
2273
- `${device.curtain?.disable_group}, connectionType; ${device.connectionType}`);
2366
+ this.debugLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] device.master: ${device.master}, disable_group: `
2367
+ + `${device.curtain?.disable_group}, connectionType; ${device.connectionType}`);
2274
2368
  this.debugWarnLog(`Device: ${device.deviceName} registerCurtains: ${registerCurtain}`);
2275
2369
  }
2276
2370
  else if (device.master && !device.group) {
2277
2371
  // OpenAPI: Master Curtains/Blind Tilts not in Group
2278
2372
  registerCurtain = true;
2279
- this.debugLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] device.master: ${device.master}, device.group: ${device.group}` +
2280
- ` connectionType; ${device.connectionType}`);
2373
+ this.debugLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] device.master: ${device.master}, device.group: ${device.group}`
2374
+ + ` connectionType; ${device.connectionType}`);
2281
2375
  this.debugWarnLog(`Device: ${device.deviceName} registerCurtains: ${registerCurtain}`);
2282
2376
  }
2283
2377
  else if (device.connectionType === 'BLE') {
2284
2378
  // BLE: Curtains/Blind Tilt
2285
2379
  registerCurtain = true;
2286
- this.debugLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] connectionType: ${device.connectionType}, ` + ` group: ${device.group}`);
2380
+ this.debugLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] connectionType: ${device.connectionType}, `
2381
+ + ` group: ${device.group}`);
2287
2382
  this.debugWarnLog(`Device: ${device.deviceName} registerCurtains: ${registerCurtain}`);
2288
2383
  }
2289
2384
  else {
2290
2385
  registerCurtain = false;
2291
- this.debugErrorLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] disable_group: ${device.curtain?.disable_group},` +
2292
- ` device.master: ${device.master}, device.group: ${device.group}`);
2386
+ this.debugErrorLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] disable_group: ${device.curtain?.disable_group},`
2387
+ + ` device.master: ${device.master}, device.group: ${device.group}`);
2293
2388
  this.debugWarnLog(`Device: ${device.deviceName} registerCurtains: ${registerCurtain}, device.connectionType: ${device.connectionType}`);
2294
2389
  }
2295
2390
  return registerCurtain;
@@ -2388,8 +2483,8 @@ export class SwitchBotPlatform {
2388
2483
  }
2389
2484
  else {
2390
2485
  registerDevice = false;
2391
- this.debugErrorLog(`Device: ${device.deviceName} connectionType: ${device.connectionType}, hide_device: ` +
2392
- `${device.hide_device}, will not display in HomeKit`);
2486
+ this.debugErrorLog(`Device: ${device.deviceName} connectionType: ${device.connectionType}, hide_device: `
2487
+ + `${device.hide_device}, will not display in HomeKit`);
2393
2488
  }
2394
2489
  return registerDevice;
2395
2490
  }
@@ -2436,7 +2531,7 @@ export class SwitchBotPlatform {
2436
2531
  this.errorLog(`Device not found, statusCode: ${statusCode}`);
2437
2532
  break;
2438
2533
  case 160:
2439
- this.errorLog(`Command is not supported, statusCode: ${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
2534
+ this.errorLog(`Command is not supported, statusCode: ${statusCode}, Submit Bugs Here: https://tinyurl.com/SwitchBotBug`);
2440
2535
  break;
2441
2536
  case 161:
2442
2537
  this.errorLog(`Device is offline, statusCode: ${statusCode}`);
@@ -2492,6 +2587,29 @@ export class SwitchBotPlatform {
2492
2587
  this.errorLog(`Unknown statusCode, statusCode: ${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
2493
2588
  }
2494
2589
  }
2590
+ async retryRequest(deviceMaxRetries, deviceDelayBetweenRetries, url, options) {
2591
+ let retryCount = 0;
2592
+ const maxRetries = deviceMaxRetries;
2593
+ const delayBetweenRetries = deviceDelayBetweenRetries;
2594
+ while (retryCount < maxRetries) {
2595
+ try {
2596
+ const { body, statusCode } = await request(url, options);
2597
+ if (statusCode === 200 || statusCode === 100) {
2598
+ return { body, statusCode };
2599
+ }
2600
+ else {
2601
+ this.debugLog(`Received status code: ${statusCode}`);
2602
+ }
2603
+ }
2604
+ catch (error) {
2605
+ this.errorLog(`Error making request: ${error.message}`);
2606
+ }
2607
+ retryCount++;
2608
+ this.debugLog(`Retry attempt ${retryCount} of ${maxRetries}`);
2609
+ await sleep(delayBetweenRetries);
2610
+ }
2611
+ return { body: null, statusCode: -1 };
2612
+ }
2495
2613
  // BLE Connection
2496
2614
  async connectBLE() {
2497
2615
  let switchbot;
@@ -2510,7 +2628,7 @@ export class SwitchBotPlatform {
2510
2628
  this.debugLog(`Plugin Version: ${json.version}`);
2511
2629
  this.version = json.version;
2512
2630
  }
2513
- async platformConfigOptions() {
2631
+ async getPlatformConfigSettings() {
2514
2632
  const platformConfig = {};
2515
2633
  if (this.config.options) {
2516
2634
  if (this.config.options.logging) {
@@ -2519,16 +2637,37 @@ export class SwitchBotPlatform {
2519
2637
  if (this.config.options.refreshRate) {
2520
2638
  platformConfig.refreshRate = this.config.options.refreshRate;
2521
2639
  }
2640
+ if (this.config.options.updateRate) {
2641
+ platformConfig.updateRate = this.config.options.updateRate;
2642
+ }
2522
2643
  if (this.config.options.pushRate) {
2523
2644
  platformConfig.pushRate = this.config.options.pushRate;
2524
2645
  }
2646
+ if (this.config.options.maxRetries) {
2647
+ this.maxRetries = this.config.options.maxRetries;
2648
+ platformConfig.maxRetries = this.config.options.maxRetries;
2649
+ }
2650
+ else {
2651
+ this.maxRetries = 3;
2652
+ this.debugWarnLog('Using Default Max Retries');
2653
+ platformConfig.maxRetries = this.maxRetries;
2654
+ }
2655
+ if (this.config.options.delayBetweenRetries) {
2656
+ this.delayBetweenRetries = this.config.options.delayBetweenRetries * 1000;
2657
+ platformConfig.delayBetweenRetries = this.config.options.delayBetweenRetries;
2658
+ }
2659
+ else {
2660
+ this.delayBetweenRetries = 3000;
2661
+ this.debugWarnLog('Using Default Delay Between Retries');
2662
+ platformConfig.delayBetweenRetries = this.delayBetweenRetries / 1000;
2663
+ }
2525
2664
  if (Object.entries(platformConfig).length !== 0) {
2526
2665
  this.debugLog(`Platform Config: ${JSON.stringify(platformConfig)}`);
2527
2666
  }
2528
2667
  this.platformConfig = platformConfig;
2529
2668
  }
2530
2669
  }
2531
- async platformLogs() {
2670
+ async getPlatformLogSettings() {
2532
2671
  this.debugMode = process.argv.includes('-D') || process.argv.includes('--debug');
2533
2672
  if (this.config.options?.logging === 'debug' || this.config.options?.logging === 'standard' || this.config.options?.logging === 'none') {
2534
2673
  this.platformLogging = this.config.options.logging;
@@ -2552,6 +2691,18 @@ export class SwitchBotPlatform {
2552
2691
  this.log.info(String(...log));
2553
2692
  }
2554
2693
  }
2694
+ successLog(...log) {
2695
+ if (this.enablingPlatformLogging()) {
2696
+ this.log.success(String(...log));
2697
+ }
2698
+ }
2699
+ debugSuccessLog(...log) {
2700
+ if (this.enablingPlatformLogging()) {
2701
+ if (this.platformLogging?.includes('debug')) {
2702
+ this.log.success('[DEBUG]', String(...log));
2703
+ }
2704
+ }
2705
+ }
2555
2706
  warnLog(...log) {
2556
2707
  if (this.enablingPlatformLogging()) {
2557
2708
  this.log.warn(String(...log));