PLCGenerator.py
changeset 1 e9d01d824086
parent 0 b622defdfd98
child 2 93bc4c2cf376
equal deleted inserted replaced
0:b622defdfd98 1:e9d01d824086
    27 from types import *
    27 from types import *
    28 
    28 
    29 varTypeNames = {"localVars" : "VAR", "tempVars" : "VAR_TEMP", "inputVars" : "VAR_INPUT", 
    29 varTypeNames = {"localVars" : "VAR", "tempVars" : "VAR_TEMP", "inputVars" : "VAR_INPUT", 
    30                 "outputVars" : "VAR_OUTPUT", "inOutVars" : "VAR_IN_OUT", "externalVars" : "VAR_EXTERNAL",
    30                 "outputVars" : "VAR_OUTPUT", "inOutVars" : "VAR_IN_OUT", "externalVars" : "VAR_EXTERNAL",
    31                 "globalVars" : "VAR_GLOBAL", "accessVars" : "VAR_ACCESS"}
    31                 "globalVars" : "VAR_GLOBAL", "accessVars" : "VAR_ACCESS"}
       
    32 
       
    33 def ReIndentText(text, nb_spaces):
       
    34     compute = ""
       
    35     lines = text.splitlines()
       
    36     if len(lines) > 0:
       
    37         spaces = 0
       
    38         while lines[0][spaces] == " ":
       
    39             spaces += 1
       
    40         indent = ""
       
    41         for i in xrange(spaces, nb_spaces):
       
    42             indent += " "
       
    43         for line in lines:
       
    44             compute += "%s%s\n"%(indent, line)
       
    45     return compute
       
    46 
    32 """
    47 """
    33 Module implementing methods for generating PLC programs in ST or IL
    48 Module implementing methods for generating PLC programs in ST or IL
    34 """
    49 """
    35 
    50 
    36 class PouProgram:
    51 class PouProgram:
    37     
    52     
    38     def __init__(self, name, type):
    53     def __init__(self, name, type):
    39         self.Name = name
    54         self.Name = name
    40         self.Type = type
    55         self.Type = type
    41         self.Interface = {}
    56         self.ReturnType = None
    42         self.Steps = {}
    57         self.Interface = []
    43         self.Transitions = {}
    58         self.InitialSteps = []
    44         self.Order = []
    59         self.SFCNetworks = {"Steps":{}, "Transitions":{}, "Actions":{}}
    45         self.Program = ""
    60         self.Program = ""
       
    61     
       
    62     def IsAlreadyDefined(self, name):
       
    63         for list_type, retain, constant, vars in self.Interface:
       
    64             for var_type, var_name in vars:
       
    65                 if name == var_name:
       
    66                     return True
       
    67         return False
    46     
    68     
    47     def GenerateInterface(self, interface):
    69     def GenerateInterface(self, interface):
    48         if self.Type == "FUNCTION":
    70         if self.Type == "FUNCTION":
    49             self.Interface["returnType"] = interface.getReturnType().getValue()
    71             self.ReturnType = interface.getReturnType().getValue()
    50         for varlist in interface.getContent():
    72         for varlist in interface.getContent():
    51             variables = {}
    73             variables = []
    52             for var in varlist["value"].getVariable():
    74             for var in varlist["value"].getVariable():
    53                 type = var.getType().getValue()
    75                 type = var.getType().getValue()
    54                 if type not in variables:
    76                 variables.append((type, var.getName()))
    55                     variables[type] = []
    77             self.Interface.append((varTypeNames[varlist["name"]], varlist["value"].getRetain(), 
    56                 variables[type].append(var.getName())
    78                             varlist["value"].getConstant(), variables))
    57             self.Interface[(varTypeNames[varlist["name"]], varlist["value"].getRetain(), 
       
    58                             varlist["value"].getConstant())] = variables
       
    59     
    79     
    60     def GenerateProgram(self, pou):
    80     def GenerateProgram(self, pou):
    61         body = pou.getBody()
    81         body = pou.getBody()
    62         body_content = body.getContent()
    82         body_content = body.getContent()
    63         body_type = body_content["name"]
    83         body_type = body_content["name"]
    64         if body_type in ["IL","ST"]:
    84         if body_type in ["IL","ST"]:
    65             self.Program = "%s\n"%body_content["value"].getText()
    85             self.Program = ReIndentText(body_content["value"].getText(), 2)
    66         elif body_type == "FBD":
    86         elif body_type == "FBD":
    67             for instance in body.getContentInstances():
    87             for instance in body.getContentInstances():
    68                 if isinstance(instance, plcopen.outVariable):
    88                 if isinstance(instance, plcopen.outVariable):
    69                     var = instance.getExpression()
    89                     var = instance.getExpression()
    70                     connections = instance.connectionPointIn.getConnections()
    90                     connections = instance.connectionPointIn.getConnections()
    79                     expression = self.ComputeLDExpression(paths, True)
    99                     expression = self.ComputeLDExpression(paths, True)
    80                     self.Program += "  %s := %s;\n"%(variable, expression)
   100                     self.Program += "  %s := %s;\n"%(variable, expression)
    81         elif body_type == "SFC":
   101         elif body_type == "SFC":
    82             for instance in body.getContentInstances():
   102             for instance in body.getContentInstances():
    83                 if isinstance(instance, plcopen.step):
   103                 if isinstance(instance, plcopen.step):
    84                     self.GenerateSFCSteps(instance, pou)
   104                     self.GenerateSFCStep(instance, pou)
    85                 elif isinstance(instance, plcopen.actionBlock):
   105                 elif isinstance(instance, plcopen.actionBlock):
    86                     self.GenerateSFCActions(instance, pou)
   106                     self.GenerateSFCStepActions(instance, pou)
    87                 elif isinstance(instance, plcopen.transition):
   107                 elif isinstance(instance, plcopen.transition):
    88                     self.GenerateSFCTransitions(instance, pou)
   108                     self.GenerateSFCTransition(instance, pou)
    89                 elif isinstance(instance, plcopen.jumpStep):
   109                 elif isinstance(instance, plcopen.jumpStep):
    90                     self.GenerateSFCJump(instance, pou)
   110                     self.GenerateSFCJump(instance, pou)
    91             for name, values in self.Steps.items():
   111             for initialstep in self.InitialSteps:
    92                 if values['initial']:
   112                 self.ComputeSFCStep(initialstep)
    93                     self.GenerateSFCStepOrder(name, [])
       
    94             steps_type = "ARRAY [1..%d] OF BOOL"%len(self.Order)
       
    95             if ("VAR", False, False) not in self.Interface:
       
    96                 self.Interface[("VAR", False, False)] = {}
       
    97             if steps_type not in self.Interface[("VAR", False, False)]:
       
    98                 self.Interface[("VAR", False, False)][steps_type] = ["Steps"]
       
    99             else:
       
   100                 self.Interface[("VAR", False, False)][steps_type].append("Steps")
       
   101             for index, name in enumerate(self.Order):
       
   102                 values = self.Steps[name]
       
   103                 self.Program += "  IF Steps[%d] THEN\n"%index
       
   104                 for action in values["actions"]:
       
   105                     if action["qualifier"] == "N":
       
   106                         for line in action["content"].splitlines():
       
   107                             self.Program += "  %s\n"%line
       
   108                     elif action["qualifier"] == "S":
       
   109                         if "R_TRIG" not in self.Interface[("VAR", False, False)]:
       
   110                             self.Interface[("VAR", False, False)]["R_TRIG"] = []
       
   111                         i = 1
       
   112                         name = "R_TRIG%d"%i
       
   113                         while name in self.Interface[("VAR", False, False)]["R_TRIG"]:
       
   114                             i += 1
       
   115                             name = "R_TRIG%d"%i
       
   116                         self.Interface[("VAR", False, False)]["R_TRIG"].append(name)
       
   117                         self.Program += "    IF %s(CLK := Steps[%d]) THEN\n"%(name, index)
       
   118                         self.Program += "      %s := TRUE;\n"%action["content"]
       
   119                 for transition in values["transitions"]:
       
   120                     if transition["compute"] != '':
       
   121                         self.Program += "    %s %s"%(transition["condition"], transition["compute"])
       
   122                     self.Program += "    IF %s THEN\n"%transition["condition"]
       
   123                     for target in transition["targets"]:
       
   124                         self.Program += "      Steps[%d] := TRUE;\n"%self.Order.index(target)
       
   125                     self.Program += "      Steps[%d] := FALSE;\n"%index
       
   126     
   113     
   127     def ComputeFBDExpression(self, body, link):
   114     def ComputeFBDExpression(self, body, link):
   128         localid = link.getRefLocalId()
   115         localid = link.getRefLocalId()
   129         instance = body.getContentInstance(localid)
   116         instance = body.getContentInstance(localid)
   130         if isinstance(instance, plcopen.inVariable):
   117         if isinstance(instance, plcopen.inVariable):
   141                         value = self.ComputeFBDExpression(body, connections[0])
   128                         value = self.ComputeFBDExpression(body, connections[0])
   142                         vars.append(self.ExtractModifier(variable, value))
   129                         vars.append(self.ExtractModifier(variable, value))
   143                 variable = instance.outputVariables.getVariable()[0]
   130                 variable = instance.outputVariables.getVariable()[0]
   144                 return self.ExtractModifier(variable, "%s(%s)"%(type, ", ".join(vars)))
   131                 return self.ExtractModifier(variable, "%s(%s)"%(type, ", ".join(vars)))
   145             elif block_infos["type"] == "functionBlock":
   132             elif block_infos["type"] == "functionBlock":
   146                 if ("VAR", False, False) not in self.Interface:
   133                 if self.Interface[-1][0] != "VAR" or self.Interface[-1][1] or self.Interface[-1][2]:
   147                     self.Interface[("VAR", False, False)] = {}
   134                     self.Interface.append(("VAR", False, False, []))
   148                 if type not in self.Interface[("VAR", False, False)]:
   135                 if not self.IsAlreadyDefined(name):
   149                     self.Interface[("VAR", False, False)][type] = []
   136                     self.Interface[-1][3].append((type, name))
   150                 if name not in self.Interface[("VAR", False, False)][type]:
       
   151                     self.Interface[("VAR", False, False)][type].append(name)
       
   152                     vars = []
   137                     vars = []
   153                     for variable in instance.inputVariables.getVariable():
   138                     for variable in instance.inputVariables.getVariable():
   154                         connections = variable.connectionPointIn.getConnections()
   139                         connections = variable.connectionPointIn.getConnections()
   155                         if connections and len(connections) == 1:
   140                         if connections and len(connections) == 1:
   156                             parameter = variable.getFormalParameter()
   141                             parameter = variable.getFormalParameter()
   188             elif paths[0]:
   173             elif paths[0]:
   189                 return [variable, paths[0]]
   174                 return [variable, paths[0]]
   190             else:
   175             else:
   191                 return variable
   176                 return variable
   192 
   177 
   193     def GenerateSFCSteps(self, step, pou):
   178     def GenerateSFCStep(self, step, pou):
   194         step_name = step.getName()
   179         step_name = step.getName()
   195         if step_name not in self.Steps:
   180         if step_name not in self.SFCNetworks["Steps"].keys():
       
   181             if step.getInitialStep():
       
   182                 self.InitialSteps.append(step_name)
   196             step_infos = {"initial" : step.getInitialStep(), "transitions" : [], "actions" : []}
   183             step_infos = {"initial" : step.getInitialStep(), "transitions" : [], "actions" : []}
   197             self.Steps[step_name] = step_infos
       
   198             if step.connectionPointIn:
   184             if step.connectionPointIn:
   199                 instances = []
   185                 instances = []
   200                 connections = step.connectionPointIn.getConnections()
   186                 connections = step.connectionPointIn.getConnections()
   201                 if len(connections) == 1:
   187                 if len(connections) == 1:
   202                     instanceLocalId = connections[0].getRefLocalId()
   188                     instanceLocalId = connections[0].getRefLocalId()
   203                     instance = pou.body.getContentInstance(instanceLocalId)
   189                     instance = pou.body.getContentInstance(instanceLocalId)
   204                     if isinstance(instance, plcopen.transition):
   190                     if isinstance(instance, plcopen.transition):
   205                         self.GenerateSFCTransitions(instance, pou)
   191                         self.GenerateSFCTransition(instance, pou)
   206                         instances.append(instance)
   192                         instances.append(instance)
   207                     elif isinstance(instance, plcopen.selectionConvergence):
   193                     elif isinstance(instance, plcopen.selectionConvergence):
   208                         for connectionPointIn in instance.getConnectionPointIn():
   194                         for connectionPointIn in instance.getConnectionPointIn():
   209                             divergence_connections = connectionPointIn.getConnections()
   195                             divergence_connections = connectionPointIn.getConnections()
   210                             if len(divergence_connections) == 1:
   196                             if len(divergence_connections) == 1:
   211                                 transitionLocalId = connections[0].getRefLocalId()
   197                                 transitionLocalId = connections[0].getRefLocalId()
   212                                 transition = pou.body.getContentInstance(transitionLocalId)
   198                                 transition = pou.body.getContentInstance(transitionLocalId)
   213                                 self.GenerateSFCTransitions(transition, pou)
   199                                 self.GenerateSFCTransition(transition, pou)
       
   200                                 instances.append(transition)
       
   201                     elif isinstance(instance, plcopen.simultaneousDivergence):
       
   202                         connectionPointIn = instance.getConnectionPointIn()
       
   203                         if connectionPointIn:
       
   204                             divergence_connections = connectionPointIn.getConnections()
       
   205                             if len(divergence_connections) == 1:
       
   206                                 transitionLocalId = connections[0].getRefLocalId()
       
   207                                 transition = pou.body.getContentInstance(transitionLocalId)
       
   208                                 self.GenerateSFCTransition(transition, pou)
   214                                 instances.append(transition)
   209                                 instances.append(transition)
   215                 for instance in instances:
   210                 for instance in instances:
   216                     self.Transitions[instance]["targets"].append(step_name)
   211                     if instance in self.SFCNetworks["Transitions"].keys():
       
   212                         self.SFCNetworks["Transitions"][instance]["to"].append(step_name)
       
   213             self.SFCNetworks["Steps"][step_name] = step_infos
   217     
   214     
   218     def GenerateSFCJump(self, jump, pou):
   215     def GenerateSFCJump(self, jump, pou):
   219         jump_target = jump.getTargetName()
   216         jump_target = jump.getTargetName()
   220         if jump.connectionPointIn:
   217         if jump.connectionPointIn:
   221             instances = []
   218             instances = []
   222             connections = jump.connectionPointIn.getConnections()
   219             connections = jump.connectionPointIn.getConnections()
   223             if len(connections) == 1:
   220             if len(connections) == 1:
   224                 instanceLocalId = connections[0].getRefLocalId()
   221                 instanceLocalId = connections[0].getRefLocalId()
   225                 instance = pou.body.getContentInstance(instanceLocalId)
   222                 instance = pou.body.getContentInstance(instanceLocalId)
   226                 if isinstance(instance, plcopen.transition):
   223                 if isinstance(instance, plcopen.transition):
   227                     self.GenerateSFCTransitions(instance, pou)
   224                     self.GenerateSFCTransition(instance, pou)
   228                     instances.append(instance)
   225                     instances.append(instance)
   229                 elif isinstance(instance, plcopen.selectionConvergence):
   226                 elif isinstance(instance, plcopen.selectionConvergence):
   230                     for connectionPointIn in instance.getConnectionPointIn():
   227                     for connectionPointIn in instance.getConnectionPointIn():
   231                         divergence_connections = connectionPointIn.getConnections()
   228                         divergence_connections = connectionPointIn.getConnections()
   232                         if len(divergence_connections) == 1:
   229                         if len(divergence_connections) == 1:
   233                             transitionLocalId = divergence_connections[0].getRefLocalId()
   230                             transitionLocalId = divergence_connections[0].getRefLocalId()
   234                             transition = pou.body.getContentInstance(transitionLocalId)
   231                             transition = pou.body.getContentInstance(transitionLocalId)
   235                             self.GenerateSFCTransitions(transition, pou)
   232                             self.GenerateSFCTransition(transition, pou)
       
   233                             instances.append(transition)
       
   234                 elif isinstance(instance, plcopen.simultaneousDivergence):
       
   235                     connectionPointIn = instance.getConnectionPointIn()
       
   236                     if connectionPointIn:
       
   237                         divergence_connections = connectionPointIn.getConnections()
       
   238                         if len(divergence_connections) == 1:
       
   239                             transitionLocalId = connections[0].getRefLocalId()
       
   240                             transition = pou.body.getContentInstance(transitionLocalId)
       
   241                             self.GenerateSFCTransition(transition, pou)
   236                             instances.append(transition)
   242                             instances.append(transition)
   237             for instance in instances:
   243             for instance in instances:
   238                 self.Transitions[instance]["targets"].append(jump_target)
   244                 if instance in self.SFCNetworks["Transitions"].keys():
   239     
   245                     self.SFCNetworks["Transitions"][instance]["to"].append(jump_target)
   240     def GenerateSFCActions(self, actionBlock, pou):
   246     
       
   247     def GenerateSFCStepActions(self, actionBlock, pou):
   241         connections = actionBlock.connectionPointIn.getConnections()
   248         connections = actionBlock.connectionPointIn.getConnections()
   242         if len(connections) == 1:
   249         if len(connections) == 1:
   243             stepLocalId = connections[0].getRefLocalId()
   250             stepLocalId = connections[0].getRefLocalId()
   244             step = pou.body.getContentInstance(stepLocalId)
   251             step = pou.body.getContentInstance(stepLocalId)
       
   252             self.GenerateSFCStep(step, pou)
   245             step_name = step.getName()
   253             step_name = step.getName()
   246             if step_name not in self.Steps:
   254             if step_name in self.SFCNetworks["Steps"].keys():
   247                 self.GenerateSFCSteps(step, pou)
       
   248             if step_name in self.Steps:
       
   249                 actions = actionBlock.getActions()
   255                 actions = actionBlock.getActions()
   250                 for action in actions:
   256                 for action in actions:
   251                     action_infos = {"qualifier" : action["qualifier"], "content" : ""}
   257                     action_infos = {"qualifier" : action["qualifier"], "content" : action["value"]}
   252                     if action["type"] == "inline":
   258                     if "duration" in action:
   253                         action_infos["content"] = action["value"]
   259                         action_infos["duration"] = action["duration"]
   254                     elif action["type"] == "reference":
   260                     if "indicator" in action:
   255                         actionContent = pou.getAction(action["value"])
   261                         action_infos["indicator"] = action["indicator"]
   256                         if actionContent:
   262                     if action["type"] == "reference":
   257                             actionType = actionContent.getBodyType()
   263                         self.GenerateSFCAction(action["value"], pou)
   258                             actionBody = actionContent.getBody()
   264                     self.SFCNetworks["Steps"][step_name]["actions"].append(action_infos)
   259                             if actionType in ["ST", "IL"]:
   265     
   260                                 action_infos["content"] = actionContent.getText()
   266     def GenerateSFCAction(self, action_name, pou):
   261                             elif actionType == "FBD":
   267         if action_name not in self.SFCNetworks["Actions"].keys():
   262                                 for instance in actionBody.getContentInstances():
   268             actionContent = pou.getAction(action_name)
   263                                     if isinstance(instance, plcopen.outVariable):
   269             if actionContent:
   264                                         var = instance.getExpression()
   270                 actionType = actionContent.getBodyType()
   265                                         connections = instance.connectionPointIn.getConnections()
   271                 actionBody = actionContent.getBody()
   266                                         if connections and len(connections) == 1:
   272                 if actionType in ["ST", "IL"]:
   267                                             expression = self.ComputeFBDExpression(actionBody, connections[0])
   273                     self.SFCNetworks["Actions"][action_name] = ReIndentText(actionContent.getText(), 4)
   268                                             action_infos["content"] = self.Program + "  %s := %s;"%(var, expression)
   274                 elif actionType == "FBD":
   269                                             self.Program = ""
   275                     for instance in actionBody.getContentInstances():
   270                             elif actionType == "LD":
   276                         if isinstance(instance, plcopen.outVariable):
   271                                 for instance in actionbody.getContentInstances():
   277                             var = instance.getExpression()
   272                                     if isinstance(instance, plcopen.coil):
   278                             connections = instance.connectionPointIn.getConnections()
   273                                         paths = self.GenerateLDPaths(instance, actionBody)
   279                             if connections and len(connections) == 1:
   274                                         variable = self.ExtractModifier(instance, instance.getVariable())
   280                                 expression = self.ComputeFBDExpression(actionBody, connections[0])
   275                                         expression = self.ComputeLDExpression(paths, True)
   281                                 self.SFCNetworks["Actions"][action_name] = self.Program + "  %s := %s;\n"%(var, expression)
   276                                         action_infos["content"] = self.Program + "  %s := %s;"%(variable, expression)
   282                                 self.Program = ""
   277                                         self.Program = ""
   283                 elif actionType == "LD":
   278                         else:
   284                     for instance in actionbody.getContentInstances():
   279                             action_infos["content"] = action["value"]
   285                         if isinstance(instance, plcopen.coil):
   280                     self.Steps[step_name]["actions"].append(action_infos)
   286                             paths = self.GenerateLDPaths(instance, actionBody)
   281                         
   287                             variable = self.ExtractModifier(instance, instance.getVariable())
   282     def GenerateSFCTransitions(self, transition, pou):
   288                             expression = self.ComputeLDExpression(paths, True)
   283         if transition not in self.Transitions:
   289                             self.SFCNetworks["Actions"][action_name] = self.Program + "  %s := %s;\n"%(variable, expression)
       
   290                             self.Program = ""
       
   291     
       
   292     def GenerateSFCTransition(self, transition, pou):
       
   293         if transition not in self.SFCNetworks["Transitions"].keys():
       
   294             steps = []
   284             connections = transition.connectionPointIn.getConnections()
   295             connections = transition.connectionPointIn.getConnections()
   285             if len(connections) == 1:
   296             if len(connections) == 1:
   286                 instanceLocalId = connections[0].getRefLocalId()
   297                 instanceLocalId = connections[0].getRefLocalId()
   287                 instance = pou.body.getContentInstance(instanceLocalId)
   298                 instance = pou.body.getContentInstance(instanceLocalId)
   288                 if isinstance(instance, plcopen.step):
   299                 if isinstance(instance, plcopen.step):
   289                     step_name = instance.getName()
   300                     self.GenerateSFCStep(instance, pou)
   290                     if step_name not in self.Steps:
   301                     steps.append(instance.getName())
   291                         self.GenerateSFCSteps(instance, pou)
       
   292                 elif isinstance(instance, plcopen.selectionDivergence):
   302                 elif isinstance(instance, plcopen.selectionDivergence):
   293                     divergence_connections = instance.connectionPointIn.getConnections()
   303                     divergence_connections = instance.connectionPointIn.getConnections()
   294                     if len(divergence_connections) == 1:
   304                     if len(divergence_connections) == 1:
   295                         stepLocalId = divergence_connections[0].getRefLocalId()
   305                         stepLocalId = divergence_connections[0].getRefLocalId()
   296                         divergence_instance = pou.body.getContentInstance(stepLocalId)
   306                         divergence_instance = pou.body.getContentInstance(stepLocalId)
   297                         if isinstance(divergence_instance, plcopen.step):
   307                         if isinstance(divergence_instance, plcopen.step):
   298                             step_name = divergence_instance.getName()
   308                             self.GenerateSFCStep(divergence_instance, pou)
   299                             if step_name not in self.Steps:
   309                             steps.append(divergence_instance.getName())
   300                                 self.GenerateSFCSteps(divergence_instance, pou)
   310             transition_infos = {"from": [], "to" : []}
   301                 if step_name in self.Steps:
   311             transitionValues = transition.getConditionContent()
   302                     transition_infos = {"targets" : []}
   312             if transitionValues["type"] == "inline":
   303                     transitionValues = transition.getConditionContent()
   313                 transition_infos["content"] = "\n    := %s;\n"%transitionValues["value"]
   304                     transition_infos["condition"] = transitionValues["value"]
   314             else:
   305                     if transitionValues["type"] == "inline":
   315                 transitionContent = pou.getTransition(transitionValues["value"])
   306                         transition_infos["compute"] = ""
   316                 transitionType = transitionContent.getBodyType()
   307                     else:
   317                 transitionBody = transitionContent.getBody()
   308                         transitionContent = pou.getTransition(transitionValues["value"])
   318                 if transitionType == "IL":
   309                         transitionType = transitionContent.getBodyType()
   319                     transition_infos["content"] = ":\n%s\n"%ReIndentText(transitionBody.getText(), 4)
   310                         transitionBody = transitionContent.getBody()
   320                 elif transitionType == "ST":
   311                         if transitionType in ["ST", "IL"]:
   321                     transition_infos["content"] = "\n%s\n"%ReIndentText(transitionBody.getText(), 4)
   312                             transition_infos["compute"] = "%s\n"%transitionContent.getText()
   322                 elif conditionType == "FBD":
   313                         elif conditionType == "FBD":
   323                     for instance in transitionBody.getContentInstances():
   314                             for instance in conditionBody.getContentInstances():
   324                         if isinstance(instance, plcopen.outVariable):
   315                                 if isinstance(instance, plcopen.outVariable):
   325                             connections = instance.connectionPointIn.getConnections()
   316                                     var = instance.getExpression()
   326                             if connections and len(connections) == 1:
   317                                     connections = instance.connectionPointIn.getConnections()
   327                                 expression = self.ComputeFBDExpression(actionBody, connections[0])
   318                                     if connections and len(connections) == 1:
   328                                 transition_infos["content"] = "\n    := %s;\n"%(var, expression)
   319                                         expression = self.ComputeFBDExpression(actionBody, connections[0])
   329                 elif actionType == "LD":
   320                                         transition_infos["compute"] = self.Program + ":= %s;\n"%(var, expression)
   330                     for instance in transitionbody.getContentInstances():
   321                                         self.Program = ""
   331                         if isinstance(instance, plcopen.coil):
   322                         elif actionType == "LD":
   332                             paths = self.GenerateLDPaths(instance, conditionBody)
   323                             for instance in conditionbody.getContentInstances():
   333                             expression = self.ComputeLDExpression(paths, True)
   324                                 if isinstance(instance, plcopen.coil):
   334                             transition_infos["content"] = "\n    := %s;\n"%expression
   325                                     paths = self.GenerateLDPaths(instance, conditionBody)
   335             for step_name in steps:
   326                                     variable = self.ExtractModifier(instance, instance.getVariable())
   336                 if step_name in self.SFCNetworks["Steps"].keys():
   327                                     expression = self.ComputeLDExpression(paths, True)
   337                     transition_infos["from"].append(step_name)
   328                                     transition_infos["compute"] = self.Program + ":= %s;\n"%(variable, expression)
   338                     self.SFCNetworks["Steps"][step_name]["transitions"].append(transition)
   329                                     self.Program = ""
   339             self.SFCNetworks["Transitions"][transition] = transition_infos
   330                     self.Steps[step_name]["transitions"].append(transition_infos)
   340 
   331                     self.Transitions[transition] = transition_infos
   341     def ComputeSFCStep(self, step_name):
   332 
   342         if step_name in self.SFCNetworks["Steps"].keys():
   333     def GenerateSFCStepOrder(self, name, path):
   343             step_infos = self.SFCNetworks["Steps"].pop(step_name)
   334         self.Order.append(name)
   344             if step_infos["initial"]:
   335         for transition in self.Steps[name]["transitions"]:
   345                 self.Program += "  INITIAL_STEP %s:\n"%step_name
   336             for target in transition["targets"]:
   346             else:
   337                 if target not in self.Order or target not in path:
   347                 self.Program += "  STEP %s:\n"%step_name
   338                     if target in self.Order:
   348             actions = []
   339                         self.Order.remove(target)
   349             for action_infos in step_infos["actions"]:
   340                     self.GenerateSFCStepOrder(target, path + [name])
   350                 actions.append(action_infos["content"])
   341 
   351                 self.Program += "    %(content)s(%(qualifier)s"%action_infos
       
   352                 if "duration" in action_infos:
       
   353                     self.Program += ", %(duration)s"%action_infos
       
   354                 if "indicator" in action_infos:
       
   355                     self.Program += ", %(indicator)s"%action_infos
       
   356                 self.Program += ");\n"
       
   357             self.Program += "  END_STEP\n\n"
       
   358             for action in actions:
       
   359                 self.ComputeSFCAction(action)
       
   360             for transition in step_infos["transitions"]:
       
   361                 self.ComputeSFCTransition(transition)
       
   362                 
       
   363     def ComputeSFCAction(self, action_name):
       
   364         if action_name in self.SFCNetworks["Actions"].keys():
       
   365             action_content = self.SFCNetworks["Actions"].pop(action_name)
       
   366             self.Program += "  ACTION %s:\n%s  END_ACTION\n\n"%(action_name, action_content)
       
   367     
       
   368     def ComputeSFCTransition(self, transition):
       
   369         if transition in self.SFCNetworks["Transitions"].keys():
       
   370             transition_infos = self.SFCNetworks["Transitions"].pop(transition)
       
   371             self.Program += "  TRANSITION FROM "
       
   372             if len(transition_infos["from"]) > 1:
       
   373                 self.Program += "(%s)"%", ".join(transition_infos["from"])
       
   374             else:
       
   375                 self.Program += "%s"%transition_infos["from"][0]
       
   376             self.Program += " TO "
       
   377             if len(transition_infos["to"]) > 1:
       
   378                 self.Program += "(%s)"%", ".join(transition_infos["to"])
       
   379             else:
       
   380                 self.Program += "%s"%transition_infos["to"][0]
       
   381             self.Program += transition_infos["content"]
       
   382             self.Program += "  END_TRANSITION\n\n"
       
   383             for step_name in transition_infos["to"]:
       
   384                 self.ComputeSFCStep(step_name)
       
   385         
   342     def ComputeLDExpression(self, paths, first = False):
   386     def ComputeLDExpression(self, paths, first = False):
   343         if type(paths) == TupleType:
   387         if type(paths) == TupleType:
   344             if None in paths:
   388             if None in paths:
   345                 return "TRUE"
   389                 return "TRUE"
   346             else:
   390             else:
   366                 elif edge.getValue() == "falling":
   410                 elif edge.getValue() == "falling":
   367                     return self.AddTrigger("F_TRIG", text)
   411                     return self.AddTrigger("F_TRIG", text)
   368         return text
   412         return text
   369     
   413     
   370     def AddTrigger(self, edge, text):
   414     def AddTrigger(self, edge, text):
   371         if ("VAR", False, False) not in self.Interface:
   415         if self.Interface[-1][0] != "VAR" or self.Interface[-1][1] or self.Interface[-1][2]:
   372             self.Interface[("VAR", False, False)] = {}
   416             self.Interface.append(("VAR", False, False, []))
   373         if type not in self.Interface[("VAR", False, False)]:
       
   374             self.Interface[("VAR", False, False)][edge] = []
       
   375         i = 1
   417         i = 1
   376         name = "%s%d"%(edge, i)
   418         name = "%s%d"%(edge, i)
   377         while name in self.Interface[("VAR", False, False)][edge]:
   419         while self.IsAlreadyDefined(name):
   378             i += 1
   420             i += 1
   379             name = "%s%d"%(edge, i)
   421             name = "%s%d"%(edge, i)
   380         self.Interface[("VAR", False, False)][edge].append(name)
   422         self.Interface[-1][3].append((edge, name))
   381         self.Program += "  %s(CLK := %s);\n"%(name, text)
   423         self.Program += "  %s(CLK := %s);\n"%(name, text)
   382         return "%s.Q"%name
   424         return "%s.Q"%name
   383     
   425     
   384     def GenerateSTProgram(self):
   426     def GenerateSTProgram(self):
   385         program = ""
   427         program = ""
   386         if "returnType" in self.Interface:
   428         if self.ReturnType:
   387             program += "%s %s : %s\n"%(self.Type, self.Name, self.Interface["returnType"])
   429             program += "%s %s : %s\n"%(self.Type, self.Name, self.ReturnType)
   388         else:
   430         else:
   389             program += "%s %s\n"%(self.Type, self.Name)
   431             program += "%s %s\n"%(self.Type, self.Name)
   390         for values, variables in self.Interface.items():
   432         for list_type, retain, constant, variables in self.Interface:
   391             if values != "returnType":
   433             program += "  %s"%list_type
   392                 program += "  %s"%values[0]
   434             if retain:
   393                 if values[1]:
   435                 program += " RETAIN"
   394                     program += " RETAIN"
   436             if constant:
   395                 if values[2]:
   437                 program += " CONSTANT"
   396                     program += " CONSTANT"
   438             program += "\n"
   397                 program += "\n"
   439             for var_type, var_name in variables:
   398                 for vartype, list in variables.items():
   440                 program += "    %s : %s;\n"%(var_name, var_type)
   399                     program += "    %s : %s;\n"%(", ".join(list), vartype)
   441             program += "  END_%s\n"%list_type
   400                 program += "  END_%s\n"%values[0]
       
   401         program += "\n"
   442         program += "\n"
   402         program += self.Program
   443         program += self.Program
   403         program += "END_%s\n\n"%self.Type
   444         program += "END_%s\n\n"%self.Type
   404         return program
   445         return program
   405     
   446