may I ask for some advice on how to access time series information e.g. through a JRuby rule (@JimT)? I got the time series data persisted with the inmemory service. Now I want to find the 3 lowest value elements in the time series. I built something in JS but its working off of the incoming JSON, not the time series. Its parsing the JSON into an array, sorting the array and that way gives me access to the lowest value elements through the array index. Can one send me an example how to use the time series to achieve something similar?
How do I get a subset of the time series first? Like all values for today. In DSL I’m trying to use the persistence extensions like .getAllStatesUntil(ZonedDateTime) or getAllStatesBetween(ZonedDateTime, ZonedDateTime). JRuby has access to those too, no?
I’m not sure I understand why you’ve had to go about messing with the JSON like that in JS. Once it’s in database it should be a simple manner of:
var futureItems = items.myItem.getAllStatesUntil(time.toZDT('13:00')); // get all states until 13:00 today
And then, as with jRuby, you can do anything you can do with an Array. To get the three lowest values:
I’m assuming you still want the timestamp associated with the three lowest values.
I’m not trying to argue you shouldn’t use jRuby. I’m just pointing out that what you want to do is also possible in JS without using the round about approach you are using.
Do you want to filter what’s in the time series for only today’s timestamp, or do you want to get data from persistence? Those are two different things, no?
I’m trying to find my way through DSL, JS, JRuby - whatever works. I’m most familiar with DSL, have 2 JRuby rules though and used JS for transformations only so far.
So I’m receiving a JSON with time stamps and data that gets persisted as a time series. That time series may contain data across multiple days. I want to pull the data (states?) for today from the time series into an array that I can process like to find the 3 lowest values (states?). I don’t care about the associated time stamps (yet).
Reading the JS code from Rich looks like its close. Not sure yet what that if/else section does. I guess I will explore JS rules next
BTW, in DSL I get an error when i do this:
val allStates = TS.getAllStatesUntil(ZonedDateTime.now().with(LocalTime.MIDNIGHT).plusDays(1),"inmemory").getState()
I get in the log:
2024-09-13 17:08:20.624 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'test-1' failed: 'getState' is not a member of 'java.lang.Iterable<org.openhab.core.persistence.HistoricItem>'; line 14, column 18, length 112 in test
You can either grab this data once you’ve parsed the json data, or once you’ve built the time series, or you can extract it out of persistence after you’ve persisted it.
I don’t know your json data structure / code, but with time series:
I tried your “Using persistence” example as this is what I want to do. How do I point to the right persistence service of the time series? Default is rrdj4 while the time series item “TS” is persisted using inmemory service.
begin_of_day = LocalTime::MIDNIGHT.to_zoned_date_time
end_of_day = begin_of_day.plus(1.day)
lowest_3_states = persistence(:inmemory) do
TS.all_states_between(begin_of_day, end_of_day).map(&:state).sort.take(3)
end
Use persistence! to indicate that you’d like to set the given persistence service as the default for the subsequent calls within this script (only!)
persistence!(:inmemory) # This will apply to this entire script only
begin_of_day = LocalTime::MIDNIGHT.to_zoned_date_time
end_of_day = begin_of_day.plus(1.day)
lowest_3_states = TS.all_states_between(begin_of_day, end_of_day).map(&:state).sort.take(3)