Nochmal der Hinweis, poste Code (sowie Logs oder Konfigurationen) immer als Code, nicht als normalen Text. Die Lesbarkeit ist einfach wesentlich besser.
Dein Code sieht ja erstmal gut aus, aber wenn man näher schaut, werden Fehler offenbar. Hier nochmal besser formatiert:
Code: Alles auswählen
rule "Waermepumpe Ein Aus"
when
Item Strom_Verkauf_ins_Netz received update
then
logInfo("Waermepumpen roule", "Aus Schalten")
var Number Strom_Bezug = Strom_Bezug_vom_Netz.state as DecimalType // Schreiben des Wertes in eine Variable
var Number Strom_Verkauf = Strom_Verkauf_ins_Netz.state as DecimalType // Schreiben des Wertes in eine Variable
var Number PV_Current = PV_Current.state as DecimalType // Schreiben des Wertes in eine Variable
if (Strom_Bezug < 100 && PV_Current > 3000) {
if(Sonoff1Channel1EIN.state != ON) Sonoff1Channel1EIN.sendCommand(ON)
}
logInfo("Waermepumpen roule", "Ein Schalten.")
logInfo("waermepumpe", "PV_Current " + PV_Current.toString)
if (Strom_Bezug > 520 ) // Strombezung groeßer als 520
logInfo("waermepumpe", "Strom_Bezug " + Strom_Bezug.toString)
{ if(Sonoff1Channel1EIN.state != OFF) Sonoff1Channel1EIN.sendCommand(OFF)
}
logInfo("Waermepumpen aus", " Aus Schalten.")
logInfo("waermepumpe aus", "Strom_Bezug " + Strom_Bezug.toString)
end
Anhand der Einrückungen solltest Du Deinen Fehler erkennen können. Deine Bedingung
if (Strom_Bezug > 520 ) wirkt schlicht nur auf die darauf folgende logInfo Zeile. Damit wird das OFF auf jeden Fall ausgeführt, gleich welche Bedingungen sonst erfüllt sind oder nicht. Besser wäre folgender Code:
Code: Alles auswählen
rule "Waermepumpe Ein Aus"
when
Item Strom_Verkauf_ins_Netz received update
then
logInfo("waermepumpe", "Schalten")
if(!(Strom_Bezug_vom_Netz.state instanceof Number)) return; // Abbruch, Strom_Bezug_vom_Netz ungültig
if(!(Strom_Verkauf_ins_Netz.state instanceof Number)) return; // Abbruch, Strom_Verkauf_ins_Netz ungültig
if(!(PV_Current.state instanceof Number)) return; // Abbruch, PV_Current ungültig
var Number Strom_Bezug = Strom_Bezug_vom_Netz.state as Number // Schreiben des Wertes in eine Variable
var Number Strom_Verkauf = Strom_Verkauf_ins_Netz.state as Number // Schreiben des Wertes in eine Variable
var Number PV_Current = PV_Current.state as Number // Schreiben des Wertes in eine Variable
if (Strom_Bezug < 100 && PV_Current > 3000) {
logInfo("waermepumpe", "Einschalten.")
logInfo("waermepumpe", "PV_Current {}",PV_Current)
if(Sonoff1Channel1EIN.state != ON) Sonoff1Channel1EIN.sendCommand(ON)
}
if (Strom_Bezug > 520 ) // Strombezug größer als 520
logInfo("waermepumpe", " Ausschalten.")
logInfo("waermepumpe", "Strom_Bezug {}", Strom_Bezug)
if(Sonoff1Channel1EIN.state != OFF) Sonoff1Channel1EIN.sendCommand(OFF)
}
end
Man sollte nicht davon ausgehen, dass alle Status der fraglichen Items gültige Zahlenwerte enthalten. Entsprechend muss also zuerst einmal überprüft werden, ob der Status vom Typ Number ist. Ist das der Fall, kann man ihn einer Variablen zuweisen. Oft enthalten die Status Berechnungsgrundlagen, ohne die die Rule sinnlos ist, weshalb es dann sinnvoll ist, die Rule einfach abzubrechen.
Die Laufzeiten könnte man mit einem Timer steurern. Wenn Du den Bezug über die letzten 15 Minuten betrachten willst, musst Du eine Persistence einrichten, die alle Updates in eine Datenbank schreibt. Hier bietet sich rrd4j an, aber eine SQL-Variante ginge auch. Ungeeignet ist hingegen mapdb, da hier keine historischen Werte betrachtet werden können.
Gesetzt den Fall, der Bezug wird mit rrd4j persistiert, sähe eine passende Rule so aus:
Code: Alles auswählen
var Timer tWaerme = null
rule "Waermepumpe Ein Aus"
when
Item Strom_Verkauf_ins_Netz received update
then
logInfo("waermepumpe", "Schalten")
if(!(Strom_Bezug_vom_Netz.state instanceof Number)) {
logWarn("waermepumpe", "Strom_Bezug_vom_Netz ungültig!")
return;
}
if(!(Strom_Verkauf_ins_Netz.state instanceof Number)) {
logWarn("waermepumpe", "Strom_Verkauf_ins_Netz ungültig!")
return;
}
if(!(PV_Current.state instanceof Number)) {
logWarn("waermepumpe", "PV_Current ungültig!")
return;
}
var Number Strom_Bezug = Strom_Bezug_vom_Netz.minimumSince(now.minusMinutes(15),"rrd4j") as Number // Schreiben des Wertes in eine Variable
var Number Strom_Verkauf = Strom_Verkauf_ins_Netz.state as Number // Schreiben des Wertes in eine Variable
var Number PV_Current = PV_Current.state as Number // Schreiben des Wertes in eine Variable
logInfo("waermepumpe", "PV_Current {}",PV_Current)
logInfo("waermepumpe", "Strom_Bezug {}", Strom_Bezug)
if(tWaerme===null) {
tWaerme = createTimer(now.plusMinutes(15), [ |
tWaerme=null
])
if((Strom_Bezug_vom_Netz.state as Number) < 100 && PV_Current > 3000) {
logInfo("waermepumpe", "Einschalten.")
if(Sonoff1Channel1EIN.state != ON) Sonoff1Channel1EIN.sendCommand(ON)
}
if(Strom_Bezug > 520) { // Strombezung groeßer als 520
logInfo("waermepumpe", " Ausschalten.")
if(Sonoff1Channel1EIN.state != OFF) Sonoff1Channel1EIN.sendCommand(OFF)
}
}
end
Der Timer dient hier nur als Schaltunterdrückung.
Die Rule ist nicht elegant, sollte aber ihren Zweck erfüllen.