@switchbot/homebridge-switchbot 1.8.2 → 1.10.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/.eslintrc +3 -1
- package/.github/ISSUE_TEMPLATE/bug-report.yml +3 -3
- package/.github/ISSUE_TEMPLATE/feature-request.yml +2 -2
- package/.github/ISSUE_TEMPLATE/support-request.yml +3 -3
- package/.github/labeler.yml +1 -1
- package/.github/workflows/codeql-analysis.yml +29 -29
- package/.github/workflows/nodejs-beta.yml +1 -1
- package/.github/workflows/prerelease-beta.js +1 -1
- package/.github/workflows/stale.yml +1 -1
- package/.prettierrc +9 -0
- package/.vscode/extensions.json +5 -0
- package/.vscode/settings.json +27 -0
- package/CHANGELOG.md +16 -0
- package/README.md +100 -99
- package/SECURITY.md +2 -2
- package/config.schema.json +17 -0
- package/dist/devices/bots.d.ts +4 -2
- package/dist/devices/bots.d.ts.map +1 -1
- package/dist/devices/bots.js +101 -86
- package/dist/devices/bots.js.map +1 -1
- package/dist/devices/colorbulb.d.ts +15 -15
- package/dist/devices/colorbulb.d.ts.map +1 -1
- package/dist/devices/colorbulb.js +60 -71
- package/dist/devices/colorbulb.js.map +1 -1
- package/dist/devices/contact.d.ts +2 -2
- package/dist/devices/contact.d.ts.map +1 -1
- package/dist/devices/contact.js +33 -31
- package/dist/devices/contact.js.map +1 -1
- package/dist/devices/curtains.d.ts +2 -2
- package/dist/devices/curtains.d.ts.map +1 -1
- package/dist/devices/curtains.js +71 -71
- package/dist/devices/curtains.js.map +1 -1
- package/dist/devices/humidifiers.d.ts +2 -2
- package/dist/devices/humidifiers.d.ts.map +1 -1
- package/dist/devices/humidifiers.js +74 -76
- package/dist/devices/humidifiers.js.map +1 -1
- package/dist/devices/meters.d.ts +2 -2
- package/dist/devices/meters.d.ts.map +1 -1
- package/dist/devices/meters.js +29 -27
- package/dist/devices/meters.js.map +1 -1
- package/dist/devices/motion.d.ts +2 -2
- package/dist/devices/motion.d.ts.map +1 -1
- package/dist/devices/motion.js +34 -32
- package/dist/devices/motion.js.map +1 -1
- package/dist/devices/plugs.d.ts +7 -7
- package/dist/devices/plugs.d.ts.map +1 -1
- package/dist/devices/plugs.js +18 -23
- package/dist/devices/plugs.js.map +1 -1
- package/dist/irdevices/airconditioners.d.ts +5 -2
- package/dist/irdevices/airconditioners.d.ts.map +1 -1
- package/dist/irdevices/airconditioners.js +61 -56
- package/dist/irdevices/airconditioners.js.map +1 -1
- package/dist/irdevices/airpurifiers.d.ts +2 -2
- package/dist/irdevices/airpurifiers.d.ts.map +1 -1
- package/dist/irdevices/airpurifiers.js +12 -17
- package/dist/irdevices/airpurifiers.js.map +1 -1
- package/dist/irdevices/cameras.d.ts +2 -2
- package/dist/irdevices/cameras.d.ts.map +1 -1
- package/dist/irdevices/cameras.js +10 -13
- package/dist/irdevices/cameras.js.map +1 -1
- package/dist/irdevices/fans.d.ts +2 -2
- package/dist/irdevices/fans.d.ts.map +1 -1
- package/dist/irdevices/fans.js +15 -17
- package/dist/irdevices/fans.js.map +1 -1
- package/dist/irdevices/lights.d.ts +2 -2
- package/dist/irdevices/lights.d.ts.map +1 -1
- package/dist/irdevices/lights.js +10 -13
- package/dist/irdevices/lights.js.map +1 -1
- package/dist/irdevices/others.d.ts +2 -2
- package/dist/irdevices/others.d.ts.map +1 -1
- package/dist/irdevices/others.js +10 -13
- package/dist/irdevices/others.js.map +1 -1
- package/dist/irdevices/tvs.d.ts +2 -2
- package/dist/irdevices/tvs.d.ts.map +1 -1
- package/dist/irdevices/tvs.js +22 -30
- package/dist/irdevices/tvs.js.map +1 -1
- package/dist/irdevices/vacuumcleaners.d.ts +2 -2
- package/dist/irdevices/vacuumcleaners.d.ts.map +1 -1
- package/dist/irdevices/vacuumcleaners.js +11 -13
- package/dist/irdevices/vacuumcleaners.js.map +1 -1
- package/dist/irdevices/waterheaters.d.ts +2 -2
- package/dist/irdevices/waterheaters.d.ts.map +1 -1
- package/dist/irdevices/waterheaters.js +10 -13
- package/dist/irdevices/waterheaters.js.map +1 -1
- package/dist/platform.d.ts +3 -3
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +13 -14
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +2 -0
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js.map +1 -1
- package/homebridge-ui/public/index.html +231 -245
- package/homebridge-ui/server.js +2 -4
- package/nodemon.json +2 -4
- package/package.json +18 -12
- package/src/devices/bots.ts +228 -186
- package/src/devices/colorbulb.ts +90 -84
- package/src/devices/contact.ts +85 -78
- package/src/devices/curtains.ts +152 -135
- package/src/devices/humidifiers.ts +162 -137
- package/src/devices/meters.ts +76 -73
- package/src/devices/motion.ts +87 -78
- package/src/devices/plugs.ts +27 -31
- package/src/irdevices/airconditioners.ts +91 -59
- package/src/irdevices/airpurifiers.ts +22 -23
- package/src/irdevices/cameras.ts +18 -19
- package/src/irdevices/fans.ts +27 -25
- package/src/irdevices/lights.ts +18 -20
- package/src/irdevices/others.ts +18 -19
- package/src/irdevices/tvs.ts +33 -41
- package/src/irdevices/vacuumcleaners.ts +19 -19
- package/src/irdevices/waterheaters.ts +21 -31
- package/src/platform.ts +32 -33
- package/src/settings.ts +9 -18
- package/.github/PULL_REQUEST_TEMPLATE/pull_requests.md +0 -27
package/src/devices/meters.ts
CHANGED
|
@@ -49,11 +49,7 @@ export class Meter {
|
|
|
49
49
|
meterUpdateInProgress!: boolean;
|
|
50
50
|
doMeterUpdate: Subject<void>;
|
|
51
51
|
|
|
52
|
-
constructor(
|
|
53
|
-
private readonly platform: SwitchBotPlatform,
|
|
54
|
-
private accessory: PlatformAccessory,
|
|
55
|
-
public device: device & devicesConfig,
|
|
56
|
-
) {
|
|
52
|
+
constructor(private readonly platform: SwitchBotPlatform, private accessory: PlatformAccessory, public device: device & devicesConfig) {
|
|
57
53
|
// default placeholders
|
|
58
54
|
this.logs(device);
|
|
59
55
|
this.scan(device);
|
|
@@ -71,8 +67,10 @@ export class Meter {
|
|
|
71
67
|
}
|
|
72
68
|
|
|
73
69
|
// Meter Config
|
|
74
|
-
this.debugLog(
|
|
75
|
-
|
|
70
|
+
this.debugLog(
|
|
71
|
+
`Meter: ${this.accessory.displayName} Config: (ble: ${device.ble}, hide_temperature: ${device.meter?.hide_temperature},` +
|
|
72
|
+
` hide_humidity: ${device.meter?.hide_humidity})`,
|
|
73
|
+
);
|
|
76
74
|
|
|
77
75
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
78
76
|
this.doMeterUpdate = new Subject();
|
|
@@ -96,8 +94,8 @@ export class Meter {
|
|
|
96
94
|
} else if (!this.temperatureservice) {
|
|
97
95
|
this.debugLog(`Meter: ${accessory.displayName} Add Temperature Sensor Service`);
|
|
98
96
|
(this.temperatureservice =
|
|
99
|
-
this.accessory.getService(this.platform.Service.TemperatureSensor) ||
|
|
100
|
-
|
|
97
|
+
this.accessory.getService(this.platform.Service.TemperatureSensor) || this.accessory.addService(this.platform.Service.TemperatureSensor)),
|
|
98
|
+
`${accessory.displayName} Temperature Sensor`;
|
|
101
99
|
|
|
102
100
|
this.temperatureservice.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Temperature Sensor`);
|
|
103
101
|
|
|
@@ -125,8 +123,8 @@ export class Meter {
|
|
|
125
123
|
} else if (!this.humidityservice) {
|
|
126
124
|
this.debugLog(`Meter: ${accessory.displayName} Add Humidity Sensor Service`);
|
|
127
125
|
(this.humidityservice =
|
|
128
|
-
this.accessory.getService(this.platform.Service.HumiditySensor) ||
|
|
129
|
-
|
|
126
|
+
this.accessory.getService(this.platform.Service.HumiditySensor) || this.accessory.addService(this.platform.Service.HumiditySensor)),
|
|
127
|
+
`${accessory.displayName} Humidity Sensor`;
|
|
130
128
|
|
|
131
129
|
this.humidityservice.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Humidity Sensor`);
|
|
132
130
|
|
|
@@ -149,20 +147,16 @@ export class Meter {
|
|
|
149
147
|
accessory.removeService(this.batteryService!);
|
|
150
148
|
} else if (device.ble && !this.batteryService) {
|
|
151
149
|
this.debugLog(`Meter: ${accessory.displayName} Add Battery Service`);
|
|
152
|
-
(this.batteryService =
|
|
153
|
-
|
|
154
|
-
this.accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
|
|
150
|
+
(this.batteryService = this.accessory.getService(this.platform.Service.Battery) || this.accessory.addService(this.platform.Service.Battery)),
|
|
151
|
+
`${accessory.displayName} Battery`;
|
|
155
152
|
|
|
156
153
|
this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Battery`);
|
|
157
154
|
|
|
158
155
|
this.batteryService.setCharacteristic(this.platform.Characteristic.ChargingState, this.platform.Characteristic.ChargingState.NOT_CHARGEABLE);
|
|
159
|
-
|
|
160
156
|
} else {
|
|
161
157
|
this.debugLog(`Meter: ${accessory.displayName} Battery Service Not Added`);
|
|
162
158
|
}
|
|
163
159
|
|
|
164
|
-
|
|
165
|
-
|
|
166
160
|
// Retrieve initial values and updateHomekit
|
|
167
161
|
this.updateHomeKitCharacteristics();
|
|
168
162
|
|
|
@@ -246,61 +240,70 @@ export class Meter {
|
|
|
246
240
|
this.debugLog(`Meter: ${this.accessory.displayName} BLE RefreshStatus`);
|
|
247
241
|
const switchbot = await this.platform.connectBLE();
|
|
248
242
|
// Convert to BLE Address
|
|
249
|
-
this.device.bleMac =
|
|
243
|
+
this.device.bleMac = this.device
|
|
244
|
+
.deviceId!.match(/.{1,2}/g)!
|
|
245
|
+
.join(':')
|
|
246
|
+
.toLowerCase();
|
|
250
247
|
this.debugLog(`Curtain: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
251
248
|
// Start to monitor advertisement packets
|
|
252
249
|
if (switchbot !== false) {
|
|
253
|
-
switchbot
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
250
|
+
switchbot
|
|
251
|
+
.startScan({
|
|
252
|
+
model: 'T',
|
|
253
|
+
id: this.device.bleMac,
|
|
254
|
+
})
|
|
255
|
+
.then(() => {
|
|
256
|
+
// Set an event hander
|
|
257
|
+
switchbot.onadvertisement = (ad: ad) => {
|
|
258
|
+
this.serviceData = ad.serviceData;
|
|
259
|
+
this.temperature = ad.serviceData.temperature!.c;
|
|
260
|
+
this.humidity = ad.serviceData.humidity;
|
|
261
|
+
this.battery = ad.serviceData.battery;
|
|
262
|
+
this.debugLog(`Meter: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
263
|
+
this.debugLog(
|
|
264
|
+
`Meter: ${this.accessory.displayName} model: ${ad.serviceData.model}, modelName: ${ad.serviceData.modelName}, ` +
|
|
265
|
+
`temperature: ${JSON.stringify(ad.serviceData.temperature?.c)}, humidity: ${ad.serviceData.humidity}, ` +
|
|
266
|
+
`battery: ${ad.serviceData.battery}`,
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
if (this.serviceData) {
|
|
270
|
+
this.connected = true;
|
|
271
|
+
this.debugLog(`Meter: ${this.accessory.displayName} connected: ${this.connected}`);
|
|
272
|
+
} else {
|
|
273
|
+
this.connected = false;
|
|
274
|
+
this.debugLog(`Meter: ${this.accessory.displayName} connected: ${this.connected}`);
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
// Wait 10 seconds
|
|
278
|
+
return switchbot.wait(this.scanDuration * 1000);
|
|
279
|
+
})
|
|
280
|
+
.then(async () => {
|
|
281
|
+
// Stop to monitor
|
|
282
|
+
switchbot.stopScan();
|
|
283
|
+
if (this.connected) {
|
|
284
|
+
this.parseStatus();
|
|
285
|
+
this.updateHomeKitCharacteristics();
|
|
271
286
|
} else {
|
|
272
|
-
this.
|
|
273
|
-
this.debugLog(`Meter: ${this.accessory.displayName} connected: ${this.connected}`);
|
|
287
|
+
await this.BLEconnection(switchbot);
|
|
274
288
|
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
this.
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
}
|
|
293
|
-
if (this.platform.debugMode) {
|
|
294
|
-
this.errorLog(`Meter: ${this.accessory.displayName} failed refreshStatus with BLE Connection,`
|
|
295
|
-
+ ` Error: ${JSON.stringify(e)}`);
|
|
296
|
-
}
|
|
297
|
-
if (this.platform.config.credentials?.openToken) {
|
|
298
|
-
this.warnLog(`Meter: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
299
|
-
this.SwitchToOpenAPI = true;
|
|
300
|
-
this.openAPIRefreshStatus();
|
|
301
|
-
}
|
|
302
|
-
this.apiError(e);
|
|
303
|
-
});
|
|
289
|
+
})
|
|
290
|
+
.catch(async (e: any) => {
|
|
291
|
+
this.errorLog(`Meter: ${this.accessory.displayName} failed refreshStatus with BLE Connection`);
|
|
292
|
+
if (this.deviceLogging === 'debug') {
|
|
293
|
+
this.errorLog(
|
|
294
|
+
`Meter: ${this.accessory.displayName} failed refreshStatus with BLE Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
if (this.platform.debugMode) {
|
|
298
|
+
this.errorLog(`Meter: ${this.accessory.displayName} failed refreshStatus with BLE Connection,` + ` Error: ${JSON.stringify(e)}`);
|
|
299
|
+
}
|
|
300
|
+
if (this.platform.config.credentials?.openToken) {
|
|
301
|
+
this.warnLog(`Meter: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
302
|
+
this.SwitchToOpenAPI = true;
|
|
303
|
+
this.openAPIRefreshStatus();
|
|
304
|
+
}
|
|
305
|
+
this.apiError(e);
|
|
306
|
+
});
|
|
304
307
|
} else {
|
|
305
308
|
await this.BLEconnection(switchbot);
|
|
306
309
|
}
|
|
@@ -328,12 +331,12 @@ export class Meter {
|
|
|
328
331
|
} catch (e: any) {
|
|
329
332
|
this.errorLog(`Meter: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
|
|
330
333
|
if (this.deviceLogging === 'debug') {
|
|
331
|
-
this.errorLog(
|
|
332
|
-
+ ` Error Message: ${JSON.stringify(e.message)}
|
|
334
|
+
this.errorLog(
|
|
335
|
+
`Meter: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
|
|
336
|
+
);
|
|
333
337
|
}
|
|
334
338
|
if (this.platform.debugMode) {
|
|
335
|
-
this.errorLog(`Meter: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,`
|
|
336
|
-
+ ` Error: ${JSON.stringify(e)}`);
|
|
339
|
+
this.errorLog(`Meter: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,` + ` Error: ${JSON.stringify(e)}`);
|
|
337
340
|
}
|
|
338
341
|
this.apiError(e);
|
|
339
342
|
}
|
|
@@ -453,8 +456,8 @@ export class Meter {
|
|
|
453
456
|
}
|
|
454
457
|
|
|
455
458
|
/**
|
|
456
|
-
|
|
457
|
-
|
|
459
|
+
* Logging for Device
|
|
460
|
+
*/
|
|
458
461
|
infoLog(...log: any[]) {
|
|
459
462
|
if (this.enablingDeviceLogging()) {
|
|
460
463
|
this.platform.log.info(String(...log));
|
package/src/devices/motion.ts
CHANGED
|
@@ -46,11 +46,7 @@ export class Motion {
|
|
|
46
46
|
motionUbpdateInProgress!: boolean;
|
|
47
47
|
doMotionUpdate!: Subject<void>;
|
|
48
48
|
|
|
49
|
-
constructor(
|
|
50
|
-
private readonly platform: SwitchBotPlatform,
|
|
51
|
-
private accessory: PlatformAccessory,
|
|
52
|
-
public device: device & devicesConfig,
|
|
53
|
-
) {
|
|
49
|
+
constructor(private readonly platform: SwitchBotPlatform, private accessory: PlatformAccessory, public device: device & devicesConfig) {
|
|
54
50
|
// default placeholders
|
|
55
51
|
this.logs(device);
|
|
56
52
|
this.scan(device);
|
|
@@ -59,9 +55,11 @@ export class Motion {
|
|
|
59
55
|
this.MotionDetected = false;
|
|
60
56
|
|
|
61
57
|
// Motion Config
|
|
62
|
-
this.debugLog(
|
|
63
|
-
|
|
64
|
-
|
|
58
|
+
this.debugLog(
|
|
59
|
+
`Motion Sensor: ${this.accessory.displayName} Config: (ble: ${device.ble}, offline: ${device.offline},` +
|
|
60
|
+
` hide_lightsensor: ${device.motion?.hide_lightsensor},` +
|
|
61
|
+
` set_minLux: ${this.device.motion?.set_minLux}, set_maxLux: ${this.device.motion?.set_maxLux})`,
|
|
62
|
+
);
|
|
65
63
|
|
|
66
64
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
67
65
|
this.doMotionUpdate = new Subject();
|
|
@@ -79,9 +77,8 @@ export class Motion {
|
|
|
79
77
|
|
|
80
78
|
// get the Battery service if it exists, otherwise create a new Motion service
|
|
81
79
|
// you can create multiple services for each accessory
|
|
82
|
-
(this.service =
|
|
83
|
-
|
|
84
|
-
accessory.addService(this.platform.Service.MotionSensor)), `${accessory.displayName} Motion Sensor`;
|
|
80
|
+
(this.service = accessory.getService(this.platform.Service.MotionSensor) || accessory.addService(this.platform.Service.MotionSensor)),
|
|
81
|
+
`${accessory.displayName} Motion Sensor`;
|
|
85
82
|
|
|
86
83
|
// To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
|
|
87
84
|
// when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
|
|
@@ -102,11 +99,10 @@ export class Motion {
|
|
|
102
99
|
} else if (!this.lightSensorService) {
|
|
103
100
|
this.debugLog(`Motion Sensor: ${accessory.displayName} Add Light Sensor Service`);
|
|
104
101
|
(this.lightSensorService =
|
|
105
|
-
this.accessory.getService(this.platform.Service.LightSensor) ||
|
|
106
|
-
|
|
102
|
+
this.accessory.getService(this.platform.Service.LightSensor) || this.accessory.addService(this.platform.Service.LightSensor)),
|
|
103
|
+
`${accessory.displayName} Light Sensor`;
|
|
107
104
|
|
|
108
105
|
this.lightSensorService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Light Sensor`);
|
|
109
|
-
|
|
110
106
|
} else {
|
|
111
107
|
this.debugLog(`Motion Sensor: ${accessory.displayName} Light Sensor Service Not Added`);
|
|
112
108
|
}
|
|
@@ -118,12 +114,10 @@ export class Motion {
|
|
|
118
114
|
accessory.removeService(this.batteryService!);
|
|
119
115
|
} else if (device.ble && !this.batteryService) {
|
|
120
116
|
this.debugLog(`Motion Sensor: ${accessory.displayName} Add Battery Service`);
|
|
121
|
-
(this.batteryService =
|
|
122
|
-
|
|
123
|
-
this.accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
|
|
117
|
+
(this.batteryService = this.accessory.getService(this.platform.Service.Battery) || this.accessory.addService(this.platform.Service.Battery)),
|
|
118
|
+
`${accessory.displayName} Battery`;
|
|
124
119
|
|
|
125
120
|
this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Battery`);
|
|
126
|
-
|
|
127
121
|
} else {
|
|
128
122
|
this.debugLog(`Motion Sensor: ${accessory.displayName} Battery Service Not Added`);
|
|
129
123
|
}
|
|
@@ -167,8 +161,10 @@ export class Motion {
|
|
|
167
161
|
default:
|
|
168
162
|
this.CurrentAmbientLightLevel = this.set_maxLux;
|
|
169
163
|
}
|
|
170
|
-
this.debugLog(
|
|
171
|
-
|
|
164
|
+
this.debugLog(
|
|
165
|
+
`Motion Sensor: ${this.accessory.displayName} LightLevel: ${this.lightLevel},` +
|
|
166
|
+
` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`,
|
|
167
|
+
);
|
|
172
168
|
}
|
|
173
169
|
// Battery
|
|
174
170
|
if (this.battery === undefined) {
|
|
@@ -205,7 +201,6 @@ export class Motion {
|
|
|
205
201
|
this.CurrentAmbientLightLevel = this.set_maxLux;
|
|
206
202
|
}
|
|
207
203
|
this.debugLog(`Motion Sensor: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
208
|
-
|
|
209
204
|
}
|
|
210
205
|
}
|
|
211
206
|
}
|
|
@@ -225,60 +220,70 @@ export class Motion {
|
|
|
225
220
|
this.debugLog(`Motion Sensor: ${this.accessory.displayName} BLE RefreshStatus`);
|
|
226
221
|
const switchbot = await this.platform.connectBLE();
|
|
227
222
|
// Convert to BLE Address
|
|
228
|
-
this.device.bleMac =
|
|
223
|
+
this.device.bleMac = this.device
|
|
224
|
+
.deviceId!.match(/.{1,2}/g)!
|
|
225
|
+
.join(':')
|
|
226
|
+
.toLowerCase();
|
|
229
227
|
this.debugLog(`Curtain: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
230
228
|
// Start to monitor advertisement packets
|
|
231
229
|
if (switchbot !== false) {
|
|
232
|
-
switchbot
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
230
|
+
switchbot
|
|
231
|
+
.startScan({
|
|
232
|
+
model: 's',
|
|
233
|
+
id: this.device.bleMac,
|
|
234
|
+
})
|
|
235
|
+
.then(() => {
|
|
236
|
+
// Set an event hander
|
|
237
|
+
switchbot.onadvertisement = (ad: any) => {
|
|
238
|
+
this.serviceData = ad.serviceData;
|
|
239
|
+
this.movement = ad.serviceData.movement;
|
|
240
|
+
this.battery = ad.serviceData.battery;
|
|
241
|
+
this.lightLevel = ad.serviceData.lightLevel;
|
|
242
|
+
this.debugLog(`Motion Sensor: ${this.accessory.displayName} serviceData: ${JSON.stringify(ad.serviceData)}`);
|
|
243
|
+
this.debugLog(
|
|
244
|
+
`Motion Sensor: ${this.accessory.displayName} movement: ${ad.serviceData.movement}, lightLevel: ` +
|
|
245
|
+
`${ad.serviceData.lightLevel}, battery: ${ad.serviceData.battery}`,
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
if (this.serviceData) {
|
|
249
|
+
this.connected = true;
|
|
250
|
+
this.debugLog(`Motion Sensor: ${this.accessory.displayName} connected: ${this.connected}`);
|
|
251
|
+
} else {
|
|
252
|
+
this.connected = false;
|
|
253
|
+
this.debugLog(`Motion Sensor: ${this.accessory.displayName} connected: ${this.connected}`);
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
// Wait 10 seconds
|
|
257
|
+
return switchbot.wait(this.scanDuration * 1000);
|
|
258
|
+
})
|
|
259
|
+
.then(async () => {
|
|
260
|
+
// Stop to monitor
|
|
261
|
+
switchbot.stopScan();
|
|
262
|
+
if (this.connected) {
|
|
263
|
+
this.parseStatus();
|
|
264
|
+
this.updateHomeKitCharacteristics();
|
|
249
265
|
} else {
|
|
250
|
-
this.
|
|
251
|
-
this.debugLog(`Motion Sensor: ${this.accessory.displayName} connected: ${this.connected}`);
|
|
266
|
+
await this.BLEconnection(switchbot);
|
|
252
267
|
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
this.errorLog(`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with BLE Connection,`
|
|
273
|
-
+ ` Error: ${JSON.stringify(e)}`);
|
|
274
|
-
}
|
|
275
|
-
if (this.platform.config.credentials?.openToken) {
|
|
276
|
-
this.warnLog(`Motion Sensor: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
277
|
-
this.SwitchToOpenAPI = true;
|
|
278
|
-
await this.openAPIRefreshStatus();
|
|
279
|
-
}
|
|
280
|
-
this.apiError(e);
|
|
281
|
-
});
|
|
268
|
+
})
|
|
269
|
+
.catch(async (e: any) => {
|
|
270
|
+
this.errorLog(`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with BLE Connection`);
|
|
271
|
+
if (this.deviceLogging === 'debug') {
|
|
272
|
+
this.errorLog(
|
|
273
|
+
`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with BLE Connection,` +
|
|
274
|
+
` Error Message: ${JSON.stringify(e.message)}`,
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
if (this.platform.debugMode) {
|
|
278
|
+
this.errorLog(`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with BLE Connection,` + ` Error: ${JSON.stringify(e)}`);
|
|
279
|
+
}
|
|
280
|
+
if (this.platform.config.credentials?.openToken) {
|
|
281
|
+
this.warnLog(`Motion Sensor: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
282
|
+
this.SwitchToOpenAPI = true;
|
|
283
|
+
await this.openAPIRefreshStatus();
|
|
284
|
+
}
|
|
285
|
+
this.apiError(e);
|
|
286
|
+
});
|
|
282
287
|
} else {
|
|
283
288
|
await this.BLEconnection(switchbot);
|
|
284
289
|
}
|
|
@@ -309,12 +314,15 @@ export class Motion {
|
|
|
309
314
|
} catch (e: any) {
|
|
310
315
|
this.errorLog(`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
|
|
311
316
|
if (this.deviceLogging === 'debug') {
|
|
312
|
-
this.errorLog(
|
|
313
|
-
|
|
317
|
+
this.errorLog(
|
|
318
|
+
`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,` +
|
|
319
|
+
` Error Message: ${JSON.stringify(e.message)}`,
|
|
320
|
+
);
|
|
314
321
|
}
|
|
315
322
|
if (this.platform.debugMode) {
|
|
316
|
-
this.errorLog(
|
|
317
|
-
+ ` Error: ${JSON.stringify(e)}
|
|
323
|
+
this.errorLog(
|
|
324
|
+
`Motion Sensor: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,` + ` Error: ${JSON.stringify(e)}`,
|
|
325
|
+
);
|
|
318
326
|
}
|
|
319
327
|
this.apiError(e);
|
|
320
328
|
}
|
|
@@ -348,8 +356,9 @@ export class Motion {
|
|
|
348
356
|
this.debugLog(`Motion Sensor: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
349
357
|
} else {
|
|
350
358
|
this.lightSensorService?.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, this.CurrentAmbientLightLevel);
|
|
351
|
-
this.debugLog(
|
|
352
|
-
+ ` updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}
|
|
359
|
+
this.debugLog(
|
|
360
|
+
`Motion Sensor: ${this.accessory.displayName}` + ` updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`,
|
|
361
|
+
);
|
|
353
362
|
}
|
|
354
363
|
}
|
|
355
364
|
}
|
|
@@ -445,8 +454,8 @@ export class Motion {
|
|
|
445
454
|
}
|
|
446
455
|
|
|
447
456
|
/**
|
|
448
|
-
|
|
449
|
-
|
|
457
|
+
* Logging for Device
|
|
458
|
+
*/
|
|
450
459
|
infoLog(...log: any[]) {
|
|
451
460
|
if (this.enablingDeviceLogging()) {
|
|
452
461
|
this.platform.log.info(String(...log));
|
package/src/devices/plugs.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
import { AxiosResponse } from 'axios';
|
|
3
2
|
import { interval, Subject } from 'rxjs';
|
|
4
3
|
import { SwitchBotPlatform } from '../platform';
|
|
@@ -27,11 +26,7 @@ export class Plug {
|
|
|
27
26
|
plugUpdateInProgress!: boolean;
|
|
28
27
|
doPlugUpdate!: Subject<void>;
|
|
29
28
|
|
|
30
|
-
constructor(
|
|
31
|
-
private readonly platform: SwitchBotPlatform,
|
|
32
|
-
private accessory: PlatformAccessory,
|
|
33
|
-
public device: device & devicesConfig,
|
|
34
|
-
) {
|
|
29
|
+
constructor(private readonly platform: SwitchBotPlatform, private accessory: PlatformAccessory, public device: device & devicesConfig) {
|
|
35
30
|
// default placeholders
|
|
36
31
|
this.logs(device);
|
|
37
32
|
this.scan(device);
|
|
@@ -62,9 +57,8 @@ export class Plug {
|
|
|
62
57
|
|
|
63
58
|
// get the WindowCovering service if it exists, otherwise create a new WindowCovering service
|
|
64
59
|
// you can create multiple services for each accessory
|
|
65
|
-
(this.service =
|
|
66
|
-
|
|
67
|
-
accessory.addService(this.platform.Service.Outlet)), `${device.deviceName} ${device.deviceType}`;
|
|
60
|
+
(this.service = accessory.getService(this.platform.Service.Outlet) || accessory.addService(this.platform.Service.Outlet)),
|
|
61
|
+
`${device.deviceName} ${device.deviceType}`;
|
|
68
62
|
|
|
69
63
|
// To avoid "Cannot add a Service with the same UUID another Service without also defining a unique 'subtype' property." error,
|
|
70
64
|
// when creating multiple services of the same type, you need to use the following syntax to specify a name and subtype id:
|
|
@@ -105,12 +99,10 @@ export class Plug {
|
|
|
105
99
|
} catch (e: any) {
|
|
106
100
|
this.errorLog(`Plug: ${this.accessory.displayName} failed pushChanges`);
|
|
107
101
|
if (this.deviceLogging === 'debug') {
|
|
108
|
-
this.errorLog(`Plug: ${this.accessory.displayName} failed pushChanges,`
|
|
109
|
-
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
102
|
+
this.errorLog(`Plug: ${this.accessory.displayName} failed pushChanges,` + ` Error Message: ${JSON.stringify(e.message)}`);
|
|
110
103
|
}
|
|
111
104
|
if (this.platform.debugMode) {
|
|
112
|
-
this.errorLog(`Plug: ${this.accessory.displayName} failed pushChanges,`
|
|
113
|
-
+ ` Error: ${JSON.stringify(e)}`);
|
|
105
|
+
this.errorLog(`Plug: ${this.accessory.displayName} failed pushChanges,` + ` Error: ${JSON.stringify(e)}`);
|
|
114
106
|
}
|
|
115
107
|
this.apiError(e);
|
|
116
108
|
}
|
|
@@ -139,23 +131,23 @@ export class Plug {
|
|
|
139
131
|
} catch (e: any) {
|
|
140
132
|
this.errorLog(`Plug: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection`);
|
|
141
133
|
if (this.deviceLogging === 'debug') {
|
|
142
|
-
this.errorLog(
|
|
143
|
-
+ ` Error Message: ${JSON.stringify(e.message)}
|
|
134
|
+
this.errorLog(
|
|
135
|
+
`Plug: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,` + ` Error Message: ${JSON.stringify(e.message)}`,
|
|
136
|
+
);
|
|
144
137
|
}
|
|
145
138
|
if (this.platform.debugMode) {
|
|
146
|
-
this.errorLog(`Plug: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,`
|
|
147
|
-
+ ` Error: ${JSON.stringify(e)}`);
|
|
139
|
+
this.errorLog(`Plug: ${this.accessory.displayName} failed refreshStatus with OpenAPI Connection,` + ` Error: ${JSON.stringify(e)}`);
|
|
148
140
|
}
|
|
149
141
|
this.apiError(e);
|
|
150
142
|
}
|
|
151
143
|
}
|
|
152
144
|
|
|
153
145
|
/**
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
146
|
+
* Pushes the requested changes to the SwitchBot API
|
|
147
|
+
* deviceType commandType Command command parameter Description
|
|
148
|
+
* Plug - "command" "turnOff" "default" = set to OFF state
|
|
149
|
+
* Plug - "command" "turnOn" "default" = set to ON state
|
|
150
|
+
*/
|
|
159
151
|
async pushChanges() {
|
|
160
152
|
if (this.On !== this.OnCached) {
|
|
161
153
|
const payload = {
|
|
@@ -169,11 +161,13 @@ export class Plug {
|
|
|
169
161
|
payload.command = 'turnOff';
|
|
170
162
|
}
|
|
171
163
|
|
|
172
|
-
this.infoLog(
|
|
173
|
-
|
|
164
|
+
this.infoLog(
|
|
165
|
+
`Plug: ${this.accessory.displayName} Sending request to SwitchBot API. command: ${payload.command},` +
|
|
166
|
+
` parameter: ${payload.parameter}, commandType: ${payload.commandType}`,
|
|
167
|
+
);
|
|
174
168
|
|
|
175
169
|
// Make the API request
|
|
176
|
-
const push: any =
|
|
170
|
+
const push: any = await this.platform.axios.post(`${DeviceURL}/${this.device.deviceId}/commands`, payload);
|
|
177
171
|
this.debugLog(`Plug: ${this.accessory.displayName} pushchanges: ${JSON.stringify(push.data)}`);
|
|
178
172
|
this.statusCode(push);
|
|
179
173
|
this.OnCached = this.On;
|
|
@@ -201,7 +195,7 @@ export class Plug {
|
|
|
201
195
|
//throw new this.platform.api.hap.HapStatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
202
196
|
}
|
|
203
197
|
|
|
204
|
-
private statusCode(push: AxiosResponse<{ statusCode: number
|
|
198
|
+
private statusCode(push: AxiosResponse<{ statusCode: number }>) {
|
|
205
199
|
switch (push.data.statusCode) {
|
|
206
200
|
case 151:
|
|
207
201
|
this.errorLog(`Plug: ${this.accessory.displayName} Command not supported by this device type.`);
|
|
@@ -221,8 +215,10 @@ export class Plug {
|
|
|
221
215
|
this.offlineOff();
|
|
222
216
|
break;
|
|
223
217
|
case 190:
|
|
224
|
-
this.errorLog(
|
|
225
|
-
|
|
218
|
+
this.errorLog(
|
|
219
|
+
`Plug: ${this.accessory.displayName} Device internal error due to device states not synchronized with server,` +
|
|
220
|
+
` Or command: ${JSON.stringify(push.data)} format is invalid`,
|
|
221
|
+
);
|
|
226
222
|
break;
|
|
227
223
|
case 100:
|
|
228
224
|
this.debugLog(`Plug: ${this.accessory.displayName} Command successfully sent.`);
|
|
@@ -312,8 +308,8 @@ export class Plug {
|
|
|
312
308
|
}
|
|
313
309
|
|
|
314
310
|
/**
|
|
315
|
-
|
|
316
|
-
|
|
311
|
+
* Logging for Device
|
|
312
|
+
*/
|
|
317
313
|
infoLog(...log: any[]) {
|
|
318
314
|
if (this.enablingDeviceLogging()) {
|
|
319
315
|
this.platform.log.info(String(...log));
|
|
@@ -345,4 +341,4 @@ export class Plug {
|
|
|
345
341
|
enablingDeviceLogging(): boolean {
|
|
346
342
|
return this.deviceLogging === 'debug' || this.deviceLogging === 'standard';
|
|
347
343
|
}
|
|
348
|
-
}
|
|
344
|
+
}
|