@switchbot/homebridge-switchbot 1.6.4-beta.2 → 1.7.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.
@@ -13,11 +13,16 @@ 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
- private garageDoorService?: Service;
18
+ private lockService?: Service;
19
+ private faucetService?: Service;
20
+ private windowService?: Service;
21
+ private switchService?: Service;
19
22
  private outletService?: Service;
20
23
  private batteryService?: Service;
24
+ private garageDoorService?: Service;
25
+ private windowCoveringService?: Service;
21
26
 
22
27
 
23
28
  // Characteristic Values
@@ -97,9 +102,14 @@ export class Bot {
97
102
  // get the LightBulb service if it exists, otherwise create a new LightBulb service
98
103
  // you can create multiple services for each accessory
99
104
  if (device.bot?.deviceType === 'switch') {
105
+ this.removeFanService(accessory);
106
+ this.removeLockService(accessory);
100
107
  this.removeDoorService(accessory);
108
+ this.removeFaucetService(accessory);
101
109
  this.removeOutletService(accessory);
110
+ this.removeWindowService(accessory);
102
111
  this.removeGarageDoorService(accessory);
112
+ this.removeWindowCoveringService(accessory);
103
113
 
104
114
  // Add switchService
105
115
  (this.switchService =
@@ -110,9 +120,14 @@ export class Bot {
110
120
  this.switchService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
111
121
  this.switchService.getCharacteristic(this.platform.Characteristic.On).onSet(this.handleOnSet.bind(this));
112
122
  } else if (device.bot?.deviceType === 'garagedoor') {
123
+ this.removeFanService(accessory);
124
+ this.removeLockService(accessory);
113
125
  this.removeDoorService(accessory);
126
+ this.removeFaucetService(accessory);
114
127
  this.removeOutletService(accessory);
115
128
  this.removeSwitchService(accessory);
129
+ this.removeWindowService(accessory);
130
+ this.removeWindowCoveringService(accessory);
116
131
 
117
132
  // Add switchService
118
133
  (this.garageDoorService =
@@ -124,15 +139,20 @@ export class Bot {
124
139
  this.garageDoorService.getCharacteristic(this.platform.Characteristic.TargetDoorState).onSet(this.handleOnSet.bind(this));
125
140
  this.garageDoorService.setCharacteristic(this.platform.Characteristic.ObstructionDetected, false);
126
141
  } else if (device.bot?.deviceType === 'door') {
142
+ this.removeFanService(accessory);
143
+ this.removeLockService(accessory);
127
144
  this.removeOutletService(accessory);
145
+ this.removeFaucetService(accessory);
128
146
  this.removeSwitchService(accessory);
147
+ this.removeWindowService(accessory);
129
148
  this.removeGarageDoorService(accessory);
149
+ this.removeWindowCoveringService(accessory);
130
150
 
131
151
  // Add switchService
132
152
  (this.doorService =
133
153
  accessory.getService(this.platform.Service.Door) ||
134
154
  accessory.addService(this.platform.Service.Door)), `${accessory.displayName} Door`;
135
- this.infoLog(`Bot: ${accessory.displayName} Displaying as Garage Door Opener`);
155
+ this.infoLog(`Bot: ${accessory.displayName} Displaying as Door`);
136
156
 
137
157
  this.doorService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
138
158
  this.doorService.getCharacteristic(this.platform.Characteristic.TargetPosition)
@@ -143,10 +163,119 @@ export class Bot {
143
163
  minStep: 100,
144
164
  }).onSet(this.handleOnSet.bind(this));
145
165
  this.doorService.setCharacteristic(this.platform.Characteristic.PositionState, this.platform.Characteristic.PositionState.STOPPED);
166
+ } else if (device.bot?.deviceType === 'window') {
167
+ this.removeFanService(accessory);
168
+ this.removeLockService(accessory);
169
+ this.removeDoorService(accessory);
170
+ this.removeOutletService(accessory);
171
+ this.removeFaucetService(accessory);
172
+ this.removeSwitchService(accessory);
173
+ this.removeGarageDoorService(accessory);
174
+ this.removeWindowCoveringService(accessory);
175
+
176
+ // Add switchService
177
+ (this.windowService =
178
+ accessory.getService(this.platform.Service.Window) ||
179
+ accessory.addService(this.platform.Service.Window)), `${accessory.displayName} Window`;
180
+ this.infoLog(`Bot: ${accessory.displayName} Displaying as Window`);
181
+
182
+ this.windowService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
183
+ this.windowService.getCharacteristic(this.platform.Characteristic.TargetPosition)
184
+ .setProps({
185
+ validValues: [0, 100],
186
+ minValue: 0,
187
+ maxValue: 100,
188
+ minStep: 100,
189
+ }).onSet(this.handleOnSet.bind(this));
190
+ this.windowService.setCharacteristic(this.platform.Characteristic.PositionState, this.platform.Characteristic.PositionState.STOPPED);
191
+ } else if (device.bot?.deviceType === 'windowcovering') {
192
+ this.removeFanService(accessory);
193
+ this.removeLockService(accessory);
194
+ this.removeDoorService(accessory);
195
+ this.removeOutletService(accessory);
196
+ this.removeFaucetService(accessory);
197
+ this.removeSwitchService(accessory);
198
+ this.removeWindowService(accessory);
199
+ this.removeGarageDoorService(accessory);
200
+
201
+ // Add switchService
202
+ (this.windowCoveringService =
203
+ accessory.getService(this.platform.Service.WindowCovering) ||
204
+ accessory.addService(this.platform.Service.WindowCovering)), `${accessory.displayName} Window Covering`;
205
+ this.infoLog(`Bot: ${accessory.displayName} Displaying as Window Covering`);
206
+
207
+ this.windowCoveringService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
208
+ this.windowCoveringService.getCharacteristic(this.platform.Characteristic.TargetPosition)
209
+ .setProps({
210
+ validValues: [0, 100],
211
+ minValue: 0,
212
+ maxValue: 100,
213
+ minStep: 100,
214
+ }).onSet(this.handleOnSet.bind(this));
215
+ this.windowCoveringService.setCharacteristic(this.platform.Characteristic.PositionState, this.platform.Characteristic.PositionState.STOPPED);
216
+ } else if (device.bot?.deviceType === 'lock') {
217
+ this.removeFanService(accessory);
218
+ this.removeDoorService(accessory);
219
+ this.removeOutletService(accessory);
220
+ this.removeSwitchService(accessory);
221
+ this.removeFaucetService(accessory);
222
+ this.removeWindowService(accessory);
223
+ this.removeGarageDoorService(accessory);
224
+ this.removeWindowCoveringService(accessory);
225
+
226
+ // Add switchService
227
+ (this.lockService =
228
+ accessory.getService(this.platform.Service.LockMechanism) ||
229
+ accessory.addService(this.platform.Service.LockMechanism)), `${accessory.displayName} Lock`;
230
+ this.infoLog(`Bot: ${accessory.displayName} Displaying as Lock`);
231
+
232
+ this.lockService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
233
+ this.lockService.getCharacteristic(this.platform.Characteristic.LockTargetState).onSet(this.handleOnSet.bind(this));
234
+ } else if (device.bot?.deviceType === 'faucet') {
235
+ this.removeFanService(accessory);
236
+ this.removeLockService(accessory);
237
+ this.removeDoorService(accessory);
238
+ this.removeOutletService(accessory);
239
+ this.removeSwitchService(accessory);
240
+ this.removeWindowService(accessory);
241
+ this.removeGarageDoorService(accessory);
242
+ this.removeWindowCoveringService(accessory);
243
+
244
+ // Add switchService
245
+ (this.faucetService =
246
+ accessory.getService(this.platform.Service.Faucet) ||
247
+ accessory.addService(this.platform.Service.Faucet)), `${accessory.displayName} Faucet`;
248
+ this.infoLog(`Bot: ${accessory.displayName} Displaying as Faucet`);
249
+
250
+ this.faucetService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
251
+ this.faucetService.getCharacteristic(this.platform.Characteristic.Active).onSet(this.handleOnSet.bind(this));
252
+ } else if (device.bot?.deviceType === 'fan') {
253
+ this.removeLockService(accessory);
254
+ this.removeDoorService(accessory);
255
+ this.removeFaucetService(accessory);
256
+ this.removeOutletService(accessory);
257
+ this.removeSwitchService(accessory);
258
+ this.removeWindowService(accessory);
259
+ this.removeGarageDoorService(accessory);
260
+ this.removeWindowCoveringService(accessory);
261
+
262
+ // Add switchService
263
+ (this.fanService =
264
+ accessory.getService(this.platform.Service.Fan) ||
265
+ accessory.addService(this.platform.Service.Fan)), `${accessory.displayName} Fan`;
266
+ this.infoLog(`Bot: ${accessory.displayName} Displaying as Fan`);
267
+
268
+ this.fanService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
269
+ this.fanService.getCharacteristic(this.platform.Characteristic.On).onSet(this.handleOnSet.bind(this));
146
270
  } else {
271
+ this.removeFanService(accessory);
272
+ this.removeLockService(accessory);
147
273
  this.removeDoorService(accessory);
274
+ this.removeFaucetService(accessory);
148
275
  this.removeSwitchService(accessory);
276
+ this.removeWindowService(accessory);
149
277
  this.removeGarageDoorService(accessory);
278
+ this.removeWindowCoveringService(accessory);
150
279
 
151
280
  // Add outletService
152
281
  (this.outletService =
@@ -207,39 +336,84 @@ export class Bot {
207
336
  });
208
337
  }
209
338
 
210
- private removeOutletService(accessory: PlatformAccessory) {
339
+ public removeOutletService(accessory: PlatformAccessory) {
211
340
  // If outletService still pressent, then remove first
341
+ this.outletService = this.accessory.getService(this.platform.Service.Outlet);
212
342
  if (this.outletService) {
213
- this.debugLog(`Bot: ${accessory.displayName} Removing Leftover outletService first`);
343
+ this.warnLog(`Bot: ${accessory.displayName} Removing Leftover Outlet Service`);
214
344
  }
215
- this.outletService = this.accessory.getService(this.platform.Service.Outlet);
216
345
  accessory.removeService(this.outletService!);
217
346
  }
218
347
 
219
- private removeGarageDoorService(accessory: PlatformAccessory) {
348
+ public removeGarageDoorService(accessory: PlatformAccessory) {
220
349
  // If garageDoorService still pressent, then remove first
350
+ this.garageDoorService = this.accessory.getService(this.platform.Service.GarageDoorOpener);
221
351
  if (this.garageDoorService) {
222
- this.debugLog(`Bot: ${accessory.displayName} Removing Leftover garageDoorService first`);
352
+ this.warnLog(`Bot: ${accessory.displayName} Removing Leftover Garage Door Service`);
223
353
  }
224
- this.garageDoorService = this.accessory.getService(this.platform.Service.GarageDoorOpener);
225
354
  accessory.removeService(this.garageDoorService!);
226
355
  }
227
356
 
228
- private removeDoorService(accessory: PlatformAccessory) {
357
+ public removeDoorService(accessory: PlatformAccessory) {
229
358
  // If doorService still pressent, then remove first
359
+ this.doorService = this.accessory.getService(this.platform.Service.Door);
230
360
  if (this.doorService) {
231
- this.debugLog(`Bot: ${accessory.displayName} Removing Leftover doorService first`);
361
+ this.warnLog(`Bot: ${accessory.displayName} Removing Leftover Door Service`);
232
362
  }
233
- this.doorService = this.accessory.getService(this.platform.Service.Door);
234
363
  accessory.removeService(this.doorService!);
235
364
  }
236
365
 
237
- private removeSwitchService(accessory: PlatformAccessory) {
366
+ public removeLockService(accessory: PlatformAccessory) {
367
+ // If lockService still pressent, then remove first
368
+ this.lockService = this.accessory.getService(this.platform.Service.LockMechanism);
369
+ if (this.lockService) {
370
+ this.warnLog(`Bot: ${accessory.displayName} Removing Leftover Lock Service`);
371
+ }
372
+ accessory.removeService(this.lockService!);
373
+ }
374
+
375
+ public removeFaucetService(accessory: PlatformAccessory) {
376
+ // If faucetService still pressent, then remove first
377
+ this.faucetService = this.accessory.getService(this.platform.Service.Faucet);
378
+ if (this.faucetService) {
379
+ this.warnLog(`Bot: ${accessory.displayName} Removing Leftover Faucet Service`);
380
+ }
381
+ accessory.removeService(this.faucetService!);
382
+ }
383
+
384
+ public removeFanService(accessory: PlatformAccessory) {
385
+ // If fanService still pressent, then remove first
386
+ this.fanService = this.accessory.getService(this.platform.Service.Fan);
387
+ if (this.fanService) {
388
+ this.warnLog(`Bot: ${accessory.displayName} Removing Leftover Fan Service`);
389
+ }
390
+ accessory.removeService(this.fanService!);
391
+ }
392
+
393
+ public removeWindowService(accessory: PlatformAccessory) {
394
+ // If windowService still pressent, then remove first
395
+ this.windowService = this.accessory.getService(this.platform.Service.Window);
396
+ if (this.windowService) {
397
+ this.warnLog(`Bot: ${accessory.displayName} Removing Leftover Window Service`);
398
+ }
399
+ accessory.removeService(this.windowService!);
400
+ }
401
+
402
+ public removeWindowCoveringService(accessory: PlatformAccessory) {
403
+ // If windowCoveringService still pressent, then remove first
404
+ this.windowCoveringService = this.accessory.getService(this.platform.Service.WindowCovering);
405
+ if (this.windowCoveringService) {
406
+ this.warnLog(`Bot: ${accessory.displayName} Removing Leftover Window Covering Service`);
407
+ }
408
+ accessory.removeService(this.windowCoveringService!);
409
+ }
410
+
411
+ public removeSwitchService(accessory: PlatformAccessory) {
238
412
  // If switchService still pressent, then remove first
413
+ this.switchService = this.accessory.getService(this.platform.Service.Switch);
239
414
  if (this.switchService) {
240
- this.debugLog(`Bot: ${accessory.displayName} Removing Leftover switchService first`);
415
+ this.warnLog(`Bot: ${accessory.displayName} Removing Leftover Switch Service`);
241
416
  }
242
- this.switchService = this.accessory.getService(this.platform.Service.Switch);
243
417
  accessory.removeService(this.switchService!);
244
418
  }
245
419
 
@@ -379,11 +553,27 @@ export class Bot {
379
553
  }
380
554
  }
381
555
 
382
- private connectBLE() {
383
- // Convert to BLE Address
384
- this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
385
- this.debugLog(`Bot: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
386
- const switchbot = this.platform.connectBLE();
556
+ public async connectBLE() {
557
+ let switchbot: any;
558
+ try {
559
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
560
+ const Switchbot = require('node-switchbot');
561
+ switchbot = new Switchbot();
562
+ // Convert to BLE Address
563
+ this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
564
+ this.debugLog(`Bot: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
565
+ } catch (e: any) {
566
+ switchbot = false;
567
+ this.errorLog(`Bot: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot}`);
568
+ if (this.deviceLogging === 'debug') {
569
+ this.errorLog(`Bot: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot},`
570
+ + ` Error Message: ${JSON.stringify(e.message)}`);
571
+ }
572
+ if (this.platform.debugMode) {
573
+ this.errorLog(`Bot: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot},`
574
+ + ` Error: ${JSON.stringify(e)}`);
575
+ }
576
+ }
387
577
  return switchbot;
388
578
  }
389
579
 
@@ -391,69 +581,64 @@ export class Bot {
391
581
  this.debugLog(`Bot: ${this.accessory.displayName} BLE refreshStatus`);
392
582
 
393
583
  // Convert to BLE Address
394
- const switchbot = this.connectBLE();
584
+ const switchbot = await this.connectBLE();
395
585
  // Start to monitor advertisement packets
396
- if (switchbot !== false) {
397
- switchbot.startScan({
398
- model: 'H',
399
- id: this.device.bleMac,
400
- }).then(() => {
401
- // Set an event hander
402
- switchbot.onadvertisement = (ad: ad) => {
403
- this.serviceData = ad.serviceData;
404
- this.mode = ad.serviceData.mode;
405
- this.state = ad.serviceData.state;
406
- this.battery = ad.serviceData.battery;
407
- this.debugLog(`Bot: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
408
- this.debugLog(`Bot: ${this.accessory.displayName}, model: ${ad.serviceData.model}, modelName: ${ad.serviceData.modelName},`
409
- + ` mode: ${ad.serviceData.mode}, state: ${ad.serviceData.state}, battery: ${ad.serviceData.battery}`);
410
-
411
- if (this.serviceData) {
412
- this.connected = true;
413
- this.debugLog(`Bot: ${this.accessory.displayName} connected: ${this.connected}`);
414
- } else {
415
- this.connected = false;
416
- this.debugLog(`Bot: ${this.accessory.displayName} connected: ${this.connected}`);
417
- }
418
- };
419
- // Wait 2 seconds
420
- return switchbot.wait(this.scanDuration * 1000);
421
- }).then(async () => {
422
- // Stop to monitor
423
- switchbot.stopScan();
424
- if (this.connected) {
425
- this.parseStatus();
426
- this.updateHomeKitCharacteristics();
586
+ if (switchbot === false) {
587
+ this.errorLog(`Bot: ${this.accessory.displayName} wasn't able to establish BLE Connection: ${switchbot}`);
588
+ }
589
+ switchbot.startScan({
590
+ model: 'H',
591
+ id: this.device.bleMac,
592
+ }).then(() => {
593
+ // Set an event hander
594
+ switchbot.onadvertisement = (ad: ad) => {
595
+ this.serviceData = ad.serviceData;
596
+ this.mode = ad.serviceData.mode;
597
+ this.state = ad.serviceData.state;
598
+ this.battery = ad.serviceData.battery;
599
+ this.debugLog(`Bot: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
600
+ this.debugLog(`Bot: ${this.accessory.displayName}, model: ${ad.serviceData.model}, modelName: ${ad.serviceData.modelName},`
601
+ + ` mode: ${ad.serviceData.mode}, state: ${ad.serviceData.state}, battery: ${ad.serviceData.battery}`);
602
+
603
+ if (this.serviceData) {
604
+ this.connected = true;
605
+ this.debugLog(`Bot: ${this.accessory.displayName} connected: ${this.connected}`);
427
606
  } else {
428
- await this.BLEconnection();
429
- }
430
- }).catch(async (e: any) => {
431
- this.errorLog(`Bot: ${this.accessory.displayName} failed refreshStatus with BLE Connection`);
432
- if (this.deviceLogging === 'debug') {
433
- this.errorLog(`Bot: ${this.accessory.displayName} failed refreshStatus with BLE Connection,`
434
- + ` Error Message: ${JSON.stringify(e.message)}`);
435
- }
436
- if (this.platform.debugMode) {
437
- this.errorLog(`Bot: ${this.accessory.displayName} failed refreshStatus with BLE Connection,`
438
- + ` Error: ${JSON.stringify(e)}`);
607
+ this.connected = false;
608
+ this.debugLog(`Bot: ${this.accessory.displayName} connected: ${this.connected}`);
439
609
  }
610
+ };
611
+ // Wait 2 seconds
612
+ return switchbot.wait(this.scanDuration * 1000);
613
+ }).then(async () => {
614
+ // Stop to monitor
615
+ switchbot.stopScan();
616
+ if (this.connected) {
617
+ this.parseStatus();
618
+ this.updateHomeKitCharacteristics();
619
+ } else {
620
+ this.errorLog(`Bot: ${this.accessory.displayName} wasn't able to establish BLE Connection`);
440
621
  if (this.platform.config.credentials?.openToken) {
441
622
  this.warnLog(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
442
623
  await this.openAPIRefreshStatus();
443
624
  }
444
- this.apiError(e);
445
- });
446
- } else {
447
- await this.BLEconnection();
448
- }
449
- }
450
-
451
- private async BLEconnection() {
452
- this.errorLog(`Bot: ${this.accessory.displayName} wasn't able to establish BLE Connection`);
453
- if (this.platform.config.credentials?.openToken) {
454
- this.warnLog(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
455
- await this.openAPIRefreshStatus();
456
- }
625
+ }
626
+ }).catch(async (e: any) => {
627
+ this.errorLog(`Bot: ${this.accessory.displayName} failed refreshStatus with BLE Connection`);
628
+ if (this.deviceLogging === 'debug') {
629
+ this.errorLog(`Bot: ${this.accessory.displayName} failed refreshStatus with BLE Connection,`
630
+ + ` Error Message: ${JSON.stringify(e.message)}`);
631
+ }
632
+ if (this.platform.debugMode) {
633
+ this.errorLog(`Bot: ${this.accessory.displayName} failed refreshStatus with BLE Connection,`
634
+ + ` Error: ${JSON.stringify(e)}`);
635
+ }
636
+ if (this.platform.config.credentials?.openToken) {
637
+ this.warnLog(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
638
+ await this.openAPIRefreshStatus();
639
+ }
640
+ this.apiError(e);
641
+ });
457
642
  }
458
643
 
459
644
  private async openAPIRefreshStatus() {
@@ -501,54 +686,30 @@ export class Bot {
501
686
  }
502
687
 
503
688
  private async BLEpushChanges() {
689
+ this.debugLog(`Bot: ${this.accessory.displayName} BLE pushChanges On: ${this.On} OnCached: ${this.OnCached}`);
504
690
  if (this.On !== this.OnCached) {
505
691
  this.debugLog(`Bot: ${this.accessory.displayName} BLE pushChanges`);
506
- const switchbot = this.connectBLE();
507
- if (switchbot !== false) {
508
- if (this.botMode === 'press') {
509
- this.debugLog(`Bot: ${this.accessory.displayName} Bot Mode: ${this.botMode}`);
510
- switchbot.discover({ model: 'H', quick: true, id: this.device.bleMac })
511
- .then((device_list: { press: (arg0: { id: string | undefined; }) => any; }[]) => {
512
- this.infoLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
513
- return device_list[0].press({ id: this.device.bleMac });
514
- }).then(() => {
515
- this.debugLog(`Bot: ${this.accessory.displayName} Done.`);
516
- this.On = false;
517
- this.OnCached = this.On;
518
- this.accessory.context.On = this.OnCached;
519
- setTimeout(() => {
520
- if (this.device.bot?.deviceType === 'switch') {
521
- this.switchService?.getCharacteristic(this.platform.Characteristic.On).updateValue(this.On);
522
- } else {
523
- this.outletService?.getCharacteristic(this.platform.Characteristic.On).updateValue(this.On);
524
- }
525
- this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}, Switch Timeout`);
526
- }, 500);
527
- }).catch(async (e: any) => {
528
- this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection`);
529
- if (this.deviceLogging === 'debug') {
530
- this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection,`
531
- + ` Error Message: ${JSON.stringify(e.message)}`);
532
- }
533
- if (this.platform.debugMode) {
534
- this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection,`
535
- + ` Error: ${JSON.stringify(e)}`);
536
- }
537
- if (this.platform.config.credentials?.openToken) {
538
- this.warnLog(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
539
- await this.openAPIpushChanges();
540
- }
541
- this.apiError(e);
542
- });
543
- } else if (this.botMode === 'switch') {
544
- this.debugLog(`Bot: ${this.accessory.displayName} Press Mode: ${this.botMode}`);
545
- switchbot.discover({ model: 'H', quick: true, id: this.device.bleMac }).then((device_list: any) => {
692
+ const switchbot = await this.connectBLE();
693
+ //if (switchbot !== false) {
694
+ if (this.botMode === 'press') {
695
+ this.debugLog(`Bot: ${this.accessory.displayName} Bot Mode: ${this.botMode}`);
696
+ switchbot.discover({ model: 'H', quick: true, id: this.device.bleMac })
697
+ .then((device_list: { press: (arg0: { id: string | undefined; }) => any; }[]) => {
546
698
  this.infoLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
547
- return this.turnOnOff(device_list);
699
+ return device_list[0].press({ id: this.device.bleMac });
548
700
  }).then(() => {
549
701
  this.debugLog(`Bot: ${this.accessory.displayName} Done.`);
702
+ this.On = false;
550
703
  this.OnCached = this.On;
551
704
  this.accessory.context.On = this.OnCached;
705
+ setTimeout(() => {
706
+ if (this.device.bot?.deviceType === 'switch') {
707
+ this.switchService?.getCharacteristic(this.platform.Characteristic.On).updateValue(this.On);
708
+ } else {
709
+ this.outletService?.getCharacteristic(this.platform.Characteristic.On).updateValue(this.On);
710
+ }
711
+ this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}, Switch Timeout`);
712
+ }, 500);
552
713
  }).catch(async (e: any) => {
553
714
  this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection`);
554
715
  if (this.deviceLogging === 'debug') {
@@ -565,16 +726,41 @@ export class Bot {
565
726
  }
566
727
  this.apiError(e);
567
728
  });
568
- } else {
569
- throw new Error(`Bot: ${this.accessory.displayName} Bot Mode: ${this.botMode}`);
570
- }
729
+ } else if (this.botMode === 'switch') {
730
+ this.debugLog(`Bot: ${this.accessory.displayName} Press Mode: ${this.botMode}`);
731
+ switchbot.discover({ model: 'H', quick: true, id: this.device.bleMac }).then((device_list: any) => {
732
+ this.infoLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
733
+ return this.turnOnOff(device_list);
734
+ }).then(() => {
735
+ this.debugLog(`Bot: ${this.accessory.displayName} Done.`);
736
+ this.OnCached = this.On;
737
+ this.accessory.context.On = this.OnCached;
738
+ }).catch(async (e: any) => {
739
+ this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection`);
740
+ if (this.deviceLogging === 'debug') {
741
+ this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection,`
742
+ + ` Error Message: ${JSON.stringify(e.message)}`);
743
+ }
744
+ if (this.platform.debugMode) {
745
+ this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection,`
746
+ + ` Error: ${JSON.stringify(e)}`);
747
+ }
748
+ if (this.platform.config.credentials?.openToken) {
749
+ this.warnLog(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
750
+ await this.openAPIpushChanges();
751
+ }
752
+ this.apiError(e);
753
+ });
571
754
  } else {
572
- this.errorLog(`Bot: ${this.accessory.displayName} wasn't able to establish BLE Connection`);
573
- if (this.platform.config.credentials?.openToken) {
574
- this.warnLog(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
575
- await this.openAPIpushChanges();
576
- }
755
+ throw new Error(`Bot: ${this.accessory.displayName} Bot Mode: ${this.botMode}`);
577
756
  }
757
+ /* } else {
758
+ this.errorLog(`Bot: ${this.accessory.displayName} wasn't able to establish BLE Connection`);
759
+ if (this.platform.config.credentials?.openToken) {
760
+ this.warnLog(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
761
+ await this.openAPIpushChanges();
762
+ }
763
+ }*/
578
764
  }
579
765
  this.OnCached = this.On;
580
766
  this.accessory.context.On = this.OnCached;
@@ -661,7 +847,7 @@ export class Bot {
661
847
  this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic TargetDoorState: Open, CurrentDoorState: Open`);
662
848
  }
663
849
  }
664
- this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
850
+ this.debugLog(`Bot: ${this.accessory.displayName} Garage Door On: ${this.On}`);
665
851
  } else if (this.device.bot?.deviceType === 'door') {
666
852
  if (this.On === undefined) {
667
853
  this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
@@ -680,7 +866,92 @@ export class Bot {
680
866
  this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic TargetPosition: 0, CurrentPosition: 0`);
681
867
  }
682
868
  }
683
- this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
869
+ this.debugLog(`Bot: ${this.accessory.displayName} Door On: ${this.On}`);
870
+ } else if (this.device.bot?.deviceType === 'window') {
871
+ if (this.On === undefined) {
872
+ this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
873
+ } else {
874
+ if (this.On) {
875
+ this.windowService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, 100);
876
+ this.windowService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, 100);
877
+ this.windowService?.updateCharacteristic(this.platform.Characteristic.PositionState,
878
+ this.platform.Characteristic.PositionState.STOPPED);
879
+ this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic TargetPosition: 100, CurrentPosition: 100`);
880
+ } else {
881
+ this.windowService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, 0);
882
+ this.windowService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, 0);
883
+ this.windowService?.updateCharacteristic(this.platform.Characteristic.PositionState,
884
+ this.platform.Characteristic.PositionState.STOPPED);
885
+ this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic TargetPosition: 0, CurrentPosition: 0`);
886
+ }
887
+ }
888
+ this.debugLog(`Bot: ${this.accessory.displayName} Window On: ${this.On}`);
889
+ } else if (this.device.bot?.deviceType === 'windowcovering') {
890
+ if (this.On === undefined) {
891
+ this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
892
+ } else {
893
+ if (this.On) {
894
+ this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, 100);
895
+ this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, 100);
896
+ this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.PositionState,
897
+ this.platform.Characteristic.PositionState.STOPPED);
898
+ this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic TargetPosition: 100, CurrentPosition: 100`);
899
+ } else {
900
+ this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, 0);
901
+ this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, 0);
902
+ this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.PositionState,
903
+ this.platform.Characteristic.PositionState.STOPPED);
904
+ this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic TargetPosition: 0, CurrentPosition: 0`);
905
+ }
906
+ }
907
+ this.debugLog(`Bot: ${this.accessory.displayName} Window Covering On: ${this.On}`);
908
+ } else if (this.device.bot?.deviceType === 'lock') {
909
+ if (this.On === undefined) {
910
+ this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
911
+ } else {
912
+ if (this.On) {
913
+ this.lockService?.updateCharacteristic(this.platform.Characteristic.LockTargetState,
914
+ this.platform.Characteristic.LockTargetState.UNSECURED);
915
+ this.lockService?.updateCharacteristic(this.platform.Characteristic.LockCurrentState,
916
+ this.platform.Characteristic.LockCurrentState.UNSECURED);
917
+ this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic LockTargetState: UNSECURED, LockCurrentState: UNSECURED`);
918
+ } else {
919
+ this.lockService?.updateCharacteristic(this.platform.Characteristic.LockTargetState,
920
+ this.platform.Characteristic.LockTargetState.SECURED);
921
+ this.lockService?.updateCharacteristic(this.platform.Characteristic.LockCurrentState,
922
+ this.platform.Characteristic.LockCurrentState.SECURED);
923
+ this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic LockTargetState: SECURED, LockCurrentState: SECURED`);
924
+ }
925
+ }
926
+ this.debugLog(`Bot: ${this.accessory.displayName} Lock On: ${this.On}`);
927
+ } else if (this.device.bot?.deviceType === 'faucet') {
928
+ if (this.On === undefined) {
929
+ this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
930
+ } else {
931
+ if (this.On) {
932
+ this.faucetService?.updateCharacteristic(this.platform.Characteristic.Active,
933
+ this.platform.Characteristic.Active.ACTIVE);
934
+ this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic Active: ${this.On}`);
935
+ } else {
936
+ this.faucetService?.updateCharacteristic(this.platform.Characteristic.Active,
937
+ this.platform.Characteristic.Active.INACTIVE);
938
+ this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic Active: ${this.On}`);
939
+ }
940
+ }
941
+ this.debugLog(`Bot: ${this.accessory.displayName} Faucet On: ${this.On}`);
942
+ } else if (this.device.bot?.deviceType === 'fan') {
943
+ if (this.On === undefined) {
944
+ this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
945
+ } else {
946
+ if (this.On) {
947
+ this.fanService?.updateCharacteristic(this.platform.Characteristic.On, this.On);
948
+ this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
949
+ } else {
950
+ this.fanService?.updateCharacteristic(this.platform.Characteristic.On, this.On);
951
+ this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
952
+ }
953
+ }
954
+ this.debugLog(`Bot: ${this.accessory.displayName} Fan On: ${this.On}`);
684
955
  } else if (this.device.bot?.deviceType === 'switch') {
685
956
  if (this.On === undefined) {
686
957
  this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
@@ -696,8 +967,6 @@ export class Bot {
696
967
  this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
697
968
  }
698
969
  }
699
-
700
-
701
970
  if (this.device.ble) {
702
971
  if (this.BatteryLevel === undefined) {
703
972
  this.debugLog(`Bot: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
@@ -723,6 +992,21 @@ export class Bot {
723
992
  this.doorService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, e);
724
993
  this.doorService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, e);
725
994
  this.doorService?.updateCharacteristic(this.platform.Characteristic.PositionState, e);
995
+ } else if (this.device.bot?.deviceType === 'window') {
996
+ this.windowService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, e);
997
+ this.windowService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, e);
998
+ this.windowService?.updateCharacteristic(this.platform.Characteristic.PositionState, e);
999
+ } else if (this.device.bot?.deviceType === 'windowcovering') {
1000
+ this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, e);
1001
+ this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, e);
1002
+ this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.PositionState, e);
1003
+ } else if (this.device.bot?.deviceType === 'lock') {
1004
+ this.doorService?.updateCharacteristic(this.platform.Characteristic.LockTargetState, e);
1005
+ this.doorService?.updateCharacteristic(this.platform.Characteristic.LockCurrentState, e);
1006
+ } else if (this.device.bot?.deviceType === 'faucet') {
1007
+ this.faucetService?.updateCharacteristic(this.platform.Characteristic.Active, e);
1008
+ } else if (this.device.bot?.deviceType === 'fan') {
1009
+ this.fanService?.updateCharacteristic(this.platform.Characteristic.On, e);
726
1010
  } else if (this.device.bot?.deviceType === 'switch') {
727
1011
  this.switchService?.updateCharacteristic(this.platform.Characteristic.On, e);
728
1012
  } else {
@@ -788,9 +1072,25 @@ export class Bot {
788
1072
  } else {
789
1073
  this.On = true;
790
1074
  }
791
- } else if (this.device.bot?.deviceType === 'door') {
1075
+ } else if (this.device.bot?.deviceType === 'door'
1076
+ || this.device.bot?.deviceType === 'window'
1077
+ || this.device.bot?.deviceType === 'windowcovering') {
792
1078
  this.debugLog(`Bot: ${this.accessory.displayName} TargetPosition: ${value}`);
793
- if (value === 100) {
1079
+ if (value === 0) {
1080
+ this.On = false;
1081
+ } else {
1082
+ this.On = true;
1083
+ }
1084
+ } else if (this.device.bot?.deviceType === 'lock') {
1085
+ this.debugLog(`Bot: ${this.accessory.displayName} LockTargetState: ${value}`);
1086
+ if (value === this.platform.Characteristic.LockTargetState.SECURED) {
1087
+ this.On = false;
1088
+ } else {
1089
+ this.On = true;
1090
+ }
1091
+ } else if (this.device.bot?.deviceType === 'faucet') {
1092
+ this.debugLog(`Bot: ${this.accessory.displayName} Active: ${value}`);
1093
+ if (value === this.platform.Characteristic.Active.INACTIVE) {
794
1094
  this.On = false;
795
1095
  } else {
796
1096
  this.On = true;