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 from __future__ import absolute_import |
27 from types import * |
|
28 import re |
27 import re |
|
28 from functools import reduce |
|
29 from six.moves import xrange |
|
30 |
29 from plcopen import PLCOpenParser |
31 from plcopen import PLCOpenParser |
30 from plcopen.structures import * |
32 from plcopen.structures import * |
31 from plcopen.types_enums import * |
33 from plcopen.types_enums import * |
32 |
34 |
33 |
35 |
706 "16": None, |
708 "16": None, |
707 } |
709 } |
708 |
710 |
709 def ComputeConnectionTypes(self, pou): |
711 def ComputeConnectionTypes(self, pou): |
710 body = pou.getbody() |
712 body = pou.getbody() |
711 if isinstance(body, ListType): |
713 if isinstance(body, list): |
712 body = body[0] |
714 body = body[0] |
713 body_content = body.getcontent() |
715 body_content = body.getcontent() |
714 body_type = body_content.getLocalTag() |
716 body_type = body_content.getLocalTag() |
715 if body_type in ["FBD", "LD", "SFC"]: |
717 if body_type in ["FBD", "LD", "SFC"]: |
716 undefined_blocks = [] |
718 undefined_blocks = [] |
939 return var_name |
941 return var_name |
940 return None |
942 return None |
941 |
943 |
942 def ComputeProgram(self, pou): |
944 def ComputeProgram(self, pou): |
943 body = pou.getbody() |
945 body = pou.getbody() |
944 if isinstance(body, ListType): |
946 if isinstance(body, list): |
945 body = body[0] |
947 body = body[0] |
946 body_content = body.getcontent() |
948 body_content = body.getcontent() |
947 body_type = body_content.getLocalTag() |
949 body_type = body_content.getLocalTag() |
948 if body_type in ["IL", "ST"]: |
950 if body_type in ["IL", "ST"]: |
949 text = body_content.getanyText() |
951 text = body_content.getanyText() |
1023 _("Undefined block type \"{a1}\" in \"{a2}\" POU"). |
1025 _("Undefined block type \"{a1}\" in \"{a2}\" POU"). |
1024 format(a1=block_type, a2=self.Name)) |
1026 format(a1=block_type, a2=self.Name)) |
1025 try: |
1027 try: |
1026 self.GenerateBlock(instance, block_infos, body, None) |
1028 self.GenerateBlock(instance, block_infos, body, None) |
1027 except ValueError as e: |
1029 except ValueError as e: |
1028 raise PLCGenException(e.message) |
1030 raise PLCGenException(str(e)) |
1029 elif isinstance(instance, ConnectorClass): |
1031 elif isinstance(instance, ConnectorClass): |
1030 connector = instance.getname() |
1032 connector = instance.getname() |
1031 if self.ComputedConnectors.get(connector, None): |
1033 if self.ComputedConnectors.get(connector, None): |
1032 continue |
1034 continue |
1033 expression = self.ComputeExpression(body, instance.connectionPointIn.getconnections()) |
1035 expression = self.ComputeExpression(body, instance.connectionPointIn.getconnections()) |
1047 def FactorizePaths(self, paths): |
1049 def FactorizePaths(self, paths): |
1048 same_paths = {} |
1050 same_paths = {} |
1049 uncomputed_index = range(len(paths)) |
1051 uncomputed_index = range(len(paths)) |
1050 factorized_paths = [] |
1052 factorized_paths = [] |
1051 for num, path in enumerate(paths): |
1053 for num, path in enumerate(paths): |
1052 if isinstance(path, ListType): |
1054 if isinstance(path, list): |
1053 if len(path) > 1: |
1055 if len(path) > 1: |
1054 str_path = str(path[-1:]) |
1056 str_path = str(path[-1:]) |
1055 same_paths.setdefault(str_path, []) |
1057 same_paths.setdefault(str_path, []) |
1056 same_paths[str_path].append((path[:-1], num)) |
1058 same_paths[str_path].append((path[:-1], num)) |
1057 else: |
1059 else: |
1301 _("Undefined block type \"{a1}\" in \"{a2}\" POU"). |
1303 _("Undefined block type \"{a1}\" in \"{a2}\" POU"). |
1302 format(a1=block_type, a2=self.Name)) |
1304 format(a1=block_type, a2=self.Name)) |
1303 try: |
1305 try: |
1304 paths.append(str(self.GenerateBlock(next, block_infos, body, connection, order, to_inout))) |
1306 paths.append(str(self.GenerateBlock(next, block_infos, body, connection, order, to_inout))) |
1305 except ValueError as e: |
1307 except ValueError as e: |
1306 raise PLCGenException(e.message) |
1308 raise PLCGenException(str(e)) |
1307 elif isinstance(next, ContinuationClass): |
1309 elif isinstance(next, ContinuationClass): |
1308 name = next.getname() |
1310 name = next.getname() |
1309 computed_value = self.ComputedConnectors.get(name, None) |
1311 computed_value = self.ComputedConnectors.get(name, None) |
1310 if computed_value is not None: |
1312 if computed_value is not None: |
1311 paths.append(str(computed_value)) |
1313 paths.append(str(computed_value)) |
1337 factorized_paths = self.FactorizePaths(result) |
1339 factorized_paths = self.FactorizePaths(result) |
1338 if len(factorized_paths) > 1: |
1340 if len(factorized_paths) > 1: |
1339 paths.append([variable, tuple(factorized_paths)]) |
1341 paths.append([variable, tuple(factorized_paths)]) |
1340 else: |
1342 else: |
1341 paths.append([variable] + factorized_paths) |
1343 paths.append([variable] + factorized_paths) |
1342 elif isinstance(result[0], ListType): |
1344 elif isinstance(result[0], list): |
1343 paths.append([variable] + result[0]) |
1345 paths.append([variable] + result[0]) |
1344 elif result[0] is not None: |
1346 elif result[0] is not None: |
1345 paths.append([variable, result[0]]) |
1347 paths.append([variable, result[0]]) |
1346 else: |
1348 else: |
1347 paths.append(variable) |
1349 paths.append(variable) |
1348 elif isinstance(next, CoilClass): |
1350 elif isinstance(next, CoilClass): |
1349 paths.append(self.GeneratePaths(next.connectionPointIn.getconnections(), body, order)) |
1351 paths.append(self.GeneratePaths(next.connectionPointIn.getconnections(), body, order)) |
1350 return paths |
1352 return paths |
1351 |
1353 |
1352 def ComputePaths(self, paths, first=False): |
1354 def ComputePaths(self, paths, first=False): |
1353 if isinstance(paths, TupleType): |
1355 if isinstance(paths, tuple): |
1354 if None in paths: |
1356 if None in paths: |
1355 return [("TRUE", ())] |
1357 return [("TRUE", ())] |
1356 else: |
1358 else: |
1357 vars = [self.ComputePaths(path) for path in paths] |
1359 vars = [self.ComputePaths(path) for path in paths] |
1358 if first: |
1360 if first: |
1359 return JoinList([(" OR ", ())], vars) |
1361 return JoinList([(" OR ", ())], vars) |
1360 else: |
1362 else: |
1361 return [("(", ())] + JoinList([(" OR ", ())], vars) + [(")", ())] |
1363 return [("(", ())] + JoinList([(" OR ", ())], vars) + [(")", ())] |
1362 elif isinstance(paths, ListType): |
1364 elif isinstance(paths, list): |
1363 vars = [self.ComputePaths(path) for path in paths] |
1365 vars = [self.ComputePaths(path) for path in paths] |
1364 return JoinList([(" AND ", ())], vars) |
1366 return JoinList([(" AND ", ())], vars) |
1365 elif paths is None: |
1367 elif paths is None: |
1366 return [("TRUE", ())] |
1368 return [("TRUE", ())] |
1367 else: |
1369 else: |
1419 if connectionPointIn is not None: |
1421 if connectionPointIn is not None: |
1420 connections = connectionPointIn.getconnections() |
1422 connections = connectionPointIn.getconnections() |
1421 if connections is not None and len(connections) == 1: |
1423 if connections is not None and len(connections) == 1: |
1422 instanceLocalId = connections[0].getrefLocalId() |
1424 instanceLocalId = connections[0].getrefLocalId() |
1423 body = pou.getbody() |
1425 body = pou.getbody() |
1424 if isinstance(body, ListType): |
1426 if isinstance(body, list): |
1425 body = body[0] |
1427 body = body[0] |
1426 return body.getcontentInstance(instanceLocalId) |
1428 return body.getcontentInstance(instanceLocalId) |
1427 return None |
1429 return None |
1428 |
1430 |
1429 def ExtractConvergenceInputs(self, convergence, pou): |
1431 def ExtractConvergenceInputs(self, convergence, pou): |
1431 for connectionPointIn in convergence.getconnectionPointIn(): |
1433 for connectionPointIn in convergence.getconnectionPointIn(): |
1432 connections = connectionPointIn.getconnections() |
1434 connections = connectionPointIn.getconnections() |
1433 if connections is not None and len(connections) == 1: |
1435 if connections is not None and len(connections) == 1: |
1434 instanceLocalId = connections[0].getrefLocalId() |
1436 instanceLocalId = connections[0].getrefLocalId() |
1435 body = pou.getbody() |
1437 body = pou.getbody() |
1436 if isinstance(body, ListType): |
1438 if isinstance(body, list): |
1437 body = body[0] |
1439 body = body[0] |
1438 instances.append(body.getcontentInstance(instanceLocalId)) |
1440 instances.append(body.getcontentInstance(instanceLocalId)) |
1439 return instances |
1441 return instances |
1440 |
1442 |
1441 def GenerateSFCStep(self, step, pou): |
1443 def GenerateSFCStep(self, step, pou): |
1452 instances = [] |
1454 instances = [] |
1453 connections = step.connectionPointIn.getconnections() |
1455 connections = step.connectionPointIn.getconnections() |
1454 if connections is not None and len(connections) == 1: |
1456 if connections is not None and len(connections) == 1: |
1455 instanceLocalId = connections[0].getrefLocalId() |
1457 instanceLocalId = connections[0].getrefLocalId() |
1456 body = pou.getbody() |
1458 body = pou.getbody() |
1457 if isinstance(body, ListType): |
1459 if isinstance(body, list): |
1458 body = body[0] |
1460 body = body[0] |
1459 instance = body.getcontentInstance(instanceLocalId) |
1461 instance = body.getcontentInstance(instanceLocalId) |
1460 if isinstance(instance, TransitionClass): |
1462 if isinstance(instance, TransitionClass): |
1461 instances.append(instance) |
1463 instances.append(instance) |
1462 elif isinstance(instance, SelectionConvergenceClass): |
1464 elif isinstance(instance, SelectionConvergenceClass): |
1486 instances = [] |
1488 instances = [] |
1487 connections = jump.connectionPointIn.getconnections() |
1489 connections = jump.connectionPointIn.getconnections() |
1488 if connections is not None and len(connections) == 1: |
1490 if connections is not None and len(connections) == 1: |
1489 instanceLocalId = connections[0].getrefLocalId() |
1491 instanceLocalId = connections[0].getrefLocalId() |
1490 body = pou.getbody() |
1492 body = pou.getbody() |
1491 if isinstance(body, ListType): |
1493 if isinstance(body, list): |
1492 body = body[0] |
1494 body = body[0] |
1493 instance = body.getcontentInstance(instanceLocalId) |
1495 instance = body.getcontentInstance(instanceLocalId) |
1494 if isinstance(instance, TransitionClass): |
1496 if isinstance(instance, TransitionClass): |
1495 instances.append(instance) |
1497 instances.append(instance) |
1496 elif isinstance(instance, SelectionConvergenceClass): |
1498 elif isinstance(instance, SelectionConvergenceClass): |
1511 def GenerateSFCStepActions(self, actionBlock, pou): |
1513 def GenerateSFCStepActions(self, actionBlock, pou): |
1512 connections = actionBlock.connectionPointIn.getconnections() |
1514 connections = actionBlock.connectionPointIn.getconnections() |
1513 if connections is not None and len(connections) == 1: |
1515 if connections is not None and len(connections) == 1: |
1514 stepLocalId = connections[0].getrefLocalId() |
1516 stepLocalId = connections[0].getrefLocalId() |
1515 body = pou.getbody() |
1517 body = pou.getbody() |
1516 if isinstance(body, ListType): |
1518 if isinstance(body, list): |
1517 body = body[0] |
1519 body = body[0] |
1518 step = body.getcontentInstance(stepLocalId) |
1520 step = body.getcontentInstance(stepLocalId) |
1519 self.GenerateSFCStep(step, pou) |
1521 self.GenerateSFCStep(step, pou) |
1520 step_name = step.getname() |
1522 step_name = step.getname() |
1521 if step_name in self.SFCNetworks["Steps"].keys(): |
1523 if step_name in self.SFCNetworks["Steps"].keys(): |
1558 steps = [] |
1560 steps = [] |
1559 connections = transition.connectionPointIn.getconnections() |
1561 connections = transition.connectionPointIn.getconnections() |
1560 if connections is not None and len(connections) == 1: |
1562 if connections is not None and len(connections) == 1: |
1561 instanceLocalId = connections[0].getrefLocalId() |
1563 instanceLocalId = connections[0].getrefLocalId() |
1562 body = pou.getbody() |
1564 body = pou.getbody() |
1563 if isinstance(body, ListType): |
1565 if isinstance(body, list): |
1564 body = body[0] |
1566 body = body[0] |
1565 instance = body.getcontentInstance(instanceLocalId) |
1567 instance = body.getcontentInstance(instanceLocalId) |
1566 if isinstance(instance, StepClass): |
1568 if isinstance(instance, StepClass): |
1567 steps.append(instance) |
1569 steps.append(instance) |
1568 elif isinstance(instance, SelectionDivergenceClass): |
1570 elif isinstance(instance, SelectionDivergenceClass): |
1613 _("Transition \"%s\" body must contain an output variable or coil referring to its name") |
1615 _("Transition \"%s\" body must contain an output variable or coil referring to its name") |
1614 % transitionValues["value"]) |
1616 % transitionValues["value"]) |
1615 self.TagName = previous_tagname |
1617 self.TagName = previous_tagname |
1616 elif transitionValues["type"] == "connection": |
1618 elif transitionValues["type"] == "connection": |
1617 body = pou.getbody() |
1619 body = pou.getbody() |
1618 if isinstance(body, ListType): |
1620 if isinstance(body, list): |
1619 body = body[0] |
1621 body = body[0] |
1620 connections = transitionValues["value"].getconnections() |
1622 connections = transitionValues["value"].getconnections() |
1621 if connections is not None: |
1623 if connections is not None: |
1622 expression = self.ComputeExpression(body, connections) |
1624 expression = self.ComputeExpression(body, connections) |
1623 if expression is not None: |
1625 if expression is not None: |