objdictgen/eds_utils.py
changeset 509 88c2ea321049
parent 492 b919a24a45cb
child 513 f0343a7457b8
equal deleted inserted replaced
508:08adb8d4b098 509:88c2ea321049
    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: