Skip to content

Commit 506ccd4

Browse files
authored
Support channel transformation chaining with a list (openhab#4353)
Signed-off-by: Jimmy Tanagra <jcode@tanagra.id.au>
1 parent bb2a2d1 commit 506ccd4

File tree

4 files changed

+70
-13
lines changed

4 files changed

+70
-13
lines changed

bundles/org.openhab.core.thing/src/main/java/org/openhab/core/thing/binding/generic/ChannelTransformation.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
import java.util.Optional;
1818
import java.util.regex.Matcher;
1919
import java.util.regex.Pattern;
20+
import java.util.stream.Stream;
2021

22+
import org.eclipse.jdt.annotation.NonNullByDefault;
2123
import org.eclipse.jdt.annotation.Nullable;
2224
import org.openhab.core.transform.TransformationException;
2325
import org.openhab.core.transform.TransformationHelper;
@@ -33,15 +35,16 @@
3335
*
3436
* @author Jan N. Klug - Initial contribution
3537
*/
38+
@NonNullByDefault
3639
public class ChannelTransformation {
3740
private final Logger logger = LoggerFactory.getLogger(ChannelTransformation.class);
3841
private List<TransformationStep> transformationSteps;
3942

4043
public ChannelTransformation(@Nullable String transformationString) {
4144
if (transformationString != null) {
4245
try {
43-
transformationSteps = Arrays.stream(transformationString.split("∩")).filter(s -> !s.isBlank())
44-
.map(TransformationStep::new).toList();
46+
transformationSteps = splitTransformationString(transformationString).map(TransformationStep::new)
47+
.toList();
4548
return;
4649
} catch (IllegalArgumentException e) {
4750
logger.warn("Transformation ignored, failed to parse {}: {}", transformationString, e.getMessage());
@@ -50,6 +53,24 @@ public ChannelTransformation(@Nullable String transformationString) {
5053
transformationSteps = List.of();
5154
}
5255

56+
public ChannelTransformation(@Nullable List<String> transformationStrings) {
57+
if (transformationStrings != null) {
58+
try {
59+
transformationSteps = transformationStrings.stream()
60+
.flatMap(ChannelTransformation::splitTransformationString).map(TransformationStep::new)
61+
.toList();
62+
return;
63+
} catch (IllegalArgumentException e) {
64+
logger.warn("Transformation ignored, failed to parse {}: {}", transformationStrings, e.getMessage());
65+
}
66+
}
67+
transformationSteps = List.of();
68+
}
69+
70+
private static Stream<String> splitTransformationString(String transformationString) {
71+
return Arrays.stream(transformationString.split("∩")).filter(s -> !s.isBlank());
72+
}
73+
5374
public Optional<String> apply(String value) {
5475
Optional<String> valueOptional = Optional.of(value);
5576

bundles/org.openhab.core.thing/src/test/java/org/openhab/core/thing/binding/generic/ChannelTransformationTest.java

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
import static org.mockito.ArgumentMatchers.any;
1818
import static org.mockito.ArgumentMatchers.eq;
1919

20+
import java.util.List;
21+
2022
import org.eclipse.jdt.annotation.NonNullByDefault;
2123
import org.junit.jupiter.api.AfterEach;
2224
import org.junit.jupiter.api.BeforeEach;
@@ -54,8 +56,8 @@ public class ChannelTransformationTest {
5456

5557
private static final String T3_NAME = T2_NAME;
5658
private static final String T3_PATTERN = "a()b()))";
57-
private static final String T3_INPUT = T2_INPUT;
58-
private static final String T3_RESULT = T2_RESULT;
59+
private static final String T3_INPUT = T2_RESULT;
60+
private static final String T3_RESULT = "T3Result";
5961

6062
private @Mock @NonNullByDefault({}) TransformationService transformationService1Mock;
6163
private @Mock @NonNullByDefault({}) TransformationService transformationService2Mock;
@@ -163,6 +165,38 @@ public void testColonDoubleTransformationWithoutSpaces() {
163165
assertEquals(T2_RESULT, result);
164166
}
165167

168+
@Test
169+
public void testTransformationsInAList() {
170+
List<String> patterns = List.of(T1_NAME + ":" + T1_PATTERN, T2_NAME + ":" + T2_PATTERN);
171+
172+
ChannelTransformation transformation = new ChannelTransformation(patterns);
173+
String result = transformation.apply(T1_INPUT).orElse(null);
174+
175+
assertEquals(T2_RESULT, result);
176+
}
177+
178+
@Test
179+
public void testMixedTransformationsInAList1() {
180+
List<String> patterns = List.of(T1_NAME + ":" + T1_PATTERN + "∩" + T2_NAME + ":" + T2_PATTERN,
181+
T3_NAME + ":" + T3_PATTERN);
182+
183+
ChannelTransformation transformation = new ChannelTransformation(patterns);
184+
String result = transformation.apply(T1_INPUT).orElse(null);
185+
186+
assertEquals(T3_RESULT, result);
187+
}
188+
189+
@Test
190+
public void testMixedTransformationsInAList2() {
191+
List<String> patterns = List.of(T1_NAME + ":" + T1_PATTERN,
192+
T2_NAME + ":" + T2_PATTERN + "∩" + T3_NAME + ":" + T3_PATTERN);
193+
194+
ChannelTransformation transformation = new ChannelTransformation(patterns);
195+
String result = transformation.apply(T1_INPUT).orElse(null);
196+
197+
assertEquals(T3_RESULT, result);
198+
}
199+
166200
@Test
167201
public void testParensDoubleTransformationWithoutSpaces() {
168202
String pattern = T1_NAME + "(" + T1_PATTERN + ")∩" + T2_NAME + "(" + T2_PATTERN + ")";

bundles/org.openhab.core.thing/src/test/java/org/openhab/core/thing/binding/generic/converter/ConverterTest.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ public class ConverterTest {
6262
@Test
6363
public void numberItemConverter() {
6464
NumberChannelHandler converter = new NumberChannelHandler(updateStateMock, postCommandMock, sendValueMock,
65-
new ChannelTransformation(null), new ChannelTransformation(null), new ChannelValueConverterConfig());
65+
new ChannelTransformation((String) null), new ChannelTransformation((String) null),
66+
new ChannelValueConverterConfig());
6667

6768
// without unit
6869
Assertions.assertEquals(Optional.of(new DecimalType(1234)), converter.toState("1234"));
@@ -80,7 +81,7 @@ public void numberItemConverterWithUnit() {
8081
ChannelValueConverterConfig channelConfig = new ChannelValueConverterConfig();
8182
channelConfig.unit = "W";
8283
NumberChannelHandler converter = new NumberChannelHandler(updateStateMock, postCommandMock, sendValueMock,
83-
new ChannelTransformation(null), new ChannelTransformation(null), channelConfig);
84+
new ChannelTransformation((String) null), new ChannelTransformation((String) null), channelConfig);
8485

8586
// without unit
8687
Assertions.assertEquals(Optional.of(new QuantityType<>(500, Units.WATT)), converter.toState("500"));
@@ -117,7 +118,7 @@ public void playerItemTypeConverter() {
117118
ChannelHandlerContent content = new ChannelHandlerContent("PLAY".getBytes(StandardCharsets.UTF_8), "UTF-8",
118119
null);
119120
PlayerChannelHandler converter = new PlayerChannelHandler(updateStateMock, postCommandMock, sendValueMock,
120-
new ChannelTransformation(null), new ChannelTransformation(null), cfg);
121+
new ChannelTransformation((String) null), new ChannelTransformation((String) null), cfg);
121122
converter.process(content);
122123
converter.process(content);
123124

@@ -132,7 +133,7 @@ public void colorItemTypeRGBConverter() {
132133
ChannelHandlerContent content = new ChannelHandlerContent("123,34,47".getBytes(StandardCharsets.UTF_8), "UTF-8",
133134
null);
134135
ColorChannelHandler converter = new ColorChannelHandler(updateStateMock, postCommandMock, sendValueMock,
135-
new ChannelTransformation(null), new ChannelTransformation(null), cfg);
136+
new ChannelTransformation((String) null), new ChannelTransformation((String) null), cfg);
136137

137138
converter.process(content);
138139
Mockito.verify(updateStateMock).accept(HSBType.fromRGB(123, 34, 47));
@@ -145,7 +146,7 @@ public void colorItemTypeHSBConverter() {
145146
ChannelHandlerContent content = new ChannelHandlerContent("123,34,47".getBytes(StandardCharsets.UTF_8), "UTF-8",
146147
null);
147148
ColorChannelHandler converter = new ColorChannelHandler(updateStateMock, postCommandMock, sendValueMock,
148-
new ChannelTransformation(null), new ChannelTransformation(null), cfg);
149+
new ChannelTransformation((String) null), new ChannelTransformation((String) null), cfg);
149150

150151
converter.process(content);
151152
Mockito.verify(updateStateMock).accept(new HSBType("123,34,47"));
@@ -155,7 +156,7 @@ public void colorItemTypeHSBConverter() {
155156
public void rollerSHutterConverter() {
156157
ChannelValueConverterConfig cfg = new ChannelValueConverterConfig();
157158
RollershutterChannelHandler converter = new RollershutterChannelHandler(updateStateMock, postCommandMock,
158-
sendValueMock, new ChannelTransformation(null), new ChannelTransformation(null), cfg);
159+
sendValueMock, new ChannelTransformation((String) null), new ChannelTransformation((String) null), cfg);
159160

160161
// test 0 and 100
161162
ChannelHandlerContent content = new ChannelHandlerContent("0".getBytes(StandardCharsets.UTF_8), "UTF-8", null);
@@ -181,6 +182,7 @@ public void rollerSHutterConverter() {
181182

182183
public GenericChannelHandler createConverter(Function<String, State> fcn) {
183184
return new GenericChannelHandler(fcn, updateStateMock, postCommandMock, sendValueMock,
184-
new ChannelTransformation(null), new ChannelTransformation(null), new ChannelValueConverterConfig());
185+
new ChannelTransformation((String) null), new ChannelTransformation((String) null),
186+
new ChannelValueConverterConfig());
185187
}
186188
}

bundles/org.openhab.core.thing/src/test/java/org/openhab/core/thing/internal/binding/generic/converter/AbstractTransformingItemConverterTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ public class AbstractTransformingItemConverterTest {
5959
private @NonNullByDefault({}) AutoCloseable closeable;
6060

6161
@Spy
62-
private ChannelTransformation stateChannelTransformation = new ChannelTransformation(null);
62+
private ChannelTransformation stateChannelTransformation = new ChannelTransformation((String) null);
6363

6464
@Spy
65-
private ChannelTransformation commandChannelTransformation = new ChannelTransformation(null);
65+
private ChannelTransformation commandChannelTransformation = new ChannelTransformation((String) null);
6666

6767
@BeforeEach
6868
public void init() {

0 commit comments

Comments
 (0)