@@ -182,11 +182,14 @@ async def _execute_request(self, request_type: str, address: int, **kwargs: Any)
182182 await self ._ensure_connected ()
183183
184184 if request_type == "read" :
185- result = await self ._client .read_holding_registers (address = address , count = kwargs ["count" ], device_id = self .slave_id )
185+ count = kwargs .get ("count" , 1 )
186+ result = await self ._client .read_holding_registers (address = address , count = count , device_id = self .slave_id )
186187 elif request_type == "write" :
187- result = await self ._client .write_register (address = address , value = kwargs ["value" ], device_id = self .slave_id )
188+ value = kwargs ["value" ]
189+ result = await self ._client .write_register (address = address , value = value , device_id = self .slave_id )
188190 elif request_type == "write_multiple" :
189- result = await self ._client .write_registers (address = address , values = kwargs ["values" ], device_id = self .slave_id )
191+ values = kwargs ["values" ]
192+ result = await self ._client .write_registers (address = address , values = values , device_id = self .slave_id )
190193 else :
191194 self ._raise_unknown_request_type (request_type )
192195
@@ -400,30 +403,30 @@ async def _execute_request(self, request_type: str, address: int, **kwargs: Any)
400403
401404 if request_type == "read" :
402405 count = kwargs .get ("count" , 1 )
403- result = await self ._client .read_holding_registers (address , count , slave = self ._slave_id )
406+ result = await self ._client .read_holding_registers (address = address , count = count , device_id = self ._slave_id )
404407 elif request_type == "write" :
405408 value = kwargs ["value" ]
406- result = await self ._client .write_register (address , value , slave = self ._slave_id )
409+ result = await self ._client .write_register (address = address , value = value , device_id = self ._slave_id )
407410 elif request_type == "write_multiple" :
408411 values = kwargs ["values" ]
409- result = await self ._client .write_registers (address , values , slave = self ._slave_id )
412+ result = await self ._client .write_registers (address = address , values = values , device_id = self ._slave_id )
410413 else :
411414 self ._raise_unknown_request_type (request_type )
412415
413- if result .isError ():
414- exception_code = getattr ( result , "exception_code" , None )
415- if exception_code in { MODBUS_DEVICE_BUSY_EXCEPTION , MODBUS_GATEWAY_TARGET_FAILED_TO_RESPOND }:
416- LOGGER . debug (
417- "Device busy/unresponsive (code %s) on %s. Retrying in %.2fs..." ,
418- result . exception_code ,
419- request_type ,
420- delay ,
421- )
422- await asyncio . sleep ( delay )
423- else :
424- self . _raise_unrecoverable_modbus_error ( result )
416+ if not result .isError ():
417+ return result . registers if request_type == "read" else True
418+
419+ if result . exception_code in { MODBUS_DEVICE_BUSY_EXCEPTION , MODBUS_GATEWAY_TARGET_FAILED_TO_RESPOND }:
420+ delay = base_delay * ( 2 ** attempt )
421+ LOGGER . debug (
422+ "Device busy/unresponsive (code %s) on %s. Retrying in %.2fs..." ,
423+ result . exception_code ,
424+ request_type ,
425+ delay ,
426+ )
427+ await asyncio . sleep ( delay )
425428 else :
426- return result
429+ self . _raise_unrecoverable_modbus_error ( result )
427430
428431 except (TimeoutError , ConnectionException , ModbusConnectionError ) as e :
429432 LOGGER .warning ("Connection error during %s: %s. Attempting to reconnect..." , request_type , e )
@@ -466,26 +469,21 @@ async def _queue_request(self, request_type: str, address: int, **kwargs: Any) -
466469
467470 async def write_register (self , address_1based : int , value : int ) -> None :
468471 """Queue a write request for a single holding register."""
469- result = await self ._queue_request ("write" , address_1based - 1 , value = value )
470- if result .isError ():
471- msg = f"Failed to write register { address_1based } "
472- raise ModbusConnectionError (msg )
472+ await self ._queue_request ("write" , address_1based - 1 , value = value )
473473
474474 async def write_registers_32bit (self , address_1based : int , value : int ) -> None :
475475 """Queue a write request for a 32-bit value across two registers."""
476476 low_word = value & 0xFFFF
477477 high_word = (value >> 16 ) & 0xFFFF
478- result = await self ._queue_request ("write_multiple" , address_1based - 1 , values = [low_word , high_word ])
479- if result .isError ():
480- msg = f"Failed to write 32-bit value to registers { address_1based } -{ address_1based + 1 } "
481- raise ModbusConnectionError (msg )
478+ values = [low_word , high_word ]
479+ await self ._queue_request ("write_multiple" , address_1based - 1 , values = values )
482480
483481 async def test_connection (self ) -> bool :
484482 """Test connection to the Modbus Serial device."""
485483 try :
486484 await self ._ensure_connection ()
487485 # Try to read a single register to verify communication
488- result = await self ._client .read_holding_registers (0 , 1 , slave = self ._slave_id )
486+ result = await self ._client .read_holding_registers (address = 0 , count = 1 , device_id = self ._slave_id )
489487 return not result .isError ()
490488 except (ModbusConnectionError , ConnectionException ) as e :
491489 LOGGER .error ("Serial connection test failed: %s" , e )
@@ -495,34 +493,24 @@ async def test_connection(self) -> bool:
495493 return False
496494
497495 async def get_all_data (self ) -> dict [str , Any ]:
498- """Get all data from device by reading all defined register blocks."""
499- all_registers : dict [str , Any ] = {}
500- has_successful_read = False
501-
502- for start_address_1based , count in READ_BLOCKS :
503- try :
504- result = await self ._queue_request ("read" , start_address_1based - 1 , count = count )
505-
506- if result .isError ():
507- LOGGER .debug ("Failed to read block at %d: error" , start_address_1based )
508- continue
509-
510- has_successful_read = True
511- registers = result .registers
496+ """Queue read requests for all required data blocks and assemble the result."""
497+ tasks = [self ._queue_request ("read" , address = start - 1 , count = count ) for start , count in READ_BLOCKS ]
512498
513- # Map register values to parameter names
514- for reg_addr in range (start_address_1based , start_address_1based + count ):
515- key = str (reg_addr )
516- reg_val = registers [reg_addr - start_address_1based ]
517- all_registers [key ] = reg_val
499+ results = await asyncio .gather (* tasks , return_exceptions = True )
518500
519- except ModbusConnectionError as e :
520- LOGGER .debug ("Error reading block at %d: %s" , start_address_1based , e )
521- continue
522- except (TimeoutError , ConnectionException ) as e :
523- LOGGER .debug ("Connection error reading block at %d: %s" , start_address_1based , e )
501+ all_registers = {}
502+ has_successful_read = False
503+ for i , result in enumerate (results ):
504+ start_addr_1based , _ = READ_BLOCKS [i ]
505+ if isinstance (result , Exception ):
506+ LOGGER .error (f"Failed to read block { start_addr_1based } : { result } " )
524507 continue
525508
509+ has_successful_read = True
510+ for offset , reg_val in enumerate (result ):
511+ key = str (start_addr_1based - 1 + offset )
512+ all_registers [key ] = reg_val
513+
526514 if not has_successful_read :
527515 msg = "Failed to read any data blocks from the device."
528516 raise ModbusConnectionError (msg )
0 commit comments