@switchbot/homebridge-switchbot 2.5.0-beta.2 → 2.5.0-beta.4
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/config.schema.json +47 -0
- package/dist/device/blindtilt.d.ts +39 -6
- package/dist/device/blindtilt.d.ts.map +1 -1
- package/dist/device/blindtilt.js +327 -115
- package/dist/device/blindtilt.js.map +1 -1
- package/dist/settings.d.ts +6 -0
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js.map +1 -1
- package/package.json +1 -1
- package/src/device/blindtilt.ts +361 -113
- package/src/settings.ts +14 -7
package/dist/device/blindtilt.js
CHANGED
|
@@ -12,11 +12,20 @@ const super_stringify_1 = __importDefault(require("super-stringify"));
|
|
|
12
12
|
const operators_1 = require("rxjs/operators");
|
|
13
13
|
const settings_1 = require("../settings");
|
|
14
14
|
const utils_1 = require("../utils");
|
|
15
|
+
var BlindTiltMappingMode;
|
|
16
|
+
(function (BlindTiltMappingMode) {
|
|
17
|
+
BlindTiltMappingMode["OnlyUp"] = "only_up";
|
|
18
|
+
BlindTiltMappingMode["OnlyDown"] = "only_down";
|
|
19
|
+
BlindTiltMappingMode["DownAndUp"] = "down_and_up";
|
|
20
|
+
BlindTiltMappingMode["UpAndDown"] = "up_and_down";
|
|
21
|
+
BlindTiltMappingMode["UseTiltForDirection"] = "use_tilt_for_direction";
|
|
22
|
+
})(BlindTiltMappingMode || (BlindTiltMappingMode = {}));
|
|
15
23
|
class BlindTilt {
|
|
16
24
|
constructor(platform, accessory, device) {
|
|
17
25
|
this.platform = platform;
|
|
18
26
|
this.accessory = accessory;
|
|
19
27
|
this.device = device;
|
|
28
|
+
this.mappingMode = BlindTiltMappingMode.OnlyUp;
|
|
20
29
|
//MQTT stuff
|
|
21
30
|
this.mqttClient = null;
|
|
22
31
|
// Connection
|
|
@@ -29,6 +38,8 @@ class BlindTilt {
|
|
|
29
38
|
this.config(device);
|
|
30
39
|
this.setupMqtt(device);
|
|
31
40
|
this.context();
|
|
41
|
+
this.mappingMode = device.blindTilt?.mappingMode ?? BlindTiltMappingMode.OnlyUp;
|
|
42
|
+
this.debugLog(`Mapping mode: ${this.mappingMode}`);
|
|
32
43
|
// this is subject we use to track when we need to POST changes to the SwitchBot API
|
|
33
44
|
this.doBlindTiltUpdate = new rxjs_1.Subject();
|
|
34
45
|
this.blindTiltUpdateInProgress = false;
|
|
@@ -82,6 +93,7 @@ class BlindTilt {
|
|
|
82
93
|
validValueRanges: [0, 100],
|
|
83
94
|
})
|
|
84
95
|
.onSet(this.TargetPositionSet.bind(this));
|
|
96
|
+
this.CurrentHorizontalTiltAngle = 90;
|
|
85
97
|
this.windowCoveringService
|
|
86
98
|
.getCharacteristic(this.platform.Characteristic.CurrentHorizontalTiltAngle)
|
|
87
99
|
.setProps({
|
|
@@ -89,11 +101,12 @@ class BlindTilt {
|
|
|
89
101
|
minValue: -90,
|
|
90
102
|
maxValue: 90,
|
|
91
103
|
validValues: [-90, 90],
|
|
92
|
-
validValueRanges: [-90, 90],
|
|
93
104
|
})
|
|
94
105
|
.onGet(() => {
|
|
106
|
+
// this.debugLog(`requested CurrentHorizontalTiltAngle: ${this.CurrentHorizontalTiltAngle}`);
|
|
95
107
|
return this.CurrentHorizontalTiltAngle;
|
|
96
108
|
});
|
|
109
|
+
this.TargetHorizontalTiltAngle = 90;
|
|
97
110
|
this.windowCoveringService
|
|
98
111
|
.getCharacteristic(this.platform.Characteristic.TargetHorizontalTiltAngle)
|
|
99
112
|
.setProps({
|
|
@@ -101,7 +114,6 @@ class BlindTilt {
|
|
|
101
114
|
minValue: -90,
|
|
102
115
|
maxValue: 90,
|
|
103
116
|
validValues: [-90, 90],
|
|
104
|
-
validValueRanges: [-90, 90],
|
|
105
117
|
})
|
|
106
118
|
.onSet(this.TargetHorizontalTiltAngleSet.bind(this));
|
|
107
119
|
// Battery Service
|
|
@@ -201,7 +213,7 @@ class BlindTilt {
|
|
|
201
213
|
this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} DECREASING PositionState: ${this.PositionState}`);
|
|
202
214
|
}
|
|
203
215
|
else {
|
|
204
|
-
this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition}
|
|
216
|
+
this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} Standby2, CurrentPosition: ${this.CurrentPosition}`);
|
|
205
217
|
this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
|
|
206
218
|
this.windowCoveringService.getCharacteristic(this.platform.Characteristic.PositionState).updateValue(this.PositionState);
|
|
207
219
|
this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} STOPPED PositionState: ${this.PositionState}`);
|
|
@@ -215,6 +227,57 @@ class BlindTilt {
|
|
|
215
227
|
}
|
|
216
228
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition},` +
|
|
217
229
|
` TargetPosition: ${this.TargetPosition}, PositionState: ${this.PositionState},`);
|
|
230
|
+
if (!this.device.curtain?.hide_lightsensor) {
|
|
231
|
+
this.set_minLux = this.minLux();
|
|
232
|
+
this.set_maxLux = this.maxLux();
|
|
233
|
+
this.spaceBetweenLevels = 9;
|
|
234
|
+
// Brightness
|
|
235
|
+
switch (this.lightLevel) {
|
|
236
|
+
case 1:
|
|
237
|
+
this.CurrentAmbientLightLevel = this.set_minLux;
|
|
238
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
|
|
239
|
+
break;
|
|
240
|
+
case 2:
|
|
241
|
+
this.CurrentAmbientLightLevel = (this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels;
|
|
242
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.lightLevel},` +
|
|
243
|
+
` Calculation: ${(this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels}`);
|
|
244
|
+
break;
|
|
245
|
+
case 3:
|
|
246
|
+
this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 2;
|
|
247
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
|
|
248
|
+
break;
|
|
249
|
+
case 4:
|
|
250
|
+
this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 3;
|
|
251
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
|
|
252
|
+
break;
|
|
253
|
+
case 5:
|
|
254
|
+
this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 4;
|
|
255
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
|
|
256
|
+
break;
|
|
257
|
+
case 6:
|
|
258
|
+
this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 5;
|
|
259
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
|
|
260
|
+
break;
|
|
261
|
+
case 7:
|
|
262
|
+
this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 6;
|
|
263
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
|
|
264
|
+
break;
|
|
265
|
+
case 8:
|
|
266
|
+
this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 7;
|
|
267
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
|
|
268
|
+
break;
|
|
269
|
+
case 9:
|
|
270
|
+
this.CurrentAmbientLightLevel = ((this.set_maxLux - this.set_minLux) / this.spaceBetweenLevels) * 8;
|
|
271
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.lightLevel}`);
|
|
272
|
+
break;
|
|
273
|
+
case 10:
|
|
274
|
+
default:
|
|
275
|
+
this.CurrentAmbientLightLevel = this.set_maxLux;
|
|
276
|
+
this.debugLog();
|
|
277
|
+
}
|
|
278
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} LightLevel: ${this.lightLevel},`
|
|
279
|
+
+ ` CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
280
|
+
}
|
|
218
281
|
// Battery
|
|
219
282
|
this.BatteryLevel = Number(this.battery);
|
|
220
283
|
if (this.BatteryLevel < 10) {
|
|
@@ -228,16 +291,23 @@ class BlindTilt {
|
|
|
228
291
|
}
|
|
229
292
|
async openAPIparseStatus() {
|
|
230
293
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} openAPIparseStatus`);
|
|
294
|
+
const [homekitPosition, homekitTiltAngle] = this.mapDeviceValuesToHomekitValues(Number(this.slidePosition), String(this.direction));
|
|
295
|
+
this.debugLog(` device: ${this.slidePosition} => HK: ${homekitPosition}`);
|
|
296
|
+
this.CurrentPosition = homekitPosition;
|
|
231
297
|
// CurrentPosition
|
|
232
|
-
this.CurrentPosition = 100 - Number(this.slidePosition);
|
|
233
298
|
await this.setMinMax();
|
|
234
299
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition}`);
|
|
300
|
+
if (homekitTiltAngle) {
|
|
301
|
+
this.CurrentHorizontalTiltAngle = homekitTiltAngle;
|
|
302
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentHorizontalTiltAngle: ${this.CurrentHorizontalTiltAngle}`);
|
|
303
|
+
}
|
|
235
304
|
if (this.setNewTarget) {
|
|
236
305
|
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Checking Status ...`);
|
|
237
306
|
}
|
|
238
|
-
|
|
307
|
+
this.debugLog(`runStatus: ${this.runStatus}`);
|
|
308
|
+
if (this.setNewTarget || (this.runStatus === undefined || this.runStatus !== 'static')) {
|
|
239
309
|
await this.setMinMax();
|
|
240
|
-
if (this.TargetPosition > this.CurrentPosition) {
|
|
310
|
+
if (this.TargetPosition > this.CurrentPosition || (homekitTiltAngle && (this.TargetHorizontalTiltAngle !== this.CurrentHorizontalTiltAngle))) {
|
|
241
311
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Closing, CurrentPosition: ${this.CurrentPosition} `);
|
|
242
312
|
this.PositionState = this.platform.Characteristic.PositionState.INCREASING;
|
|
243
313
|
this.windowCoveringService.getCharacteristic(this.platform.Characteristic.PositionState).updateValue(this.PositionState);
|
|
@@ -250,30 +320,39 @@ class BlindTilt {
|
|
|
250
320
|
this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} DECREASING PositionState: ${this.PositionState}`);
|
|
251
321
|
}
|
|
252
322
|
else {
|
|
253
|
-
this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} Standby
|
|
323
|
+
this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} Standby because reached position,` +
|
|
324
|
+
` CurrentPosition: ${this.CurrentPosition}`);
|
|
254
325
|
this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
|
|
255
326
|
this.windowCoveringService.getCharacteristic(this.platform.Characteristic.PositionState).updateValue(this.PositionState);
|
|
256
327
|
this.debugLog(`${this.device.deviceType}: ${this.CurrentPosition} STOPPED PositionState: ${this.PositionState}`);
|
|
257
328
|
}
|
|
258
329
|
}
|
|
259
330
|
else {
|
|
260
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Standby
|
|
331
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Standby because device not moving,` +
|
|
332
|
+
` CurrentPosition: ${this.CurrentPosition}`);
|
|
261
333
|
this.TargetPosition = this.CurrentPosition;
|
|
334
|
+
if (homekitTiltAngle) {
|
|
335
|
+
this.TargetHorizontalTiltAngle = this.CurrentHorizontalTiltAngle;
|
|
336
|
+
}
|
|
262
337
|
this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
|
|
263
338
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Stopped`);
|
|
264
339
|
}
|
|
265
|
-
if (this.direction === 'Up') {
|
|
266
|
-
this.CurrentHorizontalTiltAngle = 90;
|
|
267
|
-
}
|
|
268
|
-
else if (this.direction === 'Down') {
|
|
269
|
-
this.CurrentHorizontalTiltAngle = -90;
|
|
270
|
-
}
|
|
271
|
-
else {
|
|
272
|
-
this.CurrentHorizontalTiltAngle = 0;
|
|
273
|
-
}
|
|
274
340
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition},` +
|
|
275
|
-
` TargetPosition: ${this.TargetPosition}, PositionState: ${this.PositionState},`
|
|
276
|
-
|
|
341
|
+
` TargetPosition: ${this.TargetPosition}, PositionState: ${this.PositionState},`);
|
|
342
|
+
if (!this.device.curtain?.hide_lightsensor) {
|
|
343
|
+
this.set_minLux = this.minLux();
|
|
344
|
+
this.set_maxLux = this.maxLux();
|
|
345
|
+
// Brightness
|
|
346
|
+
switch (this.brightness) {
|
|
347
|
+
case 'dim':
|
|
348
|
+
this.CurrentAmbientLightLevel = this.set_minLux;
|
|
349
|
+
break;
|
|
350
|
+
case 'bright':
|
|
351
|
+
default:
|
|
352
|
+
this.CurrentAmbientLightLevel = this.set_maxLux;
|
|
353
|
+
}
|
|
354
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
355
|
+
}
|
|
277
356
|
}
|
|
278
357
|
async refreshStatus() {
|
|
279
358
|
if (!this.device.enableCloudService && this.OpenAPI) {
|
|
@@ -305,6 +384,7 @@ class BlindTilt {
|
|
|
305
384
|
if (switchbot !== false) {
|
|
306
385
|
switchbot
|
|
307
386
|
.startScan({
|
|
387
|
+
model: 'c',
|
|
308
388
|
id: this.device.bleMac,
|
|
309
389
|
})
|
|
310
390
|
.then(async () => {
|
|
@@ -318,9 +398,11 @@ class BlindTilt {
|
|
|
318
398
|
this.battery = ad.serviceData.battery;
|
|
319
399
|
this.inMotion = ad.serviceData.inMotion;
|
|
320
400
|
this.position = ad.serviceData.position;
|
|
401
|
+
this.lightLevel = ad.serviceData.lightLevel;
|
|
321
402
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} serviceData: ${(0, super_stringify_1.default)(ad.serviceData)}`);
|
|
322
403
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} calibration: ${ad.serviceData.calibration}, ` +
|
|
323
|
-
`position: ${ad.serviceData.position},
|
|
404
|
+
`position: ${ad.serviceData.position}, lightLevel: ${ad.serviceData.lightLevel}, battery: ${ad.serviceData.battery}, ` +
|
|
405
|
+
`inMotion: ${ad.serviceData.inMotion}`);
|
|
324
406
|
if (this.serviceData) {
|
|
325
407
|
this.connected = true;
|
|
326
408
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} connected: ${this.connected}`);
|
|
@@ -382,10 +464,11 @@ class BlindTilt {
|
|
|
382
464
|
try {
|
|
383
465
|
this.deviceStatus = JSON.parse(rawData);
|
|
384
466
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} refreshStatus: ${(0, super_stringify_1.default)(this.deviceStatus)}`);
|
|
385
|
-
this.slidePosition = this.deviceStatus.body.slidePosition;
|
|
467
|
+
this.slidePosition = this.deviceStatus.body.slidePosition;
|
|
468
|
+
this.direction = this.deviceStatus.body.direction;
|
|
386
469
|
this.moving = this.deviceStatus.body.moving;
|
|
387
|
-
this.
|
|
388
|
-
this.
|
|
470
|
+
this.runStatus = this.deviceStatus.body.runStatus;
|
|
471
|
+
this.brightness = this.deviceStatus.body.brightness;
|
|
389
472
|
this.openAPIparseStatus();
|
|
390
473
|
this.updateHomeKitCharacteristics();
|
|
391
474
|
}
|
|
@@ -438,6 +521,12 @@ class BlindTilt {
|
|
|
438
521
|
.join(':')
|
|
439
522
|
.toLowerCase();
|
|
440
523
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} BLE Address: ${this.device.bleMac}`);
|
|
524
|
+
this.SilentPerformance();
|
|
525
|
+
const adjustedMode = this.setPositionMode || null;
|
|
526
|
+
if (adjustedMode === null) {
|
|
527
|
+
this.Mode = 'Default Mode';
|
|
528
|
+
}
|
|
529
|
+
this.debugLog(`${this.accessory.displayName} Mode: ${this.Mode}`);
|
|
441
530
|
if (switchbot !== false) {
|
|
442
531
|
switchbot
|
|
443
532
|
.discover({ model: 'c', quick: true, id: this.device.bleMac })
|
|
@@ -446,7 +535,7 @@ class BlindTilt {
|
|
|
446
535
|
return await this.retry({
|
|
447
536
|
max: await this.maxRetry(),
|
|
448
537
|
fn: () => {
|
|
449
|
-
return device_list[0].runToPos(100 - Number(this.TargetPosition));
|
|
538
|
+
return device_list[0].runToPos(100 - Number(this.TargetPosition), adjustedMode);
|
|
450
539
|
},
|
|
451
540
|
});
|
|
452
541
|
})
|
|
@@ -504,40 +593,12 @@ class BlindTilt {
|
|
|
504
593
|
.digest();
|
|
505
594
|
const sign = signTerm.toString('base64');
|
|
506
595
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} sign: ${sign}`);
|
|
507
|
-
this.
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
if (this.TargetHorizontalTiltAngle === 90 && this.TargetPosition === 100) {
|
|
511
|
-
command = 'fullyOpen';
|
|
512
|
-
parameter = 'default';
|
|
513
|
-
}
|
|
514
|
-
else if (this.TargetHorizontalTiltAngle === -90 && this.TargetPosition === 100) {
|
|
515
|
-
command = 'fullyOpen';
|
|
516
|
-
parameter = 'default';
|
|
517
|
-
}
|
|
518
|
-
else if (this.TargetHorizontalTiltAngle === 90 && this.TargetPosition === 0) {
|
|
519
|
-
command = 'closeUp';
|
|
520
|
-
parameter = 'default';
|
|
521
|
-
}
|
|
522
|
-
else if (this.TargetHorizontalTiltAngle === -90 && this.TargetPosition === 0) {
|
|
523
|
-
command = 'closeDown';
|
|
524
|
-
parameter = 'default';
|
|
525
|
-
}
|
|
526
|
-
else {
|
|
527
|
-
let direction = '';
|
|
528
|
-
const position = this.TargetPosition;
|
|
529
|
-
if (this.TargetHorizontalTiltAngle === 90) {
|
|
530
|
-
direction = 'up';
|
|
531
|
-
}
|
|
532
|
-
else {
|
|
533
|
-
direction = 'down';
|
|
534
|
-
}
|
|
535
|
-
command = 'setPosition';
|
|
536
|
-
parameter = `${direction};${position}`;
|
|
537
|
-
}
|
|
596
|
+
const [direction, position] = this.mapHomekitValuesToDeviceValues(Number(this.TargetPosition), Number(this.TargetHorizontalTiltAngle));
|
|
597
|
+
this.debugLog(`Pushing ${this.TargetPosition} (device = ${direction};${position})`);
|
|
598
|
+
this.debugLog(`${this.accessory.displayName} Mode: ${this.Mode}`);
|
|
538
599
|
const body = (0, super_stringify_1.default)({
|
|
539
|
-
'command':
|
|
540
|
-
'parameter': `${
|
|
600
|
+
'command': 'setPosition',
|
|
601
|
+
'parameter': `${direction};${position}`,
|
|
541
602
|
'commandType': 'command',
|
|
542
603
|
});
|
|
543
604
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Sending request to SwitchBot API, body: ${body},`);
|
|
@@ -580,6 +641,23 @@ class BlindTilt {
|
|
|
580
641
|
+ ` Connection, Error Message: ${(0, super_stringify_1.default)(e.message)}`);
|
|
581
642
|
}
|
|
582
643
|
}
|
|
644
|
+
/**
|
|
645
|
+
* Handle requests to set the value of the "Target Horizontal Tilt" characteristic
|
|
646
|
+
*/
|
|
647
|
+
async TargetHorizontalTiltAngleSet(value) {
|
|
648
|
+
if (this.TargetHorizontalTiltAngle === this.accessory.context.TargetHorizontalTiltAngle) {
|
|
649
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set TargetHorizontalTiltAngle: ${value}`);
|
|
650
|
+
}
|
|
651
|
+
else {
|
|
652
|
+
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set TargetHorizontalTiltAngle: ${value}`);
|
|
653
|
+
}
|
|
654
|
+
//value = value < 0 ? -90 : 90;
|
|
655
|
+
this.TargetHorizontalTiltAngle = value;
|
|
656
|
+
if (this.device.mqttURL) {
|
|
657
|
+
this.mqttPublish('TargetHorizontalTiltAngle', this.TargetHorizontalTiltAngle);
|
|
658
|
+
}
|
|
659
|
+
this.startUpdatingBlindTiltIfNeeded();
|
|
660
|
+
}
|
|
583
661
|
/**
|
|
584
662
|
* Handle requests to set the value of the "Target Position" characteristic
|
|
585
663
|
*/
|
|
@@ -594,52 +672,28 @@ class BlindTilt {
|
|
|
594
672
|
if (this.device.mqttURL) {
|
|
595
673
|
this.mqttPublish('TargetPosition', this.TargetPosition);
|
|
596
674
|
}
|
|
675
|
+
this.startUpdatingBlindTiltIfNeeded();
|
|
676
|
+
}
|
|
677
|
+
async startUpdatingBlindTiltIfNeeded() {
|
|
597
678
|
await this.setMinMax();
|
|
598
|
-
|
|
679
|
+
this.debugLog('setMinMax');
|
|
680
|
+
if (this.TargetPosition > this.CurrentPosition || (this.TargetHorizontalTiltAngle !== this.CurrentHorizontalTiltAngle)) {
|
|
599
681
|
this.PositionState = this.platform.Characteristic.PositionState.INCREASING;
|
|
600
682
|
this.setNewTarget = true;
|
|
601
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${
|
|
683
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${this.CurrentPosition},` +
|
|
684
|
+
` CurrentPosition: ${this.CurrentPosition}`);
|
|
602
685
|
}
|
|
603
|
-
else if (
|
|
686
|
+
else if (this.TargetPosition < this.CurrentPosition) {
|
|
604
687
|
this.PositionState = this.platform.Characteristic.PositionState.DECREASING;
|
|
605
688
|
this.setNewTarget = true;
|
|
606
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${
|
|
689
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${this.CurrentPosition},` +
|
|
690
|
+
` CurrentPosition: ${this.CurrentPosition}`);
|
|
607
691
|
}
|
|
608
692
|
else {
|
|
609
693
|
this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
|
|
610
694
|
this.setNewTarget = false;
|
|
611
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${
|
|
612
|
-
|
|
613
|
-
this.windowCoveringService.setCharacteristic(this.platform.Characteristic.PositionState, this.PositionState);
|
|
614
|
-
this.windowCoveringService.getCharacteristic(this.platform.Characteristic.PositionState).updateValue(this.PositionState);
|
|
615
|
-
/**
|
|
616
|
-
* If Blind Tilt movement time is short, the moving flag from backend is always false.
|
|
617
|
-
* The minimum time depends on the network control latency.
|
|
618
|
-
*/
|
|
619
|
-
clearTimeout(this.setNewTargetTimer);
|
|
620
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateRate: ${this.updateRate}`);
|
|
621
|
-
if (this.setNewTarget) {
|
|
622
|
-
this.setNewTargetTimer = setTimeout(() => {
|
|
623
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} setNewTarget ${this.setNewTarget} timeout`);
|
|
624
|
-
this.setNewTarget = false;
|
|
625
|
-
}, this.updateRate * 1000);
|
|
626
|
-
}
|
|
627
|
-
this.doBlindTiltUpdate.next();
|
|
628
|
-
}
|
|
629
|
-
/**
|
|
630
|
-
* Handle requests to set the value of the "Target Position" characteristic
|
|
631
|
-
*/
|
|
632
|
-
async TargetHorizontalTiltAngleSet(value) {
|
|
633
|
-
if (this.TargetHorizontalTiltAngle === this.accessory.context.TargetHorizontalTiltAngle) {
|
|
634
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} No Changes, Set TargetHorizontalTiltAngle: ${value}`);
|
|
635
|
-
}
|
|
636
|
-
else {
|
|
637
|
-
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Set TargetHorizontalTiltAngle: ${value}`);
|
|
638
|
-
}
|
|
639
|
-
this.TargetHorizontalTiltAngle = value;
|
|
640
|
-
this.accessory.context.TargetHorizontalTiltAngle = this.TargetHorizontalTiltAngle;
|
|
641
|
-
if (this.device.mqttURL) {
|
|
642
|
-
this.mqttPublish('TargetHorizontalTiltAngle', this.TargetHorizontalTiltAngle);
|
|
695
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} value: ${this.CurrentPosition},` +
|
|
696
|
+
` CurrentPosition: ${this.CurrentPosition}`);
|
|
643
697
|
}
|
|
644
698
|
this.windowCoveringService.setCharacteristic(this.platform.Characteristic.PositionState, this.PositionState);
|
|
645
699
|
this.windowCoveringService.getCharacteristic(this.platform.Characteristic.PositionState).updateValue(this.PositionState);
|
|
@@ -659,6 +713,20 @@ class BlindTilt {
|
|
|
659
713
|
}
|
|
660
714
|
async updateHomeKitCharacteristics() {
|
|
661
715
|
await this.setMinMax();
|
|
716
|
+
if (this.mappingMode === BlindTiltMappingMode.UseTiltForDirection) {
|
|
717
|
+
if (this.CurrentHorizontalTiltAngle === undefined || Number.isNaN(this.CurrentHorizontalTiltAngle)) {
|
|
718
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentHorizontalTiltAngle: ${this.CurrentHorizontalTiltAngle}`);
|
|
719
|
+
}
|
|
720
|
+
else {
|
|
721
|
+
if (this.device.mqttURL) {
|
|
722
|
+
this.mqttPublish('CurrentHorizontalTiltAngle', this.CurrentHorizontalTiltAngle);
|
|
723
|
+
}
|
|
724
|
+
this.accessory.context.CurrentHorizontalTiltAngle = this.CurrentHorizontalTiltAngle;
|
|
725
|
+
this.windowCoveringService.updateCharacteristic(this.platform.Characteristic.CurrentHorizontalTiltAngle, Number(this.CurrentHorizontalTiltAngle));
|
|
726
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}
|
|
727
|
+
updateCharacteristic CurrentHorizontalTiltAngle: ${this.CurrentHorizontalTiltAngle}`);
|
|
728
|
+
}
|
|
729
|
+
}
|
|
662
730
|
if (this.CurrentPosition === undefined || Number.isNaN(this.CurrentPosition)) {
|
|
663
731
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentPosition: ${this.CurrentPosition}`);
|
|
664
732
|
}
|
|
@@ -692,17 +760,19 @@ class BlindTilt {
|
|
|
692
760
|
this.windowCoveringService.updateCharacteristic(this.platform.Characteristic.TargetPosition, Number(this.TargetPosition));
|
|
693
761
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic TargetPosition: ${this.TargetPosition}`);
|
|
694
762
|
}
|
|
695
|
-
if (this.
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
763
|
+
if (!this.device.curtain?.hide_lightsensor) {
|
|
764
|
+
if (this.CurrentAmbientLightLevel === undefined || Number.isNaN(this.CurrentAmbientLightLevel)) {
|
|
765
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
766
|
+
}
|
|
767
|
+
else {
|
|
768
|
+
if (this.device.mqttURL) {
|
|
769
|
+
this.mqttPublish('CurrentAmbientLightLevel', this.CurrentAmbientLightLevel);
|
|
770
|
+
}
|
|
771
|
+
this.accessory.context.CurrentAmbientLightLevel = this.CurrentAmbientLightLevel;
|
|
772
|
+
this.lightSensorService?.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, this.CurrentAmbientLightLevel);
|
|
773
|
+
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName}`
|
|
774
|
+
+ ` updateCharacteristic CurrentAmbientLightLevel: ${this.CurrentAmbientLightLevel}`);
|
|
701
775
|
}
|
|
702
|
-
this.accessory.context.TargetHorizontalTiltAngle = this.TargetHorizontalTiltAngle;
|
|
703
|
-
this.windowCoveringService.updateCharacteristic(this.platform.Characteristic.TargetHorizontalTiltAngle, Number(this.TargetHorizontalTiltAngle));
|
|
704
|
-
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} updateCharacteristic`
|
|
705
|
-
+ ` TargetHorizontalTiltAngle: ${this.TargetHorizontalTiltAngle}`);
|
|
706
776
|
}
|
|
707
777
|
if (this.BLE) {
|
|
708
778
|
if (this.BatteryLevel === undefined) {
|
|
@@ -800,6 +870,28 @@ class BlindTilt {
|
|
|
800
870
|
await this.openAPIRefreshStatus();
|
|
801
871
|
}
|
|
802
872
|
}
|
|
873
|
+
async SilentPerformance() {
|
|
874
|
+
if (this.TargetPosition > 50) {
|
|
875
|
+
if (this.device.curtain?.setOpenMode === '1') {
|
|
876
|
+
this.setPositionMode = 1;
|
|
877
|
+
this.Mode = 'Silent Mode';
|
|
878
|
+
}
|
|
879
|
+
else {
|
|
880
|
+
this.setPositionMode = 0;
|
|
881
|
+
this.Mode = 'Performance Mode';
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
else {
|
|
885
|
+
if (this.device.curtain?.setCloseMode === '1') {
|
|
886
|
+
this.setPositionMode = 1;
|
|
887
|
+
this.Mode = 'Silent Mode';
|
|
888
|
+
}
|
|
889
|
+
else {
|
|
890
|
+
this.setPositionMode = 0;
|
|
891
|
+
this.Mode = 'Performance Mode';
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
}
|
|
803
895
|
async setMinMax() {
|
|
804
896
|
if (this.device.curtain?.set_min) {
|
|
805
897
|
if (this.CurrentPosition <= this.device.curtain?.set_min) {
|
|
@@ -811,13 +903,16 @@ class BlindTilt {
|
|
|
811
903
|
this.CurrentPosition = 100;
|
|
812
904
|
}
|
|
813
905
|
}
|
|
906
|
+
if (this.mappingMode === BlindTiltMappingMode.UseTiltForDirection) {
|
|
907
|
+
this.CurrentHorizontalTiltAngle = this.CurrentHorizontalTiltAngle < 0 ? -90 : 90;
|
|
908
|
+
}
|
|
814
909
|
}
|
|
815
910
|
minStep(device) {
|
|
816
911
|
if (device.curtain?.set_minStep) {
|
|
817
912
|
this.set_minStep = device.curtain?.set_minStep;
|
|
818
913
|
}
|
|
819
914
|
else {
|
|
820
|
-
this.set_minStep =
|
|
915
|
+
this.set_minStep = 1;
|
|
821
916
|
}
|
|
822
917
|
return this.set_minStep;
|
|
823
918
|
}
|
|
@@ -911,6 +1006,9 @@ class BlindTilt {
|
|
|
911
1006
|
this.windowCoveringService.updateCharacteristic(this.platform.Characteristic.CurrentPosition, e);
|
|
912
1007
|
this.windowCoveringService.updateCharacteristic(this.platform.Characteristic.PositionState, e);
|
|
913
1008
|
this.windowCoveringService.updateCharacteristic(this.platform.Characteristic.TargetPosition, e);
|
|
1009
|
+
if (!this.device.curtain?.hide_lightsensor) {
|
|
1010
|
+
this.lightSensorService?.updateCharacteristic(this.platform.Characteristic.CurrentAmbientLightLevel, e);
|
|
1011
|
+
}
|
|
914
1012
|
if (this.BLE) {
|
|
915
1013
|
this.batteryService?.updateCharacteristic(this.platform.Characteristic.BatteryLevel, e);
|
|
916
1014
|
this.batteryService?.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, e);
|
|
@@ -947,12 +1045,6 @@ class BlindTilt {
|
|
|
947
1045
|
else {
|
|
948
1046
|
this.TargetPosition = this.accessory.context.TargetPosition;
|
|
949
1047
|
}
|
|
950
|
-
if (this.TargetHorizontalTiltAngle === undefined) {
|
|
951
|
-
this.TargetHorizontalTiltAngle = 0;
|
|
952
|
-
}
|
|
953
|
-
else {
|
|
954
|
-
this.TargetHorizontalTiltAngle = this.accessory.context.TargetHorizontalTiltAngle;
|
|
955
|
-
}
|
|
956
1048
|
if (this.PositionState === undefined) {
|
|
957
1049
|
this.PositionState = this.platform.Characteristic.PositionState.STOPPED;
|
|
958
1050
|
}
|
|
@@ -960,6 +1052,120 @@ class BlindTilt {
|
|
|
960
1052
|
this.PositionState = this.accessory.context.PositionState;
|
|
961
1053
|
}
|
|
962
1054
|
}
|
|
1055
|
+
/**
|
|
1056
|
+
* Maps device values to homekit values
|
|
1057
|
+
*
|
|
1058
|
+
* @param devicePosition the position as reported by the devide
|
|
1059
|
+
* @param direction the direction as reported by the device
|
|
1060
|
+
* @returns [homekit position, homekit tiltAngle]
|
|
1061
|
+
*/
|
|
1062
|
+
mapDeviceValuesToHomekitValues(devicePosition, deviceDirection) {
|
|
1063
|
+
// device position 0 => closed down
|
|
1064
|
+
// device position 50 => open
|
|
1065
|
+
// device position 100 => closed up
|
|
1066
|
+
// homekit position 0 => closed
|
|
1067
|
+
// homekit position 100 => open
|
|
1068
|
+
deviceDirection;
|
|
1069
|
+
switch (this.mappingMode) {
|
|
1070
|
+
case BlindTiltMappingMode.OnlyUp:
|
|
1071
|
+
// we only close upwards, so we see anything that is tilted downwards(<50) as open
|
|
1072
|
+
if (devicePosition < 50) {
|
|
1073
|
+
return [100, undefined]; // fully open in homekit
|
|
1074
|
+
}
|
|
1075
|
+
else {
|
|
1076
|
+
// we range from 50->100, with 100 being closed, so map to homekit by scaling to 0..100 and then reversing
|
|
1077
|
+
return [100 - (devicePosition - 50) * 2, undefined];
|
|
1078
|
+
}
|
|
1079
|
+
case BlindTiltMappingMode.OnlyDown:
|
|
1080
|
+
// we only close downwards, so we see anything that is tilted upwards(>50) as upwards
|
|
1081
|
+
if (devicePosition > 50) {
|
|
1082
|
+
return [100, undefined]; // fully open in homekit
|
|
1083
|
+
}
|
|
1084
|
+
else {
|
|
1085
|
+
// we range from 0..50 so scale to homekit and then reverse
|
|
1086
|
+
return [devicePosition * 2, undefined];
|
|
1087
|
+
}
|
|
1088
|
+
case BlindTiltMappingMode.DownAndUp:
|
|
1089
|
+
// we close both ways with closed downwards being 0 in homekit and closed upwards in homekit being 100. Open is 50 in homekit
|
|
1090
|
+
return [devicePosition, undefined];
|
|
1091
|
+
case BlindTiltMappingMode.UpAndDown:
|
|
1092
|
+
// we close both ways with closed downwards being 1000 in homekit and closed upwards in homekit being 0. Open is 50 in homekit.,
|
|
1093
|
+
// so we reverse the value
|
|
1094
|
+
return [100 - devicePosition, undefined];
|
|
1095
|
+
case BlindTiltMappingMode.UseTiltForDirection:
|
|
1096
|
+
// we use tilt for direction, so being closed downwards is 0 in homekit with -90 tilt, while being closed upwards is 0 with 90 tilt.
|
|
1097
|
+
if (devicePosition <= 50) {
|
|
1098
|
+
// downwards tilted, so we range from 0..50, with 0 being closed and 50 being open, so scale.
|
|
1099
|
+
return [devicePosition * 2, -90];
|
|
1100
|
+
}
|
|
1101
|
+
else {
|
|
1102
|
+
// upwards tilted, so we range from 50..100, with 50 being open and 100 being closed, so scale and rever
|
|
1103
|
+
return [100 - (devicePosition - 50) * 2, 90];
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
/**
|
|
1108
|
+
* Maps homekit values to device values
|
|
1109
|
+
*
|
|
1110
|
+
* @param homekitPosition the position as reported by homekit
|
|
1111
|
+
* @param homekitTiltAngle? the tilt angle as reported by homekit
|
|
1112
|
+
* @returns [device position, device direction]
|
|
1113
|
+
*/
|
|
1114
|
+
mapHomekitValuesToDeviceValues(homekitPosition, homekitTiltAngle) {
|
|
1115
|
+
// homekit position 0 => closed
|
|
1116
|
+
// homekit position 100 => open
|
|
1117
|
+
// device position [up, 0] = closed upwards
|
|
1118
|
+
// device position [down, 0] = closed downwards
|
|
1119
|
+
// device position [up, 100] = open
|
|
1120
|
+
// device position [down, 100] = open
|
|
1121
|
+
switch (this.mappingMode) {
|
|
1122
|
+
case BlindTiltMappingMode.OnlyUp:
|
|
1123
|
+
// invert
|
|
1124
|
+
return ['up', homekitPosition];
|
|
1125
|
+
case BlindTiltMappingMode.OnlyDown:
|
|
1126
|
+
// invert
|
|
1127
|
+
return ['down', homekitPosition];
|
|
1128
|
+
case BlindTiltMappingMode.DownAndUp:
|
|
1129
|
+
// homekit 0 = downwards closed,
|
|
1130
|
+
// homekit 50 = open,
|
|
1131
|
+
// homekit 100 = upwards closed
|
|
1132
|
+
if (homekitPosition <= 50) {
|
|
1133
|
+
// homekit 0..50 -> device 100..0 so scale and invert
|
|
1134
|
+
return ['down', 100 - homekitPosition * 2];
|
|
1135
|
+
}
|
|
1136
|
+
else {
|
|
1137
|
+
// homekit 50..100 -> device 0..100, so rebase, scale and invert
|
|
1138
|
+
return ['up', (homekitPosition - 50) * 2];
|
|
1139
|
+
}
|
|
1140
|
+
case BlindTiltMappingMode.UpAndDown:
|
|
1141
|
+
// homekit 0 = upwards closed,
|
|
1142
|
+
// homekit 50 = open,
|
|
1143
|
+
// homekit 100 = upwards closed
|
|
1144
|
+
if (homekitPosition <= 50) {
|
|
1145
|
+
// homekit 0..50 -> device 0..100 so scale and invert
|
|
1146
|
+
return ['up', homekitPosition * 2];
|
|
1147
|
+
}
|
|
1148
|
+
else {
|
|
1149
|
+
// homekit 50..100 -> device 100...0 so scale
|
|
1150
|
+
return ['down', 100 - homekitPosition * 2];
|
|
1151
|
+
}
|
|
1152
|
+
case BlindTiltMappingMode.UseTiltForDirection:
|
|
1153
|
+
// tilt -90, homekit 0 = closed downwards
|
|
1154
|
+
// tilt -90, homekit 100 = open
|
|
1155
|
+
// tilt 90, homekit 0 = closed upwards
|
|
1156
|
+
// tilt 90, homekit 100 = open
|
|
1157
|
+
if (homekitTiltAngle <= 0) {
|
|
1158
|
+
// downwards
|
|
1159
|
+
// homekit 0..100 -> device 0..100, so invert
|
|
1160
|
+
return ['down', homekitPosition];
|
|
1161
|
+
}
|
|
1162
|
+
else {
|
|
1163
|
+
// upwards
|
|
1164
|
+
// homekit 0..100 -> device 0..100, so invert
|
|
1165
|
+
return ['up,', homekitPosition];
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
963
1169
|
async refreshRate(device) {
|
|
964
1170
|
// refreshRate
|
|
965
1171
|
if (device.refreshRate) {
|
|
@@ -971,19 +1177,19 @@ class BlindTilt {
|
|
|
971
1177
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Platform Config refreshRate: ${this.deviceRefreshRate}`);
|
|
972
1178
|
}
|
|
973
1179
|
// updateRate
|
|
974
|
-
if (device?.
|
|
975
|
-
this.updateRate = device?.
|
|
1180
|
+
if (device?.blindTilt?.updateRate) {
|
|
1181
|
+
this.updateRate = device?.blindTilt?.updateRate;
|
|
976
1182
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Device Config Blind Tilt updateRate: ${this.updateRate}`);
|
|
977
1183
|
}
|
|
978
1184
|
else {
|
|
979
|
-
this.updateRate =
|
|
1185
|
+
this.updateRate = 2;
|
|
980
1186
|
this.debugLog(`${this.device.deviceType}: ${this.accessory.displayName} Using Default Blind Tilt updateRate: ${this.updateRate}`);
|
|
981
1187
|
}
|
|
982
1188
|
}
|
|
983
1189
|
async config(device) {
|
|
984
1190
|
let config = {};
|
|
985
|
-
if (device.
|
|
986
|
-
config = device.
|
|
1191
|
+
if (device.blindTilt) {
|
|
1192
|
+
config = device.blindTilt;
|
|
987
1193
|
}
|
|
988
1194
|
if (device.connectionType !== undefined) {
|
|
989
1195
|
config['connectionType'] = device.connectionType;
|
|
@@ -1006,6 +1212,12 @@ class BlindTilt {
|
|
|
1006
1212
|
if (device.maxRetry !== undefined) {
|
|
1007
1213
|
config['maxRetry'] = device.maxRetry;
|
|
1008
1214
|
}
|
|
1215
|
+
if (device.blindTilt?.mappingMode === undefined) {
|
|
1216
|
+
config['mappingMode'] = BlindTiltMappingMode.OnlyUp;
|
|
1217
|
+
}
|
|
1218
|
+
else {
|
|
1219
|
+
config['mappingMode'] = device.blindTilt?.mappingMode;
|
|
1220
|
+
}
|
|
1009
1221
|
if (Object.entries(config).length !== 0) {
|
|
1010
1222
|
this.infoLog(`${this.device.deviceType}: ${this.accessory.displayName} Config: ${(0, super_stringify_1.default)(config)}`);
|
|
1011
1223
|
}
|