[DSL rule] Add time of day trigger to DSL file syntax (#5440)

* [DSL rule] Add time of day trigger to DSL file syntax

Closes #5435

Exampele of rule:
```
rule "Test time of day trigger"
when
  Time is 20:13
then
  logInfo("Rule","Test")
end
```

For backward compatibility, using "noon" and "midnight" is still supported.
"timer.TimeOfDayTrigger" is now used (instead of "timer.GenericCronTrigger").

Here is the log confirming the execution of the rule at the expected time:
```
20:13:00.531 [INFO ] [org.openhab.core.model.script.Rule  ] - Test
```

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
This commit is contained in:
lolodomo
2026-03-25 21:48:52 +01:00
committed by GitHub
parent 0edae941f1
commit e2aacb11a9
3 changed files with 58 additions and 51 deletions
@@ -39,6 +39,7 @@ import org.openhab.core.automation.internal.module.handler.ItemCommandTriggerHan
import org.openhab.core.automation.internal.module.handler.ItemStateTriggerHandler;
import org.openhab.core.automation.internal.module.handler.SystemTriggerHandler;
import org.openhab.core.automation.internal.module.handler.ThingStatusTriggerHandler;
import org.openhab.core.automation.internal.module.handler.TimeOfDayTriggerHandler;
import org.openhab.core.automation.module.script.internal.handler.AbstractScriptModuleHandler;
import org.openhab.core.automation.module.script.internal.handler.ScriptActionHandler;
import org.openhab.core.events.EventPublisher;
@@ -149,6 +150,7 @@ public class DSLRuleProviderTest extends JavaOSGiTest {
" System started or\n" + //
" Time is noon or\n" + //
" Time is midnight or\n" + //
" Time is 20:57 or\n" + //
" Time cron \"0 0/1 * * * ?\" or\n" + //
" Item X received command ON or\n" + //
" Item Y received update \"A\" or\n" + //
@@ -175,70 +177,71 @@ public class DSLRuleProviderTest extends JavaOSGiTest {
assertThat(rule.getUID(), is("dslruletest-1"));
assertThat(rule.getName(), is("RuleWithAllTriggers"));
assertThat(rule.getTriggers().size(), is(13));
assertThat(rule.getTriggers().size(), is(14));
assertThat(rule.getTriggers().getFirst().getTypeUID(), is(SystemTriggerHandler.STARTLEVEL_MODULE_TYPE_ID));
assertThat(rule.getTriggers().getFirst().getConfiguration().get(SystemTriggerHandler.CFG_STARTLEVEL),
is(new BigDecimal(40)));
assertThat(rule.getTriggers().get(1).getTypeUID(), is(GenericCronTriggerHandler.MODULE_TYPE_ID));
assertThat(rule.getTriggers().get(1).getConfiguration().get(GenericCronTriggerHandler.CFG_CRON_EXPRESSION),
is("0 0 12 * * ?"));
assertThat(rule.getTriggers().get(1).getTypeUID(), is(TimeOfDayTriggerHandler.MODULE_TYPE_ID));
assertThat(rule.getTriggers().get(1).getConfiguration().get(TimeOfDayTriggerHandler.CFG_TIME), is("12:00"));
assertThat(rule.getTriggers().get(2).getTypeUID(), is(GenericCronTriggerHandler.MODULE_TYPE_ID));
assertThat(rule.getTriggers().get(2).getConfiguration().get(GenericCronTriggerHandler.CFG_CRON_EXPRESSION),
is("0 0 0 * * ?"));
assertThat(rule.getTriggers().get(2).getTypeUID(), is(TimeOfDayTriggerHandler.MODULE_TYPE_ID));
assertThat(rule.getTriggers().get(2).getConfiguration().get(TimeOfDayTriggerHandler.CFG_TIME), is("00:00"));
assertThat(rule.getTriggers().get(3).getTypeUID(), is(GenericCronTriggerHandler.MODULE_TYPE_ID));
assertThat(rule.getTriggers().get(3).getConfiguration().get(GenericCronTriggerHandler.CFG_CRON_EXPRESSION),
assertThat(rule.getTriggers().get(3).getTypeUID(), is(TimeOfDayTriggerHandler.MODULE_TYPE_ID));
assertThat(rule.getTriggers().get(3).getConfiguration().get(TimeOfDayTriggerHandler.CFG_TIME), is("20:57"));
assertThat(rule.getTriggers().get(4).getTypeUID(), is(GenericCronTriggerHandler.MODULE_TYPE_ID));
assertThat(rule.getTriggers().get(4).getConfiguration().get(GenericCronTriggerHandler.CFG_CRON_EXPRESSION),
is("0 0/1 * * * ?"));
assertThat(rule.getTriggers().get(4).getTypeUID(), is(ItemCommandTriggerHandler.MODULE_TYPE_ID));
assertThat(rule.getTriggers().get(4).getConfiguration().get(ItemCommandTriggerHandler.CFG_ITEMNAME), is("X"));
assertThat(rule.getTriggers().get(4).getConfiguration().get(ItemCommandTriggerHandler.CFG_COMMAND), is("ON"));
assertThat(rule.getTriggers().get(5).getTypeUID(), is(ItemCommandTriggerHandler.MODULE_TYPE_ID));
assertThat(rule.getTriggers().get(5).getConfiguration().get(ItemCommandTriggerHandler.CFG_ITEMNAME), is("X"));
assertThat(rule.getTriggers().get(5).getConfiguration().get(ItemCommandTriggerHandler.CFG_COMMAND), is("ON"));
assertThat(rule.getTriggers().get(5).getTypeUID(), is(ItemStateTriggerHandler.UPDATE_MODULE_TYPE_ID));
assertThat(rule.getTriggers().get(5).getConfiguration().get(ItemStateTriggerHandler.CFG_ITEMNAME), is("Y"));
assertThat(rule.getTriggers().get(5).getConfiguration().get(ItemStateTriggerHandler.CFG_STATE), is("A"));
assertThat(rule.getTriggers().get(6).getTypeUID(), is(ItemStateTriggerHandler.UPDATE_MODULE_TYPE_ID));
assertThat(rule.getTriggers().get(6).getConfiguration().get(ItemStateTriggerHandler.CFG_ITEMNAME), is("Y"));
assertThat(rule.getTriggers().get(6).getConfiguration().get(ItemStateTriggerHandler.CFG_STATE), is("A"));
assertThat(rule.getTriggers().get(6).getTypeUID(), is(ItemStateTriggerHandler.CHANGE_MODULE_TYPE_ID));
assertThat(rule.getTriggers().get(6).getConfiguration().get(ItemStateTriggerHandler.CFG_ITEMNAME), is("Z"));
assertThat(rule.getTriggers().get(6).getConfiguration().get(ItemStateTriggerHandler.CFG_PREVIOUS_STATE),
assertThat(rule.getTriggers().get(7).getTypeUID(), is(ItemStateTriggerHandler.CHANGE_MODULE_TYPE_ID));
assertThat(rule.getTriggers().get(7).getConfiguration().get(ItemStateTriggerHandler.CFG_ITEMNAME), is("Z"));
assertThat(rule.getTriggers().get(7).getConfiguration().get(ItemStateTriggerHandler.CFG_PREVIOUS_STATE),
is("1"));
assertThat(rule.getTriggers().get(6).getConfiguration().get(ItemStateTriggerHandler.CFG_STATE), is("2"));
assertThat(rule.getTriggers().get(7).getConfiguration().get(ItemStateTriggerHandler.CFG_STATE), is("2"));
assertThat(rule.getTriggers().get(7).getTypeUID(), is(GroupCommandTriggerHandler.MODULE_TYPE_ID));
assertThat(rule.getTriggers().get(7).getConfiguration().get(GroupCommandTriggerHandler.CFG_GROUPNAME),
assertThat(rule.getTriggers().get(8).getTypeUID(), is(GroupCommandTriggerHandler.MODULE_TYPE_ID));
assertThat(rule.getTriggers().get(8).getConfiguration().get(GroupCommandTriggerHandler.CFG_GROUPNAME),
is("G1"));
assertThat(rule.getTriggers().get(7).getConfiguration().get(GroupCommandTriggerHandler.CFG_COMMAND), is("UP"));
assertThat(rule.getTriggers().get(8).getConfiguration().get(GroupCommandTriggerHandler.CFG_COMMAND), is("UP"));
assertThat(rule.getTriggers().get(8).getTypeUID(), is(GroupStateTriggerHandler.UPDATE_MODULE_TYPE_ID));
assertThat(rule.getTriggers().get(8).getConfiguration().get(GroupStateTriggerHandler.CFG_GROUPNAME), is("G2"));
assertThat(rule.getTriggers().get(8).getConfiguration().get(GroupStateTriggerHandler.CFG_STATE), is("10|°C"));
assertThat(rule.getTriggers().get(9).getTypeUID(), is(GroupStateTriggerHandler.UPDATE_MODULE_TYPE_ID));
assertThat(rule.getTriggers().get(9).getConfiguration().get(GroupStateTriggerHandler.CFG_GROUPNAME), is("G2"));
assertThat(rule.getTriggers().get(9).getConfiguration().get(GroupStateTriggerHandler.CFG_STATE), is("10|°C"));
assertThat(rule.getTriggers().get(9).getTypeUID(), is(GroupStateTriggerHandler.CHANGE_MODULE_TYPE_ID));
assertThat(rule.getTriggers().get(9).getConfiguration().get(GroupStateTriggerHandler.CFG_GROUPNAME), is("G3"));
assertThat(rule.getTriggers().get(9).getConfiguration().get(GroupStateTriggerHandler.CFG_PREVIOUS_STATE),
assertThat(rule.getTriggers().get(10).getTypeUID(), is(GroupStateTriggerHandler.CHANGE_MODULE_TYPE_ID));
assertThat(rule.getTriggers().get(10).getConfiguration().get(GroupStateTriggerHandler.CFG_GROUPNAME), is("G3"));
assertThat(rule.getTriggers().get(10).getConfiguration().get(GroupStateTriggerHandler.CFG_PREVIOUS_STATE),
is("PLAY"));
assertThat(rule.getTriggers().get(9).getConfiguration().get(GroupStateTriggerHandler.CFG_STATE), is("PAUSE"));
assertThat(rule.getTriggers().get(10).getConfiguration().get(GroupStateTriggerHandler.CFG_STATE), is("PAUSE"));
assertThat(rule.getTriggers().get(10).getTypeUID(), is(ThingStatusTriggerHandler.UPDATE_MODULE_TYPE_ID));
assertThat(rule.getTriggers().get(10).getConfiguration().get(ThingStatusTriggerHandler.CFG_THING_UID),
is("T1"));
assertThat(rule.getTriggers().get(10).getConfiguration().get(ThingStatusTriggerHandler.CFG_STATUS),
is("OFFLINE"));
assertThat(rule.getTriggers().get(11).getTypeUID(), is(ThingStatusTriggerHandler.CHANGE_MODULE_TYPE_ID));
assertThat(rule.getTriggers().get(11).getTypeUID(), is(ThingStatusTriggerHandler.UPDATE_MODULE_TYPE_ID));
assertThat(rule.getTriggers().get(11).getConfiguration().get(ThingStatusTriggerHandler.CFG_THING_UID),
is("T2"));
assertThat(rule.getTriggers().get(11).getConfiguration().get(ThingStatusTriggerHandler.CFG_PREVIOUS_STATUS),
is("OFFLINE"));
is("T1"));
assertThat(rule.getTriggers().get(11).getConfiguration().get(ThingStatusTriggerHandler.CFG_STATUS),
is("OFFLINE"));
assertThat(rule.getTriggers().get(12).getTypeUID(), is(ThingStatusTriggerHandler.CHANGE_MODULE_TYPE_ID));
assertThat(rule.getTriggers().get(12).getConfiguration().get(ThingStatusTriggerHandler.CFG_THING_UID),
is("T2"));
assertThat(rule.getTriggers().get(12).getConfiguration().get(ThingStatusTriggerHandler.CFG_PREVIOUS_STATUS),
is("OFFLINE"));
assertThat(rule.getTriggers().get(12).getConfiguration().get(ThingStatusTriggerHandler.CFG_STATUS),
is("ONLINE"));
assertThat(rule.getTriggers().get(12).getTypeUID(), is(ChannelEventTriggerHandler.MODULE_TYPE_ID));
assertThat(rule.getTriggers().get(12).getConfiguration().get(ChannelEventTriggerHandler.CFG_CHANNEL),
assertThat(rule.getTriggers().get(13).getTypeUID(), is(ChannelEventTriggerHandler.MODULE_TYPE_ID));
assertThat(rule.getTriggers().get(13).getConfiguration().get(ChannelEventTriggerHandler.CFG_CHANNEL),
is("a:b:c:1"));
assertThat(rule.getTriggers().get(12).getConfiguration().get(ChannelEventTriggerHandler.CFG_CHANNEL_EVENT),
assertThat(rule.getTriggers().get(13).getConfiguration().get(ChannelEventTriggerHandler.CFG_CHANNEL_EVENT),
is("START"));
}