[homekit] allow NumberItems for BatteryLowStatus (#13449)
* [homekit] allow NumberItems for BatteryLowStatus use a lowThreshold metadata config to infer if it's low Signed-off-by: Cody Cutrer <cody@cutrer.us>
This commit is contained in:
parent
e9848e27e8
commit
64d97374ad
|
@ -424,7 +424,7 @@ Following table summarizes the optional characteristics supported by sensors.
|
|||
| ActiveStatus | Switch, Contact | Accessory current working status. "ON"/"OPEN" indicates that the accessory is active and is functioning without any errors. |
|
||||
| FaultStatus | Switch, Contact | Accessory fault status. "ON"/"OPEN" value indicates that the accessory has experienced a fault that may be interfering with its intended functionality. A value of "OFF"/"CLOSED" indicates that there is no fault. |
|
||||
| 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. |
|
||||
| BatteryLowStatus | Switch, Contact, Number | 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 that's above the low threshold. Alternatively, you can give a Number item that's the battery level, and if it's lower than the lowThreshold configuration, it will report low. |
|
||||
|
||||
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".
|
||||
|
@ -555,63 +555,63 @@ Support for this is planned for the future release of openHAB HomeKit binding.
|
|||
| | | ActiveStatus | Switch, Contact | Working status |
|
||||
| | | FaultStatus | Switch, Contact | Fault status |
|
||||
| | | TamperedStatus | Switch, Contact | Tampered status |
|
||||
| | | BatteryLowStatus | Switch, Contact | Battery status |
|
||||
| | | BatteryLowStatus | Switch, Contact, Number | Battery status |
|
||||
| LeakSensor | | | | Leak Sensor |
|
||||
| | LeakDetectedState | | Switch, Contact | Leak sensor state (ON=Leak Detected, OFF=no leak) |
|
||||
| | | Name | String | Name of the sensor |
|
||||
| | | ActiveStatus | Switch, Contact | Working status |
|
||||
| | | FaultStatus | Switch, Contact | Fault status |
|
||||
| | | TamperedStatus | Switch, Contact | Tampered status |
|
||||
| | | BatteryLowStatus | Switch, Contact | Battery status |
|
||||
| | | BatteryLowStatus | Switch, Contact, Number | Battery status |
|
||||
| MotionSensor | | | | Motion Sensor |
|
||||
| | MotionDetectedState | | Switch, Contact | Motion sensor state (ON=motion detected, OFF=no motion) |
|
||||
| | | Name | String | Name of the sensor |
|
||||
| | | ActiveStatus | Switch, Contact | Working status |
|
||||
| | | FaultStatus | Switch, Contact | Fault status |
|
||||
| | | TamperedStatus | Switch, Contact | Tampered status |
|
||||
| | | BatteryLowStatus | Switch, Contact | Battery status |
|
||||
| | | BatteryLowStatus | Switch, Contact, Number | Battery status |
|
||||
| OccupancySensor | | | | Occupancy Sensor |
|
||||
| | OccupancyDetectedState | | Switch, Contact | Occupancy sensor state (ON=occupied, OFF=not occupied) |
|
||||
| | | Name | String | Name of the sensor |
|
||||
| | | ActiveStatus | Switch, Contact | Working status |
|
||||
| | | FaultStatus | Switch, Contact | Fault status |
|
||||
| | | TamperedStatus | Switch, Contact | Tampered status |
|
||||
| | | BatteryLowStatus | Switch, Contact | Battery status |
|
||||
| | | BatteryLowStatus | Switch, Contact, Number | 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 |
|
||||
| | ContactSensorState | | Switch, Contact | Contact sensor state (ON=open, OFF=closed) |
|
||||
| | | Name | String | Name of the sensor |
|
||||
| | | ActiveStatus | Switch, Contact | Working status |
|
||||
| | | FaultStatus | Switch, Contact | Fault status |
|
||||
| | | TamperedStatus | Switch, Contact | Tampered status |
|
||||
| | | BatteryLowStatus | Switch, Contact | Battery status |
|
||||
| | | BatteryLowStatus | Switch, Contact, Number | Battery status |
|
||||
| SmokeSensor | | | | Smoke Sensor |
|
||||
| | SmokeDetectedState | | Switch, Contact | Smoke sensor state (ON=smoke detected, OFF=no smoke) |
|
||||
| | | Name | String | Name of the sensor |
|
||||
| | | ActiveStatus | Switch, Contact | Working status |
|
||||
| | | FaultStatus | Switch, Contact | Fault status |
|
||||
| | | TamperedStatus | Switch, Contact | Tampered status |
|
||||
| | | BatteryLowStatus | Switch, Contact | Battery status |
|
||||
| | | BatteryLowStatus | Switch, Contact, Number | Battery status |
|
||||
| LightSensor | | | | Light sensor |
|
||||
| | LightLevel | | Number | Light level in lux |
|
||||
| | | Name | String | Name of the sensor |
|
||||
| | | ActiveStatus | Switch, Contact | Working status |
|
||||
| | | FaultStatus | Switch, Contact | Fault status |
|
||||
| | | TamperedStatus | Switch, Contact | Tampered status |
|
||||
| | | BatteryLowStatus | Switch, Contact | Battery status |
|
||||
| | | BatteryLowStatus | Switch, Contact, Number | Battery status |
|
||||
| HumiditySensor | | | | Relative Humidity Sensor providing read-only values |
|
||||
| | RelativeHumidity | | Number | Relative humidity in % between 0 and 100. additional configuration homekitMultiplicator = <number to multiply result with>. |
|
||||
| | | Name | String | Name of the sensor |
|
||||
| | | ActiveStatus | Switch, Contact | Working status |
|
||||
| | | FaultStatus | Switch, Contact | Fault status |
|
||||
| | | TamperedStatus | Switch, Contact | Tampered status |
|
||||
| | | BatteryLowStatus | Switch, Contact | Battery status |
|
||||
| | | BatteryLowStatus | Switch, Contact, Number | Battery status |
|
||||
| TemperatureSensor | | | | Temperature sensor |
|
||||
| | CurrentTemperature | | Number | current temperature. supported configuration: minValue, maxValue, step. |
|
||||
| | | Name | String | Name of the sensor |
|
||||
| | | ActiveStatus | Switch, Contact | Working status |
|
||||
| | | FaultStatus | Switch, Contact | Fault status |
|
||||
| | | TamperedStatus | Switch, Contact | Tampered status |
|
||||
| | | BatteryLowStatus | Switch, Contact | Battery status |
|
||||
| | | BatteryLowStatus | Switch, Contact, Number | Battery status |
|
||||
| CarbonDioxideSensor | | | | Carbon Dioxide Sensor |
|
||||
| | CarbonDioxideDetectedState | | Switch, Contact | carbon dioxide sensor state (ON- abnormal level of carbon dioxide detected, OFF - level is normal) |
|
||||
| | | CarbonDioxideLevel | Number | Carbon dioxide level in ppm, max 100000 |
|
||||
|
@ -620,7 +620,7 @@ Support for this is planned for the future release of openHAB HomeKit binding.
|
|||
| | | ActiveStatus | Switch, Contact | Working status |
|
||||
| | | FaultStatus | Switch, Contact | Fault status |
|
||||
| | | TamperedStatus | Switch, Contact | Tampered status |
|
||||
| | | BatteryLowStatus | Switch, Contact | Battery status |
|
||||
| | | BatteryLowStatus | Switch, Contact, Number | Battery status |
|
||||
| CarbonMonoxideSensor | | | | Carbon monoxide Sensor |
|
||||
| | CarbonMonoxideDetectedState | | Switch, Contact | Carbon monoxide sensor state (ON- abnormal level of carbon monoxide detected, OFF - level is normal) |
|
||||
| | | CarbonMonoxideLevel | Number | Carbon monoxide level in ppm, max 100 |
|
||||
|
@ -629,7 +629,7 @@ Support for this is planned for the future release of openHAB HomeKit binding.
|
|||
| | | ActiveStatus | Switch, Contact | Working status |
|
||||
| | | FaultStatus | Switch, Contact | Fault status |
|
||||
| | | TamperedStatus | Switch, Contact | Tampered status |
|
||||
| | | BatteryLowStatus | Switch, Contact | Battery status |
|
||||
| | | BatteryLowStatus | Switch, Contact, Number | Battery status |
|
||||
| Door | | | | Motorized door. One Rollershutter item covers all mandatory characteristics. see examples below. |
|
||||
| | CurrentPosition | | Rollershutter, Dimmer, Number | Current position of motorized door |
|
||||
| | TargetPosition | | Rollershutter, Dimmer, Number | Target position of motorized door |
|
||||
|
@ -732,7 +732,7 @@ Support for this is planned for the future release of openHAB HomeKit binding.
|
|||
| | | LockTargetState | Switch | target states of lock mechanism (OFF=SECURED, ON=UNSECURED) |
|
||||
| Battery | | | | Accessory with battery. Battery can be chargeable (configuration chargeable:true) and non-chargeable (configuration chargeable:false) |
|
||||
| | BatteryLevel | | Number | Battery level 0% to 100% |
|
||||
| | BatteryLowStatus | | Switch, Contact | Battery low indicator. ON/OPEN = battery level is low. |
|
||||
| | BatteryLowStatus | | Switch, Contact, Number | Battery low indicator. ON/OPEN = battery level is low; for number if the value is below the lowThreshold, then it is low. Default is 20. |
|
||||
| | BatteryChargingState | | Switch, Contact | Mandatory only for chargeable battery. ON/OPEN = battery is charging |
|
||||
| | | Name | String | Name of the battery accessory |
|
||||
| Filter | | | | Accessory with filter maintenance indicator |
|
||||
|
|
|
@ -45,14 +45,15 @@ public class HomekitTaggedItem {
|
|||
private final Logger logger = LoggerFactory.getLogger(HomekitTaggedItem.class);
|
||||
|
||||
/** configuration keywords at items level **/
|
||||
public final static String MIN_VALUE = "minValue";
|
||||
public final static String MAX_VALUE = "maxValue";
|
||||
public final static String STEP = "step";
|
||||
public final static String DIMMER_MODE = "dimmerMode";
|
||||
public final static String DELAY = "commandDelay";
|
||||
public final static String INVERTED = "inverted";
|
||||
public final static String PRIMARY_SERVICE = "primary";
|
||||
public final static String DIMMER_MODE = "dimmerMode";
|
||||
public static final String BATTERY_LOW_THRESHOLD = "lowThreshold";
|
||||
public final static String INSTANCE = "instance";
|
||||
public final static String INVERTED = "inverted";
|
||||
public final static String MAX_VALUE = "maxValue";
|
||||
public final static String MIN_VALUE = "minValue";
|
||||
public final static String PRIMARY_SERVICE = "primary";
|
||||
public final static String STEP = "step";
|
||||
|
||||
private static final Map<Integer, String> CREATED_ACCESSORY_IDS = new ConcurrentHashMap<>();
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
*/
|
||||
package org.openhab.io.homekit.internal.accessories;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
@ -314,6 +315,25 @@ abstract class AbstractHomekitAccessoryImpl implements HomekitAccessory {
|
|||
trueOnOffValue, trueOpenClosedValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* create boolean reader for a number item with ON state mapped to the value of the
|
||||
* item being above a given threshold
|
||||
*
|
||||
* @param characteristicType characteristic id
|
||||
* @param trueThreshold threshold for true of number item
|
||||
* @param invertThreshold result is true if item is less than threshold, instead of more
|
||||
* @return boolean read
|
||||
* @throws IncompleteAccessoryException
|
||||
*/
|
||||
@NonNullByDefault
|
||||
protected BooleanItemReader createBooleanReader(HomekitCharacteristicType characteristicType,
|
||||
BigDecimal trueThreshold, boolean invertThreshold) 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, trueThreshold, invertThreshold);
|
||||
}
|
||||
|
||||
/**
|
||||
* create boolean reader with default ON/OFF mapping considering inverted flag
|
||||
*
|
||||
|
|
|
@ -12,14 +12,20 @@
|
|||
*/
|
||||
package org.openhab.io.homekit.internal.accessories;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.items.GroupItem;
|
||||
import org.openhab.core.items.Item;
|
||||
import org.openhab.core.library.items.ContactItem;
|
||||
import org.openhab.core.library.items.NumberItem;
|
||||
import org.openhab.core.library.items.StringItem;
|
||||
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.library.types.QuantityType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.io.homekit.internal.HomekitOHItemProxy;
|
||||
|
@ -38,6 +44,8 @@ public class BooleanItemReader {
|
|||
private final OnOffType trueOnOffValue;
|
||||
private final OpenClosedType trueOpenClosedValue;
|
||||
private final Logger logger = LoggerFactory.getLogger(BooleanItemReader.class);
|
||||
private final @Nullable BigDecimal trueThreshold;
|
||||
private final boolean invertThreshold;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -46,29 +54,58 @@ public class BooleanItemReader {
|
|||
* @param trueOpenClosedValue if OpenClosedType, then consider true if this value
|
||||
*/
|
||||
BooleanItemReader(Item item, OnOffType trueOnOffValue, OpenClosedType trueOpenClosedValue) {
|
||||
this(item, trueOnOffValue, trueOpenClosedValue, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param item The item to read
|
||||
* @param trueOnOffValue If OnOffType, then consider true if this value
|
||||
* @param trueOpenClosedValue if OpenClosedType, then consider true if this value
|
||||
* @param trueThreshold If the state is numeric, and this param is given, return true if the value is above this
|
||||
* threshold
|
||||
* @param invertThreshold Invert threshold to be true if below, not above
|
||||
*/
|
||||
BooleanItemReader(Item item, OnOffType trueOnOffValue, OpenClosedType trueOpenClosedValue,
|
||||
@Nullable BigDecimal trueThreshold, boolean invertThreshold) {
|
||||
this.item = item;
|
||||
this.trueOnOffValue = trueOnOffValue;
|
||||
this.trueOpenClosedValue = trueOpenClosedValue;
|
||||
final Item baseItem = HomekitOHItemProxy.getBaseItem(item);
|
||||
if (!(baseItem instanceof SwitchItem) && !(baseItem instanceof ContactItem)
|
||||
&& !(baseItem instanceof StringItem)) {
|
||||
logger.warn("Item {} is a {} instead of the expected SwitchItem, ContactItem or StringItem", item.getName(),
|
||||
item.getClass().getName());
|
||||
this.trueThreshold = trueThreshold;
|
||||
this.invertThreshold = invertThreshold;
|
||||
if (!(baseItem instanceof SwitchItem || baseItem instanceof ContactItem || baseItem instanceof StringItem
|
||||
|| (trueThreshold != null && baseItem instanceof NumberItem))) {
|
||||
if (trueThreshold != null) {
|
||||
logger.warn("Item {} is a {} instead of the expected SwitchItem, ContactItem, NumberItem or StringItem",
|
||||
item.getName(), item.getClass().getName());
|
||||
} else {
|
||||
logger.warn("Item {} is a {} instead of the expected SwitchItem, ContactItem or StringItem",
|
||||
item.getName(), item.getClass().getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean getValue() {
|
||||
final State state = item.getState();
|
||||
final BigDecimal localTrueThresheold = trueThreshold;
|
||||
if (state instanceof OnOffType) {
|
||||
return state.equals(trueOnOffValue);
|
||||
} else if (state instanceof OpenClosedType) {
|
||||
return state.equals(trueOpenClosedValue);
|
||||
} else if (state instanceof StringType) {
|
||||
return state.toString().equalsIgnoreCase("Open") || state.toString().equalsIgnoreCase("Opened");
|
||||
} else {
|
||||
logger.debug("Unexpected item state, returning false. Item {}, State {}", item.getName(), state);
|
||||
return false;
|
||||
} else if (localTrueThresheold != null) {
|
||||
if (state instanceof DecimalType) {
|
||||
final boolean result = ((DecimalType) state).toBigDecimal().compareTo(localTrueThresheold) > 0;
|
||||
return result ^ invertThreshold;
|
||||
} else if (state instanceof QuantityType) {
|
||||
final boolean result = ((QuantityType<?>) state).toBigDecimal().compareTo(localTrueThresheold) > 0;
|
||||
return result ^ invertThreshold;
|
||||
}
|
||||
}
|
||||
logger.debug("Unexpected item state, returning false. Item {}, State {}", item.getName(), state);
|
||||
return false;
|
||||
}
|
||||
|
||||
private OnOffType getOffValue(OnOffType onValue) {
|
||||
|
|
|
@ -16,12 +16,14 @@ import static org.openhab.io.homekit.internal.HomekitCharacteristicType.BATTERY_
|
|||
import static org.openhab.io.homekit.internal.HomekitCharacteristicType.BATTERY_LEVEL;
|
||||
import static org.openhab.io.homekit.internal.HomekitCharacteristicType.BATTERY_LOW_STATUS;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.io.homekit.internal.HomekitAccessoryUpdater;
|
||||
import org.openhab.io.homekit.internal.HomekitCharacteristicType;
|
||||
import org.openhab.io.homekit.internal.HomekitSettings;
|
||||
import org.openhab.io.homekit.internal.HomekitTaggedItem;
|
||||
|
||||
|
@ -42,11 +44,14 @@ public class HomekitBatteryImpl extends AbstractHomekitAccessoryImpl implements
|
|||
private final BooleanItemReader lowBatteryReader;
|
||||
private BooleanItemReader chargingBatteryReader;
|
||||
private final boolean isChargeable;
|
||||
private final BigDecimal lowThreshold;
|
||||
|
||||
public HomekitBatteryImpl(HomekitTaggedItem taggedItem, List<HomekitTaggedItem> mandatoryCharacteristics,
|
||||
HomekitAccessoryUpdater updater, HomekitSettings settings) throws IncompleteAccessoryException {
|
||||
super(taggedItem, mandatoryCharacteristics, updater, settings);
|
||||
lowBatteryReader = createBooleanReader(BATTERY_LOW_STATUS);
|
||||
lowThreshold = getAccessoryConfiguration(HomekitCharacteristicType.BATTERY_LOW_STATUS,
|
||||
HomekitTaggedItem.BATTERY_LOW_THRESHOLD, BigDecimal.valueOf(20));
|
||||
lowBatteryReader = createBooleanReader(BATTERY_LOW_STATUS, lowThreshold, true);
|
||||
isChargeable = getAccessoryConfigurationAsBoolean(BATTERY_TYPE, false);
|
||||
if (isChargeable) {
|
||||
chargingBatteryReader = createBooleanReader(BATTERY_CHARGING_STATE);
|
||||
|
|
|
@ -405,9 +405,14 @@ public class HomekitCharacteristicFactory {
|
|||
// create method for characteristic
|
||||
private static StatusLowBatteryCharacteristic createStatusLowBatteryCharacteristic(HomekitTaggedItem taggedItem,
|
||||
HomekitAccessoryUpdater updater) {
|
||||
BigDecimal lowThreshold = taggedItem.getConfiguration(HomekitTaggedItem.BATTERY_LOW_THRESHOLD,
|
||||
BigDecimal.valueOf(20));
|
||||
BooleanItemReader lowBatteryReader = new BooleanItemReader(taggedItem.getItem(),
|
||||
taggedItem.isInverted() ? OnOffType.OFF : OnOffType.ON,
|
||||
taggedItem.isInverted() ? OpenClosedType.CLOSED : OpenClosedType.OPEN, lowThreshold, true);
|
||||
return new StatusLowBatteryCharacteristic(
|
||||
() -> getEnumFromItem(taggedItem, StatusLowBatteryEnum.NORMAL, StatusLowBatteryEnum.LOW,
|
||||
StatusLowBatteryEnum.NORMAL),
|
||||
() -> CompletableFuture.completedFuture(
|
||||
lowBatteryReader.getValue() ? StatusLowBatteryEnum.LOW : StatusLowBatteryEnum.NORMAL),
|
||||
getSubscriber(taggedItem, BATTERY_LOW_STATUS, updater),
|
||||
getUnsubscriber(taggedItem, BATTERY_LOW_STATUS, updater));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue