]> git.basschouten.com Git - openhab-addons.git/blob
bb73b3d20ae0cfeee4267779b3b34ea3cd03d0d9
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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.neohub.test;
14
15 import static org.junit.jupiter.api.Assertions.*;
16 import static org.openhab.binding.neohub.internal.NeoHubBindingConstants.*;
17
18 import java.io.BufferedReader;
19 import java.io.FileReader;
20 import java.io.IOException;
21 import java.math.BigDecimal;
22 import java.time.Instant;
23
24 import org.eclipse.jdt.annotation.NonNullByDefault;
25 import org.junit.jupiter.api.Test;
26 import org.openhab.binding.neohub.internal.NeoHubAbstractDeviceData;
27 import org.openhab.binding.neohub.internal.NeoHubAbstractDeviceData.AbstractRecord;
28 import org.openhab.binding.neohub.internal.NeoHubGetEngineersData;
29 import org.openhab.binding.neohub.internal.NeoHubInfoResponse;
30 import org.openhab.binding.neohub.internal.NeoHubInfoResponse.InfoRecord;
31 import org.openhab.binding.neohub.internal.NeoHubLiveDeviceData;
32 import org.openhab.binding.neohub.internal.NeoHubReadDcbResponse;
33 import org.openhab.binding.neohub.internal.NeoHubSocket;
34 import org.openhab.core.library.unit.ImperialUnits;
35 import org.openhab.core.library.unit.SIUnits;
36
37 /**
38  * The {@link NeoHubTestData} class defines common constants, which are used
39  * across the whole binding.
40  *
41  * @author Andrew Fiddian-Green - Initial contribution
42  */
43 @NonNullByDefault
44 public class NeoHubTestData {
45
46     /*
47      * Load the test JSON payload string from a file
48      */
49     private String load(String fileName) {
50         try (FileReader file = new FileReader(String.format("src/test/resources/%s.json", fileName));
51                 BufferedReader reader = new BufferedReader(file)) {
52             StringBuilder builder = new StringBuilder();
53             String line;
54             while ((line = reader.readLine()) != null) {
55                 builder.append(line).append("\n");
56             }
57             return builder.toString();
58         } catch (IOException e) {
59             fail(e.getMessage());
60         }
61         return "";
62     }
63
64     /*
65      * Test an INFO JSON response string as produced by older firmware versions
66      */
67     @Test
68     public void testInfoJsonOld() {
69         // load INFO JSON response string in old JSON format
70         NeoHubAbstractDeviceData infoResponse = NeoHubInfoResponse.createDeviceData(load("info_old"));
71         assertNotNull(infoResponse);
72
73         // missing device
74         AbstractRecord device = infoResponse.getDeviceRecord("Aardvark");
75         assertNull(device);
76
77         // existing type 12 thermostat device
78         device = infoResponse.getDeviceRecord("Dining Room");
79         assertNotNull(device);
80         assertEquals("Dining Room", device.getDeviceName());
81         assertEquals(new BigDecimal("22.0"), device.getTargetTemperature());
82         assertEquals(new BigDecimal("22.2"), device.getActualTemperature());
83         assertEquals(new BigDecimal("23"), device.getFloorTemperature());
84         assertTrue(device instanceof InfoRecord);
85         assertEquals(12, ((InfoRecord) device).getDeviceType());
86         assertFalse(device.isStandby());
87         assertFalse(device.isHeating());
88         assertFalse(device.isPreHeating());
89         assertFalse(device.isTimerOn());
90         assertFalse(device.offline());
91         assertFalse(device.stateManual());
92         assertTrue(device.stateAuto());
93         assertFalse(device.isWindowOpen());
94         assertFalse(device.isBatteryLow());
95
96         // existing type 6 plug device (MANUAL OFF)
97         device = infoResponse.getDeviceRecord("Plug South");
98         assertNotNull(device);
99         assertEquals("Plug South", device.getDeviceName());
100         assertTrue(device instanceof InfoRecord);
101         assertEquals(6, ((InfoRecord) device).getDeviceType());
102         assertFalse(device.isTimerOn());
103         assertTrue(device.stateManual());
104
105         // existing type 6 plug device (MANUAL ON)
106         device = infoResponse.getDeviceRecord("Plug North");
107         assertNotNull(device);
108         assertEquals("Plug North", device.getDeviceName());
109         assertTrue(device instanceof InfoRecord);
110         assertEquals(6, ((InfoRecord) device).getDeviceType());
111         assertTrue(device.isTimerOn());
112         assertTrue(device.stateManual());
113
114         // existing type 6 plug device (AUTO OFF)
115         device = infoResponse.getDeviceRecord("Watering System");
116         assertNotNull(device);
117         assertEquals("Watering System", device.getDeviceName());
118         assertTrue(device instanceof InfoRecord);
119         assertEquals(6, ((InfoRecord) device).getDeviceType());
120         assertFalse(device.isTimerOn());
121         assertFalse(device.stateManual());
122     }
123
124     /*
125      * Test an INFO JSON response string as produced by newer firmware versions
126      */
127     @Test
128     public void testInfoJsonNew() {
129         // load INFO JSON response string in new JSON format
130         NeoHubAbstractDeviceData infoResponse = NeoHubInfoResponse.createDeviceData(load("info_new"));
131         assertNotNull(infoResponse);
132
133         // existing device (new JSON format)
134         AbstractRecord device = infoResponse.getDeviceRecord("Dining Room");
135         assertNotNull(device);
136         assertEquals("Dining Room", device.getDeviceName());
137         assertFalse(device.offline());
138         assertFalse(device.isWindowOpen());
139
140         // existing repeater device
141         device = infoResponse.getDeviceRecord("repeaternode54473");
142         assertNotNull(device);
143         assertEquals("repeaternode54473", device.getDeviceName());
144         assertEquals(new BigDecimal("127"), device.getFloorTemperature());
145         assertEquals(new BigDecimal("255.255"), device.getActualTemperature());
146     }
147
148     /*
149      * Test for a READ_DCB JSON string that has valid CORF C response
150      */
151     @Test
152     public void testReadDcbJson() {
153         // load READ_DCB JSON response string with valid CORF C response
154         NeoHubReadDcbResponse dcbResponse = NeoHubReadDcbResponse.createSystemData(load("dcb_celsius"));
155         assertNotNull(dcbResponse);
156         assertEquals(SIUnits.CELSIUS, dcbResponse.getTemperatureUnit());
157
158         // load READ_DCB JSON response string with valid CORF F response
159         dcbResponse = NeoHubReadDcbResponse.createSystemData(load("dcb_fahrenheit"));
160         assertNotNull(dcbResponse);
161         assertEquals(ImperialUnits.FAHRENHEIT, dcbResponse.getTemperatureUnit());
162
163         // load READ_DCB JSON response string with missing CORF element
164         dcbResponse = NeoHubReadDcbResponse.createSystemData(load("dcb_corf_missing"));
165         assertNotNull(dcbResponse);
166         assertEquals(SIUnits.CELSIUS, dcbResponse.getTemperatureUnit());
167
168         // load READ_DCB JSON response string where CORF element is an empty string
169         dcbResponse = NeoHubReadDcbResponse.createSystemData(load("dcb_corf_empty"));
170         assertNotNull(dcbResponse);
171         assertEquals(SIUnits.CELSIUS, dcbResponse.getTemperatureUnit());
172     }
173
174     /*
175      * Test an INFO JSON string that has a door contact and a temperature sensor
176      */
177     @Test
178     public void testInfoJsonWithSensors() {
179         /*
180          * load an INFO JSON response string that has a closed door contact and a
181          * temperature sensor
182          */
183         // save("info_sensors_closed", NEOHUB_JSON_TEST_STRING_INFO_SENSORS_CLOSED);
184         NeoHubAbstractDeviceData infoResponse = NeoHubInfoResponse.createDeviceData(load("info_sensors_closed"));
185         assertNotNull(infoResponse);
186
187         // existing contact device type 5 (CLOSED)
188         AbstractRecord device = infoResponse.getDeviceRecord("Back Door");
189         assertNotNull(device);
190         assertEquals("Back Door", device.getDeviceName());
191         assertTrue(device instanceof InfoRecord);
192         assertEquals(5, ((InfoRecord) device).getDeviceType());
193         assertFalse(device.isWindowOpen());
194         assertFalse(device.isBatteryLow());
195
196         // existing temperature sensor type 14
197         device = infoResponse.getDeviceRecord("Master Bedroom");
198         assertNotNull(device);
199         assertEquals("Master Bedroom", device.getDeviceName());
200         assertTrue(device instanceof InfoRecord);
201         assertEquals(14, ((InfoRecord) device).getDeviceType());
202         assertEquals(new BigDecimal("19.5"), device.getActualTemperature());
203
204         // existing thermostat type 1
205         device = infoResponse.getDeviceRecord("Living Room Floor");
206         assertNotNull(device);
207         assertEquals("Living Room Floor", device.getDeviceName());
208         assertTrue(device instanceof InfoRecord);
209         assertEquals(1, ((InfoRecord) device).getDeviceType());
210         assertEquals(new BigDecimal("19.8"), device.getActualTemperature());
211
212         // load an INFO JSON response string that has an open door contact
213         // save("info_sensors_open", NEOHUB_JSON_TEST_STRING_INFO_SENSORS_OPEN);
214         infoResponse = NeoHubInfoResponse.createDeviceData(load("info_sensors_open"));
215         assertNotNull(infoResponse);
216
217         // existing contact device type 5 (OPEN)
218         device = infoResponse.getDeviceRecord("Back Door");
219         assertNotNull(device);
220         assertEquals("Back Door", device.getDeviceName());
221         assertTrue(device instanceof InfoRecord);
222         assertEquals(5, ((InfoRecord) device).getDeviceType());
223         assertTrue(device.isWindowOpen());
224         assertTrue(device.isBatteryLow());
225     }
226
227     /*
228      * From NeoHub rev2.6 onwards the READ_DCB command is "deprecated" so we can
229      * also test the replacement GET_SYSTEM command (valid CORF response)
230      */
231     @Test
232     public void testGetSystemJson() {
233         // load GET_SYSTEM JSON response string
234         NeoHubReadDcbResponse dcbResponse;
235         dcbResponse = NeoHubReadDcbResponse.createSystemData(load("system"));
236         assertNotNull(dcbResponse);
237         assertEquals(SIUnits.CELSIUS, dcbResponse.getTemperatureUnit());
238     }
239
240     /*
241      * From NeoHub rev2.6 onwards the INFO command is "deprecated" so we must test
242      * the replacement GET_LIVE_DATA command
243      */
244     @Test
245     public void testGetLiveDataJson() {
246         // load GET_LIVE_DATA JSON response string
247         NeoHubLiveDeviceData liveDataResponse = NeoHubLiveDeviceData.createDeviceData(load("live_data"));
248         assertNotNull(liveDataResponse);
249
250         // test the time stamps
251         assertEquals(1588494785, liveDataResponse.getTimestampEngineers());
252         assertEquals(0, liveDataResponse.getTimestampSystem());
253
254         // missing device
255         AbstractRecord device = liveDataResponse.getDeviceRecord("Aardvark");
256         assertNull(device);
257
258         // test an existing thermostat device
259         device = liveDataResponse.getDeviceRecord("Dining Room");
260         assertNotNull(device);
261         assertEquals("Dining Room", device.getDeviceName());
262         assertEquals(new BigDecimal("22.0"), device.getTargetTemperature());
263         assertEquals(new BigDecimal("22.2"), device.getActualTemperature());
264         assertEquals(new BigDecimal("20.50"), device.getFloorTemperature());
265         assertFalse(device.isStandby());
266         assertFalse(device.isHeating());
267         assertFalse(device.isPreHeating());
268         assertFalse(device.isTimerOn());
269         assertFalse(device.offline());
270         assertFalse(device.stateManual());
271         assertTrue(device.stateAuto());
272         assertFalse(device.isWindowOpen());
273         assertFalse(device.isBatteryLow());
274
275         // test a plug device (MANUAL OFF)
276         device = liveDataResponse.getDeviceRecord("Living Room South");
277         assertNotNull(device);
278         assertEquals("Living Room South", device.getDeviceName());
279         assertFalse(device.isTimerOn());
280         assertTrue(device.stateManual());
281
282         // test a plug device (MANUAL ON)
283         device = liveDataResponse.getDeviceRecord("Living Room North");
284         assertNotNull(device);
285         assertEquals("Living Room North", device.getDeviceName());
286         assertTrue(device.isTimerOn());
287         assertTrue(device.stateManual());
288
289         // test a plug device (AUTO OFF)
290         device = liveDataResponse.getDeviceRecord("Green Wall Watering");
291         assertNotNull(device);
292         assertEquals("Green Wall Watering", device.getDeviceName());
293         assertFalse(device.isTimerOn());
294         assertFalse(device.stateManual());
295
296         // test a device that is offline
297         device = liveDataResponse.getDeviceRecord("Shower Room");
298         assertNotNull(device);
299         assertEquals("Shower Room", device.getDeviceName());
300         assertTrue(device.offline());
301
302         // test a device with a low battery
303         device = liveDataResponse.getDeviceRecord("Conservatory");
304         assertNotNull(device);
305         assertEquals("Conservatory", device.getDeviceName());
306         assertTrue(device.isBatteryLow());
307
308         // test a device with an open window alarm
309         device = liveDataResponse.getDeviceRecord("Door Contact");
310         assertNotNull(device);
311         assertEquals("Door Contact", device.getDeviceName());
312         assertTrue(device.isWindowOpen());
313
314         // test a wireless temperature sensor
315         device = liveDataResponse.getDeviceRecord("Room Sensor");
316         assertNotNull(device);
317         assertEquals("Room Sensor", device.getDeviceName());
318         assertEquals(new BigDecimal("21.5"), device.getActualTemperature());
319
320         // test a repeater node
321         device = liveDataResponse.getDeviceRecord("repeaternode54473");
322         assertNotNull(device);
323         assertEquals("repeaternode54473", device.getDeviceName());
324         assertTrue(MATCHER_HEATMISER_REPEATER.matcher(device.getDeviceName()).matches());
325     }
326
327     /*
328      * From NeoHub rev2.6 onwards the INFO command is "deprecated" and the DEVICE_ID
329      * element is not returned in the GET_LIVE_DATA call so we must test the
330      * replacement GET_ENGINEERS command
331      */
332     @Test
333     public void testGetEngineersJson() {
334         // load GET_ENGINEERS JSON response string
335         NeoHubGetEngineersData engResponse = NeoHubGetEngineersData.createEngineersData(load("engineers"));
336         assertNotNull(engResponse);
337
338         // test device ID (type 12 thermostat device)
339         assertEquals(12, engResponse.getDeviceType("Dining Room"));
340
341         // test device ID (type 6 plug device)
342         assertEquals(6, engResponse.getDeviceType("Living Room South"));
343     }
344
345     /*
346      * send JSON request to the socket and retrieve JSON response
347      */
348     private String testCommunicationInner(String requestJson) {
349         NeoHubSocket socket = new NeoHubSocket("192.168.1.109", 4242, 5);
350         String responseJson = "";
351         try {
352             responseJson = socket.sendMessage(requestJson);
353         } catch (Exception e) {
354             assertTrue(false);
355         }
356         return responseJson;
357     }
358
359     /*
360      * Test the communications
361      */
362     @Test
363     public void testCommunications() {
364         String responseJson = testCommunicationInner(CMD_CODE_INFO);
365         assertFalse(responseJson.isEmpty());
366
367         responseJson = testCommunicationInner(CMD_CODE_READ_DCB);
368         assertFalse(responseJson.isEmpty());
369
370         NeoHubReadDcbResponse dcbResponse = NeoHubReadDcbResponse.createSystemData(responseJson);
371         assertNotNull(dcbResponse);
372
373         long timeStamp = dcbResponse.timeStamp;
374         assertEquals(Instant.now().getEpochSecond(), timeStamp, 1);
375
376         responseJson = testCommunicationInner(CMD_CODE_GET_LIVE_DATA);
377         assertFalse(responseJson.isEmpty());
378
379         NeoHubLiveDeviceData liveDataResponse = NeoHubLiveDeviceData.createDeviceData(responseJson);
380         assertNotNull(liveDataResponse);
381
382         assertTrue(timeStamp > liveDataResponse.getTimestampEngineers());
383         assertTrue(timeStamp > liveDataResponse.getTimestampSystem());
384
385         responseJson = testCommunicationInner(CMD_CODE_GET_ENGINEERS);
386         assertFalse(responseJson.isEmpty());
387
388         responseJson = testCommunicationInner(CMD_CODE_GET_SYSTEM);
389         assertFalse(responseJson.isEmpty());
390
391         responseJson = testCommunicationInner(String.format(CMD_CODE_TEMP, "20", "Hallway"));
392         assertFalse(responseJson.isEmpty());
393     }
394 }