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 |