NEWS
Solarüberschuss immer auf Null ausbalancieren
-
Hi Leute,
ich will meinen Solarüberschuss in 100derten Schritten automatisch in die Batterie laden. D.h. ich brauche eine Logik (Blockly Programm) dass 1. prüft wie hoch ist der aktuelle Hausverbrauch (HV) und dann die Batterieladeleistung (BLL) in 100W erhöht, so dass der HV immer bei 0 sich einpendelt.
Mein Problem ist jetzt, dass die 2 Variablen HV und BLL sich gegenseitig beinflussen und mein bisheriges Skript unbrauchbar machen.
zB.
Prüfe ob HV < 0 (das heißt ich habe einen negativen Stromverbrauch also Solarüberschuss)WENN HV <0 DANN setze BLL = 100
damit geht aber die HV Variable sofort auf +100 und das ganze fällt in sich zusammen.
Hat jemand eine Idee?
-
@accu Meine Idee ist, erstmal das Forum nach anderen Threads durchsuchen, die das gleiche Thema schon bearbeitet haben ...
-
@accu sagte: Hat jemand eine Idee?
PI-Regler.
@accu sagte in Solarüberschuss immer auf Null ausbalancieren:
in 100derten Schritten automatisch in die Batterie laden.
Wie hoch ist die maximale Ladeleistung?
Wie oft wird HV aktualisiert? -
@martinp schon gesucht aber nix passendes gefunden.
-
@accu sagte: nix passendes gefunden.
Beispiel für PI-Regler:
-
@paul53 ich habe mich mal selbst an einem Blockly versucht. Aber irgendwie geht es nicht wie ich mir das vorstelle:
der Solarüberschuss kann so maximal 1.400W werden.
Das Problem ist irgendwie, dass das Script die Ladeleistung rauf und runter regelt, statt sie auf Null zu halten (siehe unterer Bildrand mit den Debug Werten)Ich stelle mir das so vor. Alle 10s soll überprüft werden was der akutelle Hausverbrauch (Real Power) ist. Bei z.B. - 945W soll mit 900 W die Batterie geladen werden (SloChgPower).
Das Problem was ich habe. Ich setze z.B. die 900 W Ladeleistung für die Batterie, was zur Folge hat, dass dann der Hausverbrauch hoch geht und der freie Solarüberschuss um die 900W weniger wird, in dem Bsp dann auf -45W. Was immer noch ok ist. (ich sollte dazu sagen dass ich AC Lade) d.h. ich habe von den Solarzellen den überschuss schon in meinem Hausnetz.
Erst wenn dann eine Wolke kommt und der gesamt überschuss auf z.B. -800W sinkt sollte das nachkorrigiert werden.
Irgendwie stehe ich aber gerade auf dem Schlauch.
-
@accu sagte: Script die Ladeleistung rauf und runter regelt
Dieser P-Regler hat eine zu hohe Schleifenverstärkung und ist deshalb instabil. Versuche es mal mit dem gezeigten PI-Regler.
EDIT: Wenn "RealPower" öfter als alle 10 s aktualisiert wird, kann
Tn
entsprechend verringert werden. Schwankungen werden dann schneller ausgeglichen. -
@paul53 hast du eine Erklärung zu deinem Skript. Verstehe das nicht ganz. Sorry bin Blockly Anfänger. Was sind den i, xP, Tn?
-
@accu sagte: Erklärung zu deinem Skript.
Das ist die Umsetzung eines PI-Reglers mit Kp = -1400 / Xp = -0,1.
p
enthält den Proportionalanteil,i
den Integralanteil. Mitlasti
wird verhindert, dass der Integralanteil weiter läuft, wenn der Regler begrenzt (output
0 / 100).@accu sagte in Solarüberschuss immer auf Null ausbalancieren:
Was sind den i, xP, Tn?
Xp
nennt sich Proportionalband
Tn
ist die Nachstellzeit in s -
@accu ,
oderalle z.B. 20sec { (Bll + HV) < -50 dann Bll = Bll + 100 (Bll + HV) > 80 dann if Bll > 0 dann Bll = Bll - 100 }
mit den Werten kann man dann noch spielen.
edit:
hier zum trocken testen und zum spielen.<xml xmlns="https://developers.google.com/blockly/xml"> <variables> <variable id="R`mn(cD#e9UrF3W.[`Jy">Bll</variable> <variable id="h~kP2331{Pb[mXj==!Xp">HV</variable> </variables> <block type="variables_set" id="G{d5b]E92BZ3RAdD!78R" x="88" y="38"> <field name="VAR" id="R`mn(cD#e9UrF3W.[`Jy">Bll</field> <value name="VALUE"> <block type="math_number" id="u./idg*w/QptQ3fJW(Ah"> <field name="NUM">0</field> </block> </value> <next> <block type="schedule" id="Ke.`x2d!Bj7%Mb5uzJAA"> <field name="SCHEDULE">*/10 * * * * *</field> <statement name="STATEMENT"> <block type="variables_set" id="blMDz?Po-?=A#f`i=]50"> <field name="VAR" id="h~kP2331{Pb[mXj==!Xp">HV</field> <value name="VALUE"> <block type="math_rndfixed" id="@6lK6fDn_c.:~h./PPk5"> <field name="n">1</field> <value name="x"> <shadow type="math_number" id="Ch=1x:dgnyQ9KWKKU)Db"> <field name="NUM">3.1234</field> </shadow> <block type="math_arithmetic" id="m%5NL{t=X;/O3}k@hXvE"> <field name="OP">MINUS</field> <value name="A"> <shadow type="math_number" id="]y)BMj_-:e%SwHtsmu%R"> <field name="NUM">1</field> </shadow> <block type="math_arithmetic" id="!aMC7buM|a]IImq36)Mc"> <field name="OP">MULTIPLY</field> <value name="A"> <shadow type="math_number" id="TsLyzW5au.y=3y~l$a(s"> <field name="NUM">1000</field> </shadow> </value> <value name="B"> <shadow type="math_number" id="/6eB*|u`#Y~_i!0ff67c"> <field name="NUM">1</field> </shadow> <block type="math_random_float" id="cuL|+%?Y#,U!o.]Jp^}Q"></block> </value> </block> </value> <value name="B"> <shadow type="math_number" id="L72j))K4RH]:R(alW`*Q"> <field name="NUM">500</field> </shadow> </value> </block> </value> </block> </value> <next> <block type="controls_if" id="JBLyu*@*S];BU~Co@n`@"> <mutation elseif="1"></mutation> <value name="IF0"> <block type="logic_operation" id="[YWV^k5Y1T:k[ekEY^Sy"> <field name="OP">AND</field> <value name="A"> <block type="logic_compare" id=",%O0O[xNBD.|ZdirgvhT"> <field name="OP">LT</field> <value name="A"> <block type="variables_get" id="na:o}nh(FcbqvgVSXmDk"> <field name="VAR" id="R`mn(cD#e9UrF3W.[`Jy">Bll</field> </block> </value> <value name="B"> <block type="math_number" id="FAlU|kY=Vr/s44Td8maC"> <field name="NUM">500</field> </block> </value> </block> </value> <value name="B"> <block type="logic_compare" id="g?BU$swetC~?/lhcIUOW"> <field name="OP">LT</field> <value name="A"> <block type="math_arithmetic" id="9C!]t7jFQ/SPaS3yd#^_"> <field name="OP">ADD</field> <value name="A"> <shadow type="math_number" id=";S]O|zuJFX2Hf=VVs`r`"> <field name="NUM">1</field> </shadow> <block type="variables_get" id="XAQR%xOa{ngVw.*E{mO."> <field name="VAR" id="h~kP2331{Pb[mXj==!Xp">HV</field> </block> </value> <value name="B"> <shadow type="math_number" id=")Cp{/nfFH|Z~H5QwFZU)"> <field name="NUM">100</field> </shadow> <block type="variables_get" id="he-h]hyMT*F[8Vb~$WMz"> <field name="VAR" id="R`mn(cD#e9UrF3W.[`Jy">Bll</field> </block> </value> </block> </value> <value name="B"> <block type="math_number" id="$Gi!wHt~tJU[MfCh(Ajx"> <field name="NUM">-50</field> </block> </value> </block> </value> </block> </value> <statement name="DO0"> <block type="math_change" id="WJFJYu`nm^~F3ys|#CVc"> <field name="VAR" id="R`mn(cD#e9UrF3W.[`Jy">Bll</field> <value name="DELTA"> <shadow type="math_number" id="lxkrR)y/p$k[b~%QTnE]"> <field name="NUM">100</field> </shadow> </value> </block> </statement> <value name="IF1"> <block type="logic_compare" id="lAi[pEK+IMNr+Xp.96U2"> <field name="OP">GT</field> <value name="A"> <block type="math_arithmetic" id="|jgo754=.M[2#gWx`@@K"> <field name="OP">ADD</field> <value name="A"> <shadow type="math_number" id="!2VPgUDjZ8?H|soN9hDt"> <field name="NUM">1</field> </shadow> <block type="variables_get" id="gB%v@:y$FUCn(@Ru:t*M"> <field name="VAR" id="h~kP2331{Pb[mXj==!Xp">HV</field> </block> </value> <value name="B"> <shadow type="math_number" id=")Cp{/nfFH|Z~H5QwFZU)"> <field name="NUM">100</field> </shadow> <block type="variables_get" id="5X0DbKYoce2igfG$hp[{"> <field name="VAR" id="R`mn(cD#e9UrF3W.[`Jy">Bll</field> </block> </value> </block> </value> <value name="B"> <block type="math_number" id="+g87mA#f0lDfC3Kp:(we"> <field name="NUM">80</field> </block> </value> </block> </value> <statement name="DO1"> <block type="controls_if" id="sFCm7.7~@k|BSk0$G%iM"> <value name="IF0"> <block type="logic_compare" id="Q3FEVxOI7u:SXUTJ^kWv"> <field name="OP">GT</field> <value name="A"> <block type="variables_get" id="U=ET!do3$cYv{k-=dRt2"> <field name="VAR" id="R`mn(cD#e9UrF3W.[`Jy">Bll</field> </block> </value> <value name="B"> <block type="math_number" id="/kxHot85ttA!4ZZ(hqAk"> <field name="NUM">0</field> </block> </value> </block> </value> <statement name="DO0"> <block type="math_change" id="/d9P#ga-s`ZBP{=IJz+%"> <field name="VAR" id="R`mn(cD#e9UrF3W.[`Jy">Bll</field> <value name="DELTA"> <shadow type="math_number" id="tb~CtTz^GH;(T_U3)*z["> <field name="NUM">-100</field> </shadow> </value> </block> </statement> </block> </statement> <next> <block type="debug" id="~HbVUC/MG8JhJ%Akl-}T"> <field name="Severity">log</field> <value name="TEXT"> <shadow type="text" id="J+tA)cp)oU1CQC8e0lgD"> <field name="TEXT">test</field> </shadow> <block type="variables_get" id="I)%b8xo:Aach|B;Nj.p/"> <field name="VAR" id="h~kP2331{Pb[mXj==!Xp">HV</field> </block> </value> <next> <block type="debug" id="KQ_WwD}*8{O(J_UaUB;M"> <field name="Severity">log</field> <value name="TEXT"> <shadow type="text" id="CQmnkOAXS@KT#!{6.QhW"> <field name="TEXT">test</field> </shadow> <block type="variables_get" id="g_52/2No-POis)`mlVOr"> <field name="VAR" id="R`mn(cD#e9UrF3W.[`Jy">Bll</field> </block> </value> </block> </next> </block> </next> </block> </next> </block> </statement> </block> </next> </block> </xml>
-
@wal MEEEEEGGGAA dank Walter. Sieht erstmal gut aus. Ich spiele mal mit den Werten rum. vielen Dank.
Was ich noch nicht ganz begriffen habe ist, wie du ausschließt dass die beiden Variablen sich gegenseitig lfd. beeinflussen. Also, wenn die Ladeleistung hochgesetzt wird, dann führt das ja auch dazu dass der verfügbare Solar-Überschuss im Netz weniger wird, welcher dann wiederum ja die einstellbare Ladeleistung beeinflusst.
-
@accu ,
weil ich die Ladeleistung zu der aktuellen Netzentnahme addiere und dann erst vergleiche und es ist auch eine Hysterese vorhanden, damit die Ladeleistung nicht hin und her kippelt.
Wenn du mit deinen Werten dann arbeiten möchtest, musst du die setzen Sachen entfernen, ich denke das du das weißt. -
@accu ,
ich habe mir ein bisschen Zeit genommen und alles nochmal durch den Kopf gehen lassen.
Man darf nur die Hysterese einbauen, sonst können sich die Werte beeinflussen wie du es festgestellt hast.
Mit den 500 begrenzt du die Ladeleistung auf 500W.
Fällt die Netzentnahme unter -50W z.B. -70W wird die Ladeleistung um 100W erhöht.
Die Netzentnahme steigt jetzt auf 30W (-70W + 100W).
30W ist aber kleiner 80W und größer -50W also ändert sich nichts.
<xml xmlns="https://developers.google.com/blockly/xml"> <variables> <variable id="R`mn(cD#e9UrF3W.[`Jy">Bll</variable> <variable id="h~kP2331{Pb[mXj==!Xp">HV</variable> </variables> <block type="variables_set" id="G{d5b]E92BZ3RAdD!78R" x="88" y="38"> <field name="VAR" id="R`mn(cD#e9UrF3W.[`Jy">Bll</field> <value name="VALUE"> <block type="math_number" id="u./idg*w/QptQ3fJW(Ah"> <field name="NUM">0</field> </block> </value> <next> <block type="schedule" id="Ke.`x2d!Bj7%Mb5uzJAA"> <field name="SCHEDULE">*/10 * * * * *</field> <statement name="STATEMENT"> <block type="variables_set" id="blMDz?Po-?=A#f`i=]50"> <field name="VAR" id="h~kP2331{Pb[mXj==!Xp">HV</field> <value name="VALUE"> <block type="math_rndfixed" id="@6lK6fDn_c.:~h./PPk5"> <field name="n">1</field> <value name="x"> <shadow type="math_number" id="Ch=1x:dgnyQ9KWKKU)Db"> <field name="NUM">3.1234</field> </shadow> <block type="math_arithmetic" id="m%5NL{t=X;/O3}k@hXvE"> <field name="OP">MINUS</field> <value name="A"> <shadow type="math_number" id="]y)BMj_-:e%SwHtsmu%R"> <field name="NUM">1</field> </shadow> <block type="math_arithmetic" id="!aMC7buM|a]IImq36)Mc"> <field name="OP">MULTIPLY</field> <value name="A"> <shadow type="math_number" id="TsLyzW5au.y=3y~l$a(s"> <field name="NUM">1000</field> </shadow> </value> <value name="B"> <shadow type="math_number" id="/6eB*|u`#Y~_i!0ff67c"> <field name="NUM">1</field> </shadow> <block type="math_random_float" id="cuL|+%?Y#,U!o.]Jp^}Q"></block> </value> </block> </value> <value name="B"> <shadow type="math_number" id="L72j))K4RH]:R(alW`*Q"> <field name="NUM">500</field> </shadow> </value> </block> </value> </block> </value> <next> <block type="controls_if" id="JBLyu*@*S];BU~Co@n`@"> <mutation elseif="1"></mutation> <value name="IF0"> <block type="logic_operation" id="[YWV^k5Y1T:k[ekEY^Sy"> <field name="OP">AND</field> <value name="A"> <block type="logic_compare" id=",%O0O[xNBD.|ZdirgvhT"> <field name="OP">LT</field> <value name="A"> <block type="variables_get" id="na:o}nh(FcbqvgVSXmDk"> <field name="VAR" id="R`mn(cD#e9UrF3W.[`Jy">Bll</field> </block> </value> <value name="B"> <block type="math_number" id="FAlU|kY=Vr/s44Td8maC"> <field name="NUM">500</field> </block> </value> </block> </value> <value name="B"> <block type="logic_compare" id="g?BU$swetC~?/lhcIUOW"> <field name="OP">LT</field> <value name="A"> <block type="variables_get" id="XAQR%xOa{ngVw.*E{mO."> <field name="VAR" id="h~kP2331{Pb[mXj==!Xp">HV</field> </block> </value> <value name="B"> <block type="math_number" id="$Gi!wHt~tJU[MfCh(Ajx"> <field name="NUM">-50</field> </block> </value> </block> </value> </block> </value> <statement name="DO0"> <block type="math_change" id="WJFJYu`nm^~F3ys|#CVc"> <field name="VAR" id="R`mn(cD#e9UrF3W.[`Jy">Bll</field> <value name="DELTA"> <shadow type="math_number" id="lxkrR)y/p$k[b~%QTnE]"> <field name="NUM">100</field> </shadow> </value> </block> </statement> <value name="IF1"> <block type="logic_compare" id="lAi[pEK+IMNr+Xp.96U2"> <field name="OP">GT</field> <value name="A"> <block type="variables_get" id="gB%v@:y$FUCn(@Ru:t*M"> <field name="VAR" id="h~kP2331{Pb[mXj==!Xp">HV</field> </block> </value> <value name="B"> <block type="math_number" id="+g87mA#f0lDfC3Kp:(we"> <field name="NUM">80</field> </block> </value> </block> </value> <statement name="DO1"> <block type="controls_if" id="sFCm7.7~@k|BSk0$G%iM"> <value name="IF0"> <block type="logic_compare" id="Q3FEVxOI7u:SXUTJ^kWv"> <field name="OP">GT</field> <value name="A"> <block type="variables_get" id="U=ET!do3$cYv{k-=dRt2"> <field name="VAR" id="R`mn(cD#e9UrF3W.[`Jy">Bll</field> </block> </value> <value name="B"> <block type="math_number" id="/kxHot85ttA!4ZZ(hqAk"> <field name="NUM">0</field> </block> </value> </block> </value> <statement name="DO0"> <block type="math_change" id="/d9P#ga-s`ZBP{=IJz+%"> <field name="VAR" id="R`mn(cD#e9UrF3W.[`Jy">Bll</field> <value name="DELTA"> <shadow type="math_number" id="tb~CtTz^GH;(T_U3)*z["> <field name="NUM">-100</field> </shadow> </value> </block> </statement> </block> </statement> <next> <block type="debug" id="~HbVUC/MG8JhJ%Akl-}T"> <field name="Severity">log</field> <value name="TEXT"> <shadow type="text" id="J+tA)cp)oU1CQC8e0lgD"> <field name="TEXT">test</field> </shadow> <block type="variables_get" id="I)%b8xo:Aach|B;Nj.p/"> <field name="VAR" id="h~kP2331{Pb[mXj==!Xp">HV</field> </block> </value> <next> <block type="debug" id="KQ_WwD}*8{O(J_UaUB;M"> <field name="Severity">log</field> <value name="TEXT"> <shadow type="text" id="CQmnkOAXS@KT#!{6.QhW"> <field name="TEXT">test</field> </shadow> <block type="variables_get" id="g_52/2No-POis)`mlVOr"> <field name="VAR" id="R`mn(cD#e9UrF3W.[`Jy">Bll</field> </block> </value> </block> </next> </block> </next> </block> </next> </block> </statement> </block> </next> </block> </xml>
-
@wal super Walter. Mein Skript schaut jetzt so aus.
Nach ersten Tests läuft das ganze jetzt wesentlich stabiler und der Ladewert, wird nicht permanent rauf- und runter reguliert. Allerdings habe ich jetzt Fälle wo er auch gerne mal 60W ins plus geht und mit Hausstrom lädt.
Seltsam ist auch, dass er nicht auf 50W runter reguliert bei niedrigen Solarüberschusswerten. Hier dazu mal das Protokoll:
-
@accu ,
wie hoch sind deine Ladeleistungsschritte die du Setzen kannst jetzt im Normalbetrieb, oben hast du was von 100 geschrieben und im Skript hast du 50 stehen ?Je höher die Hysterese und Regelintervall, desto weniger schwankt das Ganze.
-
@accu bist du sicher dass diese Werte in den flüchtigen Speicher geschrieben werden?
Wenn die ins EEPROM geschrieben werden, ist nach kurzer Zeit Schluss.
So ein EEPROM hält ca. 100.000 Schreibvorgänge. und bei 5 Sekunden Abstand..... -
@wal ich habe mal etwas mit den Werten rumgespielt. Bei Überschuss erhöhe ich die Ladeleistung in 20ger schritten, wenn ich nur noch Netzstrom habe, dann reduziere ich die Ladeleistung in 50ger Schritten.
-
@accu ,
wenn du weniger Netzstrom nutzen möchtest, musst du mit der Hysterese weiter ins negative.-80 und +20 beim Vergleich.
-
@homoran puhh gute Frage. Ich habe eine Ecoflow Delta Pro und ich nutze das ioBroker Skript, welches hier zur Verfügung gestellt wurde: https://forum.iobroker.net/topic/66743/ecoflow-connector-script-zur-dynamischen-leistungsanpassung
Ein "Writable" Datenpunkt in dem ioBroker object Baum ist die Ladegeschwindigkeit über Wechselspannung.
Ich bin kein Programmierer aber so wie ich das verstanden habe, kann man die beschreiben. Woher weißt ich ob diese Werte ins EEPROM geschrieben werden?Hier gibts noch den Beitrag von @haus-automatisierung dazu, der auch die AC Ladegeschwindigkeit erwähnt zum Einstellen via Skript.
https://haus-automatisierung.com/hardware/2023/02/13/ecoflow-river-2-usv-batteriespeicher.html?fbclid=IwAR01cgNhZGlG4m6FKbTWcpVERw8aqDFKjanJq55O8R8KZ5Agz5IcwVpV_4k -
@accu ,
ich muss mir auch sowas mal zulegen, das tut ja schon weh.