[Modbus Controller] multiple server_regiser addresses can be identical /overlap · Issue #6998 · esphome/issues · GitHub
More Web Proxy on the site http://driver.im/
You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It is possible to define more than one server_register option containing identical address.
This is unexpected behavior and will likely surprise users
It appears that the first server_register that is configured with a particular address "wins" based on how the underlying C++ code handles the incoming modbus command requests
Overlapping Addresses
It is possible to define server_register options with overlapping address ranges.
This is unexpected behavior, but it is possible that some installations are taking advantage of this quirk
Which version of ESPHome has the issue?
2025.5.0-dev
What type of installation are you using?
Docker
Which version of Home Assistant has the issue?
NA this can be seen without any HomeAssistant connections
What platform are you using?
ESP32
Board
Lolin32-Lite
Component causing the issue
modbus_controller
YAML Config
### Duplicate Addressesuart:
- id: uart_modbus_servertx_pin: GPIO25rx_pin: GPIO35baud_rate: 57600modbus:
- uart_id: uart_modbus_serverid: modbus_serverrole: servermodbus_controller:
- modbus_id: modbus_serveraddress: 0x1server_registers:
- address: 0x0000value_type: U_WORDread_lambda: |- return(22);
- address: 0x0000# note the duplicate addressvalue_type: U_WORDread_lambda: |- return(42);### Overlapping Address Rangesmodbus_controller:
- modbus_id: modbus_serveraddress: 0x1server_registers:
- address: 0x0000value_type: U_FP32read_lambda: |- return(22.0);
- address: 0x0001# note the overlapping address with the high word of the FP32 value_type: U_WORDread_lambda: |- return(42);
Anything in the logs that might be useful for us?
Additional information
Potential Fix for Identical Address Issue
In order to fix the identical addresses issue, it seems like a check can be added to the modbus_controller/__init__.py verification schema.
One possible solution is to create an empty set of server_register addresses and check on each server_register list item if the address exists in the set, if it does, fail the validation, if it is not in the set, add the register to the set.
Potential Fix for Overlapping Addresses Issue
The overlapping register ranges quirk potentially allows for hidden registers If individual modbus command 0x3 or 0x4 read commands are sent with the correct start address and with the correct number of registers, the current modbus_controller server component will allow these overlapping registers.
Fixing the overlapping ranges can also use a set of addresses, but instead of checking for an individual address in a set, create a check_set which is the range of addresses from address .. (address + register_count(value_type) -1). This check set can be inspected for intersection with the set of addresses. if there are any intersections, fail the validation. If the check set and set of addresses are disjoint then add the check set to the set of addresses.
Note
It is possible that some installations are taking advantage of the quirk of register overlapping.
I am not sure if the overlapping check should be a configurable option or just forced on the users.
Implications for future Write* Command Support
If server role support for 0x5, 0x6 or 0x10 modbus write (coil / register / registers) commands are added it would seem that this overlapping quirk will need to be eliminated.
Example
A block of 4 registers for a U_QWORD are reserved at address 0x0000 and then a U_WORD is reserved at address 0x001
modbus_controller:
- modbus_id: modbus_serveraddress: 0x1server_write_registers:
- address: 0x0000value_type: U_QWORDwrite_lambda: |- ESP_LOGD("write_lambda", "Updating address %u of QWORD\n", last_address);
- address: 0x0001# note the overlapping address with the U_QWORDvalue_type: U_WORDwrite_lambda: |- ESP_LOGD("write_lambda", "Updatint address %u of U_WORD\n", last_address);
What should happen when a write register command 0x6 is specified for register address 0x0001?
Should the second highest word in the U_QWORD be updated and its write_lambda be called, or should the U_WORD at address 0x0001 be updated and its write_lambda be called?
The text was updated successfully, but these errors were encountered:
The problem
Identical Addresses
It is possible to define more than one
server_register
option containing identical address.This is unexpected behavior and will likely surprise users
It appears that the first
server_register
that is configured with a particular address "wins" based on how the underlying C++ code handles the incoming modbus command requestsOverlapping Addresses
It is possible to define
server_register
options with overlapping address ranges.This is unexpected behavior, but it is possible that some installations are taking advantage of this quirk
Which version of ESPHome has the issue?
2025.5.0-dev
What type of installation are you using?
Docker
Which version of Home Assistant has the issue?
NA this can be seen without any HomeAssistant connections
What platform are you using?
ESP32
Board
Lolin32-Lite
Component causing the issue
modbus_controller
YAML Config
Anything in the logs that might be useful for us?
Additional information
Potential Fix for Identical Address Issue
In order to fix the identical addresses issue, it seems like a check can be added to the
modbus_controller/__init__.py
verification schema.One possible solution is to create an empty set of server_register addresses and check on each server_register list item if the address exists in the set, if it does, fail the validation, if it is not in the set, add the register to the set.
Potential Fix for Overlapping Addresses Issue
The overlapping register ranges quirk potentially allows for hidden registers If individual modbus command 0x3 or 0x4 read commands are sent with the correct start address and with the correct number of registers, the current
modbus_controller
server component will allow these overlapping registers.Fixing the overlapping ranges can also use a set of addresses, but instead of checking for an individual address in a set, create a check_set which is the range of addresses from
address .. (address + register_count(value_type) -1)
. This check set can be inspected for intersection with the set of addresses. if there are any intersections, fail the validation. If the check set and set of addresses are disjoint then add the check set to the set of addresses.Note
It is possible that some installations are taking advantage of the quirk of register overlapping.
I am not sure if the overlapping check should be a configurable option or just forced on the users.
Implications for future
Write*
Command SupportIf server role support for 0x5, 0x6 or 0x10 modbus write (coil / register / registers) commands are added it would seem that this overlapping quirk will need to be eliminated.
Example
A block of 4 registers for a U_QWORD are reserved at address 0x0000 and then a U_WORD is reserved at address 0x001
What should happen when a write register command
0x6
is specified for register address 0x0001?Should the second highest word in the U_QWORD be updated and its write_lambda be called, or should the U_WORD at address 0x0001 be updated and its write_lambda be called?
The text was updated successfully, but these errors were encountered: