[Modul] NRG-Stack ModbusServer - IP-Symcon als Modbus-TCP-Server (Slave), mit Vorlagen für Direktvermarktung und SunSpec

Hallo zusammen,

wie im Teaser zum NRG-Stack (Vorankündigung) angekündigt, stelle ich die Module einzeln vor - hier der ModbusServer. Die anderen Module des Verbunds (InverterHub, MeterHub, ChargerHub) lesen Geräte per Modbus aus. Der ModbusServer macht die Gegenrichtung: Er macht IP-Symcon selbst zu einem Modbus-Gerät, das andere Systeme abfragen und beschreiben können.

Worum geht es?

Symcon bringt von Haus aus nur die Client-Seite mit (in älteren Datenblättern „Master" genannt): Symcon fragt ein Gerät ab. Der ModbusServer ergänzt die andere Seite. Er ist der Modbus-TCP-Server (in älteren Datenblättern „Slave"), und externe Modbus-Clients (dort „Master") können frei gewählte Symcon-Variablen lesen und beschreiben - über eine Registertabelle, die man im Formular selbst festlegt.

Ein Hinweis zu den Begriffen, weil sie oft durcheinandergehen: Die Modbus-Spezifikation spricht bei Modbus TCP von Client und Server, ältere Datenblätter, Geräte und Werkzeuge (z. B. der Simulator ModRSsim2) sagen Master und Slave. Beides meint dasselbe. Im Modul und in der Doku kommen deshalb beide Schreibweisen vor, damit man sie mit der Gerätedokumentation abgleichen kann.

Wozu braucht man das?

  • Symcon-Werte an ein Leitsystem, SCADA oder Energiemanagement weitergeben, das nur Modbus spricht.
  • Sollwerte von außen entgegennehmen - z. B. von einem Regler, einer Wallbox-Steuerung oder einem Direktvermarkter.
  • Ein bekanntes Modbus-Gerät nachbilden (Zähler, Datenlogger, Wechselrichter), wenn eine Gegenstelle genau so ein Gerät erwartet.
  • Einen vorhandenen Modbus-Server ablösen, z. B. einen Simulator wie ModRSsim2 oder eine SPS, über den bisher etwas angebunden war - ohne die Gegenstelle umzustellen.

Funktionsumfang

  • Function Codes 03, 04, 06 und 16 (Holding/Input lesen, einzelnes und mehrere Register schreiben). Coils und Discrete Inputs (FC 01/02/05/15) gibt es bewusst nicht.
  • Datentypen uint16, int16, uint32, int32, float32, float64, Word-Reihenfolge umschaltbar (ABCD/CDAB).
  • Mehrere Clients gleichzeitig auf demselben Port, jede Verbindung mit eigenem Puffer.
  • Mehrere getrennte Schnittstellen (verschiedene Ports oder Registerbelegungen): eine Instanz fertig konfigurieren, Portliste eintragen (z. B. 502-505), und für jeden freien Port entsteht eine Kopie samt Server Socket - mit Rückfrage vorher.
  • Registertabelle mit Adresse, Bereich, Datentyp, Variable, Faktor, Festwert und Schreibmodus. Dieselbe Variable darf mehrfach eingetragen werden (z. B. als float32 und als int32).
  • Speicherzellen: Eine beschreibbare Zeile ohne Variable merkt sich den geschriebenen Wert (auch nach einem Neustart) und liefert ihn beim Lesen zurück - wie ein klassischer Modbus-Server. Praktisch für Sollwerte, die ein anderes Gerät von diesem Server zurückliest.
  • Sichtbar, was wirklich passiert: Je Register die Uhrzeit des letzten Lese- und Schreibzugriffs und der aktuelle Wert direkt in der Tabelle, dazu eine Verbindungszeile oben im Formular.
  • Statusampel und Kommunikationsüberwachung: Die Instanz zeigt „Inaktiv", wenn der Socket bewusst geschlossen ist, einen Fehler, wenn er laufen sollte und es nicht tut, und optional einen Fehler, wenn länger als eine einstellbare Zeit keine Anfrage mehr kam.
  • Timeout-Absicherung für schreibbare Register: Wird ein Register länger als eine Gültigkeitsdauer nicht mehr beschrieben, setzt das Modul einen Rückfallwert. Die Dauer kann fest sein oder aus einem anderen Register kommen, das die Gegenstelle selbst mitschreibt.
  • Schreibmodus je Zeile: nur lesen, per RequestAction (schaltet z. B. einen Aktor) oder direkt per SetValue.

Vorlagen

Über „Vorlage laden" lässt sich die Registertabelle mit einer vorbereiteten Belegung füllen, inklusive passender Word-Reihenfolge. Gespeichert wird erst mit „Änderungen übernehmen". Enthalten sind:

  • Meteocontrol blue’Log RPC (Direktvermarktung): Die Remote-Power-Control-Schnittstelle des blue’Log XM/XC, die viele Direktvermarkter für die Abregelung nutzen (Sollwert, Gültigkeitsdauer, Watchdog, dazu die Istwert-Register). Symcon übernimmt dabei selbst die Rolle des blue’Log - es wird kein echtes Gerät benötigt. Nach Ablauf der Gültigkeitsdauer fällt der wirksame Sollwert auf einen einstellbaren Rückfallwert zurück; optional gibt ein Ereignis-Skript den Sollwert an einen echten blue’Log weiter.
  • SunSpec Wechselrichter dreiphasig (Common Model 1 + Model 113)
  • SunSpec Zähler dreiphasig (Common Model 1 + Model 213) - damit tritt Symcon gegenüber Systemen, die einen SunSpec-Netzzähler erwarten, als solcher auf.

Weitere Vorlagen lassen sich nach demselben Muster ergänzen.

Teststand

Die Registertabelle, die Speicherzellen, die Timeout-Absicherung und die blue’Log-RPC- Emulation laufen bei mir im Praxiseinsatz an einer produktiven Direktvermarktungs-Anbindung mit mehreren Schnittstellen parallel. Die beiden SunSpec-Vorlagen habe ich nach der offiziellen SunSpec-Modelldefinition erzeugt, sie sind aber bisher nicht an echten Gegenstellen geprüft - Rückmeldungen dazu sind ausdrücklich willkommen. Der Protokollkern und das Modul haben automatische Tests, außerdem lässt sich alles von der Kommandozeile gegenprüfen (Beispiele mit modpoll stehen in der README).

Grenzen

  • Keine Coils/Discrete Inputs (FC 01/02/05/15).
  • Textfelder (z. B. Hersteller/Seriennummer im SunSpec Common Model) liefern 0, Strings unterstützt das Modul nicht.
  • PHP-Module sind nicht auf Millisekunden-Latenz ausgelegt; für übliche Abfrageintervalle ab etwa 500 ms ist das unkritisch.
  • Port 502 braucht je nach System Root-Rechte (alternativ z. B. 1502 verwenden).

Voraussetzungen

  • IP-Symcon 9.0 oder neuer
  • Optional: EMS und Dashboard aus dem NRG-Stack für Zusatzfunktionen - der ModbusServer funktioniert auch komplett eigenständig

Einrichtung in Kürze

  1. Modul hinzufügen: Modulverwaltung → Symcon Module Store → nach „NRG-Stack ModbusServer" suchen, Kanal Beta wählen. Alternativ direkt per Repository-URL: https://github.com/DG65/NRGModbusServer, Branch beta.
  2. Instanz „NRG-Stack Modbus TCP Server" anlegen - der Server Socket wird automatisch erstellt.
  3. Port am Server Socket einstellen (z. B. 502) und den Socket aktivieren.
  4. Registertabelle füllen (von Hand oder per Vorlage), Variablen zuordnen, „Änderungen übernehmen".

Lizenz

Lizenz: PolyForm Noncommercial 1.0.0 - private/nicht-kommerzielle Nutzung ist frei, gewerbliche Nutzung erfordert eine gesonderte Lizenz vom Rechteinhaber (DG65). Der vollständige Lizenztext liegt im Repo (LICENSE). Spenden sind willkommen: paypal.me/DietmarGureth.

Feedback

Das Modul ist im Beta-Stand - über Rückmeldungen, Fehler oder Wünsche (weitere Vorlagen, Rückmeldungen zu den SunSpec-Vorlagen, Erfahrungen mit anderen Direktvermarktern) freue ich mich hier im Thread.

Viele Grüße Dietmar