PLCGenerator.py
changeset 2459 21164625b393
parent 2429 15f18dc8b56a
parent 2456 7373e3048167
child 2521 48ebcbe7f19b
equal deleted inserted replaced
2458:2a70d5240300 2459:21164625b393
    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: