evcc icon indicating copy to clipboard operation
evcc copied to clipboard

Kostal Plenticore: add grid charging

Open iseeberg79 opened this issue 1 year ago • 3 comments

This change adds writing the registers for holding or mains charging the battery for the template. The changes have been discussed in the context of incident #15508. Prior to these changes, writing was done to register 1042, which has now been replaced by writing to register 1028. As before, external battery management is required to use these functions. Internal battery management is re-enabled in normal mode by resetting the watchdog. There are templates for SMA and Fronius, which have already implemented these functions and inspired the changes.

Could you please review and adapt the template?

iseeberg79 avatar Aug 26 '24 18:08 iseeberg79

Wo ist denn der Unterschied zwischen Case 1 (normal) und Case 2 (hold)? Beides setzt den Wert auf 0, verstehe die Logik dahinter nicht, warum man dafür dann zwei identische Codeblöcke braucht. Oder hab ich was übersehen?

Und zweite Frage: bei mir ist der Plenticore per default auf little-endian eingestellt, würde das dann überhaupt funktionieren? Oder sollte da im WR ohnehin big-endian eingestellt werden?

stna1981 avatar Aug 26 '24 19:08 stna1981

Der Unterschied ist im Issue bereits erwähnt. Zusätzlich wird beim Case 1 der für Case 2/3 nötige Watchdog für das regelmäßige Schreiben zurückgesetzt. Ein Vorteil ergibt sich bei der Regelung, da die Batterieladung nicht sofort endet, sondern ein paar Sekunden benötigt. Dies ist dann nach Beobachtungen für die Übergangszeit bis zur Übernahme der internen Regelung günstig. Big/Little Endian war ja vorher in der Regelung auch schon vorgesehen und wurde so übernommen und ist per Konfigurationsparameter einstellbar?

iseeberg79 avatar Aug 26 '24 20:08 iseeberg79

Ja big/little endian kann man einstellen in evcc. Sollte man auf little endian einstellen, auch bei den kostal WR, da sonst im KSEM riesige und damit falsche Werte angezeigt werden.

StevieC121176 avatar Aug 27 '24 02:08 StevieC121176

Das einzig unschöne daran ist, das der normal oder case 1 Zustand durch abwarten des timeouts im WR erreicht wird.

@deadrabbit87 nach Blick auf den PR it nicht offensichtlich, was man sonst noch tun könnte. Anscheinend lässt sich der WR nicht "per Befehl" wieder in den Normalmodus versetzen? Falls doch müsste dieses Kommando mit in case 1 rein.

andig avatar Sep 02 '24 15:09 andig

Nein, das geht nicht. Ich habe kein Register gefunden, mit dem man den WR wieder in den internen Modus schalten kann.

deadrabbit87 avatar Sep 02 '24 15:09 deadrabbit87

Die Lösung ist doch arg unglücklich. Es sollte möglich sein, eine Entladesperre zu setzen ohne dabei die Ladung zu bedindern. Wenn wir das so mergen sind die nächsten Fehlermeldungen schon vorprogrammiert :/

andig avatar Sep 05 '24 20:09 andig

Der WR kann ja auch Sunspec. Hat mal jemand probiert, ob es damit das gewünschte Verhalten gibt?

andig avatar Sep 05 '24 20:09 andig

Ja hab ich. Hatte diesbezüglich auch schon Kontakt mit Kostal.

Leider ist eine Steuerung der Batterie über Sunspec nicht implementiert.

Also leider Sunspec-Mogelpackung.... Ich finde es auch blöd, aber ich weiß leider keine andere Lösung.

deadrabbit87 avatar Sep 05 '24 20:09 deadrabbit87

@andig Ich wollte den Vorschlag gemacht haben, als eine Ausweichlösung. Die Diskussionen hatte ich zuvor nach Sunspec durchsucht, und die damaligen Antworten von @deadrabbit87 führen zu keiner abweichenden Lösung. Ich habe auch nochmal bei Kostal nachgefragt und warte auf eine Antwort. Prinzipiell fehlt das Register, um die Netzladung zu erlauben/zu verbieten durch Kostal: analog zu ChaGriSet. Also zurück zum ursprünglichen Vorschlag oder als alternatives Template die batterymode Implementierung auf Register 1028/1036 anbieten? Den PR abzubrechen und auf eine bessere Lösung zu warten ist natürlich auch eine Option ;)

Nebenbei gefragt, wäre es eigentlich richtiger den PR als Draft zu bearbeiten?

iseeberg79 avatar Sep 05 '24 20:09 iseeberg79

@andig Eine andere Option liegt im Verhalten des Watchdog? Wenn beim Wechsel in einen BatteryMode eine Ruhephase für die Reaktivierung der internen Steuerung abgewartet werden könnte, müsste man die Werte nicht selbst zurücksetzen (charge->hold). Dann wäre ein Schreiben des Registers für die Entladeleistung (Register 1040) für batteryHold ausreichend. Ich habe auf die Schnelle Fragmente für einen Ansatz im Quelltext des Watchdog gefunden, die darauf hindeuten, das ihr das vielleicht dort vorgesehen habt (flagBatteryModeWait)? Wenn es zusätzlich zum reset Parameter für den Watchdog auch einen "delay" bei einem Wechsel des Batteriemodus gibt, wäre der Kostal damit gut für beide Szenarien steuerbar.

iseeberg79 avatar Sep 06 '24 04:09 iseeberg79

Ich verstehe nur Bahnhof- kann leider den Registern nicht folgen. Aber: das einzige Problem ist doch, dass wir im hold Modus jetzt nicht mehr laden, richtig? In dem Fall: was spricht dagegen, im hold Modus limit soc=max soc (oder einfach fix 95) zu setzen und in jedem anderen Modus wieder limit soc=min soc? Und nur im charge Modus mit den anderen Registern zu arbeiten? Zweitens: bzgl. Watchdog: kann im normal Modus nicht die 1028 einmalig auf +100 geschrieben werden um das Entladen der Batterie sofort wieder zu erlauben? Oder welcher Wert steht hier per Default drin, bevor man mal charge ausprobiert hat? Und: falls irgendwas davon Sinn macht müsste es natürlich jemand ausprobieren ;)

andig avatar Sep 06 '24 06:09 andig

Normal: die Null ist aktuell ja nur bis zum Timeout, vernachlässigbar: die Regelung ist gerade nach dem erzwungenen Netzladen träge, da der Ladestrom intern im WR langsam heruntergefahren wird. Eine 100 würde sofort die reale Entladeleistung maximieren, eine -100 würde bis zum Timeout die maximale Ladeleistung setzen, bei zu wenig PV aus dem Netz.

Hold: leider ist das minsoc/maxsoc schreiben gar nicht das Problem: es hat nur leider die Wirkung, das die Daten, die im Charge-Modus vorher ins andere Register geschrieben wurden, weiterhin intern gesetzt bleiben. Daher muss der Ladewert per 0 in das Laderegister mindestens einmalig (!) zurückgesetzt werden. Weil das aber einmalig mit dem Watchdog nicht geht, lädt der WR überhaupt nicht mehr. Würde eine Zeit kein Wert per Modbus geschrieben werden, bräuchte man sich nicht selbst um das Zurücksetzen der Ladeleistung kümmern.

Charge: die Laderegister (1028/1036) sind nach meiner Auffassung redundant, beide regeln relativ die Ladeleistung, also in Prozent vom erlaubten Wert: Strom oder Leistung je nach Register

@andig Was ich gemeint habe: ein ähnlicher Mechanismus (reset), der für eine gewisse Zeit im Watchdog keine neuen Modbus-Nachrichten schreibt - insbesondere im Modus HOLD, würde andere Wege ermöglichen.

iseeberg79 avatar Sep 06 '24 07:09 iseeberg79

Was ich gemeint habe: ein ähnlicher Mechanismus (reset)

Gibts leider nicht :/

Normal: ... Eine 100 würde sofort die reale Entladeleistung maximieren, eine -100 würde bis zum Timeout die maximale Ladeleistung setzen, bei zu wenig PV aus dem Netz.

Was spricht gegen 100? Oder entlädt der dann ins Netz?

Hold: leider ist das minsoc/maxsoc schreiben gar nicht das Problem: es hat nur leider die Wirkung, das die Daten, die im Charge-Modus vorher ins andere Register geschrieben wurden, weiterhin intern gesetzt bleiben.

Kann da nicht auch 100 geschrieben werden?

andig avatar Sep 06 '24 12:09 andig

Was spricht gegen 100? Oder entlädt der dann ins Netz?

Ja, genau! Das gleiche dann bei HOLD, was ja viel schlimmer wäre als gesperrt nicht mit "dem Rest" PV zu laden. Das Register ersetzt jede interne Berechnung der nötigen Leistung (charge/discharge)

iseeberg79 avatar Sep 06 '24 12:09 iseeberg79

Gibts leider nicht :/

Noch nicht? ;-)

iseeberg79 avatar Sep 06 '24 12:09 iseeberg79

Ja, genau! Das gleiche dann bei HOLD, was ja viel schlimmer wäre als gesperrt nicht mit "dem Rest" PV zu laden. Das Register ersetzt jede interne Berechnung der nötigen Leistung (charge/discharge)

Dann versuche ich es nochmal andreas: was steht denn in dem Register, bevor man irgendwie dran rum frickelt? Und was passiert wenn man genau den Wert wiederholt schreibt?

andig avatar Sep 06 '24 13:09 andig

Dann versuche ich es nochmal andreas: was steht denn in dem Register, bevor man irgendwie dran rum frickelt? Und was passiert wenn man genau den Wert wiederholt schreibt?

Es steht kein Wert drin, bzw. initial bei 0. Der Punkt ist das Schreiben in egal welches Register: es verhindert die interne Berechnung der Register, die zuvor per Modbus verändert wurden. Wenn man zusieht ist das einfacher verständlich. Der WR schaltet automatisch zwischen interner und externer Steuerung, in Abhängigkeit vom Timer der Modbus-Regelung.

Darum braucht es auch den Watchdog in Kombination mit dem Reset für den Modus NORMAL.

iseeberg79 avatar Sep 06 '24 14:09 iseeberg79

es verhindert die interne Berechnung der Register

Wenn Modbus geschrieben wurde hat das Prio, innerhalb der erlaubten Grenzen des WR und vor den internen Berechnungen

iseeberg79 avatar Sep 06 '24 14:09 iseeberg79

Dann bleibt ja am Ende nur die Variante mit:

  • timeout des Watchdogs (sieht doof aus, nicht weiter schlimm)
  • Verschwendung des PV Überschusses im hold Modus

Obwohl...

Hold: leider ist das minsoc/maxsoc schreiben gar nicht das Problem: es hat nur leider die Wirkung, das die Daten, die im Charge-Modus vorher ins andere Register geschrieben wurden, weiterhin intern gesetzt bleiben.

Dann fällt mir noch was ein. Wie wäre es, wenn reset mehrere Werte erlauben würde? Dann könnte man minsoc für hold nutzen und dabei auch gleich den WDT deaktivieren?

andig avatar Sep 06 '24 14:09 andig

Dann fällt mir noch was ein. Wie wäre es, wenn reset mehrere Werte erlauben würde? Dann könnte man minsoc für hold nutzen und dabei auch gleich den WDT deaktivieren?

Darüber hab ich auch schon nachgedacht: es würde dann umgekehrt der Wert für minsoc oder Entladeleistungbegrenzung fehlen: denn der muss ja regelmäßig geschrieben werden. Oder übersehe ich etwas?

Ein einmaliger Modbus-Befehl beim Wechsel des Batteriemodus wäre vielleicht auch hilfreich (bin mir nicht mehr sicher). Dann könnte man einmalig Werte zurücksetzen. Birgt aber leider auch ein Risiko, falls dieses nicht erfolgreich übertragen würde... Das sauber zu implementieren, ich weiss nicht..

Ich sehe aktuell nur die Variante mit der PV Verschwendung bei HOLD - oder eben keine Netzladung...

iseeberg79 avatar Sep 06 '24 14:09 iseeberg79

Dann könnte man minsoc für hold nutzen und dabei auch gleich den WDT deaktivieren?

Ich würde das nachher mal ausprobieren (mit dem Wert 2 für reset).... vielleicht geht da ja doch was

iseeberg79 avatar Sep 06 '24 14:09 iseeberg79

Darüber hab ich auch schon nachgedacht: es würde dann umgekehrt der Wert für minsoc oder Entladeleistungbegrenzung fehlen: denn der muss ja regelmäßig geschrieben werden. Oder übersehe ich etwas?

Du brauchst min und max, bei "normal" muss ja wieder auf min zurück gestellt werden.

Siehe https://github.com/evcc-io/evcc/pull/15927

andig avatar Sep 06 '24 14:09 andig

Ich sehe aktuell nur die Variante mit der PV Verschwendung bei HOLD - oder eben keine Netzladung...

Das haben wir ja auch so bei anderen WR implementiert. Würde diese Variante im Zweifelsfall immer vor den meist auch noch persistenten SoC-Spielereien, die man auch wieder richtig(?) zurückschreiben muss immer bevorzugen. Der Verlust der Batterieladung im Hold-Modus ist eher vernachlässigbar.

premultiply avatar Sep 06 '24 23:09 premultiply

Danke für dein Feedback. Ich brech' mir die Finger, das anders hinzubekommen, aber es klappt einfach nicht vernünftig.

@andig folgende Zusammenfassung:

  • die angepasste reset-Funktion hilft hier leider nicht; im HOLD muss der Wert regelmäßig neu gesetzt werden, sonst fällt er auf den Wert der internen Steuerung zurück. Das Register minSoC wird selbstständig mit dem internen Wert des WR ersetzt, nachdem keine Modbusnachrichten mehr kommen: damit ist er dann zu niedrig (bei mir 5%).

  • was funktionieren würde, ist ein "on-Exit" Mechanismus. Ich hab mal per Javascript den Wechsel des Batteriemodus in einer Variablen innerhalb des Watchdog verfolgt und beim Wechsel von CHARGE->HOLD eine Wartezeit eingebaut, bevor dann über die Sequenz nach Ablauf des Modbus-Timeouts ein neues Register z.B. für die Entladesteuerung oder den minsoc geschrieben wird. Das klappt auch; ist aber absolut unschön.. das müsste wenn, anderswo implementiert sein.

Ich würde also gerne auf die Implementierung für das Ladeleistungsregister (1028 oder 1036) zurückfallen. Es ist die Frage zu klären, ob der Wechsel der Implementierungslogik (limitsoc/batterymode) gewünscht ist, oder ob nur die batterymode-Registersteuerung des initialen PR angewandt werden soll.

Ich bevorzuge die erste und einfachste Implementierung, also nur Register 1028. Mit dem dann NORMAL/HOLD/CHARGE möglich sind. Den Fehler aus den Tests würde ich in einem neuen Commit beseitigen...

iseeberg79 avatar Sep 06 '24 23:09 iseeberg79

Für Hold einfach nur 1040 (Battery max. discharge power limit, absolute) wie beim SMA SBS auf 0 setzen? Wird das auch vom Watchdog geschützt? Sprich ohne ständige Änderung resettet sich der WR wieder auf interne Steuerung?

grafik

Der Watchdog-Timeout im WR sollte recht niedrig eingestellt werden (10s ?), der zugehörige Template-Parameter hier entsprechend um eine zügige Rückkehr in den Normalbetrieb zu ermöglichen.

premultiply avatar Sep 07 '24 00:09 premultiply

Genau so hätte ich es auch gemacht...

deadrabbit87 avatar Sep 07 '24 05:09 deadrabbit87

Für Hold einfach nur 1040 (Battery max. discharge power limit, absolute) wie beim SMA SBS auf 0 setzen? Wird das auch vom Watchdog geschützt? Sprich ohne ständige Änderung resettet sich der WR wieder auf interne Steuerung?

Das hat zwar von der Idee die richtige Wirkung, wird aber dadurch unmöglich, dass der Watchdog des WR nicht einzelne Register schützt, sondern alle Modbus (write)-Register. Bedeutet leider, der Ladewert aus dem CHARGE bleibt auch aktiv (-100) und lädt ständig aus dem Netz/PV weiter: solange irgendein Register beschrieben wird. Ich hatte das vorher getestet, und nur Register 1028 liefert konsistente Zustände.

iseeberg79 avatar Sep 07 '24 08:09 iseeberg79

Der Watchdog-Timeout im WR sollte recht niedrig eingestellt werden (10s ?), der zugehörige Template-Parameter hier entsprechend um eine zügige Rückkehr in den Normalbetrieb zu ermöglichen

Das ist eine gute Idee. Bei der Steuerung hab ich aber bemerkt, dass die Batterieleistung träge von Ladung/Entladung wechselt. Ich glaube, es ist nicht sehr wirksam den Timer zu reduzieren, aber das kann per Parameter der Anwender entscheiden: 30s klingt interessant, probiere ich mal aus

iseeberg79 avatar Sep 07 '24 08:09 iseeberg79

Das ist völlig irrelevant. Er muss kleiner sein als der WR erwartet, alles andere hängt am WR.

andig avatar Sep 07 '24 08:09 andig

Das ist völlig irrelevant. Er muss kleiner sein als der WR erwartet, alles andere hängt am WR.

Ja, dafür welches Register ist es irrelevant und führt in der Fragestellung am Ergebnis der Netzladung vorbei. Natürlich wäre der Timeout am WR entsprechend auch zu verringern. Ich finde das Timing ist zu vernachlässigen.

In der Fragestellung sollten wir uns auf den Punkt konzentrieren, welche Register beschrieben werden, und welche Nebenwirkungen tolerierbar sind: unkontrollierten Weiterbezug aus dem Netz zu vermeiden, hat Priorität vor der Verschwendung von PV Energie im HOLD Modus.

iseeberg79 avatar Sep 07 '24 08:09 iseeberg79