@@ -55,21 +55,26 @@ def __getitem__(self, key) -> PdoBase:
5555 def __len__ (self ):
5656 return len (self .map )
5757
58- def read (self ):
58+ def read (self , from_od = False ):
5959 """Read PDO configuration from node using SDO."""
6060 for pdo_map in self .map .values ():
61- pdo_map .read ()
61+ pdo_map .read (from_od = from_od )
6262
63- async def aread (self ):
64- """Read PDO configuration from node using SDO."""
63+ async def aread (self , from_od = False ):
64+ """Read PDO configuration from node using SDO, async variant ."""
6565 for pdo_map in self .map .values ():
66- await pdo_map .aread ()
66+ await pdo_map .aread (from_od = from_od )
6767
6868 def save (self ):
6969 """Save PDO configuration to node using SDO."""
7070 for pdo_map in self .map .values ():
7171 pdo_map .save ()
7272
73+ async def asave (self ):
74+ """Save PDO configuration to node using SDO, async variant."""
75+ for pdo_map in self .map .values ():
76+ await pdo_map .asave ()
77+
7378 def subscribe (self ):
7479 """Register the node's PDOs for reception on the network.
7580
@@ -341,43 +346,43 @@ def add_callback(self, callback: Callable[["Map"], None]) -> None:
341346 """
342347 self .callbacks .append (callback )
343348
344- def read (self ) -> None :
345- """Read PDO configuration for this map using SDO ."""
346- cob_id = self .com_record [1 ]. get_raw ()
349+ def read_generator (self ):
350+ """Read PDO configuration for this map."""
351+ cob_id = yield self .com_record [1 ]
347352 self .cob_id = cob_id & 0x1FFFFFFF
348353 logger .info ("COB-ID is 0x%X" , self .cob_id )
349354 self .enabled = cob_id & PDO_NOT_VALID == 0
350355 logger .info ("PDO is %s" , "enabled" if self .enabled else "disabled" )
351356 self .rtr_allowed = cob_id & RTR_NOT_ALLOWED == 0
352357 logger .info ("RTR is %s" , "allowed" if self .rtr_allowed else "not allowed" )
353- self .trans_type = self .com_record [2 ]. get_raw ()
358+ self .trans_type = yield self .com_record [2 ]
354359 logger .info ("Transmission type is %d" , self .trans_type )
355360 if self .trans_type >= 254 :
356361 try :
357- self .inhibit_time = self .com_record [3 ]. get_raw ()
362+ self .inhibit_time = yield self .com_record [3 ]
358363 except (KeyError , SdoAbortedError ) as e :
359364 logger .info ("Could not read inhibit time (%s)" , e )
360365 else :
361366 logger .info ("Inhibit time is set to %d ms" , self .inhibit_time )
362367
363368 try :
364- self .event_timer = self .com_record [5 ]. get_raw ()
369+ self .event_timer = yield self .com_record [5 ]
365370 except (KeyError , SdoAbortedError ) as e :
366371 logger .info ("Could not read event timer (%s)" , e )
367372 else :
368373 logger .info ("Event timer is set to %d ms" , self .event_timer )
369374
370375 try :
371- self .sync_start_value = self .com_record [6 ]. get_raw ()
376+ self .sync_start_value = yield self .com_record [6 ]
372377 except (KeyError , SdoAbortedError ) as e :
373378 logger .info ("Could not read SYNC start value (%s)" , e )
374379 else :
375380 logger .info ("SYNC start value is set to %d ms" , self .sync_start_value )
376381
377382 self .clear ()
378- nof_entries = self .map_array [0 ]. get_raw ()
383+ nof_entries = yield self .map_array [0 ]
379384 for subindex in range (1 , nof_entries + 1 ):
380- value = self .map_array [subindex ]. get_raw ()
385+ value = yield self .map_array [subindex ]
381386 index = value >> 16
382387 subindex = (value >> 8 ) & 0xFF
383388 size = value & 0xFF
@@ -390,97 +395,84 @@ def read(self) -> None:
390395
391396 self .subscribe ()
392397
393- async def aread (self ) -> None :
394- """Read PDO configuration for this map using SDO."""
395- cob_id = await self .com_record [1 ].aget_raw ()
396- self .cob_id = cob_id & 0x1FFFFFFF
397- logger .info ("COB-ID is 0x%X" , self .cob_id )
398- self .enabled = cob_id & PDO_NOT_VALID == 0
399- logger .info ("PDO is %s" , "enabled" if self .enabled else "disabled" )
400- self .rtr_allowed = cob_id & RTR_NOT_ALLOWED == 0
401- logger .info ("RTR is %s" , "allowed" if self .rtr_allowed else "not allowed" )
402- self .trans_type = await self .com_record [2 ].aget_raw ()
403- logger .info ("Transmission type is %d" , self .trans_type )
404- if self .trans_type >= 254 :
405- try :
406- self .inhibit_time = await self .com_record [3 ].aget_raw ()
407- except (KeyError , SdoAbortedError ) as e :
408- logger .info ("Could not read inhibit time (%s)" , e )
398+ def read (self , from_od = False ) -> None :
399+ """Read PDO configuration for this map using SDO or from OD."""
400+ gen = self .read_generator ()
401+ var = next (gen )
402+ while var :
403+ if from_od :
404+ # Use default value from OD
405+ value = var .od .default
409406 else :
410- logger . info ( "Inhibit time is set to %d ms" , self . inhibit_time )
411-
407+ # Get value from SDO
408+ value = var . get_raw ()
412409 try :
413- self .event_timer = await self .com_record [5 ].aget_raw ()
414- except (KeyError , SdoAbortedError ) as e :
415- logger .info ("Could not read event timer (%s)" , e )
410+ # Deliver value into read_generator and wait for next object
411+ var = gen .send (value )
412+ except StopIteration :
413+ break
414+
415+ async def aread (self , from_od = False ) -> None :
416+ """Read PDO configuration for this map using SDO, async variant."""
417+ gen = self .read_generator ()
418+ var = next (gen )
419+ while var :
420+ if from_od :
421+ # Use default value from OD
422+ value = var .od .default
416423 else :
417- logger .info ("Event timer is set to %d ms" , self .event_timer )
418-
424+ # Get value from SDO
425+ value = await var .aget_raw ()
426+ pass
419427 try :
420- self .sync_start_value = await self .com_record [6 ].aget_raw ()
421- except (KeyError , SdoAbortedError ) as e :
422- logger .info ("Could not read SYNC start value (%s)" , e )
423- else :
424- logger .info ("SYNC start value is set to %d ms" , self .sync_start_value )
428+ var = gen .send (value )
429+ except StopIteration :
430+ break
425431
426- self .clear ()
427- nof_entries = await self .map_array [0 ].aget_raw ()
428- for subindex in range (1 , nof_entries + 1 ):
429- value = await self .map_array [subindex ].aget_raw ()
430- index = value >> 16
431- subindex = (value >> 8 ) & 0xFF
432- size = value & 0xFF
433- if hasattr (self .pdo_node .node , "curtis_hack" ) and self .pdo_node .node .curtis_hack : # Curtis HACK: mixed up field order
434- index = value & 0xFFFF
435- subindex = (value >> 16 ) & 0xFF
436- size = (value >> 24 ) & 0xFF
437- if index and size :
438- self .add_variable (index , subindex , size )
439-
440- self .subscribe ()
441-
442- def save (self ) -> None :
443- """Save PDO configuration for this map using SDO."""
432+ def save_generator (self ):
433+ """Save PDO configuration for this map."""
444434 logger .info ("Setting COB-ID 0x%X and temporarily disabling PDO" ,
445435 self .cob_id )
446- self .com_record [1 ]. set_raw ( self .cob_id | PDO_NOT_VALID | (RTR_NOT_ALLOWED if not self .rtr_allowed else 0x0 ) )
436+ yield self .com_record [1 ], self .cob_id | PDO_NOT_VALID | (RTR_NOT_ALLOWED if not self .rtr_allowed else 0x0 )
447437 if self .trans_type is not None :
448438 logger .info ("Setting transmission type to %d" , self .trans_type )
449- self .com_record [2 ]. set_raw ( self .trans_type )
439+ yield self .com_record [2 ], self .trans_type
450440 if self .inhibit_time is not None :
451441 logger .info ("Setting inhibit time to %d us" , (self .inhibit_time * 100 ))
452- self .com_record [3 ]. set_raw ( self .inhibit_time )
442+ yield self .com_record [3 ], self .inhibit_time
453443 if self .event_timer is not None :
454444 logger .info ("Setting event timer to %d ms" , self .event_timer )
455- self .com_record [5 ]. set_raw ( self .event_timer )
445+ yield self .com_record [5 ], self .event_timer
456446 if self .sync_start_value is not None :
457447 logger .info ("Setting SYNC start value to %d" , self .sync_start_value )
458- self .com_record [6 ]. set_raw ( self .sync_start_value )
448+ yield self .com_record [6 ], self .sync_start_value
459449
460450 if self .map is not None :
461451 try :
462- self .map_array [0 ]. set_raw ( 0 )
452+ yield self .map_array [0 ], 0
463453 except SdoAbortedError :
464454 # WORKAROUND for broken implementations: If the array has a
465455 # fixed number of entries (count not writable), generate dummy
466456 # mappings for an invalid object 0x0000:00 to overwrite any
467457 # excess entries with all-zeros.
458+
459+ # FIXME: This is a blocking call which might be called from async
468460 self ._fill_map (self .map_array [0 ].get_raw ())
469461 subindex = 1
470462 for var in self .map :
471463 logger .info ("Writing %s (0x%X:%d, %d bits) to PDO map" ,
472464 var .name , var .index , var .subindex , var .length )
473465 if hasattr (self .pdo_node .node , "curtis_hack" ) and self .pdo_node .node .curtis_hack : # Curtis HACK: mixed up field order
474- self .map_array [subindex ]. set_raw (var .index |
475- var .subindex << 16 |
476- var .length << 24 )
466+ yield self .map_array [subindex ], (var .index |
467+ var .subindex << 16 |
468+ var .length << 24 )
477469 else :
478- self .map_array [subindex ]. set_raw (var .index << 16 |
479- var .subindex << 8 |
480- var .length )
470+ yield self .map_array [subindex ], (var .index << 16 |
471+ var .subindex << 8 |
472+ var .length )
481473 subindex += 1
482474 try :
483- self .map_array [0 ]. set_raw ( len (self .map ) )
475+ yield self .map_array [0 ], len (self .map )
484476 except SdoAbortedError as e :
485477 # WORKAROUND for broken implementations: If the array
486478 # number-of-entries parameter is not writable, we have already
@@ -492,9 +484,19 @@ def save(self) -> None:
492484 self ._update_data_size ()
493485
494486 if self .enabled :
495- self .com_record [1 ]. set_raw ( self .cob_id | (RTR_NOT_ALLOWED if not self .rtr_allowed else 0x0 ) )
487+ yield self .com_record [1 ], self .cob_id | (RTR_NOT_ALLOWED if not self .rtr_allowed else 0x0 )
496488 self .subscribe ()
497489
490+ def save (self ) -> None :
491+ """Read PDO configuration for this map using SDO."""
492+ for sdo , value in self .save_generator ():
493+ sdo .set_raw (value )
494+
495+ async def asave (self ) -> None :
496+ """Read PDO configuration for this map using SDO, async variant."""
497+ for sdo , value in self .save_generator ():
498+ await sdo .aset_raw (value )
499+
498500 def subscribe (self ) -> None :
499501 """Register the PDO for reception on the network.
500502
0 commit comments