Skip to content

Commit

Permalink
Support a simpler syntax for comparing percent delta
Browse files Browse the repository at this point in the history
Signed-off-by: Jimmy Tanagra <[email protected]>
  • Loading branch information
jimtng committed Dec 4, 2024
1 parent b55c3ed commit fdf215b
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 2 deletions.
18 changes: 18 additions & 0 deletions bundles/org.openhab.transform.basicprofiles/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,12 @@ The `LHS_OPERAND` and the `RHS_OPERAND` can be either one of these:
- A number with a unit to represent a `QuantityType`, for example `1.2 kW`, or `24 °C`.
- One of the special functions supported by State Filter:
- `$DELTA` to represent the absolute difference between the incoming value and the previously accepted value.
The calculated delta value is absolute, i.e. it is always positive.
For example, with an initial data of `10`, a new data of `12` or `8` would both result in a $DELTA of `2`.
- `$DELTA_PERCENT` to represent the difference in percentage.
It is calculated as `($DELTA / current_data) * 100`.
Note that this can also be done by omitting the `LHS_OPERAND` and using a number followed with a percent sign `%` as the `RHS_OPERAND`.
See the example below.
- `$AVERAGE`, or `$AVG` to represent the average of the previous unfiltered incoming values.
- `$STDDEV` to represent the _population_ standard deviation of the previous unfiltered incoming values.
- `$MEDIAN` to represent the median value of the previous unfiltered incoming values.
Expand Down Expand Up @@ -272,6 +277,19 @@ Number:Power PowerUsage {
}
```

Accept new data only if it's 10% higher or 10% lower than the previously accepted data:

```java
Number:Temperature BoilerTemperature {
channel="mybinding:mything:mychannel" [ profile="basic-profiles:state-filter", conditions="$DELTA_PERCENT > 10" ]
}

// Or more succinctly:
Number:Temperature BoilerTemperature {
channel="mybinding:mything:mychannel" [ profile="basic-profiles:state-filter", conditions="> 10%" ]
}
```

The incoming state can be compared against other items:

```java
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,16 @@ class StateCondition {

public StateCondition(String lhs, ComparisonType comparisonType, String rhs) {
this.comparisonType = comparisonType;
this.lhsString = lhs;
this.rhsString = rhs;

if (lhs.isEmpty() && rhs.endsWith("%")) {
// Allow comparing percentages without a left hand side,
// e.g. `> 50%` -> translate this to `$DELTA_PERCENT > 50`
lhsString = "$DELTA_PERCENT";
rhsString = rhs.substring(0, rhs.length() - 1).trim();
} else {
lhsString = lhs;
rhsString = rhs;
}
// Convert quoted strings to StringType, and UnDefTypes to UnDefType
// UnDefType gets special treatment because we don't want `UNDEF` to be parsed as a string
// Anything else, defer parsing until we're checking the condition
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,13 @@ public static Stream<Arguments> testFunctions() {
Arguments.of(decimalItem, "$DELTA_PERCENT >= 10", decimals, DecimalType.valueOf("5.5"), true), //
Arguments.of(decimalItem, "$DELTA_PERCENT >= 10", decimals, DecimalType.valueOf("6"), true), //

Arguments.of(decimalItem, ">= 10 %", decimals, DecimalType.valueOf("4.6"), false), //
Arguments.of(decimalItem, ">= 10%", decimals, DecimalType.valueOf("4.6"), false), //
Arguments.of(decimalItem, ">= 10%", decimals, DecimalType.valueOf("4.5"), true), //
Arguments.of(decimalItem, ">= 10%", decimals, DecimalType.valueOf("5.4"), false), //
Arguments.of(decimalItem, ">= 10%", decimals, DecimalType.valueOf("5.5"), true), //
Arguments.of(decimalItem, ">= 10%", decimals, DecimalType.valueOf("6"), true), //

// The following will only accept new data if it is within 10% of the previously accepted data.
// so the second and subsequent initial data (i.e.: 2, 3, 4, 5) will be rejected.
// The new data is compared against the first (1)
Expand All @@ -688,6 +695,11 @@ public static Stream<Arguments> testFunctions() {
Arguments.of(decimalItem, "$DELTA_PERCENT < 10", decimals, DecimalType.valueOf("0.91"), true), //
Arguments.of(decimalItem, "$DELTA_PERCENT < 10", decimals, DecimalType.valueOf("0.89"), false), //

Arguments.of(decimalItem, "< 10%", decimals, DecimalType.valueOf("1.09"), true), //
Arguments.of(decimalItem, "< 10%", decimals, DecimalType.valueOf("1.11"), false), //
Arguments.of(decimalItem, "< 10%", decimals, DecimalType.valueOf("0.91"), true), //
Arguments.of(decimalItem, "< 10%", decimals, DecimalType.valueOf("0.89"), false), //

Arguments.of(decimalItem, "1 == $MIN", decimals, DecimalType.valueOf("20"), true), //
Arguments.of(decimalItem, "0 < $MIN", decimals, DecimalType.valueOf("20"), true), //
Arguments.of(decimalItem, "$MIN > 0", decimals, DecimalType.valueOf("20"), true), //
Expand Down

0 comments on commit fdf215b

Please sign in to comment.