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

View File

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