@switchbot/homebridge-switchbot 3.7.1-beta.9 → 3.8.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 (195) hide show
  1. package/CHANGELOG.md +8 -2
  2. package/README.md +14 -0
  3. package/assets/security-privacy-bluetooth.png +0 -0
  4. package/config.schema.json +76 -1
  5. package/dist/device/blindtilt.d.ts +18 -8
  6. package/dist/device/blindtilt.d.ts.map +1 -1
  7. package/dist/device/blindtilt.js +108 -70
  8. package/dist/device/blindtilt.js.map +1 -1
  9. package/dist/device/bot.d.ts +9 -9
  10. package/dist/device/bot.d.ts.map +1 -1
  11. package/dist/device/bot.js +133 -160
  12. package/dist/device/bot.js.map +1 -1
  13. package/dist/device/ceilinglight.d.ts +13 -13
  14. package/dist/device/ceilinglight.d.ts.map +1 -1
  15. package/dist/device/ceilinglight.js +38 -73
  16. package/dist/device/ceilinglight.js.map +1 -1
  17. package/dist/device/colorbulb.d.ts +12 -12
  18. package/dist/device/colorbulb.d.ts.map +1 -1
  19. package/dist/device/colorbulb.js +41 -79
  20. package/dist/device/colorbulb.js.map +1 -1
  21. package/dist/device/contact.d.ts +5 -5
  22. package/dist/device/contact.d.ts.map +1 -1
  23. package/dist/device/contact.js +20 -42
  24. package/dist/device/contact.js.map +1 -1
  25. package/dist/device/curtain.d.ts +15 -5
  26. package/dist/device/curtain.d.ts.map +1 -1
  27. package/dist/device/curtain.js +127 -81
  28. package/dist/device/curtain.js.map +1 -1
  29. package/dist/device/device.d.ts +18 -18
  30. package/dist/device/device.d.ts.map +1 -1
  31. package/dist/device/device.js +33 -36
  32. package/dist/device/device.js.map +1 -1
  33. package/dist/device/fan.d.ts +8 -8
  34. package/dist/device/fan.d.ts.map +1 -1
  35. package/dist/device/fan.js +43 -75
  36. package/dist/device/fan.js.map +1 -1
  37. package/dist/device/hub.d.ts +5 -5
  38. package/dist/device/hub.d.ts.map +1 -1
  39. package/dist/device/hub.js +18 -39
  40. package/dist/device/hub.js.map +1 -1
  41. package/dist/device/humidifier.d.ts +5 -5
  42. package/dist/device/humidifier.d.ts.map +1 -1
  43. package/dist/device/humidifier.js +38 -78
  44. package/dist/device/humidifier.js.map +1 -1
  45. package/dist/device/iosensor.d.ts +5 -5
  46. package/dist/device/iosensor.d.ts.map +1 -1
  47. package/dist/device/iosensor.js +21 -40
  48. package/dist/device/iosensor.js.map +1 -1
  49. package/dist/device/lightstrip.d.ts +6 -6
  50. package/dist/device/lightstrip.d.ts.map +1 -1
  51. package/dist/device/lightstrip.js +34 -73
  52. package/dist/device/lightstrip.js.map +1 -1
  53. package/dist/device/lock.d.ts +9 -9
  54. package/dist/device/lock.d.ts.map +1 -1
  55. package/dist/device/lock.js +37 -52
  56. package/dist/device/lock.js.map +1 -1
  57. package/dist/device/meter.d.ts +5 -5
  58. package/dist/device/meter.d.ts.map +1 -1
  59. package/dist/device/meter.js +21 -39
  60. package/dist/device/meter.js.map +1 -1
  61. package/dist/device/meterplus.d.ts +5 -5
  62. package/dist/device/meterplus.d.ts.map +1 -1
  63. package/dist/device/meterplus.js +21 -38
  64. package/dist/device/meterplus.js.map +1 -1
  65. package/dist/device/motion.d.ts +5 -5
  66. package/dist/device/motion.d.ts.map +1 -1
  67. package/dist/device/motion.js +14 -32
  68. package/dist/device/motion.js.map +1 -1
  69. package/dist/device/plug.d.ts +12 -12
  70. package/dist/device/plug.d.ts.map +1 -1
  71. package/dist/device/plug.js +16 -25
  72. package/dist/device/plug.js.map +1 -1
  73. package/dist/device/robotvacuumcleaner.d.ts +11 -11
  74. package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
  75. package/dist/device/robotvacuumcleaner.js +42 -56
  76. package/dist/device/robotvacuumcleaner.js.map +1 -1
  77. package/dist/device/waterdetector.d.ts +5 -5
  78. package/dist/device/waterdetector.d.ts.map +1 -1
  79. package/dist/device/waterdetector.js +47 -44
  80. package/dist/device/waterdetector.js.map +1 -1
  81. package/dist/homebridge-ui/server.js +2 -2
  82. package/dist/homebridge-ui/server.js.map +1 -1
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +0 -4
  85. package/dist/index.js.map +1 -1
  86. package/dist/irdevice/airconditioner.d.ts +8 -8
  87. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  88. package/dist/irdevice/airconditioner.js +61 -105
  89. package/dist/irdevice/airconditioner.js.map +1 -1
  90. package/dist/irdevice/airpurifier.d.ts +10 -10
  91. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  92. package/dist/irdevice/airpurifier.js +22 -42
  93. package/dist/irdevice/airpurifier.js.map +1 -1
  94. package/dist/irdevice/camera.d.ts +9 -9
  95. package/dist/irdevice/camera.d.ts.map +1 -1
  96. package/dist/irdevice/camera.js +15 -25
  97. package/dist/irdevice/camera.js.map +1 -1
  98. package/dist/irdevice/fan.d.ts +8 -8
  99. package/dist/irdevice/fan.d.ts.map +1 -1
  100. package/dist/irdevice/fan.js +21 -40
  101. package/dist/irdevice/fan.js.map +1 -1
  102. package/dist/irdevice/irdevice.d.ts +11 -11
  103. package/dist/irdevice/irdevice.d.ts.map +1 -1
  104. package/dist/irdevice/irdevice.js +14 -22
  105. package/dist/irdevice/irdevice.js.map +1 -1
  106. package/dist/irdevice/light.d.ts +9 -9
  107. package/dist/irdevice/light.d.ts.map +1 -1
  108. package/dist/irdevice/light.js +24 -47
  109. package/dist/irdevice/light.js.map +1 -1
  110. package/dist/irdevice/other.d.ts +9 -9
  111. package/dist/irdevice/other.d.ts.map +1 -1
  112. package/dist/irdevice/other.js +40 -83
  113. package/dist/irdevice/other.js.map +1 -1
  114. package/dist/irdevice/tv.d.ts +9 -9
  115. package/dist/irdevice/tv.d.ts.map +1 -1
  116. package/dist/irdevice/tv.js +29 -54
  117. package/dist/irdevice/tv.js.map +1 -1
  118. package/dist/irdevice/vacuumcleaner.d.ts +5 -5
  119. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  120. package/dist/irdevice/vacuumcleaner.js +11 -21
  121. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  122. package/dist/irdevice/waterheater.d.ts +5 -5
  123. package/dist/irdevice/waterheater.d.ts.map +1 -1
  124. package/dist/irdevice/waterheater.js +11 -22
  125. package/dist/irdevice/waterheater.js.map +1 -1
  126. package/dist/platform.d.ts +20 -19
  127. package/dist/platform.d.ts.map +1 -1
  128. package/dist/platform.js +466 -710
  129. package/dist/platform.js.map +1 -1
  130. package/dist/settings.d.ts +5 -2
  131. package/dist/settings.d.ts.map +1 -1
  132. package/dist/settings.js.map +1 -1
  133. package/dist/types/bledevicestatus.d.ts +9 -9
  134. package/dist/types/bledevicestatus.d.ts.map +1 -1
  135. package/dist/types/devicelist.d.ts +6 -6
  136. package/dist/types/devicelist.d.ts.map +1 -1
  137. package/dist/types/deviceresponse.d.ts +4 -4
  138. package/dist/types/deviceresponse.d.ts.map +1 -1
  139. package/dist/types/devicestatus.d.ts +2 -2
  140. package/dist/types/devicestatus.d.ts.map +1 -1
  141. package/dist/types/devicewebhookstatus.d.ts +5 -5
  142. package/dist/types/devicewebhookstatus.d.ts.map +1 -1
  143. package/dist/types/irdevicelist.d.ts +4 -4
  144. package/dist/types/irdevicelist.d.ts.map +1 -1
  145. package/dist/types/pushbody.d.ts +2 -2
  146. package/dist/types/pushbody.d.ts.map +1 -1
  147. package/dist/utils.d.ts +4 -4
  148. package/dist/utils.d.ts.map +1 -1
  149. package/dist/utils.js +9 -13
  150. package/dist/utils.js.map +1 -1
  151. package/eslint.config.js +48 -93
  152. package/package.json +61 -54
  153. package/src/device/blindtilt.ts +509 -460
  154. package/src/device/bot.ts +696 -718
  155. package/src/device/ceilinglight.ts +331 -364
  156. package/src/device/colorbulb.ts +412 -448
  157. package/src/device/contact.ts +200 -221
  158. package/src/device/curtain.ts +506 -444
  159. package/src/device/device.ts +206 -208
  160. package/src/device/fan.ts +307 -340
  161. package/src/device/hub.ts +184 -209
  162. package/src/device/humidifier.ts +297 -342
  163. package/src/device/iosensor.ts +182 -204
  164. package/src/device/lightstrip.ts +362 -399
  165. package/src/device/lock.ts +262 -276
  166. package/src/device/meter.ts +183 -205
  167. package/src/device/meterplus.ts +183 -204
  168. package/src/device/motion.ts +169 -185
  169. package/src/device/plug.ts +174 -177
  170. package/src/device/robotvacuumcleaner.ts +256 -269
  171. package/src/device/waterdetector.ts +185 -185
  172. package/src/homebridge-ui/server.ts +16 -15
  173. package/src/index.ts +5 -6
  174. package/src/irdevice/airconditioner.ts +277 -326
  175. package/src/irdevice/airpurifier.ts +124 -143
  176. package/src/irdevice/camera.ts +58 -64
  177. package/src/irdevice/fan.ts +106 -123
  178. package/src/irdevice/irdevice.ts +116 -119
  179. package/src/irdevice/light.ts +119 -143
  180. package/src/irdevice/other.ts +417 -461
  181. package/src/irdevice/tv.ts +155 -177
  182. package/src/irdevice/vacuumcleaner.ts +54 -60
  183. package/src/irdevice/waterheater.ts +56 -63
  184. package/src/platform.ts +1462 -1678
  185. package/src/settings.ts +173 -170
  186. package/src/types/bledevicestatus.ts +252 -256
  187. package/src/types/devicelist.ts +79 -79
  188. package/src/types/deviceresponse.ts +12 -13
  189. package/src/types/devicestatus.ts +124 -124
  190. package/src/types/devicewebhookstatus.ts +126 -131
  191. package/src/types/irdevicelist.ts +10 -10
  192. package/src/types/pushbody.ts +5 -5
  193. package/src/utils.ts +64 -65
  194. package/tsconfig.json +10 -9
  195. package/.github/npm-version-script.cjs +0 -81
package/dist/platform.js CHANGED
@@ -1,59 +1,58 @@
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';
1
+ import { Buffer } from 'node:buffer';
2
+ import crypto, { randomUUID } from 'node:crypto';
3
+ import { readFileSync, writeFileSync } from 'node:fs';
4
+ import { createServer } from 'node:http';
5
+ import process from 'node:process';
6
+ import asyncmqtt from 'async-mqtt';
7
+ import fakegato from 'fakegato-history';
8
+ import { EveHomeKitTypes } from 'homebridge-lib/EveHomeKitTypes';
9
+ /*
10
+ * For Testing Locally:
11
+ * import { SwitchBotModel } from '/Users/Shared/GitHub/OpenWonderLabs/node-switchbot/dist/index.js';
12
+ */
13
+ import { SwitchBot, SwitchBotModel } from 'node-switchbot';
14
+ import { queueScheduler } from 'rxjs';
15
+ import { request } from 'undici';
16
+ import { BlindTilt } from './device/blindtilt.js';
6
17
  import { Bot } from './device/bot.js';
7
- import { Plug } from './device/plug.js';
8
- import { Lock } from './device/lock.js';
9
- import { Meter } from './device/meter.js';
10
- import { Motion } from './device/motion.js';
18
+ import { CeilingLight } from './device/ceilinglight.js';
19
+ import { ColorBulb } from './device/colorbulb.js';
11
20
  import { Contact } from './device/contact.js';
12
21
  import { Curtain } from './device/curtain.js';
22
+ import { Fan } from './device/fan.js';
23
+ import { Hub } from './device/hub.js';
24
+ import { Humidifier } from './device/humidifier.js';
13
25
  import { IOSensor } from './device/iosensor.js';
14
- import { MeterPlus } from './device/meterplus.js';
15
- import { ColorBulb } from './device/colorbulb.js';
16
26
  import { StripLight } from './device/lightstrip.js';
17
- import { Humidifier } from './device/humidifier.js';
18
- import { CeilingLight } from './device/ceilinglight.js';
19
- import { WaterDetector } from './device/waterdetector.js';
27
+ import { Lock } from './device/lock.js';
28
+ import { Meter } from './device/meter.js';
29
+ import { MeterPlus } from './device/meterplus.js';
30
+ import { Motion } from './device/motion.js';
31
+ import { Plug } from './device/plug.js';
20
32
  import { RobotVacuumCleaner } from './device/robotvacuumcleaner.js';
21
- import { Fan } from './device/fan.js';
22
- import { TV } from './irdevice/tv.js';
33
+ import { WaterDetector } from './device/waterdetector.js';
34
+ import { AirConditioner } from './irdevice/airconditioner.js';
35
+ import { AirPurifier } from './irdevice/airpurifier.js';
36
+ import { Camera } from './irdevice/camera.js';
23
37
  import { IRFan } from './irdevice/fan.js';
24
38
  import { Light } from './irdevice/light.js';
25
39
  import { Others } from './irdevice/other.js';
26
- import { Camera } from './irdevice/camera.js';
27
- import { BlindTilt } from './device/blindtilt.js';
28
- import { AirPurifier } from './irdevice/airpurifier.js';
29
- import { WaterHeater } from './irdevice/waterheater.js';
40
+ import { TV } from './irdevice/tv.js';
30
41
  import { VacuumCleaner } from './irdevice/vacuumcleaner.js';
31
- import { AirConditioner } from './irdevice/airconditioner.js';
32
- import { Buffer } from 'buffer';
33
- import { request } from 'undici';
34
- import asyncmqtt from 'async-mqtt';
35
- import { createServer } from 'http';
36
- import { queueScheduler } from 'rxjs';
37
- import fakegato from 'fakegato-history';
38
- import crypto, { randomUUID } from 'crypto';
39
- import { readFileSync, writeFileSync } from 'fs';
40
- import { EveHomeKitTypes } from 'homebridge-lib/EveHomeKitTypes';
41
- import { PLATFORM_NAME, PLUGIN_NAME, Devices, deleteWebhook, queryWebhook, setupWebhook, updateWebhook } from './settings.js';
42
+ import { WaterHeater } from './irdevice/waterheater.js';
43
+ import { deleteWebhook, Devices, PLATFORM_NAME, PLUGIN_NAME, queryWebhook, setupWebhook, updateWebhook } from './settings.js';
42
44
  import { isBlindTiltDevice, isCurtainDevice, sleep } from './utils.js';
43
- /*
44
- * For Testing Locally:
45
- * import { SwitchBotModel } from '/Users/Shared/GitHub/OpenWonderLabs/node-switchbot/dist/index.js';
46
- */
47
- import { SwitchBotModel } from 'node-switchbot';
48
45
  /**
49
46
  * HomebridgePlatform
50
47
  * This class is the main constructor for your plugin, this is where you should
51
48
  * parse the user config and discover/register accessories with Homebridge.
52
49
  */
53
50
  export class SwitchBotPlatform {
54
- accessories;
51
+ // Platform properties
52
+ accessories = [];
55
53
  api;
56
54
  log;
55
+ // Configuration properties
57
56
  version;
58
57
  Logging;
59
58
  debugMode;
@@ -62,15 +61,16 @@ export class SwitchBotPlatform {
62
61
  platformConfig;
63
62
  platformLogging;
64
63
  config;
64
+ // MQTT and Webhook properties
65
65
  mqttClient = null;
66
66
  webhookEventListener = null;
67
+ // External APIs
67
68
  eve;
68
69
  fakegatoAPI;
70
+ // Event Handlers
69
71
  webhookEventHandler = {};
70
72
  bleEventHandler = {};
71
73
  constructor(log, config, api) {
72
- // initialize
73
- this.accessories = [];
74
74
  this.api = api;
75
75
  this.log = log;
76
76
  // only load if configured
@@ -108,21 +108,21 @@ export class SwitchBotPlatform {
108
108
  // in order to ensure they weren't added to homebridge already. This event can also be used
109
109
  // to start discovery of new accessories.
110
110
  this.api.on('didFinishLaunching', async () => {
111
- this.debugLog('Executed didFinishLaunching callback');
111
+ await this.debugLog('Executed didFinishLaunching callback');
112
112
  // run the method to discover / register your devices as accessories
113
113
  try {
114
114
  if (this.config.credentials?.openToken && !this.config.credentials.token) {
115
115
  await this.updateToken();
116
116
  }
117
117
  else if (this.config.credentials?.token && !this.config.credentials?.secret) {
118
- this.errorLog('"secret" config is not populated, you must populate then please restart Homebridge.');
118
+ await this.errorLog('"secret" config is not populated, you must populate then please restart Homebridge.');
119
119
  }
120
120
  else {
121
- this.discoverDevices();
121
+ await this.discoverDevices();
122
122
  }
123
123
  }
124
124
  catch (e) {
125
- this.errorLog(`Failed to Discover, Error Message: ${e.message}, Submit Bugs Here: ` + 'https://tinyurl.com/SwitchBotBug');
125
+ await this.errorLog(`Failed to Discover, Error Message: ${e.message}, Submit Bugs Here: ` + 'https://tinyurl.com/SwitchBotBug');
126
126
  await this.debugErrorLog(`Failed to Discover, Error: ${e}`);
127
127
  }
128
128
  });
@@ -160,7 +160,7 @@ export class SwitchBotPlatform {
160
160
  this.mqttClient.subscribe('homebridge-switchbot/webhook/+');
161
161
  this.mqttClient.on('message', async (topic, message) => {
162
162
  try {
163
- await await this.debugLog(`Received Webhook via MQTT: ${topic}=${message}`);
163
+ await this.debugLog(`Received Webhook via MQTT: ${topic}=${message}`);
164
164
  const context = JSON.parse(message.toString());
165
165
  this.webhookEventHandler[context.deviceMac]?.(context);
166
166
  }
@@ -177,7 +177,7 @@ export class SwitchBotPlatform {
177
177
  }
178
178
  }
179
179
  async setupwebhook() {
180
- //webhook configuration
180
+ // webhook configuration
181
181
  if (this.config.options?.webhookURL) {
182
182
  const url = this.config.options?.webhookURL;
183
183
  try {
@@ -192,17 +192,14 @@ export class SwitchBotPlatform {
192
192
  const body = JSON.parse(data);
193
193
  await this.debugLog(`Received Webhook: ${JSON.stringify(body)}`);
194
194
  if (this.config.options?.mqttURL) {
195
- const mac = body.context.deviceMac
196
- ?.toLowerCase()
197
- .match(/[\s\S]{1,2}/g)
198
- ?.join(':');
195
+ const mac = body.context.deviceMac?.toLowerCase().match(/[\s\S]{1,2}/g)?.join(':');
199
196
  const options = this.config.options?.mqttPubOptions || {};
200
197
  this.mqttClient?.publish(`homebridge-switchbot/webhook/${mac}`, `${JSON.stringify(body.context)}`, options);
201
198
  }
202
199
  this.webhookEventHandler[body.context.deviceMac]?.(body.context);
203
200
  }
204
201
  catch (e) {
205
- this.errorLog(`Failed to handle webhook event. Error:${e}`);
202
+ await this.errorLog(`Failed to handle webhook event. Error:${e}`);
206
203
  }
207
204
  });
208
205
  response.writeHead(200, { 'Content-Type': 'text/plain' });
@@ -216,10 +213,10 @@ export class SwitchBotPlatform {
216
213
  catch (e) {
217
214
  this.errorLog(`Failed to handle webhook event. Error:${e}`);
218
215
  }
219
- }).listen(port ? port : 80);
216
+ }).listen(port || 80);
220
217
  }
221
218
  catch (e) {
222
- this.errorLog(`Failed to create webhook listener. Error:${e.message}`);
219
+ await this.errorLog(`Failed to create webhook listener. Error:${e.message}`);
223
220
  return;
224
221
  }
225
222
  try {
@@ -227,64 +224,61 @@ export class SwitchBotPlatform {
227
224
  method: 'POST',
228
225
  headers: this.generateHeaders(),
229
226
  body: JSON.stringify({
230
- 'action': 'setupWebhook',
231
- 'url': url,
232
- 'deviceList': 'ALL',
227
+ action: 'setupWebhook',
228
+ url,
229
+ deviceList: 'ALL',
233
230
  }),
234
231
  });
235
232
  const response = await body.json();
236
- await this.debugLog(`setupWebhook: url:${url}`);
237
- await this.debugLog(`setupWebhook: body:${JSON.stringify(response)}`);
238
- await this.debugLog(`setupWebhook: statusCode:${statusCode}`);
233
+ await this.debugLog(`setupWebhook: url:${url}, body:${JSON.stringify(response)}, statusCode:${statusCode}`);
239
234
  if (statusCode !== 200 || response?.statusCode !== 100) {
240
- this.errorLog(`Failed to configure webhook. Existing webhook well be overridden. HTTP:${statusCode} API:${response?.statusCode} `
241
- + `message:${response?.message}`);
235
+ await this.errorLog(`Failed to configure webhook. Existing webhook well be overridden. HTTP:${statusCode} API:${response?.statusCode} message:${response?.message}`);
242
236
  }
243
237
  }
244
238
  catch (e) {
245
- this.errorLog(`Failed to configure webhook. Error: ${e.message}`);
239
+ await this.errorLog(`Failed to configure webhook. Error: ${e.message}`);
246
240
  }
247
241
  try {
248
242
  const { body, statusCode } = await request(updateWebhook, {
249
- method: 'POST', headers: this.generateHeaders(), body: JSON.stringify({
250
- 'action': 'updateWebhook',
251
- 'config': {
252
- 'url': url,
253
- 'enable': true,
243
+ method: 'POST',
244
+ headers: this.generateHeaders(),
245
+ body: JSON.stringify({
246
+ action: 'updateWebhook',
247
+ config: {
248
+ url,
249
+ enable: true,
254
250
  },
255
251
  }),
256
252
  });
257
253
  const response = await body.json();
258
- await this.debugLog(`updateWebhook: url:${url}`);
259
- await this.debugLog(`updateWebhook: body:${JSON.stringify(response)}`);
260
- await this.debugLog(`updateWebhook: statusCode:${statusCode}`);
254
+ await this.debugLog(`updateWebhook: url:${url}, body:${JSON.stringify(response)}, statusCode:${statusCode}`);
261
255
  if (statusCode !== 200 || response?.statusCode !== 100) {
262
- this.errorLog(`Failed to update webhook. HTTP:${statusCode} API:${response?.statusCode} message:${response?.message}`);
256
+ await this.errorLog(`Failed to update webhook. HTTP:${statusCode} API:${response?.statusCode} message:${response?.message}`);
263
257
  }
264
258
  }
265
259
  catch (e) {
266
- this.errorLog(`Failed to update webhook. Error:${e.message}`);
260
+ await this.errorLog(`Failed to update webhook. Error:${e.message}`);
267
261
  }
268
262
  try {
269
263
  const { body, statusCode } = await request(queryWebhook, {
270
264
  method: 'POST',
271
265
  headers: this.generateHeaders(),
272
266
  body: JSON.stringify({
273
- 'action': 'queryUrl',
267
+ action: 'queryUrl',
274
268
  }),
275
269
  });
276
270
  const response = await body.json();
277
271
  await this.debugLog(`queryWebhook: body:${JSON.stringify(response)}`);
278
272
  await this.debugLog(`queryWebhook: statusCode:${statusCode}`);
279
273
  if (statusCode !== 200 || response?.statusCode !== 100) {
280
- this.errorLog(`Failed to query webhook. HTTP:${statusCode} API:${response?.statusCode} message:${response?.message}`);
274
+ await this.errorLog(`Failed to query webhook. HTTP:${statusCode} API:${response?.statusCode} message:${response?.message}`);
281
275
  }
282
276
  else {
283
- this.infoLog(`Listening webhook on ${response?.body?.urls[0]}`);
277
+ await this.infoLog(`Listening webhook on ${response?.body?.urls[0]}`);
284
278
  }
285
279
  }
286
280
  catch (e) {
287
- this.errorLog(`Failed to query webhook. Error:${e}`);
281
+ await this.errorLog(`Failed to query webhook. Error:${e}`);
288
282
  }
289
283
  this.api.on('shutdown', async () => {
290
284
  try {
@@ -292,21 +286,21 @@ export class SwitchBotPlatform {
292
286
  method: 'POST',
293
287
  headers: this.generateHeaders(),
294
288
  body: JSON.stringify({
295
- 'action': 'deleteWebhook',
296
- 'url': url,
289
+ action: 'deleteWebhook',
290
+ url,
297
291
  }),
298
292
  });
299
293
  const response = await body.json();
300
294
  await this.debugLog(`deleteWebhook: url:${url}, body:${JSON.stringify(response)}, statusCode:${statusCode}`);
301
295
  if (statusCode !== 200 || response?.statusCode !== 100) {
302
- this.errorLog(`Failed to delete webhook. HTTP:${statusCode} API:${response?.statusCode} message:${response?.message}`);
296
+ await this.errorLog(`Failed to delete webhook. HTTP:${statusCode} API:${response?.statusCode} message:${response?.message}`);
303
297
  }
304
298
  else {
305
- this.infoLog('Unregistered webhook to close listening.');
299
+ await this.infoLog('Unregistered webhook to close listening.');
306
300
  }
307
301
  }
308
302
  catch (e) {
309
- this.errorLog(`Failed to delete webhook. Error:${e.message}`);
303
+ await this.errorLog(`Failed to delete webhook. Error:${e.message}`);
310
304
  }
311
305
  });
312
306
  }
@@ -314,7 +308,6 @@ export class SwitchBotPlatform {
314
308
  async setupBlE() {
315
309
  if (this.config.options?.BLE) {
316
310
  await this.debugLog('setupBLE');
317
- const SwitchBot = (await import('node-switchbot')).SwitchBot;
318
311
  const switchbot = new SwitchBot();
319
312
  if (switchbot === undefined) {
320
313
  await this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
@@ -338,10 +331,10 @@ export class SwitchBotPlatform {
338
331
  this.api.on('shutdown', async () => {
339
332
  try {
340
333
  switchbot.stopScan();
341
- this.infoLog('Stopped BLE scanning to close listening.');
334
+ await this.infoLog('Stopped BLE scanning to close listening.');
342
335
  }
343
336
  catch (e) {
344
- this.errorLog(`Failed to stop Platform BLE scanning. Error:${e.message}`);
337
+ await this.errorLog(`Failed to stop Platform BLE scanning. Error:${e.message}`);
345
338
  }
346
339
  });
347
340
  }
@@ -355,7 +348,8 @@ export class SwitchBotPlatform {
355
348
  * It should be used to setup event handlers for characteristics and update respective values.
356
349
  */
357
350
  async configureAccessory(accessory) {
358
- await this.debugLog(`Loading accessory from cache: ${accessory.displayName}`);
351
+ const { displayName } = accessory;
352
+ await this.debugLog(`Loading accessory from cache: ${displayName}`);
359
353
  // add the restored accessory to the accessories cache so we can track if it has already been registered
360
354
  this.accessories.push(accessory);
361
355
  }
@@ -363,18 +357,18 @@ export class SwitchBotPlatform {
363
357
  * Verify the config passed to the plugin is valid
364
358
  */
365
359
  async verifyConfig() {
366
- this.debugLog('Verifying Config');
360
+ await this.debugLog('Verifying Config');
367
361
  this.config = this.config || {};
368
362
  this.config.options = this.config.options || {};
369
363
  const platformConfig = {};
370
364
  if (this.config.options.logging) {
371
- platformConfig['logging'] = this.config.options.logging;
365
+ platformConfig.logging = this.config.options.logging;
372
366
  }
373
367
  if (this.config.options.logging && this.config.options.refreshRate) {
374
- platformConfig['refreshRate'] = this.config.options.refreshRate;
368
+ platformConfig.refreshRate = this.config.options.refreshRate;
375
369
  }
376
370
  if (this.config.options.logging && this.config.options.pushRate) {
377
- platformConfig['pushRate'] = this.config.options.pushRate;
371
+ platformConfig.pushRate = this.config.options.pushRate;
378
372
  }
379
373
  if (Object.entries(platformConfig).length !== 0) {
380
374
  await this.debugWarnLog(`Platform Config: ${JSON.stringify(platformConfig)}`);
@@ -398,10 +392,10 @@ export class SwitchBotPlatform {
398
392
  for (const irDeviceConfig of this.config.options.irdevices) {
399
393
  if (!irDeviceConfig.hide_device) {
400
394
  if (!irDeviceConfig.deviceId) {
401
- this.errorLog('The devices config section is missing the *Device ID* in the config. Please check your config.');
395
+ await this.errorLog('The devices config section is missing the *Device ID* in the config. Please check your config.');
402
396
  }
403
397
  if (!irDeviceConfig.deviceId && !irDeviceConfig.configRemoteType) {
404
- this.errorLog('The devices config section is missing the *Device Type* in the config. Please check your config.');
398
+ await this.errorLog('The devices config section is missing the *Device Type* in the config. Please check your config.');
405
399
  }
406
400
  }
407
401
  }
@@ -413,16 +407,16 @@ export class SwitchBotPlatform {
413
407
  if (!this.config.options.refreshRate) {
414
408
  // default 120 seconds (2 minutes)
415
409
  this.config.options.refreshRate = 120;
416
- this.debugWarnLog('Using Default Refresh Rate (2 minutes).');
410
+ await this.debugWarnLog('Using Default Refresh Rate (2 minutes).');
417
411
  }
418
412
  if (!this.config.options.pushRate) {
419
413
  // default 100 milliseconds
420
414
  this.config.options.pushRate = 0.1;
421
- this.debugWarnLog('Using Default Push Rate.');
415
+ await this.debugWarnLog('Using Default Push Rate.');
422
416
  }
423
417
  if (!this.config.options.maxRetries) {
424
418
  this.config.options.maxRetries = 5;
425
- this.debugWarnLog('Using Default Max Retries.');
419
+ await this.debugWarnLog('Using Default Max Retries.');
426
420
  }
427
421
  else {
428
422
  this.maxRetries = this.config.options.maxRetries;
@@ -430,23 +424,23 @@ export class SwitchBotPlatform {
430
424
  if (!this.config.options.delayBetweenRetries) {
431
425
  // default 3 seconds
432
426
  this.config.options.delayBetweenRetries = 3000;
433
- this.debugWarnLog('Using Default Delay Between Retries.');
427
+ await this.debugWarnLog('Using Default Delay Between Retries.');
434
428
  }
435
429
  else {
436
430
  this.delayBetweenRetries = this.config.options.delayBetweenRetries * 1000;
437
431
  }
438
432
  if (!this.config.credentials && !this.config.options) {
439
- this.debugWarnLog('Missing Credentials');
433
+ await this.debugWarnLog('Missing Credentials');
440
434
  }
441
435
  else if (this.config.credentials && !this.config.credentials.notice) {
442
436
  if (!this.config.credentials?.token) {
443
- this.debugErrorLog('Missing token');
444
- this.debugWarnLog('Cloud Enabled SwitchBot Devices & IR Devices will not work');
437
+ await this.debugErrorLog('Missing token');
438
+ await this.debugWarnLog('Cloud Enabled SwitchBot Devices & IR Devices will not work');
445
439
  }
446
440
  if (this.config.credentials?.token) {
447
441
  if (!this.config.credentials?.secret) {
448
- this.debugErrorLog('Missing secret');
449
- this.debugWarnLog('Cloud Enabled SwitchBot Devices & IR Devices will not work');
442
+ await this.debugErrorLog('Missing secret');
443
+ await this.debugWarnLog('Cloud Enabled SwitchBot Devices & IR Devices will not work');
450
444
  }
451
445
  }
452
446
  }
@@ -454,7 +448,6 @@ export class SwitchBotPlatform {
454
448
  /**
455
449
  * The openToken was old config.
456
450
  * This method saves the openToken as the token in the config.json file
457
- * @param this.config.credentials.openToken
458
451
  */
459
452
  async updateToken() {
460
453
  try {
@@ -466,7 +459,7 @@ export class SwitchBotPlatform {
466
459
  const currentConfig = JSON.parse(readFileSync(this.api.user.configPath(), 'utf8'));
467
460
  // check the platforms section is an array before we do array things on it
468
461
  if (!Array.isArray(currentConfig.platforms)) {
469
- throw new Error('Cannot find platforms array in config');
462
+ throw new TypeError('Cannot find platforms array in config');
470
463
  }
471
464
  // find this plugins current config
472
465
  const pluginConfig = currentConfig.platforms.find((x) => x.platform === PLATFORM_NAME);
@@ -475,17 +468,15 @@ export class SwitchBotPlatform {
475
468
  }
476
469
  // check the .credentials is an object before doing object things with it
477
470
  if (typeof pluginConfig.credentials !== 'object') {
478
- throw new Error('pluginConfig.credentials is not an object');
471
+ throw new TypeError('pluginConfig.credentials is not an object');
479
472
  }
480
473
  // Move openToken to token
481
474
  if (!this.config.credentials.secret) {
482
- this.warnLog('This plugin has been updated to use OpenAPI v1.1, config is set with openToken,'
483
- + ' "openToken" cconfig has been moved to the "token" config');
475
+ await 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');
484
476
  this.errorLog('"secret" config is not populated, you must populate then please restart Homebridge.');
485
477
  }
486
478
  else {
487
- this.warnLog('This plugin has been updated to use OpenAPI v1.1, config is set with openToken, '
488
- + '"openToken" config has been moved to the "token" config, please restart Homebridge.');
479
+ await this.warnLog('This plugin has been updated to use OpenAPI v1.1, config is set with openToken, "openToken" config has been moved to the "token" config, please restart Homebridge.');
489
480
  }
490
481
  // set the refresh token
491
482
  pluginConfig.credentials.token = this.config.credentials?.openToken;
@@ -495,10 +486,10 @@ export class SwitchBotPlatform {
495
486
  await this.debugWarnLog(`token: ${pluginConfig.credentials.token}`);
496
487
  // save the config, ensuring we maintain pretty json
497
488
  writeFileSync(this.api.user.configPath(), JSON.stringify(currentConfig, null, 4));
498
- this.verifyConfig();
489
+ await this.verifyConfig();
499
490
  }
500
491
  catch (e) {
501
- this.errorLog(`Update Token: ${e}`);
492
+ await this.errorLog(`Update Token: ${e}`);
502
493
  }
503
494
  }
504
495
  generateHeaders = () => {
@@ -511,340 +502,228 @@ export class SwitchBotPlatform {
511
502
  .digest();
512
503
  const sign = signTerm.toString('base64');
513
504
  return {
514
- Authorization: this.config.credentials?.token,
515
- sign: sign,
516
- nonce: nonce,
517
- t: t,
505
+ 'Authorization': this.config.credentials?.token,
506
+ 'sign': sign,
507
+ 'nonce': nonce,
508
+ 't': t,
518
509
  'Content-Type': 'application/json',
519
510
  };
520
511
  };
521
- /**
522
- * this method discovers devices
523
- *
524
- const t = `${Date.now()}`;
525
- const nonce = 'requestID';
526
- const data = this.config.credentials?.token + t + nonce;
527
- const signTerm = crypto.createHmac('sha256', this.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
528
- const sign = signTerm.toString('base64');
529
- */
530
512
  async discoverDevices() {
531
- if (this.config.credentials?.token) {
532
- let retryCount = 0;
533
- const maxRetries = this.maxRetries; // Maximum number of retries
534
- const delayBetweenRetries = this.delayBetweenRetries; // Delay between retries in milliseconds
535
- await this.debugWarnLog(`Retry Count: ${retryCount}`);
536
- await this.debugWarnLog(`Max Retries: ${maxRetries}`);
537
- await this.debugWarnLog(`Delay Between Retries: ${delayBetweenRetries}`);
538
- while (retryCount < maxRetries) {
539
- try {
540
- const { body, statusCode } = await request(Devices, {
541
- headers: this.generateHeaders(),
542
- });
543
- await this.debugWarnLog(`statusCode: ${statusCode}`);
544
- const devicesAPI = await body.json();
545
- await this.debugWarnLog(`devicesAPI: ${JSON.stringify(devicesAPI)}`);
546
- await this.debugWarnLog(`devicesAPI Body: ${JSON.stringify(devicesAPI.body)}`);
547
- await this.debugWarnLog(`devicesAPI StatusCode: ${devicesAPI.statusCode}`);
548
- if ((statusCode === 200 || statusCode === 100) && (devicesAPI.statusCode === 200 || devicesAPI.statusCode === 100)) {
549
- await this.debugErrorLog(`statusCode: ${statusCode} & devicesAPI StatusCode: ${devicesAPI.statusCode}`);
550
- // SwitchBot Devices
551
- const deviceLists = devicesAPI.body.deviceList;
552
- await this.debugWarnLog(`DeviceLists: ${JSON.stringify(deviceLists)}`);
553
- await this.debugWarnLog(`DeviceLists Length: ${deviceLists.length}`);
554
- if (!this.config.options?.devices) {
555
- await this.debugLog(`SwitchBot Device Config Not Set: ${JSON.stringify(this.config.options?.devices)}`);
556
- if (deviceLists.length === 0) {
557
- await this.debugLog(`SwitchBot API Has No Devices With Cloud Services Enabled: ${JSON.stringify(devicesAPI.body)}`);
558
- }
559
- else {
560
- const devices = deviceLists.map((v) => v);
561
- for (const device of devices) {
562
- if (device.deviceType) {
563
- if (device.configDeviceName) {
564
- device.deviceName = device.configDeviceName;
565
- }
566
- this.createDevice(device);
567
- }
568
- }
569
- }
570
- }
571
- else if (this.config.credentials?.token && this.config.options.devices) {
572
- await this.debugLog(`SwitchBot Device Config Set: ${JSON.stringify(this.config.options?.devices)}`);
573
- if (deviceLists.length === 0) {
574
- await this.debugLog(`SwitchBot API Has No Devices With Cloud Services Enabled: ${JSON.stringify(devicesAPI.body)}`);
575
- }
576
- else {
577
- const deviceConfigs = this.config.options?.devices;
578
- const mergeBydeviceId = (a1, a2) => a1.map((itm) => ({
579
- ...a2.find((item) => item.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') === itm.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') && item),
580
- ...itm,
581
- }));
582
- const devices = mergeBydeviceId(deviceLists, deviceConfigs);
583
- await this.debugLog(`SwitchBot Devices: ${JSON.stringify(devices)}`);
584
- for (const device of devices) {
585
- if (!device.deviceType) {
586
- device.deviceType = device.configDeviceType;
587
- this.errorLog(`API has displaying no deviceType: ${device.deviceType}, So using configDeviceType: ${device.configDeviceType}`);
588
- }
589
- if (device.deviceType) {
590
- if (device.configDeviceName) {
591
- device.deviceName = device.configDeviceName;
592
- }
593
- this.createDevice(device);
594
- }
595
- }
596
- }
597
- }
598
- else {
599
- this.errorLog('SwitchBot Token Supplied, Issue with Auth.');
600
- }
601
- if (devicesAPI.body.deviceList.length !== 0) {
602
- this.infoLog(`Total SwitchBot Devices Found: ${devicesAPI.body.deviceList.length}`);
603
- }
604
- else {
605
- await this.debugLog(`Total SwitchBot Devices Found: ${devicesAPI.body.deviceList.length}`);
606
- }
607
- // IR Devices
608
- const irDeviceLists = devicesAPI.body.infraredRemoteList;
609
- if (!this.config.options?.irdevices) {
610
- await this.debugLog(`IR Device Config Not Set: ${JSON.stringify(this.config.options?.irdevices)}`);
611
- const devices = irDeviceLists.map((v) => v);
612
- for (const device of devices) {
613
- if (device.remoteType) {
614
- this.createIRDevice(device);
615
- }
616
- }
617
- }
618
- else {
619
- await this.debugLog(`IR Device Config Set: ${JSON.stringify(this.config.options?.irdevices)}`);
620
- const irDeviceConfig = this.config.options?.irdevices;
621
- const mergeIRBydeviceId = (a1, a2) => a1.map((itm) => ({
622
- ...a2.find((item) => item.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') === itm.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') && item),
623
- ...itm,
624
- }));
625
- const devices = mergeIRBydeviceId(irDeviceLists, irDeviceConfig);
626
- await this.debugLog(`IR Devices: ${JSON.stringify(devices)}`);
627
- for (const device of devices) {
628
- this.createIRDevice(device);
629
- }
630
- }
631
- if (devicesAPI.body.infraredRemoteList.length !== 0) {
632
- this.infoLog(`Total IR Devices Found: ${devicesAPI.body.infraredRemoteList.length}`);
633
- }
634
- else {
635
- await this.debugLog(`Total IR Devices Found: ${devicesAPI.body.infraredRemoteList.length}`);
636
- }
637
- break;
638
- }
639
- else {
640
- this.statusCode(statusCode);
641
- this.statusCode(devicesAPI.statusCode);
642
- if (statusCode === 500) {
643
- retryCount++;
644
- this.infoLog(`statusCode: ${statusCode} Attempt ${retryCount} of ${maxRetries}`);
645
- await sleep(delayBetweenRetries);
646
- }
647
- }
513
+ if (!this.config.credentials?.token) {
514
+ return this.handleManualConfig();
515
+ }
516
+ let retryCount = 0;
517
+ const maxRetries = this.maxRetries;
518
+ const delayBetweenRetries = this.delayBetweenRetries;
519
+ await this.debugWarnLog(`Retry Count: ${retryCount}`);
520
+ await this.debugWarnLog(`Max Retries: ${maxRetries}`);
521
+ await this.debugWarnLog(`Delay Between Retries: ${delayBetweenRetries}`);
522
+ while (retryCount < maxRetries) {
523
+ try {
524
+ const { body, statusCode } = await request(Devices, { headers: this.generateHeaders() });
525
+ await this.debugWarnLog(`statusCode: ${statusCode}`);
526
+ const devicesAPI = await body.json();
527
+ await this.debugWarnLog(`devicesAPI: ${JSON.stringify(devicesAPI)}`);
528
+ if (this.isSuccessfulResponse(statusCode, devicesAPI.statusCode)) {
529
+ await this.handleDevices(devicesAPI.body.deviceList);
530
+ await this.handleIRDevices(devicesAPI.body.infraredRemoteList);
531
+ break;
648
532
  }
649
- catch (e) {
533
+ else {
534
+ await this.handleErrorResponse(statusCode, devicesAPI.statusCode, retryCount, maxRetries, delayBetweenRetries);
650
535
  retryCount++;
651
- this.debugErrorLog(`Failed to Discover Devices, Error Message: ${JSON.stringify(e.message)}, Submit Bugs Here: ` + 'https://tinyurl.com/SwitchBotBug');
652
- await this.debugErrorLog(`Failed to Discover Devices, Error: ${e}`);
653
536
  }
654
537
  }
538
+ catch (e) {
539
+ retryCount++;
540
+ await this.debugErrorLog(`Failed to Discover Devices, Error Message: ${JSON.stringify(e.message)}, Submit Bugs Here: https://tinyurl.com/SwitchBotBug`);
541
+ await this.debugErrorLog(`Failed to Discover Devices, Error: ${e}`);
542
+ }
655
543
  }
656
- else if (!this.config.credentials?.token && this.config.options?.devices) {
544
+ }
545
+ async handleManualConfig() {
546
+ if (this.config.options?.devices) {
657
547
  await this.debugLog(`SwitchBot Device Manual Config Set: ${JSON.stringify(this.config.options?.devices)}`);
658
- const deviceConfigs = this.config.options?.devices;
659
- const devices = deviceConfigs.map((v) => v);
548
+ const devices = this.config.options.devices.map((v) => v);
660
549
  for (const device of devices) {
661
550
  device.deviceType = device.configDeviceType;
662
551
  device.deviceName = device.configDeviceName;
663
552
  if (device.deviceType) {
664
- this.createDevice(device);
553
+ await this.createDevice(device);
665
554
  }
666
555
  }
667
556
  }
668
557
  else {
669
- this.errorLog('Neither SwitchBot Token or Device Config are not set.');
558
+ await this.errorLog('Neither SwitchBot Token or Device Config are set.');
559
+ }
560
+ }
561
+ isSuccessfulResponse(statusCode, apiStatusCode) {
562
+ return (statusCode === 200 || statusCode === 100) && (apiStatusCode === 200 || apiStatusCode === 100);
563
+ }
564
+ async handleDevices(deviceLists) {
565
+ if (!this.config.options?.devices) {
566
+ await this.debugLog(`SwitchBot Device Config Not Set: ${JSON.stringify(this.config.options?.devices)}`);
567
+ if (deviceLists.length === 0) {
568
+ await this.debugLog('SwitchBot API Has No Devices With Cloud Services Enabled');
569
+ }
570
+ else {
571
+ for (const device of deviceLists) {
572
+ if (device.deviceType) {
573
+ if (device.configDeviceName) {
574
+ device.deviceName = device.configDeviceName;
575
+ }
576
+ await this.createDevice(device);
577
+ }
578
+ }
579
+ }
580
+ }
581
+ else {
582
+ await this.debugLog(`SwitchBot Device Config Set: ${JSON.stringify(this.config.options?.devices)}`);
583
+ const devices = this.mergeByDeviceId(deviceLists, this.config.options.devices);
584
+ await this.debugLog(`SwitchBot Devices: ${JSON.stringify(devices)}`);
585
+ for (const device of devices) {
586
+ if (!device.deviceType && device.configDeviceType) {
587
+ device.deviceType = device.configDeviceType;
588
+ await this.warnLog(`API is displaying no deviceType: ${device.deviceType}, So using configDeviceType: ${device.configDeviceType}`);
589
+ }
590
+ else if (!device.deviceType && !device.configDeviceName) {
591
+ await this.errorLog('No deviceType or configDeviceType for device. No device will be created.');
592
+ }
593
+ if (device.deviceType) {
594
+ if (device.configDeviceName) {
595
+ device.deviceName = device.configDeviceName;
596
+ }
597
+ await this.createDevice(device);
598
+ }
599
+ }
600
+ }
601
+ }
602
+ async handleIRDevices(irDeviceLists) {
603
+ if (!this.config.options?.irdevices) {
604
+ await this.debugLog(`IR Device Config Not Set: ${JSON.stringify(this.config.options?.irdevices)}`);
605
+ for (const device of irDeviceLists) {
606
+ if (device.remoteType) {
607
+ await this.createIRDevice(device);
608
+ }
609
+ }
610
+ }
611
+ else {
612
+ await this.debugLog(`IR Device Config Set: ${JSON.stringify(this.config.options?.irdevices)}`);
613
+ const devices = this.mergeByDeviceId(irDeviceLists, this.config.options.irdevices);
614
+ await this.debugLog(`IR Devices: ${JSON.stringify(devices)}`);
615
+ for (const device of devices) {
616
+ await this.createIRDevice(device);
617
+ }
618
+ }
619
+ }
620
+ mergeByDeviceId(a1, a2) {
621
+ const normalizeDeviceId = (deviceId) => deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '');
622
+ return a1.map((itm) => {
623
+ const matchingItem = a2.find(item => normalizeDeviceId(item.deviceId) === normalizeDeviceId(itm.deviceId));
624
+ return { ...matchingItem, ...itm };
625
+ });
626
+ }
627
+ async handleErrorResponse(statusCode, apiStatusCode, retryCount, maxRetries, delayBetweenRetries) {
628
+ await this.statusCode(statusCode);
629
+ await this.statusCode(apiStatusCode);
630
+ if (statusCode === 500) {
631
+ this.infoLog(`statusCode: ${statusCode} Attempt ${retryCount + 1} of ${maxRetries}`);
632
+ await sleep(delayBetweenRetries);
670
633
  }
671
634
  }
672
635
  async createDevice(device) {
673
- switch (device.deviceType) {
674
- case 'Humidifier':
675
- await this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
676
- this.createHumidifier(device);
677
- break;
678
- case 'Hub Mini':
679
- await this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
680
- break;
681
- case 'Hub Plus':
682
- await this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
683
- break;
684
- case 'Hub 2':
685
- await this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
686
- this.createHub2(device);
687
- break;
688
- case 'Bot':
689
- await this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
690
- this.createBot(device);
691
- break;
692
- case 'Meter':
693
- await this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
694
- this.createMeter(device);
695
- break;
696
- case 'MeterPlus':
697
- case 'Meter Plus (JP)':
698
- await this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
699
- this.createMeterPlus(device);
700
- break;
701
- case 'WoIOSensor':
702
- await this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
703
- this.createIOSensor(device);
704
- break;
705
- case 'Water Detector':
706
- await this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
707
- this.createWaterDetector(device);
708
- break;
709
- case 'Motion Sensor':
710
- await this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
711
- this.createMotion(device);
712
- break;
713
- case 'Contact Sensor':
714
- await this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
715
- this.createContact(device);
716
- break;
717
- case 'Curtain':
718
- case 'Curtain3':
719
- await this.debugLog(`Discovered ${device.deviceType} ${device.deviceName}: ${device.deviceId}`);
720
- this.createCurtain(device);
721
- break;
722
- case 'Blind Tilt':
723
- await this.debugLog(`Discovered ${device.deviceType} ${device.deviceName}: ${device.deviceId}`);
724
- this.createBlindTilt(device);
725
- break;
726
- case 'Plug':
727
- case 'Plug Mini (US)':
728
- case 'Plug Mini (JP)':
729
- await this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
730
- this.createPlug(device);
731
- break;
732
- case 'Smart Lock':
733
- case 'Smart Lock Pro':
734
- await this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
735
- this.createLock(device);
736
- break;
737
- case 'Color Bulb':
738
- await this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
739
- this.createColorBulb(device);
740
- break;
741
- case 'K10+':
742
- case 'WoSweeper':
743
- case 'WoSweeperMini':
744
- case 'Robot Vacuum Cleaner S1':
745
- case 'Robot Vacuum Cleaner S1 Plus':
746
- case 'Robot Vacuum Cleaner S10':
747
- await this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
748
- this.createRobotVacuumCleaner(device);
749
- break;
750
- case 'Ceiling Light':
751
- case 'Ceiling Light Pro':
752
- await this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
753
- this.createCeilingLight(device);
754
- break;
755
- case 'Strip Light':
756
- await this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
757
- this.createStripLight(device);
758
- break;
759
- case 'Battery Circulator Fan':
760
- await this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
761
- this.createFan(device);
762
- break;
763
- case 'Remote':
764
- case 'Indoor Cam':
765
- case 'remote with screen+':
766
- await this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}, is currently not supported, device: ${JSON.stringify(device)}`);
767
- break;
768
- default:
769
- 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)}`);
636
+ const deviceTypeHandlers = {
637
+ 'Humidifier': this.createHumidifier.bind(this),
638
+ 'Hub 2': this.createHub2.bind(this),
639
+ 'Bot': this.createBot.bind(this),
640
+ 'Meter': this.createMeter.bind(this),
641
+ 'MeterPlus': this.createMeterPlus.bind(this),
642
+ 'Meter Plus (JP)': this.createMeterPlus.bind(this),
643
+ 'WoIOSensor': this.createIOSensor.bind(this),
644
+ 'Water Detector': this.createWaterDetector.bind(this),
645
+ 'Motion Sensor': this.createMotion.bind(this),
646
+ 'Contact Sensor': this.createContact.bind(this),
647
+ 'Curtain': this.createCurtain.bind(this),
648
+ 'Curtain3': this.createCurtain.bind(this),
649
+ 'WoRollerShade': this.createCurtain.bind(this),
650
+ 'Roller Shade': this.createCurtain.bind(this),
651
+ 'Blind Tilt': this.createBlindTilt.bind(this),
652
+ 'Plug': this.createPlug.bind(this),
653
+ 'Plug Mini (US)': this.createPlug.bind(this),
654
+ 'Plug Mini (JP)': this.createPlug.bind(this),
655
+ 'Smart Lock': this.createLock.bind(this),
656
+ 'Smart Lock Pro': this.createLock.bind(this),
657
+ 'Color Bulb': this.createColorBulb.bind(this),
658
+ 'K10+': this.createRobotVacuumCleaner.bind(this),
659
+ 'WoSweeper': this.createRobotVacuumCleaner.bind(this),
660
+ 'WoSweeperMini': this.createRobotVacuumCleaner.bind(this),
661
+ 'Robot Vacuum Cleaner S1': this.createRobotVacuumCleaner.bind(this),
662
+ 'Robot Vacuum Cleaner S1 Plus': this.createRobotVacuumCleaner.bind(this),
663
+ 'Robot Vacuum Cleaner S10': this.createRobotVacuumCleaner.bind(this),
664
+ 'Ceiling Light': this.createCeilingLight.bind(this),
665
+ 'Ceiling Light Pro': this.createCeilingLight.bind(this),
666
+ 'Strip Light': this.createStripLight.bind(this),
667
+ 'Battery Circulator Fan': this.createFan.bind(this),
668
+ };
669
+ if (deviceTypeHandlers[device.deviceType]) {
670
+ await this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
671
+ await deviceTypeHandlers[device.deviceType](device);
672
+ }
673
+ else if (['Hub Mini', 'Hub Plus', 'Remote', 'Indoor Cam', 'remote with screen'].includes(device.deviceType)) {
674
+ await this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}, is currently not supported, device: ${JSON.stringify(device)}`);
675
+ }
676
+ else {
677
+ await 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)}`);
770
678
  }
771
679
  }
772
680
  async createIRDevice(device) {
773
- if (device.connectionType === undefined) {
774
- device.connectionType = 'OpenAPI';
775
- }
776
- switch (device.remoteType) {
777
- case 'TV':
778
- case 'DIY TV':
779
- case 'Projector':
780
- case 'DIY Projector':
781
- case 'Set Top Box':
782
- case 'DIY Set Top Box':
783
- case 'IPTV':
784
- case 'DIY IPTV':
785
- case 'DVD':
786
- case 'DIY DVD':
787
- case 'Speaker':
788
- case 'DIY Speaker':
789
- await this.debugLog(`Discovered ${device.remoteType}: ${device.deviceId}`);
790
- if (device.external === undefined) {
791
- device.external = true;
792
- this.createTV(device);
793
- }
794
- else {
795
- this.createTV(device);
796
- }
797
- break;
798
- case 'Fan':
799
- case 'DIY Fan':
800
- await this.debugLog(`Discovered ${device.remoteType}: ${device.deviceId}`);
801
- this.createIRFan(device);
802
- break;
803
- case 'Air Conditioner':
804
- case 'DIY Air Conditioner':
805
- await this.debugLog(`Discovered ${device.remoteType}: ${device.deviceId}`);
806
- this.createAirConditioner(device);
807
- break;
808
- case 'Light':
809
- case 'DIY Light':
810
- await this.debugLog(`Discovered ${device.remoteType}: ${device.deviceId}`);
811
- this.createLight(device);
812
- break;
813
- case 'Air Purifier':
814
- case 'DIY Air Purifier':
815
- await this.debugLog(`Discovered ${device.remoteType}: ${device.deviceId}`);
816
- this.createAirPurifier(device);
817
- break;
818
- case 'Water Heater':
819
- case 'DIY Water Heater':
820
- await this.debugLog(`Discovered ${device.remoteType}: ${device.deviceId}`);
821
- this.createWaterHeater(device);
822
- break;
823
- case 'Vacuum Cleaner':
824
- case 'DIY Vacuum Cleaner':
825
- await this.debugLog(`Discovered ${device.remoteType}: ${device.deviceId}`);
826
- this.createVacuumCleaner(device);
827
- break;
828
- case 'Camera':
829
- case 'DIY Camera':
830
- await this.debugLog(`Discovered ${device.remoteType}: ${device.deviceId}`);
831
- this.createCamera(device);
832
- break;
833
- case 'Others':
834
- await this.debugLog(`Discovered ${device.remoteType}: ${device.deviceId}`);
835
- this.createOthers(device);
836
- break;
837
- default:
838
- await this.debugLog(`Unsupported Device: ${JSON.stringify(device)}`);
839
- this.warnLog(`Device: ${device.deviceName} with Device Type: ${device.remoteType}, is currently not supported.`);
840
- this.warnLog('Submit Feature Requests Here: ' + 'https://tinyurl.com/SwitchBotFeatureRequest');
681
+ device.connectionType = device.connectionType ?? 'OpenAPI';
682
+ const deviceTypeHandlers = {
683
+ 'TV': this.createTV.bind(this),
684
+ 'DIY TV': this.createTV.bind(this),
685
+ 'Projector': this.createTV.bind(this),
686
+ 'DIY Projector': this.createTV.bind(this),
687
+ 'Set Top Box': this.createTV.bind(this),
688
+ 'DIY Set Top Box': this.createTV.bind(this),
689
+ 'IPTV': this.createTV.bind(this),
690
+ 'DIY IPTV': this.createTV.bind(this),
691
+ 'DVD': this.createTV.bind(this),
692
+ 'DIY DVD': this.createTV.bind(this),
693
+ 'Speaker': this.createTV.bind(this),
694
+ 'DIY Speaker': this.createTV.bind(this),
695
+ 'Fan': this.createIRFan.bind(this),
696
+ 'DIY Fan': this.createIRFan.bind(this),
697
+ 'Air Conditioner': this.createAirConditioner.bind(this),
698
+ 'DIY Air Conditioner': this.createAirConditioner.bind(this),
699
+ 'Light': this.createLight.bind(this),
700
+ 'DIY Light': this.createLight.bind(this),
701
+ 'Air Purifier': this.createAirPurifier.bind(this),
702
+ 'DIY Air Purifier': this.createAirPurifier.bind(this),
703
+ 'Water Heater': this.createWaterHeater.bind(this),
704
+ 'DIY Water Heater': this.createWaterHeater.bind(this),
705
+ 'Vacuum Cleaner': this.createVacuumCleaner.bind(this),
706
+ 'DIY Vacuum Cleaner': this.createVacuumCleaner.bind(this),
707
+ 'Camera': this.createCamera.bind(this),
708
+ 'DIY Camera': this.createCamera.bind(this),
709
+ 'Others': this.createOthers.bind(this),
710
+ };
711
+ if (deviceTypeHandlers[device.remoteType]) {
712
+ await this.debugLog(`Discovered ${device.remoteType}: ${device.deviceId}`);
713
+ if (device.remoteType.startsWith('DIY') && device.external === undefined) {
714
+ device.external = true;
715
+ }
716
+ await deviceTypeHandlers[device.remoteType](device);
717
+ }
718
+ else {
719
+ await this.warnLog(`Device: ${device.deviceName} with Device Type: ${device.remoteType}, is currently not supported. Submit Feature Requests Here: https://tinyurl.com/SwitchBotFeatureRequest, device: ${JSON.stringify(device)}`);
841
720
  }
842
721
  }
843
722
  async createHumidifier(device) {
844
723
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
845
724
  // see if an accessory with the same uuid has already been registered and restored from
846
725
  // the cached devices we stored in the `configureAccessory` method above
847
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
726
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
848
727
  if (existingAccessory) {
849
728
  // the accessory already exists
850
729
  if (await this.registerDevice(device)) {
@@ -903,7 +782,7 @@ export class SwitchBotPlatform {
903
782
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
904
783
  // see if an accessory with the same uuid has already been registered and restored from
905
784
  // the cached devices we stored in the `configureAccessory` method above
906
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
785
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
907
786
  if (existingAccessory) {
908
787
  // the accessory already exists
909
788
  if (await this.registerDevice(device)) {
@@ -964,7 +843,7 @@ export class SwitchBotPlatform {
964
843
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
965
844
  // see if an accessory with the same uuid has already been registered and restored from
966
845
  // the cached devices we stored in the `configureAccessory` method above
967
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
846
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
968
847
  if (existingAccessory) {
969
848
  // the accessory already exists
970
849
  if (await this.registerDevice(device)) {
@@ -1024,7 +903,7 @@ export class SwitchBotPlatform {
1024
903
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
1025
904
  // see if an accessory with the same uuid has already been registered and restored from
1026
905
  // the cached devices we stored in the `configureAccessory` method above
1027
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
906
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
1028
907
  if (existingAccessory) {
1029
908
  // the accessory already exists
1030
909
  if (await this.registerDevice(device)) {
@@ -1085,7 +964,7 @@ export class SwitchBotPlatform {
1085
964
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
1086
965
  // see if an accessory with the same uuid has already been registered and restored from
1087
966
  // the cached devices we stored in the `configureAccessory` method above
1088
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
967
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
1089
968
  if (existingAccessory) {
1090
969
  // the accessory already exists
1091
970
  if (await this.registerDevice(device)) {
@@ -1146,7 +1025,7 @@ export class SwitchBotPlatform {
1146
1025
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
1147
1026
  // see if an accessory with the same uuid has already been registered and restored from
1148
1027
  // the cached devices we stored in the `configureAccessory` method above
1149
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
1028
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
1150
1029
  if (existingAccessory) {
1151
1030
  // the accessory already exists
1152
1031
  if (await this.registerDevice(device)) {
@@ -1206,7 +1085,7 @@ export class SwitchBotPlatform {
1206
1085
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
1207
1086
  // see if an accessory with the same uuid has already been registered and restored from
1208
1087
  // the cached devices we stored in the `configureAccessory` method above
1209
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
1088
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
1210
1089
  if (existingAccessory) {
1211
1090
  // the accessory already exists
1212
1091
  if (await this.registerDevice(device)) {
@@ -1266,7 +1145,7 @@ export class SwitchBotPlatform {
1266
1145
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
1267
1146
  // see if an accessory with the same uuid has already been registered and restored from
1268
1147
  // the cached devices we stored in the `configureAccessory` method above
1269
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
1148
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
1270
1149
  if (existingAccessory) {
1271
1150
  // the accessory already exists
1272
1151
  if (await this.registerDevice(device)) {
@@ -1326,7 +1205,7 @@ export class SwitchBotPlatform {
1326
1205
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
1327
1206
  // see if an accessory with the same uuid has already been registered and restored from
1328
1207
  // the cached devices we stored in the `configureAccessory` method above
1329
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
1208
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
1330
1209
  if (existingAccessory) {
1331
1210
  // the accessory already exists
1332
1211
  if (await this.registerDevice(device)) {
@@ -1386,7 +1265,7 @@ export class SwitchBotPlatform {
1386
1265
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
1387
1266
  // see if an accessory with the same uuid has already been registered and restored from
1388
1267
  // the cached devices we stored in the `configureAccessory` method above
1389
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
1268
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
1390
1269
  if (existingAccessory) {
1391
1270
  // the accessory already exists
1392
1271
  if (await this.registerDevice(device)) {
@@ -1414,8 +1293,8 @@ export class SwitchBotPlatform {
1414
1293
  else if (await this.registerDevice(device)) {
1415
1294
  if (isBlindTiltDevice(device)) {
1416
1295
  if (device.group && !device.curtain?.disable_group) {
1417
- this.debugLog('Your Curtains are grouped, ' +
1418
- `, Secondary curtain automatically hidden. Main Curtain: ${device.deviceName}, deviceId: ${device.deviceId}`);
1296
+ this.debugLog('Your Curtains are grouped, '
1297
+ + `, Secondary curtain automatically hidden. Main Curtain: ${device.deviceName}, deviceId: ${device.deviceId}`);
1419
1298
  }
1420
1299
  else {
1421
1300
  if (device.master) {
@@ -1433,7 +1312,6 @@ export class SwitchBotPlatform {
1433
1312
  // store a copy of the device object in the `accessory.context`
1434
1313
  // the `context` property can be used to store any data about the accessory you may need
1435
1314
  accessory.context.device = device;
1436
- ;
1437
1315
  accessory.context.deviceId = device.deviceId;
1438
1316
  accessory.context.deviceType = device.deviceType;
1439
1317
  accessory.context.model = SwitchBotModel.BlindTilt;
@@ -1461,7 +1339,7 @@ export class SwitchBotPlatform {
1461
1339
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
1462
1340
  // see if an accessory with the same uuid has already been registered and restored from
1463
1341
  // the cached devices we stored in the `configureAccessory` method above
1464
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
1342
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
1465
1343
  if (existingAccessory) {
1466
1344
  // the accessory already exists
1467
1345
  if (await this.registerDevice(device)) {
@@ -1489,8 +1367,8 @@ export class SwitchBotPlatform {
1489
1367
  else if (await this.registerDevice(device)) {
1490
1368
  if (isCurtainDevice(device)) {
1491
1369
  if (device.group && !device.curtain?.disable_group) {
1492
- this.debugLog('Your Curtains are grouped, ' +
1493
- `, Secondary curtain automatically hidden. Main Curtain: ${device.deviceName}, deviceId: ${device.deviceId}`);
1370
+ this.debugLog('Your Curtains are grouped, '
1371
+ + `, Secondary curtain automatically hidden. Main Curtain: ${device.deviceName}, deviceId: ${device.deviceId}`);
1494
1372
  }
1495
1373
  else {
1496
1374
  if (device.master) {
@@ -1535,7 +1413,7 @@ export class SwitchBotPlatform {
1535
1413
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
1536
1414
  // see if an accessory with the same uuid has already been registered and restored from
1537
1415
  // the cached devices we stored in the `configureAccessory` method above
1538
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
1416
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
1539
1417
  if (existingAccessory) {
1540
1418
  // the accessory already exists
1541
1419
  if (await this.registerDevice(device)) {
@@ -1543,8 +1421,11 @@ export class SwitchBotPlatform {
1543
1421
  existingAccessory.context.device = device;
1544
1422
  existingAccessory.context.deviceId = device.deviceId;
1545
1423
  existingAccessory.context.deviceType = device.deviceType;
1546
- existingAccessory.context.model = device.deviceType === 'Plug Mini (US)' ? SwitchBotModel.PlugMiniUS : device.deviceType === 'Plug Mini (JP)'
1547
- ? SwitchBotModel.PlugMiniJP : SwitchBotModel.Plug;
1424
+ existingAccessory.context.model = device.deviceType === 'Plug Mini (US)'
1425
+ ? SwitchBotModel.PlugMiniUS
1426
+ : device.deviceType === 'Plug Mini (JP)'
1427
+ ? SwitchBotModel.PlugMiniJP
1428
+ : SwitchBotModel.Plug;
1548
1429
  existingAccessory.displayName = device.configDeviceName
1549
1430
  ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1550
1431
  : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
@@ -1571,8 +1452,11 @@ export class SwitchBotPlatform {
1571
1452
  accessory.context.device = device;
1572
1453
  accessory.context.deviceId = device.deviceId;
1573
1454
  accessory.context.deviceType = device.deviceType;
1574
- accessory.context.model = device.deviceType === 'Plug Mini (US)' ? SwitchBotModel.PlugMiniUS : device.deviceType === 'Plug Mini (JP)'
1575
- ? SwitchBotModel.PlugMiniJP : SwitchBotModel.Plug;
1455
+ accessory.context.model = device.deviceType === 'Plug Mini (US)'
1456
+ ? SwitchBotModel.PlugMiniUS
1457
+ : device.deviceType === 'Plug Mini (JP)'
1458
+ ? SwitchBotModel.PlugMiniJP
1459
+ : SwitchBotModel.Plug;
1576
1460
  accessory.displayName = device.configDeviceName
1577
1461
  ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1578
1462
  : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
@@ -1597,7 +1481,7 @@ export class SwitchBotPlatform {
1597
1481
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
1598
1482
  // see if an accessory with the same uuid has already been registered and restored from
1599
1483
  // the cached devices we stored in the `configureAccessory` method above
1600
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
1484
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
1601
1485
  if (existingAccessory) {
1602
1486
  // the accessory already exists
1603
1487
  if (await this.registerDevice(device)) {
@@ -1657,7 +1541,7 @@ export class SwitchBotPlatform {
1657
1541
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
1658
1542
  // see if an accessory with the same uuid has already been registered and restored from
1659
1543
  // the cached devices we stored in the `configureAccessory` method above
1660
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
1544
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
1661
1545
  if (existingAccessory) {
1662
1546
  // the accessory already exists
1663
1547
  if (await this.registerDevice(device)) {
@@ -1717,7 +1601,7 @@ export class SwitchBotPlatform {
1717
1601
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
1718
1602
  // see if an accessory with the same uuid has already been registered and restored from
1719
1603
  // the cached devices we stored in the `configureAccessory` method above
1720
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
1604
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
1721
1605
  if (existingAccessory) {
1722
1606
  // the accessory already exists
1723
1607
  if (await this.registerDevice(device)) {
@@ -1777,7 +1661,7 @@ export class SwitchBotPlatform {
1777
1661
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
1778
1662
  // see if an accessory with the same uuid has already been registered and restored from
1779
1663
  // the cached devices we stored in the `configureAccessory` method above
1780
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
1664
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
1781
1665
  if (existingAccessory) {
1782
1666
  // the accessory already exists
1783
1667
  if (await this.registerDevice(device)) {
@@ -1837,7 +1721,7 @@ export class SwitchBotPlatform {
1837
1721
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
1838
1722
  // see if an accessory with the same uuid has already been registered and restored from
1839
1723
  // the cached devices we stored in the `configureAccessory` method above
1840
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
1724
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
1841
1725
  if (existingAccessory) {
1842
1726
  // the accessory already exists
1843
1727
  if (await this.registerDevice(device)) {
@@ -1897,7 +1781,7 @@ export class SwitchBotPlatform {
1897
1781
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
1898
1782
  // see if an accessory with the same uuid has already been registered and restored from
1899
1783
  // the cached devices we stored in the `configureAccessory` method above
1900
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
1784
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
1901
1785
  if (existingAccessory) {
1902
1786
  // the accessory already exists
1903
1787
  if (await this.registerDevice(device)) {
@@ -1905,11 +1789,17 @@ export class SwitchBotPlatform {
1905
1789
  existingAccessory.context.device = device;
1906
1790
  existingAccessory.context.deviceId = device.deviceId;
1907
1791
  existingAccessory.context.deviceType = device.deviceType;
1908
- existingAccessory.context.model = device.deviceType === 'Robot Vacuum Cleaner S1' ? SwitchBotModel.RobotVacuumCleanerS1
1909
- : device.deviceType === 'Robot Vacuum Cleaner S1 Plus' ? SwitchBotModel.RobotVacuumCleanerS1Plus
1910
- : device.deviceType === 'Robot Vacuum Cleaner S10' ? SwitchBotModel.RobotVacuumCleanerS10
1911
- : device.deviceType === 'WoSweeper' ? SwitchBotModel.WoSweeper : device.deviceType === 'WoSweeperMini' ? SwitchBotModel.WoSweeperMini
1912
- : SwitchBotModel.Unknown;
1792
+ existingAccessory.context.model = device.deviceType === 'Robot Vacuum Cleaner S1'
1793
+ ? SwitchBotModel.RobotVacuumCleanerS1
1794
+ : device.deviceType === 'Robot Vacuum Cleaner S1 Plus'
1795
+ ? SwitchBotModel.RobotVacuumCleanerS1Plus
1796
+ : device.deviceType === 'Robot Vacuum Cleaner S10'
1797
+ ? SwitchBotModel.RobotVacuumCleanerS10
1798
+ : device.deviceType === 'WoSweeper'
1799
+ ? SwitchBotModel.WoSweeper
1800
+ : device.deviceType === 'WoSweeperMini'
1801
+ ? SwitchBotModel.WoSweeperMini
1802
+ : SwitchBotModel.Unknown;
1913
1803
  existingAccessory.displayName = device.configDeviceName
1914
1804
  ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1915
1805
  : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
@@ -1936,11 +1826,17 @@ export class SwitchBotPlatform {
1936
1826
  accessory.context.device = device;
1937
1827
  accessory.context.deviceId = device.deviceId;
1938
1828
  accessory.context.deviceType = device.deviceType;
1939
- accessory.context.model = device.deviceType === 'Robot Vacuum Cleaner S1' ? SwitchBotModel.RobotVacuumCleanerS1
1940
- : device.deviceType === 'Robot Vacuum Cleaner S1 Plus' ? SwitchBotModel.RobotVacuumCleanerS1Plus
1941
- : device.deviceType === 'Robot Vacuum Cleaner S10' ? SwitchBotModel.RobotVacuumCleanerS10
1942
- : device.deviceType === 'WoSweeper' ? SwitchBotModel.WoSweeper : device.deviceType === 'WoSweeperMini' ? SwitchBotModel.WoSweeperMini
1943
- : SwitchBotModel.Unknown;
1829
+ accessory.context.model = device.deviceType === 'Robot Vacuum Cleaner S1'
1830
+ ? SwitchBotModel.RobotVacuumCleanerS1
1831
+ : device.deviceType === 'Robot Vacuum Cleaner S1 Plus'
1832
+ ? SwitchBotModel.RobotVacuumCleanerS1Plus
1833
+ : device.deviceType === 'Robot Vacuum Cleaner S10'
1834
+ ? SwitchBotModel.RobotVacuumCleanerS10
1835
+ : device.deviceType === 'WoSweeper'
1836
+ ? SwitchBotModel.WoSweeper
1837
+ : device.deviceType === 'WoSweeperMini'
1838
+ ? SwitchBotModel.WoSweeperMini
1839
+ : SwitchBotModel.Unknown;
1944
1840
  accessory.displayName = device.configDeviceName
1945
1841
  ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1946
1842
  : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
@@ -1965,7 +1861,7 @@ export class SwitchBotPlatform {
1965
1861
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.remoteType}`);
1966
1862
  // see if an accessory with the same uuid has already been registered and restored from
1967
1863
  // the cached devices we stored in the `configureAccessory` method above
1968
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
1864
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
1969
1865
  if (!device.hide_device && existingAccessory) {
1970
1866
  // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1971
1867
  existingAccessory.context.device = device;
@@ -1998,7 +1894,6 @@ export class SwitchBotPlatform {
1998
1894
  ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1999
1895
  : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
2000
1896
  accessory.context.connectionType = await this.connectionType(device);
2001
- accessory.context.connectionType = device.connectionType;
2002
1897
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
2003
1898
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
2004
1899
  await this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`);
@@ -2006,7 +1901,7 @@ export class SwitchBotPlatform {
2006
1901
  // this is imported from `platformAccessory.ts`
2007
1902
  new TV(this, accessory, device);
2008
1903
  await this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`);
2009
- this.externalOrPlatformIR(device, accessory);
1904
+ this.externalOrPlatform(device, accessory);
2010
1905
  this.accessories.push(accessory);
2011
1906
  }
2012
1907
  else {
@@ -2017,7 +1912,7 @@ export class SwitchBotPlatform {
2017
1912
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.remoteType}`);
2018
1913
  // see if an accessory with the same uuid has already been registered and restored from
2019
1914
  // the cached devices we stored in the `configureAccessory` method above
2020
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
1915
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
2021
1916
  if (existingAccessory) {
2022
1917
  // the accessory already exists
2023
1918
  if (!device.hide_device && device.hubDeviceId) {
@@ -2056,7 +1951,6 @@ export class SwitchBotPlatform {
2056
1951
  ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2057
1952
  : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
2058
1953
  accessory.context.connectionType = await this.connectionType(device);
2059
- accessory.context.connectionType = device.connectionType;
2060
1954
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
2061
1955
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
2062
1956
  await this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`);
@@ -2065,7 +1959,7 @@ export class SwitchBotPlatform {
2065
1959
  new IRFan(this, accessory, device);
2066
1960
  await this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`);
2067
1961
  // publish device externally or link the accessory to your platform
2068
- this.externalOrPlatformIR(device, accessory);
1962
+ this.externalOrPlatform(device, accessory);
2069
1963
  this.accessories.push(accessory);
2070
1964
  }
2071
1965
  else {
@@ -2076,7 +1970,7 @@ export class SwitchBotPlatform {
2076
1970
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.remoteType}`);
2077
1971
  // see if an accessory with the same uuid has already been registered and restored from
2078
1972
  // the cached devices we stored in the `configureAccessory` method above
2079
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
1973
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
2080
1974
  if (existingAccessory) {
2081
1975
  // the accessory already exists
2082
1976
  if (!device.hide_device && device.hubDeviceId) {
@@ -2115,7 +2009,6 @@ export class SwitchBotPlatform {
2115
2009
  ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2116
2010
  : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
2117
2011
  accessory.context.connectionType = await this.connectionType(device);
2118
- accessory.context.connectionType = device.connectionType;
2119
2012
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
2120
2013
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
2121
2014
  await this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`);
@@ -2124,7 +2017,7 @@ export class SwitchBotPlatform {
2124
2017
  new Light(this, accessory, device);
2125
2018
  await this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`);
2126
2019
  // publish device externally or link the accessory to your platform
2127
- this.externalOrPlatformIR(device, accessory);
2020
+ this.externalOrPlatform(device, accessory);
2128
2021
  this.accessories.push(accessory);
2129
2022
  }
2130
2023
  else {
@@ -2135,7 +2028,7 @@ export class SwitchBotPlatform {
2135
2028
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.remoteType}`);
2136
2029
  // see if an accessory with the same uuid has already been registered and restored from
2137
2030
  // the cached devices we stored in the `configureAccessory` method above
2138
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
2031
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
2139
2032
  if (existingAccessory) {
2140
2033
  // the accessory already exists
2141
2034
  if (!device.hide_device && device.hubDeviceId) {
@@ -2174,7 +2067,6 @@ export class SwitchBotPlatform {
2174
2067
  ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2175
2068
  : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
2176
2069
  accessory.context.connectionType = await this.connectionType(device);
2177
- accessory.context.connectionType = device.connectionType;
2178
2070
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
2179
2071
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
2180
2072
  await this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`);
@@ -2183,7 +2075,7 @@ export class SwitchBotPlatform {
2183
2075
  new AirConditioner(this, accessory, device);
2184
2076
  await this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`);
2185
2077
  // publish device externally or link the accessory to your platform
2186
- this.externalOrPlatformIR(device, accessory);
2078
+ this.externalOrPlatform(device, accessory);
2187
2079
  this.accessories.push(accessory);
2188
2080
  }
2189
2081
  else {
@@ -2194,7 +2086,7 @@ export class SwitchBotPlatform {
2194
2086
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.remoteType}`);
2195
2087
  // see if an accessory with the same uuid has already been registered and restored from
2196
2088
  // the cached devices we stored in the `configureAccessory` method above
2197
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
2089
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
2198
2090
  if (existingAccessory) {
2199
2091
  // the accessory already exists
2200
2092
  if (!device.hide_device && device.hubDeviceId) {
@@ -2233,7 +2125,6 @@ export class SwitchBotPlatform {
2233
2125
  ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2234
2126
  : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
2235
2127
  accessory.context.connectionType = await this.connectionType(device);
2236
- accessory.context.connectionType = device.connectionType;
2237
2128
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
2238
2129
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
2239
2130
  await this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`);
@@ -2242,7 +2133,7 @@ export class SwitchBotPlatform {
2242
2133
  new AirPurifier(this, accessory, device);
2243
2134
  await this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`);
2244
2135
  // publish device externally or link the accessory to your platform
2245
- this.externalOrPlatformIR(device, accessory);
2136
+ this.externalOrPlatform(device, accessory);
2246
2137
  this.accessories.push(accessory);
2247
2138
  }
2248
2139
  else {
@@ -2253,7 +2144,7 @@ export class SwitchBotPlatform {
2253
2144
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.remoteType}`);
2254
2145
  // see if an accessory with the same uuid has already been registered and restored from
2255
2146
  // the cached devices we stored in the `configureAccessory` method above
2256
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
2147
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
2257
2148
  if (existingAccessory) {
2258
2149
  // the accessory already exists
2259
2150
  if (!device.hide_device && device.hubDeviceId) {
@@ -2292,7 +2183,6 @@ export class SwitchBotPlatform {
2292
2183
  ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2293
2184
  : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
2294
2185
  accessory.context.connectionType = await this.connectionType(device);
2295
- accessory.context.connectionType = device.connectionType;
2296
2186
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
2297
2187
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
2298
2188
  await this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`);
@@ -2301,7 +2191,7 @@ export class SwitchBotPlatform {
2301
2191
  new WaterHeater(this, accessory, device);
2302
2192
  await this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`);
2303
2193
  // publish device externally or link the accessory to your platform
2304
- this.externalOrPlatformIR(device, accessory);
2194
+ this.externalOrPlatform(device, accessory);
2305
2195
  this.accessories.push(accessory);
2306
2196
  }
2307
2197
  else {
@@ -2312,7 +2202,7 @@ export class SwitchBotPlatform {
2312
2202
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.remoteType}`);
2313
2203
  // see if an accessory with the same uuid has already been registered and restored from
2314
2204
  // the cached devices we stored in the `configureAccessory` method above
2315
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
2205
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
2316
2206
  if (existingAccessory) {
2317
2207
  // the accessory already exists
2318
2208
  if (!device.hide_device && device.hubDeviceId) {
@@ -2351,7 +2241,6 @@ export class SwitchBotPlatform {
2351
2241
  ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2352
2242
  : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
2353
2243
  accessory.context.connectionType = await this.connectionType(device);
2354
- accessory.context.connectionType = device.connectionType;
2355
2244
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
2356
2245
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
2357
2246
  await this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`);
@@ -2360,7 +2249,7 @@ export class SwitchBotPlatform {
2360
2249
  new VacuumCleaner(this, accessory, device);
2361
2250
  await this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`);
2362
2251
  // publish device externally or link the accessory to your platform
2363
- this.externalOrPlatformIR(device, accessory);
2252
+ this.externalOrPlatform(device, accessory);
2364
2253
  this.accessories.push(accessory);
2365
2254
  }
2366
2255
  else {
@@ -2371,7 +2260,7 @@ export class SwitchBotPlatform {
2371
2260
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.remoteType}`);
2372
2261
  // see if an accessory with the same uuid has already been registered and restored from
2373
2262
  // the cached devices we stored in the `configureAccessory` method above
2374
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
2263
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
2375
2264
  if (existingAccessory) {
2376
2265
  // the accessory already exists
2377
2266
  if (!device.hide_device && device.hubDeviceId) {
@@ -2410,7 +2299,6 @@ export class SwitchBotPlatform {
2410
2299
  ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2411
2300
  : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
2412
2301
  accessory.context.connectionType = await this.connectionType(device);
2413
- accessory.context.connectionType = device.connectionType;
2414
2302
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
2415
2303
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
2416
2304
  await this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`);
@@ -2419,7 +2307,7 @@ export class SwitchBotPlatform {
2419
2307
  new Camera(this, accessory, device);
2420
2308
  await this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`);
2421
2309
  // publish device externally or link the accessory to your platform
2422
- this.externalOrPlatformIR(device, accessory);
2310
+ this.externalOrPlatform(device, accessory);
2423
2311
  this.accessories.push(accessory);
2424
2312
  }
2425
2313
  else {
@@ -2430,7 +2318,7 @@ export class SwitchBotPlatform {
2430
2318
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.remoteType}`);
2431
2319
  // see if an accessory with the same uuid has already been registered and restored from
2432
2320
  // the cached devices we stored in the `configureAccessory` method above
2433
- const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
2321
+ const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid);
2434
2322
  if (existingAccessory) {
2435
2323
  // the accessory already exists
2436
2324
  if (!device.hide_device && device.hubDeviceId) {
@@ -2469,7 +2357,6 @@ export class SwitchBotPlatform {
2469
2357
  ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2470
2358
  : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName);
2471
2359
  accessory.context.connectionType = await this.connectionType(device);
2472
- accessory.context.connectionType = device.connectionType;
2473
2360
  accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0';
2474
2361
  const newOrExternal = !device.external ? 'Adding new' : 'Loading external';
2475
2362
  await this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`);
@@ -2478,7 +2365,7 @@ export class SwitchBotPlatform {
2478
2365
  new Others(this, accessory, device);
2479
2366
  await this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`);
2480
2367
  // publish device externally or link the accessory to your platform
2481
- this.externalOrPlatformIR(device, accessory);
2368
+ this.externalOrPlatform(device, accessory);
2482
2369
  this.accessories.push(accessory);
2483
2370
  }
2484
2371
  else {
@@ -2486,24 +2373,13 @@ export class SwitchBotPlatform {
2486
2373
  }
2487
2374
  }
2488
2375
  async registerCurtains(device) {
2489
- /*function isCurtainDevice(device: device & devicesConfig): device is (curtain | curtain3) & devicesConfig {
2490
- return device.deviceType === 'Curtain' || device.deviceType === 'Curtain3';
2491
- }
2492
-
2493
- function isBlindTiltDevice(device: device & devicesConfig): device is blindTilt & devicesConfig {
2494
- return device.deviceType === 'Blind Tilt';
2495
- }*/
2496
2376
  let registerWindowCovering;
2497
2377
  if (isCurtainDevice(device)) {
2498
- await this.debugWarnLog(`deviceName: ${device.deviceName} deviceId: ${device.deviceId}, curtainDevicesIds: ${device.curtainDevicesIds},`
2499
- + ` master: ${device.master}, group: ${device.group}, disable_group: ${device.curtain?.disable_group},`
2500
- + ` connectionType: ${device.connectionType}`);
2378
+ await this.debugWarnLog(`deviceName: ${device.deviceName} deviceId: ${device.deviceId}, curtainDevicesIds: ${device.curtainDevicesIds},x master: ${device.master}, group: ${device.group}, disable_group: ${device.curtain?.disable_group}, connectionType: ${device.connectionType}`);
2501
2379
  registerWindowCovering = await this.registerWindowCovering(device);
2502
2380
  }
2503
2381
  else if (isBlindTiltDevice(device)) {
2504
- await this.debugWarnLog(`deviceName: ${device.deviceName} deviceId: ${device.deviceId}, blindTiltDevicesIds: ${device.blindTiltDevicesIds},`
2505
- + ` master: ${device.master}, group: ${device.group}, disable_group: ${device.curtain?.disable_group},`
2506
- + ` connectionType: ${device.connectionType}`);
2382
+ await this.debugWarnLog(`deviceName: ${device.deviceName} deviceId: ${device.deviceId}, blindTiltDevicesIds: ${device.blindTiltDevicesIds}, master: ${device.master}, group: ${device.group}, disable_group: ${device.curtain?.disable_group}, connectionType: ${device.connectionType}`);
2507
2383
  registerWindowCovering = await this.registerWindowCovering(device);
2508
2384
  }
2509
2385
  else {
@@ -2517,36 +2393,31 @@ export class SwitchBotPlatform {
2517
2393
  if (device.master && device.group) {
2518
2394
  // OpenAPI: Master Curtains/Blind Tilt in Group
2519
2395
  registerCurtain = true;
2520
- await this.debugLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] device.master: ${device.master},`
2521
- + ` device.group: ${device.group} connectionType; ${device.connectionType}`);
2396
+ await this.debugLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] device.master: ${device.master}, device.group: ${device.group} connectionType; ${device.connectionType}`);
2522
2397
  await this.debugWarnLog(`Device: ${device.deviceName} registerCurtains: ${registerCurtain}`);
2523
2398
  }
2524
2399
  else if (!device.master && device.curtain?.disable_group) {
2525
- //!device.group && device.connectionType === 'BLE'
2400
+ // !device.group && device.connectionType === 'BLE'
2526
2401
  // OpenAPI: Non-Master Curtains/Blind Tilts that has Disable Grouping Checked
2527
2402
  registerCurtain = true;
2528
- await this.debugLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] device.master: ${device.master}, disable_group: `
2529
- + `${device.curtain?.disable_group}, connectionType; ${device.connectionType}`);
2403
+ await this.debugLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] device.master: ${device.master}, disable_group: ${device.curtain?.disable_group}, connectionType; ${device.connectionType}`);
2530
2404
  await this.debugWarnLog(`Device: ${device.deviceName} registerCurtains: ${registerCurtain}`);
2531
2405
  }
2532
2406
  else if (device.master && !device.group) {
2533
2407
  // OpenAPI: Master Curtains/Blind Tilts not in Group
2534
2408
  registerCurtain = true;
2535
- await this.debugLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] device.master: ${device.master},`
2536
- + ` device.group: ${device.group} connectionType; ${device.connectionType}`);
2409
+ await this.debugLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] device.master: ${device.master}, device.group: ${device.group} connectionType; ${device.connectionType}`);
2537
2410
  await this.debugWarnLog(`Device: ${device.deviceName} registerCurtains: ${registerCurtain}`);
2538
2411
  }
2539
2412
  else if (device.connectionType === 'BLE') {
2540
2413
  // BLE: Curtains/Blind Tilt
2541
2414
  registerCurtain = true;
2542
- await this.debugLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] connectionType: ${device.connectionType}, `
2543
- + ` group: ${device.group}`);
2415
+ await this.debugLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] connectionType: ${device.connectionType}, group: ${device.group}`);
2544
2416
  await this.debugWarnLog(`Device: ${device.deviceName} registerCurtains: ${registerCurtain}`);
2545
2417
  }
2546
2418
  else {
2547
2419
  registerCurtain = false;
2548
- await this.debugErrorLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] disable_group: ${device.curtain?.disable_group},`
2549
- + ` device.master: ${device.master}, device.group: ${device.group}`);
2420
+ await this.debugErrorLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] disable_group: ${device.curtain?.disable_group}, device.master: ${device.master}, device.group: ${device.group}`);
2550
2421
  await this.debugWarnLog(`Device: ${device.deviceName} registerCurtains: ${registerCurtain}, device.connectionType: ${device.connectionType}`);
2551
2422
  }
2552
2423
  return registerCurtain;
@@ -2564,189 +2435,93 @@ export class SwitchBotPlatform {
2564
2435
  async registerDevice(device) {
2565
2436
  device.connectionType = await this.connectionType(device);
2566
2437
  let registerDevice;
2567
- if (!device.hide_device && device.connectionType === 'BLE/OpenAPI') {
2568
- switch (device.deviceType) {
2569
- case 'Curtain':
2570
- case 'Curtain3':
2571
- case 'Blind Tilt':
2572
- registerDevice = await this.registerCurtains(device);
2573
- await this.debugWarnLog(`Device: ${device.deviceName} ${device.deviceType} registerDevice: ${registerDevice}`);
2574
- break;
2575
- default:
2576
- registerDevice = true;
2577
- await this.debugWarnLog(`Device: ${device.deviceName} registerDevice: ${registerDevice}`);
2578
- }
2579
- if (registerDevice === true) {
2580
- await this.debugWarnLog(`Device: ${device.deviceName} connectionType: ${device.connectionType}, will display in HomeKit`);
2581
- }
2582
- else {
2583
- await this.debugErrorLog(`Device: ${device.deviceName} connectionType: ${device.connectionType}, will not display in HomeKit`);
2584
- }
2585
- }
2586
- else if (!device.hide_device && device.deviceId && device.configDeviceType && device.configDeviceName && device.connectionType === 'BLE') {
2587
- switch (device.deviceType) {
2588
- case 'Curtain':
2589
- case 'Curtain3':
2590
- case 'Blind Tilt':
2591
- registerDevice = await this.registerCurtains(device);
2592
- await this.debugWarnLog(`Device: ${device.deviceName} ${device.deviceType} registerDevice: ${registerDevice}`);
2593
- break;
2594
- default:
2595
- registerDevice = true;
2596
- await this.debugWarnLog(`Device: ${device.deviceName} registerDevice: ${registerDevice}`);
2597
- }
2598
- if (registerDevice === true) {
2599
- await this.debugWarnLog(`Device: ${device.deviceName} connectionType: ${device.connectionType}, will display in HomeKit`);
2600
- }
2601
- else {
2602
- await this.debugErrorLog(`Device: ${device.deviceName} connectionType: ${device.connectionType}, will not display in HomeKit`);
2603
- }
2604
- }
2605
- else if (!device.hide_device && device.connectionType === 'OpenAPI') {
2606
- switch (device.deviceType) {
2607
- case 'Curtain':
2608
- case 'Curtain3':
2609
- case 'Blind Tilt':
2610
- registerDevice = await this.registerCurtains(device);
2611
- await this.debugWarnLog(`Device: ${device.deviceName} ${device.deviceType} registerDevice: ${registerDevice}`);
2612
- break;
2613
- default:
2614
- registerDevice = true;
2615
- await this.debugWarnLog(`Device: ${device.deviceName} registerDevice: ${registerDevice}`);
2616
- }
2617
- if (registerDevice === true) {
2618
- await this.debugWarnLog(`Device: ${device.deviceName} connectionType: ${device.connectionType}, will display in HomeKit`);
2619
- }
2620
- else {
2621
- await this.debugErrorLog(`Device: ${device.deviceName} connectionType: ${device.connectionType}, will not display in HomeKit`);
2622
- }
2623
- }
2624
- else if (!device.hide_device && device.connectionType === 'Disabled') {
2625
- switch (device.deviceType) {
2626
- case 'Curtain':
2627
- case 'Curtain3':
2628
- case 'Blind Tilt':
2629
- registerDevice = await this.registerCurtains(device);
2630
- await this.debugWarnLog(`Device: ${device.deviceName} ${device.deviceType} registerDevice: ${registerDevice}`);
2631
- break;
2632
- default:
2633
- registerDevice = true;
2634
- await this.debugWarnLog(`Device: ${device.deviceName} registerDevice: ${registerDevice}`);
2635
- }
2636
- await this.debugWarnLog(`Device: ${device.deviceName} connectionType: ${device.connectionType}, will continue to display in HomeKit`);
2637
- }
2638
- else if (!device.connectionType && !device.hide_device) {
2639
- registerDevice = false;
2640
- await this.debugErrorLog(`Device: ${device.deviceName} connectionType: ${device.connectionType}, will not display in HomeKit`);
2641
- }
2642
- else if (device.hide_device) {
2643
- registerDevice = false;
2644
- await this.debugErrorLog(`Device: ${device.deviceName} hide_device: ${device.hide_device}, will not display in HomeKit`);
2438
+ const shouldRegister = !device.hide_device && (device.connectionType === 'BLE/OpenAPI' || (device.deviceId && device.configDeviceType && device.configDeviceName && device.connectionType === 'BLE') || device.connectionType === 'OpenAPI' || device.connectionType === 'Disabled');
2439
+ if (shouldRegister) {
2440
+ registerDevice = await this.handleDeviceRegistration(device);
2645
2441
  }
2646
2442
  else {
2647
2443
  registerDevice = false;
2648
- await this.debugErrorLog(`Device: ${device.deviceName} connectionType: ${device.connectionType}, hide_device: `
2649
- + `${device.hide_device}, will not display in HomeKit`);
2444
+ await this.debugErrorLog(`Device: ${device.deviceName} connectionType: ${device.connectionType}, hide_device: ${device.hide_device}, will not display in HomeKit`);
2650
2445
  }
2651
2446
  return registerDevice;
2652
2447
  }
2653
- async externalOrPlatformIR(device, accessory) {
2654
- /**
2655
- * Publish as external accessory
2656
- * Only one TV can exist per bridge, to bypass this limitation, you should
2657
- * publish your TV as an external accessory.
2658
- */
2659
- if (device.external) {
2660
- await this.debugWarnLog(`${accessory.displayName} External Accessory Mode`);
2661
- this.externalAccessory(accessory);
2448
+ async handleDeviceRegistration(device) {
2449
+ let registerDevice;
2450
+ switch (device.deviceType) {
2451
+ case 'Curtain':
2452
+ case 'Curtain3':
2453
+ case 'Blind Tilt':
2454
+ registerDevice = await this.registerCurtains(device);
2455
+ await this.debugWarnLog(`Device: ${device.deviceName} ${device.deviceType} registerDevice: ${registerDevice}`);
2456
+ break;
2457
+ default:
2458
+ registerDevice = true;
2459
+ await this.debugWarnLog(`Device: ${device.deviceName} registerDevice: ${registerDevice}`);
2460
+ }
2461
+ if (registerDevice) {
2462
+ await this.debugWarnLog(`Device: ${device.deviceName} connectionType: ${device.connectionType}, will display in HomeKit`);
2662
2463
  }
2663
2464
  else {
2664
- await this.debugLog(`${accessory.displayName} External Accessory Mode: ${device.external}`);
2665
- this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
2465
+ await this.debugErrorLog(`Device: ${device.deviceName} connectionType: ${device.connectionType}, will not display in HomeKit`);
2666
2466
  }
2467
+ return registerDevice;
2667
2468
  }
2668
2469
  async externalOrPlatform(device, accessory) {
2669
- if (device.external) {
2670
- await this.debugWarnLog(`${accessory.displayName} External Accessory Mode`);
2671
- await this.externalAccessory(accessory);
2470
+ const { displayName } = accessory;
2471
+ const isExternal = device.external ?? false;
2472
+ if (isExternal) {
2473
+ await this.debugWarnLog(`${displayName} External Accessory Mode`);
2474
+ this.api.publishExternalAccessories(PLUGIN_NAME, [accessory]);
2672
2475
  }
2673
2476
  else {
2674
- await this.debugLog(`${accessory.displayName} External Accessory Mode: ${device.external}`);
2477
+ await this.debugLog(`${displayName} External Accessory Mode: ${isExternal}`);
2675
2478
  this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
2676
2479
  }
2677
2480
  }
2678
- async externalAccessory(accessory) {
2679
- this.api.publishExternalAccessories(PLUGIN_NAME, [accessory]);
2680
- }
2681
2481
  unregisterPlatformAccessories(existingAccessory) {
2482
+ const { displayName } = existingAccessory;
2682
2483
  // remove platform accessories when no longer present
2683
2484
  this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [existingAccessory]);
2684
- this.warnLog(`Removing existing accessory from cache: ${existingAccessory.displayName}`);
2485
+ this.warnLog(`Removing existing accessory from cache: ${displayName}`);
2685
2486
  }
2487
+ /**
2488
+ * Handles the status codes returned by the device and logs appropriate messages.
2489
+ *
2490
+ * @param statusCode - The status code returned by the device.
2491
+ * @returns A promise that resolves when the logging is complete.
2492
+ */
2686
2493
  async statusCode(statusCode) {
2687
- switch (statusCode) {
2688
- case 151:
2689
- await this.errorLog(`Command not supported by this device type, statusCode: ${statusCode}, Submit Feature Request Here: ` +
2690
- 'https://tinyurl.com/SwitchBotFeatureRequest');
2691
- break;
2692
- case 152:
2693
- await this.errorLog(`Device not found, statusCode: ${statusCode}`);
2694
- break;
2695
- case 160:
2696
- await this.errorLog(`Command is not supported, statusCode: ${statusCode}, Submit Bugs Here: https://tinyurl.com/SwitchBotBug`);
2697
- break;
2698
- case 161:
2699
- await this.errorLog(`Device is offline, statusCode: ${statusCode}`);
2700
- break;
2701
- case 171:
2702
- await this.errorLog(`is offline, statusCode: ${statusCode}`);
2703
- break;
2704
- case 190:
2705
- await this.errorLog(`Requests reached the daily limit, statusCode: ${statusCode}`);
2706
- break;
2707
- case 100:
2708
- await this.debugLog(`Command successfully sent, statusCode: ${statusCode}`);
2709
- break;
2710
- case 200:
2711
- await this.debugLog(`Request successful, statusCode: ${statusCode}`);
2712
- break;
2713
- case 400:
2714
- await this.errorLog('Bad Request, The client has issued an invalid request. This is commonly used to specify validation errors in a request '
2715
- + `payload, statusCode: ${statusCode}`);
2716
- break;
2717
- case 401:
2718
- await this.errorLog('Unauthorized, Authorization for the API is required, but the request has not been authenticated, '
2719
- + `statusCode: ${statusCode}`);
2720
- break;
2721
- case 403:
2722
- await this.errorLog('Forbidden, The request has been authenticated but does not have appropriate permissions, or a requested resource is not '
2723
- + `found, statusCode: ${statusCode}`);
2724
- break;
2725
- case 404:
2726
- await this.errorLog(`Not Found, Specifies the requested path does not exist, statusCode: ${statusCode}`);
2727
- break;
2728
- case 406:
2729
- await this.errorLog('Not Acceptable, The client has requested a MIME type via the Accept header for a value not supported by the server, '
2730
- + `statusCode: ${statusCode}`);
2731
- break;
2732
- case 415:
2733
- await this.errorLog('Unsupported Media Type, The client has defined a contentType header that is not supported by the server, '
2734
- + `statusCode: ${statusCode}`);
2735
- break;
2736
- case 422:
2737
- await this.errorLog('Unprocessable Entity, The client has made a valid request, but the server cannot process it. This is often used for '
2738
- + `APIs for which certain limits have been exceeded, statusCode: ${statusCode}`);
2739
- break;
2740
- case 429:
2741
- await this.errorLog('Too Many Requests, The client has exceeded the number of requests allowed for a given time window, '
2742
- + `statusCode: ${statusCode}`);
2743
- break;
2744
- case 500:
2745
- await this.errorLog('Internal Server Error, An unexpected error on the SmartThings servers has occurred. These errors should be rare, '
2746
- + `statusCode: ${statusCode}`);
2747
- break;
2748
- default:
2749
- await this.errorLog(`Unknown statusCode, statusCode: ${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
2494
+ const messages = {
2495
+ 151: `Command not supported by this device type, statusCode: ${statusCode}, Submit Feature Request Here:
2496
+ https://tinyurl.com/SwitchBotFeatureRequest`,
2497
+ 152: `Device not found, statusCode: ${statusCode}`,
2498
+ 160: `Command is not supported, statusCode: ${statusCode}, Submit Bugs Here: https://tinyurl.com/SwitchBotBug`,
2499
+ 161: `Device is offline, statusCode: ${statusCode}`,
2500
+ 171: `is offline, statusCode: ${statusCode}`,
2501
+ 190: `Requests reached the daily limit, statusCode: ${statusCode}`,
2502
+ 100: `Command successfully sent, statusCode: ${statusCode}`,
2503
+ 200: `Request successful, statusCode: ${statusCode}`,
2504
+ 400: `Bad Request, The client has issued an invalid request. This is commonly used to specify validation errors in a request payload,
2505
+ statusCode: ${statusCode}`,
2506
+ 401: `Unauthorized, Authorization for the API is required, but the request has not been authenticated, statusCode: ${statusCode}`,
2507
+ 403: `Forbidden, The request has been authenticated but does not have appropriate permissions, or a requested resource is not found,
2508
+ statusCode: ${statusCode}`,
2509
+ 404: `Not Found, Specifies the requested path does not exist, statusCode: ${statusCode}`,
2510
+ 406: `Not Acceptable, The client has requested a MIME type via the Accept header for a value not supported by the server,
2511
+ statusCode: ${statusCode}`,
2512
+ 415: `Unsupported Media Type, The client has defined a contentType header that is not supported by the server, statusCode: ${statusCode}`,
2513
+ 422: `Unprocessable Entity, The client has made a valid request, but the server cannot process it. This is often used for APIs for which
2514
+ certain limits have been exceeded, statusCode: ${statusCode}`,
2515
+ 429: `Too Many Requests, The client has exceeded the number of requests allowed for a given time window, statusCode: ${statusCode}`,
2516
+ 500: `Internal Server Error, An unexpected error on the SmartThings servers has occurred. These errors should be rare,
2517
+ statusCode: ${statusCode}`,
2518
+ };
2519
+ const message = messages[statusCode] ?? `Unknown statusCode, statusCode: ${statusCode}, Submit Bugs Here: https://tinyurl.com/SwitchBotBug`;
2520
+ if ([100, 200].includes(statusCode)) {
2521
+ await this.debugLog(message);
2522
+ }
2523
+ else {
2524
+ await this.errorLog(message);
2750
2525
  }
2751
2526
  }
2752
2527
  async retryRequest(deviceMaxRetries, deviceDelayBetweenRetries, url, options) {
@@ -2774,57 +2549,42 @@ export class SwitchBotPlatform {
2774
2549
  }
2775
2550
  // BLE Connection
2776
2551
  async connectBLE(accessory, device) {
2777
- let switchbot;
2778
2552
  try {
2779
- const SwitchBot = (await import('node-switchbot')).SwitchBot;
2780
- queueScheduler.schedule(() => (switchbot = new SwitchBot()));
2553
+ const switchbot = new SwitchBot();
2554
+ queueScheduler.schedule(async () => switchbot);
2781
2555
  await this.debugLog(`${device.deviceType}: ${accessory.displayName} 'node-switchbot' found: ${switchbot}`);
2556
+ return switchbot;
2782
2557
  }
2783
2558
  catch (e) {
2784
- switchbot = false;
2785
- await this.errorLog(`${device.deviceType}: ${accessory.displayName} 'node-switchbot' found: ${switchbot}, Error: ${e}`);
2559
+ await this.errorLog(`${device.deviceType}: ${accessory.displayName} 'node-switchbot' not found, Error: ${e}`);
2560
+ return false;
2786
2561
  }
2787
- return switchbot;
2788
2562
  }
2789
2563
  async getVersion() {
2790
2564
  const json = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf-8'));
2791
2565
  await this.debugLog(`Plugin Version: ${json.version}`);
2792
2566
  this.version = json.version;
2567
+ return json.version;
2793
2568
  }
2794
2569
  async getPlatformConfigSettings() {
2570
+ const { options } = this.config;
2795
2571
  const platformConfig = {};
2796
- if (this.config.options) {
2797
- if (this.config.options.logging) {
2798
- platformConfig.logging = this.config.options.logging;
2799
- }
2800
- if (this.config.options.refreshRate) {
2801
- platformConfig.refreshRate = this.config.options.refreshRate;
2802
- }
2803
- if (this.config.options.updateRate) {
2804
- platformConfig.updateRate = this.config.options.updateRate;
2805
- }
2806
- if (this.config.options.pushRate) {
2807
- platformConfig.pushRate = this.config.options.pushRate;
2808
- }
2809
- if (this.config.options.maxRetries) {
2810
- this.maxRetries = this.config.options.maxRetries;
2811
- platformConfig.maxRetries = this.config.options.maxRetries;
2812
- }
2813
- else {
2814
- this.maxRetries = 3;
2815
- this.debugWarnLog('Using Default Max Retries');
2816
- platformConfig.maxRetries = this.maxRetries;
2817
- }
2818
- if (this.config.options.delayBetweenRetries) {
2819
- this.delayBetweenRetries = this.config.options.delayBetweenRetries * 1000;
2820
- platformConfig.delayBetweenRetries = this.config.options.delayBetweenRetries;
2821
- }
2822
- else {
2823
- this.delayBetweenRetries = 3000;
2824
- this.debugWarnLog('Using Default Delay Between Retries');
2825
- platformConfig.delayBetweenRetries = this.delayBetweenRetries / 1000;
2826
- }
2827
- if (Object.entries(platformConfig).length !== 0) {
2572
+ if (options) {
2573
+ platformConfig.logging = options.logging;
2574
+ platformConfig.refreshRate = options.refreshRate;
2575
+ platformConfig.updateRate = options.updateRate;
2576
+ platformConfig.pushRate = options.pushRate;
2577
+ this.maxRetries = options.maxRetries || 3;
2578
+ platformConfig.maxRetries = this.maxRetries;
2579
+ if (!options.maxRetries) {
2580
+ await this.debugWarnLog('Using Default Max Retries');
2581
+ }
2582
+ this.delayBetweenRetries = (options.delayBetweenRetries || 3) * 1000;
2583
+ platformConfig.delayBetweenRetries = this.delayBetweenRetries / 1000;
2584
+ if (!options.delayBetweenRetries) {
2585
+ await this.debugWarnLog('Using Default Delay Between Retries');
2586
+ }
2587
+ if (Object.keys(platformConfig).length) {
2828
2588
  await this.debugLog(`Platform Config: ${JSON.stringify(platformConfig)}`);
2829
2589
  }
2830
2590
  this.platformConfig = platformConfig;
@@ -2851,34 +2611,30 @@ export class SwitchBotPlatform {
2851
2611
  * @param name - The name of the characteristic.
2852
2612
  * @param value - The value to be validated and cleaned.
2853
2613
  * @returns The cleaned string value.
2854
- */
2614
+ */
2855
2615
  async validateAndCleanDisplayName(displayName, name, value) {
2856
2616
  if (this.config.options?.allowInvalidCharacters) {
2857
2617
  return value;
2858
2618
  }
2859
2619
  else {
2860
- const validPattern = new RegExp(/^[\p{L}\p{N}][\p{L}\p{N} ']*[\p{L}\p{N}]$/u);
2620
+ const validPattern = /^[\p{L}\p{N}][\p{L}\p{N} ']*[\p{L}\p{N}]$/u;
2861
2621
  const invalidCharsPattern = /[^\p{L}\p{N} ']/gu;
2862
2622
  const invalidStartEndPattern = /^[^\p{L}\p{N}]+|[^\p{L}\p{N}]+$/gu;
2863
2623
  if (typeof value === 'string' && !validPattern.test(value)) {
2864
- this.warnLog(`WARNING: The accessory '${displayName}' has an invalid '${name}' characteristic ('${value}'). Please use only alphanumeric,`
2865
- + ' space, and apostrophe characters. Ensure it starts and ends with an alphabetic or numeric character, and avoid emojis. This may'
2866
- + ' prevent the accessory from being added in the Home App or cause unresponsiveness.');
2624
+ await this.warnLog(`WARNING: The accessory '${displayName}' has an invalid '${name}' characteristic ('${value}'). Please use only alphanumeric, space, and apostrophe characters. Ensure it starts and ends with an alphabetic or numeric character, and avoid emojis. This may prevent the accessory from being added in the Home App or cause unresponsiveness.`);
2867
2625
  // Remove invalid characters
2868
2626
  if (invalidCharsPattern.test(value)) {
2869
2627
  const before = value;
2870
- this.warnLog(`Removing invalid characters from '${name}' characteristic, if you feel this is incorrect,`
2871
- + ' please enable \'allowInvalidCharacter\' in the config to allow all characters');
2628
+ await this.warnLog(`Removing invalid characters from '${name}' characteristic, if you feel this is incorrect, please enable \'allowInvalidCharacter\' in the config to allow all characters`);
2872
2629
  value = value.replace(invalidCharsPattern, '');
2873
- this.warnLog(`${name} Before: '${before}' After: '${value}'`);
2630
+ await this.warnLog(`${name} Before: '${before}' After: '${value}'`);
2874
2631
  }
2875
2632
  // Ensure it starts and ends with an alphanumeric character
2876
2633
  if (invalidStartEndPattern.test(value)) {
2877
2634
  const before = value;
2878
- this.warnLog(`Removing invalid starting or ending characters from '${name}' characteristic, if you feel this is incorrect,`
2879
- + ' please enable \'allowInvalidCharacter\' in the config to allow all characters');
2635
+ await this.warnLog(`Removing invalid starting or ending characters from '${name}' characteristic, if you feel this is incorrect, please enable \'allowInvalidCharacter\' in the config to allow all characters`);
2880
2636
  value = value.replace(invalidStartEndPattern, '');
2881
- this.warnLog(`${name} Before: '${before}' After: '${value}'`);
2637
+ await this.warnLog(`${name} Before: '${before}' After: '${value}'`);
2882
2638
  }
2883
2639
  }
2884
2640
  return value;