diff --git a/pymodbus/server/async_io.py b/pymodbus/server/async_io.py old mode 100755 new mode 100644 index 729eecf54..6f48bf23a --- a/pymodbus/server/async_io.py +++ b/pymodbus/server/async_io.py @@ -92,6 +92,7 @@ def __init__(self, owner): self.running = False self.receive_queue = asyncio.Queue() self.handler_task = None # coroutine to be run on asyncio loop + self._sent = b'' # for handle_local_echo def _log_exception(self): """Show log exception.""" @@ -450,6 +451,17 @@ def connection_lost(self, call_exc): def data_received(self, data): """Receive data.""" + if (hasattr(self.server, "handle_local_echo") + and self.server.handle_local_echo is True + and self._sent): + if self._sent in data: + data, self._sent = data.replace(self._sent, b'', 1), b'' + elif self._sent.startswith(data): + self._sent, data = self._sent.replace(data, b'', 1), b'' + else: + self._sent = b'' + if not data: + return self.receive_queue.put_nowait(data) async def _recv_(self): @@ -458,6 +470,9 @@ async def _recv_(self): def _send_(self, data): if self.transport is not None: self.transport.write(data) + if (hasattr(self.server, "handle_local_echo") + and self.server.handle_local_echo is True): + self._sent = data # --------------------------------------------------------------------------- # @@ -784,6 +799,7 @@ def __init__( :param parity: Which kind of parity to use :param baudrate: The baud rate to use for the serial device :param timeout: The timeout to use for the serial device + :param handle_local_echo: (optional) Discard local echo from dongle. :param ignore_missing_slaves: True to not send errors on a request to a missing slave :param broadcast_enable: True to treat unit_id 0 as broadcast address, @@ -800,6 +816,7 @@ def __init__( self.timeout = kwargs.get("timeout", Defaults.Timeout) self.device = kwargs.get("port", 0) self.stopbits = kwargs.get("stopbits", Defaults.Stopbits) + self.handle_local_echo = kwargs.get("handle_local_echo", Defaults.HandleLocalEcho) # handle_local_echo: bool = None ; handle_local_echo: bool = Defaults.HandleLocalEcho, self.ignore_missing_slaves = kwargs.get( "ignore_missing_slaves", Defaults.IgnoreMissingSlaves ) @@ -849,6 +866,7 @@ async def _connect(self): parity=self.parity, stopbits=self.stopbits, timeout=self.timeout, + # handle_local_echo=self.handle_local_echo, ) except serial.serialutil.SerialException as exc: txt = f"Failed to open serial port: {self.device}"