]> git.basschouten.com Git - openhab-addons.git/blob
0c550479f75851e6860e7852b20d870cb5561059
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 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.fineoffsetweatherstation.internal.service;
14
15 import java.time.ZoneOffset;
16 import java.util.List;
17
18 import org.assertj.core.api.Assertions;
19 import org.assertj.core.groups.Tuple;
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.junit.jupiter.api.Test;
22 import org.openhab.binding.fineoffsetweatherstation.internal.domain.Command;
23 import org.openhab.binding.fineoffsetweatherstation.internal.domain.ConversionContext;
24 import org.openhab.binding.fineoffsetweatherstation.internal.domain.DebugDetails;
25 import org.openhab.binding.fineoffsetweatherstation.internal.domain.Protocol;
26 import org.openhab.binding.fineoffsetweatherstation.internal.domain.response.MeasuredValue;
27 import org.openhab.core.util.HexUtils;
28
29 /**
30  * @author Andreas Berger - Initial contribution
31  */
32 @NonNullByDefault
33 class FineOffsetDataParserTest {
34     @Test
35     void testLiveDataWH45() {
36         byte[] bytes = HexUtils.hexToBytes(
37                 "FFFF2700510100D306280827EF0927EF020045074F0A00150B00000C0000150000000016000117001900000E0000100000110021120000002113000005850D00007000D12E0060005A005B005502AE028F0633");
38         DebugDetails debugDetails = new DebugDetails(bytes, Command.CMD_GW1000_LIVEDATA, Protocol.DEFAULT);
39         List<MeasuredValue> data = new FineOffsetDataParser(Protocol.DEFAULT).getMeasuredValues(bytes,
40                 new ConversionContext(ZoneOffset.UTC), debugDetails);
41         Assertions.assertThat(data)
42                 .extracting(MeasuredValue::getChannelId, measuredValue -> measuredValue.getState().toString())
43                 .containsExactly(new Tuple("temperature-indoor", "21.1 °C"), new Tuple("humidity-indoor", "40 %"),
44                         new Tuple("pressure-absolute", "1022.3 hPa"), new Tuple("pressure-relative", "1022.3 hPa"),
45                         new Tuple("temperature-outdoor", "6.9 °C"), new Tuple("humidity-outdoor", "79 %"),
46                         new Tuple("direction-wind", "21 °"), new Tuple("speed-wind", "0 m/s"),
47                         new Tuple("speed-gust", "0 m/s"), new Tuple("illumination", "0 lx"),
48                         new Tuple("irradiation-uv", "0.1 mW/m²"), new Tuple("uv-index", "0"),
49                         new Tuple("wind-max-day", "0 m/s"), new Tuple("rain-rate", "0 mm/h"),
50                         new Tuple("rain-day", "0 mm"), new Tuple("rain-week", "3.3 mm"),
51                         new Tuple("rain-month", "3.3 mm"), new Tuple("rain-year", "141.3 mm"),
52                         new Tuple("rain-event", "0 mm"), new Tuple("sensor-co2-temperature", "20.9 °C"),
53                         new Tuple("sensor-co2-humidity", "46 %"), new Tuple("sensor-co2-pm10", "9.6 µg/m³"),
54                         new Tuple("sensor-co2-pm10-24-hour-average", "9 µg/m³"),
55                         new Tuple("sensor-co2-pm25", "9.1 µg/m³"),
56                         new Tuple("sensor-co2-pm25-24-hour-average", "8.5 µg/m³"),
57                         new Tuple("sensor-co2-co2", "686 ppm"), new Tuple("sensor-co2-co2-24-hour-average", "655 ppm"));
58     }
59
60     @Test
61     void testLiveDataWithManySensors() {
62         byte[] bytes = HexUtils.hexToBytes(
63                 "FFFF27007B0100D206240826CC0926CC02004907450A00760B00160C001F150001C00C16000017002A00144D00372C381A0085223E1B00A72333580059005A00620000000061FFFFFFFF60FF1900380E000010002D1100A012000000A013000000A00D009F63004D417000CF2C00250020001B0018020B021E06722164");
64         DebugDetails debugDetails = new DebugDetails(bytes, Command.CMD_GW1000_LIVEDATA, Protocol.DEFAULT);
65         List<MeasuredValue> data = new FineOffsetDataParser(Protocol.DEFAULT).getMeasuredValues(bytes,
66                 new ConversionContext(ZoneOffset.UTC), debugDetails);
67         Assertions.assertThat(data)
68                 .extracting(MeasuredValue::getChannelId, measuredValue -> measuredValue.getState().toString())
69                 .containsExactly(new Tuple("temperature-indoor", "21 °C"), new Tuple("humidity-indoor", "36 %"),
70                         new Tuple("pressure-absolute", "993.2 hPa"), new Tuple("pressure-relative", "993.2 hPa"),
71                         new Tuple("temperature-outdoor", "7.3 °C"), new Tuple("humidity-outdoor", "69 %"),
72                         new Tuple("direction-wind", "118 °"), new Tuple("speed-wind", "2.2 m/s"),
73                         new Tuple("speed-gust", "3.1 m/s"), new Tuple("illumination", "11470 lx"),
74                         new Tuple("irradiation-uv", "0 mW/m²"), new Tuple("uv-index", "0"),
75                         new Tuple("air-quality-channel-1", "2 µg/m³"),
76                         new Tuple("air-quality-24-hour-average-channel-1", "5.5 µg/m³"),
77                         new Tuple("moisture-soil-channel-1", "56 %"), new Tuple("temperature-channel-1", "13.3 °C"),
78                         new Tuple("humidity-channel-1", "62 %"), new Tuple("temperature-channel-2", "16.7 °C"),
79                         new Tuple("humidity-channel-2", "51 %"), new Tuple("water-leak-channel-1", "OFF"),
80                         new Tuple("water-leak-channel-2", "OFF"), new Tuple("water-leak-channel-3", "OFF"),
81                         new Tuple("lightning-counter", "0"), new Tuple("lightning-time", "UNDEF"),
82                         new Tuple("lightning-distance", "UNDEF"), new Tuple("wind-max-day", "5.6 m/s"),
83                         new Tuple("rain-rate", "0 mm/h"), new Tuple("rain-day", "4.5 mm"),
84                         new Tuple("rain-week", "16 mm"), new Tuple("rain-month", "16 mm"),
85                         new Tuple("rain-year", "16 mm"), new Tuple("rain-event", "15.9 mm"),
86                         new Tuple("temperature-external-channel-1", "7.7 °C"),
87                         new Tuple("sensor-co2-temperature", "20.7 °C"), new Tuple("sensor-co2-humidity", "44 %"),
88                         new Tuple("sensor-co2-pm10", "3.7 µg/m³"),
89                         new Tuple("sensor-co2-pm10-24-hour-average", "3.2 µg/m³"),
90                         new Tuple("sensor-co2-pm25", "2.7 µg/m³"),
91                         new Tuple("sensor-co2-pm25-24-hour-average", "2.4 µg/m³"),
92                         new Tuple("sensor-co2-co2", "523 ppm"), new Tuple("sensor-co2-co2-24-hour-average", "542 ppm"),
93                         new Tuple("leaf-wetness-channel-1", "33 %"));
94     }
95
96     @Test
97     void testLiveDataWH34AndWh45() {
98         byte[] bytes = HexUtils.hexToBytes(
99                 "FFFF2700540100CA063E0826EC0926EC02007A074C0A002F0B001F0C0023150000032016000017001A0086225558005A00620000000661654A5AF1601B1900266300884B7000CE3F001D00240016001E041A037B0695");
100         DebugDetails debugDetails = new DebugDetails(bytes, Command.CMD_GW1000_LIVEDATA, Protocol.DEFAULT);
101         List<MeasuredValue> data = new FineOffsetDataParser(Protocol.DEFAULT).getMeasuredValues(bytes,
102                 new ConversionContext(ZoneOffset.UTC), debugDetails);
103         Assertions.assertThat(data)
104                 .extracting(MeasuredValue::getChannelId, measuredValue -> measuredValue.getState().toString())
105                 .containsExactly(new Tuple("temperature-indoor", "20.2 °C"), new Tuple("humidity-indoor", "62 %"),
106                         new Tuple("pressure-absolute", "996.4 hPa"), new Tuple("pressure-relative", "996.4 hPa"),
107                         new Tuple("temperature-outdoor", "12.2 °C"), new Tuple("humidity-outdoor", "76 %"),
108                         new Tuple("direction-wind", "47 °"), new Tuple("speed-wind", "3.1 m/s"),
109                         new Tuple("speed-gust", "3.5 m/s"), new Tuple("illumination", "80 lx"),
110                         new Tuple("irradiation-uv", "0 mW/m²"), new Tuple("uv-index", "0"),
111                         new Tuple("temperature-channel-1", "13.4 °C"), new Tuple("humidity-channel-1", "85 %"),
112                         new Tuple("water-leak-channel-1", "OFF"), new Tuple("water-leak-channel-3", "OFF"),
113                         new Tuple("lightning-counter", "6"),
114                         new Tuple("lightning-time", "2023-11-07T15:42:41.000+0000"),
115                         new Tuple("lightning-distance", "27 km"), new Tuple("wind-max-day", "3.8 m/s"),
116                         new Tuple("temperature-external-channel-1", "13.6 °C"),
117                         new Tuple("sensor-co2-temperature", "20.6 °C"), new Tuple("sensor-co2-humidity", "63 %"),
118                         new Tuple("sensor-co2-pm10", "2.9 µg/m³"),
119                         new Tuple("sensor-co2-pm10-24-hour-average", "3.6 µg/m³"),
120                         new Tuple("sensor-co2-pm25", "2.2 µg/m³"),
121                         new Tuple("sensor-co2-pm25-24-hour-average", "3 µg/m³"),
122                         new Tuple("sensor-co2-co2", "1050 ppm"),
123                         new Tuple("sensor-co2-co2-24-hour-average", "891 ppm"));
124     }
125
126     @Test
127     void testLiveDataELV() {
128         byte[] data = HexUtils.hexToBytes(
129                 "FFFF0B00500401010B0201120300620401120501120629072108254B09254B0A01480B00040C000A0E000000001000000021110000002E120000014F130000100714000012FD15000B4BB816086917056D35");
130         DebugDetails debugDetails = new DebugDetails(data, Command.CMD_WS980_LIVEDATA, Protocol.ELV);
131         List<MeasuredValue> measuredValues = new FineOffsetDataParser(Protocol.ELV).getMeasuredValues(data,
132                 new ConversionContext(ZoneOffset.UTC), debugDetails);
133         Assertions.assertThat(measuredValues)
134                 .extracting(MeasuredValue::getChannelId, measuredValue -> measuredValue.getState().toString())
135                 .containsExactly(new Tuple("temperature-indoor", "26.7 °C"),
136                         new Tuple("temperature-outdoor", "27.4 °C"), new Tuple("temperature-dew-point", "9.8 °C"),
137                         new Tuple("temperature-wind-chill", "27.4 °C"), new Tuple("temperature-heat-index", "27.4 °C"),
138                         new Tuple("humidity-indoor", "41 %"), new Tuple("humidity-outdoor", "33 %"),
139                         new Tuple("pressure-absolute", "954.7 hPa"), new Tuple("pressure-relative", "954.7 hPa"),
140                         new Tuple("direction-wind", "328 °"), new Tuple("speed-wind", "0.4 m/s"),
141                         new Tuple("speed-gust", "1 m/s"), new Tuple("rain-rate", "0 mm/h"),
142                         new Tuple("rain-day", "3.3 mm"), new Tuple("rain-week", "4.6 mm"),
143                         new Tuple("rain-month", "33.5 mm"), new Tuple("rain-year", "410.3 mm"),
144                         new Tuple("rain-total", "486.1 mm"), new Tuple("illumination", "74028 lx"),
145                         new Tuple("irradiation-uv", "215.3 mW/m²"), new Tuple("uv-index", "5"));
146     }
147
148     @Test
149     void testRainData() {
150         byte[] data = HexUtils
151                 .hexToBytes("FFFF5700290E000010000000001100000024120000003113000005030D00000F0064880000017A017B0030");
152         DebugDetails debugDetails = new DebugDetails(data, Command.CMD_READ_RAIN, Protocol.DEFAULT);
153         List<MeasuredValue> measuredValues = new FineOffsetDataParser(Protocol.DEFAULT).getRainData(data,
154                 new ConversionContext(ZoneOffset.UTC), debugDetails);
155         Assertions.assertThat(measuredValues)
156                 .extracting(MeasuredValue::getChannelId, measuredValue -> measuredValue.getState().toString())
157                 .containsExactly(new Tuple("rain-rate", "0 mm/h"), new Tuple("rain-day", "0 mm"),
158                         new Tuple("rain-week", "3.6 mm"), new Tuple("rain-month", "4.9 mm"),
159                         new Tuple("rain-year", "128.3 mm"), new Tuple("rain-event", "0 mm"),
160                         new Tuple("rain-hour", "10 mm"));
161     }
162
163     @Test
164     void testRainDataW90() {
165         byte[] data = HexUtils.hexToBytes(
166                 "FFFF5700398000008300000009840000000985000000C786000000C7810000870064006400640064006400640064006400640064880900007A02BF");
167         Assertions.assertThat(Command.CMD_READ_RAIN.isResponseValid(data)).isTrue();
168         DebugDetails debugDetails = new DebugDetails(data, Command.CMD_READ_RAIN, Protocol.DEFAULT);
169         List<MeasuredValue> measuredValues = new FineOffsetDataParser(Protocol.DEFAULT).getRainData(data,
170                 new ConversionContext(ZoneOffset.UTC), debugDetails);
171         Assertions.assertThat(measuredValues)
172                 .extracting(MeasuredValue::getChannelId, measuredValue -> measuredValue.getState().toString())
173                 .containsExactly(new Tuple("piezo-rain-rate", "0 mm/h"), new Tuple("piezo-rain-day", "0.9 mm"),
174                         new Tuple("piezo-rain-week", "0.9 mm"), new Tuple("piezo-rain-month", "19.9 mm"),
175                         new Tuple("piezo-rain-year", "19.9 mm"), new Tuple("piezo-rain-event", "0 mm"));
176     }
177
178     @Test
179     void testFirmware() {
180         byte[] data = HexUtils.hexToBytes("FFFF501511456173795765617468657256312E362E3400");
181         String firmware = new FineOffsetDataParser(Protocol.ELV).getFirmwareVersion(data);
182         Assertions.assertThat(firmware).isEqualTo("EasyWeatherV1.6.4");
183     }
184 }