Aktuell sieht es so aus, nach Variante 1: Die Rule wird getriggert, sobald sich die gemessene Einspeisung ändert.
Ist die Einspeisung unter 700 so wird ein Timer tbwwp gestoppt und entfernt, falls vorhanden.
Ist die Einspeisung über oder gleich 700, so wird ein Timer tdry gestoppt und entfernt.
ist anschließend die Leistung kleiner als 700 und das Item dry_contact nicht OFF und Timer tdry ist null, so wird der Timer tdry erzeugt, der nach 30 Minuten dry_contakt auf OFF setzt.
Ist anschließend die Leistung über 1200 und dry_contact nicht ON und der Timer tbwwp ist null, so wird der Timer angelegt, der nach fünf Minuten dry_contact auf ON schaltet.
Zusammenfassend: ist die Einspeisung ohne Unterbrechung mindestens 30 Minuten unter 700, so wird dry_contact auf OFF gesetzt.
Ist die Einspeisung kurzzeitig über 1200 und fällt dann mindestens fünf Minuten nicht unter 700, so wird dry_contact auf ON gesetzt.
Variante 2 knallt, weil da Klammerungen nicht korrekt sind.
Ich nehme an, Du möchtest, dass die Brauchwasser Wärmepumpe nach dem Einschalten mindestens 30 Minuten durch läuft, nach diesen 30 Minuten aber nach zwei Minuten abschaltet, wenn die Leistung unter 700 fällt und in den zwei Minuten auch nicht mehr über die 700 geht.
Mein Gegenangebot :
Code: Alles auswählen
// Globale Variablen zu Beginn der Datei definieren!
var Timer tBwwp = null
var Integer iBwwp = 0 // 0 = neutral, 1 = stoppen, 2 = starten
rule "bwwp laden"
when
Item PV_Einspeisung changed // Freigabe BWWP
then
if(!(newState instanceof Number)) // aktuell keine Zahl?
return;
val nCur = (newState as Number).intValue // aktueller Wert, Integer soll reichen
if(nCur < 700 && iBwwp != 1) { // Stoppbedingung und Timer nicht in Stopp Modus
logInfo("bwwp","Stoppbedingung erkannt! Leistung = {}",nCur)
iBwwp = 1 // Modus auf Stopp
tBwwp?.cancel // falls Timer vorhanden, cancel
tBwwp = createTimer(now.plusMinutes(1), [| // Timer neu anlegen und nach einer Sekunde starten
if(dry_contact.state != OFF) { // falls dry_contact nicht OFF
if(!dry_contact.changedSince(now.minusMinutes(30))) { // ist letzte Änderung mehr als 309 Minuten her?
logInfo("bwwp","Stopp erkannt, Pumpe läuft mindestens 30 Minuten! Stoppe")
dry_contact.sendCommand(OFF) // dann OFF-Command senden
} else { // ansonsten
logInfo("bwwp","Stopp erkannt, Pumpe läuft weniger als 30 Minuten! Warte...")
tBwwp.reschedule(now.plusMinutes(1)) // timer in einer Minute wieder ausführen
}
}
])
}
if(nCur > 1200 && iBwwp != 2) { // Startbedingung und Timer nicht in Start Modus
logInfo("bwwp","Startbedingung erkannt! Leistung = {}",nCur)
iBwwp = 2 // Modus auf Start
tBwwp?.cancel // falls Timer vorhanden, cancel
tBwwp = createTimer(now.plusMinutes(5), [| // in 5 Minuten
if(dry_contact.state != ON) { // falls nicht ON
logInfo("bwwp","Starte Pumpe")
dry_contact.sendCommand(ON) // einschalten
}
])
}
if(nCur >= 700 && iBwwp == 1) { // falls Stopp Modus aktiv und über 700
logInfo("bwwp","Abbruch Stoppbedingung erkannt! Leistung = {}",nCur)
iBwwp = 0 // Modus auf nix
tBwwp?.cancel // falls Timer vorhanden, cancel
}
end
Nach Prüfung auf Korrektheit des Wertes und Überführung in eine lokale Konstante laufen die Prüfungen ab:
- Liegt der Wert unter 700 aber der Timer Modus ist nicht 1, so wird der Timer Modus auf 1 gesetzt und ein eventuell laufender Timer gecancelt. Anschließend wird der Stopp Timer angelegt und nach einer Minute ausgeführt.
Innerhalb des Timers wird nun geprüft, ob dry_contact ungleich OFF ist. Ist das der Fall, wird geprüft, ob der Schaltzustand sich in den letzten 30 Minuten geändert hat. Ist das nicht der Fall, so wird dry_contact auf OFF gesetzt. Ansonsten wird der Timer erneut in einer Minute ausgeführt. - Liegt der Wert hingegen über 1200 und der Modus ist nicht 2, so wird der Modus auf 2 geändert und ein eventuell laufender Timer gestoppt. Danach wird ein Timer in 5 Minuten angelegt, der schließlich bei Bedarf dry_contact auf ON bringt.
- Liegt der Wert über 700 und der Modus ist 1, so wird der Timer gestoppt und der Modus auf neutral gesetzt.