Zähler über Modbus-Bridge abfragen. Aber wie?

Hallo,

Wir haben mehrere Zähler unterschiedlichen Typs im Einsatz (Janitza, Eastron), teils über Modbus TCP, teils RS485. Letztere werden über eine TCP/RS485 Bridge abgefragt. In OpenEMS habe ich bisher keine Möglichkeit gefunden eine Modbus-Bridge anzusprechen. Dazu gehört m.E. die Angabe der Modbus-ID des abzufragenden Geräts. In einem RS485-Strang können ja mehrere Geräte hängen …

Nette Grüße
klinki

1 Like

Hallo Klinki,

um in OpenEMS einen Modbus Zähler einzubinden musst du mehrstufig vorgehen. Zuerst wird eine Modbus-Bridge angelegt. Im Screenshot meiner Anlage sieht man z.B. drei Modbus-Bridges. modbus0 ist eine RS485 Verbindung. modbus1 und modbus3 sind jeweils Modbus-TCP Verbindungen:
grafik

Für die RS-485 Verbindung werden in der modbus0-Komponente nur die generellen Schnittstellenparameter angegeben:

Eine Modbus-TCP Verbindung sieht bei mir dann so aus (modbus3):

Diese drei Komponenten stellen in meinem Beispiel nun OpenEMS-weit eine generelle Modbus-Funktionatlität zur Verfügung (genau genommen stellen sie drei Modbus-Bridges bereit). Um nun einen bestimmten Gerätetreiber über Modbus kommunizieren zu lassen, muss der entsprechende Treiber an die entsprechende Modbus-Komponente gebunden werden:

In meinem Beispiel wird die Komponente meter1 an das Modbus Interface modbus1 gebunden. Hier wird dann auch die Modbus-Unit ID hinterlegt über die das entsprechende Gerät referenziert wird.
OpenEMS verfolgt das Konzept der losen Kopplung. Das wirkt auf den ersten Blick sehr umständlich, bietet aber viele Vorteile und Freiheitsgrade, wenn man sich erstmal daran gewöhnt hat. Es erlaubt z.b. einen weiteren Treiber anzulegen, welcher die gleiche Modbus-ID aber eine andere Modbus Unit-ID nutzen würde.
Weiterhin ist durch diese Art der Kopplung die Modbus Implementierung für den Gerätetreiber transparent. Das bedeutet, dass es dem Gerätetreiber egal ist, ob die darunterliegende Verbindung eine Modbus-TCP Verbindung oder eine Modbus-RS485 Verbindung ist.
Beide Komponenten zusammen, die Komponente meter1 und die Komponente modbus1 ergeben nun innerhalb von OpenEMS einen vollwertigen Modbus-Meter-Treiber.

In OpenEMS sind bereits mehrere Janitza Zähler implementiert (UMG 511, UMG604, UMG96RME). Diese werden analog zum obigen Beispiel konfiguriert und können direkt verwendet werden.
Ist der nötige Zähler nicht in OpenEMS implementiert, dann kann man ihn mit etwas Programmiererfahrung selbst anlegen, indem man ein neues Meter-Bundle anlegt und dort einfach die gewünschte Modbus-Tabelle umsetzt. Hier ein Link auf die Implementierung der Janitza UMG604 Modbus Tabelle. Dort werden im wesentlichen die Modbus-Adressen auf das OpenEMS Meter Interface gemappt und fertig ist die Zählerimplementierung.

Viele Grüße,
Christian

1 Like

Guten Morgen Christian,

Vielen Dank für die schnelle und hilfreiche Antwort.
Die Herangehensweise ist eigentlich gar nicht so umständlich: So konfiguriere ich 1 Mal meine Modbus Gateways und lege dann Zähler an! So arbeitet man von Anfang an strukturiert.

Für den ersten Versuch musste ein alter UMG104 herhalten. Mit dem Profil des 604 hat es auf Anhieb funktioniert, allerdings ist die Zykluszeit für die Abfrage deutlich zu hoch. Das macht das Gateway (ein Arduino Uno) nicht mit. Da muss ich mich mal durchwuseln.

Nochmal Danke!

Hallo Klinki,
es freut mich, dass es so gut funktioniert!
Auf Seiten der Edge gibt es eine Core.Cycle Komponente. Die dort eingestellte Zeit hat einen Einfluss auf die Zykluszeit vieler Komponeten. Ich bin mir gerade nicht sicher, aber der Core.Cycle müsste eigentlich auch einen Einfluss auf den Modbus-Abfrage Zyklus haben.
Viele Grüße, Christian

1 Like

Hallo Christian und Klinki,

der Core.Cycle gibt - so wie Christian das bereits vermutet hat - auch die Leserate der Modbus-Register vor. Dazu gibt es auch ein Bild in der Doku: Edge Architecture :: Open Energy Management System

Die Modbus-Bridge wird also versuchen, in jedem Cycle die Werte der Channels zu aktualisieren. Dabei werden ReadTasks mit Priority.HIGH in jedem Cycle ausgeführt und in jedem Cycle jeweils ein Task mit Priority.LOW.

Gruß,
Stefan