[automation] ActionInputsHelper: Enhance ZonedDateTime & Instant input support (#4440)

Signed-off-by: Florian Hotze <dev@florianhotze.com>
This commit is contained in:
Florian Hotze 2024-11-08 17:59:55 +01:00 committed by GitHub
parent 4eec4a3e45
commit 3bc9ae3e14
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 29 additions and 16 deletions

View File

@ -16,11 +16,9 @@ import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.HashMap;
@ -38,6 +36,7 @@ import org.openhab.core.automation.type.ActionType;
import org.openhab.core.automation.type.Input;
import org.openhab.core.config.core.ConfigDescriptionParameter;
import org.openhab.core.config.core.ConfigDescriptionParameterBuilder;
import org.openhab.core.i18n.TimeZoneProvider;
import org.openhab.core.i18n.UnitProvider;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.QuantityType;
@ -63,10 +62,13 @@ public class ActionInputsHelper {
private final Logger logger = LoggerFactory.getLogger(ActionInputsHelper.class);
private final TimeZoneProvider timeZoneProvider;
private final UnitProvider unitProvider;
@Activate
public ActionInputsHelper(final @Reference UnitProvider unitProvider) {
public ActionInputsHelper(final @Reference TimeZoneProvider timeZoneProvider,
final @Reference UnitProvider unitProvider) {
this.timeZoneProvider = timeZoneProvider;
this.unitProvider = unitProvider;
}
@ -155,11 +157,11 @@ public class ActionInputsHelper {
break;
case "java.time.LocalDateTime":
case "java.util.Date":
case "java.time.ZonedDateTime":
case "java.time.Instant":
context = "datetime";
step = BigDecimal.ONE;
break;
case "java.time.ZonedDateTime":
case "java.time.Instant":
case "java.time.Duration":
// There is no available configuration parameter context for these types.
// A text parameter is used. The expected value must respect a particular format specific
@ -290,11 +292,11 @@ public class ActionInputsHelper {
// Accepted format is: 2007-12-03T10:15:30
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").parse(valueString);
case "java.time.ZonedDateTime" ->
// Accepted format is: 2007-12-03T10:15:30+01:00[Europe/Paris]
ZonedDateTime.parse(valueString);
// Accepted format is: 2007-12-03T10:15:30
LocalDateTime.parse(valueString).atZone(timeZoneProvider.getTimeZone());
case "java.time.Instant" ->
// Accepted format is: 2007-12-03T10:15:30.00Z
Instant.parse(valueString);
// Accepted format is: 2007-12-03T10:15:30
LocalDateTime.parse(valueString).atZone(timeZoneProvider.getTimeZone()).toInstant();
case "java.time.Duration" ->
// Accepted format is: P2DT17H25M30.5S
Duration.parse(valueString);

View File

@ -24,6 +24,7 @@ import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Collection;
import java.util.Date;
@ -43,6 +44,7 @@ import org.junit.jupiter.api.Test;
import org.openhab.core.automation.type.ActionType;
import org.openhab.core.automation.type.Input;
import org.openhab.core.config.core.ConfigDescriptionParameter;
import org.openhab.core.i18n.TimeZoneProvider;
import org.openhab.core.i18n.UnitProvider;
import org.openhab.core.internal.i18n.I18nProviderImpl;
import org.openhab.core.library.types.DecimalType;
@ -58,8 +60,9 @@ public class ActionInputHelperTest {
private static final String PARAM_LABEL = "Label Parameter";
private static final String PARAM_DESCRIPTION = "Description parameter";
private TimeZoneProvider timeZoneProvider = new TestTimeZoneProvider();
private UnitProvider unitProvider = new TestUnitProvider();
private ActionInputsHelper helper = new ActionInputsHelper(unitProvider);
private ActionInputsHelper helper = new ActionInputsHelper(timeZoneProvider, unitProvider);
@Test
public void testMapActionInputToConfigDescriptionParameterWhenBoolean() {
@ -170,13 +173,13 @@ public class ActionInputHelperTest {
@Test
public void testMapActionInputToConfigDescriptionParameterWhenZonedDateTime() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.time.ZonedDateTime")),
ConfigDescriptionParameter.Type.TEXT, false, null, null, null, null);
ConfigDescriptionParameter.Type.TEXT, false, null, "datetime", null, BigDecimal.ONE);
}
@Test
public void testMapActionInputToConfigDescriptionParameterWhenInstant() {
checkParameter(helper.mapActionInputToConfigDescriptionParameter(buildInput("java.time.Instant")),
ConfigDescriptionParameter.Type.TEXT, false, null, null, null, null);
ConfigDescriptionParameter.Type.TEXT, false, null, "datetime", null, BigDecimal.ONE);
}
@Test
@ -422,8 +425,8 @@ public class ActionInputHelperTest {
@Test
public void testMapSerializedInputToActionInputWhenZonedDateTime() {
String valAsString = "2007-12-03T10:15:30+01:00[Europe/Paris]";
ZonedDateTime val = ZonedDateTime.parse(valAsString);
String valAsString = "2007-12-03T10:15:30";
ZonedDateTime val = LocalDateTime.parse(valAsString).atZone(timeZoneProvider.getTimeZone());
Input input = buildInput("java.time.ZonedDateTime");
assertThat(helper.mapSerializedInputToActionInput(input, val), is(val));
assertThat(helper.mapSerializedInputToActionInput(input, valAsString), is(val));
@ -450,8 +453,8 @@ public class ActionInputHelperTest {
@Test
public void testMapSerializedInputToActionInputWhenInstant() {
String valAsString = "2017-12-09T20:15:30.00Z";
Instant val = Instant.parse(valAsString);
String valAsString = "2017-12-09T20:15:30.00";
Instant val = LocalDateTime.parse(valAsString).atZone(timeZoneProvider.getTimeZone()).toInstant();
Input input = buildInput("java.time.Instant");
assertThat(helper.mapSerializedInputToActionInput(input, val), is(val));
assertThat(helper.mapSerializedInputToActionInput(input, valAsString), is(val));
@ -561,6 +564,14 @@ public class ActionInputHelperTest {
}
}
public class TestTimeZoneProvider implements TimeZoneProvider {
@Override
public ZoneId getTimeZone() {
return ZoneId.of("Europe/Paris");
}
}
public class TestUnitProvider implements UnitProvider {
private final Map<Class<? extends Quantity<?>>, Map<SystemOfUnits, Unit<? extends Quantity<?>>>> dimensionMap = I18nProviderImpl