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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/config.schema.json +101 -33
  3. package/dist/devices/bots.d.ts +9 -5
  4. package/dist/devices/bots.d.ts.map +1 -1
  5. package/dist/devices/bots.js +144 -77
  6. package/dist/devices/bots.js.map +1 -1
  7. package/dist/devices/colorbulb.d.ts +9 -4
  8. package/dist/devices/colorbulb.d.ts.map +1 -1
  9. package/dist/devices/colorbulb.js +40 -37
  10. package/dist/devices/colorbulb.js.map +1 -1
  11. package/dist/devices/contact.d.ts +10 -2
  12. package/dist/devices/contact.d.ts.map +1 -1
  13. package/dist/devices/contact.js +92 -51
  14. package/dist/devices/contact.js.map +1 -1
  15. package/dist/devices/curtains.d.ts +10 -3
  16. package/dist/devices/curtains.d.ts.map +1 -1
  17. package/dist/devices/curtains.js +52 -34
  18. package/dist/devices/curtains.js.map +1 -1
  19. package/dist/devices/humidifiers.d.ts +8 -2
  20. package/dist/devices/humidifiers.d.ts.map +1 -1
  21. package/dist/devices/humidifiers.js +28 -35
  22. package/dist/devices/humidifiers.js.map +1 -1
  23. package/dist/devices/meters.d.ts +14 -12
  24. package/dist/devices/meters.d.ts.map +1 -1
  25. package/dist/devices/meters.js +63 -103
  26. package/dist/devices/meters.js.map +1 -1
  27. package/dist/devices/motion.d.ts +10 -3
  28. package/dist/devices/motion.d.ts.map +1 -1
  29. package/dist/devices/motion.js +114 -68
  30. package/dist/devices/motion.js.map +1 -1
  31. package/dist/devices/plugs.d.ts +3 -1
  32. package/dist/devices/plugs.d.ts.map +1 -1
  33. package/dist/devices/plugs.js +8 -1
  34. package/dist/devices/plugs.js.map +1 -1
  35. package/dist/irdevices/airconditioners.d.ts +1 -0
  36. package/dist/irdevices/airconditioners.d.ts.map +1 -1
  37. package/dist/irdevices/airconditioners.js +6 -0
  38. package/dist/irdevices/airconditioners.js.map +1 -1
  39. package/dist/irdevices/airpurifiers.d.ts +1 -0
  40. package/dist/irdevices/airpurifiers.d.ts.map +1 -1
  41. package/dist/irdevices/airpurifiers.js +6 -0
  42. package/dist/irdevices/airpurifiers.js.map +1 -1
  43. package/dist/irdevices/cameras.d.ts +1 -0
  44. package/dist/irdevices/cameras.d.ts.map +1 -1
  45. package/dist/irdevices/cameras.js +6 -0
  46. package/dist/irdevices/cameras.js.map +1 -1
  47. package/dist/irdevices/fans.d.ts +1 -0
  48. package/dist/irdevices/fans.d.ts.map +1 -1
  49. package/dist/irdevices/fans.js +6 -0
  50. package/dist/irdevices/fans.js.map +1 -1
  51. package/dist/irdevices/lights.d.ts +1 -0
  52. package/dist/irdevices/lights.d.ts.map +1 -1
  53. package/dist/irdevices/lights.js +6 -0
  54. package/dist/irdevices/lights.js.map +1 -1
  55. package/dist/irdevices/others.d.ts +1 -0
  56. package/dist/irdevices/others.d.ts.map +1 -1
  57. package/dist/irdevices/others.js +6 -0
  58. package/dist/irdevices/others.js.map +1 -1
  59. package/dist/irdevices/tvs.d.ts +1 -0
  60. package/dist/irdevices/tvs.d.ts.map +1 -1
  61. package/dist/irdevices/tvs.js +6 -0
  62. package/dist/irdevices/tvs.js.map +1 -1
  63. package/dist/irdevices/vacuumcleaners.d.ts +1 -0
  64. package/dist/irdevices/vacuumcleaners.d.ts.map +1 -1
  65. package/dist/irdevices/vacuumcleaners.js +6 -0
  66. package/dist/irdevices/vacuumcleaners.js.map +1 -1
  67. package/dist/irdevices/waterheaters.d.ts +1 -0
  68. package/dist/irdevices/waterheaters.d.ts.map +1 -1
  69. package/dist/irdevices/waterheaters.js +6 -0
  70. package/dist/irdevices/waterheaters.js.map +1 -1
  71. package/dist/platform.d.ts +2 -1
  72. package/dist/platform.d.ts.map +1 -1
  73. package/dist/platform.js +14 -1
  74. package/dist/platform.js.map +1 -1
  75. package/dist/settings.d.ts +14 -0
  76. package/dist/settings.d.ts.map +1 -1
  77. package/dist/settings.js.map +1 -1
  78. package/package.json +71 -71
  79. package/src/devices/bots.ts +140 -74
  80. package/src/devices/colorbulb.ts +46 -40
  81. package/src/devices/contact.ts +99 -55
  82. package/src/devices/curtains.ts +60 -36
  83. package/src/devices/humidifiers.ts +36 -36
  84. package/src/devices/meters.ts +79 -113
  85. package/src/devices/motion.ts +125 -74
  86. package/src/devices/plugs.ts +11 -2
  87. package/src/irdevices/airconditioners.ts +7 -0
  88. package/src/irdevices/airpurifiers.ts +7 -0
  89. package/src/irdevices/cameras.ts +7 -0
  90. package/src/irdevices/fans.ts +7 -0
  91. package/src/irdevices/lights.ts +7 -0
  92. package/src/irdevices/others.ts +7 -0
  93. package/src/irdevices/tvs.ts +7 -0
  94. package/src/irdevices/vacuumcleaners.ts +7 -0
  95. package/src/irdevices/waterheaters.ts +7 -0
  96. package/src/platform.ts +14 -1
  97. package/src/settings.ts +15 -0
package/package.json CHANGED
@@ -1,74 +1,74 @@
1
1
  {
2
- "displayName": "Homebridge SwitchBot",
3
- "name": "@switchbot/homebridge-switchbot",
4
- "version": "1.7.0",
5
- "description": "The [Homebridge](https://homebridge.io) SwitchBot plugin allows you to access your [SwitchBot](https://www.switch-bot.com) device(s) from HomeKit.",
6
- "author": "SwitchBot <support@wondertechlabs.com> (https://github.com/SwitchBot)",
7
- "license": "ISC",
8
- "repository": {
9
- "type": "git",
10
- "url": "git://github.com/OpenWonderLabs/homebridge-switchbot.git"
11
- },
12
- "bugs": {
13
- "url": "https://github.com/OpenWonderLabs/homebridge-switchbot/issues"
14
- },
15
- "engines": {
16
- "homebridge": "^1.3.9",
17
- "node": "^14.18.2 || ^16.13.1"
18
- },
19
- "main": "dist/index.js",
20
- "scripts": {
21
- "check": "npm install && npm outdated",
22
- "update": "ncu -u && npm update && npm install",
23
- "lint": "eslint src/**.ts",
24
- "watch": "npm run build && npm link && nodemon",
25
- "build": "rimraf ./dist && tsc",
26
- "prepublishOnly": "npm run lint && npm run build"
27
- },
28
- "funding": [
29
- {
30
- "type": "Paypal",
31
- "url": "https://paypal.me/donavanbecker"
2
+ "displayName": "Homebridge SwitchBot",
3
+ "name": "@switchbot/homebridge-switchbot",
4
+ "version": "1.7.1-beta.11",
5
+ "description": "The [Homebridge](https://homebridge.io) SwitchBot plugin allows you to access your [SwitchBot](https://www.switch-bot.com) device(s) from HomeKit.",
6
+ "author": "SwitchBot <support@wondertechlabs.com> (https://github.com/SwitchBot)",
7
+ "license": "ISC",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git://github.com/OpenWonderLabs/homebridge-switchbot.git"
32
11
  },
33
- {
34
- "type": "GitHub",
35
- "url": "https://github.com/sponsors/donavanbecker"
12
+ "bugs": {
13
+ "url": "https://github.com/OpenWonderLabs/homebridge-switchbot/issues"
14
+ },
15
+ "engines": {
16
+ "homebridge": "^1.3.9",
17
+ "node": "^14.18.3 || ^16.13.2"
18
+ },
19
+ "main": "dist/index.js",
20
+ "scripts": {
21
+ "check": "npm install && npm outdated",
22
+ "update": "ncu -u && npm update && npm install",
23
+ "lint": "eslint src/**.ts",
24
+ "watch": "npm run build && npm link && nodemon",
25
+ "build": "rimraf ./dist && tsc",
26
+ "prepublishOnly": "npm run lint && npm run build"
27
+ },
28
+ "funding": [
29
+ {
30
+ "type": "Paypal",
31
+ "url": "https://paypal.me/donavanbecker"
32
+ },
33
+ {
34
+ "type": "GitHub",
35
+ "url": "https://github.com/sponsors/donavanbecker"
36
+ }
37
+ ],
38
+ "publishConfig": {
39
+ "access": "public"
40
+ },
41
+ "keywords": [
42
+ "homebridge-plugin",
43
+ "switchbot",
44
+ "humidifier",
45
+ "humidity",
46
+ "temperature",
47
+ "bot",
48
+ "curtains",
49
+ "windows",
50
+ "ble",
51
+ "ir"
52
+ ],
53
+ "dependencies": {
54
+ "@homebridge/plugin-ui-utils": "^0.0.19",
55
+ "axios": "^0.24.0",
56
+ "rxjs": "^7.5.2"
57
+ },
58
+ "devDependencies": {
59
+ "@types/node": "^17.0.8",
60
+ "@typescript-eslint/eslint-plugin": "^5.9.1",
61
+ "@typescript-eslint/parser": "^5.9.1",
62
+ "eslint": "^8.6.0",
63
+ "homebridge": "^1.3.9",
64
+ "nodemon": "^2.0.15",
65
+ "npm-check-updates": "^12.1.0",
66
+ "rimraf": "^3.0.2",
67
+ "ts-node": "^10.4.0",
68
+ "typescript": "^4.5.4",
69
+ "typescript-axios-wb": "^1.0.3"
70
+ },
71
+ "optionalDependencies": {
72
+ "node-switchbot": "^1.1.2"
36
73
  }
37
- ],
38
- "publishConfig": {
39
- "access": "public"
40
- },
41
- "keywords": [
42
- "homebridge-plugin",
43
- "switchbot",
44
- "humidifier",
45
- "humidity",
46
- "temperature",
47
- "bot",
48
- "curtains",
49
- "windows",
50
- "ble",
51
- "ir"
52
- ],
53
- "dependencies": {
54
- "@homebridge/plugin-ui-utils": "^0.0.19",
55
- "axios": "^0.24.0",
56
- "rxjs": "^7.5.1"
57
- },
58
- "devDependencies": {
59
- "@types/node": "^17.0.8",
60
- "@typescript-eslint/eslint-plugin": "^5.9.0",
61
- "@typescript-eslint/parser": "^5.9.0",
62
- "eslint": "^8.6.0",
63
- "homebridge": "^1.3.9",
64
- "nodemon": "^2.0.15",
65
- "npm-check-updates": "^12.1.0",
66
- "rimraf": "^3.0.2",
67
- "ts-node": "^10.4.0",
68
- "typescript": "^4.5.4",
69
- "typescript-axios-wb": "^1.0.3"
70
- },
71
- "optionalDependencies": {
72
- "node-switchbot": "^1.1.2"
73
- }
74
- }
74
+ }
@@ -4,7 +4,7 @@ import { interval, Subject } from 'rxjs';
4
4
  import { SwitchBotPlatform } from '../platform';
5
5
  import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
6
6
  import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
7
- import { DeviceURL, device, devicesConfig, serviceData, ad, switchbot, deviceStatusResponse, payload } from '../settings';
7
+ import { DeviceURL, device, devicesConfig, serviceData, ad, switchbot, deviceStatusResponse, payload, deviceStatus } from '../settings';
8
8
 
9
9
  /**
10
10
  * Platform Accessory
@@ -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
@@ -32,11 +33,13 @@ export class Bot {
32
33
  StatusLowBattery!: CharacteristicValue;
33
34
 
34
35
  // OpenAPI Others
36
+ power: deviceStatus['power'];
35
37
  deviceStatus!: deviceStatusResponse;
36
38
 
37
39
  // BLE Others
38
40
  connected?: boolean;
39
41
  switchbot!: switchbot;
42
+ SwitchToOpenAPI?: boolean;
40
43
  serviceData!: serviceData;
41
44
  mode!: serviceData['mode'];
42
45
  state!: serviceData['state'];
@@ -61,11 +64,11 @@ export class Bot {
61
64
  public device: device & devicesConfig,
62
65
  ) {
63
66
  // default placeholders
64
- this.logs();
65
- this.scan();
66
- this.refreshRate();
67
+ this.logs(device);
68
+ this.scan(device);
69
+ this.refreshRate(device);
67
70
  this.PressOrSwitch();
68
-
71
+ this.config(device);
69
72
  if (this.On === undefined) {
70
73
  this.On = false;
71
74
  this.accessory.context.On = this.On;
@@ -81,10 +84,6 @@ export class Bot {
81
84
  this.BatteryLevel = 100;
82
85
  this.StatusLowBattery = 0;
83
86
 
84
- // Bot Config
85
- this.debugLog(`Bot: ${this.accessory.displayName} Config: (ble: ${device.ble}, offline: ${device.offline}, mode: ${device.bot?.mode},`
86
- + ` deviceType: ${device.bot?.deviceType}, doublePress: ${this.doublePress})`);
87
-
88
87
  // this is subject we use to track when we need to POST changes to the SwitchBot API
89
88
  this.doBotUpdate = new Subject();
90
89
  this.botUpdateInProgress = false;
@@ -110,6 +109,7 @@ export class Bot {
110
109
  this.removeWindowService(accessory);
111
110
  this.removeGarageDoorService(accessory);
112
111
  this.removeWindowCoveringService(accessory);
112
+ this.removeStatefulProgrammableSwitchService(accessory);
113
113
 
114
114
  // Add switchService
115
115
  (this.switchService =
@@ -128,6 +128,7 @@ export class Bot {
128
128
  this.removeSwitchService(accessory);
129
129
  this.removeWindowService(accessory);
130
130
  this.removeWindowCoveringService(accessory);
131
+ this.removeStatefulProgrammableSwitchService(accessory);
131
132
 
132
133
  // Add switchService
133
134
  (this.garageDoorService =
@@ -147,6 +148,7 @@ export class Bot {
147
148
  this.removeWindowService(accessory);
148
149
  this.removeGarageDoorService(accessory);
149
150
  this.removeWindowCoveringService(accessory);
151
+ this.removeStatefulProgrammableSwitchService(accessory);
150
152
 
151
153
  // Add switchService
152
154
  (this.doorService =
@@ -172,6 +174,7 @@ export class Bot {
172
174
  this.removeSwitchService(accessory);
173
175
  this.removeGarageDoorService(accessory);
174
176
  this.removeWindowCoveringService(accessory);
177
+ this.removeStatefulProgrammableSwitchService(accessory);
175
178
 
176
179
  // Add switchService
177
180
  (this.windowService =
@@ -197,6 +200,7 @@ export class Bot {
197
200
  this.removeSwitchService(accessory);
198
201
  this.removeWindowService(accessory);
199
202
  this.removeGarageDoorService(accessory);
203
+ this.removeStatefulProgrammableSwitchService(accessory);
200
204
 
201
205
  // Add switchService
202
206
  (this.windowCoveringService =
@@ -222,6 +226,7 @@ export class Bot {
222
226
  this.removeWindowService(accessory);
223
227
  this.removeGarageDoorService(accessory);
224
228
  this.removeWindowCoveringService(accessory);
229
+ this.removeStatefulProgrammableSwitchService(accessory);
225
230
 
226
231
  // Add switchService
227
232
  (this.lockService =
@@ -240,6 +245,7 @@ export class Bot {
240
245
  this.removeWindowService(accessory);
241
246
  this.removeGarageDoorService(accessory);
242
247
  this.removeWindowCoveringService(accessory);
248
+ this.removeStatefulProgrammableSwitchService(accessory);
243
249
 
244
250
  // Add switchService
245
251
  (this.faucetService =
@@ -258,6 +264,7 @@ export class Bot {
258
264
  this.removeWindowService(accessory);
259
265
  this.removeGarageDoorService(accessory);
260
266
  this.removeWindowCoveringService(accessory);
267
+ this.removeStatefulProgrammableSwitchService(accessory);
261
268
 
262
269
  // Add switchService
263
270
  (this.fanService =
@@ -267,6 +274,26 @@ export class Bot {
267
274
 
268
275
  this.fanService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
269
276
  this.fanService.getCharacteristic(this.platform.Characteristic.On).onSet(this.handleOnSet.bind(this));
277
+ } else if (device.bot?.deviceType === 'stateful') {
278
+ this.removeFanService(accessory);
279
+ this.removeLockService(accessory);
280
+ this.removeDoorService(accessory);
281
+ this.removeFaucetService(accessory);
282
+ this.removeOutletService(accessory);
283
+ this.removeSwitchService(accessory);
284
+ this.removeWindowService(accessory);
285
+ this.removeGarageDoorService(accessory);
286
+ this.removeWindowCoveringService(accessory);
287
+
288
+ // Add switchService
289
+ (this.statefulProgrammableSwitchService =
290
+ accessory.getService(this.platform.Service.StatefulProgrammableSwitch) ||
291
+ accessory.addService(this.platform.Service.StatefulProgrammableSwitch)), `${accessory.displayName} Stateful Programmable Switch`;
292
+ this.infoLog(`Bot: ${accessory.displayName} Displaying as Stateful Programmable Switch`);
293
+
294
+ this.statefulProgrammableSwitchService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
295
+ this.statefulProgrammableSwitchService.getCharacteristic(this.platform.Characteristic.ProgrammableSwitchOutputState)
296
+ .onSet(this.handleOnSet.bind(this));
270
297
  } else {
271
298
  this.removeFanService(accessory);
272
299
  this.removeLockService(accessory);
@@ -276,6 +303,7 @@ export class Bot {
276
303
  this.removeWindowService(accessory);
277
304
  this.removeGarageDoorService(accessory);
278
305
  this.removeWindowCoveringService(accessory);
306
+ this.removeStatefulProgrammableSwitchService(accessory);
279
307
 
280
308
  // Add outletService
281
309
  (this.outletService =
@@ -287,12 +315,21 @@ export class Bot {
287
315
  this.outletService.getCharacteristic(this.platform.Characteristic.On).onSet(this.handleOnSet.bind(this));
288
316
  }
289
317
 
290
- if (device.ble) {
318
+ // Battery Service
319
+ if (!device.ble) {
320
+ this.debugLog(`Bot: ${accessory.displayName} Removing Battery Service`);
321
+ this.batteryService = this.accessory.getService(this.platform.Service.Battery);
322
+ accessory.removeService(this.batteryService!);
323
+ } else if (device.ble && !this.batteryService) {
324
+ this.debugLog(`Bot: ${accessory.displayName} Add Battery Service`);
291
325
  (this.batteryService =
292
- accessory.getService(this.platform.Service.Battery) ||
293
- accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
326
+ this.accessory.getService(this.platform.Service.Battery) ||
327
+ this.accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
294
328
 
295
329
  this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Battery`);
330
+
331
+ } else {
332
+ this.debugLog(`Bot: ${accessory.displayName} Battery Service Not Added`);
296
333
  }
297
334
 
298
335
  // Retrieve initial values and updateHomekit
@@ -408,6 +445,15 @@ export class Bot {
408
445
  accessory.removeService(this.windowCoveringService!);
409
446
  }
410
447
 
448
+ public removeStatefulProgrammableSwitchService(accessory: PlatformAccessory) {
449
+ // If statefulProgrammableSwitchService still pressent, then remove first
450
+ this.statefulProgrammableSwitchService = this.accessory.getService(this.platform.Service.StatefulProgrammableSwitch);
451
+ if (this.statefulProgrammableSwitchService) {
452
+ this.warnLog(`Bot: ${accessory.displayName} Removing Leftover Stateful Programmable Switch Service`);
453
+ }
454
+ accessory.removeService(this.statefulProgrammableSwitchService!);
455
+ }
456
+
411
457
  public removeSwitchService(accessory: PlatformAccessory) {
412
458
  // If switchService still pressent, then remove first
413
459
  this.switchService = this.accessory.getService(this.platform.Service.Switch);
@@ -417,50 +463,52 @@ export class Bot {
417
463
  accessory.removeService(this.switchService!);
418
464
  }
419
465
 
420
- refreshRate() {
421
- if (this.device.refreshRate) {
422
- this.deviceRefreshRate = this.accessory.context.refreshRate = this.device.refreshRate;
423
- if (this.platform.debugMode || (this.deviceLogging === 'debug')) {
424
- this.warnLog(`Bot: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
466
+ scan(device: device & devicesConfig) {
467
+ if (device.scanDuration) {
468
+ this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
469
+ if (device.ble) {
470
+ this.debugLog(`Bot: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
425
471
  }
426
- } else if (this.platform.config.options!.refreshRate) {
427
- this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
428
- if (this.platform.debugMode || (this.deviceLogging === 'debug')) {
429
- this.warnLog(`Bot: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
472
+ } else {
473
+ this.scanDuration = this.accessory.context.scanDuration = 1;
474
+ if (this.device.ble) {
475
+ this.debugLog(`Bot: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
430
476
  }
431
477
  }
432
478
  }
433
479
 
434
- scan() {
435
- if (this.device.scanDuration) {
436
- this.scanDuration = this.accessory.context.scanDuration = this.device.scanDuration;
437
- if (this.platform.debugMode || (this.deviceLogging === 'debug')) {
438
- this.warnLog(`Bot: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
439
- }
440
- } else {
441
- this.scanDuration = this.accessory.context.scanDuration = 1;
442
- if (this.platform.debugMode || (this.deviceLogging === 'debug')) {
443
- this.warnLog(`Bot: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
444
- }
480
+ config(device: device & devicesConfig) {
481
+ if (device.bot !== undefined) {
482
+ device.bot['ble'] = device.ble;
483
+ device.bot['logging'] = this.deviceLogging;
484
+ device.bot['refreshRate'] = this.deviceRefreshRate;
485
+ this.warnLog(`Bot: ${this.accessory.displayName} Config: ${JSON.stringify(device.bot)}`);
445
486
  }
446
487
  }
447
488
 
448
- logs() {
489
+ refreshRate(device: device & devicesConfig) {
490
+ if (device.refreshRate) {
491
+ this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
492
+ this.debugLog(`Bot: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
493
+ } else if (this.platform.config.options!.refreshRate) {
494
+ this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
495
+ this.debugLog(`Bot: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
496
+ }
497
+ }
498
+
499
+ logs(device: device & devicesConfig) {
449
500
  if (this.platform.debugMode) {
450
- this.deviceLogging = this.accessory.context.logging = 'debug';
451
- this.warnLog(`Bot: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
452
- } else if (this.device.logging) {
453
- this.deviceLogging = this.accessory.context.logging = this.device.logging;
454
- if (this.deviceLogging === 'debug' || this.deviceLogging === 'standard') {
455
- this.warnLog(`Bot: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
456
- }
501
+ this.deviceLogging = this.accessory.context.logging = 'debugMode';
502
+ this.debugLog(`Bot: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
503
+ } else if (device.logging) {
504
+ this.deviceLogging = this.accessory.context.logging = device.logging;
505
+ this.debugLog(`Bot: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
457
506
  } else if (this.platform.config.options?.logging) {
458
507
  this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
459
- if (this.deviceLogging === 'debug' || this.deviceLogging === 'standard') {
460
- this.warnLog(`Bot: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
461
- }
508
+ this.debugLog(`Bot: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
462
509
  } else {
463
510
  this.deviceLogging = this.accessory.context.logging = 'standard';
511
+ this.debugLog(`Bot: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
464
512
  }
465
513
  }
466
514
 
@@ -484,10 +532,10 @@ export class Bot {
484
532
  * Parse the device status from the SwitchBot api
485
533
  */
486
534
  async parseStatus() {
487
- if (this.device.ble) {
488
- await this.BLEparseStatus();
489
- } else {
535
+ if (this.SwitchToOpenAPI || !this.device.ble) {
490
536
  await this.openAPIparseStatus();
537
+ } else {
538
+ await this.BLEparseStatus();
491
539
  }
492
540
  }
493
541
 
@@ -521,6 +569,9 @@ export class Bot {
521
569
  }
522
570
 
523
571
  private async openAPIparseStatus() {
572
+ if (this.device.ble) {
573
+ this.SwitchToOpenAPI = false;
574
+ }
524
575
  if (this.platform.config.credentials?.openToken) {
525
576
  this.debugLog(`Bot: ${this.accessory.displayName} OpenAPI parseStatus`);
526
577
  if (this.botMode === 'press') {
@@ -528,7 +579,7 @@ export class Bot {
528
579
  this.OnCached = this.On;
529
580
  this.accessory.context.On = this.OnCached;
530
581
  } else {
531
- if (this.deviceStatus.body.power === 'on') {
582
+ /*if (this.power === 'on') {
532
583
  this.On = true;
533
584
  this.OnCached = this.On;
534
585
  this.accessory.context.On = this.OnCached;
@@ -536,6 +587,11 @@ export class Bot {
536
587
  this.On = false;
537
588
  this.OnCached = this.On;
538
589
  this.accessory.context.On = this.OnCached;
590
+ }*/
591
+ this.OnCached = this.On;
592
+ this.accessory.context.On = this.OnCached;
593
+ if (this.On === undefined) {
594
+ this.On = false;
539
595
  }
540
596
  }
541
597
  this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
@@ -553,35 +609,12 @@ export class Bot {
553
609
  }
554
610
  }
555
611
 
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
- }
577
- return switchbot;
578
- }
579
-
580
612
  private async BLERefreshStatus() {
581
613
  this.debugLog(`Bot: ${this.accessory.displayName} BLE refreshStatus`);
582
-
614
+ const switchbot = await this.platform.connectBLE();
583
615
  // Convert to BLE Address
584
- const switchbot = await this.connectBLE();
616
+ this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
617
+ this.debugLog(`Curtain: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
585
618
  // Start to monitor advertisement packets
586
619
  if (switchbot === false) {
587
620
  this.errorLog(`Bot: ${this.accessory.displayName} wasn't able to establish BLE Connection: ${switchbot}`);
@@ -620,6 +653,7 @@ export class Bot {
620
653
  this.errorLog(`Bot: ${this.accessory.displayName} wasn't able to establish BLE Connection`);
621
654
  if (this.platform.config.credentials?.openToken) {
622
655
  this.warnLog(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
656
+ this.SwitchToOpenAPI = true;
623
657
  await this.openAPIRefreshStatus();
624
658
  }
625
659
  }
@@ -635,6 +669,7 @@ export class Bot {
635
669
  }
636
670
  if (this.platform.config.credentials?.openToken) {
637
671
  this.warnLog(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
672
+ this.SwitchToOpenAPI = true;
638
673
  await this.openAPIRefreshStatus();
639
674
  }
640
675
  this.apiError(e);
@@ -647,6 +682,7 @@ export class Bot {
647
682
  try {
648
683
  this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
649
684
  this.debugLog(`Bot: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
685
+ this.power = this.deviceStatus.body.power;
650
686
  this.parseStatus();
651
687
  this.updateHomeKitCharacteristics();
652
688
  } catch (e: any) {
@@ -689,7 +725,10 @@ export class Bot {
689
725
  this.debugLog(`Bot: ${this.accessory.displayName} BLE pushChanges On: ${this.On} OnCached: ${this.OnCached}`);
690
726
  if (this.On !== this.OnCached) {
691
727
  this.debugLog(`Bot: ${this.accessory.displayName} BLE pushChanges`);
692
- const switchbot = await this.connectBLE();
728
+ const switchbot = await this.platform.connectBLE();
729
+ // Convert to BLE Address
730
+ this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
731
+ this.debugLog(`Curtain: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
693
732
  //if (switchbot !== false) {
694
733
  if (this.botMode === 'press') {
695
734
  this.debugLog(`Bot: ${this.accessory.displayName} Bot Mode: ${this.botMode}`);
@@ -952,6 +991,23 @@ export class Bot {
952
991
  }
953
992
  }
954
993
  this.debugLog(`Bot: ${this.accessory.displayName} Fan On: ${this.On}`);
994
+ } else if (this.device.bot?.deviceType === 'stateful') {
995
+ if (this.On === undefined) {
996
+ this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
997
+ } else {
998
+ if (this.On) {
999
+ this.statefulProgrammableSwitchService?.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchEvent,
1000
+ this.platform.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS);
1001
+ this.statefulProgrammableSwitchService?.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchOutputState, 1);
1002
+ this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic ProgrammableSwitchEvent: SINGLE, ProgrammableSwitchOutputState: 1`);
1003
+ } else {
1004
+ this.statefulProgrammableSwitchService?.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchEvent,
1005
+ this.platform.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS);
1006
+ this.statefulProgrammableSwitchService?.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchOutputState, 0);
1007
+ this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic ProgrammableSwitchEvent: SINGLE, ProgrammableSwitchOutputState: 0`);
1008
+ }
1009
+ }
1010
+ this.debugLog(`Bot: ${this.accessory.displayName} StatefulProgrammableSwitch On: ${this.On}`);
955
1011
  } else if (this.device.bot?.deviceType === 'switch') {
956
1012
  if (this.On === undefined) {
957
1013
  this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
@@ -1007,6 +1063,9 @@ export class Bot {
1007
1063
  this.faucetService?.updateCharacteristic(this.platform.Characteristic.Active, e);
1008
1064
  } else if (this.device.bot?.deviceType === 'fan') {
1009
1065
  this.fanService?.updateCharacteristic(this.platform.Characteristic.On, e);
1066
+ } else if (this.device.bot?.deviceType === 'stateful') {
1067
+ this.statefulProgrammableSwitchService?.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchEvent, e);
1068
+ this.statefulProgrammableSwitchService?.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchOutputState, e);
1010
1069
  } else if (this.device.bot?.deviceType === 'switch') {
1011
1070
  this.switchService?.updateCharacteristic(this.platform.Characteristic.On, e);
1012
1071
  } else {
@@ -1095,6 +1154,13 @@ export class Bot {
1095
1154
  } else {
1096
1155
  this.On = true;
1097
1156
  }
1157
+ } else if (this.device.bot?.deviceType === 'stateful') {
1158
+ this.debugLog(`Bot: ${this.accessory.displayName} ProgrammableSwitchOutputState: ${value}`);
1159
+ if (value === 0) {
1160
+ this.On = false;
1161
+ } else {
1162
+ this.On = true;
1163
+ }
1098
1164
  } else {
1099
1165
  this.debugLog(`Bot: ${this.accessory.displayName} On: ${value}`);
1100
1166
  this.On = value;