esphome / issues

Issue Tracker for ESPHome
https://esphome.io/
290 stars 35 forks source link

modbus_controller register ranges are note created properly if there is no gap between them #5524

Open FloMeyer opened 7 months ago

FloMeyer commented 7 months ago

The problem

If one range follows the other, the ranges are not created properly.

Given the following sensors:

  - platform: modbus_controller
    id: status_1
    name: "Status 1"
    address: 3000
    register_type: read
    value_type: U_WORD
    register_count: 125

  - platform: modbus_controller
    id: status_2
    name: "status_2"
    address: 3125
    register_type: read
    value_type: U_WORD
    register_count: 125

  - platform: modbus_controller
    id: status_3
    name: "status_3"
    address: 3250
    register_type: read
    value_type: U_WORD
    register_count: 125

This should result in 3 ranges: 3000-3124 (count 125) 3125-3249 (count 125) 3250-3374 (count 125)

But the result is:

[23:36:49][C][modbus_controller:299]: Address: 0x01

[23:36:49][C][modbus_controller:303]: Sensor type=4 start=0xBB8 offset=0x0 count=125 size=250 [23:36:49][C][modbus_controller:303]: Sensor type=4 start=0xBB8 offset=0xF4 count=125 size=250 [23:36:49][C][modbus_controller:303]: Sensor type=4 start=0xBB8 offset=0xFA count=125 size=250

[23:36:49][C][modbus_controller:309]: Range type=4 start=0xBB8 count=119 skip_updates=0 [23:36:49][C][modbus_controller.sensor:010]: modbus_controller.sensorModbus Controller Sensor 'Status 1' . . .

If there is a gap between the ranges, it is working:

  - platform: modbus_controller
    id: status_1
    name: "Status 1"
    address: 3000
    register_type: read
    value_type: U_WORD
    register_count: 124

  - platform: modbus_controller
    id: status_2
    name: "status_2"
    address: 3125
    register_type: read
    value_type: U_WORD
    register_count: 124

  - platform: modbus_controller
    id: status_3
    name: "status_3"
    address: 3250
    register_type: read
    value_type: U_WORD
    register_count: 125

[23:40:55][C][modbus_controller:299]: Address: 0x01

[23:40:55][C][modbus_controller:303]: Sensor type=4 start=0xBB8 offset=0x0 count=124 size=248 [23:40:55][C][modbus_controller:303]: Sensor type=4 start=0xC35 offset=0x0 count=124 size=248 [23:40:55][C][modbus_controller:303]: Sensor type=4 start=0xCB2 offset=0x0 count=125 size=250

[23:40:55][C][modbus_controller:309]: Range type=4 start=0xBB8 count=124 skip_updates=0 [23:40:55][C][modbus_controller:309]: Range type=4 start=0xC35 count=124 skip_updates=0 [23:40:55][C][modbus_controller:309]: Range type=4 start=0xCB2 count=125 skip_updates=0

Which version of ESPHome has the issue?

2024.2.0

What type of installation are you using?

Home Assistant Add-on

Which version of Home Assistant has the issue?

2024.2

What platform are you using?

ESP8266

Board

esp07s

Component causing the issue

modbus_controller

Example YAML snippet

No response

Anything in the logs that might be useful for us?

No response

Additional information

No response

FloMeyer commented 7 months ago

I played a little bit with offsets:

  - platform: modbus_controller
    id: status_1
    name: "Status 1"
    address: 3000
    offset: 0
    register_type: read
    value_type: U_WORD
    register_count: 125

  - platform: modbus_controller
    id: status_2
    name: "status_2"
    address: 3125
    offset: 250
    register_type: read
    value_type: U_WORD
    register_count: 125

  - platform: modbus_controller
    id: status_3
    name: "status_3"
    address: 3250
    offset: 500
    register_type: read
    value_type: U_WORD
    register_count: 125

And this brings me the warning:

In function 'void setup()': warning: unsigned conversion from 'int' to 'uint8_t' {aka 'unsigned char'} changes value from '500' to '244' [-Woverflow]

244 is the offset (FA in HEX) from my first try:

[23:36:49][C][modbus_controller:303]: Sensor type=4 start=0xBB8 offset=0x0 count=125 size=250 [23:36:49][C][modbus_controller:303]: Sensor type=4 start=0xBB8 offset=0xF4 count=125 size=250 [23:36:49][C][modbus_controller:303]: Sensor type=4 start=0xBB8 offset=0xFA count=125 size=250

[23:36:49][C][modbus_controller:309]: Range type=4 start=0xBB8 count=119 skip_updates=0

So 0xBB8 (register 3000) + 125 + 125 for the second range would give an "Woverlow" and chaned value to 244 -> offset = 0xF4, this is 6 less than the wanted 250 registers. That's why the range (the 2nd one, which unfortunately replaced the first range?!) has only 119 registers and not the wanted 125.

The Modbus specifications say:

Function        Description                Query           Response
3               Read Holding Registers     125 registers   125 registers
4               Read Input Registers       125 registers   125 registers

So the ranges have to be splitted in parts of 125 each.

ssieb commented 7 months ago

You can work around this by adding the force_new_range option.

FloMeyer commented 7 months ago

Thank you, this is working as a workaround!

But i think this should be fixed nevertheless. Because it is against the specification.

github-actions[bot] commented 3 months ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.