53 is_integer = lambda x: type(x) in (IntType, LongType) |
53 is_integer = lambda x: type(x) in (IntType, LongType) |
54 is_string = lambda x: type(x) in (StringType, UnicodeType) |
54 is_string = lambda x: type(x) in (StringType, UnicodeType) |
55 is_boolean = lambda x: x in (0, 1) |
55 is_boolean = lambda x: x in (0, 1) |
56 |
56 |
57 # Define checking of value for each attribute |
57 # Define checking of value for each attribute |
58 ENTRY_ATTRIBUTES = {"SUBNUMBER" : is_integer, "PARAMETERNAME" : is_string, |
58 ENTRY_ATTRIBUTES = {"SUBNUMBER" : is_integer, |
59 "OBJECTTYPE" : lambda x: x in (7, 8, 9), "DATATYPE" : is_integer, |
59 "PARAMETERNAME" : is_string, |
60 "LOWLIMIT" : is_integer, "HIGHLIMIT" : is_integer, |
60 "OBJECTTYPE" : lambda x: x in (2, 7, 8, 9), |
|
61 "DATATYPE" : is_integer, |
|
62 "LOWLIMIT" : is_integer, |
|
63 "HIGHLIMIT" : is_integer, |
61 "ACCESSTYPE" : lambda x: x.upper() in ACCESS_TRANSLATE.keys(), |
64 "ACCESSTYPE" : lambda x: x.upper() in ACCESS_TRANSLATE.keys(), |
62 "DEFAULTVALUE" : lambda x: True, "PDOMAPPING" : is_boolean, |
65 "DEFAULTVALUE" : lambda x: True, |
63 "OBJFLAGS" : is_integer, "PARAMETERVALUE" : lambda x: True,} |
66 "PDOMAPPING" : is_boolean, |
|
67 "OBJFLAGS" : is_integer, |
|
68 "PARAMETERVALUE" : lambda x: True, |
|
69 "UPLOADFILE" : is_string, |
|
70 "DOWNLOADFILE" : is_string} |
64 |
71 |
65 # Define entry parameters by entry ObjectType number |
72 # Define entry parameters by entry ObjectType number |
66 ENTRY_TYPES = {7 : {"name" : " VAR", |
73 ENTRY_TYPES = {2 : {"name" : " DOMAIN", |
|
74 "require" : ["PARAMETERNAME", "OBJECTTYPE"], |
|
75 "optional" : ["DATATYPE", "ACCESSTYPE", "DEFAULTVALUE", "OBJFLAGS"]}, |
|
76 7 : {"name" : " VAR", |
67 "require" : ["PARAMETERNAME", "DATATYPE", "ACCESSTYPE"], |
77 "require" : ["PARAMETERNAME", "DATATYPE", "ACCESSTYPE"], |
68 "optional" : ["OBJECTTYPE", "DEFAULTVALUE", "PDOMAPPING", "LOWLIMIT", "HIGHLIMIT", "OBJFLAGS", "PARAMETERVALUE"]}, |
78 "optional" : ["OBJECTTYPE", "DEFAULTVALUE", "PDOMAPPING", "LOWLIMIT", "HIGHLIMIT", "OBJFLAGS", "PARAMETERVALUE"]}, |
69 8 : {"name" : "n ARRAY", |
79 8 : {"name" : "n ARRAY", |
70 "require" : ["PARAMETERNAME", "OBJECTTYPE", "SUBNUMBER"], |
80 "require" : ["PARAMETERNAME", "OBJECTTYPE", "SUBNUMBER"], |
71 "optional" : ["OBJFLAGS"]}, |
81 "optional" : ["OBJFLAGS"]}, |
354 raise SyntaxError, "\"%s\" is not a valid EDS line"%assignment.strip() |
364 raise SyntaxError, "\"%s\" is not a valid EDS line"%assignment.strip() |
355 |
365 |
356 # If entry is an index or a subindex |
366 # If entry is an index or a subindex |
357 if is_entry: |
367 if is_entry: |
358 # Verify that entry has an ObjectType |
368 # Verify that entry has an ObjectType |
359 if "OBJECTTYPE" in values.keys(): |
369 values["OBJECTTYPE"] = values.get("OBJECTTYPE", 7) |
360 # Extract entry ObjectType |
|
361 objecttype = values["OBJECTTYPE"] |
|
362 else: |
|
363 # Set ObjectType to VAR by default |
|
364 objecttype = 7 |
|
365 # Extract parameters defined |
370 # Extract parameters defined |
366 keys = Set(values.keys()) |
371 keys = Set(values.keys()) |
367 keys.discard("subindexes") |
372 keys.discard("subindexes") |
368 # Extract possible parameters and parameters required |
373 # Extract possible parameters and parameters required |
369 possible = Set(ENTRY_TYPES[objecttype]["require"] + ENTRY_TYPES[objecttype]["optional"]) |
374 possible = Set(ENTRY_TYPES[values["OBJECTTYPE"]]["require"] + |
370 required = Set(ENTRY_TYPES[objecttype]["require"]) |
375 ENTRY_TYPES[values["OBJECTTYPE"]]["optional"]) |
|
376 required = Set(ENTRY_TYPES[values["OBJECTTYPE"]]["require"]) |
371 # Verify that parameters defined contains all the parameters required |
377 # Verify that parameters defined contains all the parameters required |
372 if not keys.issuperset(required): |
378 if not keys.issuperset(required): |
373 missing = required.difference(keys)._data.keys() |
379 missing = required.difference(keys)._data.keys() |
374 if len(missing) > 1: |
380 if len(missing) > 1: |
375 attributes = "Attributes %s are"%", ".join(["\"%s\""%attribute for attribute in missing]) |
381 attributes = "Attributes %s are"%", ".join(["\"%s\""%attribute for attribute in missing]) |
376 else: |
382 else: |
377 attributes = "Attribute \"%s\" is"%missing[0] |
383 attributes = "Attribute \"%s\" is"%missing[0] |
378 raise SyntaxError, "Error on section \"[%s]\":\n%s required for a%s entry"%(section_name, attributes, ENTRY_TYPES[objecttype]["name"]) |
384 raise SyntaxError, "Error on section \"[%s]\":\n%s required for a%s entry"%(section_name, attributes, ENTRY_TYPES[values["OBJECTTYPE"]]["name"]) |
379 # Verify that parameters defined are all in the possible parameters |
385 # Verify that parameters defined are all in the possible parameters |
380 if not keys.issubset(possible): |
386 if not keys.issubset(possible): |
381 unsupported = keys.difference(possible)._data.keys() |
387 unsupported = keys.difference(possible)._data.keys() |
382 if len(unsupported) > 1: |
388 if len(unsupported) > 1: |
383 attributes = "Attributes %s are"%", ".join(["\"%s\""%attribute for attribute in unsupported]) |
389 attributes = "Attributes %s are"%", ".join(["\"%s\""%attribute for attribute in unsupported]) |
384 else: |
390 else: |
385 attributes = "Attribute \"%s\" is"%unsupported[0] |
391 attributes = "Attribute \"%s\" is"%unsupported[0] |
386 raise SyntaxError, "Error on section \"[%s]\":\n%s unsupported for a%s entry"%(section_name, attributes, ENTRY_TYPES[objecttype]["name"]) |
392 raise SyntaxError, "Error on section \"[%s]\":\n%s unsupported for a%s entry"%(section_name, attributes, ENTRY_TYPES[values["OBJECTTYPE"]]["name"]) |
387 |
393 |
388 if "PARAMETERVALUE" in values: |
394 VerifyValue(values, "ParameterValue") |
389 try: |
395 VerifyValue(values, "DefaultValue") |
390 if values["DATATYPE"] in (0x09, 0x0A, 0x0B, 0x0F): |
|
391 values["PARAMETERVALUE"] = str(values["PARAMETERVALUE"]) |
|
392 elif values["DATATYPE"] in (0x08, 0x11): |
|
393 values["PARAMETERVALUE"] = float(values["PARAMETERVALUE"]) |
|
394 elif values["DATATYPE"] == 0x01: |
|
395 values["PARAMETERVALUE"] = {0 : False, 1 : True}[values["PARAMETERVALUE"]] |
|
396 else: |
|
397 if type(values["PARAMETERVALUE"]) != IntType and values["PARAMETERVALUE"].find("$NODEID") == -1: |
|
398 raise |
|
399 except: |
|
400 raise SyntaxError, "Error on section \"[%s]\":\nParameterValue incompatible with DataType"%section_name |
|
401 |
|
402 if "DEFAULTVALUE" in values: |
|
403 try: |
|
404 if values["DATATYPE"] in (0x09, 0x0A, 0x0B, 0x0F): |
|
405 values["DEFAULTVALUE"] = str(values["DEFAULTVALUE"]) |
|
406 elif values["DATATYPE"] in (0x08, 0x11): |
|
407 values["DEFAULTVALUE"] = float(values["DEFAULTVALUE"]) |
|
408 elif values["DATATYPE"] == 0x01: |
|
409 values["DEFAULTVALUE"] = {0 : True, 1 : False}[values["DEFAULTVALUE"]] |
|
410 else: |
|
411 if type(values["DEFAULTVALUE"]) != IntType and values["DEFAULTVALUE"].find("$NODEID") == -1: |
|
412 raise |
|
413 except: |
|
414 raise SyntaxError, "Error on section \"[%s]\":\nDefaultValue incompatible with DataType"%section_name |
|
415 |
396 |
416 return eds_dict |
397 return eds_dict |
|
398 |
|
399 def VerifyValue(values, param): |
|
400 if param.upper() in values: |
|
401 try: |
|
402 if values["DATATYPE"] in (0x09, 0x0A, 0x0B, 0x0F): |
|
403 values[param.upper()] = str(values[param.upper()]) |
|
404 elif values["DATATYPE"] in (0x08, 0x11): |
|
405 values[param.upper()] = float(values[param.upper()]) |
|
406 elif values["DATATYPE"] == 0x01: |
|
407 values[param.upper()] = {0 : False, 1 : True}[values[param.upper()]] |
|
408 else: |
|
409 if type(values[param.upper()]) != IntType and values[param.upper()].find("$NODEID") == -1: |
|
410 raise |
|
411 except: |
|
412 raise SyntaxError, "Error on section \"[%s]\":\n%s incompatible with DataType"%(section_name, param) |
417 |
413 |
418 |
414 |
419 # Function that write an EDS file after generate it's content |
415 # Function that write an EDS file after generate it's content |
420 def WriteFile(filepath, content): |
416 def WriteFile(filepath, content): |
421 # Open file in write mode |
417 # Open file in write mode |
663 Node = node.Node(id = nodeID) |
659 Node = node.Node(id = nodeID) |
664 try: |
660 try: |
665 # Parse file and extract dictionary of EDS entry |
661 # Parse file and extract dictionary of EDS entry |
666 eds_dict = ParseEDSFile(filepath) |
662 eds_dict = ParseEDSFile(filepath) |
667 # Extract Profile Number from Device Type entry |
663 # Extract Profile Number from Device Type entry |
668 ProfileNb = eds_dict[0x1000]["DEFAULTVALUE"] & 0x0000ffff |
664 ProfileNb = eds_dict[0x1000].get("DEFAULTVALUE", 0) & 0x0000ffff |
669 # If profile is not DS-301 or DS-302 |
665 # If profile is not DS-301 or DS-302 |
670 if ProfileNb not in [301, 302]: |
666 if ProfileNb not in [0, 301, 302]: |
671 # Compile Profile name and path to .prf file |
667 # Compile Profile name and path to .prf file |
672 ProfileName = "DS-%d"%ProfileNb |
668 ProfileName = "DS-%d"%ProfileNb |
673 ProfilePath = os.path.join(os.path.split(__file__)[0], "config/%s.prf"%ProfileName) |
669 ProfilePath = os.path.join(os.path.split(__file__)[0], "config/%s.prf"%ProfileName) |
674 # Verify that profile is available |
670 # Verify that profile is available |
675 if os.path.isfile(ProfilePath): |
671 if os.path.isfile(ProfilePath): |
690 # Extract informations for the entry |
686 # Extract informations for the entry |
691 entry_infos = Node.GetEntryInfos(entry) |
687 entry_infos = Node.GetEntryInfos(entry) |
692 |
688 |
693 # If no informations are available, then we write them |
689 # If no informations are available, then we write them |
694 if not entry_infos: |
690 if not entry_infos: |
695 # First case, entry is a VAR |
691 # First case, entry is a DOMAIN or VAR |
696 if values["OBJECTTYPE"] == 7: |
692 if values["OBJECTTYPE"] in [2, 7]: |
|
693 if values["OBJECTTYPE"] == 2: |
|
694 values["DATATYPE"] = values.get("DATATYPE", 0xF) |
|
695 if values["DATATYPE"] != 0xF: |
|
696 raise SyntaxError, "Domain entry 0x%4.4X DataType must be 0xF(DOMAIN) if defined"%entry |
697 # Add mapping for entry |
697 # Add mapping for entry |
698 Node.AddMappingEntry(entry, name = values["PARAMETERNAME"], struct = 1) |
698 Node.AddMappingEntry(entry, name = values["PARAMETERNAME"], struct = 1) |
699 # Add mapping for first subindex |
699 # Add mapping for first subindex |
700 Node.AddMappingEntry(entry, 0, values = {"name" : values["PARAMETERNAME"], |
700 Node.AddMappingEntry(entry, 0, values = {"name" : values["PARAMETERNAME"], |
701 "type" : values["DATATYPE"], |
701 "type" : values["DATATYPE"], |
743 ## else: |
743 ## else: |
744 ## raise SyntaxError, "Error on entry 0x%4.4X:\nA RECORD entry must have at least 2 subindexes"%entry |
744 ## raise SyntaxError, "Error on entry 0x%4.4X:\nA RECORD entry must have at least 2 subindexes"%entry |
745 |
745 |
746 # Define entry for the new node |
746 # Define entry for the new node |
747 |
747 |
748 # First case, entry is a VAR |
748 # First case, entry is a DOMAIN or VAR |
749 if values["OBJECTTYPE"] == 7: |
749 if values["OBJECTTYPE"] in [2, 7]: |
750 # Take default value if it is defined |
750 # Take default value if it is defined |
751 if "PARAMETERVALUE" in values: |
751 if "PARAMETERVALUE" in values: |
752 value = values["PARAMETERVALUE"] |
752 value = values["PARAMETERVALUE"] |
753 elif "DEFAULTVALUE" in values: |
753 elif "DEFAULTVALUE" in values: |
754 value = values["DEFAULTVALUE"] |
754 value = values["DEFAULTVALUE"] |
755 # Find default value for value type of the entry |
755 # Find default value for value type of the entry |
756 else: |
756 else: |
757 value = GetDefaultValue(Node, entry) |
757 value = GetDefaultValue(Node, entry) |
758 Node.AddEntry(entry, 0, value) |
758 Node.AddEntry(entry, 0, value) |
759 # Second case, entry is an ARRAY or a RECORD |
759 # Second case, entry is an ARRAY or a RECORD |
760 elif values["OBJECTTYPE"] in (8, 9): |
760 elif values["OBJECTTYPE"] in [8, 9]: |
761 # Verify that "Subnumber" attribute is defined and has a valid value |
761 # Verify that "Subnumber" attribute is defined and has a valid value |
762 if "SUBNUMBER" in values and values["SUBNUMBER"] > 0: |
762 if "SUBNUMBER" in values and values["SUBNUMBER"] > 0: |
763 consecutive = False |
763 consecutive = False |
764 # Extract maximum subindex number defined |
764 # Extract maximum subindex number defined |
765 try: |
765 try: |