IoT-Automatisierung

Wechselrichter-Überwachung per MQTT mit SunSpec Modbus und Python

Lesen Sie Live-Produktionsdaten Ihres PV-Wechselrichters über SunSpec Modbus TCP oder eine lokale API aus, veröffentlichen Sie Leistung, Tagesenergie und Status per MQTT und machen Sie Solardaten für jedes Dashboard und jede Automatisierung im Haus verfügbar.

Solarmodule auf dem Dach und ein an der Wand montierter Wechselrichter, der Daten an ein Cloud-Dashboard zur Wechselrichter-Überwachung streamt
Probieren Sie es auf Ihrem eigenen MQTT-Broker ausHolen Sie sich im Free-Tarif einen privaten, verwalteten MQTT-Broker und starten Sie mit fertigen Codebeispielen.
Kostenlos testen Codebeispiele Keine Kreditkarte erforderlich

Eine Wechselrichter-Überwachung per MQTT befreit Ihre Produktionsdaten aus der Hersteller-App und stellt sie Dashboards, Hausautomation und Logik zur Lastverschiebung in Echtzeit zur Verfügung. In diesem Tutorial lesen Sie mit Python Leistung, Energie und Status eines Wechselrichters über den Standard SunSpec Modbus TCP aus, veröffentlichen alle paar Sekunden sauberes JSON an einen Broker und lernen die Stolperfallen kennen, an denen die meisten ersten Versuche scheitern. Alternative Wege über lokale HTTP-APIs und RS485 werden ebenfalls behandelt.

Drei Wege, Daten aus einem Wechselrichter zu holen

Herstellerportale reichen für einen monatlichen Blick, aktualisieren aber meist langsam und hängen vom Internet ab. Lokaler Zugriff ist schneller, funktioniert offline und ist genau das, was Sie für Automatisierungen brauchen, etwa um eine Wärmepumpe mit Überschussstrom zu betreiben.

Methode Typische Wechselrichter Vorteile Nachteile
SunSpec Modbus TCP Viele Strangwechselrichter großer Marken Standardisierte Registerbelegung, nur LAN, schnell Muss oft in den Installateureinstellungen aktiviert werden
Lokale HTTP-API des Herstellers Einige Marken stellen JSON im LAN bereit Mit jedem HTTP-Client leicht auszulesen Je nach Hersteller unterschiedlich, ggf. Tokens nötig
Modbus RTU über RS485 Viele Hybrid- und Budget-Wechselrichter Funktioniert ohne Netzwerkanschluss Benötigt einen RS485-Adapter und die Registerbelegung des Herstellers

SunSpec ist der beste Ausgangspunkt, wenn Ihr Wechselrichter es unterstützt, denn derselbe Code funktioniert markenübergreifend. Die SunSpec Alliance definiert „Modelle“: Registerblöcke mit festem Aufbau. Die Wechselrichtermodelle 101 (einphasig), 102 (Split-Phase) und 103 (dreiphasig) teilen sich denselben Feldaufbau, und darauf stützt sich der folgende Code.

Modbus TCP am Wechselrichter aktivieren

Jede Marke versteckt diese Einstellung anders, aber das Vorgehen ist immer gleich:

  1. Geben Sie dem Wechselrichter per DHCP-Reservierung eine feste IP-Adresse.
  2. Aktivieren Sie im Installateur- oder Inbetriebnahmemenü Modbus TCP (manchmal „SunSpec“ oder „Modbus Slave“ genannt).
  3. Notieren Sie den Port (fast immer 502) und die Unit-ID (oft 1, manchmal 126 oder ein anderer Wert).
  4. Wählen Sie das Registerformat SunSpec / float oder int+SF, falls der Wechselrichter danach fragt; diese Anleitung verwendet das Format Ganzzahl plus Skalierungsfaktor, das am weitesten verbreitet ist.
  5. Bietet Ihr Wechselrichter eine Option „nur lesen“ für Modbus, aktivieren Sie sie. Sie müssen nur lesen.

Manche Wechselrichter akzeptieren jeweils nur einen Modbus-TCP-Client. Ist bereits ein Energiemanager oder eine Wallbox-Steuerung verbunden, wird Ihr Skript möglicherweise abgewiesen oder wirft den anderen Client hinaus. Planen Sie also, welches System die Verbindung besitzt.

So funktionieren SunSpec-Register

Ein SunSpec-Gerät beginnt mit der Kennung SunS an einer Basisadresse, meist 40000. Nach der Kennung folgt eine Kette von Modellen, die jeweils mit einer Modell-ID und einer Länge beginnen. Sie durchlaufen die Kette, bis Sie Modell 101, 102 oder 103 finden, und lesen dann Felder an festen Offsets:

Offset im Modell Feld Typ Bedeutung
2 A uint16 AC-Strom, skaliert mit A_SF (Offset 6)
10 PhVphA uint16 Spannung Phase A, skaliert mit V_SF (Offset 13)
14 W int16 AC-Leistung, skaliert mit W_SF (Offset 15)
16 Hz uint16 Frequenz, skaliert mit Hz_SF (Offset 17)
24–25 WH acc32 Gesamtenergie in Wh, skaliert mit WH_SF (Offset 26)
31 DCW int16 DC-Leistung, skaliert mit DCW_SF (Offset 32)
33 TmpCab int16 Gehäusetemperatur, skaliert mit Tmp_SF (Offset 37)
38 St enum16 Betriebszustand (4 = MPPT, produziert)

Die Offsets zählen ab dem Register der Modell-ID. Jeder Wert wird mit 10 hoch seinem vorzeichenbehafteten Skalierungsfaktor multipliziert; ein Rohwert W von 51234 mit W_SF von -1 bedeutet also 5123,4 W. Nicht implementierte Register liefern 0x8000 (vorzeichenbehaftet) oder 0xFFFF (vorzeichenlos) und müssen ignoriert werden.

Der Python-Publisher

Installieren Sie die Bibliotheken:

pip install "paho-mqtt>=2.0" "pymodbus>=3.7"

Das Skript findet die SunSpec-Basis, durchläuft die Modelle, liest den Wechselrichterblock und veröffentlicht JSON. Zunächst nutzt es den kostenlosen öffentlichen MQTT-Broker mit einem zufälligen Präfix, da dort alles für alle lesbar ist; er ist für Tests und Prototypen gedacht, nicht für Produktivdaten.

import json
import time
import uuid
import paho.mqtt.client as mqtt
from pymodbus.client import ModbusTcpClient

INVERTER_IP = "192.168.1.60"
INVERTER_PORT = 502
POLL_SECONDS = 10

PREFIX = f"connectmq/demo/{uuid.uuid4().hex[:8]}/solar/inverter1"
STATE_NAMES = {1: "off", 2: "sleeping", 3: "starting", 4: "mppt",
               5: "throttled", 6: "shutting_down", 7: "fault", 8: "standby"}


def s16(v):
    return None if v == 0x8000 else (v - 0x10000 if v & 0x8000 else v)


def u16(v):
    return None if v == 0xFFFF else v


def scaled(value, sf):
    if value is None or sf is None:
        return None
    return round(value * (10 ** sf), 3)


def kwh(wh_raw, sf):
    if not wh_raw or sf is None:      # acc32-Wert 0 bedeutet nicht implementiert
        return None
    return round(wh_raw * (10 ** sf) / 1000, 3)


def find_inverter_model(client):
    for base in (40000, 39999, 50000, 0):
        rr = client.read_holding_registers(base, count=2)
        if rr.isError() or rr.registers != [0x5375, 0x6E53]:   # "SunS"
            continue
        addr = base + 2
        for _ in range(30):
            rr = client.read_holding_registers(addr, count=2)
            if rr.isError():
                break
            model_id, length = rr.registers
            if model_id == 0xFFFF:
                break
            if model_id in (101, 102, 103):
                return addr, length, model_id
            addr += 2 + length
    raise RuntimeError("No SunSpec inverter model found - check Modbus settings and unit ID")


def read_inverter(client, addr, length):
    rr = client.read_holding_registers(addr, count=length + 2)
    if rr.isError():
        raise IOError(rr)
    r = rr.registers
    wh_raw = (r[24] << 16) | r[25]
    return {
        "ac_power_w": scaled(s16(r[14]), s16(r[15])),
        "ac_current_a": scaled(u16(r[2]), s16(r[6])),
        "ac_voltage_v": scaled(u16(r[10]), s16(r[13])),
        "frequency_hz": scaled(u16(r[16]), s16(r[17])),
        "energy_total_kwh": kwh(wh_raw, s16(r[26])),
        "dc_power_w": scaled(s16(r[31]), s16(r[32])),
        "temp_c": scaled(s16(r[33]), s16(r[37])),
        "state": STATE_NAMES.get(r[38], str(r[38])),
    }


mq = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
                 client_id=f"solar-{uuid.uuid4().hex[:6]}")
mq.will_set(f"{PREFIX}/status", "offline", qos=1, retain=True)
mq.connect("broker.connectmq.com", 1883, keepalive=60)
mq.loop_start()
mq.publish(f"{PREFIX}/status", "online", qos=1, retain=True)
print("Publishing to", PREFIX)

mb = ModbusTcpClient(INVERTER_IP, port=INVERTER_PORT, timeout=3)
model_addr = model_len = None

while True:
    try:
        if not mb.connected:
            mb.connect()
        if model_addr is None:
            model_addr, model_len, model_id = find_inverter_model(mb)
            print(f"Found SunSpec model {model_id} at {model_addr}")
        data = read_inverter(mb, model_addr, model_len)
        data["ts"] = int(time.time())
        mq.publish(f"{PREFIX}/telemetry", json.dumps(data), qos=1, retain=True)
        print(data)
    except Exception as exc:
        print("Read failed:", exc)
        mb.close()
        model_addr = None
    time.sleep(POLL_SECONDS)

Verwendet Ihr Wechselrichter eine andere Unit-ID als 1, übergeben Sie sie bei jedem Lesevorgang mit dem Schlüsselwort device_id (in älteren pymodbus-Versionen slave). Beobachten Sie die Ausgabe von einem anderen Rechner aus:

mosquitto_sub -h broker.connectmq.com -p 1883 -i solar-viewer-2290 -t "connectmq/demo/+/solar/#" -v

Eine typische Nachricht sieht so aus:

{"ac_power_w": 4183.0, "ac_current_a": 6.05, "ac_voltage_v": 231.4, "frequency_hz": 50.01,
 "energy_total_kwh": 18342.611, "dc_power_w": 4301.0, "temp_c": 41.2, "state": "mppt", "ts": 1760603520}

Stolperfallen bei der Wechselrichter-Überwachung

Die meisten Probleme haben eine Handvoll Ursachen:

  • Um eins verschobene Adressen. Dokumentationen mischen 0-basierte und 1-basierte Registernummerierung. Deshalb probiert das Skript sowohl 40000 als auch 39999.
  • Skalierungsfaktoren ändern sich. Manche Wechselrichter ändern W_SF dynamisch. Lesen Sie den Skalierungsfaktor immer in derselben Anfrage wie den Wert, wie es der Code durch das Lesen des gesamten Blocks tut.
  • Nachts. Viele Wechselrichter schalten nachts ihre Kommunikationsplatine ab oder melden den Zustand „sleeping“ mit leeren Werten. Behandeln Sie Timeouts nach Sonnenuntergang als normal und behalten Sie den letzten retained Wert.
  • Abfragerate. Alle 5 bis 10 Sekunden reicht für Dashboards und Überschusssteuerung völlig. Mehrmals pro Sekunde abzufragen bringt nichts und kann manche Wechselrichter aus dem Tritt bringen.
  • Zähler oder Wechselrichter. Der Wechselrichter kennt die Erzeugung, nicht den Verbrauch oder die Einspeisung. Für Eigenverbrauchslogik brauchen Sie zusätzlich einen Netzzähler; diese Hälfte behandelt der Leitfaden zum Energiemonitor für zu Hause.
  • Hybridwechselrichter mit Batterien stellen Batteriedaten oft in herstellerspezifischen statt in Standard-SunSpec-Modellen bereit. Unter Heimspeicher-Überwachung erfahren Sie, wie Sie BMS-Werte veröffentlichen.

Die Daten nutzen

Sobald die Erzeugung per MQTT verfügbar ist, kann jeder Abnehmer sie nutzen, ohne den Wechselrichter erneut anzufassen. Home Assistant kann das JSON über seine MQTT-Integration auf Sensoren abbilden, Node-RED kann eine smarte Steckdose schalten, wenn die Erzeugung einen Schwellenwert überschreitet, und Telegraf kann alles für monatliche Ertragsberichte in einer Zeitreihendatenbank speichern. Da die Telemetrienachricht retained ist, sieht ein Dashboard, das mittags geöffnet wird, sofort die aktuelle Erzeugung.

Integrationen funktionieren bewusst auf diese Weise: Der Broker ist die Zentrale, und jedes Tool verbindet sich als MQTT-Client mit ihm. Ist das Konzept neu für Sie, erklärt der Überblick darüber, was ein MQTT-Broker tut, das zugrunde liegende Publish/Subscribe-Modell. Dasselbe Muster skaliert auf Gewerbe und Industrie: Eine PV-Anlage auf dem Hallendach eines Mittelständlers liefert ihre Werte in den Unified Namespace (UNS) des Standorts, dessen Topics der ISA-95-Hierarchie folgen, etwa acme/werk-stuttgart/energie/pv-dach/wechselrichter-1/telemetry, wo Energiemonitoring und Lastmanagement sie neben den Verbrauchsdaten der Linien auswerten.

Produktivbetrieb mit einem privaten Broker

Solardaten sind nicht so geheim wie Passwörter, verraten aber Anwesenheitsmuster und Anlagendetails, und der öffentliche MQTT-Broker wird geteilt. Für einen dauerhaften Aufbau betreiben Sie den Publisher auf einem Raspberry Pi oder Heimserver und senden die Daten per TLS an einen Cloud-MQTT-Broker. Bei ConnectMQ erstellen Sie im Portal einen Broker, kopieren die generierten Zugangsdaten und ersetzen die Verbindungszeilen:

mq = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="YOUR_CLIENT_ID")
mq.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
mq.tls_set()
mq.will_set("home/solar/inverter1/status", "offline", qos=1, retain=True)
mq.connect("broker.connectmq.com", 8883, keepalive=60)

Mit einem Cloud-Broker sehen Sie die Erzeugung außerdem auf dem Handy, ohne etwas in Ihrem Heimnetz freizugeben, denn der Raspberry Pi baut nur eine ausgehende Verbindung auf. Der umfassendere Leitfaden zur IoT-Automatisierung zeigt, wie Solardaten in die Energieflüsse des ganzen Hauses passen.

Ihre Solarerzeugung mit ConnectMQ überwachen

ConnectMQ ist ein verwalteter MQTT-Broker mit TLS auf Port 8883, WebSocket-Zugang für Browser-Dashboards, Live-Topic-Explorer und Schwellenwert-Alarmregeln, zum Beispiel um Sie zu warnen, wenn ein Wechselrichter tagsüber einen Fehlerzustand meldet. Erstellen Sie unter app.connectmq.com einen kostenlosen Serverless-Broker, ganz ohne Kreditkarte.

Häufig gestellte Fragen

Unterstützt jeder Wechselrichter SunSpec Modbus?

Nein. Viele etablierte Marken von Strangwechselrichtern tun es, oft nach Aktivierung in den Installateureinstellungen, während manche Hybrid- und Budget-Wechselrichter nur herstellerspezifische Modbus-RTU-Belegungen oder Cloud-APIs anbieten. Suchen Sie in der Dokumentation Ihres Modells nach „SunSpec“.

Wie oft sollte ich den Wechselrichter abfragen?

Alle 5 bis 10 Sekunden reicht für Live-Dashboards und überschussbasierte Automatisierungen. Schnellere Abfragen bringen selten Mehrwert, und manche Wechselrichter reagieren schlecht darauf.

Warum schlägt mein Skript nachts fehl?

Viele Wechselrichter schalten ihre Kommunikationsschnittstelle ab, wenn keine PV-Leistung anliegt. Behandeln Sie nächtliche Timeouts als erwartet und verlassen Sie sich auf die letzte retained MQTT-Nachricht.

Kann ich den Wechselrichter über MQTT steuern?

Manche Wechselrichter akzeptieren SunSpec-Steuerregister zur Leistungsbegrenzung, doch Schreibzugriffe auf einen Wechselrichter können gegen Netzanschlussregeln verstoßen. Bleiben Sie bei diesem Tutorial im Lesemodus, sofern Ihr Installateur nicht bestätigt, was erlaubt ist.

Verwandte Artikel

Zigbee2MQTT einrichten: Vom Koordinator bis zum Dashboard

Installieren Sie Zigbee2MQTT mit Docker, konfigurieren Sie Koordinator und MQTT-Verbindung, lernen Sie Geräte an und benennen Sie sie um, steuern Sie sie per MQTT und zeigen Sie ihre Zustände auf einem Dashboard an, zuerst getestet auf einem kostenlosen öffentlichen MQTT-Broker.

8 Min. Lesezeit

Alle Artikel →

Ihr privater MQTT-Broker ist nur wenige Klicks entfernt

Konto anlegen, Broker-Zugangsdaten erhalten und das erste Gerät verbinden — ohne Server, die installiert, gepatcht oder skaliert werden müssen.