[basicprofiles] Support double quoted strings in state filter (#18117)

Signed-off-by: Jimmy Tanagra <jcode@tanagra.id.au>
pull/18089/merge
jimtng 2025-01-18 01:41:08 +10:00 committed by GitHub
parent 34f81c61a2
commit 3b0c78795d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 21 additions and 3 deletions

View File

@ -218,7 +218,7 @@ The `LHS_OPERAND` and the `RHS_OPERAND` can be either one of these:
- An item name, which will be evaluated to its state.
- A type constant, such as `ON`, `OFF`, `UNDEF`, `NULL`, `OPEN`, `CLOSED`, `PLAY`, `PAUSE`, `UP`, `DOWN`, etc.
Note that these are unquoted.
- A String value, enclosed with single quotes, e.g. `'ON'`.
- A String value, enclosed with single or double quotes, e.g. `'ON'`, `"FOO"`.
A string value is different to the actual `OnOffType.ON`.
To compare against an actual OnOffType, use an unquoted `ON`.
- A plain number to represent a `DecimalType`.

View File

@ -248,7 +248,7 @@ public class StateFilterProfile implements StateProfile {
// Quoted strings are parsed as StringType
if (stateString == null || stateString.isEmpty()) {
return null;
} else if (stateString.startsWith("'") && stateString.endsWith("'")) {
} else if (isQuotedString(stateString)) {
return new StringType(stateString.substring(1, stateString.length() - 1));
} else if (parseFunction(stateString) instanceof FunctionType function) {
return function;
@ -258,6 +258,11 @@ public class StateFilterProfile implements StateProfile {
return null;
}
private boolean isQuotedString(String value) {
return (value.startsWith("'") && value.endsWith("'")) || //
(value.startsWith("\"") && value.endsWith("\""));
}
@Nullable
FunctionType parseFunction(String functionDefinition) {
if (!functionDefinition.startsWith("$")) {

View File

@ -173,7 +173,7 @@ public class StateFilterProfileTest {
}
@Test
public void testSingleConditionMatchQuoted() throws ItemNotFoundException {
public void testSingleConditionMatchSingleQuoted() throws ItemNotFoundException {
when(mockContext.getConfiguration()).thenReturn(new Configuration(Map.of("conditions", "ItemName eq 'Value'")));
when(mockItemRegistry.getItem("ItemName")).thenReturn(stringItemWithState("ItemName", "Value"));
@ -184,6 +184,19 @@ public class StateFilterProfileTest {
verify(mockCallback, times(1)).sendUpdate(eq(expectation));
}
@Test
public void testSingleConditionMatchDoubleQuoted() throws ItemNotFoundException {
when(mockContext.getConfiguration())
.thenReturn(new Configuration(Map.of("conditions", "ItemName eq \"Value\"")));
when(mockItemRegistry.getItem("ItemName")).thenReturn(stringItemWithState("ItemName", "Value"));
StateFilterProfile profile = new StateFilterProfile(mockCallback, mockContext, mockItemRegistry);
State expectation = new StringType("NewValue");
profile.onStateUpdateFromHandler(expectation);
verify(mockCallback, times(1)).sendUpdate(eq(expectation));
}
private Item stringItemWithState(String itemName, String value) {
StringItem item = new StringItem(itemName);
item.setState(new StringType(value));