From 9b276798cacfdd1085369cb6dc135413084b3055 Mon Sep 17 00:00:00 2001 From: eugen Date: Thu, 25 Feb 2021 19:28:34 +0100 Subject: [PATCH] [homekit] extend support of inverted flag to other accessories (#10212) Signed-off-by: Eugen Freiter --- bundles/org.openhab.io.homekit/README.md | 18 ++++++++++--- .../doc/sensor_ui_config.png | Bin 0 -> 42215 bytes .../homekit/internal/HomekitTaggedItem.java | 10 +++++++ .../AbstractHomekitAccessoryImpl.java | 25 ++++++++++++++++++ .../HomekitCarbonDioxideSensorImpl.java | 5 +--- .../HomekitCarbonMonoxideSensorImpl.java | 5 +--- .../HomekitCharacteristicFactory.java | 10 ++++--- .../accessories/HomekitContactSensorImpl.java | 4 +-- .../internal/accessories/HomekitFanImpl.java | 4 +-- .../HomekitGarageDoorOpenerImpl.java | 3 +-- .../accessories/HomekitLeakSensorImpl.java | 4 +-- .../internal/accessories/HomekitLockImpl.java | 6 ++--- .../accessories/HomekitMotionSensorImpl.java | 5 +--- .../HomekitOccupancySensorImpl.java | 4 +-- .../accessories/HomekitOutletImpl.java | 6 ++--- .../accessories/HomekitSmokeSensorImpl.java | 4 +-- .../accessories/HomekitSpeakerImpl.java | 4 +-- .../accessories/HomekitSwitchImpl.java | 4 +-- .../accessories/HomekitValveImpl.java | 5 ++-- 19 files changed, 72 insertions(+), 54 deletions(-) create mode 100644 bundles/org.openhab.io.homekit/doc/sensor_ui_config.png diff --git a/bundles/org.openhab.io.homekit/README.md b/bundles/org.openhab.io.homekit/README.md index 763688c0129ae..4edf7b2f2eaf4 100644 --- a/bundles/org.openhab.io.homekit/README.md +++ b/bundles/org.openhab.io.homekit/README.md @@ -421,6 +421,9 @@ Following table summarizes the optional characteristics supported by sensors. | TamperedStatus | Switch, Contact | Accessory tampered status. "ON"/"OPEN" indicates that the accessory has been tampered. Value should return to "OFF"/"CLOSED" when the accessory has been reset to a non-tampered state. | | BatteryLowStatus | Switch, Contact | Accessory battery status. "ON"/"OPEN" indicates that the battery level of the accessory is low. Value should return to "OFF"/"CLOSED" when the battery charges to a level thats above the low threshold. | +Switch and Contact items support inversion of the state mapping, e.g. by default the openHAB switch state "ON" is mapped to HomeKit contact sensor state "Open", and "OFF" to "Closed". +The configuration "inverted='true'" inverts this mapping, so that "ON" will be mapped to "Closed" and "OFF" to "Open". + Examples of sensor definitions. Sensors without optional characteristics: @@ -429,6 +432,8 @@ Switch leaksensor_single "Leak Sensor" {homekit="LeakSenso Number light_sensor "Light Sensor" {homekit="LightSensor"} Number temperature_sensor "Temperature Sensor [%.1f C]" {homekit="TemperatureSensor"} Contact contact_sensor "Contact Sensor" {homekit="ContactSensor"} +Contact contact_sensor "Contact Sensor" {homekit="ContactSensor" [inverted="true"]} + Switch occupancy_sensor "Occupancy Sensor" {homekit="OccupancyDetectedState"} Switch motion_sensor "Motion Sensor" {homekit="MotionSensor"} Number humidity_sensor "Humidity Sensor" {homekit="HumiditySensor"} @@ -439,19 +444,24 @@ Sensors with optional characteristics: ```xtend Group gLeakSensor "Leak Sensor" {homekit="LeakSensor"} Switch leaksensor "Leak Sensor State" (gLeakSensor) {homekit="LeakDetectedState"} -Switch leaksensor_bat "Leak Sensor Battery" (gLeakSensor) {homekit="BatteryLowStatus"} -Switch leaksensor_active "Leak Sensor Active" (gLeakSensor) {homekit="ActiveStatus"} +Switch leaksensor_bat "Leak Sensor Battery" (gLeakSensor) {homekit="BatteryLowStatus" } +Switch leaksensor_active "Leak Sensor Active" (gLeakSensor) {homekit="ActiveStatus" [inverted="true"]} Switch leaksensor_fault "Leak Sensor Fault" (gLeakSensor) {homekit="FaultStatus"} Switch leaksensor_tampered "Leak Sensor Tampered" (gLeakSensor) {homekit="TamperedStatus"} Group gMotionSensor "Motion Sensor" {homekit="MotionSensor"} Switch motionsensor "Motion Sensor State" (gMotionSensor) {homekit="MotionDetectedState"} -Switch motionsensor_bat "Motion Sensor Battery" (gMotionSensor) {homekit="BatteryLowStatus"} +Switch motionsensor_bat "Motion Sensor Battery" (gMotionSensor) {homekit="BatteryLowStatus" [inverted="true"]} Switch motionsensor_active "Motion Sensor Active" (gMotionSensor) {homekit="ActiveStatus"} Switch motionsensor_fault "Motion Sensor Fault" (gMotionSensor) {homekit="FaultStatus"} Switch motionsensor_tampered "Motion Sensor Tampered" (gMotionSensor) {homekit="TamperedStatus"} ``` +or using UI + +![sensor_ui_config.png](doc/sensor_ui_config.png) + + ## Supported accessory type | Accessory Tag | Mandatory Characteristics | Optional Characteristics | Supported OH items | Description | @@ -490,7 +500,7 @@ Switch motionsensor_tampered "Motion Sensor Tampered" | | | FaultStatus | Switch, Contact | Fault status | | | | TamperedStatus | Switch, Contact | Tampered status | | | | BatteryLowStatus | Switch, Contact | Battery status | -| ContactSensor | | | | Contact Sensor,An accessory with on/off state that can be viewed in HomeKit but not changed such as a contact sensor for a door or window | +| ContactSensor | | | | Contact Sensor, An accessory with on/off state that can be viewed in HomeKit but not changed such as a contact sensor for a door or window | | | ContactSensorState | | Switch, Contact | Contact sensor state (ON=open, OFF=closed) | | | | Name | String | Name of the sensor | | | | ActiveStatus | Switch, Contact | Working status | diff --git a/bundles/org.openhab.io.homekit/doc/sensor_ui_config.png b/bundles/org.openhab.io.homekit/doc/sensor_ui_config.png new file mode 100644 index 0000000000000000000000000000000000000000..ffd05c1ae51622e37c1f1d29e246f1ee191efe15 GIT binary patch literal 42215 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 literal 0 HcmV?d00001 diff --git a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/HomekitTaggedItem.java b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/HomekitTaggedItem.java index cdcc6259fa716..52820f1c00d55 100644 --- a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/HomekitTaggedItem.java +++ b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/HomekitTaggedItem.java @@ -210,6 +210,16 @@ public T getConfiguration(String key, T defaultValue) { return defaultValue; } + /** + * returns true if inverted flag is set, i.e. item has the configuration "inverted=true" + * + * @return true if inverted flag is set to true + */ + public boolean isInverted() { + final String invertedConfig = getConfiguration(HomekitTaggedItem.INVERTED, "false"); + return invertedConfig.equalsIgnoreCase("yes") || invertedConfig.equalsIgnoreCase("true"); + } + /** * return configuration as double if exists otherwise return defaultValue * diff --git a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/AbstractHomekitAccessoryImpl.java b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/AbstractHomekitAccessoryImpl.java index 9791afcf074c7..cad68e734e589 100644 --- a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/AbstractHomekitAccessoryImpl.java +++ b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/AbstractHomekitAccessoryImpl.java @@ -300,6 +300,15 @@ protected double convertFromCelsius(double degrees) { ImperialUnits.FAHRENHEIT); } + /** + * create boolean reader with ON state mapped to trueOnOffValue or trueOpenClosedValue depending of item type + * + * @param characteristicType characteristic id + * @param trueOnOffValue ON value for switch + * @param trueOpenClosedValue ON value for contact + * @return boolean readed + * @throws IncompleteAccessoryException + */ @NonNullByDefault protected BooleanItemReader createBooleanReader(HomekitCharacteristicType characteristicType, OnOffType trueOnOffValue, OpenClosedType trueOpenClosedValue) throws IncompleteAccessoryException { @@ -308,4 +317,20 @@ protected BooleanItemReader createBooleanReader(HomekitCharacteristicType charac .orElseThrow(() -> new IncompleteAccessoryException(characteristicType)), trueOnOffValue, trueOpenClosedValue); } + + /** + * create boolean reader with default ON/OFF mapping considering inverted flag + * + * @param characteristicType characteristic id + * @return boolean reader + * @throws IncompleteAccessoryException + */ + @NonNullByDefault + protected BooleanItemReader createBooleanReader(HomekitCharacteristicType characteristicType) + throws IncompleteAccessoryException { + final HomekitTaggedItem taggedItem = getCharacteristic(characteristicType) + .orElseThrow(() -> new IncompleteAccessoryException(characteristicType)); + return new BooleanItemReader(taggedItem.getItem(), taggedItem.isInverted() ? OnOffType.OFF : OnOffType.ON, + taggedItem.isInverted() ? OpenClosedType.CLOSED : OpenClosedType.OPEN); + } } diff --git a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitCarbonDioxideSensorImpl.java b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitCarbonDioxideSensorImpl.java index 4bfdf2d9feea3..59602829ae5d8 100644 --- a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitCarbonDioxideSensorImpl.java +++ b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitCarbonDioxideSensorImpl.java @@ -17,8 +17,6 @@ import java.util.List; import java.util.concurrent.CompletableFuture; -import org.openhab.core.library.types.OnOffType; -import org.openhab.core.library.types.OpenClosedType; import org.openhab.io.homekit.internal.HomekitAccessoryUpdater; import org.openhab.io.homekit.internal.HomekitSettings; import org.openhab.io.homekit.internal.HomekitTaggedItem; @@ -40,8 +38,7 @@ public HomekitCarbonDioxideSensorImpl(HomekitTaggedItem taggedItem, List mandatoryCharacteristics, HomekitAccessoryUpdater updater, HomekitSettings settings) throws IncompleteAccessoryException { super(taggedItem, mandatoryCharacteristics, updater, settings); - carbonDioxideDetectedReader = createBooleanReader(CARBON_DIOXIDE_DETECTED_STATE, OnOffType.ON, - OpenClosedType.OPEN); + carbonDioxideDetectedReader = createBooleanReader(CARBON_DIOXIDE_DETECTED_STATE); getServices().add(new CarbonDioxideSensorService(this)); } diff --git a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitCarbonMonoxideSensorImpl.java b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitCarbonMonoxideSensorImpl.java index dd0d92cfc0003..560456decc869 100644 --- a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitCarbonMonoxideSensorImpl.java +++ b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitCarbonMonoxideSensorImpl.java @@ -17,8 +17,6 @@ import java.util.List; import java.util.concurrent.CompletableFuture; -import org.openhab.core.library.types.OnOffType; -import org.openhab.core.library.types.OpenClosedType; import org.openhab.io.homekit.internal.HomekitAccessoryUpdater; import org.openhab.io.homekit.internal.HomekitSettings; import org.openhab.io.homekit.internal.HomekitTaggedItem; @@ -40,8 +38,7 @@ public HomekitCarbonMonoxideSensorImpl(HomekitTaggedItem taggedItem, List mandatoryCharacteristics, HomekitAccessoryUpdater updater, HomekitSettings settings) throws IncompleteAccessoryException { super(taggedItem, mandatoryCharacteristics, updater, settings); - carbonMonoxideDetectedReader = createBooleanReader(CARBON_MONOXIDE_DETECTED_STATE, OnOffType.ON, - OpenClosedType.OPEN); + carbonMonoxideDetectedReader = createBooleanReader(CARBON_MONOXIDE_DETECTED_STATE); getServices().add(new CarbonMonoxideSensorService(this)); } diff --git a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitCharacteristicFactory.java b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitCharacteristicFactory.java index 85eec94e13ca4..4cbeb311fe324 100644 --- a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitCharacteristicFactory.java +++ b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitCharacteristicFactory.java @@ -164,9 +164,11 @@ private static CompletableFuture getEnumFromIt T offEnum, T onEnum, T defaultEnum) { final State state = item.getItem().getState(); if (state instanceof OnOffType) { - return CompletableFuture.completedFuture(state.equals(OnOffType.OFF) ? offEnum : onEnum); + return CompletableFuture + .completedFuture(state.equals(item.isInverted() ? OnOffType.ON : OnOffType.OFF) ? offEnum : onEnum); } else if (state instanceof OpenClosedType) { - return CompletableFuture.completedFuture(state.equals(OpenClosedType.CLOSED) ? offEnum : onEnum); + return CompletableFuture.completedFuture( + state.equals(item.isInverted() ? OpenClosedType.OPEN : OpenClosedType.CLOSED) ? offEnum : onEnum); } else if (state instanceof DecimalType) { return CompletableFuture.completedFuture(((DecimalType) state).intValue() == 0 ? offEnum : onEnum); } else if (state instanceof UnDefType) { @@ -182,9 +184,9 @@ private static void setValueFromEnum(HomekitTaggedItem taggedItem, Characteristi CharacteristicEnum offEnum, CharacteristicEnum onEnum) { if (taggedItem.getItem() instanceof SwitchItem) { if (value.equals(offEnum)) { - ((SwitchItem) taggedItem.getItem()).send(OnOffType.OFF); + ((SwitchItem) taggedItem.getItem()).send(taggedItem.isInverted() ? OnOffType.ON : OnOffType.OFF); } else if (value.equals(onEnum)) { - ((SwitchItem) taggedItem.getItem()).send(OnOffType.ON); + ((SwitchItem) taggedItem.getItem()).send(taggedItem.isInverted() ? OnOffType.OFF : OnOffType.ON); } else { logger.warn("Enum value {} is not supported. Only following values are supported: {},{}", value, offEnum, onEnum); diff --git a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitContactSensorImpl.java b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitContactSensorImpl.java index aa7ea4f4da6a6..bdc3bb613f614 100644 --- a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitContactSensorImpl.java +++ b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitContactSensorImpl.java @@ -17,8 +17,6 @@ import java.util.List; import java.util.concurrent.CompletableFuture; -import org.openhab.core.library.types.OnOffType; -import org.openhab.core.library.types.OpenClosedType; import org.openhab.io.homekit.internal.HomekitAccessoryUpdater; import org.openhab.io.homekit.internal.HomekitSettings; import org.openhab.io.homekit.internal.HomekitTaggedItem; @@ -38,7 +36,7 @@ public class HomekitContactSensorImpl extends AbstractHomekitAccessoryImpl imple public HomekitContactSensorImpl(HomekitTaggedItem taggedItem, List mandatoryCharacteristics, HomekitAccessoryUpdater updater, HomekitSettings settings) throws IncompleteAccessoryException { super(taggedItem, mandatoryCharacteristics, updater, settings); - contactSensedReader = createBooleanReader(CONTACT_SENSOR_STATE, OnOffType.ON, OpenClosedType.OPEN); + contactSensedReader = createBooleanReader(CONTACT_SENSOR_STATE); getServices().add(new ContactSensorService(this)); } diff --git a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitFanImpl.java b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitFanImpl.java index 709692ecc5f19..6fdc67128f652 100644 --- a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitFanImpl.java +++ b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitFanImpl.java @@ -17,8 +17,6 @@ import java.util.List; import java.util.concurrent.CompletableFuture; -import org.openhab.core.library.types.OnOffType; -import org.openhab.core.library.types.OpenClosedType; import org.openhab.io.homekit.internal.HomekitAccessoryUpdater; import org.openhab.io.homekit.internal.HomekitSettings; import org.openhab.io.homekit.internal.HomekitTaggedItem; @@ -38,7 +36,7 @@ class HomekitFanImpl extends AbstractHomekitAccessoryImpl implements FanAccessor public HomekitFanImpl(HomekitTaggedItem taggedItem, List mandatoryCharacteristics, HomekitAccessoryUpdater updater, HomekitSettings settings) throws IncompleteAccessoryException { super(taggedItem, mandatoryCharacteristics, updater, settings); - activeReader = createBooleanReader(ACTIVE_STATUS, OnOffType.ON, OpenClosedType.OPEN); + activeReader = createBooleanReader(ACTIVE_STATUS); this.getServices().add(new FanService(this)); } diff --git a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitGarageDoorOpenerImpl.java b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitGarageDoorOpenerImpl.java index 648426fb80e23..6c7995836635c 100644 --- a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitGarageDoorOpenerImpl.java +++ b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitGarageDoorOpenerImpl.java @@ -24,7 +24,6 @@ import org.openhab.core.library.items.StringItem; import org.openhab.core.library.items.SwitchItem; import org.openhab.core.library.types.OnOffType; -import org.openhab.core.library.types.OpenClosedType; import org.openhab.core.library.types.StringType; import org.openhab.io.homekit.internal.HomekitAccessoryUpdater; import org.openhab.io.homekit.internal.HomekitSettings; @@ -50,7 +49,7 @@ public class HomekitGarageDoorOpenerImpl extends AbstractHomekitAccessoryImpl im public HomekitGarageDoorOpenerImpl(HomekitTaggedItem taggedItem, List mandatoryCharacteristics, HomekitAccessoryUpdater updater, HomekitSettings settings) throws IncompleteAccessoryException { super(taggedItem, mandatoryCharacteristics, updater, settings); - obstructionReader = createBooleanReader(OBSTRUCTION_STATUS, OnOffType.ON, OpenClosedType.OPEN); + obstructionReader = createBooleanReader(OBSTRUCTION_STATUS); getServices().add(new GarageDoorOpenerService(this)); } diff --git a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitLeakSensorImpl.java b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitLeakSensorImpl.java index 2c872b516bbfe..4a5ef923f91ff 100644 --- a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitLeakSensorImpl.java +++ b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitLeakSensorImpl.java @@ -17,8 +17,6 @@ import java.util.List; import java.util.concurrent.CompletableFuture; -import org.openhab.core.library.types.OnOffType; -import org.openhab.core.library.types.OpenClosedType; import org.openhab.io.homekit.internal.HomekitAccessoryUpdater; import org.openhab.io.homekit.internal.HomekitSettings; import org.openhab.io.homekit.internal.HomekitTaggedItem; @@ -38,7 +36,7 @@ public class HomekitLeakSensorImpl extends AbstractHomekitAccessoryImpl implemen public HomekitLeakSensorImpl(HomekitTaggedItem taggedItem, List mandatoryCharacteristics, HomekitAccessoryUpdater updater, HomekitSettings settings) throws IncompleteAccessoryException { super(taggedItem, mandatoryCharacteristics, updater, settings); - leakDetectedReader = createBooleanReader(LEAK_DETECTED_STATE, OnOffType.ON, OpenClosedType.OPEN); + leakDetectedReader = createBooleanReader(LEAK_DETECTED_STATE); getServices().add(new LeakSensorService(this)); } diff --git a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitLockImpl.java b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitLockImpl.java index add1698d5a6f4..de9379334a301 100644 --- a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitLockImpl.java +++ b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitLockImpl.java @@ -46,10 +46,8 @@ public class HomekitLockImpl extends AbstractHomekitAccessoryImpl implements Loc public HomekitLockImpl(HomekitTaggedItem taggedItem, List mandatoryCharacteristics, HomekitAccessoryUpdater updater, HomekitSettings settings) { super(taggedItem, mandatoryCharacteristics, updater, settings); - final String invertedConfig = getAccessoryConfiguration(HomekitTaggedItem.INVERTED, "false"); - final boolean inverted = invertedConfig.equalsIgnoreCase("yes") || invertedConfig.equalsIgnoreCase("true"); - securedState = inverted ? OnOffType.OFF : OnOffType.ON; - unsecuredState = inverted ? OnOffType.ON : OnOffType.OFF; + securedState = taggedItem.isInverted() ? OnOffType.OFF : OnOffType.ON; + unsecuredState = taggedItem.isInverted() ? OnOffType.ON : OnOffType.OFF; getServices().add(new LockMechanismService(this)); } diff --git a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitMotionSensorImpl.java b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitMotionSensorImpl.java index 8ea96bedc42bf..37340823e250c 100644 --- a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitMotionSensorImpl.java +++ b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitMotionSensorImpl.java @@ -15,8 +15,6 @@ import java.util.List; import java.util.concurrent.CompletableFuture; -import org.openhab.core.library.types.OnOffType; -import org.openhab.core.library.types.OpenClosedType; import org.openhab.io.homekit.internal.HomekitAccessoryUpdater; import org.openhab.io.homekit.internal.HomekitCharacteristicType; import org.openhab.io.homekit.internal.HomekitSettings; @@ -36,8 +34,7 @@ public class HomekitMotionSensorImpl extends AbstractHomekitAccessoryImpl implem public HomekitMotionSensorImpl(HomekitTaggedItem taggedItem, List mandatoryCharacteristics, HomekitAccessoryUpdater updater, HomekitSettings settings) throws IncompleteAccessoryException { super(taggedItem, mandatoryCharacteristics, updater, settings); - motionSensedReader = createBooleanReader(HomekitCharacteristicType.MOTION_DETECTED_STATE, OnOffType.ON, - OpenClosedType.OPEN); + motionSensedReader = createBooleanReader(HomekitCharacteristicType.MOTION_DETECTED_STATE); getServices().add(new MotionSensorService(this)); } diff --git a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitOccupancySensorImpl.java b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitOccupancySensorImpl.java index 0904bf8428ce1..bbdcabdf133b9 100644 --- a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitOccupancySensorImpl.java +++ b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitOccupancySensorImpl.java @@ -17,8 +17,6 @@ import java.util.List; import java.util.concurrent.CompletableFuture; -import org.openhab.core.library.types.OnOffType; -import org.openhab.core.library.types.OpenClosedType; import org.openhab.io.homekit.internal.HomekitAccessoryUpdater; import org.openhab.io.homekit.internal.HomekitSettings; import org.openhab.io.homekit.internal.HomekitTaggedItem; @@ -38,7 +36,7 @@ public class HomekitOccupancySensorImpl extends AbstractHomekitAccessoryImpl imp public HomekitOccupancySensorImpl(HomekitTaggedItem taggedItem, List mandatoryCharacteristics, HomekitAccessoryUpdater updater, HomekitSettings settings) throws IncompleteAccessoryException { super(taggedItem, mandatoryCharacteristics, updater, settings); - occupancySensedReader = createBooleanReader(OCCUPANCY_DETECTED_STATE, OnOffType.ON, OpenClosedType.OPEN); + occupancySensedReader = createBooleanReader(OCCUPANCY_DETECTED_STATE); getServices().add(new OccupancySensorService(this)); } diff --git a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitOutletImpl.java b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitOutletImpl.java index a37582883075a..370d56ec2c40b 100644 --- a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitOutletImpl.java +++ b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitOutletImpl.java @@ -15,8 +15,6 @@ import java.util.List; import java.util.concurrent.CompletableFuture; -import org.openhab.core.library.types.OnOffType; -import org.openhab.core.library.types.OpenClosedType; import org.openhab.io.homekit.internal.HomekitAccessoryUpdater; import org.openhab.io.homekit.internal.HomekitCharacteristicType; import org.openhab.io.homekit.internal.HomekitSettings; @@ -37,8 +35,8 @@ public class HomekitOutletImpl extends AbstractHomekitAccessoryImpl implements O public HomekitOutletImpl(HomekitTaggedItem taggedItem, List mandatoryCharacteristics, HomekitAccessoryUpdater updater, HomekitSettings settings) throws IncompleteAccessoryException { super(taggedItem, mandatoryCharacteristics, updater, settings); - inUseReader = createBooleanReader(HomekitCharacteristicType.INUSE_STATUS, OnOffType.ON, OpenClosedType.OPEN); - onReader = createBooleanReader(HomekitCharacteristicType.ON_STATE, OnOffType.ON, OpenClosedType.OPEN); + inUseReader = createBooleanReader(HomekitCharacteristicType.INUSE_STATUS); + onReader = createBooleanReader(HomekitCharacteristicType.ON_STATE); getServices().add(new OutletService(this)); } diff --git a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitSmokeSensorImpl.java b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitSmokeSensorImpl.java index 9cf9e522d2152..bc03411ba89f4 100644 --- a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitSmokeSensorImpl.java +++ b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitSmokeSensorImpl.java @@ -17,8 +17,6 @@ import java.util.List; import java.util.concurrent.CompletableFuture; -import org.openhab.core.library.types.OnOffType; -import org.openhab.core.library.types.OpenClosedType; import org.openhab.io.homekit.internal.HomekitAccessoryUpdater; import org.openhab.io.homekit.internal.HomekitSettings; import org.openhab.io.homekit.internal.HomekitTaggedItem; @@ -38,7 +36,7 @@ public class HomekitSmokeSensorImpl extends AbstractHomekitAccessoryImpl impleme public HomekitSmokeSensorImpl(HomekitTaggedItem taggedItem, List mandatoryCharacteristics, HomekitAccessoryUpdater updater, HomekitSettings settings) throws IncompleteAccessoryException { super(taggedItem, mandatoryCharacteristics, updater, settings); - smokeDetectedReader = createBooleanReader(SMOKE_DETECTED_STATE, OnOffType.ON, OpenClosedType.OPEN); + smokeDetectedReader = createBooleanReader(SMOKE_DETECTED_STATE); this.getServices().add(new SmokeSensorService(this)); } diff --git a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitSpeakerImpl.java b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitSpeakerImpl.java index e4245dbee8f79..604c43002db4a 100644 --- a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitSpeakerImpl.java +++ b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitSpeakerImpl.java @@ -15,8 +15,6 @@ import java.util.List; import java.util.concurrent.CompletableFuture; -import org.openhab.core.library.types.OnOffType; -import org.openhab.core.library.types.OpenClosedType; import org.openhab.io.homekit.internal.HomekitAccessoryUpdater; import org.openhab.io.homekit.internal.HomekitCharacteristicType; import org.openhab.io.homekit.internal.HomekitSettings; @@ -37,7 +35,7 @@ public class HomekitSpeakerImpl extends AbstractHomekitAccessoryImpl implements public HomekitSpeakerImpl(HomekitTaggedItem taggedItem, List mandatoryCharacteristics, HomekitAccessoryUpdater updater, HomekitSettings settings) throws IncompleteAccessoryException { super(taggedItem, mandatoryCharacteristics, updater, settings); - muteReader = createBooleanReader(HomekitCharacteristicType.MUTE, OnOffType.ON, OpenClosedType.OPEN); + muteReader = createBooleanReader(HomekitCharacteristicType.MUTE); getServices().add(new SpeakerService(this)); } diff --git a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitSwitchImpl.java b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitSwitchImpl.java index be2a99418e92f..4b82df58a8012 100644 --- a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitSwitchImpl.java +++ b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitSwitchImpl.java @@ -17,8 +17,6 @@ import java.util.List; import java.util.concurrent.CompletableFuture; -import org.openhab.core.library.types.OnOffType; -import org.openhab.core.library.types.OpenClosedType; import org.openhab.io.homekit.internal.HomekitAccessoryUpdater; import org.openhab.io.homekit.internal.HomekitSettings; import org.openhab.io.homekit.internal.HomekitTaggedItem; @@ -38,7 +36,7 @@ public class HomekitSwitchImpl extends AbstractHomekitAccessoryImpl implements S public HomekitSwitchImpl(HomekitTaggedItem taggedItem, List mandatoryCharacteristics, HomekitAccessoryUpdater updater, HomekitSettings settings) throws IncompleteAccessoryException { super(taggedItem, mandatoryCharacteristics, updater, settings); - onReader = createBooleanReader(ON_STATE, OnOffType.ON, OpenClosedType.OPEN); + onReader = createBooleanReader(ON_STATE); getServices().add(new SwitchService(this)); } diff --git a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitValveImpl.java b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitValveImpl.java index 4f8394b62dcae..d54e0814c7b19 100644 --- a/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitValveImpl.java +++ b/bundles/org.openhab.io.homekit/src/main/java/org/openhab/io/homekit/internal/accessories/HomekitValveImpl.java @@ -30,7 +30,6 @@ import org.openhab.core.library.items.SwitchItem; import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.OnOffType; -import org.openhab.core.library.types.OpenClosedType; import org.openhab.core.types.RefreshType; import org.openhab.io.homekit.internal.HomekitAccessoryUpdater; import org.openhab.io.homekit.internal.HomekitCharacteristicType; @@ -75,8 +74,8 @@ public class HomekitValveImpl extends AbstractHomekitAccessoryImpl implements Va public HomekitValveImpl(HomekitTaggedItem taggedItem, List mandatoryCharacteristics, HomekitAccessoryUpdater updater, HomekitSettings settings) throws IncompleteAccessoryException { super(taggedItem, mandatoryCharacteristics, updater, settings); - inUseReader = createBooleanReader(INUSE_STATUS, OnOffType.ON, OpenClosedType.OPEN); - activeReader = createBooleanReader(ACTIVE_STATUS, OnOffType.ON, OpenClosedType.OPEN); + inUseReader = createBooleanReader(INUSE_STATUS); + activeReader = createBooleanReader(ACTIVE_STATUS); ValveService service = new ValveService(this); getServices().add(service); final String timerConfig = getAccessoryConfiguration(CONFIG_TIMER, "");