Skip to content

Commit

Permalink
[homekit] fix unit conversions on step values for temperatures (openh…
Browse files Browse the repository at this point in the history
…ab#18233)

getConfigurationAsQuantity was using toUnitRelative appropriately,
but the final conversion to Celsius was not, resulting in a 1 °F
step being interpreted as a -17.5 °C step!

Signed-off-by: Cody Cutrer <cody@cutrer.us>
  • Loading branch information
ccutrer authored Feb 9, 2025
1 parent 1650591 commit 0b13f65
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.measure.Quantity;
import javax.measure.Unit;

import org.eclipse.jdt.annotation.NonNullByDefault;
Expand Down Expand Up @@ -450,36 +451,44 @@ public double getConfigurationAsDouble(String key, double defaultValue) {
* @param defaultValue default value
* @return value
*/
public QuantityType<?> getConfigurationAsQuantity(String key, QuantityType defaultValue,
public <T extends Quantity<T>> QuantityType<T> getConfigurationAsQuantity(String key, QuantityType<T> defaultValue,
boolean relativeConversion) {
String stringValue = getConfiguration(key, new String());
if (stringValue.isEmpty()) {
return defaultValue;
}
var parsedValue = new QuantityType(stringValue);
QuantityType<?> convertedValue;
var parsedValue = new QuantityType<>(stringValue);
QuantityType<T> convertedValue;

if (relativeConversion) {
convertedValue = parsedValue.toUnitRelative(defaultValue.getUnit());
if (parsedValue.getUnit().isCompatible(defaultValue.getUnit())) {
convertedValue = ((QuantityType<T>) parsedValue).toUnitRelative(defaultValue.getUnit());
} else {
convertedValue = null;
}
} else {
convertedValue = parsedValue.toInvertibleUnit(defaultValue.getUnit());
convertedValue = (QuantityType<T>) parsedValue.toInvertibleUnit(defaultValue.getUnit());
}
// not convertible? just assume it's in the item's unit
if (convertedValue == null) {
Unit unit;
if (getBaseItem() instanceof NumberItem numberItem && (unit = numberItem.getUnit()) != null) {
var bdValue = new BigDecimal(stringValue);
parsedValue = new QuantityType(bdValue, unit);
parsedValue = new QuantityType<>(bdValue, unit);
if (relativeConversion) {
convertedValue = parsedValue.toUnitRelative(defaultValue.getUnit());
if (parsedValue.getUnit().isCompatible(defaultValue.getUnit())) {
convertedValue = ((QuantityType<T>) parsedValue).toUnitRelative(defaultValue.getUnit());
} else {
convertedValue = null;
}
} else {
convertedValue = parsedValue.toInvertibleUnit(defaultValue.getUnit());
convertedValue = (QuantityType<T>) parsedValue.toInvertibleUnit(defaultValue.getUnit());
}
}
}
// still not convertible? just assume it's in the default's unit
if (convertedValue == null) {
return new QuantityType(parsedValue.toBigDecimal(), defaultValue.getUnit());
return new QuantityType<>(parsedValue.toBigDecimal(), defaultValue.getUnit());
}
return convertedValue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -610,11 +610,6 @@ public static double convertFromCelsius(double degrees) {
return convertAndRound(degrees, SIUnits.CELSIUS, getSystemTemperatureUnit());
}

public static double getTemperatureStep(HomekitTaggedItem taggedItem, double defaultValue) {
return taggedItem.getConfigurationAsQuantity(HomekitTaggedItem.STEP,
new QuantityType(defaultValue, SIUnits.CELSIUS), true).doubleValue();
}

private static Supplier<CompletableFuture<Integer>> getAngleSupplier(HomekitTaggedItem taggedItem,
int defaultValue) {
return () -> CompletableFuture.completedFuture(getAngleFromItem(taggedItem, defaultValue));
Expand Down Expand Up @@ -899,7 +894,7 @@ private static CoolingThresholdTemperatureCharacteristic createCoolingThresholdC
Objects.requireNonNull(new QuantityType(CoolingThresholdTemperatureCharacteristic.DEFAULT_STEP,
SIUnits.CELSIUS).toUnit(getSystemTemperatureUnit())),
true)
.toUnit(SIUnits.CELSIUS).doubleValue();
.toUnitRelative(SIUnits.CELSIUS).doubleValue();
return new CoolingThresholdTemperatureCharacteristic(minValue, maxValue, step,
getTemperatureSupplier(taggedItem, minValue), setTemperatureConsumer(taggedItem),
getSubscriber(taggedItem, COOLING_THRESHOLD_TEMPERATURE, updater),
Expand Down Expand Up @@ -979,7 +974,7 @@ private static CurrentTemperatureCharacteristic createCurrentTemperatureCharacte
new QuantityType(CurrentTemperatureCharacteristic.DEFAULT_STEP, SIUnits.CELSIUS)
.toUnit(getSystemTemperatureUnit())),
true)
.toUnit(SIUnits.CELSIUS).doubleValue();
.toUnitRelative(SIUnits.CELSIUS).doubleValue();
return new CurrentTemperatureCharacteristic(minValue, maxValue, step,
getTemperatureSupplier(taggedItem, minValue), getSubscriber(taggedItem, TARGET_TEMPERATURE, updater),
getUnsubscriber(taggedItem, TARGET_TEMPERATURE, updater));
Expand Down Expand Up @@ -1073,7 +1068,7 @@ private static HeatingThresholdTemperatureCharacteristic createHeatingThresholdC
Objects.requireNonNull(new QuantityType(HeatingThresholdTemperatureCharacteristic.DEFAULT_STEP,
SIUnits.CELSIUS).toUnit(getSystemTemperatureUnit())),
true)
.toUnit(SIUnits.CELSIUS).doubleValue();
.toUnitRelative(SIUnits.CELSIUS).doubleValue();
return new HeatingThresholdTemperatureCharacteristic(minValue, maxValue, step,
getTemperatureSupplier(taggedItem, minValue), setTemperatureConsumer(taggedItem),
getSubscriber(taggedItem, HEATING_THRESHOLD_TEMPERATURE, updater),
Expand Down Expand Up @@ -1573,7 +1568,7 @@ private static TargetTemperatureCharacteristic createTargetTemperatureCharacteri
new QuantityType(TargetTemperatureCharacteristic.DEFAULT_STEP, SIUnits.CELSIUS)
.toUnit(getSystemTemperatureUnit())),
true)
.toUnit(SIUnits.CELSIUS).doubleValue();
.toUnitRelative(SIUnits.CELSIUS).doubleValue();
return new TargetTemperatureCharacteristic(minValue, maxValue, step,
getTemperatureSupplier(taggedItem, minValue), setTemperatureConsumer(taggedItem),
getSubscriber(taggedItem, TARGET_TEMPERATURE, updater),
Expand Down

0 comments on commit 0b13f65

Please sign in to comment.