@switchbot/homebridge-switchbot 1.7.0 → 1.7.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.
@@ -23,6 +23,7 @@ export class Bot {
23
23
  private batteryService?: Service;
24
24
  private garageDoorService?: Service;
25
25
  private windowCoveringService?: Service;
26
+ private statefulProgrammableSwitchService?: Service;
26
27
 
27
28
 
28
29
  // Characteristic Values
@@ -110,6 +111,7 @@ export class Bot {
110
111
  this.removeWindowService(accessory);
111
112
  this.removeGarageDoorService(accessory);
112
113
  this.removeWindowCoveringService(accessory);
114
+ this.removeStatefulProgrammableSwitchService(accessory);
113
115
 
114
116
  // Add switchService
115
117
  (this.switchService =
@@ -128,6 +130,7 @@ export class Bot {
128
130
  this.removeSwitchService(accessory);
129
131
  this.removeWindowService(accessory);
130
132
  this.removeWindowCoveringService(accessory);
133
+ this.removeStatefulProgrammableSwitchService(accessory);
131
134
 
132
135
  // Add switchService
133
136
  (this.garageDoorService =
@@ -147,6 +150,7 @@ export class Bot {
147
150
  this.removeWindowService(accessory);
148
151
  this.removeGarageDoorService(accessory);
149
152
  this.removeWindowCoveringService(accessory);
153
+ this.removeStatefulProgrammableSwitchService(accessory);
150
154
 
151
155
  // Add switchService
152
156
  (this.doorService =
@@ -172,6 +176,7 @@ export class Bot {
172
176
  this.removeSwitchService(accessory);
173
177
  this.removeGarageDoorService(accessory);
174
178
  this.removeWindowCoveringService(accessory);
179
+ this.removeStatefulProgrammableSwitchService(accessory);
175
180
 
176
181
  // Add switchService
177
182
  (this.windowService =
@@ -197,6 +202,7 @@ export class Bot {
197
202
  this.removeSwitchService(accessory);
198
203
  this.removeWindowService(accessory);
199
204
  this.removeGarageDoorService(accessory);
205
+ this.removeStatefulProgrammableSwitchService(accessory);
200
206
 
201
207
  // Add switchService
202
208
  (this.windowCoveringService =
@@ -222,6 +228,7 @@ export class Bot {
222
228
  this.removeWindowService(accessory);
223
229
  this.removeGarageDoorService(accessory);
224
230
  this.removeWindowCoveringService(accessory);
231
+ this.removeStatefulProgrammableSwitchService(accessory);
225
232
 
226
233
  // Add switchService
227
234
  (this.lockService =
@@ -240,6 +247,7 @@ export class Bot {
240
247
  this.removeWindowService(accessory);
241
248
  this.removeGarageDoorService(accessory);
242
249
  this.removeWindowCoveringService(accessory);
250
+ this.removeStatefulProgrammableSwitchService(accessory);
243
251
 
244
252
  // Add switchService
245
253
  (this.faucetService =
@@ -258,6 +266,7 @@ export class Bot {
258
266
  this.removeWindowService(accessory);
259
267
  this.removeGarageDoorService(accessory);
260
268
  this.removeWindowCoveringService(accessory);
269
+ this.removeStatefulProgrammableSwitchService(accessory);
261
270
 
262
271
  // Add switchService
263
272
  (this.fanService =
@@ -267,6 +276,26 @@ export class Bot {
267
276
 
268
277
  this.fanService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
269
278
  this.fanService.getCharacteristic(this.platform.Characteristic.On).onSet(this.handleOnSet.bind(this));
279
+ } else if (device.bot?.deviceType === 'stateful') {
280
+ this.removeFanService(accessory);
281
+ this.removeLockService(accessory);
282
+ this.removeDoorService(accessory);
283
+ this.removeFaucetService(accessory);
284
+ this.removeOutletService(accessory);
285
+ this.removeSwitchService(accessory);
286
+ this.removeWindowService(accessory);
287
+ this.removeGarageDoorService(accessory);
288
+ this.removeWindowCoveringService(accessory);
289
+
290
+ // Add switchService
291
+ (this.statefulProgrammableSwitchService =
292
+ accessory.getService(this.platform.Service.StatefulProgrammableSwitch) ||
293
+ accessory.addService(this.platform.Service.StatefulProgrammableSwitch)), `${accessory.displayName} Stateful Programmable Switch`;
294
+ this.infoLog(`Bot: ${accessory.displayName} Displaying as Stateful Programmable Switch`);
295
+
296
+ this.statefulProgrammableSwitchService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
297
+ this.statefulProgrammableSwitchService.getCharacteristic(this.platform.Characteristic.ProgrammableSwitchOutputState)
298
+ .onSet(this.handleOnSet.bind(this));
270
299
  } else {
271
300
  this.removeFanService(accessory);
272
301
  this.removeLockService(accessory);
@@ -276,6 +305,7 @@ export class Bot {
276
305
  this.removeWindowService(accessory);
277
306
  this.removeGarageDoorService(accessory);
278
307
  this.removeWindowCoveringService(accessory);
308
+ this.removeStatefulProgrammableSwitchService(accessory);
279
309
 
280
310
  // Add outletService
281
311
  (this.outletService =
@@ -408,6 +438,15 @@ export class Bot {
408
438
  accessory.removeService(this.windowCoveringService!);
409
439
  }
410
440
 
441
+ public removeStatefulProgrammableSwitchService(accessory: PlatformAccessory) {
442
+ // If statefulProgrammableSwitchService still pressent, then remove first
443
+ this.statefulProgrammableSwitchService = this.accessory.getService(this.platform.Service.StatefulProgrammableSwitch);
444
+ if (this.statefulProgrammableSwitchService) {
445
+ this.warnLog(`Bot: ${accessory.displayName} Removing Leftover Stateful Programmable Switch Service`);
446
+ }
447
+ accessory.removeService(this.statefulProgrammableSwitchService!);
448
+ }
449
+
411
450
  public removeSwitchService(accessory: PlatformAccessory) {
412
451
  // If switchService still pressent, then remove first
413
452
  this.switchService = this.accessory.getService(this.platform.Service.Switch);
@@ -528,7 +567,7 @@ export class Bot {
528
567
  this.OnCached = this.On;
529
568
  this.accessory.context.On = this.OnCached;
530
569
  } else {
531
- if (this.deviceStatus.body.power === 'on') {
570
+ /*if (this.deviceStatus.body.power === 'on') {
532
571
  this.On = true;
533
572
  this.OnCached = this.On;
534
573
  this.accessory.context.On = this.OnCached;
@@ -536,6 +575,11 @@ export class Bot {
536
575
  this.On = false;
537
576
  this.OnCached = this.On;
538
577
  this.accessory.context.On = this.OnCached;
578
+ }*/
579
+ this.OnCached = this.On;
580
+ this.accessory.context.On = this.OnCached;
581
+ if (this.On === undefined) {
582
+ this.On = false;
539
583
  }
540
584
  }
541
585
  this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
@@ -952,6 +996,23 @@ export class Bot {
952
996
  }
953
997
  }
954
998
  this.debugLog(`Bot: ${this.accessory.displayName} Fan On: ${this.On}`);
999
+ } else if (this.device.bot?.deviceType === 'stateful') {
1000
+ if (this.On === undefined) {
1001
+ this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
1002
+ } else {
1003
+ if (this.On) {
1004
+ this.statefulProgrammableSwitchService?.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchEvent,
1005
+ this.platform.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS);
1006
+ this.statefulProgrammableSwitchService?.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchOutputState, 1);
1007
+ this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic ProgrammableSwitchEvent: SINGLE, ProgrammableSwitchOutputState: 1`);
1008
+ } else {
1009
+ this.statefulProgrammableSwitchService?.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchEvent,
1010
+ this.platform.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS);
1011
+ this.statefulProgrammableSwitchService?.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchOutputState, 0);
1012
+ this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic ProgrammableSwitchEvent: SINGLE, ProgrammableSwitchOutputState: 0`);
1013
+ }
1014
+ }
1015
+ this.debugLog(`Bot: ${this.accessory.displayName} StatefulProgrammableSwitch On: ${this.On}`);
955
1016
  } else if (this.device.bot?.deviceType === 'switch') {
956
1017
  if (this.On === undefined) {
957
1018
  this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
@@ -1007,6 +1068,9 @@ export class Bot {
1007
1068
  this.faucetService?.updateCharacteristic(this.platform.Characteristic.Active, e);
1008
1069
  } else if (this.device.bot?.deviceType === 'fan') {
1009
1070
  this.fanService?.updateCharacteristic(this.platform.Characteristic.On, e);
1071
+ } else if (this.device.bot?.deviceType === 'stateful') {
1072
+ this.statefulProgrammableSwitchService?.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchEvent, e);
1073
+ this.statefulProgrammableSwitchService?.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchOutputState, e);
1010
1074
  } else if (this.device.bot?.deviceType === 'switch') {
1011
1075
  this.switchService?.updateCharacteristic(this.platform.Characteristic.On, e);
1012
1076
  } else {
@@ -1095,6 +1159,13 @@ export class Bot {
1095
1159
  } else {
1096
1160
  this.On = true;
1097
1161
  }
1162
+ } else if (this.device.bot?.deviceType === 'stateful') {
1163
+ this.debugLog(`Bot: ${this.accessory.displayName} ProgrammableSwitchOutputState: ${value}`);
1164
+ if (value === 0) {
1165
+ this.On = false;
1166
+ } else {
1167
+ this.On = true;
1168
+ }
1098
1169
  } else {
1099
1170
  this.debugLog(`Bot: ${this.accessory.displayName} On: ${value}`);
1100
1171
  this.On = value;
@@ -36,6 +36,9 @@ export class Contact {
36
36
  lightLevel!: serviceData['lightLevel'];
37
37
 
38
38
  // Config
39
+ set_minLux!: number;
40
+ set_maxLux!: number;
41
+ spaceBetweenLevels!: number;
39
42
  scanDuration!: number;
40
43
  deviceLogging!: string;
41
44
  deviceRefreshRate!: number;
@@ -191,6 +194,24 @@ export class Contact {
191
194
  }
192
195
  }
193
196
 
197
+ private minLux(): number {
198
+ if (this.device.curtain?.set_minLux) {
199
+ this.set_minLux = this.device.contact!.set_minLux!;
200
+ } else {
201
+ this.set_minLux = 1;
202
+ }
203
+ return this.set_minLux;
204
+ }
205
+
206
+ private maxLux(): number {
207
+ if (this.device.curtain?.set_maxLux) {
208
+ this.set_maxLux = this.device.contact!.set_maxLux!;
209
+ } else {
210
+ this.set_maxLux = 6001;
211
+ }
212
+ return this.set_maxLux;
213
+ }
214
+
194
215
  /**
195
216
  * Parse the device status from the SwitchBot api
196
217
  */
@@ -204,7 +225,7 @@ export class Contact {
204
225
 
205
226
  private async BLEparseStatus() {
206
227
  this.debugLog(`Contact Sensor: ${this.accessory.displayName} BLE parseStatus`);
207
- if (this.device.contact?.hide_motionsensor) {
228
+ if (!this.device.contact?.hide_motionsensor) {
208
229
  // Movement
209
230
  this.MotionDetected = Boolean(this.movement);
210
231
  }
@@ -221,7 +242,8 @@ export class Contact {
221
242
  default:
222
243
  this.errorLog(`Contact Sensor: ${this.accessory.displayName} timeout no closed, doorstate: ${this.doorState}`);
223
244
  }
224
- if (this.device.contact?.hide_lightsensor) {// Light Level
245
+ // Light Level
246
+ if (!this.device.contact?.hide_lightsensor) {
225
247
  switch (this.lightLevel) {
226
248
  case 'dark':
227
249
  case 0:
@@ -231,6 +253,63 @@ export class Contact {
231
253
  this.CurrentAmbientLightLevel = 100000;
232
254
  }
233
255
  }
256
+
257
+ /*
258
+ // Light Level
259
+ if (!this.device.contact?.hide_lightsensor) {
260
+ this.set_minLux = this.minLux();
261
+ this.set_maxLux = this.maxLux();
262
+ this.spaceBetweenLevels = 9;
263
+
264
+ //
265
+ switch (this.lightLevel) {
266
+ case 1:
267
+ this.CurrentAmbientLightLevel = this.set_minLux;
268
+ this.debugLog(`Curtain: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
269
+ break;
270
+ case 2:
271
+ this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels);
272
+ this.debugLog(`Curtain: ${this.accessory.displayName} LightLevel: ${this.lightLevel},`
273
+ + ` Calculation: ${((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels)}`);
274
+ break;
275
+ case 3:
276
+ this.CurrentAmbientLightLevel = (((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 2);
277
+ this.debugLog(`Curtain: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
278
+ break;
279
+ case 4:
280
+ this.CurrentAmbientLightLevel = (((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 3);
281
+ this.debugLog(`Curtain: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
282
+ break;
283
+ case 5:
284
+ this.CurrentAmbientLightLevel = (((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 4);
285
+ this.debugLog(`Curtain: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
286
+ break;
287
+ case 6:
288
+ this.CurrentAmbientLightLevel = (((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 5);
289
+ this.debugLog(`Curtain: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
290
+ break;
291
+ case 7:
292
+ this.CurrentAmbientLightLevel = (((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 6);
293
+ this.debugLog(`Curtain: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
294
+ break;
295
+ case 8:
296
+ this.CurrentAmbientLightLevel = (((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 7);
297
+ this.debugLog(`Curtain: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
298
+ break;
299
+ case 9:
300
+ this.CurrentAmbientLightLevel = (((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 8);
301
+ this.debugLog(`Curtain: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
302
+ break;
303
+ case 10:
304
+ default:
305
+ this.CurrentAmbientLightLevel = this.set_maxLux;
306
+ this.debugLog();
307
+ }
308
+ this.debugLog(`Curtain: ${this.accessory.displayName} LightLevel: ${this.lightLevel},`
309
+ + ` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
310
+ }*/
311
+
312
+
234
313
  // Battery
235
314
  this.BatteryLevel = Number(this.battery);
236
315
  if (this.BatteryLevel < 10) {
@@ -245,6 +324,7 @@ export class Contact {
245
324
 
246
325
  private async openAPIparseStatus() {
247
326
  if (this.platform.config.credentials?.openToken) {
327
+ // Contact State
248
328
  this.debugLog(`Contact Sensor: ${this.accessory.displayName} OpenAPI parseStatus`);
249
329
  if (this.deviceStatus.body.openState === 'open') {
250
330
  this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
@@ -255,10 +335,26 @@ export class Contact {
255
335
  } else {
256
336
  this.debugLog(`Contact Sensor: ${this.accessory.displayName} openState: ${this.deviceStatus.body.openState}`);
257
337
  }
258
- if (this.device.contact?.hide_motionsensor) {
338
+ // Motion State
339
+ if (!this.device.contact?.hide_motionsensor) {
259
340
  this.MotionDetected = Boolean(this.deviceStatus.body.moveDetected);
260
341
  }
261
342
  this.debugLog(`Contact Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
343
+ // Light Level
344
+ if (!this.device.contact?.hide_lightsensor) {
345
+ this.set_minLux = this.minLux();
346
+ this.set_maxLux = this.maxLux();
347
+ // Brightness
348
+ switch (this.deviceStatus.body.brightness) {
349
+ case 'dim':
350
+ this.CurrentAmbientLightLevel = this.set_minLux;
351
+ break;
352
+ case 'bright':
353
+ default:
354
+ this.CurrentAmbientLightLevel = this.set_maxLux;
355
+ }
356
+ this.debugLog(`Contact Sensor: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
357
+ }
262
358
  }
263
359
  }
264
360
 
package/src/settings.ts CHANGED
@@ -84,6 +84,8 @@ export type curtain = {
84
84
 
85
85
  export type contact = {
86
86
  hide_lightsensor?: boolean;
87
+ set_minLux?: number;
88
+ set_maxLux?: number;
87
89
  hide_motionsensor?: boolean;
88
90
  };
89
91