-
Notifications
You must be signed in to change notification settings - Fork 949
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sync RTU client timeout not functioning properly in _recv #380
Comments
@muhlbaier What is the read timeout in your client and corresponding read/write timeouts in your custom server. |
@dhoomakethu 1.0s on the client and the server is embedded and has exclusive control of the port so there is no timeout. I have used a logic analyzer to make sure the data on the bus is as expected and it is. There is a 2-5ms delay from the end of the request from the client to the start of the response from the server which is well within the timing requirements @ 115200 baud. |
@muhlbaier Would it help if you increase the read timeout of the client (>1sec)? |
@dhoomakethu I can test but I would be shocked if it helped. All the data is received within 10ms of the request, I'm not sure why the OS (tested on Windows and Linux) returns from self.socket.read(size) so quickly. The code posted above fixes the problem by retrying self.socket.read() until the number of bytes is what we want or we actually hit the timeout. |
@dhoomakethu I don't think the bug is in pymodbus, I think pyserial isn't properly respecting the timeout that is set when pymodbus opens the port. My fix will ensure we at least try reading bytes until we have them or until the timeout has really been reached. |
@muhlbaier I think you are hitting the issue #353, please refer for the solution there.All you need to do is create your client with kwarg |
@dhoomakethu strict=False also fixes the issue. Thank you! |
Versions
Pymodbus Specific
Description
Every few transactions _recv(self, size) in ModbusSerialClient:sync.py returns with no or partial data when elf.socket.read(size) is called and no attempt is made to read more data if there is a timeout set > 0. The scenario generates a warning like this:
WARNING:hublog:Modbus Error: [Input/Output] No Response received from the remote unit/Unable to decode response
Then, since data is received by the serial port after _recv is called on the next transaction you get a warning about the data being dumped:
WARNING:pymodbus.client.sync:Cleanup recv buffer before send: 0x2 0x7 0x0 0x16 0x1 0x45 0x0 0xa 0x0 0x1f 0x0 0x0 0x2a 0xf8 0x2e 0xe0 0x0 0x1b 0x71 0x7d 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x5b 0x19
The fix is pretty simple, if not enough bytes are received and timeout is > 0 then keep trying to received until the timeout is up. I made the following fix in _recv in the ModbusSerialClient class of client\sync.py and I went from dropping 43% of my responses to 0%.
The same fix could be applied to recvPacket in framer\rtu_framer.py or in _transact or _recv in transaction.py.
Please let me know if the fix should be left in _recv of ModbusSerialClient or if it would be better to move it elsewhere and then I can make a PR.
Code and Logs
The text was updated successfully, but these errors were encountered: