Open JPSteindlberger opened 1 year ago
This issue also just occured to me. My heating unit provides only int32
registers and I can perfectly read everything and publish to MQTT - but the way back does not work. When using the pymodbus.console
-application and calling write_registers as you proposed, I can set new values, so I assume that is the same issue.
> client.read_holding_registers address=1036 count=2 unit=1
{
"registers": [
0,
420
]
}
> client.write_registers address=1036 values=0,500 unit=1
{
"address": 1036,
"count": 2
}
> client.read_holding_registers address=1036 count=2 unit=1
{
"registers": [
0,
500
]
}
You can get round this issue by converting your two 32 bit into two 16 bits. These two 16 bits are not the values you would expect but have to be converted in a special way. I don't fully understand how it works but if you play around on this website with conversions from 16bit to 32 bit and then back again it may become clearer to you.
https://cryptii.com/pipes/integer-converter
If you have Node-red then this flow I use shows the nodes where I convert a 16 bit value into 32 bit values that work.
https://flows.nodered.org/flow/7db69e532e4c58eb8078724092c4308a
Just don't ask me to explain, it just works.
What you must understand is that your modbus server does not have any 32 bit registers, it just has 2 concurrent 16 bit registers that when jointly read can be processed and converted to a 32 bit register but all this happens outside the server. So to write backwards you also need to reverse this conversion.
In https://github.com/tjhowse/modbus4mqtt/blob/d563879da1608c2757b74978d48cce48e946d05f/modbus4mqtt/modbus_interface.py#L149 self._mb.write_register is used. But this writes only one address at once, which is only valid for devices expecting 16 bit values. Devices with values like int32 or int64 expect writing all relevant addresses at once and not in sequence. Hence self._mb.write_registers (plural) is required. Sure, this might require code changes at many other positions.