Echtzeit-Auslesung APSystems in Domoticz
Wir sind seit kurzem stolze Besitzer von Sonnenkollektoren. Denn der Energieverbrauch wurde bereits erfasst Domoticz und bin nicht für verschiedene Portale/Apps um den Überblick zu behalten, ich wollte auch den Ertrag der Solarpanels angezeigt bekommen Domoticz.
Nachdem der Lieferant alle Paneele auf dem Dach montiert hatte und die Anlage lief, fragte ich, ob die ECU-R auch per ausgelesen werden könne Domoticz. Leider stellte sich dieser als abgeschirmt heraus. Aber es gab eine App (EMA App) und eine Internetportal mit der man den Verbrauch ablesen konnte. Beide Optionen führten zu einer Verzögerung von etwa fünf Minuten. Es gab auch die ECUAPP. Durch Klicken auf die Seite des Routers sendet dieser eine Stunde lang ein WLAN-Signal. Indem Sie Ihr Telefon/Tablet mit diesem WLAN-Hotspot verbinden, können Sie die Echtzeitwerte mit der ECUAPP auslesen.
an Tweakers.net hätten sie es auch herausgefunden und einige kluge Köpfe waren bereits damit beschäftigt, einen Großteil der Daten über ein Python-Skript auszulesen. Zu beachten ist, dass dies nur via funktioniert W-lan.
Eine Reihe von Tweakers-Mitgliedern verwenden Home Assistant. Das Plug-in muss daher (geringfügig) angepasst werden, damit es für Domoticz verwendet werden kann.
PIugin installieren
Zusätzlich zum unten stehenden Code haben Sie auch die Stecker-in die von Github heruntergeladen werden kann.
Um die Python-Skripte auf dem Raspberry Pi ausführen zu können Python 3.x installiert werden.
#!/usr/bin/env python3 from APSystemsECUR import APSystemsECUR import time import asyncio import urllib.request import urllib.parse import urllib from pprint import pprint ecu_ip = " "schlaf = 300 url = ' :8080/json.htm?' Semikolon = '\u003B' loop = asyncio.get_event_loop() ecu = APSystemsECUR(ecu_ip) while True: try: data = loop.run_until_complete(ecu.async_query_ecu()) print(data) lifetime_energy = str(data.get('lifetime_energy ')*1000) today_energy_kwh = str(data.get('today_energy')*1000) current_power = str(data.get('current_power')) print('current_power: ' + current_power) generic_energy = (current_power + Semikolon + Lifetime_energy ) print('output: ' + today_energy_kwh + ';' + current_power) #pwr = .format(today_energy_kwh, current_power) #print('PWR: ' + pwr) print('Heute Energie [kWh]: ' + today_energy_kwh) if (float (today_energy_kwh) >= 0 oder float(current_power) >= 0): getVars = {'type': 'command', 'param': 'udevice', 'nvalue': 0, 'idx': 1606, 'svalue' : (generated_energy)} webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars)) print(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0') getVars = {'type ' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': 1610, 'svalue': data.get('timestamp')} webUrl = urllib.request.urlopen(url + urllib .parse.urlencode(getVars)) #print(url + urllib.parse.urlencode(getVars)) #inverter-Werte inverters = data.get('inverters') #count Anzahl der Wechselrichter Inverter_qty = len(data.get('inverters' )) print('Inverter_cnt: ' + str(Inverter_qty)) # Schleife durch alle Wechselrichter und ruft die Daten für i in range(Inverter_qty) ab: Inverter = list(inverters.keys())[i] print('InverterId: ' + Inverter ) InverterOnline = data['inverters'][Inverter]['online'] print('Online: ' + str(InverterOnline)) InverterTemperature = data['inverters'][Inverter]['temperature'] print(' Temperatur: ' + str(InverterTemperature)) nVoltage = len(data['inverters'][Inverter]['volt']) nPower = len(data['inverters'][Inverter]['power']) für x in Bereich( nLeistung): Spannung = Daten['Wechselrichter'][Wechselrichter]['Spannung'][x] Leistung = Daten['Wechselrichter'][Wechselrichter]['Leistung'][x] print('Wechselrichter ' + str( i + 1) + ' panel ' + str(x + 1) + ': ' + str(power) + ' W') #Werte nach Domoticz für Wechselrichter 1 hochladen, wenn (i == 0) und (x == 0): getVars = {'type': 'command', 'param': 'udevice', 'nvalue': 0, 'idx': 1624, 'svalue': Spannung} webUrl = urllib.request.urlopen( url + urllib. parse.urlencode(getVars)) getVars = {'type': 'command', 'param': 'udevice', 'nvalue': 0, 'idx': 1609, 'svalue': InverterTemperature} webUrl = urllib.request. urlopen(url + urllib.parse.urlencode(getVars)) if (InverterOnline == True) and (Voltage != 0) : getVars = { 'type' : 'command', 'param' : 'switchlight' , 'idx': 1607, 'switchcmd': 'On', 'level': 0, 'passcode': '' } webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars)) elif (InverterOnline == True) und (Spannung == 0): getVars = { 'type': 'command', 'param': 'switchlight', 'idx': 1607, 'switchcmd': 'Off', 'level': 0 , 'passcode' : '' } webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars)) else : getVars = {'type' : 'command', 'param' : 'switchlight', 'idx ': 1607, 'switchcmd': 'Off', 'level': 0, 'passcode': '' } webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars)) #Werte nach Domoticz hochladen für Wechselrichter 2, wenn (i == 1) und (x == 0): getVars = {'type': 'command', 'param': 'udevice', 'nvalue': 0, 'idx': 1614, ' svalue': InverterTemperature} webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars)) if (InverterOnline == True) and (spannung != 0) : getVars = { 'type' : 'command', 'param': 'switchlight', 'idx': 1611, 'switchcmd': 'On', 'level': 0, 'passcode': '' } webUrl = urllib.request.urlopen(url + urllib.parse.urlencode (getVars)) elif ( InverterOnline == True) und (Spannung == 0): getVars = { 'type' : 'command', 'param' : 'switchlight', 'idx': 1611, 'switchcmd': 'Off ', 'level': 0, 'passcode': '' } webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars)) else : getVars = {'type' : 'command', 'param' : 'switchlight', ' idx': 1611, 'switchcmd': 'Off', 'level': 0, 'passcode': '' } webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) ) #Werte nach Domoticz für Wechselrichter 3 hochladen, wenn (i == 2) und (x == 0) : getVars = { 'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': 1615, 'svalue ': InverterTemperature} webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars)) if (InverterOnline == True) and (spannung != 0) : getVars = {' type': 'command', ' param': 'switchlight', 'idx': 1612, 'switchcmd': 'On', 'level': 0, 'passcode': '' } webUrl = urllib.request.urlopen( url + urllib.parse.urlencode( getVars)) elif (InverterOnline == True) und (Spannung == 0): getVars = { 'type': 'command', 'param': 'switchlight', 'idx': 1612 , 'switchcmd' : 'Off' , 'level': 0, 'passcode': '' } webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars)) else : getVars = {'type' : 'command', 'param': 'switchlight', 'idx': 1612, 'switchcmd': 'Off', 'level': 0, 'passcode': '' } webUrl = urllib.request.urlopen(url + urllib .parse.urlencode(getVars)) #Werte nach Domoticz für Wechselrichter 4 hochladen, wenn (i == 3) und (x == 0) : getVars = {'type' : 'command', 'param' : 'udevice' , 'nvalue' : 0, 'idx' : 1616, 'svalue': InverterTemperature} webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars)) if (InverterOnline == True) und (Spannung != 0): getVars = {'type': 'command', 'param': 'switchlight', 'idx': 1613, 'switchcmd': 'On', 'level': 0, 'passcode': '' } webUrl = urllib.request.urlopen(url + urllib .parse.urlencode(getVars)) elif (InverterOnline == True) und (Spannung == 0) : getVars = { 'type' : 'command', 'param' : 'switchlight ', 'idx': 1613, 'switchcmd ': 'Off', 'level': 0, 'passcode': '' } webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars)) else: getVars = {'type': 'command', 'param': 'switchlight', 'idx': 1613, 'switchcmd': 'Off', 'level': 0, 'passcode': '' } webUrl = urllib. request.urlopen(url + urllib.parse. urlencode(getVars)) #Leistungswerte nach Domoticz für Wechselrichter 1 hochladen, wenn (i == 0) und (x == 0) : getVars = {'type' : 'command' , 'param': 'udevice', 'nvalue': 0, 'idx': 1608, 'svalue': (power)} webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon ) + '0') elif (i == 0 ) und (x == 1): getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx' : 1617, 'svalue' : (power)} webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0') elif (i == 0) und (x == 2 ) : getVars = {'type' : 'command' , 'param' : 'udevice', 'nvalue' : 0, 'idx': 198, 'svalue': (power)} webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0') elif (i == 0) und (x == 3) : getVars = { 'type' : 'command', 'param' : 'udevice ', 'nvalue': 0, 'idx': 199, 'svalue': (power)} webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0') #upload Leistungswerte an Domoticz für Wechselrichter 2, wenn (i == 1) und (x == 0): getVars = {'type': 'command', 'param': 'udevice', 'nvalue': 0, ' idx': 1618, 'svalue': (power)} webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0') elif (i == 1) und (x == 1) : getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': 1619, 'svalue': (power)} webUrl = urllib.request. urlopen(url + urllib.parse.urlencode(getVars) + ( Semikolon) + '0') elif (i == 1) und (x == 2) : getVars = { 'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx' : 202, 'svalue': (power)} webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0 ') elif (i == 1) und (x == 3): getVars = {'type': 'command', 'param': 'udevice', 'nvalue': 0, 'idx': 203, 'svalue ' : (Leistung)} webUrl = urllib.request.urlopen( url + urllib.parse.urlencode(getVars) + (Semikolon) + '0') #Leistungswerte nach Domoticz für Wechselrichter 3 hochladen, wenn (i == 2) und (x == 0) : getVars = {'type' : ' command', 'param' : 'udevice', 'nvalue' : 0, 'idx': 1620, 'svalue': (power)} webUrl = urllib .request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0') elif (i == 2) und (x == 1) : getVars = { 'type' : 'command', 'param': 'udevice', 'nvalue': 0, 'idx': 1621, 'svalue': (power)} webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0') elif (i == 2) und (x = = 2) : getVars = { 'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx' : 206 , 'svalue' : (power)} webUrl = urllib.request.urlopen (url + urllib.parse.urlencode(getVars) + (Semikolon) + '0') elif (i == 2) und (x == 3) : getVars = {'type': 'command', 'param': 'udevice', 'nvalue': 0, 'idx': 207, 'svalue': (power)} webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0' ) #Leistungswerte nach Domoticz für Wechselrichter 4 hochladen, wenn (i == 3) und (x == 0) : getVars = {'type' : ' command', 'param': 'udevice', 'nvalue': 0, ' idx': 1622, 'svalue': (power)} webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0') elif (i == 3) und (x == 1): getVars = {'type': 'command', 'param': 'udevice', 'nvalue': 0, 'idx ' : 1623, 'svalue' : (power)} webUrl = urllib.request. urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0') elif (i == 3) und (x = = 2) : getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': 210, 'svalue': (power)} webUrl = urllib.request.urlopen (url + urllib.parse.urlencode(getVars) + (Semikolon) + '0 ') elif (i == 3) und (x == 3): getVars = { 'type': 'command', 'param': 'udevice', 'nvalue': 0, 'idx': 211, 'svalue': (power)} webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0' ) außer Ausnahme als err: print(f"[ERROR]", {err} ) #print(f"Sleeping for {sleep} sec") time.sleep(sleep)
- Platzieren Sie das Plug-in und das obige Skript in Ihrem Domoticz-Ordner unter scripts/python/ECU-R.
- Erstellen Sie einen Dummy-Sensor in Domoticz und nennen Sie ihn „Virtuelle Schalter“ oder einen anderen eindeutigen Namen.
Dummy-Sensoren in Domoticz hinzufügen
- Erstellen Sie einen virtuellen Sensor vom Typ 'Elektra (Ist + Zähler)'. Geben Sie dem Sensor den Namen „Generation von Sonnenkollektoren“.
- Erstellen Sie einen virtuellen Sensor vom Typ „Switch“ und nennen Sie ihn Inverter [Wechselrichternummer].
- Wiederholen Sie diesen Schritt für die Anzahl Ihrer Mikro-Wechselrichter.
- Erstellen Sie einen virtuellen Sensor vom Typ „Verbrauch (Strom)“ und nennen Sie ihn Wechselrichter [Wechselrichternummer]-Leistung [Plattennummer].
- Wiederholen Sie diesen Schritt für die Anzahl der Panels pro Mikrowechselrichter.
- Erstellen Sie einen virtuellen Sensor vom Typ „Temperature“ und nennen Sie ihn Inverter [Wechselrichternummer] – Temperatur.
- Wiederholen Sie diesen Schritt für die Anzahl Ihrer Mikro-Wechselrichter.
- Erstellen Sie einen virtuellen Sensor vom Typ „Text“ und nennen Sie ihn Timestamp.
- Gehen Sie zu 'Geräte' und passen Sie die idxes im obigen Skript an die idx der virtuellen Sensoren an, die Sie gerade erstellt haben, und speichern Sie das Skript.
- Starten Sie das Skript mit dem Befehl
Python3 /scripts/python/ECU-R/ECU-R.py
. - Damit das Skript automatisch nach jedem Neustart des Raspberry Pi startet, fügen Sie die folgende Zeile hinzu Crontab:
@reboot python3 /home/pi/domoticz/scripts/python/ECU-R/ECU-R.py
.
Aktualisierung 25.01.2023
Benutzer Sebastiaan Terlouw hat das Skript leicht modifiziert, sodass es nun auch mit dem DS3-Controller kompatibel ist.
Update 15.02.2023
Sebastiaan Terlouw hat das Drehbuch um die Netzspannung ergänzt.
Teilen mit:
- Klick, um über Twitter zu teilen (Wird in neuem Fenster geöffnet)
- Klick, um auf Facebook zu teilen (Wird in neuem Fenster geöffnet)
- Mehr
- Klicken, um einem Freund einen Link per E-Mail zu senden (Wird in neuem Fenster geöffnet)
- Klick, um auf LinkedIn zu teilen (Wird in neuem Fenster geöffnet)
- Klick, um auf Reddit zu teilen (Wird in neuem Fenster geöffnet)
- Klick, um auf Tumblr zu teilen (Wird in neuem Fenster geöffnet)
- Klicken, um auf Telegram zu teilen (Wird in neuem Fenster geöffnet)
- Klicken, um auf WhatsApp zu teilen (Wird in neuem Fenster geöffnet)
Hallo,
Wenn ich das Skript ausführe, erhalte ich diesen Fehler:
[FEHLER] {TypeError(“Objekt vom Typ „NoneType“ hat kein len()“)}
Irgendeine Idee, was los ist?
Hallo JulienG,
Wahrscheinlich enthalten die variablen Daten keine Daten. Sie können dies testen, indem Sie den folgenden Code dazwischen einfügen
data = loop.run_until_complete(ecu.async_query_ecu()) und print(data)
Das sind Zeile 23 und 24.
wenn die Daten nicht None sind:
# Führen Sie den Rest des Codes aus, der von den Daten abhängt
lifetime_energy = str(data.get('lifetime_energy')1000)
today_energy_kwh = str(data.get('today_energy')1000)
current_power = str(data.get('current_power'))
# und so weiter…
anders:
print(„[FEHLER] Keine Daten vom Steuergerät empfangen“)
Hallo,
Ich verwende das Skript, aber es zeigt nur einen Wechselrichter an.
Haben Sie alle Wechselrichter in Domoticz hergestellt? Und funktioniert der gesamte idx-Korrespondent in Ihrem Skript?
Hallo,
Ja, ich bin es, es stimmt mit meinem idx überein, das Skript zeigt keine Fehlermeldung an, es macht nur den Schlaf.
Hallo Björn,
Ich benutze das Skript seit ungefähr einem halben Jahr und es hat perfekt funktioniert, nochmals vielen Dank!
Aber seit 2 Tagen habe ich einen Fehler, der es nicht mehr funktionieren lässt, vielleicht hat jemand eine Idee?
Danke im Voraus.
[ERROR] {APSystemsInvalidData(“Binärdatei kann nicht in int umgewandelt werden location=184 data=b'4150533131 etc long string
Hallo Paul,
Es scheint, dass die Daten (oder ein Teil der Daten) von den Wechselrichtern nicht konvertiert werden können. Sie können dies testen, indem Sie das Skript manuell starten (z. B. in einer Windows-Umgebung) und überprüfen, wie die Werte eingehen und welche Werte korrekt eingehen.
Alles funktioniert wieder Björn, danke für den Tipp!
Hallo Björn,
Vielen Dank, dass Sie Ihre Informationen geteilt haben.
Leider bleibe ich beim nächsten Schritt hängen: „Gehe zu ‚Geräte‘ und passe die idx im obigen Skript an die idx der gerade erstellten virtuellen Sensoren an und speichere das Skript.“
Die Sensoren, die ich in Domoticz erstellt habe, haben Nummern von 43 bis 67. Soll ich diese als IDXs betrachten und im bereits gespeicherten ECU-R.py-Skript mit VI anpassen / füllen? Wo im Skript?
Grüße,
Anton
Hallo Anton,
Jedes Gerät hat seine eigene IDX (Identifikationsnummer).
Das Skript, das mit #!/usr/bin/env python3 beginnt, sollte im selben Verzeichnis wie das Skript ECU-R.py gespeichert werden. Anschließend passen Sie mit einem Editor (z. B. Nano oder VI) die idxes im Skript an die idxes an, die Ihre Geräte haben.
Gruß,
Björn
Hallo Björn, heute gab es ein Update auf Domoticz 2023.1
Diese Version wird standardmäßig mit (admin) Benutzer und Passwort bereitgestellt.
Seitdem funktioniert das Skript ECU-R.py nicht mehr (HTTPError 401: 'Unauthorized'
Wissen Sie, ob es möglich ist, hier Zugangsdaten anzugeben?
Funktioniert seit einem Jahr einwandfrei.
Grüße Willem van Oosterhout
Hallo Willem,
Ich habe Domoticz nicht mehr am Laufen (ich müsste es zum Testen neu installieren). Aber können Sie nicht anhand einer (lokalen) IP-Adresse angeben, dass Sie sich nicht anmelden müssen? Weitere Informationen finden Sie im Wiki Domoticz.
Kann es leider noch nicht finden.
Dann zurück zur vorherigen Version.
Ich danke Ihnen für Ihre Antwort.
Idd möglich, lokales Netzwerk als vertrauenswürdig anzugeben, funktioniert wieder. Danke schön!
Super. Viel Glück und viel Spaß mit den Panels!
und dein Skript etwas modifiziert
Ich habe gesehen, dass er bei mir 4 Controller x 2 Panels hat.
dass er eine Switch 16x umgebaut hat, während das mit 4x auch ausreichte:
Der Controller wird in Domoticz auch auf "Aus" gesetzt, wenn die Temperatur 0 ist (weil ich sehe, dass dies passiert, wenn der Controller ausgeschaltet wird).
#!/usr/bin/env python3
von APSystemsECUR import APSystemsECUR
Importzeit
asyncio importieren
import urllib.request
import urllib.parse
urllib importieren
aus pprint import pprint
ecu_ip = "192.168.0.80"
Schlepp = 300
url = 'http://192.168.0.200:8080/json.htm?'
Semikolon = '\u003B'
loop = asyncio.get_event_loop()
ecu = APSystemsECUR(ecu_ip)
whileTrue:
Versuchen:
data = loop.run_until_complete(ecu.async_query_ecu())
#pprint(Daten)
lifetime_energy = str(data.get('lifetime_energy')*1000)
heute_energie_kwh = str(data.get('heute_energie')*1000)
aktuelle_leistung = str(data.get('aktuelle_leistung'))
print('aktuelle_Leistung: ' + aktuelle_Leistung)
generierte_energie = (aktuelle_leistung + semikolon + lebensdauer_energie)
print('output: ' + today_energy_kwh + ';' + current_power)
#pwr = .format(heute_energie_kwh, aktuelle_leistung)
#print('PWR: ' + pwr)
print('Heute Energie [kWh]: ' + heute_Energie_kwh)
if (float(today_energy_kwh) >= 0 or float(current_power) >= 0):
getVars = { 'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx' : 1606, 'svalue' : (generated_energy)}
webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars))
print(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0')
getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': 1610, 'svalue': data.get('timestamp')}
webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars))
#print(url + urllib.parse.urlencode(getVars))
#Wechselrichterwerte
Wechselrichter = data.get('Wechselrichter')
#count Anzahl Wechselrichter
Inverter_qty = len(data.get('inverters'))
print('Inverter_cnt: ' + str(Inverter_qty))
# durchschleift alle Wechselrichter und holt sich die Daten
für i im Bereich (Inverter_qty):
Inverter = list(inverters.keys())[i]
print('WechselrichterId: ' + Wechselrichter)
WechselrichterOnline = data['Wechselrichter'][Wechselrichter]['online']
print('Online: ' + str(WechselrichterOnline))
InverterTemperature = data['inverters'][Inverter]['temperature']
print('Temperatur: ' + str(Wechselrichtertemperatur))
nPower = len(data['Wechselrichter'][Wechselrichter]['Leistung'])
für x im Bereich (nPower):
Leistung = Daten['Wechselrichter'][Wechselrichter]['Leistung'][x]
print('Wechselrichter ' + str(i + 1) + 'panel ' + str(x + 1) + ': ' + str(power) + 'W')
#Upload-Werte zu Domoticz für Wechselrichter 1
wenn (i == 0) und (x == 0) :
getVars = { 'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx' : 1609, 'svalue' : InverterTemperature}
webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars))
wenn InverterOnline == True :
getVars = { 'type' : 'command', 'param' : 'switchlight', 'idx': 1607, 'switchcmd': 'On', 'level': 0, 'passcode': '' }
webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars))
anders :
getVars = { 'type' : 'command', 'param' : 'switchlight', 'idx': 1607, 'switchcmd': 'Off', 'level': 0, 'passcode': '' }
webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars))
#Upload-Werte zu Domoticz für Wechselrichter 2
wenn (i == 1) und (x == 0) :
getVars = { 'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx' : 1614, 'svalue' : InverterTemperature}
webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars))
wenn InverterOnline == True :
getVars = { 'type' : 'command', 'param' : 'switchlight', 'idx': 1611, 'switchcmd': 'On', 'level': 0, 'passcode': '' }
webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars))
anders :
getVars = { 'type' : 'command', 'param' : 'switchlight', 'idx': 1611, 'switchcmd': 'Off', 'level': 0, 'passcode': '' }
webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars))
#Upload-Werte zu Domoticz für Wechselrichter 3
wenn (i == 2) und (x == 0) :
getVars = { 'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx' : 1615, 'svalue' : InverterTemperature}
webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars))
wenn InverterOnline == True :
getVars = { 'type' : 'command', 'param' : 'switchlight', 'idx': 1612, 'switchcmd': 'On', 'level': 0, 'passcode': '' }
webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars))
anders :
getVars = { 'type' : 'command', 'param' : 'switchlight', 'idx': 1612, 'switchcmd': 'Off', 'level': 0, 'passcode': '' }
webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars))
#Upload-Werte zu Domoticz für Wechselrichter 4
wenn (i == 3) und (x == 0) :
getVars = { 'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx' : 1616, 'svalue' : InverterTemperature}
webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars))
wenn InverterOnline == True :
getVars = { 'type' : 'command', 'param' : 'switchlight', 'idx': 1613, 'switchcmd': 'On', 'level': 0, 'passcode': '' }
webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars))
anders :
getVars = { 'type' : 'command', 'param' : 'switchlight', 'idx': 1613, 'switchcmd': 'Off', 'level': 0, 'passcode': '' }
webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars))
#Leistungswerte für Wechselrichter 1 an Domoticz hochladen
wenn (i == 0) und (x == 0) :
getVars = { 'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx' : 1608, 'svalue' : (power)}
webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0')
elif (i == 0) und (x == 1) :
getVars = { 'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx' : 1617, 'svalue' : (power)}
webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0')
#elif (i == 0) und (x == 2) :
#getVars = { 'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx' : 198, 'svalue' : (power)}
#webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0')
#elif (i == 0) und (x == 3) :
#getVars = { 'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx' : 199, 'svalue' : (power)}
#webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0')
#Upload Leistungswerte zu Domoticz für Wechselrichter 2
wenn (i == 1) und (x == 0) :
getVars = { 'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx' : 1618, 'svalue' : (power)}
webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0')
elif (i == 1) und (x == 1) :
getVars = { 'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx' : 1619, 'svalue' : (power)}
webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0')
#elif (i == 1) und (x == 2) :
#getVars = { 'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx' : 202, 'svalue' : (power)}
#webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0')
#elif (i == 1) und (x == 3) :
#getVars = { 'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx' : 203, 'svalue' : (power)}
#webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0')
#Upload Leistungswerte zu Domoticz für Wechselrichter 3
wenn (i == 2) und (x == 0) :
getVars = { 'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx' : 1620, 'svalue' : (power)}
webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0')
elif (i == 2) und (x == 1) :
getVars = { 'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx' : 1621, 'svalue' : (power)}
webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0')
#elif (i == 2) und (x == 2) :
#getVars = { 'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx' : 206, 'svalue' : (power)}
#webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0')
#elif (i == 2) und (x == 3) :
#getVars = { 'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx' : 207, 'svalue' : (power)}
#webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0')
#Upload Leistungswerte zu Domoticz für Wechselrichter 4
wenn (i == 3) und (x == 0) :
getVars = { 'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx' : 1622, 'svalue' : (power)}
webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0')
elif (i == 3) und (x == 1) :
getVars = { 'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx' : 1623, 'svalue' : (power)}
webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0')
#elif (i == 3) und (x == 2) :
#getVars = { 'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx' : 210, 'svalue' : (power)}
#webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0')
#elif (i == 3) und (x == 3) :
#getVars = { 'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx' : 211, 'svalue' : (power)}
#webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (Semikolon) + '0')
Ausnahme als Fehler:
print(f"[FEHLER]", {err})
#print(f"Schlafen für {sleep} sec")
time.sleep (Schlaf)
APSystemsECUR angepasst, um mit dem DS3-Controller kompatibel zu sein:
#!/usr/bin/env python3
asyncio importieren
Steckdose importieren
binascii importieren
datetime importieren
json importieren
Protokollierung importieren
_LOGGER = Protokollierung.getLogger (Name)
aus pprint import pprint
Klasse APSystemsInvalidData (Ausnahme):
passieren
Klasse APSystemsECUR:
def __init__(self, ipaddr, port=8899, raw_ecu=Keine, raw_inverter=Keine):
self.ipaddr = ipaddr
self.port = Port
#, was wir erwarten, dass Socket-Daten enden
self.recv_suffix = b'END\n'
# wie lange auf Socket-Befehle gewartet werden soll, bis wir unser recv_suffix erhalten
self.timeout = 5
# wie oft versuchen wir denselben Befehl in einem einzelnen Update, bevor er fehlschlägt
self.cmd_attempts = 3
#, wie groß der Puffer ist, der gleichzeitig aus dem Socket gelesen werden soll
self.recv_size = 4096
self.qs1_ids = [ "802", "801" ]
self.yc600_ids = [ "406", "407", "408", "409" ]
self.yc1000_ids = [ "501", "502", "503", "504" ]
self.ds3_ids = [ "703", "704" ]
self.cmd_suffix = "END\n"
self.ecu_query = "APS1100160001" + self.cmd_suffix
self.inverter_query_prefix = "APS1100280002"
self.inverter_query_suffix = self.cmd_suffix
self.inverter_signal_prefix = "APS1100280030"
self.inverter_signal_suffix = self.cmd_suffix
self.inverter_byte_start = 26
self.ecu_id = Keine
self.qty_of_inverters = 0
self.lifetime_energy = 0
self.current_power = 0
self.today_energy = 0
self.inverters = []
self.firmware = Keine
self.timezone = Keine
self.last_update = Keine
self.ecu_raw_data = raw_ecu
self.inverter_raw_data = raw_inverter
self.inverter_raw_signal = Keine
self.read_buffer = b''
self.reader = Keine
self.writer = Keine
def Dump (selbst):
print(f"ECU: {self.ecu_id}")
print(f"Firmware: {self.firmware}")
print(f"TZ : {self.timezone}")
print(f"Anzahl Wechselrichter : {self.qty_of_inverters}")
async def async_read_from_socket(self):
self.read_buffer = b''
end_data = Keine
while end_data != self.recv_suffix:
self.read_buffer += warte auf self.reader.read (self.recv_size)
size = len(self.read_buffer)
end_data = self.read_buffer[Größe-4:]
self.read_buffer zurückgeben
async def async_send_read_from_socket(self, cmd):
aktueller_versuch = 0
while aktueller_versuch < self.cmd_versuche:
aktueller_versuch += 1
self.writer.write(cmd.encode('utf-8'))
warte auf self.writer.drain()
Versuchen:
return await asyncio.wait_for(self.async_read_from_socket(),
timeout=self.timeout)
Ausnahme als Fehler:
passieren
self.writer.close()
raise APSystemsInvalidData(f"Unvollständige Daten von ECU nach {current_attempt} Versuchen, cmd='{cmd.rstrip()}' data={self.read_buffer}")
async def async_query_ecu(self):
self.reader, self.writer = warte auf asyncio.open_connection (self.ipaddr, self.port)
_LOGGER.info(f"Verbunden mit {self.ipaddr} {self.port}")
cmd = self.ecu_query
self.ecu_raw_data = warte auf self.async_send_read_from_socket(cmd)
self.process_ecu_data()
cmd = self.inverter_query_prefix + self.ecu_id + self.inverter_query_suffix
self.inverter_raw_data = erwarte self.async_send_read_from_socket(cmd)
cmd = self.inverter_signal_prefix + self.ecu_id + self.inverter_signal_suffix
self.inverter_raw_signal = warte auf self.async_send_read_from_socket(cmd)
self.writer.close()
data = self.process_inverter_data()
data["ecu_id"] = self.ecu_id
data["heute_energie"] = self.heute_energie
data["Lebensenergie"] = self.Lebensenergie
data["aktuelle_leistung"] = self.aktuelle_leistung
Rückgabe (Daten)
def query_ecu(selbst):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((self.ipadr,self.port))
sock.sendall(self.ecu_query.encode('utf-8'))
self.ecu_raw_data = sock.recv(self.recv_size)
self.process_ecu_data()
cmd = self.inverter_query_prefix + self.ecu_id + self.inverter_query_suffix
sock.sendall(cmd.encode('utf-8'))
self.inverter_raw_data = sock.recv(self.recv_size)
cmd = self.inverter_signal_prefix + self.ecu_id + self.inverter_signal_suffix
sock.sendall(cmd.encode('utf-8'))
self.inverter_raw_signal = sock.recv(self.recv_size)
socket.shutdown(socket.SHUT_RDWR)
socke.schließen()
data = self.process_inverter_data()
data["ecu_id"] = self.ecu_id
data["heute_energie"] = self.heute_energie
data["Lebensenergie"] = self.Lebensenergie
data["aktuelle_leistung"] = self.aktuelle_leistung
Rückgabe (Daten)
def aps_int(selbst, Codec, Start):
Versuchen:
return int(binascii.b2a_hex(codec[(start):(start+2)]), 16)
außer ValueError als Fehler:
debugdata = binascii.b2a_hex(codec)
raise APSystemsInvalidData(f"Binärdatei kann nicht in int konvertiert werden location={start} data={debugdata}")
def aps_short(selbst, Codec, Start):
Versuchen:
return int(binascii.b2a_hex(codec[(start):(start+1)]), 8)
außer ValueError als Fehler:
debugdata = binascii.b2a_hex(codec)
raise APSystemsInvalidData(f"Kann binär nicht in short int konvertieren location={start} data={debugdata}")
def aps_double(selbst, Codec, Start):
Versuchen:
return int (binascii.b2a_hex(codec[(start):(start+4)]), 16)
außer ValueError als Fehler:
debugdata = binascii.b2a_hex(codec)
raise APSystemsInvalidData(f"Binärdatei kann nicht in Double umgewandelt werden location={start} data={debugdata}")
def aps_bool(selbst, Codec, Start):
return bool(binascii.b2a_hex(codec[(start):(start+2)]))
def aps_uid(selbst, Codec, Start):
return str(binascii.b2a_hex(codec[(start):(start+12)]))[2:14]
def aps_str(selbst, Codec, Start, Menge):
return str(codec[start:(start+betrag)])[2:(betrag+2)]
def aps_timestamp(selbst, Codec, Start, Menge):
timestr=str(binascii.b2a_hex(codec[Start:(Start+Menge)]))[2:(Menge+2)]
return timestr[0:4]+"-"+timestr[4:6]+"-"+timestr[6:8]+" "+timestr[8:10]+":"+timestr[10:12] +":"+timestr[12:14]
def check_ecu_checksum(selbst, Daten, cmd):
datalen = len(data) - 1
Versuchen:
Prüfsumme = int(data[5:9])
außer ValueError als Fehler:
debugdata = binascii.b2a_hex(daten)
raise APSystemsInvalidData(f"Fehler beim Abrufen der Prüfsumme int von '{cmd}' data={debugdata}")
if data != Prüfsumme:
debugdata = binascii.b2a_hex(daten)
raise APSystemsInvalidData(f"Checksum on '{cmd}' failed checksum={checksum} data={data} data={debugdata}")
start_str = self.aps_str (Daten, 0, 3)
end_str = self.aps_str(data, len(data) - 4, 3)
if start_str != 'APS':
debugdata = binascii.b2a_hex(daten)
raise APSystemsInvalidData(f"Ergebnis auf '{cmd}' falsche Startsignatur '{start_str}' != APS data={debugdata}")
if end_str != 'ENDE':
debugdata = binascii.b2a_hex(daten)
raise APSystemsInvalidData(f"Ergebnis auf '{cmd}' falsche Endsignatur '{end_str}' != END data={debugdata}")
returnTrue
def process_ecu_data(self, data=None):
wenn nicht termine:
data = self.ecu_raw_data
self.check_ecu_checksum(data, "ECU-Abfrage")
self.ecu_id = self.aps_str (Daten, 13, 12)
self.qty_of_inverters = self.aps_int(data, 46)
self.firmware = self.aps_str(data, 55, 15)
self.timezone = self.aps_str(data, 70, 9)
self.lifetime_energy = self.aps_double(data, 27) / 10
self.today_energy = self.aps_double(data, 35) / 100
self.current_power = self.aps_double(data, 31)
def process_signal_data(self, data=None):
signal_data = {}
wenn nicht termine:
Daten = self.inverter_raw_signal
self.check_ecu_checksum(data, "Signalabfrage")
wenn nicht self.qty_of_inverters:
Signaldaten zurückgeben
Ort = 15
für i in range(0, self.qty_of_inverters):
uid = self.aps_uid (Daten, Standort)
Standort += 6
Stärke = Daten[Standort]
Standort += 1
Stärke = int((Stärke / 255) * 100)
signal_data[uid] = Stärke
Signaldaten zurückgeben
def process_inverter_data(self, data=None):
wenn nicht termine:
Daten = self.inverter_raw_data
self.check_ecu_checksum(data, "Wechselrichterdaten")
Ausgabe = {}
Zeitstempel = self.aps_timestamp (Daten, 19, 14)
Inverter_qty = self.aps_int (Daten, 17)
self.last_update = Zeitstempel
Ausgabe["Zeitstempel"] = Zeitstempel
Ausgang["Wechselrichter_Menge"] = Wechselrichter_Menge
Ausgang["Wechselrichter"] = {}
# Dies ist der Beginn der Wechselrichterschleife
location = self.inverter_byte_start
signal = self.process_signal_data()
Wechselrichter = {}
für i im Bereich (0, Inverter_Menge):
inv={}
Inverter_uid = self.aps_uid (Daten, Standort)
inv["uid"] = wechselrichter_uid
Standort += 6
inv["online"] = self.aps_bool(data, location)
Standort += 1
inv["unknown"] = self.aps_str(data, location, 2)
Standort += 2
inv["Frequenz"] = self.aps_int(Daten, Ort) / 10
Standort += 2
inv["temperature"] = self.aps_int(data, location) - 100
Standort += 2
inv["signal"] = signal.get(inverter_uid, 0)
# die ersten 3 Ziffern bestimmen den Typ des Wechselrichters
Invertertyp = Inverter_uid[0:3]
if inverter_type in self.yc600_ids:
(channel_data, location) = self.process_yc600(data, location)
inv.update(channel_data)
elif inverter_type in self.qs1_ids:
(channel_data, location) = self.process_qs1(data, location)
inv.update(channel_data)
elif inverter_type in self.yc1000_ids:
(channel_data, location) = self.process_yc1000(data, location)
inv.update(channel_data)
elif inverter_type in self.ds3_ids:
(channel_data, location) = self.process_ds3(data, location)
inv.update(channel_data)
anders:
raise APSystemsInvalidData(f"Nicht unterstützter Wechselrichtertyp {inverter_type}")
Wechselrichter[inverter_uid] = inv
Ausgang["Wechselrichter"] = Wechselrichter
Rückkehr (Ausgang)
def process_yc1000(self, data, location):
Macht = []
Spannungen = []
power.append (self.aps_int (Daten, Ort))
Standort += 2
Spannung = self.aps_int (Daten, Ort)
Standort += 2
power.append (self.aps_int (Daten, Ort))
Standort += 2
Spannung = self.aps_int (Daten, Ort)
Standort += 2
power.append (self.aps_int (Daten, Ort))
Standort += 2
Spannung = self.aps_int (Daten, Ort)
Standort += 2
power.append (self.aps_int (Daten, Ort))
Standort += 2
Spannungen.append (Spannung)
Ausgabe = {
"Modell": "YC1000",
"channel_qty": 4,
"Macht" : Macht,
"Spannung": Spannungen
}
Rückkehr (Ausgang, Ort)
def process_qs1(self, data, location):
Macht = []
Spannungen = []
power.append (self.aps_int (Daten, Ort))
Standort += 2
Spannung = self.aps_int (Daten, Ort)
Standort += 2
power.append (self.aps_int (Daten, Ort))
Standort += 2
power.append (self.aps_int (Daten, Ort))
Standort += 2
power.append (self.aps_int (Daten, Ort))
Standort += 2
Spannungen.append (Spannung)
Ausgabe = {
"Modell": "QS1",
"channel_qty": 4,
"Macht" : Macht,
"Spannung": Spannungen
}
Rückkehr (Ausgang, Ort)
def process_yc600(self, data, location):
Macht = []
Spannungen = []
für i im Bereich (0, 2):
power.append (self.aps_int (Daten, Ort))
Standort += 2
voltages.append(self.aps_int(data, location))
Standort += 2
Ausgabe = {
"Modell": "YC600",
"channel_qty": 2,
"Macht" : Macht,
"Spannung" : Spannungen,
}
Rückkehr (Ausgang, Ort)
def process_ds3(self, data, location):
Macht = []
Spannungen = []
für i im Bereich (0, 2):
power.append (self.aps_int (Daten, Ort))
Standort += 2
voltages.append(self.aps_int(data, location))
Standort += 2
Ausgabe = {
"Modell": "ds3",
"channel_qty": 2,
"Macht" : Macht,
"Spannung" : Spannungen,
}
Rückkehr (Ausgang, Ort)
Hallo Björn,
Ich erhalte die folgenden Fehlermeldungen.
Wisst ihr was das sein könnte?
Datei „/home/pi/domoticz/scripts/python/ECU-R/ECU-R.py“, Zeile 23, in
data = loop.run_until_complete(ecu.async_query_ecu())
Datei „/usr/lib/python3.7/asyncio/base_events.py“, Zeile 571, in run_until_complete
self.run_forever()
Datei „/usr/lib/python3.7/asyncio/base_events.py“, Zeile 539, in run_forever
self._run_once()
Datei „/usr/lib/python3.7/asyncio/base_events.py“, Zeile 1775, in _run_once
handle._run()
Datei „/usr/lib/python3.7/asyncio/events.py“, Zeile 88, in _run
self._context.run(self._callback, *self._args)
Datei „/home/pi/domoticz/scripts/python/ECU-R/APSystemsECUR.py“, Zeile 80, in async_read_from_socket
self.read_buffer += warte auf self.reader.read (self.recv_size)
Datei „/usr/lib/python3.7/asyncio/streams.py“, Zeile 644, im Lesemodus
del self._buffer[:n]
Danke im Voraus.
Gruß Jaden
Hallo Jaden,
Woran das liegt kann ich nicht sagen. Könnte Google Licht ins Dunkel bringen?
Gruß,
Björn.
Danke für die Arbeit die du reingesteckt hast.
Auch ich bekam die Fehlermeldung, dass „today_energy_kwh“ nicht definiert sei.
Als ich den Code sorgfältig las, sah ich, dass in Zeile 27 Folgendes steht:
'heute_energie_kWh = str(data.get('heute_energie')*1000)'
Der Rest des Codes verwendet „today_energy_kwh“ (mit einem kleinen „w“)
Nach dem Anpassen von Zeile 27 funktioniert es wie ein Zauber.
Danke noch einmal!
Hallo Fred,
Vielen Dank für die Meldung und Ihre Aufmerksamkeit. Habe das Skript angepasst.
Gruß,
Björn
Hallo Björn,
Hätte besser lesen sollen, aber stimmt es nicht, dass der Raspberry mit dem AP des ECU-R verbunden werden muss? Das Abrufen der Daten über die lokal vergebene IP-Adresse meines Routers funktioniert leider definitiv nicht!
Gruß,
Albert
Hallo Albert,
Ist die ECU auf WiFi via eingestellt? Es funktioniert nicht, wenn es über ein Ethernet-Kabel eingerichtet wird.
Hallo Björn,
Könnten Sie auch angeben, wie das Plugin installiert wird? Ich verwende Domoticz und nicht Home-Assistant.
Gruß,
Albert
Hallo Albert,
Es ist kein Plugin, sondern ein Skript, das im Hintergrund läuft. Das Skript sendet die Daten über JSON an Domoticz.
Es muss lediglich ein APSystemsECUR-Plugin von der Github-Seite heruntergeladen werden. Ich habe gesehen, dass das Plugin aktualisiert und umbenannt wurde. Ich habe die Datei jetzt auf meiner Seite zur Verfügung gestellt.
Die Datei APSystemsECUR.py sollte im selben Ordner wie das obige Skript gespeichert werden.
Wenn Sie weitere Fragen haben, würde ich mich freuen, von Ihnen zu hören.
Entschuldigung für diese späte Antwort, ich hatte Ihr Skript inzwischen zum Laufen gebracht. Gefunden auf:
https://gathering.tweakers.net/forum/list_messages/2032302/3
Bis heute Nachmittag alles mit Freude funktioniert, dann hörte es auf, ich weiß noch nicht, was das Problem ist, aber ich werde noch einmal nachsehen. Vielen Dank für die Antwort und die Energie, die Sie hineingesteckt haben.
MVG William
Hallo Willem,
An der Seite der ECU befindet sich ein Knopf, es ist normalerweise so, dass wenn Sie ihn drücken, es wieder funktioniert.
Hallo Björn, ich bekomme den gleichen Fehler wie Michael:
[FEHLER] {NameError("Name 'heute_energie_kwh' ist nicht definiert")}
aktuelle_leistung: 202
Können Sie vielleicht angeben, wo diese Variable definiert werden soll?
Ich verwende Python 3.7 auf dem Pi.
Danke im Voraus,
Wilhelm
Hallo Willem,
Ich habe gesehen, dass die Variable nicht im Skript enthalten war. Ich habe es jetzt hinzugefügt.
str(data.get('lifetime_energy')*1000)
Lass uns wissen, ob es funktioniert hat.
Gruß,
Björn
Hallo Björn, ich bekomme den gleichen Fehler wie Michael.
[FEHLER] {NameError("Name 'heute_energie_kwh' ist nicht definiert")}
Können Sie auch angeben, wo diese Variable definiert werden soll?
Vielen Dank im Voraus für Ihre Hilfe.
Aufrichtig,
Wilhelm
Hallo Björn,
Ich kann deinem Text nicht wirklich entnehmen, ob das funktioniert, oder ob noch einige Anpassungen im Skript vorgenommen werden müssen?
GR
Hallo Sietze,
Im Prinzip sollte das Skript funktionieren, wenn Sie 16 Panels und 4 verschiedene Wechselrichter haben. Sollte dies bei Ihnen anders sein, muss das Skript etwas angepasst werden. Können Sie beschreiben, wie die Situation in Ihrem Fall ist?
Hallo Björn,
Vielen Dank für dein Skript!!
Ich denke, ich habe alle Schritte wie in Ihrem Beispiel durchgeführt, aber ich erhalte immer noch eine Fehlermeldung beim Ausführen.
Hast du eine Ahnung wo ich suchen soll?
Existiert beispielsweise today_energy_kwh nicht in der APS Ecu-R-Anwendung? oder habe ich den virtuellen Schalter in Domoticz falsch angelegt?
pi@Domo:~/domoticz/scripts/python/ECU-R $ python3 ECU-R.py
aktuelle_leistung: 354
[FEHLER] {NameError("Name 'heute_energie_kwh' ist nicht definiert")}
aktuelle_leistung: 354
[FEHLER] {NameError("Name 'heute_energie_kwh' ist nicht definiert")}
aktuelle_leistung: 354
[FEHLER] {NameError("Name 'heute_energie_kwh' ist nicht definiert")}
aktuelle_leistung: 354
[FEHLER] {NameError("Name 'heute_energie_kwh' ist nicht definiert")}
Vielen Dank im Voraus für Ihre Hilfe.
GR
Michael
Hallo Michael,
Sind Sie sicher, dass Sie Python 3 verwenden?
Eine andere Möglichkeit kann sein, dass die Variable „today_energy_kwh“ nicht (richtig) definiert ist.