@switchbot/homebridge-switchbot 1.3.1-beta.9 → 1.4.1-beta.2
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 +18 -2
- package/config.schema.json +82 -32
- package/dist/devices/bots.d.ts +15 -3
- package/dist/devices/bots.d.ts.map +1 -1
- package/dist/devices/bots.js +227 -165
- package/dist/devices/bots.js.map +1 -1
- package/dist/devices/colorbulb.d.ts +14 -3
- package/dist/devices/colorbulb.d.ts.map +1 -1
- package/dist/devices/colorbulb.js +163 -105
- package/dist/devices/colorbulb.js.map +1 -1
- package/dist/devices/contact.d.ts +13 -3
- package/dist/devices/contact.d.ts.map +1 -1
- package/dist/devices/contact.js +102 -63
- package/dist/devices/contact.js.map +1 -1
- package/dist/devices/curtains.d.ts +14 -5
- package/dist/devices/curtains.d.ts.map +1 -1
- package/dist/devices/curtains.js +180 -140
- package/dist/devices/curtains.js.map +1 -1
- package/dist/devices/humidifiers.d.ts +14 -3
- package/dist/devices/humidifiers.d.ts.map +1 -1
- package/dist/devices/humidifiers.js +173 -133
- package/dist/devices/humidifiers.js.map +1 -1
- package/dist/devices/meters.d.ts +17 -13
- package/dist/devices/meters.d.ts.map +1 -1
- package/dist/devices/meters.js +150 -105
- package/dist/devices/meters.js.map +1 -1
- package/dist/devices/motion.d.ts +13 -3
- package/dist/devices/motion.d.ts.map +1 -1
- package/dist/devices/motion.js +89 -45
- package/dist/devices/motion.js.map +1 -1
- package/dist/devices/plugs.d.ts +15 -3
- package/dist/devices/plugs.d.ts.map +1 -1
- package/dist/devices/plugs.js +115 -53
- package/dist/devices/plugs.js.map +1 -1
- package/dist/irdevices/airconditioners.d.ts +13 -3
- package/dist/irdevices/airconditioners.d.ts.map +1 -1
- package/dist/irdevices/airconditioners.js +97 -46
- package/dist/irdevices/airconditioners.js.map +1 -1
- package/dist/irdevices/airpurifiers.d.ts +13 -3
- package/dist/irdevices/airpurifiers.d.ts.map +1 -1
- package/dist/irdevices/airpurifiers.js +85 -31
- package/dist/irdevices/airpurifiers.js.map +1 -1
- package/dist/irdevices/cameras.d.ts +12 -3
- package/dist/irdevices/cameras.d.ts.map +1 -1
- package/dist/irdevices/cameras.js +73 -24
- package/dist/irdevices/cameras.js.map +1 -1
- package/dist/irdevices/fans.d.ts +12 -3
- package/dist/irdevices/fans.d.ts.map +1 -1
- package/dist/irdevices/fans.js +83 -35
- package/dist/irdevices/fans.js.map +1 -1
- package/dist/irdevices/lights.d.ts +12 -3
- package/dist/irdevices/lights.d.ts.map +1 -1
- package/dist/irdevices/lights.js +74 -25
- package/dist/irdevices/lights.js.map +1 -1
- package/dist/irdevices/others.d.ts +12 -3
- package/dist/irdevices/others.d.ts.map +1 -1
- package/dist/irdevices/others.js +80 -31
- package/dist/irdevices/others.js.map +1 -1
- package/dist/irdevices/tvs.d.ts +12 -3
- package/dist/irdevices/tvs.d.ts.map +1 -1
- package/dist/irdevices/tvs.js +90 -42
- package/dist/irdevices/tvs.js.map +1 -1
- package/dist/irdevices/vacuumcleaners.d.ts +12 -3
- package/dist/irdevices/vacuumcleaners.d.ts.map +1 -1
- package/dist/irdevices/vacuumcleaners.js +73 -24
- package/dist/irdevices/vacuumcleaners.js.map +1 -1
- package/dist/irdevices/waterheaters.d.ts +12 -3
- package/dist/irdevices/waterheaters.d.ts.map +1 -1
- package/dist/irdevices/waterheaters.js +73 -24
- package/dist/irdevices/waterheaters.js.map +1 -1
- package/dist/platform.d.ts +10 -10
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +290 -307
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +9 -6
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js.map +1 -1
- package/nodemon.json +1 -1
- package/package.json +6 -6
- package/src/devices/bots.ts +221 -152
- package/src/devices/colorbulb.ts +172 -108
- package/src/devices/contact.ts +109 -64
- package/src/devices/curtains.ts +190 -146
- package/src/devices/humidifiers.ts +181 -135
- package/src/devices/meters.ts +156 -105
- package/src/devices/motion.ts +95 -45
- package/src/devices/plugs.ts +121 -53
- package/src/irdevices/airconditioners.ts +102 -46
- package/src/irdevices/airpurifiers.ts +91 -31
- package/src/irdevices/cameras.ts +79 -24
- package/src/irdevices/fans.ts +89 -36
- package/src/irdevices/lights.ts +80 -25
- package/src/irdevices/others.ts +86 -31
- package/src/irdevices/tvs.ts +96 -42
- package/src/irdevices/vacuumcleaners.ts +79 -24
- package/src/irdevices/waterheaters.ts +79 -24
- package/src/platform.ts +285 -302
- package/src/settings.ts +10 -6
- package/dist/devices/indoorcam.d.ts +0 -64
- package/dist/devices/indoorcam.d.ts.map +0 -1
- package/dist/devices/indoorcam.js +0 -249
- package/dist/devices/indoorcam.js.map +0 -1
- package/src/devices/indoorcam.ts +0 -309
package/src/devices/bots.ts
CHANGED
|
@@ -4,7 +4,7 @@ import Switchbot from 'node-switchbot';
|
|
|
4
4
|
import { interval, Subject } from 'rxjs';
|
|
5
5
|
import { SwitchBotPlatform } from '../platform';
|
|
6
6
|
import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
|
|
7
|
-
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
7
|
+
import { Service, PlatformAccessory, CharacteristicValue, HAPStatus } from 'homebridge';
|
|
8
8
|
import { DeviceURL, device, devicesConfig, serviceData, ad, switchbot, deviceStatusResponse, payload } from '../settings';
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -20,6 +20,7 @@ export class Bot {
|
|
|
20
20
|
|
|
21
21
|
// Characteristic Values
|
|
22
22
|
On!: CharacteristicValue;
|
|
23
|
+
OnCached!: CharacteristicValue;
|
|
23
24
|
BatteryLevel!: CharacteristicValue;
|
|
24
25
|
StatusLowBattery!: CharacteristicValue;
|
|
25
26
|
|
|
@@ -35,8 +36,8 @@ export class Bot {
|
|
|
35
36
|
battery!: serviceData['battery'];
|
|
36
37
|
|
|
37
38
|
// Config
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
deviceLogging!: string;
|
|
40
|
+
deviceRefreshRate!: number;
|
|
40
41
|
|
|
41
42
|
// Updates
|
|
42
43
|
botUpdateInProgress!: boolean;
|
|
@@ -47,15 +48,21 @@ export class Bot {
|
|
|
47
48
|
private accessory: PlatformAccessory,
|
|
48
49
|
public device: device & devicesConfig,
|
|
49
50
|
) {
|
|
50
|
-
// Bot Config
|
|
51
|
-
this.platform.device(`Bot: ${this.accessory.displayName} Config: (ble: ${device.ble}, mode: ${device.bot?.mode},`
|
|
52
|
-
+ ` deviceType: ${device.bot?.deviceType})`);
|
|
53
|
-
|
|
54
51
|
// default placeholders
|
|
55
|
-
this.On
|
|
52
|
+
if (this.On === undefined) {
|
|
53
|
+
this.On = false;
|
|
54
|
+
} else {
|
|
55
|
+
this.On = this.accessory.context.On;
|
|
56
|
+
}
|
|
57
|
+
this.refreshRate();
|
|
58
|
+
this.logs();
|
|
56
59
|
this.BatteryLevel = 100;
|
|
57
60
|
this.StatusLowBattery = 1;
|
|
58
61
|
|
|
62
|
+
// Bot Config
|
|
63
|
+
this.debugLog(`Bot: ${this.accessory.displayName} Config: (ble: ${device.ble}, offline: ${device.offline}, mode: ${device.bot?.mode},`
|
|
64
|
+
+ ` deviceType: ${device.bot?.deviceType})`);
|
|
65
|
+
|
|
59
66
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
60
67
|
this.doBotUpdate = new Subject();
|
|
61
68
|
this.botUpdateInProgress = false;
|
|
@@ -75,7 +82,7 @@ export class Bot {
|
|
|
75
82
|
if (device.bot?.deviceType === 'switch') {
|
|
76
83
|
// If outletService still pressent, then remove first
|
|
77
84
|
if (this.outletService) {
|
|
78
|
-
this.
|
|
85
|
+
this.debugLog(`Bot: ${accessory.displayName} Removing Leftover outletService first`);
|
|
79
86
|
}
|
|
80
87
|
this.outletService = this.accessory.getService(this.platform.Service.Outlet);
|
|
81
88
|
accessory.removeService(this.outletService!);
|
|
@@ -84,13 +91,15 @@ export class Bot {
|
|
|
84
91
|
(this.switchService =
|
|
85
92
|
accessory.getService(this.platform.Service.Switch) ||
|
|
86
93
|
accessory.addService(this.platform.Service.Switch)), `${accessory.displayName} Switch`;
|
|
87
|
-
this.
|
|
94
|
+
if (this.deviceLogging !== 'none') {
|
|
95
|
+
this.infoLog(`Bot: ${accessory.displayName} Displaying as Switch`);
|
|
96
|
+
}
|
|
88
97
|
|
|
89
98
|
this.switchService?.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
|
|
90
99
|
} else {
|
|
91
100
|
// If switchService still pressent, then remove first
|
|
92
101
|
if (this.switchService) {
|
|
93
|
-
this.
|
|
102
|
+
this.debugLog(`Bot: ${accessory.displayName} Removing Leftover switchService first`);
|
|
94
103
|
}
|
|
95
104
|
this.switchService = this.accessory.getService(this.platform.Service.Switch);
|
|
96
105
|
accessory.removeService(this.switchService!);
|
|
@@ -99,7 +108,7 @@ export class Bot {
|
|
|
99
108
|
(this.outletService =
|
|
100
109
|
accessory.getService(this.platform.Service.Outlet) ||
|
|
101
110
|
accessory.addService(this.platform.Service.Outlet)), `${accessory.displayName} Outlet`;
|
|
102
|
-
this.
|
|
111
|
+
this.infoLog(`Bot: ${accessory.displayName} Displaying as Outlet`);
|
|
103
112
|
|
|
104
113
|
this.outletService?.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName);
|
|
105
114
|
}
|
|
@@ -125,7 +134,7 @@ export class Bot {
|
|
|
125
134
|
this.updateHomeKitCharacteristics();
|
|
126
135
|
|
|
127
136
|
// Start an update interval
|
|
128
|
-
interval(this.
|
|
137
|
+
interval(this.deviceRefreshRate * 1000)
|
|
129
138
|
.pipe(skipWhile(() => this.botUpdateInProgress))
|
|
130
139
|
.subscribe(() => {
|
|
131
140
|
this.refreshStatus();
|
|
@@ -144,13 +153,13 @@ export class Bot {
|
|
|
144
153
|
try {
|
|
145
154
|
await this.pushChanges();
|
|
146
155
|
} catch (e: any) {
|
|
147
|
-
this.
|
|
148
|
-
if (this.
|
|
149
|
-
this.
|
|
156
|
+
this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges`);
|
|
157
|
+
if (this.deviceLogging === 'debug') {
|
|
158
|
+
this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges,`
|
|
150
159
|
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
151
160
|
}
|
|
152
|
-
if (this.
|
|
153
|
-
this.
|
|
161
|
+
if (this.platform.debugMode) {
|
|
162
|
+
this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges,`
|
|
154
163
|
+ ` Error: ${JSON.stringify(e)}`);
|
|
155
164
|
}
|
|
156
165
|
}
|
|
@@ -158,6 +167,24 @@ export class Bot {
|
|
|
158
167
|
});
|
|
159
168
|
}
|
|
160
169
|
|
|
170
|
+
refreshRate() {
|
|
171
|
+
if (this.device.refreshRate) {
|
|
172
|
+
this.deviceRefreshRate = this.accessory.context.refreshRate = this.device.refreshRate;
|
|
173
|
+
} else if (this.platform.config.options!.refreshRate) {
|
|
174
|
+
this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
logs() {
|
|
179
|
+
if (this.device.logging) {
|
|
180
|
+
this.deviceLogging = this.accessory.context.logging = this.device.logging;
|
|
181
|
+
} else if (this.platform.config.options?.logging) {
|
|
182
|
+
this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
|
|
183
|
+
} else {
|
|
184
|
+
this.deviceLogging = this.accessory.context.logging = 'standard';
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
161
188
|
/**
|
|
162
189
|
* Parse the device status from the SwitchBot api
|
|
163
190
|
*/
|
|
@@ -170,13 +197,13 @@ export class Bot {
|
|
|
170
197
|
}
|
|
171
198
|
|
|
172
199
|
private async BLEparseStatus() {
|
|
173
|
-
this.
|
|
200
|
+
this.debugLog(`Bot: ${this.accessory.displayName} BLE parseStatus`);
|
|
174
201
|
// BLEmode (true if Switch Mode) | (false if Press Mode)
|
|
175
202
|
if (this.mode) {
|
|
176
203
|
this.On = Boolean(this.state);
|
|
177
|
-
this.
|
|
204
|
+
this.debugLog(`Bot: ${this.accessory.displayName} Switch Mode, mode: ${JSON.stringify(this.mode)}, On: ${JSON.stringify(this.On)}`);
|
|
178
205
|
} else {
|
|
179
|
-
this.
|
|
206
|
+
this.debugLog(`Bot: ${this.accessory.displayName} Press Mode, mode: ${JSON.stringify(this.mode)}, On: ${JSON.stringify(this.On)}`);
|
|
180
207
|
}
|
|
181
208
|
|
|
182
209
|
this.BatteryLevel = Number(this.battery);
|
|
@@ -188,12 +215,12 @@ export class Bot {
|
|
|
188
215
|
if (Number.isNaN(this.BatteryLevel)) {
|
|
189
216
|
this.BatteryLevel = 100;
|
|
190
217
|
}
|
|
191
|
-
this.
|
|
218
|
+
this.debugLog(`Bot: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
|
|
192
219
|
}
|
|
193
220
|
|
|
194
221
|
private async openAPIparseStatus() {
|
|
195
222
|
if (this.platform.config.credentials?.openToken) {
|
|
196
|
-
this.
|
|
223
|
+
this.debugLog(`Bot: ${this.accessory.displayName} OpenAPI parseStatus`);
|
|
197
224
|
if (this.device.bot?.mode === 'press') {
|
|
198
225
|
this.On = false;
|
|
199
226
|
} else {
|
|
@@ -203,7 +230,7 @@ export class Bot {
|
|
|
203
230
|
this.On = false;
|
|
204
231
|
}
|
|
205
232
|
}
|
|
206
|
-
this.
|
|
233
|
+
this.debugLog(`Bot ${this.accessory.displayName} On: ${this.On}`);
|
|
207
234
|
}
|
|
208
235
|
}
|
|
209
236
|
|
|
@@ -221,12 +248,12 @@ export class Bot {
|
|
|
221
248
|
private connectBLE() {
|
|
222
249
|
const switchbot = new Switchbot();
|
|
223
250
|
this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
|
|
224
|
-
this.
|
|
251
|
+
this.debugLog(`Bot: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
225
252
|
return switchbot;
|
|
226
253
|
}
|
|
227
254
|
|
|
228
255
|
private async BLERefreshStatus() {
|
|
229
|
-
this.
|
|
256
|
+
this.debugLog(`Bot: ${this.accessory.displayName} BLE refreshStatus`);
|
|
230
257
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
231
258
|
const switchbot = this.connectBLE();
|
|
232
259
|
// Start to monitor advertisement packets
|
|
@@ -240,16 +267,16 @@ export class Bot {
|
|
|
240
267
|
this.mode = ad.serviceData.mode;
|
|
241
268
|
this.state = ad.serviceData.state;
|
|
242
269
|
this.battery = ad.serviceData.battery;
|
|
243
|
-
this.
|
|
244
|
-
this.
|
|
270
|
+
this.debugLog(`Bot: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
271
|
+
this.debugLog(`Bot: ${this.accessory.displayName}, model: ${ad.serviceData.model}, modelName: ${ad.serviceData.modelName},`
|
|
245
272
|
+ ` mode: ${ad.serviceData.mode}, state: ${ad.serviceData.state}, battery: ${ad.serviceData.battery}`);
|
|
246
273
|
|
|
247
274
|
if (this.serviceData) {
|
|
248
275
|
this.connected = true;
|
|
249
|
-
this.
|
|
276
|
+
this.debugLog(`Bot: ${this.accessory.displayName} connected: ${this.connected}`);
|
|
250
277
|
} else {
|
|
251
278
|
this.connected = false;
|
|
252
|
-
this.
|
|
279
|
+
this.debugLog(`Bot: ${this.accessory.displayName} connected: ${this.connected}`);
|
|
253
280
|
}
|
|
254
281
|
};
|
|
255
282
|
// Wait 10 seconds
|
|
@@ -261,36 +288,36 @@ export class Bot {
|
|
|
261
288
|
this.parseStatus();
|
|
262
289
|
this.updateHomeKitCharacteristics();
|
|
263
290
|
} else {
|
|
264
|
-
this.
|
|
291
|
+
this.errorLog(`Bot: ${this.accessory.displayName} wasn't able to establish BLE Connection`);
|
|
265
292
|
if (this.platform.config.credentials?.openToken) {
|
|
266
|
-
this.
|
|
293
|
+
this.warnLog(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
267
294
|
await this.openAPIRefreshStatus();
|
|
268
295
|
}
|
|
269
296
|
}
|
|
270
297
|
}).catch(async (e: any) => {
|
|
271
|
-
this.
|
|
272
|
-
if (this.
|
|
273
|
-
this.
|
|
298
|
+
this.errorLog(`Bot: ${this.accessory.displayName} failed refreshStatus with BLE Connection`);
|
|
299
|
+
if (this.deviceLogging === 'debug') {
|
|
300
|
+
this.errorLog(`Bot: ${this.accessory.displayName} failed refreshStatus with BLE Connection,`
|
|
274
301
|
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
275
302
|
}
|
|
276
|
-
if (this.
|
|
277
|
-
this.
|
|
303
|
+
if (this.platform.debugMode) {
|
|
304
|
+
this.errorLog(`Bot: ${this.accessory.displayName} failed refreshStatus with BLE Connection,`
|
|
278
305
|
+ ` Error: ${JSON.stringify(e)}`);
|
|
279
306
|
}
|
|
280
307
|
if (this.platform.config.credentials?.openToken) {
|
|
281
|
-
this.
|
|
308
|
+
this.warnLog(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
282
309
|
await this.openAPIRefreshStatus();
|
|
283
310
|
}
|
|
284
|
-
this.apiError(
|
|
311
|
+
this.apiError();
|
|
285
312
|
});
|
|
286
313
|
}
|
|
287
314
|
|
|
288
315
|
private async openAPIRefreshStatus() {
|
|
289
316
|
if (this.platform.config.credentials?.openToken) {
|
|
290
|
-
this.
|
|
317
|
+
this.debugLog(`Bot: ${this.accessory.displayName} OpenAPI refreshStatus`);
|
|
291
318
|
try {
|
|
292
319
|
this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
|
|
293
|
-
this.
|
|
320
|
+
this.debugLog(`Bot: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
294
321
|
/*this.deviceStatus = {
|
|
295
322
|
statusCode: 100,
|
|
296
323
|
body: {
|
|
@@ -304,16 +331,16 @@ export class Bot {
|
|
|
304
331
|
this.parseStatus();
|
|
305
332
|
this.updateHomeKitCharacteristics();
|
|
306
333
|
} catch (e: any) {
|
|
307
|
-
this.
|
|
308
|
-
if (this.
|
|
309
|
-
this.
|
|
334
|
+
this.errorLog(`Bot: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
|
|
335
|
+
if (this.deviceLogging === 'debug') {
|
|
336
|
+
this.errorLog(`Bot: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,`
|
|
310
337
|
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
311
338
|
}
|
|
312
|
-
if (this.
|
|
313
|
-
this.
|
|
339
|
+
if (this.platform.debugMode) {
|
|
340
|
+
this.errorLog(`Bot: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,`
|
|
314
341
|
+ ` Error: ${JSON.stringify(e)}`);
|
|
315
342
|
}
|
|
316
|
-
this.apiError(
|
|
343
|
+
this.apiError();
|
|
317
344
|
}
|
|
318
345
|
}
|
|
319
346
|
}
|
|
@@ -340,58 +367,62 @@ export class Bot {
|
|
|
340
367
|
}
|
|
341
368
|
|
|
342
369
|
private async BLEpushChanges() {
|
|
343
|
-
this.
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
.
|
|
349
|
-
|
|
350
|
-
|
|
370
|
+
if (this.On !== this.OnCached) {
|
|
371
|
+
this.debugLog(`Bot: ${this.accessory.displayName} BLE pushChanges`);
|
|
372
|
+
const switchbot = this.connectBLE();
|
|
373
|
+
if (this.device.bot?.mode === 'press') {
|
|
374
|
+
this.debugLog(`Bot: ${this.accessory.displayName} Press Mode: ${this.device.bot?.mode}`);
|
|
375
|
+
switchbot.discover({ model: 'H', quick: true, id: this.device.bleMac })
|
|
376
|
+
.then((device_list: { press: (arg0: { id: string | undefined; }) => any; }[]) => {
|
|
377
|
+
this.infoLog(`Bot: ${this.accessory.displayName}, On: ${this.On}`);
|
|
378
|
+
return device_list[0].press({ id: this.device.bleMac });
|
|
379
|
+
}).then(() => {
|
|
380
|
+
this.debugLog(`Bot: ${this.accessory.displayName} Done.`);
|
|
381
|
+
}).catch(async (e: any) => {
|
|
382
|
+
this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection`);
|
|
383
|
+
if (this.deviceLogging === 'debug') {
|
|
384
|
+
this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection,`
|
|
385
|
+
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
386
|
+
}
|
|
387
|
+
if (this.platform.debugMode) {
|
|
388
|
+
this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection,`
|
|
389
|
+
+ ` Error: ${JSON.stringify(e)}`);
|
|
390
|
+
}
|
|
391
|
+
if (this.platform.config.credentials?.openToken) {
|
|
392
|
+
this.warnLog(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
393
|
+
await this.openAPIpushChanges();
|
|
394
|
+
}
|
|
395
|
+
this.apiError();
|
|
396
|
+
});
|
|
397
|
+
} else if (this.device.bot?.mode === 'switch') {
|
|
398
|
+
this.debugLog(`Bot: ${this.accessory.displayName} Press Mode: ${this.device.bot?.mode}`);
|
|
399
|
+
switchbot.discover({ model: 'H', quick: true, id: this.device.bleMac }).then((device_list: any) => {
|
|
400
|
+
this.infoLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
|
|
401
|
+
return this.turnOnOff(device_list);
|
|
351
402
|
}).then(() => {
|
|
352
|
-
this.
|
|
403
|
+
this.debugLog(`Bot: ${this.accessory.displayName} Done.`);
|
|
353
404
|
}).catch(async (e: any) => {
|
|
354
|
-
this.
|
|
355
|
-
if (this.
|
|
356
|
-
this.
|
|
405
|
+
this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection`);
|
|
406
|
+
if (this.deviceLogging === 'debug') {
|
|
407
|
+
this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection,`
|
|
357
408
|
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
358
409
|
}
|
|
359
|
-
if (this.
|
|
360
|
-
this.
|
|
410
|
+
if (this.platform.debugMode) {
|
|
411
|
+
this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection,`
|
|
361
412
|
+ ` Error: ${JSON.stringify(e)}`);
|
|
362
413
|
}
|
|
363
414
|
if (this.platform.config.credentials?.openToken) {
|
|
364
|
-
this.
|
|
415
|
+
this.warnLog(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
365
416
|
await this.openAPIpushChanges();
|
|
366
417
|
}
|
|
367
|
-
this.apiError(
|
|
418
|
+
this.apiError();
|
|
368
419
|
});
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
this.platform.log.info(`Bot: ${this.accessory.displayName} On: ${this.On}`);
|
|
373
|
-
return this.turnOnOff(device_list);
|
|
374
|
-
}).then(() => {
|
|
375
|
-
this.platform.device(`Bot: ${this.accessory.displayName} Done.`);
|
|
376
|
-
}).catch(async (e: any) => {
|
|
377
|
-
this.platform.log.error(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection`);
|
|
378
|
-
if (this.deviceDebug) {
|
|
379
|
-
this.platform.log.error(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection,`
|
|
380
|
-
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
381
|
-
}
|
|
382
|
-
if (this.debugDebug) {
|
|
383
|
-
this.platform.log.error(`Bot: ${this.accessory.displayName} failed pushChanges with BLE Connection,`
|
|
384
|
-
+ ` Error: ${JSON.stringify(e)}`);
|
|
385
|
-
}
|
|
386
|
-
if (this.platform.config.credentials?.openToken) {
|
|
387
|
-
this.platform.log.warn(`Bot: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
388
|
-
await this.openAPIpushChanges();
|
|
389
|
-
}
|
|
390
|
-
this.apiError(e);
|
|
391
|
-
});
|
|
392
|
-
} else {
|
|
393
|
-
this.platform.log.error(`Bot: ${this.accessory.displayName} Mode Not Set, mode: ${this.device.bot?.mode}`);
|
|
420
|
+
} else {
|
|
421
|
+
this.errorLog(`Bot: ${this.accessory.displayName} Mode Not Set, mode: ${this.device.bot?.mode}`);
|
|
422
|
+
}
|
|
394
423
|
}
|
|
424
|
+
this.OnCached = this.On;
|
|
425
|
+
this.accessory.context.On = this.OnCached;
|
|
395
426
|
}
|
|
396
427
|
|
|
397
428
|
private turnOnOff(device_list: any) {
|
|
@@ -405,46 +436,50 @@ export class Bot {
|
|
|
405
436
|
private async openAPIpushChanges() {
|
|
406
437
|
if (this.platform.config.credentials?.openToken) {
|
|
407
438
|
try {
|
|
408
|
-
this.
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
439
|
+
if (this.On !== this.OnCached) {
|
|
440
|
+
this.debugLog(`Bot: ${this.accessory.displayName} OpenAPI pushChanges`);
|
|
441
|
+
const payload = {
|
|
442
|
+
commandType: 'command',
|
|
443
|
+
parameter: 'default',
|
|
444
|
+
} as payload;
|
|
445
|
+
|
|
446
|
+
if (this.device.bot?.mode === 'switch' && this.On) {
|
|
447
|
+
payload.command = 'turnOn';
|
|
448
|
+
this.On = true;
|
|
449
|
+
this.debugLog(`Bot: ${this.accessory.displayName} Switch Mode, Turning ${this.On}`);
|
|
450
|
+
} else if (this.device.bot?.mode === 'switch' && !this.On) {
|
|
451
|
+
payload.command = 'turnOff';
|
|
452
|
+
this.On = false;
|
|
453
|
+
this.debugLog(`Bot: ${this.accessory.displayName} Switch Mode, Turning ${this.On}`);
|
|
454
|
+
} else if (this.device.bot?.mode === 'press') {
|
|
455
|
+
payload.command = 'press';
|
|
456
|
+
this.debugLog(`Bot: ${this.accessory.displayName} Press Mode`);
|
|
457
|
+
this.On = false;
|
|
458
|
+
} else {
|
|
459
|
+
throw new Error(`Bot: ${this.accessory.displayName} Device Paramters not set for this Bot.`);
|
|
460
|
+
}
|
|
429
461
|
|
|
430
|
-
|
|
431
|
-
|
|
462
|
+
this.infoLog(`Bot: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},`
|
|
463
|
+
+ ` parameter: ${payload.parameter}, commandType: ${payload.commandType}`);
|
|
432
464
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
465
|
+
// Make the API request
|
|
466
|
+
const push: any = (await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload));
|
|
467
|
+
this.debugLog(`Bot ${this.accessory.displayName} pushchanges: ${JSON.stringify(push.data)}`);
|
|
468
|
+
this.statusCode(push);
|
|
469
|
+
this.OnCached = this.On;
|
|
470
|
+
this.accessory.context.On = this.OnCached;
|
|
471
|
+
}
|
|
437
472
|
} catch (e: any) {
|
|
438
|
-
this.
|
|
439
|
-
if (this.
|
|
440
|
-
this.
|
|
473
|
+
this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection`);
|
|
474
|
+
if (this.deviceLogging === 'debug') {
|
|
475
|
+
this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
|
|
441
476
|
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
442
477
|
}
|
|
443
|
-
if (this.
|
|
444
|
-
this.
|
|
478
|
+
if (this.platform.debugMode) {
|
|
479
|
+
this.errorLog(`Bot: ${this.accessory.displayName} failed pushChanges with OpenAPI Connection,`
|
|
445
480
|
+ ` Error: ${JSON.stringify(e)}`);
|
|
446
481
|
}
|
|
447
|
-
this.apiError(
|
|
482
|
+
this.apiError();
|
|
448
483
|
}
|
|
449
484
|
}
|
|
450
485
|
}
|
|
@@ -454,75 +489,74 @@ export class Bot {
|
|
|
454
489
|
*/
|
|
455
490
|
updateHomeKitCharacteristics() {
|
|
456
491
|
if (this.On === undefined) {
|
|
457
|
-
this.
|
|
492
|
+
this.debugLog(`Bot: ${this.accessory.displayName} On: ${this.On}`);
|
|
458
493
|
} else {
|
|
459
494
|
if (this.device.bot?.deviceType === 'switch') {
|
|
460
495
|
this.switchService?.updateCharacteristic(this.platform.Characteristic.On, this.On);
|
|
461
496
|
} else {
|
|
462
497
|
this.outletService?.updateCharacteristic(this.platform.Characteristic.On, this.On);
|
|
463
498
|
}
|
|
464
|
-
this.
|
|
499
|
+
this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic On: ${this.On}`);
|
|
465
500
|
}
|
|
466
501
|
if (this.device.ble) {
|
|
467
502
|
if (this.BatteryLevel === undefined) {
|
|
468
|
-
this.
|
|
503
|
+
this.debugLog(`Bot: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}`);
|
|
469
504
|
} else {
|
|
470
505
|
this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, this.BatteryLevel);
|
|
471
|
-
this.
|
|
506
|
+
this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic BatteryLevel: ${this.BatteryLevel}`);
|
|
472
507
|
}
|
|
473
508
|
if (this.StatusLowBattery === undefined) {
|
|
474
|
-
this.
|
|
509
|
+
this.debugLog(`Bot: ${this.accessory.displayName} StatusLowBattery: ${this.StatusLowBattery}`);
|
|
475
510
|
} else {
|
|
476
511
|
this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.StatusLowBattery);
|
|
477
|
-
this.
|
|
512
|
+
this.debugLog(`Bot: ${this.accessory.displayName} updateCharacteristic StatusLowBattery: ${this.StatusLowBattery}`);
|
|
478
513
|
}
|
|
479
514
|
}
|
|
480
515
|
}
|
|
481
516
|
|
|
482
|
-
public apiError(
|
|
483
|
-
|
|
484
|
-
this.switchService?.updateCharacteristic(this.platform.Characteristic.On, e);
|
|
485
|
-
} else {
|
|
486
|
-
this.outletService?.updateCharacteristic(this.platform.Characteristic.On, e);
|
|
487
|
-
}
|
|
488
|
-
if (this.device.ble) {
|
|
489
|
-
this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
|
|
490
|
-
this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
|
|
491
|
-
}
|
|
517
|
+
public apiError() {
|
|
518
|
+
throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
492
519
|
}
|
|
493
520
|
|
|
494
521
|
private statusCode(push: AxiosResponse<{ statusCode: number; }>) {
|
|
495
522
|
switch (push.data.statusCode) {
|
|
496
523
|
case 151:
|
|
497
|
-
this.
|
|
524
|
+
this.errorLog(`Bot: ${this.accessory.displayName} Command not supported by this device type.`);
|
|
498
525
|
break;
|
|
499
526
|
case 152:
|
|
500
|
-
this.
|
|
527
|
+
this.errorLog(`Bot: ${this.accessory.displayName} Device not found.`);
|
|
501
528
|
break;
|
|
502
529
|
case 160:
|
|
503
|
-
this.
|
|
530
|
+
this.errorLog(`Bot: ${this.accessory.displayName} Command is not supported.`);
|
|
504
531
|
break;
|
|
505
532
|
case 161:
|
|
506
|
-
this.
|
|
507
|
-
|
|
508
|
-
this.On = false;
|
|
509
|
-
}
|
|
533
|
+
this.errorLog(`Bot: ${this.accessory.displayName} Device is offline.`);
|
|
534
|
+
this.offlineOff();
|
|
510
535
|
break;
|
|
511
536
|
case 171:
|
|
512
|
-
this.
|
|
513
|
-
|
|
514
|
-
this.On = false;
|
|
515
|
-
}
|
|
537
|
+
this.errorLog(`Bot: ${this.accessory.displayName} Hub Device is offline. Hub: ${this.device.hubDeviceId}`);
|
|
538
|
+
this.offlineOff();
|
|
516
539
|
break;
|
|
517
540
|
case 190:
|
|
518
|
-
this.
|
|
541
|
+
this.errorLog(`Bot: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,`
|
|
519
542
|
+ ` Or command: ${JSON.stringify(push.data)} format is invalid`);
|
|
520
543
|
break;
|
|
521
544
|
case 100:
|
|
522
|
-
this.
|
|
545
|
+
this.debugLog(`Bot: ${this.accessory.displayName} Command successfully sent.`);
|
|
523
546
|
break;
|
|
524
547
|
default:
|
|
525
|
-
this.
|
|
548
|
+
this.debugLog(`Bot: ${this.accessory.displayName} Unknown statusCode.`);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
private offlineOff() {
|
|
553
|
+
if (this.device.offline) {
|
|
554
|
+
this.On = false;
|
|
555
|
+
if (this.device.bot?.deviceType === 'switch') {
|
|
556
|
+
this.switchService?.getCharacteristic(this.platform.Characteristic.On).updateValue(this.On);
|
|
557
|
+
} else {
|
|
558
|
+
this.outletService?.getCharacteristic(this.platform.Characteristic.On).updateValue(this.On);
|
|
559
|
+
}
|
|
526
560
|
}
|
|
527
561
|
}
|
|
528
562
|
|
|
@@ -530,8 +564,43 @@ export class Bot {
|
|
|
530
564
|
* Handle requests to set the "On" characteristic
|
|
531
565
|
*/
|
|
532
566
|
private handleOnSet(value: CharacteristicValue) {
|
|
533
|
-
this.
|
|
567
|
+
this.debugLog(`Bot: ${this.accessory.displayName} On: ${value}`);
|
|
534
568
|
this.On = value;
|
|
535
569
|
this.doBotUpdate.next();
|
|
536
570
|
}
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* Logging for Device
|
|
574
|
+
*/
|
|
575
|
+
infoLog(...log: any[]) {
|
|
576
|
+
if (this.enablingDeviceLogging()) {
|
|
577
|
+
this.platform.log.info(String(...log));
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
warnLog(...log: any[]) {
|
|
582
|
+
if (this.enablingDeviceLogging()) {
|
|
583
|
+
this.platform.log.warn(String(...log));
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
errorLog(...log: any[]) {
|
|
588
|
+
if (this.enablingDeviceLogging()) {
|
|
589
|
+
this.platform.log.error(String(...log));
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
debugLog(...log: any[]) {
|
|
594
|
+
if (this.enablingDeviceLogging()) {
|
|
595
|
+
if (this.deviceLogging === 'debug') {
|
|
596
|
+
this.platform.log.info('[DEBUG]', String(...log));
|
|
597
|
+
} else {
|
|
598
|
+
this.platform.log.debug(String(...log));
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
enablingDeviceLogging(): boolean {
|
|
604
|
+
return this.deviceLogging === 'debug' || this.deviceLogging === 'standard';
|
|
605
|
+
}
|
|
537
606
|
}
|