I’m not at all sure that MIN/MAX aggregations are implemented for DateTime Group types. Not every function makes sense for every possible type e.g. what should AVG or SUM do with dates?
The docs do say that MIN/MAX/AVG are for “decimal type” (Number)
EDIT - so, how to do it instead? Using Group functions is a neat idea, but you’d have to do it with a Group of Number Items holding the “timestamp” as an epoch integer.
Easy enough to populate those from your timestamping rule.
Or abandon the group, and have your rule populate a dedicated “oldest” Item. The rule would have to retrieve the “old” individual value before updating the timestamp, and compare with current “oldest”.
Hmm, then you’d still need to search for the next-oldest. That’s an interesting little task … I can feel a sorted list coming on somewhere.
In Rules DSL a map/reduce would work I think. Something like:
var oldestDT = MyDateTimes.members.map[(state as DateTimeType).zonedDateTime].reduce[oldest, curr | oldest = if(curr.isBefore(oldest)) curr else oldest]
oldestDT = reduce(lambda: oldest, curr: oldest = curr if curr.isBefore(oldest) else oldest,
[items[dt.name].getZonedDateTime() for dt in ir.getItem("MyDateTimes")])
I just typed in the above two lines, there may be typos, especially in the Python verison. See Design Pattern: Working with Groups in Rules for details.
Thanks for the help!
I did it like this:
In the rule I changed to
Group:Number:MIN gLastSeen “Last Seen [JS(millisToDate.js):%s]” (gHome)
return new Date(parseInt(i)).toString();
I am also trying to a get the oldest lastupdate datetime from a group.
rule "Record LastUpdateTest"
Member of LastUpdateTest changed
logInfo("LastUpdateTest", "Groupmembertest start")
var oldestDT = LastUpdateTest.members.map[(state as DateTimeType).zonedDateTime].reduce[oldest, curr | oldest = if(curr.isBefore(oldest)) curr else oldest]
logInfo("LastUpdateTest", "Groupmembertest end")
I get the error:
Rule ‘Record LastUpdateTest’: Couldn’t invoke ‘assignValueTo’ for feature param oldest
The group LastUpdateTest contains only DateTime items. They are linked to zwave devices with the profile timestamp-update.
I think the reduce is wrong. You don’t do the assignment in the lambda.
....reduce[oldest, curr | if(curr.isBefore(oldest)) curr else oldest]
Yes, it works now. Must made that error when copied and corrected it for my enviroment.
I coincidentally stepped into this and started thinking about enhancing our available group aggregation function by support for
MAX. What I found was an undocumented bunch of DateTime group functions:
EARLIEST. I guess they will help you to get what you want.
Group:DateTime:LATEST gLastSeen "Last Seen [%1$td.%1$tm.%1$tY %1$tH:%1$tM:%1$tS]" <calendar>
Group:DateTime:EARLIEST gLatestUpdate "Latest Update [%1$td.%1$tm.%1$tY %1$tH:%1$tM:%1$tS]" <calendar>
PR for updating the docs: https://github.com/openhab/openhab-docs/pull/1206
// Edit: I will add an example tomorrow to clarify the behavior.
Useful companion features to channel profiles
Wonder how long those have been there and how many other little useful features are hiding in OH like this. I could have used this years ago. Great find!
They are available for more than two years (see PR). And I found a piece of documentation in the Concepts -> Items section. Imo Configuration Guide -> Items is a better place for it. No need to describe it twice. Just add a cross reference in the first location.
Assuming we have a Group containing three timestamps:
EARLIEST function returns
LATEST function returns