diff --git a/src/io/calimero/dptxlator/DPTXlator2ByteFloat.java b/src/io/calimero/dptxlator/DPTXlator2ByteFloat.java index 985eef76..4f4bd2c8 100644 --- a/src/io/calimero/dptxlator/DPTXlator2ByteFloat.java +++ b/src/io/calimero/dptxlator/DPTXlator2ByteFloat.java @@ -1,6 +1,6 @@ /* Calimero 2 - A library for KNX network access - Copyright (c) 2006, 2023 B. Malinowsky + Copyright (c) 2006, 2024 B. Malinowsky This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -45,13 +45,13 @@ *
* The KNX data type width is 2 bytes.
* This type is a two byte floating format with a maximum usable range of -671088.64 to
- * +670760.96. DPTs adjust the usable range to reasonable limits for its values, the
+ * 670760. DPTs adjust the usable range to reasonable limits for its values, the
* translator will check and enforce those DPT specific limits in all methods working with
* java values (e.g. {@link #setValue(double)}). Data methods for KNX data (e.g.
- * {@link #setData(byte[])} accept all data within the maximum usable range.
+ * {@link #setData(byte[])}) accept all data within the maximum usable range.
* In value methods expecting a string type, the value is a floating type representation.
*
- * The default return value after creation is {@code 0.0}.
+ * The default return value after creation is {@code 0}.
* Note, that the floating type structure specified by this data type isn't really
* precise, especially for bigger floating numbers, so you have to expect certain rounding
* deviations.
@@ -61,133 +61,133 @@
public class DPTXlator2ByteFloat extends DPTXlator
{
/**
- * DPT ID 9.001, Temperature; values from -273 to +670760 °C.
+ * DPT ID 9.001, Temperature; values from -273 to 670433.28 °C.
*/
public static final DPT DPT_TEMPERATURE =
- new DPT("9.001", "Temperature", "-273", "+670760", "°C");
+ new DPT("9.001", "Temperature", "-273", "670433.28", "°C");
/**
- * DPT ID 9.002, Temperature difference; value range +/-670760 K.
+ * DPT ID 9.002, Temperature difference; value range -671088.64 to 670433.28 K.
*/
public static final DPT DPT_TEMPERATURE_DIFFERENCE =
- new DPT("9.002", "Temperature difference", "-670760", "+670760", "K");
+ new DPT("9.002", "Temperature difference", "-671088.64", "670433.28", "K");
/**
- * DPT ID 9.003, Temperature gradient; value range +/-670760 K/h.
+ * DPT ID 9.003, Temperature gradient; value range -671088.64 to 670433.28 K/h.
*/
public static final DPT DPT_TEMPERATURE_GRADIENT =
- new DPT("9.003", "Temperature gradient", "-670760", "+670760", "K/h");
+ new DPT("9.003", "Temperature gradient", "-671088.64", "670433.28", "K/h");
/**
- * DPT ID 9.004, Intensity of light (Lux); values from 0 to +670760 lx. Note, the
+ * DPT ID 9.004, Intensity of light (Lux); values from 0 to 670433.28 lx. Note, the
* unit of measure symbol used here is "lx", and not "Lux" as originally proposed for this DPT.
*/
public static final DPT DPT_INTENSITY_OF_LIGHT =
- new DPT("9.004", "Light intensity", "0", "+670760", "lx");
+ new DPT("9.004", "Light intensity", "0", "670433.28", "lx");
/**
- * DPT ID 9.005, Wind speed; values from 0 to +670760 m/s.
+ * DPT ID 9.005, Wind speed; values from 0 to 670433.28 m/s.
*/
- public static final DPT DPT_WIND_SPEED = new DPT("9.005", "Wind speed", "0", "+670760", "m/s");
+ public static final DPT DPT_WIND_SPEED = new DPT("9.005", "Wind speed", "0", "670433.28", "m/s");
/**
- * DPT ID 9.006, Air pressure; values from 0 to +670760 Pa.
+ * DPT ID 9.006, Air pressure; values from 0 to 670433.28 Pa.
*/
- public static final DPT DPT_AIR_PRESSURE = new DPT("9.006", "Air pressure", "0", "+670760",
+ public static final DPT DPT_AIR_PRESSURE = new DPT("9.006", "Air pressure", "0", "670433.28",
"Pa");
/**
- * DPT ID 9.007, Humidity; values from 0 to +670760 %.
+ * DPT ID 9.007, Humidity; values from 0 to 670433.28 %.
*/
- public static final DPT DPT_HUMIDITY = new DPT("9.007", "Humidity", "0", "+670760", "%");
+ public static final DPT DPT_HUMIDITY = new DPT("9.007", "Humidity", "0", "670433.28", "%");
/**
- * DPT ID 9.008, Air quality; values from 0 to +670760 ppm.
+ * DPT ID 9.008, Air quality; values from 0 to 670433.28 ppm.
*/
- public static final DPT DPT_AIRQUALITY = new DPT("9.008", "Air quality", "0", "+670760", "ppm");
+ public static final DPT DPT_AIRQUALITY = new DPT("9.008", "Air quality", "0", "670433.28", "ppm");
/**
- * DPT ID 9.009, Air flow; value range +/-670760 m³/h; resolution 0.01 m³/h.
+ * DPT ID 9.009, Air flow; value range -671088.64 to 670433.28 m³/h; resolution 0.01 m³/h.
*/
- public static final DPT DPT_AIR_FLOW = new DPT("9.009", "Air flow", "-670760", "+670760",
+ public static final DPT DPT_AIR_FLOW = new DPT("9.009", "Air flow", "-671088.64", "670433.28",
"m³/h");
/**
- * DPT ID 9.010, Time difference in seconds; value range +/-670760 s.
+ * DPT ID 9.010, Time difference in seconds; value range -671088.64 to 670433.28 s.
*/
public static final DPT DPT_TIME_DIFFERENCE1 =
- new DPT("9.010", "Time difference 1", "-670760", "+670760", "s");
+ new DPT("9.010", "Time difference 1", "-671088.64", "670433.28", "s");
/**
- * DPT ID 9.011, Time difference in milliseconds; value range +/-670760 ms.
+ * DPT ID 9.011, Time difference in milliseconds; value range -671088.64 to 670433.28 ms.
*/
public static final DPT DPT_TIME_DIFFERENCE2 =
- new DPT("9.011", "Time difference 2", "-670760", "+670760", "ms");
+ new DPT("9.011", "Time difference 2", "-671088.64", "670433.28", "ms");
/**
- * DPT ID 9.020, Voltage; value range +/-670760 mV.
+ * DPT ID 9.020, Voltage; value range -671088.64 to 670433.28 mV.
*/
- public static final DPT DPT_VOLTAGE = new DPT("9.020", "Voltage", "-670760", "+670760", "mV");
+ public static final DPT DPT_VOLTAGE = new DPT("9.020", "Voltage", "-671088.64", "670433.28", "mV");
/**
- * DPT ID 9.021, Electrical current; value range +/-670760 mA.
+ * DPT ID 9.021, Electrical current; value range -671088.64 to 670433.28 mA.
*/
public static final DPT DPT_ELECTRICAL_CURRENT =
- new DPT("9.021", "Electrical current", "-670760", "+670760", "mA");
+ new DPT("9.021", "Electrical current", "-671088.64", "670433.28", "mA");
/**
- * DPT ID 9.022, Power density; value range +/-670760 W/m2.
+ * DPT ID 9.022, Power density; value range -671088.64 to 670433.28 W/m2.
*/
public static final DPT DPT_POWERDENSITY =
- new DPT("9.022", "Power density", "-670760", "+670760", "W/m²");
+ new DPT("9.022", "Power density", "-671088.64", "670433.28", "W/m²");
/**
- * DPT ID 9.023, Kelvin/percent; value range +/-670760 K/%.
+ * DPT ID 9.023, Kelvin/percent; value range -671088.64 to 670433.28 K/%.
*/
public static final DPT DPT_KELVIN_PER_PERCENT =
- new DPT("9.023", "Kelvin/percent", "-670760", "+670760", "K/%");
+ new DPT("9.023", "Kelvin/percent", "-671088.64", "670433.28", "K/%");
/**
- * DPT ID 9.024, Power; value range +/-670760 kW.
+ * DPT ID 9.024, Power; value range -671088.64 to 670433.28 kW.
*/
- public static final DPT DPT_POWER = new DPT("9.024", "Power", "-670760", "+670760", "kW");
+ public static final DPT DPT_POWER = new DPT("9.024", "Power", "-671088.64", "670433.28", "kW");
/**
- * DPT ID 9.025, Volume flow in liter/hour; value range +/-670760 l/h, resolution 0.01.
+ * DPT ID 9.025, Volume flow in liter/hour; value range -671088.64 to 670433.28 l/h, resolution 0.01.
*/
- public static final DPT DPT_VOLUME_FLOW = new DPT("9.025", "Volume flow", "-670760", "+670760",
+ public static final DPT DPT_VOLUME_FLOW = new DPT("9.025", "Volume flow", "-671088.64", "670433.28",
"l/h");
/**
* DPT ID 9.026, Rain amount in liters per square meter; values from -671088.64 to
- * 670760.96 l/m2, resolution 0.01.
+ * 670433.28 l/m2, resolution 0.01.
*/
public static final DPT DPT_RAIN_AMOUNT = new DPT("9.026", "Rain amount", "-671088.64",
- "670760.96", "l/m²");
+ "670433.28", "l/m²");
/**
- * DPT ID 9.027, Temperature in Degree Fahrenheit; values from +/-459.6 to
- * 670760.96 °F, resolution 0.01.
+ * DPT ID 9.027, Temperature in Degree Fahrenheit; values from -459.6 to
+ * 670433.28 °F, resolution 0.01.
*/
- public static final DPT DPT_TEMP_F = new DPT("9.027", "Temperature", "-459.6", "670760.96",
+ public static final DPT DPT_TEMP_F = new DPT("9.027", "Temperature", "-459.6", "670433.28",
"°F");
/**
- * DPT ID 9.028, Wind speed in km/h; values from 0 to 670760.96 km/h, resolution
+ * DPT ID 9.028, Wind speed in km/h; values from 0 to 670433.28 km/h, resolution
* 0.01.
*/
- public static final DPT DPT_WIND_SPEED_KMH = new DPT("9.028", "Wind speed", "0", "670760.96",
+ public static final DPT DPT_WIND_SPEED_KMH = new DPT("9.028", "Wind speed", "0", "670433.28",
"km/h");
/**
- * DPT ID 9.029, absolute humidity in g/m³; values from 0 to 670760.96 g/m³, resolution 0.01.
+ * DPT ID 9.029, absolute humidity in g/m³; values from 0 to 670760 g/m³, resolution 0.01.
*/
- public static final DPT DptAbsoluteHumidity = new DPT("9.029", "absolute humidity", "0", "670760.96", "g/m³");
+ public static final DPT DptAbsoluteHumidity = new DPT("9.029", "absolute humidity", "0", "670760", "g/m³");
/**
- * DPT ID 9.030, concentration in µg/m³; values from 0 to 670760.96 µg/m³, resolution 0.01.
+ * DPT ID 9.030, concentration in µg/m³; values from 0 to 670760 µg/m³, resolution 0.01.
*/
- public static final DPT DptConcentration = new DPT("9.030", "concentration", "0", "670760.96", "µg/m³");
+ public static final DPT DptConcentration = new DPT("9.030", "concentration", "0", "670760", "µg/m³");
diff --git a/test/io/calimero/dptxlator/DPTXlator2ByteFloatTest.java b/test/io/calimero/dptxlator/DPTXlator2ByteFloatTest.java
index 9343619f..9fe1e722 100644
--- a/test/io/calimero/dptxlator/DPTXlator2ByteFloatTest.java
+++ b/test/io/calimero/dptxlator/DPTXlator2ByteFloatTest.java
@@ -1,6 +1,6 @@
/*
Calimero 2 - A library for KNX network access
- Copyright (c) 2006, 2023 B. Malinowsky
+ Copyright (c) 2006, 2024 B. Malinowsky
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -36,20 +36,31 @@
package io.calimero.dptxlator;
-import org.junit.jupiter.api.BeforeEach;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.stream.Stream;
+
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
import io.calimero.KNXFormatException;
import io.calimero.KNXIllegalArgumentException;
-import static org.junit.jupiter.api.Assertions.*;
-
class DPTXlator2ByteFloatTest
{
- private DPTXlator2ByteFloat t;
private final String min = "-671088.64";
- private final String max = "670760.96";
+ private final String max = "670433.28";
+ private final String maxAlt = "670760";
private final String zero = "0.0";
private final String value1 = "735.763";
@@ -61,14 +72,15 @@ class DPTXlator2ByteFloatTest
private final double[] floats = { Double.parseDouble(min), Double.parseDouble(max),
Double.parseDouble(zero), Double.parseDouble(value1), Double.parseDouble(value2), };
- private final byte[] dataMin = { (byte) 0xf8, 0, };
- private final byte[] dataMax = { 0x7f, -1 };
+ private final byte[] dataMin = { (byte) 0xf8, 0 };
+ private final byte[] dataMax = { (byte) 0x7f, (byte) 0xfe }; // 670433.28
+ private final byte[] invalid = { 0x7f, (byte) 0xff };
private final byte[] dataZero = { 0, 0 };
- private final byte[] dataValue1 = { (byte) 0x34, (byte) 0x7e, };
+ private final byte[] dataValue1 = { (byte) 0x34, (byte) 0x7e };
// 2 byte offset, 1 byte appended
private final byte[] dataValue2 = { 0, 0, (byte) 0x1c, (byte) 0xe2, 0 };
- private final DPT[] dpts = { DPTXlator2ByteFloat.DPT_TEMPERATURE,
+ private static final DPT[] dpts = { DPTXlator2ByteFloat.DPT_TEMPERATURE,
DPTXlator2ByteFloat.DPT_TEMPERATURE_DIFFERENCE,
DPTXlator2ByteFloat.DPT_TEMPERATURE_GRADIENT, DPTXlator2ByteFloat.DPT_INTENSITY_OF_LIGHT,
DPTXlator2ByteFloat.DPT_WIND_SPEED, DPTXlator2ByteFloat.DPT_AIR_PRESSURE,
@@ -81,15 +93,66 @@ class DPTXlator2ByteFloatTest
DPTXlator2ByteFloat.DPT_WIND_SPEED_KMH, DPTXlator2ByteFloat.DptAbsoluteHumidity,
DPTXlator2ByteFloat.DptConcentration };
+ private static final DPT[] dptsLowerZero = { DPTXlator2ByteFloat.DPT_INTENSITY_OF_LIGHT,
+ DPTXlator2ByteFloat.DPT_WIND_SPEED, DPTXlator2ByteFloat.DPT_AIR_PRESSURE,
+ DPTXlator2ByteFloat.DPT_HUMIDITY, DPTXlator2ByteFloat.DPT_AIRQUALITY,
+ DPTXlator2ByteFloat.DPT_WIND_SPEED_KMH, DPTXlator2ByteFloat.DptAbsoluteHumidity,
+ DPTXlator2ByteFloat.DptConcentration };
- @BeforeEach
- void init() throws Exception
- {
- t = new DPTXlator2ByteFloat(DPTXlator2ByteFloat.DPT_RAIN_AMOUNT);
+
+ @ParameterizedTest
+ @MethodSource("allXlators")
+ void invalidData(final DPTXlator2ByteFloat t) {
+ t.setData(invalid);
}
- @Test
- void setValues() throws KNXFormatException
+ @ParameterizedTest
+ @MethodSource("allXlators")
+ void invalidValue(final DPTXlator2ByteFloat t) {
+ t.setData(invalid);
+ // TODO indicate invalid value in get(Numeric)Value
+ t.getValue();
+ t.getNumericValue();
+ }
+
+ @ParameterizedTest
+ @MethodSource("xlatorsLowerZero")
+ void min0(final DPTXlator2ByteFloat t) throws KNXFormatException {
+ t.setValue(0);
+ t.setValue(zero);
+
+ assertThrows(KNXFormatException.class, () -> t.setValue(Math.nextDown(0d)));
+ assertThrows(KNXFormatException.class, () -> t.setValue("-0.1"));
+ assertThrows(KNXFormatException.class, () -> t.setValue(min));
+ assertThrows(KNXFormatException.class, () -> t.setValue(Double.parseDouble(min)));
+ }
+
+ @ParameterizedTest
+ @MethodSource("tempXlators")
+ void minTemp(final DPTXlator2ByteFloat t, final double lowerLimit, final String sLowerLimit) throws KNXFormatException {
+ t.setValue(lowerLimit);
+ t.setValue(sLowerLimit);
+
+ assertThrows(KNXFormatException.class, () -> t.setValue(Math.nextDown(lowerLimit)));
+ assertThrows(KNXFormatException.class, () -> t.setValue("" + Math.nextDown(lowerLimit)));
+ assertThrows(KNXFormatException.class, () -> t.setValue(min));
+ assertThrows(KNXFormatException.class, () -> t.setValue(Double.parseDouble(min)));
+ }
+
+ @ParameterizedTest
+ @MethodSource("xlatorsMaxAlt")
+ void maxAlt(final DPTXlator2ByteFloat t) throws KNXFormatException {
+ t.setValue(maxAlt);
+ final double d = Double.parseDouble(maxAlt);
+ t.setValue(d);
+
+ assertThrows(KNXFormatException.class, () -> t.setValue(Math.nextUp(d)));
+ assertThrows(KNXFormatException.class, () -> t.setValue("" + Math.nextUp(d)));
+ }
+
+ @ParameterizedTest
+ @MethodSource("xlatorsMinMax")
+ void setValues(final DPTXlator2ByteFloat t) throws KNXFormatException
{
t.setValues();
assertEquals(1, t.getItems());
@@ -101,8 +164,9 @@ void setValues() throws KNXFormatException
t.setValues(t.getValue(), t.getValue());
}
- @Test
- void getAllValues() throws KNXFormatException
+ @ParameterizedTest
+ @MethodSource("xlatorsMinMax")
+ void getAllValues(final DPTXlator2ByteFloat t) throws KNXFormatException
{
assertEquals(t.getItems(), t.getItems());
assertEquals(0.0, t.getNumericValue(), 0);
@@ -114,8 +178,9 @@ void getAllValues() throws KNXFormatException
assertTrue(returned[i].contains(strings[i]));
}
- @Test
- void setValueString() throws KNXFormatException
+ @ParameterizedTest
+ @MethodSource("allXlators")
+ void setValueString(final DPTXlator2ByteFloat t) throws KNXFormatException
{
t.setValue(value1);
assertEquals(1, t.getItems());
@@ -126,8 +191,9 @@ void setValueString() throws KNXFormatException
assertTrue(t.getValue().startsWith(value1Enc));
}
- @Test
- void setDataByteArrayInt()
+ @ParameterizedTest
+ @MethodSource("xlatorsMinMax")
+ void setDataByteArrayInt(final DPTXlator2ByteFloat t)
{
t.setData(dataMin, 0);
try {
@@ -151,8 +217,9 @@ void setDataByteArrayInt()
Helper.assertSimilar(new String[] { max, value1Enc }, t.getAllValues());
}
- @Test
- void getDataByteArrayInt() throws KNXFormatException
+ @ParameterizedTest
+ @MethodSource("xlatorsMinMax")
+ void getDataByteArrayInt(final DPTXlator2ByteFloat t) throws KNXFormatException
{
t.setData(dataValue2, 2);
final byte[] data = t.getData(new byte[5], 2);
@@ -177,8 +244,8 @@ void getDataByteArrayInt() throws KNXFormatException
}
@Test
- void getSubTypes()
- {
+ void getSubTypes() throws KNXFormatException {
+ final var t = new DPTXlator2ByteFloat(dpts[0]);
assertEquals(dpts.length, t.getSubTypes().size());
t.getSubTypes().remove(dpts[0].getID());
assertEquals(dpts.length - 1, t.getSubTypes().size());
@@ -187,41 +254,33 @@ void getSubTypes()
assertEquals(dpts.length, t.getSubTypes().size());
}
- @Test
- void dptXlator2ByteFloatDPT() throws KNXFormatException
+ @ParameterizedTest
+ @MethodSource("allXlators")
+ void lowerUpperLimit(final DPTXlator2ByteFloat t) throws KNXFormatException
{
- // do no similarity test because float type rounding issues
- Helper.checkDPTs(dpts, false);
-
- for (DPT value : dpts) {
- setValueFloatFail(new DPTXlator2ByteFloat(value),
- Double.parseDouble(value.getLowerValue()) - 0.1d);
- setValueFloatFail(new DPTXlator2ByteFloat(value),
- Double.parseDouble(value.getUpperValue()) + 0.1d);
- }
-
- final DPT dpt = new DPT("0.00", "invalid", "invalid", "invalid", "invalid");
- boolean failed = false;
- try {
- new DPTXlator2ByteFloat(dpt);
- }
- catch (final KNXFormatException e) {
- failed = true;
- }
- assertTrue(failed);
+ final DPT dpt = t.getType();
+ t.setValue(dpt.getLowerValue());
+ t.setAppendUnit(false);
+ double lower = Double.parseDouble(dpt.getLowerValue());
+ assertEquals(lower, Double.parseDouble(t.getValue()), 0.09);
+
+ t.setValue(dpt.getUpperValue());
+ double upper = Double.parseDouble(dpt.getUpperValue());
+ assertEquals(upper, Double.parseDouble(t.getValue()), 0.96);
+
+ assertThrows(KNXFormatException.class, () -> t.setValue(Math.nextDown(lower)));
+ assertThrows(KNXFormatException.class, () -> t.setValue(Math.nextUp(upper)));
}
- private void setValueFloatFail(final DPTXlator2ByteFloat tr, final double d)
- {
- try {
- tr.setValue(d);
- fail("set value should fail: " + d);
- }
- catch (final KNXFormatException e) {}
+ @Test
+ void invalid() {
+ final DPT invalid = new DPT("0.00", "invalid", "invalid", "invalid", "invalid");
+ assertThrows(KNXFormatException.class, () -> new DPTXlator2ByteFloat(invalid));
}
- @Test
- void getNumericValue() throws KNXFormatException
+ @ParameterizedTest
+ @MethodSource("xlatorsMinMax")
+ void getNumericValue(final DPTXlator2ByteFloat t) throws KNXFormatException
{
assertEquals(0.0, t.getNumericValue(), 0);
@@ -242,8 +301,9 @@ void getNumericValue() throws KNXFormatException
}
}
- @Test
- void setValueDouble() throws KNXFormatException
+ @ParameterizedTest
+ @MethodSource("xlatorsMinMax")
+ void setValueDouble(final DPTXlator2ByteFloat t) throws KNXFormatException
{
for (int i = 0; i < floats.length; i++) {
t.setValue(floats[i]);
@@ -252,19 +312,21 @@ void setValueDouble() throws KNXFormatException
}
}
- @Test
- void testToString() throws KNXFormatException
+ @ParameterizedTest
+ @MethodSource("xlatorsMinMax")
+ void testToString(final DPTXlator2ByteFloat t) throws KNXFormatException
{
assertTrue(t.toString().contains("0.0"));
t.setValues(strings);
final String s = t.toString();
- for (String string : strings) {
+ for (final String string : strings) {
assertTrue(s.contains(string));
}
}
- @Test
- void getValue() throws KNXFormatException
+ @ParameterizedTest
+ @MethodSource("allXlators")
+ void getValue(final DPTXlator2ByteFloat t) throws KNXFormatException
{
assertTrue(t.getValue().contains("0"));
assertTrue(t.getValue().contains(t.getType().getUnit()));
@@ -276,9 +338,49 @@ void getValue() throws KNXFormatException
assertTrue(t.getValue().contains(s));
}
- @Test
- void getType()
- {
- assertEquals(t.getType(), dpts[17]);
+ @ParameterizedTest
+ @MethodSource("allXlators")
+ void getType(final DPTXlator2ByteFloat t) throws KNXFormatException {
+ assertEquals(t.getType(), new DPTXlator2ByteFloat(t.getType().getID()).getType());
+ }
+
+
+ private static Stream