Greetings!
I have been learning OpenHAB2 for the last month, while converting my home automation from Vera 3 (Mios) control over to OpenHAB2.2. I am now just using the Vera 3 as the Zwave controller, but all automation is done by OpenHAB2. I didn’t even know OpenHAB existed until a month ago, and I’m hooked! I’m amazed by the community involvement, and would like to start giving back, so I’ll start with this.
I have a notification rule when my garage door is opened, and then a separate notification if it stays open for more than an hour (and every hour after that). I wanted to display the time it’s been open in the notification, and have some other things that would be nice to display an elapsed time for as well, so I made a lambda function that will return a string in the form 00:00:00 (hr:min:sec) or 1d 00:00:00 (days hr:min:sec) if the elapsed time is greater than a day.
Here is the Lambda function, which you would place at the top of any .rules file it is used in:
// Lambda Function to calculate elapsed time
val Functions$Function1<DateTimeType, String> getElapsed= [ startTime |
// Get the elapsed time from a DateTimeType time to now
// Call using: val String elapsed = getElapsed.apply(StartTime_Item.state)
var String eTime = "00:00:00"
if (startTime !== NULL) {
val eSecs = (now.millis - (startTime.zonedDateTime.toInstant.toEpochMilli as Number)) / 1000
// Calculate d/h/m/s without using modulus
val d = (eSecs / (60*60*24)).intValue // Div by 86400
val h = ((eSecs - (d*60*60*24)) / (60*60)).intValue // Div by 3600
val m = ((eSecs - (d*60*60*24) - (h*60*60)) / 60).intValue // Div by 60
val s = (eSecs - (d*60*60*24) - (h*60*60) - (m*60)) // Remainder = secs
// Format the string as "00:00:00" (< 1 day) or "1d 00:00:00" (>= 1 day)
eTime = String::format("%1$02d:%2$02d:%3$02.0f",h,m,s) // 02.1f or 02.1d (float or int)
if (d >= 1) eTime = String::format("%1$dd %2$02d:%3$02d:%4$02.0f",d,h,m,s) // Include days (d)
}
eTime // Return the string
]
You then call the lambda function from within a rule passing only the start time item (DateTime item) state:
val String elapsed = getElapsed.apply(StartTime_Item.state)
And then use the variable “elapsed” wherever you need the elapsed time! I could not get modulus (%) to work in the rule, so I did it the long way (thanks to pensionado’s code in this post: Does openhab2 not support % (remainder) operator?). If the DateTime state passed to the function is NULL, the function returns an elapsed time of 00:00:00 (zero) and doesn’t throw an error.
If you have any comments or suggestions, please chime in, I’m pretty new at this.
Cheers!