2929    ModbusTlsFramer ,
3030)
3131from  pymodbus .logging  import  Log 
32- from  pymodbus .pdu  import  ModbusRequest 
32+ from  pymodbus .pdu  import  ModbusRequest ,  ModbusResponse 
3333from  pymodbus .transport  import  CommType 
3434from  pymodbus .utilities  import  ModbusTransactionState , hexlify_packets 
3535
@@ -167,13 +167,13 @@ def _set_adu_size(self):
167167        else :
168168            self .base_adu_size  =  - 1 
169169
170-     def  _calculate_response_length (self , expected_pdu_size ) :
170+     def  _calculate_response_length (self , expected_pdu_size :  int )  ->   int   |   None :
171171        """Calculate response length.""" 
172172        if  self .base_adu_size  ==  - 1 :
173173            return  None 
174174        return  self .base_adu_size  +  expected_pdu_size 
175175
176-     def  _calculate_exception_length (self ):
176+     def  _calculate_exception_length (self )  ->   int   |   None :
177177        """Return the length of the Modbus Exception Response according to the type of Framer.""" 
178178        if  isinstance (self .client .framer , (ModbusSocketFramer , ModbusTlsFramer )):
179179            return  self .base_adu_size  +  2   # Fcode(1), ExceptionCode(1) 
@@ -183,7 +183,9 @@ def _calculate_exception_length(self):
183183            return  self .base_adu_size  +  2   # Fcode(1), ExceptionCode(1) 
184184        return  None 
185185
186-     def  _validate_response (self , request : ModbusRequest , response , exp_resp_len , is_udp = False ):
186+     def  _validate_response (
187+             self , request : ModbusRequest , response : bytes  |  int , exp_resp_len : int  |  None , is_udp = False 
188+     ) ->  bool :
187189        """Validate Incoming response against request. 
188190
189191        :param request: Request sent 
@@ -208,7 +210,7 @@ def _validate_response(self, request: ModbusRequest, response, exp_resp_len, is_
208210            return  mbap .get ("length" ) ==  exp_resp_len 
209211        return  True 
210212
211-     def  execute (self , request : ModbusRequest ):  # noqa: C901 
213+     def  execute (self , request : ModbusRequest )  ->   ModbusResponse   |   bytes   |   ModbusIOException :  # noqa: C901 
212214        """Start the producer to send the next request to consumer.write(Frame(request)).""" 
213215        with  self ._transaction_lock :
214216            try :
@@ -333,7 +335,9 @@ def execute(self, request: ModbusRequest):  # noqa: C901
333335                self .client .close ()
334336                return  exc 
335337
336-     def  _retry_transaction (self , retries , reason , packet , response_length , full = False ):
338+     def  _retry_transaction (
339+             self , retries : int , reason : str , request : ModbusRequest , response_length : int  |  None , full = False 
340+     ) ->  tuple [bytes , str  |  Exception  |  None ]:
337341        """Retry transaction.""" 
338342        Log .debug ("Retry on {} response - {}" , reason , retries )
339343        Log .debug ('Changing transaction state from "WAITING_FOR_REPLY" to "RETRYING"' )
@@ -350,9 +354,11 @@ def _retry_transaction(self, retries, reason, packet, response_length, full=Fals
350354                if  response_length  ==  in_waiting :
351355                    result  =  self ._recv (response_length , full )
352356                    return  result , None 
353-         return  self ._transact (packet , response_length , full = full )
357+         return  self ._transact (request , response_length , full = full )
354358
355-     def  _transact (self , request : ModbusRequest , response_length , full = False , broadcast = False ):
359+     def  _transact (
360+             self , request : ModbusRequest , response_length : int  |  None , full = False , broadcast = False 
361+     ) ->  tuple [bytes , str  |  Exception  |  None ]:
356362        """Do a Write and Read transaction. 
357363
358364        :param packet: packet to be sent 
@@ -368,16 +374,12 @@ def _transact(self, request: ModbusRequest, response_length, full=False, broadca
368374            packet  =  self .client .framer .buildPacket (request )
369375            Log .debug ("SEND: {}" , packet , ":hex" )
370376            size  =  self ._send (packet )
371-             if  (
372-                 isinstance (size , bytes )
373-                 and  self .client .state  ==  ModbusTransactionState .RETRYING 
374-             ):
377+             if  size  and  self .client .state  ==  ModbusTransactionState .RETRYING :
375378                Log .debug (
376379                    "Changing transaction state from " 
377380                    '"RETRYING" to "PROCESSING REPLY"' 
378381                )
379382                self .client .state  =  ModbusTransactionState .PROCESSING_REPLY 
380-                 return  size , None 
381383            if  self .client .comm_params .handle_local_echo  is  True :
382384                if  self ._recv (size , full ) !=  packet :
383385                    return  b"" , "Wrong local echo" 
@@ -405,23 +407,22 @@ def _transact(self, request: ModbusRequest, response_length, full=False, broadca
405407            result  =  b"" 
406408        return  result , last_exception 
407409
408-     def  _send (self , packet : bytes , _retrying = False ):
410+     def  _send (self , packet : bytes , _retrying = False )  ->   int :
409411        """Send.""" 
410412        return  self .client .framer .sendPacket (packet )
411413
412-     def  _recv (self , expected_response_length , full ) ->  bytes :  # noqa: C901 
414+     def  _recv (self , expected_response_length :  int   |   None , full :  bool ) ->  bytes :  # noqa: C901 
413415        """Receive.""" 
414416        total  =  None 
415417        if  not  full :
416418            exception_length  =  self ._calculate_exception_length ()
419+             min_size  =  expected_response_length 
417420            if  isinstance (self .client .framer , ModbusSocketFramer ):
418421                min_size  =  8 
419422            elif  isinstance (self .client .framer , ModbusRtuFramer ):
420423                min_size  =  4 
421424            elif  isinstance (self .client .framer , ModbusAsciiFramer ):
422425                min_size  =  5 
423-             else :
424-                 min_size  =  expected_response_length 
425426
426427            read_min  =  self .client .framer .recvPacket (min_size )
427428            if  len (read_min ) !=  min_size :
@@ -462,7 +463,7 @@ def _recv(self, expected_response_length, full) -> bytes:  # noqa: C901
462463                    if  expected_response_length  is  not None :
463464                        expected_response_length  -=  min_size 
464465                        total  =  expected_response_length  +  min_size 
465-                 else :
466+                 if   func_code   >=   0x80   and   exception_length :
466467                    expected_response_length  =  exception_length  -  min_size 
467468                    total  =  expected_response_length  +  min_size 
468469            else :
0 commit comments