-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
Versions
- Python: 3.5.3
- OS: Raspbian Stretch
- Pymodbus: 1.4.0 / 1.3.2
- Modbus Hardware (if used):
Pymodbus Specific
- Server: tcp - async
- Client: tcp/rtu - sync/async
Description
Since upgrading pymodbus to v.1.4.0 the client works fine for a while and then throws an "ERROR :[Failure instance: Traceback (failure with no frames): <class 'pymodbus.exceptions.ConnectionException'>: Modbus Error: [Connection] Connection lost during request]". The program normally hangs and the error is only shown when the program is shut down. In reference to the code below, it doesn't get to "fetch_1ph_registers_from_power_meter".
Looking at the server, it seems that this only happens when the message starts with a "0x1". In relation to a normal factory request, only the first line shows. In my case, it usually hangs when the timestamp is sent every 30s. Under v.1.3.2 these messages are being processed normally, so I just reverted back for now.
I did adapt the BinaryPayloadBuilder for v.1.4.0 to "byteorder=Endian.Big" instead of "endian=Endian.Big". I also tried specifying both, byteorder and wordorder, but no success either.
Code and Logs
Normal Log:
2018-01-04 16:58:06 DEBUG :0x0 0xfd 0x0 0x0 0x0 0xb 0x0 0x10 0x7 0xd2 0x0 0x2 0x4 0x5a 0x4e 0x5d 0x1e
2018-01-04 16:58:06 DEBUG :0x0 0xfd 0x0 0x0 0x0 0xb 0x0 0x10 0x7 0xd2 0x0 0x2 0x4 0x5a 0x4e 0x5d 0x1e
2018-01-04 16:58:06 DEBUG :Factory Request[16]
2018-01-04 16:58:06 DEBUG :validate[16] 2003:2
2018-01-04 16:58:06 DEBUG :setValues[16] 2003:2
2018-01-04 16:58:06 DEBUG :send: b'00fd00000006001007d20002'
Broken Log:
2018-01-04 16:58:36 DEBUG :0x1 0x0 0x0 0x0 0x0 0xb 0x0 0x10 0x7 0xd2 0x0 0x2 0x4 0x5a 0x4e 0x5d 0x3d
Client code based on async processor example (http://pymodbus.readthedocs.io/en/latest/source/example/asynchronous_processor.html):
class ExampleProtocol(ModbusClientProtocol):
def __init__(self, framer, endpoint, input):
ModbusClientProtocol.__init__(self, framer)
self.endpoint = endpoint
self.input = input
log.info("Beginning the processing loop")
reactor.callLater(1, self.get_time)
def get_time(self):
log.info("Starting the next cycle")
d = self.input.getTime()
d.addCallbacks(self.write_time_to_server)
d.addErrback(self.error_handler)
def write_time_to_server(self,response):
d = self.write_registers(2002, response)
d.addCallbacks(self.fetch_1ph_registers_from_power_meter)
d.addErrback(self.error_handler)
def fetch_1ph_registers_from_power_meter(self, response):
d = self.input.get1PhRegisters()
d.addCallbacks(self.send_1ph_registers_to_server)
d.addErrback(self.error_handler)
...
...
class SmartMeterInterface(object):
def getTime(self):
Timestamp = int(round(time.time()))
builder = BinaryPayloadBuilder(endian=Endian.Big)
builder.add_32bit_uint(Timestamp)
payload = builder.to_registers()
return defer.succeed(payload)
...
...