@switchbot/homebridge-switchbot 3.6.1-beta.1 → 3.6.1-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/dist/device/blindtilt.d.ts.map +1 -1
- package/dist/device/blindtilt.js +35 -17
- package/dist/device/blindtilt.js.map +1 -1
- package/dist/device/bot.d.ts +1 -2
- package/dist/device/bot.d.ts.map +1 -1
- package/dist/device/bot.js +186 -396
- package/dist/device/bot.js.map +1 -1
- package/dist/device/ceilinglight.d.ts +3 -2
- package/dist/device/ceilinglight.d.ts.map +1 -1
- package/dist/device/ceilinglight.js +56 -31
- package/dist/device/ceilinglight.js.map +1 -1
- package/dist/device/colorbulb.d.ts +3 -2
- package/dist/device/colorbulb.d.ts.map +1 -1
- package/dist/device/colorbulb.js +57 -29
- package/dist/device/colorbulb.js.map +1 -1
- package/dist/device/contact.d.ts.map +1 -1
- package/dist/device/contact.js +35 -18
- package/dist/device/contact.js.map +1 -1
- package/dist/device/curtain.d.ts.map +1 -1
- package/dist/device/curtain.js +7 -5
- package/dist/device/curtain.js.map +1 -1
- package/dist/device/device.d.ts +9 -0
- package/dist/device/device.d.ts.map +1 -1
- package/dist/device/device.js +30 -3
- package/dist/device/device.js.map +1 -1
- package/dist/device/fan.d.ts.map +1 -1
- package/dist/device/fan.js +35 -18
- package/dist/device/fan.js.map +1 -1
- package/dist/device/hub.d.ts.map +1 -1
- package/dist/device/hub.js +37 -18
- package/dist/device/hub.js.map +1 -1
- package/dist/device/humidifier.d.ts.map +1 -1
- package/dist/device/humidifier.js +39 -20
- package/dist/device/humidifier.js.map +1 -1
- package/dist/device/iosensor.d.ts.map +1 -1
- package/dist/device/iosensor.js +37 -18
- package/dist/device/iosensor.js.map +1 -1
- package/dist/device/lightstrip.d.ts +4 -3
- package/dist/device/lightstrip.d.ts.map +1 -1
- package/dist/device/lightstrip.js +57 -31
- package/dist/device/lightstrip.js.map +1 -1
- package/dist/device/lock.d.ts.map +1 -1
- package/dist/device/lock.js +36 -17
- package/dist/device/lock.js.map +1 -1
- package/dist/device/meter.d.ts.map +1 -1
- package/dist/device/meter.js +37 -18
- package/dist/device/meter.js.map +1 -1
- package/dist/device/meterplus.d.ts.map +1 -1
- package/dist/device/meterplus.js +37 -18
- package/dist/device/meterplus.js.map +1 -1
- package/dist/device/motion.d.ts.map +1 -1
- package/dist/device/motion.js +35 -16
- package/dist/device/motion.js.map +1 -1
- package/dist/device/plug.d.ts.map +1 -1
- package/dist/device/plug.js +36 -17
- package/dist/device/plug.js.map +1 -1
- package/dist/device/robotvacuumcleaner.d.ts.map +1 -1
- package/dist/device/robotvacuumcleaner.js +35 -16
- package/dist/device/robotvacuumcleaner.js.map +1 -1
- package/dist/device/waterdetector.d.ts.map +1 -1
- package/dist/device/waterdetector.js +35 -16
- package/dist/device/waterdetector.js.map +1 -1
- package/dist/irdevice/other.d.ts +1 -0
- package/dist/irdevice/other.d.ts.map +1 -1
- package/dist/irdevice/other.js +186 -228
- package/dist/irdevice/other.js.map +1 -1
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +11 -2
- package/dist/platform.js.map +1 -1
- package/dist/types/bledevicestatus.d.ts +1 -0
- package/dist/types/bledevicestatus.d.ts.map +1 -1
- package/dist/utils.d.ts +8 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +16 -0
- package/dist/utils.js.map +1 -1
- package/package.json +6 -6
- package/src/device/blindtilt.ts +32 -17
- package/src/device/bot.ts +179 -406
- package/src/device/ceilinglight.ts +53 -33
- package/src/device/colorbulb.ts +55 -31
- package/src/device/contact.ts +32 -19
- package/src/device/curtain.ts +7 -6
- package/src/device/device.ts +36 -3
- package/src/device/fan.ts +32 -19
- package/src/device/hub.ts +34 -18
- package/src/device/humidifier.ts +36 -20
- package/src/device/iosensor.ts +34 -18
- package/src/device/lightstrip.ts +56 -33
- package/src/device/lock.ts +33 -17
- package/src/device/meter.ts +34 -18
- package/src/device/meterplus.ts +34 -18
- package/src/device/motion.ts +32 -16
- package/src/device/plug.ts +33 -17
- package/src/device/robotvacuumcleaner.ts +32 -16
- package/src/device/waterdetector.ts +32 -16
- package/src/irdevice/other.ts +214 -283
- package/src/platform.ts +11 -2
- package/src/types/bledevicestatus.ts +1 -0
- package/src/utils.ts +15 -0
|
@@ -42,8 +42,9 @@ export class CeilingLight extends deviceBase {
|
|
|
42
42
|
serviceData!: ceilingLightServiceData | ceilingLightProServiceData;
|
|
43
43
|
|
|
44
44
|
// Adaptive Lighting
|
|
45
|
+
adaptiveLighting!: boolean;
|
|
46
|
+
adaptiveLightingShift!: number;
|
|
45
47
|
AdaptiveLightingController?: ControllerConstructor | Controller<ControllerServiceMap>;
|
|
46
|
-
adaptiveLightingShift?: number;
|
|
47
48
|
|
|
48
49
|
// Updates
|
|
49
50
|
ceilingLightUpdateInProgress!: boolean;
|
|
@@ -59,7 +60,7 @@ export class CeilingLight extends deviceBase {
|
|
|
59
60
|
accessory.category = this.hap.Categories.LIGHTBULB;
|
|
60
61
|
|
|
61
62
|
// default placeholders
|
|
62
|
-
this.
|
|
63
|
+
this.getAdaptiveLightingSettings(accessory, device);
|
|
63
64
|
|
|
64
65
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
65
66
|
this.doCeilingLightUpdate = new Subject();
|
|
@@ -78,23 +79,24 @@ export class CeilingLight extends deviceBase {
|
|
|
78
79
|
};
|
|
79
80
|
accessory.context.LightBulb = this.LightBulb as object;
|
|
80
81
|
|
|
81
|
-
|
|
82
|
-
if (this.adaptiveLightingShift === -1 && accessory.context.adaptiveLighting) {
|
|
82
|
+
if (this.adaptiveLighting && this.adaptiveLightingShift === -1 && this.LightBulb) {
|
|
83
83
|
accessory.removeService(this.LightBulb.Service);
|
|
84
84
|
this.LightBulb.Service = accessory.addService(this.hap.Service.Lightbulb);
|
|
85
85
|
accessory.context.adaptiveLighting = false;
|
|
86
|
-
this.debugLog(`adaptiveLighting: ${
|
|
87
|
-
}
|
|
88
|
-
if (this.adaptiveLightingShift !== -1) {
|
|
86
|
+
this.debugLog(`adaptiveLighting: ${this.adaptiveLighting}`);
|
|
87
|
+
} else if (this.adaptiveLighting && this.adaptiveLightingShift >= 0 && this.LightBulb) {
|
|
89
88
|
this.AdaptiveLightingController = new platform.api.hap.AdaptiveLightingController(this.LightBulb.Service, {
|
|
89
|
+
controllerMode: this.hap.AdaptiveLightingControllerMode.AUTOMATIC,
|
|
90
90
|
customTemperatureAdjustment: this.adaptiveLightingShift,
|
|
91
91
|
});
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
this.debugLog(`adaptiveLighting: ${this.
|
|
95
|
-
|
|
92
|
+
accessory.configureController(this.AdaptiveLightingController);
|
|
93
|
+
accessory.context.adaptiveLighting = true;
|
|
94
|
+
this.debugLog(`adaptiveLighting: ${this.adaptiveLighting}, adaptiveLightingShift: ${this.adaptiveLightingShift}`,
|
|
95
|
+
);
|
|
96
|
+
} else {
|
|
97
|
+
accessory.context.adaptiveLighting = false;
|
|
98
|
+
this.debugLog(`adaptiveLighting: ${accessory.context.adaptiveLighting}`);
|
|
96
99
|
}
|
|
97
|
-
this.debugLog(`adaptiveLightingShift: ${this.adaptiveLightingShift}`);
|
|
98
100
|
|
|
99
101
|
// Initialize LightBulb Characteristics
|
|
100
102
|
this.LightBulb.Service
|
|
@@ -166,9 +168,6 @@ export class CeilingLight extends deviceBase {
|
|
|
166
168
|
this.debugLog('Registering Webhook Event Handler');
|
|
167
169
|
this.registerWebhook();
|
|
168
170
|
|
|
169
|
-
//regisiter webhook event handler
|
|
170
|
-
this.registerWebhook();
|
|
171
|
-
|
|
172
171
|
// Start an update interval
|
|
173
172
|
interval(this.deviceRefreshRate * 1000)
|
|
174
173
|
.pipe(skipWhile(() => this.ceilingLightUpdateInProgress))
|
|
@@ -288,25 +287,41 @@ export class CeilingLight extends deviceBase {
|
|
|
288
287
|
|
|
289
288
|
async BLERefreshStatus(): Promise<void> {
|
|
290
289
|
await this.debugLog('BLERefreshStatus');
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
await this.
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
// Update HomeKit
|
|
300
|
-
if ((serviceData.model === SwitchBotBLEModel.CeilingLight || SwitchBotBLEModel.CeilingLightPro)
|
|
301
|
-
&& serviceData.modelName === SwitchBotBLEModelName.CeilingLight || SwitchBotBLEModelName.CeilingLightPro) {
|
|
302
|
-
this.serviceData = serviceData;
|
|
290
|
+
if (this.config.options?.BLE) {
|
|
291
|
+
await this.debugLog('is listening to Platform BLE.');
|
|
292
|
+
this.device.bleMac = this.device.deviceId!.match(/.{1,2}/g)!.join(':').toLowerCase();
|
|
293
|
+
await this.debugLog(`bleMac: ${this.device.bleMac}`);
|
|
294
|
+
this.platform.bleEventHandler[this.device.bleMac] = async (context: ceilingLightServiceData) => {
|
|
295
|
+
try {
|
|
296
|
+
await this.debugLog(`received BLE: ${JSON.stringify(context)}`);
|
|
297
|
+
this.serviceData = context;
|
|
303
298
|
await this.BLEparseStatus();
|
|
304
299
|
await this.updateHomeKitCharacteristics();
|
|
305
|
-
}
|
|
306
|
-
await this.errorLog(`failed to
|
|
307
|
-
await this.BLERefreshConnection(switchbot);
|
|
300
|
+
} catch (e: any) {
|
|
301
|
+
await this.errorLog(`failed to handle BLE. Received: ${JSON.stringify(context)} Error: ${e}`);
|
|
308
302
|
}
|
|
309
|
-
}
|
|
303
|
+
};
|
|
304
|
+
} else {
|
|
305
|
+
await this.debugLog('is using Device BLE Scanning.');
|
|
306
|
+
const switchbot = await this.switchbotBLE();
|
|
307
|
+
if (switchbot === undefined) {
|
|
308
|
+
await this.BLERefreshConnection(switchbot);
|
|
309
|
+
} else {
|
|
310
|
+
(async () => {
|
|
311
|
+
// Start to monitor advertisement packets
|
|
312
|
+
const serviceData = await this.monitorAdvertisementPackets(switchbot) as unknown as ceilingLightServiceData;
|
|
313
|
+
// Update HomeKit
|
|
314
|
+
if ((serviceData.model === SwitchBotBLEModel.CeilingLight || SwitchBotBLEModel.CeilingLightPro)
|
|
315
|
+
&& serviceData.modelName === SwitchBotBLEModelName.CeilingLight || SwitchBotBLEModelName.CeilingLightPro) {
|
|
316
|
+
this.serviceData = serviceData;
|
|
317
|
+
await this.BLEparseStatus();
|
|
318
|
+
await this.updateHomeKitCharacteristics();
|
|
319
|
+
} else {
|
|
320
|
+
await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
|
|
321
|
+
await this.BLERefreshConnection(switchbot);
|
|
322
|
+
}
|
|
323
|
+
})();
|
|
324
|
+
}
|
|
310
325
|
}
|
|
311
326
|
}
|
|
312
327
|
|
|
@@ -687,13 +702,18 @@ export class CeilingLight extends deviceBase {
|
|
|
687
702
|
this.LightBulb.Saturation, 'Saturation');
|
|
688
703
|
}
|
|
689
704
|
|
|
690
|
-
async
|
|
705
|
+
async getAdaptiveLightingSettings(accessory: PlatformAccessory, device: device & devicesConfig): Promise<void> {
|
|
706
|
+
// Adaptive Lighting
|
|
707
|
+
this.adaptiveLighting = accessory.context.adaptiveLighting ?? true;
|
|
708
|
+
await this.debugLog(`adaptiveLighting: ${this.adaptiveLighting}`);
|
|
709
|
+
// Adaptive Lighting Shift
|
|
691
710
|
if (device.ceilinglight?.adaptiveLightingShift) {
|
|
692
711
|
this.adaptiveLightingShift = device.ceilinglight.adaptiveLightingShift;
|
|
712
|
+
this.debugLog(`adaptiveLightingShift: ${this.adaptiveLightingShift}`);
|
|
693
713
|
} else {
|
|
694
714
|
this.adaptiveLightingShift = 0;
|
|
715
|
+
this.debugLog(`adaptiveLightingShift: ${this.adaptiveLightingShift}`);
|
|
695
716
|
}
|
|
696
|
-
await this.debugLog(`adaptiveLightingShift: ${this.adaptiveLightingShift}`);
|
|
697
717
|
}
|
|
698
718
|
|
|
699
719
|
async BLEPushConnection() {
|
package/src/device/colorbulb.ts
CHANGED
|
@@ -42,8 +42,9 @@ export class ColorBulb extends deviceBase {
|
|
|
42
42
|
serviceData!: colorBulbServiceData;
|
|
43
43
|
|
|
44
44
|
// Adaptive Lighting
|
|
45
|
+
adaptiveLighting!: boolean;
|
|
46
|
+
adaptiveLightingShift!: number;
|
|
45
47
|
AdaptiveLightingController?: ControllerConstructor | Controller<ControllerServiceMap>;
|
|
46
|
-
adaptiveLightingShift?: number;
|
|
47
48
|
|
|
48
49
|
// Updates
|
|
49
50
|
colorBulbUpdateInProgress!: boolean;
|
|
@@ -59,7 +60,7 @@ export class ColorBulb extends deviceBase {
|
|
|
59
60
|
accessory.category = this.hap.Categories.LIGHTBULB;
|
|
60
61
|
|
|
61
62
|
// default placeholders
|
|
62
|
-
this.
|
|
63
|
+
this.getAdaptiveLightingSettings(accessory, device);
|
|
63
64
|
|
|
64
65
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
65
66
|
this.doColorBulbUpdate = new Subject();
|
|
@@ -67,6 +68,10 @@ export class ColorBulb extends deviceBase {
|
|
|
67
68
|
|
|
68
69
|
// Initialize LightBulb property
|
|
69
70
|
accessory.context.LightBulb = accessory.context.LightBulb ?? {};
|
|
71
|
+
if (accessory.context.LightBulb.Name) {
|
|
72
|
+
accessory.context.LightBulb.Name = this.validateAndCleanString(accessory.context.LightBulb.Name,
|
|
73
|
+
'LightBulb Name', accessory.context.LightBulb.Name);
|
|
74
|
+
}
|
|
70
75
|
this.LightBulb = {
|
|
71
76
|
Name: accessory.context.LightBulb.Name ?? accessory.displayName,
|
|
72
77
|
Service: accessory.getService(this.hap.Service.Lightbulb) ?? accessory.addService(this.hap.Service.Lightbulb) as Service,
|
|
@@ -78,23 +83,24 @@ export class ColorBulb extends deviceBase {
|
|
|
78
83
|
};
|
|
79
84
|
accessory.context.LightBulb = this.LightBulb as object;
|
|
80
85
|
|
|
81
|
-
|
|
82
|
-
if (this.adaptiveLightingShift === -1 && accessory.context.adaptiveLighting) {
|
|
86
|
+
if (this.adaptiveLighting && this.adaptiveLightingShift === -1 && this.LightBulb) {
|
|
83
87
|
accessory.removeService(this.LightBulb.Service);
|
|
84
88
|
this.LightBulb.Service = accessory.addService(this.hap.Service.Lightbulb);
|
|
85
89
|
accessory.context.adaptiveLighting = false;
|
|
86
|
-
this.debugLog(`adaptiveLighting: ${
|
|
87
|
-
}
|
|
88
|
-
if (this.adaptiveLightingShift !== -1) {
|
|
90
|
+
this.debugLog(`adaptiveLighting: ${this.adaptiveLighting}`);
|
|
91
|
+
} else if (this.adaptiveLighting && this.adaptiveLightingShift >= 0 && this.LightBulb) {
|
|
89
92
|
this.AdaptiveLightingController = new platform.api.hap.AdaptiveLightingController(this.LightBulb.Service, {
|
|
93
|
+
controllerMode: this.hap.AdaptiveLightingControllerMode.AUTOMATIC,
|
|
90
94
|
customTemperatureAdjustment: this.adaptiveLightingShift,
|
|
91
95
|
});
|
|
92
96
|
accessory.configureController(this.AdaptiveLightingController);
|
|
93
97
|
accessory.context.adaptiveLighting = true;
|
|
94
|
-
this.debugLog(`adaptiveLighting: ${
|
|
95
|
-
|
|
98
|
+
this.debugLog(`adaptiveLighting: ${this.adaptiveLighting}, adaptiveLightingShift: ${this.adaptiveLightingShift}`,
|
|
99
|
+
);
|
|
100
|
+
} else {
|
|
101
|
+
accessory.context.adaptiveLighting = false;
|
|
102
|
+
this.debugLog(`adaptiveLighting: ${accessory.context.adaptiveLighting}`);
|
|
96
103
|
}
|
|
97
|
-
this.debugLog(`adaptiveLightingShift: ${this.adaptiveLightingShift}`);
|
|
98
104
|
|
|
99
105
|
// Initialize LightBulb Characteristics
|
|
100
106
|
this.LightBulb.Service
|
|
@@ -162,9 +168,6 @@ export class ColorBulb extends deviceBase {
|
|
|
162
168
|
this.debugLog('Registering Webhook Event Handler');
|
|
163
169
|
this.registerWebhook();
|
|
164
170
|
|
|
165
|
-
//regisiter webhook event handler
|
|
166
|
-
this.registerWebhook();
|
|
167
|
-
|
|
168
171
|
// Start an update interval
|
|
169
172
|
interval(this.deviceRefreshRate * 1000)
|
|
170
173
|
.pipe(skipWhile(() => this.colorBulbUpdateInProgress))
|
|
@@ -309,25 +312,41 @@ export class ColorBulb extends deviceBase {
|
|
|
309
312
|
|
|
310
313
|
async BLERefreshStatus(): Promise<void> {
|
|
311
314
|
await this.debugLog('BLERefreshStatus');
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
await this.
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
const serviceData = await this.monitorAdvertisementPackets(switchbot) as colorBulbServiceData;
|
|
321
|
-
// Update HomeKit
|
|
322
|
-
if (serviceData.model === SwitchBotBLEModel.ColorBulb && serviceData.modelName === SwitchBotBLEModelName.ColorBulb) {
|
|
323
|
-
this.serviceData = serviceData;
|
|
315
|
+
if (this.config.options?.BLE) {
|
|
316
|
+
await this.debugLog('is listening to Platform BLE.');
|
|
317
|
+
this.device.bleMac = this.device.deviceId!.match(/.{1,2}/g)!.join(':').toLowerCase();
|
|
318
|
+
await this.debugLog(`bleMac: ${this.device.bleMac}`);
|
|
319
|
+
this.platform.bleEventHandler[this.device.bleMac] = async (context: colorBulbServiceData) => {
|
|
320
|
+
try {
|
|
321
|
+
await this.debugLog(`received BLE: ${JSON.stringify(context)}`);
|
|
322
|
+
this.serviceData = context;
|
|
324
323
|
await this.BLEparseStatus();
|
|
325
324
|
await this.updateHomeKitCharacteristics();
|
|
326
|
-
}
|
|
327
|
-
await this.errorLog(`failed to
|
|
328
|
-
await this.BLERefreshConnection(switchbot);
|
|
325
|
+
} catch (e: any) {
|
|
326
|
+
await this.errorLog(`failed to handle BLE. Received: ${JSON.stringify(context)} Error: ${e}`);
|
|
329
327
|
}
|
|
330
|
-
}
|
|
328
|
+
};
|
|
329
|
+
} else {
|
|
330
|
+
await this.debugLog('is using Device BLE Scanning.');
|
|
331
|
+
const switchbot = await this.switchbotBLE();
|
|
332
|
+
if (switchbot === undefined) {
|
|
333
|
+
await this.BLERefreshConnection(switchbot);
|
|
334
|
+
} else {
|
|
335
|
+
// Start to monitor advertisement packets
|
|
336
|
+
(async () => {
|
|
337
|
+
// Start to monitor advertisement packets
|
|
338
|
+
const serviceData = await this.monitorAdvertisementPackets(switchbot) as colorBulbServiceData;
|
|
339
|
+
// Update HomeKit
|
|
340
|
+
if (serviceData.model === SwitchBotBLEModel.ColorBulb && serviceData.modelName === SwitchBotBLEModelName.ColorBulb) {
|
|
341
|
+
this.serviceData = serviceData;
|
|
342
|
+
await this.BLEparseStatus();
|
|
343
|
+
await this.updateHomeKitCharacteristics();
|
|
344
|
+
} else {
|
|
345
|
+
await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
|
|
346
|
+
await this.BLERefreshConnection(switchbot);
|
|
347
|
+
}
|
|
348
|
+
})();
|
|
349
|
+
}
|
|
331
350
|
}
|
|
332
351
|
}
|
|
333
352
|
|
|
@@ -820,13 +839,18 @@ export class ColorBulb extends deviceBase {
|
|
|
820
839
|
this.LightBulb.Saturation, 'Saturation');
|
|
821
840
|
}
|
|
822
841
|
|
|
823
|
-
async
|
|
842
|
+
async getAdaptiveLightingSettings(accessory: PlatformAccessory, device: device & devicesConfig): Promise<void> {
|
|
843
|
+
// Adaptive Lighting
|
|
844
|
+
this.adaptiveLighting = accessory.context.adaptiveLighting ?? true;
|
|
845
|
+
await this.debugLog(`adaptiveLighting: ${this.adaptiveLighting}`);
|
|
846
|
+
// Adaptive Lighting Shift
|
|
824
847
|
if (device.colorbulb?.adaptiveLightingShift) {
|
|
825
848
|
this.adaptiveLightingShift = device.colorbulb.adaptiveLightingShift;
|
|
849
|
+
this.debugLog(`adaptiveLightingShift: ${this.adaptiveLightingShift}`);
|
|
826
850
|
} else {
|
|
827
851
|
this.adaptiveLightingShift = 0;
|
|
852
|
+
this.debugLog(`adaptiveLightingShift: ${this.adaptiveLightingShift}`);
|
|
828
853
|
}
|
|
829
|
-
await this.debugLog(`adaptiveLightingShift: ${this.adaptiveLightingShift}`);
|
|
830
854
|
}
|
|
831
855
|
|
|
832
856
|
async BLEPushConnection() {
|
package/src/device/contact.ts
CHANGED
|
@@ -176,9 +176,6 @@ export class Contact extends deviceBase {
|
|
|
176
176
|
this.debugLog('Registering Webhook Event Handler');
|
|
177
177
|
this.registerWebhook();
|
|
178
178
|
|
|
179
|
-
//regisiter webhook event handler
|
|
180
|
-
this.registerWebhook();
|
|
181
|
-
|
|
182
179
|
// Start an update interval
|
|
183
180
|
interval(this.deviceRefreshRate * 1000)
|
|
184
181
|
.pipe(skipWhile(() => this.contactUpdateInProgress))
|
|
@@ -299,25 +296,41 @@ export class Contact extends deviceBase {
|
|
|
299
296
|
|
|
300
297
|
async BLERefreshStatus(): Promise<void> {
|
|
301
298
|
await this.debugLog('BLERefreshStatus');
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
await this.
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
const serviceData = await this.monitorAdvertisementPackets(switchbot) as contactSensorServiceData;
|
|
311
|
-
// Update HomeKit
|
|
312
|
-
if (serviceData.model === SwitchBotBLEModel.ContactSensor && serviceData.modelName === SwitchBotBLEModelName.ContactSensor) {
|
|
313
|
-
this.serviceData = serviceData;
|
|
299
|
+
if (this.config.options?.BLE) {
|
|
300
|
+
await this.debugLog('is listening to Platform BLE.');
|
|
301
|
+
this.device.bleMac = this.device.deviceId!.match(/.{1,2}/g)!.join(':').toLowerCase();
|
|
302
|
+
await this.debugLog(`bleMac: ${this.device.bleMac}`);
|
|
303
|
+
this.platform.bleEventHandler[this.device.bleMac] = async (context: contactSensorServiceData) => {
|
|
304
|
+
try {
|
|
305
|
+
await this.debugLog(`received BLE: ${JSON.stringify(context)}`);
|
|
306
|
+
this.serviceData = context;
|
|
314
307
|
await this.BLEparseStatus();
|
|
315
308
|
await this.updateHomeKitCharacteristics();
|
|
316
|
-
}
|
|
317
|
-
await this.errorLog(`failed to
|
|
318
|
-
await this.BLERefreshConnection(switchbot);
|
|
309
|
+
} catch (e: any) {
|
|
310
|
+
await this.errorLog(`failed to handle BLE. Received: ${JSON.stringify(context)} Error: ${e}`);
|
|
319
311
|
}
|
|
320
|
-
}
|
|
312
|
+
};
|
|
313
|
+
} else {
|
|
314
|
+
await this.debugLog('is using Device BLE Scanning.');
|
|
315
|
+
const switchbot = await this.switchbotBLE();
|
|
316
|
+
if (switchbot === undefined) {
|
|
317
|
+
await this.BLERefreshConnection(switchbot);
|
|
318
|
+
} else {
|
|
319
|
+
// Start to monitor advertisement packets
|
|
320
|
+
(async () => {
|
|
321
|
+
// Start to monitor advertisement packets
|
|
322
|
+
const serviceData = await this.monitorAdvertisementPackets(switchbot) as contactSensorServiceData;
|
|
323
|
+
// Update HomeKit
|
|
324
|
+
if (serviceData.model === SwitchBotBLEModel.ContactSensor && serviceData.modelName === SwitchBotBLEModelName.ContactSensor) {
|
|
325
|
+
this.serviceData = serviceData;
|
|
326
|
+
await this.BLEparseStatus();
|
|
327
|
+
await this.updateHomeKitCharacteristics();
|
|
328
|
+
} else {
|
|
329
|
+
await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
|
|
330
|
+
await this.BLERefreshConnection(switchbot);
|
|
331
|
+
}
|
|
332
|
+
})();
|
|
333
|
+
}
|
|
321
334
|
}
|
|
322
335
|
}
|
|
323
336
|
|
package/src/device/curtain.ts
CHANGED
|
@@ -438,21 +438,22 @@ export class Curtain extends deviceBase {
|
|
|
438
438
|
async BLERefreshStatus(): Promise<void> {
|
|
439
439
|
await this.debugLog('BLERefreshStatus');
|
|
440
440
|
if (this.config.options?.BLE) {
|
|
441
|
-
await this.debugLog('is listening to BLE.');
|
|
442
|
-
this.
|
|
441
|
+
await this.debugLog('is listening to Platform BLE.');
|
|
442
|
+
this.device.bleMac = this.device.deviceId!.match(/.{1,2}/g)!.join(':').toLowerCase();
|
|
443
|
+
await this.debugLog(`bleMac: ${this.device.bleMac}`);
|
|
444
|
+
this.platform.bleEventHandler[this.device.bleMac] = async (context: curtainServiceData | curtain3ServiceData) => {
|
|
443
445
|
try {
|
|
444
|
-
await this.debugLog(`received
|
|
446
|
+
await this.debugLog(`received BLE: ${JSON.stringify(context)}`);
|
|
445
447
|
this.serviceData = context;
|
|
446
|
-
await this.
|
|
448
|
+
await this.BLEparseStatus();
|
|
447
449
|
await this.updateHomeKitCharacteristics();
|
|
448
450
|
} catch (e: any) {
|
|
449
451
|
await this.errorLog(`failed to handle BLE. Received: ${JSON.stringify(context)} Error: ${e}`);
|
|
450
452
|
}
|
|
451
453
|
};
|
|
452
454
|
} else {
|
|
453
|
-
await this.debugLog('is
|
|
455
|
+
await this.debugLog('is using Device BLE Scanning.');
|
|
454
456
|
const switchbot = await this.switchbotBLE();
|
|
455
|
-
|
|
456
457
|
if (switchbot === undefined) {
|
|
457
458
|
await this.BLERefreshConnection(switchbot);
|
|
458
459
|
} else {
|
package/src/device/device.ts
CHANGED
|
@@ -79,13 +79,20 @@ export abstract class deviceBase {
|
|
|
79
79
|
.getService(this.hap.Service.AccessoryInformation)!
|
|
80
80
|
.setCharacteristic(this.hap.Characteristic.Manufacturer, 'SwitchBot')
|
|
81
81
|
.setCharacteristic(this.hap.Characteristic.AppMatchingIdentifier, 'id1087374760')
|
|
82
|
-
.setCharacteristic(this.hap.Characteristic.Name,
|
|
83
|
-
.setCharacteristic(this.hap.Characteristic.ConfiguredName,
|
|
82
|
+
.setCharacteristic(this.hap.Characteristic.Name, this.validName(accessory, device))
|
|
83
|
+
.setCharacteristic(this.hap.Characteristic.ConfiguredName, this.validName(accessory, device))
|
|
84
84
|
.setCharacteristic(this.hap.Characteristic.Model, device.model ?? accessory.context.model)
|
|
85
85
|
.setCharacteristic(this.hap.Characteristic.ProductData, device.deviceId ?? accessory.context.deviceId)
|
|
86
86
|
.setCharacteristic(this.hap.Characteristic.SerialNumber, device.deviceId);
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
public validName(accessory: PlatformAccessory, device: device & devicesConfig) {
|
|
90
|
+
const Name = device.configDeviceName ?? device.deviceName ?? accessory.displayName;
|
|
91
|
+
const NameOfName = device.configDeviceName ? 'configDeviceName' : device.deviceName ? 'deviceName' : 'displayName';
|
|
92
|
+
const validName = this.validateAndCleanString(Name, NameOfName, Name);
|
|
93
|
+
return validName;
|
|
94
|
+
}
|
|
95
|
+
|
|
89
96
|
async getDeviceLogSettings(accessory: PlatformAccessory, device: device & devicesConfig): Promise<void> {
|
|
90
97
|
this.deviceLogging = this.platform.debugMode ? 'debugMode' : device.logging ?? this.config.logging ?? 'standard';
|
|
91
98
|
const logging = this.platform.debugMode ? 'Debug Mode' : device.logging ? 'Device Config' : this.config.logging ? 'Platform Config' : 'Default';
|
|
@@ -374,7 +381,7 @@ export abstract class deviceBase {
|
|
|
374
381
|
this.debugLog(`serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
375
382
|
}
|
|
376
383
|
};
|
|
377
|
-
// Wait
|
|
384
|
+
// Wait
|
|
378
385
|
await switchbot.wait(this.scanDuration * 1000);
|
|
379
386
|
// Stop to monitor
|
|
380
387
|
await switchbot.stopScan();
|
|
@@ -765,6 +772,32 @@ export abstract class deviceBase {
|
|
|
765
772
|
}
|
|
766
773
|
}
|
|
767
774
|
|
|
775
|
+
/**
|
|
776
|
+
* Validate and clean a string value for a Name Characteristic.
|
|
777
|
+
* @param displayName
|
|
778
|
+
* @param name
|
|
779
|
+
* @param value
|
|
780
|
+
* @returns string value
|
|
781
|
+
*/
|
|
782
|
+
validateAndCleanString(displayName: string, name: string, value: string): string {
|
|
783
|
+
const validPattern = /^[a-zA-Z0-9][a-zA-Z0-9 ']*[a-zA-Z0-9]$/;
|
|
784
|
+
const invalidCharsPattern = /[^a-zA-Z0-9 ']/g;
|
|
785
|
+
|
|
786
|
+
if (!validPattern.test(value)) {
|
|
787
|
+
this.warnLog(`WARNING: The accessory '${displayName}' has an invalid '${name}' characteristic ('${value}'). Please use only alphanumeric,`
|
|
788
|
+
+ ' space, and apostrophe characters. Ensure it starts and ends with an alphabetic or numeric character, and avoid emojis. This may'
|
|
789
|
+
+ ' prevent the accessory from being added in the Home App or cause unresponsiveness.');
|
|
790
|
+
|
|
791
|
+
// Remove invalid characters
|
|
792
|
+
value = value.replace(invalidCharsPattern, '');
|
|
793
|
+
|
|
794
|
+
// Ensure it starts and ends with an alphanumeric character
|
|
795
|
+
value = value.replace(/^[^a-zA-Z0-9]+|[^a-zA-Z0-9]+$/g, '');
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
return value;
|
|
799
|
+
}
|
|
800
|
+
|
|
768
801
|
/**
|
|
769
802
|
* Logging for Device
|
|
770
803
|
*/
|
package/src/device/fan.ts
CHANGED
|
@@ -168,9 +168,6 @@ export class Fan extends deviceBase {
|
|
|
168
168
|
this.debugLog('Registering Webhook Event Handler');
|
|
169
169
|
this.registerWebhook();
|
|
170
170
|
|
|
171
|
-
//regisiter webhook event handler
|
|
172
|
-
this.registerWebhook();
|
|
173
|
-
|
|
174
171
|
// Start an update interval
|
|
175
172
|
interval(this.deviceRefreshRate * 1000)
|
|
176
173
|
.pipe(skipWhile(() => this.fanUpdateInProgress))
|
|
@@ -326,25 +323,41 @@ export class Fan extends deviceBase {
|
|
|
326
323
|
|
|
327
324
|
async BLERefreshStatus(): Promise<void> {
|
|
328
325
|
await this.debugLog('BLERefreshStatus');
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
await this.
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
const serviceData = await this.monitorAdvertisementPackets(switchbot) as batteryCirculatorFanServiceData;
|
|
338
|
-
// Update HomeKit
|
|
339
|
-
if (serviceData.model === SwitchBotBLEModel.Unknown && SwitchBotBLEModelName.Unknown) {
|
|
340
|
-
this.serviceData = serviceData;
|
|
326
|
+
if (this.config.options?.BLE) {
|
|
327
|
+
await this.debugLog('is listening to Platform BLE.');
|
|
328
|
+
this.device.bleMac = this.device.deviceId!.match(/.{1,2}/g)!.join(':').toLowerCase();
|
|
329
|
+
await this.debugLog(`bleMac: ${this.device.bleMac}`);
|
|
330
|
+
this.platform.bleEventHandler[this.device.bleMac] = async (context: batteryCirculatorFanServiceData) => {
|
|
331
|
+
try {
|
|
332
|
+
await this.debugLog(`received BLE: ${JSON.stringify(context)}`);
|
|
333
|
+
this.serviceData = context;
|
|
341
334
|
await this.BLEparseStatus();
|
|
342
335
|
await this.updateHomeKitCharacteristics();
|
|
343
|
-
}
|
|
344
|
-
await this.errorLog(`failed to
|
|
345
|
-
await this.BLERefreshConnection(switchbot);
|
|
336
|
+
} catch (e: any) {
|
|
337
|
+
await this.errorLog(`failed to handle BLE. Received: ${JSON.stringify(context)} Error: ${e}`);
|
|
346
338
|
}
|
|
347
|
-
}
|
|
339
|
+
};
|
|
340
|
+
} else {
|
|
341
|
+
await this.debugLog('is using Device BLE Scanning.');
|
|
342
|
+
const switchbot = await this.switchbotBLE();
|
|
343
|
+
if (switchbot === undefined) {
|
|
344
|
+
await this.BLERefreshConnection(switchbot);
|
|
345
|
+
} else {
|
|
346
|
+
// Start to monitor advertisement packets
|
|
347
|
+
(async () => {
|
|
348
|
+
// Start to monitor advertisement packets
|
|
349
|
+
const serviceData = await this.monitorAdvertisementPackets(switchbot) as batteryCirculatorFanServiceData;
|
|
350
|
+
// Update HomeKit
|
|
351
|
+
if (serviceData.model === SwitchBotBLEModel.Unknown && SwitchBotBLEModelName.Unknown) {
|
|
352
|
+
this.serviceData = serviceData;
|
|
353
|
+
await this.BLEparseStatus();
|
|
354
|
+
await this.updateHomeKitCharacteristics();
|
|
355
|
+
} else {
|
|
356
|
+
await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
|
|
357
|
+
await this.BLERefreshConnection(switchbot);
|
|
358
|
+
}
|
|
359
|
+
})();
|
|
360
|
+
}
|
|
348
361
|
}
|
|
349
362
|
}
|
|
350
363
|
|
package/src/device/hub.ts
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { Units } from 'homebridge';
|
|
6
6
|
import { deviceBase } from './device.js';
|
|
7
|
-
import { convertUnits } from '../utils.js';
|
|
8
7
|
import { Subject, interval, skipWhile} from 'rxjs';
|
|
8
|
+
import { validHumidity, convertUnits } from '../utils.js';
|
|
9
9
|
import { SwitchBotBLEModel, SwitchBotBLEModelName } from 'node-switchbot';
|
|
10
10
|
|
|
11
11
|
import type { devicesConfig } from '../settings.js';
|
|
@@ -181,7 +181,7 @@ export class Hub extends deviceBase {
|
|
|
181
181
|
|
|
182
182
|
// CurrentRelativeHumidity
|
|
183
183
|
if (!this.device.hub?.hide_humidity && this.HumiditySensor?.Service) {
|
|
184
|
-
this.HumiditySensor!.CurrentRelativeHumidity = this.serviceData.humidity;
|
|
184
|
+
this.HumiditySensor!.CurrentRelativeHumidity = validHumidity(this.serviceData.humidity, 0, 100);
|
|
185
185
|
await this.debugLog(`CurrentRelativeHumidity: ${this.HumiditySensor.CurrentRelativeHumidity}%`);
|
|
186
186
|
}
|
|
187
187
|
|
|
@@ -290,25 +290,41 @@ export class Hub extends deviceBase {
|
|
|
290
290
|
|
|
291
291
|
async BLERefreshStatus(): Promise<void> {
|
|
292
292
|
await this.debugLog('BLERefreshStatus');
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
await this.
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
const serviceData = await this.monitorAdvertisementPackets(switchbot) as hub2ServiceData;
|
|
302
|
-
// Update HomeKit
|
|
303
|
-
if (serviceData.model === SwitchBotBLEModel.Hub2 && serviceData.modelName === SwitchBotBLEModelName.Hub2) {
|
|
304
|
-
this.serviceData = serviceData;
|
|
293
|
+
if (this.config.options?.BLE) {
|
|
294
|
+
await this.debugLog('is listening to Platform BLE.');
|
|
295
|
+
this.device.bleMac = this.device.deviceId!.match(/.{1,2}/g)!.join(':').toLowerCase();
|
|
296
|
+
await this.debugLog(`bleMac: ${this.device.bleMac}`);
|
|
297
|
+
this.platform.bleEventHandler[this.device.bleMac] = async (context: hub2ServiceData) => {
|
|
298
|
+
try {
|
|
299
|
+
await this.debugLog(`received BLE: ${JSON.stringify(context)}`);
|
|
300
|
+
this.serviceData = context;
|
|
305
301
|
await this.BLEparseStatus();
|
|
306
302
|
await this.updateHomeKitCharacteristics();
|
|
307
|
-
}
|
|
308
|
-
await this.errorLog(`failed to
|
|
309
|
-
await this.BLERefreshConnection(switchbot);
|
|
303
|
+
} catch (e: any) {
|
|
304
|
+
await this.errorLog(`failed to handle BLE. Received: ${JSON.stringify(context)} Error: ${e}`);
|
|
310
305
|
}
|
|
311
|
-
}
|
|
306
|
+
};
|
|
307
|
+
} else {
|
|
308
|
+
await this.debugLog('is using Device BLE Scanning.');
|
|
309
|
+
const switchbot = await this.switchbotBLE();
|
|
310
|
+
if (switchbot === undefined) {
|
|
311
|
+
await this.BLERefreshConnection(switchbot);
|
|
312
|
+
} else {
|
|
313
|
+
// Start to monitor advertisement packets
|
|
314
|
+
(async () => {
|
|
315
|
+
// Start to monitor advertisement packets
|
|
316
|
+
const serviceData = await this.monitorAdvertisementPackets(switchbot) as hub2ServiceData;
|
|
317
|
+
// Update HomeKit
|
|
318
|
+
if (serviceData.model === SwitchBotBLEModel.Hub2 && serviceData.modelName === SwitchBotBLEModelName.Hub2) {
|
|
319
|
+
this.serviceData = serviceData;
|
|
320
|
+
await this.BLEparseStatus();
|
|
321
|
+
await this.updateHomeKitCharacteristics();
|
|
322
|
+
} else {
|
|
323
|
+
await this.errorLog(`failed to get serviceData, serviceData: ${serviceData}`);
|
|
324
|
+
await this.BLERefreshConnection(switchbot);
|
|
325
|
+
}
|
|
326
|
+
})();
|
|
327
|
+
}
|
|
312
328
|
}
|
|
313
329
|
}
|
|
314
330
|
|