Persistence previousState not working as documented

  • Platform information:
    • Hardware: Raspberry 4 / 8GB
    • OS: 5.15.84-v8+
    • Java Runtime Environment: Java 11
    • openHAB version: 3.4.2
  • Issue of the topic:

I am using persistence with jdbc:mariadb. I persist the SetTemperature value of a thermostate. The following entries are the last two in the persistence table of the item:
2023-03-20 19:45:05 12
2023-03-20 10:32:46 18

Item.state returns 12, which is correct.
Item.previousState() returns HistoricItem with “state=12.0, timestamp=2023-03-20T19:45:05+01:00[Europe/Berlin]]” which is correct according to Persistence Documentation.
Item.previousState(true) should, according to docs, skip the entry at “2023-03-20 19:45:05” as current state and persisted state ar the same. But it returns the same HistoricItem as “Item.previousState()” instead of “state=18” from “2023-03-20 10:32:46”.

My current workaround is to use “Item.historicState(Item.lastUpdate.minusSeconds(1).state” to access the last value before the current value. But if I understand the docs, “Item.previousState(true)” should work that way. What am I missing?

Does your item have a dimension? If so, I think the comparison for equality would fail because persistence only stores plain decimal type, and DecimalType(12.0) != QuantityType(12.0)

If that is in fact the case an issue needs to be filed. It should work whether the Item has units or not.

@JimT
I understand your point and in my case it’s a “Number:Temperature”. But in my opinion, as the storage engine does not save the dimension together with the value, the comparison should always be with the base type. The persistent value belongs to the item which is persisted and must have the same dimension as the item itself.

I also think that Item.previousState() must not return the last entry which was saved to the storage engine as the last value saved is always the current value. So Item.previousState ist quite useless because Item.state returns the same value.

Agreed but if that’s not happening it needs to be fixed. Hence the question and the need to experiment what happens with just a plain Number without units so we can file an issue.

Overall, previousState is poorly named. But we have nearly a decade with it named what it is. I don’t see it being changed any time soon. But that is why previousState(true) exists, to return to most recent entry that is different from the current state.

But the last value saved is not always the current value. Instead of using a persistence strategy, one can control the persistence of an Item via a rule by calling .persist. This can be a useful way to filter out widely out of range values for example. In that case, the current state of the Item may not have been persisted at all in which case previousState would not be the same.

Just made a quick check with “Type=Number” and “Type=Number:Temperature”.

When testing with “Type=Number” the following values were in the persistence table of the item:
2023-03-21 16:20:09 20
2023-03-21 07:31:30 20
2023-03-21 06:02:14 19
Looks like changing the item type results in a new persistence entry.

Item.state = 20
Item.previousState() = state=20.0, timestamp=2023-03-21T16:20:09+01:00[Europe/Berlin]
Item.previousState(true) = state=19.0, timestamp=2023-03-21T06:02:14+01:00[Europe/Berlin]

When testing with “Type=Number:Temperatur” the following values were in the persistence table of the item:
2023-03-21 16:25:08 20
2023-03-21 16:20:09 20
2023-03-21 07:31:30 20
2023-03-21 06:02:14 19
Again, changing the item type results in a new persistence entry.

Item.state = 20 °C
Item.previousState() = state=20.0, timestamp=2023-03-21T16:25:08+01:00[Europe/Berlin]
Item.previousState(true) = state=20.0, timestamp=2023-03-21T16:25:08+01:00[Europe/Berlin]

So it looks like the dimension is the reason for this behaviour.

OK, this needs to be filed as an issue on openhab-core. It’s definitely erroneous behavior. It should be the same whether or not units are involved.

I agree that the last value might not always be the current value. But if you persist manually you know what you are doing and what to expect. Especially you know that Item.previousState() might not be the previous state.
When using Item.previousState() being on a persistence strategy it should be the state of the item just before the current state became valid. As you can see in my tests previousState() returns the HistoricItem which is the current Item (the moment the Item reached its current state). Speaking SQL the current statement is something like
SELECT * FROM Item ORDER BY Time DESC LIMIT 1
and it should be
SELECT * FROM Item ORDER BY Time DESC LIMIT 1 ,1

Do you open an issue on openhab-core or can I do it as well?

You’ve got the details and technical configs to reproduce it so it’ll probably be best if you filed it.

previousState has always only returned the most recent value in the database. That’s why it’s poorly named. You can file an issue to change it’s behavior (probably should be a different issue) but this issue has been filed and rejected more than once in the past. previousState works the way the maintainers want it to work.

Filed an issue

1 Like