Seite 1 von 1

rule syntax für photovoltaik effizienter nutzen

Verfasst: 7. Mai 2021 15:13
von linsenpago
Hallo!

Ich würde gerne meinen selbst produzierten Strom meiner Photovoltaik Anlage gerne etwas smarter nutzen.
Ich kann meiner Wärmepumpe mittels externem Kontakt sagen, sie soll "Extra Brauchwasser" erstellen.
Die Wärmepumpe heizt dann das Brauchwasser auf eine höhere Temparatur auf als normalerweise eingestellt ist.
Sie braucht dafür etwa 3,5kw Strom für etwa 30 Minuten. Diese erhöhte Temperatur wird dann für 2 oder 3 Stunden gehalten.

Ich bin gerade am schnitzen einer Rule die folgendes machen sollte.

Ich lese aus meiner RaspberryMatic den Wert aus welcher gerade ins Netz eingespeist wird.
Wenn jetzt sagen wir mal für 10minuten 4kw ins Netz eingespeist werden, dann gehe ich davon aus, dass der Sonnenschein halbwegs stabil ist.
Dann sollte der Schalter ausgelöst werden der das Extra Brauchwasser anwirft.

Diese Rule sollte dann für etwa 4 Stunden nicht mehr anspringen da der ExtraBrauchwasser Zustand in der Wärmepumpumpe von alleine endet.
Nach dieser Zeit könnte die Rule gerne wieder anspringen, denn wenn das Wasser in der Zwischenzeit wieder abgekühlt wurde und wieder für 10 Minuten alles stabil bleibt kann sie gerne wieder aufheizen bzw. wenn das Wasser noch auf dem erhöhten Niveau ist, springt die WP sowieso nicht an.

Irgendwie fehlen mir noch die Tricks und kniffe im Rules schreiben, ich bekomme die Logik irgendwie nicht so richtig hin damit die Rule erst 10 Minuten schaut ob der Wert > 4000 ist und dann für 4 Stunden schläft.

Soweit bin ich mit der Rule einmal - sie würde auslösen und dann 4 stunden schlafen...ich habe sie aber noch nicht live getestet:

Code: Alles auswählen

// globale Variablen müssen zu Beginn der rules Datei deklariert werden!
var Timer tExtraBrauchwasser = null


rule "Extra Brauchwasser"
when
    Item Einspeisung received update
then
    if (tExtraBrauchwasser === null && (Einspeisung.state as Number > 4000)) {
        logInfo("STARTING TIMER :", triggeringItem.name.toString)
        tExtraBrauchwasser = createTimer(now.plusHours(4), [ |
            tExtraBrauchwasser = null
        ])
    logInfo("Extra Brauchwasser", "Einspeisung ist größer als 4kw = " + Einspeisung.state)
    sendBroadcastNotification("Einspeisung ist größer als 4kw starte Extra Brauchwasser! Einspeisung= " + Einspeisung.state)
    ExtraBrauchwasser.sendCommand(ON)
    }
end
Hätte da jemand Ahnung wie man das noch da rein bekommen könnte?

Danke im Voraus und LG,
Alexander

Re: rule syntax für photovoltaik effizienter nutzen

Verfasst: 7. Mai 2021 20:41
von udo1toni
Also, mal abgesehen davon, dass Du den log-Befehl falsch verwendest, passt die Rule so.

Die log-Befehle logInfo(), logWarn() und logError() erwarten exakt zwei Strings als Parameter, wobei der erste String den letzten Teil des Logger Namens setzt, der zweite String ist die eigentliche Meldung. Der erste String hingegen ist NICHT Teil der Meldung.
Korrekt sieht der Befehl so aus:

Code: Alles auswählen

logInfo("waterheat","Starte extra Warmwasser, Einspeisung: {}",Einspeisung.state)
Wie zu sehen, werden im zweiten String auch Variablen substituiert, {} wird durch die nächste Variable ersetzt, im Beispiel das Status des Items Einspeisung. openHAB wandelt dabei die Daten automatisch ins passende Format, übernimmt also die Wandlung von Number nach String.

Wegen des Wartens: Das geht genauso wie mit dem Timer, den Du schon hast. Es bietet sich an, dafür den gleichen Timer zu verwenden (nur in etwas abgewandelter Form):

Code: Alles auswählen

// globale Variablen müssen zu Beginn der rules Datei deklariert werden!
var Timer tExtraBrauchwasser = null
var Boolean bExtraBrauchwasser = false

rule "Extra Brauchwasser"
when
    Item Einspeisung changed
then
    if((Einspeisung.state as Number) > 4000) {
        logInfo("waterheat", "Einspeisung ist aktuell {} W", Einspeisung.state)
        if(tExtraBrauchwasser === null)
            logInfo("waterheat", "Starte 10 Minuten Timer")
            tExtraBrauchwasser = createTimer(now.plusMinutes(10),[|
                if(!bExtraBrauchwasser) {
                    ExtraBrauchwasser.sendCommand(ON)
                    bExtraBrauchwasser = true
                    sendBroadcastNotification("Einspeisung ist größer als 4kw starte Extra Brauchwasser! Einspeisung = " + Einspeisung.state)
                    logInfo("waterheat", "Einspeisung ist seit 10 Minuten größer als 4kW (aktuell {} W)", Einspeisung.state)
                    tExtraBrauchwasser.reschedule(now.plusHours(4))
                } else {
                    bExtraBrauchwasser = false
                    tExtraBrauchwasser = null
                }
            ]
    } else if(!bExtraBrauchwasser) {
        tExtraBrauchwasser?.cancel
        tExtraBrauchwasser = null
    }
end
Falls die Einspeisung über 4000 liegt, prüft die Rule, ob ein Timer existiert. Ist dies nicht der Fall, so wird ein 10-Minuten-Timer angelegt. Sinkt die Einspeisung unter 4000, so so wird, falls die Variable bExtraBrauchwasser false ist, der Timer gestoppt und gelöscht.
Wenn der Timer nach 10 Minuten abläuft, wird der erste Codeblock ausgeführt, der im Großen und Ganzen Deiner Rule entspricht. Allerdings wird die Variable bExtraBrauchwasser auf true gesetzt und abschließend wird der Timer erneut geplant (reschedule...).
Läuft der Timer erneut ab, so wird der Timer genullt und die Variable wieder auf false gesetzt.

Re: rule syntax für photovoltaik effizienter nutzen

Verfasst: 8. Mai 2021 20:12
von linsenpago
Hallo!

Vielen Dank für deine Hilfe!

Bis auf eine fehlende Klammer (die letzte ")" vor "else if"), dürfte die Rule von dir passen! Auf diese Verschachtelung wäre ich mein Leben lang nicht von alleine gekommen, aber liest sich durchaus logisch.

Jetzt hatte ich nur noch das Problem, dass sich die Systemvariablen aus der Homematic nicht aktualisiert haben.
Alle anderen Homematic Items aktualisieren sich immer von alleine, nur die Systemvariablen nicht.

Ich habe es nun mittels zweier rules lösen können.
Eine aktualisiert alle 60 sekunden die Systemvariablen und die zweite Rule von dir überwacht dann die Einspeisung.

Code: Alles auswählen

import org.eclipse.smarthome.core.types.RefreshType
var Timer tExtraBrauchwasser = null
var Boolean bExtraBrauchwasser = false

rule "Reload datapoints"
when 
    Time cron "0 0/1 * * * ?"  // every minute
then
	sendCommand(Einspeisung, RefreshType.REFRESH)
end

rule "Extra Brauchwasser"
when
    Item Einspeisung changed
then
    if((Einspeisung.state as Number) > 4000) {
        logInfo("waterheat", "Einspeisung ist aktuell {} W", Einspeisung.state)
        if(tExtraBrauchwasser === null)
            logInfo("waterheat", "Starte 10 Minuten Timer")
            tExtraBrauchwasser = createTimer(now.plusMinutes(10),[|
                if(!bExtraBrauchwasser) {
                    ExtraBrauchwasser.sendCommand(ON)
                    bExtraBrauchwasser = true
                    sendBroadcastNotification("Einspeisung ist größer als 4kw starte Extra Brauchwasser! Einspeisung = " + Einspeisung.state)
                    logInfo("waterheat", "Einspeisung ist seit 10 Minuten größer als 4kW (aktuell {} W)", Einspeisung.state)
                    tExtraBrauchwasser.reschedule(now.plusHours(4))
                } else {
                    bExtraBrauchwasser = false
                    tExtraBrauchwasser = null
                }
            ]
            )}
        else if(!bExtraBrauchwasser) {
        tExtraBrauchwasser?.cancel
        tExtraBrauchwasser = null
    }
end
Derzeit speise ich keinen Strom mehr ein.. ich werde morgen im laufe des Tages die Logs und die Rule überwachen und bin gespannt ob es so funktioniert wie gehofft.

Danke nochmals!

LG
Alexander

Re: rule syntax für photovoltaik effizienter nutzen

Verfasst: 9. Mai 2021 10:03
von linsenpago
Hi!

Leider zu früh gefreut... Die Rule läuft nicht so wirklich sauber... ich bekomme ab und zu java exeptions und die Timer funktionieren auch nicht richtig.. es wird ständig das extra Brauchwasser aktiviert obwohl der 10 Minuten Timer oder die 4 Stunden noch nicht abgelaufen sind.

Java Exception:

Code: Alles auswählen

2021-05-09 09:54:00.138 [ERROR] [org.quartz.core.JobRunShell         ] - Job DEFAULT.Timer 109 2021-05-09T09:54:00.137+02:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {

  org.eclipse.xtext.xbase.impl.XIfExpressionImpl@185877f (conditionalExpression: false)

} ] threw an unhandled Exception: 

java.lang.NullPointerException: null

	at org.eclipse.smarthome.model.script.engine.ScriptError.<init>(ScriptError.java:65) ~[?:?]

	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:140) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:991) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:954) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:235) ~[?:?]

	at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:215) ~[?:?]

	at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluateArgumentExpressions(XbaseInterpreter.java:1205) ~[?:?]
Hier noch ein paar Logeinträge der Rule... die Einspeisung ist aber dazwischen nicht abgesunken..

Code: Alles auswählen

2021-05-09 09:49:00.099 [INFO ] [pse.smarthome.model.script.waterheat] - Einspeisung ist aktuell 5313.10 W

2021-05-09 09:50:00.165 [INFO ] [pse.smarthome.model.script.waterheat] - Einspeisung ist aktuell 5341.90 W

2021-05-09 09:50:00.170 [INFO ] [pse.smarthome.model.script.waterheat] - Starte 10 Minuten Timer

2021-05-09 09:51:00.160 [INFO ] [pse.smarthome.model.script.waterheat] - Einspeisung ist seit 10 Minuten größer als 4kW (aktuell 5341.90 W)

2021-05-09 09:51:00.194 [INFO ] [pse.smarthome.model.script.waterheat] - Einspeisung ist aktuell 5366.90 W

2021-05-09 09:52:00.088 [INFO ] [pse.smarthome.model.script.waterheat] - Einspeisung ist aktuell 5391.70 W

2021-05-09 09:53:00.126 [INFO ] [pse.smarthome.model.script.waterheat] - Einspeisung ist aktuell 5422.00 W

2021-05-09 09:53:00.130 [INFO ] [pse.smarthome.model.script.waterheat] - Starte 10 Minuten Timer

2021-05-09 09:53:00.192 [INFO ] [pse.smarthome.model.script.waterheat] - Einspeisung ist seit 10 Minuten größer als 4kW (aktuell 5422.00 W)

2021-05-09 09:49:00.099 [INFO ] [pse.smarthome.model.script.waterheat] - Einspeisung ist aktuell 5313.10 W

2021-05-09 09:50:00.165 [INFO ] [pse.smarthome.model.script.waterheat] - Einspeisung ist aktuell 5341.90 W

2021-05-09 09:50:00.170 [INFO ] [pse.smarthome.model.script.waterheat] - Starte 10 Minuten Timer

2021-05-09 09:51:00.160 [INFO ] [pse.smarthome.model.script.waterheat] - Einspeisung ist seit 10 Minuten größer als 4kW (aktuell 5341.90 W)

2021-05-09 09:51:00.194 [INFO ] [pse.smarthome.model.script.waterheat] - Einspeisung ist aktuell 5366.90 W

2021-05-09 09:52:00.088 [INFO ] [pse.smarthome.model.script.waterheat] - Einspeisung ist aktuell 5391.70 W

2021-05-09 09:53:00.126 [INFO ] [pse.smarthome.model.script.waterheat] - Einspeisung ist aktuell 5422.00 W

2021-05-09 09:53:00.130 [INFO ] [pse.smarthome.model.script.waterheat] - Starte 10 Minuten Timer

2021-05-09 09:53:00.192 [INFO ] [pse.smarthome.model.script.waterheat] - Einspeisung ist seit 10 Minuten größer als 4kW (aktuell 5422.00 W)

Re: rule syntax für photovoltaik effizienter nutzen

Verfasst: 10. Mai 2021 15:41
von udo1toni
Ja, da fehlte noch ein geschweiftes Klammerpaar.
Ansonsten noch ein paar Feinheiten(z.B. ein .toString in der Broacast Notification). Probiere es mal so:

Code: Alles auswählen

import org.eclipse.smarthome.core.types.RefreshType
var Timer tExtraBrauchwasser = null
var Boolean bExtraBrauchwasser = false

rule "Reload datapoints"
when 
    Time cron "0 * * * * ?"  // every minute
then
    Einspeisung.sendCommand(RefreshType.REFRESH)
end

rule "Extra Brauchwasser"
when
    Item Einspeisung changed
then
    if((Einspeisung.state as Number) > 4000) {
        logInfo("waterheat", "Einspeisung ist aktuell {} W", Einspeisung.state)
        if(tExtraBrauchwasser === null) {
            logInfo("waterheat", "Starte 10 Minuten Timer")
            tExtraBrauchwasser = createTimer(now.plusMinutes(10),[|
                if(!bExtraBrauchwasser) {
                    ExtraBrauchwasser.sendCommand(ON)
                    bExtraBrauchwasser = true
                    sendBroadcastNotification("Einspeisung ist größer als 4kw starte Extra Brauchwasser! Einspeisung = " + Einspeisung.state.toString)
                    logInfo("waterheat", "Einspeisung ist seit 10 Minuten größer als 4kW (aktuell {} W)", Einspeisung.state)
                    tExtraBrauchwasser.reschedule(now.plusHours(4))
                } else {
                    bExtraBrauchwasser = false
                    tExtraBrauchwasser = null
                }
            ])
        }
    } else if(!bExtraBrauchwasser) {
        tExtraBrauchwasser?.cancel
        tExtraBrauchwasser = null
    }
end

Re: rule syntax für photovoltaik effizienter nutzen

Verfasst: 11. Mai 2021 14:20
von linsenpago
Hallo Udo!

Vielen lieben dank! Die Rule schein in dieser Form nun wirklich zu funktionieren!

Sie schaut nun korrekt die 10 Minuten ob die Eingespeiste Leistung konstant über 4kw bleibt und wartet danach auch 4 Stunden bis sie wieder das Extra Brauchwasser anwerfen würde.

Vielen Dank!