Getting mapdb persistence to work with openhab2

You’ll need some content in your mapdb.persist file.
Maybe you could show us what you have done there.

1 Like
Strategies {
        default = everyUpdate
}
Items {
// persist all items once a day and on every change and restore them from the db at startup
StartPersist* : strategy = everyChange, restoreOnStartup
}

Or should I mention all individual items I want to store? Like in the rrd4j and influxdb.persist.

No, that’s fine. All members of your Group named StartPersist should be stored, as and when they change.

Where do I declare the group named StartPersist? Missed that.

In your items file.
If do not have one yet, you might persist all items in mapdb by selecting them with “*”.

If I were you, I would only persist (and restore) the things you that you actually need to.
Don’t add system load and SD card writes just because it’s easier to type *

Add a Group the same as any other Item, that depends if you are using xxx.items files or PaperUI. It’s just an Item of type Group.

Once the Group exists, you can add other ordinary Items to become members of the group.
xxx.items file with a (mygroup) field, PaperUI with the ‘Parent group’ box.

In the past I created a home.items file with about 150-200 items (nikobus installation) in openhab 1.x. Also created a home.sitemap. Most of the Basic UI structure was in the items-file?!? I don’t remember why I did so.

Today I corrected this and renamed the home.items file into nikobus.items. Deleted the Basic UI structure in this file and created a new home.sitemap. For all switch-items I created a few groups in the items-file (eg gLights, gBG, g1V, g2V etc).

Beside the nikobus.items I do have a astro.items and a weather.items file. Can groups only contain members from their own items-file or can they also contain members from other items-files?

Is it a good idea to use different items-files?

The nikobus.items are mostly for lights, rollershutters etc in my home. I do want to store their state in mapdb. Is a group gMapdb a good idea to store them?

The weather.items contains temperature, wind_speed etc. I store these in influxdb.persist. Is it logical to store these items all with the same frequency? What frequency? What do you reccomend?

Performance is not really an issue. My openhab server runs on a windows machine.

Actually, I never tried such and I’m not sure on the answer. My personal opinion on several items files is: keep all in one file. But that is my opinion!
Using a group for all items that are to be persisted is a good and often suggested idea! I did not mention such before because your response didn’t sound like you had setup the group before.
Concerning the frequency you are storing values, you have to decide with which precision you want to keep the data.
Why are you using rrd4j and influxdb? Mapdb is used for restore on startup, each of the other two could probably do whatever you need besides restoreonstartup.

I keep my items-files splitted for now. Not sure what’s best.

About the frequency storing data. It is difficult to estimate my needs. Probably I’ll know what to choose when is it too late!

I did some testing in rrd4j because it’s easy and there are many examples/tutorials on the internet. But now I’m storing my data in influxdb. I’ll remove my rrd4j settings.

Have as many xxx.items files as you want, this is just about your convenience in managing them.

Groups may have members spread across different xxx.items files; but make sure that you only define the Group Item itself in one file.

1 Like

Hi Rossko,

Thanks for you answer. I hoped it works like that!

Like xxx.items groups should be unique. Logical!

Does it make sense to put all groups in a groups.items? Makes them easier to manage?

Hi openhabers.
Spend entire date fighting with persistence to mapdb.
Finally i can see the following:

  • every item update is properly reflected in mapdb (i can check it using rest/api)
  • upon openhab restart (using systemctl) - mapdb is not queried! moreover it is out of sync after bringing openhab up (i.e. there is a mismatch between actual switch status and what is stored in mapdb - last changed value before restart). When you start playing with a switch in UI --> correct value is stored/updated in mapdb.

Can you help please? How to instruct openhab2 to query values upon startup?
my mapdb.persist is as following (and it is clearly used to store updates): but restoreOnStartup seems to have no effect:
Strategies {
}
Items {
*: strategy = everyChange, restoreOnStartup
}

Try adding a default strategy:

my current mapdb.persist is as following (and it works for updating the values - i can see it via rest request):
Strategies {
everyMinute : “0 * * * * ?”
everyHour : “0 0 * * * ?”
everyDay : “0 0 0 * * ?”

default = everyChange

}
Items {
* : strategy = everyChange, restoreOnStartup
}

i an VERY confused with wording in brackets…
" RestoreOnStartup: load and initialize the last persisted state of the Item on openHAB startup (if the Item state is undefined ( UNDEF ))"

It means that if a binding has already set some Item state when restore-on-startup acts, then it will not overwrite a valid state.
Really, I think it means it checks for NULL state.

i also think so. but it also looks like a contradiction… i don’t see how to restore the values from mapdb ?

Hi,
I am working on the functionality of openhab 2.5.0. I have installed mapdb jar file as addon manually because of my requirement. My bundle is in active state. I have included the mapdb.persist file inside /conf/persistence as follows :

Strategies {
default = everyUpdate
}
Items {

  • : strategy = everyUpdate, restoreOnStartup
    }

and also set org.eclipse.smarthome.persistence:default=mapdb inside runtime.cfg file.

When I try to fetch items from persistence through rest api http://localhost:8080/rest/persistence/items
getting the following warning and exception respectively :

Warning

18:09:45.786 [WARN ] [apdb.internal.MapDbPersistenceService] - Deserialized invalid item: [FAILED toString()]
18:09:45.796 [WARN ] [tence.mapdb.internal.StateTypeAdapter] - Couldn’t deserialize state ‘org.eclipse.smarthome.core.library.types.OnOffType@@@ON’: org.eclipse.smarthome.core.library.types.OnOffType cannot be found by org.openhab.persistence.mapdb_2.5.0

Exception

SLF4J: Failed toString() invocation on an object of type [org.openhab.persistence.mapdb.internal.MapDbItem]
Reported exception:
java.lang.NullPointerException
at org.openhab.persistence.mapdb.internal.MapDbItem.toString(MapDbItem.java:69)
at org.slf4j.helpers.MessageFormatter.safeObjectAppend(MessageFormatter.java:299)
at org.slf4j.helpers.MessageFormatter.deeplyAppendParameter(MessageFormatter.java:271)
at org.slf4j.helpers.MessageFormatter.arrayFormat(MessageFormatter.java:233)
at org.slf4j.helpers.MessageFormatter.arrayFormat(MessageFormatter.java:173)
at org.slf4j.helpers.MessageFormatter.format(MessageFormatter.java:124)
at org.ops4j.pax.logging.slf4j.Slf4jLogger.warn(Slf4jLogger.java:752)
at org.openhab.persistence.mapdb.internal.MapDbPersistenceService.deserialize(MapDbPersistenceService.java:174)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.Iterator.forEachRemaining(Iterator.java:116)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at org.openhab.persistence.mapdb.internal.MapDbPersistenceService.getItemInfo(MapDbPersistenceService.java:123)
at org.eclipse.smarthome.io.rest.core.internal.persistence.PersistenceResource.getServiceItemList(PersistenceResource.java:415)
at org.eclipse.smarthome.io.rest.core.internal.persistence.PersistenceResource.httpGetPersistenceServiceItems(PersistenceResource.java:160)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:144)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:160)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228)
at com.eclipsesource.jaxrs.publisher.internal.ServletContainerBridge.service(ServletContainerBridge.java:76)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:852)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:544)
at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:71)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:536)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1581)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1307)
at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:293)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:482)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1549)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1204)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:80)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.Server.handle(Server.java:494)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:374)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:268)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:117)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:336)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:129)
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:367)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:782)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:918)
at java.lang.Thread.run(Thread.java:748)

Can someone help me out in solving this.

Thanks in advance

Can you elaborate on this? The default setup works just fine for persisting the last state (only). Did you try without the .jar?

Also, did you verify that the Item you are testing did indeed get an update so it’s value is stored in mapdb?

I have some custom requirement to deal with persistence, where I have to change it in mapdb bundle and build jar file and test. For now I have not changed anything in the org.openhab.persistence.mapdb bundle. I have just included its jar file.

Yes I did try by installing mapdb from paperui, with the same configurations that I have mentioned in my previous post. But this time no warning , no exception but not able to see the persisted items through rest api.

Also, did you verify that the Item you are testing did indeed get an update so it’s value is stored in mapdb?

When I try to change the state of an item my console looks as follows :

10:58:20.440 [INFO ] [smarthome.event.ItemCommandEvent ] - Item ‘Light1’ received command OFF
10:58:20.443 [INFO ] [arthome.event.ItemStatePredictedEvent] - Light1 predicted to become OFF
10:58:20.458 [INFO ] [smarthome.event.ItemStateChangedEvent] - Light1 changed from ON to OFF

With the default mapdb setup, can you try to persist based on Group membership, like:

Strategies {
    default = everyUpdate
}
Items {
    gPersist* : strategy = everyChange, restoreOnStartup
}

…and add some test items to that Group.

BTW, which OH version exactly are you running, 2.5.0-1 Release or some milestone or snapshot version?