This will not do what you expect. postUpdate() is asynchronous; the instruction is sent on to openHAB event bus and passed to interested bindings, rules, UI etc, and also updating the actual Item state. Takes a few milliseconds.
Meantime, your rule does not stop and wait. If you retrieve Item state in the following lines, you will likely get the old state still.
Items are not simple variables.
That’s fine, you already know what you sent to postUpdate - use that directly.
var x = AT_Dachflache_Wind.maximumSince(now.minusMinutes(5), "jdbc")
AT_Dachflache_Wind_Max5.postUpdate(x)
logInfo("test", "posted " + x.toString)
It’s going to help your analysis not to try to do everything on one line anyway.
The next pitfall is what the persistence method returns. Clue -
See
maximumSince words -
Gets the maximum value of the State of a persisted Item since a certain point in time (returns HistoricItem)
What you get back is an object - the max record AND a timestamp. That code snippet will fail because x is a complex object. You’d be interested in x.state
rule "Wind Max 5 Test"
when
Item AT_Dachflache_Wind changed
then
var wmax = AT_Dachflache_Wind.maximumSince(now.minusMinutes(5), "jdbc") as Number
AT_Dachflache_Wind_Max5.postUpdate(wmax)
logInfo ("Wind test", "Wind posted " + wmax.toString)
end
I added “as Number” to the var line because otherwise VS Code said:
Type mismatch: cannot convert from HistoricItem to String
However, there is no log output at all.
I guess this is the corresponding error:
2022-04-05 15:36:59.876 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'wind-2' failed: Could not cast org.openhab.core.persistence.extensions.PersistenceExtensions$1@17c96a1 to java.lang.Number; line 25, column 13, length 70 in wind
Thank you @rossko57, unfortunately storing the correct values still doesn’t seem to work. To illustrate what I mean here is a log part which shows entries for your “Maximum wind gust of the day” rule:
2022-04-06 14:27:11.493 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'AT_Dachflache_Wind' changed from 8.28 to 12.24
2022-04-06 14:27:11.530 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'AT_Dachflache_Wind_MaxDay' changed from 11.933541666666667 to 12.24
2022-04-06 14:27:11.541 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'AT_Dachflache_Wind_MaxDay_Time' changed from 2022-04-06T14:08:00.000+0200 to 2022-04-06T14:27:11.510+0200
2022-04-06 14:27:15.210 [INFO ] [penhab.core.model.script.org.openhab] - Today's max wind gust is 11.933541666666667 m/s at 02:08:00 PM
2022-04-06 14:27:15.170 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'AT_Dachflache_Wind' changed from 12.24 to 10.44
2022-04-06 14:27:15.191 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'AT_Dachflache_Wind_MaxDay' changed from 12.24 to 11.933541666666667
2022-04-06 14:27:15.211 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'AT_Dachflache_Wind_MaxDay_Time' changed from 2022-04-06T14:27:11.510+0200 to 2022-04-06T14:08:00.000+0200
2022-04-06 14:27:20.666 [INFO ] [penhab.core.model.script.org.openhab] - Today's max wind gust is 11.933541666666667 m/s at 02:08:00 PM
As you can see the max. value jumps to 12.24 m/s at 14:27:11. At 14:27:15, it goes down to 11.93 m/s. That doesn’t make sense because the previously recorded value was higher. So there still seems to be an issue with persistence. Tbh, I can’t figure out how to look into the table of my MariaDB file. Maybe the values don’t get stored correctly in the database.
This is your rule for the and mine for the previous five minutes:
rule "Wind Maximum 5 Minuten"
when
//Time cron "0 0/5 * * * ?"
Time cron "0 * * * * ?" //for debug
then
var Number Wind_Max5 = AT_Dachflache_Wind.maximumSince(now.minusMinutes(5), "jdbc") as Number
AT_Dachflache_Wind_Max5.postUpdate(Wind_Max5)
logInfo ("Wind Maximumsince5","Maximum Wind was: " + AT_Dachflache_Wind_Max5.state + " m/s at " + AT_Dachflache_Wind.maximumSince(now.minusMinutes(5)).timestamp)
end
rule "Calculate today's max wind gust"
when
Item AT_Dachflache_Wind changed
then
// formatter is needed in the conversion of Java time (ZoneDateTime) to DateTime.
// See the following link for discussion on time conversion. https://community.openhab.org/t/datetime-conversion-openhab-3-x/107197/16.
// See in particular post from Bartkummel in Jan21
val formatter = java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
AT_Dachflache_Wind_MaxDay.postUpdate(AT_Dachflache_Wind.maximumSince(now.with(LocalTime.of(0,0,0,0))).state, "jdbc")
// get time of max gust. This is returned in Java time (ZoneDateTime variable)
var time_of_max_gust = AT_Dachflache_Wind.maximumSince(now.with(LocalTime.of(0,0,0,0))).timestamp
// convert to string using above formatter anmd then convert to DateTime variable using DateTimeType
AT_Dachflache_Wind_MaxDay_Time.postUpdate(DateTimeType.valueOf(time_of_max_gust.format(formatter)))
logInfo("org.openhab","Today's max wind gust is " + AT_Dachflache_Wind_MaxDay.state + " m/s at " + AT_Dachflache_Wind_MaxDay_Time.state.format("%1$tr"))
end
My intention is that the item AT_Dachflache_Wind_Max5 shows the highest wind speed of the past 5 minutes. And AT_Dachflache_Wind_MaxDay shows the highest recorded wind speed of the current day.
This is the log error I receive for my 5 minute rule:
2022-04-06 14:37:00.247 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'wind-2' failed: Could not cast org.openhab.core.persistence.extensions.PersistenceExtensions$1@165e572 to java.lang.Number; line 28, column 25, length 70 in wind
I don’t have a “Maximum wind gust of the day” rule, you do. We can try to help you with it.
Yes. As discussed, maximumSince() returns a complex object - which cannot be cast as a Number.
You’d want to look at its state component.
Seeing as you are investigating weirdness, you might find it useful to get the timestamp component as well - which record did it retrieve for you?
Maybe
var Wind_Max5 = AT_Dachflache_Wind.maximumSince(now.minusMinutes(5), "jdbc")
// this is NOT a number, you cannot beat it into a number shape
// you have to look at its parts
logInfo ("Wind Maximumsince5","Maximum Wind was: " + Wind_Max5.state.toString)
logInfo ("Wind Maximumsince5","Maximum Wind occurred at " + Wind_Max5.getTimestamp.toString)
It has not sunk in about postUpdate() being asynchronous.
Fetching the state of this Item will get the “old” state, because the postUpdate() in the preceding line has almost certainly not completed yet.
Thank you. I will try to fetch the data you suggested.
And I mixed things up with the maximum wind gust rule. It wasn’t provided by you but by @BrianS in an earlier posting. Sorry about that.
When looking into problems with this kind of thing, break it up so you can see the moving parts. Something is not what you expected, find out what. Is that time what you think? Is that whole gubbins something suitable to postUpdate to an Item?
var tt = now.with(LocalTime.of(0,0,0,0)
logInfo("diag", "Using datetime " + tt.toString)
var xx = AT_Dachflache_Wind.maximumSince(tt, "jdbc")
logInfo("diag", "got value " + xx.state.toString)
logInfo("diag", "from " + xx.timestamp.toString)
AT_Dachflache_Wind_MaxDay.postUpdate(xx.state)
How do you know, what recorded data is available for the preceding 5 minutes? Any at all?
This is a bit of a handicap, I’ve no idea how you use that either.
Let’s get openHAB to have a rough look.
var zz = AT_Dachflache_Wind.historicState(now.minusMinutes(5), "jdbc")
// this is NOT a number either
logInfo ("Wind Maximumsince5","5 mins ago was: " + zz.state.toString)
logInfo ("Wind Maximumsince5","record from " + zz.getTimestamp.toString)
It is unlikely there is any record at exactly five minutes ago to the millisecond - what historicState() should do is search backward for the last valid record before that (on the assumption it remained valid until)
You can query the DB through the API Explorer. The persistence: GET /persistence/items/{itemname} endpoint will let you create a query for all entries between two supplied date times (or a date time to now).
Thank you for pointing to the API Explorer, @rlkoshak. I can see that values have been persisted for the item. However because I guess time values are Epoch, I cannot tell when the data was recorded.
The result of that would be that the maximum of the last five minutes is … the current value. (There is no other data available for the last five minutes. historicState() will search backwards to last record whenever … but maximumSince() will not I think)
Sounds like you are not persisting the Item you are querying in the database you are looking at.
When checking data using REST API, don’t forget that needs to be told which database to look in too.
I guess that was the solution, @rossko57. I checked my persistence file again and found a mistake:
I had persisted all weather measurements, including wind, with every30Minutes. For wind explicitely I only persisted all max values (5 mins., 1 hour, all day) with
AT_Dachflache_Wind_* : strategy = everyChange
However, the original measurement for the item AT_Dachflache_Wind was not stored on everyChange (notice the underscore in the strategy).
Now I went with
AT_Dachflache_Wind : strategy = everyChange
and my database gets filled with values. I guess that all the suggestions you all made along the way helped to fix errors but as it looks this was the last missing piece of the puzzle.
Thank you all for your support. I will mark this post as the solution and I hope that this thread will help others who are working with maximumSince.
Careful with persist configuration. That is NOT a wildcard in this context. It means to persist all members of a Group named AT_Dachflache_Wind_ , and I will bet you do not even have a Group Item named exactly that.