[homekit] add support for number and dimmer item type to window covering accessory (#10051)
Signed-off-by: Eugen Freiter <freiter@gmx.de>
This commit is contained in:
parent
da387618fd
commit
0d13b8d1ef
|
@ -129,7 +129,9 @@ A HomeKit accessory has mandatory and optional characteristics (listed below in
|
||||||
The mapping between openHAB items and HomeKit accessory and characteristics is done by means of [metadata](https://www.openhab.org/docs/concepts/items.html#item-metadata)
|
The mapping between openHAB items and HomeKit accessory and characteristics is done by means of [metadata](https://www.openhab.org/docs/concepts/items.html#item-metadata)
|
||||||
|
|
||||||
### UI based Configuration
|
### UI based Configuration
|
||||||
|
|
||||||
In order to add metadata to an item:
|
In order to add metadata to an item:
|
||||||
|
|
||||||
- select desired item in mainUI
|
- select desired item in mainUI
|
||||||
- click on "Add Metadata"
|
- click on "Add Metadata"
|
||||||
|
|
||||||
|
@ -151,6 +153,7 @@ In order to add metadata to an item:
|
||||||
|
|
||||||
|
|
||||||
### Textual configuration
|
### Textual configuration
|
||||||
|
|
||||||
```xtend
|
```xtend
|
||||||
Switch leaksensor_metadata "Leak Sensor" {homekit="LeakSensor"}
|
Switch leaksensor_metadata "Leak Sensor" {homekit="LeakSensor"}
|
||||||
```
|
```
|
||||||
|
@ -283,7 +286,19 @@ Rollershutter window_covering "Blind" (gBlind)
|
||||||
Dimmer window_covering_htilt "Blind horizontal tilt" (gBlind) {homekit = "WindowCovering.CurrentHorizontalTiltAngle, WindowCovering.TargetHorizontalTiltAngle"}
|
Dimmer window_covering_htilt "Blind horizontal tilt" (gBlind) {homekit = "WindowCovering.CurrentHorizontalTiltAngle, WindowCovering.TargetHorizontalTiltAngle"}
|
||||||
Dimmer window_covering_vtilt "Blind vertical tilt" (gBlind) {homekit = "WindowCovering.CurrentVerticalTiltAngle, WindowCovering.TargetVerticalTiltAngle"}
|
Dimmer window_covering_vtilt "Blind vertical tilt" (gBlind) {homekit = "WindowCovering.CurrentVerticalTiltAngle, WindowCovering.TargetVerticalTiltAngle"}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Current and Target Position characteristics can be linked to Rollershutter but also to Number or Dimmer item types.
|
||||||
|
e.g.
|
||||||
|
|
||||||
|
```xtend
|
||||||
|
Group gBlind "Blinds" {homekit = "WindowCovering"}
|
||||||
|
Dimmer blind_current_position (gBlind) {homekit = "CurrentPosition"}
|
||||||
|
Number blind_target_position (gBlind) {homekit = "TargetPosition"}
|
||||||
|
String blind_position (gBlind) {homekit = "PositionState"}
|
||||||
|
```
|
||||||
|
|
||||||
### Thermostat
|
### Thermostat
|
||||||
|
|
||||||
A HomeKit thermostat has following mandatory characteristics:
|
A HomeKit thermostat has following mandatory characteristics:
|
||||||
|
|
||||||
- CurrentTemperature
|
- CurrentTemperature
|
||||||
|
@ -319,6 +334,7 @@ Number thermostat_heat_thrs "Thermostat Heat Threshold Temp [%.1f C]"
|
||||||
|
|
||||||
Current and target temperatures have default min and max values. Any values below or above max limits will be replaced with min or max limits.
|
Current and target temperatures have default min and max values. Any values below or above max limits will be replaced with min or max limits.
|
||||||
Default limits are:
|
Default limits are:
|
||||||
|
|
||||||
- current temperature: min value = 0 C, max value = 100 C
|
- current temperature: min value = 0 C, max value = 100 C
|
||||||
- target temperature: min value = 10 C, max value = 38 C
|
- target temperature: min value = 10 C, max value = 38 C
|
||||||
|
|
||||||
|
@ -526,23 +542,23 @@ Switch motionsensor_tampered "Motion Sensor Tampered"
|
||||||
| | | TamperedStatus | Switch, Contact | Tampered status |
|
| | | TamperedStatus | Switch, Contact | Tampered status |
|
||||||
| | | BatteryLowStatus | Switch, Contact | Battery status |
|
| | | BatteryLowStatus | Switch, Contact | Battery status |
|
||||||
| Door | | | | Motorized door. One Rollershutter item covers all mandatory characteristics. see examples below. |
|
| Door | | | | Motorized door. One Rollershutter item covers all mandatory characteristics. see examples below. |
|
||||||
| | CurrentPosition | | Rollershutter | Current position of motorized door |
|
| | CurrentPosition | | Rollershutter, Dimmer, Number | Current position of motorized door |
|
||||||
| | TargetPosition | | Rollershutter | Target position of motorized door |
|
| | TargetPosition | | Rollershutter, Dimmer, Number | Target position of motorized door |
|
||||||
| | PositionState | | Rollershutter | Position state. Supported states: DECREASING, INCREASING, STOPPED. Mapping can be redefined at item level, e.g. [DECREASING="Down", INCREASING="Up"]. If no state provided, "STOPPED" is used. |
|
| | PositionState | | Rollershutter, String | Position state. Supported states: DECREASING, INCREASING, STOPPED. Mapping can be redefined at item level, e.g. [DECREASING="Down", INCREASING="Up"]. If no state provided, "STOPPED" is used. |
|
||||||
| | | Name | String | Name of the motorized door |
|
| | | Name | String | Name of the motorized door |
|
||||||
| | | HoldPosition | Switch | Motorized door should stop at its current position. A value of ON must hold the state of the accessory. A value of OFF should be ignored. |
|
| | | HoldPosition | Switch | Motorized door should stop at its current position. A value of ON must hold the state of the accessory. A value of OFF should be ignored. |
|
||||||
| | | ObstructionStatus | Switch, Contact | Current status of obstruction sensor. ON-obstruction detected, OFF - no obstruction |
|
| | | ObstructionStatus | Switch, Contact | Current status of obstruction sensor. ON-obstruction detected, OFF - no obstruction |
|
||||||
| Window | | | | Motorized window. One Rollershutter item covers all mandatory characteristics. see examples below. |
|
| Window | | | | Motorized window. One Rollershutter item covers all mandatory characteristics. see examples below. |
|
||||||
| | CurrentPosition | | Rollershutter | Current position of motorized window |
|
| | CurrentPosition | | Rollershutter, Dimmer, Number | Current position of motorized window |
|
||||||
| | TargetPosition | | Rollershutter | Target position of motorized window |
|
| | TargetPosition | | Rollershutter, Dimmer, Number | Target position of motorized window |
|
||||||
| | PositionState | | Rollershutter | Position state. Supported states: DECREASING, INCREASING, STOPPED. Mapping can be redefined at item level, e.g. [DECREASING="Down", INCREASING="Up"]. If no state provided, "STOPPED" is used. |
|
| | PositionState | | Rollershutter, String | Position state. Supported states: DECREASING, INCREASING, STOPPED. Mapping can be redefined at item level, e.g. [DECREASING="Down", INCREASING="Up"]. If no state provided, "STOPPED" is used. |
|
||||||
| | | Name | String | Name of the motorized window |
|
| | | Name | String | Name of the motorized window |
|
||||||
| | | HoldPosition | Switch | Motorized door should stop at its current position. A value of ON must hold the state of the accessory. A value of OFF should be ignored. |
|
| | | HoldPosition | Switch | Motorized door should stop at its current position. A value of ON must hold the state of the accessory. A value of OFF should be ignored. |
|
||||||
| | | ObstructionStatus | Switch, Contact | Current status of obstruction sensor. ON-obstruction detected, OFF - no obstruction |
|
| | | ObstructionStatus | Switch, Contact | Current status of obstruction sensor. ON-obstruction detected, OFF - no obstruction |
|
||||||
| WindowCovering | | | | Window covering / blinds. One Rollershutter item covers all mandatory characteristics. see examples below. |
|
| WindowCovering | | | | Window covering / blinds. One Rollershutter item covers all mandatory characteristics. see examples below. |
|
||||||
| | CurrentPosition | | Rollershutter | Current position of window covering |
|
| | CurrentPosition | | Rollershutter, Dimmer, Number | Current position of window covering |
|
||||||
| | TargetPosition | | Rollershutter | Target position of window covering |
|
| | TargetPosition | | Rollershutter, Dimmer, Number | Target position of window covering |
|
||||||
| | PositionState | | Rollershutter | current only "STOPPED" is supported. |
|
| | PositionState | | Rollershutter, String | current only "STOPPED" is supported. |
|
||||||
| | | Name | String | Name of the windows covering |
|
| | | Name | String | Name of the windows covering |
|
||||||
| | | HoldPosition | Switch | Window covering should stop at its current position. A value of ON must hold the state of the accessory. A value of OFF should be ignored. |
|
| | | HoldPosition | Switch | Window covering should stop at its current position. A value of ON must hold the state of the accessory. A value of OFF should be ignored. |
|
||||||
| | | ObstructionStatus | Switch, Contact | Current status of obstruction sensor. ON-obstruction detected, OFF - no obstruction |
|
| | | ObstructionStatus | Switch, Contact | Current status of obstruction sensor. ON-obstruction detected, OFF - no obstruction |
|
||||||
|
|
|
@ -19,10 +19,14 @@ import static org.openhab.io.homekit.internal.HomekitCharacteristicType.TARGET_P
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.openhab.core.items.Item;
|
||||||
|
import org.openhab.core.library.items.DimmerItem;
|
||||||
|
import org.openhab.core.library.items.NumberItem;
|
||||||
import org.openhab.core.library.items.RollershutterItem;
|
import org.openhab.core.library.items.RollershutterItem;
|
||||||
import org.openhab.core.library.types.DecimalType;
|
import org.openhab.core.library.types.DecimalType;
|
||||||
import org.openhab.core.library.types.PercentType;
|
import org.openhab.core.library.types.PercentType;
|
||||||
|
@ -30,6 +34,8 @@ import org.openhab.io.homekit.internal.HomekitAccessoryUpdater;
|
||||||
import org.openhab.io.homekit.internal.HomekitCharacteristicType;
|
import org.openhab.io.homekit.internal.HomekitCharacteristicType;
|
||||||
import org.openhab.io.homekit.internal.HomekitSettings;
|
import org.openhab.io.homekit.internal.HomekitSettings;
|
||||||
import org.openhab.io.homekit.internal.HomekitTaggedItem;
|
import org.openhab.io.homekit.internal.HomekitTaggedItem;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import io.github.hapjava.characteristics.HomekitCharacteristicChangeCallback;
|
import io.github.hapjava.characteristics.HomekitCharacteristicChangeCallback;
|
||||||
import io.github.hapjava.characteristics.impl.windowcovering.PositionStateEnum;
|
import io.github.hapjava.characteristics.impl.windowcovering.PositionStateEnum;
|
||||||
|
@ -41,6 +47,7 @@ import io.github.hapjava.characteristics.impl.windowcovering.PositionStateEnum;
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
abstract class AbstractHomekitPositionAccessoryImpl extends AbstractHomekitAccessoryImpl {
|
abstract class AbstractHomekitPositionAccessoryImpl extends AbstractHomekitAccessoryImpl {
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(AbstractHomekitPositionAccessoryImpl.class);
|
||||||
protected int closedPosition;
|
protected int closedPosition;
|
||||||
protected int openPosition;
|
protected int openPosition;
|
||||||
private final Map<PositionStateEnum, String> positionStateMapping;
|
private final Map<PositionStateEnum, String> positionStateMapping;
|
||||||
|
@ -73,10 +80,24 @@ abstract class AbstractHomekitPositionAccessoryImpl extends AbstractHomekitAcces
|
||||||
return CompletableFuture.completedFuture(convertPositionState(TARGET_POSITION, openPosition, closedPosition));
|
return CompletableFuture.completedFuture(convertPositionState(TARGET_POSITION, openPosition, closedPosition));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNullByDefault({})
|
|
||||||
public CompletableFuture<Void> setTargetPosition(int value) {
|
public CompletableFuture<Void> setTargetPosition(int value) {
|
||||||
getItem(TARGET_POSITION, RollershutterItem.class)
|
getCharacteristic(TARGET_POSITION).ifPresentOrElse(taggedItem -> {
|
||||||
.ifPresent(item -> item.send(new PercentType(convertPosition(value, openPosition))));
|
final Item item = taggedItem.getItem();
|
||||||
|
final int targetPosition = convertPosition(value, openPosition);
|
||||||
|
if (item instanceof RollershutterItem) {
|
||||||
|
((RollershutterItem) item).send(new PercentType(targetPosition));
|
||||||
|
} else if (item instanceof DimmerItem) {
|
||||||
|
((DimmerItem) item).send(new PercentType(targetPosition));
|
||||||
|
} else if (item instanceof NumberItem) {
|
||||||
|
((NumberItem) item).send(new DecimalType(targetPosition));
|
||||||
|
} else {
|
||||||
|
logger.warn(
|
||||||
|
"Unsupported item type for characteristic {} at accessory {}. Expected Rollershutter, Dimmer or Number item, got {}",
|
||||||
|
TARGET_POSITION, getName(), item.getClass());
|
||||||
|
}
|
||||||
|
}, () -> {
|
||||||
|
logger.warn("Mandatory characteristic {} not found at accessory {}. ", TARGET_POSITION, getName());
|
||||||
|
});
|
||||||
return CompletableFuture.completedFuture(null);
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +151,17 @@ abstract class AbstractHomekitPositionAccessoryImpl extends AbstractHomekitAcces
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int convertPositionState(HomekitCharacteristicType type, int openPosition, int closedPosition) {
|
protected int convertPositionState(HomekitCharacteristicType type, int openPosition, int closedPosition) {
|
||||||
final @Nullable DecimalType value = getStateAs(type, PercentType.class);
|
@Nullable
|
||||||
|
DecimalType value = null;
|
||||||
|
final Optional<HomekitTaggedItem> taggedItem = getCharacteristic(type);
|
||||||
|
if (taggedItem.isPresent()) {
|
||||||
|
final Item item = taggedItem.get().getItem();
|
||||||
|
if ((item instanceof RollershutterItem) || ((item instanceof DimmerItem))) {
|
||||||
|
value = item.getStateAs(PercentType.class);
|
||||||
|
} else {
|
||||||
|
value = item.getStateAs(DecimalType.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
return value != null ? convertPosition(value.intValue(), openPosition) : closedPosition;
|
return value != null ? convertPosition(value.intValue(), openPosition) : closedPosition;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue