From c71423e237ae21c5f6eddf9064afecbd07ed7807 Mon Sep 17 00:00:00 2001 From: Andrew Harness Date: Wed, 8 May 2024 13:10:53 -0400 Subject: [PATCH 1/3] Fix writing to serial (rs485) on windows os. --- pymodbus/transport/serialtransport.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pymodbus/transport/serialtransport.py b/pymodbus/transport/serialtransport.py index c783187ad..c54b006f1 100644 --- a/pymodbus/transport/serialtransport.py +++ b/pymodbus/transport/serialtransport.py @@ -55,8 +55,17 @@ def close(self, exc: Exception | None = None) -> None: def write(self, data) -> None: """Write some data to the transport.""" self.intern_write_buffer.append(data) - if not self.poll_task: + if not self.poll_task and os.name != "nt": self.async_loop.add_writer(self.sync_serial.fileno(), self.intern_write_ready) + elif not self.poll_task and os.name == "nt": + self.poll_task = self.async_loop.create_task(self.write_task()) + + async def write_task(self): + """Write data to the serial port.""" + while self.intern_write_buffer: + data = self.intern_write_buffer.pop(0) + self.sync_serial.write(data) + await asyncio.sleep(0) # Yield control to the event loop def flush(self) -> None: """Clear output buffer and stops any more data being written.""" From 241a7ff4743b50b1823d29c5d395f791a6e73aea Mon Sep 17 00:00:00 2001 From: jan iversen Date: Fri, 31 May 2024 19:16:24 +0200 Subject: [PATCH 2/3] update PR. --- pymodbus/transport/serialtransport.py | 15 +++------------ test/transport/test_serial.py | 1 + 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/pymodbus/transport/serialtransport.py b/pymodbus/transport/serialtransport.py index 5a6f269d5..6d632fcae 100644 --- a/pymodbus/transport/serialtransport.py +++ b/pymodbus/transport/serialtransport.py @@ -13,7 +13,7 @@ class SerialTransport(asyncio.Transport): """An asyncio serial transport.""" - force_poll: bool = False + force_poll: bool = os.name == "nt" def __init__(self, loop, protocol, *args, **kwargs) -> None: """Initialize.""" @@ -29,7 +29,7 @@ def __init__(self, loop, protocol, *args, **kwargs) -> None: def setup(self) -> None: """Prepare to read/write.""" - if os.name == "nt" or self.force_poll: + if self.force_poll: self.poll_task = asyncio.create_task(self.polling_task()) self.poll_task.set_name("SerialTransport poll") else: @@ -56,17 +56,8 @@ def close(self, exc: Exception | None = None) -> None: def write(self, data) -> None: """Write some data to the transport.""" self.intern_write_buffer.append(data) - if not self.poll_task and os.name != "nt": + if not self.force_poll: self.async_loop.add_writer(self.sync_serial.fileno(), self.intern_write_ready) - elif not self.poll_task and os.name == "nt": - self.poll_task = self.async_loop.create_task(self.write_task()) - - async def write_task(self): - """Write data to the serial port.""" - while self.intern_write_buffer: - data = self.intern_write_buffer.pop(0) - self.sync_serial.write(data) - await asyncio.sleep(0) # Yield control to the event loop def flush(self) -> None: """Clear output buffer and stops any more data being written.""" diff --git a/test/transport/test_serial.py b/test/transport/test_serial.py index 62f54e8b4..c39e11e4c 100644 --- a/test/transport/test_serial.py +++ b/test/transport/test_serial.py @@ -100,6 +100,7 @@ async def test_write_force_poll(self): ) await asyncio.sleep(0) transport.write(b"abcd") + await asyncio.sleep(0.5) transport.close() SerialTransport.force_poll = False From 4aa44fc235062d93ef4d7e273fa02c2418aae99e Mon Sep 17 00:00:00 2001 From: jan iversen Date: Fri, 31 May 2024 19:30:41 +0200 Subject: [PATCH 3/3] real windows problem. --- test/transport/test_comm.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/transport/test_comm.py b/test/transport/test_comm.py index 4ddf7b742..8b175bc09 100644 --- a/test/transport/test_comm.py +++ b/test/transport/test_comm.py @@ -179,7 +179,6 @@ async def test_serial_poll(self, client, server, use_port): SerialTransport.force_poll = True assert await client.connect() await asyncio.sleep(0.5) - SerialTransport.force_poll = False assert len(server.active_connections) == 1 server_connected = list(server.active_connections.values())[0] test_data = b"abcd" * 1000