[SOLVED] Trouble with rule checking previousState of Number item

I’m trying to create a rule that will send me a notification when it’s beginning to rain but I’m having trouble getting persistence to behave the way I want. My observation is that persistence API’s behave inconsistently when trying to retrieve previousState for an item.

I am running Openhabian with OH 2.4, using mysql for persistence, and am attempting to use an item defined as:

Number:Length     HomeWeatherStationInformation_CurrentPrecipitationDay "Current precipitation day [%.2f in]" (g_HomeWeatherStation_current) {channel="weatherunderground:weather:local:current#precipitationDay"}

This item is persisted on all updates, and is working properly as my graphs appear correct and manually dumping the DB table shows the updates at the timestamps as I would expect. E.g., dumping the table for part of yesterday’s data shows:

2019-02-02 00:00:00     0
2019-02-02 00:18:13     0.01
2019-02-02 00:48:14     0.03
2019-02-02 01:18:15     0.03
2019-02-02 01:48:17     0.47
2019-02-02 02:18:18     0.47
2019-02-02 02:48:20     0.26
2019-02-02 03:18:21     0.26
2019-02-02 03:48:22     0.38
2019-02-02 04:18:24     0.44
2019-02-02 04:48:26     0.5
2019-02-02 05:18:27     0.5
2019-02-02 05:48:28     0.5
2019-02-02 06:18:30     0.51
2019-02-02 06:48:31     0.51
2019-02-02 07:18:33     0.55
2019-02-02 07:48:34     0.8
2019-02-02 08:18:36     0.91
2019-02-02 08:48:38     0.98
2019-02-02 09:18:39     0.98
2019-02-02 09:48:41     1.1
2019-02-02 10:18:42     1.1
2019-02-02 10:48:43     1.1
2019-02-02 11:18:45     1.1
2019-02-02 11:48:46     1.1
2019-02-02 12:18:47     1.23
2019-02-02 12:48:49     1.23
2019-02-02 13:18:51     1.34
2019-02-02 13:37:52     1.34
2019-02-02 13:52:54     1.38
2019-02-02 14:07:55     1.39
2019-02-02 14:22:57     1.39
2019-02-02 14:37:58     1.39
2019-02-02 14:53:05     1.39

I have a rule that resets this item to zero at midnight every day, so that my other rule might be able to detect when it starts raining by catching the change from a 0 previousState to greater than 0 current state.

My rule for detecting when it starts raining looks like this:

/////////////////////////////////////////////////////////////
rule "Notification when rain starts"
when
    Item HomeWeatherStationInformation_CurrentPrecipitationDay changed
then
    val currentRain = (HomeWeatherStationInformation_CurrentPrecipitationDay.state as QuantityType<Number>).doubleValue
    val sumForToday = HomeWeatherStationInformation_CurrentPrecipitationDay.sumSince(now.withTimeAtStartOfDay)
    val previousStateDef = HomeWeatherStationInformation_CurrentPrecipitationDay.previousState().state
    val previousStateTrue = HomeWeatherStationInformation_CurrentPrecipitationDay.previousState(true).state
    logInfo("RainNotify", "Entry. sum for today: " +
            sumForToday +
            ", current: " +
            currentRain +
            ", prevStateDef: " +
            previousStateDef +
            ", prevStateTrue: " +
            previousStateTrue)
    if ((previousStateDef == 0) && (currentRain > 0)) {
       logInfo("RainNotify", "It's beginning to rain")
       notificationSenderFunc.apply("It's beginning to rain", true, true)
    }
end

With this implementation, the previousStateDef and previousStateTrue values don’t seem to consistently report the value I’d expect based on the contents of the DB for this item.

For example, yesterday when setting up the logging in the rule, the first time it ran after the rule was modified I saw one entry where previousState* values show what I would expect in the log output:

2019-02-02 13:18:51.675 [INFO ] [se.smarthome.model.script.RainNotify] - Entry. sum for today: 17.05, current: 1.34 in, prevStateDef: 1.23, prevStateTrue: 1.23

Notice that the “current” value is higher than either of the prevState* values in the log message, matching the contents of the DB when comparing the log timestamp with the DB row timestamps.

However, after this log entry, all subsequent entries no longer correctly get the previousState for the item:

2019-02-02 13:52:54.496 [INFO ] [se.smarthome.model.script.RainNotify] - Entry. sum for today: 21.11, current: 1.38, prevStateDef: 1.38, prevStateTrue: 1.38

This is the first log showing the transition from 1.34 to 1.38, yet the “current” and both of the “prevState*” values show 1.38. How can this be? You can see from the DB data above that the log timestamp for 13:52:54 matches the DB entry where it transitioned from 1.34 to 1.38, so the previousState* values for the item should have been 1.34.

Am I missing something or is this a bug?

Thanks for any help or pointers anyone can provide.
Jeff

What is your default persistance service? Do you use more then one? Maybe MAPDB and SQL?

mysql is the default according to my Paper UI->System page.

I use mysql and I persist many items to myopenhab as well. Would that interfere?

Since you are triggering on an item changed event you should be able to use the implicit “previousState”.

val currentrain= triggeringItem.state
val previousStateDef= previousState

It’s looking like using ‘previousState’ is working properly, but does this mean that .previousState() has a defect? I also tried specifying the persistence service:

<item>.previousState([true/false],"mysql")

and it still didn’t work correctly.

Thanks.

Not a defect so much as a limitation. Persistence saves Item’s states in the background in parallel with the Rule executing. There is probably not enough time between the time the Item changes state and your call to get the previousState out of the database for the database to have saved the current value. So you are likely getting two values back instead of the previous one.

This is why the implicit variables were created.

You will have a similar problem trying to use the state of an Item with a received command trigger. The Rule fires before the Item is actually set to the commanded state so it might not yet have that state in your Rule. This is why you should use the receivedCommand implicit variable in that case.

Thanks for the info. This raised additional questions for me, but since you pointed toward implicit variables I decided I better check the manual and I found the answers. :grinning:

https://www.openhab.org/docs/configuration/rules-dsl.html#implicit-variables-inside-the-execution-block

Thanks everyone for the helpful responses.

Why not change the rule trigger to:

rule "Notification when rain starts"
when
    Item HomeWeatherStationInformation_CurrentPrecipitationDay changed from 0
then

That’s a good idea, that makes the rule body a on-liner to send the notification.

Thanks,
Jeff