Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kostal Plenticore: add battery control #15709

Merged

Conversation

iseeberg79
Copy link
Contributor

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 iseeberg79 marked this pull request as ready for review August 26, 2024 18:11
@stna1981
Copy link

stna1981 commented Aug 26, 2024

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?

@iseeberg79
Copy link
Contributor Author

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?

@StevieC121176
Copy link

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.

@andig andig changed the title implemented batterymode functions for grid charging for the "Kostal Plenticore"-template Kostal Plenticore: add grid charging Aug 27, 2024
@andig andig self-assigned this Aug 27, 2024
@andig andig added enhancement New feature or request devices Specific device support labels Aug 27, 2024
@andig
Copy link
Member

andig commented Sep 2, 2024

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 andig self-requested a review September 2, 2024 15:36
Copy link
Member

@andig andig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove min/max soc

@deadrabbit87
Copy link
Contributor

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

@andig andig removed their assignment Sep 5, 2024
@andig
Copy link
Member

andig commented Sep 5, 2024

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
Copy link
Member

andig commented Sep 5, 2024

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

@deadrabbit87
Copy link
Contributor

deadrabbit87 commented Sep 5, 2024

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.

@iseeberg79
Copy link
Contributor Author

iseeberg79 commented Sep 5, 2024

@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
Copy link
Contributor Author

iseeberg79 commented Sep 6, 2024

@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.

@andig
Copy link
Member

andig commented Sep 6, 2024

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 ;)

@iseeberg79
Copy link
Contributor Author

iseeberg79 commented Sep 6, 2024

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.

@andig
Copy link
Member

andig commented Sep 6, 2024

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
Copy link
Member

andig commented Sep 6, 2024

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 #15927

@premultiply
Copy link
Member

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.

@iseeberg79
Copy link
Contributor Author

iseeberg79 commented Sep 6, 2024

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...

@premultiply
Copy link
Member

premultiply commented Sep 7, 2024

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 premultiply changed the title Kostal Plenticore: add grid charging Kostal Plenticore: add battery control Sep 7, 2024
@deadrabbit87
Copy link
Contributor

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

@iseeberg79
Copy link
Contributor Author

iseeberg79 commented Sep 7, 2024

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
Copy link
Contributor Author

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

@andig
Copy link
Member

andig commented Sep 7, 2024

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

@iseeberg79
Copy link
Contributor Author

iseeberg79 commented Sep 7, 2024

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.

@andig
Copy link
Member

andig commented Sep 7, 2024

@premultiply warum die Änderung des Timeouts?

@premultiply
Copy link
Member

Man sollte die Leute hier motivieren kürzere Werte zu wählen damit der WR auch nochmal zeitnah seinen Normalbetrieb fortsetzt.

10s ?

Völlig egal, sollte halt nicht zu lang sein.
Eine Minute erschien mir dann doch sehr viel.

Aber ich hänge da wirklich nicht dran.

@andig
Copy link
Member

andig commented Sep 7, 2024

Man sollte die Leute hier motivieren kürzere Werte zu wählen damit der WR auch nochmal zeitnah seinen Normalbetrieb fortsetzt.

Warum? Je kürzer der Timeout, desto höher die Wahrscheinlichkeit, dass am Ende der Updatephase einer gesetzt wird. Das führt dazu, dass der WR eher noch später seinen Normalbetrieb aufnimmt nachdem dann sein Timeout abläuft.

Ich halte es generell für sinnvoll, Änderungen gezielt zu machen. Mit dem Timeout gab es hier kein Problem.

@andig andig merged commit 92abe21 into evcc-io:master Sep 7, 2024
6 checks passed
@premultiply
Copy link
Member

Je kürzer der Timeout, desto höher die Wahrscheinlichkeit, dass am Ende der Updatephase einer gesetzt wird.

Das bezog sich natürlich meinerseits auf die Timeout-Zeit in der WR-Konfig.

Bleibt hier der Standardwert konfiguriert dauert es halt entsprechend "ewig" bis der Normalbetrieb wieder einsetzt.

@andig
Copy link
Member

andig commented Sep 7, 2024

Genau. Und wenn man daran etwas ändern will gehört es in die Doku oder ins Template. Ist hier aber OT.

@iseeberg79 iseeberg79 deleted the fix-template-plenticore-batterymode branch September 7, 2024 17:21
@andig
Copy link
Member

andig commented Sep 8, 2024

Hier haben wir nicht aufgepasst. Minsoc/Maxsoc hätten deprecated gesetzt werden müssen statt zu löschen. Vmtl. Ursache von #15971.

@iseeberg79
Copy link
Contributor Author

Danke für deine Korrektur!

@ulfinho
Copy link

ulfinho commented Sep 8, 2024

Hier haben wir nicht aufgepasst. Minsoc/Maxsoc hätten deprecated gesetzt werden müssen statt zu löschen. Vmtl. Ursache von #15971.

Danke für deine Korrektur!

Ist das schon korrigiert?

@iseeberg79
Copy link
Contributor Author

m.E. commit 7bd213f

@ulfinho

This comment was marked as off-topic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
devices Specific device support enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants