1
- from __future__ import annotations
2
1
import threading
3
2
import math
4
- from typing import Callable , Dict , Iterable , List , Optional , Union , TYPE_CHECKING
3
+ from typing import Callable , Dict , Iterable , List , Optional , Union
5
4
from collections .abc import Mapping
6
5
import logging
7
6
import binascii
10
9
from canopen import objectdictionary
11
10
from canopen import variable
12
11
13
- if TYPE_CHECKING :
14
- from canopen .network import Network
15
- from canopen import LocalNode , RemoteNode
16
- from canopen .pdo import RPDO , TPDO
17
- from canopen .sdo import SdoRecord
18
-
19
12
PDO_NOT_VALID = 1 << 31
20
13
RTR_NOT_ALLOWED = 1 << 30
21
14
@@ -29,10 +22,10 @@ class PdoBase(Mapping):
29
22
Parent object associated with this PDO instance
30
23
"""
31
24
32
- def __init__ (self , node : Union [ LocalNode , RemoteNode ] ):
33
- self .network : Optional [ Network ] = None
34
- self .map : Optional [ PdoMaps ] = None
35
- self .node : Union [ LocalNode , RemoteNode ] = node
25
+ def __init__ (self , node ):
26
+ self .network = None
27
+ self .map = None # instance of PdoMaps
28
+ self .node = node
36
29
37
30
def __iter__ (self ):
38
31
return iter (self .map )
@@ -138,7 +131,7 @@ def __init__(self, com_offset, map_offset, pdo_node: PdoBase, cob_base=None):
138
131
:param pdo_node:
139
132
:param cob_base:
140
133
"""
141
- self .maps : Dict [int , PdoMap ] = {}
134
+ self .maps : Dict [int , " PdoMap" ] = {}
142
135
for map_no in range (512 ):
143
136
if com_offset + map_no in pdo_node .node .object_dictionary :
144
137
new_map = PdoMap (
@@ -150,7 +143,7 @@ def __init__(self, com_offset, map_offset, pdo_node: PdoBase, cob_base=None):
150
143
new_map .predefined_cob_id = cob_base + map_no * 0x100 + pdo_node .node .id
151
144
self .maps [map_no + 1 ] = new_map
152
145
153
- def __getitem__ (self , key : int ) -> PdoMap :
146
+ def __getitem__ (self , key : int ) -> " PdoMap" :
154
147
return self .maps [key ]
155
148
156
149
def __iter__ (self ) -> Iterable [int ]:
@@ -164,9 +157,9 @@ class PdoMap:
164
157
"""One message which can have up to 8 bytes of variables mapped."""
165
158
166
159
def __init__ (self , pdo_node , com_record , map_array ):
167
- self .pdo_node : Union [ TPDO , RPDO ] = pdo_node
168
- self .com_record : SdoRecord = com_record
169
- self .map_array : SdoRecord = map_array
160
+ self .pdo_node = pdo_node
161
+ self .com_record = com_record
162
+ self .map_array = map_array
170
163
#: If this map is valid
171
164
self .enabled : bool = False
172
165
#: COB-ID for this PDO
@@ -184,7 +177,7 @@ def __init__(self, pdo_node, com_record, map_array):
184
177
#: Ignores SYNC objects up to this SYNC counter value (optional)
185
178
self .sync_start_value : Optional [int ] = None
186
179
#: List of variables mapped to this PDO
187
- self .map : List [PdoVariable ] = []
180
+ self .map : List [" PdoVariable" ] = []
188
181
self .length : int = 0
189
182
#: Current message data
190
183
self .data = bytearray ()
@@ -221,7 +214,7 @@ def __getitem_by_name(self, value):
221
214
raise KeyError ('{0} not found in map. Valid entries are {1}' .format (
222
215
value , ', ' .join (valid_values )))
223
216
224
- def __getitem__ (self , key : Union [int , str ]) -> PdoVariable :
217
+ def __getitem__ (self , key : Union [int , str ]) -> " PdoVariable" :
225
218
if isinstance (key , int ):
226
219
# there is a maximum available of 8 slots per PDO map
227
220
if key in range (0 , 8 ):
@@ -235,7 +228,7 @@ def __getitem__(self, key: Union[int, str]) -> PdoVariable:
235
228
var = self .__getitem_by_name (key )
236
229
return var
237
230
238
- def __iter__ (self ) -> Iterable [PdoVariable ]:
231
+ def __iter__ (self ) -> Iterable [" PdoVariable" ]:
239
232
return iter (self .map )
240
233
241
234
def __len__ (self ) -> int :
@@ -310,7 +303,7 @@ def on_message(self, can_id, data, timestamp):
310
303
for callback in self .callbacks :
311
304
callback (self )
312
305
313
- def add_callback (self , callback : Callable [[PdoMap ], None ]) -> None :
306
+ def add_callback (self , callback : Callable [[" PdoMap" ], None ]) -> None :
314
307
"""Add a callback which will be called on receive.
315
308
316
309
:param callback:
@@ -395,39 +388,38 @@ def save(self) -> None:
395
388
logger .info ("Setting SYNC start value to %d" , self .sync_start_value )
396
389
self .com_record [6 ].raw = self .sync_start_value
397
390
398
- if self .map is not None :
399
- try :
400
- self .map_array [0 ].raw = 0
401
- except SdoAbortedError :
402
- # WORKAROUND for broken implementations: If the array has a
403
- # fixed number of entries (count not writable), generate dummy
404
- # mappings for an invalid object 0x0000:00 to overwrite any
405
- # excess entries with all-zeros.
406
- self ._fill_map (self .map_array [0 ].raw )
407
- subindex = 1
408
- for var in self .map :
409
- logger .info ("Writing %s (0x%X:%d, %d bits) to PDO map" ,
410
- var .name , var .index , var .subindex , var .length )
411
- if getattr (self .pdo_node .node , "curtis_hack" , False ): # Curtis HACK: mixed up field order
412
- self .map_array [subindex ].raw = (var .index |
413
- var .subindex << 16 |
414
- var .length << 24 )
415
- else :
416
- self .map_array [subindex ].raw = (var .index << 16 |
417
- var .subindex << 8 |
418
- var .length )
419
- subindex += 1
420
- try :
421
- self .map_array [0 ].raw = len (self .map )
422
- except SdoAbortedError as e :
423
- # WORKAROUND for broken implementations: If the array
424
- # number-of-entries parameter is not writable, we have already
425
- # generated the required number of mappings above.
426
- if e .code != 0x06010002 :
427
- # Abort codes other than "Attempt to write a read-only
428
- # object" should still be reported.
429
- raise
430
- self ._update_data_size ()
391
+ try :
392
+ self .map_array [0 ].raw = 0
393
+ except SdoAbortedError :
394
+ # WORKAROUND for broken implementations: If the array has a
395
+ # fixed number of entries (count not writable), generate dummy
396
+ # mappings for an invalid object 0x0000:00 to overwrite any
397
+ # excess entries with all-zeros.
398
+ self ._fill_map (self .map_array [0 ].raw )
399
+ subindex = 1
400
+ for var in self .map :
401
+ logger .info ("Writing %s (0x%X:%d, %d bits) to PDO map" ,
402
+ var .name , var .index , var .subindex , var .length )
403
+ if getattr (self .pdo_node .node , "curtis_hack" , False ): # Curtis HACK: mixed up field order
404
+ self .map_array [subindex ].raw = (var .index |
405
+ var .subindex << 16 |
406
+ var .length << 24 )
407
+ else :
408
+ self .map_array [subindex ].raw = (var .index << 16 |
409
+ var .subindex << 8 |
410
+ var .length )
411
+ subindex += 1
412
+ try :
413
+ self .map_array [0 ].raw = len (self .map )
414
+ except SdoAbortedError as e :
415
+ # WORKAROUND for broken implementations: If the array
416
+ # number-of-entries parameter is not writable, we have already
417
+ # generated the required number of mappings above.
418
+ if e .code != 0x06010002 :
419
+ # Abort codes other than "Attempt to write a read-only
420
+ # object" should still be reported.
421
+ raise
422
+ self ._update_data_size ()
431
423
432
424
if self .enabled :
433
425
self .com_record [1 ].raw = self .cob_id | (RTR_NOT_ALLOWED if not self .rtr_allowed else 0x0 )
@@ -455,7 +447,7 @@ def add_variable(
455
447
index : Union [str , int ],
456
448
subindex : Union [str , int ] = 0 ,
457
449
length : Optional [int ] = None ,
458
- ) -> PdoVariable :
450
+ ) -> " PdoVariable" :
459
451
"""Add a variable from object dictionary as the next entry.
460
452
461
453
:param index: Index of variable as name or number
0 commit comments