You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Grafana can filter via JSONB operators: `WHERE metadata->>'location' = 'living_room'`
87
+
88
+
When no value/config is set, both columns are `NULL`.
89
+
90
+
**Migration:** On startup `TimescaleDBSchema.initialize()` runs a single DO-block that adds both columns atomically:
91
+
92
+
```sql
93
+
ALTERTABLE item_meta
94
+
ADD COLUMN IF NOT EXISTS value TEXT,
95
+
ADD COLUMN IF NOT EXISTS metadata JSONB;
96
+
```
97
+
98
+
`IF NOT EXISTS` makes the statement idempotent. A `lock_timeout` of 5 s prevents blocking `@Activate` indefinitely; on timeout a WARNING is logged and the migration is retried on the next startup.
99
+
68
100
### Why `unit` is per row, not in `item_meta`
69
101
70
102
A `QuantityType` unit can change over time (sensor reconfiguration, firmware update, etc.). Storing it in `item_meta` would corrupt historical reads. The unit is stored with each measurement and read back from the row when reconstructing `QuantityType` states.
-`getValue()` → main value string, e.g. `"AVG"`, `"MAX"`, `"MIN"`, `"SUM"`, or `""` (no aggregation)
138
-
-`getConfiguration()` → `Map<String, Object>` with keys like `"downsampleInterval"`, `"retainRawDays"`, `"retentionDays"`
169
+
-`getValue()` → user-defined string (e.g. `"sensor.temperature"`), stored in `item_meta.value`
170
+
-`getConfiguration()` → `Map<String, Object>` with keys like `"aggregation"`, `"downsampleInterval"`, `"retainRawDays"`, `"retentionDays"`, plus user-defined tags
139
171
140
172
### Metadata format (configured by users in .items files)
Copy file name to clipboardExpand all lines: bundles/org.openhab.persistence.timescaledb/README.md
+60-17Lines changed: 60 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -27,7 +27,7 @@ CREATE EXTENSION IF NOT EXISTS timescaledb;
27
27
## Database Schema
28
28
29
29
The service **creates all tables automatically on startup** — no manual DDL required.
30
-
Item states are stored in a single hypertable `items` (columns: `time`, `item_id`, `value`, `string`, `unit`, `downsampled`) and a name-lookup table `item_meta`.
30
+
Item states are stored in a single hypertable `items` (columns: `time`, `item_id`, `value`, `string`, `unit`, `downsampled`) and a name-lookup table `item_meta` (columns: `id`, `name`, `label`, `value`, `metadata`).
31
31
32
32
## State Type Mapping
33
33
@@ -77,36 +77,44 @@ Items {
77
77
}
78
78
```
79
79
80
-
## Per-Item Downsampling
80
+
## Per-Item Downsampling and Metadata Tags
81
81
82
-
Downsampling is configured**per item** via item metadata in the `timescaledb` namespace.
82
+
Per-item behaviour is configured via item metadata in the `timescaledb` namespace.
| value (main) |`AVG`, `MAX`, `MIN`, `SUM`, or `" "`| Aggregation function. Use a single space `" "` for retention-only (no downsampling). openHAB rejects a truly empty value, so a space is required. |
93
-
|`downsampleInterval`| e.g. `1h`, `15m`, `1d`| Time bucket size for aggregation. Required when value is an aggregation function. |
94
-
|`retainRawDays`| integer, default `5`| Keep raw data for N days before replacing with aggregated rows. |
95
-
|`retentionDays`| integer, default `0`| Drop all data (raw + downsampled) older than N days. `0` = off. |
| value (main) | any string | User-defined label stored in `item_meta.value`. Leave blank (single space `" "`) if only retention is needed. |
94
+
|`aggregation`|`AVG`, `MAX`, `MIN`, `SUM`| Downsampling aggregation function. Omit if no downsampling is needed. |
95
+
|`downsampleInterval`| e.g. `1h`, `15m`, `1d`| Time bucket size for aggregation. Required when `aggregation` is set. |
96
+
|`retainRawDays`| integer, default `5`| Keep raw data for N days before replacing with aggregated rows. |
97
+
|`retentionDays`| integer, default `0`| Drop all data older than N days. `0` = disabled. |
98
+
| custom tags | any key=value pairs | Stored unfiltered as JSONB in `item_meta.metadata`. Queryable via Grafana/SQL JSONB operators. |
99
+
100
+
The **entire config map** (all keys including `aggregation`, `downsampleInterval`, etc.) is stored as JSONB in `item_meta.metadata`, enabling flexible SQL/Grafana filtering.
96
101
97
102
### Configuration in `.items` files
98
103
99
104
```java
105
+
// Downsampling + custom tags for Grafana filtering
Copy file name to clipboardExpand all lines: bundles/org.openhab.persistence.timescaledb/src/main/java/org/openhab/persistence/timescaledb/internal/TimescaleDBMetadataService.java
0 commit comments