1173 lines
60 KiB
Markdown
1173 lines
60 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.1
|
||
|
||
**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 via MQTT)
|
||
- die **Node-RED Automatisierungslogik** auf dem Site Server (Intel N100)
|
||
- die **Netzwerk- und Remote-Zugriffs-Konfiguration** (VPN, Firewall, Router)
|
||
|
||
Home Assistant (Phase-1-Dashboard) ist in diesem Dokument **nicht** enthalten und wird separat spezifiziert.
|
||
|
||
> **Hinweis zur physischen Installation:** Die physische Installation und Inbetriebnahme des Schaltschranks (Verdrahtung, Montage, Elektroabnahme) wird von Adrian durchgeführt und ist in einem **separaten Pflichtenheft Inbetriebnahme ASP1** dokumentiert. Dieses Dokument und das Inbetriebnahme-Pflichtenheft sind unabhängig voneinander abnahmefähig und blockieren sich nicht gegenseitig.
|
||
|
||
### 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 | Elektrische Hausinstallation |
|
||
| Energie- und Wärmemanagement-Logik | Buderus-interne Konfiguration |
|
||
| Netzwerktopologie im Schrank (Router, Switch, IP-Vergabe, VPN, Firewall) | Physische Schaltschrank-Installation (→ Pflichtenheft Inbetriebnahme) |
|
||
| Watchdog und Alarmierung | |
|
||
|
||
---
|
||
|
||
## 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. **Vollautomatischer** Modus-Wechsel (Winter/Sommer) basierend auf Außentemperatursensor ohne manuelle Eingabe. Die vier Betriebsmodi selbst (`winter`, `summer`, `transition`, `maintenance`) sowie manuelles Umschalten zwischen ihnen sind Musskriterium (FA-014); lediglich der **vollautomatische** Wechsel ohne Benutzereingriff ist 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. Elektrische Hausinstallation (Zähler, Unterverteilung, Absicherung).
|
||
4. Buderus-interne Konfiguration (Heizkurven, Hydraulikweichen).
|
||
5. Cloud-Anbindung und externe Cloud-Services (Phase 1).
|
||
6. Physische Installation und Inbetriebnahme des Schaltschranks (→ separates Pflichtenheft Inbetriebnahme ASP1).
|
||
|
||
> **Hinweis:** Die Netzwerktopologie im Schaltschrank (Router, Switch, IP-Plan, VPN, Firewall) ist explizit **Teil dieses Pflichtenhefts** und in Abschnitt 3.6 spezifiziert.
|
||
|
||
---
|
||
|
||
## 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)
|
||
|
||
Dieser Abschnitt beschreibt alle funktionalen Anforderungen an das System — d. h. was das System tun muss. Aufgeteilt in RevPi-SPS-Ebene (direkte I/O-Steuerung) und Node-RED-Ebene (Automatisierungslogik, Protokoll-Integration).
|
||
|
||
#### 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`. Alle vier Modi müssen existieren und manuell schaltbar sein. Der aktive Modus muss auf `thermiq/mode/current` (retained) publiziert werden. **Hinweis:** Der vollautomatische Modus-Wechsel ohne Benutzereingriff (basierend auf Außentemperatur) ist ein Wunschkriterium (2.2.2) und kein MUSS. |
|
||
| 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)
|
||
|
||
Dieser Abschnitt beschreibt Qualitätsanforderungen an das System — wie es sich verhalten soll (Verfügbarkeit, Reaktionszeit, Wartbarkeit, Datensicherheit). Diese Anforderungen sind unabhängig von einzelnen Funktionen und gelten systemweit.
|
||
|
||
| 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. **Anmerkung zur Programmierstrategie:** Der RevolutionPi unterstützt grundsätzlich auch CodeSys (IEC 61131-3). Für dieses Projekt wurde bewusst **Python** gewählt, da: (1) MQTT- und gRPC-Bibliotheken nativ verfügbar sind, (2) kein CodeSys-Lizenzaufwand anfällt, (3) der gesamte Stack (Node-RED, gRPC-Client, Miner-Integration) auf Python/JavaScript basiert und eine einheitliche Programmiersprache die Wartung vereinfacht. Das RevPi-Programm wird ausschließlich in Python 3 mit `paho-mqtt` und `revpimodio` entwickelt. |
|
||
| 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)
|
||
|
||
Dieser Abschnitt definiert alle Anforderungen, die den sicheren Betrieb der Anlage gewährleisten. Die Hardware-Sicherheitskette hat immer Vorrang vor Software-Schutzfunktionen; die hier aufgeführten Anforderungen beschreiben ergänzende Software-Schutzebenen sowie Anforderungen an die Dokumentation der Hardware-Sicherheit.
|
||
|
||
| ID | Verbindlichkeit | Anforderung |
|
||
|----|----------------|-------------|
|
||
| SA-001 | MUSS | Die Hardware-Sicherheitskette (Sicherheitsrelais, E-Stop, TEMP MAX) muss vollständig unabhängig von der Software arbeiten. Die Software darf die Hardware-Sicherheitskette weder überbrücken noch deaktivieren. **Anmerkung:** Ein physischer Durchflusssensor (FLOW OK) wird nicht verbaut. Die Überwachung der Miner-Kühlkreistüchtigkeit erfolgt softwareseitig durch Auswertung der Miner-Temperaturen: ein unzureichender Durchfluss äußert sich in abnormal steigenden Temperaturen (SA-007) und wird durch die Software-Sicherheitslogik erkannt und behandelt. |
|
||
| SA-002 | MUSS | Ein Hardware-Safety-Reset (Wiedereinschalten von K10/K11 nach Trip) erfordert zwingend einen physischen Reset-Taster am Schaltschrank — dies ist durch die Sicherheitsrelais-Beschaltung (Rückführkreis) hardware-seitig erzwungen und kann nicht software-seitig umgangen werden. **Software-Safety-Reset:** Der Software-Sicherheitszustand (MQTT `safety/state`) soll zusätzlich per Fernzugriff (VPN/SSH) quittierbar sein, um bei kurzfeitigen Sensor-Fehlalarmen nicht zwingend vor Ort erscheinen zu müssen. Der Software-Reset ändert ausschließlich den MQTT-Zustand; die Hardware-Sicherheitskette bleibt davon unberührt. |
|
||
| 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 | Bei `thermiq/safety/state = "tripped"` muss Node-RED sofort aktiv gRPC-Befehle an alle Miner senden, um die Leistung auf 0 W zu setzen (soweit Miner noch erreichbar). Neue Leistungs-Setpoints dürfen nur gesendet werden, wenn `thermiq/safety/state = "ok"`. Hinweis: Die Hardware-Abschaltung über K10/K11 hat Vorrang; die gRPC-Leistungsreduzierung ist eine ergänzende Software-Schutzmaßnahme für den Fall, dass die Schütze noch geschlossen sind und die Miner noch reagieren. |
|
||
| 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 Quittierung. Die Quittierung soll sowohl **physisch vor Ort** (z. B. per HA-Dashboard) als auch **per Fernzugriff via VPN** möglich sein (vgl. SA-002), um zu vermeiden, dass ein kurzfristiger Sensor-Ausreißer eine Anreise zur Anlage erzwingt. |
|
||
| SA-008 | MUSS | Die Ventil-Verriegelung (K3 und K4 dürfen niemals gleichzeitig aktiv sein; ebenso K5/K6) muss auf zwei Ebenen sichergestellt sein: (1) **Software-Verriegelung im RevPi-Programm** — der Code prüft vor jedem Schaltbefehl, dass das Gegenstück nicht aktiv ist; (2) **Dokumentation im Schaltplan** — der Verdrahtungsplan enthält eine Notiz/Empfehlung zur Hardware-Verriegelung (z. B. mechanische oder elektrische Gegensperrung), damit auch bei zukünftigen Schaltplan-Änderungen die Verriegelungs-Absicht erkennbar bleibt. |
|
||
| 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)
|
||
|
||
Dieser Abschnitt definiert die Anforderungen an alle externen und internen Kommunikationsschnittstellen — Protokolle, Formate und physische Medien. Alle Schnittstellen müssen exakt wie spezifiziert implementiert werden, um Interoperabilität zu gewährleisten.
|
||
|
||
| 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.6 Netzwerk- und Remote-Zugriff-Anforderungen (NW)
|
||
|
||
Dieser Abschnitt definiert die Anforderungen an die Netzwerktopologie im Schaltschrank sowie an den sicheren Remote-Zugriff auf das System. Remote-Zugriff ist notwendig, um Node-RED und das System aus der Ferne warten, debuggen und steuern zu können, ohne physisch vor Ort sein zu müssen.
|
||
|
||
| ID | Verbindlichkeit | Anforderung |
|
||
|----|----------------|-------------|
|
||
| NW-001 | MUSS | Der Schaltschrank muss einen Router (z. B. GL.iNet oder vergleichbar) mit konfigurierbaren Firewall-Regeln enthalten. Alle kritischen Geräte (RevPi, Site Server, Miner) sind ausschließlich hinter diesem Router. |
|
||
| NW-002 | MUSS | Der Router muss feste IP-Adressen für alle kritischen Geräte (RevPi, Site Server, Miner 1, Miner 2) verwalten (DHCP-Reservierung oder statische Konfiguration). |
|
||
| NW-003 | MUSS | Der Router muss eine Firewall-Regel-Konfiguration enthalten, die ausschließlich definierten Datenverkehr zwischen den Geräten erlaubt. Unkontrollierter Zugang aus dem Hausnetz oder Internet ist unzulässig. |
|
||
| NW-004 | MUSS | Das System muss per VPN erreichbar sein. Ein VPN-Endpunkt (z. B. WireGuard auf dem Router oder Site Server) muss konfiguriert sein, um Remote-Zugriff für Wartung und Fernsteuerung zu ermöglichen. |
|
||
| NW-005 | MUSS | Der Site Server (Node-RED) muss per SSH über das VPN fernsteuerbar sein. SSH-Zugang ist ausschließlich über VPN erlaubt; direkte SSH-Erreichbarkeit aus dem Internet ist gesperrt. |
|
||
| NW-006 | SOLL | Node-RED soll über das VPN per Browser erreichbar sein (Node-RED UI auf Port 1880), gesichert durch Passwortauthentifizierung. |
|
||
| NW-007 | MUSS | Der RevPi muss per SSH über das VPN erreichbar sein (für Wartung und Programm-Updates). |
|
||
| NW-008 | SOLL | Eine Netzwerktopologie-Dokumentation (IP-Plan, Geräteliste, offene Ports, Firewall-Regeln) soll als separates Dokument im Projektordner gepflegt werden. |
|
||
|
||
---
|
||
|
||
### 3.5 Randbedingungen (RB)
|
||
|
||
Dieser Abschnitt listet vorgegebene Rahmenbedingungen, die nicht Gegenstand der Entwicklung sind, aber die Realisierung maßgeblich beeinflussen. Sie sind unveränderliche Vorgaben des Projekts.
|
||
|
||
| 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
|
||
|
||
Dieser Abschnitt beschreibt die Systemarchitektur auf drei Ebenen (Supervision, Control, Field) und die Kommunikationswege zwischen den Komponenten. Er dient als Orientierung für alle weiteren Kapitel.
|
||
|
||
```mermaid
|
||
---
|
||
config:
|
||
layout: dagre
|
||
theme: neo
|
||
---
|
||
flowchart TB
|
||
subgraph SUP["SUPERVISION LAYER — Intel N100 Site Server"]
|
||
NRD["Node-RED Automation<br>sunsynk RS485 · gRPC Miners"]
|
||
MOS["Mosquitto MQTT Broker"]
|
||
end
|
||
subgraph CTRL["CONTROL LAYER"]
|
||
REV["RevolutionPi Core+DIO+AIO<br>Python MQTT · I/O-Treiber"]
|
||
end
|
||
subgraph FIELD["FIELD LAYER"]
|
||
AKT["Miner 1/2 · K10/K11<br>Rückkühler K2 · WP EVU K7"]
|
||
IO["Pumpen P3/P4/P5<br>Ventile RV1/RV2 · Sensoren AI"]
|
||
end
|
||
NRD -- pub/sub --> MOS
|
||
NRD -- gRPC --> AKT
|
||
MOS -- MQTT TCP 1883 --> REV
|
||
REV L_REV_IO_0@-- DO / AO --> IO
|
||
|
||
style NRD fill:#fff,stroke:#FFD600,color:#1e293b
|
||
style MOS fill:#fff,stroke:#FFD600,color:#1e293b
|
||
style REV fill:#fff,stroke:#00C853,color:#1e293b
|
||
style AKT fill:#fff,stroke:#6366f1,color:#1e293b
|
||
style IO fill:#fff,stroke:#6366f1,color:#1e293b
|
||
style SUP fill:#FFF9C4,stroke:#FFD600,color:#1e293b
|
||
style CTRL fill:#C8E6C9,stroke:#00C853,color:#1e293b
|
||
style FIELD fill:#eef2ff,stroke:#6366f1,color:#1e293b
|
||
|
||
L_REV_IO_0@{ curve: linear }
|
||
```
|
||
|
||
**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
|
||
|
||
Die Netzwerktopologie im Schaltschrank ist ein integraler Bestandteil der Software-Inbetriebnahme. Dieser Abschnitt beschreibt die physische und logische Netzwerkkonfiguration; detaillierte Anforderungen in Abschnitt 3.6.
|
||
|
||
- Ausschließlich kabelgebundenes Ethernet, kein WLAN für kritische Geräte
|
||
- Router im Schaltschrank (z. B. GL.iNet) mit VPN-Endpunkt und Firewall
|
||
- NTP-Zeitsynchronisation auf RevPi und Site Server verpflichtend
|
||
- Feste IPs für RevPi, Site Server, Miner 1, Miner 2
|
||
- VPN-Zugang für Remote-Wartung (SSH, Node-RED UI)
|
||
|
||
---
|
||
|
||
## 6. MQTT-Datenbus
|
||
|
||
Dieser Abschnitt definiert den MQTT-Datenbus als zentrales Kommunikationsrückgrat des Systems. Er beschreibt die vollständige Topic-Struktur, die Publish/Subscribe-Zuordnungen sowie die Übertragungsqualitäts- und Persistenzregeln. Alle Komponenten kommunizieren ausschließlich über den hier definierten Bus.
|
||
|
||
Mosquitto läuft auf dem Site Server. Alle Komponenten kommunizieren über diesen Broker.
|
||
|
||
### 6.1 Topic-Struktur
|
||
|
||
Dieser Abschnitt definiert die vollständige MQTT-Topic-Hierarchie. Die Struktur ist verbindlich — eigenmächtige Abweichungen sind unzulässig (SI-002). Topics ohne explizite Angabe sind lesend (publish-only); als „schreibbar" markierte Topics können von externen Systemen (Node-RED, Home Assistant) beschrieben werden.
|
||
|
||
```mermaid
|
||
---
|
||
config:
|
||
layout: elk
|
||
theme: mc
|
||
look: neo
|
||
---
|
||
flowchart LR
|
||
thermiq["thermiq/"] --> miners["miners/"] & pumps["pumps/"] & valves["valves/"] & cooler["cooler/state (W)"] & hp["heatpump/"] & inverter["inverter/"] & temps["temps/"] & safety["safety/"] & setpoints["setpoints/"] & mode["mode/current (W)"] & system["system/"]
|
||
miners --> m1["1/"] & m2["2/"]
|
||
m1 --> m1_props["state<br>power<br>hashrate<br>temp<br>power_setpoint (W)<br>contactor"]
|
||
m2 --> m2_props["state<br>power<br>hashrate<br>temp<br>power_setpoint (W)<br>contactor"]
|
||
pumps --> p3["p3/state"] & p4["p4/setpoint (V)"] & p5["p5/setpoint (V)"]
|
||
valves --> rv1["rv1/state (W)"] & rv2["rv2/state (W)"]
|
||
hp --> hp_props["evu_sperre (W)<br>state"]
|
||
inverter --> inv_p["solar_power<br>pv1_power<br>pv2_power<br>battery_soc<br>battery_power<br>battery_voltage<br>battery_current<br>battery_temp<br>grid_power<br>grid_voltage<br>grid_freq<br>load_power<br>inv_temp"] & inv_e["day_pv_energy<br>day_load_energy<br>day_grid_import<br>day_grid_export"]
|
||
temps --> t_props["puffer<br>warmwasser<br>aussen<br>miner1 (alias)<br>miner2 (alias)"]
|
||
safety --> s_props["state<br>reason"]
|
||
setpoints --> sp_props["puffer_target (W)<br>warmwasser_target (W)<br>miner1_power_target (W)<br>miner2_power_target (W)"]
|
||
system --> sys_props["revpi/heartbeat<br>nodered/heartbeat"]
|
||
|
||
style thermiq stroke:#AA00FF,fill:#E1BEE7
|
||
style miners stroke:#00C853,fill:#C8E6C9
|
||
style pumps stroke:#00C853,fill:#C8E6C9
|
||
style valves stroke:#00C853,fill:#C8E6C9
|
||
style cooler stroke:#00C853,fill:#C8E6C9
|
||
style hp stroke:#00C853,fill:#C8E6C9
|
||
style inverter stroke:#00C853,fill:#C8E6C9
|
||
style temps stroke:#00C853,fill:#C8E6C9
|
||
style safety stroke:#00C853,fill:#C8E6C9
|
||
style setpoints stroke:#00C853,fill:#C8E6C9
|
||
style mode stroke:#00C853,fill:#C8E6C9
|
||
style system stroke:#00C853,fill:#C8E6C9
|
||
style m1_props text-align:left
|
||
style m2_props text-align:left
|
||
style inv_p text-align:left
|
||
style inv_e text-align:left
|
||
style t_props text-align:left
|
||
style sp_props text-align:left
|
||
|
||
```
|
||
<!--
|
||
```
|
||
thermiq/
|
||
├── miners/
|
||
│ ├── 1/state # "online" | "offline" | "error"
|
||
│ ├── 1/power # Watt (float) — Ist-Leistung
|
||
│ ├── 1/hashrate # TH/s (float) — Miner 1 hat Hashrate-Feedback via gRPC
|
||
│ ├── 1/temp # °C (float) — Chip-Temperatur via gRPC
|
||
│ ├── 1/power_setpoint # Watt (float) — SCHREIBBAR, Ziel-Leistung
|
||
│ ├── 1/contactor # "closed" | "open" — K10 Hilfskontakt-Rückmeldung
|
||
│ ├── 2/state # "online" | "offline" | "error"
|
||
│ ├── 2/power # Watt (float) — Ist-Leistung
|
||
│ ├── 2/hashrate # TH/s (float) — Hashrate-Feedback via gRPC
|
||
│ ├── 2/temp # °C (float) — Chip-Temperatur via gRPC
|
||
│ ├── 2/power_setpoint # Watt (float) — SCHREIBBAR, Ziel-Leistung
|
||
│ └── 2/contactor # "closed" | "open" — K11 Hilfskontakt-Rückmeldung
|
||
├── pumps/
|
||
│ ├── p3/state # "on" | "off" — Relay-Zustand (P3 = einfaches Relais, kein Drehzahlsignal)
|
||
│ ├── p4/setpoint # 0.0–10.0 (V, float) — SCHREIBBAR, Drehzahl-Sollwert Wilo P4
|
||
│ └── p5/setpoint # 0.0–10.0 (V, float) — SCHREIBBAR, Drehzahl-Sollwert Wilo P5
|
||
├── valves/
|
||
│ ├── rv1/state # "open" | "closed" — SCHREIBBAR
|
||
│ └── rv2/state # "open" | "closed" — SCHREIBBAR
|
||
├── cooler/
|
||
│ └── state # "on" | "off" — SCHREIBBAR
|
||
├── heatpump/
|
||
│ ├── evu_sperre # "true" | "false" — SCHREIBBAR (true = WP gesperrt)
|
||
│ └── state # "running" | "blocked" | "fault"
|
||
├── inverter/
|
||
│ ├── solar_power # W (float) — Gesamt-PV-Erzeugung
|
||
│ ├── pv1_power # W (float) — PV-String 1
|
||
│ ├── pv2_power # W (float) — PV-String 2
|
||
│ ├── battery_soc # % (0–100, float)
|
||
│ ├── battery_power # W (float) — positiv = laden, negativ = entladen
|
||
│ ├── battery_voltage # V (float)
|
||
│ ├── battery_current # A (float)
|
||
│ ├── battery_temperature # °C (float)
|
||
│ ├── grid_power # W (float) — positiv = Bezug, negativ = Einspeisung
|
||
│ ├── grid_voltage # V (float)
|
||
│ ├── grid_frequency # Hz (float)
|
||
│ ├── load_power # W (float) — Hausverbrauch
|
||
│ ├── inverter_temperature # °C (float)
|
||
│ ├── day_pv_energy # kWh (float) — Tagesertrag PV
|
||
│ ├── day_load_energy # kWh (float) — Tagesverbrauch
|
||
│ ├── day_grid_import # kWh (float)
|
||
│ └── day_grid_export # kWh (float)
|
||
├── temps/
|
||
│ ├── puffer # °C (float) — RevPi AI1
|
||
│ ├── warmwasser # °C (float) — RevPi AI2
|
||
│ ├── aussen # °C (float) — Außentemperatursensor
|
||
│ ├── miner1 # °C (float) — Miner 1 Chip-Temp via gRPC (alias für miners/1/temp)
|
||
│ └── miner2 # °C (float) — Miner 2 Chip-Temp via gRPC (alias für miners/2/temp)
|
||
├── safety/
|
||
│ ├── state # "ok" | "tripped"
|
||
│ └── reason # "temp_hw" | "estop" | "temp_sensor_fault" | "none"
|
||
├── setpoints/
|
||
│ ├── puffer_target # °C (float) — SCHREIBBAR, Sollwert Pufferspeicher
|
||
│ ├── warmwasser_target # °C (float) — SCHREIBBAR, Sollwert Warmwasser
|
||
│ ├── miner1_power_target # W (float) — SCHREIBBAR, Alias für miners/1/power_setpoint
|
||
│ └── miner2_power_target # W (float) — SCHREIBBAR, Alias für miners/2/power_setpoint
|
||
├── mode/
|
||
│ └── current # "winter" | "summer" | "transition" | "maintenance" — SCHREIBBAR (retained)
|
||
└── system/
|
||
├── revpi/heartbeat # Unix-Timestamp (sekündlich)
|
||
└── nodered/heartbeat # Unix-Timestamp (sekündlich)
|
||
```
|
||
-->
|
||
|
||
### 6.2 Publish/Subscribe-Zuordnung
|
||
|
||
Dieser Abschnitt zeigt für jeden Topic-Bereich, welche Komponente publiziert und welche subscribed. Ein Topic kann nur einen primären Publisher haben.
|
||
|
||
| Topic-Bereich | Publisher | Subscriber |
|
||
|---------------|-----------|-----------|
|
||
| `miners/1/state`, `miners/1/power`, `miners/1/hashrate`, `miners/1/temp` | Node-RED (gRPC) | RevPi, HA |
|
||
| `miners/2/state`, `miners/2/power`, `miners/2/hashrate`, `miners/2/temp` | Node-RED (gRPC) | RevPi, HA |
|
||
| `miners/+/power_setpoint` | Node-RED (Energiemanagement) | Node-RED (gRPC-Flow) |
|
||
| `miners/+/contactor` | RevPi (DI) | Node-RED, HA |
|
||
| `pumps/p3/state` | Node-RED | RevPi |
|
||
| `pumps/p4/setpoint`, `pumps/p5/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/puffer`, `temps/warmwasser` | RevPi (AI) | Node-RED, HA |
|
||
| `temps/aussen` | RevPi (AI) oder Site Server | Node-RED, HA |
|
||
| `temps/miner1`, `temps/miner2` | Node-RED (gRPC) | Node-RED, HA |
|
||
| `safety/+` | RevPi (DI) | Node-RED, HA |
|
||
| `setpoints/+` | HA oder Extern (Phase 1) | Node-RED |
|
||
| `mode/current` | Node-RED | alle |
|
||
| `system/+/heartbeat` | RevPi / Node-RED | gegenseitig |
|
||
|
||
### 6.3 QoS und Retained
|
||
|
||
Dieser Abschnitt definiert die Übertragungsqualität und Persistenz-Einstellungen für MQTT-Nachrichten.
|
||
|
||
**Nomenklatur:**
|
||
- **QoS 0** (At most once): Nachricht wird einmal gesendet, keine Bestätigung. Geeignet für hochfrequente Messwerte, bei denen ein verlorenes Paket unerheblich ist.
|
||
- **QoS 1** (At least once): Nachricht wird so lange wiederholt, bis der Broker eine Bestätigung sendet. Geeignet für Zustandsänderungen und Steuerbefehle.
|
||
- **retained=true**: Der Broker speichert die letzte Nachricht eines Topics und sendet sie sofort an neue Subscribers. Wichtig für Sollwerte und Modus, damit Geräte beim Start sofort den aktuellen Sollwert kennen.
|
||
- **retained=false**: Keine gespeicherte Nachricht — neue Subscribers erhalten erst Daten nach dem nächsten Publish.
|
||
|
||
**Zuordnung:**
|
||
|
||
| Topic-Kategorie | QoS | Retained | Begründung |
|
||
|-----------------|-----|----------|-----------|
|
||
| Setpoints (`setpoints/+`) | 1 | true | Sollwerte überleben Neustart |
|
||
| Modus (`mode/current`) | 1 | true | Modus überleben Neustart |
|
||
| Safety-State (`safety/state`) | 1 | true | Sicherheitszustand beim Start sofort bekannt |
|
||
| Messwerte (`temps/+`, `inverter/+`) | 0 | false | Hohe Frequenz, Verlust akzeptabel |
|
||
| Miner-Status (`miners/+/state`) | 0 | false | Wird regelmäßig aktualisiert |
|
||
| Heartbeats (`system/+/heartbeat`) | 0 | false | Sekündlich, retained sinnlos |
|
||
| Alarme (`alarms/+`) | 1 | false | Sicher zustellen, kein Retain |
|
||
|
||
---
|
||
|
||
## 7. RevolutionPi SPS-Programm
|
||
|
||
Dieser Abschnitt beschreibt das Python-Programm auf dem RevolutionPi: seine Aufgaben, das I/O-Mapping aller physischen Anschlüsse, die Programmstruktur, den Zustandsautomaten sowie die Publish-Intervalle. Der RevPi ist die einzige Komponente mit direktem Zugriff auf physische I/Os.
|
||
|
||
### 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)
|
||
|
||
```mermaid
|
||
---
|
||
config:
|
||
layout: elk
|
||
theme: mc
|
||
---
|
||
flowchart LR
|
||
main["revpi_main.py (Core Logic)"] --> config["config.py<br>(Parameters & Calibration)"] & io["io_driver.py<br>(RevPiModIO Layer)"] & mqtt["mqtt_client.py<br>(Pub/Sub Handler)"] & safety["safety_monitor.py<br>(DI/State Machine)"] & control["output_controller.py<br>(Command Execution)"] & sensor["sensor_reader.py<br>(Analog Conversion)"] & hb["heartbeat.py<br>(Status Pulse)"]
|
||
|
||
style main fill:#E1BEE7,stroke:#AA00FF,stroke-width:2px
|
||
style config fill:#ffffff
|
||
style io fill:#ffffff
|
||
style safety fill:#ffffff
|
||
```
|
||
|
||
<!--
|
||
```
|
||
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
|
||
|
||
```mermaid
|
||
---
|
||
config:
|
||
layout: elk
|
||
theme: mc
|
||
---
|
||
stateDiagram
|
||
direction TB
|
||
state RUNNING {
|
||
direction TB
|
||
[*] --> Normal_Operation
|
||
[*] Normal_Operation
|
||
}
|
||
[*] --> INIT
|
||
INIT --> MQTT_CONNECT:Startup
|
||
MQTT_CONNECT --> RUNNING:Broker Connected
|
||
RUNNING --> SAFETY_TRIPPED:DI_SAFETY_OK == False
|
||
SAFETY_TRIPPED --> RUNNING:Reset Signal / OK
|
||
RUNNING --> MQTT_LOST:Connection Dropped
|
||
MQTT_LOST --> RUNNING:Reconnect Successful
|
||
```
|
||
<!--
|
||
```
|
||
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
|
||
|
||
Dieser Abschnitt beschreibt die Node-RED-Flows auf dem Site Server. Node-RED ist die einzige Quelle für Automatisierungslogik — alle Entscheidungen über Energie-, Wärme- und Sicherheitsreaktionen werden hier getroffen und über MQTT an den RevPi kommuniziert.
|
||
|
||
### 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
|
||
|
||
```mermaid
|
||
---
|
||
config:
|
||
theme: mc
|
||
---
|
||
flowchart TB
|
||
subgraph Flows["Flows/ (Node-RED Architecture)"]
|
||
F0["00_System<br># Heartbeat, MQTT-Verbindung, Systemstatus"]
|
||
F1["01_Deye_RS485<br># sunsynk Polling, MQTT-Publish Inverter-Daten"]
|
||
F2["02_Energymeter<br># Energiezähler Modbus Polling"]
|
||
F3["03_Miner_gRPC<br># Braiins gRPC Client, Miner-Status, Leistungstuning"]
|
||
F4["04_EnergyMgmt<br># Energiemanagement-Entscheidungslogik"]
|
||
F5["05_HeatMgmt<br># Wärmemanagement (Pumpen, Ventile, Rückkühler, WP)"]
|
||
F6["06_Modes<br># Betriebsmodus-Automat"]
|
||
F7["07_Safety<br># Safety-State Überwachung, Reaktion"]
|
||
F8["08_Alarms<br># Alarmierungslogik, Logging"]
|
||
end
|
||
|
||
style F0 text-align:left
|
||
style F1 text-align:left
|
||
style F2 text-align:left
|
||
style F3 text-align:left
|
||
style F4 text-align:left
|
||
style F5 text-align:left
|
||
style F6 text-align:left
|
||
style F7 text-align:left
|
||
style F8 text-align:left
|
||
style Flows fill:#E1BEE7,stroke:#AA00FF,stroke-width:2px
|
||
```
|
||
<!--
|
||
```
|
||
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
|
||
|
||
Dieser Abschnitt beschreibt die vier Betriebsmodi des Systems und ihr Verhalten. Der aktive Modus beeinflusst maßgeblich die Energie- und Wärmemanagement-Logik. Modi sind manuell schaltbar; vollautomatisches Umschalten ist optional (vgl. 2.2.2).
|
||
|
||
### 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
|
||
|
||
Dieser Abschnitt definiert die Entscheidungslogik für den optimalen Betrieb der Kryptominer. Ziel ist es, die Miner so zu betreiben, dass sie vorrangig auf Solar- oder günstiger Batterieenergie laufen und der Haushalt energetisch nicht belastet wird.
|
||
|
||
### 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
|
||
|
||
Dieser Abschnitt definiert die Steuerlogik für die thermischen Komponenten der Anlage: Pumpen, Ventile, Rückkühler und Wärmepumpen-EVU-Sperre. Ziel ist es, Miner-Abwärme sinnvoll in den Pufferspeicher einzuleiten und Übertemperaturen sicher abzuführen.
|
||
|
||
### 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)
|
||
|
||
Dieser Abschnitt beschreibt die gRPC-Kommunikation mit den Antminer S19J über die Braiins OS API. Die gRPC-Schicht ist ausschließlich für Leistungssteuerung und Status-Polling zuständig; das physische Ein-/Ausschalten der Miner erfolgt hardware-seitig über K10/K11.
|
||
|
||
### 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)
|
||
|
||
Dieser Abschnitt beschreibt die ergänzenden Software-Schutzfunktionen. Die Hardware-Sicherheitskette hat immer absoluten Vorrang; die hier definierten Maßnahmen sind eine zweite Schutzebene auf Software-Ebene, die früher eingreift und feinere Reaktionen erlaubt als die Hardware-Abschaltung.
|
||
|
||
> **Die Hardware-Sicherheitskette (Sicherheitsrelais, E-Stop, TEMP MAX) ist vollständig hardware-unabhängig von der Software und hat IMMER Vorrang. Kein Durchflusssensor verbaut — Kühlkreisüberwachung erfolgt softwareseitig über Temperaturauswertung (SA-001, SA-007).**
|
||
|
||
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
|
||
|
||
Dieser Abschnitt beschreibt das definierte Verhalten des Systems bei Komponentenausfällen oder Kommunikationsfehlern. Jeder Fehlerfall hat einen definierten sicheren Folgezustand, der die Anlage in einem kontrollierten, ungefährlichen Betrieb hält.
|
||
|
||
### 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
|
||
|
||
Dieser Abschnitt definiert die gegenseitige Überwachung zwischen RevPi und Site Server über Heartbeat-Mechanismen sowie den Hardware-Watchdog des RevPi. Ziel ist die automatische Erkennung und Reaktion auf hängende oder abgestürzte Komponenten.
|
||
|
||
### 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
|
||
|
||
Dieser Abschnitt definiert die Testfälle und Abnahmekriterien für die Software-Abnahme. Die Tests sind in drei Ebenen aufgeteilt: RevPi I/O-Tests (Punkt-zu-Punkt), Node-RED Integrationstests (Logik und Kommunikation) und End-to-End Systemtests (vollständige Anlage). Die Abnahme der physischen Installation erfolgt separat im Pflichtenheft Inbetriebnahme ASP1.
|
||
|
||
### 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
|
||
|
||
Dieser Abschnitt dokumentiert Themen, die noch nicht abschließend entschieden oder spezifiziert sind und vor oder während der Implementierung geklärt werden müssen.
|
||
|
||
| # | Thema | Status |
|
||
|---|-------|--------|
|
||
| 1 | Sensortyp Pufferspeicher (PT1000 vs. 4-20 mA) — beeinflusst AI-Kalibrierung | **offen** |
|
||
| 2 | Sensortyp Warmwasserspeicher | **offen** |
|
||
| 3 | Außentemperatursensor Typ und Anschluss (RevPi AI3 oder Site Server GPIO) | **offen** |
|
||
| 4 | Deye Modbus-Register-Map (sunsynk vs. direkte Modbus-Abfrage) | **offen** |
|
||
| 5 | Netz-Tarif-Integration (dynamischer Strompreis, API TBD) | **Phase 2** |
|
||
| 6 | Smart Meter Protokoll und Integration | **offen** |
|
||
| 7 | Batterie-Kapazität und -Typ (Auswirkung auf SOC-Schwellwerte) | **offen** |
|
||
| 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** |
|
||
| 11 | Router-Modell und VPN-Protokoll (WireGuard empfohlen, GL.iNet oder vergleichbar) | **offen** |
|
||
| 12 | Netzwerktopologie-Dokumentation (IP-Plan, Firewall-Regeln) | **offen** |
|
||
|
||
---
|
||
|
||
*Pflichtenheft ThermIQ ASP1 Software — v2.0 — 2026-05*
|