@switchbot/homebridge-switchbot 2.0.0-beta.2 → 2.0.0-beta.21

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