SunSpec – ein Standard: Warum Geräte trotzdem nicht miteinander reden

Von | Mai 16, 2026

In einem früheren Beitrag habe ich beschrieben, warum ein Modbus-Proxy für
viele Smart-Home-Setups
mit Photovoltaik sinnvoll ist – und wie ich meinen
eigenen Aufbau von einem Home Assistant Add-on in einen eigenständigen
Proxmox-LXC umgezogen habe
.

Heute geht es um ein Problem, das mir erst kürzlich begegnet ist: Zwei Geräte,
beide zertifiziert nach dem SunSpec-Standard – und trotzdem können sie nicht
miteinander reden.

Was ist SunSpec überhaupt?

SunSpec ist ein offener Industriestandard, der festlegt, wie Solar- und
Energiespeichergeräte über Modbus kommunizieren sollen. Die Idee dahinter ist
simpel: Egal ob Wechselrichter, Energiezähler oder Batteriespeicher – wer
SunSpec implementiert, soll mit jedem SunSpec-kompatiblen Energiemanagement-
system oder jeder Monitoring-Software zusammenarbeiten.

In der Praxis funktioniert das oft gut. Aber es gibt einen Haken.

Das Problem: SunSpec erlaubt zwei Datenformate

Die SunSpec-Spezifikation definiert zwei Wege, wie numerische Werte in
Modbus-Registern gespeichert werden können:

Ganzzahl-Modell (Integer Model):

Werte werden als int16 gespeichert – also als vorzeichenbehaftete 16-Bit- Ganzzahl. Da viele Messwerte (z. B. Wirkleistung in Watt) Nachkommastellen haben können, wird ein zweites Register als Scale Factor (sunssf) mitgeliefert. Der tatsächliche Wert ergibt sich dann als:

Wert = int16-Register × 10^(Scale Factor)

Beispiel: 2071 mit Scale Factor -2 ergibt 20,71 W.

Gleitkomma-Modell (Float Model):

Werte werden direkt als float32 gespeichert – also als 32-Bit-Gleitkommazahl nach IEEE 754. Kein Scale Factor, kein Umrechnen.

Beide Varianten sind laut SunSpec-Spezifikation vollständig gültig. Aber: Ein Gerät, das int16 + Scale Factor liefert, ist nicht direkt kompatibel mit einem Client, der float32 erwartet – und umgekehrt.

Ein konkretes Beispiel aus der Praxis

Mein SolarEdge-Wechselrichter implementiert das Integer-Modell. Home Assistant und meine OpenWB-Wallbox kommen damit problemlos zurecht – beide Integrationen kennen das SolarEdge-Format und rechnen den Scale Factor intern um.

Ein Bosch Energy Manager, welcher bei vielen Wärmepumpen von Bosch und z.B. Buderus mit dabei ist, erwartet die Daten im Float-Format.
Das SolarEdge liefert aber Integer + Scale Factor.

Beide Geräte sprechen SunSpec. Beide halten sich an den Standard. Und trotzdem sind sie inkompatibel – weil der Standard eben beide Varianten erlaubt, ohne eine davon vorzuschreiben.

Dieses Problem ist übrigens kein Einzelfall: Ähnliche Inkompatibilitäten entstehen überall dort, wo verschiedene Hersteller unterschiedliche SunSpec-Profile implementieren – etwa beim Austausch eines Wechselrichters gegen ein Modell eines anderen Herstellers, oder bei der Integration von Legacy-Systemen.

Die Lösung: Der Modbus-Proxy als Übersetzer

Da bei mir ohnehin bereits ein Modbus-Proxy läuft, lag die Idee nahe, diesen um eine Konvertierungsfunktion zu erweitern. Der Proxy sitzt bereits zwischen allen Clients und dem Wechselrichter – er wäre der ideale Ort, um das Datenformat transparent umzurechnen.

Das Prinzip sieht so aus:

SolarEdge WR (int16 + Scale Factor)
        ↓
    Modbus-Proxy
        ├── Port 5020 → Home Assistant, OpenWB  (int16, unverändert)
        └── Port 5021 → Bosch Energy Manager    (float32, konvertiert)Code-Sprache: JavaScript (javascript)

Der Wechselrichter wird dabei nur einmal abgefragt. Der Proxy fangt die
Antwort ab, konvertiert für den jeweiligen Client das Datenformat – und
leitet weiter. Für die Clients ist die Konvertierung vollständig transparent.

Die Erweiterung des modbus-proxy

Als Basis dient der Open-Source-Proxy modbus-proxy von Tiago Coutinho – ein schlankes Python-Tool, das ich bereits seit 2022 im Einsatz habe.

Via Claude wurde dieser Proxy um zwei neue Funktionen erweitert:

1. Mehrere Listener pro Gerät (listeners)

Statt eines einzelnen listen-Eintrags können jetzt mehrere Listener konfiguriert werden, die sich alle eine einzige Verbindung zum Gerät teilen. Jeder Listener kann eigene Konvertierungsregeln haben.

2. Register-Konvertierung (register_conversions)

Pro Listener lässt sich eine Liste von Registern angeben, die konvertiert werden sollen – inklusive Richtung (int16 → float32 oder float32 → int16).

Der Quellcode ist in meinem Fork verfügbar.

zu einem Pull-Request in das ursprüngliche Repository habe ich mich jetzt allerdings noch nicht überwunden.

Konfiguration

Die Konfiguration erfolgt wie gewohnt über YAML oder TOML.
Die bestehende listen-Syntax (Einzahl) bleibt vollständig kompatibel – wer keine Konvertierung benötigt, muss nichts ändern.

Für das neue Multi-Listener-Setup mit Konvertierung sieht die Konfiguration so aus:

Yaml:

devices:
  - modbus:
      url: 192.168.1.100:1502      # IP und Port des SolarEdge WR
    listeners:
      # Port für Home Assistant und OpenWB – unverändert (int16)
      - bind: 0:5020

      # Port für Bosch Energy Manager – konvertiert (float32)
      - bind: 0:5021
        register_conversions:
          - address: 40084         # I_AC_Power (Wirkleistung Wechselrichter)
            sf_address: 40085      # I_AC_Power_SF (Scale Factor)
            source_type: int16
            target_type: float32
          - address: 40207         # M_AC_Power (Wirkleistung Zähler)
            sf_address: 40211      # M_AC_Power_SF
            source_type: int16
            target_type: float32Code-Sprache: PHP (php)

Toml:

[[devices]]

[devices.modbus]
url = "192.168.1.100:1502"

[[devices.listeners]]
bind = "0:5020"

[[devices.listeners]]
bind = "0:5021"

[[devices.listeners.register_conversions]]
address = 40084
sf_address = 40085
source_type = "int16"
target_type = "float32"

[[devices.listeners.register_conversions]]
address = 40207
sf_address = 40211
source_type = "int16"
target_type = "float32"Code-Sprache: JavaScript (javascript)

Hinweis zu den Register-Adressen:

Die Adressen sind in der Modbus-Konvention base-1 angegeben (wie in der SolarEdge-Dokumentation und in den meisten Modbus-Tools üblich).

Ein Konkretes Beispiel für SolarEdge:
Der Scale Factor für I_AC_Power liegt bei Register 40085, der für den Zähler (M_AC_Power) bei 40211, während die entsprechenden Daten in den Registern 40084 für den I_AC_Power und 40207 für den M_AC_Power liegen

Fazit

SunSpec ist ein sinnvoller Standard – aber die Tatsache, dass er zwei
inkompatible Datenformate gleichzeitig erlaubt, schafft in der Praxis
unnötige Probleme für den Endkunden.

Wer mehrere Geräte verschiedener Hersteller betreibt,
stolpert früher oder später über genau diese Inkompatibilität.

Der Modbus-Proxy als transparenter Übersetzer ist dabei eine elegante Lösung:
Das Quellgerät muss nicht angefasst werden, die Clients müssen nicht angepasst
werden – der Proxy übernimmt die Konvertierung still im Hintergrund.

Die Erweiterung ist vollständig rückwärtskompatibel. Wer sie nicht braucht,
merkt nichts davon.

Der folgende Screenshot zeigt alle drei Varianten im direkten Vergleich.
– default proxy ist mein ursprüngliches Setup
– Test proxy Listener 1 ist der neue Proxy mit Standard-Settings ohne Typ-Conversion
– Test proxy Listener 2 ist der neue Proxy mit Typ-Conversion auf bestimmte Register.

Leichte Abweichungen in den Werten sind bedingt durch leicht unterschiedliche Polling-Zyklen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert