@switchbot/homebridge-switchbot 2.0.0-beta.9 → 2.0.1-beta.0

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