plcopen/structures.py
changeset 15 fc897b7bfa7b
parent 14 cd0133ed377b
child 18 ee18a387e80a
equal deleted inserted replaced
14:cd0133ed377b 15:fc897b7bfa7b
   176                  "TOD" : "ANY_DATE",
   176                  "TOD" : "ANY_DATE",
   177                  "DT" : "ANY_DATE"
   177                  "DT" : "ANY_DATE"
   178 }
   178 }
   179 
   179 
   180 """
   180 """
   181 Function that returns if the given data type is the same that "reference" or one
   181 returns true if the given data type is the same that "reference" meta-type or one of its types.
   182 of its children types
       
   183 """
   182 """
   184 
   183 
   185 def IsOfType(test, reference):
   184 def IsOfType(test, reference):
   186     while test != None:
   185     while test != None:
   187         if test == reference:
   186         if test == reference:
   188             return True
   187             return True
   189         test = TypeHierarchy[test]
   188         test = TypeHierarchy[test]
   190     return False
   189     return False
   191 
   190 
       
   191 """
       
   192 returns list of all types that correspont to the ANY* meta type
       
   193 """
   192 def GetSubTypes(reference):
   194 def GetSubTypes(reference):
   193     return [ typename for typename in TypeHierarchy.iterkeys() if typename[:3] != "ANY" and IsOfType(typename, reference)]
   195     return [ typename for typename in TypeHierarchy.iterkeys() if typename[:3] != "ANY" and IsOfType(typename, reference)]
   194 
   196 
   195 
   197 """
   196 
   198 take a .csv file and translate it it a "csv_table"
   197 
   199 """            
   198             
       
   199 def csv_file_to_table(file):
   200 def csv_file_to_table(file):
   200 	return [ map(string.strip,line.split(';')) for line in file.xreadlines()]
   201 	return [ map(string.strip,line.split(';')) for line in file.xreadlines()]
   201 
   202 
       
   203 """
       
   204 seek into the csv table to a section ( section_name match 1st field )
       
   205 return the matching row without first field
       
   206 """
   202 def find_section(section_name, table):
   207 def find_section(section_name, table):
   203 	fields = [None]
   208 	fields = [None]
   204 	while(fields[0] != section_name):
   209 	while(fields[0] != section_name):
   205 		fields = table.pop(0)
   210 		fields = table.pop(0)
   206 	return fields[1:]
   211 	return fields[1:]
   207 
   212 
   208 
   213 """
       
   214 extract the standard functions standard parameter names and types...
       
   215 return a { ParameterName: Type, ...}
       
   216 """
   209 def get_standard_funtions_input_variables(table):
   217 def get_standard_funtions_input_variables(table):
   210 	variables = find_section("Standard_functions_variables_types", table)
   218 	variables = find_section("Standard_functions_variables_types", table)
   211 	standard_funtions_input_variables = {}
   219 	standard_funtions_input_variables = {}
   212 	fields = [True,True]
   220 	fields = [True,True]
   213 	while(fields[1]):
   221 	while(fields[1]):
   214 		fields = table.pop(0)
   222 		fields = table.pop(0)
   215 		variable_from_csv = dict([(champ, val) for champ, val in zip(variables, fields[1:])])
   223 		variable_from_csv = dict([(champ, val) for champ, val in zip(variables, fields[1:])])
   216 		standard_funtions_input_variables[variable_from_csv['name']] = variable_from_csv['type']
   224 		standard_funtions_input_variables[variable_from_csv['name']] = variable_from_csv['type']
   217 	return standard_funtions_input_variables
   225 	return standard_funtions_input_variables
   218 	
   226 	
   219 #"(ANY_NUM, ANY_NUM)" ---> [("IN1","ANY_NUM","none"),("IN2","ANY_NUM","none")] 
   227 """
       
   228 translate .csv file input declaration into PLCOpenEditor interessting values
       
   229 in : "(ANY_NUM, ANY_NUM)" and { ParameterName: Type, ...}
       
   230 return [("IN1","ANY_NUM","none"),("IN2","ANY_NUM","none")] 
       
   231 """
   220 def csv_input_translate(str_decl, variables, base):
   232 def csv_input_translate(str_decl, variables, base):
   221 	decl = str_decl.replace('(','').replace(')','').replace(' ','').split(',')
   233 	decl = str_decl.replace('(','').replace(')','').replace(' ','').split(',')
   222 	param_types = []
   234 	param_types = []
   223 	param_names = []
   235 	param_names = []
   224 	modifiers = []
   236 	modifiers = []
   237 			suffix = str(base)
   249 			suffix = str(base)
   238 
   250 
   239 	modifiers = ["none"]*len(param_types)
   251 	modifiers = ["none"]*len(param_types)
   240 	return zip(param_names,param_types,modifiers)
   252 	return zip(param_names,param_types,modifiers)
   241 
   253 
       
   254 """
       
   255 Fillin the PLCOpenEditor standard function dictionnary
       
   256 translate input and output declaration to something more pythonesque
       
   257 and add interface description to comment
       
   258 """
   242 def decl_function(dico_from_table, variables):
   259 def decl_function(dico_from_table, variables):
   243 	Function_decl = { "type" : "function" }
   260 	Function_decl = { "type" : "function" }
   244 	for field, val in dico_from_table:
   261 	for field, val in dico_from_table:
   245 		translate = {
   262 		translate = {
   246 			"baseinputnumber" : lambda x:int(x),
   263 			"baseinputnumber" : lambda x:int(x),
   250 		Function_decl[field] = translate.get(field,lambda x:x)(val)
   267 		Function_decl[field] = translate.get(field,lambda x:x)(val)
   251 	#Function_decl.pop("baseinputnumber")
   268 	#Function_decl.pop("baseinputnumber")
   252 	Function_decl.pop("overloaded")
   269 	Function_decl.pop("overloaded")
   253 	return Function_decl
   270 	return Function_decl
   254 
   271 
   255 
   272 """
       
   273 Returns this kind of declaration for all standard functions
       
   274 
       
   275             [{"name" : "Numerical", 'list': [   {   
       
   276                 'baseinputnumber': 1,
       
   277                 'comment': 'Addition',
       
   278                 'extensible': True,
       
   279                 'inputs': [   ('IN1', 'ANY_NUM', 'none'),
       
   280                               ('IN2', 'ANY_NUM', 'none')],
       
   281                 'name': 'ADD',
       
   282                 'outputs': [('OUT', 'ANY_NUM', 'none')],
       
   283                 'type': 'function'}, ...... ] },.....]
       
   284 """
   256 def get_standard_funtions(table):
   285 def get_standard_funtions(table):
   257 	
   286 	
   258 	variables = get_standard_funtions_input_variables(table)
   287 	variables = get_standard_funtions_input_variables(table)
   259 	
   288 	
   260 	fonctions = find_section("Standard_functions_type",table)
   289 	fonctions = find_section("Standard_functions_type",table)
   294 					if outype != None:
   323 					if outype != None:
   295 						decl_tpl = Function_decl["outputs"][0]
   324 						decl_tpl = Function_decl["outputs"][0]
   296 						Function_decl["outputs"] = [decl_tpl[:1] + (outype,) + decl_tpl[2:]] + Function_decl["outputs"][1:]
   325 						Function_decl["outputs"] = [decl_tpl[:1] + (outype,) + decl_tpl[2:]] + Function_decl["outputs"][1:]
   297 						funcdeclout = funcdeclin.replace("_**", '_' + outype)
   326 						funcdeclout = funcdeclin.replace("_**", '_' + outype)
   298 						Function_decl["name"] = funcdeclout
   327 						Function_decl["name"] = funcdeclout
   299 					Current_section["list"].append(Function_decl.copy())
   328 					
       
   329 					# create the copy of decl dict to be appended to section
       
   330 					Function_decl_copy = Function_decl.copy()
       
   331 					# Have to generate type description in comment with freshly redefined types
       
   332 					Function_decl_copy["comment"] += ("\n (" +
       
   333 						str([ " " + fctdecl[1]+":"+fctdecl[0] for fctdecl in Function_decl["inputs"]]).strip("[]").replace("'",'') +
       
   334 						" ) => (" +
       
   335 						str([ " " + fctdecl[1]+":"+fctdecl[0] for fctdecl in Function_decl["outputs"]]).strip("[]").replace("'",'') +
       
   336 						" )")
       
   337 					Current_section["list"].append(Function_decl_copy)
   300 	
   338 	
   301 	return Standard_Functions_Decl
   339 	return Standard_Functions_Decl
   302 
   340 
   303 
       
   304 to_append=get_standard_funtions(csv_file_to_table(open(os.path.join(sys.path[0], "plcopen/iec_std.csv"))))
       
   305 import pprint
       
   306 pp = pprint.PrettyPrinter(indent=4)
       
   307 pp.pprint(to_append)
       
   308 BlockTypes.extend(to_append)
       
   309 pp.pprint(BlockTypes)
       
   310 #-------------------------------------------------------------------------------
   341 #-------------------------------------------------------------------------------
   311 #                             Test identifier
   342 #                             Test identifier
   312 #-------------------------------------------------------------------------------
   343 #-------------------------------------------------------------------------------
   313 
   344 
   314 
   345 
   382 IEC_KEYWORDS.extend([keyword for keyword in CONFIG_KEYWORDS if keyword not in IEC_KEYWORDS])
   413 IEC_KEYWORDS.extend([keyword for keyword in CONFIG_KEYWORDS if keyword not in IEC_KEYWORDS])
   383 IEC_KEYWORDS.extend([keyword for keyword in SFC_KEYWORDS if keyword not in IEC_KEYWORDS])
   414 IEC_KEYWORDS.extend([keyword for keyword in SFC_KEYWORDS if keyword not in IEC_KEYWORDS])
   384 IEC_KEYWORDS.extend([keyword for keyword in IL_KEYWORDS if keyword not in IEC_KEYWORDS])
   415 IEC_KEYWORDS.extend([keyword for keyword in IL_KEYWORDS if keyword not in IEC_KEYWORDS])
   385 IEC_KEYWORDS.extend([keyword for keyword in ST_KEYWORDS if keyword not in IEC_KEYWORDS])
   416 IEC_KEYWORDS.extend([keyword for keyword in ST_KEYWORDS if keyword not in IEC_KEYWORDS])
   386 
   417 
       
   418 if __name__ == '__main__':
       
   419 	import pprint
       
   420 	pp = pprint.PrettyPrinter(indent=4)
       
   421 	std_decl = get_standard_funtions(csv_file_to_table(open("iec_std.csv")))
       
   422 	pp.pprint(std_decl)
       
   423 else:
       
   424 	# Put standard functions declaration in Bloktypes
       
   425 	BlockTypes.extend(get_standard_funtions(csv_file_to_table(open(os.path.join(sys.path[0], "plcopen/iec_std.csv")))))
       
   426