@switchbot/homebridge-switchbot 1.6.4-beta.5 → 1.7.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.
@@ -13,12 +13,17 @@ import { DeviceURL, device, devicesConfig, serviceData, ad, switchbot, deviceSta
13
13
  */
14
14
  export class Bot {
15
15
  // Services
16
- private switchService?: Service;
16
+ private fanService?: Service;
17
17
  private doorService?: Service;
18
18
  private lockService?: Service;
19
- private garageDoorService?: Service;
19
+ private faucetService?: Service;
20
+ private windowService?: Service;
21
+ private switchService?: Service;
20
22
  private outletService?: Service;
21
23
  private batteryService?: Service;
24
+ private garageDoorService?: Service;
25
+ private windowCoveringService?: Service;
26
+ private statefulProgrammableSwitchService?: Service;
22
27
 
23
28
 
24
29
  // Characteristic Values
@@ -33,6 +38,7 @@ export class Bot {
33
38
  // BLE Others
34
39
  connected?: boolean;
35
40
  switchbot!: switchbot;
41
+ SwitchToOpenAPI?: boolean;
36
42
  serviceData!: serviceData;
37
43
  mode!: serviceData['mode'];
38
44
  state!: serviceData['state'];
@@ -98,10 +104,15 @@ export class Bot {
98
104
  // get the LightBulb service if it exists, otherwise create a new LightBulb service
99
105
  // you can create multiple services for each accessory
100
106
  if (device.bot?.deviceType === 'switch') {
107
+ this.removeFanService(accessory);
101
108
  this.removeLockService(accessory);
102
109
  this.removeDoorService(accessory);
110
+ this.removeFaucetService(accessory);
103
111
  this.removeOutletService(accessory);
112
+ this.removeWindowService(accessory);
104
113
  this.removeGarageDoorService(accessory);
114
+ this.removeWindowCoveringService(accessory);
115
+ this.removeStatefulProgrammableSwitchService(accessory);
105
116
 
106
117
  // Add switchService
107
118
  (this.switchService =
@@ -112,10 +123,15 @@ export class Bot {
112
123
  this.switchService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
113
124
  this.switchService.getCharacteristic(this.platform.Characteristic.On).onSet(this.handleOnSet.bind(this));
114
125
  } else if (device.bot?.deviceType === 'garagedoor') {
126
+ this.removeFanService(accessory);
115
127
  this.removeLockService(accessory);
116
128
  this.removeDoorService(accessory);
129
+ this.removeFaucetService(accessory);
117
130
  this.removeOutletService(accessory);
118
131
  this.removeSwitchService(accessory);
132
+ this.removeWindowService(accessory);
133
+ this.removeWindowCoveringService(accessory);
134
+ this.removeStatefulProgrammableSwitchService(accessory);
119
135
 
120
136
  // Add switchService
121
137
  (this.garageDoorService =
@@ -127,10 +143,15 @@ export class Bot {
127
143
  this.garageDoorService.getCharacteristic(this.platform.Characteristic.TargetDoorState).onSet(this.handleOnSet.bind(this));
128
144
  this.garageDoorService.setCharacteristic(this.platform.Characteristic.ObstructionDetected, false);
129
145
  } else if (device.bot?.deviceType === 'door') {
146
+ this.removeFanService(accessory);
130
147
  this.removeLockService(accessory);
131
148
  this.removeOutletService(accessory);
149
+ this.removeFaucetService(accessory);
132
150
  this.removeSwitchService(accessory);
151
+ this.removeWindowService(accessory);
133
152
  this.removeGarageDoorService(accessory);
153
+ this.removeWindowCoveringService(accessory);
154
+ this.removeStatefulProgrammableSwitchService(accessory);
134
155
 
135
156
  // Add switchService
136
157
  (this.doorService =
@@ -147,11 +168,68 @@ export class Bot {
147
168
  minStep: 100,
148
169
  }).onSet(this.handleOnSet.bind(this));
149
170
  this.doorService.setCharacteristic(this.platform.Characteristic.PositionState, this.platform.Characteristic.PositionState.STOPPED);
171
+ } else if (device.bot?.deviceType === 'window') {
172
+ this.removeFanService(accessory);
173
+ this.removeLockService(accessory);
174
+ this.removeDoorService(accessory);
175
+ this.removeOutletService(accessory);
176
+ this.removeFaucetService(accessory);
177
+ this.removeSwitchService(accessory);
178
+ this.removeGarageDoorService(accessory);
179
+ this.removeWindowCoveringService(accessory);
180
+ this.removeStatefulProgrammableSwitchService(accessory);
181
+
182
+ // Add switchService
183
+ (this.windowService =
184
+ accessory.getService(this.platform.Service.Window) ||
185
+ accessory.addService(this.platform.Service.Window)), `${accessory.displayName} Window`;
186
+ this.infoLog(`Bot: ${accessory.displayName} Displaying as Window`);
187
+
188
+ this.windowService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
189
+ this.windowService.getCharacteristic(this.platform.Characteristic.TargetPosition)
190
+ .setProps({
191
+ validValues: [0, 100],
192
+ minValue: 0,
193
+ maxValue: 100,
194
+ minStep: 100,
195
+ }).onSet(this.handleOnSet.bind(this));
196
+ this.windowService.setCharacteristic(this.platform.Characteristic.PositionState, this.platform.Characteristic.PositionState.STOPPED);
197
+ } else if (device.bot?.deviceType === 'windowcovering') {
198
+ this.removeFanService(accessory);
199
+ this.removeLockService(accessory);
200
+ this.removeDoorService(accessory);
201
+ this.removeOutletService(accessory);
202
+ this.removeFaucetService(accessory);
203
+ this.removeSwitchService(accessory);
204
+ this.removeWindowService(accessory);
205
+ this.removeGarageDoorService(accessory);
206
+ this.removeStatefulProgrammableSwitchService(accessory);
207
+
208
+ // Add switchService
209
+ (this.windowCoveringService =
210
+ accessory.getService(this.platform.Service.WindowCovering) ||
211
+ accessory.addService(this.platform.Service.WindowCovering)), `${accessory.displayName} Window Covering`;
212
+ this.infoLog(`Bot: ${accessory.displayName} Displaying as Window Covering`);
213
+
214
+ this.windowCoveringService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
215
+ this.windowCoveringService.getCharacteristic(this.platform.Characteristic.TargetPosition)
216
+ .setProps({
217
+ validValues: [0, 100],
218
+ minValue: 0,
219
+ maxValue: 100,
220
+ minStep: 100,
221
+ }).onSet(this.handleOnSet.bind(this));
222
+ this.windowCoveringService.setCharacteristic(this.platform.Characteristic.PositionState, this.platform.Characteristic.PositionState.STOPPED);
150
223
  } else if (device.bot?.deviceType === 'lock') {
224
+ this.removeFanService(accessory);
151
225
  this.removeDoorService(accessory);
152
226
  this.removeOutletService(accessory);
153
227
  this.removeSwitchService(accessory);
228
+ this.removeFaucetService(accessory);
229
+ this.removeWindowService(accessory);
154
230
  this.removeGarageDoorService(accessory);
231
+ this.removeWindowCoveringService(accessory);
232
+ this.removeStatefulProgrammableSwitchService(accessory);
155
233
 
156
234
  // Add switchService
157
235
  (this.lockService =
@@ -161,11 +239,74 @@ export class Bot {
161
239
 
162
240
  this.lockService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
163
241
  this.lockService.getCharacteristic(this.platform.Characteristic.LockTargetState).onSet(this.handleOnSet.bind(this));
242
+ } else if (device.bot?.deviceType === 'faucet') {
243
+ this.removeFanService(accessory);
244
+ this.removeLockService(accessory);
245
+ this.removeDoorService(accessory);
246
+ this.removeOutletService(accessory);
247
+ this.removeSwitchService(accessory);
248
+ this.removeWindowService(accessory);
249
+ this.removeGarageDoorService(accessory);
250
+ this.removeWindowCoveringService(accessory);
251
+ this.removeStatefulProgrammableSwitchService(accessory);
252
+
253
+ // Add switchService
254
+ (this.faucetService =
255
+ accessory.getService(this.platform.Service.Faucet) ||
256
+ accessory.addService(this.platform.Service.Faucet)), `${accessory.displayName} Faucet`;
257
+ this.infoLog(`Bot: ${accessory.displayName} Displaying as Faucet`);
258
+
259
+ this.faucetService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
260
+ this.faucetService.getCharacteristic(this.platform.Characteristic.Active).onSet(this.handleOnSet.bind(this));
261
+ } else if (device.bot?.deviceType === 'fan') {
262
+ this.removeLockService(accessory);
263
+ this.removeDoorService(accessory);
264
+ this.removeFaucetService(accessory);
265
+ this.removeOutletService(accessory);
266
+ this.removeSwitchService(accessory);
267
+ this.removeWindowService(accessory);
268
+ this.removeGarageDoorService(accessory);
269
+ this.removeWindowCoveringService(accessory);
270
+ this.removeStatefulProgrammableSwitchService(accessory);
271
+
272
+ // Add switchService
273
+ (this.fanService =
274
+ accessory.getService(this.platform.Service.Fan) ||
275
+ accessory.addService(this.platform.Service.Fan)), `${accessory.displayName} Fan`;
276
+ this.infoLog(`Bot: ${accessory.displayName} Displaying as Fan`);
277
+
278
+ this.fanService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
279
+ this.fanService.getCharacteristic(this.platform.Characteristic.On).onSet(this.handleOnSet.bind(this));
280
+ } else if (device.bot?.deviceType === 'stateful') {
281
+ this.removeFanService(accessory);
282
+ this.removeLockService(accessory);
283
+ this.removeDoorService(accessory);
284
+ this.removeFaucetService(accessory);
285
+ this.removeOutletService(accessory);
286
+ this.removeSwitchService(accessory);
287
+ this.removeWindowService(accessory);
288
+ this.removeGarageDoorService(accessory);
289
+ this.removeWindowCoveringService(accessory);
290
+
291
+ // Add switchService
292
+ (this.statefulProgrammableSwitchService =
293
+ accessory.getService(this.platform.Service.StatefulProgrammableSwitch) ||
294
+ accessory.addService(this.platform.Service.StatefulProgrammableSwitch)), `${accessory.displayName} Stateful Programmable Switch`;
295
+ this.infoLog(`Bot: ${accessory.displayName} Displaying as Stateful Programmable Switch`);
296
+
297
+ this.statefulProgrammableSwitchService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
298
+ this.statefulProgrammableSwitchService.getCharacteristic(this.platform.Characteristic.ProgrammableSwitchOutputState)
299
+ .onSet(this.handleOnSet.bind(this));
164
300
  } else {
301
+ this.removeFanService(accessory);
165
302
  this.removeLockService(accessory);
166
303
  this.removeDoorService(accessory);
304
+ this.removeFaucetService(accessory);
167
305
  this.removeSwitchService(accessory);
306
+ this.removeWindowService(accessory);
168
307
  this.removeGarageDoorService(accessory);
308
+ this.removeWindowCoveringService(accessory);
309
+ this.removeStatefulProgrammableSwitchService(accessory);
169
310
 
170
311
  // Add outletService
171
312
  (this.outletService =
@@ -177,12 +318,21 @@ export class Bot {
177
318
  this.outletService.getCharacteristic(this.platform.Characteristic.On).onSet(this.handleOnSet.bind(this));
178
319
  }
179
320
 
180
- if (device.ble) {
321
+ // Battery Service
322
+ if (!device.ble) {
323
+ this.debugLog(`Bot: ${accessory.displayName} Removing Battery Service`);
324
+ this.batteryService = this.accessory.getService(this.platform.Service.Battery);
325
+ accessory.removeService(this.batteryService!);
326
+ } else if (!this.batteryService) {
327
+ this.debugLog(`Bot: ${accessory.displayName} Add Battery Service`);
181
328
  (this.batteryService =
182
- accessory.getService(this.platform.Service.Battery) ||
183
- accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
329
+ this.accessory.getService(this.platform.Service.Battery) ||
330
+ this.accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
184
331
 
185
332
  this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Battery`);
333
+
334
+ } else {
335
+ this.debugLog(`Bot: ${accessory.displayName} Battery Service Not Added`);
186
336
  }
187
337
 
188
338
  // Retrieve initial values and updateHomekit
@@ -226,7 +376,7 @@ export class Bot {
226
376
  });
227
377
  }
228
378
 
229
- private removeOutletService(accessory: PlatformAccessory) {
379
+ public removeOutletService(accessory: PlatformAccessory) {
230
380
  // If outletService still pressent, then remove first
231
381
  this.outletService = this.accessory.getService(this.platform.Service.Outlet);
232
382
  if (this.outletService) {
@@ -235,7 +385,7 @@ export class Bot {
235
385
  accessory.removeService(this.outletService!);
236
386
  }
237
387
 
238
- private removeGarageDoorService(accessory: PlatformAccessory) {
388
+ public removeGarageDoorService(accessory: PlatformAccessory) {
239
389
  // If garageDoorService still pressent, then remove first
240
390
  this.garageDoorService = this.accessory.getService(this.platform.Service.GarageDoorOpener);
241
391
  if (this.garageDoorService) {
@@ -244,7 +394,7 @@ export class Bot {
244
394
  accessory.removeService(this.garageDoorService!);
245
395
  }
246
396
 
247
- private removeDoorService(accessory: PlatformAccessory) {
397
+ public removeDoorService(accessory: PlatformAccessory) {
248
398
  // If doorService still pressent, then remove first
249
399
  this.doorService = this.accessory.getService(this.platform.Service.Door);
250
400
  if (this.doorService) {
@@ -253,7 +403,7 @@ export class Bot {
253
403
  accessory.removeService(this.doorService!);
254
404
  }
255
405
 
256
- private removeLockService(accessory: PlatformAccessory) {
406
+ public removeLockService(accessory: PlatformAccessory) {
257
407
  // If lockService still pressent, then remove first
258
408
  this.lockService = this.accessory.getService(this.platform.Service.LockMechanism);
259
409
  if (this.lockService) {
@@ -262,7 +412,52 @@ export class Bot {
262
412
  accessory.removeService(this.lockService!);
263
413
  }
264
414
 
265
- private removeSwitchService(accessory: PlatformAccessory) {
415
+ public removeFaucetService(accessory: PlatformAccessory) {
416
+ // If faucetService still pressent, then remove first
417
+ this.faucetService = this.accessory.getService(this.platform.Service.Faucet);
418
+ if (this.faucetService) {
419
+ this.warnLog(`Bot: ${accessory.displayName} Removing Leftover Faucet Service`);
420
+ }
421
+ accessory.removeService(this.faucetService!);
422
+ }
423
+
424
+ public removeFanService(accessory: PlatformAccessory) {
425
+ // If fanService still pressent, then remove first
426
+ this.fanService = this.accessory.getService(this.platform.Service.Fan);
427
+ if (this.fanService) {
428
+ this.warnLog(`Bot: ${accessory.displayName} Removing Leftover Fan Service`);
429
+ }
430
+ accessory.removeService(this.fanService!);
431
+ }
432
+
433
+ public removeWindowService(accessory: PlatformAccessory) {
434
+ // If windowService still pressent, then remove first
435
+ this.windowService = this.accessory.getService(this.platform.Service.Window);
436
+ if (this.windowService) {
437
+ this.warnLog(`Bot: ${accessory.displayName} Removing Leftover Window Service`);
438
+ }
439
+ accessory.removeService(this.windowService!);
440
+ }
441
+
442
+ public removeWindowCoveringService(accessory: PlatformAccessory) {
443
+ // If windowCoveringService still pressent, then remove first
444
+ this.windowCoveringService = this.accessory.getService(this.platform.Service.WindowCovering);
445
+ if (this.windowCoveringService) {
446
+ this.warnLog(`Bot: ${accessory.displayName} Removing Leftover Window Covering Service`);
447
+ }
448
+ accessory.removeService(this.windowCoveringService!);
449
+ }
450
+
451
+ public removeStatefulProgrammableSwitchService(accessory: PlatformAccessory) {
452
+ // If statefulProgrammableSwitchService still pressent, then remove first
453
+ this.statefulProgrammableSwitchService = this.accessory.getService(this.platform.Service.StatefulProgrammableSwitch);
454
+ if (this.statefulProgrammableSwitchService) {
455
+ this.warnLog(`Bot: ${accessory.displayName} Removing Leftover Stateful Programmable Switch Service`);
456
+ }
457
+ accessory.removeService(this.statefulProgrammableSwitchService!);
458
+ }
459
+
460
+ public removeSwitchService(accessory: PlatformAccessory) {
266
461
  // If switchService still pressent, then remove first
267
462
  this.switchService = this.accessory.getService(this.platform.Service.Switch);
268
463
  if (this.switchService) {
@@ -338,10 +533,10 @@ export class Bot {
338
533
  * Parse the device status from the SwitchBot api
339
534
  */
340
535
  async parseStatus() {
341
- if (this.device.ble) {
342
- await this.BLEparseStatus();
343
- } else {
536
+ if (this.SwitchToOpenAPI || !this.device.ble) {
344
537
  await this.openAPIparseStatus();
538
+ } else {
539
+ await this.BLEparseStatus();
345
540
  }
346
541
  }
347
542
 
@@ -375,6 +570,9 @@ export class Bot {
375
570
  }
376
571
 
377
572
  private async openAPIparseStatus() {
573
+ if (this.device.ble) {
574
+ this.SwitchToOpenAPI = false;
575
+ }
378
576
  if (this.platform.config.credentials?.openToken) {
379
577
  this.debugLog(`Bot: ${this.accessory.displayName} OpenAPI parseStatus`);
380
578
  if (this.botMode === 'press') {
@@ -382,7 +580,7 @@ export class Bot {
382
580
  this.OnCached = this.On;
383
581
  this.accessory.context.On = this.OnCached;
384
582
  } else {
385
- if (this.deviceStatus.body.power === 'on') {
583
+ /*if (this.deviceStatus.body.power === 'on') {
386
584
  this.On = true;
387
585
  this.OnCached = this.On;
388
586
  this.accessory.context.On = this.OnCached;
@@ -390,6 +588,11 @@ export class Bot {
390
588
  this.On = false;
391
589
  this.OnCached = this.On;
392
590
  this.accessory.context.On = this.OnCached;
591
+ }*/
592
+ this.OnCached = this.On;
593
+ this.accessory.context.On = this.OnCached;
594
+ if (this.On === undefined) {
595
+ this.On = false;
393
596
  }
394
597
  }
395
598
  this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
@@ -474,6 +677,7 @@ export class Bot {
474
677
  this.errorLog(`Bot: ${this.accessory.displayName} wasn't able to establish BLE Connection`);
475
678
  if (this.platform.config.credentials?.openToken) {
476
679
  this.warnLog(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
680
+ this.SwitchToOpenAPI = true;
477
681
  await this.openAPIRefreshStatus();
478
682
  }
479
683
  }
@@ -489,6 +693,7 @@ export class Bot {
489
693
  }
490
694
  if (this.platform.config.credentials?.openToken) {
491
695
  this.warnLog(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
696
+ this.SwitchToOpenAPI = true;
492
697
  await this.openAPIRefreshStatus();
493
698
  }
494
699
  this.apiError(e);
@@ -721,6 +926,44 @@ export class Bot {
721
926
  }
722
927
  }
723
928
  this.debugLog(`Bot: ${this.accessory.displayName} Door On: ${this.On}`);
929
+ } else if (this.device.bot?.deviceType === 'window') {
930
+ if (this.On === undefined) {
931
+ this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
932
+ } else {
933
+ if (this.On) {
934
+ this.windowService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, 100);
935
+ this.windowService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, 100);
936
+ this.windowService?.updateCharacteristic(this.platform.Characteristic.PositionState,
937
+ this.platform.Characteristic.PositionState.STOPPED);
938
+ this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic TargetPosition: 100, CurrentPosition: 100`);
939
+ } else {
940
+ this.windowService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, 0);
941
+ this.windowService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, 0);
942
+ this.windowService?.updateCharacteristic(this.platform.Characteristic.PositionState,
943
+ this.platform.Characteristic.PositionState.STOPPED);
944
+ this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic TargetPosition: 0, CurrentPosition: 0`);
945
+ }
946
+ }
947
+ this.debugLog(`Bot: ${this.accessory.displayName} Window On: ${this.On}`);
948
+ } else if (this.device.bot?.deviceType === 'windowcovering') {
949
+ if (this.On === undefined) {
950
+ this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
951
+ } else {
952
+ if (this.On) {
953
+ this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, 100);
954
+ this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, 100);
955
+ this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.PositionState,
956
+ this.platform.Characteristic.PositionState.STOPPED);
957
+ this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic TargetPosition: 100, CurrentPosition: 100`);
958
+ } else {
959
+ this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, 0);
960
+ this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, 0);
961
+ this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.PositionState,
962
+ this.platform.Characteristic.PositionState.STOPPED);
963
+ this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic TargetPosition: 0, CurrentPosition: 0`);
964
+ }
965
+ }
966
+ this.debugLog(`Bot: ${this.accessory.displayName} Window Covering On: ${this.On}`);
724
967
  } else if (this.device.bot?.deviceType === 'lock') {
725
968
  if (this.On === undefined) {
726
969
  this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
@@ -740,6 +983,51 @@ export class Bot {
740
983
  }
741
984
  }
742
985
  this.debugLog(`Bot: ${this.accessory.displayName} Lock On: ${this.On}`);
986
+ } else if (this.device.bot?.deviceType === 'faucet') {
987
+ if (this.On === undefined) {
988
+ this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
989
+ } else {
990
+ if (this.On) {
991
+ this.faucetService?.updateCharacteristic(this.platform.Characteristic.Active,
992
+ this.platform.Characteristic.Active.ACTIVE);
993
+ this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic Active: ${this.On}`);
994
+ } else {
995
+ this.faucetService?.updateCharacteristic(this.platform.Characteristic.Active,
996
+ this.platform.Characteristic.Active.INACTIVE);
997
+ this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic Active: ${this.On}`);
998
+ }
999
+ }
1000
+ this.debugLog(`Bot: ${this.accessory.displayName} Faucet On: ${this.On}`);
1001
+ } else if (this.device.bot?.deviceType === 'fan') {
1002
+ if (this.On === undefined) {
1003
+ this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
1004
+ } else {
1005
+ if (this.On) {
1006
+ this.fanService?.updateCharacteristic(this.platform.Characteristic.On, this.On);
1007
+ this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
1008
+ } else {
1009
+ this.fanService?.updateCharacteristic(this.platform.Characteristic.On, this.On);
1010
+ this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
1011
+ }
1012
+ }
1013
+ this.debugLog(`Bot: ${this.accessory.displayName} Fan On: ${this.On}`);
1014
+ } else if (this.device.bot?.deviceType === 'stateful') {
1015
+ if (this.On === undefined) {
1016
+ this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
1017
+ } else {
1018
+ if (this.On) {
1019
+ this.statefulProgrammableSwitchService?.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchEvent,
1020
+ this.platform.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS);
1021
+ this.statefulProgrammableSwitchService?.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchOutputState, 1);
1022
+ this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic ProgrammableSwitchEvent: SINGLE, ProgrammableSwitchOutputState: 1`);
1023
+ } else {
1024
+ this.statefulProgrammableSwitchService?.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchEvent,
1025
+ this.platform.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS);
1026
+ this.statefulProgrammableSwitchService?.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchOutputState, 0);
1027
+ this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic ProgrammableSwitchEvent: SINGLE, ProgrammableSwitchOutputState: 0`);
1028
+ }
1029
+ }
1030
+ this.debugLog(`Bot: ${this.accessory.displayName} StatefulProgrammableSwitch On: ${this.On}`);
743
1031
  } else if (this.device.bot?.deviceType === 'switch') {
744
1032
  if (this.On === undefined) {
745
1033
  this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
@@ -780,9 +1068,24 @@ export class Bot {
780
1068
  this.doorService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, e);
781
1069
  this.doorService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, e);
782
1070
  this.doorService?.updateCharacteristic(this.platform.Characteristic.PositionState, e);
1071
+ } else if (this.device.bot?.deviceType === 'window') {
1072
+ this.windowService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, e);
1073
+ this.windowService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, e);
1074
+ this.windowService?.updateCharacteristic(this.platform.Characteristic.PositionState, e);
1075
+ } else if (this.device.bot?.deviceType === 'windowcovering') {
1076
+ this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, e);
1077
+ this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, e);
1078
+ this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.PositionState, e);
783
1079
  } else if (this.device.bot?.deviceType === 'lock') {
784
1080
  this.doorService?.updateCharacteristic(this.platform.Characteristic.LockTargetState, e);
785
1081
  this.doorService?.updateCharacteristic(this.platform.Characteristic.LockCurrentState, e);
1082
+ } else if (this.device.bot?.deviceType === 'faucet') {
1083
+ this.faucetService?.updateCharacteristic(this.platform.Characteristic.Active, e);
1084
+ } else if (this.device.bot?.deviceType === 'fan') {
1085
+ this.fanService?.updateCharacteristic(this.platform.Characteristic.On, e);
1086
+ } else if (this.device.bot?.deviceType === 'stateful') {
1087
+ this.statefulProgrammableSwitchService?.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchEvent, e);
1088
+ this.statefulProgrammableSwitchService?.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchOutputState, e);
786
1089
  } else if (this.device.bot?.deviceType === 'switch') {
787
1090
  this.switchService?.updateCharacteristic(this.platform.Characteristic.On, e);
788
1091
  } else {
@@ -848,7 +1151,9 @@ export class Bot {
848
1151
  } else {
849
1152
  this.On = true;
850
1153
  }
851
- } else if (this.device.bot?.deviceType === 'door') {
1154
+ } else if (this.device.bot?.deviceType === 'door'
1155
+ || this.device.bot?.deviceType === 'window'
1156
+ || this.device.bot?.deviceType === 'windowcovering') {
852
1157
  this.debugLog(`Bot: ${this.accessory.displayName} TargetPosition: ${value}`);
853
1158
  if (value === 0) {
854
1159
  this.On = false;
@@ -862,6 +1167,20 @@ export class Bot {
862
1167
  } else {
863
1168
  this.On = true;
864
1169
  }
1170
+ } else if (this.device.bot?.deviceType === 'faucet') {
1171
+ this.debugLog(`Bot: ${this.accessory.displayName} Active: ${value}`);
1172
+ if (value === this.platform.Characteristic.Active.INACTIVE) {
1173
+ this.On = false;
1174
+ } else {
1175
+ this.On = true;
1176
+ }
1177
+ } else if (this.device.bot?.deviceType === 'stateful') {
1178
+ this.debugLog(`Bot: ${this.accessory.displayName} ProgrammableSwitchOutputState: ${value}`);
1179
+ if (value === 0) {
1180
+ this.On = false;
1181
+ } else {
1182
+ this.On = true;
1183
+ }
865
1184
  } else {
866
1185
  this.debugLog(`Bot: ${this.accessory.displayName} On: ${value}`);
867
1186
  this.On = value;