All Markdown documentation files for the ThermIQ smart hybrid heating system. PDFs excluded via .gitignore — generated on demand. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
944 lines
43 KiB
Markdown
944 lines
43 KiB
Markdown
# Pflichtenheft — ThermIQ ASP1 Software
|
||
## SPS-Programmierung (RevolutionPi) & Node-RED Automatisierung
|
||
|
||
**Projekt:** ThermIQ Hybridheizungssystem
|
||
|
||
**Standort:** Walda, Deutschland
|
||
|
||
**Dokument:** Pflichtenheft Software — Phase 1
|
||
|
||
**Version:** 2.0
|
||
|
||
**Stand:** 2026-05
|
||
|
||
**Autor:** Adrian
|
||
|
||
**Norm:** DIN 69901-5, VDI 2221
|
||
|
||
---
|
||
|
||
## Inhaltsverzeichnis
|
||
|
||
1. [Einleitung und Zweck](#1-einleitung-und-zweck)
|
||
2. [Zielbestimmungen](#2-zielbestimmungen)
|
||
3. [Anforderungskatalog](#3-anforderungskatalog)
|
||
4. [Systemübersicht](#4-systemübersicht)
|
||
5. [Plattformen und Laufzeitumgebungen](#5-plattformen-und-laufzeitumgebungen)
|
||
6. [MQTT-Datenbus](#6-mqtt-datenbus)
|
||
7. [RevolutionPi SPS-Programm](#7-revolutionpi-sps-programm)
|
||
8. [Node-RED Automatisierung](#8-node-red-automatisierung)
|
||
9. [Betriebsmodi](#9-betriebsmodi)
|
||
10. [Energiemanagement-Logik](#10-energiemanagement-logik)
|
||
11. [Wärmemanagement-Logik](#11-wärmemanagement-logik)
|
||
12. [Miner-Steuerung (gRPC)](#12-miner-steuerung-grpc)
|
||
13. [Sicherheitslogik (Software-Ebene)](#13-sicherheitslogik-software-ebene)
|
||
14. [Fallback- und Fehlerverhalten](#14-fallback--und-fehlerverhalten)
|
||
15. [Watchdog und Systemüberwachung](#15-watchdog-und-systemüberwachung)
|
||
16. [Abnahme- und Testkriterien](#16-abnahme--und-testkriterien)
|
||
17. [Offene Punkte](#17-offene-punkte)
|
||
|
||
---
|
||
|
||
## 1. Einleitung und Zweck
|
||
|
||
Dieses Pflichtenheft beschreibt die Softwareanforderungen für den Automatisierungsschaltschrank ASP1 des ThermIQ-Systems. Es definiert die zu erbringenden Leistungen für:
|
||
|
||
- die **SPS-Programmierung** auf dem RevolutionPi (Python/Node-RED via MQTT)
|
||
- die **Node-RED Automatisierungslogik** auf dem Site Server (Intel N100)
|
||
|
||
Home Assistant (Phase-1-Dashboard) ist in diesem Dokument **nicht** enthalten und wird separat spezifiziert.
|
||
|
||
### Abgrenzung
|
||
|
||
| In Scope | Out of Scope |
|
||
|----------|-------------|
|
||
| RevPi I/O-Steuerung (DO, DI, AO, AI) | Home Assistant Konfiguration |
|
||
| MQTT-Kommunikation RevPi ↔ Site Server | Cloud-Anbindung |
|
||
| Node-RED Modbus-Polling (Deye, Energiezähler) | Hydraulikplanung |
|
||
| Node-RED gRPC Miner-Integration | Netzwerk-Infrastruktur (Switch, IP-Vergabe) |
|
||
| Energie- und Wärmemanagement-Logik | Elektrische Hausinstallation |
|
||
| Watchdog und Alarmierung | Buderus-interne Konfiguration |
|
||
|
||
---
|
||
|
||
## 2. Zielbestimmungen
|
||
|
||
### 2.1 Musskriterien
|
||
|
||
Die folgenden Ziele sind zwingend zu erfüllen. Das System gilt ohne diese als nicht abnahmefähig.
|
||
|
||
1. Das System muss die Kryptominer (Antminer S19J) über Kontaktoren sicher ein- und ausschalten können.
|
||
2. Das System muss die Abwärme der Miner nutzbar in den Pufferspeicher einspeisen.
|
||
3. Das System muss den Betrieb der Miner auf verfügbare Solar- und Batterieenergie optimieren.
|
||
4. Das System muss die Wärmepumpe (Buderus) über EVU-Sperre steuern können.
|
||
5. Das System muss im Fall eines Sicherheitsereignisses (E-Stop, Durchflussfehler, Hardware-Übertemperatur) die Miner über die Hardware-Sicherheitskette sofort und unabhängig von der Software abschalten.
|
||
6. Das System muss nach einem Stromausfall und Netzwiederkehr ohne manuellen Eingriff den Betrieb selbstständig wieder aufnehmen.
|
||
7. Das System muss alle Betriebszustände, Temperaturen und Alarme über MQTT für externe Systeme zugänglich machen.
|
||
|
||
### 2.2 Wunschkriterien
|
||
|
||
Die folgenden Ziele sind wünschenswert und sollen in späteren Phasen realisiert werden.
|
||
|
||
1. Integration eines dynamischen Stromtarifs (z. B. Tibber API) zur weiteren Kostenoptimierung (Phase 2).
|
||
2. Automatischer Modus-Wechsel (Winter/Sommer) basierend auf Außentemperatursensor (optional).
|
||
3. Logging aller Messwerte in einer Zeitreihendatenbank (z. B. InfluxDB) für Energiebilanz-Analysen (Phase 2).
|
||
4. Push-Benachrichtigungen (Telegram, E-Mail) bei kritischen Alarmen (Phase 2).
|
||
5. Webbasiertes Monitoring-Dashboard über Home Assistant.
|
||
6. Erweiterung auf zusätzliche Miner-Einheiten ohne Programmieraufwand.
|
||
|
||
### 2.3 Abgrenzungskriterien
|
||
|
||
Die folgenden Punkte sind explizit **nicht** Bestandteil dieses Pflichtenhefts:
|
||
|
||
1. Home Assistant Konfiguration, Dashboards und Automatisierungen.
|
||
2. Hydraulische Planung und Ausführung der Wärmesysteme.
|
||
3. Netzwerk-Infrastruktur (Switch, Verkabelung, IP-Vergabe).
|
||
4. Elektrische Hausinstallation (Zähler, Unterverteilung, Absicherung).
|
||
5. Buderus-interne Konfiguration (Heizkurven, Hydraulikweichen).
|
||
6. Cloud-Anbindung oder Remote-Zugriff (Phase 1).
|
||
7. Physische Installation und Inbetriebnahme des Schaltschranks.
|
||
|
||
---
|
||
|
||
## 3. Anforderungskatalog
|
||
|
||
### Leseanleitung
|
||
|
||
Jede Anforderung trägt eine eindeutige Kennung und eine Verbindlichkeit:
|
||
|
||
| Verbindlichkeit | Bedeutung |
|
||
|----------------|-----------|
|
||
| **MUSS** | Zwingend erforderlich. Nichterfüllung = Abnahmehindernis. |
|
||
| **SOLL** | Stark empfohlen. Abweichung nur mit Begründung. |
|
||
| **KANN** | Optional. Umsetzung wenn möglich und sinnvoll. |
|
||
|
||
Kategorien: **FA** = Funktionale Anforderung · **NFA** = Nicht-funktionale Anforderung · **SA** = Sicherheitsanforderung · **SI** = Schnittstellenanforderung · **RB** = Randbedingung
|
||
|
||
---
|
||
|
||
### 3.1 Funktionale Anforderungen (FA)
|
||
|
||
#### RevolutionPi / SPS
|
||
|
||
| ID | Verbindlichkeit | Anforderung |
|
||
|----|----------------|-------------|
|
||
| FA-001 | MUSS | Der RevPi muss alle physischen I/Os (DO, DI, AO, AI) gemäß dem I/O-Mapping in Abschnitt 7 verwalten. |
|
||
| FA-002 | MUSS | Der RevPi muss alle I/O-Zustände und Messwerte gemäß den Publish-Intervallen in Abschnitt 7.5 via MQTT publizieren. |
|
||
| FA-003 | MUSS | Der RevPi muss Steuerbefehle von Node-RED via MQTT empfangen und ohne Verzögerung (< 500 ms) auf die entsprechenden Ausgänge schalten. |
|
||
| FA-004 | MUSS | Der RevPi muss die Analogeingänge AI1 (Pufferspeicher) und AI2 (Warmwasserspeicher) auslesen, in °C umrechnen und auf Plausibilität prüfen. Werte außerhalb −10…+95 °C müssen als Fehler publiziert werden. |
|
||
| FA-005 | MUSS | Der RevPi muss den Sicherheitsrelais-Zustand (DI_SAFETY_OK) überwachen und bei Pegeländerung sofort auf `thermiq/safety/state` publizieren. |
|
||
| FA-006 | MUSS | Das RevPi-Programm muss K3 (RV1 auf) und K4 (RV1 zu) verriegeln: beide Ausgänge dürfen niemals gleichzeitig aktiv sein. |
|
||
| FA-007 | MUSS | Das RevPi-Programm muss K5 (RV2 auf) und K6 (RV2 zu) verriegeln: beide Ausgänge dürfen niemals gleichzeitig aktiv sein. |
|
||
| FA-008 | MUSS | Der RevPi muss einen sekündlichen Heartbeat (Unix-Timestamp) auf `thermiq/system/revpi/heartbeat` publizieren. |
|
||
| FA-009 | MUSS | Der RevPi muss nach Verbindungsverlust zum MQTT-Broker alle 10 Sekunden einen Reconnect versuchen und nach 60 Sekunden ohne Verbindung in den definierten Sicher-Zustand (Abschnitt 14.1) wechseln. |
|
||
|
||
#### Node-RED Automatisierung
|
||
|
||
| ID | Verbindlichkeit | Anforderung |
|
||
|----|----------------|-------------|
|
||
| FA-010 | MUSS | Node-RED muss Deye-Wechselrichter-Daten (solar_power, battery_soc, grid_power, load_power) via RS485/Modbus mit einem Intervall von ≤ 10 s pollen und auf MQTT publizieren. |
|
||
| FA-011 | MUSS | Node-RED muss Miner-Status und Ist-Leistung via Braiins OS gRPC (braiins.bos.v1) alle ≤ 30 s abfragen und Ergebnisse auf MQTT publizieren. |
|
||
| FA-012 | MUSS | Node-RED muss die Energiemanagement-Logik gemäß Abschnitt 10 ausführen und Miner-Leistungssetpoints auf MQTT publizieren. |
|
||
| FA-013 | MUSS | Node-RED muss die Wärmemanagement-Logik gemäß Abschnitt 11 ausführen und Steuerbefehle für Pumpen, Ventile, Rückkühler und EVU-Sperre auf MQTT publizieren. |
|
||
| FA-014 | MUSS | Node-RED muss vier Betriebsmodi verwalten: `winter`, `summer`, `transition`, `maintenance`. Der aktive Modus muss auf `thermiq/mode/current` (retained) publiziert werden. |
|
||
| FA-015 | MUSS | Node-RED muss bei Safety-Trip (`safety/state = "tripped"`) alle Miner-Leistungssetpoints auf 0 setzen, Pumpen auf Minimum-Setpoint stellen und den Alarm-Flow auslösen. |
|
||
| FA-016 | MUSS | Node-RED muss Alarme bei allen in Abschnitt 8.10 definierten Fehlerbedingungen auslösen und auf `thermiq/alarms/+` publizieren. |
|
||
| FA-017 | MUSS | Node-RED muss Fallback-Setpoints senden, wenn der RevPi-Heartbeat mehr als 30 Sekunden ausbleibt. |
|
||
| FA-018 | SOLL | Node-RED soll Leistungsänderungen an den Minern als Rampe (max. `miner_ramp_step` pro `miner_ramp_interval`) durchführen, um Lastsprünge zu vermeiden. |
|
||
| FA-019 | MUSS | Das Energiemanagement muss Mindest-Laufzeit (`min_run_time`) und Mindest-Stillstandszeit (`min_off_time`) für Miner einhalten. |
|
||
| FA-020 | SOLL | Node-RED soll Energiezähler-Daten via RS485/Modbus pollen und auf `thermiq/grid/meter` publizieren. |
|
||
| FA-021 | MUSS | Node-RED muss einen sekündlichen Heartbeat (Unix-Timestamp) auf `thermiq/system/nodered/heartbeat` publizieren. |
|
||
| FA-022 | MUSS | Im Betriebsmodus `maintenance` muss jede automatische Steuerlogik deaktiviert sein. Manuelle Befehle via MQTT bleiben möglich. |
|
||
|
||
---
|
||
|
||
### 3.2 Nicht-funktionale Anforderungen (NFA)
|
||
|
||
| ID | Verbindlichkeit | Anforderung |
|
||
|----|----------------|-------------|
|
||
| NFA-001 | MUSS | Das gesamte System muss nach einem Stromausfall und vollständiger Netzwiederkehr ohne manuellen Eingriff selbstständig anlaufen. Alle Dienste (RevPi Python, Node-RED, sunsynk, Mosquitto) müssen als Systemd-Services mit `Restart=always` und `WantedBy=multi-user.target` konfiguriert sein. |
|
||
| NFA-002 | MUSS | Das RevPi-Programm muss nach Watchdog-Auslösung oder Absturz innerhalb von ≤ 60 Sekunden wieder betriebsbereit sein. |
|
||
| NFA-003 | MUSS | Node-RED muss nach Neustart innerhalb von ≤ 60 Sekunden alle Flows aktiv haben und auf MQTT kommunizieren. |
|
||
| NFA-004 | MUSS | Die Reaktionszeit der Software auf einen Safety-Trip (von Empfang des MQTT-Topics bis zur Ausgabe aller Fallback-Setpoints) darf 2 Sekunden nicht überschreiten. |
|
||
| NFA-005 | MUSS | Alle konfigurierbaren Parameter (Schwellwerte, Sollwerte, Intervalle) müssen ohne Code-Änderung anpassbar sein — ausschließlich über Node-RED Context, Config-Flow oder `config.py`. |
|
||
| NFA-006 | SOLL | Der Quellcode des RevPi-Programms soll ausreichend kommentiert sein, um von einem mit Python vertrauten Dritten gewartet werden zu können. |
|
||
| NFA-007 | MUSS | Alle Zugangsdaten (Bearer-Token für Miner, MQTT-Passwörter) müssen in Umgebungsvariablen (`ENV`) gespeichert werden. Hardcodierung im Quellcode oder in Node-RED Flows ist unzulässig. |
|
||
| NFA-008 | MUSS | Alle Systemkomponenten (RevPi, Site Server) müssen per NTP zeitsynchronisiert sein. Eine Abweichung > 5 Sekunden zwischen RevPi und Site Server ist unzulässig. |
|
||
| NFA-009 | SOLL | Das System soll eine Betriebsverfügbarkeit von ≥ 99 % (maximal ≤ 87,6 Stunden ungeplanter Ausfall pro Jahr) anstreben. |
|
||
| NFA-010 | SOLL | Alle MQTT-Nachrichten sollen UTF-8-kodierte JSON- oder Plaintext-Payloads verwenden. Binäre oder proprietäre Formate sind unzulässig. |
|
||
|
||
---
|
||
|
||
### 3.3 Sicherheitsanforderungen (SA)
|
||
|
||
| ID | Verbindlichkeit | Anforderung |
|
||
|----|----------------|-------------|
|
||
| SA-001 | MUSS | Die Hardware-Sicherheitskette (Sicherheitsrelais, E-Stop, FLOW OK, TEMP MAX) muss vollständig unabhängig von der Software arbeiten. Die Software darf die Hardware-Sicherheitskette weder überbrücken noch deaktivieren. |
|
||
| SA-002 | MUSS | Ein Safety-Reset darf ausschließlich durch manuellen Eingriff am Schaltschrank erfolgen. Ein Software-Reset des Sicherheitszustands ist unzulässig. |
|
||
| SA-003 | MUSS | Das System muss bei einer Puffer-Temperatur > 80 °C (Softwaregrenze) die Miner-Leistungssetpoints auf 0 setzen und den Rückkühler einschalten, unabhängig vom aktuellen Energiebedarf. |
|
||
| SA-004 | MUSS | Das System muss bei einer Warmwasser-Temperatur > 68 °C die EVU-Sperre aufheben (Wärmepumpe sperren), um Überhitzung zu verhindern. |
|
||
| SA-005 | MUSS | Bei Ausfall des Deye-RS485-Pollings (kein Update > 60 s) muss das Energiemanagement in den konservativen Fallback-Modus wechseln: Miner werden abgeschaltet. |
|
||
| SA-006 | MUSS | gRPC-Steuerbefehle an Miner dürfen nur gesendet werden, wenn `thermiq/safety/state = "ok"`. |
|
||
| SA-007 | MUSS | Bei Plausibilitätsfehler eines Temperatursensors (Wert außerhalb −10…+95 °C) muss das System einen Alarm auslösen und in den sicheren Fallback-Zustand wechseln. Die betroffene Regelkreis-Automatik muss deaktiviert werden bis zur manuellen Quittierung. |
|
||
| SA-008 | MUSS | Die Ventil-Verriegelung (K3/K4, K5/K6) muss sowohl auf Software-Ebene (RevPi-Programm) als auch als Hardware-Empfehlung im Schaltplan dokumentiert sein. |
|
||
| SA-009 | SOLL | Das System soll Kontaktor-Feedback (DI_K10_FB, DI_K11_FB) auf Übereinstimmung mit dem Sollzustand prüfen. Bei Diskrepanz (Soll ≠ Ist > 2 s) soll ein Alarm ausgelöst werden. |
|
||
|
||
---
|
||
|
||
### 3.4 Schnittstellenanforderungen (SI)
|
||
|
||
| ID | Verbindlichkeit | Anforderung |
|
||
|----|----------------|-------------|
|
||
| SI-001 | MUSS | Alle internen Kommunikationen zwischen RevPi und Site Server müssen über den Mosquitto MQTT-Broker auf dem Site Server (TCP Port 1883) laufen. |
|
||
| SI-002 | MUSS | Die MQTT-Topic-Struktur muss exakt der in Abschnitt 6 definierten Spezifikation entsprechen. Eigenmächtige Abweichungen von Topicnamen oder Payloadformaten sind unzulässig. |
|
||
| SI-003 | MUSS | Die Deye-Integration muss entweder via sunsynk Python-Bibliothek (systemd-Service) oder via direktem Modbus RTU über USB-RS485-Adapter erfolgen. |
|
||
| SI-004 | MUSS | Die Miner-Integration muss die Braiins OS gRPC API (`braiins.bos.v1.PerformanceService`) auf Port 50051 verwenden. |
|
||
| SI-005 | SOLL | Das System soll mit Home Assistant als externer Steuerungsschicht über MQTT kompatibel sein. Setpoints (`setpoints/+`) und Modus (`mode/current`) müssen via MQTT schreibbar sein. |
|
||
| SI-006 | MUSS | Kritische Netzwerkteilnehmer (RevPi, Site Server, Miner) müssen ausschließlich über kabelgebundenes Ethernet kommunizieren. WLAN ist für diese Geräte unzulässig. |
|
||
| SI-007 | MUSS | RevPi und Site Server müssen feste IP-Adressen haben. DHCP für kritische Geräte ist unzulässig. |
|
||
|
||
---
|
||
|
||
### 3.5 Randbedingungen (RB)
|
||
|
||
Randbedingungen sind vorgegebene Rahmenbedingungen, die nicht Gegenstand der Entwicklung sind, aber die Realisierung maßgeblich beeinflussen.
|
||
|
||
| ID | Randbedingung |
|
||
|----|--------------|
|
||
| RB-001 | Der RevPi läuft auf KUNBUS RevPi Core 3+ mit DIO- und AIO-Modulen unter Raspberry Pi OS (RevPi-Variante). |
|
||
| RB-002 | Der Site Server ist ein Intel N100 Mini-PC (16 GB RAM, 500 GB SSD) mit Ubuntu Server. |
|
||
| RB-003 | Die Miner sind Antminer S19J Pro mit Braiins OS und aktivierter gRPC API. |
|
||
| RB-004 | Der Wechselrichter ist ein Deye Hybrid-Inverter mit RS485-Schnittstelle und Modbus-RTU-Protokoll. |
|
||
| RB-005 | Die Programmiersprache für das RevPi-Programm ist Python 3 mit `paho-mqtt` und `revpimodio`. |
|
||
| RB-006 | Die Automatisierungsplattform ist Node-RED 4.x als Docker-Container oder systemd-Service auf dem Site Server. |
|
||
| RB-007 | Der MQTT-Broker ist Mosquitto auf dem Site Server, lokal erreichbar. Keine externe Cloud-Verbindung in Phase 1. |
|
||
| RB-008 | Die Wärmepumpe ist ein Buderus-Gerät mit EVU-Sperr-Eingang (potenzialfreier Kontakt). |
|
||
|
||
---
|
||
|
||
## 4. Systemübersicht
|
||
|
||
```
|
||
┌────────────────────────────────────────────────────────────────────┐
|
||
│ SUPERVISION LAYER (Intel N100 Site Server) │
|
||
│ │
|
||
│ ┌─────────────┐ ┌───────────────┐ ┌────────────────────┐ │
|
||
│ │ Mosquitto │ │ Node-RED │ │ sunsynk (Python) │ │
|
||
│ │ MQTT Broker│◄──│ Automation │◄──│ RS485 Deye │ │
|
||
│ └──────┬──────┘ └───────┬───────┘ └────────────────────┘ │
|
||
│ │ │ │
|
||
│ │ ┌──────▼──────┐ │
|
||
│ │ │ gRPC Client │ │
|
||
│ │ │ (Miners) │ │
|
||
│ │ └─────────────┘ │
|
||
└──────────┼─────────────────────────────────────────────────────────┘
|
||
│ MQTT (Wired LAN, TCP 1883)
|
||
┌──────────▼─────────────────────────────────────────────────────────┐
|
||
│ CONTROL LAYER │
|
||
│ │
|
||
│ RevolutionPi (Core + DIO + AIO) ←──► Safety Relay (HW) │
|
||
│ - Python MQTT Client (Dual-channel) │
|
||
│ - I/O-Treiber │
|
||
└──────┬───────────────────────────────────────────┬────────────────┘
|
||
│ DO / AO │ Schützspulen K10/K11
|
||
┌──────▼───────────────────────────────────────────▼────────────────┐
|
||
│ FIELD LAYER │
|
||
│ Miner 1/2 (K10/K11) | P3/P4/P5 (Pumpen) | RV1/RV2 (Ventile) │
|
||
│ K2 (Rückkühler) | K7 (WP EVU) | Sensoren (AI) │
|
||
└────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
**Grundregel:** Node-RED ist die einzige Quelle für Automatisierungslogik. Der RevPi führt nur aus, was ihm via MQTT befohlen wird, und meldet seinen I/O-Zustand zurück.
|
||
|
||
---
|
||
|
||
## 5. Plattformen und Laufzeitumgebungen
|
||
|
||
### 5.1 RevolutionPi (Control Layer)
|
||
|
||
| Eigenschaft | Wert |
|
||
|-------------|------|
|
||
| Hardware | KUNBUS RevPi Core 3+ + DIO + AIO |
|
||
| OS | Raspberry Pi OS (RevPi Variante) |
|
||
| Sprache | Python 3 |
|
||
| MQTT-Bibliothek | paho-mqtt |
|
||
| Betrieb | Systemd-Service, Autostart |
|
||
| IP | Fixed (z.B. 192.168.0.10) |
|
||
|
||
### 5.2 Site Server (Supervision Layer)
|
||
|
||
| Eigenschaft | Wert |
|
||
|-------------|------|
|
||
| Hardware | Intel N100 Mini-PC, 16 GB RAM, 500 GB SSD |
|
||
| OS | Linux (Ubuntu Server oder ähnlich) |
|
||
| MQTT Broker | Mosquitto, Port 1883, lokal |
|
||
| Automation | Node-RED 4.x |
|
||
| Inverter-Polling | sunsynk (Python), systemd-Service |
|
||
| IP | Fixed (z.B. 192.168.0.11) |
|
||
|
||
### 5.3 Netzwerk
|
||
|
||
- Ausschließlich kabelgebundenes Ethernet, kein WLAN für kritische Geräte
|
||
- NTP-Zeitsynchronisation auf RevPi und Site Server verpflichtend
|
||
- Feste IPs für RevPi, Site Server, Miner 1, Miner 2
|
||
|
||
---
|
||
|
||
## 6. MQTT-Datenbus
|
||
|
||
Mosquitto läuft auf dem Site Server. Alle Komponenten kommunizieren über diesen Broker.
|
||
|
||
### 6.1 Topic-Struktur
|
||
|
||
```
|
||
thermiq/
|
||
├── miners/
|
||
│ ├── 1/state # "online" | "offline" | "error"
|
||
│ ├── 1/power # Watt (float)
|
||
│ ├── 1/hashrate # TH/s (float)
|
||
│ ├── 2/state
|
||
│ └── 2/power
|
||
├── pumps/
|
||
│ ├── p3/setpoint # 0.0–10.0 (V, als float)
|
||
│ ├── p4/setpoint
|
||
│ └── p5/setpoint
|
||
├── valves/
|
||
│ ├── rv1/state # "open" | "closed"
|
||
│ └── rv2/state
|
||
├── cooler/
|
||
│ └── state # "on" | "off"
|
||
├── heatpump/
|
||
│ ├── evu_sperre # "true" | "false"
|
||
│ └── state # "running" | "blocked" | "fault"
|
||
├── inverter/
|
||
│ ├── solar_power # W
|
||
│ ├── battery_soc # % (0–100)
|
||
│ ├── grid_power # W (negativ = Einspeisung)
|
||
│ └── load_power # W
|
||
├── temps/
|
||
│ ├── puffer # °C (float)
|
||
│ ├── warmwasser # °C (float)
|
||
│ └── miner_outlet # °C (float, optional)
|
||
├── safety/
|
||
│ ├── state # "ok" | "tripped"
|
||
│ └── reason # "flow" | "temp" | "estop" | "none"
|
||
├── setpoints/
|
||
│ ├── puffer_target # °C (Sollwert Pufferspeicher, schreibbar)
|
||
│ └── warmwasser_target # °C (Sollwert Warmwasser, schreibbar)
|
||
├── mode/
|
||
│ └── current # "winter" | "summer" | "transition" | "maintenance"
|
||
└── system/
|
||
├── revpi/heartbeat # Unix-Timestamp (sekündlich)
|
||
└── nodered/heartbeat # Unix-Timestamp (sekündlich)
|
||
```
|
||
|
||
### 6.2 Publish/Subscribe-Zuordnung
|
||
|
||
| Topic-Bereich | Publisher | Subscriber |
|
||
|---------------|-----------|-----------|
|
||
| `miners/+/state`, `miners/+/power` | Node-RED (gRPC) | RevPi, HA |
|
||
| `pumps/+/setpoint` | Node-RED | RevPi |
|
||
| `valves/+/state` | Node-RED | RevPi |
|
||
| `cooler/state` | Node-RED | RevPi |
|
||
| `heatpump/evu_sperre` | Node-RED | RevPi |
|
||
| `inverter/+` | Node-RED (sunsynk) | Node-RED |
|
||
| `temps/+` | RevPi (AI) | Node-RED, HA |
|
||
| `safety/+` | RevPi (DI) | Node-RED, HA |
|
||
| `setpoints/+` | (HA in Phase 1) | Node-RED |
|
||
| `mode/current` | Node-RED | alle |
|
||
| `system/+/heartbeat` | RevPi / Node-RED | gegenseitig |
|
||
|
||
### 6.3 QoS und Retained
|
||
|
||
- Setpoints und Modus: **QoS 1, retained=true** (überleben Neustart)
|
||
- Messwerte / Zustände: **QoS 0** (kein retained, hohe Frequenz)
|
||
- Safety-State: **QoS 1, retained=true**
|
||
- Heartbeats: **QoS 0**
|
||
|
||
---
|
||
|
||
## 7. RevolutionPi SPS-Programm
|
||
|
||
### 7.1 Aufgaben
|
||
|
||
Der RevPi ist für folgende Aufgaben zuständig:
|
||
|
||
1. Alle physischen I/O-Operationen (DO, DI, AO, AI)
|
||
2. Lesen der Temperatursensoren (AI1 Puffer, AI2 Warmwasser)
|
||
3. Lesen der Sicherheitsrückmeldung (DI_SAFETY_OK)
|
||
4. Lesen der Schützkontakt-Feedback (DI_K10_FB, DI_K11_FB)
|
||
5. Schalten von Relais und Analogausgängen laut MQTT-Befehle
|
||
6. Publizieren aller I/O-Zustände und Messwerte via MQTT
|
||
7. Heartbeat an `thermiq/system/revpi/heartbeat`
|
||
|
||
### 7.2 I/O-Mapping
|
||
|
||
#### Digitale Ausgänge (DO)
|
||
|
||
| DO-Pin | MQTT-Topic (subscribe) | Funktion | Ziel |
|
||
|--------|------------------------|----------|------|
|
||
| DO_K2 | `thermiq/cooler/state` | Rückkühler ein/aus | K2-Spule |
|
||
| DO_K3 | `thermiq/valves/rv1/state` (AUF) | RV1 öffnen | K3-Spule |
|
||
| DO_K4 | `thermiq/valves/rv1/state` (ZU) | RV1 schließen | K4-Spule |
|
||
| DO_K5 | `thermiq/valves/rv2/state` (AUF) | RV2 öffnen | K5-Spule |
|
||
| DO_K6 | `thermiq/valves/rv2/state` (ZU) | RV2 schließen | K6-Spule |
|
||
| DO_EVU | `thermiq/heatpump/evu_sperre` | EVU-Sperre WP | K7-Spule |
|
||
|
||
**Ventillogik (RV1, RV2):** K3 und K4 dürfen niemals gleichzeitig aktiv sein (Verriegelung im Programm). Gleiches gilt für K5/K6.
|
||
|
||
#### Analoge Ausgänge (AO)
|
||
|
||
| AO-Pin | MQTT-Topic (subscribe) | Funktion | Bereich |
|
||
|--------|------------------------|----------|---------|
|
||
| AO1 | `thermiq/pumps/p3/setpoint` | Pumpe P3 Drehzahl | 0–10 V |
|
||
| AO2 | `thermiq/pumps/p4/setpoint` | Pumpe P4 Drehzahl | 0–10 V |
|
||
| AO3 | `thermiq/pumps/p5/setpoint` | Pumpe P5 Drehzahl | 0–10 V |
|
||
|
||
- Wert 0.0 → 0 V (Pumpe minimal/aus)
|
||
- Wert 10.0 → 10 V (Pumpe maximal)
|
||
- Wert wird als Float im MQTT-Payload übertragen
|
||
|
||
#### Digitale Eingänge (DI)
|
||
|
||
| DI-Pin | MQTT-Topic (publish) | Signal | Quelle |
|
||
|--------|----------------------|--------|--------|
|
||
| DI_SAFETY_OK | `thermiq/safety/state` | Sicherheitsrelais-Ausgang | Sicherheitsrelais |
|
||
| DI_K10_FB | intern + `thermiq/miners/1/contactor` | K10 Hilfskontakt | K10 |
|
||
| DI_K11_FB | intern + `thermiq/miners/2/contactor` | K11 Hilfskontakt | K11 |
|
||
| DI_RK_FAULT | `thermiq/cooler/fault` | Rückkühler-Fehler | optional |
|
||
|
||
#### Analoge Eingänge (AI)
|
||
|
||
| AI-Pin | MQTT-Topic (publish) | Signal | Bereich |
|
||
|--------|----------------------|--------|---------|
|
||
| AI1 | `thermiq/temps/puffer` | Temperatur Pufferspeicher | TBD (4-20 mA oder 0-10 V) |
|
||
| AI2 | `thermiq/temps/warmwasser` | Temperatur Warmwasserspeicher | TBD |
|
||
|
||
- Rohwert wird in °C umgerechnet (Kalibrierformel TBD nach Sensortyp)
|
||
- Plausibilitätsprüfung: Wert außerhalb -10…+95 °C → Fehler publizieren
|
||
|
||
### 7.3 Programmstruktur (Python)
|
||
|
||
```
|
||
revpi_main.py
|
||
├── config.py # IP, Topics, Schwellwerte, Kalibrierung
|
||
├── io_driver.py # RevPi I/O Abstraktionsschicht (revpimodio)
|
||
├── mqtt_client.py # MQTT publish/subscribe Handler
|
||
├── safety_monitor.py # DI_SAFETY_OK Überwachung, Zustandsautomat
|
||
├── output_controller.py # Annahme und Ausführung von MQTT-Befehlen
|
||
├── sensor_reader.py # AI-Auslesen, Umrechnung, Plausibilität
|
||
└── heartbeat.py # Sekündlicher Heartbeat-Publisher
|
||
```
|
||
|
||
### 7.4 Zustandsautomat RevPi
|
||
|
||
```
|
||
INIT
|
||
└──► MQTT_CONNECT (warte auf Broker)
|
||
└──► RUNNING (Normal-Betrieb)
|
||
├──► SAFETY_TRIPPED (Sicherheitsrelais ausgelöst)
|
||
│ └──► RUNNING (nach Reset-Signal)
|
||
└──► MQTT_LOST (Verbindung verloren)
|
||
└──► RUNNING (nach Reconnect)
|
||
```
|
||
|
||
Im Zustand `SAFETY_TRIPPED`:
|
||
- Alle AO auf 0 V (Pumpen Minimum)
|
||
- Alle DO_Rückkühler, DO_EVU_SPERRE auf definierten Fallback-Wert (siehe Abschnitt 14)
|
||
- Keine Ventil-Schaltbefehle mehr ausführen
|
||
|
||
### 7.5 Publish-Intervalle
|
||
|
||
| Topic | Intervall |
|
||
|-------|-----------|
|
||
| `temps/puffer`, `temps/warmwasser` | 5 Sekunden |
|
||
| `safety/state` | Bei Zustandsänderung + alle 30 Sekunden |
|
||
| `system/revpi/heartbeat` | 1 Sekunde |
|
||
| Alle DI-Zustände | Bei Zustandsänderung + alle 60 Sekunden |
|
||
|
||
---
|
||
|
||
## 8. Node-RED Automatisierung
|
||
|
||
### 8.1 Aufgaben
|
||
|
||
Node-RED läuft auf dem Site Server und ist für folgende Aufgaben zuständig:
|
||
|
||
1. **Modbus-Polling** Deye Hybrid-Wechselrichter (RS485, sunsynk)
|
||
2. **Modbus-Polling** Energiezähler (RS485)
|
||
3. **gRPC-Client** für Antminer S19J (Braiins OS)
|
||
4. **Energiemanagement-Logik** (Entscheidung: Miner ein/aus, Leistungstuning)
|
||
5. **Wärmemanagement-Logik** (Pumpensteuerung, Ventile, Rückkühler, EVU-Sperre)
|
||
6. **Betriebsmodus-Verwaltung** (Winter / Sommer / Übergang / Wartung)
|
||
7. **Alarmierung** (bei Fehler, Timeout, Grenzwertüberschreitung)
|
||
8. **Heartbeat** an `thermiq/system/nodered/heartbeat`
|
||
|
||
### 8.2 Flow-Struktur
|
||
|
||
```
|
||
Flows/
|
||
├── 00_System # Heartbeat, MQTT-Verbindung, Systemstatus
|
||
├── 01_Deye_RS485 # sunsynk Polling, MQTT-Publish Inverter-Daten
|
||
├── 02_Energymeter # Energiezähler Modbus Polling
|
||
├── 03_Miner_gRPC # Braiins gRPC Client, Miner-Status, Leistungstuning
|
||
├── 04_EnergyMgmt # Energiemanagement-Entscheidungslogik
|
||
├── 05_HeatMgmt # Wärmemanagement (Pumpen, Ventile, Rückkühler, WP)
|
||
├── 06_Modes # Betriebsmodus-Automat
|
||
├── 07_Safety # Safety-State Überwachung, Reaktion
|
||
└── 08_Alarms # Alarmierungslogik, Logging
|
||
```
|
||
|
||
### 8.3 Flow 01 — Deye RS485 (sunsynk)
|
||
|
||
- sunsynk läuft als separater Python-Systemd-Service
|
||
- Publiziert Deye-Daten auf MQTT: `thermiq/inverter/+`
|
||
- Node-RED abonniert diese Topics und nutzt sie in den Entscheidungsflows
|
||
- Polling-Intervall: **10 Sekunden**
|
||
- Datenfelder:
|
||
- `solar_power` — PV-Erzeugung in W
|
||
- `battery_soc` — Batterieladezustand in %
|
||
- `grid_power` — Netzbezug/-einspeisung in W (negativ = Einspeisung)
|
||
- `load_power` — Hausverbrauch in W
|
||
|
||
Alternativ: Node-RED Modbus-RTU-Node direkt auf RS485 (falls sunsynk-Integration entfällt).
|
||
|
||
### 8.4 Flow 02 — Energiezähler
|
||
|
||
- Modbus RTU via USB RS485 Adapter
|
||
- Polling-Intervall: **10 Sekunden**
|
||
- Publish auf `thermiq/grid/meter` (Detail-Topics TBD nach Zählertyp)
|
||
|
||
### 8.5 Flow 03 — Miner gRPC
|
||
|
||
- Braiins OS gRPC-Server auf jedem Miner, Port **50051**
|
||
- Service: `braiins.bos.v1.PerformanceService`
|
||
- Authentifizierung: Bearer-Token in gRPC-Metadata
|
||
- **Polling-Intervall:** 30 Sekunden (Status-Abfrage)
|
||
- **Steuerbefehle:** bei Änderung der Ziel-Leistung
|
||
|
||
#### Funktionen
|
||
|
||
| Funktion | gRPC-Methode | MQTT-Trigger |
|
||
|----------|-------------|-------------|
|
||
| Miner-Status abfragen | `GetTunerState` | zyklisch 30 s |
|
||
| Leistung setzen | `SetPowerTarget` oder Tuner-API | `thermiq/miners/+/power_setpoint` |
|
||
| Miner-Power publizieren | — | publish `thermiq/miners/+/power` |
|
||
|
||
#### Miner Ein/Aus
|
||
|
||
- "Aus" = Kontaktor K10/K11 öffnen (Hardware-Sicherheitskreis) — **nicht** via gRPC
|
||
- gRPC steuert ausschließlich die **Leistung** (Power-Tuning, 0–100 %)
|
||
- Kontaktor wird über RevPi DO gesteuert (via MQTT)
|
||
|
||
> **Wichtig:** gRPC-Befehle werden nur gesendet, wenn `thermiq/safety/state = "ok"`.
|
||
|
||
### 8.6 Flow 04 — Energiemanagement
|
||
|
||
Entscheidungslogik, die sekündlich (oder bei Datenevent) ausgeführt wird:
|
||
|
||
```
|
||
Eingänge:
|
||
- solar_power (W)
|
||
- battery_soc (%)
|
||
- grid_power (W)
|
||
- load_power (W)
|
||
- mode/current
|
||
- temps/puffer (°C)
|
||
- safety/state
|
||
|
||
Entscheidungsbaum:
|
||
IF mode == "maintenance" → Miner AUS, keine Automatik
|
||
IF safety/state != "ok" → Miner AUS (bereits durch HW)
|
||
|
||
IF solar_power > (load_power + Schwellwert_solar):
|
||
→ Miner EIN, Leistung = 100%
|
||
|
||
ELSE IF battery_soc >= Schwellwert_soc_hoch:
|
||
→ Miner EIN, Leistung abhängig von SOC
|
||
|
||
ELSE IF grid_tariff == "cheap" AND zeitfenster_günstig():
|
||
→ Miner EIN, Leistung = konfigurierbar
|
||
|
||
ELSE IF battery_soc <= Schwellwert_soc_niedrig:
|
||
→ Miner AUS
|
||
|
||
ELSE:
|
||
→ Miner AUS (Standard-Fallback)
|
||
|
||
Ausgänge (via MQTT):
|
||
- thermiq/miners/1/power_setpoint
|
||
- thermiq/miners/2/power_setpoint
|
||
```
|
||
|
||
**Konfigurierbare Schwellwerte (in Node-RED Context oder Config-Flow):**
|
||
|
||
| Parameter | Default | Beschreibung |
|
||
|-----------|---------|-------------|
|
||
| `solar_excess_threshold` | 500 W | Überschuss-PV ab dem Miner laufen |
|
||
| `soc_high` | 80 % | SOC ab dem Miner aus Batterie laufen |
|
||
| `soc_low` | 20 % | SOC unter dem Miner gestoppt werden |
|
||
| `miner_ramp_step` | 10 % | Leistungsänderung pro Schritt |
|
||
| `miner_ramp_interval` | 60 s | Mindestabstand zwischen Leistungsänderungen |
|
||
|
||
### 8.7 Flow 05 — Wärmemanagement
|
||
|
||
```
|
||
Eingänge:
|
||
- temps/puffer (°C)
|
||
- temps/warmwasser (°C)
|
||
- miners/+/state (laufen Miner?)
|
||
- setpoints/puffer_target (°C)
|
||
- setpoints/warmwasser_target (°C)
|
||
- mode/current
|
||
|
||
Steuerausgaben (via MQTT → RevPi):
|
||
- pumps/p3/setpoint (Miner-Kühlkreis)
|
||
- pumps/p4/setpoint (Pufferspeicher-Kreis)
|
||
- pumps/p5/setpoint (Solar/Glykol-Kreis)
|
||
- valves/rv1/state (Wärmeverteilung)
|
||
- valves/rv2/state (Wärmeverteilung)
|
||
- cooler/state (Rückkühler)
|
||
- heatpump/evu_sperre (WP freigeben/sperren)
|
||
```
|
||
|
||
#### Wärmerouting-Logik
|
||
|
||
```
|
||
IF Miner laufen:
|
||
P3 EIN (Miner-Kühlkreis aktiv)
|
||
P4 EIN (Wärme Richtung Pufferspeicher)
|
||
|
||
IF temps/puffer >= puffer_target:
|
||
WP sperren (EVU_SPERRE = true / K7 geschlossen)
|
||
IF temp_miner_outlet > Schwellwert_rückkühlung:
|
||
Rückkühler EIN (K2)
|
||
ELSE:
|
||
Rückkühler AUS
|
||
ELSE:
|
||
WP freigeben (EVU_SPERRE = false / K7 offen)
|
||
Rückkühler AUS
|
||
|
||
ELSE (Miner AUS):
|
||
P3 AUS
|
||
IF temps/puffer < puffer_target:
|
||
WP freigeben (EVU_SPERRE = false)
|
||
ELSE:
|
||
WP sperren (EVU_SPERRE = true)
|
||
```
|
||
|
||
**Pumpendrehzahl-Regelung:** Einfache proportionale Regelung (P-Regler) oder feste Stufen (konfigurierbar). Hysterese bei Schaltgrenzen verpflichtend (min. 2 K Hysterese).
|
||
|
||
### 8.8 Flow 06 — Betriebsmodus
|
||
|
||
Manuell oder zeitgesteuert schaltbar.
|
||
|
||
| Modus | Beschreibung | Automatik |
|
||
|-------|-------------|-----------|
|
||
| `winter` | Miner-Wärme primär für Heizung | ja |
|
||
| `summer` | Miner-Wärme über Rückkühler ablösen | ja |
|
||
| `transition` | Hybrid, temperaturgesteuert | ja |
|
||
| `maintenance` | Alles manuell, keine Automatik | nein |
|
||
|
||
- Modus-Wechsel publiziert auf `thermiq/mode/current` (retained)
|
||
- Kein automatischer Modus-Wechsel ohne explizite Freigabe (konfigurierbar)
|
||
|
||
### 8.9 Flow 07 — Safety-Reaktion
|
||
|
||
- Abonniert `thermiq/safety/state`
|
||
- Bei `"tripped"`:
|
||
- Alle Miner-Leistungssetpoints auf 0
|
||
- Pumpen auf Minimum-Setpoint (konfigurierbar, z.B. 2 V für Grundzirkulation)
|
||
- Rückkühler AUS
|
||
- EVU-Sperre aufheben (WP darf laufen, übernimmt Heizung)
|
||
- Alarm-Flow auslösen
|
||
|
||
> Safety-Hardware handelt unabhängig und schneller. Dieser Flow ist die Softwarereaktions-Ebene.
|
||
|
||
### 8.10 Flow 08 — Alarmierung
|
||
|
||
Alarm-Bedingungen:
|
||
|
||
| Alarm | Bedingung | Schweregrad |
|
||
|-------|-----------|-------------|
|
||
| Safety Trip | `safety/state = "tripped"` | KRITISCH |
|
||
| RevPi Heartbeat Timeout | kein Heartbeat > 30 s | KRITISCH |
|
||
| Miner offline | `miners/+/state = "offline"` > 5 min | WARNUNG |
|
||
| Temperatur-Sensor Fehler | Wert außerhalb Plausibilitätsbereich | WARNUNG |
|
||
| Deye Polling Timeout | kein Inverter-Update > 60 s | WARNUNG |
|
||
| Puffer Temperatur kritisch | temp > 85 °C | KRITISCH |
|
||
|
||
Alarmausgabe (Phase 1): MQTT-Topic `thermiq/alarms/+` + Node-RED Dashboard-Eintrag.
|
||
Erweiterung (Phase 2): Push-Benachrichtigung, E-Mail (optional).
|
||
|
||
---
|
||
|
||
## 9. Betriebsmodi
|
||
|
||
### 9.1 Winter-Modus
|
||
|
||
- Miner laufen vorrangig bei Solar-Überschuss oder günstigem Netzstrom
|
||
- Miner-Wärme → Pufferspeicher
|
||
- WP ist Backup-Wärmequelle (freigegeben wenn Puffer zu kalt)
|
||
- Rückkühler nur bei Puffer-Überhitzung
|
||
|
||
### 9.2 Sommer-Modus
|
||
|
||
- Miner laufen bei Solar-Überschuss (Mining-Optimierung)
|
||
- Miner-Wärme → Rückkühler (Wärme nach außen ablösen)
|
||
- WP gesperrt (nicht nötig)
|
||
- Warmwasserbereitung weiterhin aktiv
|
||
|
||
### 9.3 Übergangs-Modus
|
||
|
||
- Hybrid-Entscheidung basierend auf Außentemperatur (sofern Sensor vorhanden) oder Datum
|
||
- Puffer-Sollwert temperaturabhängig angepasst
|
||
|
||
### 9.4 Wartungs-Modus
|
||
|
||
- Alle Automatikfunktionen deaktiviert
|
||
- Manuelle Steuerung über MQTT-Topics möglich (z.B. via HA oder MQTT-Client)
|
||
- Keine automatischen Eingriffe
|
||
|
||
---
|
||
|
||
## 10. Energiemanagement-Logik
|
||
|
||
### 10.1 Entscheidungspriorität (absteigend)
|
||
|
||
1. Sicherheitszustand (Safety OK?)
|
||
2. Betriebsmodus (Wartung → kein Automat)
|
||
3. Thermische Grenze (Puffer voll → Miner-Leistung reduzieren oder stoppen)
|
||
4. Solare Verfügbarkeit
|
||
5. Batterie-SOC
|
||
6. Netz-Tarif / Zeitfenster
|
||
|
||
### 10.2 Leistungsrampe
|
||
|
||
- Keine sprunghaften Leistungsänderungen
|
||
- Rampe: max. `miner_ramp_step` % pro `miner_ramp_interval` Sekunden
|
||
- Gilt für Hochfahren und Runterfahren
|
||
|
||
### 10.3 Mindest-Laufzeit / Sperrzeit
|
||
|
||
| Parameter | Default | Beschreibung |
|
||
|-----------|---------|-------------|
|
||
| `min_run_time` | 300 s | Miner läuft mindestens diese Zeit |
|
||
| `min_off_time` | 120 s | Miner bleibt mindestens diese Zeit aus |
|
||
|
||
---
|
||
|
||
## 11. Wärmemanagement-Logik
|
||
|
||
### 11.1 Temperaturgrenzen
|
||
|
||
| Sensor | Min (Alarm) | Sollwert (Default) | Max (Alarm) |
|
||
|--------|------------|-------------------|-------------|
|
||
| Pufferspeicher | 10 °C | 55 °C (konfigurierbar) | 85 °C |
|
||
| Warmwasserspeicher | 40 °C | 60 °C (konfigurierbar) | 70 °C |
|
||
|
||
### 11.2 Hysterese
|
||
|
||
Alle Schaltgrenzen haben eine Hysterese von **2 K** (konfigurierbar), um Flackern zu verhindern.
|
||
|
||
Beispiel Puffer:
|
||
- Einschalten WP: temp < (puffer_target - 2)
|
||
- Ausschalten WP: temp >= puffer_target
|
||
|
||
### 11.3 Pumpensteuerung
|
||
|
||
- P3 (Miner-Kühlkreis): **Ein/Aus** (keine Drehzahlregelung, DO reicht — AO0 = aus, AO_max = ein)
|
||
- P4 (Puffer-Kreis): **Drehzahlgeregelt** via AO2 (0–10 V), proportional zur Temperaturdifferenz
|
||
- P5 (Solar/Glykol-Kreis): **Drehzahlgeregelt** via AO3 (0–10 V)
|
||
|
||
### 11.4 Ventilsteuerung
|
||
|
||
- RV1 und RV2: **Schaltventile** (AUF/ZU, keine Zwischenstellung)
|
||
- Verriegelung: K3 und K4 niemals gleichzeitig aktiv (Programm + Hardware-Empfehlung)
|
||
- Fahrzeit beachten: nach Schaltbefehl min. 150 s warten bis Endlage (Belimo CQ230A typisch 120 s)
|
||
|
||
---
|
||
|
||
## 12. Miner-Steuerung (gRPC)
|
||
|
||
### 12.1 Verbindungsmanagement
|
||
|
||
- gRPC-Client baut Verbindung zu jedem Miner beim Start auf
|
||
- Reconnect-Logik: bei Verbindungsverlust alle 30 Sekunden Wiederverbindungsversuch
|
||
- Timeout pro gRPC-Call: 10 Sekunden
|
||
- Miner-Status `offline` nach 3 fehlgeschlagenen Polls
|
||
|
||
### 12.2 Power-Tuning
|
||
|
||
- Leistungsbereich: 0–100 % des Miner-Maximums
|
||
- Setpoint wird vom Energiemanagement-Flow gesetzt
|
||
- gRPC-Befehl nur senden wenn Differenz zum aktuellen Wert > 5 % (Totband)
|
||
- Bei Miner `offline`: kein gRPC-Befehl senden, Status `error` publizieren
|
||
|
||
### 12.3 Token-Verwaltung
|
||
|
||
- Bearer-Token in Node-RED Environment-Variable gespeichert (nicht im Flow hardcodiert)
|
||
- Konfiguration: `MINER1_TOKEN`, `MINER2_TOKEN`
|
||
|
||
---
|
||
|
||
## 13. Sicherheitslogik (Software-Ebene)
|
||
|
||
> **Die Hardware-Sicherheitskette (Sicherheitsrelais, E-Stop, FLOW OK, TEMP MAX) ist vollständig hardware-unabhängig von der Software und hat IMMER Vorrang.**
|
||
|
||
Die Software-Ebene ergänzt folgende Schutzfunktionen:
|
||
|
||
| Schutzfunktion | Beschreibung | Reaktion |
|
||
|---------------|-------------|---------|
|
||
| Puffer-Überhitzung (Software) | `temps/puffer > 80 °C` | Miner-Leistung auf 0, Rückkühler EIN |
|
||
| Warmwasser-Überhitzung | `temps/warmwasser > 68 °C` | EVU-Sperre AUS (WP blockiert) |
|
||
| Sensor-Ausfall | Plausibilitätsfehler AI | Sicherer Fallback-Zustand, Alarm |
|
||
| RevPi Heartbeat-Timeout | kein Heartbeat > 30 s | Node-RED stellt alle Setpoints auf Fallback |
|
||
| Gleichzeitige Ventil-Befehle | K3 + K4 gleichzeitig | Verriegelung im RevPi-Code |
|
||
| EVU-Kontakt-Check | K7-Ausgang überwacht | Kein Spannungsnachweis auf I1 möglich (informativ) |
|
||
|
||
---
|
||
|
||
## 14. Fallback- und Fehlerverhalten
|
||
|
||
### 14.1 MQTT-Verbindungsverlust (RevPi)
|
||
|
||
- RevPi verliert MQTT-Verbindung → alle letzten Befehle bleiben aktiv (kein Ändern mehr)
|
||
- Reconnect alle 10 Sekunden
|
||
- Nach 60 Sekunden ohne MQTT → RevPi fährt in definierten Sicher-Zustand:
|
||
- AO Pumpen: Grundlast-Setpoint (z.B. 3 V, konfigurierbar)
|
||
- DO Rückkühler: AUS
|
||
- DO EVU-Sperre: AUS (WP darf laufen — Heizung bleibt sicher)
|
||
- Ventile: letzte Position beibehalten
|
||
|
||
### 14.2 Node-RED Absturz
|
||
|
||
- MQTT Retained Topics bleiben aktiv → RevPi führt letzten bekannten Zustand aus
|
||
- Miner laufen weiter (Kontaktoren bleiben geschlossen solange Safety OK)
|
||
- Wärmepumpe reguliert sich autonom (EVU-Kontakt offen = WP läuft)
|
||
|
||
### 14.3 Deye RS485 Polling-Ausfall
|
||
|
||
- `solar_power`, `battery_soc` nicht mehr verfügbar
|
||
- Energiemanagement schaltet in Fallback-Modus: Miner AUS (konservativ)
|
||
- Alarm-Flow auslösen
|
||
|
||
### 14.4 Miner offline (gRPC)
|
||
|
||
- Status `offline` publizieren
|
||
- Leistungssteuerung via gRPC eingestellt
|
||
- Kontaktoren bleiben in letztem Zustand (keine automatische Abschaltung durch Software)
|
||
- Alarm-Flow auslösen
|
||
|
||
### 14.5 Sicherheitsrelais ausgelöst
|
||
|
||
- Hardware schaltet K10/K11 ab (Miner stromlos)
|
||
- RevPi erkennt DI_SAFETY_OK = LOW → publiziert `thermiq/safety/state = "tripped"`
|
||
- Node-RED Safety-Flow (Flow 07) reagiert (siehe 8.9)
|
||
- Kein automatischer Reset — manueller Reset am Schaltschrank erforderlich
|
||
|
||
---
|
||
|
||
## 15. Watchdog und Systemüberwachung
|
||
|
||
### 15.1 RevPi Watchdog
|
||
|
||
- Hardware-Watchdog des RevPi aktivieren (Systemd-Watchdog oder RevPi-intern)
|
||
- Wenn Programm hängt → Watchdog löst Neustart aus
|
||
- Nach Neustart: Autostart via Systemd, MQTT-Reconnect
|
||
|
||
### 15.2 Gegenseitige Heartbeat-Überwachung
|
||
|
||
- RevPi sendet sekündlich: `thermiq/system/revpi/heartbeat` (Unix-Timestamp)
|
||
- Node-RED sendet sekündlich: `thermiq/system/nodered/heartbeat`
|
||
- Timeout-Erkennung:
|
||
- RevPi überwacht Node-RED Heartbeat → bei Ausfall: Sicher-Zustand (14.2)
|
||
- Node-RED überwacht RevPi Heartbeat → bei Ausfall: Alarm, Fallback-Flow
|
||
|
||
### 15.3 Datums- und Zeitprüfung
|
||
|
||
- NTP-Synchronisation verpflichtend
|
||
- Systemzeit-Sprünge > 60 s auslösen Warnung im Alarm-Flow
|
||
|
||
---
|
||
|
||
## 16. Abnahme- und Testkriterien
|
||
|
||
### 16.1 RevPi I/O-Tests
|
||
|
||
| Test | Erwartetes Ergebnis |
|
||
|------|---------------------|
|
||
| MQTT-Befehl `pumps/p4/setpoint = 5.0` | AO2 misst 5 V ± 0,2 V |
|
||
| MQTT-Befehl `pumps/p4/setpoint = 0.0` | AO2 misst 0 V |
|
||
| MQTT-Befehl `pumps/p4/setpoint = 10.0` | AO2 misst 10 V |
|
||
| MQTT-Befehl `valves/rv1/state = open` | K3 zieht an, K4 bleibt offen |
|
||
| MQTT-Befehl `valves/rv1/state = closed` | K4 zieht an, K3 fällt ab |
|
||
| K3 und K4 gleichzeitig: Softwareverriegelung | K4 wird blockiert, Alarm |
|
||
| MQTT-Befehl `cooler/state = on` | DO_K2 = HIGH, K2 zieht an |
|
||
| MQTT-Befehl `heatpump/evu_sperre = true` | DO_EVU = HIGH, K7 zieht an |
|
||
| DI_SAFETY_OK = LOW | `safety/state = "tripped"` publiziert |
|
||
| AI1 Puffersensor 4 mA (0 °C) | `temps/puffer` publiziert 0 °C ± 1 K |
|
||
| AI1 Puffersensor 20 mA (100 °C) | `temps/puffer` publiziert 100 °C ± 1 K |
|
||
|
||
### 16.2 Node-RED Integrationstests
|
||
|
||
| Test | Erwartetes Ergebnis |
|
||
|------|---------------------|
|
||
| Deye RS485 erreichbar | `inverter/solar_power` aktualisiert alle ≤ 15 s |
|
||
| Deye offline | Alarm nach 60 s, Energiemanagement Fallback |
|
||
| Miner 1 gRPC erreichbar | `miners/1/state = "online"` |
|
||
| Miner 1 gRPC Timeout | `miners/1/state = "offline"`, Alarm |
|
||
| Energiemanagement: solar_power = 4000 W, soc = 50 % | Miner EIN, 100 % Leistung |
|
||
| Energiemanagement: solar_power = 0 W, soc = 15 % | Miner AUS |
|
||
| Wärmemanagement: temps/puffer = 60 °C, target = 55 °C | EVU_SPERRE = true |
|
||
| Wärmemanagement: temps/puffer = 40 °C, target = 55 °C | EVU_SPERRE = false |
|
||
| RevPi Heartbeat-Ausfall > 30 s | Alarm, Fallback-Setpoints gesendet |
|
||
| Safety Trip | Pumpen Minimum, Rückkühler AUS, EVU_SPERRE AUS |
|
||
|
||
### 16.3 Systemtest (End-to-End)
|
||
|
||
| Test | Kriterium |
|
||
|------|-----------|
|
||
| Miner anlaufen bei Solar-Überschuss | Binnen 5 min nach Schwellwert-Erreichen |
|
||
| Miner stoppen bei Batterie-Unterspannung | Binnen 2 min nach Schwellwert-Unterschreitung |
|
||
| WP blockiert bei warmem Puffer | EVU-Sperre gesetzt, WP läuft nicht |
|
||
| WP freigegeben bei kaltem Puffer | EVU-Sperre aufgehoben, WP kann anlaufen |
|
||
| E-Stop auslösen | K10/K11 sofort offen, `safety/state = "tripped"` |
|
||
| Kompletter Site-Server-Neustart | Alle Dienste nach ≤ 60 s wieder aktiv |
|
||
|
||
### 16.4 Anforderungsabdeckung (Traceability)
|
||
|
||
Die folgende Matrix verknüpft die formalen Anforderungen mit den Testfällen:
|
||
|
||
| Anforderung | Abgedeckt durch Test |
|
||
|-------------|---------------------|
|
||
| FA-001 bis FA-009 | Abschnitt 16.1 (RevPi I/O-Tests) |
|
||
| FA-010, FA-020 | 16.2 — Deye RS485 erreichbar / Polling |
|
||
| FA-011 | 16.2 — Miner gRPC erreichbar |
|
||
| FA-012, FA-019 | 16.2 — Energiemanagement-Tests |
|
||
| FA-013 | 16.2 — Wärmemanagement-Tests |
|
||
| FA-015, FA-016, FA-017 | 16.2 — Safety Trip, Heartbeat-Ausfall |
|
||
| SA-001, SA-002 | 16.3 — E-Stop auslösen |
|
||
| SA-003 | 16.2 — Wärmemanagement: Puffer > 80 °C |
|
||
| NFA-001, NFA-002, NFA-003 | 16.3 — Kompletter Neustart |
|
||
| NFA-004 | 16.2 — Safety Trip (Reaktionszeit messen) |
|
||
|
||
---
|
||
|
||
## 17. Offene Punkte
|
||
|
||
| # | Thema | Status |
|
||
|---|-------|--------|
|
||
| 1 | Sensortyp Pufferspeicher (PT1000 vs. 4-20 mA) — beeinflusst AI-Kalibrierung | **offen** |
|
||
| 2 | Sensortyp Warmwasserspeicher | **offen** |
|
||
| 3 | Deye Modbus-Register-Map (sunsynk vs. direkte Modbus-Abfrage) | **offen** |
|
||
| 4 | Netz-Tarif-Integration (dynamischer Strompreis, API TBD) | **Phase 2** |
|
||
| 5 | Smart Meter Protokoll und Integration | **offen** |
|
||
| 6 | Batterie-Kapazität und -Typ (Auswirkung auf SOC-Schwellwerte) | **offen** |
|
||
| 7 | Außentemperatursensor (für Übergangs-Modus automatisch) | **optional** |
|
||
| 8 | gRPC-Token-Rotations-Strategie (Miner Braiins OS) | **offen** |
|
||
| 9 | Node-RED Environment-Variables Setup Dokumentation | **offen** |
|
||
| 10 | Logging-Strategie (Influx DB, CSV, oder nur MQTT?) | **Phase 2** |
|
||
|
||
---
|
||
|
||
*Pflichtenheft ThermIQ ASP1 Software — v2.0 — 2026-05*
|