@switchbot/homebridge-switchbot 2.6.0-beta.4 → 2.6.0
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/.vscode/tasks.json +13 -0
- package/CHANGELOG.md +4 -2
- package/README.md +18 -9
- package/dist/device/blindtilt.d.ts +1 -5
- package/dist/device/blindtilt.d.ts.map +1 -1
- package/dist/device/blindtilt.js +80 -140
- package/dist/device/blindtilt.js.map +1 -1
- package/dist/device/bot.d.ts +1 -5
- package/dist/device/bot.d.ts.map +1 -1
- package/dist/device/bot.js +79 -138
- package/dist/device/bot.js.map +1 -1
- package/dist/device/ceilinglight.d.ts +2 -6
- package/dist/device/ceilinglight.d.ts.map +1 -1
- package/dist/device/ceilinglight.js +157 -304
- package/dist/device/ceilinglight.js.map +1 -1
- package/dist/device/colorbulb.d.ts +2 -6
- package/dist/device/colorbulb.d.ts.map +1 -1
- package/dist/device/colorbulb.js +164 -311
- package/dist/device/colorbulb.js.map +1 -1
- package/dist/device/contact.d.ts +1 -5
- package/dist/device/contact.d.ts.map +1 -1
- package/dist/device/contact.js +36 -72
- package/dist/device/contact.js.map +1 -1
- package/dist/device/curtain.d.ts +1 -5
- package/dist/device/curtain.d.ts.map +1 -1
- package/dist/device/curtain.js +78 -138
- package/dist/device/curtain.js.map +1 -1
- package/dist/device/hub.d.ts +2 -6
- package/dist/device/hub.d.ts.map +1 -1
- package/dist/device/hub.js +30 -63
- package/dist/device/hub.js.map +1 -1
- package/dist/device/humidifier.d.ts +1 -5
- package/dist/device/humidifier.d.ts.map +1 -1
- package/dist/device/humidifier.js +115 -228
- package/dist/device/humidifier.js.map +1 -1
- package/dist/device/iosensor.d.ts +1 -5
- package/dist/device/iosensor.d.ts.map +1 -1
- package/dist/device/iosensor.js +38 -74
- package/dist/device/iosensor.js.map +1 -1
- package/dist/device/{striplight.d.ts → lightstrip.d.ts} +2 -10
- package/dist/device/lightstrip.d.ts.map +1 -0
- package/dist/device/{striplight.js → lightstrip.js} +138 -194
- package/dist/device/lightstrip.js.map +1 -0
- package/dist/device/lock.d.ts +1 -5
- package/dist/device/lock.d.ts.map +1 -1
- package/dist/device/lock.js +66 -126
- package/dist/device/lock.js.map +1 -1
- package/dist/device/meter.d.ts +1 -5
- package/dist/device/meter.d.ts.map +1 -1
- package/dist/device/meter.js +38 -74
- package/dist/device/meter.js.map +1 -1
- package/dist/device/meterplus.d.ts +1 -5
- package/dist/device/meterplus.d.ts.map +1 -1
- package/dist/device/meterplus.js +39 -75
- package/dist/device/meterplus.js.map +1 -1
- package/dist/device/motion.d.ts +1 -5
- package/dist/device/motion.d.ts.map +1 -1
- package/dist/device/motion.js +35 -72
- package/dist/device/motion.js.map +1 -1
- package/dist/device/plug.d.ts +1 -5
- package/dist/device/plug.d.ts.map +1 -1
- package/dist/device/plug.js +65 -126
- package/dist/device/plug.js.map +1 -1
- package/dist/device/robotvacuumcleaner.d.ts +1 -5
- package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
- package/dist/device/robotvacuumcleaner.js +79 -151
- package/dist/device/robotvacuumcleaner.js.map +1 -1
- package/dist/irdevice/airconditioner.d.ts +3 -7
- package/dist/irdevice/airconditioner.d.ts.map +1 -1
- package/dist/irdevice/airconditioner.js +34 -62
- package/dist/irdevice/airconditioner.js.map +1 -1
- package/dist/irdevice/airpurifier.d.ts +3 -7
- package/dist/irdevice/airpurifier.d.ts.map +1 -1
- package/dist/irdevice/airpurifier.js +31 -59
- package/dist/irdevice/airpurifier.js.map +1 -1
- package/dist/irdevice/camera.d.ts +1 -5
- package/dist/irdevice/camera.d.ts.map +1 -1
- package/dist/irdevice/camera.js +30 -57
- package/dist/irdevice/camera.js.map +1 -1
- package/dist/irdevice/fan.d.ts +2 -6
- package/dist/irdevice/fan.d.ts.map +1 -1
- package/dist/irdevice/fan.js +39 -66
- package/dist/irdevice/fan.js.map +1 -1
- package/dist/irdevice/light.d.ts +1 -5
- package/dist/irdevice/light.d.ts.map +1 -1
- package/dist/irdevice/light.js +32 -59
- package/dist/irdevice/light.js.map +1 -1
- package/dist/irdevice/other.d.ts +1 -5
- package/dist/irdevice/other.d.ts.map +1 -1
- package/dist/irdevice/other.js +30 -57
- package/dist/irdevice/other.js.map +1 -1
- package/dist/irdevice/tv.d.ts +3 -7
- package/dist/irdevice/tv.d.ts.map +1 -1
- package/dist/irdevice/tv.js +46 -76
- package/dist/irdevice/tv.js.map +1 -1
- package/dist/irdevice/vacuumcleaner.d.ts +2 -6
- package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
- package/dist/irdevice/vacuumcleaner.js +30 -58
- package/dist/irdevice/vacuumcleaner.js.map +1 -1
- package/dist/irdevice/waterheater.d.ts +7 -23
- package/dist/irdevice/waterheater.d.ts.map +1 -1
- package/dist/irdevice/waterheater.js +41 -74
- package/dist/irdevice/waterheater.js.map +1 -1
- package/dist/platform.d.ts +14 -5
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +156 -149
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +4 -0
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +5 -1
- package/dist/settings.js.map +1 -1
- package/nodemon.json +1 -1
- package/package.json +10 -10
- package/src/device/blindtilt.ts +122 -181
- package/src/device/bot.ts +96 -149
- package/src/device/ceilinglight.ts +172 -315
- package/src/device/colorbulb.ts +178 -324
- package/src/device/contact.ts +48 -78
- package/src/device/curtain.ts +93 -148
- package/src/device/hub.ts +34 -63
- package/src/device/humidifier.ts +135 -243
- package/src/device/iosensor.ts +49 -79
- package/src/device/{striplight.ts → lightstrip.ts} +148 -200
- package/src/device/lock.ts +78 -134
- package/src/device/meter.ts +48 -78
- package/src/device/meterplus.ts +50 -80
- package/src/device/motion.ts +46 -77
- package/src/device/plug.ts +76 -134
- package/src/device/robotvacuumcleaner.ts +91 -159
- package/src/irdevice/airconditioner.ts +56 -81
- package/src/irdevice/airpurifier.ts +41 -67
- package/src/irdevice/camera.ts +35 -60
- package/src/irdevice/fan.ts +46 -71
- package/src/irdevice/light.ts +38 -63
- package/src/irdevice/other.ts +35 -60
- package/src/irdevice/tv.ts +52 -80
- package/src/irdevice/vacuumcleaner.ts +36 -62
- package/src/irdevice/waterheater.ts +46 -76
- package/src/platform.ts +144 -158
- package/src/settings.ts +5 -0
- package/.github/npm-version-script.js +0 -81
- package/dist/device/striplight.d.ts.map +0 -1
- package/dist/device/striplight.js.map +0 -1
package/src/device/lock.ts
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import https from 'https';
|
|
2
|
-
import crypto from 'crypto';
|
|
3
1
|
import { Context } from 'vm';
|
|
4
|
-
import {
|
|
2
|
+
import { request } from 'undici';
|
|
3
|
+
import { sleep } from '../utils';
|
|
5
4
|
import { interval, Subject } from 'rxjs';
|
|
6
|
-
import superStringify from 'super-stringify';
|
|
7
5
|
import { SwitchBotPlatform } from '../platform';
|
|
8
6
|
import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
|
|
9
7
|
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
10
|
-
import { device, devicesConfig, deviceStatus,
|
|
11
|
-
import { sleep } from '../utils';
|
|
8
|
+
import { device, devicesConfig, deviceStatus, switchbot, ad, serviceData, Devices } from '../settings';
|
|
12
9
|
|
|
13
10
|
export class Lock {
|
|
14
11
|
// Services
|
|
@@ -144,7 +141,7 @@ export class Lock {
|
|
|
144
141
|
} catch (e: any) {
|
|
145
142
|
this.apiError(e);
|
|
146
143
|
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,`
|
|
147
|
-
|
|
144
|
+
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
148
145
|
}
|
|
149
146
|
this.lockUpdateInProgress = false;
|
|
150
147
|
});
|
|
@@ -163,7 +160,7 @@ export class Lock {
|
|
|
163
160
|
} else {
|
|
164
161
|
await this.offlineOff();
|
|
165
162
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
166
|
-
|
|
163
|
+
+ ` ${this.device.connectionType}, parseStatus will not happen.`);
|
|
167
164
|
}
|
|
168
165
|
}
|
|
169
166
|
|
|
@@ -222,7 +219,7 @@ export class Lock {
|
|
|
222
219
|
} else {
|
|
223
220
|
await this.offlineOff();
|
|
224
221
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
225
|
-
|
|
222
|
+
+ ` ${this.device.connectionType}, refreshStatus will not happen.`);
|
|
226
223
|
}
|
|
227
224
|
}
|
|
228
225
|
|
|
@@ -248,7 +245,7 @@ export class Lock {
|
|
|
248
245
|
switchbot.onadvertisement = async (ad: any) => {
|
|
249
246
|
this.address = ad.address;
|
|
250
247
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},`
|
|
251
|
-
|
|
248
|
+
+ ` BLE Address Found: ${this.address}`);
|
|
252
249
|
this.serviceData = ad.serviceData;
|
|
253
250
|
this.battery = ad.serviceData.battery;
|
|
254
251
|
this.calibration = ad.serviceData.calibration;
|
|
@@ -259,11 +256,11 @@ export class Lock {
|
|
|
259
256
|
this.unclosed_alarm = ad.serviceData.unclosed_alarm;
|
|
260
257
|
this.unlocked_alarm = ad.serviceData.unlocked_alarm;
|
|
261
258
|
this.auto_lock_paused = ad.serviceData.auto_lock_paused;
|
|
262
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${
|
|
259
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
263
260
|
this.debugLog(
|
|
264
261
|
`${this.device.deviceType}: ${this.accessory.displayName} battery: ${ad.serviceData.battery}, ` +
|
|
265
|
-
|
|
266
|
-
|
|
262
|
+
`calibration: ${ad.serviceData.calibration}, status: ${ad.serviceData.status}, battery: ${ad.serviceData.battery}, ` +
|
|
263
|
+
`door_open: ${ad.serviceData.door_open}`);
|
|
267
264
|
|
|
268
265
|
if (this.serviceData) {
|
|
269
266
|
this.connected = true;
|
|
@@ -284,7 +281,7 @@ export class Lock {
|
|
|
284
281
|
.catch(async (e: any) => {
|
|
285
282
|
this.apiError(e);
|
|
286
283
|
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}`
|
|
287
|
-
|
|
284
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
288
285
|
await this.BLERefreshConnection(switchbot);
|
|
289
286
|
});
|
|
290
287
|
} else {
|
|
@@ -295,53 +292,25 @@ export class Lock {
|
|
|
295
292
|
async openAPIRefreshStatus(): Promise<void> {
|
|
296
293
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
|
|
297
294
|
try {
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
const data = this.platform.config.credentials?.token + t + nonce;
|
|
301
|
-
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
302
|
-
const sign = signTerm.toString('base64');
|
|
303
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
|
|
304
|
-
const options = {
|
|
305
|
-
hostname: HostDomain,
|
|
306
|
-
port: 443,
|
|
307
|
-
path: `${DevicePath}/${this.device.deviceId}/status`,
|
|
308
|
-
method: 'GET',
|
|
309
|
-
headers: {
|
|
310
|
-
Authorization: this.platform.config.credentials?.token,
|
|
311
|
-
sign: sign,
|
|
312
|
-
nonce: nonce,
|
|
313
|
-
t: t,
|
|
314
|
-
'Content-Type': 'application/json',
|
|
315
|
-
},
|
|
316
|
-
};
|
|
317
|
-
const req = https.request(options, (res) => {
|
|
318
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus statusCode: ${res.statusCode}`);
|
|
319
|
-
let rawData = '';
|
|
320
|
-
res.on('data', (d) => {
|
|
321
|
-
rawData += d;
|
|
322
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
|
|
323
|
-
});
|
|
324
|
-
res.on('end', () => {
|
|
325
|
-
try {
|
|
326
|
-
this.deviceStatus = JSON.parse(rawData);
|
|
327
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus: ${superStringify(this.deviceStatus)}`);
|
|
328
|
-
this.lockState = this.deviceStatus.body.lockState;
|
|
329
|
-
this.doorState = this.deviceStatus.body.doorState;
|
|
330
|
-
this.openAPIparseStatus();
|
|
331
|
-
this.updateHomeKitCharacteristics();
|
|
332
|
-
} catch (e: any) {
|
|
333
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
334
|
-
}
|
|
335
|
-
});
|
|
336
|
-
});
|
|
337
|
-
req.on('error', (e: any) => {
|
|
338
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
295
|
+
const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/status`, {
|
|
296
|
+
headers: this.platform.generateHeaders(),
|
|
339
297
|
});
|
|
340
|
-
|
|
298
|
+
const deviceStatus = await body.json();
|
|
299
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Devices: ${JSON.stringify(deviceStatus.body)}`);
|
|
300
|
+
this.statusCode(statusCode);
|
|
301
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Headers: ${JSON.stringify(headers)}`);
|
|
302
|
+
this.debugLog(
|
|
303
|
+
`${this.device.deviceType}: ${this.accessory.displayName
|
|
304
|
+
} refreshStatus: ${JSON.stringify(deviceStatus)}`,
|
|
305
|
+
);
|
|
306
|
+
this.lockState = deviceStatus.body.lockState;
|
|
307
|
+
this.doorState = deviceStatus.body.doorState;
|
|
308
|
+
this.openAPIparseStatus();
|
|
309
|
+
this.updateHomeKitCharacteristics();
|
|
341
310
|
} catch (e: any) {
|
|
342
311
|
this.apiError(e);
|
|
343
312
|
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
|
|
344
|
-
|
|
313
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
345
314
|
}
|
|
346
315
|
}
|
|
347
316
|
|
|
@@ -361,7 +330,7 @@ export class Lock {
|
|
|
361
330
|
} else {
|
|
362
331
|
await this.offlineOff();
|
|
363
332
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
364
|
-
|
|
333
|
+
+ ` ${this.device.connectionType}, pushChanges will not happen.`);
|
|
365
334
|
}
|
|
366
335
|
// Refresh the status from the API
|
|
367
336
|
interval(15000)
|
|
@@ -376,7 +345,7 @@ export class Lock {
|
|
|
376
345
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges`);
|
|
377
346
|
if (this.LockTargetState !== this.accessory.context.LockTargetState) {
|
|
378
347
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEpushChanges LockTargetState: ${this.LockTargetState}`
|
|
379
|
-
|
|
348
|
+
+ ` LockTargetStateCached: ${this.accessory.context.LockTargetState}`);
|
|
380
349
|
const switchbot = await this.platform.connectBLE();
|
|
381
350
|
// Convert to BLE Address
|
|
382
351
|
this.device.bleMac = this.device
|
|
@@ -396,80 +365,50 @@ export class Lock {
|
|
|
396
365
|
.catch(async (e: any) => {
|
|
397
366
|
this.apiError(e);
|
|
398
367
|
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}`
|
|
399
|
-
|
|
368
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
400
369
|
await this.BLEPushConnection();
|
|
401
370
|
});
|
|
402
371
|
} else {
|
|
403
372
|
this.debugLog(
|
|
404
373
|
`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges.` + `LockTargetState: ${this.LockTargetState}, `
|
|
405
|
-
|
|
374
|
+
+ `LockTargetStateCached: ${this.accessory.context.LockTargetState}`,
|
|
406
375
|
);
|
|
407
376
|
}
|
|
408
377
|
}
|
|
409
378
|
|
|
410
379
|
async openAPIpushChanges(): Promise<void> {
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
}
|
|
427
|
-
command = 'unlock';
|
|
428
|
-
}
|
|
429
|
-
const body = superStringify({
|
|
430
|
-
'command': `${command}`,
|
|
431
|
-
'parameter': 'default',
|
|
432
|
-
'commandType': 'command',
|
|
433
|
-
});
|
|
434
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${body},`);
|
|
435
|
-
const options = {
|
|
436
|
-
hostname: HostDomain,
|
|
437
|
-
port: 443,
|
|
438
|
-
path: `${DevicePath}/${this.device.deviceId}/commands`,
|
|
380
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges`);
|
|
381
|
+
if (this.LockTargetState !== this.accessory.context.LockTargetState) {
|
|
382
|
+
let command = '';
|
|
383
|
+
if (this.LockTargetState) {
|
|
384
|
+
command = 'lock';
|
|
385
|
+
} else {
|
|
386
|
+
command = 'unlock';
|
|
387
|
+
}
|
|
388
|
+
const body = JSON.stringify({
|
|
389
|
+
'command': `${command}`,
|
|
390
|
+
'parameter': 'default',
|
|
391
|
+
'commandType': 'command',
|
|
392
|
+
});
|
|
393
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${body},`);
|
|
394
|
+
try {
|
|
395
|
+
const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/commands`, {
|
|
439
396
|
method: 'POST',
|
|
440
|
-
headers:
|
|
441
|
-
'Authorization': this.platform.config.credentials?.token,
|
|
442
|
-
'sign': sign,
|
|
443
|
-
'nonce': nonce,
|
|
444
|
-
't': t,
|
|
445
|
-
'Content-Type': 'application/json',
|
|
446
|
-
'Content-Length': body.length,
|
|
447
|
-
},
|
|
448
|
-
};
|
|
449
|
-
const req = https.request(options, res => {
|
|
450
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges statusCode: ${res.statusCode}`);
|
|
451
|
-
this.statusCode({ res });
|
|
452
|
-
res.on('data', d => {
|
|
453
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
|
|
454
|
-
});
|
|
455
|
-
});
|
|
456
|
-
req.on('error', (e: any) => {
|
|
457
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
397
|
+
headers: this.platform.generateHeaders(),
|
|
458
398
|
});
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
this.
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
399
|
+
const deviceStatus = await body.json();
|
|
400
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Devices: ${JSON.stringify(deviceStatus.body)}`);
|
|
401
|
+
this.statusCode(statusCode);
|
|
402
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Headers: ${JSON.stringify(headers)}`);
|
|
403
|
+
} catch (e: any) {
|
|
404
|
+
this.apiError(e);
|
|
405
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
|
|
406
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`,
|
|
466
407
|
);
|
|
467
408
|
}
|
|
468
|
-
}
|
|
469
|
-
this.
|
|
470
|
-
|
|
471
|
-
+ ` Connection, Error Message: ${superStringify(e.message)}`,
|
|
472
|
-
);
|
|
409
|
+
} else {
|
|
410
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No openAPIpushChanges.` + `LockTargetState: ${this.LockTargetState}, `
|
|
411
|
+
+ `LockTargetStateCached: ${this.accessory.context.LockTargetState}`);
|
|
473
412
|
}
|
|
474
413
|
}
|
|
475
414
|
|
|
@@ -532,7 +471,7 @@ export class Lock {
|
|
|
532
471
|
});
|
|
533
472
|
// Set an event handler
|
|
534
473
|
switchbot.onadvertisement = (ad: any) => {
|
|
535
|
-
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${
|
|
474
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
|
|
536
475
|
};
|
|
537
476
|
await sleep(10000);
|
|
538
477
|
// Stop to monitor
|
|
@@ -570,36 +509,41 @@ export class Lock {
|
|
|
570
509
|
}
|
|
571
510
|
}
|
|
572
511
|
|
|
573
|
-
async statusCode(
|
|
574
|
-
switch (
|
|
512
|
+
async statusCode(statusCode: number): Promise<void> {
|
|
513
|
+
switch (statusCode) {
|
|
575
514
|
case 151:
|
|
576
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this
|
|
515
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
|
|
577
516
|
break;
|
|
578
517
|
case 152:
|
|
579
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found
|
|
518
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
|
|
580
519
|
break;
|
|
581
520
|
case 160:
|
|
582
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported
|
|
521
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
|
|
583
522
|
break;
|
|
584
523
|
case 161:
|
|
585
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline
|
|
586
|
-
|
|
524
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
|
|
525
|
+
this.offlineOff();
|
|
587
526
|
break;
|
|
588
527
|
case 171:
|
|
589
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline
|
|
590
|
-
|
|
528
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. `
|
|
529
|
+
+ `Hub: ${this.device.hubDeviceId}`);
|
|
530
|
+
this.offlineOff();
|
|
591
531
|
break;
|
|
592
532
|
case 190:
|
|
593
533
|
this.errorLog(
|
|
594
534
|
`${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
595
|
-
|
|
535
|
+
` Or command format is invalid, statusCode: ${statusCode}`,
|
|
596
536
|
);
|
|
597
537
|
break;
|
|
598
538
|
case 100:
|
|
599
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent
|
|
539
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
|
|
540
|
+
break;
|
|
541
|
+
case 200:
|
|
542
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
|
|
600
543
|
break;
|
|
601
544
|
default:
|
|
602
|
-
this.
|
|
545
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: `
|
|
546
|
+
+ `${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
|
|
603
547
|
}
|
|
604
548
|
}
|
|
605
549
|
|
|
@@ -621,7 +565,7 @@ export class Lock {
|
|
|
621
565
|
FirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
|
|
622
566
|
let FirmwareRevision: string;
|
|
623
567
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
624
|
-
|
|
568
|
+
+ ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
|
|
625
569
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
|
|
626
570
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
|
|
627
571
|
if (accessory.context.FirmwareRevision) {
|
|
@@ -673,7 +617,7 @@ export class Lock {
|
|
|
673
617
|
config['scanDuration'] = device.scanDuration;
|
|
674
618
|
}
|
|
675
619
|
if (Object.entries(config).length !== 0) {
|
|
676
|
-
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${
|
|
620
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
|
|
677
621
|
}
|
|
678
622
|
}
|
|
679
623
|
|
package/src/device/meter.ts
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
import https from 'https';
|
|
2
|
-
import crypto from 'crypto';
|
|
3
1
|
import { Context } from 'vm';
|
|
4
2
|
import { hostname } from 'os';
|
|
3
|
+
import { request } from 'undici';
|
|
4
|
+
import { sleep } from '../utils';
|
|
5
5
|
import { MqttClient } from 'mqtt';
|
|
6
|
-
import { connectAsync } from 'async-mqtt';
|
|
7
6
|
import { interval, Subject } from 'rxjs';
|
|
7
|
+
import { connectAsync } from 'async-mqtt';
|
|
8
8
|
import { skipWhile } from 'rxjs/operators';
|
|
9
|
-
import superStringify from 'super-stringify';
|
|
10
9
|
import { SwitchBotPlatform } from '../platform';
|
|
11
10
|
import { Service, PlatformAccessory, Units, CharacteristicValue } from 'homebridge';
|
|
12
|
-
import { device, devicesConfig, serviceData, ad, switchbot, temperature, deviceStatus,
|
|
13
|
-
import { IncomingMessage } from 'http';
|
|
14
|
-
import { sleep } from '../utils';
|
|
11
|
+
import { device, devicesConfig, serviceData, ad, switchbot, temperature, deviceStatus, Devices } from '../settings';
|
|
15
12
|
|
|
16
13
|
/**
|
|
17
14
|
* Platform Accessory
|
|
@@ -194,7 +191,7 @@ export class Meter {
|
|
|
194
191
|
} else {
|
|
195
192
|
await this.offlineOff();
|
|
196
193
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
197
|
-
|
|
194
|
+
+ ` ${this.device.connectionType}, parseStatus will not happen.`);
|
|
198
195
|
}
|
|
199
196
|
}
|
|
200
197
|
|
|
@@ -252,7 +249,7 @@ export class Meter {
|
|
|
252
249
|
} else {
|
|
253
250
|
await this.offlineOff();
|
|
254
251
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
255
|
-
|
|
252
|
+
+ ` ${this.device.connectionType}, refreshStatus will not happen.`);
|
|
256
253
|
}
|
|
257
254
|
}
|
|
258
255
|
|
|
@@ -278,7 +275,7 @@ export class Meter {
|
|
|
278
275
|
switchbot.onadvertisement = async (ad: ad) => {
|
|
279
276
|
this.address = ad.address;
|
|
280
277
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},`
|
|
281
|
-
|
|
278
|
+
+ ` BLE Address Found: ${this.address}`);
|
|
282
279
|
if (ad.serviceData.humidity! > 0) {
|
|
283
280
|
// reject unreliable data
|
|
284
281
|
this.humidity = ad.serviceData.humidity;
|
|
@@ -288,11 +285,11 @@ export class Meter {
|
|
|
288
285
|
this.celsius = ad.serviceData.temperature!.c;
|
|
289
286
|
this.fahrenheit = ad.serviceData.temperature!.f;
|
|
290
287
|
this.battery = ad.serviceData.battery;
|
|
291
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${
|
|
288
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
292
289
|
this.debugLog(
|
|
293
290
|
`${this.device.deviceType}: ${this.accessory.displayName} model: ${ad.serviceData.model}, modelName: ${ad.serviceData.modelName}, ` +
|
|
294
|
-
|
|
295
|
-
|
|
291
|
+
`temperature: ${JSON.stringify(ad.serviceData.temperature?.c)}, humidity: ${ad.serviceData.humidity}, ` +
|
|
292
|
+
`battery: ${ad.serviceData.battery}`,
|
|
296
293
|
);
|
|
297
294
|
|
|
298
295
|
if (this.serviceData) {
|
|
@@ -314,7 +311,7 @@ export class Meter {
|
|
|
314
311
|
.catch(async (e: any) => {
|
|
315
312
|
this.apiError(e);
|
|
316
313
|
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}`
|
|
317
|
-
|
|
314
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
318
315
|
await this.BLERefreshConnection(switchbot);
|
|
319
316
|
});
|
|
320
317
|
} else {
|
|
@@ -325,53 +322,25 @@ export class Meter {
|
|
|
325
322
|
async openAPIRefreshStatus(): Promise<void> {
|
|
326
323
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
|
|
327
324
|
try {
|
|
328
|
-
const
|
|
329
|
-
|
|
330
|
-
const data = this.platform.config.credentials?.token + t + nonce;
|
|
331
|
-
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
332
|
-
const sign = signTerm.toString('base64');
|
|
333
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
|
|
334
|
-
const options = {
|
|
335
|
-
hostname: HostDomain,
|
|
336
|
-
port: 443,
|
|
337
|
-
path: `${DevicePath}/${this.device.deviceId}/status`,
|
|
338
|
-
method: 'GET',
|
|
339
|
-
headers: {
|
|
340
|
-
Authorization: this.platform.config.credentials?.token,
|
|
341
|
-
sign: sign,
|
|
342
|
-
nonce: nonce,
|
|
343
|
-
t: t,
|
|
344
|
-
'Content-Type': 'application/json',
|
|
345
|
-
},
|
|
346
|
-
};
|
|
347
|
-
const req = https.request(options, (res) => {
|
|
348
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus statusCode: ${res.statusCode}`);
|
|
349
|
-
let rawData = '';
|
|
350
|
-
res.on('data', (d) => {
|
|
351
|
-
rawData += d;
|
|
352
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
|
|
353
|
-
});
|
|
354
|
-
res.on('end', () => {
|
|
355
|
-
try {
|
|
356
|
-
this.deviceStatus = JSON.parse(rawData);
|
|
357
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus: ${superStringify(this.deviceStatus)}`);
|
|
358
|
-
this.Humidity = this.deviceStatus.body.humidity!;
|
|
359
|
-
this.Temperature = this.deviceStatus.body.temperature!;
|
|
360
|
-
this.openAPIparseStatus();
|
|
361
|
-
this.updateHomeKitCharacteristics();
|
|
362
|
-
} catch (e: any) {
|
|
363
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
364
|
-
}
|
|
365
|
-
});
|
|
366
|
-
});
|
|
367
|
-
req.on('error', (e: any) => {
|
|
368
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
325
|
+
const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/status`, {
|
|
326
|
+
headers: this.platform.generateHeaders(),
|
|
369
327
|
});
|
|
370
|
-
|
|
328
|
+
const deviceStatus = await body.json();
|
|
329
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Devices: ${JSON.stringify(deviceStatus.body)}`);
|
|
330
|
+
this.statusCode(statusCode);
|
|
331
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Headers: ${JSON.stringify(headers)}`);
|
|
332
|
+
this.debugLog(
|
|
333
|
+
`${this.device.deviceType}: ${this.accessory.displayName
|
|
334
|
+
} refreshStatus: ${JSON.stringify(deviceStatus)}`,
|
|
335
|
+
);
|
|
336
|
+
this.Humidity = deviceStatus.body.humidity!;
|
|
337
|
+
this.Temperature = deviceStatus.body.temperature!;
|
|
338
|
+
this.openAPIparseStatus();
|
|
339
|
+
this.updateHomeKitCharacteristics();
|
|
371
340
|
} catch (e: any) {
|
|
372
341
|
this.apiError(e);
|
|
373
342
|
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
|
|
374
|
-
|
|
343
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
375
344
|
}
|
|
376
345
|
}
|
|
377
346
|
|
|
@@ -388,7 +357,7 @@ export class Meter {
|
|
|
388
357
|
this.accessory.context.CurrentRelativeHumidity = this.CurrentRelativeHumidity;
|
|
389
358
|
this.humidityservice?.updateCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity, this.CurrentRelativeHumidity);
|
|
390
359
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
391
|
-
|
|
360
|
+
+ ` CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
|
|
392
361
|
if (this.device.mqttURL) {
|
|
393
362
|
mqttmessage.push(`"humidity": ${this.CurrentRelativeHumidity}`);
|
|
394
363
|
}
|
|
@@ -457,7 +426,7 @@ export class Meter {
|
|
|
457
426
|
?.join(':');
|
|
458
427
|
const options = this.device.mqttPubOptions || {};
|
|
459
428
|
this.mqttClient?.publish(`homebridge-switchbot/meter/${mac}`, `${message}`, options);
|
|
460
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT message: ${message} options:${
|
|
429
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT message: ${message} options:${JSON.stringify(options)}`);
|
|
461
430
|
}
|
|
462
431
|
|
|
463
432
|
/*
|
|
@@ -514,7 +483,7 @@ export class Meter {
|
|
|
514
483
|
});
|
|
515
484
|
// Set an event handler
|
|
516
485
|
switchbot.onadvertisement = (ad: any) => {
|
|
517
|
-
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${
|
|
486
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
|
|
518
487
|
};
|
|
519
488
|
await sleep(10000);
|
|
520
489
|
// Stop to monitor
|
|
@@ -545,40 +514,41 @@ export class Meter {
|
|
|
545
514
|
}
|
|
546
515
|
}
|
|
547
516
|
|
|
548
|
-
async statusCode(
|
|
549
|
-
switch (
|
|
517
|
+
async statusCode(statusCode: number): Promise<void> {
|
|
518
|
+
switch (statusCode) {
|
|
550
519
|
case 151:
|
|
551
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this
|
|
520
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
|
|
552
521
|
break;
|
|
553
522
|
case 152:
|
|
554
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found
|
|
523
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
|
|
555
524
|
break;
|
|
556
525
|
case 160:
|
|
557
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported
|
|
526
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
|
|
558
527
|
break;
|
|
559
528
|
case 161:
|
|
560
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline
|
|
561
|
-
|
|
529
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
|
|
530
|
+
this.offlineOff();
|
|
562
531
|
break;
|
|
563
532
|
case 171:
|
|
564
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} is offline
|
|
565
|
-
|
|
533
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. `
|
|
534
|
+
+ `Hub: ${this.device.hubDeviceId}`);
|
|
535
|
+
this.offlineOff();
|
|
566
536
|
break;
|
|
567
537
|
case 190:
|
|
568
538
|
this.errorLog(
|
|
569
539
|
`${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
570
|
-
|
|
540
|
+
` Or command format is invalid, statusCode: ${statusCode}`,
|
|
571
541
|
);
|
|
572
542
|
break;
|
|
573
543
|
case 100:
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
544
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
|
|
545
|
+
break;
|
|
546
|
+
case 200:
|
|
547
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
|
|
577
548
|
break;
|
|
578
549
|
default:
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
}
|
|
550
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: `
|
|
551
|
+
+ `${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
|
|
582
552
|
}
|
|
583
553
|
}
|
|
584
554
|
|
|
@@ -605,7 +575,7 @@ export class Meter {
|
|
|
605
575
|
FirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
|
|
606
576
|
let FirmwareRevision: string;
|
|
607
577
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
608
|
-
|
|
578
|
+
+ ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
|
|
609
579
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
|
|
610
580
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
|
|
611
581
|
if (accessory.context.FirmwareRevision) {
|
|
@@ -678,7 +648,7 @@ export class Meter {
|
|
|
678
648
|
config['scanDuration'] = device.scanDuration;
|
|
679
649
|
}
|
|
680
650
|
if (Object.entries(config).length !== 0) {
|
|
681
|
-
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${
|
|
651
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
|
|
682
652
|
}
|
|
683
653
|
}
|
|
684
654
|
|