Modbus TCP – Schnellstartanleitung
Ergänzung zur Modbus-TCP-Registerdokumentation. Diese Seite beschreibt, was die Ladestation von einem EMS erwartet, bevor die Ladesteuerung über Modbus TCP wie erwartet arbeitet, und die Schreibsequenzen, gegen die wir testen. Entspricht dem Firmware-Verhalten mit Stand Juli 2026.
Adressierung
Registeradressen erscheinen in zwei Schreibweisen, und Modbus-Werkzeuge sind sich uneinig, welche sie erwarten. Diese Anleitung nennt immer beide:
- die Registernummer (40202, 30027, …) – die übliche 1-basierte Schreibweise aus den Registertabellen, und
- die PDU-Adresse – der Wert, der tatsächlich über die Leitung geht: Registernummer minus 40001 bei Holding-Registern, minus 30001 bei Input-Registern.
Holding-Register (4xxxx) werden mit FC03 gelesen und mit FC06/FC16 geschrieben. Input-Register (3xxxx) sind nur lesbar, FC04. Wenn Ihr Werkzeug einen Versatz um eins zeigt, verwechselt es fast immer diese beiden Schreibweisen. Ein Wert, der zulässig aussieht und trotzdem abgelehnt wird, liegt dagegen meist an der zweiten clientseitigen Ursache – siehe Wertcodierung weiter unten.
Register, die in dieser Anleitung vorkommen:
| Name | Register | PDU (dez) | PDU (hex) | Zugriff |
|---|---|---|---|---|
| ChargeMode | 40107 | 106 | 0x006A | FC03 lesen, FC06/16 schreiben |
| Set_Charge_Current_Target | 40202 | 201 | 0x00C9 | FC03 lesen, FC06/16 schreiben |
| Start_Stop_Charging | 40203 | 202 | 0x00CA | FC03 lesen, FC06/16 schreiben |
| Failsafe_Timeout | 40204 | 203 | 0x00CB | FC03 lesen, FC06/16 schreiben |
| Failsafe_Current_Target | 40206 | 205 | 0x00CD | FC03 lesen, FC06/16 schreiben |
| Heartbeat | 40208 | 207 | 0x00CF | FC06/16 schreiben |
| EVCS_State | 30001 | 0 | 0x0000 | FC04 |
| ErrorCode | 30004 | 3 | 0x0003 | FC04 |
| Failsafe_Active | 30027 | 26 | 0x001A | FC04 |
| DaemonStatus | 30050 | 49 | 0x0031 | FC04 |
| Availability | 30101 | 100 | 0x0064 | FC04 |
| OfferedCurrentLimit | 30105 | 104 | 0x0068 | FC04 |
| EV_Present | 30201 | 200 | 0x00C8 | FC04 |
| Charging | 30202 | 201 | 0x00C9 | FC04 |
| CP_Status | 30203 | 202 | 0x00CA | FC04 |
Wertcodierung
Modbus ist Big-Endian, und dieses Gateway hält sich in beide Richtungen exakt daran:
- Bytereihenfolge: Jedes 16-Bit-Register wird mit dem höherwertigen Byte
zuerst übertragen. Ein Stromsollwert von 10 A geht als
00 0Aauf den Bus, niemals als0A 00. - Wortreihenfolge: Werte über mehrere Register tragen das höherwertige Wort an der niedrigeren Registeradresse. Das betrifft nur die f32- und u32-Telemetrieregister – jedes beschreibbare Steuerregister dieser Anleitung ist ein einzelnes u16.
Manche Clients bieten beides als Einstellung pro Objekt an, statt es aus dem Protokoll abzuleiten. Dann müssen alle Objekte auf Big-Endian stehen, und korrekt dekodierte Telemetrie ist kein Beleg dafür, dass die Schreibobjekte genauso eingestellt sind. Die Wortreihenfolge ist bei den Steuerregistern harmlos, weil es Einzelregister sind – die Bytereihenfolge ist es nicht. Ein bytevertauschter Wert kommt trotzdem an, nur still verändert: Aus einem Sollwert 10 wird 2560, aus 8 wird 2048, beides weit außerhalb des zulässigen Bereichs. Der Schreibzugriff wird mit Exception 0x03 abgelehnt, während der Wert auf Ihrem Bildschirm völlig korrekt aussieht.
Das Erkennungsmerkmal: Jeder Stromsollwert wird abgelehnt, egal welchen Sie wählen – nur 0 funktioniert, denn eine Bytevertauschung lässt 0 unverändert. Wenn Sie die Einstellung in Ihrem Client nicht finden, senden Sie 2560 als Sollwert: bytevertauscht ist das 10. Wird der Schreibzugriff angenommen und lädt die Ladestation mit 10 A, ist die Vertauschung bestätigt. Skalierungen oder Korrekturtabellen im Client für diesen Test abschalten.
Die Kurzfassung
-
Fahrzeug anstecken. EV_Present 30201 (PDU 200) muss 1 sein, CP_Status 30203 (PDU 202) muss 1, 2 oder 3 sein (IEC-61851-Zustände B/C/D).
-
Ladestation in den manuellen Lademodus schalten: ChargeMode 40107 (PDU 106) = 2 schreiben. Das muss vor jedem Sollwert geschehen – jeder Moduswechsel setzt die Strombegrenzung auf das konfigurierte Maximum zurück.
-
Ladung mit einem einzigen FC16-Telegramm starten, das Set_Charge_Current_Target 40202 (PDU 201) = 6..32 A und Start_Stop_Charging 40203 (PDU 202) = 1 gemeinsam schreibt:
Code -
Sitzung am Leben halten. Der Failsafe-Watchdog ist ab Werk aktiv mit 20 s Timeout, also Heartbeat 40208 (PDU 207, beliebiger Wert) mindestens alle 10 s schreiben – oder 40202 in diesem Takt erneut schreiben.
-
Zum Ändern des Stroms 40202 erneut schreiben. Die Ladestation folgt binnen weniger Sekunden; die Telemetrieregister aktualisieren im Abstand von bis zu 5 s.
-
Zum Beenden 40203 = 0 schreiben (oder 40202 = 0).
Anfragen gehen an die konfigurierte Unit ID (Standard 1, im Web-Oberfläche sichtbar). Bei einem Master mit angebundenen Slave-Boxen antwortet jede Slave-Ladestation unter ihrer eigenen Unit ID hinter der IP-Adresse des Masters.
Manueller Modus – und warum die anderen Modi dagegenhalten
Die Salia kennt drei Lademodi: Eco (0), Power (1) und Manuell (2). Nur Manuell übergibt die Strombegrenzung an eine externe Steuerung.
In Eco und Power läuft die interne Ladesteuerung alle 3 Sekunden
(charge_control_interval in der Stationskonfiguration, Standard 3.0) und
schreibt ihr eigenes Ergebnis auf denselben Begrenzungskanal, den auch das
Modbus-Gateway beschreibt:
- Power hebt die Begrenzung je Takt um rund 1 A an, bis das konfigurierte Maximum erreicht ist. Solange ein Fahrzeug angesteckt ist, aber noch nicht lädt, setzt Power die Begrenzung in jedem Takt direkt auf das Maximum.
- Eco bewegt die Begrenzung je Takt um 1 A nach oben oder unten und folgt damit dem Solarüberschuss. Der wandernde Strom im Eco-Modus ist gewolltes Verhalten, kein Fehler.
Ein über Modbus geschriebener Sollwert überlebt daher höchstens bis zum nächsten Takt. Im manuellen Modus lässt die interne Steuerung den Begrenzungskanal in Ruhe, und der Modbus-Wert bleibt in Kraft.
Weitere Punkte, die dazugehören:
- Der Modus wird von der Ladestation persistent gespeichert, 40107 = 2 übersteht also einen Neustart. Solar- und Eco-Logik bleiben aus, bis jemand den Modus zurückschaltet (Web-Oberfläche oder Register).
- Jeder Moduswechsel setzt die Strombegrenzung zurück: Wechsel nach Power oder Manuell setzt sie auf das konfigurierte Maximum, Wechsel nach Eco während einer laufenden Ladung auf das Minimum. Also erst den Modus schreiben, dann den Sollwert – und nach jedem späteren Moduswechsel 40202 erneut schreiben.
- Der Wechsel nach Power schaltet außerdem Eco+ ab und erzwingt bei Ladestationen mit Phasenumschaltung dreiphasigen Betrieb.
- Der Autorisierungsmodus (frei / RFID / OCPP / Schlüsselschalter) ist eine Stationseinstellung; ein Modbus-Register dafür gibt es nicht (Register 30022 / PDU 21 meldet ihn nur). Bei Ladestationen an einem OCPP-Backend kann das Backend Sitzungen autorisieren oder die Autorisierung entziehen und eigene Grenzen auf dieselbe Ladestation legen – für Integrationstests ist es daher einfacher, den Autorisierungsmodus in der Web-Oberfläche auf „free“ (frei) zu stellen. Ein Modbus-Start (40203 = 1) setzt die Sitzungsautorisierung auf der Ladestation selbst.
Was den Strom sonst noch bewegt – in jedem Modus
Die folgenden Mechanismen greifen auch im manuellen Modus. Sie sind gewollt und keine Modbus-Fehler:
- Hausanschluss-Absicherung. Bei Anlagen mit Netzzähler senkt die Ladesteuerung die Begrenzung oder pausiert die Ladung, wenn die Gebäudeversorgung an ihre Sicherungsgrenze läuft. Wird eine solche Pause aufgehoben, steht die Begrenzung wieder auf dem konfigurierten Maximum – danach 40202 erneut schreiben.
- Lastmanagement und Netzbetreibergrenze. Verbundene Ladestationen teilen sich ein Strombudget, die Netzbetreibergrenze liegt auf einem eigenen Kanal. Der dem Fahrzeug tatsächlich angebotene Strom ist durch den niedrigsten aktiven Kanal begrenzt; ein zweites ladendes Fahrzeug oder eine Netzvorgabe kann den gelieferten Strom jederzeit unter Ihren Sollwert ziehen. Werden 32 A an einer auf 16 A begrenzten Ladestation angefordert, ergibt das 16 A – eine Begrenzung, kein Fehler.
Das alte Heartbeat-Flag (nicht der Modbus-Failsafe)
Die Salia hat zusätzlich eine ältere, separate Heartbeat-Funktion: das Flag
heartbeat in der Stationskonfiguration (saliaconf), geschaltet über das
MQTT-Topic port0/salia/heartbeat. Ist dieses Flag gesetzt und trifft auf dem
Topic länger als 60 s keine Nachricht ein, zwingt die Ladesteuerung die
Strombegrenzung in jedem 3-s-Takt auf das konfigurierte Minimum, solange ein
Fahrzeug lädt – in jedem Lademodus, auch im manuellen. Das Modbus-Gateway
veröffentlicht dieses Topic nie.
Auf einer Modbus-gesteuerten Ladestation muss dieses Flag auf false stehen. Wir haben Ladestationen im Feld gesehen, bei denen es aktiv war; das Erkennungsmerkmal ist ein Strom, der alle paar Sekunden exakt auf das Stationsminimum (meist 6 A) einbricht.
Prüfliste vor der Registersuche
| Prüfung | Wo | Erwartet |
|---|---|---|
| Fahrzeug angesteckt | 30201 / PDU 200, 30203 / PDU 202 | 1; CP in B/C/D |
| Ladestation betriebsbereit | 30101 / PDU 100 | 1 |
| Kein aktiver Fehler | 30004 / PDU 3 | 0 (7 bedeutet Failsafe aktiv) |
| Lademodus | 40107 / PDU 106 | 2 (manuell) |
| Ladung kommandiert | 40203 / PDU 202 | 1 (nach Neustart wieder 0) |
| Stromsollwert | 40202 / PDU 201 | 6..32 (0 = Stopp) |
| Daemon bereit | 30050 / PDU 49, Bit 0 | 1 (Anfragen im Startvorgang liefern 0x06) |
| Altes Heartbeat-Flag aus | saliaconf heartbeat | false (Web-/Service-Zugang) |
Stolperfallen
- 40202 allein zu schreiben bewirkt nichts, solange 40203 = 0 ist. Das Gateway kommandiert dann 0 A an die Ladestation, unabhängig vom geschriebenen Sollwert. Immer mit dem Paar 40202 + 40203 in einem FC16-Telegramm starten.
- 40202 und 40203 sind flüchtig. Nach einem Daemon-Neustart oder einem Reboot der Box stehen sie wieder auf 0, und das EMS muss die Startsequenz erneut senden.
- Der Failsafe-Watchdog ist ab Werk aktiv: Failsafe_Timeout 40204 (PDU 203) steht standardmäßig auf 20 s, Failsafe_Current_Target 40206 (PDU 205) standardmäßig auf 0 A. Trifft innerhalb des Timeouts kein angenommener Steuerschreibzugriff (40202, 40203, 40208, 40209) ein, fällt die Ladestation auf den Failsafe-Strom zurück, ErrorCode 30004 liest 7 und Failsafe_Active 30027 (PDU 26) liest 1. Der nächste angenommene Schreibzugriff stellt Ihren Sollwert wieder her. Ein EMS, das nur einmal pro Minute schreibt, sieht den Strom zwischen Sollwert und Rückfallwert springen. Entweder Heartbeats im halben Timeout senden, 40204/40206 auf Werte setzen, die zu Ihrem Regeltakt passen (10..3600 s, 0 oder 6..32 A), oder den Watchdog mit 40204 = 0 abschalten. An einer im Leerlauf stehenden Ladestation ohne EMS-Verkehr ist ErrorCode 7 mit Failsafe_Active 1 der normale Ruhezustand und kein Defekt.
- Der Sollwert ist eine Anforderung, keine Zusage. Siehe den Abschnitt zu den Begrenzungen oben; OfferedCurrentLimit 30105 (PDU 104), CurrentOffered 30106+ und die Zählerströme 31009+ (PDU 1008+) zeigen, was tatsächlich angeboten und gezogen wird.
- Set_Charge_Power_Target 40201 (PDU 200) ist nicht implementiert. Schreibzugriffe werden angenommen und gespeichert, bleiben aber wirkungslos. Stattdessen den Stromsollwert 40202 verwenden.
- 30202 („Charging“, PDU 201, FC04) ist ein reines Lesestatus-Flag und nicht beschreibbar. Es wird leicht mit 40202 verwechselt – gleiche Endziffern, anderer Registerraum.
- Der Rücklesewert von 40107 kann veralten: Er wird beim Start des Daemons und bei EMS-Schreibzugriffen gesetzt, ein späterer Moduswechsel in der Web-Oberfläche wird aber nicht ins Register zurückgespiegelt. Im Zweifel zeigt das Web-Oberfläche den tatsächlich wirksamen Modus.
Symptome und Ursachen
Eine nützliche Abkürzung: Der Wert, auf den der Strom springt, verrät meist, welcher Mechanismus beteiligt ist.
| Symptom | Wahrscheinliche Ursache |
|---|---|
| Schreiben auf 40202 angenommen, es lädt nichts | 40203 = 0, kein Fahrzeug / CP = A, oder ErrorCode ≠ 0 |
| Strom kriecht zurück Richtung Maximum, ~1 A alle 3 s | Lademodus ist Power → 40107 = 2 setzen |
| Strom wandert ±1 A um einen solargeführten Wert | Lademodus ist Eco (so gewollt) → für EMS-Steuerung Manuell |
| Strom fällt ~20 s nach dem letzten Schreibzugriff auf den Failsafe-Wert (Standard 0 A), ErrorCode = 7 | Failsafe-Watchdog ausgelöst → häufiger Heartbeat, oder 40204 anpassen/abschalten |
| Strom bricht alle paar Sekunden exakt auf das Stationsminimum ein | saliaconf-Flag heartbeat steht auf true → auf false setzen |
| Strom springt direkt nach einem Moduswechsel auf das Maximum | Rücksetzen der Begrenzung durch den Moduswechsel → nach Ändern von 40107 erneut 40202 schreiben |
| Strom niedriger als der Sollwert, während eine verbundene Box mitlädt | Aufteilung des Lastmanagement-Budgets (kein Fehler) |
| Jeder Schreibzugriff auf 40202 wird abgelehnt, egal welcher Wert – nur 0 wird angenommen | Bytereihenfolge des Clients ist nicht Big-Endian → siehe Wertcodierung |
| Exception 0x03 beim Schreiben | Wert außerhalb 0 / 6..32 (die Stationskonfiguration kann den Bereich enger ziehen). Liegt der gesendete Wert im Bereich, ist die Bytereihenfolge des Clients verdächtig – eine vertauschte 10 kommt als 2560 an |
| Exception 0x03 beim Start (40203 = 1); 0x04 bei Firmware vor MapVersion 2.1.0 | Stromsollwert 40202 steht noch auf 0 – erst den Sollwert schreiben, am besten beides in einem FC16-Telegramm |
| Exception 0x06 | Ratenbegrenzung (50 Anfragen/s je IP) oder Daemon startet noch (30050 Bit 0 prüfen) |
| Lief vor einem Neustart, danach nie wieder | Die flüchtigen 40202/40203 stehen wieder auf 0 → Startsequenz erneut senden |
Eine Sitzung überprüfen
Nach dem Start abfragen (FC04, sofern nicht anders angegeben):
- 30001 EVCS_State (PDU 0) = 2 (CHARGING) und 30202 Charging (PDU 201) = 1
- 30004 ErrorCode (PDU 3) = 0 und 30027 Failsafe_Active (PDU 26) = 0
- 30105 OfferedCurrentLimit (PDU 104) und 30106+ CurrentOffered = Ihr Sollwert oder die Begrenzung der Ladestation
- 31009+ Zählerströme (PDU 1008+) = was das Fahrzeug tatsächlich zieht; dass das Fahrzeug weniger zieht als angeboten, ist normal
Wenn Ihre Beobachtung nicht zu dieser Anleitung passt, senden Sie uns die Firmware-Version zusammen mit den Werten aus localhost/api der Salia – wir schauen uns das an.

