HistoricItem.getState() on null

Every now and then my db4o db gets very large and I remove it. The problem I run into is that when I do that a bunch of my rules break because there is no .previousState(true, “db4o”).state for the items. I tried to setup a if == null but I still get the error because it’s not there when I test for it.

val short previous_distance = if (Softener_Salt_Level.previousState(false, "db4o").state == null) 0 else Softener_Salt_Level.previousState(false, "db4o").state

The only solution I have right now is to manually fill the db with 0 values, but there has got to be a better way…

I’ve been wondering if it would be a good thing to add to the Persistence service a “cleanup” flag that removes data that gets beyond a certain age automatically (could even be configured per Item) when using a non-fixed size DB.

But since that isn’t happening anytime soon, you might be able to only remove older items using this:

https://marketplace.eclipse.org/content/object-manager-enterprise-db4o-ome

Or write a utility that deletes stuff that is old but preserve at least the most recent values.

I think that may have, but my biggest problem is that when you start with a blank DB, that even checking if something is in the DB will throw an error. As an example I thought I could do something like:

val double today_grid = if(Today_Grid_kWh.previousState().state == null) 0 else Today_Grid_kWh.previousState().state

However if I start with a clean db that throws and error because there is no Today_Grid_kWh previous state in the db. I have been getting past this for now by manually entering data in my db after I clear my db, but I would like to not do that manually.

Also, on a side note. One of your posts suggested looking at mapdb because it only keeps the last value so it would not grow. The problem I am having is that .state is the same as .previousState().state and I can’t figure out why.

2016-05-22 14:38:04.271 [INFO ] [runtime.busevents             ] - Grid_wh state updated to 7720402.496
2016-05-22 14:38:04.273 [INFO ] [g.openhab.model.script.Grid_wh] - Current: 7720402.496 Previous: 7720402.496
2016-05-22 14:38:22.261 [INFO ] [runtime.busevents             ] - Grid_wh state updated to 7720408.593
2016-05-22 14:38:22.263 [INFO ] [g.openhab.model.script.Grid_wh] - Current: 7720408.593 Previous: 7720408.593
2016-05-22 14:38:22.287 [INFO ] [runtime.busevents             ] - Grid_wh state updated to 7720414.681
2016-05-22 14:38:22.300 [INFO ] [g.openhab.model.script.Grid_wh] - Current: 7720414.681 Previous: 7720414.681

My rule:

rule "Today Grid Used"
when
        Item Grid_wh changed
then
        val double previous_meter = Grid_wh.previousState().state
        val double current_meter = Grid_wh.state
        logInfo("Grid_wh", "Current: " + current_meter + " Previous: " + previous_meter)
        val double today_grid = if(Today_Grid_kWh.state == Uninitialized) 0 else Today_Grid_kWh.state
        postUpdate(Today_Grid_kWh, today_grid + ((current_meter - previous_meter)/1000))
end

MapDB is great for restoreOnStartup but worthless for previous value because it only saves the most recent value. Consequently, by the time your rule executes the cake in the dB will have ashtray been replaced with the current value.

This may not work, but I wonder if the following might auto populate db40 after you delete it:

Configure everything to save in MapDB and restore on startup.

Do not restore on startup with db40. Configure db40 to save at heart everyUpdate.

Stop OH before deleting db40 files.

Delete files.

Start OH.

My thought is that the restoreOnStartup from MapDB will cause db40 to save the restored value as an update and populate your db40 dB accordingly.

If that doesn’t work, you could probably do something like that in a rule.