diff --git a/README.md b/README.md index bb30b96..c83da7a 100644 --- a/README.md +++ b/README.md @@ -317,16 +317,20 @@ CurrentHeatingCoolingState = 0 for OFF, 1 for HEAT and 2 for COOL This accessory type can be used for shutters or blinds. Because the differnce between HomeKit and the controlling technology, for example KNX, can be significant this accessory has a lot of parameters. Luckily most are optional. #### Characteristics in addition to [common characteristics](#common-accessories-characteristics) -| Parameter | Possible values | Mandatory | Default | Description | -|:------------------------|:----------------|:----------|:--------|:------------------------------------------------------------------| -| CurrentPosition | \ | Yes | | SHNG item to monitor thecurrent position | -| TargetPosition | \ | Yes | | SHNG item to monitor and set the target position | -| CurrentPositionMin | \ | No | 0 | Your device's minimum value for current position | -| CurrentPositionMax | \ | No | 100 | Your device's maximum value for current position | -| CurrentPositionInverted | \ | No | false | Should the values be inverted, ex: 0 for Homekit = 100 for device | -| TargetPositionMin | \ | No | 0 | Your device's minimum value for target position | -| TargetPositionMax | \ | No | 100 | Your device's maximum value for target position | -| TargetPositionInverted | \ | No | false | Should the values be inverted, ex: 0 for Homekit = 100 for device | +| Parameter | Possible values | Mandatory | Default | Description | +|:---------------------------|:----------------|:----------|:--------|:------------------------------------------------------------------| +| CurrentPosition | \ | Yes | | SHNG item to monitor thecurrent position | +| TargetPosition | \ | Yes | | SHNG item to monitor and set the target position | +| CurrentPositionMin | \ | No | 0 | Your device's minimum value for current position | +| CurrentPositionMax | \ | No | 100 | Your device's maximum value for current position | +| CurrentPositionInverted | \ | No | false | Should the values be inverted, ex: 0 for Homekit = 100 for device | +| TargetPositionMin | \ | No | 0 | Your device's minimum value for target position | +| TargetPositionMax | \ | No | 100 | Your device's maximum value for target position | +| TargetPositionInverted | \ | No | false | Should the values be inverted, ex: 0 for Homekit = 100 for device | +| CurrentHorizontalTiltAngle | \ | No | | SHNG item to monitor current horizontal tilt angle | +| TargetHorizontalTiltAngle | \ | No | | SHNG item to monitor and set the target horizontal tilt angle | +| CurrentVerticalTiltAngle | \ | No | | SHNG item to monitor current vertical tilt angle | +| TargetVerticalTiltAngle | \ | No | | SHNG item to monitor and set the target vertical tilt angle | #### Additional comments diff --git a/src/Accessories/WindowCovering.ts b/src/Accessories/WindowCovering.ts index ad690d3..26c9bed 100644 --- a/src/Accessories/WindowCovering.ts +++ b/src/Accessories/WindowCovering.ts @@ -15,6 +15,8 @@ export class WindowCovering implements AccessoryPlugin { private currentPosition = 0; private currentPositionMin = 0; private currentPositionMax = 100; private currentPositionInverted = false; private targetPosition = 0; private targetPositionMin = 0; private targetPositionMax = 100; private targetPositionInverted = false; private positionState = this.platform.Characteristic.PositionState.STOPPED; + private currentHorizontalTiltAngle = 0; private targetHorizontalTiltAngle = 0; + private currentVerticalTiltAngle = 0; private targetVerticalTiltAngle = 0; constructor(private readonly platform: SmartHomeNGPlatform, private readonly accessory) { this.name = accessory.name; @@ -28,6 +30,20 @@ export class WindowCovering implements AccessoryPlugin { .onGet(this.getTargetPosition.bind(this)) .onSet(this.setTargetPosition.bind(this)); + this.deviceService.getCharacteristic(this.platform.Characteristic.CurrentHorizontalTiltAngle) + .onGet(this.getCurrentHorizontalTiltAngle.bind(this)); + + this.deviceService.getCharacteristic(this.platform.Characteristic.TargetHorizontalTiltAngle) + .onGet(this.getTargetHorizontalTiltAngle.bind(this)) + .onSet(this.setTargetHorizontalTiltAngle.bind(this)); + + this.deviceService.getCharacteristic(this.platform.Characteristic.CurrentVerticalTiltAngle) + .onGet(this.getCurrentVerticalTiltAngle.bind(this)); + + this.deviceService.getCharacteristic(this.platform.Characteristic.TargetVerticalTiltAngle) + .onGet(this.getTargetVerticalTiltAngle.bind(this)) + .onSet(this.setTargetVerticalTiltAngle.bind(this)); + this.deviceService.getCharacteristic(this.platform.Characteristic.PositionState) .onGet(this.getPositionState.bind(this)); @@ -39,6 +55,18 @@ export class WindowCovering implements AccessoryPlugin { this.platform.shng.addMonitor(accessory.currentposition, this.shngCurrentPositionCallback.bind(this)); this.platform.shng.addMonitor(accessory.targetposition, this.shngTargetPositionCallback.bind(this)); + if (accessory.currenthorizontaltiltangle) { + this.platform.shng.addMonitor(accessory.currenthorizontaltiltangle, this.shngCurrentHorizontalTiltAngleCallback.bind(this)); + } + if (accessory.targethorizontaltiltangle) { + this.platform.shng.addMonitor(accessory.targethorizontaltiltangle, this.shngTargetHorizontalTiltAngleCallback.bind(this)); + } + if (accessory.currentverticaltiltangle) { + this.platform.shng.addMonitor(accessory.currentverticaltiltangle, this.shngCurrentVerticalTiltAngleCallback.bind(this)); + } + if (accessory.targetverticaltiltangle) { + this.platform.shng.addMonitor(accessory.targetverticaltiltangle, this.shngTargetVerticalTiltAngleCallback.bind(this)); + } this.currentPositionMax = accessory.currentpositionmax ? accessory.currentpositionmax : this.currentPositionMax; this.currentPositionMin = accessory.currentpositionmin ? accessory.currentpositionmin : this.currentPositionMin; @@ -74,7 +102,7 @@ export class WindowCovering implements AccessoryPlugin { setTargetPosition(value: CharacteristicValue) { this.targetPosition = value as number; - this.platform.log.info('SetOn:', this.accessory.name, 'was set to', this.targetPosition); + this.platform.log.info('setTargetPosition:', this.accessory.name, 'was set to', this.targetPosition); const transposedTarget = this.convertRange( value as number, 0, 100, @@ -84,6 +112,39 @@ export class WindowCovering implements AccessoryPlugin { this.platform.shng.setItem(this.accessory.targetposition, transposedTarget); } + getCurrentHorizontalTiltAngle(): Nullable { + this.platform.log.info('getCurrentHorizontalTiltAngle:', this.accessory.name, 'is currently', this.currentHorizontalTiltAngle); + return this.currentHorizontalTiltAngle; + } + + getTargetHorizontalTiltAngle(): Nullable { + this.platform.log.info('getTargetHorizontalTiltAngle:', this.accessory.name, 'is currently', this.targetHorizontalTiltAngle); + return this.targetHorizontalTiltAngle; + } + + setTargetHorizontalTiltAngle(value: CharacteristicValue) { + this.targetHorizontalTiltAngle = value as number; + this.platform.log.info('setTargetHorizontalTiltAngle:', this.accessory.name, 'was set to', this.targetHorizontalTiltAngle); + this.platform.shng.setItem(this.accessory.targethorizontaltiltangle, this.targetHorizontalTiltAngle); + } + + getCurrentVerticalTiltAngle(): Nullable { + this.platform.log.info('getCurrentVerticalTiltAngle:', this.accessory.name, 'is currently', this.currentVerticalTiltAngle); + return this.currentVerticalTiltAngle; + } + + getTargetVerticalTiltAngle(): Nullable { + this.platform.log.info('getTargetVerticalTiltAngle:', this.accessory.name, 'is currently', this.targetVerticalTiltAngle); + return this.targetVerticalTiltAngle; + } + + setTargetVerticalTiltAngle(value: CharacteristicValue) { + this.targetVerticalTiltAngle = value as number; + this.platform.log.info('setTargetVerticalTiltAngle:', this.accessory.name, 'was set to', this.targetVerticalTiltAngle); + this.platform.shng.setItem(this.accessory.targetverticaltiltangle, this.targetVerticalTiltAngle); + } + + shngCurrentPositionCallback(value: unknown): void { this.platform.log.debug('shngCurrentPositionCallback:', this.accessory.name, '=', value, '(' + typeof value + ')'); if (typeof value === 'number') { @@ -117,6 +178,43 @@ export class WindowCovering implements AccessoryPlugin { this.updateDirection(); } + + shngCurrentHorizontalTiltAngleCallback(value: unknown): void { + this.platform.log.debug('shngCurrentHorizontalTiltAngleCallback:', this.accessory.name, '=', value, '(' + typeof value + ')'); + if (typeof value === 'number') { + this.currentHorizontalTiltAngle = value; + } else { + this.platform.log.warn('Unknown type ', typeof value, 'received for', this.accessory.name + ':', value); + } + } + + shngTargetHorizontalTiltAngleCallback(value: unknown): void { + this.platform.log.debug('shngTargetHorizontalTiltAngleCallback:', this.accessory.name, '=', value, '(' + typeof value + ')'); + if (typeof value === 'number') { + this.targetHorizontalTiltAngle = value; + } else { + this.platform.log.warn('Unknown type ', typeof value, 'received for', this.accessory.name + ':', value); + } + } + + shngCurrentVerticalTiltAngleCallback(value: unknown): void { + this.platform.log.debug('shngCurrentVerticalTiltAngleCallback:', this.accessory.name, '=', value, '(' + typeof value + ')'); + if (typeof value === 'number') { + this.currentVerticalTiltAngle = value; + } else { + this.platform.log.warn('Unknown type ', typeof value, 'received for', this.accessory.name + ':', value); + } + } + + shngTargetVerticalTiltAngleCallback(value: unknown): void { + this.platform.log.debug('shngTargetVerticalTiltAngleCallback:', this.accessory.name, '=', value, '(' + typeof value + ')'); + if (typeof value === 'number') { + this.targetVerticalTiltAngle = value; + } else { + this.platform.log.warn('Unknown type ', typeof value, 'received for', this.accessory.name + ':', value); + } + } + updateDirection() { let direction; if (this.targetPosition < this.currentPosition) {