Files
Enelix-EMS/docs/module/Wassererwaermer/README.md
T
dh 49fe18c2eb
Tests / test (push) Failing after 41s
Wassererwaermer umfassend dokumentieren
2026-09-17 09:55:28 +00:00

406 lines
19 KiB
Markdown

# Verbraucher Warmwassererwaermer
> Status: implementiert fuer IP-Symcon 8.0+ und den Enelix-2-Vertrag `3.0`.
Das Modul bindet einen elektrischen Warmwasserspeicher mit einer oder mehreren
exklusiven Leistungsstufen an den Enelix-Manager an. Der Manager kann nur eine
der aktuell angebotenen Leistungen vorgeben. Lokale Schutz- und Komfortregeln
fuer Mindesttemperatur, Maximaltemperatur, Zeitplan und Legionellenfunktion
haben Vorrang vor einer Manager-Vorgabe.
Das Modul ist eine gezielte Adaption des Enelix-1-Moduls
`Boiler_x_Stufig`. Zyklische Altlogik und alte Kommunikationsvariablen wurden
nicht uebernommen. Die Regelung arbeitet ereignisbasiert und verwendet
ausschliesslich den Enelix-2-Nachrichtenvertrag.
| Technisches Merkmal | Wert |
| --- | --- |
| Modulname | `VerbraucherWarmwassererwaermer` |
| Alias | `Wassererwärmer` |
| Modul-ID | `{B7C54AF4-AD7D-4FE4-B75D-203693906251}` |
| Modultyp | Geraeteinstanz (`3`) |
| Funktionspraefix | `ENELIX` |
| Enelix-Vertrag | `3.0` |
## Funktionsumfang
- beliebig viele, eindeutig konfigurierte Leistungsstufen inklusive `0 W`,
- exklusive Break-before-make-Schaltung der Stufenkontakte,
- lokale Mindest- und Maximaltemperatur mit Hysterese,
- optionale PT1-Glaettung des Temperaturmesswerts,
- thermische Vorhersage fuer taegliche Solltemperatur-Zeitpunkte,
- zweistufige Legionellenfunktion mit Fruehest- und Spaetestintervall,
- berechnete Istleistung, aktive Stufe und bezogene Energie,
- ereignisbasierte Regelung mit einstellbarer Lastwechselsperre,
- Kommunikation mit manuell oder automatisch zugeordneten Enelix-Managern,
- optionale Diagnosevariablen und Debug-Logging.
## Voraussetzungen
- IP-Symcon ab Version 8.0,
- installierte Bibliothek `Enelix-EMS` vom Branch `develop`,
- eine Integer- oder Floatvariable als Temperaturfuehler,
- mindestens eine positive Leistungsstufe,
- je Leistungsstufe eine eigene Booleanvariable mit funktionsfaehiger Aktion,
- ein Enelix-Manager, dem die Verbraucherinstanz aktiv zugeordnet wird.
Die Schaltkontakte duerfen nicht mehrfach verwendet werden. Der Anlagenaufbau
muss sicherstellen, dass die konfigurierten Leistungsstufen elektrisch
zulaessig sind. Die Software ersetzt keine hardwareseitigen Verriegelungen,
Temperaturbegrenzer oder Schutzorgane.
## Regelungsablauf
Eine Neuberechnung wird insbesondere ausgeloest durch:
- einen neuen oder aktualisierten Temperaturmesswert,
- das Ein- oder Ausschalten von `Aktiv`,
- eine neue Manager-Vorgabe,
- eine Aenderung der bedienbaren Temperatursollwerte,
- das Ende der Lastwechselsperre,
- das Uebernehmen einer neuen Instanzkonfiguration,
- eine periodische Vollmeldung an den Manager.
`Meldeintervall` ist kein Regelintervall. Es stellt die regelmaessige
vollstaendige Rueckmeldung sicher. Die Lastwechselsperre verwendet einen
einmaligen Timer und loest nach ihrem Ablauf genau eine Neuberechnung aus.
Die Zielentscheidung folgt dieser Prioritaet:
1. Bei deaktivierter Instanz oder ungueltiger Temperatur ist der Verbraucher
nicht verfuegbar und wird ausgeschaltet. Eine ungueltige Konfiguration wird
bereits beim Uebernehmen mit Status `202` abgewiesen.
2. Unterschreitet die Temperatur die wirksame Mindesttemperatur oder reicht die
verbleibende Zeit bis zum naechsten Zeitplanziel rechnerisch nicht aus, wird
die hoechste Leistungsstufe lokal erzwungen.
3. Ab der wirksamen Maximaltemperatur wird ausgeschaltet.
4. Im Bereich unmittelbar unter der Maximaltemperatur wird eine bereits aktive
Stufe bis zum Erreichen der Abschaltgrenze gehalten.
5. In allen anderen Zustaenden darf der Manager zwischen `0 W` und allen
konfigurierten Leistungsstufen waehlen.
Lokale Zwangsvorgaben werden mit `AenderungMoeglich=false` und einem
entsprechend eingeschraenkten `Leistungswerte_W` gemeldet.
## Konfiguration
Das Modul besitzt 19 Properties: sechs gemeinsame Verbraucher-Properties und
13 modulspezifische Properties.
### Manager und Zeitverhalten
| Ident | Typ | Standard | Beschreibung |
| --- | --- | ---: | --- |
| `PrioritaetPV` | Integer | `0` | Prioritaet im PV-Betrieb; kleinere Werte werden zuerst beruecksichtigt. |
| `PrioritaetPeak` | Integer | `0` | Prioritaet im Peak-Betrieb; kleinere Werte werden zuerst beruecksichtigt. |
| `Meldeintervall` | Integer | `10` | Abstand der vollstaendigen Verbraucherrueckmeldungen in Sekunden. |
| `VorgabeTimeout` | Integer | `120` | Zeit in Sekunden, nach der eine nicht erneuerte Manager-Vorgabe ungueltig wird. |
| `LastwechselSperrzeit` | Integer | `5` | Mindestzeit zwischen zwei Lastwechseln in Sekunden. |
### Speichereinstellungen
| Ident | Typ | Standard | Beschreibung |
| --- | --- | ---: | --- |
| `LeistungsStufen` | JSON-Liste | `[]` | Positive Leistung, Stufennummer und Boolean-Schaltkontakt jeder Stufe. |
| `Boilerfuehler_PT1` | Integer | `0` | Objekt-ID der Integer- oder Floatvariable fuer die Speichertemperatur. |
| `LegionellenfunktionAktiv` | Boolean | `true` | Aktiviert die periodische Anhebung auf Legionellentemperatur. |
| `LegionellenMinimalintervallTage` | Integer | `4` | Fruehestens: Legionellentemperatur wird zur Maximaltemperatur. |
| `LegionellenMaximalintervallTage` | Integer | `7` | Spaetestens: Legionellentemperatur wird zur Mindesttemperatur. |
Jeder Eintrag in `LeistungsStufen` besteht aus:
| Feld | Anforderung |
| --- | --- |
| `Stufe` | Positive Ganzzahl. |
| `Leistung` | Eindeutige positive Ganzzahl in Watt. |
| `Schaltkontakt_Stufe` | Eindeutige Objekt-ID einer Booleanvariable. |
Die Eintraege werden intern nach Leistung sortiert. `0 W` wird automatisch als
Aus-Zustand in das Leistungsangebot aufgenommen und darf nicht als eigene
Stufe konfiguriert werden.
### Erweiterte Speichereinstellungen
| Ident | Typ | Standard | Beschreibung |
| --- | --- | ---: | --- |
| `Boilervolumen` | Integer | `300` | Speichervolumen in Litern fuer die thermische Zeitplanprognose. |
| `Hysterese` | Float | `5.0` | Temperaturhysterese in Kelvin. |
| `Zeitplan` | JSON-Liste | `[]` | Taegliche Zielwerte mit `Uhrzeit` im Format `HH:MM` und `Solltemperatur`. |
Der jeweils naechste Zeitplaneintrag wird fuer heute oder den folgenden Tag
ermittelt. Reicht die verbleibende Zeit bei maximaler elektrischer Leistung
rechnerisch nicht mehr aus, wird sofort die hoechste Stufe angefordert. Die
Berechnung verwendet Wasser mit `4186 J/(kg K)` und beruecksichtigt keine
Speicher- oder Leitungsverluste. Fuer Datum und Uhrzeit gilt die in IP-Symcon
eingestellte lokale Zeitzone.
### Erweiterte sonstige Einstellungen
| Ident | Typ | Standard | Beschreibung |
| --- | --- | ---: | --- |
| `TemperaturMaxAlter` | Integer | `30` | Maximal zulaessiges Alter des Temperaturmesswerts in Sekunden. |
| `BoilertemperaturGlaetten` | Boolean | `false` | Aktiviert die PT1-Glaettung. |
| `ZeitKonstante` | Integer | `120` | PT1-Zeitkonstante in Sekunden. |
| `EinstellungenInVisu` | Boolean | `false` | Zeigt Temperatursollwerte an und gibt ihre Bedienung frei. |
| `DiagnosevariablenAnzeigen` | Boolean | `false` | Legt die 14 Diagnosevariablen an. |
| `LoggingEin` | Boolean | `false` | Aktiviert laufende Debug-Ausgaben des Moduls. |
Alle Zeitwerte und Intervalle muessen groesser als `0` sein. Die beiden
Prioritaeten muessen mindestens `0` betragen. Das Legionellen-Minimalintervall
darf nicht groesser als das Maximalintervall sein.
## Temperaturverarbeitung
Der Rohwert des konfigurierten Fuehlers muss numerisch und juenger als
`TemperaturMaxAlter` sein. Andernfalls werden `TemperaturGueltig=false`,
`Verfuegbar=false` und eine Stoerung gemeldet; eine aktive Stufe wird
ausgeschaltet.
Ohne Glaettung entspricht `Boilertemperatur` dem letzten gueltigen Rohwert.
Mit aktivierter Glaettung verwendet das Modul ein PT1-Glied. Der erste Wert
initialisiert den Filter; danach wird die tatsaechlich seit der letzten
Temperaturberechnung vergangene Zeit verwendet.
Die Solltemperaturen werden bei der ersten Initialisierung auf folgende Werte
gesetzt:
| Variable | Initialwert |
| --- | ---: |
| `Mindesttemperatur` | `45.0 Grad C` |
| `Maximaltemperatur` | `60.0 Grad C` |
| `Legionellentemperatur` | `65.0 Grad C` |
Es gilt immer:
`Mindesttemperatur < Maximaltemperatur <= Legionellentemperatur`
Temperaturwerte muessen zwischen `0` und `100 Grad C` liegen. Bedienaktionen sind
nur erlaubt, wenn `EinstellungenInVisu=true` gesetzt ist.
## Hysterese und lokales Nachladen
Sinkt die Temperatur unter die wirksame Mindesttemperatur, beginnt das lokale
Nachladen mit der hoechsten Leistungsstufe. Es endet, sobald mindestens
`Mindesttemperatur + Hysterese` erreicht ist. Oberhalb der wirksamen
Maximaltemperatur wird ausgeschaltet.
Ist bereits eine Stufe aktiv und liegt die Temperatur bei mindestens
`Maximaltemperatur - Hysterese`, wird diese Stufe bis zur Abschaltgrenze
gehalten. Dadurch werden unnoetige Stufenwechsel kurz vor dem Ziel vermieden.
## Legionellenfunktion
Die Legionellenfunktion arbeitet zweistufig:
1. Ab `LegionellenMinimalintervallTage` wird die Legionellentemperatur zur
wirksamen Maximaltemperatur. Der Manager kann die Aufheizung innerhalb des
verbleibenden Zeitfensters ermoeglichen.
2. Ab `LegionellenMaximalintervallTage` wird die Legionellentemperatur auch zur
wirksamen Mindesttemperatur. Die hoechste Stufe wird dadurch lokal
erzwungen, bis das Ziel erreicht ist.
Erreicht die gueltige Speichertemperatur die Legionellentemperatur, wird der
Zeitpunkt als erfolgreicher Abschluss gespeichert und das Intervall beginnt
neu. `LegioCounter` zeigt die Sekunden seit diesem Abschluss.
`Legionellentemperatur` wird nur als Symcon-Variable angelegt, wenn
`LegionellenfunktionAktiv=true` ist. Beim Ausschalten der Funktion wird die
Variable geloescht; der letzte Wert bleibt intern erhalten und steht bei einem
spaeteren Wiedereinschalten wieder zur Verfuegung.
## Lastwechselsperre und Schaltsicherheit
Nach jedem tatsaechlichen Lastwechsel wird fuer
`LastwechselSperrzeit` Sekunden kein weiterer regulaerer Wechsel zugelassen.
In dieser Zeit gilt:
- `AenderungMoeglich=false`,
- `Leistungswerte_W` enthaelt nur die aktuell gehaltene Leistung,
- eine abweichende Manager-Vorgabe wird abgewiesen,
- ein einmaliger Timer plant die Freigabe.
Ein sicherheitsbedingtes Ausschalten, beispielsweise bei ungueltiger
Temperatur oder erreichter Maximaltemperatur, darf die Sperre uebergehen.
Separate Variablen `Idle` oder `IdleCounter` existieren nicht.
Beim Schalten werden zuerst alle konfigurierten Kontakte ausgeschaltet und
anschliessend hoechstens der Kontakt der Zielstufe eingeschaltet. Schlaegt ein
Schaltvorgang fehl, versucht das Modul alle Kontakte auszuschalten, setzt die
berechnete Istleistung auf `0 W` und meldet einen Schaltfehler.
## Variablen
### Betriebs- und Einstellvariablen
| Ident | Typ / Zugriff | Sichtbarkeit | Beschreibung |
| --- | --- | --- | --- |
| `Aktiv` | Boolean / bedienbar | immer | Lokale EMS-Freigabe; Startwert `false`. |
| `Boilertemperatur` | Float / Anzeige | immer | Letzter gueltiger, gegebenenfalls geglaetteter Temperaturwert. |
| `Mindesttemperatur` | Float / bedienbar | bei `EinstellungenInVisu` | Untere Grenze fuer lokales Nachladen. |
| `Maximaltemperatur` | Float / bedienbar | bei `EinstellungenInVisu` | Abschaltgrenze im Normalbetrieb. |
| `Legionellentemperatur` | Float / bedienbar | Funktion aktiv; Anzeige freigegeben | Ziel des Legionellenprogramms. |
### Diagnosevariablen
Mit `DiagnosevariablenAnzeigen=true` werden diese 14 Variablen angelegt. Beim
Abschalten der Property werden sie wieder geloescht. Die Regellogik verwendet
persistente interne Zustaende und funktioniert unabhaengig von diesen
Anzeigevariablen.
| Ident | Typ | Bedeutung |
| --- | --- | --- |
| `Istleistung` | Float | Berechnete aktuelle Leistung in Watt. |
| `Leistungsquelle` | Integer | Immer `1` fuer berechnete Leistung. |
| `Sollleistung` | Integer | Aktuell angenommene oder lokal erzwungene Zielvorgabe in Watt. |
| `SollwertGueltig` | Boolean | Eine Manager-Vorgabe ist vorhanden und noch nicht abgelaufen. |
| `Verfuegbar` | Boolean | Das Modul kann grundsaetzlich durch das EMS gesteuert werden. |
| `AenderungMoeglich` | Boolean | Der Manager darf momentan eine neue Leistung vorgeben. |
| `Stoerung` | Boolean | Mindestens eine Stoerbedingung ist aktiv. |
| `Stoertext` | String | Zusammengefasste lesbare Stoerbeschreibung. |
| `AktiveStufe` | Integer | Stufennummer der berechneten aktuellen Leistung; `0` bedeutet aus. |
| `BezogeneEnergie` | Float | Aus Istleistung und verstrichener Zeit berechnete Energie in kWh. |
| `TemperaturGueltig` | Boolean | Temperaturfuehler vorhanden, numerisch und nicht veraltet. |
| `NachladenAktiv` | Boolean | Lokales Nachladen aufgrund der Mindesttemperatur ist aktiv. |
| `LegionellenbetriebAktiv` | Boolean | Das Fruehestintervall der Legionellenfunktion ist erreicht. |
| `LegioCounter` | Integer | Sekunden seit dem letzten erfolgreichen Legionellenabschluss. |
## Managerkommunikation
Das Modul implementiert
`VerbraucherSchnittstelle::ManagerdatenEmpfangen()` und verwendet den
Enelix-2-Vertrag `3.0`. Es besitzt keine Manager-ID-Property. Zugelassen sind
nur Manager, in deren manueller oder automatischer Verbraucherzuordnung die
Instanz aktiv eingetragen ist.
Eine Manager-Vorgabe wird nur angenommen, wenn:
- Vertragsversion, Absender, Empfaenger und Datentypen gueltig sind,
- der Manager die Instanz aktiv zugeordnet hat,
- `Sollleistung_W` im zuletzt berechneten `Leistungswerte_W` enthalten ist.
Rueckmeldungen erfolgen bei relevanten Ereignissen, kurz verzoegert nach einer
Manager-Vorgabe und zusaetzlich alle `Meldeintervall` Sekunden. Die kurze
Verzoegerung verhindert eine synchrone Manager-Verbraucher-Endlosschleife.
Die Verbraucherrueckmeldung enthaelt insbesondere:
- Prioritaeten fuer PV- und Peak-Betrieb,
- `Leistungswerte_W`, `AenderungMoeglich` und `Verfuegbar`,
- `Istleistung_W` mit `Leistungsquelle=1`,
- Zustandseintraege fuer Sollleistung, Wassertemperatur, Maximaltemperatur,
aktive Stufe, Nachladen, Legionellenbetrieb und Stoerungen.
Nach `VorgabeTimeout` Sekunden ohne Erneuerung wird eine Manager-Vorgabe
bei der naechsten Neuberechnung, spaetestens bei der folgenden Vollmeldung,
ungueltig. Beim Neustart wird keine alte Manager-Vorgabe ungeprueft wieder
aufgenommen.
## Abgrenzung des aktuellen Stands
- `Istleistung`, `AktiveStufe` und `BezogeneEnergie` sind berechnete Werte; das
Modul besitzt keinen Anschluss fuer einen elektrischen Leistungsmesser.
- Die Stufenkontakte sind Aktoren, keine separate physische Rueckmeldung. Ihr
Booleanzustand wird bei einer Regelberechnung auf Plausibilitaet geprueft.
- Externe Aenderungen an den Stufenkontakten loesen selbst keine
Neuberechnung aus. Der Temperaturfuehler ist die abonnierte Messvariable.
- Der Zeitplan beschreibt taeglich wiederkehrende Zielzeitpunkte und keine
einmaligen Kalendertermine.
## Status- und Fehlerzustaende
| Status | Bedeutung | Typische Ursache |
| ---: | --- | --- |
| `102` | Aktiv | Konfiguration und Temperaturmessung sind gueltig. |
| `201` | Temperaturmessung ungueltig | Fuehler fehlt, ist nicht numerisch oder zu alt. |
| `202` | Konfiguration ungueltig | Unzulaessige Intervalle, Temperaturen, Stufen, Kontakte oder Zeitplaneintraege. |
| `203` | Schaltfehler | Eine Aktion eines Stufenkontakts ist fehlgeschlagen. |
Eine Uebertemperatur liegt vor, wenn `Boilertemperatur` die hoehere Grenze aus
Maximal- und Legionellentemperatur um mehr als `Hysterese` ueberschreitet. Sie
wird ueber `Stoerung` und `Stoertext` gemeldet; der Modulstatus bleibt ohne
zusaetzlichen Schalt- oder Fuehlerfehler `102`.
## Installation und Inbetriebnahme
1. Im IP-Symcon Module Control den Branch `develop` der Bibliothek
`https://git.belevo.ch/ENELIX/Enelix-EMS.git` installieren oder
aktualisieren.
2. Unter **Instanz hinzufuegen** nach dem Alias **Wassererwärmer** oder dem
Modulnamen `VerbraucherWarmwassererwaermer` suchen und eine Instanz anlegen.
3. Den Temperaturfuehler auswaehlen und `TemperaturMaxAlter` passend zum
Aktualisierungsintervall des Fuehlers einstellen.
4. Alle Leistungsstufen mit positiver Leistung und jeweils eigenem
Boolean-Schaltkontakt konfigurieren.
5. Normal-, Legionellen- und Zeitplanwerte pruefen. Danach die Konfiguration
uebernehmen.
6. Die Instanz im Enelix-Manager manuell aktiv zuordnen oder bei automatischer
Suche in der gefundenen Liste aktivieren.
7. Fuer die Erstpruefung `DiagnosevariablenAnzeigen` und bei Bedarf
`LoggingEin` einschalten.
8. Unter Aufsicht `Aktiv` einschalten und jede Stufe einzeln pruefen. Dabei
kontrollieren, dass nie zwei Stufenkontakte gleichzeitig aktiv sind.
9. Eine Manager-Vorgabe fuer `0 W` und fuer jede konfigurierte Stufe pruefen.
10. Diagnosevariablen nach der Abnahme bei Bedarf wieder ausschalten.
## Abnahmecheckliste
- Die Instanz erreicht Status `102`.
- `Aktiv=false` schaltet alle Stufenkontakte aus.
- Der Fuehlerwert erscheint unverfaelscht oder erwartungsgemaess geglaettet in
`Boilertemperatur`.
- Unterhalb der Mindesttemperatur wird die hoechste Stufe lokal erzwungen.
- Oberhalb der Maximaltemperatur werden alle Stufen ausgeschaltet.
- Jede Manager-Vorgabe schaltet genau den zugeordneten Kontakt.
- Direkt nach einem Wechsel ist `AenderungMoeglich=false`; nach der
konfigurierten Sperrzeit wird ein regulaerer Wechsel wieder freigegeben.
- Eine Gegenanforderung waehrend der Sperre liegt nicht im gemeldeten
Leistungsangebot.
- Ein veralteter oder ungueltiger Fuehlerwert fuehrt zu Status `201`, einer
Stoerung und sicherem Ausschalten.
- Bei aktiver Legionellenfunktion wird `Legionellentemperatur` angelegt; nach
dem Abschalten der Funktion wird die Variable geloescht.
- Mit ausgeschalteten Diagnosevariablen bleiben Regelung und Kommunikation
funktionsfaehig.
## Diagnosehinweise
- Status `202`: zuerst Fuehler-ID, Leistungsstufen, eindeutige Kontakte,
Temperaturreihenfolge, Intervalle und Zeitplanformat pruefen.
- Status `201`: `VariableUpdated`, Datentyp des Fuehlers und
`TemperaturMaxAlter` kontrollieren.
- Status `203`: Aktionen der Boolean-Schaltkontakte einzeln in IP-Symcon
testen; das Modul versucht bei einem Fehler alle Kontakte auszuschalten.
- Manager-Vorgabe wird abgewiesen: Zuordnung im Manager,
`AenderungMoeglich` und das aktuelle `Leistungswerte_W` pruefen.
- Unerwartetes Nachladen: Mindesttemperatur, Hysterese, naechstes Zeitplanziel
und Alter des letzten Legionellenabschlusses kontrollieren.
## Tests
`WarmwasserReglerTest.php` prueft die reine Regellogik fuer Leistungsstufen,
PT1, Lastwechselsperre, Energieberechnung, thermische Prognose, Zeitplan und
Legionellengrenzen.
`WarmwassererwaermerModulstrukturTest.php` prueft Metadaten, Formular, alle 19
Properties, ereignisbasierte Lastwechselsperre, Vertrag `3.0`, bedarfsgesteuerte
Diagnosevariablen, Legionellentemperatur, Temperatursollwerte und
Break-before-make-Schaltung.
## Migration von Enelix 1
Die Zuordnung der uebernommenen, angepassten und entfallenen Felder des alten
Moduls `Boiler_x_Stufig` ist in
[`docs/migration/Boiler-x-Stufig.md`](../../migration/Boiler-x-Stufig.md)
dokumentiert.
Wesentliche Unterschiede:
- `Interval` entfaellt; die Regelung ist ereignisbasiert.
- `IdleCounterMax` wird durch `LastwechselSperrzeit` in Sekunden ersetzt.
- `Idle` und `IdleCounter` entfallen vollstaendig.
- `PowerSteps` wird durch das Vertragsfeld `Leistungswerte_W` ersetzt.
- Prioritaeten sind Properties; Betriebsart und Leistungsverteilung liegen im
Manager.
- Die neue Modul-ID erfordert eine neue Instanz; eine automatische Umwandlung
des Enelix-1-Objekts findet nicht statt.