@switchbot/homebridge-switchbot 2.0.0-beta.3 → 2.0.0-beta.31

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 (113) hide show
  1. package/CHANGELOG.md +8 -1
  2. package/README.md +1 -2
  3. package/config.schema.json +75 -20
  4. package/dist/device/bot.d.ts +34 -28
  5. package/dist/device/bot.d.ts.map +1 -1
  6. package/dist/device/bot.js +655 -649
  7. package/dist/device/bot.js.map +1 -1
  8. package/dist/device/colorbulb.d.ts +36 -19
  9. package/dist/device/colorbulb.d.ts.map +1 -1
  10. package/dist/device/colorbulb.js +483 -309
  11. package/dist/device/colorbulb.js.map +1 -1
  12. package/dist/device/contact.d.ts +18 -8
  13. package/dist/device/contact.d.ts.map +1 -1
  14. package/dist/device/contact.js +303 -237
  15. package/dist/device/contact.js.map +1 -1
  16. package/dist/device/curtain.d.ts +23 -16
  17. package/dist/device/curtain.d.ts.map +1 -1
  18. package/dist/device/curtain.js +541 -498
  19. package/dist/device/curtain.js.map +1 -1
  20. package/dist/device/humidifier.d.ts +24 -18
  21. package/dist/device/humidifier.d.ts.map +1 -1
  22. package/dist/device/humidifier.js +450 -369
  23. package/dist/device/humidifier.js.map +1 -1
  24. package/dist/device/lock.d.ts +27 -8
  25. package/dist/device/lock.d.ts.map +1 -1
  26. package/dist/device/lock.js +302 -148
  27. package/dist/device/lock.js.map +1 -1
  28. package/dist/device/meter.d.ts +22 -16
  29. package/dist/device/meter.d.ts.map +1 -1
  30. package/dist/device/meter.js +340 -262
  31. package/dist/device/meter.js.map +1 -1
  32. package/dist/device/meterplus.d.ts +24 -12
  33. package/dist/device/meterplus.d.ts.map +1 -1
  34. package/dist/device/meterplus.js +359 -213
  35. package/dist/device/meterplus.js.map +1 -1
  36. package/dist/device/motion.d.ts +18 -8
  37. package/dist/device/motion.d.ts.map +1 -1
  38. package/dist/device/motion.js +276 -216
  39. package/dist/device/motion.js.map +1 -1
  40. package/dist/device/plug.d.ts +27 -17
  41. package/dist/device/plug.d.ts.map +1 -1
  42. package/dist/device/plug.js +292 -251
  43. package/dist/device/plug.js.map +1 -1
  44. package/dist/device/striplight.d.ts +43 -19
  45. package/dist/device/striplight.d.ts.map +1 -1
  46. package/dist/device/striplight.js +503 -262
  47. package/dist/device/striplight.js.map +1 -1
  48. package/dist/irdevice/airconditioner.d.ts +9 -12
  49. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  50. package/dist/irdevice/airconditioner.js +275 -230
  51. package/dist/irdevice/airconditioner.js.map +1 -1
  52. package/dist/irdevice/airpurifier.d.ts +5 -3
  53. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  54. package/dist/irdevice/airpurifier.js +151 -104
  55. package/dist/irdevice/airpurifier.js.map +1 -1
  56. package/dist/irdevice/camera.d.ts +11 -8
  57. package/dist/irdevice/camera.d.ts.map +1 -1
  58. package/dist/irdevice/camera.js +130 -86
  59. package/dist/irdevice/camera.js.map +1 -1
  60. package/dist/irdevice/fan.d.ts +10 -7
  61. package/dist/irdevice/fan.d.ts.map +1 -1
  62. package/dist/irdevice/fan.js +157 -109
  63. package/dist/irdevice/fan.js.map +1 -1
  64. package/dist/irdevice/light.d.ts +11 -8
  65. package/dist/irdevice/light.d.ts.map +1 -1
  66. package/dist/irdevice/light.js +134 -103
  67. package/dist/irdevice/light.js.map +1 -1
  68. package/dist/irdevice/other.d.ts +11 -8
  69. package/dist/irdevice/other.d.ts.map +1 -1
  70. package/dist/irdevice/other.js +142 -98
  71. package/dist/irdevice/other.js.map +1 -1
  72. package/dist/irdevice/tv.d.ts +12 -9
  73. package/dist/irdevice/tv.d.ts.map +1 -1
  74. package/dist/irdevice/tv.js +140 -93
  75. package/dist/irdevice/tv.js.map +1 -1
  76. package/dist/irdevice/vacuumcleaner.d.ts +9 -10
  77. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  78. package/dist/irdevice/vacuumcleaner.js +129 -89
  79. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  80. package/dist/irdevice/waterheater.d.ts +8 -9
  81. package/dist/irdevice/waterheater.d.ts.map +1 -1
  82. package/dist/irdevice/waterheater.js +129 -89
  83. package/dist/irdevice/waterheater.js.map +1 -1
  84. package/dist/platform.d.ts +14 -12
  85. package/dist/platform.d.ts.map +1 -1
  86. package/dist/platform.js +456 -434
  87. package/dist/platform.js.map +1 -1
  88. package/dist/settings.d.ts +16 -11
  89. package/dist/settings.d.ts.map +1 -1
  90. package/dist/settings.js.map +1 -1
  91. package/package.json +12 -10
  92. package/src/device/bot.ts +654 -660
  93. package/src/device/colorbulb.ts +487 -344
  94. package/src/device/contact.ts +306 -241
  95. package/src/device/curtain.ts +546 -512
  96. package/src/device/humidifier.ts +453 -403
  97. package/src/device/lock.ts +311 -149
  98. package/src/device/meter.ts +351 -275
  99. package/src/device/meterplus.ts +369 -219
  100. package/src/device/motion.ts +282 -222
  101. package/src/device/plug.ts +296 -260
  102. package/src/device/striplight.ts +519 -289
  103. package/src/irdevice/airconditioner.ts +279 -241
  104. package/src/irdevice/airpurifier.ts +148 -103
  105. package/src/irdevice/camera.ts +128 -85
  106. package/src/irdevice/fan.ts +154 -106
  107. package/src/irdevice/light.ts +132 -103
  108. package/src/irdevice/other.ts +140 -97
  109. package/src/irdevice/tv.ts +139 -93
  110. package/src/irdevice/vacuumcleaner.ts +128 -89
  111. package/src/irdevice/waterheater.ts +127 -89
  112. package/src/platform.ts +447 -457
  113. package/src/settings.ts +16 -11
package/src/platform.ts CHANGED
@@ -22,9 +22,11 @@ import https from 'https';
22
22
  import crypto from 'crypto';
23
23
  import { Buffer } from 'buffer';
24
24
  import fakegato from 'fakegato-history';
25
+ import superStringify from 'super-stringify';
25
26
  import { readFileSync, writeFileSync } from 'fs';
26
27
  import { API, DynamicPlatformPlugin, Logger, PlatformAccessory, Service, Characteristic } from 'homebridge';
27
28
  import { PLATFORM_NAME, PLUGIN_NAME, irdevice, device, SwitchBotPlatformConfig, devicesConfig, DevicePath, HostDomain } from './settings';
29
+ import { IncomingMessage } from 'http';
28
30
 
29
31
  /**
30
32
  * HomebridgePlatform
@@ -40,7 +42,6 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
40
42
 
41
43
  version = require('../package.json').version || '1.12.8'; // eslint-disable-line @typescript-eslint/no-var-requires
42
44
  deviceStatus!: any;
43
- registeringDevice!: boolean;
44
45
  debugMode!: boolean;
45
46
  platformLogging?: string;
46
47
 
@@ -48,7 +49,6 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
48
49
 
49
50
  constructor(public readonly log: Logger, public readonly config: SwitchBotPlatformConfig, public readonly api: API) {
50
51
  this.logs();
51
-
52
52
  this.debugLog('Finished initializing platform:', this.config.name);
53
53
  // only load if configured
54
54
  if (!this.config) {
@@ -65,10 +65,8 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
65
65
  this.verifyConfig();
66
66
  this.debugLog('Config OK');
67
67
  } catch (e: any) {
68
- this.errorLog(JSON.stringify(e.message));
69
- if (this.platformLogging?.includes('debug')) {
70
- this.errorLog(JSON.stringify(e));
71
- }
68
+ this.errorLog(`Verify Config, Error Message: ${e.message}`);
69
+ this.debugErrorLog(`Verify Config, Error: ${e}`);
72
70
  return;
73
71
  }
74
72
 
@@ -85,38 +83,19 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
85
83
  try {
86
84
  if (this.config.credentials?.openToken && !this.config.credentials.token) {
87
85
  await this.updateToken();
86
+ } else if (this.config.credentials?.token && !this.config.credentials?.secret) {
87
+ // eslint-disable-next-line no-useless-escape
88
+ this.errorLog('\"secret\" config is not populated, you must populate then please restart Homebridge.');
88
89
  } else {
89
90
  this.discoverDevices();
90
91
  }
91
92
  } catch (e: any) {
92
- this.errorLog('Failed to Discover Devices.', JSON.stringify(e.message));
93
- if (this.platformLogging?.includes('debug')) {
94
- this.errorLog(JSON.stringify(e));
95
- }
93
+ this.errorLog(`Failed to Discover, Error Message: ${e.message}`);
94
+ this.debugErrorLog(`Failed to Discover, Error: ${e}`);
96
95
  }
97
96
  });
98
97
  }
99
98
 
100
- logs() {
101
- this.debugMode = process.argv.includes('-D') || process.argv.includes('--debug');
102
- if (this.config.options?.logging === 'debug' || this.config.options?.logging === 'standard' || this.config.options?.logging === 'none') {
103
- this.platformLogging = this.config.options!.logging;
104
- if (this.platformLogging.includes('debug')) {
105
- this.log.warn(`Using Config Logging: ${this.platformLogging}`);
106
- }
107
- } else if (this.debugMode) {
108
- this.platformLogging = 'debugMode';
109
- if (this.platformLogging?.includes('debug')) {
110
- this.log.warn(`Using ${this.platformLogging} Logging`);
111
- }
112
- } else {
113
- this.platformLogging = 'standard';
114
- if (this.platformLogging?.includes('debug')) {
115
- this.log.warn(`Using ${this.platformLogging} Logging`);
116
- }
117
- }
118
- }
119
-
120
99
  /**
121
100
  * This function is invoked when homebridge restores cached accessories from disk at startup.
122
101
  * It should be used to setup event handlers for characteristics and update respective values.
@@ -138,14 +117,14 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
138
117
  if (this.config.options.logging) {
139
118
  platformConfig['logging'] = this.config.options.logging;
140
119
  }
141
- if (this.config.options.logging) {
120
+ if (this.config.options.logging && this.config.options.refreshRate) {
142
121
  platformConfig['refreshRate'] = this.config.options.refreshRate;
143
122
  }
144
- if (this.config.options.logging) {
123
+ if (this.config.options.logging && this.config.options.pushRate) {
145
124
  platformConfig['pushRate'] = this.config.options.pushRate;
146
125
  }
147
126
  if (Object.entries(platformConfig).length !== 0) {
148
- this.infoLog(`Platform Config: ${JSON.stringify(platformConfig)}`);
127
+ this.infoLog(`Platform Config: ${superStringify(platformConfig)}`);
149
128
  }
150
129
 
151
130
  if (this.config.options) {
@@ -156,7 +135,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
156
135
  if (!deviceConfig.deviceId) {
157
136
  throw new Error('The devices config section is missing the *Device ID* in the config. Please check your config.');
158
137
  }
159
- if (!deviceConfig.configDeviceType && deviceConfig.ble) {
138
+ if (!deviceConfig.configDeviceType && deviceConfig.connectionType) {
160
139
  throw new Error('The devices config section is missing the *Device Type* in the config. Please check your config.');
161
140
  }
162
141
  }
@@ -185,36 +164,26 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
185
164
  if (!this.config.options.refreshRate) {
186
165
  // default 120 seconds (2 minutes)
187
166
  this.config.options!.refreshRate! = 120;
188
- if (this.platformLogging?.includes('debug')) {
189
- this.debugLog('Using Default Refresh Rate (2 minutes).');
190
- }
167
+ this.debugWarnLog('Using Default Refresh Rate (2 minutes).');
168
+ }
191
169
 
192
- if (!this.config.options.pushRate) {
170
+ if (!this.config.options.pushRate) {
193
171
  // default 100 milliseconds
194
172
  this.config.options!.pushRate! = 0.1;
195
- if (this.platformLogging?.includes('debug')) {
196
- this.warnLog('Using Default Push Rate.');
197
- }
198
- }
173
+ this.debugWarnLog('Using Default Push Rate.');
174
+ }
199
175
 
200
- if (!this.config.credentials) {
201
- if (this.platformLogging?.includes('debug')) {
202
- this.debugLog('Missing Credentials');
203
- }
204
- }
176
+ if (!this.config.credentials && !this.config.options) {
177
+ this.debugWarnLog('Missing Credentials');
178
+ } else if (this.config.credentials && !this.config.credentials.notice) {
205
179
  if (!this.config.credentials?.token) {
206
- if (this.platformLogging?.includes('debug')) {
207
- this.errorLog('Missing token');
208
- this.warnLog('Cloud Enabled SwitchBot Devices & IR Devices will not work');
209
- }
180
+ this.debugErrorLog('Missing token');
181
+ this.debugWarnLog('Cloud Enabled SwitchBot Devices & IR Devices will not work');
210
182
  }
211
183
  if (this.config.credentials?.token) {
212
184
  if (!this.config.credentials?.secret) {
213
- if (this.platformLogging?.includes('debug')) {
214
- this.errorLog('Missing secret');
215
- this.warnLog('Cloud Enabled SwitchBot Devices & IR Devices will not work');
216
- }
217
- throw Error('Missing secret');
185
+ this.debugErrorLog('Missing secret');
186
+ this.debugWarnLog('Cloud Enabled SwitchBot Devices & IR Devices will not work');
218
187
  }
219
188
  }
220
189
  }
@@ -252,21 +221,27 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
252
221
  throw new Error('pluginConfig.credentials is not an object');
253
222
  }
254
223
  // Move openToken to token
255
- this.warnLog('This plugin has been updated to use OpenAPI v1.1, config is set with openToken.');
256
- this.warnLog('`openToken` config has been moved to the `token` config, Please restart Homebridge.');
224
+ if (!this.config.credentials.secret){
225
+ // eslint-disable-next-line no-useless-escape, max-len
226
+ 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' );
227
+ // eslint-disable-next-line no-useless-escape
228
+ this.errorLog('\"secret\" config is not populated, you must populate then please restart Homebridge.');
229
+ } else {
230
+ // eslint-disable-next-line no-useless-escape, max-len
231
+ 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.');
232
+ }
257
233
 
258
234
  // set the refresh token
259
235
  pluginConfig.credentials.token = this.config.credentials?.openToken;
260
236
  pluginConfig.credentials.openToken = 'Delete';
261
237
 
262
- if (this.platformLogging?.includes('debug')) {
263
- this.warnLog(`Token: ${pluginConfig.credentials.token}`);
264
- }
238
+ this.debugWarnLog(`Token: ${pluginConfig.credentials.token}`);
239
+
265
240
  // save the config, ensuring we maintain pretty json
266
241
  writeFileSync(this.api.user.configPath(), JSON.stringify(currentConfig, null, 4));
267
242
  this.verifyConfig();
268
243
  } catch (e: any) {
269
- this.errorLog(e);
244
+ this.errorLog(`Update Token: ${e}`);
270
245
  }
271
246
  }
272
247
 
@@ -295,111 +270,136 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
295
270
  'Content-Type': 'application/json',
296
271
  },
297
272
  };
298
- const req = https.request(options, (res) => {
273
+ const req = https.request(options, async (res) => {
299
274
  this.debugLog(`statusCode: ${res.statusCode}`);
300
- this.debugLog(`headers: ${JSON.stringify(res.headers)}`);
275
+ await this.statusCode({ res });
276
+ this.debugLog(`headers: ${superStringify(res.headers)}`);
301
277
  let rawData = '';
302
278
  res.on('data', (d) => {
303
279
  rawData += d;
280
+ this.deviceStatus = d;
304
281
  this.debugLog(`d: ${d}`);
305
282
  });
306
283
  res.on('end', () => {
307
284
  try {
308
285
  const devicesAPI = JSON.parse(rawData);
309
- this.debugLog(`devicesAPI: ${JSON.stringify(devicesAPI.body)}`);
286
+ this.debugLog(`devicesAPI: ${superStringify(devicesAPI.body)}`);
310
287
 
311
288
  // SwitchBot Devices
312
- if (devicesAPI.body.deviceList.length !== 0) {
289
+ /*if (devicesAPI.body.deviceList.length !== 0) {
313
290
  this.infoLog(`Total SwitchBot Devices Found: ${devicesAPI.body.deviceList.length}`);
314
291
  } else {
315
292
  this.debugLog(`Total SwitchBot Devices Found: ${devicesAPI.body.deviceList.length}`);
316
- }
317
- const deviceLists = devicesAPI.body.deviceList;
318
- if (!this.config.options?.devices) {
319
- this.debugLog(`SwitchBot Device Config Not Set: ${JSON.stringify(this.config.options?.devices)}`);
320
- const devices = deviceLists.map((v: any) => v);
321
- for (const device of devices) {
322
- if (device.deviceType) {
323
- if (device.configDeviceName) {
324
- device.deviceName = device.configDeviceName;
293
+ }*/
294
+ const deviceBodyList = devicesAPI.body.deviceList;
295
+ let deviceLists: any[];
296
+ if (deviceBodyList) {
297
+ if (deviceBodyList.length > 1) {
298
+ deviceLists = deviceBodyList;
299
+ this.infoLog(`Total SwitchBot Devices Found: ${deviceLists.length}`);
300
+ } else {
301
+ deviceLists = [deviceBodyList];
302
+ this.infoLog(`Total SwitchBot Devices Found: ${deviceLists.length}`);
303
+ }
304
+ if (!this.config.options?.devices) {
305
+ this.debugLog(`SwitchBot Device Config Not Set: ${superStringify(this.config.options?.devices)}`);
306
+ const devices = deviceLists.map((v: any) => v);
307
+ for (const device of devices) {
308
+ if (device.deviceType) {
309
+ if (device.configDeviceName) {
310
+ device.deviceName = device.configDeviceName;
311
+ }
312
+ this.createDevice(device);
325
313
  }
326
- this.createDevice(device);
327
314
  }
328
- }
329
- } else if (this.config.credentials?.token && this.config.options.devices) {
330
- this.debugLog(`SwitchBot Device Config Set: ${JSON.stringify(this.config.options?.devices)}`);
331
- const deviceConfigs = this.config.options?.devices;
332
-
333
- const mergeBydeviceId = (a1: { deviceId: string }[], a2: any[]) =>
334
- a1.map((itm: { deviceId: string }) => ({
335
- ...a2.find(
336
- (item: { deviceId: string }) =>
337
- item.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') === itm.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') && item,
338
- ),
339
- ...itm,
340
- }));
341
-
342
- const devices = mergeBydeviceId(deviceLists, deviceConfigs);
343
- this.debugLog(`SwitchBot Devices: ${JSON.stringify(devices)}`);
344
- for (const device of devices) {
345
- if (device.deviceType) {
346
- if (device.configDeviceName) {
347
- device.deviceName = device.configDeviceName;
315
+ } else if (this.config.credentials?.token && this.config.options.devices) {
316
+ this.debugLog(`SwitchBot Device Config Set: ${superStringify(this.config.options?.devices)}`);
317
+ const deviceConfigs = this.config.options?.devices;
318
+
319
+ const mergeBydeviceId = (a1: { deviceId: string }[], a2: any[]) =>
320
+ a1.map((itm: { deviceId: string }) => ({
321
+ ...a2.find(
322
+ (item: { deviceId: string }) =>
323
+ item.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') === itm.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') && item,
324
+ ),
325
+ ...itm,
326
+ }));
327
+
328
+ const devices = mergeBydeviceId(deviceLists, deviceConfigs);
329
+ this.debugLog(`SwitchBot Devices: ${superStringify(devices)}`);
330
+ for (const device of devices) {
331
+ if (device.deviceType) {
332
+ if (device.configDeviceName) {
333
+ device.deviceName = device.configDeviceName;
334
+ }
335
+ this.createDevice(device);
348
336
  }
349
- this.createDevice(device);
350
337
  }
338
+ } else {
339
+ this.errorLog('SwitchBot Token Supplied, Issue with Auth.');
351
340
  }
352
341
  } else {
353
- this.errorLog('SwitchBot Token Supplied, Issue with Auth.');
342
+ this.errorLog(`SwitchBot Device Request Issue: ${this.deviceStatus}`);
354
343
  }
355
-
356
344
  // IR Devices
357
- if (devicesAPI.body.infraredRemoteList.length !== 0) {
345
+ /*if (devicesAPI.body.infraredRemoteList.length !== 0) {
358
346
  this.infoLog(`Total IR Devices Found: ${devicesAPI.body.infraredRemoteList.length}`);
359
347
  } else {
360
348
  this.debugLog(`Total IR Devices Found: ${devicesAPI.body.infraredRemoteList.length}`);
361
- }
362
- const irDeviceLists = devicesAPI.body.infraredRemoteList;
363
- if (!this.config.options?.irdevices) {
364
- this.debugLog(`IR Device Config Not Set: ${JSON.stringify(this.config.options?.irdevices)}`);
365
- const devices = irDeviceLists.map((v: any) => v);
366
- for (const device of devices) {
367
- if (device.remoteType) {
368
- this.createIRDevice(device);
369
- }
349
+ }*/
350
+ const irDeviceBodyList = devicesAPI.body.infraredRemoteList;
351
+ let irDeviceLists: any[];
352
+ if (irDeviceBodyList) {
353
+ if (irDeviceBodyList.length > 1) {
354
+ irDeviceLists = irDeviceBodyList;
355
+ this.infoLog(`Total IR Devices Found: ${irDeviceLists.length}`);
356
+ } else {
357
+ irDeviceLists = [irDeviceBodyList];
358
+ this.infoLog(`Total IR Devices Found: ${irDeviceLists.length}`);
370
359
  }
371
- } else {
372
- this.debugLog(`IR Device Config Set: ${JSON.stringify(this.config.options?.irdevices)}`);
373
- const irDeviceConfig = this.config.options?.irdevices;
374
-
375
- const mergeIRBydeviceId = (a1: { deviceId: string }[], a2: any[]) =>
376
- a1.map((itm: { deviceId: string }) => ({
377
- ...a2.find(
378
- (item: { deviceId: string }) =>
379
- item.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') === itm.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') && item,
380
- ),
381
- ...itm,
382
- }));
383
-
384
- const devices = mergeIRBydeviceId(irDeviceLists, irDeviceConfig);
385
- this.debugLog(`IR Devices: ${JSON.stringify(devices)}`);
386
- for (const device of devices) {
387
- if (device.remoteType) {
388
- this.createIRDevice(device);
360
+ if (!this.config.options?.irdevices) {
361
+ this.debugLog(`IR Device Config Not Set: ${superStringify(this.config.options?.irdevices)}`);
362
+ const devices = irDeviceLists.map((v: any) => v);
363
+ for (const device of devices) {
364
+ if (device.remoteType) {
365
+ this.createIRDevice(device);
366
+ }
367
+ }
368
+ } else {
369
+ this.debugLog(`IR Device Config Set: ${superStringify(this.config.options?.irdevices)}`);
370
+ const irDeviceConfig = this.config.options?.irdevices;
371
+
372
+ const mergeIRBydeviceId = (a1: { deviceId: string }[], a2: any[]) =>
373
+ a1.map((itm: { deviceId: string }) => ({
374
+ ...a2.find(
375
+ (item: { deviceId: string }) =>
376
+ item.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') === itm.deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '') && item,
377
+ ),
378
+ ...itm,
379
+ }));
380
+
381
+ const devices = mergeIRBydeviceId(irDeviceLists, irDeviceConfig);
382
+ this.debugLog(`IR Devices: ${superStringify(devices)}`);
383
+ for (const device of devices) {
384
+ if (device.remoteType) {
385
+ this.createIRDevice(device);
386
+ }
389
387
  }
390
388
  }
389
+ } else {
390
+ this.errorLog(`SwitchBot IR Device Request Issue: ${this.deviceStatus}`);
391
391
  }
392
392
  } catch (e:any) {
393
- this.errorLog(e.message);
393
+ this.errorLog(`API Request: ${e}`);
394
394
  }
395
395
  });
396
396
  });
397
- req.on('error', (error) => {
398
- this.errorLog(error);
397
+ req.on('error', (e: any) => {
398
+ this.errorLog(`req: ${e}`);
399
399
  });
400
400
  req.end();
401
401
  } else if (!this.config.credentials?.token && this.config.options?.devices) {
402
- this.debugLog(`SwitchBot Device Manual Config Set: ${JSON.stringify(this.config.options?.devices)}`);
402
+ this.debugLog(`SwitchBot Device Manual Config Set: ${superStringify(this.config.options?.devices)}`);
403
403
  const deviceConfigs = this.config.options?.devices;
404
404
  const devices = deviceConfigs.map((v: any) => v);
405
405
  for (const device of devices) {
@@ -413,49 +413,8 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
413
413
  this.errorLog('Neither SwitchBot Token or Device Config are not set.');
414
414
  }
415
415
  } catch (e: any) {
416
- this.deviceError(e);
417
- }
418
- }
419
-
420
- deviceError(e: any) {
421
- if (e.message.includes('400')) {
422
- this.errorLog('Failed to Discover Devices: Bad Request');
423
- this.debugLog('The client has issued an invalid request. This is commonly used to specify validation errors in a request payload.');
424
- } else if (e.message.includes('401')) {
425
- this.errorLog('Failed to Discover Devices: Unauthorized Request');
426
- this.debugLog('Authorization for the API is required, but the request has not been authenticated.');
427
- } else if (e.message.includes('403')) {
428
- this.errorLog('Failed to Discover Devices: Forbidden Request');
429
- this.debugLog('The request has been authenticated but does not have appropriate permissions, or a requested resource is not found.');
430
- } else if (e.message.includes('404')) {
431
- this.errorLog('Failed to Discover Devices: Requst Not Found');
432
- this.debugLog('Specifies the requested path does not exist.');
433
- } else if (e.message.includes('406')) {
434
- this.errorLog('Failed to Discover Devices: Request Not Acceptable');
435
- this.debugLog('The client has requested a MIME type via the Accept header for a value not supported by the server.');
436
- } else if (e.message.includes('415')) {
437
- this.errorLog('Failed to Discover Devices: Unsupported Requst Header');
438
- this.debugLog('The client has defined a contentType header that is not supported by the server.');
439
- } else if (e.message.includes('422')) {
440
- this.errorLog('Failed to Discover Devices: Unprocessable Entity');
441
- this.debugLog(
442
- 'The client has made a valid request, but the server cannot process it.' +
443
- ' This is often used for APIs for which certain limits have been exceeded.',
444
- );
445
- } else if (e.message.includes('429')) {
446
- this.errorLog('Failed to Discover Devices: Too Many Requests');
447
- this.debugLog('The client has exceeded the number of requests allowed for a given time window.');
448
- } else if (e.message.includes('500')) {
449
- this.errorLog('Failed to Discover Devices: Internal Server Error');
450
- this.debugLog('An unexpected error on the SmartThings servers has occurred. These errors should be rare.');
451
- } else {
452
- this.errorLog('Failed to Discover Devices');
453
- }
454
- if (this.platformLogging === 'debug') {
455
- this.errorLog(`Failed to Discover Devices, Error Message: ${JSON.stringify(e.message)}`);
456
- }
457
- if (this.platformLogging === 'debugMode') {
458
- this.errorLog(`Failed to Discover Devices, Error: ${JSON.stringify(e)}`);
416
+ this.debugErrorLog(`Failed to Discover Devices, Error Message: ${superStringify(e.message)}`);
417
+ this.debugErrorLog(`Failed to Discover Devices, Error: ${e}`);
459
418
  }
460
419
  }
461
420
 
@@ -492,7 +451,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
492
451
  this.createContact(device);
493
452
  break;
494
453
  case 'Curtain':
495
- this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
454
+ this.debugLog(`Discovered ${device.deviceType} ${device.deviceName}: ${device.deviceId}`);
496
455
  this.createCurtain(device);
497
456
  break;
498
457
  case 'Plug':
@@ -514,7 +473,6 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
514
473
  this.createStripLight(device);
515
474
  break;
516
475
  case 'Indoor Cam':
517
- this.deviceInfo(device);
518
476
  this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`);
519
477
  this.warnLog(`Device: ${device.deviceName} with Device Type: ${device.deviceType}, is currently not supported.`);
520
478
  break;
@@ -522,7 +480,6 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
522
480
  this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId} is Not Supported.`);
523
481
  break;
524
482
  default:
525
- this.deviceInfo(device);
526
483
  this.warnLog(`Device: ${device.deviceName} with Device Type: ${device.deviceType}, is currently not supported.`);
527
484
  this.warnLog('Submit Feature Requests Here: https://git.io/JL14Z');
528
485
  }
@@ -585,29 +542,12 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
585
542
  this.createOthers(device);
586
543
  break;
587
544
  default:
588
- this.deviceInfo(device);
545
+ this.debugLog(`Unsupported Device: ${superStringify(device)}`);
589
546
  this.warnLog(`Device: ${device.deviceName} with Device Type: ${device.remoteType}, is currently not supported.`);
590
547
  this.warnLog('Submit Feature Requests Here: https://git.io/JL14Z');
591
548
  }
592
549
  }
593
550
 
594
- private registerDevice(device: device & devicesConfig) {
595
- if (!device.hide_device && device.enableCloudService && device.ble) {
596
- this.registeringDevice = true;
597
- this.debugLog(`Device: ${device.deviceName} Both OpenAPI and BLE Connections Enabled`);
598
- } else if (!device.hide_device && device.deviceId && device.configDeviceType && device.configDeviceName && !device.enableCloudService) {
599
- this.registeringDevice = true;
600
- this.debugLog(`Device: ${device.deviceName} BLE Connection Enabled`);
601
- } else if (!device.hide_device && device.enableCloudService && !device.ble) {
602
- this.registeringDevice = true;
603
- this.debugLog(`Device: ${device.deviceName} OpenAPI Connection Enabled`);
604
- } else {
605
- this.registeringDevice = false;
606
- this.debugLog(`Device: ${device.deviceName} OpenAPI and BLE Are Not Enabled`);
607
- }
608
- return this.registeringDevice;
609
- }
610
-
611
551
  private async createHumidifier(device: device & devicesConfig) {
612
552
  const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`);
613
553
 
@@ -617,17 +557,15 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
617
557
 
618
558
  if (existingAccessory) {
619
559
  // the accessory already exists
620
- if (this.registerDevice(device)) {
621
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
622
-
560
+ if (await this.registerDevice(device)) {
623
561
  // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
624
- //existingAccessory.context.firmwareRevision = firmware;
625
562
  existingAccessory.context.model = device.deviceType;
626
563
  existingAccessory.context.deviceID = device.deviceId;
627
- existingAccessory.displayName = device.deviceName;
564
+ existingAccessory.displayName = device.configDeviceName || device.deviceName;
628
565
  existingAccessory.context.firmwareRevision = device.firmware;
629
566
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
630
- await this.connectionTypeExistingAccessory(device, existingAccessory);
567
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
568
+ existingAccessory.context.connectionType = await this.connectionType(device);
631
569
  this.api.updatePlatformAccessories([existingAccessory]);
632
570
  // create the accessory handler for the restored accessory
633
571
  // this is imported from `platformAccessory.ts`
@@ -636,7 +574,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
636
574
  } else {
637
575
  this.unregisterPlatformAccessories(existingAccessory);
638
576
  }
639
- } else if (this.registerDevice(device)) {
577
+ } else if (await this.registerDevice(device)) {
640
578
  // the accessory does not yet exist, so we need to create it
641
579
  this.infoLog(`Adding new accessory: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
642
580
 
@@ -650,17 +588,17 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
650
588
  accessory.context.deviceID = device.deviceId;
651
589
  accessory.context.firmwareRevision = device.firmware;
652
590
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
653
- await this.connectionTypeNewAccessory(device, accessory);
591
+ accessory.context.connectionType = await this.connectionType(device);
654
592
  // create the accessory handler for the newly create accessory
655
593
  // this is imported from `platformAccessory.ts`
656
594
  new Humidifier(this, accessory, device);
657
595
  this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`);
658
596
 
659
- // link the accessory to your platform
660
- this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
597
+ // publish device externally or link the accessory to your platform
598
+ this.externalOrPlatform(device, accessory);
661
599
  this.accessories.push(accessory);
662
600
  } else {
663
- this.debugLog(`Unable to Register new device: ${device.deviceName} ${device.deviceType} - ${device.deviceId}`);
601
+ this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
664
602
  }
665
603
  }
666
604
 
@@ -673,18 +611,17 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
673
611
 
674
612
  if (existingAccessory) {
675
613
  // the accessory already exists
676
- if (this.registerDevice(device)) {
677
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
678
-
679
- this.debugLog(JSON.stringify(device.bot?.mode));
614
+ if (await this.registerDevice(device)) {
680
615
 
616
+ this.debugLog(superStringify(device.bot?.mode));
681
617
  // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
682
618
  existingAccessory.context.model = device.deviceType;
683
619
  existingAccessory.context.deviceID = device.deviceId;
684
- existingAccessory.displayName = device.deviceName;
620
+ existingAccessory.displayName = device.configDeviceName || device.deviceName;
685
621
  existingAccessory.context.firmwareRevision = device.firmware;
686
622
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
687
- await this.connectionTypeExistingAccessory(device, existingAccessory);
623
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
624
+ existingAccessory.context.connectionType = await this.connectionType(device);
688
625
  this.api.updatePlatformAccessories([existingAccessory]);
689
626
  // create the accessory handler for the restored accessory
690
627
  // this is imported from `platformAccessory.ts`
@@ -693,11 +630,11 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
693
630
  } else {
694
631
  this.unregisterPlatformAccessories(existingAccessory);
695
632
  }
696
- } else if (this.registerDevice(device)) {
633
+ } else if (await this.registerDevice(device)) {
697
634
  // the accessory does not yet exist, so we need to create it
698
635
  this.infoLog(`Adding new accessory: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
699
636
 
700
- this.debugLog(JSON.stringify(device.bot?.mode));
637
+ this.debugLog(superStringify(device.bot?.mode));
701
638
 
702
639
  // create a new accessory
703
640
  const accessory = new this.api.platformAccessory(device.deviceName, uuid);
@@ -709,18 +646,18 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
709
646
  accessory.context.deviceID = device.deviceId;
710
647
  accessory.context.firmwareRevision = device.firmware;
711
648
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
712
- await this.connectionTypeNewAccessory(device, accessory);
649
+ accessory.context.connectionType = await this.connectionType(device);
713
650
  // accessory.context.firmwareRevision = findaccessories.accessoryAttribute.softwareRevision;
714
651
  // create the accessory handler for the newly create accessory
715
652
  // this is imported from `platformAccessory.ts`
716
653
  new Bot(this, accessory, device);
717
654
  this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`);
718
655
 
719
- // link the accessory to your platform
720
- this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
656
+ // publish device externally or link the accessory to your platform
657
+ this.externalOrPlatform(device, accessory);
721
658
  this.accessories.push(accessory);
722
659
  } else {
723
- this.debugLog(`Unable to Register new device: ${device.deviceName} ${device.deviceType} - ${device.deviceId}`);
660
+ this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
724
661
  }
725
662
  }
726
663
 
@@ -733,16 +670,15 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
733
670
 
734
671
  if (existingAccessory) {
735
672
  // the accessory already exists
736
- if (this.registerDevice(device)) {
737
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
738
-
673
+ if (await this.registerDevice(device)) {
739
674
  // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
740
675
  existingAccessory.context.model = device.deviceType;
741
676
  existingAccessory.context.deviceID = device.deviceId;
742
- existingAccessory.displayName = device.deviceName;
677
+ existingAccessory.displayName = device.configDeviceName || device.deviceName;
743
678
  existingAccessory.context.firmwareRevision = device.firmware;
744
679
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
745
- await this.connectionTypeExistingAccessory(device, existingAccessory);
680
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
681
+ existingAccessory.context.connectionType = await this.connectionType(device);
746
682
  this.api.updatePlatformAccessories([existingAccessory]);
747
683
  // create the accessory handler for the restored accessory
748
684
  // this is imported from `platformAccessory.ts`
@@ -751,7 +687,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
751
687
  } else {
752
688
  this.unregisterPlatformAccessories(existingAccessory);
753
689
  }
754
- } else if (this.registerDevice(device)) {
690
+ } else if (await this.registerDevice(device)) {
755
691
  // the accessory does not yet exist, so we need to create it
756
692
  this.infoLog(`Adding new accessory: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
757
693
 
@@ -765,17 +701,17 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
765
701
  accessory.context.deviceID = device.deviceId;
766
702
  accessory.context.firmwareRevision = device.firmware;
767
703
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
768
- await this.connectionTypeNewAccessory(device, accessory);
704
+ accessory.context.connectionType = await this.connectionType(device);
769
705
  // create the accessory handler for the newly create accessory
770
706
  // this is imported from `platformAccessory.ts`
771
707
  new Meter(this, accessory, device);
772
708
  this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`);
773
709
 
774
- // link the accessory to your platform
775
- this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
710
+ // publish device externally or link the accessory to your platform
711
+ this.externalOrPlatform(device, accessory);
776
712
  this.accessories.push(accessory);
777
713
  } else {
778
- this.debugLog(`Unable to Register new device: ${device.deviceName} ${device.deviceType} - ${device.deviceId}`);
714
+ this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
779
715
  }
780
716
  }
781
717
 
@@ -788,16 +724,15 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
788
724
 
789
725
  if (existingAccessory) {
790
726
  // the accessory already exists
791
- if (this.registerDevice(device)) {
792
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
793
-
727
+ if (await this.registerDevice(device)) {
794
728
  // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
795
729
  existingAccessory.context.model = device.deviceType;
796
730
  existingAccessory.context.deviceID = device.deviceId;
797
- existingAccessory.displayName = device.deviceName;
731
+ existingAccessory.displayName = device.configDeviceName || device.deviceName;
798
732
  existingAccessory.context.firmwareRevision = device.firmware;
799
733
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
800
- await this.connectionTypeExistingAccessory(device, existingAccessory);
734
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
735
+ existingAccessory.context.connectionType = await this.connectionType(device);
801
736
  this.api.updatePlatformAccessories([existingAccessory]);
802
737
  // create the accessory handler for the restored accessory
803
738
  // this is imported from `platformAccessory.ts`
@@ -806,7 +741,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
806
741
  } else {
807
742
  this.unregisterPlatformAccessories(existingAccessory);
808
743
  }
809
- } else if (this.registerDevice(device)) {
744
+ } else if (await this.registerDevice(device)) {
810
745
  // the accessory does not yet exist, so we need to create it
811
746
  this.infoLog(`Adding new accessory: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
812
747
 
@@ -820,17 +755,17 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
820
755
  accessory.context.deviceID = device.deviceId;
821
756
  accessory.context.firmwareRevision = device.firmware;
822
757
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
823
- await this.connectionTypeNewAccessory(device, accessory);
758
+ accessory.context.connectionType = await this.connectionType(device);
824
759
  // create the accessory handler for the newly create accessory
825
760
  // this is imported from `platformAccessory.ts`
826
761
  new MeterPlus(this, accessory, device);
827
762
  this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`);
828
763
 
829
- // link the accessory to your platform
830
- this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
764
+ // publish device externally or link the accessory to your platform
765
+ this.externalOrPlatform(device, accessory);
831
766
  this.accessories.push(accessory);
832
767
  } else {
833
- this.debugLog(`Unable to Register new device: ${device.deviceName} ${device.deviceType} - ${device.deviceId}`);
768
+ this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
834
769
  }
835
770
  }
836
771
 
@@ -843,16 +778,15 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
843
778
 
844
779
  if (existingAccessory) {
845
780
  // the accessory already exists
846
- if (this.registerDevice(device)) {
847
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
848
-
781
+ if (await this.registerDevice(device)) {
849
782
  // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
850
783
  existingAccessory.context.model = device.deviceType;
851
784
  existingAccessory.context.deviceID = device.deviceId;
852
- existingAccessory.displayName = device.deviceName;
785
+ existingAccessory.displayName = device.configDeviceName || device.deviceName;
853
786
  existingAccessory.context.firmwareRevision = device.firmware;
854
787
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
855
- await this.connectionTypeExistingAccessory(device, existingAccessory);
788
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
789
+ existingAccessory.context.connectionType = await this.connectionType(device);
856
790
  this.api.updatePlatformAccessories([existingAccessory]);
857
791
  // create the accessory handler for the restored accessory
858
792
  // this is imported from `platformAccessory.ts`
@@ -861,7 +795,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
861
795
  } else {
862
796
  this.unregisterPlatformAccessories(existingAccessory);
863
797
  }
864
- } else if (this.registerDevice(device)) {
798
+ } else if (await this.registerDevice(device)) {
865
799
  // the accessory does not yet exist, so we need to create it
866
800
  this.infoLog(`Adding new accessory: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
867
801
 
@@ -875,17 +809,17 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
875
809
  accessory.context.deviceID = device.deviceId;
876
810
  accessory.context.firmwareRevision = device.firmware;
877
811
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
878
- await this.connectionTypeNewAccessory(device, accessory);
812
+ accessory.context.connectionType = await this.connectionType(device);
879
813
  // create the accessory handler for the newly create accessory
880
814
  // this is imported from `platformAccessory.ts`
881
815
  new Motion(this, accessory, device);
882
816
  this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`);
883
817
 
884
- // link the accessory to your platform
885
- this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
818
+ // publish device externally or link the accessory to your platform
819
+ this.externalOrPlatform(device, accessory);
886
820
  this.accessories.push(accessory);
887
821
  } else {
888
- this.debugLog(`Unable to Register new device: ${device.deviceName} ${device.deviceType} - ${device.deviceId}`);
822
+ this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
889
823
  }
890
824
  }
891
825
 
@@ -898,16 +832,15 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
898
832
 
899
833
  if (existingAccessory) {
900
834
  // the accessory already exists
901
- if (this.registerDevice(device)) {
902
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
903
-
835
+ if (await this.registerDevice(device)) {
904
836
  // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
905
837
  existingAccessory.context.model = device.deviceType;
906
838
  existingAccessory.context.deviceID = device.deviceId;
907
- existingAccessory.displayName = device.deviceName;
839
+ existingAccessory.displayName = device.configDeviceName || device.deviceName;
908
840
  existingAccessory.context.firmwareRevision = device.firmware;
909
841
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
910
- await this.connectionTypeExistingAccessory(device, existingAccessory);
842
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
843
+ existingAccessory.context.connectionType = await this.connectionType(device);
911
844
  this.api.updatePlatformAccessories([existingAccessory]);
912
845
  // create the accessory handler for the restored accessory
913
846
  // this is imported from `platformAccessory.ts`
@@ -916,7 +849,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
916
849
  } else {
917
850
  this.unregisterPlatformAccessories(existingAccessory);
918
851
  }
919
- } else if (this.registerDevice(device)) {
852
+ } else if (await this.registerDevice(device)) {
920
853
  // the accessory does not yet exist, so we need to create it
921
854
  this.infoLog(`Adding new accessory: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
922
855
 
@@ -930,17 +863,17 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
930
863
  accessory.context.deviceID = device.deviceId;
931
864
  accessory.context.firmwareRevision = device.firmware;
932
865
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
933
- await this.connectionTypeNewAccessory(device, accessory);
866
+ accessory.context.connectionType = await this.connectionType(device);
934
867
  // create the accessory handler for the newly create accessory
935
868
  // this is imported from `platformAccessory.ts`
936
869
  new Contact(this, accessory, device);
937
870
  this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`);
938
871
 
939
- // link the accessory to your platform
940
- this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
872
+ // publish device externally or link the accessory to your platform
873
+ this.externalOrPlatform(device, accessory);
941
874
  this.accessories.push(accessory);
942
875
  } else {
943
- this.debugLog(`Unable to Register new device: ${device.deviceName} ${device.deviceType} - ${device.deviceId}`);
876
+ this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
944
877
  }
945
878
  }
946
879
 
@@ -953,16 +886,15 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
953
886
 
954
887
  if (existingAccessory) {
955
888
  // the accessory already exists
956
- if (this.isCurtainGrouped(device)) {
957
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
958
-
889
+ if (await this.registerDevice(device)) {
959
890
  // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
960
891
  existingAccessory.context.model = device.deviceType;
961
892
  existingAccessory.context.deviceID = device.deviceId;
962
- existingAccessory.displayName = device.deviceName;
893
+ existingAccessory.displayName = device.configDeviceName || device.deviceName;
963
894
  existingAccessory.context.firmwareRevision = device.firmware;
964
895
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
965
- await this.connectionTypeExistingAccessory(device, existingAccessory);
896
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
897
+ existingAccessory.context.connectionType = await this.connectionType(device);
966
898
  this.api.updatePlatformAccessories([existingAccessory]);
967
899
  // create the accessory handler for the restored accessory
968
900
  // this is imported from `platformAccessory.ts`
@@ -971,7 +903,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
971
903
  } else {
972
904
  this.unregisterPlatformAccessories(existingAccessory);
973
905
  }
974
- } else if (this.isCurtainGrouped(device)) {
906
+ } else if (await this.registerDevice(device)) {
975
907
  // the accessory does not yet exist, so we need to create it
976
908
  this.infoLog(`Adding new accessory: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
977
909
 
@@ -980,9 +912,9 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
980
912
  , Secondary curtain automatically hidden. Main Curtain: ${device.deviceName}, DeviceID: ${device.deviceId}`);
981
913
  } else {
982
914
  if (device.master) {
983
- this.debugLog(`Main Curtain: ${device.deviceName}, DeviceID: ${device.deviceId}`);
915
+ this.warnLog(`Main Curtain: ${device.deviceName}, DeviceID: ${device.deviceId}`);
984
916
  } else {
985
- this.debugLog(`Secondary Curtain: ${device.deviceName}, DeviceID: ${device.deviceId}`);
917
+ this.errorLog(`Secondary Curtain: ${device.deviceName}, DeviceID: ${device.deviceId}`);
986
918
  }
987
919
  }
988
920
 
@@ -996,32 +928,17 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
996
928
  accessory.context.deviceID = device.deviceId;
997
929
  accessory.context.firmwareRevision = device.firmware;
998
930
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
999
- await this.connectionTypeNewAccessory(device, accessory);
931
+ accessory.context.connectionType = await this.connectionType(device);
1000
932
  // create the accessory handler for the newly create accessory
1001
933
  // this is imported from `platformAccessory.ts`
1002
934
  new Curtain(this, accessory, device);
1003
935
  this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`);
1004
936
 
1005
- // link the accessory to your platform
1006
- this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
937
+ // publish device externally or link the accessory to your platform
938
+ this.externalOrPlatform(device, accessory);
1007
939
  this.accessories.push(accessory);
1008
940
  } else {
1009
- this.debugLog(`Unable to Register new device: ${device.deviceName} ${device.deviceType} - ${device.deviceId}`);
1010
- }
1011
- }
1012
-
1013
- private isCurtainGrouped(device: device & devicesConfig) {
1014
- this.debugLog(
1015
- `deviceId: ${device.deviceId}, curtainDevicesIds: ${device.curtainDevicesIds},` +
1016
- ` master: ${device.master}, group: ${device.group}, disable_group: ${device.curtain?.disable_group}`,
1017
- );
1018
-
1019
- if (device.group && !device.curtain?.disable_group) {
1020
- this.debugLog(`[Curtain Config] disable_group: ${device.curtain?.disable_group}`);
1021
- return device.master && this.registerDevice(device);
1022
- } else {
1023
- this.debugLog(`[Curtain Config] disable_group: ${device.curtain?.disable_group}, UnGrouping ${device.master}`);
1024
- return this.registerDevice(device);
941
+ this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
1025
942
  }
1026
943
  }
1027
944
 
@@ -1034,16 +951,15 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1034
951
 
1035
952
  if (existingAccessory) {
1036
953
  // the accessory already exists
1037
- if (this.registerDevice(device)) {
1038
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1039
-
954
+ if (await this.registerDevice(device)) {
1040
955
  // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1041
956
  existingAccessory.context.model = device.deviceType;
1042
957
  existingAccessory.context.deviceID = device.deviceId;
1043
- existingAccessory.displayName = device.deviceName;
958
+ existingAccessory.displayName = device.configDeviceName || device.deviceName;
1044
959
  existingAccessory.context.firmwareRevision = device.firmware;
1045
960
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1046
- await this.connectionTypeExistingAccessory(device, existingAccessory);
961
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
962
+ existingAccessory.context.connectionType = await this.connectionType(device);
1047
963
  this.api.updatePlatformAccessories([existingAccessory]);
1048
964
  // create the accessory handler for the restored accessory
1049
965
  // this is imported from `platformAccessory.ts`
@@ -1052,7 +968,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1052
968
  } else {
1053
969
  this.unregisterPlatformAccessories(existingAccessory);
1054
970
  }
1055
- } else if (this.registerDevice(device)) {
971
+ } else if (await this.registerDevice(device)) {
1056
972
  // the accessory does not yet exist, so we need to create it
1057
973
  this.infoLog(`Adding new accessory: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
1058
974
 
@@ -1066,17 +982,17 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1066
982
  accessory.context.deviceID = device.deviceId;
1067
983
  accessory.context.firmwareRevision = device.firmware;
1068
984
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1069
- await this.connectionTypeNewAccessory(device, accessory);
985
+ accessory.context.connectionType = await this.connectionType(device);
1070
986
  // create the accessory handler for the newly create accessory
1071
987
  // this is imported from `platformAccessory.ts`
1072
988
  new Plug(this, accessory, device);
1073
989
  this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`);
1074
990
 
1075
- // link the accessory to your platform
1076
- this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
991
+ // publish device externally or link the accessory to your platform
992
+ this.externalOrPlatform(device, accessory);
1077
993
  this.accessories.push(accessory);
1078
994
  } else {
1079
- this.debugLog(`Unable to Register new device: ${device.deviceName} ${device.deviceType} - ${device.deviceId}`);
995
+ this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
1080
996
  }
1081
997
  }
1082
998
 
@@ -1089,16 +1005,15 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1089
1005
 
1090
1006
  if (existingAccessory) {
1091
1007
  // the accessory already exists
1092
- if (this.registerDevice(device)) {
1093
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1094
-
1008
+ if (await this.registerDevice(device)) {
1095
1009
  // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1096
1010
  existingAccessory.context.model = device.deviceType;
1097
1011
  existingAccessory.context.deviceID = device.deviceId;
1098
- existingAccessory.displayName = device.deviceName;
1012
+ existingAccessory.displayName = device.configDeviceName || device.deviceName;
1099
1013
  existingAccessory.context.firmwareRevision = device.firmware;
1100
1014
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1101
- await this.connectionTypeExistingAccessory(device, existingAccessory);
1015
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1016
+ existingAccessory.context.connectionType = await this.connectionType(device);
1102
1017
  this.api.updatePlatformAccessories([existingAccessory]);
1103
1018
  // create the accessory handler for the restored accessory
1104
1019
  // this is imported from `platformAccessory.ts`
@@ -1107,7 +1022,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1107
1022
  } else {
1108
1023
  this.unregisterPlatformAccessories(existingAccessory);
1109
1024
  }
1110
- } else if (this.registerDevice(device)) {
1025
+ } else if (await this.registerDevice(device)) {
1111
1026
  // the accessory does not yet exist, so we need to create it
1112
1027
  this.infoLog(`Adding new accessory: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
1113
1028
 
@@ -1121,17 +1036,17 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1121
1036
  accessory.context.deviceID = device.deviceId;
1122
1037
  accessory.context.firmwareRevision = device.firmware;
1123
1038
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1124
- await this.connectionTypeNewAccessory(device, accessory);
1039
+ accessory.context.connectionType = await this.connectionType(device);
1125
1040
  // create the accessory handler for the newly create accessory
1126
1041
  // this is imported from `platformAccessory.ts`
1127
1042
  new Lock(this, accessory, device);
1128
1043
  this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`);
1129
1044
 
1130
- // link the accessory to your platform
1131
- this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
1045
+ // publish device externally or link the accessory to your platform
1046
+ this.externalOrPlatform(device, accessory);
1132
1047
  this.accessories.push(accessory);
1133
1048
  } else {
1134
- this.debugLog(`Unable to Register new device: ${device.deviceName} ${device.deviceType} - ${device.deviceId}`);
1049
+ this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
1135
1050
  }
1136
1051
  }
1137
1052
 
@@ -1144,16 +1059,15 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1144
1059
 
1145
1060
  if (existingAccessory) {
1146
1061
  // the accessory already exists
1147
- if (this.registerDevice(device)) {
1148
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1149
-
1062
+ if (await this.registerDevice(device)) {
1150
1063
  // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1151
1064
  existingAccessory.context.model = device.deviceType;
1152
1065
  existingAccessory.context.deviceID = device.deviceId;
1153
- existingAccessory.displayName = device.deviceName;
1066
+ existingAccessory.displayName = device.configDeviceName || device.deviceName;
1154
1067
  existingAccessory.context.firmwareRevision = device.firmware;
1155
1068
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1156
- await this.connectionTypeExistingAccessory(device, existingAccessory);
1069
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1070
+ existingAccessory.context.connectionType = await this.connectionType(device);
1157
1071
  this.api.updatePlatformAccessories([existingAccessory]);
1158
1072
  // create the accessory handler for the restored accessory
1159
1073
  // this is imported from `platformAccessory.ts`
@@ -1162,7 +1076,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1162
1076
  } else {
1163
1077
  this.unregisterPlatformAccessories(existingAccessory);
1164
1078
  }
1165
- } else if (this.registerDevice(device)) {
1079
+ } else if (await this.registerDevice(device)) {
1166
1080
  // the accessory does not yet exist, so we need to create it
1167
1081
  this.infoLog(`Adding new accessory: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
1168
1082
 
@@ -1176,17 +1090,17 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1176
1090
  accessory.context.deviceID = device.deviceId;
1177
1091
  accessory.context.firmwareRevision = device.firmware;
1178
1092
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1179
- await this.connectionTypeNewAccessory(device, accessory);
1093
+ accessory.context.connectionType = await this.connectionType(device);
1180
1094
  // create the accessory handler for the newly create accessory
1181
1095
  // this is imported from `platformAccessory.ts`
1182
1096
  new ColorBulb(this, accessory, device);
1183
1097
  this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`);
1184
1098
 
1185
- // link the accessory to your platform
1186
- this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
1099
+ // publish device externally or link the accessory to your platform
1100
+ this.externalOrPlatform(device, accessory);
1187
1101
  this.accessories.push(accessory);
1188
1102
  } else {
1189
- this.debugLog(`Unable to Register new device: ${device.deviceName} ${device.deviceType} - ${device.deviceId}`);
1103
+ this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
1190
1104
  }
1191
1105
  }
1192
1106
 
@@ -1199,16 +1113,15 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1199
1113
 
1200
1114
  if (existingAccessory) {
1201
1115
  // the accessory already exists
1202
- if (this.registerDevice(device)) {
1203
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1204
-
1116
+ if (await this.registerDevice(device)) {
1205
1117
  // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1206
1118
  existingAccessory.context.model = device.deviceType;
1207
1119
  existingAccessory.context.deviceID = device.deviceId;
1208
- existingAccessory.displayName = device.deviceName;
1120
+ existingAccessory.displayName = device.configDeviceName || device.deviceName;
1209
1121
  existingAccessory.context.firmwareRevision = device.firmware;
1210
1122
  existingAccessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1211
- await this.connectionTypeExistingAccessory(device, existingAccessory);
1123
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1124
+ existingAccessory.context.connectionType = await this.connectionType(device);
1212
1125
  this.api.updatePlatformAccessories([existingAccessory]);
1213
1126
  // create the accessory handler for the restored accessory
1214
1127
  // this is imported from `platformAccessory.ts`
@@ -1217,7 +1130,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1217
1130
  } else {
1218
1131
  this.unregisterPlatformAccessories(existingAccessory);
1219
1132
  }
1220
- } else if (this.registerDevice(device)) {
1133
+ } else if (await this.registerDevice(device)) {
1221
1134
  // the accessory does not yet exist, so we need to create it
1222
1135
  this.infoLog(`Adding new accessory: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
1223
1136
 
@@ -1231,17 +1144,17 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1231
1144
  accessory.context.deviceID = device.deviceId;
1232
1145
  accessory.context.firmwareRevision = device.firmware;
1233
1146
  accessory.context.deviceType = `SwitchBot: ${device.deviceType}`;
1234
- await this.connectionTypeNewAccessory(device, accessory);
1147
+ accessory.context.connectionType = await this.connectionType(device);
1235
1148
  // create the accessory handler for the newly create accessory
1236
1149
  // this is imported from `platformAccessory.ts`
1237
1150
  new StripLight(this, accessory, device);
1238
1151
  this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`);
1239
1152
 
1240
- // link the accessory to your platform
1241
- this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
1153
+ // publish device externally or link the accessory to your platform
1154
+ this.externalOrPlatform(device, accessory);
1242
1155
  this.accessories.push(accessory);
1243
1156
  } else {
1244
- this.debugLog(`Unable to Register new device: ${device.deviceName} ${device.deviceType} - ${device.deviceId}`);
1157
+ this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} DeviceID: ${device.deviceId}`);
1245
1158
  }
1246
1159
  }
1247
1160
 
@@ -1253,15 +1166,14 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1253
1166
  const existingAccessory = this.accessories.find((accessory) => accessory.UUID === uuid);
1254
1167
 
1255
1168
  if (!device.hide_device && existingAccessory) {
1256
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1257
-
1258
1169
  // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1259
1170
  existingAccessory.context.model = device.remoteType;
1260
1171
  existingAccessory.context.deviceID = device.deviceId;
1261
- existingAccessory.displayName = device.deviceName;
1172
+ existingAccessory.displayName = device.configDeviceName || device.deviceName;
1262
1173
  existingAccessory.context.firmwareRevision = device.firmware;
1263
1174
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1264
- await this.connectionTypeExistingIRAccessory(existingAccessory);
1175
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1176
+ existingAccessory.context.connectionType = await this.connectionType(device);
1265
1177
  this.api.updatePlatformAccessories([existingAccessory]);
1266
1178
  // create the accessory handler for the restored accessory
1267
1179
  // this is imported from `platformAccessory.ts`
@@ -1281,7 +1193,7 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1281
1193
  accessory.context.deviceID = device.deviceId;
1282
1194
  accessory.context.firmwareRevision = device.firmware;
1283
1195
  accessory.context.deviceType = `IR: ${device.remoteType}`;
1284
- await this.connectionTypeNewIRAccessory(accessory);
1196
+ accessory.context.connectionType = await this.connectionType(device);
1285
1197
  // create the accessory handler for the newly create accessory
1286
1198
  // this is imported from `platformAccessory.ts`
1287
1199
  new TV(this, accessory, device);
@@ -1292,10 +1204,10 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1292
1204
  * Only one TV can exist per bridge, to bypass this limitation, you should
1293
1205
  * publish your TV as an external accessory.
1294
1206
  */
1295
- this.api.publishExternalAccessories(PLUGIN_NAME, [accessory]);
1207
+ this.externalAccessory(accessory);
1296
1208
  this.accessories.push(accessory);
1297
1209
  } else {
1298
- this.debugLog(`Unable to Register new device: ${device.deviceName} ${device.remoteType} - ${device.deviceId}`);
1210
+ this.debugLog(`Device not registered: ${device.deviceName} ${device.remoteType} DeviceID: ${device.deviceId}`);
1299
1211
  }
1300
1212
  }
1301
1213
 
@@ -1309,16 +1221,14 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1309
1221
  if (existingAccessory) {
1310
1222
  // the accessory already exists
1311
1223
  if (!device.hide_device && device.hubDeviceId) {
1312
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1313
-
1314
1224
  // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1315
-
1316
1225
  existingAccessory.context.model = device.remoteType;
1317
1226
  existingAccessory.context.deviceID = device.deviceId;
1318
- existingAccessory.displayName = device.deviceName;
1227
+ existingAccessory.displayName = device.configDeviceName || device.deviceName;
1319
1228
  existingAccessory.context.firmwareRevision = device.firmware;
1320
1229
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1321
- await this.connectionTypeExistingIRAccessory(existingAccessory);
1230
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1231
+ existingAccessory.context.connectionType = await this.connectionType(device);
1322
1232
  this.api.updatePlatformAccessories([existingAccessory]);
1323
1233
  // create the accessory handler for the restored accessory
1324
1234
  // this is imported from `platformAccessory.ts`
@@ -1341,17 +1251,17 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1341
1251
  accessory.context.deviceID = device.deviceId;
1342
1252
  accessory.context.firmwareRevision = device.firmware;
1343
1253
  accessory.context.deviceType = `IR: ${device.remoteType}`;
1344
- await this.connectionTypeNewIRAccessory(accessory);
1254
+ accessory.context.connectionType = await this.connectionType(device);
1345
1255
  // create the accessory handler for the newly create accessory
1346
1256
  // this is imported from `platformAccessory.ts`
1347
1257
  new Fan(this, accessory, device);
1348
1258
  this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`);
1349
1259
 
1350
- // link the accessory to your platform
1351
- this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
1260
+ // publish device externally or link the accessory to your platform
1261
+ this.externalOrPlatform(device, accessory);
1352
1262
  this.accessories.push(accessory);
1353
1263
  } else {
1354
- this.debugLog(`Unable to Register new device: ${device.deviceName} ${device.remoteType} - ${device.deviceId}`);
1264
+ this.debugLog(`Device not registered: ${device.deviceName} ${device.remoteType} DeviceID: ${device.deviceId}`);
1355
1265
  }
1356
1266
  }
1357
1267
 
@@ -1365,15 +1275,14 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1365
1275
  if (existingAccessory) {
1366
1276
  // the accessory already exists
1367
1277
  if (!device.hide_device && device.hubDeviceId) {
1368
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1369
-
1370
1278
  // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1371
1279
  existingAccessory.context.model = device.remoteType;
1372
1280
  existingAccessory.context.deviceID = device.deviceId;
1373
- existingAccessory.displayName = device.deviceName;
1281
+ existingAccessory.displayName = device.configDeviceName || device.deviceName;
1374
1282
  existingAccessory.context.firmwareRevision = device.firmware;
1375
1283
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1376
- await this.connectionTypeExistingIRAccessory(existingAccessory);
1284
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1285
+ existingAccessory.context.connectionType = await this.connectionType(device);
1377
1286
  this.api.updatePlatformAccessories([existingAccessory]);
1378
1287
  // create the accessory handler for the restored accessory
1379
1288
  // this is imported from `platformAccessory.ts`
@@ -1396,17 +1305,17 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1396
1305
  accessory.context.deviceID = device.deviceId;
1397
1306
  accessory.context.firmwareRevision = device.firmware;
1398
1307
  accessory.context.deviceType = `IR: ${device.remoteType}`;
1399
- await this.connectionTypeNewIRAccessory(accessory);
1308
+ accessory.context.connectionType = await this.connectionType(device);
1400
1309
  // create the accessory handler for the newly create accessory
1401
1310
  // this is imported from `platformAccessory.ts`
1402
1311
  new Light(this, accessory, device);
1403
1312
  this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`);
1404
1313
 
1405
- // link the accessory to your platform
1406
- this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
1314
+ // publish device externally or link the accessory to your platform
1315
+ this.externalOrPlatform(device, accessory);
1407
1316
  this.accessories.push(accessory);
1408
1317
  } else {
1409
- this.debugLog(`Unable to Register new device: ${device.deviceName} ${device.remoteType} - ${device.deviceId}`);
1318
+ this.debugLog(`Device not registered: ${device.deviceName} ${device.remoteType} DeviceID: ${device.deviceId}`);
1410
1319
  }
1411
1320
  }
1412
1321
 
@@ -1420,15 +1329,14 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1420
1329
  if (existingAccessory) {
1421
1330
  // the accessory already exists
1422
1331
  if (!device.hide_device && device.hubDeviceId) {
1423
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1424
-
1425
1332
  // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1426
1333
  existingAccessory.context.model = device.remoteType;
1427
1334
  existingAccessory.context.deviceID = device.deviceId;
1428
- existingAccessory.displayName = device.deviceName;
1335
+ existingAccessory.displayName = device.configDeviceName || device.deviceName;
1429
1336
  existingAccessory.context.firmwareRevision = device.firmware;
1430
1337
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1431
- await this.connectionTypeExistingIRAccessory(existingAccessory);
1338
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1339
+ existingAccessory.context.connectionType = await this.connectionType(device);
1432
1340
  this.api.updatePlatformAccessories([existingAccessory]);
1433
1341
  // create the accessory handler for the restored accessory
1434
1342
  // this is imported from `platformAccessory.ts`
@@ -1451,17 +1359,17 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1451
1359
  accessory.context.deviceID = device.deviceId;
1452
1360
  accessory.context.firmwareRevision = device.firmware;
1453
1361
  accessory.context.deviceType = `IR: ${device.remoteType}`;
1454
- await this.connectionTypeNewIRAccessory(accessory);
1362
+ accessory.context.connectionType = await this.connectionType(device);
1455
1363
  // create the accessory handler for the newly create accessory
1456
1364
  // this is imported from `platformAccessory.ts`
1457
1365
  new AirConditioner(this, accessory, device);
1458
1366
  this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`);
1459
1367
 
1460
- // link the accessory to your platform
1461
- this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
1368
+ // publish device externally or link the accessory to your platform
1369
+ this.externalOrPlatform(device, accessory);
1462
1370
  this.accessories.push(accessory);
1463
1371
  } else {
1464
- this.debugLog(`Unable to Register new device: ${device.deviceName} ${device.remoteType} - ${device.deviceId}`);
1372
+ this.debugLog(`Device not registered: ${device.deviceName} ${device.remoteType} DeviceID: ${device.deviceId}`);
1465
1373
  }
1466
1374
  }
1467
1375
 
@@ -1475,15 +1383,14 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1475
1383
  if (existingAccessory) {
1476
1384
  // the accessory already exists
1477
1385
  if (!device.hide_device && device.hubDeviceId) {
1478
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1479
-
1480
1386
  // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1481
1387
  existingAccessory.context.model = device.remoteType;
1482
1388
  existingAccessory.context.deviceID = device.deviceId;
1483
- existingAccessory.displayName = device.deviceName;
1389
+ existingAccessory.displayName = device.configDeviceName || device.deviceName;
1484
1390
  existingAccessory.context.firmwareRevision = device.firmware;
1485
1391
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1486
- await this.connectionTypeExistingIRAccessory(existingAccessory);
1392
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1393
+ existingAccessory.context.connectionType = await this.connectionType(device);
1487
1394
  this.api.updatePlatformAccessories([existingAccessory]);
1488
1395
  // create the accessory handler for the restored accessory
1489
1396
  // this is imported from `platformAccessory.ts`
@@ -1506,17 +1413,17 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1506
1413
  accessory.context.deviceID = device.deviceId;
1507
1414
  accessory.context.firmwareRevision = device.firmware;
1508
1415
  accessory.context.deviceType = `IR: ${device.remoteType}`;
1509
- await this.connectionTypeNewIRAccessory(accessory);
1416
+ accessory.context.connectionType = await this.connectionType(device);
1510
1417
  // create the accessory handler for the newly create accessory
1511
1418
  // this is imported from `platformAccessory.ts`
1512
1419
  new AirPurifier(this, accessory, device);
1513
1420
  this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`);
1514
1421
 
1515
- // link the accessory to your platform
1516
- this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
1422
+ // publish device externally or link the accessory to your platform
1423
+ this.externalOrPlatform(device, accessory);
1517
1424
  this.accessories.push(accessory);
1518
1425
  } else {
1519
- this.debugLog(`Unable to Register new device: ${device.deviceName} ${device.remoteType} - ${device.deviceId}`);
1426
+ this.debugLog(`Device not registered: ${device.deviceName} ${device.remoteType} DeviceID: ${device.deviceId}`);
1520
1427
  }
1521
1428
  }
1522
1429
 
@@ -1530,15 +1437,14 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1530
1437
  if (existingAccessory) {
1531
1438
  // the accessory already exists
1532
1439
  if (!device.hide_device && device.hubDeviceId) {
1533
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1534
-
1535
1440
  // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1536
1441
  existingAccessory.context.model = device.remoteType;
1537
1442
  existingAccessory.context.deviceID = device.deviceId;
1538
- existingAccessory.displayName = device.deviceName;
1443
+ existingAccessory.displayName = device.configDeviceName || device.deviceName;
1539
1444
  existingAccessory.context.firmwareRevision = device.firmware;
1540
1445
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1541
- await this.connectionTypeExistingIRAccessory(existingAccessory);
1446
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1447
+ existingAccessory.context.connectionType = await this.connectionType(device);
1542
1448
  this.api.updatePlatformAccessories([existingAccessory]);
1543
1449
  // create the accessory handler for the restored accessory
1544
1450
  // this is imported from `platformAccessory.ts`
@@ -1561,17 +1467,17 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1561
1467
  accessory.context.deviceID = device.deviceId;
1562
1468
  accessory.context.firmwareRevision = device.firmware;
1563
1469
  accessory.context.deviceType = `IR: ${device.remoteType}`;
1564
- await this.connectionTypeNewIRAccessory(accessory);
1470
+ accessory.context.connectionType = await this.connectionType(device);
1565
1471
  // create the accessory handler for the newly create accessory
1566
1472
  // this is imported from `platformAccessory.ts`
1567
1473
  new WaterHeater(this, accessory, device);
1568
1474
  this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`);
1569
1475
 
1570
- // link the accessory to your platform
1571
- this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
1476
+ // publish device externally or link the accessory to your platform
1477
+ this.externalOrPlatform(device, accessory);
1572
1478
  this.accessories.push(accessory);
1573
1479
  } else {
1574
- this.debugLog(`Unable to Register new device: ${device.deviceName} ${device.remoteType} - ${device.deviceId}`);
1480
+ this.debugLog(`Device not registered: ${device.deviceName} ${device.remoteType} DeviceID: ${device.deviceId}`);
1575
1481
  }
1576
1482
  }
1577
1483
 
@@ -1585,15 +1491,14 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1585
1491
  if (existingAccessory) {
1586
1492
  // the accessory already exists
1587
1493
  if (!device.hide_device && device.hubDeviceId) {
1588
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1589
-
1590
1494
  // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1591
1495
  existingAccessory.context.model = device.remoteType;
1592
1496
  existingAccessory.context.deviceID = device.deviceId;
1593
- existingAccessory.displayName = device.deviceName;
1497
+ existingAccessory.displayName = device.configDeviceName || device.deviceName;
1594
1498
  existingAccessory.context.firmwareRevision = device.firmware;
1595
1499
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1596
- await this.connectionTypeExistingIRAccessory(existingAccessory);
1500
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1501
+ existingAccessory.context.connectionType = await this.connectionType(device);
1597
1502
  this.api.updatePlatformAccessories([existingAccessory]);
1598
1503
  // create the accessory handler for the restored accessory
1599
1504
  // this is imported from `platformAccessory.ts`
@@ -1616,17 +1521,17 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1616
1521
  accessory.context.deviceID = device.deviceId;
1617
1522
  accessory.context.firmwareRevision = device.firmware;
1618
1523
  accessory.context.deviceType = `IR: ${device.remoteType}`;
1619
- await this.connectionTypeNewIRAccessory(accessory);
1524
+ accessory.context.connectionType = await this.connectionType(device);
1620
1525
  // create the accessory handler for the newly create accessory
1621
1526
  // this is imported from `platformAccessory.ts`
1622
1527
  new VacuumCleaner(this, accessory, device);
1623
1528
  this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`);
1624
1529
 
1625
- // link the accessory to your platform
1626
- this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
1530
+ // publish device externally or link the accessory to your platform
1531
+ this.externalOrPlatform(device, accessory);
1627
1532
  this.accessories.push(accessory);
1628
1533
  } else {
1629
- this.debugLog(`Unable to Register new device: ${device.deviceName} ${device.remoteType} - ${device.deviceId}`);
1534
+ this.debugLog(`Device not registered: ${device.deviceName} ${device.remoteType} DeviceID: ${device.deviceId}`);
1630
1535
  }
1631
1536
  }
1632
1537
 
@@ -1640,15 +1545,14 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1640
1545
  if (existingAccessory) {
1641
1546
  // the accessory already exists
1642
1547
  if (!device.hide_device && device.hubDeviceId) {
1643
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1644
-
1645
1548
  // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1646
1549
  existingAccessory.context.model = device.remoteType;
1647
1550
  existingAccessory.context.deviceID = device.deviceId;
1648
- existingAccessory.displayName = device.deviceName;
1551
+ existingAccessory.displayName = device.configDeviceName || device.deviceName;
1649
1552
  existingAccessory.context.firmwareRevision = device.firmware;
1650
1553
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1651
- await this.connectionTypeExistingIRAccessory(existingAccessory);
1554
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1555
+ existingAccessory.context.connectionType = await this.connectionType(device);
1652
1556
  this.api.updatePlatformAccessories([existingAccessory]);
1653
1557
  // create the accessory handler for the restored accessory
1654
1558
  // this is imported from `platformAccessory.ts`
@@ -1671,17 +1575,17 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1671
1575
  accessory.context.deviceID = device.deviceId;
1672
1576
  accessory.context.firmwareRevision = device.firmware;
1673
1577
  accessory.context.deviceType = `IR: ${device.remoteType}`;
1674
- await this.connectionTypeNewIRAccessory(accessory);
1578
+ accessory.context.connectionType = await this.connectionType(device);
1675
1579
  // create the accessory handler for the newly create accessory
1676
1580
  // this is imported from `platformAccessory.ts`
1677
1581
  new Camera(this, accessory, device);
1678
1582
  this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`);
1679
1583
 
1680
- // link the accessory to your platform
1681
- this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
1584
+ // publish device externally or link the accessory to your platform
1585
+ this.externalOrPlatform(device, accessory);
1682
1586
  this.accessories.push(accessory);
1683
1587
  } else {
1684
- this.debugLog(`Unable to Register new device: ${device.deviceName} ${device.remoteType} - ${device.deviceId}`);
1588
+ this.debugLog(`Device not registered: ${device.deviceName} ${device.remoteType} DeviceID: ${device.deviceId}`);
1685
1589
  }
1686
1590
  }
1687
1591
 
@@ -1695,15 +1599,14 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1695
1599
  if (existingAccessory) {
1696
1600
  // the accessory already exists
1697
1601
  if (!device.hide_device && device.hubDeviceId) {
1698
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1699
-
1700
1602
  // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1701
1603
  existingAccessory.context.model = device.remoteType;
1702
1604
  existingAccessory.context.deviceID = device.deviceId;
1703
- existingAccessory.displayName = device.deviceName;
1605
+ existingAccessory.displayName = device.configDeviceName || device.deviceName;
1704
1606
  existingAccessory.context.firmwareRevision = device.firmware;
1705
1607
  existingAccessory.context.deviceType = `IR: ${device.remoteType}`;
1706
- await this.connectionTypeExistingIRAccessory(existingAccessory);
1608
+ this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} DeviceID: ${device.deviceId}`);
1609
+ existingAccessory.context.connectionType = await this.connectionType(device);
1707
1610
  this.api.updatePlatformAccessories([existingAccessory]);
1708
1611
  // create the accessory handler for the restored accessory
1709
1612
  // this is imported from `platformAccessory.ts`
@@ -1726,42 +1629,117 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1726
1629
  accessory.context.deviceID = device.deviceId;
1727
1630
  accessory.context.firmwareRevision = device.firmware;
1728
1631
  accessory.context.deviceType = `IR: ${device.remoteType}`;
1729
- await this.connectionTypeNewIRAccessory(accessory);
1632
+ accessory.context.connectionType = await this.connectionType(device);
1730
1633
  // create the accessory handler for the newly create accessory
1731
1634
  // this is imported from `platformAccessory.ts`
1732
1635
  new Others(this, accessory, device);
1733
1636
  this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`);
1734
1637
 
1735
- // link the accessory to your platform
1736
- this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
1638
+ // publish device externally or link the accessory to your platform
1639
+ this.externalOrPlatform(device, accessory);
1737
1640
  this.accessories.push(accessory);
1738
1641
  } else {
1739
- this.debugLog(`Unable to Register new device: ${device.deviceName} ${device.remoteType} - ${device.deviceId}`);
1642
+ this.debugLog(`Device not registered: ${device.deviceName} ${device.remoteType} DeviceID: ${device.deviceId}`);
1740
1643
  }
1741
1644
  }
1742
1645
 
1743
- public async connectionTypeNewAccessory(device: device & devicesConfig, accessory: PlatformAccessory) {
1744
- if (device.ble) {
1745
- accessory.context.connectionType = 'BLE';
1646
+ async registerCurtains(device: device & devicesConfig) {
1647
+ this.warnLog(`deviceName: ${device.deviceName} deviceId: ${device.deviceId}, curtainDevicesIds: ${device.curtainDevicesIds}, master: ` +
1648
+ `${device.master}, group: ${device.group}, disable_group: ${device.curtain?.disable_group}, connectionType: ${device.connectionType}`);
1649
+
1650
+ let registerCurtain: boolean;
1651
+ if (device.group && !device.curtain?.disable_group) {
1652
+ registerCurtain = true;
1653
+ this.debugLog(`deviceName: ${device.deviceName} [Curtain Config] disable_group: ${device.curtain?.disable_group}`);
1654
+ this.debugWarnLog(`Device: ${device.deviceName} registerCurtains: ${registerCurtain}`);
1655
+ } else if (device.connectionType?.includes('BLE') || device.connectionType === 'Disabled') {
1656
+ registerCurtain = true;
1657
+ this.debugLog(`deviceName: ${device.deviceName} [Curtain Config] connectionType: ${device.connectionType}`);
1658
+ this.debugWarnLog(`Device: ${device.deviceName} registerCurtains: ${registerCurtain}`);
1746
1659
  } else {
1747
- accessory.context.connectionType = 'OpenAPI';
1660
+ registerCurtain = false;
1661
+ this.errorLog(`deviceName: ${device.deviceName} [Curtain Config] disable_group: ${device.curtain?.disable_group}, UnGrouping ${device.master}`);
1662
+ this.debugWarnLog(`Device: ${device.deviceName} registerCurtains: ${registerCurtain}`);
1748
1663
  }
1664
+ return registerCurtain;
1749
1665
  }
1750
1666
 
1751
- public async connectionTypeExistingAccessory(device: device & devicesConfig, existingAccessory: PlatformAccessory) {
1752
- if (device.ble) {
1753
- existingAccessory.context.connectionType = 'BLE';
1667
+ async connectionType(device: device & devicesConfig): Promise<any> {
1668
+ let connectionType: string;
1669
+ if (!device.connectionType && this.config.credentials?.token && this.config.credentials.secret) {
1670
+ connectionType = 'OpenAPI';
1754
1671
  } else {
1755
- existingAccessory.context.connectionType = 'OpenAPI';
1672
+ connectionType = device.connectionType!;
1756
1673
  }
1674
+ return connectionType;
1757
1675
  }
1758
1676
 
1759
- public async connectionTypeNewIRAccessory(accessory: PlatformAccessory) {
1760
- accessory.context.connectionType = 'IR wirth OpenAPI';
1677
+ async registerDevice(device: device & devicesConfig) {
1678
+ device.connectionType = await this.connectionType(device);
1679
+ let registerDevice: boolean;
1680
+ if (!device.hide_device && device.enableCloudService && device.connectionType === 'BLE/OpenAPI') {
1681
+ if (device.deviceType === 'Curtain') {
1682
+ registerDevice = await this.registerCurtains(device);
1683
+ this.debugWarnLog(`Device: ${device.deviceName} Curtain registerDevice: ${registerDevice}`);
1684
+ } else {
1685
+ registerDevice = true;
1686
+ this.debugWarnLog(`Device: ${device.deviceName} registerDevice: ${registerDevice}`);
1687
+ }
1688
+ this.debugWarnLog(`Device: ${device.deviceName} connectionType: ${device.connectionType}, will display in HomeKit`);
1689
+ } else if (!device.hide_device && device.deviceId && device.configDeviceType && device.configDeviceName
1690
+ && device.connectionType === 'BLE') {
1691
+ if (device.deviceType === 'Curtain') {
1692
+ registerDevice = await this.registerCurtains(device);
1693
+ this.debugWarnLog(`Device: ${device.deviceName} Curtain registerDevice: ${registerDevice}`);
1694
+ } else {
1695
+ registerDevice = true;
1696
+ this.debugWarnLog(`Device: ${device.deviceName} registerDevice: ${registerDevice}`);
1697
+ }
1698
+ this.debugWarnLog(`Device: ${device.deviceName} connectionType: ${device.connectionType}, will display in HomeKit`);
1699
+ } else if (!device.hide_device && device.enableCloudService && device.connectionType === 'OpenAPI') {
1700
+ if (device.deviceType === 'Curtain') {
1701
+ registerDevice = await this.registerCurtains(device);
1702
+ this.debugWarnLog(`Device: ${device.deviceName} Curtain registerDevice: ${registerDevice}`);
1703
+ } else {
1704
+ registerDevice = true;
1705
+ this.debugWarnLog(`Device: ${device.deviceName} registerDevice: ${registerDevice}`);
1706
+ }
1707
+ this.debugWarnLog(`Device: ${device.deviceName} connectionType: ${device.connectionType}, will display in HomeKit`);
1708
+ } else if (!device.hide_device && device.connectionType === 'Disabled') {
1709
+ if (device.deviceType === 'Curtain') {
1710
+ registerDevice = await this.registerCurtains(device);
1711
+ this.debugWarnLog(`Device: ${device.deviceName} Curtain registerDevice: ${registerDevice}`);
1712
+ } else {
1713
+ registerDevice = true;
1714
+ this.debugWarnLog(`Device: ${device.deviceName} registerDevice: ${registerDevice}`);
1715
+ }
1716
+ this.debugWarnLog(`Device: ${device.deviceName} connectionType: ${device.connectionType}, will continue to display in HomeKit`);
1717
+ } else if (!device.connectionType && !device.hide_device) {
1718
+ registerDevice = false;
1719
+ this.debugErrorLog(`Device: ${device.deviceName} connectionType: ${device.connectionType}, will not display in HomeKit`);
1720
+ } else if (device.hide_device){
1721
+ registerDevice = false;
1722
+ this.debugErrorLog(`Device: ${device.deviceName} hide_device: ${device.hide_device}, will not display in HomeKit`);
1723
+ } else {
1724
+ registerDevice = false;
1725
+ this.debugErrorLog(`Device: ${device.deviceName} connectionType: ${device.connectionType}, hide_device: `
1726
+ + `${device.hide_device}, will not display in HomeKit`);
1727
+ }
1728
+ return registerDevice;
1761
1729
  }
1762
1730
 
1763
- public async connectionTypeExistingIRAccessory(existingAccessory: PlatformAccessory) {
1764
- existingAccessory.context.connectionType = 'IR with OpenAPI';
1731
+ public async externalOrPlatform(device: device & devicesConfig, accessory: PlatformAccessory) {
1732
+ this.debugLog(`${accessory.displayName} External Accessory Mode: ${device.external}`);
1733
+ if (device.external) {
1734
+ this.warnLog(`${accessory.displayName} External Accessory Mode`);
1735
+ this.externalAccessory(accessory);
1736
+ } else {
1737
+ this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]);
1738
+ }
1739
+ }
1740
+
1741
+ public async externalAccessory(accessory: PlatformAccessory) {
1742
+ this.api.publishExternalAccessories(PLUGIN_NAME, [accessory]);
1765
1743
  }
1766
1744
 
1767
1745
  public unregisterPlatformAccessories(existingAccessory: PlatformAccessory) {
@@ -1770,53 +1748,35 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1770
1748
  this.warnLog(`Removing existing accessory from cache: ${existingAccessory.displayName}`);
1771
1749
  }
1772
1750
 
1773
- public deviceListInfo(devices) {
1774
- if (this.platformLogging?.includes('debug')) {
1775
- this.warnLog(`deviceListInfoStatus: ${JSON.stringify(devices)}`);
1776
- }
1777
- }
1778
-
1779
- public async deviceInfo(device: (irdevice & devicesConfig) | (device & devicesConfig)) {
1780
- if (this.platformLogging?.includes('debug')) {
1781
- this.warnLog(JSON.stringify(device));
1782
-
1783
- const t = Date.now();
1784
- const nonce = 'requestID';
1785
- const data = this.config.credentials?.token + t + nonce;
1786
- const signTerm = crypto.createHmac('sha256', this.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
1787
- const sign = signTerm.toString('base64');
1788
- this.debugLog(sign);
1789
- const options = {
1790
- hostname: HostDomain,
1791
- port: 443,
1792
- path: `${DevicePath}/${device.deviceId}/status`,
1793
- method: 'GET',
1794
- headers: {
1795
- Authorization: this.config.credentials?.token,
1796
- sign: sign,
1797
- nonce: nonce,
1798
- t: t,
1799
- 'Content-Type': 'application/json',
1800
- },
1801
- };
1802
- const req = https.request(options, (res) => {
1803
- this.debugLog(`statusCode: ${res.statusCode}`);
1804
- res.on('data', (d) => {
1805
- process.stdout.write(d);
1806
- });
1807
- });
1808
- req.on('error', (error) => {
1809
- this.errorLog(error);
1810
- });
1811
- req.end();
1812
-
1813
- this.deviceStatus = req;
1814
- if (this.deviceStatus.message === 'success') {
1815
- this.warnLog(`${device.deviceName} deviceInfoStatus: ${JSON.stringify(this.deviceStatus)}`);
1816
- } else {
1817
- this.warnLog(`${device.deviceName} deviceInfoStatus: ${JSON.stringify(this.deviceStatus.message)}`);
1818
- this.warnLog('Unable to retreive deviceInfoStatus.');
1819
- }
1751
+ async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
1752
+ switch (res.statusCode) {
1753
+ case 151:
1754
+ this.errorLog('Command not supported by this device type.');
1755
+ break;
1756
+ case 152:
1757
+ this.errorLog('Device not found.');
1758
+ break;
1759
+ case 160:
1760
+ this.errorLog('Command is not supported.');
1761
+ break;
1762
+ case 161:
1763
+ this.errorLog('Device is offline.');
1764
+ break;
1765
+ case 171:
1766
+ this.errorLog('is offline');
1767
+ break;
1768
+ case 190:
1769
+ this.errorLog('Requests reached the daily limit');
1770
+ break;
1771
+ case 100:
1772
+ if (this.debugMode) {
1773
+ this.debugLog('Command successfully sent.');
1774
+ }
1775
+ break;
1776
+ default:
1777
+ if (this.debugMode) {
1778
+ this.debugLog('Unknown statusCode.');
1779
+ }
1820
1780
  }
1821
1781
  }
1822
1782
 
@@ -1827,13 +1787,27 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1827
1787
  try {
1828
1788
  Switchbot = require('node-switchbot');
1829
1789
  switchbot = new Switchbot();
1830
- } catch (e) {
1790
+ } catch (e: any) {
1831
1791
  switchbot = false;
1832
1792
  this.errorLog(`Was 'node-switchbot' found: ${switchbot}`);
1833
1793
  }
1834
1794
  return switchbot;
1835
1795
  }
1836
1796
 
1797
+ logs() {
1798
+ this.debugMode = process.argv.includes('-D') || process.argv.includes('--debug');
1799
+ if (this.config.options?.logging === 'debug' || this.config.options?.logging === 'standard' || this.config.options?.logging === 'none') {
1800
+ this.platformLogging = this.config.options!.logging;
1801
+ this.debugWarnLog(`Using Config Logging: ${this.platformLogging}`);
1802
+ } else if (this.debugMode) {
1803
+ this.platformLogging = 'debugMode';
1804
+ this.debugWarnLog(`Using ${this.platformLogging} Logging`);
1805
+ } else {
1806
+ this.platformLogging = 'standard';
1807
+ this.debugWarnLog(`Using ${this.platformLogging} Logging`);
1808
+ }
1809
+ }
1810
+
1837
1811
  /**
1838
1812
  * If device level logging is turned on, log to log.warn
1839
1813
  * Otherwise send debug logs to log.debug
@@ -1850,12 +1824,28 @@ export class SwitchBotPlatform implements DynamicPlatformPlugin {
1850
1824
  }
1851
1825
  }
1852
1826
 
1827
+ debugWarnLog(...log: any[]): void {
1828
+ if (this.enablingPlatfromLogging()) {
1829
+ if (this.platformLogging?.includes('debug')) {
1830
+ this.log.warn('[DEBUG]', String(...log));
1831
+ }
1832
+ }
1833
+ }
1834
+
1853
1835
  errorLog(...log: any[]): void {
1854
1836
  if (this.enablingPlatfromLogging()) {
1855
1837
  this.log.error(String(...log));
1856
1838
  }
1857
1839
  }
1858
1840
 
1841
+ debugErrorLog(...log: any[]): void {
1842
+ if (this.enablingPlatfromLogging()) {
1843
+ if (this.platformLogging?.includes('debug')) {
1844
+ this.log.error('[DEBUG]', String(...log));
1845
+ }
1846
+ }
1847
+ }
1848
+
1859
1849
  debugLog(...log: any[]): void {
1860
1850
  if (this.enablingPlatfromLogging()) {
1861
1851
  if (this.platformLogging === 'debugMode') {