APSystems EZ-1

Begonnen von rubberduck67, 15 August 2023, 11:40:39

Vorheriges Thema - Nächstes Thema

rubberduck67

Moin!
nach längerem suchen, werde ich jetzt einen Forumseintrag erstellen. O:-)
Ich versuche von APSystems das Balkonkraftwerk mit dem Inverter EZ-1 in FHEM zu integrieren. Leider finde ich nichts. Zum Unterschied zu den großen Invertern kann dieser WiFi (Cloud) und Bluetooth. Damit scheidet patience4711 ECU wohl aus. Gibt es trotzdem etwas. Ein Denkanstoß würde auch gehen...
oder nur die Zwischendose?

Gruß
Sven

VB90

#1
Hi,

kannst du den EZ-1 im WLAN sehen und ansprechen?
Falls er eine eigene WebUI hat, würde ich per HTTPMOD versuchen, ihm Daten zu entlocken...

vb

edit:
Nach allem was man auf die Schnelle so findet, ist der EZ-1 doch sehr zugenagelt und schweigsam.
Ich betreue nebenbei drei Hoymiles-Wechselrichter, das sind richtige Plaudertaschen und technisch sehr einfach einzubinden.
Man muss das Rad nicht neu erfinden, nur wissen wie es gedreht wird.

rubberduck67

Leider sind die im Web ohne IP. Ähnlichwie die Sonoff S55, diw musste man umflashen.

masterpete23

Wie meinst du das sie sind im Netz ohne IP?

rubberduck67


masterpete23

Es ist doch technisch nicht möglich im WLAN zu sein ohne IP Adresse?!

rubberduck67

Doch... IP ist nur ein Protokoll

rubberduck67

Aber inzwischen hat der inverter sich gemeldet. Per IP. Gerade im Router geschaut.

masterpete23

 ;)
Und hast du schon was auslesen können?
Mal auf Port 8899 geschaut?
Siehe auch https://github.com/npeter/ioBroker.apsystems-ecu

rubberduck67

Nmap sagt
Host is up (0.045s latency).
Not shown: 999 closed tcp ports (conn-refused)
PORT  STATE    SERVICE
9/tcp filtered discard

Nmap done: 1 IP address (1 host up) scanned in 16.84 seconds

rubberduck67

Die ecu kommuniziert über  Zigbee, kann die Box nicht

rubberduck67


Lehmi54

Guten Morgen,
gestern wurde für den EZ1-M eine lokale API, die Installation und die Einbindung in ein anderes Smarthome System vorgestellt.
EZ1-M Lokale API
Leider reicht meine Kompetenz nicht eine Einbindung in FHEM zu realisieren, habe aber großes Interesse daran.
Eine angenehme Vorweihnachtszeit
Uwe
2x Raspberry 4 und 3 - FHEM 6.2
z-wave Netzwerk, SIGNALduino

VB90

Na das sieht aber machbar aus.
Immerhin ist diese Lösung mal was ohne Cloud.

vb
Man muss das Rad nicht neu erfinden, nur wissen wie es gedreht wird.

rubberduck67

#14
War ein paar Tage mehr mit der Heizung beschäftigt.

Das scheint ein gangbarer Weg zu sein... aber der Punkt taucht bei mir im Menü nicht auf... muß ich den Inverter neu anlernen?

Nur in der App neu anmelden... ;-)

rubberduck67

So, das mit dem Python ist am laufen

Power PV-Input 1: 0 W
Power PV-Input 2: 0 W
Generation today 0.071 kWh

Jetzt mal wegen der Integration überlegen

Lehmi54

Hallo rubberduck67,
habe die Datenübergabe nach fhem mit einem Pythonscript und der Python FHEM API in einen Dummy und einem cronjob aller Minute von 8 bis 16 Uhr gelöst. Das Einstellen des  Powerlimits erfolgt über ein DOIF und GetHttpFile. Habe es auch mit MQTT probiert. Funktioniert auch ohne Probleme.
Es ist, wie schon geschrieben, eine Anfängerlösung ohne schnick schnack und Fehlerbehandlung. Hatte bisher mit Python noch nie Kontakt...
Schönes WE
Uwe 
2x Raspberry 4 und 3 - FHEM 6.2
z-wave Netzwerk, SIGNALduino

AlexMuc

Hallo Uwe,
seit heute läuft bei mir auch ein AP EZ1-M. Leider bin ich bereits beim Installieren der Pythongeschichte (auf einem Raspberry) für das lokale API auf die Nase gefallen, s.u.
Magst / kannst du eine detailiertere (für doofe wie mich) Anleitung schreiben wie du genau vorgegangen bist. Dann brauchen wir nur noch jemanden, der sich gut mit FHEM und "Modulen" auskennt, der uns das formal korrekt in FHEM einbaut :-)

Mein aktueller Stand scheitert bereits bei der Installation des "lokalen APIs" auf dem Raspberry...
"pip install apsystems-ez1" liefert bei mir den Fehler
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
ERROR: Could not find a version that satisfies the requirement apsystems-ez1
ERROR: No matching distribution found for apsystems-ez1
Python hat bei mir noch die V 3.9.2, die 3.12.1, bei der dieser Fehler angeblich nicht mehr auftritt, krieg ich irgendwie nicht installiert. Da fehlt mir wohl noch die richtige Anleitung.

Gruß
Michael

rubberduck67

Zitat von: Lehmi54 am 16 Dezember 2023, 11:00:41Hallo rubberduck67,
habe die Datenübergabe nach fhem mit einem Pythonscript und der Python FHEM API in einen Dummy und einem cronjob aller Minute von 8 bis 16 Uhr gelöst. Das Einstellen des  Powerlimits erfolgt über ein DOIF und GetHttpFile. Habe es auch mit MQTT probiert. Funktioniert auch ohne Probleme.
Es ist, wie schon geschrieben, eine Anfängerlösung ohne schnick schnack und Fehlerbehandlung. Hatte bisher mit Python noch nie Kontakt...
Schönes WE
Uwe 
Wie übergibst Du das Phyton Script? Direct aus dem Dummy? Hast du im Fhem noch ein Modul installiert? Es gibt etwas mit  dem du Phyton über FHEM ausführen kannst.

Gruß
Sven

rubberduck67

ZitatPython hat bei mir noch die V 3.9.2, die 3.12.1, bei der dieser Fehler angeblich nicht mehr auftritt, krieg ich irgendwie nicht installiert. Da fehlt mir wohl noch die richtige Anleitung.


Bei mir ging das mit 
sudo apt install python3
python --version

Lehmi54

Zitat von: rubberduck67 am 16 Dezember 2023, 17:16:45Wie übergibst Du das Phyton Script?
Hallo Sven, hallo Michael,
ich  versuchs mal mit einem ersten längeren Beitrag überhaupt, also Nachsicht :-)
Die Installation
pip install apsystems-ez1brachte eine Fehlermeldung externally managed, die ich behoben habe mit
sudo rm /usr/lib/python3.11/EXTERNALLY-MANAGEDdannach habe konnt ich die API und die fhem api installieren
pip install fhemdas neu zusammengebaute Script "aps_basis_3.py"
#!/usr/bin/python3
from APsystemsEZ1 import APsystemsEZ1M
import asyncio
import fhem
import time
# Initialize the inverter with the specified IP address and port number.
inverter = APsystemsEZ1M("192.168.2.XXX", 8050)
fh = fhem.Fhem("192.168.2.XXX")
async def main():
      try:
        # Fetch output data from the inverter.
        response = await inverter.get_output_data()

        # Display power input from PV-Input 1 and 2.
        print("Power PV-Input 1: " + str(response.p1) + " W")
        print("Power PV-Input 2: " + str(response.p2) + " W")
        fh.send_cmd("setreading ez1_m Power_1 " + str(response.p1))
        fh.send_cmd("setreading ez1_m Power_2 " + str(response.p2))
        fh.send_cmd("setreading ez1_m Energie_1 " + str(response.e1))
        fh.send_cmd("setreading ez1_m Energie_2 " + str(response.e2))
        fh.send_cmd("setreading ez1_m Energie_1_bisher " + str(response.te1))
        fh.send_cmd("setreading ez1_m Energie_2_bisher " + str(response.te2))


        # Display total energy generation for the current day.
        print("Generation today " + str(round(response.e1 + response.e2, 3)) + " kWh")
        fh.send_cmd("setreading ez1_m Gesamt_heute " + str(round(response.e1 + response.e2, 3)))
        fh.send_cmd("setreading ez1_m BKW_bisher " + str(round(response.te1 + response.te2, 3)))

        maxPower = await inverter.get_max_power()
        fh.send_cmd("setreading ez1_m t_akt_max_power " + str(maxPower))
       
       
      except Exception as e:
        # Handle any exceptions that occur during the data fetch and print the error.
        print(f"An error occurred: {e}")
# Run the main coroutine.
# This is the entry point of the script and it runs the main function in an asynchronous manner.
asyncio.run(main())
habe ich mit WinSCP nach /home/pi/kopiert und lauffähig (755) gemacht
in FHEM habe ich einen Dummy definiert
define ez1_m dummy
attr ez1_m readingList state
attr ez1_m room Dummy
attr ez1_m setList state:selectnumbers,100,50,800,0,lin
attr ez1_m webCmd state
mit crotab -e habe ich am Ende ergänzt
*/1 8-16 * * * /home/pi/aps_basis_3.py >/dev/null 2>&1
00 12 * * * /home/pi/aps_wr_daten.py /dev/null 2>&1
zu Setzen des Powerlimits habe ich ein DOIF definiert
#***************Power Limit EZ1_M setzen *************************
define di_max_power DOIF ([ez1_m:?state])({my $max_power = Value("ez1_m");;GetHttpFile("192.168.2.XXX:8050", "/setMaxPower?p=$max_power")})
setuuid di_max_power 657dc21f-f33f-942f-ed4f-5b310c999e88057c
attr di_max_power addStateEvent 1
attr di_max_power do always
attr di_max_power room Balkonkraftwerk,Dummy
mit "setreading ez1_m state 312" oder direkt am Dummy über set kann ich damit das Powerlimit setzen.
Die Visualisierung mache ich mit Damians genialen SVG-uiTable-Funktionen realisiert z.B.
define di_ha_power DOIF ##
attr di_ha_power event_Readings ha_power_ges_av:{[MQTT2_DVES_A65A29:GS303_Power_cur]-([ez1_m:Power_1:d]+[ez1_m:Power_2:d])},ha_power_einspeisung:{[$SELF:ha_power_ges_av:d]<0 ? [$SELF:ha_power_ges_av:d]:"0"}
attr di_ha_power room Balkonkraftwerk
attr di_ha_power state [#sum:d2:"wallplug":power_1]
attr di_ha_power uiTable {package ui_Table;;\
$TC{0..4}="style='padding-left: 3px;;padding-right: 3px'"\
}\
card([ez1_m:Power_1:144col],"Leistung West","solar",0,300,120,0,"W",\&temp_hue,"1","400,,,,,1")\
card([ez1_m:Power_2:144col],"Leistung Ost","solar",0,300,120,0,"W",\&temp_hue,"1","400,,,,,1")\
card([ez1_m:Gesamt_heute:144col],"BKW Energy","solar",0,3000,120,0,"kWh",\&temp_hue,"1","400,,,,,1")
"MQTT2_DVES_A65A29:GS303_Power_cur" ist der Verbrauch am Stromzaehler
Ich hoffe, ich habe nichts vergessen und nicht in der Luft zerreissen, ich bin absoluter Pythonanfänger!
Freuen würde ich mich, wenn ein Profi eine Idee hat, wie ich überprüfen kann, ob der Wechselrichter erreichbar ist. ich glaube requests sollte man nutzen.
Das ganze funktioniert natürlich nur tagsüber, wenn der Wechselrichter Power von den Modulen bekommt.
Schönen 3. Advent
Uwe




2x Raspberry 4 und 3 - FHEM 6.2
z-wave Netzwerk, SIGNALduino

rubberduck67

Klingt einfach, mal sehen das ich das einmal morgen in Angriff nehme.

Danke! das gibt erst einmal Ideen!


Gruß
Sven

AlexMuc

Ich hab mir wohl mein System total zerschossen, muß das zwischen den Feiertagen erstmal ,,bereinigen  >:(
So wie ich das (leider) bis jetzt verstehe, muß man die Daten aktiv am Gerät abholen und bis jetzt habe ich noch nirgends etwas über irgendwelche ,,Sicherheitsfunktionen" gelesen die beim Zugriff auf das ,,lokale API" vorhanden sein sollten.
Viel besser wäre es doch eigentlich, wenn man in der App bei der Konfiguration des APIs einfach einen MQTT Server mit Anmeldedaten angeben könnte und dann sendet der Wechselrichter nicht mehr zum Cloudserver sondern direkt an einen lokalen Server. Das wäre einfach und universal für alle :-) Werde das mal auf der Projektseite zur Diskussion stellen. Das Projekt ist ja noch jung.

Wer Spaß und Lust hat, könnte ja mal den Verkehr zwischen WR und dem Cloudserver mitschneiden und untersuchen. Sofern man da was brauchbares mitlesen kann.

rubberduck67

Zitat von: rubberduck67 am 16 Dezember 2023, 20:16:19Klingt einfach, mal sehen das ich das einmal morgen in Angriff nehme.

Läuft jetzt
Änderung: es muß zwingend das FHEM Modul eingebunden werden
 Im Cronjob den Pfad zum Phyton eintragen

AlexMuc

Mein aktueller Stand ist:
Python ist immer noch im Eimer aber: das braucht man garnicht :-)
Der Wechselrichter läßt sich ganz simple mit einigen wenigen HTTP-Zeilen abfragen wenn das lokale API aktiviert ist. Hier der Link zur Anleitung: Local API EZ1-m

Aktuell hab ich mir 2 Devices per HTTPmod zusammengestückelt. Ist leider nicht besonders schön und elegant weil ich kaum Ahnung hab, aber zumindest bekomme ich jetzt schonmal alle 30 Sekunden die aktuellen Daten direkt vom Wechselrichter.
Ein kleiner Fortschritt wäre es schon, wenn sich diese 4 Anfragen und die 2 Setbefehle in ein Device integrieren ließen und dann per doif aktualisiert würden.
- http://ipadresse/getDeviceInfo
- http://ipadresse/getOutputData
- http://ipadresse/getMaxPower
- http://ipadresse/getAlarm

- http://ipadresse/setMaxPower?p=600.  [30..800]
- http://ipadresse/setOnOff?status=1   0=on, 1 = off

Wesentlich cooler wäre es aber, wenn man sich diesen Wechselrichter einfach per Template einrichten könnte und dann alles "automagisch" passiert, also so in etwa:
defmod meinWechselrichter AP_System_EZ1m ipAdresse Abfrageinterval_Daten Abfrageinterval_Status Abfrageinterval_Alarm

Gibt es irgendwo Beispiele für solch ein Vorhaben? Bei den bisherigen Wechselrichtern die ich gesehen habe war mir das als Anfänger leider alles zu kompliziert oder ich hab nur noch nicht das "richtige Musterdevice" gefunden was sich ähnlich abfragen / steuern läßt. Wer kann mich da in die richtige Richtung schubsen damit  da "was schönes" bei raus kommt. Gerne liefere ich auch "echte Antworten" vom Wechselrichter denn die in der Doku sind bereits formatiert. In Wirklichkeit kommt das alles in einer Zeile "angeschwommen" :-)
Falls Interesse an meinen Versuchen besteht, dann poste ich gerne. Einfach Bescheid sagen.


Michael

huri-kane

#25
Na da kann ich vielleicht ein wenig helfen. Ich hab eher zufällig vor wenigen Wochen mitbekommen, dass APSystems diese Funktion quasi "stillschweigend" eingebaut hat und war sehr erfreut, dass man den Wechselrichter damit nun von der Cloud abkoppeln kann. Die Template-Variante wäre natürlich ein Extraschleifchen. Aber einmal eingerichtet tut es auch so seinen Dienst.

Ich hab mir das Ganze als ein Device mit dem HttpMod-Modul eingerichtet.
define EZ1_inverter HTTPMOD http://apsystems:8050/getOutputData 60
attr EZ1_inverter get1JSON data_maxPower
attr EZ1_inverter get1Name MaxPower
attr EZ1_inverter get1Poll 1
attr EZ1_inverter get1URL http://apsystems:8050/getMaxPower
attr EZ1_inverter get2Name OutputData
attr EZ1_inverter get2Poll 1
attr EZ1_inverter get2URL http://apsystems:8050/getOutputData
attr EZ1_inverter get3Name Alarm
attr EZ1_inverter get3Poll 1
attr EZ1_inverter get3URL http://apsystems:8050/getAlarm
attr EZ1_inverter get4Name Disabled
attr EZ1_inverter get4Poll 1
attr EZ1_inverter get4URL http://apsystems:8050/getOnOff
attr EZ1_inverter get5Name DeviceInfo
attr EZ1_inverter get5Poll 1
attr EZ1_inverter get5PollDelay 3600
attr EZ1_inverter get5URL http://apsystems:8050/getDeviceInfo
attr EZ1_inverter icon measure_photovoltaic_inst
attr EZ1_inverter reading101JSON data_maxPower
attr EZ1_inverter reading101Name MaxPower
attr EZ1_inverter reading201JSON data_e1
attr EZ1_inverter reading201Name e1
attr EZ1_inverter reading202JSON data_e2
attr EZ1_inverter reading202Name e2
attr EZ1_inverter reading203JSON data_te1
attr EZ1_inverter reading203Name te1
attr EZ1_inverter reading204JSON data_te2
attr EZ1_inverter reading204Name te2
attr EZ1_inverter reading205JSON data_p1
attr EZ1_inverter reading205Name p1
attr EZ1_inverter reading206JSON data_p2
attr EZ1_inverter reading206Name p2
attr EZ1_inverter reading301JSON data_og
attr EZ1_inverter reading301Name alarm_off_grid
attr EZ1_inverter reading302JSON data_oe
attr EZ1_inverter reading302Name alarm_output_fault
attr EZ1_inverter reading303JSON data_isce1
attr EZ1_inverter reading303Name alarm_dc1_short
attr EZ1_inverter reading304JSON data_isce2
attr EZ1_inverter reading304Name alarm_dc2_short
attr EZ1_inverter reading401JSON data_status
attr EZ1_inverter reading401Name disabled
attr EZ1_inverter reading501JSON data_deviceId
attr EZ1_inverter reading501Name deviceId
attr EZ1_inverter reading502JSON data_devVer
attr EZ1_inverter reading502Name deviceVersion
attr EZ1_inverter reading503JSON data_ssid
attr EZ1_inverter reading503Name SSID
attr EZ1_inverter set1Hint slider,30,10,800
attr EZ1_inverter set1JSON data_maxPower
attr EZ1_inverter set1Name MaxPower
attr EZ1_inverter set1ParseResponse 1
attr EZ1_inverter set1URL http://apsystems:8050/setMaxPower?p=$val
attr EZ1_inverter set4Hint 0,1
attr EZ1_inverter set4Name Disabled
attr EZ1_inverter set4ParseResponse 1
attr EZ1_inverter set4URL http://apsystems:8050/setOnOff?status=$val
attr EZ1_inverter stateFormat {\
  sprintf("%.2fkWh / %.2fkWh / %.0fW",\
          ReadingsVal($name, "total_energy", 0),\
          ReadingsVal($name, "total_energy_today", 0),\
          ReadingsVal($name, "total_power", 0));;\
}
attr EZ1_inverter userReadings total_power:p.* { ReadingsVal($name, "p1", 0) + ReadingsVal($name, "p2", 0) },\
total_energy_today:e.* { ReadingsVal($name, "e1", 0) + ReadingsVal($name, "e2", 0) },\
total_energy:te.* { ReadingsVal($name, "te1", 0) + ReadingsVal($name, "te2", 0) },\
energy_today:e.* monotonic { ReadingsVal($name, "e1", 0) + ReadingsVal($name, "e2", 0) },\
energy_month:te.* monotonic { ReadingsVal($name, "te1", 0) + ReadingsVal($name, "te2", 0) }

Über die einzelnen get*Poll- bzw. get*PollDelay-Attribute lässt sich für die individuelle URI das Polling mitsamt Intervall anpassen - schließlich müssen nicht alle Informationen mit der gleichen Granularität abgefragt werden.

Die zusätzlichen UserReadings 'energy_today' und 'energy_month' summieren einfach die erzeugte Energie auf und werden einmal am Tag/Monat durch ein zusätzliches 'at' Device verarbeitet, welches dann noch "Hilfs-Readings" setzt. Ich habe bisher noch keinen Monat Laufzeit durch, daher können sich durchaus noch Fehler drin sein:
define EZ1_inverter_tag at *00:00:00 {\
  my $NAME = "EZ1_inverter";;\
  my $total_energy = ReadingsVal($NAME, "total_energy", 0);;\
  my $energy_today = ReadingsVal($NAME, "energy_today", 0);;\
  fhem("setreading $NAME energy_today 0");;\
  fhem("setreading $NAME energy_yesterday $energy_today");;\
  fhem("setreading $NAME total_energy_yesterday $total_energy");;\
  if ( (strftime("%d", localtime(time()) ) ) eq "01")  # 1. des Monats\
  {\
    my $energy_month = ReadingsVal($NAME, "energy_month", 0);;\
    fhem("setreading $NAME energy_month 0");;\
    fhem("setreading $NAME energy_lastmonth $energy_month");;\
    fhem("setreading $NAME total_energy_lastmonth $total_energy");;\
  }\
}

Die Readings "total_power", "energy_yesterday" und "energy_lastmonth" lasse ich loggen um damit den Leistungsverlauf am Tag sowie die Energieproduktion pro Tag bzw. pro Monat zu visualisieren (siehe Anhänge). Für ersteres muss man für sich entscheiden, ob einem eine "Messung" pro Minute reicht (über das define vom HTTPMOD): Das wäre dann ein Abwägen zwischen Genauigkeit und Speicherbedarf des Logs bzw. Rendering-Zeit des Graphen (bei mit ein Raspi3).

Hoffe das hilft ein wenig.

Grüße
André

AlexMuc

Hallo André,
das sieht aber gut aus.
Genau so hab ich mir das vorgestellt aber nicht hinbekommen. Mit dem Vorbild werde ich mich nachher in den Übungsraum begeben und schauen, wo ich bei meinen Versuchen jeweils gescheitert bin. Teile deines Devices hab ich ja bereits geschafft, aber ,,alles in einem", da haperte es halt :-)
Vielen Dank dafür, das du das mit uns teilst. Da können sicher viel was von lernen denen ähnliche Aufgaben bevorstehen.

Für das ,,Extraschleifchen" brauchen wir nun nur noch einen Idealisten mit Langweile der solche Templates zum Zeitvertreib baut ;-)

Huabafranze

#27
Hallo zusammen,
ich verfolge diesen Verlauf schon ein paar Wochen. Gerade habe ich gesehen, das es neue Beiträge gibt. Leider bin ich nur ein reiner Copy/Paste FHEM-Programmierer und Python ist für mir nur eine Schlange  :))
Mein geplantes vorhaben mit dem Wechselrichter wäre folgendes. Wenn ein Überschuss an Leistung produziert wird, soll dieser in einen Akku geladen werden. Die sogenannte Nachteinspeisung wollte ich dann realisieren, indem ich den Akku (evtl. über DC-DC-Wandler an einen Eingang eines zweiten EZ-1 M anschließe, und sich die einsprechend benötigte Einspeiseleistung über den Ausgang des Wechselrichters automatisch regelt. Die benötigte Leistung soll über einen bereits eingebauten  Shelly Pro 3EM passieren. Vielleicht hat jemand zu diesem Vorhaben Ideen oder auch Hardwaretipps.
Einen Punkt habe ich noch. Zur EZ1-M FHEM-Einbindung muss der Wechselrichter wohl in den Lokalen Modus gebracht werden, ich würde aber gerne weiterhin von unterwegs die APSystems App (also Cloud) nutzen. Eben auch um unterwegs in der App den Verlauf der Nachteinspeisung beobachten zu können.

Vielen Dank an alle die hier so fleißig programmieren und ihr Wissen anderen zur Verfügung stellen.

AlexMuc

Bisher hab ich noch keine Stelle im Internet gefunden, die die gleichzeitige Meldung der Wechselrichterdaten in die Cloud beschreibt. Das ist wohl vorerst nur ein entweder oder. Was du aber machen könntest wäre eine eigene Website zu betreiben auf die du von Fhem die Daten schreibst. Wäre zumindest meine Lösung zu dem Problem solange die Firmware des EZ1m nicht mehr hergibt.

Deine Batterielösung solltest du nochmal überdenken und schauen, wie das andere bereits gelöst haben. Das sollte mit nur einem Wechselrichter machbar sein. Genaueres können die aber sicher kundigere beschreiben, ich bin im Thema auch erst Anfänger, könnte mir aber jetzt schon, nach einem knappen Monat mit dem BKW, eine Erweiterung um eine Akkulösung vorstellen. Nach bisheriger Datenlage sollte selbst im Winter an sonnigen Tagen ausreichend Energie über sein, um den Grundbedarf bis zum nächsten Tag zu decken. Ist zumindest mein erster Eindruck. An trüben Tage gewinnt man allerdings nichtmal nen winzigen Blumenpott

Lehmi54

Zitat von: huri-kane am 10 Januar 2024, 07:51:50Hoffe das hilft ein wenig.

Grüße
André
Guten Abend, André und ihr Interessierten,
ja es hat sehr, ganz herzlichen Dank für die gute Lösung. Ich habe am letzten Wochenende von meiner Pythonmqtt-Version auf Deine Lösung umgestellt und dabei den Raspi gleich neu aufgesetzt. Läuft seitdem ohne Probleme bis auf den winterbedingten Ertrag :-), Super Lösung! Die Visualisierung läuft bei mir weiterhin über uiTable.
Grüße
Uwe
2x Raspberry 4 und 3 - FHEM 6.2
z-wave Netzwerk, SIGNALduino

Huabafranze

Hallo,
habe den EZ1 nun auch nach der Methode von huri-kane eingebuden. Funktioniert soweit gut, nur mit dem Einstellen der maximalen Leistung stimmt irgendetwas nicht.
Angenommen ich stelle 800W ein und die Solarpanels liefern 190W. Wenn ich jetzt 200W einstelle, lässt er nur ca.125W durch.
Kurz gesagt, es werden immer weniger Watt ausgegeben als eingestellt, obwohl die Leistung der Panels ausreichend wäre.
Vielleicht kann das jemand erklären.
PS. Es ist nur ein Eingang belegt.

Grüße Franz

AlexMuc

Gerüchteweise teilen die meisten Wechselrichtung die Leistung bei einer Drosselung immer auf alle Eingänge auf, dh bei 2 Eingängen wird, wenn man die Leistung von 800 auf 400 drosselt, kommen aus beiden Eingängen maximal nur noch je 200W.
Das ist zwar Blödsinn weil als Endverbraucher interessiert einen nur, was ,, hinten raus, kommt. Wenn also wie bei dir nur ein Eingang belegt ist, dann sollte der WR so intelligent sein, das er sich aus allen Eingängen soviel holt, bis das eingestellte Limit am Ausgang erreicht wird.
Ich hab das erst vor kurzem irgendwo gelesen und dort wurde ein Wechselrichter erwähnt, der in der neuesten Version genau so arbeiten soll. Frag nicht, wo. Google findet sicher einiges dazu ;-)

Boe3eh

Hallo zusammen, wollte auch das HTTP-Modul von huri-kane anwenden, bekomme da aber keine Daten ausgelesen. Sieht hier jemand die Ursache? Finde irgendwie den Fehler nicht:

Im Log steht:
024.06.23 20:48:09 4: EZ1_inverter: UpdateTimer called from GetUpdate with cmd next sets timer to call update function in 60.0 sec at 20:49:09.038, interval 60
2024.06.23 20:48:09 5: EZ1_inverter: AddToQueue adds type update to URL http://apsystems:8050/getOutputData, no data, no headers, retry 0, initial queue len: 0
2024.06.23 20:48:09 5: EZ1_inverter: HandleSendQueue called from AddToSendQueue, qlen = 1
2024.06.23 20:48:09 5: EZ1_inverter: no separator for multiple values (Context update, unknown)
2024.06.23 20:48:09 4: EZ1_inverter: HandleSendQueue sends update with timeout 2 to http://apsystems:8050/getOutputData, No Data, No Header
2024.06.23 20:48:10 5: EZ1_inverter: ReadCallback called from __ANON__
2024.06.23 20:48:10 4: EZ1_inverter: Read callback: request type was update retry 0,
header: HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 125, body length 125
2024.06.23 20:48:10 5: EZ1_inverter: Read callback: body
{"data":{"p1":8,"e1":2.08913,"te1":2.20986,"p2":12,"e2":1.90394,"te2":2.04412},"message":"SUCCESS","deviceId":"E07000061123"}
2024.06.23 20:48:10 4: EZ1_inverter: BodyDecode is not decoding the response body (charset not found, bodyDecode defaults to none)
2024.06.23 20:48:10 5: EZ1_inverter: GetCookies is looking for Cookies
2024.06.23 20:48:10 5: EZ1_inverter: ExtractSid called, context reading, num unknown
2024.06.23 20:48:10 4: EZ1_inverter: checking for redirects, code=200, ignore=0
2024.06.23 20:48:10 4: EZ1_inverter: no redirects to handle
2024.06.23 20:48:10 5: EZ1_inverter: Read callback sets LAST_REQUEST to update
2024.06.23 20:48:10 5: EZ1_inverter: CheckAuth decided no authentication required
2024.06.23 20:48:10 5: EZ1_inverter: Read starts parsing response to update with defined readings:
2024.06.23 20:48:10 4: EZ1_inverter: Read response to update didn't match any Reading
2024.06.23 20:48:10 5: EZ1_inverter: HandleSendQueue called from ReadCallback, qlen = 0
2024.06.23 20:48:10 5: EZ1_inverter: HandleSendQueue found no usable entry in queue

huri-kane

Hi Boe3eh,

was ich aus dem Log sehe ist, dass Du auf jeden Fall Daten vom Wechselrichter bekommst. Zu dem Zeitpunkt hattest Du in Summe noch 8+12=20W Leistung - ist OK für die Abendstunden ;) (das ist die Zeile mit den JSON-Daten nach "EZ1_inverter: Read callback: body")
Ich stecke zugegebenermaßen nicht wirklich im HTTPMOD-Modul drin aber aus dem Bauch heraus würde ich mutmaßen, dass selbiges die gelesenen Daten nicht zu den Readings verarbeitet - das suggeriert zumindest die Meldung "Read response to update didn't match any Reading". Kannst Du mal ein listing deines FHEM-Devices vom Wechselrichter posten ("list EZ1_inverter" entweder auf der Telnet-Konsole oder oben in der Web-UI-Zeile ausführen)? Möglicherweise passt da was nicht in deiner Device-Konfiguration.

Boe3eh

#34
Hallo huri-kane, danke für die schnelle Antwort, hier das Ergebnis von "list EZ1_inverter"
Internals:
   BUSY       0
   CFGFN     
   DEF        http://apsystems:8050/getOutputData 60 attr EZ1_inverter get1JSON data_maxPower attr EZ1_inverter get1Name MaxPower attr EZ1_inverter get1Poll 1 attr EZ1_inverter get1URL http://apsystems:8050/getMaxPower attr EZ1_inverter get2Name OutputData attr EZ1_inverter get2Poll 1 attr EZ1_inverter get2URL http://apsystems:8050/getOutputData attr EZ1_inverter get3Name Alarm attr EZ1_inverter get3Poll 1 attr EZ1_inverter get3URL http://apsystems:8050/getAlarm attr EZ1_inverter get4Name Disabled attr EZ1_inverter get4Poll 1 attr EZ1_inverter get4URL http://apsystems:8050/getOnOff attr EZ1_inverter get5Name DeviceInfo attr EZ1_inverter get5Poll 1 attr EZ1_inverter get5PollDelay 3600 attr EZ1_inverter get5URL http://apsystems:8050/getDeviceInfo attr EZ1_inverter icon measure_photovoltaic_inst attr EZ1_inverter reading101JSON data_maxPower attr EZ1_inverter reading101Name MaxPower attr EZ1_inverter reading201JSON data_e1 attr EZ1_inverter reading201Name e1 attr EZ1_inverter reading202JSON data_e2 attr EZ1_inverter reading202Name e2 attr EZ1_inverter reading203JSON data_te1 attr EZ1_inverter reading203Name te1 attr EZ1_inverter reading204JSON data_te2 attr EZ1_inverter reading204Name te2 attr EZ1_inverter reading205JSON data_p1 attr EZ1_inverter reading205Name p1 attr EZ1_inverter reading206JSON data_p2 attr EZ1_inverter reading206Name p2 attr EZ1_inverter reading301JSON data_og attr EZ1_inverter reading301Name alarm_off_grid attr EZ1_inverter reading302JSON data_oe attr EZ1_inverter reading302Name alarm_output_fault attr EZ1_inverter reading303JSON data_isce1 attr EZ1_inverter reading303Name alarm_dc1_short attr EZ1_inverter reading304JSON data_isce2 attr EZ1_inverter reading304Name alarm_dc2_short attr EZ1_inverter reading401JSON data_status attr EZ1_inverter reading401Name disabled attr EZ1_inverter reading501JSON data_deviceId attr EZ1_inverter reading501Name deviceId attr EZ1_inverter reading502JSON data_devVer attr EZ1_inverter reading502Name deviceVersion attr EZ1_inverter reading503JSON data_ssid attr EZ1_inverter reading503Name SSID attr EZ1_inverter set1Hint slider,30,10,800 attr EZ1_inverter set1JSON data_maxPower attr EZ1_inverter set1Name MaxPower attr EZ1_inverter set1ParseResponse 1 attr EZ1_inverter set1URL http://apsystems:8050/setMaxPower?p=$val attr EZ1_inverter set4Hint 0,1 attr EZ1_inverter set4Name Disabled attr EZ1_inverter set4ParseResponse 1 attr EZ1_inverter set4URL http://apsystems:8050/setOnOff?status=$val attr EZ1_inverter stateFormat {\   sprintf("%.2fkWh / %.2fkWh / %.0fW",\           ReadingsVal($name, "total_energy", 0),\           ReadingsVal($name, "total_energy_today", 0),\           ReadingsVal($name, "total_power", 0));\ } attr EZ1_inverter userReadings total_power:p.* { ReadingsVal($name, "p1", 0) + ReadingsVal($name, "p2", 0) },\ total_energy_today:e.* { ReadingsVal($name, "e1", 0) + ReadingsVal($name, "e2", 0) },\ total_energy:te.* { ReadingsVal($name, "te1", 0) + ReadingsVal($name, "te2", 0) },\ energy_today:e.* monotonic { ReadingsVal($name, "e1", 0) + ReadingsVal($name, "e2", 0) },\ energy_month:te.* monotonic { ReadingsVal($name, "te1", 0) + ReadingsVal($name, "te2", 0) }
   FUUID      667aff60-f33f-d16c-e764-c8eb9a33e64d8465
   Interval   60
   MainURL    http://apsystems:8050/getOutputData
   ModuleVersion 4.2.0 - 11.8.2023
   NAME       EZ1_inverter
   NOTIFYDEV  global
   NR         417
   NTFY_ORDER 50-EZ1_inverter
   STATE      ???
   TYPE       HTTPMOD
   value     
   HttpUtils:
     NAME      
     addr       http://apsystems:8050
     auth       0
     data      
     displayurl http://apsystems:8050/getOutputData
     header    
     host       apsystems
     httpversion 1.0
     ignoreredirects 1
     loglevel   4
     path       /getOutputData
     protocol   http
     redirects  0
     timeout    2
     url        http://apsystems:8050/getOutputData
     sslargs:
   QUEUE:
   READINGS:
   REQUEST:
     context    reading
     data      
     header    
     ignoreredirects 0
     num        unknown
     retryCount 0
     type       update
     url        http://apsystems:8050/getOutputData
Attributes:
   room       PV-Anlage
   verbose    5
Fehlt mir eventuell eine HttpUtils-Datei? Wo würde die leigen müssen?

huri-kane

Ob Dateien fehlen lässt sich hier nicht erkennen, allerdings ist deine Device-Definition etwas "daneben". Wie hast du das angelegt? Ich frage deshalb, weil beim "DEF" Internal viel zu viel steht. Das Kommando für die Device-Definition lautet ja
define EZ1_inverter HTTPMOD http://apsystems:8050/getOutputData 60
Das heißt das "DEF" Internal solle nur
http://apsystems:8050/getOutputData 60enthalten. Die ganzen "attr" Anhängsel dahinter sollten eigentlich einzelne Attribute des Device' sein und müssten entsprechend im Listing in einem separaten Abschnitt "Attributes" auftauchen. Das wird auch der Grund sein, warum HTTPMOD keine Zuordnung findet - es gibt einfach keine reading*JSON-Attribute.

Wenn du den Text aus meinem initialen Post per copy&paste ins FHEM übernehmen möchtest musst Du jede Zeile einzeln ein die Kommando-Zeile der WebUI kopieren und ausführen (dort werden die Zeilenumbrüche nicht als neues Kommando verarbeitet!). Den kompletten Block kannst Du nur im Telnet-Zugang kopieren: Dort entspricht ein Zeilenumbruch einem "Enter"-Tastendruck und damit der Befehlsausführung. Bevor Du aber in dem vorhandenen Device änderst empfehle ich selbiges lieber vorher zu löschen und neu anzulegen.

Hier mal als Vergleich das Listing von meinem Device:
Internals:
   BUSY       0
   DEF        http://apsystems:8050/getOutputData 60
   FUUID      6595722a-f33f-8d27-351b-cb16bcbc8f95dee3
   Interval   60
   MainURL    http://apsystems:8050/getOutputData
   ModuleVersion 4.1.12 - 19.4.2022
   NAME       EZ1_inverter
   NOTIFYDEV  global
   NR         170
   NTFY_ORDER 50-EZ1_inverter
   STATE      661.97kWh / 0.69kWh / 375W
   TYPE       HTTPMOD
   eventCount 63064
   value     
   Helper:
    [...] (entfernt da automatisch angelegt)
Attributes:
   alias      Stromerzeugung
   get1JSON   data_maxPower
   get1Name   MaxPower
   get1Poll   1
   get1URL    http://apsystems:8050/getMaxPower
   get2Name   OutputData
   get2Poll   1
   get2URL    http://apsystems:8050/getOutputData
   get3Name   Alarm
   get3Poll   1
   get3URL    http://apsystems:8050/getAlarm
   get4Name   Disabled
   get4Poll   1
   get4URL    http://apsystems:8050/getOnOff
   get5Name   DeviceInfo
   get5Poll   1
   get5PollDelay 3600
   get5URL    http://apsystems:8050/getDeviceInfo
   group      Home State
   icon       measure_photovoltaic_inst
   reading101JSON data_maxPower
   reading101Name MaxPower
   reading201JSON data_e1
   reading201Name e1
   reading202JSON data_e2
   reading202Name e2
   reading203JSON data_te1
   reading203Name te1
   reading204JSON data_te2
   reading204Name te2
   reading205JSON data_p1
   reading205Name p1
   reading206JSON data_p2
   reading206Name p2
   reading301JSON data_og
   reading301Name alarm_off_grid
   reading302JSON data_oe
   reading302Name alarm_output_fault
   reading303JSON data_isce1
   reading303Name alarm_dc1_short
   reading304JSON data_isce2
   reading304Name alarm_dc2_short
   reading401JSON data_status
   reading401Name disabled
   reading501JSON data_deviceId
   reading501Name deviceId
   reading502JSON data_devVer
   reading502Name deviceVersion
   reading503JSON data_ssid
   reading503Name SSID
   room       Balkonkraftwerk,Status
   set1Hint   slider,30,10,800
   set1JSON   data_maxPower
   set1Name   MaxPower
   set1ParseResponse 1
   set1URL    http://apsystems:8050/setMaxPower?p=$val
   set4Hint   0,1
   set4Name   Disabled
   set4ParseResponse 1
   set4URL    http://apsystems:8050/setOnOff?status=$val
   stateFormat {
  sprintf("%.2fkWh / %.2fkWh / %.0fW",
          ReadingsVal($name, "total_energy", 0),
          ReadingsVal($name, "total_energy_today", 0),
          ReadingsVal($name, "total_power", 0));
}

   userReadings total_power:p.* { ReadingsVal($name, "p1", 0) + ReadingsVal($name, "p2", 0) },
total_energy_today:e.* { ReadingsVal($name, "e1", 0) + ReadingsVal($name, "e2", 0) },
total_energy:te.* { ReadingsVal($name, "te1", 0) + ReadingsVal($name, "te2", 0) },
energy_today:e.* monotonic { ReadingsVal($name, "e1", 0) + ReadingsVal($name, "e2", 0) },
energy_month:te.* monotonic { ReadingsVal($name, "te1", 0) + ReadingsVal($name, "te2", 0) }

Grüße
André

Boe3eh

Hallo André,
vielen Dank für die entscheidenden Hinweise. Da ist wirklich was beim kopieren schief gelaufen.
Kaum macht man´s richtig... ;D  ;D  ;D
Internals:
   BUSY       0
   CFGFN     
   DEF        http://192.168.0.239:8050/getOutputData 60
   FUUID      667c443c-f33f-d16c-ac57-aebad2cd615084a0
   Interval   60
   MainURL    http://192.168.0.239:8050/getOutputData
   ModuleVersion 4.2.0 - 11.8.2023
   NAME       EZ1_inverter
   NOTIFYDEV  global
   NR         418
   NTFY_ORDER 50-EZ1_inverter
   STATE      18.62kWh / 4.74kWh / 94W
   TYPE       HTTPMOD
   eventCount 182
   value     
   HttpUtils:
     NAME      
     addr       http://192.168.0.239:8050
     auth       0
     buf       
     code       200
     conn      
     data      
     displayurl http://192.168.0.239:8050/getOnOff
     header    
     host       192.168.0.239
     httpheader HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 69
     httpversion 1.0
     hu_blocking 0
     hu_filecount 1
     hu_port    8050
     hu_portSfx :8050
     ignoreredirects 1
     loglevel   4
     path       /getOnOff
     protocol   http
     redirects  0
     timeout    2
     url        http://192.168.0.239:8050/getOnOff
     sslargs:
   QUEUE:
   READINGS:
     2024-06-26 19:17:33   MaxPower        800
     2024-06-26 19:17:35   alarm_dc1_short 0
     2024-06-26 19:17:35   alarm_dc2_short 0
     2024-06-26 19:17:35   alarm_off_grid  0
     2024-06-26 19:17:35   alarm_output_fault 0
     2024-06-26 18:42:29   data_e1         2.34926
     2024-06-26 18:43:28   data_te2        9.44186
     2024-06-26 19:17:36   disabled        0
     2024-06-26 19:17:34   e1              2.37682
     2024-06-26 19:17:34   e2              2.36145
     2024-06-26 19:17:34   energy_month    18.62209
     2024-06-26 19:17:34   energy_today    4.73827
     2024-06-26 19:17:34   p1              36
     2024-06-26 19:17:34   p2              58
     2024-06-26 19:17:34   te1             9.11817
     2024-06-26 19:17:34   te2             9.50392
     2024-06-26 19:17:34   total_energy    18.62209
     2024-06-26 19:17:34   total_energy_today 4.73827
     2024-06-26 19:17:34   total_power     94
Ärgert mich, dass mir das nicht selber aufgefallen ist. Manchmal sieht man eben den Wald vor lauter Bäumen nicht  :)
Viele sonnige Grüße
René

huri-kane

Dafür ist das Forum doch auch da: Als Wegweiser zum Wald ;). Freut mich, dass es geklappt hat.

Reepa

Ich alles soweit aber bei dem code weiß ich nicht wie ich es machen soll da klappt eine Zeile nach der anderen nicht. Kann mir hier jemand helfen?

define EZ1_inverter_tag at *00:00:00 {\
  my $NAME = "EZ1_inverter";;\
  my $total_energy = ReadingsVal($NAME, "total_energy", 0);;\
  my $energy_today = ReadingsVal($NAME, "energy_today", 0);;\
  fhem("setreading $NAME energy_today 0");;\
  fhem("setreading $NAME energy_yesterday $energy_today");;\
  fhem("setreading $NAME total_energy_yesterday $total_energy");;\
  if ( (strftime("%d", localtime(time()) ) ) eq "01")  # 1. des Monats\
  {\
    my $energy_month = ReadingsVal($NAME, "energy_month", 0);;\
    fhem("setreading $NAME energy_month 0");;\
    fhem("setreading $NAME energy_lastmonth $energy_month");;\
    fhem("setreading $NAME total_energy_lastmonth $total_energy");;\
  }\
}

huri-kane

Da gibt es zwei Möglichkeiten:

  • Variante 1
    Du verbindest dich per Telnet zum FHEM server (sofern aktiviert, "telnet localhost 7072") und fügst den Abschnitt per copy&paste ein.
  • Variante 2
    Du legst das "at" Device in der Web-Oberfläche erst einmal ohne Inhalt an:
    define ET1_inverter_tag at *00:00:00 { }
    Im Anschluss editierst Du das "DEF" Internal und fügst den Block zwischen die geschweiften Klammern - ersetze dann allerdings das ";;\" mit ";" bzw. lösche die "\".

Grüße
André