Support offset in DateTimeTrigger (#4271)

Signed-off-by: Jimmy Tanagra <jcode@tanagra.id.au>
This commit is contained in:
jimtng 2024-09-08 15:54:45 +10:00 committed by GitHub
parent 3e912eca4b
commit 69dc83237b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 41 additions and 2 deletions

View File

@ -52,6 +52,7 @@ import org.slf4j.LoggerFactory;
* based on a {@link org.openhab.core.library.types.DateTimeType} stored in an item
*
* @author Jan N. Klug - Initial contribution
* @author Jimmy Tanagra - Add offset support
*/
@NonNullByDefault
public class DateTimeTriggerHandler extends BaseTriggerModuleHandler
@ -60,6 +61,7 @@ public class DateTimeTriggerHandler extends BaseTriggerModuleHandler
public static final String MODULE_TYPE_ID = "timer.DateTimeTrigger";
public static final String CONFIG_ITEM_NAME = "itemName";
public static final String CONFIG_TIME_ONLY = "timeOnly";
public static final String CONFIG_OFFSET = "offset";
private static final DateTimeFormatter CRON_FORMATTER = DateTimeFormatter.ofPattern("s m H d M * uuuu");
private static final DateTimeFormatter CRON_TIMEONLY_FORMATTER = DateTimeFormatter.ofPattern("s m H * * * *");
@ -71,6 +73,7 @@ public class DateTimeTriggerHandler extends BaseTriggerModuleHandler
private final @Nullable EventFilter eventFilter;
private String cronExpression = CronAdjuster.REBOOT;
private Boolean timeOnly = false;
private Long offset = 0L;
private @Nullable ScheduledCompletableFuture<?> schedule;
private @Nullable ServiceRegistration<?> eventSubscriberRegistration;
@ -88,6 +91,7 @@ public class DateTimeTriggerHandler extends BaseTriggerModuleHandler
this.eventFilter = new TopicPrefixEventFilter("openhab/items/" + itemName + "/");
this.timeOnly = ConfigParser.valueAsOrElse(module.getConfiguration().get(CONFIG_TIME_ONLY), Boolean.class,
false);
this.offset = ConfigParser.valueAsOrElse(module.getConfiguration().get(CONFIG_OFFSET), Long.class, 0L);
eventSubscriberRegistration = bundleContext.registerService(EventSubscriber.class.getName(), this, null);
try {
process(itemRegistry.getItem(itemName).getState());
@ -153,8 +157,8 @@ public class DateTimeTriggerHandler extends BaseTriggerModuleHandler
cancelScheduler();
if (!CronAdjuster.REBOOT.equals(cronExpression)) {
schedule = scheduler.schedule(this, cronExpression);
logger.debug("Scheduled cron job '{}' for trigger '{}'.", module.getConfiguration().get(CONFIG_ITEM_NAME),
module.getId());
logger.debug("Scheduled cron job '{}' from item '{}' for trigger '{}'.", cronExpression,
module.getConfiguration().get(CONFIG_ITEM_NAME), module.getId());
}
}
@ -174,6 +178,7 @@ public class DateTimeTriggerHandler extends BaseTriggerModuleHandler
} else if (value instanceof DateTimeType dateTimeType) {
boolean itemIsTimeOnly = dateTimeType.toString().startsWith("1970-01-01T");
cronExpression = dateTimeType.getZonedDateTime().withZoneSameInstant(ZoneId.systemDefault())
.plusSeconds(offset.longValue())
.format(timeOnly || itemIsTimeOnly ? CRON_TIMEONLY_FORMATTER : CRON_FORMATTER);
startScheduler();
} else {

View File

@ -29,6 +29,12 @@
"value": "false"
}
]
},
{
"name": "offset",
"type": "INTEGER",
"label": "Offset",
"description": "The offset in seconds to add to the time of the item."
}
]
}

View File

@ -396,6 +396,8 @@ module-type.timer.DateTimeTrigger.config.timeOnly.label = Time only
module-type.timer.DateTimeTrigger.config.timeOnly.description = Specifies whether only the time of the item should be compared or the date and time.
module-type.timer.DateTimeTrigger.config.timeOnly.option.true = Yes
module-type.timer.DateTimeTrigger.config.timeOnly.option.false = No
module-type.timer.DateTimeTrigger.config.offset.label = Offset
module-type.timer.DateTimeTrigger.config.offset.description = The offset in seconds to add to the time of the item.
# timer.DayOfWeekCondition

View File

@ -80,4 +80,30 @@ public class DateTimeTriggerHandlerTest {
verify(mockScheduler).schedule(eq(handler), eq("0 0 0 11 8 * 2022"));
}
@Test
public void testOffsetPositive() {
ZonedDateTime zdt = ZonedDateTime.of(2024, 6, 7, 0, 0, 0, 0, ZoneId.systemDefault());
item.setState(new DateTimeType(zdt));
when(mockTrigger.getConfiguration())
.thenReturn(new Configuration(Map.ofEntries(entry(DateTimeTriggerHandler.CONFIG_ITEM_NAME, ITEM_NAME),
entry(DateTimeTriggerHandler.CONFIG_OFFSET, 10))));
DateTimeTriggerHandler handler = new DateTimeTriggerHandler(mockTrigger, mockScheduler, mockItemRegistry,
mockBundleContext);
verify(mockScheduler).schedule(eq(handler), eq("10 0 0 7 6 * 2024"));
}
@Test
public void testOffsetNegative() {
ZonedDateTime zdt = ZonedDateTime.of(2024, 6, 7, 0, 0, 0, 0, ZoneId.systemDefault());
item.setState(new DateTimeType(zdt));
when(mockTrigger.getConfiguration())
.thenReturn(new Configuration(Map.ofEntries(entry(DateTimeTriggerHandler.CONFIG_ITEM_NAME, ITEM_NAME),
entry(DateTimeTriggerHandler.CONFIG_OFFSET, -10))));
DateTimeTriggerHandler handler = new DateTimeTriggerHandler(mockTrigger, mockScheduler, mockItemRegistry,
mockBundleContext);
verify(mockScheduler).schedule(eq(handler), eq("50 59 23 6 6 * 2024"));
}
}