Skip to content

Commit

Permalink
Support channel transformation chaining with a list (#4353)
Browse files Browse the repository at this point in the history
Signed-off-by: Jimmy Tanagra <jcode@tanagra.id.au>
  • Loading branch information
jimtng committed Aug 18, 2024
1 parent bb2a2d1 commit 506ccd4
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.transform.TransformationException;
import org.openhab.core.transform.TransformationHelper;
Expand All @@ -33,15 +35,16 @@
*
* @author Jan N. Klug - Initial contribution
*/
@NonNullByDefault
public class ChannelTransformation {
private final Logger logger = LoggerFactory.getLogger(ChannelTransformation.class);
private List<TransformationStep> transformationSteps;

public ChannelTransformation(@Nullable String transformationString) {
if (transformationString != null) {
try {
transformationSteps = Arrays.stream(transformationString.split("∩")).filter(s -> !s.isBlank())
.map(TransformationStep::new).toList();
transformationSteps = splitTransformationString(transformationString).map(TransformationStep::new)
.toList();
return;
} catch (IllegalArgumentException e) {
logger.warn("Transformation ignored, failed to parse {}: {}", transformationString, e.getMessage());
Expand All @@ -50,6 +53,24 @@ public ChannelTransformation(@Nullable String transformationString) {
transformationSteps = List.of();
}

public ChannelTransformation(@Nullable List<String> transformationStrings) {
if (transformationStrings != null) {
try {
transformationSteps = transformationStrings.stream()
.flatMap(ChannelTransformation::splitTransformationString).map(TransformationStep::new)
.toList();
return;
} catch (IllegalArgumentException e) {
logger.warn("Transformation ignored, failed to parse {}: {}", transformationStrings, e.getMessage());
}
}
transformationSteps = List.of();
}

private static Stream<String> splitTransformationString(String transformationString) {
return Arrays.stream(transformationString.split("∩")).filter(s -> !s.isBlank());
}

public Optional<String> apply(String value) {
Optional<String> valueOptional = Optional.of(value);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;

import java.util.List;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
Expand Down Expand Up @@ -54,8 +56,8 @@ public class ChannelTransformationTest {

private static final String T3_NAME = T2_NAME;
private static final String T3_PATTERN = "a()b()))";
private static final String T3_INPUT = T2_INPUT;
private static final String T3_RESULT = T2_RESULT;
private static final String T3_INPUT = T2_RESULT;
private static final String T3_RESULT = "T3Result";

private @Mock @NonNullByDefault({}) TransformationService transformationService1Mock;
private @Mock @NonNullByDefault({}) TransformationService transformationService2Mock;
Expand Down Expand Up @@ -163,6 +165,38 @@ public void testColonDoubleTransformationWithoutSpaces() {
assertEquals(T2_RESULT, result);
}

@Test
public void testTransformationsInAList() {
List<String> patterns = List.of(T1_NAME + ":" + T1_PATTERN, T2_NAME + ":" + T2_PATTERN);

ChannelTransformation transformation = new ChannelTransformation(patterns);
String result = transformation.apply(T1_INPUT).orElse(null);

assertEquals(T2_RESULT, result);
}

@Test
public void testMixedTransformationsInAList1() {
List<String> patterns = List.of(T1_NAME + ":" + T1_PATTERN + "∩" + T2_NAME + ":" + T2_PATTERN,
T3_NAME + ":" + T3_PATTERN);

ChannelTransformation transformation = new ChannelTransformation(patterns);
String result = transformation.apply(T1_INPUT).orElse(null);

assertEquals(T3_RESULT, result);
}

@Test
public void testMixedTransformationsInAList2() {
List<String> patterns = List.of(T1_NAME + ":" + T1_PATTERN,
T2_NAME + ":" + T2_PATTERN + "∩" + T3_NAME + ":" + T3_PATTERN);

ChannelTransformation transformation = new ChannelTransformation(patterns);
String result = transformation.apply(T1_INPUT).orElse(null);

assertEquals(T3_RESULT, result);
}

@Test
public void testParensDoubleTransformationWithoutSpaces() {
String pattern = T1_NAME + "(" + T1_PATTERN + ")∩" + T2_NAME + "(" + T2_PATTERN + ")";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ public class ConverterTest {
@Test
public void numberItemConverter() {
NumberChannelHandler converter = new NumberChannelHandler(updateStateMock, postCommandMock, sendValueMock,
new ChannelTransformation(null), new ChannelTransformation(null), new ChannelValueConverterConfig());
new ChannelTransformation((String) null), new ChannelTransformation((String) null),
new ChannelValueConverterConfig());

// without unit
Assertions.assertEquals(Optional.of(new DecimalType(1234)), converter.toState("1234"));
Expand All @@ -80,7 +81,7 @@ public void numberItemConverterWithUnit() {
ChannelValueConverterConfig channelConfig = new ChannelValueConverterConfig();
channelConfig.unit = "W";
NumberChannelHandler converter = new NumberChannelHandler(updateStateMock, postCommandMock, sendValueMock,
new ChannelTransformation(null), new ChannelTransformation(null), channelConfig);
new ChannelTransformation((String) null), new ChannelTransformation((String) null), channelConfig);

// without unit
Assertions.assertEquals(Optional.of(new QuantityType<>(500, Units.WATT)), converter.toState("500"));
Expand Down Expand Up @@ -117,7 +118,7 @@ public void playerItemTypeConverter() {
ChannelHandlerContent content = new ChannelHandlerContent("PLAY".getBytes(StandardCharsets.UTF_8), "UTF-8",
null);
PlayerChannelHandler converter = new PlayerChannelHandler(updateStateMock, postCommandMock, sendValueMock,
new ChannelTransformation(null), new ChannelTransformation(null), cfg);
new ChannelTransformation((String) null), new ChannelTransformation((String) null), cfg);
converter.process(content);
converter.process(content);

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

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

converter.process(content);
Mockito.verify(updateStateMock).accept(new HSBType("123,34,47"));
Expand All @@ -155,7 +156,7 @@ public void colorItemTypeHSBConverter() {
public void rollerSHutterConverter() {
ChannelValueConverterConfig cfg = new ChannelValueConverterConfig();
RollershutterChannelHandler converter = new RollershutterChannelHandler(updateStateMock, postCommandMock,
sendValueMock, new ChannelTransformation(null), new ChannelTransformation(null), cfg);
sendValueMock, new ChannelTransformation((String) null), new ChannelTransformation((String) null), cfg);

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

public GenericChannelHandler createConverter(Function<String, State> fcn) {
return new GenericChannelHandler(fcn, updateStateMock, postCommandMock, sendValueMock,
new ChannelTransformation(null), new ChannelTransformation(null), new ChannelValueConverterConfig());
new ChannelTransformation((String) null), new ChannelTransformation((String) null),
new ChannelValueConverterConfig());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ public class AbstractTransformingItemConverterTest {
private @NonNullByDefault({}) AutoCloseable closeable;

@Spy
private ChannelTransformation stateChannelTransformation = new ChannelTransformation(null);
private ChannelTransformation stateChannelTransformation = new ChannelTransformation((String) null);

@Spy
private ChannelTransformation commandChannelTransformation = new ChannelTransformation(null);
private ChannelTransformation commandChannelTransformation = new ChannelTransformation((String) null);

@BeforeEach
public void init() {
Expand Down

0 comments on commit 506ccd4

Please sign in to comment.