NEWS
Zendure zenSDK Lokal API, SmartMode, SolarFlow AC 800 Pro 2
-
Blockly - Einfache DPL Regelung (Nulleinspeisung & AC-Laden) für Einsteiger in Verbindung mit dem Steuerungs-Script dieses Threads
Dazu wird der dp auto_in_out_Limit verwendet.
Dieses Blockly bietet eine einfache und robuste DPL-Regelung mit integriertem Batterie-Entladeschutz, die vorhandenen PV-Überschuss intelligent zum Laden der Batterien verwendet.
-
Keine blockierenden Timer oder Timeouts:
Die zeitliche Entprellung (Regeltakt) wird rein ressourcenschonend über den Vergleich der Systemzeit gelöst. -
Hardware-Schonung:
Integrierte Hysterese (30W voreingetellt in Variable, leicht anpassbar) sowie feste Rundungsschritte (10W beim Entladen / 50W beim AC-Laden) verhindern Zappeln der Leistungselektronik und minimieren den Bus-Traffic. -
BMS- & PV-Priorisierung:
reine Geräteleistungen werden mit dem Zähler verrechnet, sodass das System auch bei BMS-Abregelung (SoC > 95%) stabil bleibt.
Das Blockly ist im Inneren ausführlich kommentiert, weshalb ich mir eine lange Erklärung erspare.
Wichtige Hinweise zum Setup:
-
Konfiguration:
Alle Variablen im Konfigurations-Bereich (oberhalb des Triggers) dürfen NUR als positive Werte eingetragen werden!
Die Vorzeichen-Umkehrung übernimmt das Skript automatisch. -
Trigger-Wert:
Der Trigger erwartet positive Werte als Bezug und negative Werte als Einspeisung.
Sollte auf ein json getriggert werden, muss das json in ein Objekt übergeben werden.
Ein Beispiel dazu (für z.B. einen Shelly Pro 3EM) ist HIER -
Erweiterter Entladeschutz:
sollte lieber auf Basis von echten Messwerten erfolgen.
Dazu empfehle ich das Blockly von HIER
Es kann einfach per Import angepasst und integriert werden.
edit/Nachtrag Hinweis:
Verhalten in der Dämmerung (Tote Zone):
Wundert euch nicht, wenn das LOG beim Übergang vom Tag zur Nacht (Überschuss zwischen 0W und -120W) einige Zeit still bleibt und nichts loggt.
Das ist gewollt!
In diesem Bereich berechnet das Skript im Hintergrund ein Limit von 0.
Sobald es richtig dunkel wird und/oder euer Haus echten Netzbezug anfordert, wirft das Script die positiven Logs für die Entladung.
Die "debug output"-Blöcke sind ohnehin nur zum ersten Testen und können/sollten von euch im Live-Betrieb gelöscht werden.Bitte Urheber im Skript beachten. Viel Spaß damit!






Im nächsten post folgt der Blockly-Code.
Blockly von Post
Das Blockly musste als Datei hinzugefügt werden, weil es zu groß ist
Datei: zenSDK_DPL_BLOCKLY.zip enthält nur zenSDK_DPL_BLOCKLY.xml
- Datei herunterladen und Virenscan.
- zenSDK_DPL_BLOCKLY.zip entpacken
- in iobroker neues, leeres Blockly erstellen
- zenSDK_DPL_BLOCKLY.xml
importieren:


Bitte den Urheber im Skript beachten.
Falls es Dir hilft oder Du Dich bedanken möchtest: Ein positives Voting als Dankeschön ist völlig ausreichend :-)
download:
zenSDK_DPL_BLOCKLY.zip
edit/ps:
so sieht es aus, wenn Batterie-Entladeschutz auf Messwerten basierend aus post nachträglich intergriert wurde:

-
-
Blockly von Post
Das Blockly musste als Datei hinzugefügt werden, weil es zu groß ist
Datei: zenSDK_DPL_BLOCKLY.zip enthält nur zenSDK_DPL_BLOCKLY.xml
- Datei herunterladen und Virenscan.
- zenSDK_DPL_BLOCKLY.zip entpacken
- in iobroker neues, leeres Blockly erstellen
- zenSDK_DPL_BLOCKLY.xml
importieren:


Bitte den Urheber im Skript beachten.
Falls es Dir hilft oder Du Dich bedanken möchtest: Ein positives Voting als Dankeschön ist völlig ausreichend :-)
download:
zenSDK_DPL_BLOCKLY.zip
edit/ps:
so sieht es aus, wenn Batterie-Entladeschutz auf Messwerten basierend aus post nachträglich intergriert wurde:

@maxclaudi Wow, da hast du ja ordentlich was erstellt - danke fürs Teilen

Mir ist da etwas bezüglich smartMode aufgefallen.
Am Wochenende wollte ich meinen IR Lesekopf etwas nachjustieren, da ist plötzlich das komplette Gehäuse zerbröselt und er damit unbenutzbar geworden.
Ich also zum Baumarkt und habe mir als schnellen Ersatz nen EcoTracker besorgt. Da ich ein neugieriger Mensch bin habe ich ihn natürlich in der Zendure App gekoppelt und den Speicher im Eigenverbrauchsmodus laufen lassen.Dabei habe ich folgendes beobachtet: Speicher und Tracker kommunizieren nach der Kopplung (via Cloud) lokal und die Regelung funktioniert gut und sehr schnell. Allerdings wechselt der Wert von smartMode je nach dem was gerade für ein acMode aktiv ist. Bei acMode 1 (laden) springt der smartMode auf 0 und umgekehrt. Gerade morgens und abends geschieht das natürlich ständig im Wechsel.
Es läuft nebenher kein weiteres Skript, auch deins nicht, ich frage die Werte nur per http get vom Speicher ab.Wenn das wirklich so designt ist, wird bei smartMode=0 wirklich alles in den Flash geschrieben? Immerhin wechselt inputLimit am Tage ständig in kurzen Intervallen.
Da Zendure 10 Jahre Garantie auf die Geräte gibt, sollten sie das doch so konstruiert haben, dass der Flash bei der internen Steuerung diese Zeit überlebt.Das wollte ich nur mal so berichten, jetzt gucke ich mir dein Skript an - ganz schön viel Stoff für einen alten Mann

-
@maxclaudi Wow, da hast du ja ordentlich was erstellt - danke fürs Teilen

Mir ist da etwas bezüglich smartMode aufgefallen.
Am Wochenende wollte ich meinen IR Lesekopf etwas nachjustieren, da ist plötzlich das komplette Gehäuse zerbröselt und er damit unbenutzbar geworden.
Ich also zum Baumarkt und habe mir als schnellen Ersatz nen EcoTracker besorgt. Da ich ein neugieriger Mensch bin habe ich ihn natürlich in der Zendure App gekoppelt und den Speicher im Eigenverbrauchsmodus laufen lassen.Dabei habe ich folgendes beobachtet: Speicher und Tracker kommunizieren nach der Kopplung (via Cloud) lokal und die Regelung funktioniert gut und sehr schnell. Allerdings wechselt der Wert von smartMode je nach dem was gerade für ein acMode aktiv ist. Bei acMode 1 (laden) springt der smartMode auf 0 und umgekehrt. Gerade morgens und abends geschieht das natürlich ständig im Wechsel.
Es läuft nebenher kein weiteres Skript, auch deins nicht, ich frage die Werte nur per http get vom Speicher ab.Wenn das wirklich so designt ist, wird bei smartMode=0 wirklich alles in den Flash geschrieben? Immerhin wechselt inputLimit am Tage ständig in kurzen Intervallen.
Da Zendure 10 Jahre Garantie auf die Geräte gibt, sollten sie das doch so konstruiert haben, dass der Flash bei der internen Steuerung diese Zeit überlebt.Das wollte ich nur mal so berichten, jetzt gucke ich mir dein Skript an - ganz schön viel Stoff für einen alten Mann

Hallo @Jockel_Bln,
zu deiner Sorge bezüglich des Flash-Speichers:
Jeder moderne Hersteller setzt bei Steuerungsgeräten heute auf Flash-Komponenten mit sogenanntem Wear-Leveling.
Dieses Verfahren sorgt dafür, dass Schreibvorgänge gleichmäßig über den gesamten Speicher (Blöcke) verteilt werden, um die Lebensdauer der Zellen drastisch zu erhöhen.Wenn Zendure hier die üblichen Industriestandards nutzt, sollte die Lebensdauer für den "normalen" Betrieb ausreichend ausgelegt sein.
Allerdings altern Flash-Speicher bei übermäßig vielen Schreibzyklen unweigerlich.
Wenn Speicherbereiche degradieren, zeigt sich das meistens nicht durch einen Totalausfall, sondern durch sporadische, schwer zu diagnostizierende Fehler im System.Meine goldene Regel für Skripte:
Man sollte es trotz Wear-Leveling einfach nicht übertreiben.Genau aus diesem Grund nutzt mein Beispiel-Blockly die Hysterese und eine Zeitsperre.
Alle wichtigen Werte dafür sind in den Variablen auf die eigenen Bedürfnisse und das eigene Setup einstellbar.Werte sollten niemals im Sekunden- oder Minutentakt unfiltriert oder in Dauerschleifen zum Zendure-System gesendet werden.
Solange man das beachtet und dem System "Ruhepausen" gönnt, ist man – denke ich – auf der sicheren Seite.Viel Spaß beim Einlesen in das Skript – nimm Dir ruhig Zeit, es läuft Dir nicht weg! :-)
-
Hallo @Jockel_Bln,
zu deiner Sorge bezüglich des Flash-Speichers:
Jeder moderne Hersteller setzt bei Steuerungsgeräten heute auf Flash-Komponenten mit sogenanntem Wear-Leveling.
Dieses Verfahren sorgt dafür, dass Schreibvorgänge gleichmäßig über den gesamten Speicher (Blöcke) verteilt werden, um die Lebensdauer der Zellen drastisch zu erhöhen.Wenn Zendure hier die üblichen Industriestandards nutzt, sollte die Lebensdauer für den "normalen" Betrieb ausreichend ausgelegt sein.
Allerdings altern Flash-Speicher bei übermäßig vielen Schreibzyklen unweigerlich.
Wenn Speicherbereiche degradieren, zeigt sich das meistens nicht durch einen Totalausfall, sondern durch sporadische, schwer zu diagnostizierende Fehler im System.Meine goldene Regel für Skripte:
Man sollte es trotz Wear-Leveling einfach nicht übertreiben.Genau aus diesem Grund nutzt mein Beispiel-Blockly die Hysterese und eine Zeitsperre.
Alle wichtigen Werte dafür sind in den Variablen auf die eigenen Bedürfnisse und das eigene Setup einstellbar.Werte sollten niemals im Sekunden- oder Minutentakt unfiltriert oder in Dauerschleifen zum Zendure-System gesendet werden.
Solange man das beachtet und dem System "Ruhepausen" gönnt, ist man – denke ich – auf der sicheren Seite.Viel Spaß beim Einlesen in das Skript – nimm Dir ruhig Zeit, es läuft Dir nicht weg! :-)
Werte sollten niemals im Sekunden- oder Minutentakt unfiltriert oder in Dauerschleifen zum Zendure-System gesendet werden.
Solange man das beachtet und dem System "Ruhepausen" gönnt, ist man – denke ich – auf der sicheren Seite.Das sehe ich ganz genau so und das lässt sich ja per externer Regelung so umsetzen.
Um so mehr wundert es mich, dass es bei der internen Regelung eben nicht so läuft. Entweder läuft da etwas anders als von extern, oder sie fahren werkseitig auf Verschleiß
-
Werte sollten niemals im Sekunden- oder Minutentakt unfiltriert oder in Dauerschleifen zum Zendure-System gesendet werden.
Solange man das beachtet und dem System "Ruhepausen" gönnt, ist man – denke ich – auf der sicheren Seite.Das sehe ich ganz genau so und das lässt sich ja per externer Regelung so umsetzen.
Um so mehr wundert es mich, dass es bei der internen Regelung eben nicht so läuft. Entweder läuft da etwas anders als von extern, oder sie fahren werkseitig auf Verschleiß
@Jockel_Bln,
es kommt vermutlich ganz darauf an, wie lange man ein System heute überhaupt noch nutzen möchte.Ich lese in den Foren immer wieder von Amortisierung in X Jahren.
Die Leute kaufen ein Gerät und erwarten voller Vorfreude ein System, das sich nach kürzester Zeit bezahlt gemacht haben soll.
Dabei werden dann Zeiträume von mehreren Jahren oft als „kurze Zeit“ abgetan.Am Anfang ist man dann mehr oder weniger zufrieden.
Doch nach einigen Monaten oder ein, zwei Jahren ist das System zwar noch lange nicht amortisiert, aber es gibt bereits neuere, bessere Geräte mit noch mehr Software-Features.
Die älteren Generationen profitieren davon meist gar nicht oder nur bedingt.Ich habe – nicht nur im näheren Bekanntenkreis – beobachtet, dass viele Nutzer dann vom „Mehr-haben-wollen“-Fieber gepackt werden, ähnlich einem kleinen Goldrausch.
Vorbei sind die anfänglichen Berechnungen und das geduldige Abwarten der Amortisation.
Das eigene, eigentlich tadellos funktionierende System wird plötzlich als „altes Eisen“ degradiert.Kurzerhand wird ein Gerät, das zuvor einige hundert Euro gekostet hat, durch ein neues Modell ersetzt – das nach nicht einmal zwei Jahren Betrieb.
Ich nehme mich da selbst ehrlich gesagt gar nicht mal aus.Und bis zu diesem Zeitpunkt hält ein FLASH-Speicher wahrscheinlich immer locker durch.
Edit/PS: Beim krampfhaften Hinterherjagen nach jedem einzelnen Watt sollte man immer bedenken: Was kostet eine gesparte kWh – selbst bei einem angenommenen Preis von 1 Euro – im Verhältnis zu einem durchgedrehten Gerät mit defektem FLASH-Speicher?
-
Ich habe testweise in der config das API Skriptes mal "const maxOutputLimit = 2400" eingestellt, trotzdem lässt sich der Datenpunkt control.inverseMaxPower auf max 800 stellen. Wie kommt das?
In der App kann ich die max Ausgangsleistung auf 2400 stellen, das ist dann auch unter properties.inverseMaxPower zu sehen. -
Ich habe testweise in der config das API Skriptes mal "const maxOutputLimit = 2400" eingestellt, trotzdem lässt sich der Datenpunkt control.inverseMaxPower auf max 800 stellen. Wie kommt das?
In der App kann ich die max Ausgangsleistung auf 2400 stellen, das ist dann auch unter properties.inverseMaxPower zu sehen.@Jockel_Bln sagte:
Ich habe testweise in der config das API Skriptes mal "const maxOutputLimit = 2400" eingestellt, trotzdem lässt sich der Datenpunkt control.inverseMaxPower auf max 800 stellen. Wie kommt das?maxOutputLimit und control.inverseMaxPower sollten aus meiner Sicht denselben maximalen Leistungswert haben und sind im Script auch so vorgesehen.
maxOutputLimit = 2400verhindert jedoch nicht, dass Du den Datenpunktcontrol.inverseMaxPowerspäter auf 800 W setzt. Der Datenpunkt schreibt die Einstellung direkt ins Gerät – genau wie die Zendure-App. Die Script-Konfiguration wird dadurch nicht verändert.Deshalb ist es ganz normal, dass Du
control.inverseMaxPowerauf 800 W einstellen kannst, obwohlmaxOutputLimitim Script auf 2400 W steht.Meine Empfehlung ist,
inverseMaxPowerniemals dynamisch zu verändern. Das Script ist bewusst so aufgebaut, dassmaxOutputLimitundinverseMaxPowerdenselben maximalen Leistungswert repräsentieren.Wenn Du
inverseMaxPowerdauerhaft ändern möchtest, solltest Du deshalb auchmaxOutputLimitin der Script-Konfiguration auf denselben Wert anpassen. Nur so stimmen Script-Konfiguration und Gerätekonfiguration weiterhin überein.Die eigentliche Leistungsregelung sollte anschließend ausschließlich über
outputLimiterfolgen.inverseMaxPowersehe ich als feste Obergrenze des Wechselrichters und nicht als Regelparameter.Der Hintergrund ist auch, dass Zendure
inverseMaxPowerselbst als maximale Geräteleistung behandelt.
In der App ist eine Erhöhung über die Standardleistung hinaus nur nach entsprechender Bestätigung möglich; für noch höhere Leistungen sind sogar weitere Nachweise erforderlich.
Deshalb habe ich das Script bewusst auf diese Verwendung ausgelegt. -
@Jockel_Bln sagte:
Ich habe testweise in der config das API Skriptes mal "const maxOutputLimit = 2400" eingestellt, trotzdem lässt sich der Datenpunkt control.inverseMaxPower auf max 800 stellen. Wie kommt das?maxOutputLimit und control.inverseMaxPower sollten aus meiner Sicht denselben maximalen Leistungswert haben und sind im Script auch so vorgesehen.
maxOutputLimit = 2400verhindert jedoch nicht, dass Du den Datenpunktcontrol.inverseMaxPowerspäter auf 800 W setzt. Der Datenpunkt schreibt die Einstellung direkt ins Gerät – genau wie die Zendure-App. Die Script-Konfiguration wird dadurch nicht verändert.Deshalb ist es ganz normal, dass Du
control.inverseMaxPowerauf 800 W einstellen kannst, obwohlmaxOutputLimitim Script auf 2400 W steht.Meine Empfehlung ist,
inverseMaxPowerniemals dynamisch zu verändern. Das Script ist bewusst so aufgebaut, dassmaxOutputLimitundinverseMaxPowerdenselben maximalen Leistungswert repräsentieren.Wenn Du
inverseMaxPowerdauerhaft ändern möchtest, solltest Du deshalb auchmaxOutputLimitin der Script-Konfiguration auf denselben Wert anpassen. Nur so stimmen Script-Konfiguration und Gerätekonfiguration weiterhin überein.Die eigentliche Leistungsregelung sollte anschließend ausschließlich über
outputLimiterfolgen.inverseMaxPowersehe ich als feste Obergrenze des Wechselrichters und nicht als Regelparameter.Der Hintergrund ist auch, dass Zendure
inverseMaxPowerselbst als maximale Geräteleistung behandelt.
In der App ist eine Erhöhung über die Standardleistung hinaus nur nach entsprechender Bestätigung möglich; für noch höhere Leistungen sind sogar weitere Nachweise erforderlich.
Deshalb habe ich das Script bewusst auf diese Verwendung ausgelegt.Wenn Du inverseMaxPower dauerhaft ändern möchtest, solltest Du deshalb auch maxOutputLimit in der Script-Konfiguration auf denselben Wert anpassen. Nur so stimmen Script-Konfiguration und Gerätekonfiguration weiterhin überein.
Danke für deine ausführliche Antwort, aber kann es sein, dass wir aneinander vorbei reden?
Ich habe ja maxOutputLimit in der Konfiguration geändert, trotzdem steht im Datenpunkt control.inverseMaxPower weiterhin 800 und lässt sich auch nicht größer einstellen.inverseMaxPower sehe ich als feste Obergrenze des Wechselrichters und nicht als Regelparameter.
Das habe ich ja auch so verstanden und wollte sie halt zum Test über 800 setzen.
In der App ging es nach einer Bestätigung durch mich. Im Automatikmodus des HEMS regelt er dann auch über die 800 hinaus hoch. -
Wenn Du inverseMaxPower dauerhaft ändern möchtest, solltest Du deshalb auch maxOutputLimit in der Script-Konfiguration auf denselben Wert anpassen. Nur so stimmen Script-Konfiguration und Gerätekonfiguration weiterhin überein.
Danke für deine ausführliche Antwort, aber kann es sein, dass wir aneinander vorbei reden?
Ich habe ja maxOutputLimit in der Konfiguration geändert, trotzdem steht im Datenpunkt control.inverseMaxPower weiterhin 800 und lässt sich auch nicht größer einstellen.inverseMaxPower sehe ich als feste Obergrenze des Wechselrichters und nicht als Regelparameter.
Das habe ich ja auch so verstanden und wollte sie halt zum Test über 800 setzen.
In der App ging es nach einer Bestätigung durch mich. Im Automatikmodus des HEMS regelt er dann auch über die 800 hinaus hoch.@jockel_bln
ach ja :-)- Stoppe das Script.
- setze: const maxOutputLimit = 2400;
- Script speichern
- Komplettes Verzeichnis "0_userdata.0.zendure.xxxxx" löschen.
- Script neu starten.
Es sollte auch reichen, wenn bei gestoppten Script - vor Neustart - nur der Datenpunkt gelöscht wird: 0_userdata.0.zendure.xxxxx.control.inverseMaxPower
-
Das war es

Hey! Du scheinst an dieser Unterhaltung interessiert zu sein, hast aber noch kein Konto.
Hast du es satt, bei jedem Besuch durch die gleichen Beiträge zu scrollen? Wenn du dich für ein Konto anmeldest, kommst du immer genau dorthin zurück, wo du zuvor warst, und kannst dich über neue Antworten benachrichtigen lassen (entweder per E-Mail oder Push-Benachrichtigung). Du kannst auch Lesezeichen speichern und Beiträge positiv bewerten, um anderen Community-Mitgliedern deine Wertschätzung zu zeigen.
Mit deinem Input könnte dieser Beitrag noch besser werden 💗
Registrieren Anmelden