@switchbot/homebridge-switchbot 1.15.0 → 1.15.1-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/config.schema.json +1 -1
  2. package/dist/device/bot.d.ts.map +1 -1
  3. package/dist/device/bot.js +3 -3
  4. package/dist/device/bot.js.map +1 -1
  5. package/dist/device/colorbulb.d.ts +15 -1
  6. package/dist/device/colorbulb.d.ts.map +1 -1
  7. package/dist/device/colorbulb.js +140 -13
  8. package/dist/device/colorbulb.js.map +1 -1
  9. package/dist/device/contact.d.ts.map +1 -1
  10. package/dist/device/contact.js +8 -5
  11. package/dist/device/contact.js.map +1 -1
  12. package/dist/device/curtain.d.ts.map +1 -1
  13. package/dist/device/curtain.js +6 -2
  14. package/dist/device/curtain.js.map +1 -1
  15. package/dist/device/humidifier.d.ts.map +1 -1
  16. package/dist/device/humidifier.js +2 -1
  17. package/dist/device/humidifier.js.map +1 -1
  18. package/dist/device/lock.d.ts.map +1 -1
  19. package/dist/device/lock.js +2 -1
  20. package/dist/device/lock.js.map +1 -1
  21. package/dist/device/meter.d.ts.map +1 -1
  22. package/dist/device/meter.js +25 -14
  23. package/dist/device/meter.js.map +1 -1
  24. package/dist/device/meterplus.d.ts.map +1 -1
  25. package/dist/device/meterplus.js +2 -1
  26. package/dist/device/meterplus.js.map +1 -1
  27. package/dist/device/motion.d.ts.map +1 -1
  28. package/dist/device/motion.js +2 -1
  29. package/dist/device/motion.js.map +1 -1
  30. package/dist/device/plug.d.ts +7 -7
  31. package/dist/device/plug.d.ts.map +1 -1
  32. package/dist/device/plug.js +1 -1
  33. package/dist/device/plug.js.map +1 -1
  34. package/dist/device/striplight.d.ts.map +1 -1
  35. package/dist/device/striplight.js +7 -11
  36. package/dist/device/striplight.js.map +1 -1
  37. package/package.json +79 -79
  38. package/src/device/bot.ts +3 -3
  39. package/src/device/colorbulb.ts +169 -18
  40. package/src/device/contact.ts +9 -6
  41. package/src/device/curtain.ts +6 -2
  42. package/src/device/humidifier.ts +2 -1
  43. package/src/device/lock.ts +4 -3
  44. package/src/device/meter.ts +42 -32
  45. package/src/device/meterplus.ts +2 -1
  46. package/src/device/motion.ts +2 -1
  47. package/src/device/plug.ts +9 -9
  48. package/src/device/striplight.ts +8 -14
@@ -3,7 +3,20 @@ import { interval, Subject } from 'rxjs';
3
3
  import { SwitchBotPlatform } from '../platform';
4
4
  import { debounceTime, skipWhile, tap } from 'rxjs/operators';
5
5
  import { Service, PlatformAccessory, CharacteristicValue, ControllerConstructor, Controller, ControllerServiceMap } from 'homebridge';
6
- import { DeviceURL, device, devicesConfig, switchbot, deviceStatusResponse, payload, hs2rgb, rgb2hs, m2hs, deviceStatus } from '../settings';
6
+ import {
7
+ DeviceURL,
8
+ device,
9
+ devicesConfig,
10
+ switchbot,
11
+ deviceStatusResponse,
12
+ payload,
13
+ hs2rgb,
14
+ rgb2hs,
15
+ m2hs,
16
+ deviceStatus,
17
+ serviceData,
18
+ ad,
19
+ } from '../settings';
7
20
  import { Context } from 'vm';
8
21
 
9
22
  /**
@@ -35,10 +48,18 @@ export class ColorBulb {
35
48
  deviceStatus!: deviceStatusResponse;
36
49
 
37
50
  // BLE Others
51
+ connected?: boolean;
38
52
  switchbot!: switchbot;
53
+ address!: ad['address'];
54
+ SwitchToOpenAPI?: boolean;
55
+ serviceData!: serviceData;
56
+ state: serviceData['state'];
57
+ delay: serviceData['delay'];
58
+ wifiRssi: serviceData['wifiRssi'];
39
59
 
40
60
  // Config
41
61
  set_minStep?: number;
62
+ scanDuration!: number;
42
63
  deviceLogging!: string;
43
64
  deviceRefreshRate!: number;
44
65
  adaptiveLightingShift?: number;
@@ -86,7 +107,8 @@ export class ColorBulb {
86
107
  .setCharacteristic(this.platform.Characteristic.Model, 'W1401400')
87
108
  .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!)
88
109
  .setCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision(accessory, device))
89
- .getCharacteristic(this.platform.Characteristic.FirmwareRevision).updateValue(this.FirmwareRevision(accessory, device));
110
+ .getCharacteristic(this.platform.Characteristic.FirmwareRevision)
111
+ .updateValue(this.FirmwareRevision(accessory, device));
90
112
 
91
113
  // get the Lightbulb service if it exists, otherwise create a new Lightbulb service
92
114
  // you can create multiple services for each accessory
@@ -212,6 +234,27 @@ export class ColorBulb {
212
234
  }
213
235
 
214
236
  async parseStatus(): Promise<void> {
237
+ if (this.SwitchToOpenAPI || !this.device.ble) {
238
+ await this.openAPIparseStatus();
239
+ } else {
240
+ await this.BLEparseStatus();
241
+ }
242
+ }
243
+
244
+ async BLEparseStatus(): Promise<void> {
245
+ this.debugLog(`Color Bulb: ${this.accessory.displayName} BLE parseStatus`);
246
+ // State
247
+ switch (this.state) {
248
+ case 'on':
249
+ this.On = true;
250
+ break;
251
+ default:
252
+ this.On = false;
253
+ }
254
+ this.debugLog(`Color Bulb: ${this.accessory.displayName} On: ${this.On}`);
255
+ }
256
+
257
+ async openAPIparseStatus() {
215
258
  switch (this.power) {
216
259
  case 'on':
217
260
  this.On = true;
@@ -234,9 +277,7 @@ export class ColorBulb {
234
277
  this.debugLog(`Color Bulb: ${this.accessory.displayName} blue: ${JSON.stringify(blue)}`);
235
278
 
236
279
  const [hue, saturation] = rgb2hs(Number(red), Number(green), Number(blue));
237
- this.debugLog(
238
- `Color Bulb: ${this.accessory.displayName} hs: ${JSON.stringify(rgb2hs(Number(red), Number(green), Number(blue)))}`,
239
- );
280
+ this.debugLog(`Color Bulb: ${this.accessory.displayName} hs: ${JSON.stringify(rgb2hs(Number(red), Number(green), Number(blue)))}`);
240
281
 
241
282
  // Hue
242
283
  this.Hue = hue;
@@ -257,10 +298,126 @@ export class ColorBulb {
257
298
  this.ColorTemperature = Math.max(Math.min(this.ColorTemperature, 500), 140);
258
299
  this.debugLog(`Color Bulb: ${this.accessory.displayName} ColorTemperature: ${this.ColorTemperature}`);
259
300
  }
260
-
261
301
  }
262
302
 
263
303
  async refreshStatus(): Promise<void> {
304
+ if (this.device.ble) {
305
+ await this.BLERefreshStatus();
306
+ } else {
307
+ await this.openAPIRefreshStatus();
308
+ }
309
+ }
310
+
311
+ async BLERefreshStatus(): Promise<void> {
312
+ this.debugLog(`Color Bulb: ${this.accessory.displayName} BLE refreshStatus`);
313
+ const switchbot = await this.platform.connectBLE();
314
+ // Convert to BLE Address
315
+ this.device.bleMac = this.device
316
+ .deviceId!.match(/.{1,2}/g)!
317
+ .join(':')
318
+ .toLowerCase();
319
+ this.debugLog(`Color Bulb: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
320
+ this.getCustomBLEAddress(switchbot);
321
+ // Start to monitor advertisement packets
322
+ if (switchbot !== false) {
323
+ switchbot
324
+ .startScan({
325
+ model: 'u',
326
+ id: this.device.bleMac,
327
+ })
328
+ .then(() => {
329
+ // Set an event hander
330
+ switchbot.onadvertisement = (ad: any) => {
331
+ this.address = ad.address;
332
+ if (this.deviceLogging.includes('debug')) {
333
+ this.infoLog(this.address);
334
+ this.infoLog(this.device.bleMac);
335
+ this.infoLog(`Color Bulb: ${this.accessory.displayName} BLE Address Found: ${this.address}`);
336
+ this.infoLog(`Color Bulb: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac}`);
337
+ }
338
+ this.serviceData = ad.serviceData;
339
+ this.state = ad.serviceData.state;
340
+ this.delay = ad.serviceData.delay;
341
+ //this.timer = ad.serviceData.timer;
342
+ //this.syncUtcTime = ad.serviceData.syncUtcTime;
343
+ this.wifiRssi = ad.serviceData.wifiRssi;
344
+ //this.overload = ad.serviceData.overload;
345
+ //this.currentPower = ad.serviceData.currentPower;
346
+ this.debugLog(`Color Bulb: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
347
+ this.debugLog(
348
+ `Color Bulb: ${this.accessory.displayName} state: ${ad.serviceData.state}, ` +
349
+ `delay: ${ad.serviceData.delay}, timer: ${ad.serviceData.timer}, syncUtcTime: ${ad.serviceData.syncUtcTime} ` +
350
+ `wifiRssi: ${ad.serviceData.wifiRssi}, overload: ${ad.serviceData.overload}, currentPower: ${ad.serviceData.currentPower}`,
351
+ );
352
+
353
+ if (this.serviceData) {
354
+ this.connected = true;
355
+ this.debugLog(`Color Bulb: ${this.accessory.displayName} connected: ${this.connected}`);
356
+ } else {
357
+ this.connected = false;
358
+ this.debugLog(`Color Bulb: ${this.accessory.displayName} connected: ${this.connected}`);
359
+ }
360
+ };
361
+ // Wait 2 seconds
362
+ return switchbot.wait(this.scanDuration * 1000);
363
+ })
364
+ .then(async () => {
365
+ // Stop to monitor
366
+ switchbot.stopScan();
367
+ if (this.connected) {
368
+ this.parseStatus();
369
+ this.updateHomeKitCharacteristics();
370
+ } else {
371
+ await this.BLEconnection(switchbot);
372
+ }
373
+ })
374
+ .catch(async (e: any) => {
375
+ this.errorLog(`Color Bulb: ${this.accessory.displayName} failed refreshStatus with BLE Connection`);
376
+ if (this.deviceLogging.includes('debug')) {
377
+ this.errorLog(
378
+ `Color Bulb: ${this.accessory.displayName} failed refreshStatus with BLE Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
379
+ );
380
+ }
381
+ if (this.platform.config.credentials?.openToken) {
382
+ this.warnLog(`Color Bulb: ${this.accessory.displayName} Using OpenAPI Connection`);
383
+ this.SwitchToOpenAPI = true;
384
+ await this.openAPIRefreshStatus();
385
+ }
386
+ this.apiError(e);
387
+ });
388
+ } else {
389
+ await this.BLEconnection(switchbot);
390
+ }
391
+ }
392
+
393
+ async getCustomBLEAddress(switchbot: any) {
394
+ if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
395
+ (async () => {
396
+ // Start to monitor advertisement packets
397
+ await switchbot.startScan({
398
+ model: 'u',
399
+ });
400
+ // Set an event handler
401
+ switchbot.onadvertisement = (ad: any) => {
402
+ this.warnLog(JSON.stringify(ad, null, ' '));
403
+ };
404
+ await switchbot.wait(10000);
405
+ // Stop to monitor
406
+ switchbot.stopScan();
407
+ })();
408
+ }
409
+ }
410
+
411
+ async BLEconnection(switchbot: any): Promise<void> {
412
+ this.errorLog(`Color Bulb: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
413
+ if (this.platform.config.credentials?.openToken) {
414
+ this.warnLog(`Color Bulb: ${this.accessory.displayName} Using OpenAPI Connection`);
415
+ this.SwitchToOpenAPI = true;
416
+ await this.openAPIRefreshStatus();
417
+ }
418
+ }
419
+
420
+ private async openAPIRefreshStatus() {
264
421
  try {
265
422
  this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
266
423
  this.debugLog(`Color Bulb: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
@@ -275,8 +432,7 @@ export class ColorBulb {
275
432
  this.errorLog(`Color Bulb: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
276
433
  if (this.deviceLogging.includes('debug')) {
277
434
  this.errorLog(
278
- `Color Bulb: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,` +
279
- ` Error Message: ${JSON.stringify(e.message)}`,
435
+ `Color Bulb: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
280
436
  );
281
437
  }
282
438
  this.apiError(e);
@@ -339,8 +495,7 @@ export class ColorBulb {
339
495
  this.errorLog(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
340
496
  if (this.deviceLogging.includes('debug')) {
341
497
  this.errorLog(
342
- `Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` +
343
- ` Error Message: ${JSON.stringify(e.message)}`,
498
+ `Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
344
499
  );
345
500
  }
346
501
  this.apiError(e);
@@ -383,8 +538,7 @@ export class ColorBulb {
383
538
  this.errorLog(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
384
539
  if (this.deviceLogging.includes('debug')) {
385
540
  this.errorLog(
386
- `Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` +
387
- ` Error Message: ${JSON.stringify(e.message)}`,
541
+ `Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
388
542
  );
389
543
  }
390
544
  this.apiError(e);
@@ -423,8 +577,7 @@ export class ColorBulb {
423
577
  this.errorLog(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
424
578
  if (this.deviceLogging.includes('debug')) {
425
579
  this.errorLog(
426
- `Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` +
427
- ` Error Message: ${JSON.stringify(e.message)}`,
580
+ `Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
428
581
  );
429
582
  }
430
583
  this.apiError(e);
@@ -452,16 +605,14 @@ export class ColorBulb {
452
605
  this.BrightnessCached = this.Brightness;
453
606
  } else {
454
607
  this.debugLog(
455
- `Color Bulb: ${this.accessory.displayName} No Changes.` +
456
- `Brightness: ${this.Brightness}, BrightnessCached: ${this.BrightnessCached}`,
608
+ `Color Bulb: ${this.accessory.displayName} No Changes.` + `Brightness: ${this.Brightness}, BrightnessCached: ${this.BrightnessCached}`,
457
609
  );
458
610
  }
459
611
  } catch (e: any) {
460
612
  this.errorLog(`Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
461
613
  if (this.deviceLogging.includes('debug')) {
462
614
  this.errorLog(
463
- `Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` +
464
- ` Error Message: ${JSON.stringify(e.message)}`,
615
+ `Color Bulb: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
465
616
  );
466
617
  }
467
618
  this.apiError(e);
@@ -74,7 +74,8 @@ export class Contact {
74
74
  .setCharacteristic(this.platform.Characteristic.Model, 'W1201500')
75
75
  .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!)
76
76
  .setCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision(accessory, device))
77
- .getCharacteristic(this.platform.Characteristic.FirmwareRevision).updateValue(this.FirmwareRevision(accessory, device));
77
+ .getCharacteristic(this.platform.Characteristic.FirmwareRevision)
78
+ .updateValue(this.FirmwareRevision(accessory, device));
78
79
 
79
80
  // get the Contact service if it exists, otherwise create a new Contact service
80
81
  // you can create multiple services for each accessory
@@ -265,10 +266,12 @@ export class Contact {
265
266
  this.debugLog(`Contact Sensor: ${this.accessory.displayName} BLE refreshStatus`);
266
267
  const switchbot = await this.platform.connectBLE();
267
268
  // Convert to BLE Address
268
- this.device.bleMac = this.device.customBLEaddress || this.device
269
- .deviceId!.match(/.{1,2}/g)!
270
- .join(':')
271
- .toLowerCase();
269
+ this.device.bleMac =
270
+ this.device.customBLEaddress ||
271
+ this.device
272
+ .deviceId!.match(/.{1,2}/g)!
273
+ .join(':')
274
+ .toLowerCase();
272
275
  this.debugLog(`Contact Sensor: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
273
276
  this.getCustomBLEAddress(switchbot);
274
277
  // Start to monitor advertisement packets
@@ -296,7 +299,7 @@ export class Contact {
296
299
  this.debugLog(`Contact Sensor: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
297
300
  this.debugLog(
298
301
  `Contact Sensor: ${this.accessory.displayName} movement: ${ad.serviceData.movement}, doorState: ` +
299
- `${ad.serviceData.doorState}, lightLevel: ${ad.serviceData.lightLevel}, battery: ${ad.serviceData.battery}`,
302
+ `${ad.serviceData.doorState}, lightLevel: ${ad.serviceData.lightLevel}, battery: ${ad.serviceData.battery}`,
300
303
  );
301
304
 
302
305
  if (this.serviceData) {
@@ -90,7 +90,8 @@ export class Curtain {
90
90
  .setCharacteristic(this.platform.Characteristic.Model, 'W0701600')
91
91
  .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId)
92
92
  .setCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision(accessory, device))
93
- .getCharacteristic(this.platform.Characteristic.FirmwareRevision).updateValue(this.FirmwareRevision(accessory, device));
93
+ .getCharacteristic(this.platform.Characteristic.FirmwareRevision)
94
+ .updateValue(this.FirmwareRevision(accessory, device));
94
95
 
95
96
  // get the WindowCovering service if it exists, otherwise create a new WindowCovering service
96
97
  // you can create multiple services for each accessory
@@ -212,7 +213,10 @@ export class Curtain {
212
213
  * 'homebridge-switchbot/curtain/xx:xx:xx:xx:xx:xx'
213
214
  */
214
215
  mqttPublish(topic: string, message: any) {
215
- const mac = this.device.deviceId?.toLowerCase().match(/[\s\S]{1,2}/g)?.join(':');
216
+ const mac = this.device.deviceId
217
+ ?.toLowerCase()
218
+ .match(/[\s\S]{1,2}/g)
219
+ ?.join(':');
216
220
  const options = this.device.mqttPubOptions || {};
217
221
  this.mqttClient?.publish(`homebridge-switchbot/curtain/${mac}/${topic}`, `${message}`, options);
218
222
  this.debugLog(`Meter: ${this.accessory.displayName} MQTT message: ${topic}/${message} options:${JSON.stringify(options)}`);
@@ -80,7 +80,8 @@ export class Humidifier {
80
80
  .setCharacteristic(this.platform.Characteristic.Model, 'W0801800')
81
81
  .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!)
82
82
  .setCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision(accessory, device))
83
- .getCharacteristic(this.platform.Characteristic.FirmwareRevision).updateValue(this.FirmwareRevision(accessory, device));
83
+ .getCharacteristic(this.platform.Characteristic.FirmwareRevision)
84
+ .updateValue(this.FirmwareRevision(accessory, device));
84
85
 
85
86
  // get the service if it exists, otherwise create a new service
86
87
  // you can create multiple services for each accessory
@@ -56,7 +56,8 @@ export class Lock {
56
56
  .setCharacteristic(this.platform.Characteristic.Model, 'W1601700')
57
57
  .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!)
58
58
  .setCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision(accessory, device))
59
- .getCharacteristic(this.platform.Characteristic.FirmwareRevision).updateValue(this.FirmwareRevision(accessory, device));
59
+ .getCharacteristic(this.platform.Characteristic.FirmwareRevision)
60
+ .updateValue(this.FirmwareRevision(accessory, device));
60
61
 
61
62
  // get the LockMechanism service if it exists, otherwise create a new LockMechanism service
62
63
  // you can create multiple services for each accessory
@@ -187,7 +188,7 @@ export class Lock {
187
188
 
188
189
  this.infoLog(
189
190
  `Lock: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},` +
190
- ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`,
191
+ ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`,
191
192
  );
192
193
 
193
194
  // Make the API request
@@ -254,7 +255,7 @@ export class Lock {
254
255
  case 190:
255
256
  this.errorLog(
256
257
  `Lock: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
257
- ` Or command: ${JSON.stringify(push.data)} format is invalid`,
258
+ ` Or command: ${JSON.stringify(push.data)} format is invalid`,
258
259
  );
259
260
  break;
260
261
  case 100:
@@ -6,7 +6,7 @@ import { DeviceURL, device, devicesConfig, serviceData, ad, switchbot, deviceSta
6
6
  import { Context } from 'vm';
7
7
  import { MqttClient } from 'mqtt';
8
8
  import { connectAsync } from 'async-mqtt';
9
- import { hostname } from "os";
9
+ import { hostname } from 'os';
10
10
 
11
11
  /**
12
12
  * Platform Accessory
@@ -56,7 +56,7 @@ export class Meter {
56
56
 
57
57
  //MQTT stuff
58
58
  mqttClient: MqttClient | null = null;
59
-
59
+
60
60
  // EVE history service handler
61
61
  historyService: any;
62
62
 
@@ -93,7 +93,8 @@ export class Meter {
93
93
  .setCharacteristic(this.platform.Characteristic.Model, 'METERTH-S1')
94
94
  .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!)
95
95
  .setCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision(accessory, device))
96
- .getCharacteristic(this.platform.Characteristic.FirmwareRevision).updateValue(this.FirmwareRevision(accessory, device));
96
+ .getCharacteristic(this.platform.Characteristic.FirmwareRevision)
97
+ .updateValue(this.FirmwareRevision(accessory, device));
97
98
 
98
99
  // Temperature Sensor Service
99
100
  if (device.meter?.hide_temperature) {
@@ -182,7 +183,10 @@ export class Meter {
182
183
  * 'homebridge-switchbot/meter/xx:xx:xx:xx:xx:xx'
183
184
  */
184
185
  mqttPublish(message: any) {
185
- const mac = this.device.deviceId?.toLowerCase().match(/[\s\S]{1,2}/g)?.join(':');
186
+ const mac = this.device.deviceId
187
+ ?.toLowerCase()
188
+ .match(/[\s\S]{1,2}/g)
189
+ ?.join(':');
186
190
  const options = this.device.mqttPubOptions || {};
187
191
  this.mqttClient?.publish(`homebridge-switchbot/meter/${mac}`, `${message}`, options);
188
192
  this.debugLog(`Meter: ${this.accessory.displayName} MQTT message: ${message} options:${JSON.stringify(options)}`);
@@ -194,14 +198,14 @@ export class Meter {
194
198
  async setupMqtt(device: device & devicesConfig): Promise<void> {
195
199
  if (device.mqttURL) {
196
200
  try {
197
- this.mqttClient = await connectAsync(device.mqttURL, device.mqttOptions || {});
198
- this.debugLog(`Meter: ${this.accessory.displayName} MQTT connection has been established successfully.`)
199
- this.mqttClient.on('error', (e: Error) => {
200
- this.errorLog(`Meter: ${this.accessory.displayName} Failed to publish MQTT messages. ${e}`)
201
- });
201
+ this.mqttClient = await connectAsync(device.mqttURL, device.mqttOptions || {});
202
+ this.debugLog(`Meter: ${this.accessory.displayName} MQTT connection has been established successfully.`);
203
+ this.mqttClient.on('error', (e: Error) => {
204
+ this.errorLog(`Meter: ${this.accessory.displayName} Failed to publish MQTT messages. ${e}`);
205
+ });
202
206
  } catch (e) {
203
- this.mqttClient = null;
204
- this.errorLog(`Meter: ${this.accessory.displayName} Failed to establish MQTT connection. ${e}`)
207
+ this.mqttClient = null;
208
+ this.errorLog(`Meter: ${this.accessory.displayName} Failed to establish MQTT connection. ${e}`);
205
209
  }
206
210
  }
207
211
  }
@@ -210,15 +214,19 @@ export class Meter {
210
214
  * Setup EVE history graph feature if enabled.
211
215
  */
212
216
  async setupHistoryService(device: device & devicesConfig): Promise<void> {
213
- const mac = this.device.deviceId!.match(/.{1,2}/g)!.join(':').toLowerCase();
214
- this.historyService = device.history ?
215
- new this.platform.fakegatoAPI('room', this.accessory,
216
- {log: this.platform.log, storage: 'fs',
217
- filename: `${hostname().split(".")[0]}_${mac}_persist.json`
218
- }) :
219
- null;
217
+ const mac = this.device
218
+ .deviceId!.match(/.{1,2}/g)!
219
+ .join(':')
220
+ .toLowerCase();
221
+ this.historyService = device.history
222
+ ? new this.platform.fakegatoAPI('room', this.accessory, {
223
+ log: this.platform.log,
224
+ storage: 'fs',
225
+ filename: `${hostname().split('.')[0]}_${mac}_persist.json`,
226
+ })
227
+ : null;
220
228
  }
221
-
229
+
222
230
  /**
223
231
  * Parse the device status from the SwitchBot api
224
232
  */
@@ -240,7 +248,7 @@ export class Meter {
240
248
  } else {
241
249
  this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
242
250
  }
243
- this.debugLog(`Meter: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}, StatusLowBattery: ${this.StatusLowBattery}`);
251
+ this.debugLog(`Meter: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}, StatusLowBattery: ${this.StatusLowBattery}`);
244
252
 
245
253
  // Humidity
246
254
  if (!this.device.meter?.hide_humidity) {
@@ -314,12 +322,13 @@ export class Meter {
314
322
  this.infoLog(`Meter: ${this.accessory.displayName} BLE Address Found: ${this.address}`);
315
323
  this.infoLog(`Meter: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac}`);
316
324
  }
317
- if (ad.serviceData.humidity! > 0) { // reject unreliable data
325
+ if (ad.serviceData.humidity! > 0) {
326
+ // reject unreliable data
318
327
  this.serviceData = ad.serviceData;
319
328
  this.temperature = ad.serviceData.temperature!.c;
320
329
  this.humidity = ad.serviceData.humidity;
321
330
  this.battery = ad.serviceData.battery;
322
- }
331
+ }
323
332
  this.debugLog(`Meter: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
324
333
  this.debugLog(
325
334
  `Meter: ${this.accessory.displayName} model: ${ad.serviceData.model}, modelName: ${ad.serviceData.modelName}, ` +
@@ -420,16 +429,16 @@ export class Meter {
420
429
  * Updates the status for each of the HomeKit Characteristics
421
430
  */
422
431
  async updateHomeKitCharacteristics(): Promise<void> {
423
- let mqttmessage: string[] = [];
424
- let entry = {time: Math.round(new Date().valueOf()/1000)};
432
+ const mqttmessage: string[] = [];
433
+ const entry = { time: Math.round(new Date().valueOf() / 1000) };
425
434
  if (!this.device.meter?.hide_humidity) {
426
435
  if (this.CurrentRelativeHumidity === undefined) {
427
436
  this.debugLog(`Meter: ${this.accessory.displayName} CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
428
437
  } else {
429
438
  this.humidityservice?.updateCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity, this.CurrentRelativeHumidity);
430
439
  this.debugLog(`Meter: ${this.accessory.displayName} updateCharacteristic CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
431
- mqttmessage.push(`"humidity": ${this.CurrentRelativeHumidity}`);
432
- entry["humidity"] = this.CurrentRelativeHumidity;
440
+ mqttmessage.push(`"humidity": ${this.CurrentRelativeHumidity}`);
441
+ entry['humidity'] = this.CurrentRelativeHumidity;
433
442
  }
434
443
  }
435
444
  if (!this.device.meter?.hide_temperature) {
@@ -438,8 +447,8 @@ export class Meter {
438
447
  } else {
439
448
  this.temperatureservice?.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, this.CurrentTemperature);
440
449
  this.debugLog(`Meter: ${this.accessory.displayName} updateCharacteristic CurrentTemperature: ${this.CurrentTemperature}`);
441
- mqttmessage.push(`"temperature": ${this.CurrentTemperature}`);
442
- entry["temp"] = this.CurrentTemperature;
450
+ mqttmessage.push(`"temperature": ${this.CurrentTemperature}`);
451
+ entry['temp'] = this.CurrentTemperature;
443
452
  }
444
453
  }
445
454
  if (this.device.ble) {
@@ -448,18 +457,19 @@ export class Meter {
448
457
  } else {
449
458
  this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.BatteryLevel);
450
459
  this.debugLog(`Meter: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
451
- mqttmessage.push(`"battery": ${this.BatteryLevel}`);
460
+ mqttmessage.push(`"battery": ${this.BatteryLevel}`);
452
461
  }
453
462
  if (this.StatusLowBattery === undefined) {
454
463
  this.debugLog(`Meter: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
455
464
  } else {
456
465
  this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.StatusLowBattery);
457
466
  this.debugLog(`Meter: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
458
- mqttmessage.push(`"lowBattery": ${this.StatusLowBattery}`);
467
+ mqttmessage.push(`"lowBattery": ${this.StatusLowBattery}`);
459
468
  }
460
469
  }
461
- this.mqttPublish(`{${mqttmessage.join(',')}}`)
462
- if (this.CurrentRelativeHumidity > 0) { // reject unreliable data
470
+ this.mqttPublish(`{${mqttmessage.join(',')}}`);
471
+ if (this.CurrentRelativeHumidity > 0) {
472
+ // reject unreliable data
463
473
  this.historyService?.addEntry(entry);
464
474
  }
465
475
  }
@@ -82,7 +82,8 @@ export class MeterPlus {
82
82
  .setCharacteristic(this.platform.Characteristic.Model, this.model(device))
83
83
  .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!)
84
84
  .setCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision(accessory, device))
85
- .getCharacteristic(this.platform.Characteristic.FirmwareRevision).updateValue(this.FirmwareRevision(accessory, device));
85
+ .getCharacteristic(this.platform.Characteristic.FirmwareRevision)
86
+ .updateValue(this.FirmwareRevision(accessory, device));
86
87
 
87
88
  // Temperature Sensor Service
88
89
  if (device.meter?.hide_temperature) {
@@ -70,7 +70,8 @@ export class Motion {
70
70
  .setCharacteristic(this.platform.Characteristic.Model, 'W1101500')
71
71
  .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!)
72
72
  .setCharacteristic(this.platform.Characteristic.FirmwareRevision, this.FirmwareRevision(accessory, device))
73
- .getCharacteristic(this.platform.Characteristic.FirmwareRevision).updateValue(this.FirmwareRevision(accessory, device));
73
+ .getCharacteristic(this.platform.Characteristic.FirmwareRevision)
74
+ .updateValue(this.FirmwareRevision(accessory, device));
74
75
 
75
76
  // get the Battery service if it exists, otherwise create a new Motion service
76
77
  // you can create multiple services for each accessory
@@ -21,9 +21,16 @@ export class Plug {
21
21
  // BLE Others
22
22
  connected?: boolean;
23
23
  switchbot!: switchbot;
24
+ address!: ad['address'];
24
25
  SwitchToOpenAPI?: boolean;
25
26
  serviceData!: serviceData;
26
- address!: ad['address'];
27
+ state: serviceData['state'];
28
+ delay: serviceData['delay'];
29
+ timer: serviceData['timer'];
30
+ wifiRssi: serviceData['wifiRssi'];
31
+ overload: serviceData['overload'];
32
+ syncUtcTime: serviceData['syncUtcTime'];
33
+ currentPower: serviceData['currentPower'];
27
34
 
28
35
  // Config
29
36
  scanDuration!: number;
@@ -33,13 +40,6 @@ export class Plug {
33
40
  // Updates
34
41
  plugUpdateInProgress!: boolean;
35
42
  doPlugUpdate!: Subject<void>;
36
- state: serviceData['state'];
37
- delay: serviceData['delay'];
38
- timer: serviceData['timer'];
39
- syncUtcTime: serviceData['syncUtcTime'];
40
- wifiRssi: serviceData['wifiRssi'];
41
- overload: serviceData['overload'];
42
- currentPower: serviceData['currentPower'];
43
43
 
44
44
  constructor(private readonly platform: SwitchBotPlatform, private accessory: PlatformAccessory, public device: device & devicesConfig) {
45
45
  // default placeholders
@@ -271,7 +271,7 @@ export class Plug {
271
271
  }
272
272
 
273
273
  async BLEconnection(switchbot: any): Promise<void> {
274
- this.errorLog(`Plug: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchPlug: ${switchbot}`);
274
+ this.errorLog(`Plug: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
275
275
  if (this.platform.config.credentials?.openToken) {
276
276
  this.warnLog(`Plug: ${this.accessory.displayName} Using OpenAPI Connection`);
277
277
  this.SwitchToOpenAPI = true;