@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/curtain.ts
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
|
-
import https from 'https';
|
|
2
|
-
import crypto from 'crypto';
|
|
3
1
|
import { Context } from 'vm';
|
|
2
|
+
import { request } from 'undici';
|
|
3
|
+
import { sleep } from '../utils';
|
|
4
4
|
import { MqttClient } from 'mqtt';
|
|
5
|
-
import { IncomingMessage } from 'http';
|
|
6
5
|
import { interval, Subject } from 'rxjs';
|
|
7
6
|
import { connectAsync } from 'async-mqtt';
|
|
8
|
-
import superStringify from 'super-stringify';
|
|
9
7
|
import { SwitchBotPlatform } from '../platform';
|
|
10
8
|
import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
|
|
11
9
|
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
12
|
-
import { device, devicesConfig, serviceData, switchbot, deviceStatus, ad,
|
|
13
|
-
import { sleep } from '../utils';
|
|
10
|
+
import { device, devicesConfig, serviceData, switchbot, deviceStatus, ad, Devices } from '../settings';
|
|
14
11
|
|
|
15
12
|
export class Curtain {
|
|
16
13
|
// Services
|
|
@@ -217,7 +214,7 @@ export class Curtain {
|
|
|
217
214
|
} catch (e: any) {
|
|
218
215
|
this.apiError(e);
|
|
219
216
|
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed pushChanges with ${this.device.connectionType} Connection,`
|
|
220
|
-
|
|
217
|
+
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
221
218
|
}
|
|
222
219
|
this.curtainUpdateInProgress = false;
|
|
223
220
|
});
|
|
@@ -236,7 +233,7 @@ export class Curtain {
|
|
|
236
233
|
} else {
|
|
237
234
|
await this.offlineOff();
|
|
238
235
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
239
|
-
|
|
236
|
+
+ ` ${this.device.connectionType}, parseStatus will not happen.`);
|
|
240
237
|
}
|
|
241
238
|
}
|
|
242
239
|
|
|
@@ -273,7 +270,7 @@ export class Curtain {
|
|
|
273
270
|
}
|
|
274
271
|
this.debugLog(
|
|
275
272
|
`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition},` +
|
|
276
|
-
|
|
273
|
+
` TargetPosition: ${this.TargetPosition}, PositionState: ${this.PositionState},`,
|
|
277
274
|
);
|
|
278
275
|
|
|
279
276
|
if (!this.device.curtain?.hide_lightsensor) {
|
|
@@ -291,7 +288,7 @@ export class Curtain {
|
|
|
291
288
|
this.CurrentAmbientLightLevel = (this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels;
|
|
292
289
|
this.debugLog(
|
|
293
290
|
`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.lightLevel},` +
|
|
294
|
-
|
|
291
|
+
` Calculation: ${(this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels}`,
|
|
295
292
|
);
|
|
296
293
|
break;
|
|
297
294
|
case 3:
|
|
@@ -340,7 +337,7 @@ export class Curtain {
|
|
|
340
337
|
this.StatusLowBattery = this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
|
|
341
338
|
}
|
|
342
339
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel},`
|
|
343
|
-
|
|
340
|
+
+ ` StatusLowBattery: ${this.StatusLowBattery}`);
|
|
344
341
|
}
|
|
345
342
|
|
|
346
343
|
async openAPIparseStatus(): Promise<void> {
|
|
@@ -379,7 +376,7 @@ export class Curtain {
|
|
|
379
376
|
}
|
|
380
377
|
this.debugLog(
|
|
381
378
|
`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition},` +
|
|
382
|
-
|
|
379
|
+
` TargetPosition: ${this.TargetPosition}, PositionState: ${this.PositionState},`,
|
|
383
380
|
);
|
|
384
381
|
|
|
385
382
|
if (!this.device.curtain?.hide_lightsensor) {
|
|
@@ -408,7 +405,7 @@ export class Curtain {
|
|
|
408
405
|
} else {
|
|
409
406
|
await this.offlineOff();
|
|
410
407
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
411
|
-
|
|
408
|
+
+ ` ${this.device.connectionType}, refreshStatus will not happen.`);
|
|
412
409
|
}
|
|
413
410
|
}
|
|
414
411
|
|
|
@@ -434,18 +431,18 @@ export class Curtain {
|
|
|
434
431
|
switchbot.onadvertisement = async (ad: any) => {
|
|
435
432
|
this.address = ad.address;
|
|
436
433
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Config BLE Address: ${this.device.bleMac},`
|
|
437
|
-
|
|
434
|
+
+ ` BLE Address Found: ${this.address}`);
|
|
438
435
|
this.serviceData = ad.serviceData;
|
|
439
436
|
this.calibration = ad.serviceData.calibration;
|
|
440
437
|
this.battery = ad.serviceData.battery;
|
|
441
438
|
this.inMotion = ad.serviceData.inMotion;
|
|
442
439
|
this.position = ad.serviceData.position;
|
|
443
440
|
this.lightLevel = ad.serviceData.lightLevel;
|
|
444
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${
|
|
441
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
445
442
|
this.debugLog(
|
|
446
443
|
`${this.device.deviceType}: ${this.accessory.displayName} calibration: ${ad.serviceData.calibration}, ` +
|
|
447
|
-
|
|
448
|
-
|
|
444
|
+
`position: ${ad.serviceData.position}, lightLevel: ${ad.serviceData.lightLevel}, battery: ${ad.serviceData.battery}, ` +
|
|
445
|
+
`inMotion: ${ad.serviceData.inMotion}`);
|
|
449
446
|
|
|
450
447
|
if (this.serviceData) {
|
|
451
448
|
this.connected = true;
|
|
@@ -466,7 +463,7 @@ export class Curtain {
|
|
|
466
463
|
.catch(async (e: any) => {
|
|
467
464
|
this.apiError(e);
|
|
468
465
|
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLERefreshStatus with ${this.device.connectionType}`
|
|
469
|
-
|
|
466
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
470
467
|
await this.BLERefreshConnection(switchbot);
|
|
471
468
|
});
|
|
472
469
|
} else {
|
|
@@ -477,54 +474,26 @@ export class Curtain {
|
|
|
477
474
|
async openAPIRefreshStatus(): Promise<void> {
|
|
478
475
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
|
|
479
476
|
try {
|
|
480
|
-
const
|
|
481
|
-
|
|
482
|
-
const data = this.platform.config.credentials?.token + t + nonce;
|
|
483
|
-
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
484
|
-
const sign = signTerm.toString('base64');
|
|
485
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
|
|
486
|
-
const options = {
|
|
487
|
-
hostname: HostDomain,
|
|
488
|
-
port: 443,
|
|
489
|
-
path: `${DevicePath}/${this.device.deviceId}/status`,
|
|
490
|
-
method: 'GET',
|
|
491
|
-
headers: {
|
|
492
|
-
Authorization: this.platform.config.credentials?.token,
|
|
493
|
-
sign: sign,
|
|
494
|
-
nonce: nonce,
|
|
495
|
-
t: t,
|
|
496
|
-
'Content-Type': 'application/json',
|
|
497
|
-
},
|
|
498
|
-
};
|
|
499
|
-
const req = https.request(options, (res) => {
|
|
500
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
501
|
-
let rawData = '';
|
|
502
|
-
res.on('data', (d) => {
|
|
503
|
-
rawData += d;
|
|
504
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
|
|
505
|
-
});
|
|
506
|
-
res.on('end', () => {
|
|
507
|
-
try {
|
|
508
|
-
this.deviceStatus = JSON.parse(rawData);
|
|
509
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} refreshStatus: ${superStringify(this.deviceStatus)}`);
|
|
510
|
-
this.slidePosition = this.deviceStatus.body.slidePosition;
|
|
511
|
-
this.moving = this.deviceStatus.body.moving;
|
|
512
|
-
this.brightness = this.deviceStatus.body.brightness;
|
|
513
|
-
this.openAPIparseStatus();
|
|
514
|
-
this.updateHomeKitCharacteristics();
|
|
515
|
-
} catch (e: any) {
|
|
516
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
517
|
-
}
|
|
518
|
-
});
|
|
477
|
+
const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/status`, {
|
|
478
|
+
headers: this.platform.generateHeaders(),
|
|
519
479
|
});
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
480
|
+
const deviceStatus = await body.json();
|
|
481
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Devices: ${JSON.stringify(deviceStatus.body)}`);
|
|
482
|
+
this.statusCode(statusCode);
|
|
483
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Headers: ${JSON.stringify(headers)}`);
|
|
484
|
+
this.debugLog(
|
|
485
|
+
`${this.device.deviceType}: ${this.accessory.displayName
|
|
486
|
+
} refreshStatus: ${JSON.stringify(deviceStatus)}`,
|
|
487
|
+
);
|
|
488
|
+
this.slidePosition = deviceStatus.body.slidePosition;
|
|
489
|
+
this.moving = deviceStatus.body.moving;
|
|
490
|
+
this.brightness = deviceStatus.body.brightness;
|
|
491
|
+
this.openAPIparseStatus();
|
|
492
|
+
this.updateHomeKitCharacteristics();
|
|
524
493
|
} catch (e: any) {
|
|
525
494
|
this.apiError(e);
|
|
526
495
|
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
|
|
527
|
-
|
|
496
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
528
497
|
}
|
|
529
498
|
}
|
|
530
499
|
|
|
@@ -538,7 +507,7 @@ export class Curtain {
|
|
|
538
507
|
} else {
|
|
539
508
|
await this.offlineOff();
|
|
540
509
|
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
541
|
-
|
|
510
|
+
+ ` ${this.device.connectionType}, pushChanges will not happen.`);
|
|
542
511
|
}
|
|
543
512
|
// Refresh the status from the API
|
|
544
513
|
interval(15000)
|
|
@@ -581,7 +550,7 @@ export class Curtain {
|
|
|
581
550
|
.catch(async (e: any) => {
|
|
582
551
|
this.apiError(e);
|
|
583
552
|
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed BLEpushChanges with ${this.device.connectionType}`
|
|
584
|
-
+ ` Connection, Error Message: ${
|
|
553
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
585
554
|
await this.BLEPushConnection();
|
|
586
555
|
throw new Error('Connection error');
|
|
587
556
|
});
|
|
@@ -593,7 +562,7 @@ export class Curtain {
|
|
|
593
562
|
}
|
|
594
563
|
} else {
|
|
595
564
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No BLEpushChanges, CurrentPosition & TargetPosition Are the Same.` +
|
|
596
|
-
|
|
565
|
+
` CurrentPosition: ${this.CurrentPosition}, TargetPosition ${this.TargetPosition}`,
|
|
597
566
|
);
|
|
598
567
|
}
|
|
599
568
|
}
|
|
@@ -619,77 +588,48 @@ export class Curtain {
|
|
|
619
588
|
}
|
|
620
589
|
|
|
621
590
|
async openAPIpushChanges(): Promise<void> {
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
this.
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
}
|
|
648
|
-
this.debugLog(`${this.accessory.displayName} Mode: ${this.Mode}`);
|
|
649
|
-
const adjustedMode = this.setPositionMode || 'ff';
|
|
650
|
-
const body = superStringify({
|
|
651
|
-
'command': 'setPosition',
|
|
652
|
-
'parameter': `0,${adjustedMode},${adjustedTargetPosition}`,
|
|
653
|
-
'commandType': 'command',
|
|
654
|
-
});
|
|
655
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${body},`);
|
|
656
|
-
const options = {
|
|
657
|
-
hostname: HostDomain,
|
|
658
|
-
port: 443,
|
|
659
|
-
path: `${DevicePath}/${this.device.deviceId}/commands`,
|
|
591
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} OpenAPI pushChanges`);
|
|
592
|
+
if ((this.TargetPosition !== this.CurrentPosition) || this.device.disableCaching) {
|
|
593
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Pushing ${this.TargetPosition}`);
|
|
594
|
+
const adjustedTargetPosition = 100 - Number(this.TargetPosition);
|
|
595
|
+
if (Number(this.TargetPosition) > 50) {
|
|
596
|
+
this.setPositionMode = this.device.curtain?.setOpenMode;
|
|
597
|
+
} else {
|
|
598
|
+
this.setPositionMode = this.device.curtain?.setCloseMode;
|
|
599
|
+
}
|
|
600
|
+
if (this.setPositionMode === '1') {
|
|
601
|
+
this.Mode = 'Silent Mode';
|
|
602
|
+
} else if (this.setPositionMode === '0') {
|
|
603
|
+
this.Mode = 'Performance Mode';
|
|
604
|
+
} else {
|
|
605
|
+
this.Mode = 'Default Mode';
|
|
606
|
+
}
|
|
607
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Mode: ${this.Mode}`);
|
|
608
|
+
const adjustedMode = this.setPositionMode || 'ff';
|
|
609
|
+
const body = JSON.stringify({
|
|
610
|
+
'command': 'setPosition',
|
|
611
|
+
'parameter': `0,${adjustedMode},${adjustedTargetPosition}`,
|
|
612
|
+
'commandType': 'command',
|
|
613
|
+
});
|
|
614
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${body},`);
|
|
615
|
+
try {
|
|
616
|
+
const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/commands`, {
|
|
660
617
|
method: 'POST',
|
|
661
|
-
headers:
|
|
662
|
-
'Authorization': this.platform.config.credentials?.token,
|
|
663
|
-
'sign': sign,
|
|
664
|
-
'nonce': nonce,
|
|
665
|
-
't': t,
|
|
666
|
-
'Content-Type': 'application/json',
|
|
667
|
-
'Content-Length': body.length,
|
|
668
|
-
},
|
|
669
|
-
};
|
|
670
|
-
const req = https.request(options, res => {
|
|
671
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIpushChanges statusCode: ${res.statusCode}`);
|
|
672
|
-
this.statusCode({ res });
|
|
673
|
-
res.on('data', d => {
|
|
674
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
|
|
675
|
-
});
|
|
618
|
+
headers: this.platform.generateHeaders(),
|
|
676
619
|
});
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
this.
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
+` CurrentPosition: ${this.CurrentPosition}, TargetPosition ${this.TargetPosition}`,
|
|
620
|
+
const deviceStatus = await body.json();
|
|
621
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Devices: ${JSON.stringify(deviceStatus.body)}`);
|
|
622
|
+
this.statusCode(statusCode);
|
|
623
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Headers: ${JSON.stringify(headers)}`);
|
|
624
|
+
} catch (e: any) {
|
|
625
|
+
this.apiError(e);
|
|
626
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIpushChanges with ${this.device.connectionType}`
|
|
627
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`,
|
|
686
628
|
);
|
|
687
629
|
}
|
|
688
|
-
}
|
|
689
|
-
this.
|
|
690
|
-
|
|
691
|
-
+ ` Connection, Error Message: ${superStringify(e.message)}`,
|
|
692
|
-
);
|
|
630
|
+
} else {
|
|
631
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No OpenAPI Changes, CurrentPosition & TargetPosition Are the Same.`
|
|
632
|
+
+ ` CurrentPosition: ${this.CurrentPosition}, TargetPosition ${this.TargetPosition}`);
|
|
693
633
|
}
|
|
694
634
|
}
|
|
695
635
|
|
|
@@ -782,7 +722,7 @@ export class Curtain {
|
|
|
782
722
|
this.accessory.context.CurrentAmbientLightLevel = this.CurrentAmbientLightLevel;
|
|
783
723
|
this.lightSensorService?.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, this.CurrentAmbientLightLevel);
|
|
784
724
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
785
|
-
|
|
725
|
+
+ ` updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
786
726
|
}
|
|
787
727
|
}
|
|
788
728
|
if (this.BLE) {
|
|
@@ -820,7 +760,7 @@ export class Curtain {
|
|
|
820
760
|
?.join(':');
|
|
821
761
|
const options = this.device.mqttPubOptions || {};
|
|
822
762
|
this.mqttClient?.publish(`homebridge-switchbot/curtain/${mac}/${topic}`, `${message}`, options);
|
|
823
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT message: ${topic}/${message} options:${
|
|
763
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} MQTT message: ${topic}/${message} options:${JSON.stringify(options)}`);
|
|
824
764
|
}
|
|
825
765
|
|
|
826
766
|
/*
|
|
@@ -860,7 +800,7 @@ export class Curtain {
|
|
|
860
800
|
});
|
|
861
801
|
// Set an event handler
|
|
862
802
|
switchbot.onadvertisement = (ad: any) => {
|
|
863
|
-
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${
|
|
803
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} ad: ${JSON.stringify(ad, null, ' ')}`);
|
|
864
804
|
};
|
|
865
805
|
await sleep(10000);
|
|
866
806
|
// Stop to monitor
|
|
@@ -950,7 +890,7 @@ export class Curtain {
|
|
|
950
890
|
this.scanDuration = this.updateRate;
|
|
951
891
|
if (this.BLE) {
|
|
952
892
|
this.warnLog(`${this.device.deviceType}: `
|
|
953
|
-
|
|
893
|
+
+ `${this.accessory.displayName} scanDuration is less than updateRate, overriding scanDuration with updateRate`);
|
|
954
894
|
}
|
|
955
895
|
} else {
|
|
956
896
|
this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
|
|
@@ -970,36 +910,41 @@ export class Curtain {
|
|
|
970
910
|
}
|
|
971
911
|
}
|
|
972
912
|
|
|
973
|
-
async statusCode(
|
|
974
|
-
switch (
|
|
913
|
+
async statusCode(statusCode: number): Promise<void> {
|
|
914
|
+
switch (statusCode) {
|
|
975
915
|
case 151:
|
|
976
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this
|
|
916
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
|
|
977
917
|
break;
|
|
978
918
|
case 152:
|
|
979
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found
|
|
919
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
|
|
980
920
|
break;
|
|
981
921
|
case 160:
|
|
982
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported
|
|
922
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
|
|
983
923
|
break;
|
|
984
924
|
case 161:
|
|
985
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline
|
|
925
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
|
|
986
926
|
this.offlineOff();
|
|
987
927
|
break;
|
|
988
928
|
case 171:
|
|
989
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline
|
|
929
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. `
|
|
930
|
+
+ `Hub: ${this.device.hubDeviceId}`);
|
|
990
931
|
this.offlineOff();
|
|
991
932
|
break;
|
|
992
933
|
case 190:
|
|
993
934
|
this.errorLog(
|
|
994
935
|
`${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
995
|
-
|
|
936
|
+
` Or command format is invalid, statusCode: ${statusCode}`,
|
|
996
937
|
);
|
|
997
938
|
break;
|
|
998
939
|
case 100:
|
|
999
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent
|
|
940
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
|
|
941
|
+
break;
|
|
942
|
+
case 200:
|
|
943
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
|
|
1000
944
|
break;
|
|
1001
945
|
default:
|
|
1002
|
-
this.
|
|
946
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: `
|
|
947
|
+
+ `${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
|
|
1003
948
|
}
|
|
1004
949
|
}
|
|
1005
950
|
|
|
@@ -1027,7 +972,7 @@ export class Curtain {
|
|
|
1027
972
|
FirmwareRevision(accessory: PlatformAccessory<Context>, device: device & devicesConfig): CharacteristicValue {
|
|
1028
973
|
let FirmwareRevision: string;
|
|
1029
974
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
1030
|
-
|
|
975
|
+
+ ` accessory.context.FirmwareRevision: ${accessory.context.FirmwareRevision}`);
|
|
1031
976
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} device.firmware: ${device.firmware}`);
|
|
1032
977
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} this.platform.version: ${this.platform.version}`);
|
|
1033
978
|
if (accessory.context.FirmwareRevision) {
|
|
@@ -1106,7 +1051,7 @@ export class Curtain {
|
|
|
1106
1051
|
config['maxRetry'] = device.maxRetry;
|
|
1107
1052
|
}
|
|
1108
1053
|
if (Object.entries(config).length !== 0) {
|
|
1109
|
-
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${
|
|
1054
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
|
|
1110
1055
|
}
|
|
1111
1056
|
}
|
|
1112
1057
|
|
package/src/device/hub.ts
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import https from 'https';
|
|
2
|
-
import crypto from 'crypto';
|
|
3
1
|
import { Context } from 'vm';
|
|
4
|
-
import { IncomingMessage } from 'http';
|
|
5
2
|
import { interval } from 'rxjs';
|
|
6
|
-
import
|
|
3
|
+
import { request } from 'undici';
|
|
4
|
+
import { sleep } from '../utils';
|
|
7
5
|
import { SwitchBotPlatform } from '../platform';
|
|
6
|
+
import { device, devicesConfig, Devices } from '../settings';
|
|
8
7
|
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
9
|
-
import { device, devicesConfig, HostDomain, DevicePath } from '../settings';
|
|
10
|
-
import { sleep } from '../utils';
|
|
11
8
|
|
|
12
9
|
export class Hub {
|
|
13
10
|
// Services
|
|
@@ -163,56 +160,25 @@ export class Hub {
|
|
|
163
160
|
async openAPIRefreshStatus(): Promise<void> {
|
|
164
161
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
|
|
165
162
|
try {
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
const data = this.platform.config.credentials?.token + t + nonce;
|
|
169
|
-
const signTerm = crypto.createHmac('sha256', this.platform.config.credentials?.secret).update(Buffer.from(data, 'utf-8')).digest();
|
|
170
|
-
const sign = signTerm.toString('base64');
|
|
171
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
|
|
172
|
-
const options = {
|
|
173
|
-
hostname: HostDomain,
|
|
174
|
-
port: 443,
|
|
175
|
-
path: `${DevicePath}/${this.device.deviceId}/status`,
|
|
176
|
-
method: 'GET',
|
|
177
|
-
headers: {
|
|
178
|
-
Authorization: this.platform.config.credentials?.token,
|
|
179
|
-
sign: sign,
|
|
180
|
-
nonce: nonce,
|
|
181
|
-
t: t,
|
|
182
|
-
'Content-Type': 'application/json',
|
|
183
|
-
},
|
|
184
|
-
};
|
|
185
|
-
const req = https.request(options, (res) => {
|
|
186
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${res.statusCode}`);
|
|
187
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}: ${res}`);
|
|
188
|
-
let rawData = '';
|
|
189
|
-
res.on('data', (d) => {
|
|
190
|
-
rawData += d;
|
|
191
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} d: ${d}`);
|
|
192
|
-
});
|
|
193
|
-
res.on('end', () => {
|
|
194
|
-
try {
|
|
195
|
-
this.deviceStatus = JSON.parse(rawData);
|
|
196
|
-
this.CurrentTemperature = this.deviceStatus.body.temperature;
|
|
197
|
-
this.CurrentRelativeHumidity = this.deviceStatus.body.humidity;
|
|
198
|
-
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} refreshStatus: ${superStringify(this.deviceStatus)}`);
|
|
199
|
-
this.openAPIparseStatus();
|
|
200
|
-
this.updateHomeKitCharacteristics();
|
|
201
|
-
} catch (e: any) {
|
|
202
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
203
|
-
}
|
|
204
|
-
});
|
|
205
|
-
});
|
|
206
|
-
req.on('error', (e: any) => {
|
|
207
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} error message: ${e.message}`);
|
|
163
|
+
const { body, statusCode, headers } = await request(`${Devices}/${this.device.deviceId}/status`, {
|
|
164
|
+
headers: this.platform.generateHeaders(),
|
|
208
165
|
});
|
|
209
|
-
|
|
166
|
+
const deviceStatus = await body.json();
|
|
167
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Devices: ${JSON.stringify(deviceStatus.body)}`);
|
|
168
|
+
this.statusCode(statusCode);
|
|
169
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Headers: ${JSON.stringify(headers)}`);
|
|
170
|
+
this.debugLog(
|
|
171
|
+
`${this.device.deviceType}: ${this.accessory.displayName
|
|
172
|
+
} refreshStatus: ${JSON.stringify(deviceStatus)}`,
|
|
173
|
+
);
|
|
174
|
+
this.CurrentTemperature = deviceStatus.body.temperature;
|
|
175
|
+
this.CurrentRelativeHumidity = deviceStatus.body.humidity;
|
|
176
|
+
this.openAPIparseStatus();
|
|
177
|
+
this.updateHomeKitCharacteristics();
|
|
210
178
|
} catch (e: any) {
|
|
211
179
|
this.apiError(e);
|
|
212
|
-
this.errorLog(
|
|
213
|
-
|
|
214
|
-
` Connection, Error Message: ${superStringify(e.message)}`,
|
|
215
|
-
);
|
|
180
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed openAPIRefreshStatus with ${this.device.connectionType}`
|
|
181
|
+
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
216
182
|
}
|
|
217
183
|
}
|
|
218
184
|
|
|
@@ -246,36 +212,41 @@ export class Hub {
|
|
|
246
212
|
this.hubTemperatureSensor?.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, this.CurrentTemperature);
|
|
247
213
|
}
|
|
248
214
|
|
|
249
|
-
async statusCode(
|
|
250
|
-
switch (
|
|
215
|
+
async statusCode(statusCode: number): Promise<void> {
|
|
216
|
+
switch (statusCode) {
|
|
251
217
|
case 151:
|
|
252
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this
|
|
218
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command not supported by this deviceType, statusCode: ${statusCode}`);
|
|
253
219
|
break;
|
|
254
220
|
case 152:
|
|
255
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found
|
|
221
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device not found, statusCode: ${statusCode}`);
|
|
256
222
|
break;
|
|
257
223
|
case 160:
|
|
258
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported
|
|
224
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Command is not supported, statusCode: ${statusCode}`);
|
|
259
225
|
break;
|
|
260
226
|
case 161:
|
|
261
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline
|
|
227
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Device is offline, statusCode: ${statusCode}`);
|
|
262
228
|
this.offlineOff();
|
|
263
229
|
break;
|
|
264
230
|
case 171:
|
|
265
|
-
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline
|
|
231
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} Hub Device is offline, statusCode: ${statusCode}. `
|
|
232
|
+
+ `Hub: ${this.device.hubDeviceId}`);
|
|
266
233
|
this.offlineOff();
|
|
267
234
|
break;
|
|
268
235
|
case 190:
|
|
269
236
|
this.errorLog(
|
|
270
237
|
`${this.device.deviceType}: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
271
|
-
|
|
238
|
+
` Or command format is invalid, statusCode: ${statusCode}`,
|
|
272
239
|
);
|
|
273
240
|
break;
|
|
274
241
|
case 100:
|
|
275
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent
|
|
242
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Command successfully sent, statusCode: ${statusCode}`);
|
|
243
|
+
break;
|
|
244
|
+
case 200:
|
|
245
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Request successful, statusCode: ${statusCode}`);
|
|
276
246
|
break;
|
|
277
247
|
default:
|
|
278
|
-
this.
|
|
248
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Unknown statusCode: `
|
|
249
|
+
+ `${statusCode}, Submit Bugs Here: ' + 'https://tinyurl.com/SwitchBotBug`);
|
|
279
250
|
}
|
|
280
251
|
}
|
|
281
252
|
|