PLCGenerator.py
branchpython3
changeset 3750 f62625418bff
parent 3704 c17fac18c663
child 3752 9f6f46dbe3ae
equal deleted inserted replaced
3749:fda6c1a37662 3750:f62625418bff
    21 # You should have received a copy of the GNU General Public License
    21 # You should have received a copy of the GNU General Public License
    22 # along with this program; if not, write to the Free Software
    22 # along with this program; if not, write to the Free Software
    23 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    23 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    24 
    24 
    25 
    25 
    26 from __future__ import absolute_import
    26 
    27 import re
    27 import re
    28 from functools import reduce
    28 from functools import reduce
    29 from six.moves import xrange
    29 from six.moves import xrange
    30 
    30 
    31 from plcopen import PLCOpenParser
    31 from plcopen import PLCOpenParser
    63         if line_num < len(lines):
    63         if line_num < len(lines):
    64             spaces = 0
    64             spaces = 0
    65             while lines[line_num][spaces] == " ":
    65             while lines[line_num][spaces] == " ":
    66                 spaces += 1
    66                 spaces += 1
    67             indent = ""
    67             indent = ""
    68             for dummy in xrange(spaces, nb_spaces):
    68             for dummy in range(spaces, nb_spaces):
    69                 indent += " "
    69                 indent += " "
    70             for line in lines:
    70             for line in lines:
    71                 if line != "":
    71                 if line != "":
    72                     compute += "%s%s\n" % (indent, line)
    72                     compute += "%s%s\n" % (indent, line)
    73                 else:
    73                 else:
   262             else:
   262             else:
   263                 raise PLCGenException(_("Undefined pou type \"%s\"") % pou_type)
   263                 raise PLCGenException(_("Undefined pou type \"%s\"") % pou_type)
   264 
   264 
   265     # Generate a POU defined and used in text
   265     # Generate a POU defined and used in text
   266     def GeneratePouProgramInText(self, text):
   266     def GeneratePouProgramInText(self, text):
   267         for pou_name in self.PouComputed.keys():
   267         for pou_name in list(self.PouComputed.keys()):
   268             model = re.compile("(?:^|[^0-9^A-Z])%s(?:$|[^0-9^A-Z])" % pou_name.upper())
   268             model = re.compile("(?:^|[^0-9^A-Z])%s(?:$|[^0-9^A-Z])" % pou_name.upper())
   269             if model.search(text) is not None:
   269             if model.search(text) is not None:
   270                 self.GeneratePouProgram(pou_name)
   270                 self.GeneratePouProgram(pou_name)
   271 
   271 
   272     # Generate a configuration from its model
   272     # Generate a configuration from its model
   470         # Generate data type declaration structure if there is at least one data
   470         # Generate data type declaration structure if there is at least one data
   471         # type defined
   471         # type defined
   472         if len(self.DatatypeComputed) > 0:
   472         if len(self.DatatypeComputed) > 0:
   473             self.Program += [("TYPE\n", ())]
   473             self.Program += [("TYPE\n", ())]
   474             # Generate every data types defined
   474             # Generate every data types defined
   475             for datatype_name in self.DatatypeComputed.keys():
   475             for datatype_name in list(self.DatatypeComputed.keys()):
   476                 log("Generate Data Type %s"%datatype_name)
   476                 log("Generate Data Type %s"%datatype_name)
   477                 self.GenerateDataType(datatype_name)
   477                 self.GenerateDataType(datatype_name)
   478             self.Program += [("END_TYPE\n\n", ())]
   478             self.Program += [("END_TYPE\n\n", ())]
   479         # Generate every POUs defined
   479         # Generate every POUs defined
   480         for pou_name in self.PouComputed.keys():
   480         for pou_name in list(self.PouComputed.keys()):
   481             log("Generate POU %s"%pou_name)
   481             log("Generate POU %s"%pou_name)
   482             self.GeneratePouProgram(pou_name)
   482             self.GeneratePouProgram(pou_name)
   483         if noconfig:
   483         if noconfig:
   484             return
   484             return
   485         # Generate every configurations defined
   485         # Generate every configurations defined
   893                         else:
   893                         else:
   894                             self.ConnectionTypes[variable.connectionPointIn] = itype
   894                             self.ConnectionTypes[variable.connectionPointIn] = itype
   895                             if connected is not None and connected not in self.ConnectionTypes:
   895                             if connected is not None and connected not in self.ConnectionTypes:
   896                                 for connection in self.ExtractRelatedConnections(connected):
   896                                 for connection in self.ExtractRelatedConnections(connected):
   897                                     self.ConnectionTypes[connection] = itype
   897                                     self.ConnectionTypes[connection] = itype
   898         for var_type, connections in undefined.items():
   898         for var_type, connections in list(undefined.items()):
   899             related = []
   899             related = []
   900             for connection in connections:
   900             for connection in connections:
   901                 connection_type = self.ConnectionTypes.get(connection)
   901                 connection_type = self.ConnectionTypes.get(connection)
   902                 if connection_type and not connection_type.startswith("ANY"):
   902                 if connection_type and not connection_type.startswith("ANY"):
   903                     var_type = connection_type
   903                     var_type = connection_type
  1053                             self.Program += [(instance.getvariable(), coil_info + ("reference",))]
  1053                             self.Program += [(instance.getvariable(), coil_info + ("reference",))]
  1054                             self.Program += [(" := ", ())] + expression + [(";\n", ())]
  1054                             self.Program += [(" := ", ())] + expression + [(";\n", ())]
  1055 
  1055 
  1056     def FactorizePaths(self, paths):
  1056     def FactorizePaths(self, paths):
  1057         same_paths = {}
  1057         same_paths = {}
  1058         uncomputed_index = range(len(paths))
  1058         uncomputed_index = list(range(len(paths)))
  1059         factorized_paths = []
  1059         factorized_paths = []
  1060         for num, path in enumerate(paths):
  1060         for num, path in enumerate(paths):
  1061             if isinstance(path, list):
  1061             if isinstance(path, list):
  1062                 if len(path) > 1:
  1062                 if len(path) > 1:
  1063                     str_path = str(path[-1:])
  1063                     str_path = str(path[-1:])
  1064                     same_paths.setdefault(str_path, [])
  1064                     same_paths.setdefault(str_path, [])
  1065                     same_paths[str_path].append((path[:-1], num))
  1065                     same_paths[str_path].append((path[:-1], num))
  1066             else:
  1066             else:
  1067                 factorized_paths.append(path)
  1067                 factorized_paths.append(path)
  1068                 uncomputed_index.remove(num)
  1068                 uncomputed_index.remove(num)
  1069         for same_path, elements in same_paths.items():
  1069         for same_path, elements in list(same_paths.items()):
  1070             if len(elements) > 1:
  1070             if len(elements) > 1:
  1071                 elements_paths = self.FactorizePaths([path for path, num in elements])
  1071                 elements_paths = self.FactorizePaths([path for path, num in elements])
  1072                 if len(elements_paths) > 1:
  1072                 if len(elements_paths) > 1:
  1073                     factorized_paths.append([tuple(elements_paths)] + eval(same_path))
  1073                     factorized_paths.append([tuple(elements_paths)] + eval(same_path))
  1074                 else:
  1074                 else:
  1450                 instances.append(body.getcontentInstance(instanceLocalId))
  1450                 instances.append(body.getcontentInstance(instanceLocalId))
  1451         return instances
  1451         return instances
  1452 
  1452 
  1453     def GenerateSFCStep(self, step, pou):
  1453     def GenerateSFCStep(self, step, pou):
  1454         step_name = step.getname()
  1454         step_name = step.getname()
  1455         if step_name not in self.SFCNetworks["Steps"].keys():
  1455         if step_name not in list(self.SFCNetworks["Steps"].keys()):
  1456             if step.getinitialStep():
  1456             if step.getinitialStep():
  1457                 self.InitialSteps.append(step_name)
  1457                 self.InitialSteps.append(step_name)
  1458             step_infos = {"id":          step.getlocalId(),
  1458             step_infos = {"id":          step.getlocalId(),
  1459                           "initial":     step.getinitialStep(),
  1459                           "initial":     step.getinitialStep(),
  1460                           "transitions": [],
  1460                           "transitions": [],
  1480                                 instances.append(transition)
  1480                                 instances.append(transition)
  1481                             elif isinstance(transition, SelectionConvergenceClass):
  1481                             elif isinstance(transition, SelectionConvergenceClass):
  1482                                 instances.extend(self.ExtractConvergenceInputs(transition, pou))
  1482                                 instances.extend(self.ExtractConvergenceInputs(transition, pou))
  1483                 for instance in instances:
  1483                 for instance in instances:
  1484                     self.GenerateSFCTransition(instance, pou)
  1484                     self.GenerateSFCTransition(instance, pou)
  1485                     if instance in self.SFCNetworks["Transitions"].keys():
  1485                     if instance in list(self.SFCNetworks["Transitions"].keys()):
  1486                         target_info = (self.TagName, "transition", instance.getlocalId(), "to", step_infos["id"])
  1486                         target_info = (self.TagName, "transition", instance.getlocalId(), "to", step_infos["id"])
  1487                         self.SFCNetworks["Transitions"][instance]["to"].append([(step_name, target_info)])
  1487                         self.SFCNetworks["Transitions"][instance]["to"].append([(step_name, target_info)])
  1488 
  1488 
  1489     def GenerateSFCJump(self, jump, pou):
  1489     def GenerateSFCJump(self, jump, pou):
  1490         jump_target = jump.gettargetName()
  1490         jump_target = jump.gettargetName()
  1514                             instances.append(transition)
  1514                             instances.append(transition)
  1515                         elif isinstance(transition, SelectionConvergenceClass):
  1515                         elif isinstance(transition, SelectionConvergenceClass):
  1516                             instances.extend(self.ExtractConvergenceInputs(transition, pou))
  1516                             instances.extend(self.ExtractConvergenceInputs(transition, pou))
  1517             for instance in instances:
  1517             for instance in instances:
  1518                 self.GenerateSFCTransition(instance, pou)
  1518                 self.GenerateSFCTransition(instance, pou)
  1519                 if instance in self.SFCNetworks["Transitions"].keys():
  1519                 if instance in list(self.SFCNetworks["Transitions"].keys()):
  1520                     target_info = (self.TagName, "jump", jump.getlocalId(), "target")
  1520                     target_info = (self.TagName, "jump", jump.getlocalId(), "target")
  1521                     self.SFCNetworks["Transitions"][instance]["to"].append([(jump_target, target_info)])
  1521                     self.SFCNetworks["Transitions"][instance]["to"].append([(jump_target, target_info)])
  1522 
  1522 
  1523     def GenerateSFCStepActions(self, actionBlock, pou):
  1523     def GenerateSFCStepActions(self, actionBlock, pou):
  1524         connections = actionBlock.connectionPointIn.getconnections()
  1524         connections = actionBlock.connectionPointIn.getconnections()
  1528             if isinstance(body, list):
  1528             if isinstance(body, list):
  1529                 body = body[0]
  1529                 body = body[0]
  1530             step = body.getcontentInstance(stepLocalId)
  1530             step = body.getcontentInstance(stepLocalId)
  1531             self.GenerateSFCStep(step, pou)
  1531             self.GenerateSFCStep(step, pou)
  1532             step_name = step.getname()
  1532             step_name = step.getname()
  1533             if step_name in self.SFCNetworks["Steps"].keys():
  1533             if step_name in list(self.SFCNetworks["Steps"].keys()):
  1534                 actions = actionBlock.getactions()
  1534                 actions = actionBlock.getactions()
  1535                 for i, action in enumerate(actions):
  1535                 for i, action in enumerate(actions):
  1536                     action_infos = {"id":        actionBlock.getlocalId(),
  1536                     action_infos = {"id":        actionBlock.getlocalId(),
  1537                                     "qualifier": action["qualifier"],
  1537                                     "qualifier": action["qualifier"],
  1538                                     "content":   action["value"],
  1538                                     "content":   action["value"],
  1553                             ("\n", ())], ())
  1553                             ("\n", ())], ())
  1554                         action_infos["content"] = action_name
  1554                         action_infos["content"] = action_name
  1555                     self.SFCNetworks["Steps"][step_name]["actions"].append(action_infos)
  1555                     self.SFCNetworks["Steps"][step_name]["actions"].append(action_infos)
  1556 
  1556 
  1557     def GenerateSFCAction(self, action_name, pou):
  1557     def GenerateSFCAction(self, action_name, pou):
  1558         if action_name not in self.SFCNetworks["Actions"].keys():
  1558         if action_name not in list(self.SFCNetworks["Actions"].keys()):
  1559             actionContent = pou.getaction(action_name)
  1559             actionContent = pou.getaction(action_name)
  1560             if actionContent is not None:
  1560             if actionContent is not None:
  1561                 previous_tagname = self.TagName
  1561                 previous_tagname = self.TagName
  1562                 self.TagName = ComputePouActionName(self.Name, action_name)
  1562                 self.TagName = ComputePouActionName(self.Name, action_name)
  1563                 self.ComputeProgram(actionContent)
  1563                 self.ComputeProgram(actionContent)
  1564                 self.SFCNetworks["Actions"][action_name] = (self.Program, (self.TagName, "name"))
  1564                 self.SFCNetworks["Actions"][action_name] = (self.Program, (self.TagName, "name"))
  1565                 self.Program = []
  1565                 self.Program = []
  1566                 self.TagName = previous_tagname
  1566                 self.TagName = previous_tagname
  1567 
  1567 
  1568     def GenerateSFCTransition(self, transition, pou):
  1568     def GenerateSFCTransition(self, transition, pou):
  1569         if transition not in self.SFCNetworks["Transitions"].keys():
  1569         if transition not in list(self.SFCNetworks["Transitions"].keys()):
  1570             steps = []
  1570             steps = []
  1571             connections = transition.connectionPointIn.getconnections()
  1571             connections = transition.connectionPointIn.getconnections()
  1572             if connections is not None and len(connections) == 1:
  1572             if connections is not None and len(connections) == 1:
  1573                 instanceLocalId = connections[0].getrefLocalId()
  1573                 instanceLocalId = connections[0].getrefLocalId()
  1574                 body = pou.getbody()
  1574                 body = pou.getbody()
  1637                         self.SFCComputedBlocks += self.Program
  1637                         self.SFCComputedBlocks += self.Program
  1638                         self.Program = []
  1638                         self.Program = []
  1639             for step in steps:
  1639             for step in steps:
  1640                 self.GenerateSFCStep(step, pou)
  1640                 self.GenerateSFCStep(step, pou)
  1641                 step_name = step.getname()
  1641                 step_name = step.getname()
  1642                 if step_name in self.SFCNetworks["Steps"].keys():
  1642                 if step_name in list(self.SFCNetworks["Steps"].keys()):
  1643                     transition_infos["from"].append([(step_name, (self.TagName, "transition", transition.getlocalId(), "from", step.getlocalId()))])
  1643                     transition_infos["from"].append([(step_name, (self.TagName, "transition", transition.getlocalId(), "from", step.getlocalId()))])
  1644                     self.SFCNetworks["Steps"][step_name]["transitions"].append(transition)
  1644                     self.SFCNetworks["Steps"][step_name]["transitions"].append(transition)
  1645 
  1645 
  1646     def ComputeSFCStep(self, step_name):
  1646     def ComputeSFCStep(self, step_name):
  1647         if step_name in self.SFCNetworks["Steps"].keys():
  1647         if step_name in list(self.SFCNetworks["Steps"].keys()):
  1648             step_infos = self.SFCNetworks["Steps"].pop(step_name)
  1648             step_infos = self.SFCNetworks["Steps"].pop(step_name)
  1649             self.Program += [(self.CurrentIndent, ())]
  1649             self.Program += [(self.CurrentIndent, ())]
  1650             if step_infos["initial"]:
  1650             if step_infos["initial"]:
  1651                 self.Program += [("INITIAL_", ())]
  1651                 self.Program += [("INITIAL_", ())]
  1652             self.Program += [("STEP ", ()),
  1652             self.Program += [("STEP ", ()),
  1677                 self.ComputeSFCAction(action)
  1677                 self.ComputeSFCAction(action)
  1678             for transition in step_infos["transitions"]:
  1678             for transition in step_infos["transitions"]:
  1679                 self.ComputeSFCTransition(transition)
  1679                 self.ComputeSFCTransition(transition)
  1680 
  1680 
  1681     def ComputeSFCAction(self, action_name):
  1681     def ComputeSFCAction(self, action_name):
  1682         if action_name in self.SFCNetworks["Actions"].keys():
  1682         if action_name in list(self.SFCNetworks["Actions"].keys()):
  1683             action_content, action_info = self.SFCNetworks["Actions"].pop(action_name)
  1683             action_content, action_info = self.SFCNetworks["Actions"].pop(action_name)
  1684             self.Program += [("%sACTION " % self.CurrentIndent, ()),
  1684             self.Program += [("%sACTION " % self.CurrentIndent, ()),
  1685                              (action_name, action_info),
  1685                              (action_name, action_info),
  1686                              (":\n", ())]
  1686                              (":\n", ())]
  1687             self.Program += action_content
  1687             self.Program += action_content
  1688             self.Program += [("%sEND_ACTION\n\n" % self.CurrentIndent, ())]
  1688             self.Program += [("%sEND_ACTION\n\n" % self.CurrentIndent, ())]
  1689 
  1689 
  1690     def ComputeSFCTransition(self, transition):
  1690     def ComputeSFCTransition(self, transition):
  1691         if transition in self.SFCNetworks["Transitions"].keys():
  1691         if transition in list(self.SFCNetworks["Transitions"].keys()):
  1692             transition_infos = self.SFCNetworks["Transitions"].pop(transition)
  1692             transition_infos = self.SFCNetworks["Transitions"].pop(transition)
  1693             self.Program += [("%sTRANSITION" % self.CurrentIndent, ())]
  1693             self.Program += [("%sTRANSITION" % self.CurrentIndent, ())]
  1694             if transition_infos["priority"] is not None:
  1694             if transition_infos["priority"] is not None:
  1695                 self.Program += [(" (PRIORITY := ", ()),
  1695                 self.Program += [(" (PRIORITY := ", ()),
  1696                                  ("%d" % transition_infos["priority"], (self.TagName, "transition", transition_infos["id"], "priority")),
  1696                                  ("%d" % transition_infos["priority"], (self.TagName, "transition", transition_infos["id"], "priority")),