Standard-Konfiguration der Modbus-Schnittstelle
Automatisch generiert am: 2026-10-02 14:51:24 CEST
Generated from: Version 1.0.1 (Commit: 995abc7aa88c, Build: 2026-10-02T12:16:17+00:00Z)
Modbus-Server-Parameter
Hinweis: Der Modbus-Server wird auf den Standard-Modbus-TCP-Port 502 gemappt, sodass Clients sich wie gewohnt verbinden können. Erreichbar ist der Server dann unter <IP-Adresse>:502 wobei die IP Adresse die des Hostsystems ist. Im Normalfall werden die Geräte mit DHCP arbeiten, sodass die IP-Adresse automatisch zugewiesen wird. Es wird empfohlen im Router eine feste IP-Adresse zu konfigurieren.
| Parameter | Standardwert | Bedeutung | Als Umgebungsvariable setzbar |
|---|---|---|---|
| protocol | tcp | Verwendetes Modbus-Protokoll (aktuell steht nur tcp zur Verfügung). | MODBUS_PROTOCOL |
| ip | 0.0.0.0 | IP-Adresse oder Hostname, auf dem der Modbus-Server intern lauscht. Extern wird die IP-Adresse des Hostsystems verwendet. | MODBUS_IP |
| port | 5020 | TCP-Port des internen Modbus-Servers. Dieser wird auf den Modbus TCP-Port 502 gemappt. | MODBUS_PORT |
| update_interval | 0.1 | Abstand zwischen zwei internen Modbus-Updatezyklen in Sekunden. | - |
| maximum_responses_per_cycle | 20 | Maximale Anzahl bearbeiteter Anfragen pro Zyklus. | - |
| timeout | 30 | Timeout fuer Modbus-Kommunikation in Sekunden. | - |
| string_encoding | utf-8 | String-Encoding fuer Register mit Textdaten. | MODBUS_STRING_ENCODING |
| byteorder | little | Byte-Reihenfolge fuer die Konvertierung mehrbyteiger Werte. | MODBUS_BYTEORDER |
Register-Definition
Hinweis: Die erste verknuepfte Pumpe beginnt bei Register 100. Die Registeradresse berechnet sich mit: Pumpen-Nr * 100 + Address-Offset.
Alle Adressen sind 1-basierte Registernummern. Im Modbus-Telegramm steht die Adresse minus 1 (Register 100 = Protokolladresse 99); Clients, die Protokolladressen erwarten (z. B. pymodbus), muessen 1 abziehen.
| Name | Register-Typ | Address-Offset | Count | Daten-Typ | Zugriff | Einheit | Min | Max | Standardwert | Beschreibung |
|---|---|---|---|---|---|---|---|---|---|---|
| flow_rate | holding | 0 | 2 | float | rw | qmh | 0.0 | 10000.0 | 0.0 | Flow rate in cubic meters per hour |
| pressure_pressure_side | holding | 2 | 2 | float | rw | bar | -1.0 | 20.0 | 0.0 | Pressure on the pressure side in bar |
| pressure_suction_side | holding | 4 | 2 | float | rw | bar | -1.0 | 20.0 | 0.0 | Pressure on the suction side in bar |
| pressure_prefilter | holding | 6 | 2 | float | rw | bar | -1.0 | 20.0 | 0.0 | Pressure on the prefilter in bar |
| rotational_speed | holding | 8 | 2 | int | rw | rpm | -3600 | 3600 | 0 | Rotational speed in revolutions per minute |
| shaft_power | holding | 10 | 2 | uint | rw | W | 0 | 150000 | 0 | Shaft power in watts |
| motor_current | holding | 12 | 2 | float | rw | A | 0.0 | 5000.0 | 0.0 | Motor current in amperes |
| motor_voltage | holding | 14 | 2 | uint | rw | V | 0 | 700 | 0 | Motor voltage in volts |
| motor_operating_hours | holding | 16 | 2 | uint | rw | s | 0 | 4294967295 | 0 | Motor operating hours in seconds |
| motor_energy_consumption | holding | 18 | 2 | uint | rw | kWh | 0 | 4294967295 | 0 | Motor energy consumption in kilowatt-hours |
| fc_statusword | holding | 20 | 2 | uint | rw | - | 0 | 65535 | 0 | Statusword of the frequency converter |
| fc_errorcode | holding | 22 | 2 | uint | rw | - | 0 | 4294967295 | 0 | Error code of the frequency converter |
| fill_level_surge_tank | holding | 24 | 2 | float | rw | bar | 0.0 | 10.0 | 0.0 | Fill level in the surge tank in bar |
| prefilter_cleaning_done | holding | 26 | 2 | bool | rw | - | - | - | False | Indicates if prefilter cleaning is done (False = not done, True = done) |
| prefilter_contamination_level | holding | 28 | 2 | uint | rw | - | 0 | 4 | 0 | Prefilter contamination level (0 = no contamination (clean), 1 = low contamination, 2 = medium contamination, 3 = high contamination) |
| flow_rate_calculated | input | 0 | 2 | float | r | qmh | 0.0 | 10000.0 | 0.0 | Flow rate in cubic meters per hour estimated |
| pressure_difference_calculated | input | 2 | 2 | float | r | bar | -1.0 | 20.0 | 0.0 | Differential pressure calculated in bar |
| efficiency | input | 4 | 2 | float | r | percent | 0.0 | 100.0 | 0.0 | Pump efficiency in percent |
| pump_statusword | input | 6 | 2 | uint | r | - | 0 | 4294967295 | 0 | Status word of the pump |
| prefilter_state | input | 8 | 2 | uint | r | - | 0 | 65535 | 0 | Prefilter state (e.g., 0 = clean, 1 = cleaning recommended, 2 = cleaning required) |
| name | input | 10 | 30 | string | r | - | - | - | Name of the pump | |
| serial | input | 40 | 10 | string | r | - | - | - | Serial number of the pump |
Geraeteidentifikation (FC 43 / 0x2B)
Die App beantwortet Read Device Identification (Function Code 43, MEI-Typ 14 / 0x0E) mit allen vier Zugriffsarten: 01 Basic, 02 Regular, 03 Extended (als Stream, bei Bedarf ueber mehrere Antworten mit More Follows) und 04 einzelnes Objekt. Conformity Level ist 0x83.
Pflicht sind laut Modbus-Spezifikation nur die Basic-Objekte 0x00-0x02. Alle Werte sind ASCII-Texte und werden unabhaengig von byteorder und string_encoding uebertragen.
| OID | Objekt | Kategorie | Wert |
|---|---|---|---|
0x00 |
VendorName | Basic (Pflicht) | Herborner Pumpen |
0x01 |
ProductCode | Basic (Pflicht) | hp.modbus-connector |
0x02 |
MajorMinorRevision | Basic (Pflicht) | Version der App, z. B. 1.4.2 |
0x03 |
VendorUrl | Regular | https://herborner-pumpen.com |
0x04 |
ProductName | Regular | HP.ModbusConnector |
0x05 |
ModelName | Regular | Modbus TCP Server |
0x06 |
UserApplicationName | Regular | MODBUS-CONNECTOR |
0x80 |
Build | Extended | Version und Commit des Builds, z. B. 1.4.2-a1b2c3d4e5f6 |
0x81 |
Hostname | Extended | Hostname des App-Containers |
0x82 |
Geraete-Ident | Extended | SHA256 der FLECS-Lizenz (64 Hex-Zeichen), identifiziert das Geraet eindeutig¹ |
0x83 |
FLECS-Version | Extended | Version des FLECS-Core, z. B. v3.2.0¹ |
0x84 |
Architektur | Extended | CPU-Architektur des Geraets, z. B. arm64¹ |
0x85 |
Layout-Version | Extended | Version der Belegung von Input-Register 1-99, aktuell 1 |
¹ Aus der FLECS-API. Die App fragt sie beim Start ab, bei Misserfolg bis zu 3-mal im Abstand von 60 s. Bis dahin bzw. danach fehlen diese Objekte.
Fehlerantworten: ungueltiger Zugriffscode -> Exception 03, unbekanntes Einzelobjekt -> Exception 02, anderer MEI-Typ -> Exception 01.
Info-Block Input Register 1-99
Die Input Register 1-99 (Protokolladressen 0-98) beschreiben das Geraet, die Registerbelegung und den Zustand der App. Sie sind nur lesbar. Zahlen und Texte folgen byteorder und string_encoding wie alle uebrigen Register; zu lange Texte werden abgeschnitten - vollstaendig stehen sie in der Geraeteidentifikation.
| Register | Name | Typ | Bedeutung |
|---|---|---|---|
| 1 | signature_hp | uint16 | Signatur "HP", unabhaengig von Byte-Reihenfolge und Encoding |
| 2 | signature_mb | uint16 | Signatur "MB", unabhaengig von Byte-Reihenfolge und Encoding |
| 3 | layout_version | uint16 | Version dieser Belegung; nur bekannte Versionen auswerten |
| 4-5 | byteorder_probe | uint32 | Immer 0x12345678; die Reihenfolge der Woerter zeigt die Byte-Reihenfolge |
| 6 | byteorder | uint16 | Byte-Reihenfolge: 0 = big, 1 = little |
| 7 | string_encoding | uint16 | String-Encoding: 0 utf-8, 1 latin-1, 2 ascii, 3 cp1252, 4 utf-16 |
| 8 | version_major | uint16 | App-Version Major |
| 9 | version_minor | uint16 | App-Version Minor |
| 10 | version_patch | uint16 | App-Version Patch |
| 11-12 | build_time | uint32 | Build-Zeitpunkt in Unix-Sekunden (UTC) |
| 13-28 | vendor_name | String, 32 Byte | Herstellername |
| 29-44 | product_name | String, 32 Byte | Produktname |
| 45-52 | product_code | String, 16 Byte | Produktcode |
| 53-60 | flecs_version | String, 16 Byte | Version des FLECS-Core¹ |
| 61-68 | hostname | String, 16 Byte | Hostname des App-Containers |
| 69-76 | device_ident | String, 16 Byte | Erste 16 Zeichen des Geraete-Idents (SHA256 der FLECS-Lizenz)¹ |
| 77-80 | arch | String, 8 Byte | CPU-Architektur des Geraets¹ |
| 81 | register_space_pump | uint16 | Register je Pumpe; Pumpe i beginnt bei i x diesem Wert |
| 82 | register_offset_entity | uint16 | Erstes Register des Entity-Bereichs |
| 83 | register_space_entity | uint16 | Register je Entity |
| 84 | register_count_entity_datablock | uint16 | Register je Entity-Datenpunkt |
| 85 | status_word | uint16 | Statuswort, Bits siehe unten |
| 86 | heartbeat | uint16 | Zaehlt je Austauschzyklus um 1 hoch und laeuft nach 65535 auf 0 ueber; steht er still, liefert die App keine frischen Daten |
| 87 | active_connections | uint16 | Anzahl verbundener Modbus-Clients |
| 88 | num_pumps | uint16 | Anzahl konfigurierter Pumpen |
| 89 | num_entities | uint16 | Anzahl konfigurierter Entities |
| 90-91 | uptime | uint32 | Laufzeit des Modbus-Servers in Sekunden |
| 92-93 | unix_time | uint32 | Aktuelle Uhrzeit des Geraets in Unix-Sekunden (UTC) |
| 94-99 | reserviert | - | Immer 0 |
¹ Aus der FLECS-API, bis dahin leer (siehe Geraeteidentifikation).
Bits im Statuswort:
| Bit | Name | Bedeutung |
|---|---|---|
| 0 | flecs_info_loaded | Die Geraetedaten der FLECS-API wurden gelesen |
| 1 | pumps_configured | Mindestens eine Pumpe ist konfiguriert |
| 2 | client_connected | Mindestens ein Modbus-Client ist verbunden (fuer den lesenden Client also immer gesetzt) |
Beispiel: Read Input Registers (Server -> Client)
Function Code: 4 (Read Input Registers)
Startadresse: 1 (Protokolladresse 0)
Anzahl Register: 99
Byte-Reihenfolge: little, Encoding: utf-8
Payload: [18512, 19778, 1, 22136, 4660, 1, 0, 1, 4, 2, 63936, 27324, 25928, 25202, 29295, 25966, 8306, 30032, 28781, 28261, 0, 0, 0, 0, 0, 0, 0, 0, 20552, 19758, 25711, 30050, 17267, 28271, 25966, 29795, 29295, 0, 0, 0, 0, 0, 0, 0, 28776, 27950, 25711, 30050, 11635, 28515, 28270, 25445, 13174, 12846, 12334, 0, 0, 0, 0, 0, 12641, 12898, 13155, 13412, 13669, 13926, 0, 0, 26163, 24889, 25392, 25911, 25137, 25650, 25396, 25909, 29281, 13933, 52, 0, 100, 20000, 1000, 10, 7, 1234, 2, 3, 1, 24464, 1, 19627, 27327, 0, 0, 0, 0, 0, 0]
| Name | Register | Beispielwert | Kodierte Registerwoerter |
|---|---|---|---|
| signature_hp | 1 | 0x4850 | 0x4850 |
| signature_mb | 2 | 0x4D42 | 0x4D42 |
| layout_version | 3 | 1 | 0x0001 |
| byteorder_probe | 4-5 | 0x12345678 | 0x5678 0x1234 |
| byteorder | 6 | 1 | 0x0001 |
| string_encoding | 7 | 0 | 0x0000 |
| version_major | 8 | 1 | 0x0001 |
| version_minor | 9 | 4 | 0x0004 |
| version_patch | 10 | 2 | 0x0002 |
| build_time | 11-12 | 1790769600 | 0xF9C0 0x6ABC |
| vendor_name | 13-28 | Herborner Pumpen | 0x6548 0x6272 0x726F 0x656E 0x2072 0x7550 0x706D 0x6E65 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 |
| product_name | 29-44 | HP.ModbusConnector | 0x5048 0x4D2E 0x646F 0x7562 0x4373 0x6E6F 0x656E 0x7463 0x726F 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 |
| product_code | 45-52 | hp.modbus-connector (gekuerzt auf 16 Byte) | 0x7068 0x6D2E 0x646F 0x7562 0x2D73 0x6F63 0x6E6E 0x6365 |
| flecs_version | 53-60 | v3.2.0 | 0x3376 0x322E 0x302E 0x0000 0x0000 0x0000 0x0000 0x0000 |
| hostname | 61-68 | a1b2c3d4e5f6 | 0x3161 0x3262 0x3363 0x3464 0x3565 0x3666 0x0000 0x0000 |
| device_ident | 69-76 | 3f9a0c7e1b2d4c5e | 0x6633 0x6139 0x6330 0x6537 0x6231 0x6432 0x6334 0x6535 |
| arch | 77-80 | arm64 | 0x7261 0x366D 0x0034 0x0000 |
| register_space_pump | 81 | 100 | 0x0064 |
| register_offset_entity | 82 | 20000 | 0x4E20 |
| register_space_entity | 83 | 1000 | 0x03E8 |
| register_count_entity_datablock | 84 | 10 | 0x000A |
| status_word | 85 | 7 | 0x0007 |
| heartbeat | 86 | 1234 | 0x04D2 |
| active_connections | 87 | 2 | 0x0002 |
| num_pumps | 88 | 3 | 0x0003 |
| num_entities | 89 | 1 | 0x0001 |
| uptime | 90-91 | 90000 | 0x5F90 0x0001 |
| unix_time | 92-93 | 1790921899 | 0x4CAB 0x6ABF |
Beispiele fuer Modbus-Datentransfer
Gesamtnachricht: Write Holding Registers (Client -> Server)
Function Code: 16 (Write Multiple Holding Registers)
Startadresse: 100 (Protokolladresse 99)
Anzahl Register: 30
Payload (alle Holding Register): [53801, 17863, 41943, 48880, 62915, 16536, 10486, 16492, 2433, 0, 26868, 0, 30720, 17747, 558, 0, 4505, 27651, 51822, 1952, 28657, 0, 58948, 39453, 34079, 16563, 1, 0, 1, 0]
| Register | Adresse | Count | Beispielwert | Kodierte Registerwoerter |
|---|---|---|---|---|
| flow_rate | 100-101 | 2 | 6394.27 | [53801, 17863] |
| pressure_pressure_side | 102-103 | 2 | -0.47 | [41943, 48880] |
| pressure_suction_side | 104-105 | 2 | 4.78 | [62915, 16536] |
| pressure_prefilter | 106-107 | 2 | 3.69 | [10486, 16492] |
| rotational_speed | 108-109 | 2 | 2433 | [2433, 0] |
| shaft_power | 110-111 | 2 | 26868 | [26868, 0] |
| motor_current | 112-113 | 2 | 3383.5 | [30720, 17747] |
| motor_voltage | 114-115 | 2 | 558 | [558, 0] |
| motor_operating_hours | 116-117 | 2 | 1812140441 | [4505, 27651] |
| motor_energy_consumption | 118-119 | 2 | 127978094 | [51822, 1952] |
| fc_statusword | 120-121 | 2 | 28657 | [28657, 0] |
| fc_errorcode | 122-123 | 2 | 2585650756 | [58948, 39453] |
| fill_level_surge_tank | 124-125 | 2 | 5.61 | [34079, 16563] |
| prefilter_cleaning_done | 126-127 | 2 | True | [1, 0] |
| prefilter_contamination_level | 128-129 | 2 | 1 | [1, 0] |
Gesamtnachricht: Read Input Registers (Server -> Client)
Function Code: 4 (Read Input Registers)
Startadresse: 100 (Protokolladresse 99)
Anzahl Register: 50
Payload (Antwort mit allen Input Registern): [24760, 17804, 57672, 16538, 56361, 17069, 29969, 27696, 36421, 0, 21840, 20557, 12589, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20051, 13357, 12338, 13361, 0, 0, 0, 0, 0, 0]
| Register | Adresse | Count | Beispielwert | Kodierte Registerwoerter |
|---|---|---|---|---|
| flow_rate_calculated | 100-101 | 2 | 4492.09 | [24760, 17804] |
| pressure_difference_calculated | 102-103 | 2 | 4.84 | [57672, 16538] |
| efficiency | 104-105 | 2 | 86.93 | [56361, 17069] |
| pump_statusword | 106-107 | 2 | 1815115025 | [29969, 27696] |
| prefilter_state | 108-109 | 2 | 36421 | [36421, 0] |
| name | 110-139 | 30 | PUMP-1 | [21840, 20557, 12589, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] |
| serial | 140-149 | 10 | SN-42014 | [20051, 13357, 12338, 13361, 0, 0, 0, 0, 0, 0] |