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 |
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")), |