Modbus
Einige Geräte, wie z.b. Zähler (meters
) oder Wallboxen (chargers
) werden über das Modbus-Protokoll angebunden und angesprochen.
Die meter
Konfiguration besteht hierbei aus der Art der pysikalischen Verbindung (Schnittstelle), ggf. den technischen Schnittstellenparametern, dem verwendeten Modbus-Protokoll, der eindeutigen Modbus-ID des Gerätes auf dem Bus und der Nummer und Art des Registers welches letztendlich gelesen oder geschrieben werden soll.
Zu beachten ist, dass es drei verschiedene Modbus-Protokolle gibt: Modbus RTU, Modbus ASCII und Modbus TCP. Diese können technisch auch über unterschiedliche Schnittstellentypen übertragen werden können. Die klassische Variante ist dabei Modbus RTU über eine serielle RS485-Busschnittstelle wie sie bei den meisten Zählern oder manchen Wallboxen genutzt wird. Geräte mit einer nativen Netzwerkschnittstelle (Ethernet/WiFi) hingegen werden typischerweise über das Modbus TCP-Protokoll angesprochen.
Soll ein serielles Modbus-Gerät über einen Schnittstellenkonverter via Netzwerk (Ethernet/WiFi/PowerLAN) angebunden werden kommt dabei letztendlich ein Modbus RTU Protokoll über eine TCP/IP-Verbindung zustande. Das Modbus RTU Protokoll wird dabei 1:1 über das Netzwerk übertragen (sprich "getunnelt"). Auch wenn der Transportweg (TCP/IP) hierbei identisch ist handelt es sich vom Protokoll dennoch NICHT um Modbus TCP! Hierbei muss sehr genau zwischen Protokoll und Transportweg unterschieden werden. "Modbus (RTU) over TCP" ist etwas anderes als Modbus TCP!
Achtung: Es gibt auch komplexere Schnittstellenkonverter die optional das Modbus-Protokoll selbst zwischen Modbus RTU und Modbus TCP übersetzen können! Ist diese Funktion aktiv muss evcc mit dem Konverter mittels Modbus TCP kommunizieren während der Konverter auf der anderen Seite mit dem seriellen Gerät via Modbus RTU kommuniziert und die beiden Protokolle bidirektional übersetzt. Hier muss man ggf. genau auf die Gerätespezifikation und Konfiguration achten sonst ist keine Kommunikation möglich!
Im Falle einer Konfiguration mit einem Schnittstellenkonverter wird die serielle Buskonfiguration nur am Konverter festgelegt. Die evcc-Konfiguration betrifft dann nur den Abschnitt zum Konverter.
Physikalische Verbindung
Serielle Verbindung (RS485)
Wenn das Gerät direkt über einen RS485-Adapter verbunden ist (Modbus RTU), muss device
und die seriellen Kommunikationsparameter baudrate
, comset
entsprechend der Gerätekonfiguration angegeben werden.
Dazu bitte die jeweilige Betriebanleitung, Datenblätter oder Systemeinstellungen vergleichen.
An einem seriellen RS485-Bus lassen sich mehrere Geräte mit identischen Kommunikationsparameter betreiben wenn jedes Gerät eine eigene Modbus ID zugewiesen bekommen hat. Lassen sich nicht alle Geräte an einem Bus auf einheitliche Kommunikationseinstellungen (aber unterschiedliche IDs) konfigurieren ist eine Aufteilung auf mehrere voneinander unabhängige Bussysteme erforderlich.
Das Mischen von Geräten mit voneinander abweichenden seriellen Kommunikationsparametern an einem Bus ist nicht möglich und führt zu unvorhersehbaren Kommunikationsfehlern.
Beispiel:
source: modbus
id: 1
device: /dev/ttyUSB0
baudrate: 38400
comset: "8E1"
Direkte Netzwerkverbindung
Wenn das Gerät direkt über eine native Netzwerkverbindung (Modbus TCP) angebunden ist, muss eine uri
bestehend aus HOSTNAME:PORT oder IP:PORT angegeben werden:
Beispiel:
source: modbus
id: 1
uri: 192.168.0.11:502
Serielles Gerät über Netzwerkverbindung (mit Schnittstellenkonverter)
Wird ein serielles Gerät über einen zwischengeschalteten transparenten RS485-IP-Schnittstellenkonverter (ohne Protokollübersetzung) angeschlossen muss das Protokoll über die TCP/IP-Verbindung zusätzlich mittels rtu: true
auf Modbus RTU umgestellt werden.
Beispiel:
source: modbus
id: 1
uri: 192.168.0.10:502
rtu: true # Modbus RTU over TCP
Vordefinierte Geräte
Die integrierten vordefinierten Gerätemodelle model
sind identisch zu MBMD:
ABB ABB A/B-Series meters DDM DDM18SD DZG DZG Metering GmbH DVH4013 meters IEM3000 Schneider Electric iEM3000 series INEPRO Inepro Metering Pro 380 JANITZA Janitza meters MPM Bernecker Engineering MPM3PM meters ORNO1P ORNO WE-514 & WE-515 ORNO1P504 ORNO WE-504 ORNO3P ORNO WE-516 & WE-517 SBC Saia Burgess Controls ALE3 meters SDM Eastron SDM630/120/72DMv2 SDM220 Eastron SDM220 SDM230 Eastron SDM230 SDM72 Eastron SDM72 SEMTR SolarEdge SE-MTR-3Y
Alle davon abweichenden model
werden als Gerät vom Typ SunSpec behandelt.
Verwende value
um den Wert der vom Gerät gelesen werden soll zu definieren. Alle unterstützten Werte sind auf MBMD voreingestellt.
Im Falle eines SunSpec-kompatiblen Wechselrichters oder Zählers werden die zu lesenden Werte in der Form model:[block:]point
nach der SunSpec-Definition angegeben. Zum Beispiel wird die DC-Leistung auf dem zweiten String eines dreiphasigen PV-Wechselrichters (enspricht SunSpec Model 103) wie folgt abgefragt: value: 103:2:W
.
Das Geräte-model
und die Slave ID id
sind immer erforderlich:
Beispiel:
source: modbus
---
model: sdm
value: Power
scale: -1 # floating point factor applied to result, e.g. for kW to W conversion
Manuelle Konfiguration
Falls das Modbus-Gerät nicht direkt unterstützt wird oder von den vordefinierten Modellen abweichende Werte gelesen oder geschrieben werden sollen, können die Modbus Register auch vollständig manuell konfiguriert werden.
Dazu bedarf es neben den allgemeinen 'modbus' Einstellungen (siehe oben) auch der Definition eines registers
an Stelle eines value
, wie bei vordefinierten Geräten. Es ist nicht zulässig, sowohl value
als auch register
anzugeben.
Die Definition eines Registers benötigt folgende Parameter:
address
: die Registeradressetype
: Der Registertyp, zulässig sindcoil
,input
,holding
decode
: Die Art der Codierung der Daten. Zulässig sind:int16|32|64, uint16|32|64, float32|64 and u|int32s + float32s
. Beim Typcoil
wird die Codierung ignoriert, muss aber trotzdem angegeben werden.bitmask
: Eine optionale Angabe. Der angegebene Wert wird mit dem gelesenen UND verknüpft, um so einzelne Bits extrahieren zu können.
Weitere zulässige Parameter einer manuellen Konfiguration sind:
scale
: Fließkommazahl, die zur Konvertierung von gelesenen Werten (z.B. W in kW oder umgekehrt) verwendet werden kann. Dieser Wert wird mit dem gelesenen und decodierten Rohwert multipliziert.timeout
: modbus timeout. Ohne Einheit ist der Wertt in ns, ansonsten Einheit mit angeben, z.B. 10s für 10 Sekunden.
Beispiel:
source: modbus
---
register:
address: 40070
type: holding # coil, holding or input
decode: int32 # int16|32|64, uint16|32|64, float32|64 and u|int32s + float32s
bitmask: 2 # Optional: a bitmask that is applied to the read value. Here the mask is 0000000000000010b, ignored if value is 0
scale: -1.0 # floating point factor applied to result, e.g. for kW to W conversion
timeout: 2s # timeout, without unit in ns
Bei den int32s/uint32s
Dekodierungen wird die Wortreihenfolge vertauscht und sind z.B. bei E3/DC Geräten nützlich.
Schreiben von Registern
Es können sowohl Holding-Register als auch Coils beschrieben werden. Dazu muss entweder type: writeholding
für Holding-Register oder type: writecoil
für Coils angegeben werden.
type: writeholding
schreibt immer ein 16Bit Register (int oder bool16). Für decode
muss hier daher immer uint16
angegeben werden.
type: writecoil
schreibt ein Coil. Angaben für decode
werden ignoriert.
Beispiel:
source: modbus
---
register:
address: 40070
type: writeholding # writeholding oder writecoil
Gesamtbeispiel
Ein vollständiges Beispiel für einen custom Charger mit modbus Interface (hier ein Phoenix EM-CP-PP-ETH mit der IP-Adresse 192.168.1.10) könnte z.B. so aussehen:
Beispiel:
chargers:
- type: custom
name: CustomCharger
status:
# Read the status of the charger
# Either A,B,C or F
source: modbus
id: 180
uri: 192.168.1.10:502
timeout: 3s
register:
address: 100
type: input # Read an input register
decode: int16
enabled:
# Is the charger enabled (1) or not (0)
source: modbus
id: 180
uri: 192.168.1.10:502
register:
address: 400
type: coil # Read a coil
decode: bool16 # Doesn't matter but required
enable:
# Enable the charger
source: modbus
id: 180
uri: 192.168.1.10:502
register:
address: 400
type: writecoil # Write a coil
decode: uint8 # Doesn't matter but required
maxcurrent:
# Set the maximum current
source: modbus
id: 180
uri: 192.168.1.10:502
register:
address: 300
type: writeholding # Write a holding register
decode: uint16