I'm currently trying to implement a modbus request that has a custom function code. The implementation is based on this example: custom_message.py
import struct
from pymodbus.pdu import ModbusRequest, ModbusResponse
from pymodbus.client.sync import ModbusTcpClient
client = ModbusTcpClient('192.168.0.55')
connection = client.connect()
class CustomModbusResponse(ModbusResponse):
# some fancy decoding should be done here..
pass
class CustomModbusRequest(ModbusRequest):
function_code = 55
def __init__(self, address):
ModbusRequest.__init__(self)
self.address = address
self.count = 1
def encode(self):
return struct.pack('>HH', self.address, self.count)
def decode(self, data):
self.address, self.count = struct.unpack('>HH', data)
def execute(self, context):
if not (1 <= self.count <= 0x7d0):
return self.doException(ModbusExceptions.IllegalValue)
if not context.validate(self.function_code, self.address, self.count):
return self.doException(ModbusExceptions.IllegalAddress)
values = context.getValues(self.function_code, self.address,
self.count)
return CustomModbusResponse(values)
request = CustomModbusRequest(0)
result = client.execute(request)
print(result)
The request works as expected. I can see the correct response on the network layer. However I can't parse the result. Pymodbus is throwing the following error:
DEBUG:pymodbus.factory:Factory Response[55]
ERROR:pymodbus.factory:Unable to decode response Modbus Error: Unknown response 55
ERROR:pymodbus.transaction:Modbus Error: [Input/Output] Unable to decode request
The example states that in this case, I would have to:
If you implement a new method that is not currently implemented, you must register the request and response with a ClientDecoder factory.
Is there an elegant way to do this without patching the library?