]> git.basschouten.com Git - openhab-addons.git/blob
35dfbd9fb18050310711f347f6dc8d2fab4ec1ac
[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.rfxcom.internal.messages;
14
15 import static org.junit.jupiter.api.Assertions.*;
16 import static org.openhab.binding.rfxcom.internal.RFXComBindingConstants.*;
17 import static org.openhab.binding.rfxcom.internal.RFXComTestHelper.*;
18 import static org.openhab.binding.rfxcom.internal.messages.RFXComBaseMessage.PacketType.LIGHTING4;
19 import static org.openhab.binding.rfxcom.internal.messages.RFXComLighting4Message.SubType.PT2262;
20
21 import java.util.Arrays;
22 import java.util.List;
23 import java.util.Map;
24
25 import org.eclipse.jdt.annotation.NonNullByDefault;
26 import org.eclipse.jdt.annotation.Nullable;
27 import org.junit.jupiter.api.Test;
28 import org.openhab.binding.rfxcom.internal.RFXComTestHelper;
29 import org.openhab.binding.rfxcom.internal.config.RFXComDeviceConfiguration;
30 import org.openhab.binding.rfxcom.internal.config.RFXComLighting4DeviceConfiguration;
31 import org.openhab.binding.rfxcom.internal.exceptions.RFXComException;
32 import org.openhab.binding.rfxcom.internal.exceptions.RFXComInvalidStateException;
33 import org.openhab.binding.rfxcom.internal.messages.RFXComBaseMessage.PacketType;
34 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
35 import org.openhab.core.library.types.OnOffType;
36 import org.openhab.core.library.types.OpenClosedType;
37 import org.openhab.core.thing.ChannelUID;
38 import org.openhab.core.thing.ThingUID;
39 import org.openhab.core.types.Command;
40 import org.openhab.core.util.HexUtils;
41
42 /**
43  * Test for RFXCom-binding
44  *
45  * @author Martin van Wingerden - Initial contribution
46  */
47 @NonNullByDefault
48 public class RFXComLighting4MessageTest {
49     static public final ChannelUID contactChannelUID = new ChannelUID(thingUID, CHANNEL_CONTACT);
50
51     static public void checkDiscoveryResult(RFXComDeviceMessage<RFXComLighting4Message.SubType> msg, String deviceId,
52             @Nullable Integer pulse, String subType) throws RFXComException {
53         String thingUID = "homeduino:rfxcom:fssfsd:thing";
54         DiscoveryResultBuilder builder = DiscoveryResultBuilder.create(new ThingUID(thingUID));
55
56         // check whether the pulse is stored
57         msg.addDevicePropertiesTo(builder);
58
59         Map<String, Object> properties = builder.build().getProperties();
60         assertEquals(deviceId, properties.get("deviceId"), "Device Id");
61         assertEquals(subType, properties.get("subType"), "Sub type");
62         if (pulse != null) {
63             assertEquals(pulse, properties.get("pulse"), "Pulse");
64         }
65     }
66
67     @Test
68     public void basicBoundaryCheck() throws RFXComException {
69         RFXComLighting4DeviceConfiguration config = new RFXComLighting4DeviceConfiguration();
70         config.deviceId = "90000";
71         config.subType = "PT2262";
72         config.pulse = 300;
73
74         RFXComLighting4Message message = (RFXComLighting4Message) RFXComMessageFactoryImpl.INSTANCE
75                 .createMessage(LIGHTING4, config, commandChannelUID, OnOffType.ON);
76
77         byte[] binaryMessage = message.decodeMessage();
78         RFXComLighting4Message msg = (RFXComLighting4Message) RFXComMessageFactoryImpl.INSTANCE
79                 .createMessage(binaryMessage);
80
81         assertEquals("90000", msg.getDeviceId(), "Sensor Id");
82     }
83
84     private void testMessageWithoutCommandIds(String hexMsg, RFXComLighting4Message.SubType subType, String deviceId,
85             @Nullable Integer pulse, int commandByte, @Nullable Integer seqNbr, int signalLevel, Command command)
86             throws RFXComException {
87         // These tests rely on the deprecated behaviour of a "known" set of ON/OFF values and will
88         // be removed in a later release to be replaced with test that check we throw an exception
89         // if the config isn't specified (see the open/closed tests).
90         RFXComLighting4DeviceConfiguration config = new RFXComLighting4DeviceConfiguration();
91         config.deviceId = deviceId;
92         config.subType = subType.toString();
93
94         RFXComLighting4Message msg = (RFXComLighting4Message) RFXComMessageFactoryImpl.INSTANCE
95                 .createMessage(HexUtils.hexToBytes(hexMsg));
96         assertEquals(deviceId, msg.getDeviceId(), "Sensor Id");
97         assertEquals(commandByte, RFXComTestHelper.getActualIntValue(msg, config, CHANNEL_COMMAND_ID), "Command");
98         if (seqNbr != null) {
99             assertEquals(seqNbr.shortValue(), (short) (msg.seqNbr & 0xFF), "Seq Number");
100         }
101         assertEquals(signalLevel, RFXComTestHelper.getActualIntValue(msg, config, CHANNEL_SIGNAL_LEVEL),
102                 "Signal Level");
103         assertEquals(command, msg.convertToCommand(CHANNEL_COMMAND, config, null));
104
105         byte[] decoded = msg.decodeMessage();
106
107         assertEquals(hexMsg, HexUtils.bytesToHex(decoded), "Message converted back");
108
109         checkDiscoveryResult(msg, deviceId, pulse, subType.toString());
110     }
111
112     @Test
113     public void testSomeMessages() throws RFXComException {
114         testMessageWithoutCommandIds("091300E1D8AD59018F70", PT2262, "887509", 399, 9, 225, 2, OnOffType.ON);
115         testMessageWithoutCommandIds("0913005FA9A9C901A170", PT2262, "694940", 417, 9, 95, 2, OnOffType.ON);
116         testMessageWithoutCommandIds("091300021D155C01E960", PT2262, "119125", 489, 12, 2, 2, OnOffType.ON);
117         testMessageWithoutCommandIds("091300D345DD99018C50", PT2262, "286169", 396, 9, 211, 2, OnOffType.ON);
118         testMessageWithoutCommandIds("09130035D149A2017750", PT2262, "857242", 375, 2, 53, 2, OnOffType.OFF);
119         testMessageWithoutCommandIds("0913000B4E462A012280", PT2262, "320610", 290, 10, 11, 3, OnOffType.ON);
120         testMessageWithoutCommandIds("09130009232D2E013970", PT2262, "144082", 313, 14, 9, 2, OnOffType.OFF);
121         testMessageWithoutCommandIds("091300CA0F8D2801AA70", PT2262, "63698", 426, 8, 202, 2, OnOffType.ON);
122     }
123
124     @Test
125     public void testSomeAlarmRemote() throws RFXComException {
126         testMessageWithoutCommandIds("0913004A0D8998016E60", PT2262, "55449", 366, 8, 74, 2, OnOffType.ON);
127     }
128
129     @Test
130     public void testCheapPirSensor() throws RFXComException {
131         testMessageWithoutCommandIds("091300EF505FC6019670", PT2262, "329212", 406, 6, 239, 2, OnOffType.ON);
132     }
133
134     @Test
135     public void testSomeConradMessages() throws RFXComException {
136         testMessageWithoutCommandIds("0913003554545401A150", PT2262, "345413", 417, 4, 53, 2, OnOffType.OFF);
137     }
138
139     @Test
140     public void testPhenixMessages() throws RFXComException {
141         List<String> onMessages = Arrays.asList("09130046044551013780", "09130048044551013780", "0913004A044551013980",
142                 "0913004C044551013780", "0913004E044551013780");
143
144         for (String message : onMessages) {
145             testMessageWithoutCommandIds(message, PT2262, "17493", null, 1, null, 3, OnOffType.ON);
146         }
147
148         List<String> offMessages = Arrays.asList("09130051044554013980", "09130053044554013680", "09130055044554013680",
149                 "09130057044554013680", "09130059044554013680", "0913005B044554013680", "0913005D044554013480",
150                 "09130060044554013980", "09130062044554013680", "09130064044554013280");
151
152         for (String message : offMessages) {
153             testMessageWithoutCommandIds(message, PT2262, "17493", null, 4, null, 3, OnOffType.OFF);
154         }
155     }
156
157     private void testRxWithConfig(String hexMsg, RFXComDeviceConfiguration config,
158             RFXComLighting4Message.SubType subType, String deviceId, @Nullable Integer pulse, int commandByte,
159             @Nullable Integer seqNbr, int signalLevel, ChannelUID channelUID, Command command) throws RFXComException {
160         RFXComLighting4Message msg = (RFXComLighting4Message) RFXComMessageFactoryImpl.INSTANCE
161                 .createMessage(HexUtils.hexToBytes(hexMsg));
162         assertEquals(deviceId, msg.getDeviceId(), "Sensor Id");
163         assertEquals(commandByte, RFXComTestHelper.getActualIntValue(msg, config, CHANNEL_COMMAND_ID), "Command");
164         if (seqNbr != null) {
165             assertEquals(seqNbr.shortValue(), (short) (msg.seqNbr & 0xFF), "Seq Number");
166         }
167         assertEquals(signalLevel, RFXComTestHelper.getActualIntValue(msg, config, CHANNEL_SIGNAL_LEVEL),
168                 "Signal Level");
169         assertEquals(command, msg.convertToCommand(channelUID.getId(), config, null));
170
171         byte[] decoded = msg.decodeMessage();
172
173         assertEquals(hexMsg, HexUtils.bytesToHex(decoded), "Message converted back");
174
175         checkDiscoveryResult(msg, deviceId, pulse, subType.toString());
176     }
177
178     @Test
179     public void testRxWithFullConfig() throws RFXComException {
180         RFXComLighting4DeviceConfiguration config = new RFXComLighting4DeviceConfiguration();
181         config.deviceId = "12345";
182         config.subType = PT2262.toString();
183         config.onCommandId = 0xA;
184         config.offCommandId = 0xB;
185         config.openCommandId = 0xC;
186         config.closedCommandId = 0xD;
187
188         testRxWithConfig("0913003503039A01A150", config, PT2262, "12345", 417, 0xA, 53, 2, commandChannelUID,
189                 OnOffType.ON);
190         testRxWithConfig("0913003503039B01A150", config, PT2262, "12345", 417, 0xB, 53, 2, commandChannelUID,
191                 OnOffType.OFF);
192         testRxWithConfig("0913003503039C01A150", config, PT2262, "12345", 417, 0xC, 53, 2, contactChannelUID,
193                 OpenClosedType.OPEN);
194         testRxWithConfig("0913003503039D01A150", config, PT2262, "12345", 417, 0xD, 53, 2, contactChannelUID,
195                 OpenClosedType.CLOSED);
196     }
197
198     @Test
199     public void testRxWithPartialConfig() throws RFXComException {
200         RFXComLighting4DeviceConfiguration config = new RFXComLighting4DeviceConfiguration();
201         config.deviceId = "12345";
202         config.subType = PT2262.toString();
203         config.onCommandId = 0xA;
204         config.openCommandId = 0xC;
205
206         testRxWithConfig("0913003503039A01A150", config, PT2262, "12345", 417, 0xA, 53, 2, commandChannelUID,
207                 OnOffType.ON);
208         assertThrows(RFXComInvalidStateException.class, () -> testRxWithConfig("0913003503039B01A150", config, PT2262,
209                 "12345", 417, 0xB, 53, 2, commandChannelUID, OnOffType.OFF));
210         testRxWithConfig("0913003503039C01A150", config, PT2262, "12345", 417, 0xC, 53, 2, contactChannelUID,
211                 OpenClosedType.OPEN);
212         assertThrows(RFXComInvalidStateException.class, () -> testRxWithConfig("0913003503039D01A150", config, PT2262,
213                 "12345", 417, 0xD, 53, 2, contactChannelUID, OpenClosedType.CLOSED));
214     }
215
216     @Test
217     public void testRxWithNoConfig() throws RFXComException {
218         RFXComLighting4DeviceConfiguration config = new RFXComLighting4DeviceConfiguration();
219         config.deviceId = "12345";
220         config.subType = PT2262.toString();
221
222         // These will fall back on deprecated behaviour, but should all be assertThrows in the future.
223         testRxWithConfig("0913003503039A01A150", config, PT2262, "12345", 417, 0xA, 53, 2, commandChannelUID,
224                 OnOffType.ON);
225         testRxWithConfig("0913003503039B01A150", config, PT2262, "12345", 417, 0xB, 53, 2, commandChannelUID,
226                 OnOffType.ON);
227         testRxWithConfig("0913003503039C01A150", config, PT2262, "12345", 417, 0xC, 53, 2, contactChannelUID,
228                 OpenClosedType.OPEN);
229         testRxWithConfig("0913003503039D01A150", config, PT2262, "12345", 417, 0xD, 53, 2, contactChannelUID,
230                 OpenClosedType.OPEN);
231     }
232
233     private void testTxWithConfig(RFXComDeviceConfiguration config, ChannelUID channelUID, Command command,
234             RFXComLighting4Message.SubType subType, String deviceId, @Nullable Integer pulse, int commandByte,
235             String hexMsg) throws RFXComException {
236         RFXComLighting4Message msg = (RFXComLighting4Message) RFXComMessageFactoryImpl.INSTANCE
237                 .createMessage(PacketType.LIGHTING4, config, channelUID, command);
238         assertEquals(deviceId, msg.getDeviceId(), "Sensor Id");
239         assertEquals(commandByte, RFXComTestHelper.getActualIntValue(msg, config, CHANNEL_COMMAND_ID), "Command");
240         assertEquals(0, msg.seqNbr & 0xFF, "Seq Number");
241         assertEquals(0, RFXComTestHelper.getActualIntValue(msg, config, CHANNEL_SIGNAL_LEVEL), "Signal Level");
242         assertEquals(hexMsg, HexUtils.bytesToHex(msg.decodeMessage()), "Message bytes");
243     }
244
245     @Test
246     void testTxWithFullConfig() throws RFXComException {
247         RFXComLighting4DeviceConfiguration config = new RFXComLighting4DeviceConfiguration();
248         config.deviceId = "703696";
249         config.subType = PT2262.toString();
250         config.onCommandId = 0xA;
251         config.offCommandId = 0xB;
252         config.openCommandId = 0xC;
253         config.closedCommandId = 0xD;
254         config.pulse = 417;
255
256         testTxWithConfig(config, commandChannelUID, OnOffType.ON, PT2262, "703696", 417, 0xA, "09130000ABCD0A01A100");
257         testTxWithConfig(config, commandChannelUID, OnOffType.OFF, PT2262, "703696", 417, 0xB, "09130000ABCD0B01A100");
258         testTxWithConfig(config, contactChannelUID, OpenClosedType.OPEN, PT2262, "703696", 417, 0xC,
259                 "09130000ABCD0C01A100");
260         testTxWithConfig(config, contactChannelUID, OpenClosedType.CLOSED, PT2262, "703696", 417, 0xD,
261                 "09130000ABCD0D01A100");
262     }
263
264     @Test
265     void testTxWithPartialConfig() throws RFXComException {
266         RFXComLighting4DeviceConfiguration config = new RFXComLighting4DeviceConfiguration();
267         config.deviceId = "703696";
268         config.subType = PT2262.toString();
269         config.onCommandId = 0xA;
270         config.openCommandId = 0xC;
271         config.pulse = 417;
272
273         testTxWithConfig(config, commandChannelUID, OnOffType.ON, PT2262, "703696", 417, 0xA, "09130000ABCD0A01A100");
274         // Falls back on deprecated behaviour, but should be assertThrows in the future.
275         testTxWithConfig(config, commandChannelUID, OnOffType.OFF, PT2262, "703696", 417, 0x4, "09130000ABCD0401A100");
276         testTxWithConfig(config, contactChannelUID, OpenClosedType.OPEN, PT2262, "703696", 417, 0xC,
277                 "09130000ABCD0C01A100");
278         assertThrows(RFXComInvalidStateException.class, () -> testTxWithConfig(config, contactChannelUID,
279                 OpenClosedType.CLOSED, PT2262, "703696", 417, 0xD, "??"));
280     }
281
282     @Test
283     void testTxWithNoConfig() throws RFXComException {
284         RFXComLighting4DeviceConfiguration config = new RFXComLighting4DeviceConfiguration();
285         config.deviceId = "703696";
286         config.subType = PT2262.toString();
287         config.pulse = 417;
288
289         // Falls back on deprecated behaviour, but should be assertThrows in the future.
290         testTxWithConfig(config, commandChannelUID, OnOffType.ON, PT2262, "703696", 417, 0x1, "09130000ABCD0101A100");
291         // Falls back on deprecated behaviour, but should be assertThrows in the future.
292         testTxWithConfig(config, commandChannelUID, OnOffType.OFF, PT2262, "703696", 417, 0x4, "09130000ABCD0401A100");
293         assertThrows(RFXComInvalidStateException.class, () -> testTxWithConfig(config, contactChannelUID,
294                 OpenClosedType.OPEN, PT2262, "703696", 417, 0xC, "??"));
295         assertThrows(RFXComInvalidStateException.class, () -> testTxWithConfig(config, contactChannelUID,
296                 OpenClosedType.CLOSED, PT2262, "703696", 417, 0xD, "??"));
297     }
298 }