]> git.basschouten.com Git - openhab-addons.git/blob
52c48b63595c5da111467427703a9c8a93cf06b5
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.echonetlite.internal.protocol;
14
15 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
16 import static org.junit.jupiter.api.Assertions.assertEquals;
17 import static org.openhab.binding.echonetlite.internal.LangUtil.b;
18
19 import java.nio.ByteBuffer;
20 import java.nio.ByteOrder;
21 import java.util.concurrent.TimeUnit;
22
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.junit.jupiter.api.Test;
25 import org.openhab.binding.echonetlite.internal.StateCodec;
26 import org.openhab.binding.echonetlite.internal.StateCodec.HexStringCodec;
27 import org.openhab.binding.echonetlite.internal.StateCodec.OperatingTimeDecode;
28 import org.openhab.binding.echonetlite.internal.StateCodec.Option;
29 import org.openhab.binding.echonetlite.internal.StateCodec.OptionCodec;
30 import org.openhab.binding.echonetlite.internal.StateCodec.StandardVersionInformationCodec;
31 import org.openhab.binding.echonetlite.internal.StateDecode;
32 import org.openhab.core.library.types.DecimalType;
33 import org.openhab.core.library.types.OnOffType;
34 import org.openhab.core.library.types.QuantityType;
35 import org.openhab.core.library.types.StringType;
36 import org.openhab.core.library.unit.SIUnits;
37 import org.openhab.core.types.State;
38
39 /**
40  * @author Michael Barker - Initial contribution
41  */
42 @NonNullByDefault
43 class StateCodecTest {
44     private void assertEncodeDecode(StateCodec stateCodec, State state, byte[] expectedOutput) {
45         final ByteBuffer buffer = ByteBuffer.allocate(1024);
46         stateCodec.encodeState(state, buffer);
47         buffer.flip();
48
49         final byte[] encoded = new byte[buffer.remaining()];
50         buffer.get(encoded);
51         assertArrayEquals(expectedOutput, encoded);
52
53         buffer.flip();
54
55         assertEquals(state, stateCodec.decodeState(buffer));
56     }
57
58     private void assertDecode(StateDecode stateDecode, State expectedState, byte[] data) {
59         assertEquals(expectedState, stateDecode.decodeState(ByteBuffer.wrap(data)));
60     }
61
62     @Test
63     void shouldEncodeOnOff() {
64         final int on = 34;
65         final int off = 27;
66         final StateCodec.OnOffCodec onOffCodec = new StateCodec.OnOffCodec(on, off);
67
68         assertEncodeDecode(onOffCodec, OnOffType.ON, new byte[] { b(on) });
69         assertEncodeDecode(onOffCodec, OnOffType.OFF, new byte[] { b(off) });
70     }
71
72     @Test
73     void shouldDecodeStandardVersionInformation() {
74         assertDecode(StandardVersionInformationCodec.INSTANCE, StringType.EMPTY, new byte[0]);
75         assertDecode(StandardVersionInformationCodec.INSTANCE, StringType.EMPTY, new byte[1]);
76         assertDecode(StandardVersionInformationCodec.INSTANCE, StringType.EMPTY, new byte[2]);
77         assertDecode(StandardVersionInformationCodec.INSTANCE, StringType.EMPTY, new byte[3]);
78         assertDecode(StandardVersionInformationCodec.INSTANCE, StringType.EMPTY, new byte[5]);
79         assertDecode(StandardVersionInformationCodec.INSTANCE, new StringType("A"), new byte[] { 0, 0, 'A', 0 });
80         assertDecode(StandardVersionInformationCodec.INSTANCE, new StringType("Z"), new byte[] { 0, 0, 'Z', 0 });
81     }
82
83     @Test
84     void shouldDecodeHexString() {
85         assertDecode(HexStringCodec.INSTANCE, new StringType("000102030467"), new byte[] { 0, 1, 2, 3, 4, b(0x67) });
86     }
87
88     @Test
89     void shouldDecodeCumulativeOperatingTime() {
90         final ByteBuffer buffer = ByteBuffer.wrap(new byte[5]);
91         buffer.order(ByteOrder.BIG_ENDIAN);
92
93         final int valueInSeconds = 484260;
94         final long valueInMinutes = TimeUnit.SECONDS.toMinutes(valueInSeconds);
95         buffer.put(b(0x42));
96         buffer.putInt((int) valueInMinutes);
97
98         buffer.flip();
99         buffer.order(ByteOrder.LITTLE_ENDIAN);
100         assertEquals(valueInSeconds, ((QuantityType<?>) OperatingTimeDecode.INSTANCE.decodeState(buffer)).intValue());
101
102         buffer.flip();
103         buffer.order(ByteOrder.BIG_ENDIAN);
104         assertEquals(valueInSeconds, ((QuantityType<?>) OperatingTimeDecode.INSTANCE.decodeState(buffer)).intValue());
105     }
106
107     @Test
108     void shouldEncodeDecodeOption() {
109         final OptionCodec optionCodec = new OptionCodec(new Option("ABC", 123), new Option("DEF", 101));
110         assertEncodeDecode(optionCodec, new StringType("ABC"), new byte[] { 123 });
111         assertEncodeDecode(optionCodec, new StringType("DEF"), new byte[] { 101 });
112     }
113
114     @Test
115     void shouldEncodeAndDecode8Bit() {
116         assertEncodeDecode(StateCodec.Decimal8bitCodec.INSTANCE, new DecimalType(123), new byte[] { 123 });
117         assertEncodeDecode(StateCodec.Decimal8bitCodec.INSTANCE, new DecimalType(1), new byte[] { 1 });
118         assertEncodeDecode(StateCodec.Decimal8bitCodec.INSTANCE, new DecimalType(-1), new byte[] { b(255) });
119     }
120
121     @Test
122     void shouldEncodeAndDecodeTemperature() {
123         assertEncodeDecode(StateCodec.Temperature8bitCodec.INSTANCE, new QuantityType<>(123, SIUnits.CELSIUS),
124                 new byte[] { 123 });
125         assertEncodeDecode(StateCodec.Temperature8bitCodec.INSTANCE, new QuantityType<>(1, SIUnits.CELSIUS),
126                 new byte[] { 1 });
127         assertEncodeDecode(StateCodec.Temperature8bitCodec.INSTANCE, new QuantityType<>(-1, SIUnits.CELSIUS),
128                 new byte[] { b(255) });
129     }
130 }