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.
pull/33843/head
jan iversen 2020-04-08 22:04:47 +02:00 committed by GitHub
parent 7dd42bc32d
commit 2d1002d40d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 12 additions and 2 deletions

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
@ -242,7 +243,12 @@ class ModbusHub:
await self._connect_delay()
async with self._lock:
kwargs = {"unit": unit} if unit else {}
result = await func(address, count, **kwargs)
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
@ -252,7 +258,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."""