@switchbot/homebridge-switchbot 1.7.0 → 1.7.1-beta.3

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.
@@ -26,11 +26,13 @@ export class Curtain {
26
26
  // BLE Others
27
27
  connected?: boolean;
28
28
  switchbot!: switchbot;
29
+ SwitchToOpenAPI?: boolean;
29
30
  serviceData!: serviceData;
30
31
  calibration: serviceData['calibration'];
31
32
  battery: serviceData['battery'];
32
33
  position: serviceData['position'];
33
34
  lightLevel: serviceData['lightLevel'];
35
+ spaceBetweenLevels!: number;
34
36
 
35
37
  // Target
36
38
  setNewTarget!: boolean;
@@ -44,7 +46,6 @@ export class Curtain {
44
46
  scanDuration!: number;
45
47
  deviceLogging!: string;
46
48
  deviceRefreshRate!: number;
47
- spaceBetweenLevels!: number;
48
49
 
49
50
  // Updates
50
51
  curtainUpdateInProgress!: boolean;
@@ -142,6 +143,23 @@ export class Curtain {
142
143
  this.debugLog(`Curtain: ${accessory.displayName} Light Sensor Service Not Added`);
143
144
  }
144
145
 
146
+ // Battery Service
147
+ if (!device.ble) {
148
+ this.debugLog(`Curtain: ${accessory.displayName} Removing Battery Service`);
149
+ this.batteryService = this.accessory.getService(this.platform.Service.Battery);
150
+ accessory.removeService(this.batteryService!);
151
+ } else if (!this.batteryService) {
152
+ this.debugLog(`Curtain: ${accessory.displayName} Add Battery Service`);
153
+ (this.batteryService =
154
+ this.accessory.getService(this.platform.Service.Battery) ||
155
+ this.accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
156
+
157
+ this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Battery`);
158
+
159
+ } else {
160
+ this.debugLog(`Curtain: ${accessory.displayName} Battery Service Not Added`);
161
+ }
162
+
145
163
 
146
164
  // Update Homekit
147
165
  this.updateHomeKitCharacteristics();
@@ -304,11 +322,14 @@ export class Curtain {
304
322
  return this.set_maxLux;
305
323
  }
306
324
 
325
+ /**
326
+ * Parse the device status from the SwitchBot api
327
+ */
307
328
  async parseStatus() {
308
- if (this.device.ble) {
309
- await this.BLEparseStatus();
310
- } else {
329
+ if (this.SwitchToOpenAPI || !this.device.ble) {
311
330
  await this.openAPIparseStatus();
331
+ } else {
332
+ await this.BLEparseStatus();
312
333
  }
313
334
  }
314
335
 
@@ -407,6 +428,9 @@ export class Curtain {
407
428
  }
408
429
 
409
430
  private async openAPIparseStatus() {
431
+ if (this.device.ble) {
432
+ this.SwitchToOpenAPI = false;
433
+ }
410
434
  if (this.platform.config.credentials?.openToken) {
411
435
  this.debugLog(`Curtain: ${this.accessory.displayName} OpenAPI parseStatus`);
412
436
  // CurrentPosition
@@ -506,6 +530,7 @@ export class Curtain {
506
530
  this.errorLog(`Curtain: ${this.accessory.displayName} wasn't able to establish BLE Connection`);
507
531
  if (this.platform.config.credentials?.openToken) {
508
532
  this.warnLog(`Curtain: ${this.accessory.displayName} Using OpenAPI Connection`);
533
+ this.SwitchToOpenAPI = true;
509
534
  await this.openAPIRefreshStatus();
510
535
  }
511
536
  }
@@ -521,6 +546,7 @@ export class Curtain {
521
546
  }
522
547
  if (this.platform.config.credentials?.openToken) {
523
548
  this.warnLog(`Curtain: ${this.accessory.displayName} Using OpenAPI Connection`);
549
+ this.SwitchToOpenAPI = true;
524
550
  await this.openAPIRefreshStatus();
525
551
  }
526
552
  this.apiError(e);
@@ -534,6 +560,7 @@ export class Curtain {
534
560
  this.errorLog(`Curtain: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
535
561
  if (this.platform.config.credentials?.openToken) {
536
562
  this.warnLog(`Curtain: ${this.accessory.displayName} Using OpenAPI Connection`);
563
+ this.SwitchToOpenAPI = true;
537
564
  await this.openAPIRefreshStatus();
538
565
  }
539
566
  }
@@ -33,6 +33,7 @@ export class Meter {
33
33
  // BLE Others
34
34
  connected?: boolean;
35
35
  switchbot!: switchbot;
36
+ SwitchToOpenAPI?: boolean;
36
37
  serviceData!: serviceData;
37
38
  temperature!: temperature['c'];
38
39
  battery!: serviceData['battery'];
@@ -232,10 +233,10 @@ export class Meter {
232
233
  * Parse the device status from the SwitchBot api
233
234
  */
234
235
  async parseStatus() {
235
- if (this.device.ble) {
236
- await this.BLEparseStatus();
237
- } else {
236
+ if (this.SwitchToOpenAPI || !this.device.ble) {
238
237
  await this.openAPIparseStatus();
238
+ } else {
239
+ await this.BLEparseStatus();
239
240
  }
240
241
  }
241
242
 
@@ -266,6 +267,9 @@ export class Meter {
266
267
  }
267
268
 
268
269
  private async openAPIparseStatus() {
270
+ if (this.device.ble) {
271
+ this.SwitchToOpenAPI = false;
272
+ }
269
273
  if (this.platform.config.credentials?.openToken) {
270
274
  this.debugLog(`Meter: ${this.accessory.displayName} OpenAPI parseStatus`);
271
275
  if (this.deviceStatus.body) {
@@ -385,6 +389,7 @@ export class Meter {
385
389
  }
386
390
  if (this.platform.config.credentials?.openToken) {
387
391
  this.warnLog(`Meter: ${this.accessory.displayName} Using OpenAPI Connection`);
392
+ this.SwitchToOpenAPI = true;
388
393
  this.openAPIRefreshStatus();
389
394
  }
390
395
  this.apiError(e);
@@ -398,6 +403,7 @@ export class Meter {
398
403
  this.errorLog(`Meter: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
399
404
  if (this.platform.config.credentials?.openToken) {
400
405
  this.warnLog(`Meter: ${this.accessory.displayName} Using OpenAPI Connection`);
406
+ this.SwitchToOpenAPI = true;
401
407
  await this.openAPIRefreshStatus();
402
408
  }
403
409
  }
@@ -17,9 +17,9 @@ export class Motion {
17
17
 
18
18
  // Characteristic Values
19
19
  MotionDetected!: CharacteristicValue;
20
+ CurrentAmbientLightLevel!: CharacteristicValue;
20
21
  BatteryLevel?: CharacteristicValue;
21
22
  StatusLowBattery?: CharacteristicValue;
22
- CurrentAmbientLightLevel?: CharacteristicValue;
23
23
 
24
24
  // OpenAPI Others
25
25
  deviceStatus!: deviceStatusResponse;
@@ -27,12 +27,15 @@ export class Motion {
27
27
  // BLE Others
28
28
  connected?: boolean;
29
29
  switchbot!: switchbot;
30
+ SwitchToOpenAPI?: boolean;
30
31
  serviceData!: serviceData;
31
32
  battery!: serviceData['battery'];
32
33
  movement!: serviceData['movement'];
33
34
  lightLevel!: serviceData['lightLevel'];
34
35
 
35
36
  // Config
37
+ set_minLux!: number;
38
+ set_maxLux!: number;
36
39
  scanDuration!: number;
37
40
  deviceLogging!: string;
38
41
  deviceRefreshRate!: number;
@@ -52,6 +55,11 @@ export class Motion {
52
55
  this.refreshRate();
53
56
  this.MotionDetected = false;
54
57
 
58
+ // Motion Config
59
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} Config: (ble: ${device.ble}, offline: ${device.offline},`
60
+ + ` hide_lightsensor: ${device.motion?.hide_lightsensor},`
61
+ + ` set_minLux: ${this.device.motion?.set_minLux}, set_maxLux: ${this.device.motion?.set_maxLux})`);
62
+
55
63
  // this is subject we use to track when we need to POST changes to the SwitchBot API
56
64
  this.doMotionUpdate = new Subject();
57
65
  this.motionUbpdateInProgress = false;
@@ -72,21 +80,6 @@ export class Motion {
72
80
  accessory.getService(this.platform.Service.MotionSensor) ||
73
81
  accessory.addService(this.platform.Service.MotionSensor)), `${accessory.displayName} Motion Sensor`;
74
82
 
75
- if (device.ble) {
76
- (this.lightSensorService =
77
- accessory.getService(this.platform.Service.LightSensor) ||
78
- accessory.addService(this.platform.Service.LightSensor)), `${accessory.displayName} Light Sensor`;
79
-
80
- this.lightSensorService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Light Sensor`);
81
-
82
-
83
- (this.batteryService =
84
- accessory.getService(this.platform.Service.Battery) ||
85
- accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
86
-
87
- this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Battery`);
88
- }
89
-
90
83
  // To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
91
84
  // when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
92
85
  // accessory.getService('NAME') ?? accessory.addService(this.platform.Service.Motion, 'NAME', 'USER_DEFINED_SUBTYPE');
@@ -98,8 +91,39 @@ export class Motion {
98
91
  // each service must implement at-minimum the "required characteristics" for the given service type
99
92
  // see https://developers.homebridge.io/#/service/MotionSensor
100
93
 
101
- // create handlers for required characteristics
102
- //this.service.setCharacteristic(this.platform.Characteristic.ChargingState, 2);
94
+ // Light Sensor Service
95
+ if (device.motion?.hide_lightsensor) {
96
+ this.debugLog(`Motion Sensor: ${accessory.displayName} Removing Light Sensor Service`);
97
+ this.lightSensorService = this.accessory.getService(this.platform.Service.LightSensor);
98
+ accessory.removeService(this.lightSensorService!);
99
+ } else if (!this.lightSensorService) {
100
+ this.debugLog(`Motion Sensor: ${accessory.displayName} Add Light Sensor Service`);
101
+ (this.lightSensorService =
102
+ this.accessory.getService(this.platform.Service.LightSensor) ||
103
+ this.accessory.addService(this.platform.Service.LightSensor)), `${accessory.displayName} Light Sensor`;
104
+
105
+ this.lightSensorService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Light Sensor`);
106
+
107
+ } else {
108
+ this.debugLog(`Motion Sensor: ${accessory.displayName} Light Sensor Service Not Added`);
109
+ }
110
+
111
+ // Battery Service
112
+ if (!device.ble) {
113
+ this.debugLog(`Motion Sensor: ${accessory.displayName} Removing Battery Service`);
114
+ this.batteryService = this.accessory.getService(this.platform.Service.Battery);
115
+ accessory.removeService(this.batteryService!);
116
+ } else if (!this.batteryService) {
117
+ this.debugLog(`Motion Sensor: ${accessory.displayName} Add Battery Service`);
118
+ (this.batteryService =
119
+ this.accessory.getService(this.platform.Service.Battery) ||
120
+ this.accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
121
+
122
+ this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Battery`);
123
+
124
+ } else {
125
+ this.debugLog(`Motion Sensor: ${accessory.displayName} Battery Service Not Added`);
126
+ }
103
127
 
104
128
  // Retrieve initial values and updateHomekit
105
129
  this.updateHomeKitCharacteristics();
@@ -159,59 +183,94 @@ export class Motion {
159
183
  }
160
184
  }
161
185
 
186
+ private minLux(): number {
187
+ if (this.device.motion?.set_minLux) {
188
+ this.set_minLux = this.device.motion!.set_minLux!;
189
+ } else {
190
+ this.set_minLux = 1;
191
+ }
192
+ return this.set_minLux;
193
+ }
194
+
195
+ private maxLux(): number {
196
+ if (this.device.motion?.set_maxLux) {
197
+ this.set_maxLux = this.device.motion!.set_maxLux!;
198
+ } else {
199
+ this.set_maxLux = 6001;
200
+ }
201
+ return this.set_maxLux;
202
+ }
203
+
162
204
  /**
163
205
  * Parse the device status from the SwitchBot api
164
206
  */
165
207
  async parseStatus() {
166
- if (this.device.ble) {
167
- await this.BLEparseStatus();
168
- } else {
208
+ if (this.SwitchToOpenAPI || !this.device.ble) {
169
209
  await this.openAPIparseStatus();
210
+ } else {
211
+ await this.BLEparseStatus();
170
212
  }
171
213
  }
172
214
 
173
215
  private async BLEparseStatus() {
174
216
  this.debugLog(`Motion Sensor: ${this.accessory.displayName} BLE parseStatus`);
217
+ // Movement
175
218
  this.MotionDetected = Boolean(this.movement);
176
219
  this.debugLog(`Motion Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
177
220
  // Light Level
178
- switch (this.lightLevel) {
179
- case 'dark':
180
- case 0:
181
- this.CurrentAmbientLightLevel = 0.0001;
182
- break;
183
- default:
184
- this.CurrentAmbientLightLevel = 100000;
221
+ if (!this.device.motion?.hide_lightsensor) {
222
+ this.set_minLux = this.minLux();
223
+ this.set_maxLux = this.maxLux();
224
+ switch (this.lightLevel) {
225
+ case 'dark':
226
+ case 1:
227
+ this.CurrentAmbientLightLevel = this.set_minLux;
228
+ break;
229
+ default:
230
+ this.CurrentAmbientLightLevel = this.set_maxLux;
231
+ }
232
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} LightLevel: ${this.lightLevel},`
233
+ + ` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
185
234
  }
186
235
  // Battery
236
+ if (this.battery === undefined) {
237
+ this.battery = 100;
238
+ }
187
239
  this.BatteryLevel = Number(this.battery);
188
240
  if (this.BatteryLevel < 10) {
189
241
  this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW;
190
242
  } else {
191
243
  this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
192
244
  }
245
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}, StatusLowBattery: ${this.StatusLowBattery}`);
193
246
  }
194
247
 
195
248
  private async openAPIparseStatus() {
196
- try {
197
- if (this.platform.config.credentials?.openToken) {
198
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} OpenAPI parseStatus`);
199
- if (typeof this.deviceStatus.body.moveDetected === 'boolean') {
200
- this.MotionDetected = this.deviceStatus.body.moveDetected;
201
- }
202
- this.debugLog(`Motion Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
203
- }
204
- } catch (e: any) {
205
- this.errorLog(`Motion Sensor: ${this.accessory.displayName} failed parseStatus with OpenAPI Connection`);
206
- if (this.deviceLogging === 'debug') {
207
- this.errorLog(`Motion Sensor: ${this.accessory.displayName} failed parseStatus with OpenAPI Connection,`
208
- + ` Error Message: ${JSON.stringify(e.message)}`);
249
+ if (this.device.ble) {
250
+ this.SwitchToOpenAPI = false;
251
+ }
252
+ if (this.platform.config.credentials?.openToken) {
253
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} OpenAPI parseStatus`);
254
+ // Motion State
255
+ if (typeof this.deviceStatus.body.moveDetected === 'boolean') {
256
+ this.MotionDetected = this.deviceStatus.body.moveDetected;
209
257
  }
210
- if (this.platform.debugMode) {
211
- this.errorLog(`Motion Sensor: ${this.accessory.displayName} failed parseStatus with OpenAPI Connection,`
212
- + ` Error: ${JSON.stringify(e)}`);
258
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
259
+ // Light Level
260
+ if (!this.device.motion?.hide_lightsensor) {
261
+ this.set_minLux = this.minLux();
262
+ this.set_maxLux = this.maxLux();
263
+ switch (this.deviceStatus.body.brightness) {
264
+ case 'dim':
265
+ this.CurrentAmbientLightLevel = this.set_minLux;
266
+ break;
267
+ case 'bright':
268
+ default:
269
+ this.CurrentAmbientLightLevel = this.set_maxLux;
270
+ }
271
+ this.debugLog(`Motion Sensor: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
272
+
213
273
  }
214
- this.apiError(e);
215
274
  }
216
275
  }
217
276
 
@@ -301,6 +360,7 @@ export class Motion {
301
360
  }
302
361
  if (this.platform.config.credentials?.openToken) {
303
362
  this.warnLog(`Motion Sensor: ${this.accessory.displayName} Using OpenAPI Connection`);
363
+ this.SwitchToOpenAPI = true;
304
364
  await this.openAPIRefreshStatus();
305
365
  }
306
366
  this.apiError(e);
@@ -314,6 +374,7 @@ export class Motion {
314
374
  this.errorLog(`Motion Sensor: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
315
375
  if (this.platform.config.credentials?.openToken) {
316
376
  this.warnLog(`Motion Sensor: ${this.accessory.displayName} Using OpenAPI Connection`);
377
+ this.SwitchToOpenAPI = true;
317
378
  await this.openAPIRefreshStatus();
318
379
  }
319
380
  }
package/src/settings.ts CHANGED
@@ -48,6 +48,7 @@ export interface devicesConfig extends device {
48
48
  humidifier?: humidifier;
49
49
  curtain?: curtain;
50
50
  contact?: contact;
51
+ motion?: motion;
51
52
  colorbulb?: colorbulb;
52
53
  ble?: string;
53
54
  scanDuration?: number;
@@ -84,9 +85,17 @@ export type curtain = {
84
85
 
85
86
  export type contact = {
86
87
  hide_lightsensor?: boolean;
88
+ set_minLux?: number;
89
+ set_maxLux?: number;
87
90
  hide_motionsensor?: boolean;
88
91
  };
89
92
 
93
+ export type motion = {
94
+ hide_lightsensor?: boolean;
95
+ set_minLux?: number;
96
+ set_maxLux?: number;
97
+ };
98
+
90
99
  export type colorbulb = {
91
100
  set_minStep?: number;
92
101
  adaptiveLightingShift?: number;