OH2 to OH3 Simple date based rule Help

Hi Folks,

I have been quietly bashing away at migrating from OH2 to OH3 (currently on RC1) and trying not to raise daft questions as I know everybody is busy beavering away trying to get OH3 ready for release, I have however ran into a few rule rule problems so wondering if anybody can help?

I’m essentially moving from OH2 text based things/items/rules to OH3 UI based syntax to try and adapt to this new way (been slow going) and getting there gradually, for rules I’m moving (as mentioned) from test based to using the UI and using dsl rules so that I can keep the main “rule action” syntax as is (assuming this is an ok approach).

First is a simple rule that uses “Date()” syntax but even searching the forum cant get my head round how to make it work:

OH2 text based rule looks like:

rule "Generate Time of Day Events"
when
	System started or
    Item CurrentTime received update
then
    val now = new Date()
    val sunset = new Date((SunsetStart_Time.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli)
    val sunrise = new Date((SunriseStart_Time.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli)

    if((now.getTime-(now.getTime%60000)) == (sunrise.getTime-(sunrise.getTime%60000))) {
        //logInfo("time-of-day.rules", "Start of Sunrise!")
        SunriseStart_Event.postUpdate(ON)
    }
    else if((now.getTime-(now.getTime%60000)) == (sunset.getTime-(sunset.getTime%60000))) {
        //logInfo("time-of-day.rules", "Start of Sunset!")
        SunsetStart_Event.postUpdate(ON)
    }
end

The new DSL rule looks like:

triggers:
  - id: "1"
    configuration:
      startlevel: 20
    type: core.SystemStartlevelTrigger
  - id: "2"
    configuration:
      itemName: CurrentTime
    type: core.ItemStateUpdateTrigger
conditions: []
actions:
  - inputs: {}
    id: "3"
    configuration:
      type: application/vnd.openhab.dsl.rule
      script: >
        val now = new Date()

        val sunset = new Date((SunsetStart_Time.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli)

        val sunrise = new Date((SunriseStart_Time.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli)


        if((now.getTime-(now.getTime%60000)) == (sunrise.getTime-(sunrise.getTime%60000))) {
            //logInfo("time-of-day.rules", "Start of Sunrise!")
            SunriseStart_Event.postUpdate(ON)
          }
          else if((now.getTime-(now.getTime%60000)) == (sunset.getTime-(sunset.getTime%60000))) {
            //logInfo("time-of-day.rules", "Start of Sunset!")
            SunsetStart_Event.postUpdate(ON)
          }
    type: script.ScriptAction

The logged error when testing the rule is:

2020-12-17 12:31:16.207 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID '6ee051d55f' failed: val now = new  ___ Date()
val sunset = new Date((SunsetStart_Tim ___ e.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli)
val sunrise = new Date((SunriseStart_Time.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli)

if((now.getTime-(now.getTime%60000)) == (sunrise.getTime-(sunrise.getTime%60000))) {
    //logInfo("time-of-day.rules", "Start of Sunrise!")
    SunriseStart_Event.postUpdate(ON)
  }
  else if((now.getTime-(now.getTime%60000)) == (sunset.getTime-(sunset.getTime%60000))) {
    //logInfo("time-of-day.rules", "Start of Sunset!")
    SunsetStart_Event.postUpdate(ON)
  }

   1. Date cannot be resolved.; line 1, column 14, length 4
   2. Date cannot be resolved.; line 2, column 38, length 4
   3. Date cannot be resolved.; line 3, column 140, length 4

The second rule issue is around the ookla/speedtest rule, has anyone got that working on OH3?, and I will paste the issue in a separate topic later.
Cheers

Change to

val sunset = SunsetStart_Time.state.getZonedDatetime.toInstant.toEpochMilli

It looks like you are trying to measure things down to the minute. It might make the rule more clear if you use something like

val now_min = now.withSecond(0).withNano(0)
if(now_min == sunrise) {

You don’t need to create a Date() to get now. You already have an implicit variable called now that is a ZonedDateTime that represents that instant when now was referenced.

The specific error you are seeing is that Date is not automatically imported to the context and UI generated rules can’t import stuff so you would need to use the full class name: java.util.Date.

Can’t help with the second problem, but if it uses executeCommandLine, the arguments to executeCommandLine changed in OH 3.

Hi Rich,

Thanks for the guidance, Ive setup a basic test using the above suggestion, see below, but still getting an error when running the test rule?

val sunset = SunsetStart_Time.state.getZonedDatetime.toInstant.toEpochMilli
val sunrise = SunriseStart_Time.state.getZonedDatetime.toInstant.toEpochMilli
val now_min = now.withSecond(0).withNano(0)

logInfo("time-of-day.rules", "sunset" + sunset)
logInfo("time-of-day.rules", "sunrise" + sunrise)
logInfo("time-of-day.rules", "now_min" + now_min)

Getting:

2020-12-17 17:08:10.448 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID '6ee051d55f' failed: val sunset = SunsetStart_Time.state. ___ getZonedDatetime.toInstant.toEpochMilli
val sunrise = SunriseStart_Time.state.getZonedDatetime.toInstant.toEpochMilli
val now_min = now.withSecond(0).withNano(0)

logInfo("time-of-day.rules", "sunset" + sunset)
logInfo("time-of-day.rules", "sunrise" + sunrise)
logInfo("time-of-day.rules", "now_min" + now_min)

   1. The method or field getZonedDatetime is undefined for the type State; line 1, column 36, length 16
   2. The method or field getZonedDatetime is undefined for the type State; line 2, column 114, length 16

Guessing I’m missing something

The second rule relating to ookla/speedtest is resolved and did turn out to be the new syntax for executeCommandLine so that’s all resolved.

Cheers

You need to cast the state to a DateTimeType.

val sunset = (SunsetStart_Time.state as DateTimeType).getZonedDatetime.toInstant.toEpochMilli

Hi,
I have tried that but still no joy, I need to bring OH2 back online for this evening so will take a look again tomorrow, thanks the the help.

2020-12-17 18:02:53.587 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID '6ee051d55f' failed: val sunset = (SunsetStart_Time.state as DateTimeType). ___ getZonedDatetime.toInstant.toEpochMilli
val sunrise = (SunriseStart_Time.state as DateTimeType).getZonedDatetime.toInstant.toEpochMilli
val now_min = now.withSecond(0).withNano(0)

logInfo("time-of-day.rules", "sunset" + sunset)
logInfo("time-of-day.rules", "sunrise" + sunrise)
logInfo("time-of-day.rules", "now_min" + now_min)

/*
if((now.getTime-(now.getTime%60000)) == (sunrise.getTime-(sunrise.getTime%60000))) {
    logInfo("time-of-day.rules", "Start of Sunrise!")
    SunriseStart_Event.postUpdate(ON)
  }
  else if((now.getTime-(now.getTime%60000)) == (sunset.getTime-(sunset.getTime%60000))) {
    logInfo("time-of-day.rules", "Start of Sunset!")
    SunsetStart_Event.postUpdate(ON)
  }
 */

   1. The method or field getZonedDatetime is undefined for the type DateTimeType; line 1, column 54, length 16
   2. The method or field getZonedDatetime is undefined for the type DateTimeType; line 2, column 150, length 16

getZonedDateTime

Thanks Rich,
Couldn’t see the wood for the tree’s, that sorted the date functions, I will go play with the rest of the actual rule now and continue my foray into OH3.
Regards