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