25 from plcopen import PLCOpenParser |
25 from plcopen import PLCOpenParser |
26 from plcopen.structures import * |
26 from plcopen.structures import * |
27 from types import * |
27 from types import * |
28 import re |
28 import re |
29 |
29 |
30 # Dictionary associating PLCOpen variable categories to the corresponding |
30 # Dictionary associating PLCOpen variable categories to the corresponding |
31 # IEC 61131-3 variable categories |
31 # IEC 61131-3 variable categories |
32 varTypeNames = {"localVars" : "VAR", "tempVars" : "VAR_TEMP", "inputVars" : "VAR_INPUT", |
32 varTypeNames = {"localVars" : "VAR", "tempVars" : "VAR_TEMP", "inputVars" : "VAR_INPUT", |
33 "outputVars" : "VAR_OUTPUT", "inOutVars" : "VAR_IN_OUT", "externalVars" : "VAR_EXTERNAL", |
33 "outputVars" : "VAR_OUTPUT", "inOutVars" : "VAR_IN_OUT", "externalVars" : "VAR_EXTERNAL", |
34 "globalVars" : "VAR_GLOBAL", "accessVars" : "VAR_ACCESS"} |
34 "globalVars" : "VAR_GLOBAL", "accessVars" : "VAR_ACCESS"} |
35 |
35 |
36 |
36 |
37 # Dictionary associating PLCOpen POU categories to the corresponding |
37 # Dictionary associating PLCOpen POU categories to the corresponding |
38 # IEC 61131-3 POU categories |
38 # IEC 61131-3 POU categories |
39 pouTypeNames = {"function" : "FUNCTION", "functionBlock" : "FUNCTION_BLOCK", "program" : "PROGRAM"} |
39 pouTypeNames = {"function" : "FUNCTION", "functionBlock" : "FUNCTION_BLOCK", "program" : "PROGRAM"} |
40 |
40 |
41 |
41 |
42 errorVarTypes = { |
42 errorVarTypes = { |
123 def GenerateDataType(self, datatype_name): |
123 def GenerateDataType(self, datatype_name): |
124 # Verify that data type hasn't been generated yet |
124 # Verify that data type hasn't been generated yet |
125 if not self.DatatypeComputed.get(datatype_name, True): |
125 if not self.DatatypeComputed.get(datatype_name, True): |
126 # If not mark data type as computed |
126 # If not mark data type as computed |
127 self.DatatypeComputed[datatype_name] = True |
127 self.DatatypeComputed[datatype_name] = True |
128 |
128 |
129 # Getting datatype model from project |
129 # Getting datatype model from project |
130 datatype = self.Project.getdataType(datatype_name) |
130 datatype = self.Project.getdataType(datatype_name) |
131 tagname = self.Controler.ComputeDataTypeName(datatype.getname()) |
131 tagname = self.Controler.ComputeDataTypeName(datatype.getname()) |
132 datatype_def = [(" ", ()), |
132 datatype_def = [(" ", ()), |
133 (datatype.getname(), (tagname, "name")), |
133 (datatype.getname(), (tagname, "name")), |
134 (" : ", ())] |
134 (" : ", ())] |
135 basetype_content = datatype.baseType.getcontent() |
135 basetype_content = datatype.baseType.getcontent() |
136 basetype_content_type = basetype_content.getLocalTag() |
136 basetype_content_type = basetype_content.getLocalTag() |
137 # Data type derived directly from a user defined type |
137 # Data type derived directly from a user defined type |
138 if basetype_content_type == "derived": |
138 if basetype_content_type == "derived": |
139 basetype_name = basetype_content.getname() |
139 basetype_name = basetype_content.getname() |
140 self.GenerateDataType(basetype_name) |
140 self.GenerateDataType(basetype_name) |
141 datatype_def += [(basetype_name, (tagname, "base"))] |
141 datatype_def += [(basetype_name, (tagname, "base"))] |
142 # Data type is a subrange |
142 # Data type is a subrange |
143 elif basetype_content_type in ["subrangeSigned", "subrangeUnsigned"]: |
143 elif basetype_content_type in ["subrangeSigned", "subrangeUnsigned"]: |
144 base_type = basetype_content.baseType.getcontent() |
144 base_type = basetype_content.baseType.getcontent() |
145 base_type_type = base_type.getLocalTag() |
145 base_type_type = base_type.getLocalTag() |
146 # Subrange derived directly from a user defined type |
146 # Subrange derived directly from a user defined type |
147 if base_type_type == "derived": |
147 if base_type_type == "derived": |
148 basetype_name = base_type_type.getname() |
148 basetype_name = base_type_type.getname() |
149 self.GenerateDataType(basetype_name) |
149 self.GenerateDataType(basetype_name) |
150 # Subrange derived directly from an elementary type |
150 # Subrange derived directly from an elementary type |
151 else: |
151 else: |
152 basetype_name = base_type_type |
152 basetype_name = base_type_type |
153 min_value = basetype_content.range.getlower() |
153 min_value = basetype_content.range.getlower() |
154 max_value = basetype_content.range.getupper() |
154 max_value = basetype_content.range.getupper() |
155 datatype_def += [(basetype_name, (tagname, "base")), |
155 datatype_def += [(basetype_name, (tagname, "base")), |
160 (")",())] |
160 (")",())] |
161 # Data type is an enumerated type |
161 # Data type is an enumerated type |
162 elif basetype_content_type == "enum": |
162 elif basetype_content_type == "enum": |
163 values = [[(value.getname(), (tagname, "value", i))] |
163 values = [[(value.getname(), (tagname, "value", i))] |
164 for i, value in enumerate( |
164 for i, value in enumerate( |
165 basetype_content.xpath("ppx:values/ppx:value", |
165 basetype_content.xpath("ppx:values/ppx:value", |
166 namespaces=PLCOpenParser.NSMAP))] |
166 namespaces=PLCOpenParser.NSMAP))] |
167 datatype_def += [("(", ())] |
167 datatype_def += [("(", ())] |
168 datatype_def += JoinList([(", ", ())], values) |
168 datatype_def += JoinList([(", ", ())], values) |
169 datatype_def += [(")", ())] |
169 datatype_def += [(")", ())] |
170 # Data type is an array |
170 # Data type is an array |
171 elif basetype_content_type == "array": |
171 elif basetype_content_type == "array": |
172 base_type = basetype_content.baseType.getcontent() |
172 base_type = basetype_content.baseType.getcontent() |
173 base_type_type = base_type.getLocalTag() |
173 base_type_type = base_type.getLocalTag() |
174 # Array derived directly from a user defined type |
174 # Array derived directly from a user defined type |
175 if base_type_type == "derived": |
175 if base_type_type == "derived": |
176 basetype_name = base_type.getname() |
176 basetype_name = base_type.getname() |
177 self.GenerateDataType(basetype_name) |
177 self.GenerateDataType(basetype_name) |
178 # Array derived directly from an elementary type |
178 # Array derived directly from an elementary type |
179 else: |
179 else: |
180 basetype_name = base_type_type.upper() |
180 basetype_name = base_type_type.upper() |
181 dimensions = [[("%s"%dimension.getlower(), (tagname, "range", i, "lower")), |
181 dimensions = [[("%s"%dimension.getlower(), (tagname, "range", i, "lower")), |
182 ("..", ()), |
182 ("..", ()), |
183 ("%s"%dimension.getupper(), (tagname, "range", i, "upper"))] |
183 ("%s"%dimension.getupper(), (tagname, "range", i, "upper"))] |
184 for i, dimension in enumerate(basetype_content.getdimension())] |
184 for i, dimension in enumerate(basetype_content.getdimension())] |
185 datatype_def += [("ARRAY [", ())] |
185 datatype_def += [("ARRAY [", ())] |
186 datatype_def += JoinList([(",", ())], dimensions) |
186 datatype_def += JoinList([(",", ())], dimensions) |
187 datatype_def += [("] OF " , ()), |
187 datatype_def += [("] OF " , ()), |
188 (basetype_name, (tagname, "base"))] |
188 (basetype_name, (tagname, "base"))] |
190 elif basetype_content_type == "struct": |
190 elif basetype_content_type == "struct": |
191 elements = [] |
191 elements = [] |
192 for i, element in enumerate(basetype_content.getvariable()): |
192 for i, element in enumerate(basetype_content.getvariable()): |
193 element_type = element.type.getcontent() |
193 element_type = element.type.getcontent() |
194 element_type_type = element_type.getLocalTag() |
194 element_type_type = element_type.getLocalTag() |
195 # Structure element derived directly from a user defined type |
195 # Structure element derived directly from a user defined type |
196 if element_type_type == "derived": |
196 if element_type_type == "derived": |
197 elementtype_name = element_type.getname() |
197 elementtype_name = element_type.getname() |
198 self.GenerateDataType(elementtype_name) |
198 self.GenerateDataType(elementtype_name) |
199 elif element_type_type == "array": |
199 elif element_type_type == "array": |
200 base_type = element_type.baseType.getcontent() |
200 base_type = element_type.baseType.getcontent() |
201 base_type_type = base_type.getLocalTag() |
201 base_type_type = base_type.getLocalTag() |
202 # Array derived directly from a user defined type |
202 # Array derived directly from a user defined type |
203 if base_type_type == "derived": |
203 if base_type_type == "derived": |
204 basetype_name = base_type.getname() |
204 basetype_name = base_type.getname() |
205 self.GenerateDataType(basetype_name) |
205 self.GenerateDataType(basetype_name) |
206 # Array derived directly from an elementary type |
206 # Array derived directly from an elementary type |
207 else: |
207 else: |
208 basetype_name = base_type_type.upper() |
208 basetype_name = base_type_type.upper() |
209 dimensions = ["%s..%s" % (dimension.getlower(), dimension.getupper()) |
209 dimensions = ["%s..%s" % (dimension.getlower(), dimension.getupper()) |
210 for dimension in element_type.getdimension()] |
210 for dimension in element_type.getdimension()] |
211 elementtype_name = "ARRAY [%s] OF %s" % (",".join(dimensions), basetype_name) |
211 elementtype_name = "ARRAY [%s] OF %s" % (",".join(dimensions), basetype_name) |
212 # Structure element derived directly from an elementary type |
212 # Structure element derived directly from an elementary type |
213 else: |
213 else: |
214 elementtype_name = element_type_type.upper() |
214 elementtype_name = element_type_type.upper() |
215 element_text = [("\n ", ()), |
215 element_text = [("\n ", ()), |
216 (element.getname(), (tagname, "struct", i, "name")), |
216 (element.getname(), (tagname, "struct", i, "name")), |
217 (" : ", ()), |
217 (" : ", ()), |
222 element_text.append((";", ())) |
222 element_text.append((";", ())) |
223 elements.append(element_text) |
223 elements.append(element_text) |
224 datatype_def += [("STRUCT", ())] |
224 datatype_def += [("STRUCT", ())] |
225 datatype_def += JoinList([("", ())], elements) |
225 datatype_def += JoinList([("", ())], elements) |
226 datatype_def += [("\n END_STRUCT", ())] |
226 datatype_def += [("\n END_STRUCT", ())] |
227 # Data type derived directly from a elementary type |
227 # Data type derived directly from a elementary type |
228 else: |
228 else: |
229 datatype_def += [(basetype_content_type.upper(), (tagname, "base"))] |
229 datatype_def += [(basetype_content_type.upper(), (tagname, "base"))] |
230 # Data type has an initial value |
230 # Data type has an initial value |
231 if datatype.initialValue is not None: |
231 if datatype.initialValue is not None: |
232 datatype_def += [(" := ", ()), |
232 datatype_def += [(" := ", ()), |
238 def GeneratePouProgram(self, pou_name): |
238 def GeneratePouProgram(self, pou_name): |
239 # Verify that POU hasn't been generated yet |
239 # Verify that POU hasn't been generated yet |
240 if not self.PouComputed.get(pou_name, True): |
240 if not self.PouComputed.get(pou_name, True): |
241 # If not mark POU as computed |
241 # If not mark POU as computed |
242 self.PouComputed[pou_name] = True |
242 self.PouComputed[pou_name] = True |
243 |
243 |
244 # Getting POU model from project |
244 # Getting POU model from project |
245 pou = self.Project.getpou(pou_name) |
245 pou = self.Project.getpou(pou_name) |
246 pou_type = pou.getpouType() |
246 pou_type = pou.getpouType() |
247 # Verify that POU type exists |
247 # Verify that POU type exists |
248 if pouTypeNames.has_key(pou_type): |
248 if pouTypeNames.has_key(pou_type): |
250 pou_program = PouProgramGenerator(self, pou.getname(), pouTypeNames[pou_type], self.Errors, self.Warnings) |
250 pou_program = PouProgramGenerator(self, pou.getname(), pouTypeNames[pou_type], self.Errors, self.Warnings) |
251 program = pou_program.GenerateProgram(pou) |
251 program = pou_program.GenerateProgram(pou) |
252 self.Program += program |
252 self.Program += program |
253 else: |
253 else: |
254 raise PLCGenException, _("Undefined pou type \"%s\"")%pou_type |
254 raise PLCGenException, _("Undefined pou type \"%s\"")%pou_type |
255 |
255 |
256 # Generate a POU defined and used in text |
256 # Generate a POU defined and used in text |
257 def GeneratePouProgramInText(self, text): |
257 def GeneratePouProgramInText(self, text): |
258 for pou_name in self.PouComputed.keys(): |
258 for pou_name in self.PouComputed.keys(): |
259 model = re.compile("(?:^|[^0-9^A-Z])%s(?:$|[^0-9^A-Z])"%pou_name.upper()) |
259 model = re.compile("(?:^|[^0-9^A-Z])%s(?:$|[^0-9^A-Z])"%pou_name.upper()) |
260 if model.search(text) is not None: |
260 if model.search(text) is not None: |
261 self.GeneratePouProgram(pou_name) |
261 self.GeneratePouProgram(pou_name) |
262 |
262 |
263 # Generate a configuration from its model |
263 # Generate a configuration from its model |
264 def GenerateConfiguration(self, configuration): |
264 def GenerateConfiguration(self, configuration): |
265 tagname = self.Controler.ComputeConfigurationName(configuration.getname()) |
265 tagname = self.Controler.ComputeConfigurationName(configuration.getname()) |
266 config = [("\nCONFIGURATION ", ()), |
266 config = [("\nCONFIGURATION ", ()), |
267 (configuration.getname(), (tagname, "name")), |
267 (configuration.getname(), (tagname, "name")), |
268 ("\n", ())] |
268 ("\n", ())] |
269 var_number = 0 |
269 var_number = 0 |
270 |
270 |
271 varlists = [(varlist, varlist.getvariable()[:]) for varlist in configuration.getglobalVars()] |
271 varlists = [(varlist, varlist.getvariable()[:]) for varlist in configuration.getglobalVars()] |
272 |
272 |
273 extra_variables = self.Controler.GetConfigurationExtraVariables() |
273 extra_variables = self.Controler.GetConfigurationExtraVariables() |
274 extra_global_vars = None |
274 extra_global_vars = None |
275 if len(extra_variables) > 0 and len(varlists) == 0: |
275 if len(extra_variables) > 0 and len(varlists) == 0: |
276 extra_global_vars = PLCOpenParser.CreateElement("globalVars", "interface") |
276 extra_global_vars = PLCOpenParser.CreateElement("globalVars", "interface") |
277 configuration.setglobalVars([extra_global_vars]) |
277 configuration.setglobalVars([extra_global_vars]) |
278 varlists = [(extra_global_vars, [])] |
278 varlists = [(extra_global_vars, [])] |
279 |
279 |
280 for variable in extra_variables: |
280 for variable in extra_variables: |
281 varlists[-1][0].appendvariable(variable) |
281 varlists[-1][0].appendvariable(variable) |
282 varlists[-1][1].append(variable) |
282 varlists[-1][1].append(variable) |
283 |
283 |
284 # Generate any global variable in configuration |
284 # Generate any global variable in configuration |
285 for varlist, varlist_variables in varlists: |
285 for varlist, varlist_variables in varlists: |
286 variable_type = errorVarTypes.get("VAR_GLOBAL", "var_local") |
286 variable_type = errorVarTypes.get("VAR_GLOBAL", "var_local") |
287 # Generate variable block with modifier |
287 # Generate variable block with modifier |
288 config += [(" VAR_GLOBAL", ())] |
288 config += [(" VAR_GLOBAL", ())] |
299 if vartype_content.getLocalTag() == "derived": |
299 if vartype_content.getLocalTag() == "derived": |
300 var_type = vartype_content.getname() |
300 var_type = vartype_content.getname() |
301 self.GenerateDataType(var_type) |
301 self.GenerateDataType(var_type) |
302 else: |
302 else: |
303 var_type = var.gettypeAsText() |
303 var_type = var.gettypeAsText() |
304 |
304 |
305 config += [(" ", ()), |
305 config += [(" ", ()), |
306 (var.getname(), (tagname, variable_type, var_number, "name")), |
306 (var.getname(), (tagname, variable_type, var_number, "name")), |
307 (" ", ())] |
307 (" ", ())] |
308 # Generate variable address if exists |
308 # Generate variable address if exists |
309 address = var.getaddress() |
309 address = var.getaddress() |
319 config += [(" := ", ()), |
319 config += [(" := ", ()), |
320 (self.ComputeValue(initial.getvalue(), var_type), (tagname, variable_type, var_number, "initial value"))] |
320 (self.ComputeValue(initial.getvalue(), var_type), (tagname, variable_type, var_number, "initial value"))] |
321 config += [(";\n", ())] |
321 config += [(";\n", ())] |
322 var_number += 1 |
322 var_number += 1 |
323 config += [(" END_VAR\n", ())] |
323 config += [(" END_VAR\n", ())] |
324 |
324 |
325 if extra_global_vars is not None: |
325 if extra_global_vars is not None: |
326 configuration.remove(extra_global_vars) |
326 configuration.remove(extra_global_vars) |
327 else: |
327 else: |
328 for variable in extra_variables: |
328 for variable in extra_variables: |
329 varlists[-1][0].remove(variable) |
329 varlists[-1][0].remove(variable) |
330 |
330 |
331 # Generate any resource in the configuration |
331 # Generate any resource in the configuration |
332 for resource in configuration.getresource(): |
332 for resource in configuration.getresource(): |
333 config += self.GenerateResource(resource, configuration.getname()) |
333 config += self.GenerateResource(resource, configuration.getname()) |
334 config += [("END_CONFIGURATION\n", ())] |
334 config += [("END_CONFIGURATION\n", ())] |
335 return config |
335 return config |
336 |
336 |
337 # Generate a resource from its model |
337 # Generate a resource from its model |
338 def GenerateResource(self, resource, config_name): |
338 def GenerateResource(self, resource, config_name): |
339 tagname = self.Controler.ComputeConfigurationResourceName(config_name, resource.getname()) |
339 tagname = self.Controler.ComputeConfigurationResourceName(config_name, resource.getname()) |
340 resrce = [("\n RESOURCE ", ()), |
340 resrce = [("\n RESOURCE ", ()), |
341 (resource.getname(), (tagname, "name")), |
341 (resource.getname(), (tagname, "name")), |
359 if vartype_content.getLocalTag() == "derived": |
359 if vartype_content.getLocalTag() == "derived": |
360 var_type = vartype_content.getname() |
360 var_type = vartype_content.getname() |
361 self.GenerateDataType(var_type) |
361 self.GenerateDataType(var_type) |
362 else: |
362 else: |
363 var_type = var.gettypeAsText() |
363 var_type = var.gettypeAsText() |
364 |
364 |
365 resrce += [(" ", ()), |
365 resrce += [(" ", ()), |
366 (var.getname(), (tagname, variable_type, var_number, "name")), |
366 (var.getname(), (tagname, variable_type, var_number, "name")), |
367 (" ", ())] |
367 (" ", ())] |
368 address = var.getaddress() |
368 address = var.getaddress() |
369 # Generate variable address if exists |
369 # Generate variable address if exists |
411 ## resrce += [("%ds"%interval.second, (tagname, "task", task_number, "interval", "second"))] |
411 ## resrce += [("%ds"%interval.second, (tagname, "task", task_number, "interval", "second"))] |
412 ## if interval.microsecond != 0: |
412 ## if interval.microsecond != 0: |
413 ## resrce += [("%dms"%(interval.microsecond / 1000), (tagname, "task", task_number, "interval", "millisecond"))] |
413 ## resrce += [("%dms"%(interval.microsecond / 1000), (tagname, "task", task_number, "interval", "millisecond"))] |
414 ## resrce += [(",", ())] |
414 ## resrce += [(",", ())] |
415 # Priority argument |
415 # Priority argument |
416 resrce += [("PRIORITY := ", ()), |
416 resrce += [("PRIORITY := ", ()), |
417 ("%d"%task.getpriority(), (tagname, "task", task_number, "priority")), |
417 ("%d"%task.getpriority(), (tagname, "task", task_number, "priority")), |
418 (");\n", ())] |
418 (");\n", ())] |
419 task_number += 1 |
419 task_number += 1 |
420 instance_number = 0 |
420 instance_number = 0 |
421 # Generate any program assign to each task |
421 # Generate any program assign to each task |
437 (instance.gettypeName(), (tagname, "instance", instance_number, "type")), |
437 (instance.gettypeName(), (tagname, "instance", instance_number, "type")), |
438 (";\n", ())] |
438 (";\n", ())] |
439 instance_number += 1 |
439 instance_number += 1 |
440 resrce += [(" END_RESOURCE\n", ())] |
440 resrce += [(" END_RESOURCE\n", ())] |
441 return resrce |
441 return resrce |
442 |
442 |
443 # Generate the entire program for current project |
443 # Generate the entire program for current project |
444 def GenerateProgram(self): |
444 def GenerateProgram(self): |
445 # Find all data types defined |
445 # Find all data types defined |
446 for datatype in self.Project.getdataTypes(): |
446 for datatype in self.Project.getdataTypes(): |
447 self.DatatypeComputed[datatype.getname()] = False |
447 self.DatatypeComputed[datatype.getname()] = False |
448 # Find all data types defined |
448 # Find all data types defined |
449 for pou in self.Project.getpous(): |
449 for pou in self.Project.getpous(): |
450 self.PouComputed[pou.getname()] = False |
450 self.PouComputed[pou.getname()] = False |
451 # Generate data type declaration structure if there is at least one data |
451 # Generate data type declaration structure if there is at least one data |
452 # type defined |
452 # type defined |
453 if len(self.DatatypeComputed) > 0: |
453 if len(self.DatatypeComputed) > 0: |
454 self.Program += [("TYPE\n", ())] |
454 self.Program += [("TYPE\n", ())] |
455 # Generate every data types defined |
455 # Generate every data types defined |
456 for datatype_name in self.DatatypeComputed.keys(): |
456 for datatype_name in self.DatatypeComputed.keys(): |
479 PLCOpenParser.GetElementClass(instance_name, "fbdObjects") |
479 PLCOpenParser.GetElementClass(instance_name, "fbdObjects") |
480 for instance_name in ["inVariable", "inOutVariable", "outVariable", "block"]] |
480 for instance_name in ["inVariable", "inOutVariable", "outVariable", "block"]] |
481 [ContactClass, CoilClass, LeftPowerRailClass, RightPowerRailClass] = [ |
481 [ContactClass, CoilClass, LeftPowerRailClass, RightPowerRailClass] = [ |
482 PLCOpenParser.GetElementClass(instance_name, "ldObjects") |
482 PLCOpenParser.GetElementClass(instance_name, "ldObjects") |
483 for instance_name in ["contact", "coil", "leftPowerRail", "rightPowerRail"]] |
483 for instance_name in ["contact", "coil", "leftPowerRail", "rightPowerRail"]] |
484 [StepClass, TransitionClass, JumpStepClass, |
484 [StepClass, TransitionClass, JumpStepClass, |
485 SelectionConvergenceClass, SelectionDivergenceClass, |
485 SelectionConvergenceClass, SelectionDivergenceClass, |
486 SimultaneousConvergenceClass, SimultaneousDivergenceClass] = [ |
486 SimultaneousConvergenceClass, SimultaneousDivergenceClass] = [ |
487 PLCOpenParser.GetElementClass(instance_name, "sfcObjects") |
487 PLCOpenParser.GetElementClass(instance_name, "sfcObjects") |
488 for instance_name in ["step", "transition", "jumpStep", |
488 for instance_name in ["step", "transition", "jumpStep", |
489 "selectionConvergence", "selectionDivergence", |
489 "selectionConvergence", "selectionDivergence", |
490 "simultaneousConvergence", "simultaneousDivergence"]] |
490 "simultaneousConvergence", "simultaneousDivergence"]] |
491 TransitionObjClass = PLCOpenParser.GetElementClass("transition", "transitions") |
491 TransitionObjClass = PLCOpenParser.GetElementClass("transition", "transitions") |
492 ActionObjClass = PLCOpenParser.GetElementClass("action", "actions") |
492 ActionObjClass = PLCOpenParser.GetElementClass("action", "actions") |
493 |
493 |
494 class PouProgramGenerator: |
494 class PouProgramGenerator: |
495 |
495 |
496 # Create a new POU program generator |
496 # Create a new POU program generator |
497 def __init__(self, parent, name, type, errors, warnings): |
497 def __init__(self, parent, name, type, errors, warnings): |
498 # Keep Reference to the parent generator |
498 # Keep Reference to the parent generator |
499 self.ParentGenerator = parent |
499 self.ParentGenerator = parent |
500 self.Name = name |
500 self.Name = name |
512 self.SFCComputedBlocks = [] |
512 self.SFCComputedBlocks = [] |
513 self.ActionNumber = 0 |
513 self.ActionNumber = 0 |
514 self.Program = [] |
514 self.Program = [] |
515 self.Errors = errors |
515 self.Errors = errors |
516 self.Warnings = warnings |
516 self.Warnings = warnings |
517 |
517 |
518 def GetBlockType(self, type, inputs=None): |
518 def GetBlockType(self, type, inputs=None): |
519 return self.ParentGenerator.Controler.GetBlockType(type, inputs) |
519 return self.ParentGenerator.Controler.GetBlockType(type, inputs) |
520 |
520 |
521 def IndentLeft(self): |
521 def IndentLeft(self): |
522 if len(self.CurrentIndent) >= 2: |
522 if len(self.CurrentIndent) >= 2: |
523 self.CurrentIndent = self.CurrentIndent[:-2] |
523 self.CurrentIndent = self.CurrentIndent[:-2] |
524 |
524 |
525 def IndentRight(self): |
525 def IndentRight(self): |
526 self.CurrentIndent += " " |
526 self.CurrentIndent += " " |
527 |
527 |
528 # Generator of unique ID for inline actions |
528 # Generator of unique ID for inline actions |
529 def GetActionNumber(self): |
529 def GetActionNumber(self): |
530 self.ActionNumber += 1 |
530 self.ActionNumber += 1 |
531 return self.ActionNumber |
531 return self.ActionNumber |
532 |
532 |
533 # Test if a variable has already been defined |
533 # Test if a variable has already been defined |
534 def IsAlreadyDefined(self, name): |
534 def IsAlreadyDefined(self, name): |
535 for list_type, option, located, vars in self.Interface: |
535 for list_type, option, located, vars in self.Interface: |
536 for var_type, var_name, var_address, var_initial in vars: |
536 for var_type, var_name, var_address, var_initial in vars: |
537 if name == var_name: |
537 if name == var_name: |
538 return True |
538 return True |
539 return False |
539 return False |
540 |
540 |
541 # Return the type of a variable defined in interface |
541 # Return the type of a variable defined in interface |
542 def GetVariableType(self, name): |
542 def GetVariableType(self, name): |
543 parts = name.split('.') |
543 parts = name.split('.') |
544 current_type = None |
544 current_type = None |
545 if len(parts) > 0: |
545 if len(parts) > 0: |
567 for element in infos["elements"]: |
567 for element in infos["elements"]: |
568 if element["Name"] == name: |
568 if element["Name"] == name: |
569 current_type = element["Type"] |
569 current_type = element["Type"] |
570 break |
570 break |
571 return current_type |
571 return current_type |
572 |
572 |
573 # Return connectors linked by a connection to the given connector |
573 # Return connectors linked by a connection to the given connector |
574 def GetConnectedConnector(self, connector, body): |
574 def GetConnectedConnector(self, connector, body): |
575 links = connector.getconnections() |
575 links = connector.getconnections() |
576 if links is not None and len(links) == 1: |
576 if links is not None and len(links) == 1: |
577 return self.GetLinkedConnector(links[0], body) |
577 return self.GetLinkedConnector(links[0], body) |
578 return None |
578 return None |
579 |
579 |
580 def GetLinkedConnector(self, link, body): |
580 def GetLinkedConnector(self, link, body): |
581 parameter = link.getformalParameter() |
581 parameter = link.getformalParameter() |
582 instance = body.getcontentInstance(link.getrefLocalId()) |
582 instance = body.getcontentInstance(link.getrefLocalId()) |
583 if isinstance(instance, (InVariableClass, InOutVariableClass, |
583 if isinstance(instance, (InVariableClass, InOutVariableClass, |
584 ContinuationClass, ContactClass, CoilClass)): |
584 ContinuationClass, ContactClass, CoilClass)): |
585 return instance.connectionPointOut |
585 return instance.connectionPointOut |
586 elif isinstance(instance, BlockClass): |
586 elif isinstance(instance, BlockClass): |
587 outputvariables = instance.outputVariables.getvariable() |
587 outputvariables = instance.outputVariables.getvariable() |
588 if len(outputvariables) == 1: |
588 if len(outputvariables) == 1: |
608 relposition = outputconnection.getrelPositionXY() |
608 relposition = outputconnection.getrelPositionXY() |
609 powerrailposition = instance.getposition() |
609 powerrailposition = instance.getposition() |
610 if point.x == powerrailposition.x + relposition[0] and point.y == powerrailposition.y + relposition[1]: |
610 if point.x == powerrailposition.x + relposition[0] and point.y == powerrailposition.y + relposition[1]: |
611 return outputconnection |
611 return outputconnection |
612 return None |
612 return None |
613 |
613 |
614 def ExtractRelatedConnections(self, connection): |
614 def ExtractRelatedConnections(self, connection): |
615 for i, related in enumerate(self.RelatedConnections): |
615 for i, related in enumerate(self.RelatedConnections): |
616 if connection in related: |
616 if connection in related: |
617 return self.RelatedConnections.pop(i) |
617 return self.RelatedConnections.pop(i) |
618 return [connection] |
618 return [connection] |
619 |
619 |
620 def ComputeInterface(self, pou): |
620 def ComputeInterface(self, pou): |
621 interface = pou.getinterface() |
621 interface = pou.getinterface() |
622 if interface is not None: |
622 if interface is not None: |
623 body = pou.getbody() |
623 body = pou.getbody() |
624 if isinstance(body, ListType): |
624 if isinstance(body, ListType): |
625 body = body[0] |
625 body = body[0] |
626 body_content = body.getcontent() |
626 body_content = body.getcontent() |
627 body_type = body_content.getLocalTag() |
627 body_type = body_content.getLocalTag() |
628 if self.Type == "FUNCTION": |
628 if self.Type == "FUNCTION": |
629 returntype_content = interface.getreturnType().getcontent() |
629 returntype_content = interface.getreturnType()[0] |
630 returntype_content_type = returntype_content.getLocalTag() |
630 returntype_content_type = returntype_content.getLocalTag() |
631 if returntype_content_type == "derived": |
631 if returntype_content_type == "derived": |
632 self.ReturnType = returntype_content.getname() |
632 self.ReturnType = returntype_content.getname() |
633 else: |
633 else: |
634 self.ReturnType = returntype_content_type.upper() |
634 self.ReturnType = returntype_content_type.upper() |
697 body_content = body.getcontent() |
697 body_content = body.getcontent() |
698 body_type = body_content.getLocalTag() |
698 body_type = body_content.getLocalTag() |
699 if body_type in ["FBD", "LD", "SFC"]: |
699 if body_type in ["FBD", "LD", "SFC"]: |
700 undefined_blocks = [] |
700 undefined_blocks = [] |
701 for instance in body.getcontentInstances(): |
701 for instance in body.getcontentInstances(): |
702 if isinstance(instance, (InVariableClass, OutVariableClass, |
702 if isinstance(instance, (InVariableClass, OutVariableClass, |
703 InOutVariableClass)): |
703 InOutVariableClass)): |
704 expression = instance.getexpression() |
704 expression = instance.getexpression() |
705 var_type = self.GetVariableType(expression) |
705 var_type = self.GetVariableType(expression) |
706 if (isinstance(pou, TransitionObjClass) |
706 if (isinstance(pou, TransitionObjClass) |
707 and expression == pou.getname()): |
707 and expression == pou.getname()): |
708 var_type = "BOOL" |
708 var_type = "BOOL" |
709 elif (not isinstance(pou, (TransitionObjClass, ActionObjClass)) and |
709 elif (not isinstance(pou, (TransitionObjClass, ActionObjClass)) and |
710 pou.getpouType() == "function" and expression == pou.getname()): |
710 pou.getpouType() == "function" and expression == pou.getname()): |
711 returntype_content = pou.interface.getreturnType().getcontent() |
711 returntype_content = pou.interface.getreturnType().getcontent() |
820 self.ComputeConnectionTypes(action) |
820 self.ComputeConnectionTypes(action) |
821 for transition in pou.gettransitionList(): |
821 for transition in pou.gettransitionList(): |
822 self.TagName = self.ParentGenerator.Controler.ComputePouTransitionName(self.Name, transition.getname()) |
822 self.TagName = self.ParentGenerator.Controler.ComputePouTransitionName(self.Name, transition.getname()) |
823 self.ComputeConnectionTypes(transition) |
823 self.ComputeConnectionTypes(transition) |
824 self.TagName = previous_tagname |
824 self.TagName = previous_tagname |
825 |
825 |
826 def ComputeBlockInputTypes(self, instance, block_infos, body): |
826 def ComputeBlockInputTypes(self, instance, block_infos, body): |
827 undefined = {} |
827 undefined = {} |
828 for variable in instance.outputVariables.getvariable(): |
828 for variable in instance.outputVariables.getvariable(): |
829 output_name = variable.getformalParameter() |
829 output_name = variable.getformalParameter() |
830 if output_name == "ENO": |
830 if output_name == "ENO": |
881 body_content = body.getcontent() |
881 body_content = body.getcontent() |
882 body_type = body_content.getLocalTag() |
882 body_type = body_content.getLocalTag() |
883 if body_type in ["IL","ST"]: |
883 if body_type in ["IL","ST"]: |
884 text = body_content.getanyText() |
884 text = body_content.getanyText() |
885 self.ParentGenerator.GeneratePouProgramInText(text.upper()) |
885 self.ParentGenerator.GeneratePouProgramInText(text.upper()) |
886 self.Program = [(ReIndentText(text, len(self.CurrentIndent)), |
886 self.Program = [(ReIndentText(text, len(self.CurrentIndent)), |
887 (self.TagName, "body", len(self.CurrentIndent)))] |
887 (self.TagName, "body", len(self.CurrentIndent)))] |
888 elif body_type == "SFC": |
888 elif body_type == "SFC": |
889 self.IndentRight() |
889 self.IndentRight() |
890 for instance in body.getcontentInstances(): |
890 for instance in body.getcontentInstances(): |
891 if isinstance(instance, StepClass): |
891 if isinstance(instance, StepClass): |
964 if expression is not None: |
964 if expression is not None: |
965 expression = self.ExtractModifier(instance, expression, coil_info) |
965 expression = self.ExtractModifier(instance, expression, coil_info) |
966 self.Program += [(self.CurrentIndent, ())] |
966 self.Program += [(self.CurrentIndent, ())] |
967 self.Program += [(instance.getvariable(), coil_info + ("reference",))] |
967 self.Program += [(instance.getvariable(), coil_info + ("reference",))] |
968 self.Program += [(" := ", ())] + expression + [(";\n", ())] |
968 self.Program += [(" := ", ())] + expression + [(";\n", ())] |
969 |
969 |
970 def FactorizePaths(self, paths): |
970 def FactorizePaths(self, paths): |
971 same_paths = {} |
971 same_paths = {} |
972 uncomputed_index = range(len(paths)) |
972 uncomputed_index = range(len(paths)) |
973 factorized_paths = [] |
973 factorized_paths = [] |
974 for num, path in enumerate(paths): |
974 for num, path in enumerate(paths): |
982 uncomputed_index.remove(num) |
982 uncomputed_index.remove(num) |
983 for same_path, elements in same_paths.items(): |
983 for same_path, elements in same_paths.items(): |
984 if len(elements) > 1: |
984 if len(elements) > 1: |
985 elements_paths = self.FactorizePaths([path for path, num in elements]) |
985 elements_paths = self.FactorizePaths([path for path, num in elements]) |
986 if len(elements_paths) > 1: |
986 if len(elements_paths) > 1: |
987 factorized_paths.append([tuple(elements_paths)] + eval(same_path)) |
987 factorized_paths.append([tuple(elements_paths)] + eval(same_path)) |
988 else: |
988 else: |
989 factorized_paths.append(elements_paths + eval(same_path)) |
989 factorized_paths.append(elements_paths + eval(same_path)) |
990 for path, num in elements: |
990 for path, num in elements: |
991 uncomputed_index.remove(num) |
991 uncomputed_index.remove(num) |
992 for num in uncomputed_index: |
992 for num in uncomputed_index: |
1011 if block_infos["type"] == "function": |
1011 if block_infos["type"] == "function": |
1012 if not self.ComputedBlocks.get(block, False) and not order: |
1012 if not self.ComputedBlocks.get(block, False) and not order: |
1013 self.ComputedBlocks[block] = True |
1013 self.ComputedBlocks[block] = True |
1014 connected_vars = [] |
1014 connected_vars = [] |
1015 if not block_infos["extensible"]: |
1015 if not block_infos["extensible"]: |
1016 input_connected = dict([("EN", None)] + |
1016 input_connected = dict([("EN", None)] + |
1017 [(input_name, None) for input_name in input_names]) |
1017 [(input_name, None) for input_name in input_names]) |
1018 for variable in input_variables: |
1018 for variable in input_variables: |
1019 parameter = variable.getformalParameter() |
1019 parameter = variable.getformalParameter() |
1020 if input_connected.has_key(parameter): |
1020 if input_connected.has_key(parameter): |
1021 input_connected[parameter] = variable |
1021 input_connected[parameter] = variable |
1069 if variable.connectionPointOut in self.ConnectionTypes: |
1069 if variable.connectionPointOut in self.ConnectionTypes: |
1070 self.Interface[-1][3].append((self.ConnectionTypes[variable.connectionPointOut], variable_name, None, None)) |
1070 self.Interface[-1][3].append((self.ConnectionTypes[variable.connectionPointOut], variable_name, None, None)) |
1071 else: |
1071 else: |
1072 self.Interface[-1][3].append(("ANY", variable_name, None, None)) |
1072 self.Interface[-1][3].append(("ANY", variable_name, None, None)) |
1073 if len(output_variables) > 1 and parameter not in ["", "OUT"]: |
1073 if len(output_variables) > 1 and parameter not in ["", "OUT"]: |
1074 vars.append([(parameter, (self.TagName, "block", block.getlocalId(), "output", i)), |
1074 vars.append([(parameter, (self.TagName, "block", block.getlocalId(), "output", i)), |
1075 (" => %s"%variable_name, ())]) |
1075 (" => %s"%variable_name, ())]) |
1076 else: |
1076 else: |
1077 output_info = (self.TagName, "block", block.getlocalId(), "output", i) |
1077 output_info = (self.TagName, "block", block.getlocalId(), "output", i) |
1078 output_name = variable_name |
1078 output_name = variable_name |
1079 self.Program += [(self.CurrentIndent, ()), |
1079 self.Program += [(self.CurrentIndent, ()), |
1103 if connections is not None: |
1103 if connections is not None: |
1104 expression = self.ComputeExpression(body, connections, executionOrderId > 0, inout_variables.has_key(parameter)) |
1104 expression = self.ComputeExpression(body, connections, executionOrderId > 0, inout_variables.has_key(parameter)) |
1105 if expression is not None: |
1105 if expression is not None: |
1106 vars.append([(parameter, input_info), |
1106 vars.append([(parameter, input_info), |
1107 (" := ", ())] + self.ExtractModifier(variable, expression, input_info)) |
1107 (" := ", ())] + self.ExtractModifier(variable, expression, input_info)) |
1108 self.Program += [(self.CurrentIndent, ()), |
1108 self.Program += [(self.CurrentIndent, ()), |
1109 (name, (self.TagName, "block", block.getlocalId(), "name")), |
1109 (name, (self.TagName, "block", block.getlocalId(), "name")), |
1110 ("(", ())] |
1110 ("(", ())] |
1111 self.Program += JoinList([(", ", ())], vars) |
1111 self.Program += JoinList([(", ", ())], vars) |
1112 self.Program += [(");\n", ())] |
1112 self.Program += [(");\n", ())] |
1113 |
1113 |
1114 if link is not None: |
1114 if link is not None: |
1115 connectionPoint = link.getposition()[-1] |
1115 connectionPoint = link.getposition()[-1] |
1116 output_parameter = link.getformalParameter() |
1116 output_parameter = link.getformalParameter() |
1117 else: |
1117 else: |
1118 connectionPoint = None |
1118 connectionPoint = None |
1119 output_parameter = None |
1119 output_parameter = None |
1120 |
1120 |
1121 output_variable = None |
1121 output_variable = None |
1122 output_idx = 0 |
1122 output_idx = 0 |
1123 if output_parameter is not None: |
1123 if output_parameter is not None: |
1124 if output_parameter in output_names or output_parameter == "ENO": |
1124 if output_parameter in output_names or output_parameter == "ENO": |
1125 for variable in output_variables: |
1125 for variable in output_variables: |
1128 if output_parameter != "ENO": |
1128 if output_parameter != "ENO": |
1129 output_idx = output_names.index(output_parameter) |
1129 output_idx = output_names.index(output_parameter) |
1130 else: |
1130 else: |
1131 for i, variable in enumerate(output_variables): |
1131 for i, variable in enumerate(output_variables): |
1132 blockPointx, blockPointy = variable.connectionPointOut.getrelPositionXY() |
1132 blockPointx, blockPointy = variable.connectionPointOut.getrelPositionXY() |
1133 if (connectionPoint is None or |
1133 if (connectionPoint is None or |
1134 block.getx() + blockPointx == connectionPoint.getx() and |
1134 block.getx() + blockPointx == connectionPoint.getx() and |
1135 block.gety() + blockPointy == connectionPoint.gety()): |
1135 block.gety() + blockPointy == connectionPoint.gety()): |
1136 output_variable = variable |
1136 output_variable = variable |
1137 output_parameter = variable.getformalParameter() |
1137 output_parameter = variable.getformalParameter() |
1138 output_idx = i |
1138 output_idx = i |
1139 |
1139 |
1140 if output_variable is not None: |
1140 if output_variable is not None: |
1141 if block_infos["type"] == "function": |
1141 if block_infos["type"] == "function": |
1142 output_info = (self.TagName, "block", block.getlocalId(), "output", output_idx) |
1142 output_info = (self.TagName, "block", block.getlocalId(), "output", output_idx) |
1143 if inout_variables.has_key(output_parameter): |
1143 if inout_variables.has_key(output_parameter): |
1144 output_value = inout_variables[output_parameter] |
1144 output_value = inout_variables[output_parameter] |
1147 output_name = "%s%d"%(type, block.getlocalId()) |
1147 output_name = "%s%d"%(type, block.getlocalId()) |
1148 else: |
1148 else: |
1149 output_name = "%s%d_%s"%(type, block.getlocalId(), output_parameter) |
1149 output_name = "%s%d_%s"%(type, block.getlocalId(), output_parameter) |
1150 output_value = [(output_name, output_info)] |
1150 output_value = [(output_name, output_info)] |
1151 return self.ExtractModifier(output_variable, output_value, output_info) |
1151 return self.ExtractModifier(output_variable, output_value, output_info) |
1152 |
1152 |
1153 if block_infos["type"] == "functionBlock": |
1153 if block_infos["type"] == "functionBlock": |
1154 output_info = (self.TagName, "block", block.getlocalId(), "output", output_idx) |
1154 output_info = (self.TagName, "block", block.getlocalId(), "output", output_idx) |
1155 output_name = self.ExtractModifier(output_variable, [("%s.%s"%(name, output_parameter), output_info)], output_info) |
1155 output_name = self.ExtractModifier(output_variable, [("%s.%s"%(name, output_parameter), output_info)], output_info) |
1156 if to_inout: |
1156 if to_inout: |
1157 variable_name = "%s_%s"%(name, output_parameter) |
1157 variable_name = "%s_%s"%(name, output_parameter) |
1166 self.Program += [(self.CurrentIndent, ()), |
1166 self.Program += [(self.CurrentIndent, ()), |
1167 ("%s := "%variable_name, ())] |
1167 ("%s := "%variable_name, ())] |
1168 self.Program += output_name |
1168 self.Program += output_name |
1169 self.Program += [(";\n", ())] |
1169 self.Program += [(";\n", ())] |
1170 return [(variable_name, ())] |
1170 return [(variable_name, ())] |
1171 return output_name |
1171 return output_name |
1172 if link is not None: |
1172 if link is not None: |
1173 if output_parameter is None: |
1173 if output_parameter is None: |
1174 output_parameter = "" |
1174 output_parameter = "" |
1175 if name: |
1175 if name: |
1176 blockname = "%s(%s)" % (name, type) |
1176 blockname = "%s(%s)" % (name, type) |
1289 if edge == "rising": |
1289 if edge == "rising": |
1290 return self.AddTrigger("R_TRIG", expression, var_info + ("rising",)) |
1290 return self.AddTrigger("R_TRIG", expression, var_info + ("rising",)) |
1291 elif edge == "falling": |
1291 elif edge == "falling": |
1292 return self.AddTrigger("F_TRIG", expression, var_info + ("falling",)) |
1292 return self.AddTrigger("F_TRIG", expression, var_info + ("falling",)) |
1293 return expression |
1293 return expression |
1294 |
1294 |
1295 def AddTrigger(self, edge, expression, var_info): |
1295 def AddTrigger(self, edge, expression, var_info): |
1296 if self.Interface[-1][0] != "VAR" or self.Interface[-1][1] is not None or self.Interface[-1][2]: |
1296 if self.Interface[-1][0] != "VAR" or self.Interface[-1][1] is not None or self.Interface[-1][2]: |
1297 self.Interface.append(("VAR", None, False, [])) |
1297 self.Interface.append(("VAR", None, False, [])) |
1298 i = 1 |
1298 i = 1 |
1299 name = "%s%d"%(edge, i) |
1299 name = "%s%d"%(edge, i) |
1300 while self.IsAlreadyDefined(name): |
1300 while self.IsAlreadyDefined(name): |
1301 i += 1 |
1301 i += 1 |
1302 name = "%s%d"%(edge, i) |
1302 name = "%s%d"%(edge, i) |
1303 self.Interface[-1][3].append((edge, name, None, None)) |
1303 self.Interface[-1][3].append((edge, name, None, None)) |
1304 self.Program += [(self.CurrentIndent, ()), (name, var_info), ("(CLK := ", ())] |
1304 self.Program += [(self.CurrentIndent, ()), (name, var_info), ("(CLK := ", ())] |
1305 self.Program += expression |
1305 self.Program += expression |
1306 self.Program += [(");\n", ())] |
1306 self.Program += [(");\n", ())] |
1307 return [("%s.Q"%name, var_info)] |
1307 return [("%s.Q"%name, var_info)] |
1308 |
1308 |
1309 def ExtractDivergenceInput(self, divergence, pou): |
1309 def ExtractDivergenceInput(self, divergence, pou): |
1310 connectionPointIn = divergence.getconnectionPointIn() |
1310 connectionPointIn = divergence.getconnectionPointIn() |
1311 if connectionPointIn is not None: |
1311 if connectionPointIn is not None: |
1312 connections = connectionPointIn.getconnections() |
1312 connections = connectionPointIn.getconnections() |
1313 if connections is not None and len(connections) == 1: |
1313 if connections is not None and len(connections) == 1: |
1333 def GenerateSFCStep(self, step, pou): |
1333 def GenerateSFCStep(self, step, pou): |
1334 step_name = step.getname() |
1334 step_name = step.getname() |
1335 if step_name not in self.SFCNetworks["Steps"].keys(): |
1335 if step_name not in self.SFCNetworks["Steps"].keys(): |
1336 if step.getinitialStep(): |
1336 if step.getinitialStep(): |
1337 self.InitialSteps.append(step_name) |
1337 self.InitialSteps.append(step_name) |
1338 step_infos = {"id" : step.getlocalId(), |
1338 step_infos = {"id" : step.getlocalId(), |
1339 "initial" : step.getinitialStep(), |
1339 "initial" : step.getinitialStep(), |
1340 "transitions" : [], |
1340 "transitions" : [], |
1341 "actions" : []} |
1341 "actions" : []} |
1342 self.SFCNetworks["Steps"][step_name] = step_infos |
1342 self.SFCNetworks["Steps"][step_name] = step_infos |
1343 if step.connectionPointIn is not None: |
1343 if step.connectionPointIn is not None: |
1344 instances = [] |
1344 instances = [] |
1345 connections = step.connectionPointIn.getconnections() |
1345 connections = step.connectionPointIn.getconnections() |
1363 for instance in instances: |
1363 for instance in instances: |
1364 self.GenerateSFCTransition(instance, pou) |
1364 self.GenerateSFCTransition(instance, pou) |
1365 if instance in self.SFCNetworks["Transitions"].keys(): |
1365 if instance in self.SFCNetworks["Transitions"].keys(): |
1366 target_info = (self.TagName, "transition", instance.getlocalId(), "to", step_infos["id"]) |
1366 target_info = (self.TagName, "transition", instance.getlocalId(), "to", step_infos["id"]) |
1367 self.SFCNetworks["Transitions"][instance]["to"].append([(step_name, target_info)]) |
1367 self.SFCNetworks["Transitions"][instance]["to"].append([(step_name, target_info)]) |
1368 |
1368 |
1369 def GenerateSFCJump(self, jump, pou): |
1369 def GenerateSFCJump(self, jump, pou): |
1370 jump_target = jump.gettargetName() |
1370 jump_target = jump.gettargetName() |
1371 if jump.connectionPointIn is not None: |
1371 if jump.connectionPointIn is not None: |
1372 instances = [] |
1372 instances = [] |
1373 connections = jump.connectionPointIn.getconnections() |
1373 connections = jump.connectionPointIn.getconnections() |
1391 for instance in instances: |
1391 for instance in instances: |
1392 self.GenerateSFCTransition(instance, pou) |
1392 self.GenerateSFCTransition(instance, pou) |
1393 if instance in self.SFCNetworks["Transitions"].keys(): |
1393 if instance in self.SFCNetworks["Transitions"].keys(): |
1394 target_info = (self.TagName, "jump", jump.getlocalId(), "target") |
1394 target_info = (self.TagName, "jump", jump.getlocalId(), "target") |
1395 self.SFCNetworks["Transitions"][instance]["to"].append([(jump_target, target_info)]) |
1395 self.SFCNetworks["Transitions"][instance]["to"].append([(jump_target, target_info)]) |
1396 |
1396 |
1397 def GenerateSFCStepActions(self, actionBlock, pou): |
1397 def GenerateSFCStepActions(self, actionBlock, pou): |
1398 connections = actionBlock.connectionPointIn.getconnections() |
1398 connections = actionBlock.connectionPointIn.getconnections() |
1399 if connections is not None and len(connections) == 1: |
1399 if connections is not None and len(connections) == 1: |
1400 stepLocalId = connections[0].getrefLocalId() |
1400 stepLocalId = connections[0].getrefLocalId() |
1401 body = pou.getbody() |
1401 body = pou.getbody() |
1405 self.GenerateSFCStep(step, pou) |
1405 self.GenerateSFCStep(step, pou) |
1406 step_name = step.getname() |
1406 step_name = step.getname() |
1407 if step_name in self.SFCNetworks["Steps"].keys(): |
1407 if step_name in self.SFCNetworks["Steps"].keys(): |
1408 actions = actionBlock.getactions() |
1408 actions = actionBlock.getactions() |
1409 for i, action in enumerate(actions): |
1409 for i, action in enumerate(actions): |
1410 action_infos = {"id" : actionBlock.getlocalId(), |
1410 action_infos = {"id" : actionBlock.getlocalId(), |
1411 "qualifier" : action["qualifier"], |
1411 "qualifier" : action["qualifier"], |
1412 "content" : action["value"], |
1412 "content" : action["value"], |
1413 "num" : i} |
1413 "num" : i} |
1414 if "duration" in action: |
1414 if "duration" in action: |
1415 action_infos["duration"] = action["duration"] |
1415 action_infos["duration"] = action["duration"] |
1416 if "indicator" in action: |
1416 if "indicator" in action: |
1417 action_infos["indicator"] = action["indicator"] |
1417 action_infos["indicator"] = action["indicator"] |
1418 if action["type"] == "reference": |
1418 if action["type"] == "reference": |
1419 self.GenerateSFCAction(action["value"], pou) |
1419 self.GenerateSFCAction(action["value"], pou) |
1420 else: |
1420 else: |
1421 action_name = "%s_INLINE%d"%(step_name.upper(), self.GetActionNumber()) |
1421 action_name = "%s_INLINE%d"%(step_name.upper(), self.GetActionNumber()) |
1422 self.SFCNetworks["Actions"][action_name] = ([(self.CurrentIndent, ()), |
1422 self.SFCNetworks["Actions"][action_name] = ([(self.CurrentIndent, ()), |
1423 (action["value"], (self.TagName, "action_block", action_infos["id"], "action", i, "inline")), |
1423 (action["value"], (self.TagName, "action_block", action_infos["id"], "action", i, "inline")), |
1424 ("\n", ())], ()) |
1424 ("\n", ())], ()) |
1425 action_infos["content"] = action_name |
1425 action_infos["content"] = action_name |
1426 self.SFCNetworks["Steps"][step_name]["actions"].append(action_infos) |
1426 self.SFCNetworks["Steps"][step_name]["actions"].append(action_infos) |
1427 |
1427 |
1428 def GenerateSFCAction(self, action_name, pou): |
1428 def GenerateSFCAction(self, action_name, pou): |
1429 if action_name not in self.SFCNetworks["Actions"].keys(): |
1429 if action_name not in self.SFCNetworks["Actions"].keys(): |
1430 actionContent = pou.getaction(action_name) |
1430 actionContent = pou.getaction(action_name) |
1431 if actionContent is not None: |
1431 if actionContent is not None: |
1432 previous_tagname = self.TagName |
1432 previous_tagname = self.TagName |
1433 self.TagName = self.ParentGenerator.Controler.ComputePouActionName(self.Name, action_name) |
1433 self.TagName = self.ParentGenerator.Controler.ComputePouActionName(self.Name, action_name) |
1434 self.ComputeProgram(actionContent) |
1434 self.ComputeProgram(actionContent) |
1435 self.SFCNetworks["Actions"][action_name] = (self.Program, (self.TagName, "name")) |
1435 self.SFCNetworks["Actions"][action_name] = (self.Program, (self.TagName, "name")) |
1436 self.Program = [] |
1436 self.Program = [] |
1437 self.TagName = previous_tagname |
1437 self.TagName = previous_tagname |
1438 |
1438 |
1439 def GenerateSFCTransition(self, transition, pou): |
1439 def GenerateSFCTransition(self, transition, pou): |
1440 if transition not in self.SFCNetworks["Transitions"].keys(): |
1440 if transition not in self.SFCNetworks["Transitions"].keys(): |
1441 steps = [] |
1441 steps = [] |
1442 connections = transition.connectionPointIn.getconnections() |
1442 connections = transition.connectionPointIn.getconnections() |
1443 if connections is not None and len(connections) == 1: |
1443 if connections is not None and len(connections) == 1: |
1455 steps.append(step) |
1455 steps.append(step) |
1456 elif isinstance(step, SimultaneousConvergenceClass): |
1456 elif isinstance(step, SimultaneousConvergenceClass): |
1457 steps.extend(self.ExtractConvergenceInputs(step, pou)) |
1457 steps.extend(self.ExtractConvergenceInputs(step, pou)) |
1458 elif isinstance(instance, SimultaneousConvergenceClass): |
1458 elif isinstance(instance, SimultaneousConvergenceClass): |
1459 steps.extend(self.ExtractConvergenceInputs(instance, pou)) |
1459 steps.extend(self.ExtractConvergenceInputs(instance, pou)) |
1460 transition_infos = {"id" : transition.getlocalId(), |
1460 transition_infos = {"id" : transition.getlocalId(), |
1461 "priority": transition.getpriority(), |
1461 "priority": transition.getpriority(), |
1462 "from": [], |
1462 "from": [], |
1463 "to" : [], |
1463 "to" : [], |
1464 "content": []} |
1464 "content": []} |
1465 self.SFCNetworks["Transitions"][transition] = transition_infos |
1465 self.SFCNetworks["Transitions"][transition] = transition_infos |
1466 transitionValues = transition.getconditionContent() |
1466 transitionValues = transition.getconditionContent() |
1467 if transitionValues["type"] == "inline": |
1467 if transitionValues["type"] == "inline": |
1544 self.Program += [("%sEND_STEP\n\n"%self.CurrentIndent, ())] |
1544 self.Program += [("%sEND_STEP\n\n"%self.CurrentIndent, ())] |
1545 for action in actions: |
1545 for action in actions: |
1546 self.ComputeSFCAction(action) |
1546 self.ComputeSFCAction(action) |
1547 for transition in step_infos["transitions"]: |
1547 for transition in step_infos["transitions"]: |
1548 self.ComputeSFCTransition(transition) |
1548 self.ComputeSFCTransition(transition) |
1549 |
1549 |
1550 def ComputeSFCAction(self, action_name): |
1550 def ComputeSFCAction(self, action_name): |
1551 if action_name in self.SFCNetworks["Actions"].keys(): |
1551 if action_name in self.SFCNetworks["Actions"].keys(): |
1552 action_content, action_info = self.SFCNetworks["Actions"].pop(action_name) |
1552 action_content, action_info = self.SFCNetworks["Actions"].pop(action_name) |
1553 self.Program += [("%sACTION "%self.CurrentIndent, ()), |
1553 self.Program += [("%sACTION "%self.CurrentIndent, ()), |
1554 (action_name, action_info), |
1554 (action_name, action_info), |
1555 (":\n", ())] |
1555 (":\n", ())] |
1556 self.Program += action_content |
1556 self.Program += action_content |
1557 self.Program += [("%sEND_ACTION\n\n"%self.CurrentIndent, ())] |
1557 self.Program += [("%sEND_ACTION\n\n"%self.CurrentIndent, ())] |
1558 |
1558 |
1559 def ComputeSFCTransition(self, transition): |
1559 def ComputeSFCTransition(self, transition): |
1560 if transition in self.SFCNetworks["Transitions"].keys(): |
1560 if transition in self.SFCNetworks["Transitions"].keys(): |
1561 transition_infos = self.SFCNetworks["Transitions"].pop(transition) |
1561 transition_infos = self.SFCNetworks["Transitions"].pop(transition) |
1562 self.Program += [("%sTRANSITION"%self.CurrentIndent, ())] |
1562 self.Program += [("%sTRANSITION"%self.CurrentIndent, ())] |
1563 if transition_infos["priority"] != None: |
1563 if transition_infos["priority"] != None: |
1584 raise PLCGenException, _("Transition with content \"%s\" not connected to a next step in \"%s\" POU")%(transition_infos["content"], self.Name) |
1584 raise PLCGenException, _("Transition with content \"%s\" not connected to a next step in \"%s\" POU")%(transition_infos["content"], self.Name) |
1585 self.Program += transition_infos["content"] |
1585 self.Program += transition_infos["content"] |
1586 self.Program += [("%sEND_TRANSITION\n\n"%self.CurrentIndent, ())] |
1586 self.Program += [("%sEND_TRANSITION\n\n"%self.CurrentIndent, ())] |
1587 for [(step_name, step_infos)] in transition_infos["to"]: |
1587 for [(step_name, step_infos)] in transition_infos["to"]: |
1588 self.ComputeSFCStep(step_name) |
1588 self.ComputeSFCStep(step_name) |
1589 |
1589 |
1590 def GenerateProgram(self, pou): |
1590 def GenerateProgram(self, pou): |
1591 self.ComputeInterface(pou) |
1591 self.ComputeInterface(pou) |
1592 self.ComputeConnectionTypes(pou) |
1592 self.ComputeConnectionTypes(pou) |
1593 self.ComputeProgram(pou) |
1593 self.ComputeProgram(pou) |
1594 |
1594 |
1595 program = [("%s "%self.Type, ()), |
1595 program = [("%s "%self.Type, ()), |
1596 (self.Name, (self.TagName, "name"))] |
1596 (self.Name, (self.TagName, "name"))] |
1597 if self.ReturnType is not None: |
1597 if self.ReturnType is not None: |
1598 program += [(" : ", ()), |
1598 program += [(" : ", ()), |
1599 (self.ReturnType, (self.TagName, "return"))] |
1599 (self.ReturnType, (self.TagName, "return"))] |