ActionInputsHelper: Allow any number of decimals & Apply primitive input default values (#4424)

* ActionInputHelper: Set step site to 0 if param type decimal

This makes the UI allow any step size, i.e. entering any number of decimals.

Signed-off-by: Florian Hotze <dev@florianhotze.com>

* ActionInputHelper: Apply default values when mapping from serialised to action inputs

This has been forgotten to be implemented.

Signed-off-by: Florian Hotze <dev@florianhotze.com>
This commit is contained in:
Florian Hotze 2024-10-26 21:49:18 +02:00 committed by GitHub
parent 4125f3d87b
commit 52b26baf17
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 84 additions and 31 deletions

View File

@ -33,6 +33,7 @@ import javax.measure.Quantity;
import javax.measure.Unit; import javax.measure.Unit;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.automation.type.ActionType; import org.openhab.core.automation.type.ActionType;
import org.openhab.core.automation.type.Input; import org.openhab.core.automation.type.Input;
import org.openhab.core.config.core.ConfigDescriptionParameter; import org.openhab.core.config.core.ConfigDescriptionParameter;
@ -177,6 +178,9 @@ public class ActionInputsHelper {
if (unit != null) { if (unit != null) {
builder = builder.withUnit(unit.getSymbol()); builder = builder.withUnit(unit.getSymbol());
} }
if (parameterType == ConfigDescriptionParameter.Type.DECIMAL) {
builder = builder.withStepSize(BigDecimal.ZERO);
}
return builder.build(); return builder.build();
} }
@ -197,11 +201,29 @@ public class ActionInputsHelper {
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
logger.warn("{} Input parameter is ignored.", e.getMessage()); logger.warn("{} Input parameter is ignored.", e.getMessage());
} }
} else {
value = getDefaultValueForActionInput(input);
if (value != null) {
newArguments.put(input.getName(), value);
}
} }
} }
return newArguments; return newArguments;
} }
private @Nullable Object getDefaultValueForActionInput(Input input) {
return switch (input.getType()) {
case "boolean" -> false;
case "byte" -> (byte) 0;
case "short" -> (short) 0;
case "int" -> 0;
case "long" -> 0L;
case "float" -> 0.0f;
case "double" -> 0.0d;
default -> null;
};
}
/** /**
* Maps a serialised input to the Java type required by the given {@link Input}. * Maps a serialised input to the Java type required by the given {@link Input}.
* *

View File

@ -16,6 +16,7 @@ import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
import java.math.BigDecimal;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.Duration; import java.time.Duration;
@ -63,63 +64,63 @@ public class ActionInputHelperTest {
@Test @Test
public void testMapActionInputToConfigDescriptionParameterWhenBoolean() { public void testMapActionInputToConfigDescriptionParameterWhenBoolean() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.Boolean")), checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.Boolean")),
ConfigDescriptionParameter.Type.BOOLEAN, false, null, null, null); ConfigDescriptionParameter.Type.BOOLEAN, false, null, null, null, null);
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("boolean")), checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("boolean")),
ConfigDescriptionParameter.Type.BOOLEAN, true, "false", null, null); ConfigDescriptionParameter.Type.BOOLEAN, true, "false", null, null, null);
} }
@Test @Test
public void testMapActionInputToConfigDescriptionParameterWhenByte() { public void testMapActionInputToConfigDescriptionParameterWhenByte() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.Byte")), checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.Byte")),
ConfigDescriptionParameter.Type.INTEGER, false, null, null, null); ConfigDescriptionParameter.Type.INTEGER, false, null, null, null, null);
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("byte")), checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("byte")),
ConfigDescriptionParameter.Type.INTEGER, true, "0", null, null); ConfigDescriptionParameter.Type.INTEGER, true, "0", null, null, null);
} }
@Test @Test
public void testMapActionInputToConfigDescriptionParameterWhenShort() { public void testMapActionInputToConfigDescriptionParameterWhenShort() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.Short")), checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.Short")),
ConfigDescriptionParameter.Type.INTEGER, false, null, null, null); ConfigDescriptionParameter.Type.INTEGER, false, null, null, null, null);
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("short")), checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("short")),
ConfigDescriptionParameter.Type.INTEGER, true, "0", null, null); ConfigDescriptionParameter.Type.INTEGER, true, "0", null, null, null);
} }
@Test @Test
public void testMapActionInputToConfigDescriptionParameterWhenInteger() { public void testMapActionInputToConfigDescriptionParameterWhenInteger() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.Integer")), checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.Integer")),
ConfigDescriptionParameter.Type.INTEGER, false, null, null, null); ConfigDescriptionParameter.Type.INTEGER, false, null, null, null, null);
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("int")), checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("int")),
ConfigDescriptionParameter.Type.INTEGER, true, "0", null, null); ConfigDescriptionParameter.Type.INTEGER, true, "0", null, null, null);
} }
@Test @Test
public void testMapActionInputToConfigDescriptionParameterWhenLong() { public void testMapActionInputToConfigDescriptionParameterWhenLong() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.Long")), checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.Long")),
ConfigDescriptionParameter.Type.INTEGER, false, null, null, null); ConfigDescriptionParameter.Type.INTEGER, false, null, null, null, null);
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("long")), checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("long")),
ConfigDescriptionParameter.Type.INTEGER, true, "0", null, null); ConfigDescriptionParameter.Type.INTEGER, true, "0", null, null, null);
} }
@Test @Test
public void testMapActionInputToConfigDescriptionParameterWhenFloat() { public void testMapActionInputToConfigDescriptionParameterWhenFloat() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.Float")), checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.Float")),
ConfigDescriptionParameter.Type.DECIMAL, false, null, null, null); ConfigDescriptionParameter.Type.DECIMAL, false, null, null, null, BigDecimal.ZERO);
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("float")), checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("float")),
ConfigDescriptionParameter.Type.DECIMAL, true, "0", null, null); ConfigDescriptionParameter.Type.DECIMAL, true, "0", null, null, BigDecimal.ZERO);
} }
@Test @Test
public void testMapActionInputToConfigDescriptionParameterWhenDouble() { public void testMapActionInputToConfigDescriptionParameterWhenDouble() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.Double")), checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.Double")),
ConfigDescriptionParameter.Type.DECIMAL, false, null, null, null); ConfigDescriptionParameter.Type.DECIMAL, false, null, null, null, BigDecimal.ZERO);
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("double")), checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("double")),
ConfigDescriptionParameter.Type.DECIMAL, true, "0", null, null); ConfigDescriptionParameter.Type.DECIMAL, true, "0", null, null, BigDecimal.ZERO);
} }
@Test @Test
public void testMapActionInputToConfigDescriptionParameterWhenNumber() { public void testMapActionInputToConfigDescriptionParameterWhenNumber() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.Number")), checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.Number")),
ConfigDescriptionParameter.Type.DECIMAL, false, null, null, null); ConfigDescriptionParameter.Type.DECIMAL, false, null, null, null, BigDecimal.ZERO);
} }
@Test @Test
@ -127,68 +128,68 @@ public class ActionInputHelperTest {
checkParameter( checkParameter(
helper.mapActionInputToConfigDescriptionParameter( helper.mapActionInputToConfigDescriptionParameter(
buildInput("org.openhab.core.library.types.DecimalType")), buildInput("org.openhab.core.library.types.DecimalType")),
ConfigDescriptionParameter.Type.DECIMAL, false, null, null, null); ConfigDescriptionParameter.Type.DECIMAL, false, null, null, null, BigDecimal.ZERO);
} }
@Test @Test
public void testMapActionInputToConfigDescriptionParameterWhenQuantityType() { public void testMapActionInputToConfigDescriptionParameterWhenQuantityType() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("QuantityType<Temperature>")), checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("QuantityType<Temperature>")),
ConfigDescriptionParameter.Type.DECIMAL, false, null, null, "°C"); ConfigDescriptionParameter.Type.DECIMAL, false, null, null, "°C", BigDecimal.ZERO);
} }
@Test @Test
public void testMapActionInputToConfigDescriptionParameterWhenString() { public void testMapActionInputToConfigDescriptionParameterWhenString() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.String")), checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.lang.String")),
ConfigDescriptionParameter.Type.TEXT, false, null, null, null); ConfigDescriptionParameter.Type.TEXT, false, null, null, null, null);
} }
@Test @Test
public void testMapActionInputToConfigDescriptionParameterWhenLocalDate() { public void testMapActionInputToConfigDescriptionParameterWhenLocalDate() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.time.LocalDate")), checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.time.LocalDate")),
ConfigDescriptionParameter.Type.TEXT, false, null, "date", null); ConfigDescriptionParameter.Type.TEXT, false, null, "date", null, null);
} }
@Test @Test
public void testMapActionInputToConfigDescriptionParameterWhenLocalTime() { public void testMapActionInputToConfigDescriptionParameterWhenLocalTime() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.time.LocalTime")), checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.time.LocalTime")),
ConfigDescriptionParameter.Type.TEXT, false, null, "time", null); ConfigDescriptionParameter.Type.TEXT, false, null, "time", null, null);
} }
@Test @Test
public void testMapActionInputToConfigDescriptionParameterWhenLocalDateTime() { public void testMapActionInputToConfigDescriptionParameterWhenLocalDateTime() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.time.LocalDateTime")), checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.time.LocalDateTime")),
ConfigDescriptionParameter.Type.TEXT, false, null, "datetime", null); ConfigDescriptionParameter.Type.TEXT, false, null, "datetime", null, null);
} }
@Test @Test
public void testMapActionInputToConfigDescriptionParameterWhenDate() { public void testMapActionInputToConfigDescriptionParameterWhenDate() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.util.Date")), checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.util.Date")),
ConfigDescriptionParameter.Type.TEXT, false, null, "datetime", null); ConfigDescriptionParameter.Type.TEXT, false, null, "datetime", null, null);
} }
@Test @Test
public void testMapActionInputToConfigDescriptionParameterWhenZonedDateTime() { public void testMapActionInputToConfigDescriptionParameterWhenZonedDateTime() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.time.ZonedDateTime")), checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.time.ZonedDateTime")),
ConfigDescriptionParameter.Type.TEXT, false, null, null, null); ConfigDescriptionParameter.Type.TEXT, false, null, null, null, null);
} }
@Test @Test
public void testMapActionInputToConfigDescriptionParameterWhenInstant() { public void testMapActionInputToConfigDescriptionParameterWhenInstant() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.time.Instant")), checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.time.Instant")),
ConfigDescriptionParameter.Type.TEXT, false, null, null, null); ConfigDescriptionParameter.Type.TEXT, false, null, null, null, null);
} }
@Test @Test
public void testMapActionInputToConfigDescriptionParameterWhenDuration() { public void testMapActionInputToConfigDescriptionParameterWhenDuration() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.time.Duration")), checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.time.Duration")),
ConfigDescriptionParameter.Type.TEXT, false, null, null, null); ConfigDescriptionParameter.Type.TEXT, false, null, null, null, null);
} }
@Test @Test
public void testMapActionInputToConfigDescriptionParameterWhenDefaultValue() { public void testMapActionInputToConfigDescriptionParameterWhenDefaultValue() {
Input input = new Input(PARAM_NAME, "int", PARAM_LABEL, PARAM_DESCRIPTION, null, false, null, "-1"); Input input = new Input(PARAM_NAME, "int", PARAM_LABEL, PARAM_DESCRIPTION, null, false, null, "-1");
checkParameter(helper.mapActionInputToConfigDescriptionParameter(input), checkParameter(helper.mapActionInputToConfigDescriptionParameter(input),
ConfigDescriptionParameter.Type.INTEGER, true, "-1", null, null); ConfigDescriptionParameter.Type.INTEGER, true, "-1", null, null, null);
} }
@Test @Test
@ -205,9 +206,9 @@ public class ActionInputHelperTest {
.mapActionInputsToConfigDescriptionParameters(List.of(input1, input2)); .mapActionInputsToConfigDescriptionParameters(List.of(input1, input2));
assertThat(params.size(), is(2)); assertThat(params.size(), is(2));
checkParameter(params.get(0), "Boolean", ConfigDescriptionParameter.Type.BOOLEAN, PARAM_LABEL, checkParameter(params.get(0), "Boolean", ConfigDescriptionParameter.Type.BOOLEAN, PARAM_LABEL,
PARAM_DESCRIPTION, true, "false", null, null); PARAM_DESCRIPTION, true, "false", null, null, null);
checkParameter(params.get(1), "String", ConfigDescriptionParameter.Type.TEXT, PARAM_LABEL, PARAM_DESCRIPTION, checkParameter(params.get(1), "String", ConfigDescriptionParameter.Type.TEXT, PARAM_LABEL, PARAM_DESCRIPTION,
false, null, null, null); false, null, null, null, null);
} }
@Test @Test
@ -476,6 +477,29 @@ public class ActionInputHelperTest {
assertThat(helper.mapSerializedInputToActionInput(input, val), is(val)); assertThat(helper.mapSerializedInputToActionInput(input, val), is(val));
} }
@Test
public void testMapSerializedInputsToActionInputsAppliesDefaults() {
Input inputBoolean = buildInput("BooleanParam", "boolean");
Input inputByte = buildInput("ByteParam", "byte");
Input inputShort = buildInput("ShortParam", "short");
Input inputInteger = buildInput("IntegerParam", "int");
Input inputLong = buildInput("LongParam", "long");
Input inputFloat = buildInput("FloatParam", "float");
Input inputDouble = buildInput("DoubleParam", "double");
ActionType action = new ActionType("action", null,
List.of(inputBoolean, inputByte, inputShort, inputInteger, inputLong, inputFloat, inputDouble));
Map<String, Object> result = helper.mapSerializedInputsToActionInputs(action, Map.of());
assertThat(result.size(), is(7));
assertThat(result.get("BooleanParam"), is(Boolean.FALSE));
assertThat(result.get("ByteParam"), is((byte) 0));
assertThat(result.get("ShortParam"), is((short) 0));
assertThat(result.get("IntegerParam"), is(0));
assertThat(result.get("LongParam"), is(0L));
assertThat(result.get("FloatParam"), is(0.0f));
assertThat(result.get("DoubleParam"), is(0.0));
}
@Test @Test
public void testMapSerializedInputsToActionInputs() { public void testMapSerializedInputsToActionInputs() {
Input input1 = buildInput("BooleanParam", "java.lang.Boolean"); Input input1 = buildInput("BooleanParam", "java.lang.Boolean");
@ -500,13 +524,15 @@ public class ActionInputHelperTest {
} }
private void checkParameter(ConfigDescriptionParameter param, ConfigDescriptionParameter.Type type, private void checkParameter(ConfigDescriptionParameter param, ConfigDescriptionParameter.Type type,
boolean required, @Nullable String defaultValue, @Nullable String context, @Nullable String unit) { boolean required, @Nullable String defaultValue, @Nullable String context, @Nullable String unit,
checkParameter(param, PARAM_NAME, type, PARAM_LABEL, PARAM_DESCRIPTION, required, defaultValue, context, unit); @Nullable BigDecimal step) {
checkParameter(param, PARAM_NAME, type, PARAM_LABEL, PARAM_DESCRIPTION, required, defaultValue, context, unit,
step);
} }
private void checkParameter(ConfigDescriptionParameter param, String name, ConfigDescriptionParameter.Type type, private void checkParameter(ConfigDescriptionParameter param, String name, ConfigDescriptionParameter.Type type,
String label, String description, boolean required, @Nullable String defaultValue, @Nullable String context, String label, String description, boolean required, @Nullable String defaultValue, @Nullable String context,
@Nullable String unit) { @Nullable String unit, @Nullable BigDecimal step) {
assertThat(param.getName(), is(name)); assertThat(param.getName(), is(name));
assertThat(param.getLabel(), is(label)); assertThat(param.getLabel(), is(label));
assertThat(param.getDescription(), is(description)); assertThat(param.getDescription(), is(description));
@ -528,6 +554,11 @@ public class ActionInputHelperTest {
} else { } else {
assertNotNull(param.getUnit()); assertNotNull(param.getUnit());
} }
if (step == null) {
assertNull(param.getStepSize());
} else {
assertThat(param.getStepSize(), is(step));
}
} }
public class TestUnitProvider implements UnitProvider { public class TestUnitProvider implements UnitProvider {