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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/CHANGELOG.md +10 -1
  2. package/README.md +1 -2
  3. package/config.schema.json +102 -20
  4. package/dist/device/bot.d.ts +34 -28
  5. package/dist/device/bot.d.ts.map +1 -1
  6. package/dist/device/bot.js +655 -649
  7. package/dist/device/bot.js.map +1 -1
  8. package/dist/device/colorbulb.d.ts +36 -19
  9. package/dist/device/colorbulb.d.ts.map +1 -1
  10. package/dist/device/colorbulb.js +483 -309
  11. package/dist/device/colorbulb.js.map +1 -1
  12. package/dist/device/contact.d.ts +18 -8
  13. package/dist/device/contact.d.ts.map +1 -1
  14. package/dist/device/contact.js +303 -237
  15. package/dist/device/contact.js.map +1 -1
  16. package/dist/device/curtain.d.ts +23 -16
  17. package/dist/device/curtain.d.ts.map +1 -1
  18. package/dist/device/curtain.js +541 -498
  19. package/dist/device/curtain.js.map +1 -1
  20. package/dist/device/humidifier.d.ts +24 -18
  21. package/dist/device/humidifier.d.ts.map +1 -1
  22. package/dist/device/humidifier.js +450 -369
  23. package/dist/device/humidifier.js.map +1 -1
  24. package/dist/device/lock.d.ts +27 -8
  25. package/dist/device/lock.d.ts.map +1 -1
  26. package/dist/device/lock.js +302 -148
  27. package/dist/device/lock.js.map +1 -1
  28. package/dist/device/meter.d.ts +22 -16
  29. package/dist/device/meter.d.ts.map +1 -1
  30. package/dist/device/meter.js +340 -262
  31. package/dist/device/meter.js.map +1 -1
  32. package/dist/device/meterplus.d.ts +24 -12
  33. package/dist/device/meterplus.d.ts.map +1 -1
  34. package/dist/device/meterplus.js +359 -213
  35. package/dist/device/meterplus.js.map +1 -1
  36. package/dist/device/motion.d.ts +18 -8
  37. package/dist/device/motion.d.ts.map +1 -1
  38. package/dist/device/motion.js +276 -216
  39. package/dist/device/motion.js.map +1 -1
  40. package/dist/device/plug.d.ts +27 -17
  41. package/dist/device/plug.d.ts.map +1 -1
  42. package/dist/device/plug.js +292 -251
  43. package/dist/device/plug.js.map +1 -1
  44. package/dist/device/striplight.d.ts +43 -19
  45. package/dist/device/striplight.d.ts.map +1 -1
  46. package/dist/device/striplight.js +503 -262
  47. package/dist/device/striplight.js.map +1 -1
  48. package/dist/irdevice/airconditioner.d.ts +9 -12
  49. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  50. package/dist/irdevice/airconditioner.js +275 -230
  51. package/dist/irdevice/airconditioner.js.map +1 -1
  52. package/dist/irdevice/airpurifier.d.ts +5 -3
  53. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  54. package/dist/irdevice/airpurifier.js +151 -104
  55. package/dist/irdevice/airpurifier.js.map +1 -1
  56. package/dist/irdevice/camera.d.ts +11 -8
  57. package/dist/irdevice/camera.d.ts.map +1 -1
  58. package/dist/irdevice/camera.js +130 -86
  59. package/dist/irdevice/camera.js.map +1 -1
  60. package/dist/irdevice/fan.d.ts +10 -7
  61. package/dist/irdevice/fan.d.ts.map +1 -1
  62. package/dist/irdevice/fan.js +157 -109
  63. package/dist/irdevice/fan.js.map +1 -1
  64. package/dist/irdevice/light.d.ts +11 -8
  65. package/dist/irdevice/light.d.ts.map +1 -1
  66. package/dist/irdevice/light.js +134 -103
  67. package/dist/irdevice/light.js.map +1 -1
  68. package/dist/irdevice/other.d.ts +11 -8
  69. package/dist/irdevice/other.d.ts.map +1 -1
  70. package/dist/irdevice/other.js +142 -98
  71. package/dist/irdevice/other.js.map +1 -1
  72. package/dist/irdevice/tv.d.ts +12 -9
  73. package/dist/irdevice/tv.d.ts.map +1 -1
  74. package/dist/irdevice/tv.js +140 -93
  75. package/dist/irdevice/tv.js.map +1 -1
  76. package/dist/irdevice/vacuumcleaner.d.ts +9 -10
  77. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  78. package/dist/irdevice/vacuumcleaner.js +129 -89
  79. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  80. package/dist/irdevice/waterheater.d.ts +8 -9
  81. package/dist/irdevice/waterheater.d.ts.map +1 -1
  82. package/dist/irdevice/waterheater.js +129 -89
  83. package/dist/irdevice/waterheater.js.map +1 -1
  84. package/dist/platform.d.ts +14 -12
  85. package/dist/platform.d.ts.map +1 -1
  86. package/dist/platform.js +479 -434
  87. package/dist/platform.js.map +1 -1
  88. package/dist/settings.d.ts +18 -11
  89. package/dist/settings.d.ts.map +1 -1
  90. package/dist/settings.js.map +1 -1
  91. package/package.json +12 -10
  92. package/src/device/bot.ts +654 -660
  93. package/src/device/colorbulb.ts +487 -344
  94. package/src/device/contact.ts +306 -241
  95. package/src/device/curtain.ts +546 -512
  96. package/src/device/humidifier.ts +453 -403
  97. package/src/device/lock.ts +311 -149
  98. package/src/device/meter.ts +351 -275
  99. package/src/device/meterplus.ts +369 -219
  100. package/src/device/motion.ts +282 -222
  101. package/src/device/plug.ts +296 -260
  102. package/src/device/striplight.ts +519 -289
  103. package/src/irdevice/airconditioner.ts +279 -241
  104. package/src/irdevice/airpurifier.ts +148 -103
  105. package/src/irdevice/camera.ts +128 -85
  106. package/src/irdevice/fan.ts +154 -106
  107. package/src/irdevice/light.ts +132 -103
  108. package/src/irdevice/other.ts +140 -97
  109. package/src/irdevice/tv.ts +139 -93
  110. package/src/irdevice/vacuumcleaner.ts +128 -89
  111. package/src/irdevice/waterheater.ts +127 -89
  112. package/src/platform.ts +469 -456
  113. package/src/settings.ts +18 -11
@@ -3,6 +3,7 @@ import crypto from 'crypto';
3
3
  import { Context } from 'vm';
4
4
  import { IncomingMessage } from 'http';
5
5
  import { interval, Subject } from 'rxjs';
6
+ import superStringify from 'super-stringify';
6
7
  import { SwitchBotPlatform } from '../platform';
7
8
  import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
8
9
  import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
@@ -14,7 +15,6 @@ export class Plug {
14
15
 
15
16
  // Characteristic Values
16
17
  On!: CharacteristicValue;
17
- OnCached!: CharacteristicValue;
18
18
 
19
19
  // OpenAPI Others
20
20
  power: deviceStatus['power'];
@@ -24,7 +24,6 @@ export class Plug {
24
24
  connected?: boolean;
25
25
  switchbot!: switchbot;
26
26
  address!: ad['address'];
27
- SwitchToOpenAPI?: boolean;
28
27
  serviceData!: serviceData;
29
28
  state: serviceData['state'];
30
29
  delay: serviceData['delay'];
@@ -43,17 +42,17 @@ export class Plug {
43
42
  plugUpdateInProgress!: boolean;
44
43
  doPlugUpdate!: Subject<void>;
45
44
 
45
+ // Connection
46
+ private readonly BLE = (this.device.connectionType === 'BLE' || this.device.connectionType === 'BLE/OpenAPI');
47
+ private readonly OpenAPI = (this.device.connectionType === 'OpenAPI' || this.device.connectionType === 'BLE/OpenAPI');
48
+
46
49
  constructor(private readonly platform: SwitchBotPlatform, private accessory: PlatformAccessory, public device: device & devicesConfig) {
47
50
  // default placeholders
48
51
  this.logs(device);
49
52
  this.scan(device);
50
53
  this.refreshRate(device);
51
54
  this.config(device);
52
- if (this.On === undefined) {
53
- this.On = false;
54
- } else {
55
- this.On = this.accessory.context.On;
56
- }
55
+ this.context();
57
56
 
58
57
  // this is subject we use to track when we need to POST changes to the SwitchBot API
59
58
  this.doPlugUpdate = new Subject();
@@ -89,7 +88,7 @@ export class Plug {
89
88
  // see https://developers.homebridge.io/#/service/Outlet
90
89
 
91
90
  // create handlers for required characteristics
92
- this.outletService.getCharacteristic(this.platform.Characteristic.On).onSet(this.handleOnSet.bind(this));
91
+ this.outletService.getCharacteristic(this.platform.Characteristic.On).onSet(this.OnSet.bind(this));
93
92
 
94
93
  // Update Homekit
95
94
  this.updateHomeKitCharacteristics();
@@ -114,26 +113,30 @@ export class Plug {
114
113
  try {
115
114
  await this.pushChanges();
116
115
  } catch (e: any) {
117
- this.errorLog(`Plug: ${this.accessory.displayName} failed pushChanges`);
118
- if (this.deviceLogging.includes('debug')) {
119
- this.errorLog(`Plug: ${this.accessory.displayName} failed pushChanges,` + ` Error Message: ${JSON.stringify(e.message)}`);
120
- }
121
116
  this.apiError(e);
117
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,`
118
+ + ` Error Message: ${superStringify(e.message)}`);
122
119
  }
123
120
  this.plugUpdateInProgress = false;
124
121
  });
125
122
  }
126
123
 
124
+ /**
125
+ * Parse the device status from the SwitchBot api
126
+ */
127
127
  async parseStatus(): Promise<void> {
128
- if (this.SwitchToOpenAPI || !this.device.ble) {
128
+ if (this.BLE) {
129
+ await this.BLEparseStatus();
130
+ } else if (this.OpenAPI && this.platform.config.credentials?.token) {
129
131
  await this.openAPIparseStatus();
130
132
  } else {
131
- await this.BLEparseStatus();
133
+ this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
134
+ + ` ${this.device.connectionType}, parseStatus will not happen.`);
132
135
  }
133
136
  }
134
137
 
135
138
  async BLEparseStatus(): Promise<void> {
136
- this.debugLog(`Plug: ${this.accessory.displayName} BLE parseStatus`);
139
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
137
140
  // State
138
141
  switch (this.state) {
139
142
  case 'on':
@@ -142,10 +145,11 @@ export class Plug {
142
145
  default:
143
146
  this.On = false;
144
147
  }
145
- this.debugLog(`Plug: ${this.accessory.displayName} On: ${this.On}`);
148
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
146
149
  }
147
150
 
148
151
  async openAPIparseStatus() {
152
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
149
153
  switch (this.power) {
150
154
  case 'on':
151
155
  this.On = true;
@@ -153,26 +157,32 @@ export class Plug {
153
157
  default:
154
158
  this.On = false;
155
159
  }
156
- this.debugLog(`Plug: ${this.accessory.displayName} On: ${this.On}`);
160
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
157
161
  }
158
162
 
163
+ /**
164
+ * Asks the SwitchBot API for the latest device information
165
+ */
159
166
  async refreshStatus(): Promise<void> {
160
- if (this.device.ble) {
167
+ if (this.BLE) {
161
168
  await this.BLERefreshStatus();
162
- } else {
169
+ } else if (this.OpenAPI && this.platform.config.credentials?.token) {
163
170
  await this.openAPIRefreshStatus();
171
+ } else {
172
+ this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
173
+ + ` ${this.device.connectionType}, refreshStatus will not happen.`);
164
174
  }
165
175
  }
166
176
 
167
177
  async BLERefreshStatus(): Promise<void> {
168
- this.debugLog(`Plug: ${this.accessory.displayName} BLE refreshStatus`);
178
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
169
179
  const switchbot = await this.platform.connectBLE();
170
180
  // Convert to BLE Address
171
181
  this.device.bleMac = this.device
172
182
  .deviceId!.match(/.{1,2}/g)!
173
183
  .join(':')
174
184
  .toLowerCase();
175
- this.debugLog(`Plug: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
185
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
176
186
  this.getCustomBLEAddress(switchbot);
177
187
  // Start to monitor advertisement packets
178
188
  if (switchbot !== false) {
@@ -185,12 +195,8 @@ export class Plug {
185
195
  // Set an event hander
186
196
  switchbot.onadvertisement = (ad: any) => {
187
197
  this.address = ad.address;
188
- if (this.deviceLogging.includes('debug')) {
189
- this.infoLog(this.address);
190
- this.infoLog(this.device.bleMac);
191
- this.infoLog(`Plug: ${this.accessory.displayName} BLE Address Found: ${this.address}`);
192
- this.infoLog(`Plug: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac}`);
193
- }
198
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},`
199
+ + ` BLE Address Found: ${this.address}`);
194
200
  this.serviceData = ad.serviceData;
195
201
  this.state = ad.serviceData.state;
196
202
  this.delay = ad.serviceData.delay;
@@ -199,19 +205,19 @@ export class Plug {
199
205
  this.wifiRssi = ad.serviceData.wifiRssi;
200
206
  this.overload = ad.serviceData.overload;
201
207
  this.currentPower = ad.serviceData.currentPower;
202
- this.debugLog(`Plug: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
208
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${superStringify(ad.serviceData)}`);
203
209
  this.debugLog(
204
- `Plug: ${this.accessory.displayName} state: ${ad.serviceData.state}, ` +
210
+ `${this.device.deviceType}: ${this.accessory.displayName} state: ${ad.serviceData.state}, ` +
205
211
  `delay: ${ad.serviceData.delay}, timer: ${ad.serviceData.timer}, syncUtcTime: ${ad.serviceData.syncUtcTime} ` +
206
212
  `wifiRssi: ${ad.serviceData.wifiRssi}, overload: ${ad.serviceData.overload}, currentPower: ${ad.serviceData.currentPower}`,
207
213
  );
208
214
 
209
215
  if (this.serviceData) {
210
216
  this.connected = true;
211
- this.debugLog(`Plug: ${this.accessory.displayName} connected: ${this.connected}`);
217
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.connected}`);
212
218
  } else {
213
219
  this.connected = false;
214
- this.debugLog(`Plug: ${this.accessory.displayName} connected: ${this.connected}`);
220
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.connected}`);
215
221
  }
216
222
  };
217
223
  // Wait 2 seconds
@@ -221,74 +227,32 @@ export class Plug {
221
227
  // Stop to monitor
222
228
  switchbot.stopScan();
223
229
  if (this.connected) {
224
- this.parseStatus();
230
+ this.BLEparseStatus();
225
231
  this.updateHomeKitCharacteristics();
226
232
  } else {
227
- await this.BLEconnection(switchbot);
233
+ await this.BLERefreshConnection(switchbot);
228
234
  }
229
235
  })
230
236
  .catch(async (e: any) => {
231
- this.errorLog(`Plug: ${this.accessory.displayName} failed refreshStatus with BLE Connection`);
232
- if (this.deviceLogging.includes('debug')) {
233
- this.errorLog(
234
- `Plug: ${this.accessory.displayName} failed refreshStatus with BLE Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
235
- );
236
- }
237
- if (this.platform.config.credentials?.token) {
238
- this.warnLog(`Plug: ${this.accessory.displayName} Using OpenAPI Connection`);
239
- this.SwitchToOpenAPI = true;
240
- await this.openAPIRefreshStatus();
241
- }
242
237
  this.apiError(e);
238
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}`
239
+ + ` Connection, Error Message: ${superStringify(e.message)}`);
240
+ await this.BLERefreshConnection(switchbot);
243
241
  });
244
242
  } else {
245
- await this.BLEconnection(switchbot);
246
- }
247
- }
248
-
249
- BLEmodel(): 'g' | 'j' {
250
- if (this.device.deviceType === 'Plug Mini (US)') {
251
- return 'g';
252
- } else {
253
- return 'j';
254
- }
255
- }
256
-
257
- async getCustomBLEAddress(switchbot: any) {
258
- if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
259
- (async () => {
260
- // Start to monitor advertisement packets
261
- await switchbot.startScan({
262
- model: this.BLEmodel(),
263
- });
264
- // Set an event handler
265
- switchbot.onadvertisement = (ad: any) => {
266
- this.warnLog(`Plug: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
267
- };
268
- await switchbot.wait(10000);
269
- // Stop to monitor
270
- switchbot.stopScan();
271
- })();
272
- }
273
- }
274
-
275
- async BLEconnection(switchbot: any): Promise<void> {
276
- this.errorLog(`Plug: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
277
- if (this.platform.config.credentials?.token) {
278
- this.warnLog(`Plug: ${this.accessory.displayName} Using OpenAPI Connection`);
279
- this.SwitchToOpenAPI = true;
280
- await this.openAPIRefreshStatus();
243
+ await this.BLERefreshConnection(switchbot);
281
244
  }
282
245
  }
283
246
 
284
247
  async openAPIRefreshStatus() {
248
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
285
249
  try {
286
250
  const t = Date.now();
287
251
  const nonce = 'requestID';
288
252
  const data = this.platform.config.credentials?.token + t + nonce;
289
253
  const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
290
254
  const sign = signTerm.toString('base64');
291
- this.debugLog(`Plug: ${this.accessory.displayName} sign: ${sign}`);
255
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
292
256
  const options = {
293
257
  hostname: HostDomain,
294
258
  port: 443,
@@ -303,36 +267,33 @@ export class Plug {
303
267
  },
304
268
  };
305
269
  const req = https.request(options, (res) => {
306
- this.debugLog(`Plug: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
270
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus statusCode: ${res.statusCode}`);
271
+ this.statusCode({ res });
307
272
  let rawData = '';
308
273
  res.on('data', (d) => {
309
274
  rawData += d;
310
- this.debugLog(`Plug: ${this.accessory.displayName} d: ${d}`);
275
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
311
276
  });
312
277
  res.on('end', () => {
313
278
  try {
314
279
  this.deviceStatus = JSON.parse(rawData);
315
- this.debugLog(`Plug: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
280
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus: ${superStringify(this.deviceStatus)}`);
316
281
  this.power = this.deviceStatus.body.power;
317
- this.parseStatus();
282
+ this.openAPIparseStatus();
318
283
  this.updateHomeKitCharacteristics();
319
284
  } catch (e: any) {
320
- this.errorLog(`Plug: ${this.accessory.displayName} error message: ${e.message}`);
285
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
321
286
  }
322
287
  });
323
288
  });
324
289
  req.on('error', (e: any) => {
325
- this.errorLog(`Plug: ${this.accessory.displayName} error message: ${e.message}`);
290
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
326
291
  });
327
292
  req.end();
328
293
  } catch (e: any) {
329
- this.errorLog(`Plug: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
330
- if (this.deviceLogging.includes('debug')) {
331
- this.errorLog(
332
- `Plug: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
333
- );
334
- }
335
294
  this.apiError(e);
295
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
296
+ + ` Connection, Error Message: ${superStringify(e.message)}`);
336
297
  }
337
298
  }
338
299
 
@@ -347,76 +308,64 @@ export class Plug {
347
308
  */
348
309
 
349
310
  async pushChanges(): Promise<void> {
350
- if (this.device.ble) {
311
+ if (this.BLE) {
351
312
  await this.BLEpushChanges();
352
- } else {
313
+ } else if (this.OpenAPI && this.platform.config.credentials?.token) {
353
314
  await this.openAPIpushChanges();
315
+ } else {
316
+ this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
317
+ + ` ${this.device.connectionType}, pushChanges will not happen.`);
354
318
  }
355
- }
356
-
357
- async BLEpushChanges(): Promise<void> {
358
- this.debugLog(`Plug: ${this.accessory.displayName} BLE pushChanges On: ${this.On} OnCached: ${this.OnCached}`);
359
- this.debugLog(`Plug: ${this.accessory.displayName} BLE pushChanges`);
360
- const switchbot = await this.platform.connectBLE();
361
- // Convert to BLE Address
362
- this.device.bleMac = this.device
363
- .deviceId!.match(/.{1,2}/g)!
364
- .join(':')
365
- .toLowerCase();
366
- this.debugLog(`Plug: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
367
- switchbot
368
- .discover({
369
- model: this.BLEmodel(),
370
- id: this.device.bleMac,
371
- })
372
- .then((device_list: any) => {
373
- this.infoLog(`Plug: ${this.accessory.displayName} On: ${this.On}`);
374
- return this.turnOnOff(device_list);
375
- })
376
- .then(() => {
377
- this.debugLog(`Plug: ${this.accessory.displayName} Done.`);
378
- this.On = false;
379
- this.OnCached = this.On;
380
- this.accessory.context.On = this.OnCached;
381
- })
382
- .catch(async (e: any) => {
383
- this.errorLog(`Plug: ${this.accessory.displayName} failed pushChanges with BLE Connection`);
384
- if (this.deviceLogging.includes('debug')) {
385
- this.errorLog(
386
- `Plug: ${this.accessory.displayName} failed pushChanges with BLE Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
387
- );
388
- }
389
- if (this.platform.debugMode) {
390
- this.errorLog(`Plug: ${this.accessory.displayName} failed pushChanges with BLE Connection,` + ` Error: ${JSON.stringify(e)}`);
391
- }
392
- if (this.platform.config.credentials?.token) {
393
- this.warnLog(`Plug: ${this.accessory.displayName} Using OpenAPI Connection`);
394
- await this.openAPIpushChanges();
395
- }
396
- this.apiError(e);
319
+ interval(5000)
320
+ .pipe(take(1))
321
+ .subscribe(async () => {
322
+ await this.refreshStatus();
397
323
  });
398
- this.OnCached = this.On;
399
- this.accessory.context.On = this.OnCached;
400
324
  }
401
325
 
402
- async turnOnOff(device_list: any): Promise<any> {
403
- return await this.retry({
404
- max: await this.maxRetry(),
405
- fn: () => {
406
- if (this.On) {
407
- return device_list[0].turnOn({ id: this.device.bleMac });
408
- } else {
409
- return device_list[0].turnOff({ id: this.device.bleMac });
410
- }
411
- },
412
- });
326
+ async BLEpushChanges(): Promise<void> {
327
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`);
328
+ if (this.On !== this.accessory.context.On) {
329
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges On: ${this.On} OnCached: ${this.accessory.context.On}`);
330
+ const switchbot = await this.platform.connectBLE();
331
+ // Convert to BLE Address
332
+ this.device.bleMac = this.device
333
+ .deviceId!.match(/.{1,2}/g)!
334
+ .join(':')
335
+ .toLowerCase();
336
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
337
+ switchbot
338
+ .discover({
339
+ model: this.BLEmodel(),
340
+ id: this.device.bleMac,
341
+ })
342
+ .then((device_list: any) => {
343
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
344
+ return this.turnOnOff(device_list);
345
+ })
346
+ .then(() => {
347
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
348
+ this.On = false;
349
+ })
350
+ .catch(async (e: any) => {
351
+ this.apiError(e);
352
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}`
353
+ + ` Connection, Error Message: ${superStringify(e.message)}`);
354
+ await this.BLEPushConnection();
355
+ });
356
+ } else {
357
+ this.debugLog(
358
+ `${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges.` + `On: ${this.On}, `
359
+ +`OnCached: ${this.accessory.context.On}`,
360
+ );
361
+ }
413
362
  }
414
363
 
415
364
  async openAPIpushChanges() {
416
- if (this.platform.config.credentials?.token) {
417
- if (this.On !== this.OnCached) {
365
+ try {
366
+ if (this.On !== this.accessory.context.On) {
418
367
  // Make Push On request to the API
419
- this.debugLog(`Plug: ${this.accessory.displayName} OpenAPI pushChanges`);
368
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
420
369
  const t = Date.now();
421
370
  const nonce = 'requestID';
422
371
  const data = this.platform.config.credentials?.token + t + nonce;
@@ -424,7 +373,7 @@ export class Plug {
424
373
  .update(Buffer.from(data, 'utf-8'))
425
374
  .digest();
426
375
  const sign = signTerm.toString('base64');
427
- this.debugLog(`Plug: ${this.accessory.displayName} sign: ${sign}`);
376
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
428
377
 
429
378
  let command = '';
430
379
  if (this.On) {
@@ -432,12 +381,12 @@ export class Plug {
432
381
  } else {
433
382
  command = 'turnOff';
434
383
  }
435
- const body = JSON.stringify({
384
+ const body = superStringify({
436
385
  'command': `${command}`,
437
386
  'parameter': 'default',
438
387
  'commandType': 'command',
439
388
  });
440
- this.infoLog(`Plug: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
389
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
441
390
  const options = {
442
391
  hostname: HostDomain,
443
392
  port: 443,
@@ -453,73 +402,188 @@ export class Plug {
453
402
  },
454
403
  };
455
404
  const req = https.request(options, res => {
456
- this.debugLog(`Plug: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
405
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges statusCode: ${res.statusCode}`);
457
406
  this.statusCode({ res });
458
407
  res.on('data', d => {
459
- this.debugLog(`Plug: ${this.accessory.displayName} d: ${d}`);
408
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
460
409
  });
461
410
  });
462
411
  req.on('error', (e: any) => {
463
- this.errorLog(`Plug: ${this.accessory.displayName} error message: ${e.message}`);
412
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
464
413
  });
465
414
  req.write(body);
466
415
  req.end();
467
- this.debugLog(`Plug: ${this.accessory.displayName} openAPIpushChanges: ${JSON.stringify(req)}`);
468
- this.OnCached = this.On;
469
- this.accessory.context.On = this.OnCached;
416
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges: ${superStringify(req)}`);
417
+ } else {
418
+ this.debugLog(
419
+ `${this.device.deviceType}: ${this.accessory.displayName} No openAPIpushChanges.` + `On: ${this.On}, `
420
+ +`OnCached: ${this.accessory.context.On}`,
421
+ );
470
422
  }
471
- interval(5000)
472
- .pipe(take(1))
473
- .subscribe(async () => {
474
- await this.refreshStatus();
475
- });
423
+ } catch (e: any) {
424
+ this.apiError(e);
425
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
426
+ + ` Connection, Error Message: ${superStringify(e.message)}`,
427
+ );
428
+ }
429
+ }
430
+
431
+ /**
432
+ * Handle requests to set the value of the "On" characteristic
433
+ */
434
+ async OnSet(value: CharacteristicValue): Promise<void> {
435
+ if (this.On === this.accessory.context.On) {
436
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set On: ${value}`);
437
+ } else {
438
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set On: ${value}`);
476
439
  }
440
+
441
+ this.On = value;
442
+ this.doPlugUpdate.next();
477
443
  }
478
444
 
479
445
  async updateHomeKitCharacteristics(): Promise<void> {
480
446
  if (this.On === undefined) {
481
- this.debugLog(`Plug: ${this.accessory.displayName} On: ${this.On}`);
447
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
482
448
  } else {
449
+ this.accessory.context.On = this.On;
483
450
  this.outletService.updateCharacteristic(this.platform.Characteristic.On, this.On);
484
- this.debugLog(`Plug: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
451
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
485
452
  }
486
453
  }
487
454
 
488
- async apiError(e: any): Promise<void> {
489
- this.outletService.updateCharacteristic(this.platform.Characteristic.On, e);
490
- //throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
455
+ BLEmodel(): 'g' | 'j' {
456
+ if (this.device.deviceType === 'Plug Mini (US)') {
457
+ return 'g';
458
+ } else {
459
+ return 'j';
460
+ }
461
+ }
462
+
463
+ async getCustomBLEAddress(switchbot: any) {
464
+ if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
465
+ (async () => {
466
+ // Start to monitor advertisement packets
467
+ await switchbot.startScan({
468
+ model: this.BLEmodel(),
469
+ });
470
+ // Set an event handler
471
+ switchbot.onadvertisement = (ad: any) => {
472
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${superStringify(ad, null, ' ')}`);
473
+ };
474
+ await switchbot.wait(10000);
475
+ // Stop to monitor
476
+ switchbot.stopScan();
477
+ })();
478
+ }
479
+ }
480
+
481
+ async BLEPushConnection() {
482
+ if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
483
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Push Changes`);
484
+ await this.openAPIpushChanges();
485
+ }
486
+ }
487
+
488
+ async BLERefreshConnection(switchbot: any): Promise<void> {
489
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
490
+ if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
491
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Refresh Status`);
492
+ await this.openAPIRefreshStatus();
493
+ }
494
+ }
495
+
496
+ async turnOnOff(device_list: any): Promise<any> {
497
+ return await this.retry({
498
+ max: await this.maxRetry(),
499
+ fn: () => {
500
+ if (this.On) {
501
+ return device_list[0].turnOn({ id: this.device.bleMac });
502
+ } else {
503
+ return device_list[0].turnOff({ id: this.device.bleMac });
504
+ }
505
+ },
506
+ });
507
+ }
508
+
509
+ async retry({ max, fn }: { max: number; fn: { (): any; (): Promise<any> } }): Promise<null> {
510
+ return fn().catch(async (err: any) => {
511
+ if (max === 0) {
512
+ throw err;
513
+ }
514
+ this.infoLog(err);
515
+ this.infoLog('Retrying');
516
+ await this.switchbot.wait(1000);
517
+ return this.retry({ max: max - 1, fn });
518
+ });
519
+ }
520
+
521
+ async maxRetry(): Promise<number> {
522
+ let maxRetry: number;
523
+ if (this.device.bot?.maxRetry) {
524
+ maxRetry = this.device.bot?.maxRetry;
525
+ } else {
526
+ maxRetry = 5;
527
+ }
528
+ return maxRetry;
529
+ }
530
+
531
+ model(device: device & devicesConfig): string {
532
+ let model: string;
533
+ if (device.deviceType === 'Plug Mini (US)') {
534
+ model = 'W1901400';
535
+ } else if (device.deviceType === 'Plug Mini (JP)') {
536
+ model = 'W2001400';
537
+ } else {
538
+ model = 'SP11';
539
+ }
540
+ return model;
541
+ }
542
+
543
+ async scan(device: device & devicesConfig): Promise<void> {
544
+ if (device.scanDuration) {
545
+ this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
546
+ if (this.BLE) {
547
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
548
+ }
549
+ } else {
550
+ this.scanDuration = this.accessory.context.scanDuration = 1;
551
+ if (this.BLE) {
552
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
553
+ }
554
+ }
491
555
  }
492
556
 
493
557
  async statusCode({ res }: { res: IncomingMessage }): Promise<void> {
494
558
  switch (res.statusCode) {
495
559
  case 151:
496
- this.errorLog(`Plug: ${this.accessory.displayName} Command not supported by this device type.`);
560
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this device type.`);
497
561
  break;
498
562
  case 152:
499
- this.errorLog(`Plug: ${this.accessory.displayName} Device not found.`);
563
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found.`);
500
564
  break;
501
565
  case 160:
502
- this.errorLog(`Plug: ${this.accessory.displayName} Command is not supported.`);
566
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported.`);
503
567
  break;
504
568
  case 161:
505
- this.errorLog(`Plug: ${this.accessory.displayName} Device is offline.`);
569
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline.`);
506
570
  this.offlineOff();
507
571
  break;
508
572
  case 171:
509
- this.errorLog(`Plug: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
573
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
510
574
  this.offlineOff();
511
575
  break;
512
576
  case 190:
513
577
  this.errorLog(
514
- `Plug: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
515
- ` Or command: ${JSON.stringify(res)} format is invalid`,
578
+ `${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
579
+ ` Or command: ${superStringify(res)} format is invalid`,
516
580
  );
517
581
  break;
518
582
  case 100:
519
- this.debugLog(`Plug: ${this.accessory.displayName} Command successfully sent.`);
583
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent.`);
520
584
  break;
521
585
  default:
522
- this.debugLog(`Plug: ${this.accessory.displayName} Unknown statusCode.`);
586
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode.`);
523
587
  }
524
588
  }
525
589
 
@@ -527,51 +591,46 @@ export class Plug {
527
591
  if (this.device.offline) {
528
592
  this.On = false;
529
593
  this.outletService.getCharacteristic(this.platform.Characteristic.On).updateValue(this.On);
594
+ await this.updateHomeKitCharacteristics();
530
595
  }
531
596
  }
532
597
 
533
- /**
534
- * Handle requests to set the value of the "On" characteristic
535
- */
536
- async handleOnSet(value: CharacteristicValue): Promise<void> {
537
- this.debugLog(`Plug: ${this.accessory.displayName} - Set On: ${value}`);
538
-
539
- this.On = value;
540
- this.doPlugUpdate.next();
598
+ async apiError(e: any): Promise<void> {
599
+ this.outletService.updateCharacteristic(this.platform.Characteristic.On, e);
541
600
  }
542
601
 
543
- model(device: device & devicesConfig): string {
544
- let model: string;
545
- if (device.deviceType === 'Plug Mini (US)') {
546
- model = 'W1901400';
547
- } else if (device.deviceType === 'Plug Mini (JP)') {
548
- model = 'W2001400';
602
+ FirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
603
+ let FirmwareRevision: string;
604
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
605
+ +` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
606
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
607
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
608
+ if (accessory.context.FirmwareRevision) {
609
+ FirmwareRevision = accessory.context.FirmwareRevision;
610
+ } else if (device.firmware) {
611
+ FirmwareRevision = device.firmware;
549
612
  } else {
550
- model = 'SP11';
613
+ FirmwareRevision = this.platform.version;
551
614
  }
552
- return model;
615
+ return FirmwareRevision;
553
616
  }
554
617
 
555
- async retry({ max, fn }: { max: number; fn: { (): any; (): Promise<any> } }): Promise<null> {
556
- return fn().catch(async (err: any) => {
557
- if (max === 0) {
558
- throw err;
559
- }
560
- this.infoLog(err);
561
- this.infoLog('Retrying');
562
- await this.switchbot.wait(1000);
563
- return this.retry({ max: max - 1, fn });
564
- });
618
+ async context() {
619
+ if (this.On === undefined) {
620
+ this.On = false;
621
+ } else {
622
+ this.On = this.accessory.context.On;
623
+ }
565
624
  }
566
625
 
567
- async maxRetry(): Promise<number> {
568
- let maxRetry: number;
569
- if (this.device.bot?.maxRetry) {
570
- maxRetry = this.device.bot?.maxRetry;
571
- } else {
572
- maxRetry = 5;
626
+ async refreshRate(device: device & devicesConfig): Promise<void> {
627
+ if (device.refreshRate) {
628
+ this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
629
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
630
+ } else if (this.platform.config.options!.refreshRate) {
631
+ this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
632
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
573
633
  }
574
- return maxRetry;
575
634
  }
576
635
 
577
636
  async config(device: device & devicesConfig): Promise<void> {
@@ -579,8 +638,8 @@ export class Plug {
579
638
  if (device.plug) {
580
639
  config = device.plug;
581
640
  }
582
- if (device.ble !== undefined) {
583
- config['ble'] = device.ble;
641
+ if (device.connectionType !== undefined) {
642
+ config['connectionType'] = device.connectionType;
584
643
  }
585
644
  if (device.logging !== undefined) {
586
645
  config['logging'] = device.logging;
@@ -595,63 +654,24 @@ export class Plug {
595
654
  config['offline'] = device.offline;
596
655
  }
597
656
  if (Object.entries(config).length !== 0) {
598
- this.infoLog(`Plug: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
599
- }
600
- }
601
-
602
- async refreshRate(device: device & devicesConfig): Promise<void> {
603
- if (device.refreshRate) {
604
- this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
605
- this.debugLog(`Plug: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
606
- } else if (this.platform.config.options!.refreshRate) {
607
- this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
608
- this.debugLog(`Plug: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
609
- }
610
- }
611
-
612
- async scan(device: device & devicesConfig): Promise<void> {
613
- if (device.scanDuration) {
614
- this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
615
- if (device.ble) {
616
- this.debugLog(`Plug: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
617
- }
618
- } else {
619
- this.scanDuration = this.accessory.context.scanDuration = 1;
620
- if (this.device.ble) {
621
- this.debugLog(`Plug: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
622
- }
657
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${superStringify(config)}`);
623
658
  }
624
659
  }
625
660
 
626
661
  async logs(device: device & devicesConfig): Promise<void> {
627
662
  if (this.platform.debugMode) {
628
663
  this.deviceLogging = this.accessory.context.logging = 'debugMode';
629
- this.debugLog(`Plug: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
664
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
630
665
  } else if (device.logging) {
631
666
  this.deviceLogging = this.accessory.context.logging = device.logging;
632
- this.debugLog(`Plug: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
667
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
633
668
  } else if (this.platform.config.options?.logging) {
634
669
  this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
635
- this.debugLog(`Plug: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
670
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
636
671
  } else {
637
672
  this.deviceLogging = this.accessory.context.logging = 'standard';
638
- this.debugLog(`Plug: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
639
- }
640
- }
641
-
642
- FirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
643
- let FirmwareRevision: string;
644
- this.debugLog(`Plug: ${this.accessory.displayName} accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
645
- this.debugLog(`Plug: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
646
- this.debugLog(`Plug: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
647
- if (accessory.context.FirmwareRevision) {
648
- FirmwareRevision = accessory.context.FirmwareRevision;
649
- } else if (device.firmware) {
650
- FirmwareRevision = device.firmware;
651
- } else {
652
- FirmwareRevision = this.platform.version;
673
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
653
674
  }
654
- return FirmwareRevision;
655
675
  }
656
676
 
657
677
  /**
@@ -669,12 +689,28 @@ export class Plug {
669
689
  }
670
690
  }
671
691
 
692
+ debugWarnLog(...log: any[]): void {
693
+ if (this.enablingDeviceLogging()) {
694
+ if (this.deviceLogging?.includes('debug')) {
695
+ this.platform.log.warn('[DEBUG]', String(...log));
696
+ }
697
+ }
698
+ }
699
+
672
700
  errorLog(...log: any[]): void {
673
701
  if (this.enablingDeviceLogging()) {
674
702
  this.platform.log.error(String(...log));
675
703
  }
676
704
  }
677
705
 
706
+ debugErrorLog(...log: any[]): void {
707
+ if (this.enablingDeviceLogging()) {
708
+ if (this.deviceLogging?.includes('debug')) {
709
+ this.platform.log.error('[DEBUG]', String(...log));
710
+ }
711
+ }
712
+ }
713
+
678
714
  debugLog(...log: any[]): void {
679
715
  if (this.enablingDeviceLogging()) {
680
716
  if (this.deviceLogging === 'debug') {