Edit: Updated for OH 4
See Design Pattern: What is a Design Pattern and How Do I Use Them for an explanation of what a DP is and how to use them.
Problem Statement
There are several reasons why a home automation enthusiast would want to use openHAB persistence: charting, using historical Item states in rules logic, restore previous values on openHAB restart, detailed analysis, access to the data with external tools, etc.
By default, a persistence add-on will implement a default strategy which will usually be something like “all Items on every change with restoreOnStartup”. This may be just fine for most use cases. However, many times one may not want to save all Items to a given database, or they may want to apply filters that apply to some Items, or have some Items save to one database and other Items saved to a different one.
Concept
Use Groups to identify those Items that should be saved to a specific database under a specific strategy and set up the persistence configuration using the “member of Group” list of Items.
For example, one can set up MapDB for restoreOnStartup, rrd4j for charting recent data and historical data, and InfluxDB for a small set of Items for detailed external analysis.
For each strategy, create a Group and only use these groups in the .persist files.
Then allocate your Items to whatever Group(s) based on how that specific Item will be used.
An advantage is that one applies the strategy at the Item level. However, this means your persistence configuration gets spread out across your Items instead of centralized in your persistence configs.
Example
Let’s say we have a small set of Items we have a set of Items we want to do restoreOnStartup, another set we want to save on every change for basic charting, and a few we want to save to a different database on every change to detailed analysis. We’ll create three Group Items:
RestoreOnStartup
DefaultEveryChange
AnalysisEveryChange
Set the Items whose persistence fits into one or more of these strategies as members of the strategy to apply. Let’s say we’ll use MapDB for RestoreOnStartup
, rrd4j for DefaultEveryChange
, and InfluxDB for AnalysisEveryChange
. Note that this does not mean that two or all three of these strategies are used in the same database.
Managed Configs
Navigate to Settings → Persistence and select the desired add-on to configure under “Configure Persistence Policies”.
MapDB Config:
- Click “add configuration”, click “Select groups” and select “RestoreOnStartup”
- Under “strategies” make sure “everyChange” and “restoreOnStartup” are selected
Note, if you want to apply filters, create the filter first and then select the filter(s) you want to apply for this Group under “Select filters”.
Repeat the steps above for RRD4J and InfluxDB, selecting the Group name and strategies and filters (if applicable) as appropriate.
File Based Config
mapdb.persist file:
Strategies {
default = everyChange
}
Items {
RestoreOnStartup* : strategy = everyChange, restoreOnStartup
}
NOTE: To make restoreOnStartup work we need to persist every change. The *
after the Group name means “all members of this Group”.
rrd4j.persist file:
Strategies {
everyMinute : "0 * * * * ?"
default = everyChange
}
Items {
// additionally persist weather info every minute
DefaultEveryChange* : strategy = everyUpdate, everyMinute
}
NOTE: Because of the way rrd4j works, an everyMinute strategy is required.
**influxdb.persist file:
// persistence strategies have a name and a definition and are referred to in the "Items" section
Strategies {
default = everyChange
}
Items {
AnalysisEveryChange* : strategy = everyUpdate
}
Advantages
The advantages of this approach include:
- The persistence behavior for each Item is documented with the Item (i.e. the Group membership) keeping as much information about the behavior of the Item in one place
- Adding new Items or changing how they are persisted simply involves changing that Item’s Group membership.
- Once set up, the .persist files/config need never be changed unless you decide move from one persistence engine to another
- Uses the best persist engine for the desired behavior. For example MapDB can save all types of Items but only keeps the last value do it is great for restoreOnStartup but not great for historic data whereas rrd4j is great for charting recent data but can’t save anything that isn’t a numerical value.
Disadvantages:
- If you have a Group with an aggregation function that you also want to persist, this DP cannot be used on that Group Item. The Group Item will need to be listed individually in the .persist files.
A note about usage:
openHAB can have only one default persistence engine. Any calls you make in Rules where you do not specify a persistence engine will use the default. When using this approach for Persistence be careful when and if you change the default persistence engine as that may break some of your Rules.
To avoid problems, I recommend always specifying the persistence engine you want to use in all of your persistence calls in rules. For example, in JS Scripting:
items.MyItem.history.previousState(true, 'rrd4j');
items.MyItem.history.lastUpdate('mapdb');