@@ -1254,7 +1254,9 @@ async def _enrich_device(dev: DiscoveredDevice) -> DiscoveredDevice:
12541254 if elem .property_access_error is not None :
12551255 continue
12561256 pid = elem .property_identifier
1257- val = elem .property_value
1257+ val = (
1258+ decode_and_unwrap (elem .property_value ) if elem .property_value else None
1259+ )
12581260 if pid == PropertyIdentifier .PROFILE_NAME :
12591261 profile_name = val if isinstance (val , str ) else None
12601262 elif pid == PropertyIdentifier .PROFILE_LOCATION :
@@ -1337,13 +1339,13 @@ async def _traverse_hierarchy_recursive(
13371339 PropertyIdentifier .SUBORDINATE_LIST ,
13381340 timeout = timeout ,
13391341 )
1340- subordinates = ack .property_value
1341- if not isinstance (subordinates , list ):
1342+ raw_subordinates = decode_all_application_values ( ack .property_value )
1343+ if not isinstance (raw_subordinates , list ):
13421344 return
13431345 except (BACnetError , BACnetTimeoutError , TimeoutError ):
13441346 return
13451347
1346- for sub in subordinates :
1348+ for sub in raw_subordinates :
13471349 if isinstance (sub , ObjectIdentifier ):
13481350 result .append (sub )
13491351 if sub .object_type == ObjectType .STRUCTURED_VIEW :
@@ -2780,12 +2782,13 @@ async def backup_device(
27802782 timeout = timeout ,
27812783 )
27822784 config_file_ids : list [ObjectIdentifier ] = []
2783- if isinstance (ack .property_value , list ):
2784- for v in ack .property_value :
2785+ decoded_files = decode_all_application_values (ack .property_value )
2786+ if isinstance (decoded_files , list ):
2787+ for v in decoded_files :
27852788 if isinstance (v , ObjectIdentifier ):
27862789 config_file_ids .append (v )
2787- elif isinstance (ack . property_value , ObjectIdentifier ):
2788- config_file_ids .append (ack . property_value )
2790+ elif isinstance (decoded_files , ObjectIdentifier ):
2791+ config_file_ids .append (decoded_files )
27892792
27902793 # Step 4: Download each file
27912794 file_contents : list [tuple [ObjectIdentifier , bytes ]] = []
@@ -2881,8 +2884,9 @@ async def _discover_device_oid(
28812884 PropertyIdentifier .OBJECT_IDENTIFIER ,
28822885 timeout = timeout ,
28832886 )
2884- if isinstance (ack .property_value , ObjectIdentifier ):
2885- return ack .property_value
2887+ decoded = decode_and_unwrap (ack .property_value )
2888+ if isinstance (decoded , ObjectIdentifier ):
2889+ return decoded
28862890 return ObjectIdentifier (ObjectType .DEVICE , 4194303 )
28872891
28882892 async def _poll_backup_restore_state (
@@ -2892,21 +2896,28 @@ async def _poll_backup_restore_state(
28922896 target_states : tuple [BackupAndRestoreState , ...],
28932897 poll_interval : float = 1.0 ,
28942898 timeout : float | None = None ,
2899+ overall_timeout : float = 300.0 ,
28952900 ) -> BackupAndRestoreState :
28962901 """Poll BACKUP_AND_RESTORE_STATE until it reaches a target state."""
2902+ deadline = asyncio .get_event_loop ().time () + overall_timeout
28972903 while True :
28982904 ack = await self .read_property (
28992905 address ,
29002906 device_oid ,
29012907 PropertyIdentifier .BACKUP_AND_RESTORE_STATE ,
29022908 timeout = timeout ,
29032909 )
2904- raw_state = ack .property_value
2905- if isinstance (raw_state , int ):
2906- state = BackupAndRestoreState (raw_state )
2910+ decoded_state = decode_and_unwrap ( ack .property_value )
2911+ if isinstance (decoded_state , int ):
2912+ state = BackupAndRestoreState (decoded_state )
29072913 if state in target_states :
29082914 return state
2909- await asyncio .sleep (poll_interval )
2915+ remaining = deadline - asyncio .get_event_loop ().time ()
2916+ if remaining <= 0 :
2917+ from bac_py .services .errors import BACnetTimeoutError
2918+
2919+ raise BACnetTimeoutError ("Timed out waiting for backup/restore state" )
2920+ await asyncio .sleep (min (poll_interval , remaining ))
29102921
29112922 async def _download_file (
29122923 self ,
0 commit comments