@@ -55,21 +55,26 @@ def __getitem__(self, key) -> PdoBase:
55
55
def __len__ (self ):
56
56
return len (self .map )
57
57
58
- def read (self ):
58
+ def read (self , from_od = False ):
59
59
"""Read PDO configuration from node using SDO."""
60
60
for pdo_map in self .map .values ():
61
- pdo_map .read ()
61
+ pdo_map .read (from_od = from_od )
62
62
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 ."""
65
65
for pdo_map in self .map .values ():
66
- await pdo_map .aread ()
66
+ await pdo_map .aread (from_od = from_od )
67
67
68
68
def save (self ):
69
69
"""Save PDO configuration to node using SDO."""
70
70
for pdo_map in self .map .values ():
71
71
pdo_map .save ()
72
72
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
+
73
78
def subscribe (self ):
74
79
"""Register the node's PDOs for reception on the network.
75
80
@@ -341,43 +346,43 @@ def add_callback(self, callback: Callable[["Map"], None]) -> None:
341
346
"""
342
347
self .callbacks .append (callback )
343
348
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 ]
347
352
self .cob_id = cob_id & 0x1FFFFFFF
348
353
logger .info ("COB-ID is 0x%X" , self .cob_id )
349
354
self .enabled = cob_id & PDO_NOT_VALID == 0
350
355
logger .info ("PDO is %s" , "enabled" if self .enabled else "disabled" )
351
356
self .rtr_allowed = cob_id & RTR_NOT_ALLOWED == 0
352
357
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 ]
354
359
logger .info ("Transmission type is %d" , self .trans_type )
355
360
if self .trans_type >= 254 :
356
361
try :
357
- self .inhibit_time = self .com_record [3 ]. get_raw ()
362
+ self .inhibit_time = yield self .com_record [3 ]
358
363
except (KeyError , SdoAbortedError ) as e :
359
364
logger .info ("Could not read inhibit time (%s)" , e )
360
365
else :
361
366
logger .info ("Inhibit time is set to %d ms" , self .inhibit_time )
362
367
363
368
try :
364
- self .event_timer = self .com_record [5 ]. get_raw ()
369
+ self .event_timer = yield self .com_record [5 ]
365
370
except (KeyError , SdoAbortedError ) as e :
366
371
logger .info ("Could not read event timer (%s)" , e )
367
372
else :
368
373
logger .info ("Event timer is set to %d ms" , self .event_timer )
369
374
370
375
try :
371
- self .sync_start_value = self .com_record [6 ]. get_raw ()
376
+ self .sync_start_value = yield self .com_record [6 ]
372
377
except (KeyError , SdoAbortedError ) as e :
373
378
logger .info ("Could not read SYNC start value (%s)" , e )
374
379
else :
375
380
logger .info ("SYNC start value is set to %d ms" , self .sync_start_value )
376
381
377
382
self .clear ()
378
- nof_entries = self .map_array [0 ]. get_raw ()
383
+ nof_entries = yield self .map_array [0 ]
379
384
for subindex in range (1 , nof_entries + 1 ):
380
- value = self .map_array [subindex ]. get_raw ()
385
+ value = yield self .map_array [subindex ]
381
386
index = value >> 16
382
387
subindex = (value >> 8 ) & 0xFF
383
388
size = value & 0xFF
@@ -390,97 +395,84 @@ def read(self) -> None:
390
395
391
396
self .subscribe ()
392
397
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
409
406
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 ()
412
409
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
416
423
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
419
427
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
425
431
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."""
444
434
logger .info ("Setting COB-ID 0x%X and temporarily disabling PDO" ,
445
435
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 )
447
437
if self .trans_type is not None :
448
438
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
450
440
if self .inhibit_time is not None :
451
441
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
453
443
if self .event_timer is not None :
454
444
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
456
446
if self .sync_start_value is not None :
457
447
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
459
449
460
450
if self .map is not None :
461
451
try :
462
- self .map_array [0 ]. set_raw ( 0 )
452
+ yield self .map_array [0 ], 0
463
453
except SdoAbortedError :
464
454
# WORKAROUND for broken implementations: If the array has a
465
455
# fixed number of entries (count not writable), generate dummy
466
456
# mappings for an invalid object 0x0000:00 to overwrite any
467
457
# excess entries with all-zeros.
458
+
459
+ # FIXME: This is a blocking call which might be called from async
468
460
self ._fill_map (self .map_array [0 ].get_raw ())
469
461
subindex = 1
470
462
for var in self .map :
471
463
logger .info ("Writing %s (0x%X:%d, %d bits) to PDO map" ,
472
464
var .name , var .index , var .subindex , var .length )
473
465
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 )
477
469
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 )
481
473
subindex += 1
482
474
try :
483
- self .map_array [0 ]. set_raw ( len (self .map ) )
475
+ yield self .map_array [0 ], len (self .map )
484
476
except SdoAbortedError as e :
485
477
# WORKAROUND for broken implementations: If the array
486
478
# number-of-entries parameter is not writable, we have already
@@ -492,9 +484,19 @@ def save(self) -> None:
492
484
self ._update_data_size ()
493
485
494
486
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 )
496
488
self .subscribe ()
497
489
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
+
498
500
def subscribe (self ) -> None :
499
501
"""Register the PDO for reception on the network.
500
502
0 commit comments