pymodbus icon indicating copy to clipboard operation
pymodbus copied to clipboard

Async code does not support timeout

Open winterscar opened this issue 5 years ago • 3 comments

Versions

  • Python: 3.6
  • OS: Ubuntu 18.04 LTS
  • Pymodbus: 2.1.0
  • Modbus Hardware (if used): N/A

Pymodbus Specific

  • Client: TCP asyncio

Description

There is an issue where the async versions of the library dont respect the timeout. I'm running the asyncio example here and connecting to netcat running on the same machine. However, the code always gets stuck like so:

DEBUG:root:Running Async client
DEBUG:root:------------------------------------------------------
DEBUG:asyncio:Using selector: EpollSelector
DEBUG:pymodbus.client.async.asyncio:Connecting to 10.10.10.14:23.
DEBUG:pymodbus.client.async.asyncio:Connecting.
DEBUG:pymodbus.client.async.asyncio:Client connected to modbus server
INFO:pymodbus.client.async.asyncio:Protocol made connection.
INFO:pymodbus.client.async.asyncio:Connected to 10.10.10.14:23.
DEBUG:root:Reading Coils
DEBUG:pymodbus.client.async.asyncio:send: 0x0 0x1 0x0 0x0 0x0 0x6 0x1 0x1 0x0 0x1 0x0 0x1
DEBUG:pymodbus.transaction:Adding transaction 1

What I expect to happen, is after 1s or so of no response, the query times out and the next one gets sent.

Hotfix

If anyone else has this issue before it is remedied, you can use the following code to add a timeout yourself:

    rr = client.read_coils(1, 1, unit=0x01)
    rr = await asyncio.wait_for(rr, timeout=3)

winterscar avatar Oct 08 '18 08:10 winterscar

BTW. This example will not work

https://pymodbus.readthedocs.io/en/latest/source/example/async_asyncio_serial_client.html

as pymodbus.client.asynchronous.asyncio.AsyncioModbusSerialClient does not support timeout parameter (ver 2.2.0rc1).

wrobell avatar Feb 04 '19 19:02 wrobell

Can you try this with 2.2.0 https://github.com/riptideio/pymodbus/pull/367 was merged into it and I think might help.

Instead of a timeout value passed in you can use asyncio timeouts. https://docs.python.org/3/library/asyncio-task.html#timeouts

pazzarpj avatar May 08 '19 05:05 pazzarpj

I believe I am having a similar issue with hanging code using the AsyncioModbusSerialClient, and I believe it is due to the timeout. The coroutine just hangs forever, and when I use the asyncio.wait_for() workaround I just get a timeout every time.

Using the synchronous equivalent works perfectly fine, provided I use a reasonable timeout value on the serial connection (client.socket.timeout). I am more familiar with minimalmodbus, and its default timeout of 0.05 on the serial connection is too fast for the devices I communicate with. Using the same value in pymodbus also yields a ModbusIoException('No Response received from the remote unit/Unable to decode response', 3).

I am thinking my issue is at the serial port level, so adding the timeout on the await is not going to help when it is something at the lower level timing out. As wrobell commented earlier, the AsyncioModbusSerialClient does not support the timeout parameter (despite the docstring).

kashperanto avatar Jul 30 '19 18:07 kashperanto

timeout is added.

janiversen avatar Sep 10 '22 07:09 janiversen