@switchbot/homebridge-switchbot 3.5.0 → 3.5.1-beta.1
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/.github/npm-version-script.cjs +81 -0
- package/config.schema.json +4 -4
- package/dist/device/blindtilt.d.ts.map +1 -1
- package/dist/device/blindtilt.js +64 -189
- package/dist/device/blindtilt.js.map +1 -1
- package/dist/device/bot.d.ts.map +1 -1
- package/dist/device/bot.js +34 -68
- package/dist/device/bot.js.map +1 -1
- package/dist/device/ceilinglight.d.ts +1 -1
- package/dist/device/ceilinglight.d.ts.map +1 -1
- package/dist/device/ceilinglight.js +65 -158
- package/dist/device/ceilinglight.js.map +1 -1
- package/dist/device/colorbulb.d.ts +1 -1
- package/dist/device/colorbulb.d.ts.map +1 -1
- package/dist/device/colorbulb.js +47 -159
- package/dist/device/colorbulb.js.map +1 -1
- package/dist/device/contact.d.ts.map +1 -1
- package/dist/device/contact.js +42 -105
- package/dist/device/contact.js.map +1 -1
- package/dist/device/curtain.d.ts +1 -0
- package/dist/device/curtain.d.ts.map +1 -1
- package/dist/device/curtain.js +61 -182
- package/dist/device/curtain.js.map +1 -1
- package/dist/device/device.d.ts +41 -2
- package/dist/device/device.d.ts.map +1 -1
- package/dist/device/device.js +182 -5
- package/dist/device/device.js.map +1 -1
- package/dist/device/fan.d.ts.map +1 -1
- package/dist/device/fan.js +76 -145
- package/dist/device/fan.js.map +1 -1
- package/dist/device/hub.d.ts +7 -1
- package/dist/device/hub.d.ts.map +1 -1
- package/dist/device/hub.js +54 -17
- package/dist/device/hub.js.map +1 -1
- package/dist/device/humidifier.d.ts.map +1 -1
- package/dist/device/humidifier.js +55 -104
- package/dist/device/humidifier.js.map +1 -1
- package/dist/device/iosensor.d.ts.map +1 -1
- package/dist/device/iosensor.js +27 -46
- package/dist/device/iosensor.js.map +1 -1
- package/dist/device/lightstrip.d.ts +1 -1
- package/dist/device/lightstrip.d.ts.map +1 -1
- package/dist/device/lightstrip.js +56 -120
- package/dist/device/lightstrip.js.map +1 -1
- package/dist/device/lock.d.ts +1 -1
- package/dist/device/lock.d.ts.map +1 -1
- package/dist/device/lock.js +36 -66
- package/dist/device/lock.js.map +1 -1
- package/dist/device/meter.d.ts.map +1 -1
- package/dist/device/meter.js +27 -46
- package/dist/device/meter.js.map +1 -1
- package/dist/device/meterplus.d.ts.map +1 -1
- package/dist/device/meterplus.js +26 -45
- package/dist/device/meterplus.js.map +1 -1
- package/dist/device/motion.d.ts.map +1 -1
- package/dist/device/motion.js +24 -43
- package/dist/device/motion.js.map +1 -1
- package/dist/device/plug.d.ts.map +1 -1
- package/dist/device/plug.js +32 -66
- package/dist/device/plug.js.map +1 -1
- package/dist/device/robotvacuumcleaner.d.ts +1 -1
- package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
- package/dist/device/robotvacuumcleaner.js +43 -88
- package/dist/device/robotvacuumcleaner.js.map +1 -1
- package/dist/device/waterdetector.d.ts.map +1 -1
- package/dist/device/waterdetector.js +23 -43
- package/dist/device/waterdetector.js.map +1 -1
- package/dist/irdevice/airconditioner.d.ts.map +1 -1
- package/dist/irdevice/airconditioner.js +10 -28
- package/dist/irdevice/airconditioner.js.map +1 -1
- package/dist/irdevice/airpurifier.d.ts.map +1 -1
- package/dist/irdevice/airpurifier.js +8 -20
- package/dist/irdevice/airpurifier.js.map +1 -1
- package/dist/irdevice/camera.d.ts.map +1 -1
- package/dist/irdevice/camera.js +8 -20
- package/dist/irdevice/camera.js.map +1 -1
- package/dist/irdevice/fan.d.ts.map +1 -1
- package/dist/irdevice/fan.js +8 -20
- package/dist/irdevice/fan.js.map +1 -1
- package/dist/irdevice/irdevice.d.ts +7 -0
- package/dist/irdevice/irdevice.d.ts.map +1 -1
- package/dist/irdevice/irdevice.js +28 -0
- package/dist/irdevice/irdevice.js.map +1 -1
- package/dist/irdevice/light.d.ts.map +1 -1
- package/dist/irdevice/light.js +8 -20
- package/dist/irdevice/light.js.map +1 -1
- package/dist/irdevice/other.d.ts.map +1 -1
- package/dist/irdevice/other.js +8 -20
- package/dist/irdevice/other.js.map +1 -1
- package/dist/irdevice/tv.d.ts.map +1 -1
- package/dist/irdevice/tv.js +8 -20
- package/dist/irdevice/tv.js.map +1 -1
- package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
- package/dist/irdevice/vacuumcleaner.js +8 -20
- package/dist/irdevice/vacuumcleaner.js.map +1 -1
- package/dist/irdevice/waterheater.d.ts.map +1 -1
- package/dist/irdevice/waterheater.js +8 -20
- package/dist/irdevice/waterheater.js.map +1 -1
- package/dist/settings.d.ts +4 -2
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js.map +1 -1
- package/dist/utils.d.ts +19 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +20 -1
- package/dist/utils.js.map +1 -1
- package/package.json +8 -8
- package/src/device/blindtilt.ts +71 -186
- package/src/device/bot.ts +32 -68
- package/src/device/ceilinglight.ts +67 -153
- package/src/device/colorbulb.ts +51 -155
- package/src/device/contact.ts +49 -104
- package/src/device/curtain.ts +70 -177
- package/src/device/device.ts +207 -8
- package/src/device/fan.ts +75 -147
- package/src/device/hub.ts +55 -19
- package/src/device/humidifier.ts +52 -104
- package/src/device/iosensor.ts +25 -46
- package/src/device/lightstrip.ts +54 -121
- package/src/device/lock.ts +35 -67
- package/src/device/meter.ts +25 -46
- package/src/device/meterplus.ts +24 -45
- package/src/device/motion.ts +22 -43
- package/src/device/plug.ts +30 -66
- package/src/device/robotvacuumcleaner.ts +40 -89
- package/src/device/waterdetector.ts +22 -43
- package/src/irdevice/airconditioner.ts +10 -26
- package/src/irdevice/airpurifier.ts +8 -20
- package/src/irdevice/camera.ts +8 -20
- package/src/irdevice/fan.ts +8 -20
- package/src/irdevice/irdevice.ts +29 -0
- package/src/irdevice/light.ts +8 -20
- package/src/irdevice/other.ts +8 -20
- package/src/irdevice/tv.ts +8 -20
- package/src/irdevice/vacuumcleaner.ts +8 -20
- package/src/irdevice/waterheater.ts +8 -20
- package/src/settings.ts +4 -2
- package/src/utils.ts +20 -1
package/src/device/fan.ts
CHANGED
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
*
|
|
3
3
|
* plug.ts: @switchbot/homebridge-switchbot.
|
|
4
4
|
*/
|
|
5
|
-
import { request } from 'undici';
|
|
6
5
|
import { deviceBase } from './device.js';
|
|
7
|
-
import { Devices } from '../settings.js';
|
|
8
6
|
import { Subject, debounceTime, interval, skipWhile, take, tap } from 'rxjs';
|
|
9
7
|
|
|
10
8
|
import type { SwitchBotPlatform } from '../platform.js';
|
|
@@ -243,8 +241,6 @@ export class Fan extends deviceBase {
|
|
|
243
241
|
}
|
|
244
242
|
}
|
|
245
243
|
|
|
246
|
-
|
|
247
|
-
|
|
248
244
|
/**
|
|
249
245
|
* Asks the SwitchBot API for the latest device information
|
|
250
246
|
*/
|
|
@@ -264,63 +260,43 @@ export class Fan extends deviceBase {
|
|
|
264
260
|
|
|
265
261
|
async BLERefreshStatus(): Promise<void> {
|
|
266
262
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
|
|
267
|
-
const switchbot = await this.
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
.
|
|
271
|
-
|
|
272
|
-
.toLowerCase();
|
|
273
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
274
|
-
this.getCustomBLEAddress(switchbot);
|
|
275
|
-
// Start to monitor advertisement packets
|
|
276
|
-
(async () => {
|
|
263
|
+
const switchbot = await this.switchbotBLE();
|
|
264
|
+
|
|
265
|
+
if (switchbot === undefined) {
|
|
266
|
+
await this.BLERefreshConnection(switchbot);
|
|
267
|
+
} else {
|
|
277
268
|
// Start to monitor advertisement packets
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
this.
|
|
284
|
-
|
|
269
|
+
(async () => {
|
|
270
|
+
// Start to monitor advertisement packets
|
|
271
|
+
const serviceData: serviceData = await this.monitorAdvertisementPackets(switchbot);
|
|
272
|
+
// Update HomeKit
|
|
273
|
+
if (serviceData.model !== '' && serviceData.modelName !== '') {
|
|
274
|
+
await this.BLEparseStatus(serviceData);
|
|
275
|
+
await this.updateHomeKitCharacteristics();
|
|
285
276
|
} else {
|
|
286
|
-
this.
|
|
277
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed to get serviceData, serviceData: ${serviceData}`);
|
|
278
|
+
await this.BLERefreshConnection(switchbot);
|
|
287
279
|
}
|
|
288
|
-
};
|
|
289
|
-
// Wait 10 seconds
|
|
290
|
-
await switchbot.wait(this.scanDuration * 1000);
|
|
291
|
-
// Stop to monitor
|
|
292
|
-
await switchbot.stopScan();
|
|
293
|
-
// Update HomeKit
|
|
294
|
-
await this.BLEparseStatus(switchbot.onadvertisement.serviceData);
|
|
295
|
-
await this.updateHomeKitCharacteristics();
|
|
296
|
-
})();
|
|
297
|
-
if (switchbot === undefined) {
|
|
298
|
-
await this.BLERefreshConnection(switchbot);
|
|
280
|
+
})();
|
|
299
281
|
}
|
|
300
282
|
}
|
|
301
283
|
|
|
302
284
|
async openAPIRefreshStatus(): Promise<void> {
|
|
303
285
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
|
|
304
286
|
try {
|
|
305
|
-
const { body, statusCode } = await this.
|
|
306
|
-
`${Devices}/${this.device.deviceId}/status`, { headers: this.platform.generateHeaders() });
|
|
307
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
|
|
287
|
+
const { body, statusCode } = await this.deviceRefreshStatus();
|
|
308
288
|
const deviceStatus: any = await body.json();
|
|
309
|
-
this.
|
|
310
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
|
|
289
|
+
await this.refreshStatusCodes(statusCode, deviceStatus);;
|
|
311
290
|
if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
|
|
312
|
-
this.
|
|
313
|
-
|
|
314
|
-
this.
|
|
315
|
-
this.updateHomeKitCharacteristics();
|
|
291
|
+
await this.successfulRefreshStatus(statusCode, deviceStatus);
|
|
292
|
+
await this.openAPIparseStatus(deviceStatus);
|
|
293
|
+
await this.updateHomeKitCharacteristics();
|
|
316
294
|
} else {
|
|
317
|
-
this.
|
|
318
|
-
this.statusCode(deviceStatus.statusCode);
|
|
295
|
+
await this.statusCodes(statusCode, deviceStatus);
|
|
319
296
|
}
|
|
320
297
|
} catch (e: any) {
|
|
321
|
-
this.apiError(e);
|
|
322
|
-
this.
|
|
323
|
-
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
298
|
+
await this.apiError(e);
|
|
299
|
+
await this.openAPIRefreshError(e);
|
|
324
300
|
}
|
|
325
301
|
}
|
|
326
302
|
|
|
@@ -393,8 +369,7 @@ export class Fan extends deviceBase {
|
|
|
393
369
|
await this.openAPIpushChanges();
|
|
394
370
|
} else {
|
|
395
371
|
await this.offlineOff();
|
|
396
|
-
this.
|
|
397
|
-
+ ` ${this.device.connectionType}, pushChanges will not happen.`);
|
|
372
|
+
await this.pushChangeDisabled();
|
|
398
373
|
}
|
|
399
374
|
// Refresh the status from the API
|
|
400
375
|
interval(15000)
|
|
@@ -412,16 +387,9 @@ export class Fan extends deviceBase {
|
|
|
412
387
|
+ ` On: ${this.Fan.Active} OnCached: ${this.accessory.context.Active}`);
|
|
413
388
|
const switchbot = await this.platform.connectBLE();
|
|
414
389
|
// Convert to BLE Address
|
|
415
|
-
|
|
416
|
-
.deviceId!.match(/.{1,2}/g)!
|
|
417
|
-
.join(':')
|
|
418
|
-
.toLowerCase();
|
|
419
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
390
|
+
await this.convertBLEAddress();
|
|
420
391
|
switchbot
|
|
421
|
-
.discover({
|
|
422
|
-
model: this.device.bleModel,
|
|
423
|
-
id: this.device.bleMac,
|
|
424
|
-
})
|
|
392
|
+
.discover({ model: this.device.bleModel, id: this.device.bleMac })
|
|
425
393
|
.then(async (device_list: any) => {
|
|
426
394
|
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} On: ${this.Fan.Active}`);
|
|
427
395
|
return await this.retryBLE({
|
|
@@ -435,16 +403,13 @@ export class Fan extends deviceBase {
|
|
|
435
403
|
},
|
|
436
404
|
});
|
|
437
405
|
})
|
|
438
|
-
.then(() => {
|
|
439
|
-
this.
|
|
440
|
-
this.
|
|
441
|
-
+ `Active: ${this.Fan.Active} sent over BLE, sent successfully`);
|
|
442
|
-
this.Fan.Active = false;
|
|
406
|
+
.then(async () => {
|
|
407
|
+
await this.successfulPushChange_BLE('Active', this.Fan.Active, 'BLE API');
|
|
408
|
+
await this.updateHomeKitCharacteristics();
|
|
443
409
|
})
|
|
444
410
|
.catch(async (e: any) => {
|
|
445
|
-
this.apiError(e);
|
|
446
|
-
this.
|
|
447
|
-
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
411
|
+
await this.apiError(e);
|
|
412
|
+
await this.pushChangeError('BLEpushChanges', e);
|
|
448
413
|
await this.BLEPushConnection();
|
|
449
414
|
});
|
|
450
415
|
} else {
|
|
@@ -469,29 +434,19 @@ export class Fan extends deviceBase {
|
|
|
469
434
|
});
|
|
470
435
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${bodyChange},`);
|
|
471
436
|
try {
|
|
472
|
-
const { body, statusCode } = await
|
|
473
|
-
body: bodyChange,
|
|
474
|
-
method: 'POST',
|
|
475
|
-
headers: this.platform.generateHeaders(),
|
|
476
|
-
});
|
|
477
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
|
|
437
|
+
const { body, statusCode } = await this.pushChangeRequest(bodyChange);
|
|
478
438
|
const deviceStatus: any = await body.json();
|
|
479
|
-
this.
|
|
480
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus body: ${JSON.stringify(deviceStatus.body)}`);
|
|
481
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
|
|
439
|
+
await this.pushStatusCodes(statusCode, deviceStatus);
|
|
482
440
|
if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
|
|
483
|
-
this.
|
|
484
|
-
|
|
485
|
-
this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
486
|
-
+ `request to SwitchBot API, body: ${JSON.stringify(JSON.parse(bodyChange))} sent successfully`);
|
|
441
|
+
await this.successfulPushChange(statusCode, deviceStatus, bodyChange);
|
|
442
|
+
await this.updateHomeKitCharacteristics();
|
|
487
443
|
} else {
|
|
488
|
-
this.statusCode(statusCode);
|
|
489
|
-
this.statusCode(deviceStatus.statusCode);
|
|
444
|
+
await this.statusCode(statusCode);
|
|
445
|
+
await this.statusCode(deviceStatus.statusCode);
|
|
490
446
|
}
|
|
491
447
|
} catch (e: any) {
|
|
492
448
|
this.apiError(e);
|
|
493
|
-
this.
|
|
494
|
-
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
449
|
+
await this.pushChangeError('openAPIpushChanges', e);
|
|
495
450
|
}
|
|
496
451
|
} else {
|
|
497
452
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No openAPIpushChanges.`
|
|
@@ -508,88 +463,61 @@ export class Fan extends deviceBase {
|
|
|
508
463
|
}
|
|
509
464
|
|
|
510
465
|
async pushRotationSpeedChanges(): Promise<void> {
|
|
511
|
-
this.
|
|
466
|
+
await this.pushChange('pushRotationSpeedChanges');
|
|
512
467
|
if (this.Fan.SwingMode !== this.accessory.context.SwingMode) {
|
|
513
468
|
const bodyChange = JSON.stringify({
|
|
514
469
|
command: 'setWindSpeed',
|
|
515
470
|
parameter: `${this.Fan.RotationSpeed}`,
|
|
516
471
|
commandType: 'command',
|
|
517
472
|
});
|
|
518
|
-
this.
|
|
473
|
+
await this.bodyChange(bodyChange, 'SwitchBot OpenAPI');
|
|
519
474
|
try {
|
|
520
|
-
const { body, statusCode } = await
|
|
521
|
-
body: bodyChange,
|
|
522
|
-
method: 'POST',
|
|
523
|
-
headers: this.platform.generateHeaders(),
|
|
524
|
-
});
|
|
525
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
|
|
475
|
+
const { body, statusCode } = await this.pushChangeRequest(bodyChange);
|
|
526
476
|
const deviceStatus: any = await body.json();
|
|
527
|
-
this.
|
|
528
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus body: ${JSON.stringify(deviceStatus.body)}`);
|
|
529
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
|
|
477
|
+
await this.pushStatusCodes(statusCode, deviceStatus);
|
|
530
478
|
if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
|
|
531
|
-
this.
|
|
532
|
-
|
|
533
|
-
this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
534
|
-
+ `request to SwitchBot API, body: ${JSON.stringify(JSON.parse(bodyChange))} sent successfully`);
|
|
479
|
+
await this.successfulPushChange(statusCode, deviceStatus, bodyChange);
|
|
480
|
+
await this.updateHomeKitCharacteristics();
|
|
535
481
|
} else {
|
|
536
|
-
this.statusCode(statusCode);
|
|
537
|
-
this.statusCode(deviceStatus.statusCode);
|
|
482
|
+
await this.statusCode(statusCode);
|
|
483
|
+
await this.statusCode(deviceStatus.statusCode);
|
|
538
484
|
}
|
|
539
485
|
} catch (e: any) {
|
|
540
486
|
this.apiError(e);
|
|
541
|
-
this.
|
|
542
|
-
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
487
|
+
await this.pushChangeError('pushRotationSpeedChanges', e);
|
|
543
488
|
}
|
|
544
489
|
} else {
|
|
545
|
-
this.
|
|
546
|
-
+ `pushRotationSpeedChangesCached: ${this.accessory.context.RotationSpeed}`);
|
|
490
|
+
await this.noChanges('RotationSpeed', this.Fan.RotationSpeed, this.accessory.context.RotationSpeed);
|
|
547
491
|
}
|
|
548
492
|
}
|
|
549
493
|
|
|
550
494
|
async pushSwingModeChanges(): Promise<void> {
|
|
551
|
-
this.
|
|
495
|
+
await this.pushChange('pushSwingModeChanges');
|
|
552
496
|
if (this.Fan.SwingMode !== this.accessory.context.SwingMode) {
|
|
553
|
-
|
|
554
|
-
if (this.Fan.SwingMode === this.hap.Characteristic.SwingMode.SWING_ENABLED) {
|
|
555
|
-
parameter = 'on';
|
|
556
|
-
} else {
|
|
557
|
-
parameter = 'off';
|
|
558
|
-
}
|
|
497
|
+
const parameter = this.Fan.SwingMode === this.hap.Characteristic.SwingMode.SWING_ENABLED ? 'on' : 'off';
|
|
559
498
|
const bodyChange = JSON.stringify({
|
|
560
499
|
command: 'setOscillation',
|
|
561
500
|
parameter: `${parameter}`,
|
|
562
501
|
commandType: 'command',
|
|
563
502
|
});
|
|
564
|
-
this.
|
|
503
|
+
await this.bodyChange(bodyChange, 'SwitchBot OpenAPI');
|
|
565
504
|
try {
|
|
566
|
-
const { body, statusCode } = await
|
|
567
|
-
body: bodyChange,
|
|
568
|
-
method: 'POST',
|
|
569
|
-
headers: this.platform.generateHeaders(),
|
|
570
|
-
});
|
|
571
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
|
|
505
|
+
const { body, statusCode } = await this.pushChangeRequest(bodyChange);
|
|
572
506
|
const deviceStatus: any = await body.json();
|
|
573
|
-
this.
|
|
574
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus body: ${JSON.stringify(deviceStatus.body)}`);
|
|
575
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
|
|
507
|
+
await this.pushStatusCodes(statusCode, deviceStatus);
|
|
576
508
|
if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
|
|
577
|
-
this.
|
|
578
|
-
|
|
579
|
-
this.successLog(`${this.device.deviceType}: ${this.accessory.displayName} `
|
|
580
|
-
+ `request to SwitchBot API, body: ${JSON.stringify(JSON.parse(bodyChange))} sent successfully`);
|
|
509
|
+
await this.successfulPushChange(statusCode, deviceStatus, bodyChange);
|
|
510
|
+
await this.updateHomeKitCharacteristics();
|
|
581
511
|
} else {
|
|
582
|
-
this.statusCode(statusCode);
|
|
583
|
-
this.statusCode(deviceStatus.statusCode);
|
|
512
|
+
await this.statusCode(statusCode);
|
|
513
|
+
await this.statusCode(deviceStatus.statusCode);
|
|
584
514
|
}
|
|
585
515
|
} catch (e: any) {
|
|
586
516
|
this.apiError(e);
|
|
587
|
-
this.
|
|
588
|
-
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
517
|
+
await this.pushChangeError('pushSwingModeChanges', e);
|
|
589
518
|
}
|
|
590
519
|
} else {
|
|
591
|
-
this.
|
|
592
|
-
+ `SwingModeCached: ${this.accessory.context.SwingMode}`);
|
|
520
|
+
await this.noChanges('SwingMode', this.Fan.SwingMode, this.accessory.context.SwingMode);
|
|
593
521
|
}
|
|
594
522
|
}
|
|
595
523
|
|
|
@@ -597,10 +525,10 @@ export class Fan extends deviceBase {
|
|
|
597
525
|
* Handle requests to set the value of the "On" characteristic
|
|
598
526
|
*/
|
|
599
527
|
async ActiveSet(value: CharacteristicValue): Promise<void> {
|
|
600
|
-
if (this.Fan.Active
|
|
601
|
-
this.
|
|
528
|
+
if (this.Fan.Active !== this.accessory.context.Active) {
|
|
529
|
+
await this.changeSet(value, 'Active');
|
|
602
530
|
} else {
|
|
603
|
-
this.
|
|
531
|
+
await this.noChangeSet(value, 'Active');
|
|
604
532
|
}
|
|
605
533
|
|
|
606
534
|
this.Fan.Active = value;
|
|
@@ -611,10 +539,10 @@ export class Fan extends deviceBase {
|
|
|
611
539
|
* Handle requests to set the value of the "On" characteristic
|
|
612
540
|
*/
|
|
613
541
|
async RotationSpeedSet(value: CharacteristicValue): Promise<void> {
|
|
614
|
-
if (this.Fan.RotationSpeed
|
|
615
|
-
this.
|
|
542
|
+
if (this.Fan.RotationSpeed !== this.accessory.context.RotationSpeed) {
|
|
543
|
+
await this.changeSet(value, 'RotationSpeed');
|
|
616
544
|
} else {
|
|
617
|
-
this.
|
|
545
|
+
await this.noChangeSet(value, 'RotationSpeed');
|
|
618
546
|
}
|
|
619
547
|
|
|
620
548
|
this.Fan.RotationSpeed = value;
|
|
@@ -625,10 +553,10 @@ export class Fan extends deviceBase {
|
|
|
625
553
|
* Handle requests to set the value of the "On" characteristic
|
|
626
554
|
*/
|
|
627
555
|
async SwingModeSet(value: CharacteristicValue): Promise<void> {
|
|
628
|
-
if (this.Fan.SwingMode
|
|
629
|
-
this.
|
|
556
|
+
if (this.Fan.SwingMode !== this.accessory.context.SwingMode) {
|
|
557
|
+
await this.changeSet(value, 'SwingMode');
|
|
630
558
|
} else {
|
|
631
|
-
this.
|
|
559
|
+
await this.noChangeSet(value, 'SwingMode');
|
|
632
560
|
}
|
|
633
561
|
|
|
634
562
|
this.Fan.SwingMode = value;
|
|
@@ -639,10 +567,10 @@ export class Fan extends deviceBase {
|
|
|
639
567
|
* Handle requests to set the value of the "On" characteristic
|
|
640
568
|
*/
|
|
641
569
|
async OnSet(value: CharacteristicValue): Promise<void> {
|
|
642
|
-
if (this.LightBulb.On
|
|
643
|
-
this.
|
|
570
|
+
if (this.LightBulb.On !== this.accessory.context.On) {
|
|
571
|
+
await this.changeSet(value, 'On');
|
|
644
572
|
} else {
|
|
645
|
-
this.
|
|
573
|
+
await this.noChangeSet(value, 'On');
|
|
646
574
|
}
|
|
647
575
|
|
|
648
576
|
this.LightBulb.On = value;
|
|
@@ -653,12 +581,12 @@ export class Fan extends deviceBase {
|
|
|
653
581
|
* Handle requests to set the value of the "Brightness" characteristic
|
|
654
582
|
*/
|
|
655
583
|
async BrightnessSet(value: CharacteristicValue): Promise<void> {
|
|
656
|
-
if (this.LightBulb.Brightness
|
|
657
|
-
this.
|
|
584
|
+
if (this.LightBulb.Brightness !== this.accessory.context.Brightness) {
|
|
585
|
+
await this.changeSet(value, 'Brightness');
|
|
658
586
|
} else if (this.LightBulb.On) {
|
|
659
|
-
this.
|
|
587
|
+
await this.changeSet(value, 'Brightness');
|
|
660
588
|
} else {
|
|
661
|
-
this.
|
|
589
|
+
await this.noChangeSet(value, 'Brightness');
|
|
662
590
|
}
|
|
663
591
|
|
|
664
592
|
this.LightBulb.Brightness = value;
|
package/src/device/hub.ts
CHANGED
|
@@ -4,13 +4,12 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { Units } from 'homebridge';
|
|
6
6
|
import { deviceBase } from './device.js';
|
|
7
|
-
import { Devices } from '../settings.js';
|
|
8
7
|
import { convertUnits } from '../utils.js';
|
|
9
8
|
import { Subject, interval, skipWhile } from 'rxjs';
|
|
10
9
|
|
|
11
10
|
import type { SwitchBotPlatform } from '../platform.js';
|
|
12
|
-
import type { device, deviceStatus, devicesConfig } from '../settings.js';
|
|
13
11
|
import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge';
|
|
12
|
+
import type { device, devicesConfig, serviceData, deviceStatus } from '../settings.js';
|
|
14
13
|
|
|
15
14
|
export class Hub extends deviceBase {
|
|
16
15
|
// Services
|
|
@@ -152,6 +151,11 @@ export class Hub extends deviceBase {
|
|
|
152
151
|
|
|
153
152
|
}
|
|
154
153
|
|
|
154
|
+
async BLEparseStatus(serviceData: serviceData): Promise<void> {
|
|
155
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLEparseStatus`);
|
|
156
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${JSON.stringify(serviceData)}`);
|
|
157
|
+
}
|
|
158
|
+
|
|
155
159
|
async openAPIparseStatus(deviceStatus: deviceStatus): Promise<void> {
|
|
156
160
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
|
|
157
161
|
// CurrentRelativeHumidity
|
|
@@ -198,39 +202,62 @@ export class Hub extends deviceBase {
|
|
|
198
202
|
}
|
|
199
203
|
}
|
|
200
204
|
|
|
205
|
+
/**
|
|
206
|
+
* Asks the SwitchBot API for the latest device information
|
|
207
|
+
*/
|
|
201
208
|
async refreshStatus(): Promise<void> {
|
|
202
|
-
if (this.
|
|
203
|
-
this.
|
|
209
|
+
if (!this.device.enableCloudService && this.OpenAPI) {
|
|
210
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} refreshStatus enableCloudService: ${this.device.enableCloudService}`);
|
|
211
|
+
} else if (this.BLE) {
|
|
212
|
+
await this.BLERefreshStatus();
|
|
204
213
|
} else if (this.OpenAPI && this.platform.config.credentials?.token) {
|
|
205
214
|
await this.openAPIRefreshStatus();
|
|
206
215
|
} else {
|
|
207
216
|
await this.offlineOff();
|
|
208
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type
|
|
217
|
+
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} Connection Type:`
|
|
218
|
+
+ ` ${this.device.connectionType}, refreshStatus will not happen.`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
async BLERefreshStatus(): Promise<void> {
|
|
223
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLERefreshStatus`);
|
|
224
|
+
const switchbot = await this.switchbotBLE();
|
|
225
|
+
|
|
226
|
+
if (switchbot === undefined) {
|
|
227
|
+
await this.BLERefreshConnection(switchbot);
|
|
228
|
+
} else {
|
|
229
|
+
// Start to monitor advertisement packets
|
|
230
|
+
(async () => {
|
|
231
|
+
// Start to monitor advertisement packets
|
|
232
|
+
const serviceData: serviceData = await this.monitorAdvertisementPackets(switchbot);
|
|
233
|
+
// Update HomeKit
|
|
234
|
+
if (serviceData.model !== '' && serviceData.modelName !== '') {
|
|
235
|
+
await this.BLEparseStatus(serviceData);
|
|
236
|
+
await this.updateHomeKitCharacteristics();
|
|
237
|
+
} else {
|
|
238
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} failed to get serviceData, serviceData: ${serviceData}`);
|
|
239
|
+
await this.BLERefreshConnection(switchbot);
|
|
240
|
+
}
|
|
241
|
+
})();
|
|
209
242
|
}
|
|
210
243
|
}
|
|
211
244
|
|
|
212
245
|
async openAPIRefreshStatus(): Promise<void> {
|
|
213
246
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIRefreshStatus`);
|
|
214
247
|
try {
|
|
215
|
-
const { body, statusCode } = await this.
|
|
216
|
-
`${Devices}/${this.device.deviceId}/status`, { headers: this.platform.generateHeaders() });
|
|
217
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} statusCode: ${statusCode}`);
|
|
248
|
+
const { body, statusCode } = await this.deviceRefreshStatus();
|
|
218
249
|
const deviceStatus: any = await body.json();
|
|
219
|
-
this.
|
|
220
|
-
this.debugWarnLog(`${this.device.deviceType}: ${this.accessory.displayName} deviceStatus statusCode: ${deviceStatus.statusCode}`);
|
|
250
|
+
await this.refreshStatusCodes(statusCode, deviceStatus);;
|
|
221
251
|
if ((statusCode === 200 || statusCode === 100) && (deviceStatus.statusCode === 200 || deviceStatus.statusCode === 100)) {
|
|
222
|
-
this.
|
|
223
|
-
|
|
224
|
-
this.
|
|
225
|
-
this.updateHomeKitCharacteristics();
|
|
252
|
+
await this.successfulRefreshStatus(statusCode, deviceStatus);
|
|
253
|
+
await this.openAPIparseStatus(deviceStatus);
|
|
254
|
+
await this.updateHomeKitCharacteristics();
|
|
226
255
|
} else {
|
|
227
|
-
this.
|
|
228
|
-
this.statusCode(deviceStatus.statusCode);
|
|
256
|
+
await this.statusCodes(statusCode, deviceStatus);
|
|
229
257
|
}
|
|
230
258
|
} catch (e: any) {
|
|
231
|
-
this.apiError(e);
|
|
232
|
-
this.
|
|
233
|
-
+ ` Connection, Error Message: ${JSON.stringify(e.message)}`);
|
|
259
|
+
await this.apiError(e);
|
|
260
|
+
await this.openAPIRefreshError(e);
|
|
234
261
|
}
|
|
235
262
|
}
|
|
236
263
|
|
|
@@ -350,6 +377,15 @@ export class Hub extends deviceBase {
|
|
|
350
377
|
}
|
|
351
378
|
}
|
|
352
379
|
|
|
380
|
+
async BLERefreshConnection(switchbot: any): Promise<void> {
|
|
381
|
+
this.errorLog(`${this.device.deviceType}: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot:`
|
|
382
|
+
+ ` ${JSON.stringify(switchbot)}`);
|
|
383
|
+
if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
|
|
384
|
+
this.warnLog(`${this.device.deviceType}: ${this.accessory.displayName} Using OpenAPI Connection to Refresh Status`);
|
|
385
|
+
await this.openAPIRefreshStatus();
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
353
389
|
async offlineOff(): Promise<void> {
|
|
354
390
|
if (this.device.offline) {
|
|
355
391
|
if (!this.device.hub?.hide_temperature) {
|