Echtzeit-Auslesung APSystems in Domoticz

Echtzeit-Auslesung APSystems in Domoticz

1. Mai 2021 32 Von Björn Meijer

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 = "<ECU-R-IP>"
sleep = 300
 
url = '<DomoticzIP>:8080/json.htm?'
puntcomma = '\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)
                generated_energy = (current_power + puntcomma + lifetime_energy)
                print('output: ' + today_energy_kwh + ';' + current_power)
                #pwr = .format(today_energy_kwh, current_power)
                #print('PWR: ' + pwr)
                print('Today energy [kWh]: ' + today_energy_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) + (puntcomma) + '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 values
                inverters = data.get('inverters')
        #count number of inverters
                Inverter_qty = len(data.get('inverters'))
                print('Inverter_cnt: ' + str(Inverter_qty))
        # loop trough all inverters and get the data
                for i in range(Inverter_qty):
                    Inverter = list(inverters.keys())[i]
                    print('InverterId: ' + Inverter)
                    InverterOnline = data['inverters'][Inverter]['online']
                    print('Online: ' + str(InverterOnline))
                    InverterTemperature = data['inverters'][Inverter]['temperature']
                    print('Temperature: ' + str(InverterTemperature))
                    nVoltage = len(data['inverters'][Inverter]['voltage'])
                    nPower = len(data['inverters'][Inverter]['power'])
                    for x in range(nPower):
                        voltage = data['inverters'][Inverter]['voltage'][x]
                        power = data['inverters'][Inverter]['power'][x]
                        print('Power inverter ' + str(i + 1) + ' panel ' + str(x + 1) + ': ' + str(power) + ' W')
                    
        #upload values to Domoticz voor inverter 1
                        if (i == 0) and (x == 0) :
                            getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': 1624, 'svalue': voltage}
                            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) and (voltage == 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))
 
        #upload values to Domoticz voor inverter 2
                        if (i == 1) and (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 (voltage != 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) and (voltage == 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))
 
        #upload values to Domoticz voor inverter 3
                        if (i == 2) and (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 (voltage != 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) and (voltage == 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))
 
        #upload values to Domoticz voor inverter 4
                        if (i == 3) and (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)  and (voltage != 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) and (voltage == 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))
 
        #upload power values to Domoticz voor inverter 1
                        if (i == 0) and (x == 0) :
                            getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': 1608, 'svalue': (power)}
                            webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (puntcomma) + '0')
                        elif (i == 0) and (x == 1) :
                            getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': 1617, 'svalue': (power)}
                            webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (puntcomma) + '0')
                        elif (i == 0) and (x == 2) :
                            getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': 198, 'svalue': (power)}
                            webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (puntcomma) + '0')
                        elif (i == 0) and (x == 3) :
                            getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': 199, 'svalue': (power)}
                            webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (puntcomma) + '0')
 
        #upload power values to Domoticz voor inverter 2
                        if (i == 1) and (x == 0) :
                            getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': 1618, 'svalue': (power)}
                            webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (puntcomma) + '0')
                        elif (i == 1) and (x == 1) :
                            getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': 1619, 'svalue': (power)}
                            webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (puntcomma) + '0')
                        elif (i == 1) and (x == 2) :
                            getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': 202, 'svalue': (power)}
                            webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (puntcomma) + '0')
                        elif (i == 1) and (x == 3) :
                            getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': 203, 'svalue': (power)}
                            webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (puntcomma) + '0')
 
        #upload power values to Domoticz voor inverter 3
                        if (i == 2) and (x == 0) :
                            getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': 1620, 'svalue': (power)}
                            webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (puntcomma) + '0')
                        elif (i == 2) and (x == 1) :
                            getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': 1621, 'svalue': (power)}
                            webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (puntcomma) + '0')
                        elif (i == 2) and (x == 2) :
                            getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': 206, 'svalue': (power)}
                            webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (puntcomma) + '0')
                        elif (i == 2) and (x == 3) :
                            getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': 207, 'svalue': (power)}
                            webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (puntcomma) + '0')
 
        #upload power values to Domoticz voor inverter 4
                        if (i == 3) and (x == 0) :
                            getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': 1622, 'svalue': (power)}
                            webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (puntcomma) + '0')
                        elif (i == 3) and (x == 1) :
                            getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': 1623, 'svalue': (power)}
                            webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (puntcomma) + '0')
                        elif (i == 3) and (x == 2) :
                            getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': 210, 'svalue': (power)}
                            webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (puntcomma) + '0')
                        elif (i == 3) and (x == 3) :
                            getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': 211, 'svalue': (power)}
                            webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (puntcomma) + '0')
 
 
        except Exception as 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

Dummy-Sensor in Domoticz hinzufügen
Dummy-Sensor 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 zur Erzeugung von Sonnenkollektoren
Erstellen Sie einen virtuellen Sensor zur Erzeugung 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 für den APSystem-Wechselrichter
Erstellen Sie einen virtuellen Sensor für den APSystems-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.
Virtueller Sensor für erzeugten Wechselrichter
Virtueller Sensor für erzeugten Wechselrichter
  • 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.
Virtueller Sensor zur Anzeige der Wechselrichtertemperatur
Virtueller Sensor zur Anzeige der Wechselrichtertemperatur
  • 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.