@switchbot/homebridge-switchbot 1.7.1-beta.4 → 1.7.1-beta.8

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 (42) hide show
  1. package/config.schema.json +45 -32
  2. package/dist/devices/bots.d.ts +2 -2
  3. package/dist/devices/bots.d.ts.map +1 -1
  4. package/dist/devices/bots.js +10 -28
  5. package/dist/devices/bots.js.map +1 -1
  6. package/dist/devices/colorbulb.d.ts +5 -1
  7. package/dist/devices/colorbulb.d.ts.map +1 -1
  8. package/dist/devices/colorbulb.js +12 -8
  9. package/dist/devices/colorbulb.js.map +1 -1
  10. package/dist/devices/contact.d.ts +4 -2
  11. package/dist/devices/contact.d.ts.map +1 -1
  12. package/dist/devices/contact.js +13 -34
  13. package/dist/devices/contact.js.map +1 -1
  14. package/dist/devices/curtains.d.ts +5 -2
  15. package/dist/devices/curtains.d.ts.map +1 -1
  16. package/dist/devices/curtains.js +11 -6
  17. package/dist/devices/curtains.js.map +1 -1
  18. package/dist/devices/humidifiers.d.ts +7 -2
  19. package/dist/devices/humidifiers.d.ts.map +1 -1
  20. package/dist/devices/humidifiers.js +22 -35
  21. package/dist/devices/humidifiers.js.map +1 -1
  22. package/dist/devices/meters.d.ts +12 -12
  23. package/dist/devices/meters.d.ts.map +1 -1
  24. package/dist/devices/meters.js +49 -100
  25. package/dist/devices/meters.js.map +1 -1
  26. package/dist/devices/motion.d.ts +3 -4
  27. package/dist/devices/motion.d.ts.map +1 -1
  28. package/dist/devices/motion.js +5 -27
  29. package/dist/devices/motion.js.map +1 -1
  30. package/dist/devices/plugs.d.ts +2 -1
  31. package/dist/devices/plugs.d.ts.map +1 -1
  32. package/dist/devices/plugs.js +2 -1
  33. package/dist/devices/plugs.js.map +1 -1
  34. package/package.json +1 -1
  35. package/src/devices/bots.ts +12 -30
  36. package/src/devices/colorbulb.ts +17 -9
  37. package/src/devices/contact.ts +17 -35
  38. package/src/devices/curtains.ts +16 -8
  39. package/src/devices/humidifiers.ts +29 -36
  40. package/src/devices/meters.ts +63 -110
  41. package/src/devices/motion.ts +8 -30
  42. package/src/devices/plugs.ts +4 -2
@@ -2,7 +2,7 @@ import { interval, Subject } from 'rxjs';
2
2
  import { skipWhile } from 'rxjs/operators';
3
3
  import { SwitchBotPlatform } from '../platform';
4
4
  import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
5
- import { DeviceURL, device, devicesConfig, serviceData, switchbot, deviceStatusResponse } from '../settings';
5
+ import { DeviceURL, device, devicesConfig, serviceData, switchbot, deviceStatusResponse, deviceStatus } from '../settings';
6
6
 
7
7
  /**
8
8
  * Platform Accessory
@@ -24,6 +24,9 @@ export class Contact {
24
24
  StatusLowBattery!: CharacteristicValue;
25
25
 
26
26
  // OpenAPI others
27
+ openState: deviceStatus['openState'];
28
+ moveDetected: deviceStatus['moveDetected'];
29
+ brightness: deviceStatus['brightness'];
27
30
  deviceStatus!: deviceStatusResponse;
28
31
 
29
32
  // BLE Others
@@ -133,7 +136,7 @@ export class Contact {
133
136
  this.debugLog(`Contact Sensor: ${accessory.displayName} Removing Battery Service`);
134
137
  this.batteryService = this.accessory.getService(this.platform.Service.Battery);
135
138
  accessory.removeService(this.batteryService!);
136
- } else if (!this.batteryService) {
139
+ } else if (device.ble && !this.batteryService) {
137
140
  this.debugLog(`Contact Sensor: ${accessory.displayName} Add Battery Service`);
138
141
  (this.batteryService =
139
142
  this.accessory.getService(this.platform.Service.Battery) ||
@@ -287,27 +290,25 @@ export class Contact {
287
290
  if (this.platform.config.credentials?.openToken) {
288
291
  this.debugLog(`Contact Sensor: ${this.accessory.displayName} OpenAPI parseStatus`);
289
292
  // Contact State
290
- if (this.deviceStatus.body.openState === 'open') {
293
+ if (this.openState === 'open') {
291
294
  this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
292
295
  this.debugLog(`Contact Sensor: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensorState}`);
293
- } else if (this.deviceStatus.body.openState === 'close') {
296
+ } else if (this.openState === 'close') {
294
297
  this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_DETECTED;
295
298
  this.debugLog(`Contact Sensor: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensorState}`);
296
299
  } else {
297
- this.debugLog(`Contact Sensor: ${this.accessory.displayName} openState: ${this.deviceStatus.body.openState}`);
300
+ this.debugLog(`Contact Sensor: ${this.accessory.displayName} openState: ${this.openState}`);
298
301
  }
299
302
  // Motion State
300
303
  if (!this.device.contact?.hide_motionsensor) {
301
- if (typeof this.deviceStatus.body.moveDetected === 'boolean') {
302
- this.MotionDetected = this.deviceStatus.body.moveDetected;
303
- }
304
+ this.MotionDetected = this.moveDetected!;
304
305
  this.debugLog(`Contact Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
305
306
  }
306
307
  // Light Level
307
308
  if (!this.device.contact?.hide_lightsensor) {
308
309
  this.set_minLux = this.minLux();
309
310
  this.set_maxLux = this.maxLux();
310
- switch (this.deviceStatus.body.brightness) {
311
+ switch (this.brightness) {
311
312
  case 'dim':
312
313
  this.CurrentAmbientLightLevel = this.set_minLux;
313
314
  break;
@@ -331,34 +332,12 @@ export class Contact {
331
332
  }
332
333
  }
333
334
 
334
- public async connectBLE() {
335
- let switchbot: any;
336
- try {
337
- // eslint-disable-next-line @typescript-eslint/no-var-requires
338
- const Switchbot = require('node-switchbot');
339
- switchbot = new Switchbot();
340
- // Convert to BLE Address
341
- this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
342
- this.debugLog(`Contact Sensor: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
343
- } catch (e: any) {
344
- switchbot = false;
345
- this.errorLog(`Contact Sensor: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot}`);
346
- if (this.deviceLogging === 'debug') {
347
- this.errorLog(`Contact Sensor: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot},`
348
- + ` Error Message: ${JSON.stringify(e.message)}`);
349
- }
350
- if (this.platform.debugMode) {
351
- this.errorLog(`Contact Sensor: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot},`
352
- + ` Error: ${JSON.stringify(e)}`);
353
- }
354
- }
355
- return switchbot;
356
- }
357
-
358
335
  private async BLERefreshStatus() {
359
336
  this.debugLog(`Contact Sensor: ${this.accessory.displayName} BLE refreshStatus`);
360
- // eslint-disable-next-line @typescript-eslint/no-var-requires
361
- const switchbot = await this.connectBLE();
337
+ const switchbot = await this.platform.connectBLE();
338
+ // Convert to BLE Address
339
+ this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
340
+ this.debugLog(`Curtain: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
362
341
  // Start to monitor advertisement packets
363
342
  if (switchbot !== false) {
364
343
  switchbot.startScan({
@@ -436,6 +415,9 @@ export class Contact {
436
415
  try {
437
416
  this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
438
417
  this.debugLog(`Contact Sensor: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
418
+ this.openState = this.deviceStatus.body.openState;
419
+ this.moveDetected = this.deviceStatus.body.moveDetected;
420
+ this.brightness = this.deviceStatus.body.brightness;
439
421
  this.parseStatus();
440
422
  this.updateHomeKitCharacteristics();
441
423
  } catch (e: any) {
@@ -4,7 +4,7 @@ import { interval, Subject } from 'rxjs';
4
4
  import { SwitchBotPlatform } from '../platform';
5
5
  import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
6
6
  import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
7
- import { DeviceURL, device, devicesConfig, serviceData, switchbot, deviceStatusResponse, payload } from '../settings';
7
+ import { DeviceURL, device, devicesConfig, serviceData, switchbot, deviceStatusResponse, payload, deviceStatus } from '../settings';
8
8
 
9
9
  export class Curtain {
10
10
  // Services
@@ -22,17 +22,20 @@ export class Curtain {
22
22
 
23
23
  // OpenAPI Others
24
24
  deviceStatus!: deviceStatusResponse;
25
+ slidePosition: deviceStatus['slidePosition'];
26
+ moving: deviceStatus['moving'];
27
+ brightness: deviceStatus['brightness'];
25
28
 
26
29
  // BLE Others
27
30
  connected?: boolean;
28
31
  switchbot!: switchbot;
29
32
  SwitchToOpenAPI?: boolean;
30
33
  serviceData!: serviceData;
34
+ spaceBetweenLevels!: number;
31
35
  calibration: serviceData['calibration'];
32
36
  battery: serviceData['battery'];
33
37
  position: serviceData['position'];
34
38
  lightLevel: serviceData['lightLevel'];
35
- spaceBetweenLevels!: number;
36
39
 
37
40
  // Target
38
41
  setNewTarget!: boolean;
@@ -148,7 +151,7 @@ export class Curtain {
148
151
  this.debugLog(`Curtain: ${accessory.displayName} Removing Battery Service`);
149
152
  this.batteryService = this.accessory.getService(this.platform.Service.Battery);
150
153
  accessory.removeService(this.batteryService!);
151
- } else if (!this.batteryService) {
154
+ } else if (device.ble && !this.batteryService) {
152
155
  this.debugLog(`Curtain: ${accessory.displayName} Add Battery Service`);
153
156
  (this.batteryService =
154
157
  this.accessory.getService(this.platform.Service.Battery) ||
@@ -311,6 +314,7 @@ export class Curtain {
311
314
 
312
315
  private async BLEparseStatus() {
313
316
  this.debugLog(`Curtain: ${this.accessory.displayName} BLE parseStatus`);
317
+ // CurrentPosition
314
318
  this.setMinMax();
315
319
  this.CurrentPosition = 100 - Number(this.position);
316
320
  this.debugLog(`Curtain: ${this.accessory.displayName} CurrentPosition ${this.CurrentPosition}`);
@@ -336,6 +340,7 @@ export class Curtain {
336
340
  // If Curtain calibration distance is short, there will be an error between the current percentage and the target percentage.
337
341
  this.TargetPosition = this.CurrentPosition;
338
342
  this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
343
+ this.debugLog(`Curtain: ${this.accessory.displayName} Stopped`);
339
344
  }
340
345
  }
341
346
  this.debugLog(`Curtain: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition},`
@@ -411,13 +416,13 @@ export class Curtain {
411
416
  this.debugLog(`Curtain: ${this.accessory.displayName} OpenAPI parseStatus`);
412
417
  // CurrentPosition
413
418
  this.setMinMax();
414
- this.CurrentPosition = 100 - this.deviceStatus.body.slidePosition!;
419
+ this.CurrentPosition = 100 - Number(this.slidePosition);
415
420
  this.debugLog(`Curtain ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition}`);
416
421
  if (this.setNewTarget) {
417
- this.infoLog(`Checking ${this.accessory.displayName} Status ...`);
422
+ this.infoLog(`Curtain: ${this.accessory.displayName} Checking Status ...`);
418
423
  }
419
424
 
420
- if (this.deviceStatus.body.moving) {
425
+ if (this.setNewTarget && this.moving) {
421
426
  this.setMinMax();
422
427
  if (this.TargetPosition > this.CurrentPosition) {
423
428
  this.debugLog(`Curtain: ${this.accessory.displayName} Closing, CurrentPosition: ${this.CurrentPosition} `);
@@ -435,6 +440,7 @@ export class Curtain {
435
440
  /*If Curtain calibration distance is short, there will be an error between the current percentage and the target percentage.*/
436
441
  this.TargetPosition = this.CurrentPosition;
437
442
  this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
443
+ this.debugLog(`Curtain: ${this.accessory.displayName} Stopped`);
438
444
  }
439
445
  }
440
446
  this.debugLog(`Curtain: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition},`
@@ -444,7 +450,7 @@ export class Curtain {
444
450
  this.set_minLux = this.minLux();
445
451
  this.set_maxLux = this.maxLux();
446
452
  // Brightness
447
- switch (this.deviceStatus.body.brightness) {
453
+ switch (this.brightness) {
448
454
  case 'dim':
449
455
  this.CurrentAmbientLightLevel = this.set_minLux;
450
456
  break;
@@ -467,7 +473,6 @@ export class Curtain {
467
473
 
468
474
  private async BLERefreshStatus() {
469
475
  this.debugLog(`Curtain: ${this.accessory.displayName} BLE refreshStatus`);
470
- // eslint-disable-next-line @typescript-eslint/no-var-requires
471
476
  const switchbot = await this.platform.connectBLE();
472
477
  // Convert to BLE Address
473
478
  this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
@@ -550,6 +555,9 @@ export class Curtain {
550
555
  try {
551
556
  this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
552
557
  this.debugLog(`Curtain: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
558
+ this.slidePosition = this.deviceStatus.body.slidePosition;
559
+ this.moving = this.deviceStatus.body.moving;
560
+ this.brightness = this.deviceStatus.body.brightness;
553
561
  this.parseStatus();
554
562
  this.updateHomeKitCharacteristics();
555
563
  } catch (e: any) {
@@ -3,7 +3,7 @@ import { interval, Subject } from 'rxjs';
3
3
  import { SwitchBotPlatform } from '../platform';
4
4
  import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
5
5
  import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
6
- import { DeviceURL, device, devicesConfig, serviceData, ad, deviceStatusResponse, payload } from '../settings';
6
+ import { DeviceURL, device, devicesConfig, serviceData, ad, deviceStatusResponse, payload, deviceStatus } from '../settings';
7
7
 
8
8
  /**
9
9
  * Platform Accessory
@@ -25,6 +25,12 @@ export class Humidifier {
25
25
  WaterLevel!: CharacteristicValue;
26
26
 
27
27
  // OpenAPI
28
+ auto: deviceStatus['auto'];
29
+ power: deviceStatus['power'];
30
+ humidity: deviceStatus['humidity'];
31
+ lackWater: deviceStatus['lackWater'];
32
+ temperature: deviceStatus['temperature'];
33
+ nebulizationEfficiency: deviceStatus['nebulizationEfficiency'];
28
34
  deviceStatus!: deviceStatusResponse;
29
35
 
30
36
  // BLE Others
@@ -276,15 +282,15 @@ export class Humidifier {
276
282
  if (this.platform.config.credentials?.openToken) {
277
283
  this.debugLog(`Humidifier: ${this.accessory.displayName} OpenAPI parseStatus`);
278
284
  // Current Relative Humidity
279
- this.CurrentRelativeHumidity = this.deviceStatus.body.humidity!;
285
+ this.CurrentRelativeHumidity = this.humidity!;
280
286
  this.debugLog(`Humidifier: ${this.accessory.displayName} CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
281
287
  // Current Temperature
282
288
  if (!this.device.humidifier?.hide_temperature) {
283
- this.CurrentTemperature = Number(this.deviceStatus.body.temperature);
289
+ this.CurrentTemperature = this.temperature!;
284
290
  this.debugLog(`Humidifier: ${this.accessory.displayName} CurrentTemperature: ${this.CurrentTemperature}`);
285
291
  }
286
292
  // Target Humidifier Dehumidifier State
287
- switch (this.deviceStatus.body.auto) {
293
+ switch (this.auto) {
288
294
  case true:
289
295
  this.TargetHumidifierDehumidifierState = this.platform.Characteristic.TargetHumidifierDehumidifierState.HUMIDIFIER_OR_DEHUMIDIFIER;
290
296
  this.CurrentHumidifierDehumidifierState = this.platform.Characteristic.CurrentHumidifierDehumidifierState.HUMIDIFYING;
@@ -292,10 +298,10 @@ export class Humidifier {
292
298
  break;
293
299
  default:
294
300
  this.TargetHumidifierDehumidifierState = this.platform.Characteristic.TargetHumidifierDehumidifierState.HUMIDIFIER;
295
- if (this.deviceStatus.body.nebulizationEfficiency! > 100) {
301
+ if (this.nebulizationEfficiency! > 100) {
296
302
  this.RelativeHumidityHumidifierThreshold = 100;
297
303
  } else {
298
- this.RelativeHumidityHumidifierThreshold = this.deviceStatus.body.nebulizationEfficiency!;
304
+ this.RelativeHumidityHumidifierThreshold = this.nebulizationEfficiency!;
299
305
  }
300
306
  if (this.CurrentRelativeHumidity > this.RelativeHumidityHumidifierThreshold) {
301
307
  this.CurrentHumidifierDehumidifierState = this.platform.Characteristic.CurrentHumidifierDehumidifierState.IDLE;
@@ -310,7 +316,7 @@ export class Humidifier {
310
316
  + ` RelativeHumidityHumidifierThreshold: ${this.RelativeHumidityHumidifierThreshold}`);
311
317
  this.debugLog(`Humidifier: ${this.accessory.displayName} CurrentHumidifierDehumidifierState: ${this.CurrentHumidifierDehumidifierState}`);
312
318
  // Active
313
- switch (this.deviceStatus.body.power) {
319
+ switch (this.power) {
314
320
  case 'on':
315
321
  this.Active = this.platform.Characteristic.Active.ACTIVE;
316
322
  break;
@@ -319,7 +325,7 @@ export class Humidifier {
319
325
  }
320
326
  this.debugLog(`Humidifier: ${this.accessory.displayName} Active: ${this.Active}`);
321
327
  // Water Level
322
- if (this.deviceStatus.body.lackWater) {
328
+ if (this.lackWater) {
323
329
  this.WaterLevel = 0;
324
330
  } else {
325
331
  this.WaterLevel = 100;
@@ -339,34 +345,12 @@ export class Humidifier {
339
345
  }
340
346
  }
341
347
 
342
- public async connectBLE() {
343
- let switchbot: any;
344
- try {
345
- // eslint-disable-next-line @typescript-eslint/no-var-requires
346
- const Switchbot = require('node-switchbot');
347
- switchbot = new Switchbot();
348
- // Convert to BLE Address
349
- this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
350
- this.debugLog(`Humidifier: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
351
- } catch (e: any) {
352
- switchbot = false;
353
- this.errorLog(`Humidifier: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot}`);
354
- if (this.deviceLogging === 'debug') {
355
- this.errorLog(`Humidifier: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot},`
356
- + ` Error Message: ${JSON.stringify(e.message)}`);
357
- }
358
- if (this.platform.debugMode) {
359
- this.errorLog(`Humidifier: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot},`
360
- + ` Error: ${JSON.stringify(e)}`);
361
- }
362
- }
363
- return switchbot;
364
- }
365
-
366
348
  private async BLERefreshStatus() {
367
349
  this.debugLog(`Humidifier: ${this.accessory.displayName} BLE refreshStatus`);
368
- // eslint-disable-next-line @typescript-eslint/no-var-requires
369
- const switchbot = await this.connectBLE();
350
+ const switchbot = await this.platform.connectBLE();
351
+ // Convert to BLE Address
352
+ this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
353
+ this.debugLog(`Curtain: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
370
354
  // Start to monitor advertisement packets
371
355
  if (switchbot !== false) {
372
356
  switchbot.startScan({
@@ -438,10 +422,16 @@ export class Humidifier {
438
422
  this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
439
423
  if (this.deviceStatus.message === 'success') {
440
424
  this.debugLog(`Humidifier: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
425
+ this.auto = this.deviceStatus.body.auto;
426
+ this.power = this.deviceStatus.body.power;
427
+ this.lackWater = this.deviceStatus.body.lackWater;
428
+ this.humidity = this.deviceStatus.body.humidity;
429
+ this.temperature = this.deviceStatus.body.temperature;
430
+ this.nebulizationEfficiency = this.deviceStatus.body.nebulizationEfficiency;
441
431
  this.parseStatus();
442
432
  this.updateHomeKitCharacteristics();
443
433
  } else {
444
- this.debugLog(this.deviceStatus);
434
+ this.errorLog(`Humidifier: ${this.accessory.displayName} message: ${JSON.stringify(this.deviceStatus.message)}`);
445
435
  }
446
436
  } catch (e: any) {
447
437
  this.errorLog(`Humidifier: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
@@ -477,7 +467,10 @@ export class Humidifier {
477
467
 
478
468
  private async BLEpushChanges() {
479
469
  this.debugLog(`Humidifier: ${this.accessory.displayName} BLE pushChanges`);
480
- const switchbot = await this.connectBLE();
470
+ const switchbot = await this.platform.connectBLE();
471
+ // Convert to BLE Address
472
+ this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
473
+ this.debugLog(`Curtain: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
481
474
  if (switchbot !== false) {
482
475
  switchbot.discover({ model: 'e', quick: true, id: this.device.bleMac }).then((device_list) => {
483
476
  this.infoLog(`${this.accessory.displayName} Target Position: ${this.Active}`);
@@ -2,7 +2,7 @@ import { interval, Subject } from 'rxjs';
2
2
  import { skipWhile } from 'rxjs/operators';
3
3
  import { SwitchBotPlatform } from '../platform';
4
4
  import { Service, PlatformAccessory, Units, CharacteristicValue } from 'homebridge';
5
- import { DeviceURL, device, devicesConfig, serviceData, ad, switchbot, deviceStatusResponse, temperature } from '../settings';
5
+ import { DeviceURL, device, devicesConfig, serviceData, ad, switchbot, deviceStatusResponse, temperature, deviceStatus } from '../settings';
6
6
 
7
7
  /**
8
8
  * Platform Accessory
@@ -11,23 +11,24 @@ import { DeviceURL, device, devicesConfig, serviceData, ad, switchbot, deviceSta
11
11
  */
12
12
  export class Meter {
13
13
  // Services
14
- private service: Service;
15
- temperatureservice?: Service;
16
- humidityservice?: Service;
14
+ private batteryService?: Service;
15
+ private temperatureservice?: Service;
16
+ private humidityservice?: Service;
17
17
 
18
18
  // Characteristic Values
19
19
  CurrentRelativeHumidity!: CharacteristicValue;
20
20
  CurrentRelativeHumidityCached!: CharacteristicValue;
21
- CurrentTemperature!: CharacteristicValue;
22
- CurrentTemperatureCached!: CharacteristicValue;
23
- BatteryLevel!: CharacteristicValue;
24
- BatteryLevelCached!: CharacteristicValue;
25
- ChargingState!: CharacteristicValue;
26
- StatusLowBattery!: CharacteristicValue;
21
+ CurrentTemperature?: CharacteristicValue;
22
+ CurrentTemperatureCached?: CharacteristicValue;
23
+ BatteryLevel?: CharacteristicValue;
24
+ ChargingState?: CharacteristicValue;
25
+ StatusLowBattery?: CharacteristicValue;
27
26
  Active!: CharacteristicValue;
28
27
  WaterLevel!: CharacteristicValue;
29
28
 
30
29
  // OpenAPI Others
30
+ Temperature: deviceStatus['temperature'];
31
+ Humidity: deviceStatus['humidity'];
31
32
  deviceStatus!: deviceStatusResponse;
32
33
 
33
34
  // BLE Others
@@ -57,17 +58,6 @@ export class Meter {
57
58
  this.logs();
58
59
  this.scan();
59
60
  this.refreshRate();
60
- if (this.BatteryLevel === undefined) {
61
- this.BatteryLevel = 100;
62
- } else {
63
- this.BatteryLevel = this.accessory.context.BatteryLevel;
64
- }
65
- if (this.BatteryLevel < 15) {
66
- this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
67
- } else {
68
- this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
69
- }
70
- this.ChargingState = this.platform.Characteristic.ChargingState.NOT_CHARGEABLE;
71
61
  if (this.CurrentRelativeHumidity === undefined) {
72
62
  this.CurrentRelativeHumidity = 0;
73
63
  } else {
@@ -97,26 +87,6 @@ export class Meter {
97
87
  .setCharacteristic(this.platform.Characteristic.Model, 'SWITCHBOT-METERTH-S1')
98
88
  .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!);
99
89
 
100
- // get the Battery service if it exists, otherwise create a new Battery service
101
- // you can create multiple services for each accessory
102
- (this.service =
103
- accessory.getService(this.platform.Service.Battery) ||
104
- accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
105
-
106
- // To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
107
- // when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
108
- // accessory.getService('NAME') ?? accessory.addService(this.platform.Service.Battery, 'NAME', 'USER_DEFINED_SUBTYPE');
109
-
110
- // set the service name, this is what is displayed as the default name on the Home app
111
- // in this example we are using the name we stored in the `accessory.context` in the `discoverDevices` method.
112
- this.service.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
113
-
114
- // each service must implement at-minimum the "required characteristics" for the given service type
115
- // see https://developers.homebridge.io/#/service/Battery
116
-
117
- // create handlers for required characteristics
118
- this.service.setCharacteristic(this.platform.Characteristic.ChargingState, 2);
119
-
120
90
  // Temperature Sensor Service
121
91
  if (device.meter?.hide_temperature) {
122
92
  this.debugLog(`Meter: ${accessory.displayName} Removing Temperature Sensor Service`);
@@ -128,7 +98,7 @@ export class Meter {
128
98
  this.accessory.getService(this.platform.Service.TemperatureSensor) ||
129
99
  this.accessory.addService(this.platform.Service.TemperatureSensor)), `${accessory.displayName} Temperature Sensor`;
130
100
 
131
- this.service.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Temperature Sensor`);
101
+ this.temperatureservice.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Temperature Sensor`);
132
102
 
133
103
  this.temperatureservice
134
104
  .getCharacteristic(this.platform.Characteristic.CurrentTemperature)
@@ -140,7 +110,7 @@ export class Meter {
140
110
  minStep: 0.1,
141
111
  })
142
112
  .onGet(() => {
143
- return this.CurrentTemperature;
113
+ return this.CurrentTemperature!;
144
114
  });
145
115
  } else {
146
116
  this.debugLog(`Meter: ${accessory.displayName} Temperature Sensor Service Not Added`);
@@ -157,7 +127,7 @@ export class Meter {
157
127
  this.accessory.getService(this.platform.Service.HumiditySensor) ||
158
128
  this.accessory.addService(this.platform.Service.HumiditySensor)), `${accessory.displayName} Humidity Sensor`;
159
129
 
160
- this.service.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Humidity Sensor`);
130
+ this.humidityservice.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Humidity Sensor`);
161
131
 
162
132
  this.humidityservice
163
133
  .getCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity)
@@ -171,6 +141,27 @@ export class Meter {
171
141
  this.debugLog(`Meter: ${accessory.displayName} Humidity Sensor Service Not Added`);
172
142
  }
173
143
 
144
+ // Battery Service
145
+ if (!device.ble) {
146
+ this.debugLog(`Meter: ${accessory.displayName} Removing Battery Service`);
147
+ this.batteryService = this.accessory.getService(this.platform.Service.Battery);
148
+ accessory.removeService(this.batteryService!);
149
+ } else if (device.ble && !this.batteryService) {
150
+ this.debugLog(`Meter: ${accessory.displayName} Add Battery Service`);
151
+ (this.batteryService =
152
+ this.accessory.getService(this.platform.Service.Battery) ||
153
+ this.accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
154
+
155
+ this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Battery`);
156
+
157
+ this.batteryService.setCharacteristic(this.platform.Characteristic.ChargingState, this.platform.Characteristic.ChargingState.NOT_CHARGEABLE);
158
+
159
+ } else {
160
+ this.debugLog(`Meter: ${accessory.displayName} Battery Service Not Added`);
161
+ }
162
+
163
+
164
+
174
165
  // Retrieve initial values and updateHomekit
175
166
  this.updateHomeKitCharacteristics();
176
167
 
@@ -252,9 +243,9 @@ export class Meter {
252
243
  }
253
244
  this.debugLog(`${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}, StatusLowBattery: ${this.StatusLowBattery}`);
254
245
 
246
+ // Humidity
255
247
  if (!this.device.meter?.hide_humidity) {
256
- // Humidity
257
- this.CurrentRelativeHumidity = Number(this.humidity);
248
+ this.CurrentRelativeHumidity = this.humidity!;
258
249
  this.debugLog(`Meter: ${this.accessory.displayName} Humidity: ${this.CurrentRelativeHumidity}%`);
259
250
  }
260
251
 
@@ -272,25 +263,15 @@ export class Meter {
272
263
  }
273
264
  if (this.platform.config.credentials?.openToken) {
274
265
  this.debugLog(`Meter: ${this.accessory.displayName} OpenAPI parseStatus`);
275
- if (this.deviceStatus.body) {
276
- this.BatteryLevel = 100;
277
- } else {
278
- this.BatteryLevel = 10;
279
- }
280
- if (this.BatteryLevel < 15) {
281
- this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
282
- } else {
283
- this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
284
- }
285
266
  // Current Relative Humidity
286
267
  if (!this.device.meter?.hide_humidity) {
287
- this.CurrentRelativeHumidity = this.deviceStatus.body.humidity!;
268
+ this.CurrentRelativeHumidity = this.Humidity!;
288
269
  this.debugLog(`Meter: ${this.accessory.displayName} Humidity: ${this.CurrentRelativeHumidity}%`);
289
270
  }
290
271
 
291
272
  // Current Temperature
292
273
  if (!this.device.meter?.hide_temperature) {
293
- this.CurrentTemperature = Number(this.deviceStatus.body.temperature);
274
+ this.CurrentTemperature = this.Temperature!;
294
275
  this.debugLog(`Meter: ${this.accessory.displayName} Temperature: ${this.CurrentTemperature}°c`);
295
276
  }
296
277
  }
@@ -307,34 +288,12 @@ export class Meter {
307
288
  }
308
289
  }
309
290
 
310
- private async connectBLE() {
311
- let switchbot: any;
312
- try {
313
- // eslint-disable-next-line @typescript-eslint/no-var-requires
314
- const Switchbot = require('node-switchbot');
315
- switchbot = new Switchbot();
316
- // Convert to BLE Address
317
- this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
318
- this.debugLog(`Meter: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
319
- } catch (e: any) {
320
- switchbot = false;
321
- this.errorLog(`Meter: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot}`);
322
- if (this.deviceLogging === 'debug') {
323
- this.errorLog(`Meter: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot},`
324
- + ` Error Message: ${JSON.stringify(e.message)}`);
325
- }
326
- if (this.platform.debugMode) {
327
- this.errorLog(`Meter: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot},`
328
- + ` Error: ${JSON.stringify(e)}`);
329
- }
330
- }
331
- return switchbot;
332
- }
333
-
334
291
  private async BLErefreshStatus() {
335
292
  this.debugLog(`Meter: ${this.accessory.displayName} BLE RefreshStatus`);
336
- // eslint-disable-next-line @typescript-eslint/no-var-requires
337
- const switchbot = await this.connectBLE();
293
+ const switchbot = await this.platform.connectBLE();
294
+ // Convert to BLE Address
295
+ this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
296
+ this.debugLog(`Curtain: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
338
297
  // Start to monitor advertisement packets
339
298
  if (switchbot !== false) {
340
299
  switchbot.startScan({
@@ -366,12 +325,6 @@ export class Meter {
366
325
  // Stop to monitor
367
326
  switchbot.stopScan();
368
327
  if (this.connected) {
369
- this.CurrentTemperatureCached = this.temperature;
370
- this.accessory.context.CurrentTemperature = this.CurrentTemperatureCached;
371
- this.CurrentRelativeHumidityCached = this.humidity!;
372
- this.accessory.context.CurrentRelativeHumidity = this.CurrentRelativeHumidityCached;
373
- this.BatteryLevelCached = this.battery!;
374
- this.accessory.context.BatteryLevel = this.BatteryLevelCached;
375
328
  this.parseStatus();
376
329
  this.updateHomeKitCharacteristics();
377
330
  } else {
@@ -414,12 +367,8 @@ export class Meter {
414
367
  try {
415
368
  this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
416
369
  this.debugLog(`Meter: ${this.accessory.displayName} openAPIRefreshStatus: ${JSON.stringify(this.deviceStatus)}`);
417
- this.CurrentTemperatureCached = this.deviceStatus.body.humidity!;
418
- this.accessory.context.CurrentTemperature = this.CurrentTemperatureCached;
419
- this.CurrentRelativeHumidityCached = this.deviceStatus.body.humidity!;
420
- this.accessory.context.CurrentRelativeHumidity = this.CurrentRelativeHumidityCached;
421
- this.BatteryLevelCached = 100;
422
- this.accessory.context.BatteryLevel = this.BatteryLevelCached;
370
+ this.Humidity = this.deviceStatus.body.humidity!;
371
+ this.Temperature = this.deviceStatus.body.temperature!;
423
372
  this.parseStatus();
424
373
  this.updateHomeKitCharacteristics();
425
374
  } catch (e: any) {
@@ -441,18 +390,6 @@ export class Meter {
441
390
  * Updates the status for each of the HomeKit Characteristics
442
391
  */
443
392
  updateHomeKitCharacteristics() {
444
- if (this.StatusLowBattery === undefined) {
445
- this.debugLog(`Meter: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
446
- } else {
447
- this.service.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.StatusLowBattery);
448
- this.debugLog(`Meter: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
449
- }
450
- if (this.BatteryLevel === undefined) {
451
- this.debugLog(`Meter: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
452
- } else {
453
- this.service.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.BatteryLevel);
454
- this.debugLog(`Meter: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
455
- }
456
393
  if (!this.device.meter?.hide_humidity) {
457
394
  if (this.CurrentRelativeHumidity === undefined) {
458
395
  this.debugLog(`Meter: ${this.accessory.displayName} CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
@@ -469,17 +406,33 @@ export class Meter {
469
406
  this.debugLog(`Meter: ${this.accessory.displayName} updateCharacteristic CurrentTemperature: ${this.CurrentTemperature}`);
470
407
  }
471
408
  }
409
+ if (this.device.ble) {
410
+ if (this.BatteryLevel === undefined) {
411
+ this.debugLog(`Bot: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
412
+ } else {
413
+ this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.BatteryLevel);
414
+ this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
415
+ }
416
+ if (this.StatusLowBattery === undefined) {
417
+ this.debugLog(`Bot: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
418
+ } else {
419
+ this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.StatusLowBattery);
420
+ this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
421
+ }
422
+ }
472
423
  }
473
424
 
474
425
  public apiError(e: any) {
475
- this.service.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
476
- this.service.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
477
426
  if (!this.device.meter?.hide_humidity) {
478
427
  this.humidityservice?.updateCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity, e);
479
428
  }
480
429
  if (!this.device.meter?.hide_temperature) {
481
430
  this.temperatureservice?.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, e);
482
431
  }
432
+ if (this.device.ble) {
433
+ this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
434
+ this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
435
+ }
483
436
  //throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
484
437
  }
485
438