33
44import asyncio
55import socket
6+ from abc import abstractmethod
67from collections .abc import Awaitable , Callable
78from dataclasses import dataclass
89from typing import Any , cast
1415from pymodbus .framer import FRAMER_NAME_TO_CLASS , FramerType , ModbusFramer
1516from pymodbus .logging import Log
1617from pymodbus .pdu import ModbusRequest , ModbusResponse
17- from pymodbus .transaction import ModbusTransactionManager
18+ from pymodbus .transaction import SyncModbusTransactionManager
1819from pymodbus .transport import CommParams
1920from pymodbus .utilities import ModbusTransactionState
2021
@@ -53,7 +54,6 @@ def __init__(
5354 framer : FramerType ,
5455 timeout : float = 3 ,
5556 retries : int = 3 ,
56- retry_on_empty : bool = False ,
5757 broadcast_enable : bool = False ,
5858 reconnect_delay : float = 0.1 ,
5959 reconnect_delay_max : float = 300 ,
@@ -81,8 +81,6 @@ def __init__(
8181 stopbits = kwargs .get ("stopbits" , None ),
8282 handle_local_echo = kwargs .get ("handle_local_echo" , False ),
8383 ),
84- retries ,
85- retry_on_empty ,
8684 on_connect_callback ,
8785 )
8886 self .no_resend_on_retry = no_resend_on_retry
@@ -143,7 +141,7 @@ def idle_time(self) -> float:
143141 return 0
144142 return self .last_frame_end + self .silent_interval
145143
146- def execute (self , request : ModbusRequest | None = None ):
144+ def execute (self , request : ModbusRequest ):
147145 """Execute request and get response (call **sync/async**).
148146
149147 :param request: The request to process
@@ -165,7 +163,7 @@ async def async_execute(self, request) -> ModbusResponse:
165163 count = 0
166164 while count <= self .retries :
167165 async with self ._lock :
168- req = self .build_response (request . transaction_id )
166+ req = self .build_response (request )
169167 if not count or not self .no_resend_on_retry :
170168 self .ctx .framer .resetFrame ()
171169 self .ctx .send (packet )
@@ -187,25 +185,17 @@ async def async_execute(self, request) -> ModbusResponse:
187185
188186 return resp # type: ignore[return-value]
189187
190- def build_response (self , tid ):
188+ def build_response (self , request : ModbusRequest ):
191189 """Return a deferred response for the current request."""
192190 my_future : asyncio .Future = asyncio .Future ()
191+ request .fut = my_future
193192 if not self .ctx .transport :
194193 if not my_future .done ():
195194 my_future .set_exception (ConnectionException ("Client is not connected" ))
196195 else :
197- self .ctx .transaction .addTransaction (my_future , tid )
196+ self .ctx .transaction .addTransaction (request )
198197 return my_future
199198
200- # ----------------------------------------------------------------------- #
201- # Internal methods
202- # ----------------------------------------------------------------------- #
203- def recv (self , size ):
204- """Receive data.
205-
206- :meta private:
207- """
208-
209199 # ----------------------------------------------------------------------- #
210200 # The magic methods
211201 # ----------------------------------------------------------------------- #
@@ -309,10 +299,10 @@ def __init__(
309299 self .slaves : list [int ] = []
310300
311301 # Common variables.
312- self .framer = FRAMER_NAME_TO_CLASS .get (
302+ self .framer : ModbusFramer = FRAMER_NAME_TO_CLASS .get (
313303 framer , cast (type [ModbusFramer ], framer )
314304 )(ClientDecoder (), self )
315- self .transaction = ModbusTransactionManager (
305+ self .transaction = SyncModbusTransactionManager (
316306 self , retries = retries , retry_on_empty = retry_on_empty , ** kwargs
317307 )
318308 self .reconnect_delay_current = self .params .reconnect_delay or 0
@@ -346,7 +336,7 @@ def idle_time(self) -> float:
346336 return 0
347337 return self .last_frame_end + self .silent_interval
348338
349- def execute (self , request : ModbusRequest | None = None ) -> ModbusResponse :
339+ def execute (self , request : ModbusRequest ) -> ModbusResponse :
350340 """Execute request and get response (call **sync/async**).
351341
352342 :param request: The request to process
@@ -360,22 +350,28 @@ def execute(self, request: ModbusRequest | None = None) -> ModbusResponse:
360350 # ----------------------------------------------------------------------- #
361351 # Internal methods
362352 # ----------------------------------------------------------------------- #
363- def send (self , request ):
353+ def _start_send (self ):
364354 """Send request.
365355
366356 :meta private:
367357 """
368358 if self .state != ModbusTransactionState .RETRYING :
369359 Log .debug ('New Transaction state "SENDING"' )
370360 self .state = ModbusTransactionState .SENDING
371- return request
372361
373- def recv (self , size ):
362+ @abstractmethod
363+ def send (self , request : bytes ) -> int :
364+ """Send request.
365+
366+ :meta private:
367+ """
368+
369+ @abstractmethod
370+ def recv (self , size : int | None ) -> bytes :
374371 """Receive data.
375372
376373 :meta private:
377374 """
378- return size
379375
380376 @classmethod
381377 def get_address_family (cls , address ):
0 commit comments