Überschussleistung Laden
- udo1toni
- Beiträge: 13864
- Registriert: 11. Apr 2018 18:05
- Wohnort: Darmstadt
Re: Überschussleistung Laden
Ah, klar... rrd4j gibt logischerweise immer eine Zahl zurück. Wobei ich aber nicht sicher bin, ob das auch der Fall ist, wenn keine Daten vorliegen. Die Zeile als solche hat also ihre Berechtigung, Du kannst aber hinten das „as Number“ weg lassen. Damit fällt auch die Klammer um den Ausdruck weg. (Öffnende Klammer nach dem if() und schließende Klammer vor dem else)
Gesendet von iPad mit Tapatalk
Gesendet von iPad mit Tapatalk
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet
-
- Beiträge: 163
- Registriert: 13. Dez 2018 17:42
Re: Überschussleistung Laden
Ich versuche mich seit ein paar Tagen ebenfalls einer einer Regel für die Überschussladung.
Soweit sollte es funktionieren allerdings würde ich gerne verhindern, dass bei jeder Wolke die Ladung unterbrochen wird.
Meine Idee ist es wie bereits in diesem Thread erwähnt, einen Timer laufen zu lassen, welcher bspw. nach 5 Minuten Erzeugungsleistung kleiner 1380W die Ladung unterbricht. Ich bekomme es aber nicht hin...
Soweit sollte es funktionieren allerdings würde ich gerne verhindern, dass bei jeder Wolke die Ladung unterbrochen wird.
Meine Idee ist es wie bereits in diesem Thread erwähnt, einen Timer laufen zu lassen, welcher bspw. nach 5 Minuten Erzeugungsleistung kleiner 1380W die Ladung unterbricht. Ich bekomme es aber nicht hin...
Code: Alles auswählen
val reduceFactor = 0.90 // Faktor, um newPower zu reduzieren, um weniger nahe an der verfügbaren Leistung zu sein, z.B. 0,9 setzt newPower auf 90% der möglichen Leistung
rule "PV Charging"
when
Item huawei_last changed // Aktuelle Netzeinspeisung (positiver Wert) / Netzbezug (negativer Wert)
then
//nur wenn ladenmodus == PV Überschuss
if(goecharger_lademodus.state == 1)
{
//Aktuelle Netzeinspeisung / Netzbezug
var int verfuegbareLeistung = (huawei_last.state as Number).intValue
//mögliche Leistung berechnen
var int newPower = (verfuegbareLeistung * reduceFactor).intValue
//Wenn mögliche Leistung kleiner 6A nicht laden bzw. unterbrechen
//ToDo Timer einfügen
if (newPower < 1380)
{
if(goecharger_allow.state == 1) //Wenn aktuell geladen wird, Ladung abbrechen
{
goecharger_allow.sendCommand(0)
}
return
}
else
{
//prüfen ob mögliche Leistung größer der Kabelcodierung, falls ja Leistung auf Kabelcodierung reduzieren
if (newPower / 230 > (goecharger_cable_current.state as Number))
{
goecharger_ampere.sendCommand(goecharger_cable_current.state as Number)
}
else
{
goecharger_ampere.sendCommand(newPower/230)
}
if(goecharger_allow.state == 0) //Wenn aktuell nicht geladen wird, Ladung starten
{
goecharger_allow.sendCommand(1)
}
}
}
end
-
- Beiträge: 181
- Registriert: 1. Sep 2018 18:24
Re: Überschussleistung Laden
Hi,
ich würde Dir empfehlen nicht mit einem Timer zu arbeiten, sondern vielmehr die Funktion des Mittelwertes zu verwenden.
Ich benutze aktuell den Mittelwert von 5 Min was ganz gut läuft. Ich hab auch als prio und eine Abhängigkeit noch mein aktuellen Verbrauch im Haus mit berücksichtigt....
Den Timer habe ich eingebaut, damit meine Wallbox nach 5 min ausschaltet. Das heißt wenn 5 min der Verbrauch höher ist als die Produktion wird abgeschalten
Hier ein Auszug:
Bei Fragen einfach melden
ich würde Dir empfehlen nicht mit einem Timer zu arbeiten, sondern vielmehr die Funktion des Mittelwertes zu verwenden.
Ich benutze aktuell den Mittelwert von 5 Min was ganz gut läuft. Ich hab auch als prio und eine Abhängigkeit noch mein aktuellen Verbrauch im Haus mit berücksichtigt....
Den Timer habe ich eingebaut, damit meine Wallbox nach 5 min ausschaltet. Das heißt wenn 5 min der Verbrauch höher ist als die Produktion wird abgeschalten
Hier ein Auszug:
Code: Alles auswählen
if (Symo_PowerflowchannelpgridkW.state < 0 ){
val Number nPV_smoothed = if(Symo_Inverterdatachannelpac.state instanceof Number) (Symo_Inverterdatachannelpac.averageSince(now.minusMinutes(5), "rrd4j") as Number).floatValue else 0
val Number nHaus_smoothed = if(Symo_Powerflowchannelpload.state instanceof Number) (Symo_Powerflowchannelpload.averageSince(now.minusMinutes(5), "rrd4j") as Number).floatValue else 500
(Symo_Inverterdatachannelpac.averageSince(now.minusMinutes(1), "rrd4j") as Number) else 0
val Number nPV = if(Symo_Inverterdatachannelpac.state instanceof Number) (Symo_Inverterdatachannelpac.state as Number).floatValue else 0
val Number nHaus = if(Symo_Powerflowchannelpload.state instanceof Number) (Symo_Powerflowchannelpload.state as Number).floatValue else 500 // zu erwartender Spitzenbedarf als Default Wert
logInfo("Verfügbare Energie", "nPV_smoothed: {}, nHaus_smoothed: {}, nPV: {}, nHaus: {},", nPV_smoothed, nHaus_smoothed, nPV, nHaus )
val Number nDiff = nPV - ( -1 * nHaus)
val Number nDiff_smoothed = nPV_smoothed - (-1 * nHaus_smoothed)
Available_Energy.sendCommand(nDiff)
Charging_Energy.sendCommand(nDiff_smoothed)
} else {
Available_Energy.sendCommand(0)
Charging_Energy.sendCommand(0)
}
if(((Symo_PowerflowchannelpgridkW.state as Number).floatValue > (Symo_Inverterdatachannelpac.state as Number).floatValue)
&& tCharge === null
&& RenaultZEServices_Zoe_Charging.state == "Charging"
&& KebaState.state == 3 ){
tCharge = createTimer(now.plusMinutes(5),[|
sendBroadcastNotification("Achtung. Keine Sonnenenergie. Es 100% Netzbezug beim laden. Schalte Ladevorgang ab" )
KebaSwitch.sendCommand(OFF)
tCharge = null
])}
else if ((Symo_PowerflowchannelpgridkW.state as Number).floatValue < (Symo_Inverterdatachannelpac.state as Number).floatValue) {
tCharge?.cancel
tCharge = null
}
end
-
- Beiträge: 163
- Registriert: 13. Dez 2018 17:42
Re: Überschussleistung Laden
Vielen Dank für deine Unterstützung...aber ganz ehrlich bei deinem Code bin ich raus
Das ist mir doch eine Nummer zu heftig...
Das ist mir doch eine Nummer zu heftig...
-
- Beiträge: 181
- Registriert: 1. Sep 2018 18:24
Re: Überschussleistung Laden
Wenn Du möchtest, kann ich Dir mit Kommenataren helfen....
Was hast denn für eine Wallbox, bzw Wechselrichter? Welche Items stehen zur Verfügung?
Was hast denn für eine Wallbox, bzw Wechselrichter? Welche Items stehen zur Verfügung?
- udo1toni
- Beiträge: 13864
- Registriert: 11. Apr 2018 18:05
- Wohnort: Darmstadt
Re: Überschussleistung Laden
Ich hab die Rule mal etwas umgeschrieben, damit der Code etwas klarer wird:
Der ternäre Operator (a = if(b) c else d) ist schick, um eine lokale Konstante mit einem von zwei Werten zu belegen. In obigem Codebeispiel wird es aber leider sehr unübersichtlich, obwohl die verschiedenen Schritte recht einfach sind.
Der erste Teil des Codes überträgt alle Status der verschiedenen Items bzw. der Persistence Quelle in lokale Variablen. Dabei wird beachtet, dass Teile dieser Werte eventuell nicht zur Verfügung stehen. In diesem Fall wird dann ein Default Wert gesetzt.
Im zweiten Teil werden die Differenzen berechnet. Hier wird dafür gesorgt, dass der niedrigste Wert jeweils 0 ist.
Der dritte Teil gibt die Werte im Log aus und befüllt die Anzeige für die UI.
Im vierten Teil wird ein Timer gesteuert, falls der Verbrauch über der Produktion liegt, wird der Timer angelegt (nur, falls der Zoe gerade lädt). Falls der Verbrauch unter der Produktion liegt, wird ein eventuell laufender Timer abgebrochen.
Code: Alles auswählen
// Teil 1
var Number nPV = 0 // definiere Variable mit Default 0
if(Symo_Inverterdatachannelpac.state instanceof Number) // Falls das Item gültig ist
nPV =(Symo_Inverterdatachannelpac.state as Number).floatValue // Übernimm Itemstatus
var Number nHaus = 500 // definiere Variable mit Default 500
if(Symo_Powerflowchannelpload.state instanceof Number) // ...
nHaus = (Symo_Powerflowchannelpload.state as Number).floatValue // ...
var Number nPV_smoothed = 0 // ...
if(Symo_Inverterdatachannelpac.averageSince(now.minusMinutes(5), "rrd4j") instanceof Number) // Falls die Persistence einen gültigen Wert liefert
nPV_smoothed = (Symo_Inverterdatachannelpac.averageSince(now.minusMinutes(5), "rrd4j") as Number).floatValue // Übernimm den Wert der Persistence
var Number nHaus_smoothed = 500 // ...
if(Symo_Powerflowchannelpload.averageSince(now.minusMinutes(5), "rrd4j") instanceof Number) // ...
nHaus_smoothed = (Symo_Powerflowchannelpload.averageSince(now.minusMinutes(5), "rrd4j") as Number).floatValue// ...
var Number nPower = 0 // ...
if(Symo_PowerflowchannelpgridkW.state instanceof Number) // ...
nPower = (Symo_PowerflowchannelpgridkW.state as Number).floatValue // ...
// Teil 2
var Number nDiff = 0 // ...
var Number nDiff_smoothed = 0 // ...
if(nPV + nHaus > 0) // nur falls Wert größer 0
nDiff = nPV + nHaus // Übernimm Wert
if(nPV_smoothed + nHaus_smoothed > 0) // nur falls Wert größer 0
nDiff_smoothed = nPV_smoothed + nHaus_smoothed // Übernimm Wert
// Teil 3
logInfo("Verfügbare Energie", "nPV_smoothed: {}, nHaus_smoothed: {}, nPV: {}, nHaus: {},", nPV_smoothed, nHaus_smoothed, nPV, nHaus )
Available_Energy.sendCommand(nDiff)
Charging_Energy.sendCommand(nDiff_smoothed)
// Teil 4
if(nPower < nPV) { // Falls Strommenge ausreichend
tCharge?.cancel // brich einen laufenden Timer ab
tCharge = null // und lösche ihn
} else { // Falls Strommenge nicht ausreichend
if(tCharge === null && RenaultZEServices_Zoe_Charging.state == "Charging" && KebaState.state == 3 ) // Falls kein Timer vorhanden und Zoe lädt auf Stufe 3(?)
tCharge = createTimer(now.plusMinutes(5), [| // Erzeuge Abschlattimer
sendBroadcastNotification("Achtung. Keine Sonnenenergie. 100% Netzbezug beim Laden. Schalte Ladevorgang ab" )
KebaSwitch.sendCommand(OFF)
tCharge = null
])
}
end
Der erste Teil des Codes überträgt alle Status der verschiedenen Items bzw. der Persistence Quelle in lokale Variablen. Dabei wird beachtet, dass Teile dieser Werte eventuell nicht zur Verfügung stehen. In diesem Fall wird dann ein Default Wert gesetzt.
Im zweiten Teil werden die Differenzen berechnet. Hier wird dafür gesorgt, dass der niedrigste Wert jeweils 0 ist.
Der dritte Teil gibt die Werte im Log aus und befüllt die Anzeige für die UI.
Im vierten Teil wird ein Timer gesteuert, falls der Verbrauch über der Produktion liegt, wird der Timer angelegt (nur, falls der Zoe gerade lädt). Falls der Verbrauch unter der Produktion liegt, wird ein eventuell laufender Timer abgebrochen.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet
-
- Beiträge: 163
- Registriert: 13. Dez 2018 17:42
Re: Überschussleistung Laden
Ich habe einen Huawei Wechselrichter und einen goeCharger verbaut. Die folgenden Items stehen zur Verfügung:Wenn Du möchtest, kann ich Dir mit Kommenataren helfen....
Was hast denn für eine Wallbox, bzw Wechselrichter? Welche Items stehen zur Verfügung?
Wechserlrichter
Number Huawei_Last --> postiver Wert --> aktuelle Einspeiseleistung, d.h. Überschuss der ins Netz geht
--> negativer Wert --> aktueller Bezug aus dem Netz
Number Active_power --> Aktuelle AC Erzeugungsleistung der Wechselrichters
Ladestation
Number goecharger_state --> aktueller Status (Auto verbunden, Auto verbunden und lädt, Auto nicht verbunden)
Number goecharger_allow --> Ladefreigabe ja (1)/nein (0)
Number goecharger_ampere --> Ladestärke in Ampere (6 - 16A)
-
- Beiträge: 181
- Registriert: 1. Sep 2018 18:24
Re: Überschussleistung Laden
Naja, ich finde Udo hat eine vorbilldliche Erklärung hier eingestellt, die mich auch nochmal dazu bewegt hat meinen Code anzupassen und "hübscher" zu machen:)
Udo, ich hätte da mal eine Frage. Ich habe Teil 3 (Logging) benutzt um zu die Glättung zu sehen. Jetzt würde ich gerne das Regeln beginnen.
Grundsätzlich kann ich die Leistung mit dem Strom einstellen. Ich habe "respekt" vor einer do-while Schleife.
Hast eine Idee, wie ich das "elegant" lösen kann?
Also sowas wie (pseudo code):
Udo, ich hätte da mal eine Frage. Ich habe Teil 3 (Logging) benutzt um zu die Glättung zu sehen. Jetzt würde ich gerne das Regeln beginnen.
Grundsätzlich kann ich die Leistung mit dem Strom einstellen. Ich habe "respekt" vor einer do-while Schleife.
Hast eine Idee, wie ich das "elegant" lösen kann?
Also sowas wie (pseudo code):
Code: Alles auswählen
do (erhöhe / reduziere den Strom)
while (Verfügbare Leistung == Ladeleistung )
-
- Beiträge: 163
- Registriert: 13. Dez 2018 17:42
Re: Überschussleistung Laden
Auch nach einer Stunde intensiven lesen des Codes verstehe ich es einfach nicht.
Zum Teil ist mir unklar welche Bedeutung die Variablen im Codebeispiel haben
nPV = Erzeugungsleistung des Wechselrichters
nHaus = Verbrauch im Haus
Doch was bedeutet "Symo_Inverterdatachannelpac", "Symo_Powerflowchannelpload", "nPV_smoothed " usw....?
Ich habe mich jetzt mal selbst heran getastet und denke soweit sollte der Quellcode passen.
Was mir noch fehlt ist eine Art Timer welcher ein ständiges switchen zwischen ON und OFF verhindert.
Das ständige anpassen der Ladestärke sollte kein Problem sein....bei der Rekuperation macht das Fahrzeug ja eigentlich auch nichts anderes.
Zum Teil ist mir unklar welche Bedeutung die Variablen im Codebeispiel haben
nPV = Erzeugungsleistung des Wechselrichters
nHaus = Verbrauch im Haus
Doch was bedeutet "Symo_Inverterdatachannelpac", "Symo_Powerflowchannelpload", "nPV_smoothed " usw....?
Ich habe mich jetzt mal selbst heran getastet und denke soweit sollte der Quellcode passen.
Was mir noch fehlt ist eine Art Timer welcher ein ständiges switchen zwischen ON und OFF verhindert.
Das ständige anpassen der Ladestärke sollte kein Problem sein....bei der Rekuperation macht das Fahrzeug ja eigentlich auch nichts anderes.
Code: Alles auswählen
val reduceFactor = 0.90 // Faktor, um newPower zu reduzieren, um weniger nahe an der verfügbaren Leistung zu sein, z.B. 0,9 setzt newPower auf 90% der möglichen Leistung
//PV geführtes Laden
rule "PV laden"
when
Item Huawei_Last changed
then
//Lademodus: 1 = PV geführtes Laden und Charger bereit (Fahrzeug angeschlossen)
if(goecharger_lademodus.state == 1 && goecharger_state.state == 4)
{
//Aktuelle Leistung (negativ = Netzbezug, postiv = Erzeugung
var Number leistung = (Huawei_Last.state as Number).intValue
//mögliche Leistung berechnen
var Number newPower = (leistung * reduceFactor).intValue
//Wenn mögliche Leistung kleiner 6A laden beenden
if (newPower < 1380)
{
goecharger_allow.sendCommand(0) //Ladung beenden
return
}
else
{
//prüfen ob mögliche Leistung größer der Kabelcodierung, falls ja Leistung auf Kabelcodierung reduzieren
if (newPower / 230 > (goecharger_cable_current.state as Number))
{
goecharger_ampere.sendCommand((goecharger_cable_current.state as Number))
goecharger_allow.sendCommand(1)
return
}
else
{
goecharger_ampere.sendCommand(newPower/230)
goecharger_allow.sendCommand(1)
}
}
}
end