51 compute += "%s%s\n"%(indent, line) |
52 compute += "%s%s\n"%(indent, line) |
52 else: |
53 else: |
53 compute += "\n" |
54 compute += "\n" |
54 return compute |
55 return compute |
55 |
56 |
|
57 def GenerateDataType(datatype_name): |
|
58 if not datatypeComputed.get(datatype_name, True): |
|
59 datatypeComputed[datatype_name] = True |
|
60 global currentProject, currentProgram |
|
61 datatype = currentProject.getDataType(datatype_name) |
|
62 datatype_def = " %s :"%datatype.getName() |
|
63 basetype_content = datatype.baseType.getContent() |
|
64 if basetype_content["value"] is None: |
|
65 datatype_def += " %s"%basetype_content["name"] |
|
66 elif basetype_content["name"] == "derived": |
|
67 basetype_name = basetype_content["value"].getName() |
|
68 GenerateDataType(basetype_name) |
|
69 datatype_def += " %s"%basetype_name |
|
70 elif basetype_content["name"] in ["subrangeSigned", "subrangeUnsigned"]: |
|
71 base_type = basetype_content["value"].baseType.getContent() |
|
72 if base_type["value"] is None: |
|
73 basetype_name = base_type["name"] |
|
74 else: |
|
75 basetype_name = base_type["value"].getName() |
|
76 GenerateDataType(basetype_name) |
|
77 min_value = basetype_content["value"].range.getLower() |
|
78 max_value = basetype_content["value"].range.getUpper() |
|
79 datatype_def += " %s (%d..%d)"%(basetype_name, min_value, max_value) |
|
80 elif basetype_content["name"] == "enum": |
|
81 values = [] |
|
82 for value in basetype_content["value"].values.getValue(): |
|
83 values.append(value.getName()) |
|
84 datatype_def += " (%s)"%", ".join(values) |
|
85 elif basetype_content["name"] == "array": |
|
86 base_type = basetype_content["value"].baseType.getContent() |
|
87 if base_type["value"] is None: |
|
88 basetype_name = base_type["name"] |
|
89 else: |
|
90 basetype_name = base_type["value"].getName() |
|
91 GenerateDataType(basetype_name) |
|
92 dimensions = [] |
|
93 for dimension in basetype_content["value"].getDimension(): |
|
94 dimensions.append("0..%d"%(dimension.getUpper() - 1)) |
|
95 datatype_def += " ARRAY [%s] OF %s"%(",".join(dimensions), basetype_name) |
|
96 if datatype.initialValue is not None: |
|
97 datatype_def += " := %s"%str(datatype.initialValue.getValue()) |
|
98 currentProgram += "%s;\n"%datatype_def |
|
99 |
56 def GeneratePouProgram(pou_name): |
100 def GeneratePouProgram(pou_name): |
57 if not pouComputed.get(pou_name, True): |
101 if not pouComputed.get(pou_name, True): |
58 pouComputed[pou_name] = True |
102 pouComputed[pou_name] = True |
59 global currentProject, currentProgram |
103 global currentProject, currentProgram |
60 pou = currentProject.getPou(pou_name) |
104 pou = currentProject.getPou(pou_name) |
185 for var_type, var_name, var_address, var_initial in vars: |
241 for var_type, var_name, var_address, var_initial in vars: |
186 if name == var_name: |
242 if name == var_name: |
187 return True |
243 return True |
188 return False |
244 return False |
189 |
245 |
|
246 def GetVariableType(self, name): |
|
247 for list_type, retain, constant, located, vars in self.Interface: |
|
248 for var_type, var_name, var_address, var_initial in vars: |
|
249 if name == var_name: |
|
250 return var_type |
|
251 return None |
|
252 |
|
253 def GetConnectedConnection(self, connection, body): |
|
254 links = connection.getConnections() |
|
255 if links and len(links) == 1: |
|
256 return self.GetLinkedConnection(links[0], body) |
|
257 return None |
|
258 |
|
259 def GetLinkedConnection(self, link, body): |
|
260 parameter = link.getFormalParameter() |
|
261 instance = body.getContentInstance(link.getRefLocalId()) |
|
262 if isinstance(instance, (plcopen.inVariable, plcopen.inOutVariable, plcopen.continuation, plcopen.contact, plcopen.coil)): |
|
263 return instance.connectionPointOut |
|
264 elif isinstance(instance, plcopen.block): |
|
265 outputvariables = instance.outputVariables.getVariable() |
|
266 if len(outputvariables) == 1: |
|
267 return outputvariables[0].connectionPointOut |
|
268 elif parameter: |
|
269 for variable in outputvariables: |
|
270 if variable.getFormalParameter() == parameter: |
|
271 return variable.connectionPointOut |
|
272 else: |
|
273 point = link.getPosition()[-1] |
|
274 for variable in outputvariables: |
|
275 relposition = variable.connectionPointOut.getRelPosition() |
|
276 blockposition = instance.getPosition() |
|
277 if point.x == blockposition.x + relposition[0] and point.y == blockposition.y + relposition[1]: |
|
278 return variable.connectionPointOut |
|
279 elif isinstance(instance, plcopen.leftPowerRail): |
|
280 outputconnections = instance.getConnectionPointOut() |
|
281 if len(outputconnections) == 1: |
|
282 return outputconnections[0] |
|
283 else: |
|
284 point = link.getPosition()[-1] |
|
285 for outputconnection in outputconnections: |
|
286 relposition = outputconnection.getRelPosition() |
|
287 powerrailposition = instance.getPosition() |
|
288 if point.x == powerrailposition.x + relposition[0] and point.y == powerrailposition.y + relposition[1]: |
|
289 return outputconnection |
|
290 return None |
|
291 |
|
292 def ExtractRelatedConnections(self, connection): |
|
293 for i, related in enumerate(self.RelatedConnections): |
|
294 if connection in related: |
|
295 return self.RelatedConnections.pop(i) |
|
296 return [connection] |
|
297 |
190 def GenerateInterface(self, interface): |
298 def GenerateInterface(self, interface): |
191 if self.Type == "FUNCTION": |
299 if self.Type == "FUNCTION": |
192 self.ReturnType = interface.getReturnType().getValue() |
300 returntype_content = interface.getReturnType().getContent() |
|
301 if returntype_content["value"] is None: |
|
302 self.ReturnType = returntype_content["name"] |
|
303 else: |
|
304 self.ReturnType = returntype_content["value"].getName() |
193 for varlist in interface.getContent(): |
305 for varlist in interface.getContent(): |
194 variables = [] |
306 variables = [] |
195 located = False |
307 located = False |
196 for var in varlist["value"].getVariable(): |
308 for var in varlist["value"].getVariable(): |
197 type = var.getType().getValue() |
309 vartype_content = var.getType().getContent() |
198 if not isinstance(type, (StringType, UnicodeType)): |
310 if vartype_content["value"] is None: |
199 type = type.getName() |
|
200 GeneratePouProgram(type) |
|
201 blocktype = GetBlockType(type) |
|
202 if blocktype: |
|
203 variables.extend(blocktype["initialise"](type, var.getName())) |
|
204 located = False |
|
205 else: |
|
206 initial = var.getInitialValue() |
311 initial = var.getInitialValue() |
207 if initial: |
312 if initial: |
208 initial_value = initial.getValue() |
313 initial_value = initial.getValue() |
209 else: |
314 else: |
210 initial_value = None |
315 initial_value = None |
211 address = var.getAddress() |
316 address = var.getAddress() |
212 if address: |
317 if address: |
213 located = True |
318 located = True |
214 variables.append((type, var.getName(), address, initial_value)) |
319 variables.append((vartype_content["name"], var.getName(), address, initial_value)) |
|
320 else: |
|
321 var_type = vartype_content["value"].getName() |
|
322 GeneratePouProgram(var_type) |
|
323 blocktype = GetBlockType(var_type) |
|
324 if blocktype is not None: |
|
325 variables.extend(blocktype["initialise"](var_type, var.getName())) |
|
326 located = False |
|
327 else: |
|
328 initial = var.getInitialValue() |
|
329 if initial: |
|
330 initial_value = initial.getValue() |
|
331 else: |
|
332 initial_value = None |
|
333 address = var.getAddress() |
|
334 if address: |
|
335 located = True |
|
336 variables.append((vartype_content["value"].getName(), var.getName(), address, initial_value)) |
215 if len(variables) > 0: |
337 if len(variables) > 0: |
216 self.Interface.append((varTypeNames[varlist["name"]], varlist["value"].getRetain(), |
338 self.Interface.append((varTypeNames[varlist["name"]], varlist["value"].getRetain(), |
217 varlist["value"].getConstant(), located, variables)) |
339 varlist["value"].getConstant(), located, variables)) |
218 |
340 |
|
341 def GenerateConnectionTypes(self, pou): |
|
342 body = pou.getBody() |
|
343 body_content = body.getContent() |
|
344 body_type = body_content["name"] |
|
345 if body_type in ["FBD", "LD", "SFC"]: |
|
346 for instance in body.getContentInstances(): |
|
347 if isinstance(instance, (plcopen.inVariable, plcopen.outVariable, plcopen.inOutVariable)): |
|
348 expression = instance.getExpression() |
|
349 var_type = self.GetVariableType(expression) |
|
350 if expression == pou.getName(): |
|
351 returntype_content = pou.interface.getReturnType().getContent() |
|
352 if returntype_content["value"] is None: |
|
353 var_type = returntype_content["name"] |
|
354 else: |
|
355 var_type = returntype_content["value"].getName() |
|
356 elif var_type is None: |
|
357 var_type = expression.split("#")[0] |
|
358 if isinstance(instance, (plcopen.inVariable, plcopen.inOutVariable)): |
|
359 self.ConnectionTypes[instance.connectionPointOut] = var_type |
|
360 if isinstance(instance, (plcopen.outVariable, plcopen.inOutVariable)): |
|
361 self.ConnectionTypes[instance.connectionPointIn] = var_type |
|
362 connected = self.GetConnectedConnection(instance.connectionPointIn, body) |
|
363 if connected and connected not in self.ConnectionTypes: |
|
364 for connection in self.ExtractRelatedConnections(connected): |
|
365 self.ConnectionTypes[connection] = var_type |
|
366 elif isinstance(instance, (plcopen.contact, plcopen.coil)): |
|
367 self.ConnectionTypes[instance.connectionPointOut] = "BOOL" |
|
368 self.ConnectionTypes[instance.connectionPointIn] = "BOOL" |
|
369 connected = self.GetConnectedConnection(instance.connectionPointIn, body) |
|
370 if connected and connected not in self.ConnectionTypes: |
|
371 for connection in self.ExtractRelatedConnections(connected): |
|
372 self.ConnectionTypes[connection] = "BOOL" |
|
373 elif isinstance(instance, plcopen.leftPowerRail): |
|
374 for connection in instance.getConnectionPointOut(): |
|
375 self.ConnectionTypes[connection] = "BOOL" |
|
376 elif isinstance(instance, plcopen.rightPowerRail): |
|
377 for connection in instance.getConnectionPointIn(): |
|
378 self.ConnectionTypes[connection] = "BOOL" |
|
379 connected = self.GetConnectedConnection(connection, body) |
|
380 if connected and connected not in self.ConnectionTypes: |
|
381 for connection in self.ExtractRelatedConnections(connected): |
|
382 self.ConnectionTypes[connection] = "BOOL" |
|
383 elif isinstance(instance, plcopen.transition): |
|
384 content = instance.condition.getContent() |
|
385 if content["name"] == "connection" and len(content["value"]) == 1: |
|
386 connected = self.GetLinkedConnection(content["value"][0], body) |
|
387 if connected and connected not in self.ConnectionTypes: |
|
388 for connection in self.ExtractRelatedConnections(connected): |
|
389 self.ConnectionTypes[connection] = "BOOL" |
|
390 elif isinstance(instance, plcopen.block): |
|
391 block_infos = GetBlockType(instance.getTypeName()) |
|
392 undefined = {} |
|
393 for variable in instance.outputVariables.getVariable(): |
|
394 output_name = variable.getFormalParameter() |
|
395 for oname, otype, oqualifier in block_infos["outputs"]: |
|
396 if output_name == oname and variable.connectionPointOut not in self.ConnectionTypes: |
|
397 if otype.startswith("ANY"): |
|
398 if otype not in undefined: |
|
399 undefined[otype] = [] |
|
400 undefined[otype].append(variable.connectionPointOut) |
|
401 else: |
|
402 for connection in self.ExtractRelatedConnections(variable.connectionPointOut): |
|
403 self.ConnectionTypes[connection] = otype |
|
404 for variable in instance.inputVariables.getVariable(): |
|
405 input_name = variable.getFormalParameter() |
|
406 for iname, itype, iqualifier in block_infos["inputs"]: |
|
407 if input_name == iname: |
|
408 connected = self.GetConnectedConnection(variable.connectionPointIn, body) |
|
409 if itype.startswith("ANY"): |
|
410 if itype not in undefined: |
|
411 undefined[itype] = [] |
|
412 undefined[itype].append(variable.connectionPointIn) |
|
413 if connected: |
|
414 undefined[itype].append(connected) |
|
415 else: |
|
416 self.ConnectionTypes[variable.connectionPointIn] = itype |
|
417 if connected and connected not in self.ConnectionTypes: |
|
418 for connection in self.ExtractRelatedConnections(connected): |
|
419 self.ConnectionTypes[connection] = itype |
|
420 for var_type, connections in undefined.items(): |
|
421 related = [] |
|
422 for connection in connections: |
|
423 if connection in self.ConnectionTypes: |
|
424 var_type = self.ConnectionTypes[connection] |
|
425 else: |
|
426 related.extend(self.ExtractRelatedConnections(connection)) |
|
427 if var_type.startswith("ANY") and len(related) > 0: |
|
428 self.RelatedConnections.append(related) |
|
429 else: |
|
430 for connection in related: |
|
431 self.ConnectionTypes[connection] = var_type |
|
432 |
219 def GenerateProgram(self, pou): |
433 def GenerateProgram(self, pou): |
220 body = pou.getBody() |
434 body = pou.getBody() |
221 body_content = body.getContent() |
435 body_content = body.getContent() |
222 body_type = body_content["name"] |
436 body_type = body_content["name"] |
223 if body_type in ["IL","ST"]: |
437 if body_type in ["IL","ST"]: |
224 self.Program = ReIndentText(body_content["value"].getText(), 2) |
438 self.Program = ReIndentText(body_content["value"].getText(), 2) |
225 elif body_type == "FBD": |
439 elif body_type == "FBD": |
|
440 orderedInstances = [] |
|
441 otherInstances = [] |
226 for instance in body.getContentInstances(): |
442 for instance in body.getContentInstances(): |
|
443 if isinstance(instance, (plcopen.outVariable, plcopen.inOutVariable, plcopen.block)): |
|
444 executionOrderId = instance.getExecutionOrderId() |
|
445 if executionOrderId > 0: |
|
446 orderedInstances.append((executionOrderId, instance)) |
|
447 else: |
|
448 otherInstances.append(instance) |
|
449 elif isinstance(instance, plcopen.connector): |
|
450 otherInstances.append(instance) |
|
451 orderedInstances.sort() |
|
452 instances = [instance for (executionOrderId, instance) in orderedInstances] + otherInstances |
|
453 for instance in instances: |
227 if isinstance(instance, (plcopen.outVariable, plcopen.inOutVariable)): |
454 if isinstance(instance, (plcopen.outVariable, plcopen.inOutVariable)): |
228 var = instance.getExpression() |
455 var = instance.getExpression() |
229 connections = instance.connectionPointIn.getConnections() |
456 connections = instance.connectionPointIn.getConnections() |
230 if connections and len(connections) == 1: |
457 if connections and len(connections) == 1: |
231 expression = self.ComputeFBDExpression(body, connections[0]) |
458 expression = self.ComputeFBDExpression(body, connections[0]) |
232 self.Program += " %s := %s;\n"%(var, expression) |
459 self.Program += " %s := %s;\n"%(var, expression) |
233 elif isinstance(instance, plcopen.block): |
460 elif isinstance(instance, plcopen.block): |
234 type = instance.getTypeName() |
461 block_type = instance.getTypeName() |
235 block_infos = GetBlockType(type) |
462 self.GeneratePouProgram(block_type) |
|
463 block_infos = GetBlockType(block_type) |
236 block_infos["generate"](self, instance, body, None) |
464 block_infos["generate"](self, instance, body, None) |
237 elif isinstance(instance, plcopen.connector): |
465 elif isinstance(instance, plcopen.connector): |
238 connector = instance.getName() |
466 connector = instance.getName() |
239 if self.ComputedConnectors.get(connector, None): |
467 if self.ComputedConnectors.get(connector, None): |
240 continue |
468 continue |
269 self.SFCNetworks["Actions"][action_name] = ReIndentText(self.SFCComputedBlocks, 4) |
497 self.SFCNetworks["Actions"][action_name] = ReIndentText(self.SFCComputedBlocks, 4) |
270 self.Program = "" |
498 self.Program = "" |
271 for initialstep in self.InitialSteps: |
499 for initialstep in self.InitialSteps: |
272 self.ComputeSFCStep(initialstep) |
500 self.ComputeSFCStep(initialstep) |
273 |
501 |
274 def ComputeFBDExpression(self, body, link): |
502 def ComputeFBDExpression(self, body, link, order = False): |
275 localid = link.getRefLocalId() |
503 localid = link.getRefLocalId() |
276 instance = body.getContentInstance(localid) |
504 instance = body.getContentInstance(localid) |
277 if isinstance(instance, (plcopen.inVariable, plcopen.inOutVariable)): |
505 if isinstance(instance, (plcopen.inVariable, plcopen.inOutVariable)): |
278 return instance.getExpression() |
506 return instance.getExpression() |
279 elif isinstance(instance, plcopen.block): |
507 elif isinstance(instance, plcopen.block): |
280 block_type = instance.getTypeName() |
508 block_type = instance.getTypeName() |
|
509 self.GeneratePouProgram(block_type) |
281 block_infos = GetBlockType(block_type) |
510 block_infos = GetBlockType(block_type) |
282 return block_infos["generate"](self, instance, body, link) |
511 return block_infos["generate"](self, instance, body, link, order) |
283 elif isinstance(instance, plcopen.continuation): |
512 elif isinstance(instance, plcopen.continuation): |
284 name = instance.getName() |
513 name = instance.getName() |
285 computed_value = self.ComputedConnectors.get(name, None) |
514 computed_value = self.ComputedConnectors.get(name, None) |
286 if computed_value != None: |
515 if computed_value != None: |
287 return computed_value |
516 return computed_value |
288 for tmp_instance in body.getContentInstances(): |
517 for tmp_instance in body.getContentInstances(): |
289 if isinstance(tmp_instance, plcopen.connector): |
518 if isinstance(tmp_instance, plcopen.connector): |
290 if tmp_instance.getName() == name: |
519 if tmp_instance.getName() == name: |
291 connections = tmp_instance.connectionPointIn.getConnections() |
520 connections = tmp_instance.connectionPointIn.getConnections() |
292 if connections and len(connections) == 1: |
521 if connections and len(connections) == 1: |
293 expression = self.ComputeFBDExpression(body, connections[0]) |
522 expression = self.ComputeFBDExpression(body, connections[0], order) |
294 self.ComputedConnectors[name] = expression |
523 self.ComputedConnectors[name] = expression |
295 return expression |
524 return expression |
296 raise ValueError, "No connector found" |
525 raise ValueError, "No connector found" |
297 |
526 |
298 def GenerateLDPaths(self, connections, body): |
527 def GenerateLDPaths(self, connections, body): |