homelab-brain/docs/projekte/garage-decke-monitoring.md
Homelab Cursor 48852c8665 Garage-Decke Doku und Hermes-MCP ins Git versionieren.
Projektdoku, MCP-Skript und Deploy-Hinweise als Quelle der Wahrheit in homelab-brain; CT999 und Telegraf-README verlinken darauf.
2026-06-28 17:05:03 +02:00

341 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Garage-Decke — Deckentemperaturen (Klimadecke, Brunnen/PWT)
**Stand:** 27.06.2026 (Abend) · **Datendrehscheibe:** CT 143 (Raspi-Broker) · **Grafana:** https://grafana.orbitalo.net/d/garage_decke/garage-decke
## Ziel
Fuenf DS18B20-Fuehler an der Garage-Decke **dauerhaft messen und auswerten**:
- **Klimadecke:** Vorlauf + Ruecklauf (VL/RL) — passive/strahlungsbasierte Kuehlung
- **Brunnen/PWT:** Vorlauf vor Plattenwaermetauscher + Ruecklauf danach
- **PWT-Oberflaeche:** Fuehler oben auf PWT geklemmt (Gehaeuse, schneller Indikator)
Aus den Temperaturen werden **ΔT (Effektivitaet)** und — nur fuer den Brunnenkreis — **thermische Leistung** abgeleitet.
Getrennt vom **Garagen-Raum-Satelliten** (`garage/temp`, ESP-Werkstattknoten) — der misst Raumluft, nicht Deckenrohre.
## Architektur
```
Brunnen (Garten)
│ Brunnenpumpe + ggf. Verstaerkerpumpe(n) in Reihe
│ lange Leitung → Garage
Plattenwaermetauscher (PWT) — Primaer: Brunnen / Sekundaer: KaelteDecke
2x Shelly 1 (Gen1, SHSW-1) + DS18B20-Addon
│ HTTP lokal: 192.168.178.86 / .78
│ MQTT (Gen1: Cloud ODER MQTT, nicht beides!)
│ Topics: shellies/<id>/ext_temperature/<idx> (float °C)
mosquitto CT143 :1883 (192.168.178.36)
Telegraf satellites.conf (5 Inputs, feste Tags)
InfluxDB DB `sensors`, Measurement `temperature`
Tags: node=garage_decke, sensor=<rolle>
Grafana Dashboard „Garage Decke“ (UID: garage_decke)
→ Stat: Temperaturen, ΔT, Leistung Brunnen
→ Verlauf: 5 Fuehler + ΔT/Leistung
```
### Code / Git (homelab-brain auf pve-hetzner)
| Artefakt | Pfad im Repo | Deploy-Ziel |
|----------|--------------|-------------|
| Telegraf MQTT-Inputs | `infra/telegraf/satellites.conf` | CT143 `/etc/telegraf/telegraf.d/satellites.conf` |
| Grafana Dashboard JSON | `infra/grafana/garage_decke.json` | CT143 `/etc/grafana/provisioning/dashboards/garage_decke.json` |
| Hermes MCP | `infra/hermes/garage_decke_mcp.py` | CT151 `/root/.hermes/garage_decke_mcp.py` |
| Projektdoku | `docs/projekte/garage-decke-monitoring.md` | CT999 `/root/docs/projekte/garage-decke-monitoring.md` |
Nach Aenderung: **sofort `git push origin main`**, sonst ueberschreibt Auto-Sync (`sync-state.sh` alle 15 min).
## Hardware
### Sensoren (Shelly)
| Geraet | IP | Shelly-ID | MQTT-Prefix | Fuehler |
|--------|-----|-----------|-------------|---------|
| Shelly 1 | 192.168.178.86 | shelly1-F4CFA2D3B444 | `shellies/shelly1-F4CFA2D3B444` | 3x DS18B20 (idx 02) |
| Shelly 1 | 192.168.178.78 | shelly1-8CAAB55D9A15 | `shellies/shelly1-8CAAB55D9A15` | 2x DS18B20 (idx 01) |
### Sensor-Zuordnung (final 26.06.2026)
| InfluxDB `sensor` | Bedeutung | Shelly | idx | hwID |
|-------------------|-----------|--------|-----|------|
| `rl_klimadecke` | RL Klimadecke (Ruecklauf, waermer) | .86 | 0 | 28ff641e01be641a |
| `pwt` | PWT-Oberflaeche (Gehaeuse oben) | .86 | 1 | 28ff641e01b534e2 |
| `vl_kaeltedecke` | VL KaelteDecke (Vorlauf, kalt) | .86 | 2 | 28ff641e23c9d2f6 |
| `vl_brunnen` | VL Brunnen (vor PWT, kalt) | .78 | 0 | 28ff641e23ea0235 |
| `rl_brunnen` | RL Brunnen (nach PWT, waermer) | .78 | 1 | 28ff641e23f7232d |
**Wichtig:** InfluxDB-Tag `node=garage_decke`**nicht** `garage` (das ist der Raum-Satellit).
Urspruenglich `decke_1..5` / `reserve` — umbenannt in semantische Tags; alte `last()`-Werte in Influx ignorieren.
### Hydraulik / Pumpen (Stand 27.06.2026 Abend)
| Komponente | Details |
|------------|---------|
| **Brunnenpumpe** | Bestehend, liefert Volumen am Brunnen |
| **KD-Pumpe** | 2. Pumpe KaelteDecke; Flussrichtung umgedreht (Entlueftung) → Grafana `kd_flussrichtung = Umgekehrt` |
| **Verstaerkerpumpe** | **ZC-T50** (haendlerisch „50 W“), Typenschild: **24 V DC, 3,5 A ≈ 84 W** elektrisch; als Druckerhoehungspumpe |
| **Aktueller Test** | **3 Pumpen in Reihe** (Brunnen + Verstaerker + KD) — Durchfluss **5,27 l/min** gemessen (27.06. Abend) |
| **Mittelfristig** | **12 Pumpen ausbauen** — minimale Kombination finden, bei der l/min + PWT/KD-ΔT gleich bleiben |
**Erkenntnis Garten vs. Garage:** Am Brunnen direkt wirkt die Zusatzpumpe stark; in der Garage weniger. Engpass ist **Druckverlust** (lange Leitung + PWT + KaelteDecke), nicht zu wenig Brunnenwasser. Mehr Pumpen in Reihe kompensieren das kurzfristig; dauerhaft besser: **eine** gut platzierte Verstaerkerpumpe (Zulauf beachten, Kavitation vermeiden).
**Nach jedem Pumpen-Umbau:** entlueften, 3060 min stabilisieren, Durchfluss mit Wasseruhr messen (gleiche Stelle wie Benchmark), Grafana-Variable `brunnen_durchfluss` setzen.
### KD-Flussrichtung optimiert (27.06.2026 — zentraler Befund)
**Problem vor Umkehr:** Nur ca. **20 % der KaelteDecke** wurde spuerbar kalt — Rest stagnierte oder wurde nicht durchstroemt (Hydraulik/Entlueftung, nicht Sensorfehler).
**Massnahme:** Durchfluss in der **KaelteDecke** optimiert durch **Umkehr der Flussrichtung** (2. KD-Pumpe, Entlueftung). Grafana: `kd_flussrichtung = Umgekehrt` (-1).
**Ergebnis:** Erst **nach** der Umkehr wurde die **gesamte** KaelteDecke kalt. Daten bestaetigen den Sprung (~09:30 Uhr):
| Phase | Hydraulisches VL KD | Hydraulisches RL KD | ΔT KD | Wirkung |
|-------|---------------------|---------------------|-------|---------|
| Frueh (wenig Durchfluss) | ~27 °C | ~20 °C | ~0 K (VL waermer als RL) | Decke praktisch aus |
| Nach Flussumkehr + Pumpen | **~20 °C** ↓ | **~25 °C** ↑ | **~5,5 K** | volle Decke kalt |
**Interpretation:** Fuehler bleiben am Rohr fix montiert — die **hydraulische** VL/RL-Zuordnung aendert sich durch die Flussrichtung. Vorher lief vermutlich nur ein Kurzschluss-/Teilstrom (ein Strang kalt, Rest tot). Nach Umkehr: Durchstroemung der gesamten Flaeche, VL faellt deutlich, RL steigt — typisches Kuehlbetriebsbild.
**Fuer kuenftige Wartung:** Flussrichtung und Entlueftung sind genauso wichtig wie Pumpenleistung. Ohne korrekte Richtung liefert mehr Druck allein keine volle Decke.
### Montage Fuehler
| Fuehler | Status | Anmerkung |
|---------|--------|-----------|
| Klimadecke VL/RL | montiert, plausibel | ΔT ~46 K je nach Hydraulik |
| PWT-Oberflaeche | auf PWT geklemmt | reagiert schnell; Indikator „PWT wird kalt“ |
| Brunnen VL/RL | isoliert gegen Raumluft (27.06.) | ΔT ~2,42,8 K; optional Tauchhuelle nachruesten |
### Shelly Gen1: MQTT statt App
Shelly 1 (Gen1) kann **entweder Cloud (Shelly-App) oder MQTT** — nicht parallel. Fuer Monitoring ist MQTT aktiv:
```
http://<ip>/settings/mqtt?mqtt_enable=true&mqtt_server=192.168.178.36:1883&mqtt_clean_session=true&mqtt_update_period=30
```
Lokale Werte/Identifikation: Browser `http://192.168.178.86` bzw. `.78/status``ext_temperature`.
## MQTT-Topics (Beispiel)
```
shellies/shelly1-F4CFA2D3B444/ext_temperature/0 → 29.5
shellies/shelly1-F4CFA2D3B444/ext_temperatures → JSON mit hwID + tC
shellies/shelly1-8CAAB55D9A15/ext_temperature/1 → 22.1
```
## Telegraf / InfluxDB
Fuenf feste `[[inputs.mqtt_consumer]]`-Bloecke in `satellites.conf` — je Topic ein Input mit festen Tags `node=garage_decke`, `sensor=<rolle>`.
```toml
# Auszug infra/telegraf/satellites.conf (Kommentarblock + Tags)
# rl_klimadecke = shelly .86 idx0
# pwt = shelly .86 idx1
# vl_kaeltedecke = shelly .86 idx2
# vl_brunnen = shelly .78 idx0
# rl_brunnen = shelly .78 idx1
[[inputs.mqtt_consumer]]
topics = ["shellies/shelly1-F4CFA2D3B444/ext_temperature/0"]
name_override = "temperature"
[inputs.mqtt_consumer.tags]
node = "garage_decke"
sensor = "rl_klimadecke"
# ... analog fuer pwt, vl_kaeltedecke, vl_brunnen, rl_brunnen
```
### Verifikation
```bash
# MQTT live (auf CT143)
mosquitto_sub -h 127.0.0.1 -t 'shellies/shelly1-F4CFA2D3B444/ext_temperature/#' -v
# InfluxDB
curl -sG 'http://127.0.0.1:8086/query' --data-urlencode 'db=sensors' \
--data-urlencode "q=SELECT last(\"value\") FROM \"temperature\" WHERE \"node\"='garage_decke' GROUP BY \"sensor\""
```
## Benchmark / Messwerte
### Durchfluss
| Datum | Konfiguration | l/min | Quelle |
|-------|---------------|-------|--------|
| 27.06.2026 | Brunnenpumpe + KD (ohne Verstaerker) | **3,5** | Wasseruhr |
| 27.06.2026 Abend | + ZC-T50, 3 Pumpen in Reihe | **5,27** | Wasseruhr — **Grafana-Default** |
### Temperatur-Vergleich (kd_flussrichtung = Umgekehrt)
| Kennzahl | Vor Verstaerkerpumpe | Nach Verstaerkerpumpe (27.06. Abend) |
|----------|----------------------|--------------------------------------|
| VL Brunnen | 15,8 °C | **15,1 °C** |
| RL Brunnen | 18,5 °C | **17,6 °C** |
| **ΔT Brunnen** | 2,7 K | **2,42,5 K** |
| PWT-Oberflaeche | 17,7 °C | **16,2 °C** |
| KD-ΔT (RLVL) | ~4,5 K | **~6,0 K** |
| Leistung Brunnen | **~659684 W** @ 3,5 l/min, ΔT ~2,7 K | **~772 W** @ 5,27 l/min, ΔT ~2,1 K (live); **~920 W** bei ΔT 2,5 K |
| Garage-Raum (`node=garage`) | ~27,4 °C | ~27,8 °C (Traegheit; Decke fuehlt sich kaelter an) |
**Interpretation:** Sekundaerseite (PWT, KD) profitiert deutlich. Brunnen-ΔT sinkt leicht (typisch bei mehr Volumen). **Netto-Leistung** erst nach neuem Durchfluss: `Q [W] ≈ l/min × ΔT × 69,8`.
**Beispielrechnung bei ΔT = 2,5 K:**
| l/min | ~Leistung |
|-------|-----------|
| 5,0 | ~837 W |
| 6,0 | ~1005 W |
| 7,0 | ~1172 W |
## Grafana
| Eigenschaft | Wert |
|-------------|------|
| Titel | Garage Decke |
| UID | `garage_decke` |
| URL | `/d/garage_decke/garage-decke` |
| Datasource | InfluxDB-sensors (DB `sensors`), Math-Panels: **Mixed** |
| Refresh | 30 s |
| Stat-Anzeige | Hintergrund **gruen** (OK) oder **schwarz** (kein Signal) |
### Dashboard-Variablen
| Variable | Typ | Default | Zweck |
|----------|-----|---------|-------|
| `kd_flussrichtung` | Dropdown `1` / `-1` | **-1** (Umgekehrt) | Tauscht hydraulische VL/RL-Zuordnung der fest montierten KD-Fuehler |
| `brunnen_durchfluss` | Dropdown 3 … 8 l/min (inkl. **5,27**) | **5,27** | Brunnen-Volumenstrom fuer Leistungsberechnung |
Durchfluss nur **Brunnenkreis** bekannt. KD-Kreis: nur ΔT, keine kW ohne Durchflussmesser.
### KD Flussrichtung (`kd_flussrichtung`)
Fuehler bleiben am Rohr (`rl_klimadecke` idx0, `vl_kaeltedecke` idx2). Math in `garage_decke.json`:
```
RL_anzeige = (A + B - kd_flussrichtung * (B - A)) / 2
VL_anzeige = (A + B + kd_flussrichtung * (B - A)) / 2
ΔT_KD = RL_anzeige - VL_anzeige
```
(A = `rl_klimadecke`, B = `vl_kaeltedecke` in Influx)
### Panels
**Zeile 1 — Temperaturen:** RL KD, PWT, VL KD, VL Brunnen, RL Brunnen
**Zeile 2 — Berechnet:**
| Panel | Formel | Einheit |
|-------|--------|---------|
| ΔT KaelteDecke | RL VL (per Flussrichtung) | K |
| ΔT Brunnen | `rl_brunnen vl_brunnen` | K |
| Leistung Brunnen | `brunnen_durchfluss × ΔT_Brunnen × 0,0698` | kW (Anzeige W) |
**Verlaufs-Charts:** 5 Temperaturen; ΔT KD + ΔT Brunnen + Leistung Brunnen
### Formel Leistung Brunnen
```
Q [kW] ≈ V̇ [l/min] × ΔT [K] × 0,0698
Q [W] ≈ V̇ [l/min] × ΔT [K] × 69,8
```
**Benchmark ohne Verstaerker (27.06.):** 3,5 l/min × 2,8 K × 69,8 ≈ **684 W**
**Benchmark mit Verstaerker (27.06. Abend):** 5,27 l/min × 2,1 K × 69,8 ≈ **772 W** (gemessen); bei ΔT 2,5 K ≈ **920 W**
### Grafana — technische Fixes (27.06.2026)
| Problem | Ursache | Fix (Commit) |
|---------|---------|--------------|
| 5× No Data in Stat-Panels | `filterByRefId` filterte Math-Abhaengigkeiten A/B weg | `hide: true` auf A/B, kein filterByRefId |
| No Data bei Math | Panel-DS Influx statt Mixed | Datasource `-- Mixed --` |
| Rot/Gruen-Flackern | `colorMode: background` + mehrere Serien | Nur eine sichtbare Serie; zweistufige Thresholds |
| KD-ΔT negativ | Swap-Formel (BA) statt (BA) mit Richtung | `kd_flussrichtung` + korrigierte Math |
| PWT-ΔT-Panel | wenig Aussagekraft | durch **ΔT Brunnen** ersetzt |
### Grenzen
- **KD-Leistung kW:** ohne Durchflussmesser im KD-Kreis nicht berechenbar
- **Garagen-Kuehlleistung gesamt:** Raumtemp `garage` vs. `aussen` — separates Orakel
- **Brunnen-Leistung:** abhaengig von Wasseruhr-Messung und VL/RL-Montage
## Deploy
```bash
# Sync auf pve-hetzner AUS, dann in /root/homelab-brain/ editieren, commit + push
# auf pve-mu-3:
pct push 143 satellites.conf /etc/telegraf/telegraf.d/satellites.conf
pct exec 143 -- systemctl restart telegraf
pct push 143 garage_decke.json /etc/grafana/provisioning/dashboards/garage_decke.json
# Optional: API-Overwrite fuer sofortige Live-Aenderung (siehe Session 27.06.)
pct exec 143 -- systemctl restart grafana-server
```
## Verwandte Messpunkte
| Quelle | node | Zweck |
|--------|------|-------|
| Garagen-Raum-Satellit | `garage` | Raumluft Werkstatt |
| Aussenfuehler ESP8266 | `aussen` | Temp. unter Dach/Vordach (MQTT legacy: `oelraum/temp`) |
| Oelknoten | `oelknoten` | Oelraum-Temperaturen (separates Board `oelknoten`) |
## Historie
- **26.06.2026:** MQTT an beiden Shellys, Telegraf-Ingest, Grafana-Board. `node=garage_decke` (Kollision mit Raum-Satellit `garage`). Sensor-Zuordnung identifiziert.
- **26.06. Abend:** `reserve``pwt`, Fuehler auf PWT geklemmt (~26 °C → ~16 °C).
- **27.06.:** Brunnen-Fuehler isoliert; ΔT Brunnen plausibel (~2,8 K). Durchfluss **3,5 l/min** gemessen. Benchmark **684 W**.
- **27.06.:** 2. KD-Pumpe, Flussrichtung umgedreht → `kd_flussrichtung`. Grafana: ΔT KD/Brunnen, Leistung Brunnen.
- **27.06.:** Grafana-Stabilisierung (Mixed-DS, hide A/B, gruen/schwarz Hintergrund). Forgejo Issue [#132](https://git.orbitalo.net/orbitalo/homelab-brain/issues/132).
- **27.06. Abend:** ZC-T50 Verstaerkerpumpe eingebaut; **3 Pumpen in Reihe** (Test). Durchfluss **5,27 l/min** (+50 % vs. 3,5). Leistung ~772 W @ ΔT 2,1 K. Mittelfristig Pumpen reduzieren.
- **27.06.:** KD-Flussrichtung umgekehrt (Entlueftung/Optimierung). **Vorher ~20 % der Decke kalt**, danach **volle Flaeche** — VL KD von ~27 °C auf ~20 °C, ΔT ~5,5 K. Belastungstest bei ~38 °C aussen.
- **27.06. Abend — Test bestanden:** Brunnenkühlung + KaelteDecke unter Extremhitze (~38 °C aussen) hydraulisch OK. 5,27 l/min, ~772 W Brunnenleistung, volle Decke kalt. Pumpenstrom (~84 W Verstaerker + bestehend) bei PV-Ueberschuss akzeptabel. Naechster Schritt: Pumpen-Kombination vereinfachen.
## Hermes MCP (CT151, ab 28.06.2026)
Hermes fragt Brunnen/Kältedecke **nicht** per curl/ioBroker ab — festes MCP-Tool.
| Artefakt | Pfad im Repo | Deploy-Ziel (CT151) |
|----------|--------------|---------------------|
| MCP-Server | `infra/hermes/garage_decke_mcp.py` | `/root/.hermes/garage_decke_mcp.py` |
| Gateway-Config | manuell in `/root/.hermes/config.yaml` | Block `mcp_servers.garage_decke` |
### Tools
| Tool | Funktion |
|------|----------|
| `garage_decke_live` | Alle 5 Sensoren, ΔT Brunnen/KD, Leistung @ `BRUNNEN_DURCHFLUSS`, Garage-Raum + Außen |
| `garage_decke_compare` | Jetzt vs. vor N Stunden (`hours`, default 24) |
### config.yaml (Auszug)
```yaml
garage_decke:
command: /opt/hermes-agent/.venv/bin/python3
args:
- /root/.hermes/garage_decke_mcp.py
env:
KD_FLUSSRICHTUNG: "-1"
BRUNNEN_DURCHFLUSS: "5.27"
```
### Deploy
```bash
# auf pve-mu-3:
pct push 151 garage_decke_mcp.py /root/.hermes/garage_decke_mcp.py
pct exec 151 -- chmod +x /root/.hermes/garage_decke_mcp.py
# config.yaml Block ergänzen (siehe oben)
pct exec 151 -- systemctl restart hermes-gateway
```
**Regel (MEMORY.md):** Bei Fragen zu Brunnen/Kältedecke immer `garage_decke_live` — niemals Vorher-Werte erfinden.