2222
2323logger = logging .getLogger (__name__ )
2424
25+
2526def import_eds (source , node_id ):
26- eds = RawConfigParser (inline_comment_prefixes = (';' ,))
27+ eds = RawConfigParser (inline_comment_prefixes = (";" ,))
2728 eds .optionxform = str
2829 opened_here = False
2930 try :
@@ -42,25 +43,26 @@ def import_eds(source, node_id):
4243
4344 if eds .has_section ("FileInfo" ):
4445 od .__edsFileInfo = {
45- opt : eds .get ("FileInfo" , opt )
46- for opt in eds .options ("FileInfo" )
46+ opt : eds .get ("FileInfo" , opt ) for opt in eds .options ("FileInfo" )
4747 }
4848
4949 if eds .has_section ("Comments" ):
5050 linecount = int (eds .get ("Comments" , "Lines" ), 0 )
51- od .comments = '\n ' .join ([
52- eds .get ("Comments" , f"Line{ line } " )
53- for line in range (1 , linecount + 1 )
54- ])
51+ od .comments = "\n " .join (
52+ [eds .get ("Comments" , f"Line{ line } " ) for line in range (1 , linecount + 1 )]
53+ )
5554
5655 if not eds .has_section ("DeviceInfo" ):
57- logger .warn ("eds file does not have a DeviceInfo section. This section is mandatory" )
56+ logger .warn (
57+ "eds file does not have a DeviceInfo section. This section is mandatory"
58+ )
5859 else :
5960 for rate in [10 , 20 , 50 , 125 , 250 , 500 , 800 , 1000 ]:
6061 baudPossible = int (
61- eds .get ("DeviceInfo" , f"BaudRate_{ rate } " , fallback = '0' ), 0 )
62+ eds .get ("DeviceInfo" , f"BaudRate_{ rate } " , fallback = "0" ), 0
63+ )
6264 if baudPossible != 0 :
63- od .device_information .allowed_baudrates .add (rate * 1000 )
65+ od .device_information .allowed_baudrates .add (rate * 1000 )
6466
6567 for t , eprop , odprop in [
6668 (str , "VendorName" , "vendor_name" ),
@@ -80,13 +82,13 @@ def import_eds(source, node_id):
8082 ]:
8183 try :
8284 if t in (int , bool ):
83- setattr (od .device_information , odprop ,
84- t (int (eds .get ("DeviceInfo" , eprop ), 0 ))
85- )
85+ setattr (
86+ od .device_information ,
87+ odprop ,
88+ t (int (eds .get ("DeviceInfo" , eprop ), 0 )),
89+ )
8690 elif t is str :
87- setattr (od .device_information , odprop ,
88- eds .get ("DeviceInfo" , eprop )
89- )
91+ setattr (od .device_information , odprop , eds .get ("DeviceInfo" , eprop ))
9092 except NoOptionError :
9193 pass
9294
@@ -131,10 +133,11 @@ def import_eds(source, node_id):
131133 if object_type in (objectcodes .VAR , objectcodes .DOMAIN ):
132134 var = build_variable (eds , section , node_id , index )
133135 od .add_object (var )
134- elif object_type == objectcodes .ARRAY and eds .has_option (section , "CompactSubObj" ):
136+ elif object_type == objectcodes .ARRAY and eds .has_option (
137+ section , "CompactSubObj"
138+ ):
135139 arr = ODArray (name , index )
136- last_subindex = ODVariable (
137- "Number of entries" , index , 0 )
140+ last_subindex = ODVariable ("Number of entries" , index , 0 )
138141 last_subindex .data_type = datatypes .UNSIGNED8
139142 arr .add_member (last_subindex )
140143 arr .add_member (build_variable (eds , section , node_id , index , 1 ))
@@ -178,7 +181,7 @@ def import_eds(source, node_id):
178181
179182
180183def import_from_node (node_id : int , network : canopen .network .Network ):
181- """ Download the configuration from the remote node
184+ """Download the configuration from the remote node
182185 :param int node_id: Identifier of the node
183186 :param network: network object
184187 """
@@ -192,25 +195,23 @@ def import_from_node(node_id: int, network: canopen.network.Network):
192195 with sdo_client .open (0x1021 , 0 , "rt" ) as eds_fp :
193196 od = import_eds (eds_fp , node_id )
194197 except Exception as e :
195- logger .error ("No object dictionary could be loaded for node %d: %s" ,
196- node_id , e )
198+ logger .error ("No object dictionary could be loaded for node %d: %s" , node_id , e )
197199 od = None
198200 finally :
199201 network .unsubscribe (0x580 + node_id )
200202 return od
201203
202204
203- def _calc_bit_length (data_type ):
204- if data_type == datatypes .INTEGER8 :
205- return 8
206- elif data_type == datatypes .INTEGER16 :
207- return 16
208- elif data_type == datatypes .INTEGER32 :
209- return 32
210- elif data_type == datatypes .INTEGER64 :
211- return 64
212- else :
213- raise ValueError (f"Invalid data_type '{ data_type } ', expecting a signed integer data_type." )
205+ _SIGNED_BIT_LENGTHS = {
206+ datatypes .INTEGER8 : 8 ,
207+ datatypes .INTEGER16 : 16 ,
208+ datatypes .INTEGER24 : 24 ,
209+ datatypes .INTEGER32 : 32 ,
210+ datatypes .INTEGER40 : 40 ,
211+ datatypes .INTEGER48 : 48 ,
212+ datatypes .INTEGER56 : 56 ,
213+ datatypes .INTEGER64 : 64 ,
214+ }
214215
215216
216217def _signed_int_from_hex (hex_str , bit_length ):
@@ -233,8 +234,8 @@ def _convert_variable(node_id, var_type, value):
233234 else :
234235 # COB-ID can contain '$NODEID+' so replace this with node_id before converting
235236 value = value .replace (" " , "" ).upper ()
236- if ' $NODEID' in value and node_id is not None :
237- return int (re .sub (r' \+?\$NODEID\+?' , '' , value ), 0 ) + node_id
237+ if " $NODEID" in value and node_id is not None :
238+ return int (re .sub (r" \+?\$NODEID\+?" , "" , value ), 0 ) + node_id
238239 else :
239240 return int (value , 0 )
240241
@@ -276,7 +277,9 @@ def build_variable(eds, section, node_id, index, subindex=0):
276277 try :
277278 var .data_type = int (eds .get (f"{ var .data_type :X} sub1" , "DefaultValue" ), 0 )
278279 except NoSectionError :
279- logger .warning ("%s has an unknown or unsupported data type (0x%X)" , name , var .data_type )
280+ logger .warning (
281+ "%s has an unknown or unsupported data type (0x%X)" , name , var .data_type
282+ )
280283 # Assume DOMAIN to force application to interpret the byte data
281284 var .data_type = datatypes .DOMAIN
282285
@@ -286,32 +289,40 @@ def build_variable(eds, section, node_id, index, subindex=0):
286289 try :
287290 min_string = eds .get (section , "LowLimit" )
288291 if var .data_type in datatypes .SIGNED_TYPES :
289- var .min = _signed_int_from_hex (min_string , _calc_bit_length (var .data_type ))
292+ var .min = _signed_int_from_hex (
293+ min_string , _SIGNED_BIT_LENGTHS [var .data_type ]
294+ )
290295 else :
291296 var .min = int (min_string , 0 )
292297 except ValueError :
293- pass
298+ logger . warning ( "Failed to parse LowLimit for %s: %r" , name , min_string )
294299 if eds .has_option (section , "HighLimit" ):
295300 try :
296301 max_string = eds .get (section , "HighLimit" )
297302 if var .data_type in datatypes .SIGNED_TYPES :
298- var .max = _signed_int_from_hex (max_string , _calc_bit_length (var .data_type ))
303+ var .max = _signed_int_from_hex (
304+ max_string , _SIGNED_BIT_LENGTHS [var .data_type ]
305+ )
299306 else :
300307 var .max = int (max_string , 0 )
301308 except ValueError :
302- pass
309+ logger . warning ( "Failed to parse HighLimit for %s: %r" , name , max_string )
303310 if eds .has_option (section , "DefaultValue" ):
304311 try :
305312 var .default_raw = eds .get (section , "DefaultValue" )
306- if ' $NODEID' in var .default_raw :
313+ if " $NODEID" in var .default_raw :
307314 var .relative = True
308- var .default = _convert_variable (node_id , var .data_type , eds .get (section , "DefaultValue" ))
315+ var .default = _convert_variable (
316+ node_id , var .data_type , eds .get (section , "DefaultValue" )
317+ )
309318 except ValueError :
310319 pass
311320 if eds .has_option (section , "ParameterValue" ):
312321 try :
313322 var .value_raw = eds .get (section , "ParameterValue" )
314- var .value = _convert_variable (node_id , var .data_type , eds .get (section , "ParameterValue" ))
323+ var .value = _convert_variable (
324+ node_id , var .data_type , eds .get (section , "ParameterValue" )
325+ )
315326 except ValueError :
316327 pass
317328 # Factor, Description and Unit are not standard according to the CANopen specifications, but they are implemented in the python canopen package, so we can at least try to use them
@@ -376,32 +387,36 @@ def export_variable(var, eds):
376387 if var .access_type :
377388 eds .set (section , "AccessType" , var .access_type )
378389
379- if getattr (var , ' default_raw' , None ) is not None :
390+ if getattr (var , " default_raw" , None ) is not None :
380391 eds .set (section , "DefaultValue" , var .default_raw )
381- elif getattr (var , 'default' , None ) is not None :
382- eds .set (section , "DefaultValue" , _revert_variable (
383- var .data_type , var .default ))
392+ elif getattr (var , "default" , None ) is not None :
393+ eds .set (
394+ section , "DefaultValue" , _revert_variable (var .data_type , var .default )
395+ )
384396
385397 if device_commisioning :
386- if getattr (var , ' value_raw' , None ) is not None :
398+ if getattr (var , " value_raw" , None ) is not None :
387399 eds .set (section , "ParameterValue" , var .value_raw )
388- elif getattr (var , 'value' , None ) is not None :
389- eds .set (section , "ParameterValue" ,
390- _revert_variable (var .data_type , var .value ))
400+ elif getattr (var , "value" , None ) is not None :
401+ eds .set (
402+ section ,
403+ "ParameterValue" ,
404+ _revert_variable (var .data_type , var .value ),
405+ )
391406
392407 eds .set (section , "DataType" , f"0x{ var .data_type :04X} " )
393408 eds .set (section , "PDOMapping" , hex (var .pdo_mappable ))
394409
395- if getattr (var , ' min' , None ) is not None :
410+ if getattr (var , " min" , None ) is not None :
396411 eds .set (section , "LowLimit" , var .min )
397- if getattr (var , ' max' , None ) is not None :
412+ if getattr (var , " max" , None ) is not None :
398413 eds .set (section , "HighLimit" , var .max )
399414
400- if getattr (var , ' description' , '' ) != '' :
415+ if getattr (var , " description" , "" ) != "" :
401416 eds .set (section , "Description" , var .description )
402- if getattr (var , ' factor' , 1 ) != 1 :
417+ if getattr (var , " factor" , 1 ) != 1 :
403418 eds .set (section , "Factor" , var .factor )
404- if getattr (var , ' unit' , '' ) != '' :
419+ if getattr (var , " unit" , "" ) != "" :
405420 eds .set (section , "Unit" , var .unit )
406421
407422 def export_record (var , eds ):
@@ -420,6 +435,7 @@ def export_record(var, eds):
420435 eds .optionxform = str
421436
422437 from datetime import datetime as dt
438+
423439 defmtime = dt .utcnow ()
424440
425441 try :
@@ -469,10 +485,13 @@ def export_record(var, eds):
469485
470486 # we are also adding out of spec baudrates here.
471487 for rate in od .device_information .allowed_baudrates .union (
472- {10e3 , 20e3 , 50e3 , 125e3 , 250e3 , 500e3 , 800e3 , 1000e3 }):
488+ {10e3 , 20e3 , 50e3 , 125e3 , 250e3 , 500e3 , 800e3 , 1000e3 }
489+ ):
473490 eds .set (
474- "DeviceInfo" , f"BaudRate_{ int (rate // 1000 )} " ,
475- int (rate in od .device_information .allowed_baudrates ))
491+ "DeviceInfo" ,
492+ f"BaudRate_{ int (rate // 1000 )} " ,
493+ int (rate in od .device_information .allowed_baudrates ),
494+ )
476495
477496 if device_commisioning and (od .bitrate or od .node_id ):
478497 eds .add_section ("DeviceComissioning" )
@@ -500,11 +519,13 @@ def manufacturer_indices(x):
500519 return 0x2000 <= x < 0x6000
501520
502521 def optional_indices (x ):
503- return all ((
504- x > 0x1001 ,
505- not mandatory_indices (x ),
506- not manufacturer_indices (x ),
507- ))
522+ return all (
523+ (
524+ x > 0x1001 ,
525+ not mandatory_indices (x ),
526+ not manufacturer_indices (x ),
527+ )
528+ )
508529
509530 supported_mantatory_indices = list (filter (mandatory_indices , od ))
510531 supported_optional_indices = list (filter (optional_indices , od ))
@@ -524,6 +545,7 @@ def add_list(section, list):
524545
525546 if not dest :
526547 import sys
548+
527549 dest = sys .stdout
528550
529551 eds .write (dest , False )
0 commit comments