@switchbot/homebridge-switchbot 2.0.0-beta.3 → 2.0.0-beta.31

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 (113) hide show
  1. package/CHANGELOG.md +8 -1
  2. package/README.md +1 -2
  3. package/config.schema.json +75 -20
  4. package/dist/device/bot.d.ts +34 -28
  5. package/dist/device/bot.d.ts.map +1 -1
  6. package/dist/device/bot.js +655 -649
  7. package/dist/device/bot.js.map +1 -1
  8. package/dist/device/colorbulb.d.ts +36 -19
  9. package/dist/device/colorbulb.d.ts.map +1 -1
  10. package/dist/device/colorbulb.js +483 -309
  11. package/dist/device/colorbulb.js.map +1 -1
  12. package/dist/device/contact.d.ts +18 -8
  13. package/dist/device/contact.d.ts.map +1 -1
  14. package/dist/device/contact.js +303 -237
  15. package/dist/device/contact.js.map +1 -1
  16. package/dist/device/curtain.d.ts +23 -16
  17. package/dist/device/curtain.d.ts.map +1 -1
  18. package/dist/device/curtain.js +541 -498
  19. package/dist/device/curtain.js.map +1 -1
  20. package/dist/device/humidifier.d.ts +24 -18
  21. package/dist/device/humidifier.d.ts.map +1 -1
  22. package/dist/device/humidifier.js +450 -369
  23. package/dist/device/humidifier.js.map +1 -1
  24. package/dist/device/lock.d.ts +27 -8
  25. package/dist/device/lock.d.ts.map +1 -1
  26. package/dist/device/lock.js +302 -148
  27. package/dist/device/lock.js.map +1 -1
  28. package/dist/device/meter.d.ts +22 -16
  29. package/dist/device/meter.d.ts.map +1 -1
  30. package/dist/device/meter.js +340 -262
  31. package/dist/device/meter.js.map +1 -1
  32. package/dist/device/meterplus.d.ts +24 -12
  33. package/dist/device/meterplus.d.ts.map +1 -1
  34. package/dist/device/meterplus.js +359 -213
  35. package/dist/device/meterplus.js.map +1 -1
  36. package/dist/device/motion.d.ts +18 -8
  37. package/dist/device/motion.d.ts.map +1 -1
  38. package/dist/device/motion.js +276 -216
  39. package/dist/device/motion.js.map +1 -1
  40. package/dist/device/plug.d.ts +27 -17
  41. package/dist/device/plug.d.ts.map +1 -1
  42. package/dist/device/plug.js +292 -251
  43. package/dist/device/plug.js.map +1 -1
  44. package/dist/device/striplight.d.ts +43 -19
  45. package/dist/device/striplight.d.ts.map +1 -1
  46. package/dist/device/striplight.js +503 -262
  47. package/dist/device/striplight.js.map +1 -1
  48. package/dist/irdevice/airconditioner.d.ts +9 -12
  49. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  50. package/dist/irdevice/airconditioner.js +275 -230
  51. package/dist/irdevice/airconditioner.js.map +1 -1
  52. package/dist/irdevice/airpurifier.d.ts +5 -3
  53. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  54. package/dist/irdevice/airpurifier.js +151 -104
  55. package/dist/irdevice/airpurifier.js.map +1 -1
  56. package/dist/irdevice/camera.d.ts +11 -8
  57. package/dist/irdevice/camera.d.ts.map +1 -1
  58. package/dist/irdevice/camera.js +130 -86
  59. package/dist/irdevice/camera.js.map +1 -1
  60. package/dist/irdevice/fan.d.ts +10 -7
  61. package/dist/irdevice/fan.d.ts.map +1 -1
  62. package/dist/irdevice/fan.js +157 -109
  63. package/dist/irdevice/fan.js.map +1 -1
  64. package/dist/irdevice/light.d.ts +11 -8
  65. package/dist/irdevice/light.d.ts.map +1 -1
  66. package/dist/irdevice/light.js +134 -103
  67. package/dist/irdevice/light.js.map +1 -1
  68. package/dist/irdevice/other.d.ts +11 -8
  69. package/dist/irdevice/other.d.ts.map +1 -1
  70. package/dist/irdevice/other.js +142 -98
  71. package/dist/irdevice/other.js.map +1 -1
  72. package/dist/irdevice/tv.d.ts +12 -9
  73. package/dist/irdevice/tv.d.ts.map +1 -1
  74. package/dist/irdevice/tv.js +140 -93
  75. package/dist/irdevice/tv.js.map +1 -1
  76. package/dist/irdevice/vacuumcleaner.d.ts +9 -10
  77. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  78. package/dist/irdevice/vacuumcleaner.js +129 -89
  79. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  80. package/dist/irdevice/waterheater.d.ts +8 -9
  81. package/dist/irdevice/waterheater.d.ts.map +1 -1
  82. package/dist/irdevice/waterheater.js +129 -89
  83. package/dist/irdevice/waterheater.js.map +1 -1
  84. package/dist/platform.d.ts +14 -12
  85. package/dist/platform.d.ts.map +1 -1
  86. package/dist/platform.js +456 -434
  87. package/dist/platform.js.map +1 -1
  88. package/dist/settings.d.ts +16 -11
  89. package/dist/settings.d.ts.map +1 -1
  90. package/dist/settings.js.map +1 -1
  91. package/package.json +12 -10
  92. package/src/device/bot.ts +654 -660
  93. package/src/device/colorbulb.ts +487 -344
  94. package/src/device/contact.ts +306 -241
  95. package/src/device/curtain.ts +546 -512
  96. package/src/device/humidifier.ts +453 -403
  97. package/src/device/lock.ts +311 -149
  98. package/src/device/meter.ts +351 -275
  99. package/src/device/meterplus.ts +369 -219
  100. package/src/device/motion.ts +282 -222
  101. package/src/device/plug.ts +296 -260
  102. package/src/device/striplight.ts +519 -289
  103. package/src/irdevice/airconditioner.ts +279 -241
  104. package/src/irdevice/airpurifier.ts +148 -103
  105. package/src/irdevice/camera.ts +128 -85
  106. package/src/irdevice/fan.ts +154 -106
  107. package/src/irdevice/light.ts +132 -103
  108. package/src/irdevice/other.ts +140 -97
  109. package/src/irdevice/tv.ts +139 -93
  110. package/src/irdevice/vacuumcleaner.ts +128 -89
  111. package/src/irdevice/waterheater.ts +127 -89
  112. package/src/platform.ts +447 -457
  113. package/src/settings.ts +16 -11
@@ -7,6 +7,7 @@ exports.Bot = void 0;
7
7
  const https_1 = __importDefault(require("https"));
8
8
  const crypto_1 = __importDefault(require("crypto"));
9
9
  const rxjs_1 = require("rxjs");
10
+ const super_stringify_1 = __importDefault(require("super-stringify"));
10
11
  const operators_1 = require("rxjs/operators");
11
12
  const settings_1 = require("../settings");
12
13
  /**
@@ -19,6 +20,9 @@ class Bot {
19
20
  this.platform = platform;
20
21
  this.accessory = accessory;
21
22
  this.device = device;
23
+ // Connection
24
+ this.BLE = (this.device.connectionType === 'BLE' || this.device.connectionType === 'BLE/OpenAPI');
25
+ this.OpenAPI = (this.device.connectionType === 'OpenAPI' || this.device.connectionType === 'BLE/OpenAPI');
22
26
  // default placeholders
23
27
  this.logs(device);
24
28
  this.scan(device);
@@ -26,22 +30,8 @@ class Bot {
26
30
  this.PressOrSwitch(device);
27
31
  this.allowPushChanges(device);
28
32
  this.config(device);
29
- if (this.On === undefined) {
30
- this.On = false;
31
- this.accessory.context.On = this.On;
32
- }
33
- else {
34
- this.On = this.accessory.context.On;
35
- }
36
- if (device.bot?.doublePress) {
37
- this.doublePress = device.bot?.doublePress;
38
- this.accessory.context.doublePress = this.doublePress;
39
- }
40
- else {
41
- this.doublePress = 1;
42
- }
43
- this.BatteryLevel = 100;
44
- this.StatusLowBattery = 0;
33
+ this.context();
34
+ this.DoublePress(device);
45
35
  // this is subject we use to track when we need to POST changes to the SwitchBot API
46
36
  this.doBotUpdate = new rxjs_1.Subject();
47
37
  this.botUpdateInProgress = false;
@@ -71,9 +61,9 @@ class Bot {
71
61
  // Add switchService
72
62
  (this.switchService = accessory.getService(this.platform.Service.Switch) || accessory.addService(this.platform.Service.Switch)),
73
63
  `${accessory.displayName} Switch`;
74
- this.infoLog(`Bot: ${accessory.displayName} Displaying as Switch`);
64
+ this.infoLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Switch`);
75
65
  this.switchService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
76
- this.switchService.getCharacteristic(this.platform.Characteristic.On).onSet(this.handleOnSet.bind(this));
66
+ this.switchService.getCharacteristic(this.platform.Characteristic.On).onSet(this.OnSet.bind(this));
77
67
  }
78
68
  else if (device.bot?.deviceType === 'garagedoor') {
79
69
  this.removeFanService(accessory);
@@ -89,9 +79,9 @@ class Bot {
89
79
  (this.garageDoorService =
90
80
  accessory.getService(this.platform.Service.GarageDoorOpener) || accessory.addService(this.platform.Service.GarageDoorOpener)),
91
81
  `${accessory.displayName} Garage Door Opener`;
92
- this.infoLog(`Bot: ${accessory.displayName} Displaying as Garage Door Opener`);
82
+ this.infoLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Garage Door Opener`);
93
83
  this.garageDoorService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
94
- this.garageDoorService.getCharacteristic(this.platform.Characteristic.TargetDoorState).onSet(this.handleOnSet.bind(this));
84
+ this.garageDoorService.getCharacteristic(this.platform.Characteristic.TargetDoorState).onSet(this.OnSet.bind(this));
95
85
  this.garageDoorService.setCharacteristic(this.platform.Characteristic.ObstructionDetected, false);
96
86
  }
97
87
  else if (device.bot?.deviceType === 'door') {
@@ -107,7 +97,7 @@ class Bot {
107
97
  // Add switchService
108
98
  (this.doorService = accessory.getService(this.platform.Service.Door) || accessory.addService(this.platform.Service.Door)),
109
99
  `${accessory.displayName} Door`;
110
- this.infoLog(`Bot: ${accessory.displayName} Displaying as Door`);
100
+ this.infoLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Door`);
111
101
  this.doorService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
112
102
  this.doorService
113
103
  .getCharacteristic(this.platform.Characteristic.TargetPosition)
@@ -117,7 +107,7 @@ class Bot {
117
107
  maxValue: 100,
118
108
  minStep: 100,
119
109
  })
120
- .onSet(this.handleOnSet.bind(this));
110
+ .onSet(this.OnSet.bind(this));
121
111
  this.doorService.setCharacteristic(this.platform.Characteristic.PositionState, this.platform.Characteristic.PositionState.STOPPED);
122
112
  }
123
113
  else if (device.bot?.deviceType === 'window') {
@@ -133,7 +123,7 @@ class Bot {
133
123
  // Add switchService
134
124
  (this.windowService = accessory.getService(this.platform.Service.Window) || accessory.addService(this.platform.Service.Window)),
135
125
  `${accessory.displayName} Window`;
136
- this.infoLog(`Bot: ${accessory.displayName} Displaying as Window`);
126
+ this.infoLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Window`);
137
127
  this.windowService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
138
128
  this.windowService
139
129
  .getCharacteristic(this.platform.Characteristic.TargetPosition)
@@ -143,7 +133,7 @@ class Bot {
143
133
  maxValue: 100,
144
134
  minStep: 100,
145
135
  })
146
- .onSet(this.handleOnSet.bind(this));
136
+ .onSet(this.OnSet.bind(this));
147
137
  this.windowService.setCharacteristic(this.platform.Characteristic.PositionState, this.platform.Characteristic.PositionState.STOPPED);
148
138
  }
149
139
  else if (device.bot?.deviceType === 'windowcovering') {
@@ -160,7 +150,7 @@ class Bot {
160
150
  (this.windowCoveringService =
161
151
  accessory.getService(this.platform.Service.WindowCovering) || accessory.addService(this.platform.Service.WindowCovering)),
162
152
  `${accessory.displayName} Window Covering`;
163
- this.infoLog(`Bot: ${accessory.displayName} Displaying as Window Covering`);
153
+ this.infoLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Window Covering`);
164
154
  this.windowCoveringService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
165
155
  this.windowCoveringService
166
156
  .getCharacteristic(this.platform.Characteristic.TargetPosition)
@@ -170,7 +160,7 @@ class Bot {
170
160
  maxValue: 100,
171
161
  minStep: 100,
172
162
  })
173
- .onSet(this.handleOnSet.bind(this));
163
+ .onSet(this.OnSet.bind(this));
174
164
  this.windowCoveringService.setCharacteristic(this.platform.Characteristic.PositionState, this.platform.Characteristic.PositionState.STOPPED);
175
165
  }
176
166
  else if (device.bot?.deviceType === 'lock') {
@@ -186,9 +176,9 @@ class Bot {
186
176
  // Add switchService
187
177
  (this.lockService = accessory.getService(this.platform.Service.LockMechanism) || accessory.addService(this.platform.Service.LockMechanism)),
188
178
  `${accessory.displayName} Lock`;
189
- this.infoLog(`Bot: ${accessory.displayName} Displaying as Lock`);
179
+ this.infoLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Lock`);
190
180
  this.lockService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
191
- this.lockService.getCharacteristic(this.platform.Characteristic.LockTargetState).onSet(this.handleOnSet.bind(this));
181
+ this.lockService.getCharacteristic(this.platform.Characteristic.LockTargetState).onSet(this.OnSet.bind(this));
192
182
  }
193
183
  else if (device.bot?.deviceType === 'faucet') {
194
184
  this.removeFanService(accessory);
@@ -203,9 +193,9 @@ class Bot {
203
193
  // Add switchService
204
194
  (this.faucetService = accessory.getService(this.platform.Service.Faucet) || accessory.addService(this.platform.Service.Faucet)),
205
195
  `${accessory.displayName} Faucet`;
206
- this.infoLog(`Bot: ${accessory.displayName} Displaying as Faucet`);
196
+ this.infoLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Faucet`);
207
197
  this.faucetService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
208
- this.faucetService.getCharacteristic(this.platform.Characteristic.Active).onSet(this.handleOnSet.bind(this));
198
+ this.faucetService.getCharacteristic(this.platform.Characteristic.Active).onSet(this.OnSet.bind(this));
209
199
  }
210
200
  else if (device.bot?.deviceType === 'fan') {
211
201
  this.removeLockService(accessory);
@@ -220,9 +210,9 @@ class Bot {
220
210
  // Add switchService
221
211
  (this.fanService = accessory.getService(this.platform.Service.Fan) || accessory.addService(this.platform.Service.Fan)),
222
212
  `${accessory.displayName} Fan`;
223
- this.infoLog(`Bot: ${accessory.displayName} Displaying as Fan`);
213
+ this.infoLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Fan`);
224
214
  this.fanService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
225
- this.fanService.getCharacteristic(this.platform.Characteristic.On).onSet(this.handleOnSet.bind(this));
215
+ this.fanService.getCharacteristic(this.platform.Characteristic.On).onSet(this.OnSet.bind(this));
226
216
  }
227
217
  else if (device.bot?.deviceType === 'stateful') {
228
218
  this.removeFanService(accessory);
@@ -239,11 +229,11 @@ class Bot {
239
229
  accessory.getService(this.platform.Service.StatefulProgrammableSwitch) ||
240
230
  accessory.addService(this.platform.Service.StatefulProgrammableSwitch)),
241
231
  `${accessory.displayName} Stateful Programmable Switch`;
242
- this.infoLog(`Bot: ${accessory.displayName} Displaying as Stateful Programmable Switch`);
232
+ this.infoLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Stateful Programmable Switch`);
243
233
  this.statefulProgrammableSwitchService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
244
234
  this.statefulProgrammableSwitchService
245
235
  .getCharacteristic(this.platform.Characteristic.ProgrammableSwitchOutputState)
246
- .onSet(this.handleOnSet.bind(this));
236
+ .onSet(this.OnSet.bind(this));
247
237
  }
248
238
  else {
249
239
  this.removeFanService(accessory);
@@ -258,24 +248,24 @@ class Bot {
258
248
  // Add outletService
259
249
  (this.outletService = accessory.getService(this.platform.Service.Outlet) || accessory.addService(this.platform.Service.Outlet)),
260
250
  `${accessory.displayName} Outlet`;
261
- this.infoLog(`Bot: ${accessory.displayName} Displaying as Outlet`);
251
+ this.infoLog(`${this.device.deviceType}: ${accessory.displayName} Displaying as Outlet`);
262
252
  this.outletService.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
263
- this.outletService.getCharacteristic(this.platform.Characteristic.On).onSet(this.handleOnSet.bind(this));
253
+ this.outletService.getCharacteristic(this.platform.Characteristic.On).onSet(this.OnSet.bind(this));
264
254
  }
265
255
  // Battery Service
266
- if (!device.ble) {
267
- this.debugLog(`Bot: ${accessory.displayName} Removing Battery Service`);
256
+ if (!this.BLE) {
257
+ this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Removing Battery Service`);
268
258
  this.batteryService = this.accessory.getService(this.platform.Service.Battery);
269
259
  accessory.removeService(this.batteryService);
270
260
  }
271
- else if (device.ble && !this.batteryService) {
272
- this.debugLog(`Bot: ${accessory.displayName} Add Battery Service`);
261
+ else if (this.BLE && !this.batteryService) {
262
+ this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Add Battery Service`);
273
263
  (this.batteryService = this.accessory.getService(this.platform.Service.Battery) || this.accessory.addService(this.platform.Service.Battery)),
274
264
  `${accessory.displayName} Battery`;
275
265
  this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Battery`);
276
266
  }
277
267
  else {
278
- this.debugLog(`Bot: ${accessory.displayName} Battery Service Not Added`);
268
+ this.debugLog(`${this.device.deviceType}: ${accessory.displayName} Battery Service Not Added`);
279
269
  }
280
270
  // Retrieve initial values and updateHomekit
281
271
  this.updateHomeKitCharacteristics();
@@ -286,27 +276,23 @@ class Bot {
286
276
  await this.refreshStatus();
287
277
  });
288
278
  // Watch for Bot change events
289
- // We put in a debounce of 100ms so we don't make duplicate calls
279
+ // We put in a debounce of 1000ms so we don't make duplicate calls
290
280
  this.doBotUpdate
291
281
  .pipe((0, operators_1.tap)(() => {
292
282
  this.botUpdateInProgress = true;
293
- }), (0, operators_1.debounceTime)(100))
283
+ }), (0, operators_1.debounceTime)(this.platform.config.options.pushRate * 1000))
294
284
  .subscribe(async () => {
295
285
  try {
296
- (0, rxjs_1.interval)(100)
286
+ (0, rxjs_1.interval)(15000)
297
287
  .pipe((0, operators_1.take)(this.doublePress))
298
288
  .subscribe(async () => {
299
289
  await this.pushChanges();
300
290
  });
301
291
  }
302
292
  catch (e) {
303
- this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges`);
304
- if (this.deviceLogging.includes('debug')) {
305
- this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges,` + ` Error Message: ${JSON.stringify(e.message)}`);
306
- }
307
- if (this.platform.debugMode) {
308
- this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges,` + ` Error: ${JSON.stringify(e)}`);
309
- }
293
+ this.apiError(e);
294
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,`
295
+ + ` Error Message: ${(0, super_stringify_1.default)(e.message)}`);
310
296
  }
311
297
  this.botUpdateInProgress = false;
312
298
  });
@@ -315,29 +301,31 @@ class Bot {
315
301
  * Parse the device status from the SwitchBot api
316
302
  */
317
303
  async parseStatus() {
318
- if (this.SwitchToOpenAPI || !this.device.ble) {
304
+ if (this.BLE) {
305
+ await this.BLEparseStatus();
306
+ }
307
+ else if (this.OpenAPI && this.platform.config.credentials?.token) {
319
308
  await this.openAPIparseStatus();
320
309
  }
321
310
  else {
322
- await this.BLEparseStatus();
311
+ this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
312
+ + ` ${this.device.connectionType}, parseStatus will not happen.`);
323
313
  }
324
314
  }
325
315
  async BLEparseStatus() {
326
- this.debugLog(`Bot: ${this.accessory.displayName} BLE parseStatus`);
316
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
327
317
  // BLEmode (true if Switch Mode) | (false if Press Mode)
328
318
  if (this.mode) {
329
- this.OnCached = this.On;
330
- this.accessory.context.On = this.OnCached;
319
+ this.accessory.context.On = this.On;
331
320
  if (this.On === undefined) {
332
321
  this.On = Boolean(this.state);
333
322
  }
334
- this.debugLog(`Bot: ${this.accessory.displayName} Switch Mode, mode: ${this.mode}, On: ${this.On}`);
323
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Switch Mode, mode: ${this.mode}, On: ${this.On}`);
335
324
  }
336
325
  else {
337
326
  this.On = false;
338
- this.OnCached = this.On;
339
- this.accessory.context.On = this.OnCached;
340
- this.debugLog(`Bot: ${this.accessory.displayName} Press Mode, mode: ${this.mode}, On: ${this.On}`);
327
+ this.accessory.context.On = this.On;
328
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Press Mode, mode: ${this.mode}, On: ${this.On}`);
341
329
  }
342
330
  this.BatteryLevel = Number(this.battery);
343
331
  if (this.BatteryLevel < 10) {
@@ -349,201 +337,152 @@ class Bot {
349
337
  if (Number.isNaN(this.BatteryLevel)) {
350
338
  this.BatteryLevel = 100;
351
339
  }
352
- this.debugLog(`Bot: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
340
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
353
341
  }
354
342
  async openAPIparseStatus() {
355
- if (this.device.ble) {
356
- this.SwitchToOpenAPI = false;
343
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
344
+ if (this.botMode === 'press') {
345
+ this.On = false;
346
+ this.accessory.context.On = this.On;
357
347
  }
358
- if (this.platform.config.credentials?.token) {
359
- this.debugLog(`Bot: ${this.accessory.displayName} OpenAPI parseStatus`);
360
- if (this.botMode === 'press') {
348
+ else {
349
+ this.accessory.context.On = this.On;
350
+ if (this.On === undefined) {
361
351
  this.On = false;
362
- this.OnCached = this.On;
363
- this.accessory.context.On = this.OnCached;
364
- }
365
- else {
366
- /*if (this.power === 'on') {
367
- this.On = true;
368
- this.OnCached = this.On;
369
- this.accessory.context.On = this.OnCached;
370
- } else {
371
- this.On = false;
372
- this.OnCached = this.On;
373
- this.accessory.context.On = this.OnCached;
374
- }*/
375
- this.OnCached = this.On;
376
- this.accessory.context.On = this.OnCached;
377
- if (this.On === undefined) {
378
- this.On = false;
379
- }
380
352
  }
381
- this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
382
353
  }
354
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
383
355
  }
384
356
  /**
385
357
  * Asks the SwitchBot API for the latest device information
386
358
  */
387
359
  async refreshStatus() {
388
- if (this.device.ble) {
360
+ if (this.BLE) {
389
361
  await this.BLERefreshStatus();
390
362
  }
391
- else {
363
+ else if (this.OpenAPI && this.platform.config.credentials?.token) {
392
364
  await this.openAPIRefreshStatus();
393
365
  }
366
+ else {
367
+ this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
368
+ + ` ${this.device.connectionType}, refreshStatus will not happen.`);
369
+ }
394
370
  }
395
371
  async BLERefreshStatus() {
396
- this.debugLog(`Bot: ${this.accessory.displayName} BLE refreshStatus`);
372
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
397
373
  const switchbot = await this.platform.connectBLE();
398
374
  // Convert to BLE Address
399
375
  this.device.bleMac = this.device
400
376
  .deviceId.match(/.{1,2}/g)
401
377
  .join(':')
402
378
  .toLowerCase();
403
- this.debugLog(`Bot: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
379
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
404
380
  this.getCustomBLEAddress(switchbot);
405
381
  // Start to monitor advertisement packets
406
- if (switchbot === false) {
407
- this.errorLog(`Bot: ${this.accessory.displayName} wasn't able to establish BLE Connection: ${switchbot}`);
408
- }
409
- switchbot
410
- .startScan({
411
- model: 'H',
412
- id: this.device.bleMac,
413
- })
414
- .then(() => {
415
- // Set an event hander
416
- switchbot.onadvertisement = (ad) => {
417
- this.address = ad.address;
418
- if (this.deviceLogging.includes('debug')) {
419
- this.infoLog(this.address);
420
- this.infoLog(this.device.bleMac);
421
- this.infoLog(`Bot: ${this.accessory.displayName} BLE Address Found: ${this.address}`);
422
- this.infoLog(`Bot: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac}`);
423
- }
424
- this.serviceData = ad.serviceData;
425
- this.mode = ad.serviceData.mode;
426
- this.state = ad.serviceData.state;
427
- this.battery = ad.serviceData.battery;
428
- this.debugLog(`Bot: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
429
- this.debugLog(`Bot: ${this.accessory.displayName}, model: ${ad.serviceData.model}, modelName: ${ad.serviceData.modelName},` +
430
- ` mode: ${ad.serviceData.mode}, state: ${ad.serviceData.state}, battery: ${ad.serviceData.battery}`);
431
- if (this.serviceData) {
432
- this.connected = true;
433
- this.debugLog(`Bot: ${this.accessory.displayName} connected: ${this.connected}`);
434
- }
435
- else {
436
- this.connected = false;
437
- this.debugLog(`Bot: ${this.accessory.displayName} connected: ${this.connected}`);
438
- }
439
- };
440
- // Wait 2 seconds
441
- return switchbot.wait(this.scanDuration * 1000);
442
- })
443
- .then(async () => {
444
- // Stop to monitor
445
- switchbot.stopScan();
446
- if (this.connected) {
447
- this.parseStatus();
448
- this.updateHomeKitCharacteristics();
449
- }
450
- else {
451
- this.errorLog(`Bot: ${this.accessory.displayName} wasn't able to establish BLE Connection`);
452
- if (this.platform.config.credentials?.token) {
453
- this.warnLog(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
454
- this.SwitchToOpenAPI = true;
455
- await this.openAPIRefreshStatus();
456
- }
457
- }
458
- })
459
- .catch(async (e) => {
460
- this.errorLog(`Bot: ${this.accessory.displayName} failed refreshStatus with BLE Connection`);
461
- if (this.deviceLogging.includes('debug')) {
462
- this.errorLog(`Bot: ${this.accessory.displayName} failed refreshStatus with BLE Connection,` + ` Error Message: ${JSON.stringify(e.message)}`);
463
- }
464
- if (this.platform.config.credentials?.token) {
465
- this.warnLog(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
466
- this.SwitchToOpenAPI = true;
467
- await this.openAPIRefreshStatus();
468
- }
469
- this.apiError(e);
470
- });
471
- }
472
- async getCustomBLEAddress(switchbot) {
473
- if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
474
- (async () => {
475
- // Start to monitor advertisement packets
476
- await switchbot.startScan({
477
- model: 'H',
478
- });
479
- // Set an event handler
382
+ if (switchbot !== false) {
383
+ switchbot
384
+ .startScan({
385
+ model: 'H',
386
+ id: this.device.bleMac,
387
+ })
388
+ .then(() => {
389
+ // Set an event hander
480
390
  switchbot.onadvertisement = (ad) => {
481
- this.warnLog(`Bot: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
391
+ this.address = ad.address;
392
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},`
393
+ + ` BLE Address Found: ${this.address}`);
394
+ this.serviceData = ad.serviceData;
395
+ this.mode = ad.serviceData.mode;
396
+ this.state = ad.serviceData.state;
397
+ this.battery = ad.serviceData.battery;
398
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${(0, super_stringify_1.default)(ad.serviceData)}`);
399
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}, model: ${ad.serviceData.model}, modelName: ${ad.serviceData.modelName},` +
400
+ ` mode: ${ad.serviceData.mode}, state: ${ad.serviceData.state}, battery: ${ad.serviceData.battery}`);
401
+ if (this.serviceData) {
402
+ this.connected = true;
403
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.connected}`);
404
+ }
405
+ else {
406
+ this.connected = false;
407
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.connected}`);
408
+ }
482
409
  };
483
- await switchbot.wait(10000);
410
+ // Wait 2 seconds
411
+ return switchbot.wait(this.scanDuration * 1000);
412
+ })
413
+ .then(async () => {
484
414
  // Stop to monitor
485
415
  switchbot.stopScan();
486
- })();
416
+ if (this.connected) {
417
+ this.BLEparseStatus();
418
+ this.updateHomeKitCharacteristics();
419
+ }
420
+ else {
421
+ await this.BLERefreshConnection(switchbot);
422
+ }
423
+ })
424
+ .catch(async (e) => {
425
+ this.apiError(e);
426
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}`
427
+ + ` Connection, Error Message: ${(0, super_stringify_1.default)(e.message)}`);
428
+ await this.BLERefreshConnection(switchbot);
429
+ });
430
+ }
431
+ else {
432
+ await this.BLERefreshConnection(switchbot);
487
433
  }
488
434
  }
489
435
  async openAPIRefreshStatus() {
490
- if (this.platform.config.credentials?.token) {
491
- this.debugLog(`Bot: ${this.accessory.displayName} OpenAPI refreshStatus`);
492
- try {
493
- const t = Date.now();
494
- const nonce = 'requestID';
495
- const data = this.platform.config.credentials?.token + t + nonce;
496
- const signTerm = crypto_1.default.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
497
- const sign = signTerm.toString('base64');
498
- this.debugLog(`Bot: ${this.accessory.displayName} sign: ${sign}`);
499
- const options = {
500
- hostname: settings_1.HostDomain,
501
- port: 443,
502
- path: `${settings_1.DevicePath}/${this.device.deviceId}/status`,
503
- method: 'GET',
504
- headers: {
505
- Authorization: this.platform.config.credentials?.token,
506
- sign: sign,
507
- nonce: nonce,
508
- t: t,
509
- 'Content-Type': 'application/json',
510
- },
511
- };
512
- const req = https_1.default.request(options, (res) => {
513
- this.debugLog(`Bot: ${this.accessory.displayName} Refresh statusCode: ${res.statusCode}`);
514
- let rawData = '';
515
- res.on('data', (d) => {
516
- rawData += d;
517
- this.debugLog(`d: ${d}`);
518
- });
519
- res.on('end', () => {
520
- try {
521
- this.deviceStatus = JSON.parse(rawData);
522
- this.debugLog(`Bot: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
523
- this.power = this.deviceStatus.body.power;
524
- this.parseStatus();
525
- this.updateHomeKitCharacteristics();
526
- }
527
- catch (e) {
528
- this.errorLog(`Bot: ${this.accessory.displayName} error message: ${e.message}`);
529
- }
530
- });
436
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
437
+ try {
438
+ const t = Date.now();
439
+ const nonce = 'requestID';
440
+ const data = this.platform.config.credentials?.token + t + nonce;
441
+ const signTerm = crypto_1.default.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
442
+ const sign = signTerm.toString('base64');
443
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
444
+ const options = {
445
+ hostname: settings_1.HostDomain,
446
+ port: 443,
447
+ path: `${settings_1.DevicePath}/${this.device.deviceId}/status`,
448
+ method: 'GET',
449
+ headers: {
450
+ Authorization: this.platform.config.credentials?.token,
451
+ sign: sign,
452
+ nonce: nonce,
453
+ t: t,
454
+ 'Content-Type': 'application/json',
455
+ },
456
+ };
457
+ const req = https_1.default.request(options, (res) => {
458
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus statusCode: ${res.statusCode}`);
459
+ let rawData = '';
460
+ res.on('data', (d) => {
461
+ rawData += d;
462
+ this.debugLog(`d: ${d}`);
531
463
  });
532
- req.on('error', (e) => {
533
- this.errorLog(`Bot: ${this.accessory.displayName} error message: ${e.message}`);
464
+ res.on('end', () => {
465
+ try {
466
+ this.deviceStatus = JSON.parse(rawData);
467
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus: ${(0, super_stringify_1.default)(this.deviceStatus)}`);
468
+ this.power = this.deviceStatus.body.power;
469
+ this.openAPIparseStatus();
470
+ this.updateHomeKitCharacteristics();
471
+ }
472
+ catch (e) {
473
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
474
+ }
534
475
  });
535
- req.end();
536
- }
537
- catch (e) {
538
- this.errorLog(`Bot: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
539
- if (this.deviceLogging.includes('debug')) {
540
- this.errorLog(`Bot: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`);
541
- }
542
- if (this.platform.debugMode) {
543
- this.errorLog(`Bot: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,` + ` Error: ${JSON.stringify(e)}`);
544
- }
545
- this.apiError(e);
546
- }
476
+ });
477
+ req.on('error', (e) => {
478
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
479
+ });
480
+ req.end();
481
+ }
482
+ catch (e) {
483
+ this.apiError(e);
484
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
485
+ + ` Connection, Error Message: ${(0, super_stringify_1.default)(e.message)}`);
547
486
  }
548
487
  }
549
488
  /**
@@ -554,12 +493,16 @@ class Bot {
554
493
  * Bot - "command" "press" "default" = trigger press
555
494
  */
556
495
  async pushChanges() {
557
- if (this.device.ble) {
558
- await this.BLEpushChanges();
496
+ if (this.BLE) {
497
+ await this.BLERefreshStatus();
559
498
  }
560
- else {
499
+ else if (this.OpenAPI) {
561
500
  await this.openAPIpushChanges();
562
501
  }
502
+ else {
503
+ this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
504
+ + ` ${this.device.connectionType}, pushChanges will not happen.`);
505
+ }
563
506
  (0, rxjs_1.interval)(5000)
564
507
  .pipe((0, operators_1.take)(1))
565
508
  .subscribe(async () => {
@@ -567,30 +510,28 @@ class Bot {
567
510
  });
568
511
  }
569
512
  async BLEpushChanges() {
570
- this.debugLog(`Bot: ${this.accessory.displayName} BLE pushChanges On: ${this.On} OnCached: ${this.OnCached}`);
571
- if (this.On !== this.OnCached || this.allowPush) {
572
- this.debugLog(`Bot: ${this.accessory.displayName} BLE pushChanges`);
513
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`);
514
+ if (this.On !== this.accessory.context.On || this.allowPush) {
515
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges On: ${this.On} OnCached: ${this.accessory.context.On}`);
573
516
  const switchbot = await this.platform.connectBLE();
574
517
  // Convert to BLE Address
575
518
  this.device.bleMac = this.device
576
519
  .deviceId.match(/.{1,2}/g)
577
520
  .join(':')
578
521
  .toLowerCase();
579
- this.debugLog(`Bot: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
522
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
580
523
  //if (switchbot !== false) {
581
524
  if (this.botMode === 'press') {
582
- this.debugLog(`Bot: ${this.accessory.displayName} Bot Mode: ${this.botMode}`);
525
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Bot Mode: ${this.botMode}`);
583
526
  switchbot
584
527
  .discover({ model: 'H', quick: true, id: this.device.bleMac })
585
528
  .then((device_list) => {
586
- this.infoLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
529
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
587
530
  return device_list[0].press({ id: this.device.bleMac });
588
531
  })
589
532
  .then(() => {
590
- this.debugLog(`Bot: ${this.accessory.displayName} Done.`);
591
- this.On = false;
592
- this.OnCached = this.On;
593
- this.accessory.context.On = this.OnCached;
533
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
534
+ this.accessory.context.On = this.On;
594
535
  setTimeout(() => {
595
536
  if (this.device.bot?.deviceType === 'switch') {
596
537
  this.switchService?.getCharacteristic(this.platform.Characteristic.On).updateValue(this.On);
@@ -598,153 +539,177 @@ class Bot {
598
539
  else {
599
540
  this.outletService?.getCharacteristic(this.platform.Characteristic.On).updateValue(this.On);
600
541
  }
601
- this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}, Switch Timeout`);
542
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}, Switch Timeout`);
602
543
  }, 500);
603
544
  })
604
545
  .catch(async (e) => {
605
- this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection`);
606
- if (this.deviceLogging.includes('debug')) {
607
- this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection,` + ` Error Message: ${JSON.stringify(e.message)}`);
608
- }
609
- if (this.platform.debugMode) {
610
- this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection,` + ` Error: ${JSON.stringify(e)}`);
611
- }
612
- if (this.platform.config.credentials?.token) {
613
- this.warnLog(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
614
- await this.openAPIpushChanges();
615
- }
616
546
  this.apiError(e);
547
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}`
548
+ + ` Connection & botMode: ${this.botMode}, Error Message: ${(0, super_stringify_1.default)(e.message)}`);
549
+ await this.BLEPushConnection();
617
550
  });
618
551
  }
619
552
  else if (this.botMode === 'switch') {
620
- this.debugLog(`Bot: ${this.accessory.displayName} Press Mode: ${this.botMode}`);
553
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Press Mode: ${this.botMode}`);
621
554
  switchbot
622
555
  .discover({ model: 'H', quick: true, id: this.device.bleMac })
623
556
  .then((device_list) => {
624
- this.infoLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
557
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
625
558
  return this.turnOnOff(device_list);
626
559
  })
627
560
  .then(() => {
628
- this.debugLog(`Bot: ${this.accessory.displayName} Done.`);
629
- this.OnCached = this.On;
630
- this.accessory.context.On = this.OnCached;
561
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Done.`);
562
+ this.accessory.context.On = this.On;
631
563
  })
632
564
  .catch(async (e) => {
633
- this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection`);
634
- if (this.deviceLogging.includes('debug')) {
635
- this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection,` + ` Error Message: ${JSON.stringify(e.message)}`);
636
- }
637
- if (this.platform.debugMode) {
638
- this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection,` + ` Error: ${JSON.stringify(e)}`);
639
- }
640
- if (this.platform.config.credentials?.token) {
641
- this.warnLog(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
642
- await this.openAPIpushChanges();
643
- }
644
565
  this.apiError(e);
566
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}`
567
+ + ` Connection & botMode: ${this.botMode}, Error Message: ${(0, super_stringify_1.default)(e.message)}`);
568
+ await this.BLEPushConnection();
645
569
  });
646
570
  }
647
571
  else {
648
- throw new Error(`Bot: ${this.accessory.displayName} Bot Mode: ${this.botMode}`);
572
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Bot Mode: ${this.botMode}`);
649
573
  }
650
574
  }
651
- this.OnCached = this.On;
652
- this.accessory.context.On = this.OnCached;
575
+ else {
576
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges.` + `On: ${this.On}, `
577
+ + `OnCached: ${this.accessory.context.On}`);
578
+ }
653
579
  }
654
- async turnOnOff(device_list) {
655
- return await this.retry({
656
- max: await this.maxRetry(),
657
- fn: () => {
658
- if (this.On) {
659
- return device_list[0].turnOn({ id: this.device.bleMac });
580
+ async openAPIpushChanges() {
581
+ try {
582
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
583
+ if (this.On !== this.accessory.context.On || this.allowPush) {
584
+ // Make Push On request to the API
585
+ const t = Date.now();
586
+ const nonce = 'requestID';
587
+ const data = this.platform.config.credentials?.token + t + nonce;
588
+ const signTerm = crypto_1.default.createHmac('sha256', this.platform.config.credentials?.secret)
589
+ .update(Buffer.from(data, 'utf-8'))
590
+ .digest();
591
+ const sign = signTerm.toString('base64');
592
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
593
+ let command = '';
594
+ if (this.botMode === 'switch' && this.On) {
595
+ command = 'turnOn';
596
+ this.On = true;
597
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Switch Mode, Turning ${this.On}`);
598
+ }
599
+ else if (this.botMode === 'switch' && !this.On) {
600
+ command = 'turnOff';
601
+ this.On = false;
602
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Switch Mode, Turning ${this.On}`);
603
+ }
604
+ else if (this.botMode === 'press') {
605
+ command = 'press';
606
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Press Mode`);
607
+ this.On = false;
660
608
  }
661
609
  else {
662
- return device_list[0].turnOff({ id: this.device.bleMac });
610
+ throw new Error(`${this.device.deviceType}: ${this.accessory.displayName} Device Paramters not set for this Bot.`);
663
611
  }
664
- },
665
- });
666
- }
667
- async openAPIpushChanges() {
668
- if (this.platform.config.credentials?.token) {
669
- try {
670
- if (this.On !== this.OnCached || this.allowPush) {
671
- this.debugLog(`Bot: ${this.accessory.displayName} OpenAPI pushChanges`);
672
- // Make Push On request to the API
673
- const t = Date.now();
674
- const nonce = 'requestID';
675
- const data = this.platform.config.credentials?.token + t + nonce;
676
- const signTerm = crypto_1.default.createHmac('sha256', this.platform.config.credentials?.secret)
677
- .update(Buffer.from(data, 'utf-8'))
678
- .digest();
679
- const sign = signTerm.toString('base64');
680
- this.debugLog(`Bot: ${this.accessory.displayName} sign: ${sign}`);
681
- let command = '';
682
- if (this.botMode === 'switch' && this.On) {
683
- command = 'turnOn';
684
- this.On = true;
685
- this.debugLog(`Bot: ${this.accessory.displayName} Switch Mode, Turning ${this.On}`);
686
- }
687
- else if (this.botMode === 'switch' && !this.On) {
688
- command = 'turnOff';
689
- this.On = false;
690
- this.debugLog(`Bot: ${this.accessory.displayName} Switch Mode, Turning ${this.On}`);
691
- }
692
- else if (this.botMode === 'press') {
693
- command = 'press';
694
- this.debugLog(`Bot: ${this.accessory.displayName} Press Mode`);
695
- this.On = false;
696
- }
697
- else {
698
- throw new Error(`Bot: ${this.accessory.displayName} Device Paramters not set for this Bot.`);
699
- }
700
- const body = JSON.stringify({
701
- 'command': `${command}`,
702
- 'parameter': 'default',
703
- 'commandType': 'command',
704
- });
705
- this.infoLog(`Bot: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
706
- const options = {
707
- hostname: settings_1.HostDomain,
708
- port: 443,
709
- path: `${settings_1.DevicePath}/${this.device.deviceId}/commands`,
710
- method: 'POST',
711
- headers: {
712
- 'Authorization': this.platform.config.credentials?.token,
713
- 'sign': sign,
714
- 'nonce': nonce,
715
- 't': t,
716
- 'Content-Type': 'application/json',
717
- 'Content-Length': body.length,
718
- },
719
- };
720
- const req = https_1.default.request(options, res => {
721
- this.debugLog(`Bot: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
722
- this.statusCode({ res });
723
- res.on('data', d => {
724
- this.debugLog(`Bot: ${this.accessory.displayName} d: ${d}`);
725
- });
726
- });
727
- req.on('error', (e) => {
728
- this.errorLog(`Bot: ${this.accessory.displayName} error message: ${e.message}`);
612
+ const body = (0, super_stringify_1.default)({
613
+ 'command': `${command}`,
614
+ 'parameter': 'default',
615
+ 'commandType': 'command',
616
+ });
617
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API. body: ${body},`);
618
+ const options = {
619
+ hostname: settings_1.HostDomain,
620
+ port: 443,
621
+ path: `${settings_1.DevicePath}/${this.device.deviceId}/commands`,
622
+ method: 'POST',
623
+ headers: {
624
+ 'Authorization': this.platform.config.credentials?.token,
625
+ 'sign': sign,
626
+ 'nonce': nonce,
627
+ 't': t,
628
+ 'Content-Type': 'application/json',
629
+ 'Content-Length': body.length,
630
+ },
631
+ };
632
+ const req = https_1.default.request(options, res => {
633
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges statusCode: ${res.statusCode}`);
634
+ this.statusCode({ res });
635
+ res.on('data', d => {
636
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
729
637
  });
730
- req.write(body);
731
- req.end();
732
- this.debugLog(`Bot: ${this.accessory.displayName} openAPIpushChanges: ${JSON.stringify(req)}`);
733
- this.OnCached = this.On;
734
- this.accessory.context.On = this.OnCached;
735
- }
638
+ });
639
+ req.on('error', (e) => {
640
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
641
+ });
642
+ req.write(body);
643
+ req.end();
644
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges: ${(0, super_stringify_1.default)(req)}`);
736
645
  }
737
- catch (e) {
738
- this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
739
- if (this.deviceLogging.includes('debug')) {
740
- this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`);
741
- }
742
- if (this.platform.debugMode) {
743
- this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,` + ` Error: ${JSON.stringify(e)}`);
744
- }
745
- this.apiError(e);
646
+ else {
647
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No openAPIpushChanges.` + `On: ${this.On}, `
648
+ + `OnCached: ${this.accessory.context.On}`);
649
+ }
650
+ }
651
+ catch (e) {
652
+ this.apiError(e);
653
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
654
+ + ` Connection, Error Message: ${(0, super_stringify_1.default)(e.message)}`);
655
+ }
656
+ }
657
+ /**
658
+ * Handle requests to set the "On" characteristic
659
+ */
660
+ async OnSet(value) {
661
+ if (this.device.bot?.deviceType === 'garagedoor') {
662
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set TargetDoorState: ${value}`);
663
+ if (value === this.platform.Characteristic.TargetDoorState.CLOSED) {
664
+ this.On = false;
665
+ }
666
+ else {
667
+ this.On = true;
668
+ }
669
+ }
670
+ else if (this.device.bot?.deviceType === 'door' ||
671
+ this.device.bot?.deviceType === 'window' ||
672
+ this.device.bot?.deviceType === 'windowcovering') {
673
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set TargetPosition: ${value}`);
674
+ if (value === 0) {
675
+ this.On = false;
676
+ }
677
+ else {
678
+ this.On = true;
679
+ }
680
+ }
681
+ else if (this.device.bot?.deviceType === 'lock') {
682
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set LockTargetState: ${value}`);
683
+ if (value === this.platform.Characteristic.LockTargetState.SECURED) {
684
+ this.On = false;
685
+ }
686
+ else {
687
+ this.On = true;
688
+ }
689
+ }
690
+ else if (this.device.bot?.deviceType === 'faucet') {
691
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set Active: ${value}`);
692
+ if (value === this.platform.Characteristic.Active.INACTIVE) {
693
+ this.On = false;
694
+ }
695
+ else {
696
+ this.On = true;
697
+ }
698
+ }
699
+ else if (this.device.bot?.deviceType === 'stateful') {
700
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set ProgrammableSwitchOutputState: ${value}`);
701
+ if (value === 0) {
702
+ this.On = false;
746
703
  }
704
+ else {
705
+ this.On = true;
706
+ }
707
+ }
708
+ else {
709
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set On: ${value}`);
710
+ this.On = value;
747
711
  }
712
+ this.doBotUpdate.next();
748
713
  }
749
714
  /**
750
715
  * Updates the status for each of the HomeKit Characteristics
@@ -752,329 +717,325 @@ class Bot {
752
717
  async updateHomeKitCharacteristics() {
753
718
  if (this.device.bot?.deviceType === 'garagedoor') {
754
719
  if (this.On === undefined) {
755
- this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
720
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
756
721
  }
757
722
  else {
758
723
  if (this.On) {
759
724
  this.garageDoorService?.updateCharacteristic(this.platform.Characteristic.TargetDoorState, this.platform.Characteristic.TargetDoorState.OPEN);
760
725
  this.garageDoorService?.updateCharacteristic(this.platform.Characteristic.CurrentDoorState, this.platform.Characteristic.CurrentDoorState.OPEN);
761
- this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic TargetDoorState: Open, CurrentDoorState: Open`);
726
+ this.debugLog(`${this.device.deviceType}: `
727
+ + `${this.accessory.displayName} updateCharacteristic TargetDoorState: Open, CurrentDoorState: Open`);
762
728
  }
763
729
  else {
764
730
  this.garageDoorService?.updateCharacteristic(this.platform.Characteristic.TargetDoorState, this.platform.Characteristic.TargetDoorState.CLOSED);
765
731
  this.garageDoorService?.updateCharacteristic(this.platform.Characteristic.CurrentDoorState, this.platform.Characteristic.CurrentDoorState.CLOSED);
766
- this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic TargetDoorState: Open, CurrentDoorState: Open`);
732
+ this.debugLog(`${this.device.deviceType}: `
733
+ + `${this.accessory.displayName} updateCharacteristic TargetDoorState: Open, CurrentDoorState: Open`);
767
734
  }
768
735
  }
769
- this.debugLog(`Bot: ${this.accessory.displayName} Garage Door On: ${this.On}`);
736
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Garage Door On: ${this.On}`);
770
737
  }
771
738
  else if (this.device.bot?.deviceType === 'door') {
772
739
  if (this.On === undefined) {
773
- this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
740
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
774
741
  }
775
742
  else {
776
743
  if (this.On) {
777
744
  this.doorService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, 100);
778
745
  this.doorService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, 100);
779
746
  this.doorService?.updateCharacteristic(this.platform.Characteristic.PositionState, this.platform.Characteristic.PositionState.STOPPED);
780
- this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic TargetPosition: 100, CurrentPosition: 100`);
747
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic TargetPosition: 100, CurrentPosition: 100`);
781
748
  }
782
749
  else {
783
750
  this.doorService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, 0);
784
751
  this.doorService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, 0);
785
752
  this.doorService?.updateCharacteristic(this.platform.Characteristic.PositionState, this.platform.Characteristic.PositionState.STOPPED);
786
- this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic TargetPosition: 0, CurrentPosition: 0`);
753
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic TargetPosition: 0, CurrentPosition: 0`);
787
754
  }
788
755
  }
789
- this.debugLog(`Bot: ${this.accessory.displayName} Door On: ${this.On}`);
756
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Door On: ${this.On}`);
790
757
  }
791
758
  else if (this.device.bot?.deviceType === 'window') {
792
759
  if (this.On === undefined) {
793
- this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
760
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
794
761
  }
795
762
  else {
796
763
  if (this.On) {
797
764
  this.windowService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, 100);
798
765
  this.windowService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, 100);
799
766
  this.windowService?.updateCharacteristic(this.platform.Characteristic.PositionState, this.platform.Characteristic.PositionState.STOPPED);
800
- this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic TargetPosition: 100, CurrentPosition: 100`);
767
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic TargetPosition: 100, CurrentPosition: 100`);
801
768
  }
802
769
  else {
803
770
  this.windowService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, 0);
804
771
  this.windowService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, 0);
805
772
  this.windowService?.updateCharacteristic(this.platform.Characteristic.PositionState, this.platform.Characteristic.PositionState.STOPPED);
806
- this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic TargetPosition: 0, CurrentPosition: 0`);
773
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic TargetPosition: 0, CurrentPosition: 0`);
807
774
  }
808
775
  }
809
- this.debugLog(`Bot: ${this.accessory.displayName} Window On: ${this.On}`);
776
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Window On: ${this.On}`);
810
777
  }
811
778
  else if (this.device.bot?.deviceType === 'windowcovering') {
812
779
  if (this.On === undefined) {
813
- this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
780
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
814
781
  }
815
782
  else {
816
783
  if (this.On) {
817
784
  this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, 100);
818
785
  this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, 100);
819
786
  this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.PositionState, this.platform.Characteristic.PositionState.STOPPED);
820
- this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic TargetPosition: 100, CurrentPosition: 100`);
787
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic TargetPosition: 100, CurrentPosition: 100`);
821
788
  }
822
789
  else {
823
790
  this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, 0);
824
791
  this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, 0);
825
792
  this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.PositionState, this.platform.Characteristic.PositionState.STOPPED);
826
- this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic TargetPosition: 0, CurrentPosition: 0`);
793
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic TargetPosition: 0, CurrentPosition: 0`);
827
794
  }
828
795
  }
829
- this.debugLog(`Bot: ${this.accessory.displayName} Window Covering On: ${this.On}`);
796
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Window Covering On: ${this.On}`);
830
797
  }
831
798
  else if (this.device.bot?.deviceType === 'lock') {
832
799
  if (this.On === undefined) {
833
- this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
800
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
834
801
  }
835
802
  else {
836
803
  if (this.On) {
837
804
  this.lockService?.updateCharacteristic(this.platform.Characteristic.LockTargetState, this.platform.Characteristic.LockTargetState.UNSECURED);
838
805
  this.lockService?.updateCharacteristic(this.platform.Characteristic.LockCurrentState, this.platform.Characteristic.LockCurrentState.UNSECURED);
839
- this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic LockTargetState: UNSECURED, LockCurrentState: UNSECURED`);
806
+ this.debugLog(`${this.device.deviceType}: `
807
+ + `${this.accessory.displayName} updateCharacteristic LockTargetState: UNSECURED, LockCurrentState: UNSECURED`);
840
808
  }
841
809
  else {
842
810
  this.lockService?.updateCharacteristic(this.platform.Characteristic.LockTargetState, this.platform.Characteristic.LockTargetState.SECURED);
843
811
  this.lockService?.updateCharacteristic(this.platform.Characteristic.LockCurrentState, this.platform.Characteristic.LockCurrentState.SECURED);
844
- this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic LockTargetState: SECURED, LockCurrentState: SECURED`);
812
+ this.debugLog(`${this.device.deviceType}: `
813
+ + `${this.accessory.displayName} updateCharacteristic LockTargetState: SECURED, LockCurrentState: SECURED`);
845
814
  }
846
815
  }
847
- this.debugLog(`Bot: ${this.accessory.displayName} Lock On: ${this.On}`);
816
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Lock On: ${this.On}`);
848
817
  }
849
818
  else if (this.device.bot?.deviceType === 'faucet') {
850
819
  if (this.On === undefined) {
851
- this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
820
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
852
821
  }
853
822
  else {
854
823
  if (this.On) {
855
824
  this.faucetService?.updateCharacteristic(this.platform.Characteristic.Active, this.platform.Characteristic.Active.ACTIVE);
856
- this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic Active: ${this.On}`);
825
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic Active: ${this.On}`);
857
826
  }
858
827
  else {
859
828
  this.faucetService?.updateCharacteristic(this.platform.Characteristic.Active, this.platform.Characteristic.Active.INACTIVE);
860
- this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic Active: ${this.On}`);
829
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic Active: ${this.On}`);
861
830
  }
862
831
  }
863
- this.debugLog(`Bot: ${this.accessory.displayName} Faucet On: ${this.On}`);
832
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Faucet On: ${this.On}`);
864
833
  }
865
834
  else if (this.device.bot?.deviceType === 'fan') {
866
835
  if (this.On === undefined) {
867
- this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
836
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
868
837
  }
869
838
  else {
870
839
  if (this.On) {
871
840
  this.fanService?.updateCharacteristic(this.platform.Characteristic.On, this.On);
872
- this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
841
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
873
842
  }
874
843
  else {
875
844
  this.fanService?.updateCharacteristic(this.platform.Characteristic.On, this.On);
876
- this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
845
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
877
846
  }
878
847
  }
879
- this.debugLog(`Bot: ${this.accessory.displayName} Fan On: ${this.On}`);
848
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Fan On: ${this.On}`);
880
849
  }
881
850
  else if (this.device.bot?.deviceType === 'stateful') {
882
851
  if (this.On === undefined) {
883
- this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
852
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
884
853
  }
885
854
  else {
886
855
  if (this.On) {
887
856
  this.statefulProgrammableSwitchService?.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchEvent, this.platform.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS);
888
857
  this.statefulProgrammableSwitchService?.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchOutputState, 1);
889
- this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic ProgrammableSwitchEvent: SINGLE, ProgrammableSwitchOutputState: 1`);
858
+ this.debugLog(`${this.device.deviceType}: `
859
+ + `${this.accessory.displayName} updateCharacteristic ProgrammableSwitchEvent: SINGLE, ProgrammableSwitchOutputState: 1`);
890
860
  }
891
861
  else {
892
862
  this.statefulProgrammableSwitchService?.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchEvent, this.platform.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS);
893
863
  this.statefulProgrammableSwitchService?.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchOutputState, 0);
894
- this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic ProgrammableSwitchEvent: SINGLE, ProgrammableSwitchOutputState: 0`);
864
+ this.debugLog(`${this.device.deviceType}: `
865
+ + `${this.accessory.displayName} updateCharacteristic ProgrammableSwitchEvent: SINGLE, ProgrammableSwitchOutputState: 0`);
895
866
  }
896
867
  }
897
- this.debugLog(`Bot: ${this.accessory.displayName} StatefulProgrammableSwitch On: ${this.On}`);
868
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatefulProgrammableSwitch On: ${this.On}`);
898
869
  }
899
870
  else if (this.device.bot?.deviceType === 'switch') {
900
871
  if (this.On === undefined) {
901
- this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
872
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
902
873
  }
903
874
  else {
904
875
  this.switchService?.updateCharacteristic(this.platform.Characteristic.On, this.On);
905
- this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
876
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
906
877
  }
907
878
  }
908
879
  else {
909
880
  if (this.On === undefined) {
910
- this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
881
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.On}`);
911
882
  }
912
883
  else {
913
884
  this.outletService?.updateCharacteristic(this.platform.Characteristic.On, this.On);
914
- this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
885
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
915
886
  }
916
887
  }
917
- if (this.device.ble) {
888
+ this.accessory.context.On = this.On;
889
+ if (this.BLE) {
918
890
  if (this.BatteryLevel === undefined) {
919
- this.debugLog(`Bot: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
891
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
920
892
  }
921
893
  else {
894
+ this.accessory.context.BatteryLevel = this.BatteryLevel;
922
895
  this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.BatteryLevel);
923
- this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
896
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
924
897
  }
925
898
  if (this.StatusLowBattery === undefined) {
926
- this.debugLog(`Bot: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
899
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
927
900
  }
928
901
  else {
902
+ this.accessory.context.StatusLowBattery = this.StatusLowBattery;
929
903
  this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.StatusLowBattery);
930
- this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
904
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
931
905
  }
932
906
  }
933
907
  }
934
- async apiError(e) {
935
- if (this.device.bot?.deviceType === 'garagedoor') {
936
- this.garageDoorService?.updateCharacteristic(this.platform.Characteristic.TargetDoorState, e);
937
- this.garageDoorService?.updateCharacteristic(this.platform.Characteristic.CurrentDoorState, e);
938
- this.garageDoorService?.updateCharacteristic(this.platform.Characteristic.ObstructionDetected, e);
939
- }
940
- else if (this.device.bot?.deviceType === 'door') {
941
- this.doorService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, e);
942
- this.doorService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, e);
943
- this.doorService?.updateCharacteristic(this.platform.Characteristic.PositionState, e);
908
+ async removeOutletService(accessory) {
909
+ // If outletService still pressent, then remove first
910
+ this.outletService = this.accessory.getService(this.platform.Service.Outlet);
911
+ if (this.outletService) {
912
+ this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Outlet Service`);
944
913
  }
945
- else if (this.device.bot?.deviceType === 'window') {
946
- this.windowService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, e);
947
- this.windowService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, e);
948
- this.windowService?.updateCharacteristic(this.platform.Characteristic.PositionState, e);
914
+ accessory.removeService(this.outletService);
915
+ }
916
+ async removeGarageDoorService(accessory) {
917
+ // If garageDoorService still pressent, then remove first
918
+ this.garageDoorService = this.accessory.getService(this.platform.Service.GarageDoorOpener);
919
+ if (this.garageDoorService) {
920
+ this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Garage Door Service`);
949
921
  }
950
- else if (this.device.bot?.deviceType === 'windowcovering') {
951
- this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, e);
952
- this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, e);
953
- this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.PositionState, e);
922
+ accessory.removeService(this.garageDoorService);
923
+ }
924
+ async removeDoorService(accessory) {
925
+ // If doorService still pressent, then remove first
926
+ this.doorService = this.accessory.getService(this.platform.Service.Door);
927
+ if (this.doorService) {
928
+ this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Door Service`);
954
929
  }
955
- else if (this.device.bot?.deviceType === 'lock') {
956
- this.doorService?.updateCharacteristic(this.platform.Characteristic.LockTargetState, e);
957
- this.doorService?.updateCharacteristic(this.platform.Characteristic.LockCurrentState, e);
930
+ accessory.removeService(this.doorService);
931
+ }
932
+ async removeLockService(accessory) {
933
+ // If lockService still pressent, then remove first
934
+ this.lockService = this.accessory.getService(this.platform.Service.LockMechanism);
935
+ if (this.lockService) {
936
+ this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Lock Service`);
958
937
  }
959
- else if (this.device.bot?.deviceType === 'faucet') {
960
- this.faucetService?.updateCharacteristic(this.platform.Characteristic.Active, e);
961
- }
962
- else if (this.device.bot?.deviceType === 'fan') {
963
- this.fanService?.updateCharacteristic(this.platform.Characteristic.On, e);
964
- }
965
- else if (this.device.bot?.deviceType === 'stateful') {
966
- this.statefulProgrammableSwitchService?.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchEvent, e);
967
- this.statefulProgrammableSwitchService?.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchOutputState, e);
968
- }
969
- else if (this.device.bot?.deviceType === 'switch') {
970
- this.switchService?.updateCharacteristic(this.platform.Characteristic.On, e);
938
+ accessory.removeService(this.lockService);
939
+ }
940
+ async removeFaucetService(accessory) {
941
+ // If faucetService still pressent, then remove first
942
+ this.faucetService = this.accessory.getService(this.platform.Service.Faucet);
943
+ if (this.faucetService) {
944
+ this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Faucet Service`);
971
945
  }
972
- else {
973
- this.outletService?.updateCharacteristic(this.platform.Characteristic.On, e);
946
+ accessory.removeService(this.faucetService);
947
+ }
948
+ async removeFanService(accessory) {
949
+ // If fanService still pressent, then remove first
950
+ this.fanService = this.accessory.getService(this.platform.Service.Fan);
951
+ if (this.fanService) {
952
+ this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Fan Service`);
974
953
  }
975
- if (this.device.ble) {
976
- this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
977
- this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
954
+ accessory.removeService(this.fanService);
955
+ }
956
+ async removeWindowService(accessory) {
957
+ // If windowService still pressent, then remove first
958
+ this.windowService = this.accessory.getService(this.platform.Service.Window);
959
+ if (this.windowService) {
960
+ this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Window Service`);
978
961
  }
979
- //throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
962
+ accessory.removeService(this.windowService);
980
963
  }
981
- async statusCode({ res }) {
982
- switch (res.statusCode) {
983
- case 151:
984
- this.errorLog(`Bot: ${this.accessory.displayName} Command not supported by this device type.`);
985
- break;
986
- case 152:
987
- this.errorLog(`Bot: ${this.accessory.displayName} Device not found.`);
988
- break;
989
- case 160:
990
- this.errorLog(`Bot: ${this.accessory.displayName} Command is not supported.`);
991
- break;
992
- case 161:
993
- this.errorLog(`Bot: ${this.accessory.displayName} Device is offline.`);
994
- this.offlineOff();
995
- break;
996
- case 171:
997
- this.errorLog(`Bot: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
998
- this.offlineOff();
999
- break;
1000
- case 190:
1001
- this.errorLog(`Bot: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
1002
- ` Or command: ${JSON.stringify(res)} format is invalid`);
1003
- break;
1004
- case 100:
1005
- this.debugLog(`Bot: ${this.accessory.displayName} Command successfully sent.`);
1006
- break;
1007
- default:
1008
- this.debugLog(`Bot: ${this.accessory.displayName} Unknown statusCode.`);
964
+ async removeWindowCoveringService(accessory) {
965
+ // If windowCoveringService still pressent, then remove first
966
+ this.windowCoveringService = this.accessory.getService(this.platform.Service.WindowCovering);
967
+ if (this.windowCoveringService) {
968
+ this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Window Covering Service`);
1009
969
  }
970
+ accessory.removeService(this.windowCoveringService);
1010
971
  }
1011
- async offlineOff() {
1012
- if (this.device.offline) {
1013
- this.On = false;
1014
- if (this.device.bot?.deviceType === 'switch') {
1015
- this.switchService?.getCharacteristic(this.platform.Characteristic.On).updateValue(this.On);
1016
- }
1017
- else {
1018
- this.outletService?.getCharacteristic(this.platform.Characteristic.On).updateValue(this.On);
1019
- }
972
+ async removeStatefulProgrammableSwitchService(accessory) {
973
+ // If statefulProgrammableSwitchService still pressent, then remove first
974
+ this.statefulProgrammableSwitchService = this.accessory.getService(this.platform.Service.StatefulProgrammableSwitch);
975
+ if (this.statefulProgrammableSwitchService) {
976
+ this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Stateful Programmable Switch Service`);
1020
977
  }
978
+ accessory.removeService(this.statefulProgrammableSwitchService);
1021
979
  }
1022
- /**
1023
- * Handle requests to set the "On" characteristic
1024
- */
1025
- async handleOnSet(value) {
1026
- if (this.device.bot?.deviceType === 'garagedoor') {
1027
- this.debugLog(`Bot: ${this.accessory.displayName} TargetDoorState: ${value}`);
1028
- if (value === this.platform.Characteristic.TargetDoorState.CLOSED) {
1029
- this.On = false;
1030
- }
1031
- else {
1032
- this.On = true;
1033
- }
980
+ async removeSwitchService(accessory) {
981
+ // If switchService still pressent, then remove first
982
+ this.switchService = this.accessory.getService(this.platform.Service.Switch);
983
+ if (this.switchService) {
984
+ this.warnLog(`${this.device.deviceType}: ${accessory.displayName} Removing Leftover Switch Service`);
1034
985
  }
1035
- else if (this.device.bot?.deviceType === 'door' ||
1036
- this.device.bot?.deviceType === 'window' ||
1037
- this.device.bot?.deviceType === 'windowcovering') {
1038
- this.debugLog(`Bot: ${this.accessory.displayName} TargetPosition: ${value}`);
1039
- if (value === 0) {
1040
- this.On = false;
1041
- }
1042
- else {
1043
- this.On = true;
1044
- }
986
+ accessory.removeService(this.switchService);
987
+ }
988
+ DoublePress(device) {
989
+ if (device.bot?.doublePress) {
990
+ this.doublePress = device.bot?.doublePress;
991
+ this.accessory.context.doublePress = this.doublePress;
1045
992
  }
1046
- else if (this.device.bot?.deviceType === 'lock') {
1047
- this.debugLog(`Bot: ${this.accessory.displayName} LockTargetState: ${value}`);
1048
- if (value === this.platform.Characteristic.LockTargetState.SECURED) {
1049
- this.On = false;
1050
- }
1051
- else {
1052
- this.On = true;
1053
- }
993
+ else {
994
+ this.doublePress = 1;
1054
995
  }
1055
- else if (this.device.bot?.deviceType === 'faucet') {
1056
- this.debugLog(`Bot: ${this.accessory.displayName} Active: ${value}`);
1057
- if (value === this.platform.Characteristic.Active.INACTIVE) {
1058
- this.On = false;
1059
- }
1060
- else {
1061
- this.On = true;
1062
- }
996
+ }
997
+ async getCustomBLEAddress(switchbot) {
998
+ if (this.device.customBLEaddress && this.deviceLogging.includes('debug')) {
999
+ (async () => {
1000
+ // Start to monitor advertisement packets
1001
+ await switchbot.startScan({
1002
+ model: 'H',
1003
+ });
1004
+ // Set an event handler
1005
+ switchbot.onadvertisement = (ad) => {
1006
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${(0, super_stringify_1.default)(ad, null, ' ')}`);
1007
+ };
1008
+ await switchbot.wait(10000);
1009
+ // Stop to monitor
1010
+ switchbot.stopScan();
1011
+ })();
1063
1012
  }
1064
- else if (this.device.bot?.deviceType === 'stateful') {
1065
- this.debugLog(`Bot: ${this.accessory.displayName} ProgrammableSwitchOutputState: ${value}`);
1066
- if (value === 0) {
1067
- this.On = false;
1068
- }
1069
- else {
1070
- this.On = true;
1071
- }
1013
+ }
1014
+ async BLEPushConnection() {
1015
+ if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
1016
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Push Changes`);
1017
+ await this.openAPIpushChanges();
1072
1018
  }
1073
- else {
1074
- this.debugLog(`Bot: ${this.accessory.displayName} On: ${value}`);
1075
- this.On = value;
1019
+ }
1020
+ async BLERefreshConnection(switchbot) {
1021
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
1022
+ if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
1023
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Refresh Status`);
1024
+ await this.openAPIRefreshStatus();
1076
1025
  }
1077
- this.doBotUpdate.next();
1026
+ }
1027
+ async turnOnOff(device_list) {
1028
+ return await this.retry({
1029
+ max: await this.maxRetry(),
1030
+ fn: () => {
1031
+ if (this.On) {
1032
+ return device_list[0].turnOn({ id: this.device.bleMac });
1033
+ }
1034
+ else {
1035
+ return device_list[0].turnOff({ id: this.device.bleMac });
1036
+ }
1037
+ },
1038
+ });
1078
1039
  }
1079
1040
  async retry({ max, fn }) {
1080
1041
  return fn().catch(async (err) => {
@@ -1097,77 +1058,141 @@ class Bot {
1097
1058
  }
1098
1059
  return maxRetry;
1099
1060
  }
1100
- async config(device) {
1101
- let config = {};
1102
- if (device.bot) {
1103
- config = device.bot;
1104
- }
1105
- if (device.ble) {
1106
- config['ble'] = device.ble;
1107
- }
1108
- if (device.logging !== undefined) {
1109
- config['logging'] = device.logging;
1110
- }
1111
- if (device.refreshRate !== undefined) {
1112
- config['refreshRate'] = device.refreshRate;
1061
+ async PressOrSwitch(device) {
1062
+ if (!device.bot?.mode) {
1063
+ this.botMode = 'switch';
1064
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} does not have bot mode set in the Plugin's SwitchBot Device Settings,`);
1065
+ this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} is defaulting to "${this.botMode}" mode, you may experience issues.`);
1113
1066
  }
1114
- if (device.scanDuration !== undefined) {
1115
- config['scanDuration'] = device.scanDuration;
1067
+ else if (device.bot?.mode === 'switch') {
1068
+ this.botMode = 'switch';
1069
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Bot Mode: ${this.botMode}`);
1116
1070
  }
1117
- if (device.offline !== undefined) {
1118
- config['offline'] = device.offline;
1071
+ else if (device.bot?.mode === 'press') {
1072
+ this.botMode = 'press';
1073
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Bot Mode: ${this.botMode}`);
1119
1074
  }
1120
- if (Object.entries(config).length !== 0) {
1121
- this.infoLog(`Bot: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
1075
+ else {
1076
+ throw new Error(`${this.device.deviceType}: ${this.accessory.displayName} Bot Mode: ${this.botMode}`);
1122
1077
  }
1123
1078
  }
1124
- async refreshRate(device) {
1125
- if (device.refreshRate) {
1126
- this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
1127
- this.debugLog(`Bot: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
1079
+ async allowPushChanges(device) {
1080
+ if (device.bot?.allowPush) {
1081
+ this.allowPush = true;
1128
1082
  }
1129
- else if (this.platform.config.options.refreshRate) {
1130
- this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options.refreshRate;
1131
- this.debugLog(`Bot: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
1083
+ else {
1084
+ this.allowPush = false;
1132
1085
  }
1086
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Allowing Push Changes: ${this.allowPush}`);
1133
1087
  }
1134
1088
  async scan(device) {
1135
1089
  if (device.scanDuration) {
1136
1090
  this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
1137
- if (device.ble) {
1138
- this.debugLog(`Bot: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
1091
+ if (this.BLE) {
1092
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
1139
1093
  }
1140
1094
  }
1141
1095
  else {
1142
1096
  this.scanDuration = this.accessory.context.scanDuration = 1;
1143
- if (this.device.ble) {
1144
- this.debugLog(`Bot: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
1097
+ if (this.BLE) {
1098
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
1145
1099
  }
1146
1100
  }
1147
1101
  }
1148
- async logs(device) {
1149
- if (this.platform.debugMode) {
1150
- this.deviceLogging = this.accessory.context.logging = 'debugMode';
1151
- this.debugLog(`Bot: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
1102
+ async statusCode({ res }) {
1103
+ switch (res.statusCode) {
1104
+ case 151:
1105
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this device type.`);
1106
+ break;
1107
+ case 152:
1108
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found.`);
1109
+ break;
1110
+ case 160:
1111
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported.`);
1112
+ break;
1113
+ case 161:
1114
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline.`);
1115
+ this.offlineOff();
1116
+ break;
1117
+ case 171:
1118
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
1119
+ this.offlineOff();
1120
+ break;
1121
+ case 190:
1122
+ this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
1123
+ ` Or command: ${(0, super_stringify_1.default)(res)} format is invalid`);
1124
+ break;
1125
+ case 100:
1126
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent.`);
1127
+ break;
1128
+ default:
1129
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode.`);
1152
1130
  }
1153
- else if (device.logging) {
1154
- this.deviceLogging = this.accessory.context.logging = device.logging;
1155
- this.debugLog(`Bot: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
1131
+ }
1132
+ async offlineOff() {
1133
+ if (this.device.offline) {
1134
+ this.On = false;
1135
+ if (this.device.bot?.deviceType === 'switch') {
1136
+ this.switchService?.getCharacteristic(this.platform.Characteristic.On).updateValue(this.On);
1137
+ }
1138
+ else {
1139
+ this.outletService?.getCharacteristic(this.platform.Characteristic.On).updateValue(this.On);
1140
+ }
1141
+ await this.updateHomeKitCharacteristics();
1156
1142
  }
1157
- else if (this.platform.config.options?.logging) {
1158
- this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
1159
- this.debugLog(`Bot: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
1143
+ }
1144
+ async apiError(e) {
1145
+ if (this.device.bot?.deviceType === 'garagedoor') {
1146
+ this.garageDoorService?.updateCharacteristic(this.platform.Characteristic.TargetDoorState, e);
1147
+ this.garageDoorService?.updateCharacteristic(this.platform.Characteristic.CurrentDoorState, e);
1148
+ this.garageDoorService?.updateCharacteristic(this.platform.Characteristic.ObstructionDetected, e);
1149
+ }
1150
+ else if (this.device.bot?.deviceType === 'door') {
1151
+ this.doorService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, e);
1152
+ this.doorService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, e);
1153
+ this.doorService?.updateCharacteristic(this.platform.Characteristic.PositionState, e);
1154
+ }
1155
+ else if (this.device.bot?.deviceType === 'window') {
1156
+ this.windowService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, e);
1157
+ this.windowService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, e);
1158
+ this.windowService?.updateCharacteristic(this.platform.Characteristic.PositionState, e);
1159
+ }
1160
+ else if (this.device.bot?.deviceType === 'windowcovering') {
1161
+ this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.TargetPosition, e);
1162
+ this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.CurrentPosition, e);
1163
+ this.windowCoveringService?.updateCharacteristic(this.platform.Characteristic.PositionState, e);
1164
+ }
1165
+ else if (this.device.bot?.deviceType === 'lock') {
1166
+ this.doorService?.updateCharacteristic(this.platform.Characteristic.LockTargetState, e);
1167
+ this.doorService?.updateCharacteristic(this.platform.Characteristic.LockCurrentState, e);
1168
+ }
1169
+ else if (this.device.bot?.deviceType === 'faucet') {
1170
+ this.faucetService?.updateCharacteristic(this.platform.Characteristic.Active, e);
1171
+ }
1172
+ else if (this.device.bot?.deviceType === 'fan') {
1173
+ this.fanService?.updateCharacteristic(this.platform.Characteristic.On, e);
1174
+ }
1175
+ else if (this.device.bot?.deviceType === 'stateful') {
1176
+ this.statefulProgrammableSwitchService?.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchEvent, e);
1177
+ this.statefulProgrammableSwitchService?.updateCharacteristic(this.platform.Characteristic.ProgrammableSwitchOutputState, e);
1178
+ }
1179
+ else if (this.device.bot?.deviceType === 'switch') {
1180
+ this.switchService?.updateCharacteristic(this.platform.Characteristic.On, e);
1160
1181
  }
1161
1182
  else {
1162
- this.deviceLogging = this.accessory.context.logging = 'standard';
1163
- this.debugLog(`Bot: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
1183
+ this.outletService?.updateCharacteristic(this.platform.Characteristic.On, e);
1184
+ }
1185
+ if (this.BLE) {
1186
+ this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
1187
+ this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
1164
1188
  }
1165
1189
  }
1166
1190
  FirmwareRevision(accessory, device) {
1167
1191
  let FirmwareRevision;
1168
- this.debugLog(`Bot: ${this.accessory.displayName} accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
1169
- this.debugLog(`Bot: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
1170
- this.debugLog(`Bot: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
1192
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
1193
+ + ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
1194
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
1195
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
1171
1196
  if (accessory.context.FirmwareRevision) {
1172
1197
  FirmwareRevision = accessory.context.FirmwareRevision;
1173
1198
  }
@@ -1179,112 +1204,79 @@ class Bot {
1179
1204
  }
1180
1205
  return FirmwareRevision;
1181
1206
  }
1182
- async PressOrSwitch(device) {
1183
- if (!device.bot?.mode) {
1184
- this.botMode = 'switch';
1185
- this.warnLog(`Bot: ${this.accessory.displayName} does not have bot mode set in the Plugin's SwitchBot Device Settings,`);
1186
- this.warnLog(`Bot: ${this.accessory.displayName} is defaulting to "${this.botMode}" mode, you may experience issues.`);
1207
+ context() {
1208
+ if (this.On === undefined) {
1209
+ this.On = false;
1210
+ this.accessory.context.On = this.On;
1187
1211
  }
1188
- else if (device.bot?.mode === 'switch') {
1189
- this.botMode = 'switch';
1190
- this.debugLog(`Bot: ${this.accessory.displayName} Using Bot Mode: ${this.botMode}`);
1212
+ else {
1213
+ this.On = this.accessory.context.On;
1191
1214
  }
1192
- else if (device.bot?.mode === 'press') {
1193
- this.botMode = 'press';
1194
- this.debugLog(`Bot: ${this.accessory.displayName} Using Bot Mode: ${this.botMode}`);
1215
+ if (this.BatteryLevel === undefined) {
1216
+ this.BatteryLevel = 100;
1195
1217
  }
1196
1218
  else {
1197
- throw new Error(`Bot: ${this.accessory.displayName} Bot Mode: ${this.botMode}`);
1219
+ this.BatteryLevel = this.accessory.context.BatteryLevel;
1198
1220
  }
1199
- }
1200
- async allowPushChanges(device) {
1201
- if (device.bot?.allowPush) {
1202
- this.allowPush = true;
1221
+ if (this.StatusLowBattery === undefined) {
1222
+ this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
1223
+ this.accessory.context.StatusLowBattery = this.StatusLowBattery;
1203
1224
  }
1204
1225
  else {
1205
- this.allowPush = false;
1226
+ this.StatusLowBattery = this.accessory.context.StatusLowBattery;
1206
1227
  }
1207
- this.debugLog(`Bot: ${this.accessory.displayName} Allowing Push Changes: ${this.allowPush}`);
1208
1228
  }
1209
- async removeOutletService(accessory) {
1210
- // If outletService still pressent, then remove first
1211
- this.outletService = this.accessory.getService(this.platform.Service.Outlet);
1212
- if (this.outletService) {
1213
- this.warnLog(`Bot: ${accessory.displayName} Removing Leftover Outlet Service`);
1229
+ async refreshRate(device) {
1230
+ if (device.refreshRate) {
1231
+ this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
1232
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
1214
1233
  }
1215
- accessory.removeService(this.outletService);
1216
- }
1217
- async removeGarageDoorService(accessory) {
1218
- // If garageDoorService still pressent, then remove first
1219
- this.garageDoorService = this.accessory.getService(this.platform.Service.GarageDoorOpener);
1220
- if (this.garageDoorService) {
1221
- this.warnLog(`Bot: ${accessory.displayName} Removing Leftover Garage Door Service`);
1234
+ else if (this.platform.config.options.refreshRate) {
1235
+ this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options.refreshRate;
1236
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
1222
1237
  }
1223
- accessory.removeService(this.garageDoorService);
1224
1238
  }
1225
- async removeDoorService(accessory) {
1226
- // If doorService still pressent, then remove first
1227
- this.doorService = this.accessory.getService(this.platform.Service.Door);
1228
- if (this.doorService) {
1229
- this.warnLog(`Bot: ${accessory.displayName} Removing Leftover Door Service`);
1239
+ async config(device) {
1240
+ let config = {};
1241
+ if (device.bot) {
1242
+ config = device.bot;
1230
1243
  }
1231
- accessory.removeService(this.doorService);
1232
- }
1233
- async removeLockService(accessory) {
1234
- // If lockService still pressent, then remove first
1235
- this.lockService = this.accessory.getService(this.platform.Service.LockMechanism);
1236
- if (this.lockService) {
1237
- this.warnLog(`Bot: ${accessory.displayName} Removing Leftover Lock Service`);
1244
+ if (device.connectionType !== undefined) {
1245
+ config['connectionType'] = device.connectionType;
1238
1246
  }
1239
- accessory.removeService(this.lockService);
1240
- }
1241
- async removeFaucetService(accessory) {
1242
- // If faucetService still pressent, then remove first
1243
- this.faucetService = this.accessory.getService(this.platform.Service.Faucet);
1244
- if (this.faucetService) {
1245
- this.warnLog(`Bot: ${accessory.displayName} Removing Leftover Faucet Service`);
1247
+ if (device.logging !== undefined) {
1248
+ config['logging'] = device.logging;
1246
1249
  }
1247
- accessory.removeService(this.faucetService);
1248
- }
1249
- async removeFanService(accessory) {
1250
- // If fanService still pressent, then remove first
1251
- this.fanService = this.accessory.getService(this.platform.Service.Fan);
1252
- if (this.fanService) {
1253
- this.warnLog(`Bot: ${accessory.displayName} Removing Leftover Fan Service`);
1250
+ if (device.refreshRate !== undefined) {
1251
+ config['refreshRate'] = device.refreshRate;
1254
1252
  }
1255
- accessory.removeService(this.fanService);
1256
- }
1257
- async removeWindowService(accessory) {
1258
- // If windowService still pressent, then remove first
1259
- this.windowService = this.accessory.getService(this.platform.Service.Window);
1260
- if (this.windowService) {
1261
- this.warnLog(`Bot: ${accessory.displayName} Removing Leftover Window Service`);
1253
+ if (device.scanDuration !== undefined) {
1254
+ config['scanDuration'] = device.scanDuration;
1262
1255
  }
1263
- accessory.removeService(this.windowService);
1264
- }
1265
- async removeWindowCoveringService(accessory) {
1266
- // If windowCoveringService still pressent, then remove first
1267
- this.windowCoveringService = this.accessory.getService(this.platform.Service.WindowCovering);
1268
- if (this.windowCoveringService) {
1269
- this.warnLog(`Bot: ${accessory.displayName} Removing Leftover Window Covering Service`);
1256
+ if (device.offline !== undefined) {
1257
+ config['offline'] = device.offline;
1270
1258
  }
1271
- accessory.removeService(this.windowCoveringService);
1272
- }
1273
- async removeStatefulProgrammableSwitchService(accessory) {
1274
- // If statefulProgrammableSwitchService still pressent, then remove first
1275
- this.statefulProgrammableSwitchService = this.accessory.getService(this.platform.Service.StatefulProgrammableSwitch);
1276
- if (this.statefulProgrammableSwitchService) {
1277
- this.warnLog(`Bot: ${accessory.displayName} Removing Leftover Stateful Programmable Switch Service`);
1259
+ if (Object.entries(config).length !== 0) {
1260
+ this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${(0, super_stringify_1.default)(config)}`);
1278
1261
  }
1279
- accessory.removeService(this.statefulProgrammableSwitchService);
1280
1262
  }
1281
- async removeSwitchService(accessory) {
1282
- // If switchService still pressent, then remove first
1283
- this.switchService = this.accessory.getService(this.platform.Service.Switch);
1284
- if (this.switchService) {
1285
- this.warnLog(`Bot: ${accessory.displayName} Removing Leftover Switch Service`);
1263
+ async logs(device) {
1264
+ if (this.platform.debugMode) {
1265
+ this.deviceLogging = this.accessory.context.logging = 'debugMode';
1266
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
1267
+ }
1268
+ else if (device.logging) {
1269
+ this.deviceLogging = this.accessory.context.logging = device.logging;
1270
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
1271
+ }
1272
+ else if (this.platform.config.options?.logging) {
1273
+ this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
1274
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
1275
+ }
1276
+ else {
1277
+ this.deviceLogging = this.accessory.context.logging = 'standard';
1278
+ this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
1286
1279
  }
1287
- accessory.removeService(this.switchService);
1288
1280
  }
1289
1281
  /**
1290
1282
  * Logging for Device
@@ -1299,11 +1291,25 @@ class Bot {
1299
1291
  this.platform.log.warn(String(...log));
1300
1292
  }
1301
1293
  }
1294
+ debugWarnLog(...log) {
1295
+ if (this.enablingDeviceLogging()) {
1296
+ if (this.deviceLogging?.includes('debug')) {
1297
+ this.platform.log.warn('[DEBUG]', String(...log));
1298
+ }
1299
+ }
1300
+ }
1302
1301
  errorLog(...log) {
1303
1302
  if (this.enablingDeviceLogging()) {
1304
1303
  this.platform.log.error(String(...log));
1305
1304
  }
1306
1305
  }
1306
+ debugErrorLog(...log) {
1307
+ if (this.enablingDeviceLogging()) {
1308
+ if (this.deviceLogging?.includes('debug')) {
1309
+ this.platform.log.error('[DEBUG]', String(...log));
1310
+ }
1311
+ }
1312
+ }
1307
1313
  debugLog(...log) {
1308
1314
  if (this.enablingDeviceLogging()) {
1309
1315
  if (this.deviceLogging === 'debug') {