mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-02-04 19:34:05 +01:00
[basicprofiles] Convert to relative unit in State Filter's Delta check (#18127)
* [basicprofiles] Convert to relative unit in State Filter's Delta check Signed-off-by: Jimmy Tanagra <jcode@tanagra.id.au>
This commit is contained in:
parent
247495335e
commit
019fb8acf4
@ -334,6 +334,7 @@ public class StateFilterProfile implements StateProfile {
|
|||||||
State rhsState = this.rhsState;
|
State rhsState = this.rhsState;
|
||||||
Item lhsItem = null;
|
Item lhsItem = null;
|
||||||
Item rhsItem = null;
|
Item rhsItem = null;
|
||||||
|
boolean isDeltaCheck = false;
|
||||||
|
|
||||||
if (rhsState == null) {
|
if (rhsState == null) {
|
||||||
rhsItem = getItemOrNull(rhsString);
|
rhsItem = getItemOrNull(rhsString);
|
||||||
@ -387,6 +388,9 @@ public class StateFilterProfile implements StateProfile {
|
|||||||
logger.debug("Couldn't calculate the left hand side function '{}'", lhsString);
|
logger.debug("Couldn't calculate the left hand side function '{}'", lhsString);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (lhsFunction.getType() == FunctionType.Function.DELTA) {
|
||||||
|
isDeltaCheck = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rhsState == null) {
|
if (rhsState == null) {
|
||||||
@ -395,6 +399,10 @@ public class StateFilterProfile implements StateProfile {
|
|||||||
|
|
||||||
// Don't convert QuantityType to other types, so that 1500 != 1500 W
|
// Don't convert QuantityType to other types, so that 1500 != 1500 W
|
||||||
if (rhsState != null && !(rhsState instanceof QuantityType)) {
|
if (rhsState != null && !(rhsState instanceof QuantityType)) {
|
||||||
|
if (rhsState instanceof FunctionType rhsFunction
|
||||||
|
&& rhsFunction.getType() == FunctionType.Function.DELTA) {
|
||||||
|
isDeltaCheck = true;
|
||||||
|
}
|
||||||
// Try to convert it to the same type as the lhs
|
// Try to convert it to the same type as the lhs
|
||||||
// This allows comparing compatible types, e.g. PercentType vs OnOffType
|
// This allows comparing compatible types, e.g. PercentType vs OnOffType
|
||||||
rhsState = rhsState.as(lhsState.getClass());
|
rhsState = rhsState.as(lhsState.getClass());
|
||||||
@ -432,6 +440,12 @@ public class StateFilterProfile implements StateProfile {
|
|||||||
|
|
||||||
rhs = Objects.requireNonNull(rhsState instanceof StringType ? rhsState.toString() : rhsState);
|
rhs = Objects.requireNonNull(rhsState instanceof StringType ? rhsState.toString() : rhsState);
|
||||||
|
|
||||||
|
if (isDeltaCheck && rhs instanceof QuantityType rhsQty && lhs instanceof QuantityType lhsQty) {
|
||||||
|
if (rhsQty.toUnitRelative(lhsQty.getUnit()) instanceof QuantityType relativeRhs) {
|
||||||
|
rhs = relativeRhs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
if (lhsString.isEmpty()) {
|
if (lhsString.isEmpty()) {
|
||||||
logger.debug("Performing a comparison between input '{}' ({}) and value '{}' ({})", lhs,
|
logger.debug("Performing a comparison between input '{}' ({}) and value '{}' ({})", lhs,
|
||||||
|
@ -793,6 +793,68 @@ public class StateFilterProfileTest {
|
|||||||
@MethodSource
|
@MethodSource
|
||||||
public void testFunctions(Item item, String condition, List<State> states, State input, boolean expected)
|
public void testFunctions(Item item, String condition, List<State> states, State input, boolean expected)
|
||||||
throws ItemNotFoundException {
|
throws ItemNotFoundException {
|
||||||
|
internalTestFunctions(item, condition, states, input, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Stream<Arguments> testDeltaWithRelativeUnit() {
|
||||||
|
NumberItem temperatureItem = new NumberItem("Number:Temperature", "temperatureItem", UNIT_PROVIDER);
|
||||||
|
|
||||||
|
State initialC = QuantityType.valueOf("5 °C");
|
||||||
|
State initialF = QuantityType.valueOf("5 °F");
|
||||||
|
|
||||||
|
State qty_7_C = QuantityType.valueOf("7 °C");
|
||||||
|
State qty_7_F = QuantityType.valueOf("7 °F");
|
||||||
|
|
||||||
|
return Stream.of( //
|
||||||
|
// Celsius inputs
|
||||||
|
// same unit
|
||||||
|
Arguments.of(temperatureItem, "$DELTA > 1 °C", initialC, qty_7_C, true), //
|
||||||
|
Arguments.of(temperatureItem, "1 °C < $DELTA", initialC, qty_7_C, true), //
|
||||||
|
Arguments.of(temperatureItem, "$DELTA < 1 °C", initialC, qty_7_C, false), //
|
||||||
|
Arguments.of(temperatureItem, "1 °C > $DELTA", initialC, qty_7_C, false), //
|
||||||
|
|
||||||
|
// Celsius vs Fahrenheit: 2 °C = 35.6 °F (absolute), 2 °C = 3.6 °F (relative)
|
||||||
|
Arguments.of(temperatureItem, "$DELTA > 4 °F", initialC, qty_7_C, false), //
|
||||||
|
Arguments.of(temperatureItem, "4 °F < $DELTA", initialC, qty_7_C, false), //
|
||||||
|
Arguments.of(temperatureItem, "$DELTA < 4 °F", initialC, qty_7_C, true), //
|
||||||
|
Arguments.of(temperatureItem, "4 °F > $DELTA", initialC, qty_7_C, true), //
|
||||||
|
|
||||||
|
// Celsius vs Kelvin: °C = K in relative unit
|
||||||
|
Arguments.of(temperatureItem, "$DELTA > 1 K", initialC, qty_7_C, true), //
|
||||||
|
Arguments.of(temperatureItem, "1 K < $DELTA", initialC, qty_7_C, true), //
|
||||||
|
Arguments.of(temperatureItem, "$DELTA < 1 K", initialC, qty_7_C, false), //
|
||||||
|
Arguments.of(temperatureItem, "1 K > $DELTA", initialC, qty_7_C, false), //
|
||||||
|
|
||||||
|
// Fahrenheit inputs
|
||||||
|
// same unit, in F
|
||||||
|
Arguments.of(temperatureItem, "$DELTA > 1 °F", initialF, qty_7_F, true), //
|
||||||
|
Arguments.of(temperatureItem, "1 °F < $DELTA", initialF, qty_7_F, true), //
|
||||||
|
Arguments.of(temperatureItem, "$DELTA < 2 °F", initialF, qty_7_F, false), //
|
||||||
|
Arguments.of(temperatureItem, "2 °F > $DELTA", initialF, qty_7_F, false), //
|
||||||
|
|
||||||
|
// Fahrenheit vs Celsius: 2 °F = -16.67 °C (absolute), 2 °F = 1.11 °C (relative)
|
||||||
|
Arguments.of(temperatureItem, "$DELTA > 1 °C", initialF, qty_7_F, true), //
|
||||||
|
Arguments.of(temperatureItem, "1 °C < $DELTA", initialF, qty_7_F, true), //
|
||||||
|
Arguments.of(temperatureItem, "$DELTA < 1 °C", initialF, qty_7_F, false), //
|
||||||
|
Arguments.of(temperatureItem, "1 °C > $DELTA", initialF, qty_7_F, false), //
|
||||||
|
|
||||||
|
// Fahreheit vs Kelvin: 2 °F = 256.48 K (absolute), 2 °F = 1.11 K (relative)
|
||||||
|
Arguments.of(temperatureItem, "$DELTA > 2 K", initialF, qty_7_F, false), //
|
||||||
|
Arguments.of(temperatureItem, "2 K < $DELTA", initialF, qty_7_F, false), //
|
||||||
|
Arguments.of(temperatureItem, "$DELTA < 2 K", initialF, qty_7_F, true), //
|
||||||
|
Arguments.of(temperatureItem, "2 K > $DELTA", initialF, qty_7_F, true) //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource
|
||||||
|
public void testDeltaWithRelativeUnit(Item item, String condition, State initialState, State input,
|
||||||
|
boolean expected) throws ItemNotFoundException {
|
||||||
|
internalTestFunctions(item, condition, List.of(initialState), input, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void internalTestFunctions(Item item, String condition, List<State> states, State input, boolean expected)
|
||||||
|
throws ItemNotFoundException {
|
||||||
when(mockContext.getConfiguration()).thenReturn(new Configuration(Map.of("conditions", condition)));
|
when(mockContext.getConfiguration()).thenReturn(new Configuration(Map.of("conditions", condition)));
|
||||||
when(mockItemRegistry.getItem(item.getName())).thenReturn(item);
|
when(mockItemRegistry.getItem(item.getName())).thenReturn(item);
|
||||||
when(mockItemChannelLink.getItemName()).thenReturn(item.getName());
|
when(mockItemChannelLink.getItemName()).thenReturn(item.getName());
|
||||||
|
Loading…
Reference in New Issue
Block a user