e223278771
- Easy docker push (MQTTower ergonomics + the image push it lacks): VERSION file → version-tag.yml (semver-guard auto-tag) → docker-publish.yml (buildx multi-arch → GHCR, registry centralized for one-line retarget to git.finalfactory.de) + ci.yml + build-and-push.ps1. - Verified end to end: deploy/Dockerfile builds; docker compose stack (app + timescaledb) comes up healthy; /healthz and the dashboard respond in-container. - JSON config export/import (ExportService) with id remapping on restore + GET /export, POST /import endpoints; round-trip test preserves meter→type, meter-scoped tariff, category links. - README, HA/Tasmota/MQTT wiring guide (docs/wiring.md), Unraid template. - CLAUDE.md updated to reflect the built codebase. - i18n: locale-aware number/currency formatting (de-DE); full de UI string localization deferred. 95 tests green (56 Core + 39 integration). Claude-Session: https://claude.ai/code/session_01WujdMtMJPbxDpDnMeK22rr
73 lines
2.5 KiB
Markdown
73 lines
2.5 KiB
Markdown
# Wiring up sources
|
|
|
|
MeterVault ingests from MQTT/Tasmota and Home Assistant. Sources are attached to meters; each
|
|
source's `config` JSON says where the value comes from. Secrets are referenced by environment
|
|
variable name, never stored in the database.
|
|
|
|
## 1. Create an MQTT broker endpoint
|
|
|
|
`ingestion_endpoint` (type `MqttBroker`) config:
|
|
|
|
```json
|
|
{
|
|
"host": "192.168.1.10",
|
|
"port": 1883,
|
|
"usernameEnv": "MQTT_USER",
|
|
"passwordEnv": "MQTT_PASS",
|
|
"extraTopics": ["tele/+/SENSOR"]
|
|
}
|
|
```
|
|
|
|
Set `MQTT_USER` / `MQTT_PASS` in the container environment. The worker connects on startup and
|
|
resubscribes automatically after outages.
|
|
|
|
## 2. Tasmota plug → electricity meter
|
|
|
|
Create a `Tasmota` source on the meter with:
|
|
|
|
```json
|
|
{ "topic": "tele/plug1/SENSOR", "path": "ENERGY.Total" }
|
|
```
|
|
|
|
Tasmota publishes e.g. `{"Time":"2026-01-01T12:00:00","ENERGY":{"Total":1234.56,"Today":1.2,"Power":50}}`.
|
|
MeterVault reads `ENERGY.Total`, and uses the payload's `Time` field as the timestamp. Use
|
|
`ENERGY.Today` for daily-delta meters (`direct_delta` mode) or `ENERGY.Power` for `instant_rate`.
|
|
`scale`/`offset` on the source convert units (e.g. Wh → kWh with `scale: 0.001`).
|
|
|
|
## 3. Raw MQTT sensor
|
|
|
|
Same as Tasmota but source type `Mqtt`; point `path` at the JSON field, or omit it for a bare
|
|
numeric payload. `timePath` names a timestamp field in the payload if present.
|
|
|
|
## 4. Home Assistant
|
|
|
|
Two options:
|
|
|
|
**A — HA pushes to MQTT.** Configure an HA MQTT sensor/automation to publish to a topic and treat
|
|
it as an MQTT source (above). No HA endpoint needed.
|
|
|
|
**B — MeterVault polls HA.** Create an `ingestion_endpoint` (type `HomeAssistant`):
|
|
|
|
```json
|
|
{ "baseUrl": "http://homeassistant.local:8123", "tokenEnv": "HA_TOKEN" }
|
|
```
|
|
|
|
and a `HomeAssistant` source on the meter:
|
|
|
|
```json
|
|
{ "entityId": "sensor.house_power", "attribute": null, "pollSeconds": 60 }
|
|
```
|
|
|
|
Set `HA_TOKEN` (a long-lived access token) in the environment. Numeric state (or a named
|
|
`attribute`) is read every `pollSeconds`; `unavailable`/`unknown` states are skipped.
|
|
|
|
**C — HA pushes to the REST API.** POST to `/api/v1/readings` with an `X-Api-Key` header (see the
|
|
README). Good when HA should drive the cadence.
|
|
|
|
## Notes
|
|
|
|
- Cumulative registers reject spurious **decreases** unless a `counter_reset`/`meter_swap` event
|
|
explains them — record swaps via `POST /api/v1/events`.
|
|
- High-frequency sources: MeterVault stores raw readings idempotently on `(meter, time)`; use
|
|
Tasmota's `TelePeriod` and per-source sampling to bound volume.
|