2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.mqtt.generic.values;
15 import static org.hamcrest.CoreMatchers.is;
16 import static org.hamcrest.MatcherAssert.assertThat;
17 import static org.junit.jupiter.api.Assertions.*;
19 import java.math.BigDecimal;
20 import java.util.Objects;
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.State;
39 import org.openhab.core.types.TypeParser;
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.
45 * The on/off value class should accept a multitude of values including the custom defined ones.
47 * The string value class states are tested.
49 * @author David Graeff - Initial contribution
52 public class ValueTests {
53 private Command p(Value v, String str) {
54 return Objects.requireNonNull(TypeParser.parseCommand(v.getSupportedCommandTypes(), str));
58 public void illegalTextStateUpdate() {
59 TextValue v = new TextValue("one,two".split(","));
60 assertThrows(IllegalArgumentException.class, () -> v.parseCommand(p(v, "three")));
64 public void textStateUpdate() {
65 TextValue v = new TextValue("one,two".split(","));
66 v.parseCommand(p(v, "one"));
70 public void colorUpdate() {
71 ColorValue v = new ColorValue(ColorMode.RGB, "fancyON", "fancyOFF", 77);
72 v.update((State) v.parseCommand(p(v, "255,255,255")));
74 HSBType hsb = (HSBType) v.parseCommand(p(v, "OFF"));
75 assertThat(hsb.getBrightness().intValue(), is(0));
77 hsb = (HSBType) v.parseCommand(p(v, "ON"));
78 assertThat(hsb.getBrightness().intValue(), is(77));
80 hsb = (HSBType) v.parseCommand(p(v, "0"));
81 assertThat(hsb.getBrightness().intValue(), is(0));
82 hsb = (HSBType) v.parseCommand(p(v, "1"));
83 assertThat(hsb.getBrightness().intValue(), is(1));
87 public void illegalColorUpdate() {
88 ColorValue v = new ColorValue(ColorMode.RGB, null, null, 10);
89 assertThrows(IllegalArgumentException.class, () -> v.parseCommand(p(v, "255,255,abc")));
93 public void illegalNumberCommand() {
94 NumberValue v = new NumberValue(null, null, null, null);
95 assertThrows(IllegalArgumentException.class, () -> v.parseCommand(OnOffType.OFF));
99 public void illegalPercentCommand() {
100 PercentageValue v = new PercentageValue(null, null, null, null, null);
101 assertThrows(IllegalStateException.class, () -> v.parseCommand(new StringType("demo")));
105 public void illegalOnOffCommand() {
106 OnOffValue v = new OnOffValue(null, null);
107 assertThrows(IllegalArgumentException.class, () -> v.parseCommand(new DecimalType(101.0)));
111 public void illegalPercentUpdate() {
112 PercentageValue v = new PercentageValue(null, null, null, null, null);
113 assertThrows(IllegalArgumentException.class, () -> v.parseCommand(new DecimalType(101.0)));
117 public void onoffUpdate() {
118 OnOffValue v = new OnOffValue("fancyON", "fancyOff");
121 assertThat(v.parseCommand(OnOffType.OFF), is(OnOffType.OFF));
122 assertThat(v.parseCommand(OnOffType.ON), is(OnOffType.ON));
124 // Test with string, representing the command
125 assertThat(v.parseCommand(new StringType("OFF")), is(OnOffType.OFF));
126 assertThat(v.parseCommand(new StringType("ON")), is(OnOffType.ON));
128 // Test with custom string, setup in the constructor
129 assertThat(v.parseCommand(new StringType("fancyOff")), is(OnOffType.OFF));
130 assertThat(v.parseCommand(new StringType("fancyON")), is(OnOffType.ON));
132 // Test basic formatting
133 assertThat(v.getMQTTpublishValue(OnOffType.ON, null), is("fancyON"));
134 assertThat(v.getMQTTpublishValue(OnOffType.OFF, null), is("fancyOff"));
136 // Test custom formatting
137 assertThat(v.getMQTTpublishValue(OnOffType.OFF, "=%s"), is("=fancyOff"));
138 assertThat(v.getMQTTpublishValue(OnOffType.ON, "=%s"), is("=fancyON"));
142 public void openCloseUpdate() {
143 OpenCloseValue v = new OpenCloseValue("fancyON", "fancyOff");
146 assertThat(v.parseCommand(OpenClosedType.CLOSED), is(OpenClosedType.CLOSED));
147 assertThat(v.parseCommand(OpenClosedType.OPEN), is(OpenClosedType.OPEN));
149 // Test with string, representing the command
150 assertThat(v.parseCommand(new StringType("CLOSED")), is(OpenClosedType.CLOSED));
151 assertThat(v.parseCommand(new StringType("OPEN")), is(OpenClosedType.OPEN));
153 // Test with custom string, setup in the constructor
154 assertThat(v.parseCommand(new StringType("fancyOff")), is(OpenClosedType.CLOSED));
155 assertThat(v.parseCommand(new StringType("fancyON")), is(OpenClosedType.OPEN));
157 // Test basic formatting
158 assertThat(v.getMQTTpublishValue(OpenClosedType.CLOSED, null), is("fancyOff"));
159 assertThat(v.getMQTTpublishValue(OpenClosedType.OPEN, null), is("fancyON"));
163 public void numberUpdate() {
164 NumberValue v = new NumberValue(null, null, new BigDecimal(10), Units.WATT);
166 // Test with command with units
167 Command command = v.parseCommand(new QuantityType<>(20, Units.WATT));
168 assertThat(command, is(new QuantityType<>(20, Units.WATT)));
169 assertThat(v.getMQTTpublishValue(command, null), is("20"));
170 command = v.parseCommand(new QuantityType<>(20, MetricPrefix.KILO(Units.WATT)));
171 assertThat(command, is(new QuantityType<>(20, MetricPrefix.KILO(Units.WATT))));
172 assertThat(v.getMQTTpublishValue(command, null), is("20000"));
174 // Test with command without units
175 command = v.parseCommand(new QuantityType<>("20"));
176 assertThat(command, is(new QuantityType<>(20, Units.WATT)));
177 assertThat(v.getMQTTpublishValue(command, null), is("20"));
181 public void numberUpdateMireds() {
182 NumberValue v = new NumberValue(null, null, new BigDecimal(10), Units.MIRED);
184 Command command = v.parseCommand(new QuantityType<>(2700, Units.KELVIN));
185 assertThat(v.getMQTTpublishValue(command, "%.0f"), is("370"));
189 public void numberPercentageUpdate() {
190 NumberValue v = new NumberValue(null, null, new BigDecimal(10), Units.PERCENT);
192 // Test with command with units
193 Command command = v.parseCommand(new QuantityType<>(20, Units.PERCENT));
194 assertThat(command, is(new QuantityType<>(20, Units.PERCENT)));
195 assertThat(v.getMQTTpublishValue(command, null), is("20"));
197 // Test with command without units
198 command = v.parseCommand(new QuantityType<>("20"));
199 assertThat(command, is(new QuantityType<>(20, Units.PERCENT)));
200 assertThat(v.getMQTTpublishValue(command, null), is("20"));
204 public void rollershutterUpdateWithStrings() {
205 RollershutterValue v = new RollershutterValue("fancyON", "fancyOff", "fancyStop");
206 // Test with UP/DOWN/STOP command
207 assertThat(v.parseCommand(UpDownType.UP), is(UpDownType.UP));
208 assertThat(v.getMQTTpublishValue(UpDownType.UP, null), is("fancyON"));
209 assertThat(v.parseCommand(UpDownType.DOWN), is(UpDownType.DOWN));
210 assertThat(v.getMQTTpublishValue(UpDownType.DOWN, null), is("fancyOff"));
211 assertThat(v.parseCommand(StopMoveType.STOP), is(StopMoveType.STOP));
212 assertThat(v.getMQTTpublishValue(StopMoveType.STOP, null), is("fancyStop"));
214 // Test with custom string
215 assertThat(v.parseCommand(new StringType("fancyON")), is(UpDownType.UP));
216 assertThat(v.parseCommand(new StringType("fancyOff")), is(UpDownType.DOWN));
218 // Test with exact percent
219 Command command = new PercentType(27);
220 assertThat(v.parseCommand((Command) command), is(command));
221 assertThat(v.getMQTTpublishValue(command, null), is("27"));
223 // Test formatting 0/100
224 assertThat(v.getMQTTpublishValue(PercentType.ZERO, null), is("fancyON"));
225 assertThat(v.getMQTTpublishValue(PercentType.HUNDRED, null), is("fancyOff"));
229 public void rollershutterUpdateWithOutStrings() {
230 RollershutterValue v = new RollershutterValue(null, null, "fancyStop");
232 assertThat(v.parseCommand(UpDownType.UP), is(PercentType.ZERO));
233 assertThat(v.parseCommand(UpDownType.DOWN), is(PercentType.HUNDRED));
235 // Test with custom string
236 // Test formatting 0/100
237 assertThat(v.getMQTTpublishValue(PercentType.ZERO, null), is("0"));
238 assertThat(v.getMQTTpublishValue(PercentType.HUNDRED, null), is("100"));
242 public void percentCalc() {
243 PercentageValue v = new PercentageValue(new BigDecimal(10.0), new BigDecimal(110.0), new BigDecimal(1.0), null,
245 assertThat(v.parseCommand(new DecimalType("110.0")), is(PercentType.HUNDRED));
246 assertThat(v.getMQTTpublishValue(PercentType.HUNDRED, null), is("110"));
247 assertThat(v.parseCommand(new DecimalType(10.0)), is(PercentType.ZERO));
248 assertThat(v.getMQTTpublishValue(PercentType.ZERO, null), is("10"));
250 assertThat(v.parseCommand(OnOffType.ON), is(PercentType.HUNDRED));
251 assertThat(v.parseCommand(OnOffType.OFF), is(PercentType.ZERO));
255 public void percentMQTTValue() {
256 PercentageValue v = new PercentageValue(null, null, null, null, null);
257 assertThat(v.parseCommand(new DecimalType("10.10000")), is(new PercentType("10.1")));
258 assertThat(v.getMQTTpublishValue(new PercentType("10.1"), null), is("10.1"));
260 for (int i = 0; i <= 100; i++) {
261 command = v.parseCommand(new DecimalType(i));
262 assertThat(v.getMQTTpublishValue(command, null), is("" + i));
267 public void percentCustomOnOff() {
268 PercentageValue v = new PercentageValue(new BigDecimal("0.0"), new BigDecimal("100.0"), new BigDecimal("1.0"),
270 assertThat(v.parseCommand(new StringType("on")), is(PercentType.HUNDRED));
271 assertThat(v.parseCommand(new StringType("off")), is(PercentType.ZERO));
275 public void decimalCalc() {
276 PercentageValue v = new PercentageValue(new BigDecimal("0.1"), new BigDecimal("1.0"), new BigDecimal("0.1"),
278 assertThat(v.parseCommand(new DecimalType(1.0)), is(PercentType.HUNDRED));
279 assertThat(v.parseCommand(new DecimalType(0.1)), is(PercentType.ZERO));
280 PercentType command = (PercentType) v.parseCommand(new DecimalType(0.2));
281 assertEquals(command.floatValue(), 11.11f, 0.01f);
285 public void increaseDecreaseCalc() {
286 PercentageValue v = new PercentageValue(new BigDecimal("1.0"), new BigDecimal("11.0"), new BigDecimal("0.5"),
290 PercentType command = (PercentType) v.parseCommand(new DecimalType("6.0"));
291 assertEquals(command.floatValue(), 50.0f, 0.01f);
293 command = (PercentType) v.parseCommand(IncreaseDecreaseType.INCREASE);
294 assertEquals(command.floatValue(), 55.0f, 0.01f);
295 command = (PercentType) v.parseCommand(IncreaseDecreaseType.DECREASE);
296 assertEquals(command.floatValue(), 45.0f, 0.01f);
299 command = (PercentType) v.parseCommand(new DecimalType("1.1"));
300 assertEquals(command.floatValue(), 1.0f, 0.01f);
302 command = (PercentType) v.parseCommand(IncreaseDecreaseType.DECREASE);
303 assertEquals(command.floatValue(), 0.0f, 0.01f);
306 command = (PercentType) v.parseCommand(new DecimalType("10.8"));
307 assertEquals(command.floatValue(), 98.0f, 0.01f);
309 command = (PercentType) v.parseCommand(IncreaseDecreaseType.INCREASE);
310 assertEquals(command.floatValue(), 100.0f, 0.01f);
314 public void upDownCalc() {
315 PercentageValue v = new PercentageValue(new BigDecimal("1.0"), new BigDecimal("11.0"), new BigDecimal("0.5"),
319 PercentType command = (PercentType) v.parseCommand(new DecimalType("6.0"));
320 assertEquals(command.floatValue(), 50.0f, 0.01f);
322 command = (PercentType) v.parseCommand(UpDownType.UP);
323 assertEquals(command.floatValue(), 55.0f, 0.01f);
324 command = (PercentType) v.parseCommand(UpDownType.DOWN);
325 assertEquals(command.floatValue(), 45.0f, 0.01f);
328 command = (PercentType) v.parseCommand(new DecimalType("1.1"));
329 assertEquals(command.floatValue(), 1.0f, 0.01f);
331 command = (PercentType) v.parseCommand(UpDownType.DOWN);
332 assertEquals(command.floatValue(), 0.0f, 0.01f);
335 command = (PercentType) v.parseCommand(new DecimalType("10.8"));
336 assertEquals(command.floatValue(), 98.0f, 0.01f);
338 command = (PercentType) v.parseCommand(UpDownType.UP);
339 assertEquals(command.floatValue(), 100.0f, 0.01f);
343 public void percentCalcInvalid() {
344 PercentageValue v = new PercentageValue(new BigDecimal(10.0), new BigDecimal(110.0), new BigDecimal(1.0), null,
346 assertThrows(IllegalArgumentException.class, () -> v.parseCommand(new DecimalType(9.0)));