Fix modbus transaction response (#33824)

Sometimes a modbus server do not respond to a transaction,
this is a contradiction to the modbus protocol specification,
but merely a matter of fact.

Use asynio.await_for() to provoke a timeout, and close the
transaction.
This commit is contained in:
jan iversen 2020-04-08 22:04:47 +02:00 committed by Paulus Schoutsen
parent 7eba08f385
commit 663c994dfb

View File

@ -2,6 +2,7 @@
import asyncio
import logging
from async_timeout import timeout
from pymodbus.client.asynchronous import schedulers
from pymodbus.client.asynchronous.serial import AsyncModbusSerialClient as ClientSerial
from pymodbus.client.asynchronous.tcp import AsyncModbusTCPClient as ClientTCP
@ -246,7 +247,12 @@ class ModbusHub:
await self._connect_delay()
async with self._lock:
kwargs = {"unit": unit} if unit else {}
try:
async with timeout(self._config_timeout):
result = await func(address, count, **kwargs)
except asyncio.TimeoutError:
result = None
if isinstance(result, (ModbusException, ExceptionResponse)):
_LOGGER.error("Hub %s Exception (%s)", self._config_name, result)
return result
@ -256,7 +262,11 @@ class ModbusHub:
await self._connect_delay()
async with self._lock:
kwargs = {"unit": unit} if unit else {}
await func(address, value, **kwargs)
try:
async with timeout(self._config_timeout):
func(address, value, **kwargs)
except asyncio.TimeoutError:
return
async def read_coils(self, unit, address, count):
"""Read coils."""