mirror of
https://github.com/danieldemus/openhab-core.git
synced 2025-01-25 19:55:48 +01:00
add QuantityType.toUnitRelative (#3177)
this is a useful helper that can eliminate some complicated code elsewhere. starting in SystemOffsetProfile. then I also want to use it in the homekit addon. Signed-off-by: Cody Cutrer <cody@cutrer.us>
This commit is contained in:
parent
0cceb5b156
commit
af3738487c
@ -21,8 +21,6 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.unit.ImperialUnits;
|
||||
import org.openhab.core.library.unit.SIUnits;
|
||||
import org.openhab.core.library.unit.Units;
|
||||
import org.openhab.core.thing.profiles.ProfileCallback;
|
||||
import org.openhab.core.thing.profiles.ProfileContext;
|
||||
@ -44,10 +42,6 @@ import org.slf4j.LoggerFactory;
|
||||
@NonNullByDefault
|
||||
public class SystemOffsetProfile implements StateProfile {
|
||||
|
||||
private static final @Nullable QuantityType<Temperature> ZERO_CELSIUS_IN_KELVIN = new QuantityType<>(0,
|
||||
SIUnits.CELSIUS).toUnit(Units.KELVIN);
|
||||
private static final @Nullable QuantityType<Temperature> ZERO_FAHRENHEIT_IN_KELVIN = new QuantityType<>(0,
|
||||
ImperialUnits.FAHRENHEIT).toUnit(Units.KELVIN);
|
||||
static final String OFFSET_PARAM = "offset";
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(SystemOffsetProfile.class);
|
||||
@ -152,20 +146,11 @@ public class SystemOffsetProfile implements StateProfile {
|
||||
QuantityType<Temperature> offset) {
|
||||
// do the math in Kelvin and afterwards convert it back to the unit of the state
|
||||
final QuantityType<Temperature> kelvinState = qtState.toUnit(Units.KELVIN);
|
||||
final QuantityType<Temperature> kelvinOffset = offset.toUnit(Units.KELVIN);
|
||||
final QuantityType<Temperature> kelvinOffset = offset.toUnitRelative(Units.KELVIN);
|
||||
if (kelvinState == null || kelvinOffset == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final QuantityType<Temperature> finalOffset;
|
||||
if (SIUnits.CELSIUS.equals(offset.getUnit())) {
|
||||
finalOffset = kelvinOffset.add(ZERO_CELSIUS_IN_KELVIN.negate());
|
||||
} else if (ImperialUnits.FAHRENHEIT.equals(offset.getUnit())) {
|
||||
finalOffset = kelvinOffset.add(ZERO_FAHRENHEIT_IN_KELVIN.negate());
|
||||
} else {
|
||||
// offset is already in Kelvin
|
||||
finalOffset = offset;
|
||||
}
|
||||
return kelvinState.add(finalOffset).toUnit(qtState.getUnit());
|
||||
return kelvinState.add(kelvinOffset).toUnit(qtState.getUnit());
|
||||
}
|
||||
}
|
||||
|
@ -314,6 +314,31 @@ public class QuantityType<T extends Quantity<T>> extends Number
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert this QuantityType to a new {@link QuantityType} using the given target unit.
|
||||
*
|
||||
* Similar to {@link toUnit}, except that it treats the values as relative instead of absolute.
|
||||
* This means that any offsets in the conversion of absolute values are ignored.
|
||||
* This is useful when your quantity represents a delta, and not necessarily a measured
|
||||
* value itself. For example, 32 °F, when converted with toUnit to Celsius, it will become 0 °C.
|
||||
* But when converted with toUnitRelative, it will become 17.8 °C.
|
||||
*
|
||||
* @param targetUnit the unit to which this {@link QuantityType} will be converted to.
|
||||
* @return the new {@link QuantityType} in the given {@link Unit} or {@code null} in case of an error.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public @Nullable QuantityType<T> toUnitRelative(Unit<T> targetUnit) {
|
||||
if (targetUnit.equals(getUnit())) {
|
||||
return this;
|
||||
}
|
||||
if (!quantity.getUnit().isCompatible(targetUnit)) {
|
||||
return null;
|
||||
}
|
||||
Quantity<?> result = quantity.to(targetUnit);
|
||||
|
||||
return new QuantityType<T>(result.getValue(), (Unit<T>) targetUnit);
|
||||
}
|
||||
|
||||
public BigDecimal toBigDecimal() {
|
||||
return new BigDecimal(quantity.getValue().toString());
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ import org.openhab.core.library.dimension.DataTransferRate;
|
||||
import org.openhab.core.library.dimension.Density;
|
||||
import org.openhab.core.library.dimension.Intensity;
|
||||
import org.openhab.core.library.unit.BinaryPrefix;
|
||||
import org.openhab.core.library.unit.ImperialUnits;
|
||||
import org.openhab.core.library.unit.MetricPrefix;
|
||||
import org.openhab.core.library.unit.SIUnits;
|
||||
import org.openhab.core.library.unit.Units;
|
||||
@ -483,4 +484,11 @@ public class QuantityTypeTest {
|
||||
QuantityType<?> andBack = mireds.toInvertibleUnit(Units.KELVIN);
|
||||
assertEquals(2700, andBack.intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRelativeConversion() {
|
||||
QuantityType<Temperature> c = new QuantityType("1 °C");
|
||||
QuantityType<Temperature> f = c.toUnitRelative(ImperialUnits.FAHRENHEIT);
|
||||
assertEquals(1.8, f.doubleValue());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user