@switchbot/homebridge-switchbot 1.7.1-beta.1 → 1.7.1-beta.13
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 +9 -2
- package/config.schema.json +49 -36
- package/dist/devices/bots.d.ts +7 -5
- package/dist/devices/bots.d.ts.map +1 -1
- package/dist/devices/bots.js +72 -66
- package/dist/devices/bots.js.map +1 -1
- package/dist/devices/colorbulb.d.ts +9 -4
- package/dist/devices/colorbulb.d.ts.map +1 -1
- package/dist/devices/colorbulb.js +50 -37
- package/dist/devices/colorbulb.js.map +1 -1
- package/dist/devices/contact.d.ts +9 -10
- package/dist/devices/contact.d.ts.map +1 -1
- package/dist/devices/contact.js +105 -137
- package/dist/devices/contact.js.map +1 -1
- package/dist/devices/curtains.d.ts +11 -4
- package/dist/devices/curtains.d.ts.map +1 -1
- package/dist/devices/curtains.js +70 -44
- package/dist/devices/curtains.js.map +1 -1
- package/dist/devices/humidifiers.d.ts +8 -2
- package/dist/devices/humidifiers.d.ts.map +1 -1
- package/dist/devices/humidifiers.js +42 -36
- package/dist/devices/humidifiers.js.map +1 -1
- package/dist/devices/meters.d.ts +17 -15
- package/dist/devices/meters.d.ts.map +1 -1
- package/dist/devices/meters.js +99 -133
- package/dist/devices/meters.js.map +1 -1
- package/dist/devices/motion.d.ts +8 -9
- package/dist/devices/motion.d.ts.map +1 -1
- package/dist/devices/motion.js +97 -120
- package/dist/devices/motion.js.map +1 -1
- package/dist/devices/plugs.d.ts +6 -4
- package/dist/devices/plugs.d.ts.map +1 -1
- package/dist/devices/plugs.js +44 -31
- package/dist/devices/plugs.js.map +1 -1
- package/dist/irdevices/airconditioners.d.ts +2 -1
- package/dist/irdevices/airconditioners.d.ts.map +1 -1
- package/dist/irdevices/airconditioners.js +19 -12
- package/dist/irdevices/airconditioners.js.map +1 -1
- package/dist/irdevices/airpurifiers.d.ts +4 -3
- package/dist/irdevices/airpurifiers.d.ts.map +1 -1
- package/dist/irdevices/airpurifiers.js +23 -16
- package/dist/irdevices/airpurifiers.js.map +1 -1
- package/dist/irdevices/cameras.d.ts +2 -1
- package/dist/irdevices/cameras.d.ts.map +1 -1
- package/dist/irdevices/cameras.js +19 -12
- package/dist/irdevices/cameras.js.map +1 -1
- package/dist/irdevices/fans.d.ts +2 -1
- package/dist/irdevices/fans.d.ts.map +1 -1
- package/dist/irdevices/fans.js +19 -12
- package/dist/irdevices/fans.js.map +1 -1
- package/dist/irdevices/lights.d.ts +2 -1
- package/dist/irdevices/lights.d.ts.map +1 -1
- package/dist/irdevices/lights.js +19 -12
- package/dist/irdevices/lights.js.map +1 -1
- package/dist/irdevices/others.d.ts +3 -2
- package/dist/irdevices/others.d.ts.map +1 -1
- package/dist/irdevices/others.js +23 -16
- package/dist/irdevices/others.js.map +1 -1
- package/dist/irdevices/tvs.d.ts +2 -1
- package/dist/irdevices/tvs.d.ts.map +1 -1
- package/dist/irdevices/tvs.js +19 -12
- package/dist/irdevices/tvs.js.map +1 -1
- package/dist/irdevices/vacuumcleaners.d.ts +2 -1
- package/dist/irdevices/vacuumcleaners.d.ts.map +1 -1
- package/dist/irdevices/vacuumcleaners.js +19 -12
- package/dist/irdevices/vacuumcleaners.js.map +1 -1
- package/dist/irdevices/waterheaters.d.ts +2 -1
- package/dist/irdevices/waterheaters.d.ts.map +1 -1
- package/dist/irdevices/waterheaters.js +19 -12
- package/dist/irdevices/waterheaters.js.map +1 -1
- package/dist/platform.d.ts +2 -1
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +14 -1
- package/dist/platform.js.map +1 -1
- package/dist/settings.d.ts +7 -1
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js.map +1 -1
- package/package.json +5 -5
- package/src/devices/bots.ts +75 -70
- package/src/devices/colorbulb.ts +56 -40
- package/src/devices/contact.ts +108 -138
- package/src/devices/curtains.ts +79 -48
- package/src/devices/humidifiers.ts +50 -37
- package/src/devices/meters.ts +115 -143
- package/src/devices/motion.ts +102 -121
- package/src/devices/plugs.ts +47 -32
- package/src/irdevices/airconditioners.ts +20 -12
- package/src/irdevices/airpurifiers.ts +24 -16
- package/src/irdevices/cameras.ts +20 -12
- package/src/irdevices/fans.ts +20 -12
- package/src/irdevices/lights.ts +20 -12
- package/src/irdevices/others.ts +24 -16
- package/src/irdevices/tvs.ts +20 -12
- package/src/irdevices/vacuumcleaners.ts +20 -12
- package/src/irdevices/waterheaters.ts +20 -12
- package/src/platform.ts +14 -1
- package/src/settings.ts +7 -1
package/src/devices/contact.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { interval, Subject } from 'rxjs';
|
|
|
2
2
|
import { skipWhile } from 'rxjs/operators';
|
|
3
3
|
import { SwitchBotPlatform } from '../platform';
|
|
4
4
|
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
5
|
-
import { DeviceURL, device, devicesConfig, serviceData, switchbot, deviceStatusResponse } from '../settings';
|
|
5
|
+
import { DeviceURL, device, devicesConfig, serviceData, switchbot, deviceStatusResponse, deviceStatus } from '../settings';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Platform Accessory
|
|
@@ -24,11 +24,15 @@ export class Contact {
|
|
|
24
24
|
StatusLowBattery!: CharacteristicValue;
|
|
25
25
|
|
|
26
26
|
// OpenAPI others
|
|
27
|
+
openState: deviceStatus['openState'];
|
|
28
|
+
moveDetected: deviceStatus['moveDetected'];
|
|
29
|
+
brightness: deviceStatus['brightness'];
|
|
27
30
|
deviceStatus!: deviceStatusResponse;
|
|
28
31
|
|
|
29
32
|
// BLE Others
|
|
30
33
|
connected?: boolean;
|
|
31
34
|
switchbot!: switchbot;
|
|
35
|
+
SwitchToOpenAPI!: boolean;
|
|
32
36
|
serviceData!: serviceData;
|
|
33
37
|
battery!: serviceData['battery'];
|
|
34
38
|
movement!: serviceData['movement'];
|
|
@@ -52,16 +56,12 @@ export class Contact {
|
|
|
52
56
|
public device: device & devicesConfig,
|
|
53
57
|
) {
|
|
54
58
|
// default placeholders
|
|
55
|
-
this.logs();
|
|
56
|
-
this.scan();
|
|
57
|
-
this.refreshRate();
|
|
59
|
+
this.logs(device);
|
|
60
|
+
this.scan(device);
|
|
61
|
+
this.refreshRate(device);
|
|
62
|
+
this.config(device);
|
|
58
63
|
this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_DETECTED;
|
|
59
64
|
|
|
60
|
-
// Contact Config
|
|
61
|
-
this.debugLog(`Contact Sensor: ${this.accessory.displayName} Config: (ble: ${device.ble}, offline: ${device.offline},`
|
|
62
|
-
+ ` hide_lightsensor: ${device.contact?.hide_lightsensor}, hide_motionsensor: ${device.contact?.hide_motionsensor},`
|
|
63
|
-
+ ` set_minLux: ${this.device.contact?.set_minLux}, set_maxLux: ${this.device.contact?.set_maxLux})`);
|
|
64
|
-
|
|
65
65
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
66
66
|
this.doContactUpdate = new Subject();
|
|
67
67
|
this.contactUbpdateInProgress = false;
|
|
@@ -128,12 +128,20 @@ export class Contact {
|
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
// Battery Service
|
|
131
|
-
if (device.ble) {
|
|
131
|
+
if (!device.ble) {
|
|
132
|
+
this.debugLog(`Contact Sensor: ${accessory.displayName} Removing Battery Service`);
|
|
133
|
+
this.batteryService = this.accessory.getService(this.platform.Service.Battery);
|
|
134
|
+
accessory.removeService(this.batteryService!);
|
|
135
|
+
} else if (device.ble && !this.batteryService) {
|
|
136
|
+
this.debugLog(`Contact Sensor: ${accessory.displayName} Add Battery Service`);
|
|
132
137
|
(this.batteryService =
|
|
133
|
-
accessory.getService(this.platform.Service.Battery) ||
|
|
134
|
-
accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
|
|
138
|
+
this.accessory.getService(this.platform.Service.Battery) ||
|
|
139
|
+
this.accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
|
|
135
140
|
|
|
136
141
|
this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Battery`);
|
|
142
|
+
|
|
143
|
+
} else {
|
|
144
|
+
this.debugLog(`Contact Sensor: ${accessory.displayName} Battery Service Not Added`);
|
|
137
145
|
}
|
|
138
146
|
|
|
139
147
|
// Retrieve initial values and updateHomekit
|
|
@@ -147,50 +155,62 @@ export class Contact {
|
|
|
147
155
|
});
|
|
148
156
|
}
|
|
149
157
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
158
|
+
config(device: device & devicesConfig) {
|
|
159
|
+
const config: any = device.contact;
|
|
160
|
+
if (device.ble !== undefined) {
|
|
161
|
+
config['ble'] = device.ble;
|
|
162
|
+
}
|
|
163
|
+
if (device.logging !== undefined) {
|
|
164
|
+
config['logging'] = device.logging;
|
|
165
|
+
}
|
|
166
|
+
if (device.refreshRate !== undefined) {
|
|
167
|
+
config['refreshRate'] = device.refreshRate;
|
|
168
|
+
}
|
|
169
|
+
if (device.scanDuration !== undefined) {
|
|
170
|
+
config['scanDuration'] = device.scanDuration;
|
|
171
|
+
}
|
|
172
|
+
if (config !== undefined) {
|
|
173
|
+
this.warnLog(`Contact Sensor: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
refreshRate(device: device & devicesConfig) {
|
|
178
|
+
if (device.refreshRate) {
|
|
179
|
+
this.deviceRefreshRate = this.accessory.context.refreshRate = device.refreshRate;
|
|
180
|
+
this.debugLog(`Contact Sensor: ${this.accessory.displayName} Using Device Config refreshRate: ${this.deviceRefreshRate}`);
|
|
156
181
|
} else if (this.platform.config.options!.refreshRate) {
|
|
157
182
|
this.deviceRefreshRate = this.accessory.context.refreshRate = this.platform.config.options!.refreshRate;
|
|
158
|
-
|
|
159
|
-
this.warnLog(`Contact Sensor: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
|
|
160
|
-
}
|
|
183
|
+
this.debugLog(`Contact Sensor: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
|
|
161
184
|
}
|
|
162
185
|
}
|
|
163
186
|
|
|
164
|
-
scan() {
|
|
165
|
-
if (
|
|
166
|
-
this.scanDuration = this.accessory.context.scanDuration =
|
|
167
|
-
if (
|
|
168
|
-
this.
|
|
187
|
+
scan(device: device & devicesConfig) {
|
|
188
|
+
if (device.scanDuration) {
|
|
189
|
+
this.scanDuration = this.accessory.context.scanDuration = device.scanDuration;
|
|
190
|
+
if (device.ble) {
|
|
191
|
+
this.debugLog(`Contact Sensor: ${this.accessory.displayName} Using Device Config scanDuration: ${this.scanDuration}`);
|
|
169
192
|
}
|
|
170
193
|
} else {
|
|
171
194
|
this.scanDuration = this.accessory.context.scanDuration = 1;
|
|
172
|
-
if (this.
|
|
173
|
-
this.
|
|
195
|
+
if (this.device.ble) {
|
|
196
|
+
this.debugLog(`Contact Sensor: ${this.accessory.displayName} Using Default scanDuration: ${this.scanDuration}`);
|
|
174
197
|
}
|
|
175
198
|
}
|
|
176
199
|
}
|
|
177
200
|
|
|
178
|
-
logs() {
|
|
201
|
+
logs(device: device & devicesConfig) {
|
|
179
202
|
if (this.platform.debugMode) {
|
|
180
|
-
this.deviceLogging = this.accessory.context.logging = '
|
|
181
|
-
this.
|
|
182
|
-
} else if (
|
|
183
|
-
this.deviceLogging = this.accessory.context.logging =
|
|
184
|
-
|
|
185
|
-
this.warnLog(`Contact Sensor: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
|
|
186
|
-
}
|
|
203
|
+
this.deviceLogging = this.accessory.context.logging = 'debugMode';
|
|
204
|
+
this.debugLog(`Contact Sensor: ${this.accessory.displayName} Using Debug Mode Logging: ${this.deviceLogging}`);
|
|
205
|
+
} else if (device.logging) {
|
|
206
|
+
this.deviceLogging = this.accessory.context.logging = device.logging;
|
|
207
|
+
this.debugLog(`Contact Sensor: ${this.accessory.displayName} Using Device Config Logging: ${this.deviceLogging}`);
|
|
187
208
|
} else if (this.platform.config.options?.logging) {
|
|
188
209
|
this.deviceLogging = this.accessory.context.logging = this.platform.config.options?.logging;
|
|
189
|
-
|
|
190
|
-
this.warnLog(`Contact Sensor: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
|
|
191
|
-
}
|
|
210
|
+
this.debugLog(`Contact Sensor: ${this.accessory.displayName} Using Platform Config Logging: ${this.deviceLogging}`);
|
|
192
211
|
} else {
|
|
193
212
|
this.deviceLogging = this.accessory.context.logging = 'standard';
|
|
213
|
+
this.debugLog(`Contact Sensor: ${this.accessory.displayName} Logging Not Set, Using: ${this.deviceLogging}`);
|
|
194
214
|
}
|
|
195
215
|
}
|
|
196
216
|
|
|
@@ -216,10 +236,10 @@ export class Contact {
|
|
|
216
236
|
* Parse the device status from the SwitchBot api
|
|
217
237
|
*/
|
|
218
238
|
async parseStatus() {
|
|
219
|
-
if (this.device.ble) {
|
|
220
|
-
await this.BLEparseStatus();
|
|
221
|
-
} else {
|
|
239
|
+
if (this.SwitchToOpenAPI || !this.device.ble) {
|
|
222
240
|
await this.openAPIparseStatus();
|
|
241
|
+
} else {
|
|
242
|
+
await this.BLEparseStatus();
|
|
223
243
|
}
|
|
224
244
|
}
|
|
225
245
|
|
|
@@ -240,27 +260,23 @@ export class Contact {
|
|
|
240
260
|
}
|
|
241
261
|
// Movement
|
|
242
262
|
if (!this.device.contact?.hide_motionsensor) {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
} else if (this.movement === undefined) {
|
|
246
|
-
this.movement = false;
|
|
247
|
-
this.BLEmotion();
|
|
248
|
-
} else {
|
|
249
|
-
this.BLEmotion();
|
|
250
|
-
}
|
|
263
|
+
this.MotionDetected = Boolean(this.movement);
|
|
264
|
+
this.debugLog(`Contact Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
|
|
251
265
|
}
|
|
252
266
|
// Light Level
|
|
253
267
|
if (!this.device.contact?.hide_lightsensor) {
|
|
254
268
|
this.set_minLux = this.minLux();
|
|
255
269
|
this.set_maxLux = this.maxLux();
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
270
|
+
switch (this.lightLevel) {
|
|
271
|
+
case 'dark':
|
|
272
|
+
case 0:
|
|
273
|
+
this.CurrentAmbientLightLevel = this.set_minLux;
|
|
274
|
+
break;
|
|
275
|
+
default:
|
|
276
|
+
this.CurrentAmbientLightLevel = this.set_maxLux;
|
|
263
277
|
}
|
|
278
|
+
this.debugLog(`Contact Sensor: ${this.accessory.displayName} LightLevel: ${this.lightLevel},`
|
|
279
|
+
+ ` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
264
280
|
}
|
|
265
281
|
// Battery
|
|
266
282
|
if (this.battery === undefined) {
|
|
@@ -275,73 +291,44 @@ export class Contact {
|
|
|
275
291
|
this.debugLog(`Contact Sensor: ${this.accessory.displayName} BatteryLevel: ${this.BatteryLevel}, StatusLowBattery: ${this.StatusLowBattery}`);
|
|
276
292
|
}
|
|
277
293
|
|
|
278
|
-
private BLEmotion() {
|
|
279
|
-
this.MotionDetected = Boolean(this.movement);
|
|
280
|
-
this.debugLog(`Contact Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
private BLElux() {
|
|
284
|
-
switch (this.lightLevel) {
|
|
285
|
-
case 'dark':
|
|
286
|
-
case 0:
|
|
287
|
-
this.CurrentAmbientLightLevel = this.set_minLux;
|
|
288
|
-
break;
|
|
289
|
-
default:
|
|
290
|
-
this.CurrentAmbientLightLevel = this.set_maxLux;
|
|
291
|
-
}
|
|
292
|
-
this.debugLog(`Contact Sensor: ${this.accessory.displayName} LightLevel: ${this.lightLevel},`
|
|
293
|
-
+ ` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
294
|
-
}
|
|
295
|
-
|
|
296
294
|
private async openAPIparseStatus() {
|
|
295
|
+
if (this.device.ble) {
|
|
296
|
+
this.SwitchToOpenAPI = false;
|
|
297
|
+
}
|
|
297
298
|
if (this.platform.config.credentials?.openToken) {
|
|
299
|
+
this.debugLog(`Contact Sensor: ${this.accessory.displayName} OpenAPI parseStatus`);
|
|
298
300
|
// Contact State
|
|
299
|
-
this.
|
|
301
|
+
if (this.openState === 'open') {
|
|
302
|
+
this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
|
|
303
|
+
this.debugLog(`Contact Sensor: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensorState}`);
|
|
304
|
+
} else if (this.openState === 'close') {
|
|
305
|
+
this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_DETECTED;
|
|
306
|
+
this.debugLog(`Contact Sensor: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensorState}`);
|
|
307
|
+
} else {
|
|
308
|
+
this.debugLog(`Contact Sensor: ${this.accessory.displayName} openState: ${this.openState}`);
|
|
309
|
+
}
|
|
300
310
|
// Motion State
|
|
301
311
|
if (!this.device.contact?.hide_motionsensor) {
|
|
302
|
-
this.
|
|
312
|
+
this.MotionDetected = this.moveDetected!;
|
|
313
|
+
this.debugLog(`Contact Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
|
|
303
314
|
}
|
|
304
315
|
// Light Level
|
|
305
316
|
if (!this.device.contact?.hide_lightsensor) {
|
|
306
|
-
this.
|
|
317
|
+
this.set_minLux = this.minLux();
|
|
318
|
+
this.set_maxLux = this.maxLux();
|
|
319
|
+
switch (this.brightness) {
|
|
320
|
+
case 'dim':
|
|
321
|
+
this.CurrentAmbientLightLevel = this.set_minLux;
|
|
322
|
+
break;
|
|
323
|
+
case 'bright':
|
|
324
|
+
default:
|
|
325
|
+
this.CurrentAmbientLightLevel = this.set_maxLux;
|
|
326
|
+
}
|
|
327
|
+
this.debugLog(`Contact Sensor: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
307
328
|
}
|
|
308
329
|
}
|
|
309
330
|
}
|
|
310
331
|
|
|
311
|
-
private openAPIlux() {
|
|
312
|
-
this.set_minLux = this.minLux();
|
|
313
|
-
this.set_maxLux = this.maxLux();
|
|
314
|
-
switch (this.deviceStatus.body.brightness) {
|
|
315
|
-
case 'dim':
|
|
316
|
-
this.CurrentAmbientLightLevel = this.set_minLux;
|
|
317
|
-
break;
|
|
318
|
-
case 'bright':
|
|
319
|
-
default:
|
|
320
|
-
this.CurrentAmbientLightLevel = this.set_maxLux;
|
|
321
|
-
}
|
|
322
|
-
this.debugLog(`Contact Sensor: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
private openAPImotion() {
|
|
326
|
-
if (typeof this.deviceStatus.body.moveDetected === 'boolean') {
|
|
327
|
-
this.MotionDetected = this.deviceStatus.body.moveDetected;
|
|
328
|
-
}
|
|
329
|
-
this.debugLog(`Contact Sensor: ${this.accessory.displayName} MotionDetected: ${this.MotionDetected}`);
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
private openAPIcontact() {
|
|
333
|
-
this.debugLog(`Contact Sensor: ${this.accessory.displayName} OpenAPI parseStatus`);
|
|
334
|
-
if (this.deviceStatus.body.openState === 'open') {
|
|
335
|
-
this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_NOT_DETECTED;
|
|
336
|
-
this.debugLog(`Contact Sensor: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensorState}`);
|
|
337
|
-
} else if (this.deviceStatus.body.openState === 'close') {
|
|
338
|
-
this.ContactSensorState = this.platform.Characteristic.ContactSensorState.CONTACT_DETECTED;
|
|
339
|
-
this.debugLog(`Contact Sensor: ${this.accessory.displayName} ContactSensorState: ${this.ContactSensorState}`);
|
|
340
|
-
} else {
|
|
341
|
-
this.debugLog(`Contact Sensor: ${this.accessory.displayName} openState: ${this.deviceStatus.body.openState}`);
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
|
|
345
332
|
/**
|
|
346
333
|
* Asks the SwitchBot API for the latest device information
|
|
347
334
|
*/
|
|
@@ -353,34 +340,12 @@ export class Contact {
|
|
|
353
340
|
}
|
|
354
341
|
}
|
|
355
342
|
|
|
356
|
-
public async connectBLE() {
|
|
357
|
-
let switchbot: any;
|
|
358
|
-
try {
|
|
359
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
360
|
-
const Switchbot = require('node-switchbot');
|
|
361
|
-
switchbot = new Switchbot();
|
|
362
|
-
// Convert to BLE Address
|
|
363
|
-
this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
|
|
364
|
-
this.debugLog(`Contact Sensor: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
365
|
-
} catch (e: any) {
|
|
366
|
-
switchbot = false;
|
|
367
|
-
this.errorLog(`Contact Sensor: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot}`);
|
|
368
|
-
if (this.deviceLogging === 'debug') {
|
|
369
|
-
this.errorLog(`Contact Sensor: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot},`
|
|
370
|
-
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
371
|
-
}
|
|
372
|
-
if (this.platform.debugMode) {
|
|
373
|
-
this.errorLog(`Contact Sensor: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot},`
|
|
374
|
-
+ ` Error: ${JSON.stringify(e)}`);
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
return switchbot;
|
|
378
|
-
}
|
|
379
|
-
|
|
380
343
|
private async BLERefreshStatus() {
|
|
381
344
|
this.debugLog(`Contact Sensor: ${this.accessory.displayName} BLE refreshStatus`);
|
|
382
|
-
|
|
383
|
-
|
|
345
|
+
const switchbot = await this.platform.connectBLE();
|
|
346
|
+
// Convert to BLE Address
|
|
347
|
+
this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
|
|
348
|
+
this.debugLog(`Curtain: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
384
349
|
// Start to monitor advertisement packets
|
|
385
350
|
if (switchbot !== false) {
|
|
386
351
|
switchbot.startScan({
|
|
@@ -433,6 +398,7 @@ export class Contact {
|
|
|
433
398
|
}
|
|
434
399
|
if (this.platform.config.credentials?.openToken) {
|
|
435
400
|
this.warnLog(`Contact Sensor: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
401
|
+
this.SwitchToOpenAPI = true;
|
|
436
402
|
await this.openAPIRefreshStatus();
|
|
437
403
|
}
|
|
438
404
|
this.apiError(e);
|
|
@@ -446,6 +412,7 @@ export class Contact {
|
|
|
446
412
|
this.errorLog(`Contact Sensor: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
|
|
447
413
|
if (this.platform.config.credentials?.openToken) {
|
|
448
414
|
this.warnLog(`Contact Sensor: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
415
|
+
this.SwitchToOpenAPI = true;
|
|
449
416
|
await this.openAPIRefreshStatus();
|
|
450
417
|
}
|
|
451
418
|
}
|
|
@@ -456,6 +423,9 @@ export class Contact {
|
|
|
456
423
|
try {
|
|
457
424
|
this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
|
|
458
425
|
this.debugLog(`Contact Sensor: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
426
|
+
this.openState = this.deviceStatus.body.openState;
|
|
427
|
+
this.moveDetected = this.deviceStatus.body.moveDetected;
|
|
428
|
+
this.brightness = this.deviceStatus.body.brightness;
|
|
459
429
|
this.parseStatus();
|
|
460
430
|
this.updateHomeKitCharacteristics();
|
|
461
431
|
} catch (e: any) {
|
package/src/devices/curtains.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { interval, Subject } from 'rxjs';
|
|
|
4
4
|
import { SwitchBotPlatform } from '../platform';
|
|
5
5
|
import { debounceTime, skipWhile, take, tap } from 'rxjs/operators';
|
|
6
6
|
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
7
|
-
import { DeviceURL, device, devicesConfig, serviceData, switchbot, deviceStatusResponse, payload } from '../settings';
|
|
7
|
+
import { DeviceURL, device, devicesConfig, serviceData, switchbot, deviceStatusResponse, payload, deviceStatus } from '../settings';
|
|
8
8
|
|
|
9
9
|
export class Curtain {
|
|
10
10
|
// Services
|
|
@@ -22,16 +22,20 @@ export class Curtain {
|
|
|
22
22
|
|
|
23
23
|
// OpenAPI Others
|
|
24
24
|
deviceStatus!: deviceStatusResponse;
|
|
25
|
+
slidePosition: deviceStatus['slidePosition'];
|
|
26
|
+
moving: deviceStatus['moving'];
|
|
27
|
+
brightness: deviceStatus['brightness'];
|
|
25
28
|
|
|
26
29
|
// BLE Others
|
|
27
30
|
connected?: boolean;
|
|
28
31
|
switchbot!: switchbot;
|
|
32
|
+
SwitchToOpenAPI?: boolean;
|
|
29
33
|
serviceData!: serviceData;
|
|
34
|
+
spaceBetweenLevels!: number;
|
|
30
35
|
calibration: serviceData['calibration'];
|
|
31
36
|
battery: serviceData['battery'];
|
|
32
37
|
position: serviceData['position'];
|
|
33
38
|
lightLevel: serviceData['lightLevel'];
|
|
34
|
-
spaceBetweenLevels!: number;
|
|
35
39
|
|
|
36
40
|
// Target
|
|
37
41
|
setNewTarget!: boolean;
|
|
@@ -39,7 +43,7 @@ export class Curtain {
|
|
|
39
43
|
|
|
40
44
|
// Config
|
|
41
45
|
set_minStep!: number;
|
|
42
|
-
|
|
46
|
+
updateRate!: number;
|
|
43
47
|
set_minLux!: number;
|
|
44
48
|
set_maxLux!: number;
|
|
45
49
|
scanDuration!: number;
|
|
@@ -60,16 +64,11 @@ export class Curtain {
|
|
|
60
64
|
this.scan();
|
|
61
65
|
this.setMinMax();
|
|
62
66
|
this.refreshRate();
|
|
67
|
+
this.config(device);
|
|
63
68
|
this.CurrentPosition = 0;
|
|
64
69
|
this.TargetPosition = 0;
|
|
65
70
|
this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
|
|
66
71
|
|
|
67
|
-
// Curtain Config
|
|
68
|
-
this.debugLog(`Curtain: ${this.accessory.displayName} Config: (ble: ${device.ble}, disable_group: ${device.curtain?.disable_group},`
|
|
69
|
-
+ ` hide_lightsensor: ${device.curtain?.hide_lightsensor}, set_minLux: ${device.curtain?.set_minLux}, set_maxLux: `
|
|
70
|
-
+ `${device.curtain?.set_maxLux}, refreshRate: ${device.curtain?.refreshRate}, set_max: ${device.curtain?.set_max}, set_min: `
|
|
71
|
-
+ `${device.curtain?.set_min}, set_minStep: ${device.curtain?.set_minStep})`);
|
|
72
|
-
|
|
73
72
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
74
73
|
this.doCurtainUpdate = new Subject();
|
|
75
74
|
this.curtainUpdateInProgress = false;
|
|
@@ -142,6 +141,23 @@ export class Curtain {
|
|
|
142
141
|
this.debugLog(`Curtain: ${accessory.displayName} Light Sensor Service Not Added`);
|
|
143
142
|
}
|
|
144
143
|
|
|
144
|
+
// Battery Service
|
|
145
|
+
if (!device.ble) {
|
|
146
|
+
this.debugLog(`Curtain: ${accessory.displayName} Removing Battery Service`);
|
|
147
|
+
this.batteryService = this.accessory.getService(this.platform.Service.Battery);
|
|
148
|
+
accessory.removeService(this.batteryService!);
|
|
149
|
+
} else if (device.ble && !this.batteryService) {
|
|
150
|
+
this.debugLog(`Curtain: ${accessory.displayName} Add Battery Service`);
|
|
151
|
+
(this.batteryService =
|
|
152
|
+
this.accessory.getService(this.platform.Service.Battery) ||
|
|
153
|
+
this.accessory.addService(this.platform.Service.Battery)), `${accessory.displayName} Battery`;
|
|
154
|
+
|
|
155
|
+
this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${accessory.displayName} Battery`);
|
|
156
|
+
|
|
157
|
+
} else {
|
|
158
|
+
this.debugLog(`Curtain: ${accessory.displayName} Battery Service Not Added`);
|
|
159
|
+
}
|
|
160
|
+
|
|
145
161
|
|
|
146
162
|
// Update Homekit
|
|
147
163
|
this.updateHomeKitCharacteristics();
|
|
@@ -154,7 +170,7 @@ export class Curtain {
|
|
|
154
170
|
});
|
|
155
171
|
|
|
156
172
|
// update slide progress
|
|
157
|
-
interval(this.
|
|
173
|
+
interval(this.updateRate * 1000)
|
|
158
174
|
.pipe(skipWhile(() => this.curtainUpdateInProgress))
|
|
159
175
|
.subscribe(() => {
|
|
160
176
|
if (this.PositionState === this.platform.Characteristic.PositionState.STOPPED) {
|
|
@@ -193,6 +209,25 @@ export class Curtain {
|
|
|
193
209
|
});
|
|
194
210
|
}
|
|
195
211
|
|
|
212
|
+
config(device: device & devicesConfig) {
|
|
213
|
+
const config: any = device.curtain;
|
|
214
|
+
if (device.ble !== undefined) {
|
|
215
|
+
config['ble'] = device.ble;
|
|
216
|
+
}
|
|
217
|
+
if (device.logging !== undefined) {
|
|
218
|
+
config['logging'] = device.logging;
|
|
219
|
+
}
|
|
220
|
+
if (device.refreshRate !== undefined) {
|
|
221
|
+
config['refreshRate'] = device.refreshRate;
|
|
222
|
+
}
|
|
223
|
+
if (device.scanDuration !== undefined) {
|
|
224
|
+
config['scanDuration'] = device.scanDuration;
|
|
225
|
+
}
|
|
226
|
+
if (config !== undefined) {
|
|
227
|
+
this.warnLog(`Curtain: ${this.accessory.displayName} Config: ${JSON.stringify(config)}`);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
196
231
|
refreshRate() {
|
|
197
232
|
// refreshRate
|
|
198
233
|
if (this.device.refreshRate) {
|
|
@@ -206,14 +241,14 @@ export class Curtain {
|
|
|
206
241
|
this.warnLog(`Curtain: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
|
|
207
242
|
}
|
|
208
243
|
}
|
|
209
|
-
//
|
|
210
|
-
if (this.device?.curtain?.
|
|
211
|
-
this.
|
|
244
|
+
// updateRate
|
|
245
|
+
if (this.device?.curtain?.updateRate) {
|
|
246
|
+
this.updateRate = this.device?.curtain?.updateRate;
|
|
212
247
|
if (this.platform.debugMode || (this.deviceLogging === 'debug')) {
|
|
213
248
|
this.warnLog(`Curtain: ${this.accessory.displayName} Using Device Config Curtain refreshRate: ${this.deviceRefreshRate}`);
|
|
214
249
|
}
|
|
215
250
|
} else {
|
|
216
|
-
this.
|
|
251
|
+
this.updateRate = 5;
|
|
217
252
|
if (this.platform.debugMode || (this.deviceLogging === 'debug')) {
|
|
218
253
|
this.warnLog(`Curtain: ${this.accessory.displayName} Using Default Curtain Refresh Rate.`);
|
|
219
254
|
}
|
|
@@ -253,30 +288,6 @@ export class Curtain {
|
|
|
253
288
|
}
|
|
254
289
|
}
|
|
255
290
|
|
|
256
|
-
public async connectBLE() {
|
|
257
|
-
let switchbot: any;
|
|
258
|
-
try {
|
|
259
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
260
|
-
const Switchbot = require('node-switchbot');
|
|
261
|
-
switchbot = new Switchbot();
|
|
262
|
-
// Convert to BLE Address
|
|
263
|
-
this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
|
|
264
|
-
this.debugLog(`Curtain: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
265
|
-
} catch (e: any) {
|
|
266
|
-
switchbot = false;
|
|
267
|
-
this.errorLog(`Curtain: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot}`);
|
|
268
|
-
if (this.deviceLogging === 'debug') {
|
|
269
|
-
this.errorLog(`Curtain: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot},`
|
|
270
|
-
+ ` Error Message: ${JSON.stringify(e.message)}`);
|
|
271
|
-
}
|
|
272
|
-
if (this.platform.debugMode) {
|
|
273
|
-
this.errorLog(`Curtain: ${this.accessory.displayName} 'node-switchbot' found: ${switchbot},`
|
|
274
|
-
+ ` Error: ${JSON.stringify(e)}`);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
return switchbot;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
291
|
private minStep(): number {
|
|
281
292
|
if (this.device.curtain?.set_minStep) {
|
|
282
293
|
this.set_minStep = this.device.curtain?.set_minStep;
|
|
@@ -304,16 +315,20 @@ export class Curtain {
|
|
|
304
315
|
return this.set_maxLux;
|
|
305
316
|
}
|
|
306
317
|
|
|
318
|
+
/**
|
|
319
|
+
* Parse the device status from the SwitchBot api
|
|
320
|
+
*/
|
|
307
321
|
async parseStatus() {
|
|
308
|
-
if (this.device.ble) {
|
|
309
|
-
await this.BLEparseStatus();
|
|
310
|
-
} else {
|
|
322
|
+
if (this.SwitchToOpenAPI || !this.device.ble) {
|
|
311
323
|
await this.openAPIparseStatus();
|
|
324
|
+
} else {
|
|
325
|
+
await this.BLEparseStatus();
|
|
312
326
|
}
|
|
313
327
|
}
|
|
314
328
|
|
|
315
329
|
private async BLEparseStatus() {
|
|
316
330
|
this.debugLog(`Curtain: ${this.accessory.displayName} BLE parseStatus`);
|
|
331
|
+
// CurrentPosition
|
|
317
332
|
this.setMinMax();
|
|
318
333
|
this.CurrentPosition = 100 - Number(this.position);
|
|
319
334
|
this.debugLog(`Curtain: ${this.accessory.displayName} CurrentPosition ${this.CurrentPosition}`);
|
|
@@ -339,6 +354,7 @@ export class Curtain {
|
|
|
339
354
|
// If Curtain calibration distance is short, there will be an error between the current percentage and the target percentage.
|
|
340
355
|
this.TargetPosition = this.CurrentPosition;
|
|
341
356
|
this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
|
|
357
|
+
this.debugLog(`Curtain: ${this.accessory.displayName} Stopped`);
|
|
342
358
|
}
|
|
343
359
|
}
|
|
344
360
|
this.debugLog(`Curtain: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition},`
|
|
@@ -407,17 +423,20 @@ export class Curtain {
|
|
|
407
423
|
}
|
|
408
424
|
|
|
409
425
|
private async openAPIparseStatus() {
|
|
426
|
+
if (this.device.ble) {
|
|
427
|
+
this.SwitchToOpenAPI = false;
|
|
428
|
+
}
|
|
410
429
|
if (this.platform.config.credentials?.openToken) {
|
|
411
430
|
this.debugLog(`Curtain: ${this.accessory.displayName} OpenAPI parseStatus`);
|
|
412
431
|
// CurrentPosition
|
|
413
432
|
this.setMinMax();
|
|
414
|
-
this.CurrentPosition = 100 - this.
|
|
433
|
+
this.CurrentPosition = 100 - Number(this.slidePosition);
|
|
415
434
|
this.debugLog(`Curtain ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition}`);
|
|
416
435
|
if (this.setNewTarget) {
|
|
417
|
-
this.infoLog(`
|
|
436
|
+
this.infoLog(`Curtain: ${this.accessory.displayName} Checking Status ...`);
|
|
418
437
|
}
|
|
419
438
|
|
|
420
|
-
if (this.
|
|
439
|
+
if (this.setNewTarget && this.moving) {
|
|
421
440
|
this.setMinMax();
|
|
422
441
|
if (this.TargetPosition > this.CurrentPosition) {
|
|
423
442
|
this.debugLog(`Curtain: ${this.accessory.displayName} Closing, CurrentPosition: ${this.CurrentPosition} `);
|
|
@@ -435,6 +454,7 @@ export class Curtain {
|
|
|
435
454
|
/*If Curtain calibration distance is short, there will be an error between the current percentage and the target percentage.*/
|
|
436
455
|
this.TargetPosition = this.CurrentPosition;
|
|
437
456
|
this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
|
|
457
|
+
this.debugLog(`Curtain: ${this.accessory.displayName} Stopped`);
|
|
438
458
|
}
|
|
439
459
|
}
|
|
440
460
|
this.debugLog(`Curtain: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition},`
|
|
@@ -444,7 +464,7 @@ export class Curtain {
|
|
|
444
464
|
this.set_minLux = this.minLux();
|
|
445
465
|
this.set_maxLux = this.maxLux();
|
|
446
466
|
// Brightness
|
|
447
|
-
switch (this.
|
|
467
|
+
switch (this.brightness) {
|
|
448
468
|
case 'dim':
|
|
449
469
|
this.CurrentAmbientLightLevel = this.set_minLux;
|
|
450
470
|
break;
|
|
@@ -467,8 +487,10 @@ export class Curtain {
|
|
|
467
487
|
|
|
468
488
|
private async BLERefreshStatus() {
|
|
469
489
|
this.debugLog(`Curtain: ${this.accessory.displayName} BLE refreshStatus`);
|
|
470
|
-
|
|
471
|
-
|
|
490
|
+
const switchbot = await this.platform.connectBLE();
|
|
491
|
+
// Convert to BLE Address
|
|
492
|
+
this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
|
|
493
|
+
this.debugLog(`Curtain: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
472
494
|
// Start to monitor advertisement packets
|
|
473
495
|
if (switchbot !== false) {
|
|
474
496
|
switchbot.startScan({
|
|
@@ -506,6 +528,7 @@ export class Curtain {
|
|
|
506
528
|
this.errorLog(`Curtain: ${this.accessory.displayName} wasn't able to establish BLE Connection`);
|
|
507
529
|
if (this.platform.config.credentials?.openToken) {
|
|
508
530
|
this.warnLog(`Curtain: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
531
|
+
this.SwitchToOpenAPI = true;
|
|
509
532
|
await this.openAPIRefreshStatus();
|
|
510
533
|
}
|
|
511
534
|
}
|
|
@@ -521,6 +544,7 @@ export class Curtain {
|
|
|
521
544
|
}
|
|
522
545
|
if (this.platform.config.credentials?.openToken) {
|
|
523
546
|
this.warnLog(`Curtain: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
547
|
+
this.SwitchToOpenAPI = true;
|
|
524
548
|
await this.openAPIRefreshStatus();
|
|
525
549
|
}
|
|
526
550
|
this.apiError(e);
|
|
@@ -534,6 +558,7 @@ export class Curtain {
|
|
|
534
558
|
this.errorLog(`Curtain: ${this.accessory.displayName} wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`);
|
|
535
559
|
if (this.platform.config.credentials?.openToken) {
|
|
536
560
|
this.warnLog(`Curtain: ${this.accessory.displayName} Using OpenAPI Connection`);
|
|
561
|
+
this.SwitchToOpenAPI = true;
|
|
537
562
|
await this.openAPIRefreshStatus();
|
|
538
563
|
}
|
|
539
564
|
}
|
|
@@ -544,6 +569,9 @@ export class Curtain {
|
|
|
544
569
|
try {
|
|
545
570
|
this.deviceStatus = (await this.platform.axios.get(`${DeviceURL}/${this.device.deviceId}/status`)).data;
|
|
546
571
|
this.debugLog(`Curtain: ${this.accessory.displayName} refreshStatus: ${JSON.stringify(this.deviceStatus)}`);
|
|
572
|
+
this.slidePosition = this.deviceStatus.body.slidePosition;
|
|
573
|
+
this.moving = this.deviceStatus.body.moving;
|
|
574
|
+
this.brightness = this.deviceStatus.body.brightness;
|
|
547
575
|
this.parseStatus();
|
|
548
576
|
this.updateHomeKitCharacteristics();
|
|
549
577
|
} catch (e: any) {
|
|
@@ -578,7 +606,10 @@ export class Curtain {
|
|
|
578
606
|
private async BLEpushChanges() {
|
|
579
607
|
if (this.TargetPosition !== this.CurrentPosition) {
|
|
580
608
|
this.debugLog(`Curtain: ${this.accessory.displayName} BLE pushChanges`);
|
|
581
|
-
const switchbot = await this.connectBLE();
|
|
609
|
+
const switchbot = await this.platform.connectBLE();
|
|
610
|
+
// Convert to BLE Address
|
|
611
|
+
this.device.bleMac = ((this.device.deviceId!.match(/.{1,2}/g))!.join(':')).toLowerCase();
|
|
612
|
+
this.debugLog(`Curtain: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
582
613
|
if (switchbot !== false) {
|
|
583
614
|
switchbot.discover({ model: 'c', quick: true, id: this.device.bleMac }).then((device_list) => {
|
|
584
615
|
this.infoLog(`${this.accessory.displayName} Target Position: ${this.TargetPosition}`);
|