Zendure Solarflow in Fhem via MQTT einbinden

Begonnen von Reinhart, 15 Februar 2024, 17:29:53

Vorheriges Thema - Nächstes Thema

Reinhart

Ich habe vor wenigen Tagen meinen Zendure Solarflow Akkuspeicher bekommen und mir einmal die Sache mit dem externen MQTT Server von Zendure angesehen.
In den letzten 2-3 Tagen habe ich dazu etwas näher befasst und teilweise mit Try und Error mich an die richtige Vorgangsweise heran getastet, aber diese Definition erschien mir am einfachsten.

Damit man hier an die erforderlichen Readings des "Zendure Broker" ran kommt, sind folgende Daten zur Abfrage in der Clientdefinition notwendig:
appkey = Username
secret = Password
clientID = Seriennummer Hub
subscriptions = topic/#


Topic = Username

wie man ganz schnell an die Keys kommt ist hier beschrieben. Voraussetzung natürlich das ihr bereits die App von Zendure eingerichtet habt. 

Also App auf "Global" stellen und unter Windows (Cmd) folgenden Befehl absetzen.
curl -i -v --json "{'snNumber': 'EureHubSeriennummer', 'account': 'EureEmailadresse'}" https://app.zendure.tech/v2/developer/api/apply

Nachdem ihr die Keys erhalten habt, empfiehlt es sich einen MQTT-Explorer (Windows) zu installieren (obiger Link) und man kann die gewonnen Zugangsdaten sofort überprüfen und seht auch gleich Readings die da ankommen.
Nun steht nichts mehr im Wege und es kann ein MQTT2-Client nach folgendem Muster angelegt werden. Ersetzt die beiden Platzhalter <appKey> und <Ser.Nr.Hub>
mit euren Daten. Anschließend bitte mit "set ZendureCloud password" (links oben in der Befehlszeile) den "secret" eingeben (nicht eurer Password das ihr in der App angelegt habt).


MQTT2 Client definieren

define ZendureCloud MQTT2_CLIENT mqtt.zen-iot.com:1883
attr ZendureCloud autocreate complex
attr ZendureCloud clientId <Ser.Nr.Hub>
attr ZendureCloud rawEvents .*
attr ZendureCloud room zendure
attr ZendureCloud username <appKey>
attr ZendureCloud verbose 5

Der Client sollte nun unter STATE "opened" anzeigen, Wenn nicht, ist irgendwas mit den Zugangsdaten falsch gelaufen.
Wurde der MQTT2 Client auf "autocreate complex" gestellt sollte innerhalb weniger Sekunden die ersten Readings auftauchen. Wenn keine Änderungen am HUB sind (Abendstunden)
kann das durchaus länger dauern. Einfach dazu parallel im MQTT-Explorer vergleichen.

Wenn alles geklappt hat sollte folgender Define automatisch durch Autocreate angelegt.

define MQTT2_ZendureHub MQTT2_DEVICE <Ser.Nr.Hub>
attr MQTT2_ZendureHub icon mqtt_bridge_2
attr MQTT2_ZendureHub readingList <Ser.Nr.Hub>:<appKey>/<Client Topic>/state:.* { json2nameValue($EVENT) }\
attr MQTT2_ZendureHub room MQTT2_DEVICE,zendure
attr MQTT2_ZendureHub stateFormat Speicher-AB2000: electricLevel

und hier noch die grafische Auswertung einiger Readings so wie ich sie einmal definiert habe.

define Zendure_Akku DOIF ##
attr Zendure_Akku room zendure
attr Zendure_Akku uiTable {package ui_Table}\
cylinder(" ",0,100,"%",100,110,140,0,[MQTT2_ZendureHub:electricLevel],80,undef)|\
card([MQTT2_ZendureHub:electricLevel:col8],"AB2000 1/2","sani_solar\@colorVal1",0,400,180,0,"%",undef,0,180)\
\
card([MQTT2_ZendureHub:solarPower1:col8],"Panel-1/2","sani_solar\@colorVal1",0,400,180,0,"Watt",undef,0,180)|\
card([MQTT2_ZendureHub:solarPower2:col8],"Panel-3","sani_solar\@colorVal1",0,400,180,0,"Watt",undef,0,180)\
\
card([MQTT2_ZendureHub:outputPackPower:col8],"Ausgang Akku","sani_solar\@colorVal1",0,400,180,0,"Watt",undef,0,180)|\
card([MQTT2_ZendureHub:outputHomePower:col8],"Wechselrichter","sani_solar\@colorVal1",0,400,180,0,"Watt",undef,0,180)|\

Viel Erfolg mit dem Solarflow!

edit 08.03: Topic unter subscriptions hinzugefügt.


FHEM auf Raspy4 mit Bullseye + SSD, Homematic, ESP8266, ESP32, Sonoff, eBus, NanoCUL, MapleCUL, , MQTT2, Alexa

Reinhart

ich habe mich nun noch mit dem Schreiben von Werten via MQTT eingelesen, aber so wie es derzeit ausschaut ist die User API von Zendure "readonly". Zendure schreibt ja im Github dies unter Futures Plans.

ZitatSupport data downlink and device control.
.

Eigentlich wollte ich auch die Entnahme des Akkuspeichers selbst über Fhem steuern können, um zB. bei schlechter Sonneneinstrahlung des nächsten Tages (Wettervorschau Proplanta) den Akku nicht ganz zu entleeren. Meine Situation ist ja so, dass ich eine sehr hohe Grundlast habe und der 4Kw Akku ohnehin nicht für die Nacht ausreicht. Ob ich hier nochmals mit Kapazität aufstocken kann muss sich in den nächsten Monaten zeigen ob der Sonnenertrag ausreicht um mehr als 4 Kw am Tag zu laden. Der neue HUB von Zendure sollte das ja können, aber da war ich mit dem Kauf zu schnell. Habe aber jetzt schon zwei Panels über Dioden zusammen geschalten und so insgesamt 3 Panels mit je 415 Watt alleine zum Speichern zur Verfügung.
Zendure ist aber eh sehr zackig und erweitert seine Firmware ständig, also noch etwas warten und dann klappt auch das Senden zu ihrem MQTT Server.

Dafür habe ich heute noch schnell meinen Floorplan um die gewonnen Daten ergänzt.
FHEM auf Raspy4 mit Bullseye + SSD, Homematic, ESP8266, ESP32, Sonoff, eBus, NanoCUL, MapleCUL, , MQTT2, Alexa

mkriegl

Hallo Reinhard,

danke schon mal für die Devines, allerdings habe ich so meine Probleme Informationen zu empfangen. Er connected, aber ich bekomme gar nichts zurück,  obwohl heute die Sonne schien.
In Home Assistant hat es bei mir einwandfrei funktioniert, ich bekomme aber weder in FHEM noch in MQTT Explorer Informationen.

Im Vergleich zu deiner Beschreibung musste ich EU statt V2 abfragen, da es mir einen Fehler liefert.
curl -i -v --json "{'snNumber': 'EureHubSeriennummer', 'account': 'EureEmailadresse'}" https://app.zendure.tech/eu/developer/api/apply
In HASS, MQTT Explorer und FHEM sind Server, Port, username, Passwort alle eins zu ein (plus clientId bei FHEM)
Das einzige was ich mir jetzt noch vorstellen kann ist, das nur ein Gerät verbunden sein kann. Ansonsten kann ich mir es nicht erklären

Gruß .. Max

Reinhart

was ich gelesen habe funktioniert es nur mit "global" Einstellung. Ich habe auch gleich bei der Einrichtung der App auf Global gestellt. Wenn du umstellst, ist die History aber weg!

Hast du denn den App Key mit der EU Einstellung und den Secerect mit "curl" bekommen?
FHEM auf Raspy4 mit Bullseye + SSD, Homematic, ESP8266, ESP32, Sonoff, eBus, NanoCUL, MapleCUL, , MQTT2, Alexa

Fhemotto

Hallo zusammen,
habe heute mein erstes Gerät mit MQTT eingebunden, ohne wirklich zu verstehen was da passiert.
Möchte nur kurz auf mein anfängliches Problem hinweisen.

In dem Link den du oben aufgeführt hast mit der Beschreibung steht unter anderen:

,,Unter Advanced (Button) müsst ihr dann noch euren appKey als Topic abonnieren, also als neue Subscription hinzufügen --> appKey/#."

Somit klappts bei mir auch im MQTT Explorer.

Da in FHEM aber trotz ,,STATE "opened" nichts ankam, habe ich alle möglichen Attribute mir angeschaut und hier das Attribut  ,,subscriptions" gefunden und auf appKey/# gesetzt
und sofort kamen Unmengen an Daten im Logfile sowie wurde auch das neue Device mit autocreate angelegt.

Übrigens habe ich die Abfrage mit  "EU"
curl -i -v --json "{'snNumber': 'EureHubSeriennummer', 'account': 'EureEmailadresse'}" https://app.zendure.tech/eu/developer/api/applygemacht

Eventuell solltest du diesen Hinweis oben mit angeben, damit andere nicht auch darüber stolpern,
wenn nichts ankommt.

Vielen Dank für die Beschreibung.




mkriegl

@Reinhard: Ja, genau, wie auch Fhemotto beschrieben hat
@Fhemotto: danke für den Tipp. Hätte ich doch mal genauer lesen sollen. Jetzt kommen bei mir auch Daten rein.

Meine defines habe ich zwar noch nicht gefunden, aber muss ich heute abend mal in Ruhe schauen. Danke

Reinhart

#6
Danke für den Hinweis, habe euch das in der Beschreibung einfach unterschlagen, habe den bei mir auch gesetzt gehabt.
Aber schön zu wissen, das auch in der Einstellung "EU" alles klappt.
Es gab ja vor wenigen Tagen ein Update, aber schade das noch nix gesendet werden kann.

Übrigens  ich habe für die Wintermonate vorgebaut und mir über einen Y-Adapter und 2 Dioden zur Entkopplung ein Netzteil mit 400 Watt angeschlossen das ich über Tasmota schalten kann. So kann ich bei Bedarf vor einer Tiefentladung nun Einspeisen und so bequem den Akku wieder zwischen 10-20% bringen.

Da ich ja insgesamt 4 Balkonkraftwerke mit je 4 Panele habe und eine Anlage mit drei Panele fix für den Akkubetrieb zum Laden verwende, kann ich nun bei schwachem Sonnenschein auch mit der überschüssigen Energie der 3 anderen Anlagen den Akku laden. Mit dieser Methode bin ich selbst im März ständig auf 80-96%. Bei Sonnenschein ist der 4KW Akku ohnehin schon um 13:00 Uhr voll. Das Netzteil ist regelbar, somit läßt sich die Leistung auch drosseln.
Zuviel Einspeisen kann man ja nicht, da der Solarflow bei mir die Leistung pro Eingang auf etwa 390 Watt begrenzt. siehe Bild2.
FHEM auf Raspy4 mit Bullseye + SSD, Homematic, ESP8266, ESP32, Sonoff, eBus, NanoCUL, MapleCUL, , MQTT2, Alexa

Olaf A

Moin zusammen ich habe das bei mir auch eingestellt und lief bis Sonntag Abend klasse. Seit 23 Uhr kommen jetzt keine Daten mehr habt ihr das auch beobachtet?
FHEM auf CubieTruck:
Max mit Cube, HMLAN; MAX-Thermostaten; Homematic-Komponenten, SIS PM Schalter, JeeLink.

mkriegl

Bei mir kamen seit gestern 17.6. 4h keine Daten mehr rein. Jetzt seit etwa 8h tröpfelt wieder was rein

Olaf A

FHEM auf CubieTruck:
Max mit Cube, HMLAN; MAX-Thermostaten; Homematic-Komponenten, SIS PM Schalter, JeeLink.

Blackcat

Hi,

hier ein Tipp für alle die offline Daten nutzen wollen.
Ich habe meine AIO ganz neu (seit diesem Wochenende) und über BT und folgendem Skript als MQTT Client eingebunden
https://github.com/reinhard-brandstaedter/solarflow-bt-manager

Die Daten kann man super auch loggen und anzeigen.
Aktuell stelle ich die Einspeisung noch manuell im Ahoy ein, soll aber noch automatisch erfolgen.

Eine schöne Fluss Grafik habe ich noch keine, aber da wollte ich mal das SolarForecast Module testen
Viele Grüße Sandra - FHEM Style Entwicklerin iOS6+12
-----
ZBox nano, Homematic, Homebridge, Hue + Mi Light, ZWave, Dyson, etc.
https://www.foodcat.de
https://www.youtube.com/c/FoodCat (hier gibt es auch immer mehr Hausautomatisierungsvideos)

RalfP

Hallo,

vielen Dank für die Informationen. Sie haben mir geholfen auf das MQTT von Zendure zuzugreifen.

Jetzt aber mal eine Frage: Habt ihr das Setzen des OutputLimit schon mal per publish via Zendure Cloud MMQTT hinbekommen? Laut der Daten, klingt es ja danach, das das möglich wäre.

config_command_topic
xxxxxxxx/xxxxxxxx/dcOutputPower/set

config_value_template
{{ value_json.dcOutputPower}}

Vielen Dank
grüße Ralf

RalfP

Hallo,

...also, das geht nicht. MQTT publish ist nicht von Zendure umgesetz, maximal ist es vorbereitet. Sofern hier nichts neues beschrieben wird, wird es nicht funktionieren.

Um trotzdem eine Regelung hinzubekommen, habe ich den Bypass auf immer aus gestellt, Grenzen entsprechend dem Umrichter gesetzt und regele jetzt die Leistungsbegrenzung des Umrichters. Der Zendure reagiert auch darauf und schiebt die überschüssige Energie in den Speicher.

Grüße
Ralf

dombar

Hallo,
Ich weiß nicht ob es nur bei mir so ist aber seit Samstag oder Sonntag wurden keine Werte mehr geliefert.
Es scheint als wenn Zendure den Servernamen geändert hat. Diese Adresse sollte funktionieren: mqtt-eu.zen-iot.com:1883
Gruß
Dominik
1x FB7490, 2x FBDECT200, 1x RPI als Öltankanzeige mit TEK603, 1x Synology NAS, 1xCUL FS20, 2x CCU3, 1xFS20DWT , 1x FS20 DI22-4, 1x FS20IR, 3x FS20ST, 1 x KS300, 3x HM-LC-Sw1PBU-FM, 6x HM-ES-PMSw1-Pl,  Siemens S7 CPU 315 für Stromzähler auf S0 Basis uvm.

mkriegl

Danke. Ich hatte schon länger Probleme mit aktuellen Daten. Unter deinem Link scheint das wesentlich besser zu sein.

Shadow3561

Moin,

ich versuche gerade meinen Hyper2000 ein zu binden.
Es klappt alles nur bekomme ich keine readings.

was muss ich bei
Zitat<Ser.Nr.Hub>:<appKey>/<Client Topic>/state:.* { json2nameValue($EVENT) }

<Client Topic>
einfügen?

Mit freundlichen Grüßen

Shadow3561

#16
Dann antworte ich mir mal selbst und stelle die Lösung hier rein, falls andere das gleiche Problem haben.
als erstes die erforderliche Daten besorgen

in OSX ein Terminal öffnen und folgendes eingeben


curl -H "Content-Type: application/json" -X POST -d '{"snNumber":"<Serial vom Hub oder Inverter>","account": "Username/email von der Zendure App>"}' https://app.zendure.tech/eu/developer/api/applymit Enter bestätigen,

Jetzt solltet ihr folgende Meldung bekommen
{"code":200,"success":true,"data":{"appKey":"xxxxxxxxxx","secret":"xxxxxxxxxxxx","mqttUrl":"mqtt-eu.zen-iot.com","port":1883},"msg":"Successful operation"}%
appKey und secret abspeichern, die benötigen wir noch.




MQTT2 Client definieren


defmod ZendureCloud MQTT2_CLIENT mqtt-eu.zen-iot.com:1883
attr ZendureCloud autocreate complex
attr ZendureCloud clientId <appKey>
attr ZendureCloud rawEvents .*
attr ZendureCloud room Zendure
attr ZendureCloud subscriptions <appKey>/#
attr ZendureCloud username <appKey>

danach ein
set ZendureCloud password <secret>
jetzt noch
set ZendureCloud connect
Nun sollte der state "opened" angezeigt werden.

jetzt ein neues Device anlegen

defmod MQTT2_ZendureHyper2000 MQTT2_DEVICE eCXh0pnS
attr MQTT2_ZendureHyper2000 icon mqtt_bridge_2
attr MQTT2_ZendureHyper2000 readingList <Serial vom Hub oder Inverter>:<appKey>/<appKey>/.* { json2nameValue($EVENT) }
attr MQTT2_ZendureHyper2000 room Zendure

Jetzt abwarten bis die readings erscheinen.

Hier noch ein paar Änderungen für stateFormat und userReading die ich vorgenommen habe.

attr MQTT2_ZendureHyper2000 stateFormat Akkustand: <span style='color:{(ReadingsNum("$name",'state_packData_1_socLevel','')>=50 ? "green":"orange")}'>[$name:state_packData_1_socLevel] %</span> <span style='color:{(ReadingsVal("$name",'Akku-be-endladen','on') eq "entlädt" ? "red":"green")}'>[$name:Akku-be-endladen] </span><br/>\
Akku-Restzeit: <span style='color:{(ReadingsNum("$name",'akku-remaining','')>=50 ? "green":"orange")}'>[$name:akku-remaining] </span><br/>\
PV-in: <span style='color:{(ReadingsNum("$name",'state_solarInputPower','')<=0 ? "red":"green")}'>[$name:state_solarInputPower] W</span>\

attr MQTT2_ZendureHyper2000 userReadings Akku-be-endladen {if(ReadingsVal($NAME,"state_packState","") eq "1") {return "lädt"} elsif (ReadingsVal($NAME,"state_packState","") eq "0") {return "standby"} elsif (ReadingsVal($NAME,"state_packState","") eq "2") {return "entlädt"} else {"prüfen"}},\
akku-remaining {if(ReadingsVal($NAME,"state_remainOutTime","") eq "59940") {return "∞"} elsif (ReadingsVal($NAME,"state_packState","") ne "59940") {return ( strftime('%T', gmtime(ReadingsNum($NAME, "state_remainOutTime", 0))) )}}
attr MQTT2_ZendureHyper2000 verbose 0

Mit freundlichen Grüßen


RalfP

Hallo,

habe mir mal verschiedene Lösungen angeschaut und den ersten Schritt für Fhem umgesetzt - Login und Token für einen MQTT Client

https://github.com/RP-Develop/Zendure

Ist noch nicht perfekt, hilft aber einen MQTT Client so zu konfigurieren, das er im Prinzip die Funktion der Zendure App übernimmt. Läuft seit einigen Tagen, ohne das ich den Token erneuern musste als Mosquitto Bridge. Output setzen funktioniert!

Bin am überlegen, ob ich einen eigenen MQTT Client integriere, um ein Token-Refresh besser hinzubekommen. Liegt aber noch in weiter Ferne. Mal sehen was ihr sagt.

Testen - natürlich auf eigene Gefahr und möglichst erst in einer Testinstanz von Fhem.

Achtung! Wenn jemand Logs oder Konfigurationen posten möchte, bitte Nutzernamen, Passwörter und deviceId's unkenntlich machen. Das Ganze ist ein POC und an mancher Stelle noch nicht ganz sicher.

Grüße Ralf

Shadow3561

#18
Moin,
Weil ich auf eine schnellere Aktualisierung der readings hoffe habe ich es mal probiert und bekomme leider keinen Login hin.

es sieht so aus:
define <name> MQTT2_CLIENT mqtteu.zen-iot.com:1883
set <name> password oK#*********
attr <name> username zenApp
attr <name> clientId *****:*******-***-****-***-*******
attr <name> autocreate no
attr <name> subscriptions

FHEM meckert bei "attr <name> subscriptions" weil kein Eintrag gemacht wird, also habe ich es erst mal weg gelassen.

Jedoch bekomme ich keinen connect hin.
Im Log steht
Connection refused, bad user name or password
Mit freundlichen Grüßen


RalfP

Hallo Shadow,

ja, das liegt daran, das du dich am EU Server in deiner App angemeldet hast. Der hat ein anderes Password. Es gab mal die Aussage, das der EU Server nicht richtig funktioniert, was ich damals auch in meiner App merkte. Darum hatte ich schon frühzeitig auf Global gewechselt. Und wie es so ist, habe ich alles darauf ausgelegt, sorry. Wenn du wechseln würdest, gehen dir alle bisherigen Daten verloren, so meine Kenntnis.

Bitte sei noch etwas geduldig. Habe gerade eine Lösung mit einer Anmeldung im MQTT Client am entwickeln. Ich versuche die unterschiedlichen Server gleich mit zu beachten.

Grüße Ralf

RalfP

Hallo,

hatte einen guten Tipp von Rudi bekommen, wie man das Attr connectFn im MQTT2_CLIENT benutzen kann, um den Client mit einem Login zu versehen. Schaut mal bei https://github.com/RP-Develop/Zendure vorbei.

Theoretisch hab ich alles beschrieben. Bei Fragen bitte melden.

@Shadow: Da ich nicht wieder auf einen EU Server wechseln kann, hätte ich natürlich gern ein Feedback, ob die eine, wie die andere, Variante mit dem EU Server überhaupt arbeitet. Vielen Dank

Interessant wären auch, ob mehr als ein Gerät angelegt wird, wenn jemand >1 Geräte in seiner App hat. Habe selbst nur ein HUB 2000.

Grüße Ralf

Shadow3561

Moin Ralf,
Ich bin auch auf den globalen Server gewechselt. Daher kann ich es mit der EU-Variante nicht probieren.

Dein Modul funktioniert wunderbar und die readings kommen schnell(schneller als bei der Variante ohne Modul) und zuverlässig.

Bei mir erscheint bei einem "get DeviceList" nur der Hyper2000. Der Schelly pro 3EM taucht nicht in der Liste auf.

Danke für deine tolle Arbeit.

Mit freundlichen Grüßen

RalfP

Hallo Shadow,

hört sich gut an, vielen Dank.

Einen Stromzähler Pro 3EM hab ich auch. Den habe ich aber lokal auf meinem Mosquitto MQTT eingebunden. Der sendet in keine Cloud (hätte ich mir für Zendure auch gewünscht). Auch wenn du ihn mit der Cloud verbunden hast und den CT-Mode (glaube so nannte sich das) arbeitest, hätte ich mich gewundert, wenn Zendure die Daten auf ihrem Server präsentiert.

Diese Regelung mache ich lokal bei mir mit Fhem. Hauptsächlich steuere ich derzeit den Umrichter je nach Verbrauch (Daten vom 3EM), um keine Energie ins Netz zu verschenken, sondern in die Batterie zu speichern. Mit den jetzigen Steuermöglichkeiten kann ich dan Ganze bestimmt nochmals optimieren und vor allem den HUB auf meine Einstellungen wieder setzen, wenn er mal aus war.

PS: lass mal hören, wie lange der Token bei dir gültig ist. Einen habe ich schon über eine Woche aktiv. Mir geht es darum, ob man ihn mal refreshen muss.

Grüße Ralf 

Shadow3561

Der Token sollte solange gültig sein bis sich ein anderes Gerät mit dem selben einloggt.
Wie steuerst du den Hyper 2000 mit FHEM?
Das würde mich brennend interessieren da die CT_Mode Steuerung nicht wirklich zuverlässig funktioniert.
Meine PV speist teilweise über Stunden ins Netz ein bevor der Hyper anfängt aus der Steckdose zu laden.
Genauso speist er den Überschüssigen Strom aus den angeschlossenen PV nicht ins Netz ein obwohl der Akku voll ist. Dann geht PV einfach auf 0 obwohl "ins Netz einspeisen" auf zugelassen steht.

Wenn du also deinen Code oder deine DEF zur Steuerung des Hyper bereitstellen würdest wäre ich dir sehr dankbar.

BTW
Was bewirken die Bypass und autoRecover Einstellungen in deinem Modul?

Mit freundlichen Grüßen

RalfP

#24
Hallo Shadow,

Bypass - ist unter den Einstellungen deines HUB in der Zendure App zu finden.

Bypass auto - der HUB regelt es selbst. Er soll erkennen wann die Batterie voll ist und dann alles weitere an Energie an den Umrichter geben. Mein Hoymiles (über AHOYDTU - MQTT angesteuert) hat in dieser Situation komplett auf gemacht und sämtliche Energie ins Netz geliefert. Das Ganze hat sich aber nicht wieder zurückgestellt und hat selbst Batterieenergie ins Netz gespeist. War für mich somit keine Option.
Bypass immer an - Die ganze Energie wird an den Umrichter geliefert.
Bypass immer aus - Wenn die Batterie voll ist und nichts abgenommen wird, werden die Eingänge der Paneele zu gemacht. Diese Funktion nutze ich.

Du darfst diesen Dateianhang nicht ansehen.

Standart ist auto, was sich leider auch nach einem ausgeschalteten HUB wieder setzt.

autoRecover ist der Schalter unter Bypass Schalter, der auf Bypass ein oder aus reagiert und den nächsten Tag den Bypass wieder auf auto schalten würde.

Da ich aber Bypass AUS und den autoRecover auch immer auf AUS haben möchte, hab ich Beides zum Steuern definiert.

Jetzt zu deiner anderen Frage, welche nicht mit wenig Erklärung zu erläutern ist.

Man kann im Allgemeinen dem Umrichter sagen, wieviel Energie er vom HUB abfordern soll oder man setzt den Output des HUB. Beides ist möglich. Wenn nur 100W gefordert werden (Umrichter auf 100W begrenzt oder Output HUB auf 100W gesetzt) aber die PV's 200W gerade liefert, gehen 100W in die Batterie. Bedeutet, wenn dein Haushalt gerade nur 100W verbraucht (ermitteln über Pro 3EM) musst du den Umrichter oder den HUB so einstellen, das er nur 90W oder 80W liefert, um nicht unter 0 zu kommen und etwas verschenkt wird. Der Rest geht automatisch in die Batterie.

Das Ganze habe ich in einem zyklisch ablaufenden Script behandelt. Das wird aller 2min aufgerufen. Dabei wird geprüft, welche Leistung gerade mein Haushalt benötigt. Ich regele nicht genau auf 0, das würde das System evtl. zu schnell machen und zum Überschwingen neigen. Darum lasse ich immer nur feste Schrittweiten zu (30W). Als unterer Grenze habe ich 20W festgelegt. Liege ich im Verbrauch über einem Bereich von 20W + 30W erhöhe ich den Umrichter um 30W, um wieder in Richtung 20W zu kommen. Nach 2min wird wieder nachgeschaut, liege ich immer noch höher, wird die Leistung am Umrichter um weitere 30W erhöht. Das ganze auch wieder anders herum, nur mit doppelter Schrittweite.

Das Ganze hat den Vorteil, das es nicht zu einem übermäßigen Überschwingen ins Negative kommt, wenn Verbraucher (z.B. Wasserkocher) eingeschaltet werden, die nur für kurze Zeit hohe Energie ziehen.

Du darfst diesen Dateianhang nicht ansehen.
Du darfst diesen Dateianhang nicht ansehen. 

Ich kann hier zwar mein Script dazu posten, es wird aber maximal nur als Anregung dienen, da du es nicht 1:1 verwenden kannst.

Derzeit steuere ich meinen Umrichter. Wenn du aber keine Schnittstelle zu deinem Umrichter hast, hättest du jetzt die Möglichkeit mit Zendure Fhem den Output vom HUB zu steuern und damit die Regelung aufzubauen.

...habe es eigentlich gut kommentiert, sonst würde ich selbst nicht mehr wissen, was ich da programmiert hab  ;)


+*00:02:00 {
    # ToDo
    #

    # Verbrauch
    my $total_act_power = ReadingsVal("WG.Energie","total_act_power",0);
   
    # Ausgangsleistung Inverter
    # Wenn Bypass an ist bzw. die Batterie voll und Schaltung auf Bypass auto steht,
    # wird die Limitierung des Inverters übergangen und alles von den Paneelen wird geliefert.
    # ToDo: Limit auf 100% dann...???
    my $P_AC = ReadingsVal("WG.Balkonkraftwerk","P_AC",0);
   
    # Batterie Status
    # 0    standbyBat
    # 1    loadBat (Laden)
    # 2 unloadBat (Enladen)   
    my $packState = ReadingsVal("WG.Balkonkraftwerk.HUB","packState",0);
    my $electricLevel = ReadingsVal("WG.Balkonkraftwerk.HUB","electricLevel",0);
    my $socSet = ReadingsVal("WG.Balkonkraftwerk.HUB","socSet",0) / 10;
    my $inverseMaxPower = ReadingsVal("WG.Balkonkraftwerk.HUB","inverseMaxPower",0);
   
    # Output Limit vom HUB
    my $outputLimit = ReadingsVal("WG.Balkonkraftwerk.HUB","outputLimit",0);
   
    # Reading Inverter available
    # 0    not available and not producing
    # 1    available but not producing
    # 2    available and producing
    # 3    available and was producing
    # 4    was available
    my $available = ReadingsVal("WG.Balkonkraftwerk.Inverter","available",0);

    # aktuelles Limit
    my $limit_act = ReadingsVal("WG.Balkonkraftwerk.Inverter","limit",0);
   
    # Default
    my $default = ReadingsVal("WG.Balkonkraftwerk.control","default",0);
   
    # Control
    my $controlLevel = ReadingsVal("WG.Balkonkraftwerk.control","controlLevel",20);
    my $controlStep = ReadingsVal("WG.Balkonkraftwerk.control","controlStep",50);
    my $controlFirstStart = ReadingsVal("WG.Balkonkraftwerk.control","controlFirstStart",0);
    my $controlBatteryLevel = ReadingsVal("WG.Balkonkraftwerk.control","controlBatteryLevel",20);
    my $controlBatteryLevelReached = ReadingsVal("WG.Balkonkraftwerk.control","controlBatteryLevelReached",20);
   

    # State
    # 0 keine Regelung
    # 1 in Regelung
    # 2 in Regelung, aber Begrenzung auf default, wegen Batterie unter 20%
    # 3 Inverter nicht verfügbar
    # 4 Limit noch nicht verarbeitet, Abbruch
    # 5 Sonderbetrieb weil Batterie voll oder Bypass geschaltet   
    my $controlState = ReadingsVal("WG.Balkonkraftwerk.control","controlState",0);
   
    # Regelung an, wenn Batterie voll ist == 1
    my $controlBatteryFull = ReadingsVal("WG.Balkonkraftwerk.control","controlBatteryFull",0);

    # Überwachung "set limit", derzeit nur Test und Log
    my $controlSetCount = ReadingsVal("WG.Balkonkraftwerk.control","controlSetCount",0);
   
    # Prüfung, ob Bypass auf "immer aus" steht, sonst setzen. Nach Reboot vom Hub ist sonst Automatik eingeschaltet
    my $controlBypass = ReadingsNum("WG.Balkonkraftwerk.control","controlBypass",0);
    my $passMode = ReadingsNum("WG.Balkonkraftwerk.HUB.global","report_properties_passMode",0);
    my $autoRecover = ReadingsNum("WG.Balkonkraftwerk.HUB.global","report_properties_autoRecover",0);
    if($controlBypass == 1){
        fhem("set WG.Balkonkraftwerk.HUB.global Bypass 1") if($passMode != 1);
        fhem("set WG.Balkonkraftwerk.HUB.global autoRecover 0") if($autoRecover != 0);
    }
   
    if($available == 2){

        # Abbruch, wenn das letzte Limmit noch verarbeitet wird
        unless($limit_act =~ m/set limit/){
            # Wenn letztes Limit verarbeitet wurde...
           
            # Zähler zurück auf 0
            fhem("set WG.Balkonkraftwerk.control controlSetCount 0");
           
            # Begrenzung bis Batterie Level einmal erreicht
            if(($electricLevel >= $controlBatteryLevel) && ($controlBatteryLevelReached == 0)){
                fhem("set WG.Balkonkraftwerk.control controlBatteryLevelReached 1");
                $controlBatteryLevelReached = 1;
            }
           
            # Umrechnung in Watt
            my $limit_watt = int(($limit_act * 600) / 100);


            # Grundzustand herstellen???
            # Inverter auf NULL ???
            # Nein, Wechselrichter startet mit 100% und wird dann runtergeregelt
           
            # Erster Start Limit wird auf default gesetzt

            if(($electricLevel < $socSet) || ($controlBatteryFull == 1)){
                # Wenn Batterie nicht voll ist, dann...

                if((ReadingsVal("WG.Balkonkraftwerk.control","state","off") eq "on") && ($controlFirstStart == 1)){
                    # wenn Regelung eingeschaltet und Inverter in Produktion, dann...

                    # Status setzen
                    $controlState = 1;

                    if($total_act_power > $controlLevel){
                        # sind es mehr als Step die ausgeregelt werden können?
                        if(($total_act_power - $controlLevel) > $controlStep){
                            # neuer Wert
                            $limit_watt = $limit_watt + $controlStep;

                            # Grenzen prüfen
                            ($limit_watt = $outputLimit)if($limit_watt > $outputLimit);

                            # Batterie unter Level und noch nicht drüber gewesen, dann begrenzen auf Default
                            if(($limit_watt > $default) && ($controlBatteryLevelReached == 0)){
                                $limit_watt = $default;
                               
                                # Status setzen
                                $controlState = 2;
                               
                            }
                        }

                        # nichts tun, ist gut eingestellt

                    }
                    else{
                        # neuer Wert, *2 um schneller wieder herunterzukommen, um nicht zu stark ins Minus zu kommen
                        $limit_watt = $limit_watt - ($controlStep * 2);

                        # Grenzen prüfen
                        ($limit_watt = 0)if($limit_watt < 0);
                    }
                }
                else{
                    # Wenn keine Regelung, dann Defaultwert aus Dummy
                    $limit_watt = $default;
                   
                    # Erster Start setzen
                    fhem("set WG.Balkonkraftwerk.control controlFirstStart 1") if($controlFirstStart == 0);

                    # Status setzen
                    $controlState = 0;
                }
            }
            else{
                # Wenn Batterie in Standby und voll, dann Limit auf 100% (max Inverterleistung im HUB)
                $limit_watt = $inverseMaxPower;  

                # Status setzen
                $controlState = 5;
            }

            # Umrechnung in Prozent
            my $limit_pct = int(($limit_watt * 100) / 600);

            # Wert setzen, wenn er ungleich zum Aktuellen ist und beim ersten Start
            if(($limit_act != $limit_pct) || ($controlFirstStart == 0)){
                fhem("set WG.Balkonkraftwerk.Inverter limit $limit_pct");
            }
        }
        else{
            # Wenn Limit noch verarbeitet wird nichts weiter tun
           
            # Zähler zu Kontrolle erhöhen
            $controlSetCount++;
            fhem("set WG.Balkonkraftwerk.control controlSetCount $controlSetCount");
            Log3 undef, 1, "Regelung: set limit count = ".$controlSetCount;
           
            # Status setzen
            $controlState = 4;
        }
    }
    else{
        # Wenn der Inverter nicht verfügbar ist nichts weiter tun
       
        # Batterie Level erreicht zurücksetzen
        fhem("set WG.Balkonkraftwerk.control controlBatteryLevelReached 0") if($controlBatteryLevelReached == 1);

        # Erster Start rücksetzen
        fhem("set WG.Balkonkraftwerk.control controlFirstStart 0") if($controlFirstStart == 1);
       
        # Status setzen
        $controlState = 3;
    }
   
    # Status setzen
    fhem("set WG.Balkonkraftwerk.control controlState $controlState");
   
}

Grüße Ralf

rudolfkoenig

Woher weiss das Programm, welche der 3 Phasen belastet wurde?
Tut mir leid, falls mein Unwissen auf dem Gebiet hier zu offensichtlich wird.

schwatter

Der Zähler ist saldierend. Daher kann immer mit der Gesamtsumme gerechnet werden.

Gruß schwatter

RalfP

Hallo Rudolf,

vielen Dank hier auf diesem Wege nochmals, mit dem Tipp betreffs connectFn beim MQTT_CLIENT. Wie du siehst hab ich es erfolgreich umgesetzt, wie die ersten Tests zeigen.

Der Shelly Pro 3EM ist ein 3 Phasen Zähler, den man zentral in seinen Sicherungskasten einbauen muss. Er saldiert die 3 Phasen. Die Abrechnung des Versorgers unterscheidet auch nicht zwischen den Phasen. Der Gesamtwert kommt über 'total_act_power' per MQTT vom Shelly Pro 3EM rein.

Ich erkläre es immer so: Akzeptiere immer die Anzeige deines Stomzählers. Er berechnet dir gerade, was aus deinem Haushalt rausgeht, oder auch reingeht, immer über alle 3 Phasen. Das bezahlst du auch nur an den Versorger. Damit ist es für den Haushalt egal, ob gerade über eine Phase eingespeist wird und über eine andere gerade Strom gezogen wird. Die Summe macht es.

Ist die Summe negativ, schenkt man dem Versorger Energie. Darum mein Versuch die Regelung so zu optimieren, das ich überschüssige Energie im Akku speichere und später nutze.

Hier noch eine Erklärung im Netz dazu:
https://solarblitz.blogspot.com/2018/08/einspeisung-auf-einer-oder-3-phasen.html

Grüße Ralf

blofield

Steuert einer von euch mit RalfP's Modul einen Hyper2000?

Ich vermute ich verstehe es noch nicht ganz oder mache etwas falsch, aber ob ich outputLimit setze oder nicht, da passiert nix.
Fehlermeldungen im Log habe ich keine. Bin auf dem EU Server. Habe das ConfigProposal angenommen...

Grüße
blofield

Shadow3561

#29
Moin,
Ich steuere einen Hyper2000.

Das Output-Limit kann man nur setzen wenn die Energiepläne wie Smart-CT oder Zeitsteuerung ausgeschaltet sind.

Mfg

RalfP

Hallo blofield,

sofern Shadow's Tipp nicht hilft, ist es für mich irgendwie wieder ein Zeichen, dass das Publishing auf den EU Server nicht funktioniert. Habe ich leider nie testen können.

Verstehen würde ich es aber nicht, da die App auch nur über MQTT sendet. Die funktioniert ja, oder?

Sofern du deine App auf einem Mac installiert hättest (geht bei macOS  :D ) und gleichzeitig Wireshark mit Filter mqtt lauschen lässt, müsstest du die Kommunikation theoretisch sehen können, wenn du in der App den Output veränderst. Wäre interessant, was da übermittelt wird.

Du darfst diesen Dateianhang nicht ansehen.

Grüße Ralf

RalfP

Hallo blofield,

noch etwas:

Ich nehme an, du hast einen MQTT2_CLIENT in Fhem mit meinem Vorschlag konfiguriert (76_Zendure.pm), wie auch ein Login und damit den AccessToken generiert. Bekommst du Daten in deine Readings geschrieben?

In der App darfst du den zweiten Zendure Account, welchen du auch nun in Fhem benutzt, nicht wieder anmelden! Der Token in Fhem wird damit ungültig. Sollte dies passieren, musst du einen neuen Token erzeugen, bzw. im MQTT2_Client mit connectFn Konfiguration (ZendureUtils.pm) einmal disconnecten und, nach 10s Warten, wieder connecten. Ein Token wird dann neu erzeugt.

Ich hatte festgestellt, das wenn man nach dem Login und connect des MQTT2_Client, die App wieder (mit gleichem Account) startet. Der MQTT2_Client zwar immer noch Daten empfängt, aber das Publish nicht funktioniert.

Andersherum ist es ganz cool, beobachte mit dem automatisch konfigurierten MQTT2_Client über connectFn, dass nach erfolgreichem Connect der Nutzer in der App abgemeldet wird.


Übrigens: Wenn du mit deinem Hauptaccount in der Zendure App den Output veränderst, sollte dies auch in den iot Topics sichtbar werden. So ungefähr:

Du darfst diesen Dateianhang nicht ansehen.

Ich gehe mal davon aus, das beim Hyper2000 der Wert sich auch 'outputLimit' nennt.

Grüße Ralf

blofield

Hallo Shadow3561 & RalfP,

erstmal vielen Dank für die schnelle Unterstützung!
Es lag an dem von Shadow3561 angesprochenen, eingstellten Modi in der App.
Ich habe in der App alle Modi ausgeschaltet, dann hat es sofort funktioniert, auch über den EU Server.

Den Hyper 2000 kann ich jetzt über inputLimit & outputLimit steuern, ich ergänze jeweils mit dem passenden acMode 1 || 2.

Hatte gestern leider Probleme mit meinem Hostsystem, nach dem Neustart hat aber leider nichts mehr funktioniert.
Ich musste mir einen neuen Access-Token erstellen, damit es wieder steuerbar war.
Meine Vermutung war allerdings, dass der Token ja noch Gültigkeit haben müsste, da ich mich nicht in der APP angemeldet hatte.
@RalfP ist das Setup rebootfähig?

Grüße
blofield

RalfP

Hallo blofield,

ja, ich selbst habe mir einen Token für meine Mosquitto Bridge config vor langer Zeit erzeugt und er funktioniert immer noch. Auch nach mehrerem Neustarts von Mosquitto.

Auch wenn du einen eigenen MQTT2_CLIENT angelegt hast, klappte es.

Wenn du mit connectFn (ZentureUtils.pm) im MQTT2_ClIENT arbeitest, wird mit jedem Connect ein neuer Token erzeugt. Da währest du auf der sicheren Seite.

Grüße Ralf

Reinhart

Danke das hier so ein tolles und funktionales Modul entwickelt wurde!
Ich habe das jetzt alles so nachgebaut und es funktioniert alles genauso wie beschrieben. Ich bin notgedrungen am EU Server und auch da klappt alles, speziell die Befehlsausgabe und somit das MQTT Write. EU Server ist deshalb für mich so wichtig, weil ich einen ACE1500 mit dynamischen Stromtarif nutze. Hier ist es zwingend notwendig in der App im Profil das Land exakt einzustellen, sonst werden falsche Börsenpreise geladen. Jedes Land hat seine eigenen Börsentarife wegen der unterschiedlichen Anteile von Nachfrage, Wind, PV und Wasser!
Da ich zur Zeit alles mit dem nachgeschaltenen Hoymiles Wechselrichter steuere habe ich zur Zeit kein Einsatzgebiet für diesen MQTT Write Zugang des Zendure Solarflow, aber wer weiß was mir noch alles einfällt.

Im Augenblick habe ich meine Anlage so verschaltet mit zusätzlicher Möglichkeit über ein externes Netzteil den Akku zu laden. Letzteres kann jetzt fast wegen dem ACE 1500 entfallen weil der das auch kann.
Mit diesem Modul ergeben sich natürlich völlig neue Möglichkeiten, vor allem weil die dynamischen Börsendaten nicht immer deckungsgleich von meinem Anbieter aWATTar sind. Da der ACE 1500 jedoch noch keine MQTT Daten liefert muss man wohl noch etwas auf eine Zendure Unterstützung warten.
FHEM auf Raspy4 mit Bullseye + SSD, Homematic, ESP8266, ESP32, Sonoff, eBus, NanoCUL, MapleCUL, , MQTT2, Alexa

RalfP

@Reinhard: Das ist mal eine echt umfangreiche Installation  :)

Habe mal noch eine Frage an die Nutzer, die einen Energieplan eingestellt haben: Steht bei euch etwas in den Werten "smartMode" und "smartPower". Verändert sich "smartPower" und wenn, wie und in welcher Abhängigkeit (wenn erkennbar)?

Vielen Dank
Ralf