How to convert DateTime-Item (DateTimeType) to DateTime in rules

I would like to isolate in a rule the hour from a DateTime-Item like Sunrise_time into a Number-variable.
For DateTime like now I use now.getHourOfDay for that.
How can I do this or is it posible to convert the DateTimeType to DateTime?

import java.util.Calendar

...

    // in a rule
    hourOfDay = (Sunrise_time.state as DateTimeType).calendar.get(Calendar::HOUR_OF_DAY)
2 Likes

I’m trying to set limits on when a light comes in response to a MQTT sensor based on a range of hours in a day (like, between the hours of 6AM and 10PM the light goes on, otherwise there is no change to the light status). So, in other languages I’ve taken the current hour of the time object and compared that to a range.

I have a MQTT item like so:

DateTime    OfficeMotion_time       "Office Motion Last Detection"                  { channel="mqtt:topic:RTL_433:office_motion_time"}

I have a test rule like so:

import java.util.Calendar
val logName = "office.rules"
rule "Office Motion Detected"
    when 
        Item OfficeMotion_time changed
    then
        logInfo(logName, OfficeMotion_time.state.toString)
        hourOfDay = (OfficeMotion_time.state as DateTimeType).calendar.get(Calendar::HOUR_OF_DAY)
        logInfo(logName, hourOfDay)
    }
end

I’m getting an error like this:

2020-11-01 13:12:39.922 [INFO ] [.smarthome.model.script.office.rules] - 2020-11-01T13:12:39.000-0800
2020-11-01 13:12:39.922 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Office Motion Detected': An error occurred during the script execution: Couldn't invoke 'assignValueTo' for feature JvmVoid:  (eProxyURI: office.rules#|::0.2.0.2.0.1::0::/1)

What is the error here?

logInfo() requires two string parameters.

I added a dummy string to the log like this:

 logInfo(logName, OfficeMotion_time.state.toString)
 hourOfDay = (OfficeMotion_time.state as DateTimeType).calendar.get(Calendar::HOUR_OF_DAY)
 logInfo(logName, "hello")

The log says this:

2020-11-02 08:41:54.229 [INFO ] [.smarthome.model.script.office.rules] - 2020-11-02T08:41:52.000-0800
2020-11-02 08:41:54.231 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Office Motion Detected': An error occurred during the script execution: Couldn't invoke 'assignValueTo' for feature JvmVoid:  (eProxyURI: office.rules#|::0.2.0.2.0.2::0::/1)

The issue is the second line.

Looking at org.eclipse.smarthome.core.library.types for DateTimeType, there doesn’t appear to be a method to extract the hours. Is the only option to parse the date string, get the hour and convert that to an int?

Well, this is fairly comprehensive

Thanks - I’m on OH 2.5.3 so this was helpful:

Using that, these work to get hours:

rule "testing"
when
    System started
then
    logInfo("rules", "Testing")

    // now is Joda DateTime class
    var hours = now.getHourOfDay()
    logInfo("rules", hours.toString())

    // OfficeMotion_time is a DateTime object so convert to Joda
    val jodaValue = new DateTime((OfficeMotion_time.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli)
    var hours_2 = jodaValue.getHourOfDay()
    logInfo("rules", hours_2.toString())

end
1 Like

ZonedDateTime has a getHour method.

Thanks, and to complete my example here is that alternative

// Another alternative
val jodaValue2 = (OfficeMotion_time.state as DateTimeType).zonedDateTime
var hours_3 = jodaValue2.getHour()
logInfo("rules", hours_3.toString())

And all this is to be depreciated in OH 3, which ditches Jodatime for Java Time

1 Like