@switchbot/homebridge-switchbot 2.6.0-beta.4 → 2.6.0-beta.5
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/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/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/device/striplight.d.ts +1 -9
- package/dist/device/striplight.d.ts.map +1 -1
- package/dist/device/striplight.js +137 -193
- package/dist/device/striplight.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 +153 -146
- 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/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/device/striplight.ts +148 -200
- 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 +143 -157
- package/src/settings.ts +5 -0
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
|
|
package/src/device/meterplus.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
|
|
@@ -195,7 +192,7 @@ export class MeterPlus {
|
|
|
195
192
|
} else {
|
|
196
193
|
await this.offlineOff();
|
|
197
194
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
198
|
-
|
|
195
|
+
+ ` ${this.device.connectionType}, parseStatus will not happen.`);
|
|
199
196
|
}
|
|
200
197
|
}
|
|
201
198
|
|
|
@@ -254,7 +251,7 @@ export class MeterPlus {
|
|
|
254
251
|
} else {
|
|
255
252
|
await this.offlineOff();
|
|
256
253
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
257
|
-
|
|
254
|
+
+ ` ${this.device.connectionType}, refreshStatus will not happen.`);
|
|
258
255
|
}
|
|
259
256
|
}
|
|
260
257
|
|
|
@@ -280,7 +277,7 @@ export class MeterPlus {
|
|
|
280
277
|
switchbot.onadvertisement = async (ad: ad) => {
|
|
281
278
|
this.address = ad.address;
|
|
282
279
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},`
|
|
283
|
-
|
|
280
|
+
+ ` BLE Address Found: ${this.address}`);
|
|
284
281
|
if (ad.serviceData.humidity! > 0) {
|
|
285
282
|
// reject unreliable data
|
|
286
283
|
this.humidity = ad.serviceData.humidity;
|
|
@@ -290,11 +287,11 @@ export class MeterPlus {
|
|
|
290
287
|
this.celsius = ad.serviceData.temperature!.c;
|
|
291
288
|
this.fahrenheit = ad.serviceData.temperature!.f;
|
|
292
289
|
this.battery = ad.serviceData.battery;
|
|
293
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${
|
|
290
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
294
291
|
this.debugLog(
|
|
295
292
|
`${this.device.deviceType}: ${this.accessory.displayName} model: ${ad.serviceData.model}, modelName: ${ad.serviceData.modelName}, ` +
|
|
296
|
-
|
|
297
|
-
|
|
293
|
+
`temperature: ${JSON.stringify(ad.serviceData.temperature?.c)}, humidity: ${ad.serviceData.humidity}, ` +
|
|
294
|
+
`battery: ${ad.serviceData.battery}`,
|
|
298
295
|
);
|
|
299
296
|
|
|
300
297
|
if (this.serviceData) {
|
|
@@ -316,7 +313,7 @@ export class MeterPlus {
|
|
|
316
313
|
.catch(async (e: any) => {
|
|
317
314
|
this.apiError(e);
|
|
318
315
|
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}`
|
|
319
|
-
|
|
316
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
320
317
|
await this.BLERefreshConnection(switchbot);
|
|
321
318
|
});
|
|
322
319
|
} else {
|
|
@@ -327,54 +324,26 @@ export class MeterPlus {
|
|
|
327
324
|
async openAPIRefreshStatus(): Promise<void> {
|
|
328
325
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
|
|
329
326
|
try {
|
|
330
|
-
const
|
|
331
|
-
|
|
332
|
-
const data = this.platform.config.credentials?.token + t + nonce;
|
|
333
|
-
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
334
|
-
const sign = signTerm.toString('base64');
|
|
335
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
|
|
336
|
-
const options = {
|
|
337
|
-
hostname: HostDomain,
|
|
338
|
-
port: 443,
|
|
339
|
-
path: `${DevicePath}/${this.device.deviceId}/status`,
|
|
340
|
-
method: 'GET',
|
|
341
|
-
headers: {
|
|
342
|
-
Authorization: this.platform.config.credentials?.token,
|
|
343
|
-
sign: sign,
|
|
344
|
-
nonce: nonce,
|
|
345
|
-
t: t,
|
|
346
|
-
'Content-Type': 'application/json',
|
|
347
|
-
},
|
|
348
|
-
};
|
|
349
|
-
const req = https.request(options, (res) => {
|
|
350
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus statusCode: ${res.statusCode}`);
|
|
351
|
-
let rawData = '';
|
|
352
|
-
res.on('data', (d) => {
|
|
353
|
-
rawData += d;
|
|
354
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
|
|
355
|
-
});
|
|
356
|
-
res.on('end', () => {
|
|
357
|
-
try {
|
|
358
|
-
this.deviceStatus = JSON.parse(rawData);
|
|
359
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus: ${superStringify(this.deviceStatus)}`);
|
|
360
|
-
this.Humidity = this.deviceStatus.body.humidity!;
|
|
361
|
-
this.Temperature = this.deviceStatus.body.temperature!;
|
|
362
|
-
this.Battery = this.deviceStatus.body.battery!;
|
|
363
|
-
this.parseStatus();
|
|
364
|
-
this.updateHomeKitCharacteristics();
|
|
365
|
-
} catch (e: any) {
|
|
366
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
367
|
-
}
|
|
368
|
-
});
|
|
327
|
+
const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/status`, {
|
|
328
|
+
headers: this.platform.generateHeaders(),
|
|
369
329
|
});
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
330
|
+
const deviceStatus = await body.json();
|
|
331
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Devices: ${JSON.stringify(deviceStatus.body)}`);
|
|
332
|
+
this.statusCode(statusCode);
|
|
333
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Headers: ${JSON.stringify(headers)}`);
|
|
334
|
+
this.debugLog(
|
|
335
|
+
`${this.device.deviceType}: ${this.accessory.displayName
|
|
336
|
+
} refreshStatus: ${JSON.stringify(deviceStatus)}`,
|
|
337
|
+
);
|
|
338
|
+
this.Humidity = deviceStatus.body.humidity!;
|
|
339
|
+
this.Temperature = deviceStatus.body.temperature!;
|
|
340
|
+
this.Battery = deviceStatus.body.battery!;
|
|
341
|
+
this.openAPIparseStatus();
|
|
342
|
+
this.updateHomeKitCharacteristics();
|
|
374
343
|
} catch (e: any) {
|
|
375
344
|
this.apiError(e);
|
|
376
345
|
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
|
|
377
|
-
|
|
346
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
378
347
|
}
|
|
379
348
|
}
|
|
380
349
|
|
|
@@ -391,7 +360,7 @@ export class MeterPlus {
|
|
|
391
360
|
this.accessory.context.CurrentRelativeHumidity = this.CurrentRelativeHumidity;
|
|
392
361
|
this.humidityservice?.updateCharacteristic(this.platform.Characteristic.CurrentRelativeHumidity, this.CurrentRelativeHumidity);
|
|
393
362
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
394
|
-
|
|
363
|
+
+ ` updateCharacteristic CurrentRelativeHumidity: ${this.CurrentRelativeHumidity}`);
|
|
395
364
|
if (this.device.mqttURL) {
|
|
396
365
|
mqttmessage.push(`"humidity": ${this.CurrentRelativeHumidity}`);
|
|
397
366
|
}
|
|
@@ -407,7 +376,7 @@ export class MeterPlus {
|
|
|
407
376
|
if (this.device.mqttURL) {
|
|
408
377
|
mqttmessage.push(`"temperature": ${this.CurrentTemperature}`);
|
|
409
378
|
}
|
|
410
|
-
if (this.device.history){
|
|
379
|
+
if (this.device.history) {
|
|
411
380
|
entry['temp'] = this.CurrentTemperature;
|
|
412
381
|
}
|
|
413
382
|
this.accessory.context.CurrentTemperature = this.CurrentTemperature;
|
|
@@ -459,7 +428,7 @@ export class MeterPlus {
|
|
|
459
428
|
?.join(':');
|
|
460
429
|
const options = this.device.mqttPubOptions || {};
|
|
461
430
|
this.mqttClient?.publish(`homebridge-switchbot/meter/${mac}`, `${message}`, options);
|
|
462
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT message: ${message} options:${
|
|
431
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT message: ${message} options:${JSON.stringify(options)}`);
|
|
463
432
|
}
|
|
464
433
|
|
|
465
434
|
/*
|
|
@@ -516,7 +485,7 @@ export class MeterPlus {
|
|
|
516
485
|
});
|
|
517
486
|
// Set an event handler
|
|
518
487
|
switchbot.onadvertisement = (ad: any) => {
|
|
519
|
-
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${
|
|
488
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
|
|
520
489
|
};
|
|
521
490
|
await sleep(10000);
|
|
522
491
|
// Stop to monitor
|
|
@@ -557,40 +526,41 @@ export class MeterPlus {
|
|
|
557
526
|
}
|
|
558
527
|
}
|
|
559
528
|
|
|
560
|
-
async statusCode(
|
|
561
|
-
switch (
|
|
529
|
+
async statusCode(statusCode: number): Promise<void> {
|
|
530
|
+
switch (statusCode) {
|
|
562
531
|
case 151:
|
|
563
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this
|
|
532
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
|
|
564
533
|
break;
|
|
565
534
|
case 152:
|
|
566
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found
|
|
535
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
|
|
567
536
|
break;
|
|
568
537
|
case 160:
|
|
569
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported
|
|
538
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
|
|
570
539
|
break;
|
|
571
540
|
case 161:
|
|
572
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline
|
|
573
|
-
|
|
541
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
|
|
542
|
+
this.offlineOff();
|
|
574
543
|
break;
|
|
575
544
|
case 171:
|
|
576
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} is offline
|
|
577
|
-
|
|
545
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. `
|
|
546
|
+
+ `Hub: ${this.device.hubDeviceId}`);
|
|
547
|
+
this.offlineOff();
|
|
578
548
|
break;
|
|
579
549
|
case 190:
|
|
580
550
|
this.errorLog(
|
|
581
551
|
`${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
582
|
-
|
|
552
|
+
` Or command format is invalid, statusCode: ${statusCode}`,
|
|
583
553
|
);
|
|
584
554
|
break;
|
|
585
555
|
case 100:
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
556
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
|
|
557
|
+
break;
|
|
558
|
+
case 200:
|
|
559
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
|
|
589
560
|
break;
|
|
590
561
|
default:
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
}
|
|
562
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: `
|
|
563
|
+
+ `${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
|
|
594
564
|
}
|
|
595
565
|
}
|
|
596
566
|
|
|
@@ -617,7 +587,7 @@ export class MeterPlus {
|
|
|
617
587
|
FirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
|
|
618
588
|
let FirmwareRevision: string;
|
|
619
589
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
620
|
-
|
|
590
|
+
+ ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
|
|
621
591
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
|
|
622
592
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
|
|
623
593
|
if (accessory.context.FirmwareRevision) {
|
|
@@ -690,7 +660,7 @@ export class MeterPlus {
|
|
|
690
660
|
config['scanDuration'] = device.scanDuration;
|
|
691
661
|
}
|
|
692
662
|
if (Object.entries(config).length !== 0) {
|
|
693
|
-
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${
|
|
663
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
|
|
694
664
|
}
|
|
695
665
|
}
|
|
696
666
|
|