I’ve been running OH2 on an rPi3 for over a year. Like, I suspect, many other people, I started with it as a “plaything”, just to mess around. Later, I got a Z-Wave piHAT and ever more devices, I added a few ESP8266 IR blasters around the home, and I connected more and more bindings to devices around my home.
Now, OpenHAB is vital to our home. My partner and our child use OpenHAB2 (usually without knowing) to control heating, music, air conditioning, the entire home entertainment system and even VMs in Azure (required for her job). If OpenHAB failed, our normal daily lives would be disrupted.
I’m a computer systems engineer by trade, and I know that all systems eventually fail. Raspberry Pis with a single SD-Card running via PoE while balanced on top of a UPS will probably fail sooner.
Also, because I started with this “as a toy”, I wasn’t particularly careful about how or where I stored the configuration. Things were tried, rushed, and forgotten, and misnamed, and renamed, and forgotten again.
I am therefore in a mess, and I am to blame.
Now I think I want to start again, but with a clean logical configuration rather than backup/restore, preferably text-based and stored in git so I can see what changed and why. Ideally this would all be in one place, and it would be the preferred location for the OpenHAB project in the future.
I understand this is a lively FOSS project, and the rapid pace of development has left a few choices about where configuration data “should” be stored. I’ve read the docs and I’m afraid I’m still a little unclear.
I think configuring Items and Things via PaperUI creates entries in /usr/share/openhab2/jsondb, whereas I can still create Items and Things in /etc/openhab2/. Is there a “best” single choice? If I create them via PaperUI, would copying /usr/share/openhab2/jsondb into git store all the configuration changes? Can I e.g. configure the expire binding via PaperUI?
What about Rules? I understand there’s a new rule engine on the way, but I think the only place that rules can exist is in /etc/openhab2/rules.
Lastly, I’m a fan of Ansible-driven configuration. If I wanted to drive the configuration via Ansible, I’m guessing that I couldn’t e.g. write lines into /usr/share/openhab2/jsondb while the service is running. Could I instead interact with the karaf console in an idempotent way to e.g. create an Item?
I cannot answer your questions directly, but theese posts might be interessting for you.
Personally I am running openhab in a docker container on my DIY NAS/Home Server.
My configuration is storen in /var/lib/docker/volumes/openhab-config and I use git to manage and backup the files.
I am not using PaperUI at all!
I started with openHAB when there was no PaperUI.
Mine is the more that you can put into jsondb the better. It’s a JSON formatted text file so it is very git friendly and I personally have all my configs in git. The only gotcha is the order is not guaranteed. On very rare occasions (I’ve seen it happen once) the entries in the file will end up reordered which can mess up the ordering.
The official recommendation is to put all Things in the JSONDB and everything else in text configs. This lets you take advantage of automatic discovery and there are some bindings that have some features that cannot be accomplished with .things files. The problem with Items is there is no way in PaperUI to define tags or metadata or OH 1.x binding configurations on Items. The PaperUI config for Rules is barely functional so we can’t recommend doing Rules that way. And there is no API to do persistence or sitemaps through PaperUI so those are not even an option.
Here is what I do. I run OH in Docker but I’ve had this set up using an installed OH as well.
Create an /opt/openhab2 folder which will be the root of your git repo
Create /opt/openhab2/conf and /opt/openhab2/userdata
Copy /etc/openhab2/ to conf and /var/lib/openhab2 to userdata
configure your .gitignore to at a minimum ignore the backup folders, cache and tmp in userdata. You might want to exclude some of the binary files in persistence which is where embedded DBs like MapDB and RRD4j store their data. I keep these files as it makes a nice backup for those as well. Some bindings will also have their own folder (zwave, mqtt) which you may or may not want to configuration control.
If you are using docker, link these folders as volumes into the container. If installed, create a symlink to /etc/openhab and /var/lib/openhab2
check it all in.
I’ve an Ansible role that configures the host like this, checks out the OH config from my Gogs server, and runs the container.
I’ve not yet migrated my Rules to JSONDB but it’s high on my list. The benefits I’ve seen on that RPi0w really opened my eyes. It was “this is how it’s supposed to work” moment. But because PaperUI is not that useful for entering Rules, I hand code the JSON and push it to the REST API which seems to work reasonably well.
No, it’s a 1.x binding.
Right now they can only be defined using text configs.
Personally I’m not a fan of code to write code which is essentially what you would be doing since your OH config is, for all intents and purposes, code. Indeed, you should not manually edit the JSONDB files while OH is running. You can “edit” them using the Karaf Console or the REST API, but doing so in a idempotent way is going to require you to code in check first and update if necessary stuff yourself, either through your playbooks or by creating a custom task.
It also gets awkward when you realize that stuff like Things can be automatically discovered and created. In that case your Ansible isn’t so much creating those Things as it would be restoring them.
Instead of trying to code through Ansible, I’d recommend setting up a git workflow where you code the configs, check them into git, and then perhaps through Ansible check the configs out and deploys them. Though even that somewhat breaks down as in some cases you can’t, for example, have the same Zwave device connected to multiple master controllers so you won’t be able to discover the Thing for that device on a test instance of OH and then deploy it to production. The technology just won’t allow it.
I can provide links or answer questions you may have.
Honestly, an opinion of an experienced user is good enough for me. If you do it that way, it’s likely it’ll work for me too, and it’ll be considerably better than my mish-mash.
Just to be clear, is your preference of “everything in JSONDB” different to this official recommendation? I believe it is, and you @rlkoshak, prefer to e.g. configure your Items in JSONDB. I’m guessing here that if I want to stick to JSONDB as much as possible, I’d have to e.g. re-write my Expire Binding configs as Scripted Automation, right?
Lastly, thanks for the rest of the answer; it’s pretty clear that I need to seriously consider my approach with Ansible fairly deeply. Thanks in general, actually.
It’s hard to answer that question. There are just some things that the UI and even the REST API makes a little awkward to do, mainly Item metadata. Therefore I think it might be just a tad premature to move Items to JSONDB. In my HestiaPi experience, there was no Item metadata to worry about so migration was not problem. And to be fair, Yannick has written an importer for Items already that is/will be part of the replacement for PaperUI, so I could manage Items in PaperUI, or more likely through the REST API directly in my case. But I’ve more than half a decade of legacy OH stuff to deal with and I’m not yet ready to move my Items to JSONDB.
I do know that some startup problems will go away when I do but I’m just not ready to make the move. Given that I’m not yet ready I don’t think it’s fair for me to recommend others do what I’m not willing to do.
And there are some drawbacks. It’s not as easy to search through, edit, copy and paste and that sort of stuff with JSONDB. You can’t really group or organize them in separate files or other logical organizations like you can do with separate files.
Already done. JSR223 Jython Replacement for Expire Binding. Though honestly, the simplification that comes with using Expire as Timers in Rules DSL simply doesn’t exist for Python. Put another way, it’s just as simple to define a Timer with it’s lambda in Python as it is to use Expire binding. So the link above is mainly intended as a bridge to use temporarily and not really intended to be something you would use forever, though that’s obviously an option.