]> git.basschouten.com Git - openhab-addons.git/blob
21a9046b0e047e91386d490e2051907e04502d39
[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.mqtt.generic.values;
14
15 import static org.hamcrest.CoreMatchers.is;
16 import static org.hamcrest.MatcherAssert.assertThat;
17 import static org.junit.jupiter.api.Assertions.*;
18
19 import java.math.BigDecimal;
20 import java.util.Objects;
21
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.junit.jupiter.api.Test;
24 import org.openhab.binding.mqtt.generic.mapping.ColorMode;
25 import org.openhab.core.library.types.DecimalType;
26 import org.openhab.core.library.types.HSBType;
27 import org.openhab.core.library.types.IncreaseDecreaseType;
28 import org.openhab.core.library.types.OnOffType;
29 import org.openhab.core.library.types.OpenClosedType;
30 import org.openhab.core.library.types.PercentType;
31 import org.openhab.core.library.types.QuantityType;
32 import org.openhab.core.library.types.StopMoveType;
33 import org.openhab.core.library.types.StringType;
34 import org.openhab.core.library.types.UpDownType;
35 import org.openhab.core.library.unit.MetricPrefix;
36 import org.openhab.core.library.unit.Units;
37 import org.openhab.core.types.Command;
38 import org.openhab.core.types.TypeParser;
39 import org.openhab.core.types.UnDefType;
40
41 /**
42  * Test cases for the value classes. They should throw exceptions if the wrong command type is used
43  * for an update. The percent value class should raise an exception if the value is out of range.
44  *
45  * The on/off value class should accept a multitude of values including the custom defined ones.
46  *
47  * The string value class states are tested.
48  *
49  * @author David Graeff - Initial contribution
50  */
51 @NonNullByDefault
52 public class ValueTests {
53     private Command p(Value v, String str) {
54         return Objects.requireNonNull(TypeParser.parseCommand(v.getSupportedCommandTypes(), str));
55     }
56
57     @Test
58     public void illegalTextStateUpdate() {
59         TextValue v = new TextValue("one,two".split(","));
60         assertThrows(IllegalArgumentException.class, () -> v.parseCommand(p(v, "three")));
61     }
62
63     @Test
64     public void textStateUpdate() {
65         TextValue v = new TextValue("one,two".split(","));
66         v.parseCommand(p(v, "one"));
67     }
68
69     @Test
70     public void colorUpdate() {
71         ColorValue v = new ColorValue(ColorMode.RGB, "fancyON", "fancyOFF", 77);
72         v.update(v.parseCommand(p(v, "255,255,255")));
73
74         HSBType hsb = v.parseCommand(p(v, "OFF"));
75         assertThat(hsb.getBrightness().intValue(), is(0));
76         v.update(hsb);
77         hsb = v.parseCommand(p(v, "ON"));
78         assertThat(hsb.getBrightness().intValue(), is(77));
79
80         hsb = v.parseCommand(p(v, "0"));
81         assertThat(hsb.getBrightness().intValue(), is(0));
82         hsb = v.parseCommand(p(v, "1"));
83         assertThat(hsb.getBrightness().intValue(), is(1));
84
85         assertThat(v.parseMessage(new StringType("")), is(UnDefType.NULL));
86     }
87
88     @Test
89     public void illegalColorUpdate() {
90         ColorValue v = new ColorValue(ColorMode.RGB, null, null, 10);
91         assertThrows(IllegalArgumentException.class, () -> v.parseCommand(p(v, "255,255,abc")));
92     }
93
94     @Test
95     public void illegalNumberCommand() {
96         NumberValue v = new NumberValue(null, null, null, null);
97         assertThrows(IllegalArgumentException.class, () -> v.parseCommand(OnOffType.OFF));
98     }
99
100     @Test
101     public void illegalPercentCommand() {
102         PercentageValue v = new PercentageValue(null, null, null, null, null);
103         assertThrows(IllegalStateException.class, () -> v.parseCommand(new StringType("demo")));
104     }
105
106     @Test
107     public void illegalOnOffCommand() {
108         OnOffValue v = new OnOffValue(null, null);
109         assertThrows(IllegalArgumentException.class, () -> v.parseCommand(new DecimalType(101.0)));
110     }
111
112     @Test
113     public void illegalPercentUpdate() {
114         PercentageValue v = new PercentageValue(null, null, null, null, null);
115         assertThrows(IllegalArgumentException.class, () -> v.parseCommand(new DecimalType(101.0)));
116     }
117
118     @Test
119     public void onoffUpdate() {
120         OnOffValue v = new OnOffValue("fancyON", "fancyOff");
121
122         // Test with command
123         assertThat(v.parseCommand(OnOffType.OFF), is(OnOffType.OFF));
124         assertThat(v.parseCommand(OnOffType.ON), is(OnOffType.ON));
125
126         // Test with string, representing the command
127         assertThat(v.parseCommand(new StringType("OFF")), is(OnOffType.OFF));
128         assertThat(v.parseCommand(new StringType("ON")), is(OnOffType.ON));
129
130         // Test with custom string, setup in the constructor
131         assertThat(v.parseCommand(new StringType("fancyOff")), is(OnOffType.OFF));
132         assertThat(v.parseCommand(new StringType("fancyON")), is(OnOffType.ON));
133
134         // Test basic formatting
135         assertThat(v.getMQTTpublishValue(OnOffType.ON, null), is("fancyON"));
136         assertThat(v.getMQTTpublishValue(OnOffType.OFF, null), is("fancyOff"));
137
138         // Test custom formatting
139         assertThat(v.getMQTTpublishValue(OnOffType.OFF, "=%s"), is("=fancyOff"));
140         assertThat(v.getMQTTpublishValue(OnOffType.ON, "=%s"), is("=fancyON"));
141
142         assertThat(v.parseMessage(new StringType("")), is(UnDefType.NULL));
143     }
144
145     @Test
146     public void onoffMultiStates() {
147         OnOffValue v = new OnOffValue(new String[] { "LOCKED" }, new String[] { "UNLOCKED", "JAMMED" }, "LOCK",
148                 "UNLOCK");
149
150         assertThat(v.parseCommand(new StringType("LOCKED")), is(OnOffType.ON));
151         assertThat(v.parseCommand(new StringType("UNLOCKED")), is(OnOffType.OFF));
152         assertThat(v.parseCommand(new StringType("JAMMED")), is(OnOffType.OFF));
153     }
154
155     @Test
156     public void openCloseUpdate() {
157         OpenCloseValue v = new OpenCloseValue("fancyON", "fancyOff");
158
159         // Test with command
160         assertThat(v.parseCommand(OpenClosedType.CLOSED), is(OpenClosedType.CLOSED));
161         assertThat(v.parseCommand(OpenClosedType.OPEN), is(OpenClosedType.OPEN));
162
163         // Test with string, representing the command
164         assertThat(v.parseCommand(new StringType("CLOSED")), is(OpenClosedType.CLOSED));
165         assertThat(v.parseCommand(new StringType("OPEN")), is(OpenClosedType.OPEN));
166
167         // Test with custom string, setup in the constructor
168         assertThat(v.parseCommand(new StringType("fancyOff")), is(OpenClosedType.CLOSED));
169         assertThat(v.parseCommand(new StringType("fancyON")), is(OpenClosedType.OPEN));
170
171         // Test basic formatting
172         assertThat(v.getMQTTpublishValue(OpenClosedType.CLOSED, null), is("fancyOff"));
173         assertThat(v.getMQTTpublishValue(OpenClosedType.OPEN, null), is("fancyON"));
174
175         assertThat(v.parseMessage(new StringType("")), is(UnDefType.NULL));
176     }
177
178     @Test
179     public void numberUpdate() {
180         NumberValue v = new NumberValue(null, null, new BigDecimal(10), Units.WATT);
181
182         // Test with command with units
183         Command command = v.parseCommand(new QuantityType<>(20, Units.WATT));
184         assertThat(command, is(new QuantityType<>(20, Units.WATT)));
185         assertThat(v.getMQTTpublishValue(command, null), is("20"));
186         command = v.parseCommand(new QuantityType<>(20, MetricPrefix.KILO(Units.WATT)));
187         assertThat(command, is(new QuantityType<>(20, MetricPrefix.KILO(Units.WATT))));
188         assertThat(v.getMQTTpublishValue(command, null), is("20000"));
189
190         // Test with command without units
191         command = v.parseCommand(new QuantityType<>("20"));
192         assertThat(command, is(new QuantityType<>(20, Units.WATT)));
193         assertThat(v.getMQTTpublishValue(command, null), is("20"));
194
195         assertThat(v.parseMessage(new StringType("NaN")), is(UnDefType.UNDEF));
196         assertThat(v.parseMessage(new StringType("nan")), is(UnDefType.UNDEF));
197         assertThat(v.parseMessage(new StringType("-NaN")), is(UnDefType.UNDEF));
198         assertThat(v.parseMessage(new StringType("-nan")), is(UnDefType.UNDEF));
199
200         assertThat(v.parseMessage(new StringType("")), is(UnDefType.NULL));
201     }
202
203     @Test
204     public void numberUpdateMireds() {
205         NumberValue v = new NumberValue(null, null, new BigDecimal(10), Units.MIRED);
206
207         Command command = v.parseCommand(new QuantityType<>(2700, Units.KELVIN));
208         assertThat(v.getMQTTpublishValue(command, "%.0f"), is("370"));
209     }
210
211     @Test
212     public void numberPercentageUpdate() {
213         NumberValue v = new NumberValue(null, null, new BigDecimal(10), Units.PERCENT);
214
215         // Test with command with units
216         Command command = v.parseCommand(new QuantityType<>(20, Units.PERCENT));
217         assertThat(command, is(new QuantityType<>(20, Units.PERCENT)));
218         assertThat(v.getMQTTpublishValue(command, null), is("20"));
219
220         // Test with command with units.ONE
221         command = v.parseCommand(new QuantityType<>("0.2"));
222         assertThat(command, is(new QuantityType<>(20, Units.PERCENT)));
223         assertThat(v.getMQTTpublishValue(command, null), is("20"));
224
225         // Test with command with DecimalType
226         command = v.parseCommand(new DecimalType(20));
227         assertThat(command, is(new QuantityType<>(20, Units.PERCENT)));
228         assertThat(v.getMQTTpublishValue(command, null), is("20"));
229     }
230
231     @Test
232     public void rollershutterUpdateWithStrings() {
233         RollershutterValue v = new RollershutterValue("fancyON", "fancyOff", "fancyStop");
234         // Test with UP/DOWN/STOP command
235         assertThat(v.parseCommand(UpDownType.UP), is(UpDownType.UP));
236         assertThat(v.getMQTTpublishValue(UpDownType.UP, null), is("fancyON"));
237         assertThat(v.parseCommand(UpDownType.DOWN), is(UpDownType.DOWN));
238         assertThat(v.getMQTTpublishValue(UpDownType.DOWN, null), is("fancyOff"));
239         assertThat(v.parseCommand(StopMoveType.STOP), is(StopMoveType.STOP));
240         assertThat(v.getMQTTpublishValue(StopMoveType.STOP, null), is("fancyStop"));
241
242         // Test with custom string
243         assertThat(v.parseCommand(new StringType("fancyON")), is(UpDownType.UP));
244         assertThat(v.parseCommand(new StringType("fancyOff")), is(UpDownType.DOWN));
245
246         // Test with exact percent
247         Command command = new PercentType(27);
248         assertThat(v.parseCommand(command), is(command));
249         assertThat(v.getMQTTpublishValue(command, null), is("27"));
250
251         // Test formatting 0/100
252         assertThat(v.getMQTTpublishValue(PercentType.ZERO, null), is("fancyON"));
253         assertThat(v.getMQTTpublishValue(PercentType.HUNDRED, null), is("fancyOff"));
254
255         // Test parsing from MQTT
256         assertThat(v.parseMessage(new StringType("fancyON")), is(UpDownType.UP));
257         assertThat(v.parseMessage(new StringType("fancyOff")), is(UpDownType.DOWN));
258
259         assertThat(v.parseMessage(new StringType("")), is(UnDefType.NULL));
260     }
261
262     @Test
263     public void rollershutterUpdateWithDiscreteCommandAndStateStrings() {
264         RollershutterValue v = new RollershutterValue("OPEN", "CLOSE", "STOP", "open", "closed", false, true);
265         // Test with UP/DOWN/STOP command
266         assertThat(v.parseCommand(UpDownType.UP), is(UpDownType.UP));
267         assertThat(v.getMQTTpublishValue(UpDownType.UP, null), is("OPEN"));
268         assertThat(v.parseCommand(UpDownType.DOWN), is(UpDownType.DOWN));
269         assertThat(v.getMQTTpublishValue(UpDownType.DOWN, null), is("CLOSE"));
270         assertThat(v.parseCommand(StopMoveType.STOP), is(StopMoveType.STOP));
271         assertThat(v.getMQTTpublishValue(StopMoveType.STOP, null), is("STOP"));
272
273         // Test with custom string
274         assertThat(v.parseCommand(new StringType("OPEN")), is(UpDownType.UP));
275         assertThat(v.parseCommand(new StringType("CLOSE")), is(UpDownType.DOWN));
276
277         // Test with exact percent
278         Command command = new PercentType(27);
279         assertThat(v.parseCommand(command), is(command));
280         assertThat(v.getMQTTpublishValue(command, null), is("27"));
281
282         // Test formatting 0/100
283         assertThat(v.getMQTTpublishValue(PercentType.ZERO, null), is("OPEN"));
284         assertThat(v.getMQTTpublishValue(PercentType.HUNDRED, null), is("CLOSE"));
285
286         // Test parsing from MQTT
287         assertThat(v.parseMessage(new StringType("open")), is(UpDownType.UP));
288         assertThat(v.parseMessage(new StringType("closed")), is(UpDownType.DOWN));
289     }
290
291     @Test
292     public void rollershutterUpdateWithOutStrings() {
293         RollershutterValue v = new RollershutterValue(null, null, "fancyStop");
294         // Test with command
295         assertThat(v.parseCommand(UpDownType.UP), is(PercentType.ZERO));
296         assertThat(v.parseCommand(UpDownType.DOWN), is(PercentType.HUNDRED));
297
298         // Test with custom string
299         // Test formatting 0/100
300         assertThat(v.getMQTTpublishValue(PercentType.ZERO, null), is("0"));
301         assertThat(v.getMQTTpublishValue(PercentType.HUNDRED, null), is("100"));
302     }
303
304     @Test
305     public void percentCalc() {
306         PercentageValue v = new PercentageValue(new BigDecimal(10.0), new BigDecimal(110.0), new BigDecimal(1.0), null,
307                 null);
308         assertThat(v.parseCommand(new DecimalType("110.0")), is(PercentType.HUNDRED));
309         assertThat(v.getMQTTpublishValue(PercentType.HUNDRED, null), is("110"));
310         assertThat(v.parseCommand(new DecimalType(10.0)), is(PercentType.ZERO));
311         assertThat(v.getMQTTpublishValue(PercentType.ZERO, null), is("10"));
312
313         assertThat(v.parseCommand(OnOffType.ON), is(PercentType.HUNDRED));
314         assertThat(v.parseCommand(OnOffType.OFF), is(PercentType.ZERO));
315     }
316
317     @Test
318     public void percentMQTTValue() {
319         PercentageValue v = new PercentageValue(null, null, null, null, null);
320         assertThat(v.parseCommand(new DecimalType("10.10000")), is(new PercentType("10.1")));
321         assertThat(v.getMQTTpublishValue(new PercentType("10.1"), null), is("10.1"));
322         Command command;
323         for (int i = 0; i <= 100; i++) {
324             command = v.parseCommand(new DecimalType(i));
325             assertThat(v.getMQTTpublishValue(command, null), is("" + i));
326         }
327
328         assertThat(v.parseMessage(new StringType("")), is(UnDefType.NULL));
329     }
330
331     @Test
332     public void percentCustomOnOff() {
333         PercentageValue v = new PercentageValue(new BigDecimal("0.0"), new BigDecimal("100.0"), new BigDecimal("1.0"),
334                 "on", "off");
335         assertThat(v.parseCommand(new StringType("on")), is(PercentType.HUNDRED));
336         assertThat(v.parseCommand(new StringType("off")), is(PercentType.ZERO));
337     }
338
339     @Test
340     public void decimalCalc() {
341         PercentageValue v = new PercentageValue(new BigDecimal("0.1"), new BigDecimal("1.0"), new BigDecimal("0.1"),
342                 null, null);
343         assertThat(v.parseCommand(new DecimalType(1.0)), is(PercentType.HUNDRED));
344         assertThat(v.parseCommand(new DecimalType(0.1)), is(PercentType.ZERO));
345         PercentType command = v.parseCommand(new DecimalType(0.2));
346         assertEquals(command.floatValue(), 11.11f, 0.01f);
347     }
348
349     @Test
350     public void increaseDecreaseCalc() {
351         PercentageValue v = new PercentageValue(new BigDecimal("1.0"), new BigDecimal("11.0"), new BigDecimal("0.5"),
352                 null, null);
353
354         // Normal operation.
355         PercentType command = v.parseCommand(new DecimalType("6.0"));
356         assertEquals(command.floatValue(), 50.0f, 0.01f);
357         v.update(command);
358         command = v.parseCommand(IncreaseDecreaseType.INCREASE);
359         assertEquals(command.floatValue(), 55.0f, 0.01f);
360         command = v.parseCommand(IncreaseDecreaseType.DECREASE);
361         assertEquals(command.floatValue(), 45.0f, 0.01f);
362
363         // Lower limit.
364         command = v.parseCommand(new DecimalType("1.1"));
365         assertEquals(command.floatValue(), 1.0f, 0.01f);
366         v.update(command);
367         command = v.parseCommand(IncreaseDecreaseType.DECREASE);
368         assertEquals(command.floatValue(), 0.0f, 0.01f);
369
370         // Upper limit.
371         command = v.parseCommand(new DecimalType("10.8"));
372         assertEquals(command.floatValue(), 98.0f, 0.01f);
373         v.update(command);
374         command = v.parseCommand(IncreaseDecreaseType.INCREASE);
375         assertEquals(command.floatValue(), 100.0f, 0.01f);
376     }
377
378     @Test
379     public void upDownCalc() {
380         PercentageValue v = new PercentageValue(new BigDecimal("1.0"), new BigDecimal("11.0"), new BigDecimal("0.5"),
381                 null, null);
382
383         // Normal operation.
384         PercentType command = v.parseCommand(new DecimalType("6.0"));
385         assertEquals(command.floatValue(), 50.0f, 0.01f);
386         v.update(command);
387         command = v.parseCommand(UpDownType.UP);
388         assertEquals(command.floatValue(), 55.0f, 0.01f);
389         command = v.parseCommand(UpDownType.DOWN);
390         assertEquals(command.floatValue(), 45.0f, 0.01f);
391
392         // Lower limit.
393         command = v.parseCommand(new DecimalType("1.1"));
394         assertEquals(command.floatValue(), 1.0f, 0.01f);
395         v.update(command);
396         command = v.parseCommand(UpDownType.DOWN);
397         assertEquals(command.floatValue(), 0.0f, 0.01f);
398
399         // Upper limit.
400         command = v.parseCommand(new DecimalType("10.8"));
401         assertEquals(command.floatValue(), 98.0f, 0.01f);
402         v.update(command);
403         command = v.parseCommand(UpDownType.UP);
404         assertEquals(command.floatValue(), 100.0f, 0.01f);
405     }
406
407     @Test
408     public void percentCalcInvalid() {
409         PercentageValue v = new PercentageValue(new BigDecimal(10.0), new BigDecimal(110.0), new BigDecimal(1.0), null,
410                 null);
411         assertThrows(IllegalArgumentException.class, () -> v.parseCommand(new DecimalType(9.0)));
412     }
413
414     @Test
415     public void textUpdate() {
416         TextValue v = new TextValue();
417
418         assertThat(v.parseMessage(new StringType("")), is(new StringType("")));
419         assertThat(v.parseMessage(new StringType("NULL")), is(new StringType("NULL")));
420
421         v.setNullValue("");
422         assertThat(v.parseMessage(new StringType("")), is(UnDefType.NULL));
423         assertThat(v.parseMessage(new StringType("NULL")), is(new StringType("NULL")));
424
425         v.setNullValue("NULL");
426         assertThat(v.parseMessage(new StringType("NULL")), is(UnDefType.NULL));
427         assertThat(v.parseMessage(new StringType("")), is(new StringType("")));
428     }
429 }