thermIQ/docs/PFLICHTENHEFT_SOFTWARE.md
Adrian Bretsch ba6622bed7 Initial commit: ThermIQ ASP1 documentation
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>
2026-05-08 12:30:03 +02:00

43 KiB
Raw Blame History

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
  2. Zielbestimmungen
  3. Anforderungskatalog
  4. Systemübersicht
  5. Plattformen und Laufzeitumgebungen
  6. MQTT-Datenbus
  7. RevolutionPi SPS-Programm
  8. Node-RED Automatisierung
  9. Betriebsmodi
  10. Energiemanagement-Logik
  11. Wärmemanagement-Logik
  12. Miner-Steuerung (gRPC)
  13. Sicherheitslogik (Software-Ebene)
  14. Fallback- und Fehlerverhalten
  15. Watchdog und Systemüberwachung
  16. Abnahme- und Testkriterien
  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.010.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       # % (0100)
│   ├── 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 010 V
AO2 thermiq/pumps/p4/setpoint Pumpe P4 Drehzahl 010 V
AO3 thermiq/pumps/p5/setpoint Pumpe P5 Drehzahl 010 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. Betriebs­modus-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, 0100 %)
  • 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 (010 V), proportional zur Temperaturdifferenz
  • P5 (Solar/Glykol-Kreis): Drehzahlgeregelt via AO3 (010 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: 0100 % 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