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