Echtzeit-Auslesung APSystems in Domoticz

Echtzeit-Auslesung APSystems in Domoticz

1. Mai 2021 34 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 = " "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

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.