etisserant@0: #!/usr/bin/env python etisserant@0: # -*- coding: utf-8 -*- etisserant@0: etisserant@0: #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor etisserant@0: #based on the plcopen standard. etisserant@0: # lbessard@58: #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD etisserant@0: # etisserant@0: #See COPYING file for copyrights details. etisserant@0: # etisserant@0: #This library is free software; you can redistribute it and/or etisserant@5: #modify it under the terms of the GNU General Public etisserant@0: #License as published by the Free Software Foundation; either etisserant@0: #version 2.1 of the License, or (at your option) any later version. etisserant@0: # etisserant@0: #This library is distributed in the hope that it will be useful, etisserant@0: #but WITHOUT ANY WARRANTY; without even the implied warranty of etisserant@0: #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU lbessard@58: #General Public License for more details. etisserant@0: # etisserant@5: #You should have received a copy of the GNU General Public etisserant@0: #License along with this library; if not, write to the Free Software etisserant@0: #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA etisserant@0: etisserant@0: from plcopen import plcopen etisserant@0: from plcopen.structures import * etisserant@0: from types import * etisserant@0: etisserant@0: varTypeNames = {"localVars" : "VAR", "tempVars" : "VAR_TEMP", "inputVars" : "VAR_INPUT", etisserant@0: "outputVars" : "VAR_OUTPUT", "inOutVars" : "VAR_IN_OUT", "externalVars" : "VAR_EXTERNAL", etisserant@0: "globalVars" : "VAR_GLOBAL", "accessVars" : "VAR_ACCESS"} lbessard@1: lbessard@6: pouTypeNames = {"function" : "FUNCTION", "functionBlock" : "FUNCTION_BLOCK", "program" : "PROGRAM"} lbessard@6: lbessard@1: def ReIndentText(text, nb_spaces): lbessard@1: compute = "" lbessard@1: lines = text.splitlines() lbessard@1: if len(lines) > 0: lbessard@1: spaces = 0 lbessard@1: while lines[0][spaces] == " ": lbessard@1: spaces += 1 lbessard@1: indent = "" lbessard@1: for i in xrange(spaces, nb_spaces): lbessard@1: indent += " " lbessard@1: for line in lines: lbessard@2: if line != "": lbessard@2: compute += "%s%s\n"%(indent, line) lbessard@2: else: lbessard@2: compute += "\n" lbessard@1: return compute lbessard@1: etisserant@0: """ etisserant@0: Module implementing methods for generating PLC programs in ST or IL etisserant@0: """ etisserant@0: etisserant@0: class PouProgram: etisserant@0: etisserant@0: def __init__(self, name, type): etisserant@0: self.Name = name etisserant@0: self.Type = type lbessard@1: self.ReturnType = None lbessard@1: self.Interface = [] lbessard@1: self.InitialSteps = [] lbessard@68: self.BlockComputed = {} lbessard@70: self.ComputedBlocks = "" lbessard@1: self.SFCNetworks = {"Steps":{}, "Transitions":{}, "Actions":{}} lbessard@46: self.ActionNumber = 0 etisserant@0: self.Program = "" etisserant@0: lbessard@46: def GetActionNumber(self): lbessard@46: self.ActionNumber += 1 lbessard@46: return self.ActionNumber lbessard@46: lbessard@1: def IsAlreadyDefined(self, name): lbessard@33: for list_type, retain, constant, located, vars in self.Interface: lbessard@30: for var_type, var_name, var_address, var_initial in vars: lbessard@1: if name == var_name: lbessard@1: return True lbessard@1: return False lbessard@1: etisserant@0: def GenerateInterface(self, interface): etisserant@0: if self.Type == "FUNCTION": lbessard@1: self.ReturnType = interface.getReturnType().getValue() etisserant@0: for varlist in interface.getContent(): lbessard@1: variables = [] lbessard@33: located = False etisserant@0: for var in varlist["value"].getVariable(): etisserant@0: type = var.getType().getValue() lbessard@68: if not isinstance(type, (StringType, UnicodeType)): lbessard@68: type = type.getName() lbessard@28: initial = var.getInitialValue() lbessard@28: if initial: lbessard@28: initial_value = initial.getValue() lbessard@28: else: lbessard@28: initial_value = None lbessard@30: address = var.getAddress() lbessard@68: if address: lbessard@33: located = True lbessard@30: variables.append((type, var.getName(), address, initial_value)) lbessard@1: self.Interface.append((varTypeNames[varlist["name"]], varlist["value"].getRetain(), lbessard@33: varlist["value"].getConstant(), located, variables)) etisserant@0: etisserant@0: def GenerateProgram(self, pou): etisserant@0: body = pou.getBody() etisserant@0: body_content = body.getContent() etisserant@0: body_type = body_content["name"] etisserant@0: if body_type in ["IL","ST"]: lbessard@1: self.Program = ReIndentText(body_content["value"].getText(), 2) etisserant@0: elif body_type == "FBD": etisserant@0: for instance in body.getContentInstances(): etisserant@0: if isinstance(instance, plcopen.outVariable): etisserant@0: var = instance.getExpression() etisserant@0: connections = instance.connectionPointIn.getConnections() etisserant@0: if connections and len(connections) == 1: etisserant@0: expression = self.ComputeFBDExpression(body, connections[0]) etisserant@0: self.Program += " %s := %s;\n"%(var, expression) etisserant@0: elif body_type == "LD": etisserant@0: for instance in body.getContentInstances(): etisserant@0: if isinstance(instance, plcopen.coil): lbessard@66: paths = self.GenerateLDPaths(instance.connectionPointIn.getConnections(), body) etisserant@0: variable = self.ExtractModifier(instance, instance.getVariable()) etisserant@0: expression = self.ComputeLDExpression(paths, True) etisserant@0: self.Program += " %s := %s;\n"%(variable, expression) etisserant@0: elif body_type == "SFC": etisserant@0: for instance in body.getContentInstances(): etisserant@0: if isinstance(instance, plcopen.step): lbessard@1: self.GenerateSFCStep(instance, pou) etisserant@0: elif isinstance(instance, plcopen.actionBlock): lbessard@1: self.GenerateSFCStepActions(instance, pou) etisserant@0: elif isinstance(instance, plcopen.transition): lbessard@1: self.GenerateSFCTransition(instance, pou) etisserant@0: elif isinstance(instance, plcopen.jumpStep): etisserant@0: self.GenerateSFCJump(instance, pou) lbessard@70: if len(self.InitialSteps) > 0 and self.ComputedBlocks != "": lbessard@66: action_name = "COMPUTE_FUNCTION_BLOCKS" lbessard@66: action_infos = {"qualifier" : "S", "content" : action_name} lbessard@66: self.SFCNetworks["Steps"][self.InitialSteps[0]]["actions"].append(action_infos) lbessard@70: self.SFCNetworks["Actions"][action_name] = ReIndentText(self.ComputedBlocks, 4) lbessard@66: self.Program = "" lbessard@66: else: lbessard@66: raise Exception lbessard@1: for initialstep in self.InitialSteps: lbessard@1: self.ComputeSFCStep(initialstep) etisserant@0: etisserant@0: def ComputeFBDExpression(self, body, link): etisserant@0: localid = link.getRefLocalId() etisserant@0: instance = body.getContentInstance(localid) etisserant@0: if isinstance(instance, plcopen.inVariable): etisserant@0: return instance.getExpression() etisserant@0: elif isinstance(instance, plcopen.block): etisserant@0: name = instance.getInstanceName() etisserant@0: type = instance.getTypeName() etisserant@0: block_infos = GetBlockType(type) etisserant@0: if block_infos["type"] == "function": etisserant@0: vars = [] etisserant@0: for variable in instance.inputVariables.getVariable(): etisserant@0: connections = variable.connectionPointIn.getConnections() etisserant@0: if connections and len(connections) == 1: etisserant@0: value = self.ComputeFBDExpression(body, connections[0]) etisserant@0: vars.append(self.ExtractModifier(variable, value)) etisserant@0: variable = instance.outputVariables.getVariable()[0] etisserant@0: return self.ExtractModifier(variable, "%s(%s)"%(type, ", ".join(vars))) etisserant@0: elif block_infos["type"] == "functionBlock": lbessard@68: if not self.BlockComputed.get(name, False): etisserant@0: vars = [] etisserant@0: for variable in instance.inputVariables.getVariable(): etisserant@0: connections = variable.connectionPointIn.getConnections() etisserant@0: if connections and len(connections) == 1: etisserant@0: parameter = variable.getFormalParameter() etisserant@0: value = self.ComputeFBDExpression(body, connections[0]) etisserant@0: vars.append(self.ExtractModifier(variable, "%s := %s"%(parameter, value))) etisserant@0: self.Program += " %s(%s);\n"%(name, ", ".join(vars)) lbessard@68: self.BlockComputed[name] = True etisserant@0: connectionPoint = link.getPosition()[-1] etisserant@0: for variable in instance.outputVariables.getVariable(): etisserant@0: blockPointx, blockPointy = variable.connectionPointOut.getRelPosition() etisserant@0: if instance.getX() + blockPointx == connectionPoint.getX() and instance.getY() + blockPointy == connectionPoint.getY(): etisserant@0: return self.ExtractModifier(variable, "%s.%s"%(name, variable.getFormalParameter())) etisserant@0: raise ValueError, "No output variable found" etisserant@0: lbessard@66: def GenerateLDPaths(self, connections, body): etisserant@0: paths = [] etisserant@0: for connection in connections: etisserant@0: localId = connection.getRefLocalId() etisserant@0: next = body.getContentInstance(localId) etisserant@0: if isinstance(next, plcopen.leftPowerRail): etisserant@0: paths.append(None) etisserant@0: else: lbessard@66: variable = self.ExtractModifier(next, next.getVariable()) lbessard@66: result = self.GenerateLDPaths(next.connectionPointIn.getConnections(), body) lbessard@66: if len(result) > 1: lbessard@66: paths.append([variable, tuple(result)]) lbessard@66: elif type(result[0]) == ListType: lbessard@66: paths.append([variable] + result[0]) lbessard@66: elif result[0]: lbessard@66: paths.append([variable, result[0]]) lbessard@66: else: lbessard@66: paths.append(variable) lbessard@66: return paths lbessard@66: lbessard@66: def GetNetworkType(self, connections, body): lbessard@66: network_type = "FBD" lbessard@66: for connection in connections: lbessard@66: localId = connection.getRefLocalId() lbessard@66: next = body.getContentInstance(localId) lbessard@66: if isinstance(next, plcopen.leftPowerRail) or isinstance(next, plcopen.contact): lbessard@66: return "LD" lbessard@66: elif isinstance(next, plcopen.block): lbessard@70: for variable in next.inputVariables.getVariable(): lbessard@66: result = self.GetNetworkType(variable.connectionPointIn.getConnections(), body) lbessard@66: if result != "FBD": lbessard@66: return result lbessard@66: elif isinstance(next, plcopen.inVariable): lbessard@66: return "FBD" lbessard@66: elif isinstance(next, plcopen.inOutVariable): lbessard@66: return self.GetNetworkType(next.connectionPointIn.getConnections(), body) lbessard@66: else: lbessard@66: return None lbessard@66: return "FBD" lbessard@66: lbessard@2: def ExtractDivergenceInput(self, divergence, pou): lbessard@2: connectionPointIn = divergence.getConnectionPointIn() lbessard@2: if connectionPointIn: lbessard@2: connections = connectionPointIn.getConnections() lbessard@2: if len(connections) == 1: lbessard@2: instanceLocalId = connections[0].getRefLocalId() lbessard@2: return pou.body.getContentInstance(instanceLocalId) lbessard@2: return None lbessard@2: lbessard@2: def ExtractConvergenceInputs(self, convergence, pou): lbessard@2: instances = [] lbessard@2: for connectionPointIn in convergence.getConnectionPointIn(): lbessard@2: connections = connectionPointIn.getConnections() lbessard@2: if len(connections) == 1: lbessard@2: instanceLocalId = connections[0].getRefLocalId() lbessard@2: instances.append(pou.body.getContentInstance(instanceLocalId)) lbessard@2: return instances lbessard@2: lbessard@1: def GenerateSFCStep(self, step, pou): etisserant@0: step_name = step.getName() lbessard@1: if step_name not in self.SFCNetworks["Steps"].keys(): lbessard@1: if step.getInitialStep(): lbessard@1: self.InitialSteps.append(step_name) etisserant@0: step_infos = {"initial" : step.getInitialStep(), "transitions" : [], "actions" : []} etisserant@0: if step.connectionPointIn: etisserant@0: instances = [] etisserant@0: connections = step.connectionPointIn.getConnections() etisserant@0: if len(connections) == 1: etisserant@0: instanceLocalId = connections[0].getRefLocalId() etisserant@0: instance = pou.body.getContentInstance(instanceLocalId) etisserant@0: if isinstance(instance, plcopen.transition): etisserant@0: instances.append(instance) etisserant@0: elif isinstance(instance, plcopen.selectionConvergence): lbessard@2: instances.extend(self.ExtractConvergenceInputs(instance, pou)) lbessard@2: elif isinstance(instance, plcopen.simultaneousDivergence): lbessard@2: transition = self.ExtractDivergenceInput(instance, pou) lbessard@2: if transition: lbessard@2: if isinstance(transition, plcopen.transition): lbessard@1: instances.append(transition) lbessard@2: elif isinstance(transition, plcopen.selectionConvergence): lbessard@2: instances.extend(self.ExtractConvergenceInputs(transition, pou)) etisserant@0: for instance in instances: lbessard@2: self.GenerateSFCTransition(instance, pou) lbessard@1: if instance in self.SFCNetworks["Transitions"].keys(): lbessard@1: self.SFCNetworks["Transitions"][instance]["to"].append(step_name) lbessard@1: self.SFCNetworks["Steps"][step_name] = step_infos etisserant@0: etisserant@0: def GenerateSFCJump(self, jump, pou): etisserant@0: jump_target = jump.getTargetName() etisserant@0: if jump.connectionPointIn: etisserant@0: instances = [] etisserant@0: connections = jump.connectionPointIn.getConnections() etisserant@0: if len(connections) == 1: etisserant@0: instanceLocalId = connections[0].getRefLocalId() etisserant@0: instance = pou.body.getContentInstance(instanceLocalId) etisserant@0: if isinstance(instance, plcopen.transition): etisserant@0: instances.append(instance) etisserant@0: elif isinstance(instance, plcopen.selectionConvergence): lbessard@2: instances.extend(self.ExtractConvergenceInputs(instance, pou)) lbessard@2: elif isinstance(instance, plcopen.simultaneousDivergence): lbessard@2: transition = self.ExtractDivergenceInput(instance, pou) lbessard@2: if transition: lbessard@2: if isinstance(transition, plcopen.transition): lbessard@1: instances.append(transition) lbessard@2: elif isinstance(transition, plcopen.selectionConvergence): lbessard@2: instances.extend(self.ExtractConvergenceInputs(transition, pou)) etisserant@0: for instance in instances: lbessard@2: self.GenerateSFCTransition(instance, pou) lbessard@1: if instance in self.SFCNetworks["Transitions"].keys(): lbessard@1: self.SFCNetworks["Transitions"][instance]["to"].append(jump_target) lbessard@1: lbessard@1: def GenerateSFCStepActions(self, actionBlock, pou): etisserant@0: connections = actionBlock.connectionPointIn.getConnections() etisserant@0: if len(connections) == 1: etisserant@0: stepLocalId = connections[0].getRefLocalId() etisserant@0: step = pou.body.getContentInstance(stepLocalId) lbessard@1: self.GenerateSFCStep(step, pou) etisserant@0: step_name = step.getName() lbessard@1: if step_name in self.SFCNetworks["Steps"].keys(): etisserant@0: actions = actionBlock.getActions() etisserant@0: for action in actions: lbessard@1: action_infos = {"qualifier" : action["qualifier"], "content" : action["value"]} lbessard@1: if "duration" in action: lbessard@1: action_infos["duration"] = action["duration"] lbessard@1: if "indicator" in action: lbessard@1: action_infos["indicator"] = action["indicator"] lbessard@1: if action["type"] == "reference": lbessard@1: self.GenerateSFCAction(action["value"], pou) lbessard@46: else: lbessard@46: action_name = "INLINE%d"%self.GetActionNumber() lbessard@46: self.SFCNetworks["Actions"][action_name] = " %s\n"%action["value"] lbessard@46: action_infos["content"] = action_name lbessard@1: self.SFCNetworks["Steps"][step_name]["actions"].append(action_infos) lbessard@1: lbessard@1: def GenerateSFCAction(self, action_name, pou): lbessard@1: if action_name not in self.SFCNetworks["Actions"].keys(): lbessard@1: actionContent = pou.getAction(action_name) lbessard@1: if actionContent: lbessard@1: actionType = actionContent.getBodyType() lbessard@1: actionBody = actionContent.getBody() lbessard@1: if actionType in ["ST", "IL"]: lbessard@1: self.SFCNetworks["Actions"][action_name] = ReIndentText(actionContent.getText(), 4) lbessard@1: elif actionType == "FBD": lbessard@1: for instance in actionBody.getContentInstances(): lbessard@1: if isinstance(instance, plcopen.outVariable): lbessard@1: var = instance.getExpression() lbessard@1: connections = instance.connectionPointIn.getConnections() lbessard@1: if connections and len(connections) == 1: lbessard@1: expression = self.ComputeFBDExpression(actionBody, connections[0]) lbessard@70: action_content = self.Program + " %s := %s;\n"%(var, expression) lbessard@1: self.Program = "" lbessard@70: self.SFCNetworks["Actions"][action_name] = ReIndentText(action_content, 4) lbessard@1: elif actionType == "LD": lbessard@1: for instance in actionbody.getContentInstances(): lbessard@1: if isinstance(instance, plcopen.coil): lbessard@66: paths = self.GenerateLDPaths(instance.connectionPointIn.getConnections(), actionBody) lbessard@1: variable = self.ExtractModifier(instance, instance.getVariable()) lbessard@1: expression = self.ComputeLDExpression(paths, True) lbessard@70: action_content = self.Program + " %s := %s;\n"%(variable, expression) lbessard@1: self.Program = "" lbessard@70: self.SFCNetworks["Actions"][action_name] = ReIndentText(action_content, 4) lbessard@1: lbessard@1: def GenerateSFCTransition(self, transition, pou): lbessard@1: if transition not in self.SFCNetworks["Transitions"].keys(): lbessard@1: steps = [] etisserant@0: connections = transition.connectionPointIn.getConnections() etisserant@0: if len(connections) == 1: etisserant@0: instanceLocalId = connections[0].getRefLocalId() etisserant@0: instance = pou.body.getContentInstance(instanceLocalId) etisserant@0: if isinstance(instance, plcopen.step): lbessard@2: steps.append(instance) etisserant@0: elif isinstance(instance, plcopen.selectionDivergence): lbessard@2: step = self.ExtractDivergenceInput(instance, pou) lbessard@2: if step: lbessard@2: if isinstance(step, plcopen.step): lbessard@2: steps.append(step) lbessard@2: elif isinstance(step, plcopen.simultaneousConvergence): lbessard@2: steps.extend(self.ExtractConvergenceInputs(step, pou)) lbessard@2: elif isinstance(instance, plcopen.simultaneousConvergence): lbessard@2: steps.extend(self.ExtractConvergenceInputs(instance, pou)) lbessard@1: transition_infos = {"from": [], "to" : []} lbessard@1: transitionValues = transition.getConditionContent() lbessard@1: if transitionValues["type"] == "inline": lbessard@1: transition_infos["content"] = "\n := %s;\n"%transitionValues["value"] lbessard@66: elif transitionValues["type"] == "reference": lbessard@1: transitionContent = pou.getTransition(transitionValues["value"]) lbessard@1: transitionType = transitionContent.getBodyType() lbessard@1: transitionBody = transitionContent.getBody() lbessard@1: if transitionType == "IL": lbessard@2: transition_infos["content"] = ":\n%s"%ReIndentText(transitionBody.getText(), 4) lbessard@1: elif transitionType == "ST": lbessard@2: transition_infos["content"] = "\n%s"%ReIndentText(transitionBody.getText(), 4) lbessard@66: elif transitionType == "FBD": lbessard@1: for instance in transitionBody.getContentInstances(): lbessard@1: if isinstance(instance, plcopen.outVariable): lbessard@1: connections = instance.connectionPointIn.getConnections() lbessard@1: if connections and len(connections) == 1: lbessard@66: expression = self.ComputeFBDExpression(transitionBody, connections[0]) lbessard@66: transition_infos["content"] = "\n := %s;\n"%expression lbessard@70: self.ComputedBlocks += self.Program lbessard@70: self.Program = "" lbessard@66: elif transitionType == "LD": lbessard@66: for instance in transitionBody.getContentInstances(): lbessard@1: if isinstance(instance, plcopen.coil): lbessard@66: paths = self.GenerateLDPaths(instance.connectionPointIn.getConnections(), transitionBody) lbessard@1: expression = self.ComputeLDExpression(paths, True) lbessard@1: transition_infos["content"] = "\n := %s;\n"%expression lbessard@70: self.ComputedBlocks += self.Program lbessard@70: self.Program = "" lbessard@66: elif transitionValues["type"] == "connection": lbessard@66: body = pou.getBody() lbessard@66: connections = transition.getConnections() lbessard@66: network_type = self.GetNetworkType(connections, body) lbessard@66: if network_type == None: lbessard@66: raise Exception lbessard@66: if len(connections) > 1 or network_type == "LD": lbessard@66: paths = self.GenerateLDPaths(connections, body) lbessard@66: expression = self.ComputeLDExpression(paths, True) lbessard@66: transition_infos["content"] = "\n := %s;\n"%expression lbessard@70: self.ComputedBlocks += self.Program lbessard@70: self.Program = "" lbessard@66: else: lbessard@66: expression = self.ComputeFBDExpression(body, connections[0]) lbessard@66: transition_infos["content"] = "\n := %s;\n"%expression lbessard@70: self.ComputedBlocks += self.Program lbessard@70: self.Program = "" lbessard@2: for step in steps: lbessard@2: self.GenerateSFCStep(step, pou) lbessard@2: step_name = step.getName() lbessard@1: if step_name in self.SFCNetworks["Steps"].keys(): lbessard@1: transition_infos["from"].append(step_name) lbessard@1: self.SFCNetworks["Steps"][step_name]["transitions"].append(transition) lbessard@1: self.SFCNetworks["Transitions"][transition] = transition_infos lbessard@1: lbessard@1: def ComputeSFCStep(self, step_name): lbessard@1: if step_name in self.SFCNetworks["Steps"].keys(): lbessard@1: step_infos = self.SFCNetworks["Steps"].pop(step_name) lbessard@1: if step_infos["initial"]: lbessard@1: self.Program += " INITIAL_STEP %s:\n"%step_name lbessard@1: else: lbessard@1: self.Program += " STEP %s:\n"%step_name lbessard@1: actions = [] lbessard@1: for action_infos in step_infos["actions"]: lbessard@1: actions.append(action_infos["content"]) lbessard@1: self.Program += " %(content)s(%(qualifier)s"%action_infos lbessard@1: if "duration" in action_infos: lbessard@1: self.Program += ", %(duration)s"%action_infos lbessard@1: if "indicator" in action_infos: lbessard@1: self.Program += ", %(indicator)s"%action_infos lbessard@1: self.Program += ");\n" lbessard@1: self.Program += " END_STEP\n\n" lbessard@1: for action in actions: lbessard@1: self.ComputeSFCAction(action) lbessard@1: for transition in step_infos["transitions"]: lbessard@1: self.ComputeSFCTransition(transition) lbessard@1: lbessard@1: def ComputeSFCAction(self, action_name): lbessard@1: if action_name in self.SFCNetworks["Actions"].keys(): lbessard@1: action_content = self.SFCNetworks["Actions"].pop(action_name) lbessard@1: self.Program += " ACTION %s:\n%s END_ACTION\n\n"%(action_name, action_content) lbessard@1: lbessard@1: def ComputeSFCTransition(self, transition): lbessard@1: if transition in self.SFCNetworks["Transitions"].keys(): lbessard@1: transition_infos = self.SFCNetworks["Transitions"].pop(transition) lbessard@1: self.Program += " TRANSITION FROM " lbessard@1: if len(transition_infos["from"]) > 1: lbessard@1: self.Program += "(%s)"%", ".join(transition_infos["from"]) lbessard@1: else: lbessard@1: self.Program += "%s"%transition_infos["from"][0] lbessard@1: self.Program += " TO " lbessard@1: if len(transition_infos["to"]) > 1: lbessard@1: self.Program += "(%s)"%", ".join(transition_infos["to"]) lbessard@1: else: lbessard@1: self.Program += "%s"%transition_infos["to"][0] lbessard@1: self.Program += transition_infos["content"] lbessard@1: self.Program += " END_TRANSITION\n\n" lbessard@1: for step_name in transition_infos["to"]: lbessard@1: self.ComputeSFCStep(step_name) lbessard@1: etisserant@0: def ComputeLDExpression(self, paths, first = False): etisserant@0: if type(paths) == TupleType: etisserant@0: if None in paths: etisserant@0: return "TRUE" etisserant@0: else: etisserant@0: var = [self.ComputeLDExpression(path) for path in paths] etisserant@0: if first: etisserant@0: return " OR ".join(var) etisserant@0: else: etisserant@0: return "(%s)"%" OR ".join(var) etisserant@0: elif type(paths) == ListType: etisserant@0: var = [self.ComputeLDExpression(path) for path in paths] etisserant@0: return " AND ".join(var) etisserant@0: else: etisserant@0: return paths etisserant@0: etisserant@0: def ExtractModifier(self, variable, text): etisserant@0: if variable.getNegated(): etisserant@0: return "NOT(%s)"%text etisserant@0: else: etisserant@0: edge = variable.getEdge() etisserant@0: if edge: etisserant@0: if edge.getValue() == "rising": etisserant@0: return self.AddTrigger("R_TRIG", text) etisserant@0: elif edge.getValue() == "falling": etisserant@0: return self.AddTrigger("F_TRIG", text) etisserant@0: return text etisserant@0: etisserant@0: def AddTrigger(self, edge, text): lbessard@33: if self.Interface[-1][0] != "VAR" or self.Interface[-1][1] or self.Interface[-1][2] or self.Interface[-1][3]: lbessard@33: self.Interface.append(("VAR", False, False, False, [])) etisserant@0: i = 1 etisserant@0: name = "%s%d"%(edge, i) lbessard@1: while self.IsAlreadyDefined(name): etisserant@0: i += 1 etisserant@0: name = "%s%d"%(edge, i) lbessard@33: self.Interface[-1][4].append((edge, name, None, None)) etisserant@0: self.Program += " %s(CLK := %s);\n"%(name, text) etisserant@0: return "%s.Q"%name etisserant@0: etisserant@0: def GenerateSTProgram(self): lbessard@1: if self.ReturnType: lbessard@29: program = "%s %s : %s\n"%(self.Type, self.Name, self.ReturnType) etisserant@0: else: lbessard@29: program = "%s %s\n"%(self.Type, self.Name) lbessard@33: for list_type, retain, constant, located, variables in self.Interface: lbessard@1: program += " %s"%list_type lbessard@1: if retain: lbessard@1: program += " RETAIN" lbessard@1: if constant: lbessard@1: program += " CONSTANT" lbessard@1: program += "\n" lbessard@30: for var_type, var_name, var_address, var_initial in variables: lbessard@30: program += " %s "%var_name lbessard@30: if var_address != None: lbessard@31: program += "AT %s "%var_address lbessard@30: program += ": %s"%var_type lbessard@28: if var_initial != None: lbessard@33: value = {"TRUE":"0","FALSE":"1"}.get(str(var_initial).upper(), str(var_initial)) lbessard@37: if var_type == "STRING": lbessard@37: program += " := '%s'"%value lbessard@37: elif var_type == "WSTRING": lbessard@33: program += " := \"%s\""%value lbessard@33: else: lbessard@33: program += " := %s"%value lbessard@30: program += ";\n" lbessard@4: program += " END_VAR\n" etisserant@0: program += "\n" etisserant@0: program += self.Program etisserant@0: program += "END_%s\n\n"%self.Type etisserant@0: return program etisserant@0: lbessard@29: def GenerateConfiguration(self, configuration): lbessard@29: config = "\nCONFIGURATION %s\n"%configuration.getName() lbessard@29: for varlist in configuration.getGlobalVars(): lbessard@29: config += " VAR_GLOBAL" lbessard@29: if varlist.getRetain(): lbessard@29: config += " RETAIN" lbessard@29: if varlist.getConstant(): lbessard@29: config += " CONSTANT" lbessard@29: config += "\n" lbessard@29: for var in varlist.getVariable(): lbessard@33: var_type = var.getType().getValue() lbessard@33: config += " %s "%var.getName() lbessard@30: address = var.getAddress() lbessard@30: if address: lbessard@30: config += "AT %s "%address lbessard@33: config += ": %s"%var_type lbessard@29: initial = var.getInitialValue() lbessard@29: if initial: lbessard@30: value = str(initial.getValue()) lbessard@33: value = {"TRUE":"0","FALSE":"1"}.get(value.upper(), value) lbessard@37: if var_type == "STRING": lbessard@37: config += " := '%s'"%value lbessard@37: elif var_type == "WSTRING": lbessard@33: config += " := \"%s\""%value lbessard@33: else: lbessard@33: config += " := %s"%value lbessard@30: config += ";\n" lbessard@29: config += " END_VAR\n" lbessard@29: for resource in configuration.getResource(): lbessard@29: config += self.GenerateResource(resource) lbessard@29: config += "END_CONFIGURATION\n" lbessard@29: return config lbessard@29: lbessard@29: def GenerateResource(self, resource): lbessard@33: resrce = "\n RESOURCE %s ON BEREMIZ\n"%resource.getName() lbessard@29: for varlist in resource.getGlobalVars(): lbessard@29: resrce += " VAR_GLOBAL" lbessard@29: if varlist.getRetain(): lbessard@29: resrce += " RETAIN" lbessard@29: if varlist.getConstant(): lbessard@29: resrce += " CONSTANT" lbessard@29: resrce += "\n" lbessard@29: for var in varlist.getVariable(): lbessard@33: var_type = var.getType().getValue() lbessard@30: resrce += " %s "%var.getName() lbessard@30: address = var.getAddress() lbessard@30: if address: lbessard@30: resrce += "AT %s "%address lbessard@30: resrce += ": %s"%var.getType().getValue() lbessard@29: initial = var.getInitialValue() lbessard@29: if initial: lbessard@30: value = str(initial.getValue()) lbessard@33: value = {"TRUE":"0","FALSE":"1"}.get(value.upper(), value) lbessard@37: if var_type == "STRING": lbessard@37: resrce += " := '%s'"%value lbessard@37: elif var_type == "WSTRING": lbessard@33: resrce += " := \"%s\""%value lbessard@33: else: lbessard@33: resrce += " := %s"%value lbessard@30: resrce += ";\n" lbessard@29: resrce += " END_VAR\n" lbessard@30: tasks = resource.getTask() lbessard@30: for task in tasks: lbessard@30: resrce += " TASK %s("%task.getName() lbessard@30: args = [] lbessard@30: single = task.getSingle() lbessard@30: if single: lbessard@30: args.append("SINGLE := %s"%single) lbessard@30: interval = task.getInterval() lbessard@30: if interval: lbessard@30: text = "t#" lbessard@30: if interval.hour != 0: lbessard@30: text += "%dh"%interval.hour lbessard@30: if interval.minute != 0: lbessard@30: text += "%dm"%interval.minute lbessard@30: if interval.second != 0: lbessard@30: text += "%ds"%interval.second lbessard@30: if interval.microsecond != 0: lbessard@30: text += "%dms"%(interval.microsecond / 1000) lbessard@30: args.append("INTERVAL := %s"%text) lbessard@30: args.append("PRIORITY := %s"%str(task.priority.getValue())) lbessard@30: resrce += ",".join(args) + ");\n" lbessard@30: for task in tasks: lbessard@30: for instance in task.getPouInstance(): lbessard@30: resrce += " PROGRAM %s WITH %s : %s;\n"%(instance.getName(), task.getName(), instance.getType()) lbessard@30: for instance in resource.getPouInstance(): lbessard@30: resrce += " PROGRAM %s : %s;\n"%(instance.getName(), instance.getType()) lbessard@30: resrce += " END_RESOURCE\n" lbessard@29: return resrce lbessard@29: lbessard@29: etisserant@0: def GenerateCurrentProgram(project): etisserant@0: program = "" etisserant@0: for pou in project.getPous(): etisserant@0: pou_type = pou.getPouType().getValue() lbessard@6: if pou_type in pouTypeNames: lbessard@6: pou_program = PouProgram(pou.getName(), pouTypeNames[pou_type]) etisserant@0: else: etisserant@0: raise ValueError, "Undefined pou type" etisserant@0: pou_program.GenerateInterface(pou.getInterface()) etisserant@0: pou_program.GenerateProgram(pou) etisserant@0: program += pou_program.GenerateSTProgram() lbessard@29: for config in project.getConfigurations(): lbessard@29: program += pou_program.GenerateConfiguration(config) etisserant@0: return program etisserant@0: