pythonpymodbus

Pymodbus: catch packet and perform operation based on function


I am implementing a modbus server in python using the Pymodbus library (v3.0.2). While the server is running, I have a parallel thread that updates some of its registers, to simulate data variation, using the setValues method of the ModbusSlaveContext. This data are queried by a second machine via RTU/485 serial protocol, using the modbus function 03. From this second machine I can also request writing data, sending modbus commands 05/06/15/16 to my server. When I receive this commands, I want to persist the address/value pairs on a file. I tried the following:

  1. Implement a custom datablock (derived from ModbusSequentialDatablock), overriding the setValues function, but this catch both the 05/06/15/16 commands and the setValues calls in the updating thread, because I can't recognize which modbus function has been received
  2. Implement a custom framer (derived from ModbusRtuFramer), but, in this case, many times I get incomplete frames:
class MyFramer(ModbusRtuFramer):

    def processIncomingPacket(self, data, callback, unit, **kwargs):
        res = super().processIncomingPacket(data, callback, unit, **kwargs)

        # the device address is in the first byte of the raw data
        device = int(data[0])

        # the function code is in the second byte of the raw data
        function = int(data[1])

        # the address is always in the same position: for single register the
        # meaning is absolute address, for multiple registers the meaning is
        # starting address
        address = (int(data[2]) * 256) + int(data[3]) #<-- Runtime error, many times data has only 1 or 2 bytes
...

Solution

  • My solution was to implement my custom slave context, deriving it from ModbusSlaveContext. I implement a custom version of setValues, with an additional parameters dont_persist (which defaults to 0, meaning the value must be written to a file on disk). Then, in my updating function, I pass the value True to this argument, which means the value is not written to file.