@switchbot/homebridge-switchbot 0.2.0-alpha.2 → 1.0.1-beta.2

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 (99) hide show
  1. package/.github/workflows/nodejs-beta.yml +1 -1
  2. package/.github/workflows/nodejs.yml +1 -1
  3. package/.github/workflows/{prerelease.js → prerelease-beta.js} +0 -0
  4. package/CHANGELOG.md +1 -1
  5. package/README.md +9 -5
  6. package/config.schema.json +370 -142
  7. package/dist/devices/bots.d.ts +18 -34
  8. package/dist/devices/bots.d.ts.map +1 -1
  9. package/dist/devices/bots.js +166 -171
  10. package/dist/devices/bots.js.map +1 -1
  11. package/dist/devices/{bulb.d.ts → colorbulb.d.ts} +12 -19
  12. package/dist/devices/colorbulb.d.ts.map +1 -0
  13. package/dist/devices/{bulb.js → colorbulb.js} +34 -32
  14. package/dist/devices/colorbulb.js.map +1 -0
  15. package/dist/devices/contact.d.ts +18 -16
  16. package/dist/devices/contact.d.ts.map +1 -1
  17. package/dist/devices/contact.js +101 -44
  18. package/dist/devices/contact.js.map +1 -1
  19. package/dist/devices/curtains.d.ts +17 -51
  20. package/dist/devices/curtains.d.ts.map +1 -1
  21. package/dist/devices/curtains.js +170 -248
  22. package/dist/devices/curtains.js.map +1 -1
  23. package/dist/devices/humidifiers.d.ts +13 -4
  24. package/dist/devices/humidifiers.d.ts.map +1 -1
  25. package/dist/devices/humidifiers.js +81 -8
  26. package/dist/devices/humidifiers.js.map +1 -1
  27. package/dist/devices/indoorcam.d.ts +6 -13
  28. package/dist/devices/indoorcam.d.ts.map +1 -1
  29. package/dist/devices/indoorcam.js.map +1 -1
  30. package/dist/devices/meters.d.ts +12 -15
  31. package/dist/devices/meters.d.ts.map +1 -1
  32. package/dist/devices/meters.js +38 -44
  33. package/dist/devices/meters.js.map +1 -1
  34. package/dist/devices/motion.d.ts +17 -15
  35. package/dist/devices/motion.d.ts.map +1 -1
  36. package/dist/devices/motion.js +87 -40
  37. package/dist/devices/motion.js.map +1 -1
  38. package/dist/devices/plugs.d.ts +6 -13
  39. package/dist/devices/plugs.d.ts.map +1 -1
  40. package/dist/devices/plugs.js.map +1 -1
  41. package/dist/irdevices/airconditioners.d.ts +10 -10
  42. package/dist/irdevices/airconditioners.d.ts.map +1 -1
  43. package/dist/irdevices/airconditioners.js +29 -9
  44. package/dist/irdevices/airconditioners.js.map +1 -1
  45. package/dist/irdevices/airpurifiers.d.ts +11 -11
  46. package/dist/irdevices/airpurifiers.d.ts.map +1 -1
  47. package/dist/irdevices/airpurifiers.js.map +1 -1
  48. package/dist/irdevices/cameras.d.ts +3 -3
  49. package/dist/irdevices/cameras.d.ts.map +1 -1
  50. package/dist/irdevices/cameras.js.map +1 -1
  51. package/dist/irdevices/fans.d.ts +6 -6
  52. package/dist/irdevices/fans.d.ts.map +1 -1
  53. package/dist/irdevices/fans.js +10 -10
  54. package/dist/irdevices/fans.js.map +1 -1
  55. package/dist/irdevices/lights.d.ts +3 -3
  56. package/dist/irdevices/lights.d.ts.map +1 -1
  57. package/dist/irdevices/lights.js.map +1 -1
  58. package/dist/irdevices/others.d.ts +3 -3
  59. package/dist/irdevices/others.d.ts.map +1 -1
  60. package/dist/irdevices/others.js.map +1 -1
  61. package/dist/irdevices/tvs.d.ts +3 -3
  62. package/dist/irdevices/tvs.d.ts.map +1 -1
  63. package/dist/irdevices/tvs.js +7 -5
  64. package/dist/irdevices/tvs.js.map +1 -1
  65. package/dist/irdevices/vacuumcleaners.d.ts +3 -3
  66. package/dist/irdevices/vacuumcleaners.d.ts.map +1 -1
  67. package/dist/irdevices/vacuumcleaners.js.map +1 -1
  68. package/dist/irdevices/waterheaters.d.ts +3 -3
  69. package/dist/irdevices/waterheaters.d.ts.map +1 -1
  70. package/dist/irdevices/waterheaters.js.map +1 -1
  71. package/dist/platform.d.ts +3 -2
  72. package/dist/platform.d.ts.map +1 -1
  73. package/dist/platform.js +136 -46
  74. package/dist/platform.js.map +1 -1
  75. package/dist/settings.d.ts +51 -8
  76. package/dist/settings.d.ts.map +1 -1
  77. package/package.json +65 -65
  78. package/src/devices/bots.ts +188 -193
  79. package/src/devices/{bulb.ts → colorbulb.ts} +46 -51
  80. package/src/devices/contact.ts +124 -68
  81. package/src/devices/curtains.ts +192 -300
  82. package/src/devices/humidifiers.ts +97 -14
  83. package/src/devices/indoorcam.ts +10 -20
  84. package/src/devices/meters.ts +57 -69
  85. package/src/devices/motion.ts +108 -62
  86. package/src/devices/plugs.ts +8 -19
  87. package/src/irdevices/airconditioners.ts +43 -20
  88. package/src/irdevices/airpurifiers.ts +15 -11
  89. package/src/irdevices/cameras.ts +5 -3
  90. package/src/irdevices/fans.ts +22 -16
  91. package/src/irdevices/lights.ts +5 -3
  92. package/src/irdevices/others.ts +5 -3
  93. package/src/irdevices/tvs.ts +13 -7
  94. package/src/irdevices/vacuumcleaners.ts +5 -3
  95. package/src/irdevices/waterheaters.ts +5 -3
  96. package/src/platform.ts +148 -49
  97. package/src/settings.ts +80 -8
  98. package/dist/devices/bulb.d.ts.map +0 -1
  99. package/dist/devices/bulb.js.map +0 -1
@@ -1,15 +1,16 @@
1
- import { Service, PlatformAccessory, CharacteristicValue, MacAddress } from 'homebridge';
1
+ import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
2
2
  import { SwitchBotPlatform } from '../platform';
3
3
  import { interval, Subject } from 'rxjs';
4
4
  import { debounceTime, skipWhile, tap } from 'rxjs/operators';
5
- import { DeviceURL, device, devicesConfig } from '../settings';
5
+ import { DeviceURL, device, devicesConfig, switchbot, deviceStatusResponse } from '../settings';
6
+ import { AxiosResponse } from 'axios';
6
7
 
7
8
  /**
8
9
  * Platform Accessory
9
10
  * An instance of this class is created for each accessory your platform registers
10
11
  * Each accessory may expose multiple services of different service types.
11
12
  */
12
- export class Bulb {
13
+ export class ColorBulb {
13
14
  // Services
14
15
  service!: Service;
15
16
 
@@ -18,33 +19,27 @@ export class Bulb {
18
19
  Brightness!: CharacteristicValue;
19
20
  ColorTemperature!: CharacteristicValue;
20
21
 
21
- // Others
22
- deviceStatus: any;
23
- switchbot!: {
24
- discover: (
25
- arg0:
26
- {
27
- duration: any;
28
- model: string;
29
- quick: boolean;
30
- id: MacAddress;
31
- }
32
- ) => Promise<any>;
33
- wait: (
34
- arg0: number
35
- ) => any;
36
- };
22
+ // OpenAPI Others
23
+ deviceStatus!: deviceStatusResponse;
24
+
25
+ // BLE Others
26
+ switchbot!: switchbot;
27
+
28
+ // Config
29
+ set_minStep?: number;
37
30
 
38
31
  // Updates
39
- bulbUpdateInProgress!: boolean;
40
- doBulbUpdate;
41
- set_minStep: any;
32
+ colorBulbUpdateInProgress!: boolean;
33
+ doColorBulbUpdate!: Subject<void>;
42
34
 
43
35
  constructor(
44
36
  private readonly platform: SwitchBotPlatform,
45
37
  private accessory: PlatformAccessory,
46
38
  public device: device & devicesConfig,
47
39
  ) {
40
+ // ColorBulb Config
41
+ this.platform.device(`[ColorBulb Config] ble: ${device.ble}, set_minStep: ${device.colorbulb?.set_minStep}`);
42
+
48
43
  // default placeholders
49
44
  this.On = false;
50
45
  this.Brightness = 0;
@@ -59,8 +54,8 @@ export class Bulb {
59
54
  }
60
55
 
61
56
  // this is subject we use to track when we need to POST changes to the SwitchBot API
62
- this.doBulbUpdate = new Subject();
63
- this.bulbUpdateInProgress = false;
57
+ this.doColorBulbUpdate = new Subject();
58
+ this.colorBulbUpdateInProgress = false;
64
59
 
65
60
 
66
61
  // Retrieve initial values and updateHomekit
@@ -70,7 +65,7 @@ export class Bulb {
70
65
  accessory
71
66
  .getService(this.platform.Service.AccessoryInformation)!
72
67
  .setCharacteristic(this.platform.Characteristic.Manufacturer, 'SwitchBot')
73
- .setCharacteristic(this.platform.Characteristic.Model, 'SWITCHBOT-BULB-W1401400')
68
+ .setCharacteristic(this.platform.Characteristic.Model, 'SWITCHBOT-COLORBULB-W1401400')
74
69
  .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!);
75
70
 
76
71
  // get the Television service if it exists, otherwise create a new Television service
@@ -122,17 +117,17 @@ export class Bulb {
122
117
 
123
118
  // Start an update interval
124
119
  interval(this.platform.config.options!.refreshRate! * 1000)
125
- .pipe(skipWhile(() => this.bulbUpdateInProgress))
120
+ .pipe(skipWhile(() => this.colorBulbUpdateInProgress))
126
121
  .subscribe(() => {
127
122
  this.refreshStatus();
128
123
  });
129
124
 
130
125
  // Watch for Bulb change events
131
126
  // We put in a debounce of 100ms so we don't make duplicate calls
132
- this.doBulbUpdate
127
+ this.doColorBulbUpdate
133
128
  .pipe(
134
129
  tap(() => {
135
- this.bulbUpdateInProgress = true;
130
+ this.colorBulbUpdateInProgress = true;
136
131
  }),
137
132
  debounceTime(this.platform.config.options!.pushRate! * 1000),
138
133
  )
@@ -141,16 +136,16 @@ export class Bulb {
141
136
  await this.pushChanges();
142
137
  } catch (e: any) {
143
138
  this.platform.log.error(JSON.stringify(e.message));
144
- this.platform.debug(`Bulb ${accessory.displayName} - ${JSON.stringify(e)}`);
139
+ this.platform.debug(`Color Bulb ${accessory.displayName} - ${JSON.stringify(e)}`);
145
140
  this.apiError(e);
146
141
  }
147
- this.bulbUpdateInProgress = false;
142
+ this.colorBulbUpdateInProgress = false;
148
143
  });
149
144
  }
150
145
 
151
146
  private minStep(): number | undefined {
152
- if (this.device.bulb?.set_minStep) {
153
- this.set_minStep = this.device.bulb?.set_minStep;
147
+ if (this.device.colorbulb?.set_minStep) {
148
+ this.set_minStep = this.device.colorbulb?.set_minStep;
154
149
  } else {
155
150
  this.set_minStep = 1;
156
151
  }
@@ -165,21 +160,21 @@ export class Bulb {
165
160
  default:
166
161
  this.On = false;
167
162
  }
168
- this.platform.debug(`Bulb ${this.accessory.displayName} On: ${this.On}`);
163
+ this.platform.debug(`Color Bulb ${this.accessory.displayName} On: ${this.On}`);
169
164
  this.deviceStatus.body.brightness = Number(this.Brightness);
170
165
  this.deviceStatus.body.colorTemperature = Number(this.ColorTemperature);
171
166
  }
172
167
 
173
168
  async refreshStatus() {
174
169
  try {
175
- this.platform.debug('Bulb - Reading', `${DeviceURL}/${this.device.deviceId}/status`);
170
+ this.platform.debug('Color Bulb - Reading', `${DeviceURL}/${this.device.deviceId}/status`);
176
171
  this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
177
- this.platform.device(`Bulb ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
172
+ this.platform.device(`Color Bulb ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
178
173
  this.parseStatus();
179
174
  this.updateHomeKitCharacteristics();
180
175
  } catch (e: any) {
181
- this.platform.log.error(`Bulb ${this.accessory.displayName} failed to refresh status, Error Message ${JSON.stringify(e.message)}`);
182
- this.platform.debug(`Bulb ${this.accessory.displayName}, Error: ${JSON.stringify(e)}`);
176
+ this.platform.log.error(`Color Bulb ${this.accessory.displayName} failed to refresh status, Error Message ${JSON.stringify(e.message)}`);
177
+ this.platform.debug(`Color Bulb ${this.accessory.displayName}, Error: ${JSON.stringify(e)}`);
183
178
  this.apiError(e);
184
179
  }
185
180
  }
@@ -187,8 +182,8 @@ export class Bulb {
187
182
  /**
188
183
  * Pushes the requested changes to the SwitchBot API
189
184
  * deviceType commandType Command command parameter Description
190
- * Bulb - "command" "turnOff" "default" = set to OFF state
191
- * Bulb - "command" "turnOn" "default" = set to ON state
185
+ * Color Bulb - "command" "turnOff" "default" = set to OFF state
186
+ * Color Bulb - "command" "turnOn" "default" = set to ON state
192
187
  */
193
188
  async pushChanges() {
194
189
  const payload = {
@@ -212,32 +207,32 @@ export class Bulb {
212
207
  'commandType:',
213
208
  payload.commandType,
214
209
  );
215
- this.platform.debug(`Bulb ${this.accessory.displayName} pushchanges: ${JSON.stringify(payload)}`);
210
+ this.platform.debug(`Color Bulb ${this.accessory.displayName} pushchanges: ${JSON.stringify(payload)}`);
216
211
 
217
212
  // Make the API request
218
213
  const push: any = (await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload));
219
- this.platform.debug(`Bulb ${this.accessory.displayName} Changes pushed: ${JSON.stringify(push.data)}`);
214
+ this.platform.debug(`Color Bulb ${this.accessory.displayName} Changes pushed: ${JSON.stringify(push.data)}`);
220
215
  this.statusCode(push);
221
216
  }
222
217
 
223
218
  updateHomeKitCharacteristics() {
224
219
  if (this.On === undefined) {
225
- this.platform.debug(`Bulb ${this.accessory.displayName} On: ${this.On}`);
220
+ this.platform.debug(`Color Bulb ${this.accessory.displayName} On: ${this.On}`);
226
221
  } else {
227
222
  this.service.updateCharacteristic(this.platform.Characteristic.On, this.On);
228
- this.platform.device(`Bulb ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
223
+ this.platform.device(`Color Bulb ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
229
224
  }
230
225
  if (this.Brightness === undefined) {
231
- this.platform.debug(`Bulb ${this.accessory.displayName} Brightness: ${this.Brightness}`);
226
+ this.platform.debug(`Color Bulb ${this.accessory.displayName} Brightness: ${this.Brightness}`);
232
227
  } else {
233
228
  this.service.updateCharacteristic(this.platform.Characteristic.Brightness, this.Brightness);
234
- this.platform.device(`Bulb ${this.accessory.displayName} updateCharacteristic Brightness: ${this.Brightness}`);
229
+ this.platform.device(`Color Bulb ${this.accessory.displayName} updateCharacteristic Brightness: ${this.Brightness}`);
235
230
  }
236
231
  if (this.ColorTemperature === undefined) {
237
- this.platform.debug(`Bulb ${this.accessory.displayName} ColorTemperature: ${this.ColorTemperature}`);
232
+ this.platform.debug(`Color Bulb ${this.accessory.displayName} ColorTemperature: ${this.ColorTemperature}`);
238
233
  } else {
239
234
  this.service.updateCharacteristic(this.platform.Characteristic.Brightness, this.ColorTemperature);
240
- this.platform.debug(`Bulb ${this.accessory.displayName} updateCharacteristic ColorTemperature: ${this.ColorTemperature}`);
235
+ this.platform.debug(`Color Bulb ${this.accessory.displayName} updateCharacteristic ColorTemperature: ${this.ColorTemperature}`);
241
236
  }
242
237
  }
243
238
 
@@ -248,7 +243,7 @@ export class Bulb {
248
243
  }
249
244
 
250
245
 
251
- private statusCode(push: { data: { statusCode: any; }; }) {
246
+ private statusCode(push: AxiosResponse<{ statusCode: number;}>) {
252
247
  switch (push.data.statusCode) {
253
248
  case 151:
254
249
  this.platform.log.error('Command not supported by this device type.');
@@ -285,7 +280,7 @@ export class Bulb {
285
280
  this.platform.debug(`${this.accessory.displayName} - Set On: ${value}`);
286
281
 
287
282
  this.On = value;
288
- this.doBulbUpdate.next();
283
+ this.doColorBulbUpdate.next();
289
284
  }
290
285
 
291
286
  /**
@@ -295,7 +290,7 @@ export class Bulb {
295
290
  this.platform.debug(`${this.accessory.displayName} - Set On: ${value}`);
296
291
 
297
292
  this.Brightness = value;
298
- this.doBulbUpdate.next();
293
+ this.doColorBulbUpdate.next();
299
294
  }
300
295
 
301
296
  /**
@@ -305,6 +300,6 @@ export class Bulb {
305
300
  this.platform.debug(`${this.accessory.displayName} - Set On: ${value}`);
306
301
 
307
302
  this.ColorTemperature = value;
308
- this.doBulbUpdate.next();
303
+ this.doColorBulbUpdate.next();
309
304
  }
310
305
  }
@@ -1,8 +1,8 @@
1
- import { Service, PlatformAccessory, CharacteristicValue, MacAddress } from 'homebridge';
1
+ import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
2
2
  import { SwitchBotPlatform } from '../platform';
3
3
  import { interval, Subject } from 'rxjs';
4
4
  import { skipWhile } from 'rxjs/operators';
5
- import { DeviceURL, device, devicesConfig } from '../settings';
5
+ import { DeviceURL, device, devicesConfig, serviceData, switchbot, deviceStatusResponse } from '../settings';
6
6
 
7
7
  /**
8
8
  * Platform Accessory
@@ -12,34 +12,31 @@ import { DeviceURL, device, devicesConfig } from '../settings';
12
12
  export class Contact {
13
13
  // Services
14
14
  private service: Service;
15
- motionService: Service;
15
+ private motionService: Service;
16
+ private lightSensorService: Service;
17
+ private batteryService?: Service;
16
18
 
17
19
  // Characteristic Values
18
20
  ContactSensorState!: CharacteristicValue;
19
21
  MotionDetected!: CharacteristicValue;
22
+ CurrentAmbientLightLevel!: CharacteristicValue;
23
+ BatteryLevel!: CharacteristicValue;
24
+ StatusLowBattery!: CharacteristicValue;
20
25
 
21
- // Others
22
- deviceStatus!: any;
23
- BLEmotion!: boolean;
24
- BLEstate!: boolean;
25
- switchbot!: {
26
- discover: (
27
- arg0:
28
- {
29
- duration: any;
30
- model: string;
31
- quick: boolean;
32
- id: MacAddress;
33
- }
34
- ) => Promise<any>;
35
- wait: (
36
- arg0: number
37
- ) => any;
38
- };
26
+ // OpenAPI others
27
+ deviceStatus!: deviceStatusResponse;
28
+
29
+ // BLE Others
30
+ switchbot!: switchbot;
31
+ serviceData!: serviceData;
32
+ battery!: serviceData['battery'];
33
+ movement!: serviceData['movement'];
34
+ doorState!: serviceData['doorState'];
35
+ lightLevel!: serviceData['lightLevel'];
39
36
 
40
37
  // Updates
41
38
  contactUbpdateInProgress!: boolean;
42
- doContactUpdate;
39
+ doContactUpdate!: Subject<void>;
43
40
 
44
41
  constructor(
45
42
  private readonly platform: SwitchBotPlatform,
@@ -74,7 +71,7 @@ export class Contact {
74
71
  .setCharacteristic(this.platform.Characteristic.Model, 'SWITCHBOT-WOCONTACT-W1201500')
75
72
  .setCharacteristic(this.platform.Characteristic.SerialNumber, device.deviceId!);
76
73
 
77
- // get the Battery service if it exists, otherwise create a new Contact service
74
+ // get the Contact service if it exists, otherwise create a new Contact service
78
75
  // you can create multiple services for each accessory
79
76
  (this.service =
80
77
  accessory.getService(this.platform.Service.ContactSensor) ||
@@ -96,6 +93,20 @@ export class Contact {
96
93
 
97
94
  this.motionService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Motion Sensor`);
98
95
 
96
+ (this.lightSensorService =
97
+ accessory.getService(this.platform.Service.LightSensor) ||
98
+ accessory.addService(this.platform.Service.LightSensor)), `${accessory.displayName} Light Sensor`;
99
+
100
+ this.lightSensorService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Light Sensor`);
101
+
102
+ if (device.ble) {
103
+ (this.batteryService =
104
+ accessory.getService(this.platform.Service.Battery) ||
105
+ accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
106
+
107
+ this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Battery`);
108
+ }
109
+
99
110
  // Retrieve initial values and updateHomekit
100
111
  this.updateHomeKitCharacteristics();
101
112
 
@@ -121,10 +132,41 @@ export class Contact {
121
132
  }
122
133
 
123
134
  private async BLEparseStatus() {
124
- this.MotionDetected = Boolean(this.BLEmotion);
125
- this.ContactSensorState = Boolean(this.BLEstate);
126
- this.platform.debug(`${this.accessory.displayName}
127
- , ContactSensorState: ${this.ContactSensorState}, MotionDetected: ${this.MotionDetected}`);
135
+ this.platform.debug('Contact BLE Device parseStatus');
136
+ // Movement
137
+ this.MotionDetected = Boolean(this.movement);
138
+ // Door State
139
+ switch (this.doorState) {
140
+ case 'open':
141
+ case 1:
142
+ this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
143
+ break;
144
+ case 'close':
145
+ case 0:
146
+ this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_DETECTED;
147
+ break;
148
+ default:
149
+ this.platform.log.error('timeout no closed');
150
+ }
151
+ // Light Level
152
+ switch (this.lightLevel) {
153
+ case 'dark':
154
+ case 0:
155
+ this.CurrentAmbientLightLevel = 0.0001;
156
+ break;
157
+ default:
158
+ this.CurrentAmbientLightLevel = 100000;
159
+ }
160
+ // Battery
161
+ this.BatteryLevel = Number(this.battery);
162
+ if (this.BatteryLevel < 10) {
163
+ this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
164
+ } else {
165
+ this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
166
+ }
167
+
168
+ this.platform.debug(`${this.accessory.displayName}, ContactSensorState: ${this.ContactSensorState}, MotionDetected: ${this.MotionDetected}`
169
+ + `CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}, BatteryLevel: ${this.BatteryLevel}`);
128
170
  }
129
171
 
130
172
  private async openAPIparseStatus() {
@@ -155,8 +197,7 @@ export class Contact {
155
197
  }
156
198
  }
157
199
 
158
- private async BLERefreshStatus() {
159
- this.platform.debug('Contact BLE Device RefreshStatus');
200
+ private connectBLE() {
160
201
  // eslint-disable-next-line @typescript-eslint/no-var-requires
161
202
  const Switchbot = require('node-switchbot');
162
203
  const switchbot = new Switchbot();
@@ -164,47 +205,41 @@ export class Contact {
164
205
  const bleMac = colon!.join(':'); //returns 1A:23:B4:56:78:9A;
165
206
  this.device.bleMac = bleMac.toLowerCase();
166
207
  this.platform.device(this.device.bleMac!);
167
- switchbot.onadvertisement = (ad: any) => {
168
- this.platform.log.info(JSON.stringify(ad, null, ' '));
169
- this.platform.device('ad:', JSON.stringify(ad));
170
- this.BLEmotion = ad.serviceData.motion;
171
- this.BLEstate = ad.serviceData.state;
172
- };
173
- switchbot
174
- .startScan({
175
- id: this.device.bleMac,
176
- })
177
- .then(() => {
178
- return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
179
- })
180
- .then(() => {
181
- switchbot.stopScan();
182
- })
183
- .catch(async (error: any) => {
184
- this.platform.log.error(error);
185
- await this.openAPIRefreshStatus();
186
- });
187
- setInterval(() => {
188
- this.platform.log.info('Start scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
189
- switchbot
190
- .startScan({
191
- mode: 'D',
192
- id: bleMac,
193
- })
194
- .then(() => {
195
- return switchbot.wait(this.platform.config.options!.refreshRate! * 1000);
196
- })
197
- .then(() => {
198
- switchbot.stopScan();
199
- this.platform.log.info('Stop scan ' + this.device.deviceName + '(' + this.device.bleMac + ')');
200
- })
201
- .catch(async (error: any) => {
202
- this.platform.log.error(error);
203
- await this.openAPIRefreshStatus();
204
- });
208
+ return switchbot;
209
+ }
210
+
211
+ private async BLERefreshStatus() {
212
+ this.platform.debug('Contact BLE Device RefreshStatus');
213
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
214
+ const switchbot = this.connectBLE();
215
+ // Start to monitor advertisement packets
216
+ switchbot.startScan({
217
+ model: 'd',
218
+ id: this.device.bleMac,
219
+ }).then(() => {
220
+ // Set an event hander
221
+ switchbot.onadvertisement = (ad: any) => {
222
+ this.serviceData = ad.serviceData;
223
+ this.platform.device(`${this.device.bleMac}: ${JSON.stringify(ad.serviceData)}`);
224
+ this.movement = ad.serviceData.movement;
225
+ this.doorState = ad.serviceData.doorState;
226
+ this.lightLevel = ad.serviceData.lightLevel;
227
+ this.battery = ad.serviceData.battery;
228
+ this.platform.device(`${this.accessory.displayName}, Movement: ${ad.serviceData.movement}, Door State: ${ad.serviceData.doorState},`
229
+ + ` Light Level: ${ad.serviceData.lightLevel}, Battery: ${ad.serviceData.battery}`);
230
+ };
231
+ // Wait 10 seconds
232
+ return switchbot.wait(10000);
233
+ }).then(() => {
234
+ // Stop to monitor
235
+ switchbot.stopScan();
205
236
  this.parseStatus();
206
237
  this.updateHomeKitCharacteristics();
207
- }, this.platform.config.options!.refreshRate! * 60000);
238
+ }).catch(async (e: any) => {
239
+ this.platform.log.error(`BLE Connection Failed: ${e.message}`);
240
+ this.platform.log.warn('Using OpenAPI Connection');
241
+ await this.openAPIRefreshStatus();
242
+ });
208
243
  }
209
244
 
210
245
  private async openAPIRefreshStatus() {
@@ -236,10 +271,31 @@ export class Contact {
236
271
  this.motionService.updateCharacteristic(this.platform.Characteristic.MotionDetected, this.MotionDetected);
237
272
  this.platform.device(`Contact ${this.accessory.displayName} updateCharacteristic MotionDetected: ${this.MotionDetected}`);
238
273
  }
274
+ if (this.CurrentAmbientLightLevel === undefined) {
275
+ this.platform.debug(`Contact ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
276
+ } else {
277
+ this.lightSensorService.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, this.CurrentAmbientLightLevel);
278
+ this.platform.device(`Contact ${this.accessory.displayName} updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
279
+ }
280
+ if (this.BatteryLevel === undefined) {
281
+ this.platform.debug(`Contact ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
282
+ } else {
283
+ this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.BatteryLevel);
284
+ this.platform.device(`Contact ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
285
+ }
286
+ if (this.StatusLowBattery === undefined) {
287
+ this.platform.debug(`Contact ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
288
+ } else {
289
+ this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.StatusLowBattery);
290
+ this.platform.device(`Contact ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
291
+ }
239
292
  }
240
293
 
241
294
  public apiError(e: any) {
242
295
  this.service.updateCharacteristic(this.platform.Characteristic.ContactSensorState, e);
243
296
  this.motionService.updateCharacteristic(this.platform.Characteristic.MotionDetected, e);
297
+ this.lightSensorService.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, e);
298
+ this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
299
+ this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
244
300
  }
245
301
  }