plcopen/plcopen.py
changeset 1736 7e61baa047f0
parent 1734 750eeb7230a1
child 1739 ec153828ded2
equal deleted inserted replaced
1735:c02818d7e29f 1736:7e61baa047f0
    57     ("P1", False), ("SD", True), ("DS", True), ("SL", True)])
    57     ("P1", False), ("SD", True), ("DS", True), ("SL", True)])
    58 
    58 
    59 
    59 
    60 FILTER_ADDRESS_MODEL = "(%%[IQM](?:[XBWDL])?)(%s)((?:\.[0-9]+)*)"
    60 FILTER_ADDRESS_MODEL = "(%%[IQM](?:[XBWDL])?)(%s)((?:\.[0-9]+)*)"
    61 
    61 
       
    62 
    62 def update_address(address, address_model, new_leading):
    63 def update_address(address, address_model, new_leading):
    63     result = address_model.match(address)
    64     result = address_model.match(address)
    64     if result is None:
    65     if result is None:
    65         return address
    66         return address
    66     groups = result.groups()
    67     groups = result.groups()
    67     return groups[0] + new_leading + groups[2]
    68     return groups[0] + new_leading + groups[2]
    68 
    69 
       
    70 
    69 def _init_and_compare(function, v1, v2):
    71 def _init_and_compare(function, v1, v2):
    70     if v1 is None:
    72     if v1 is None:
    71         return v2
    73         return v2
    72     if v2 is not None:
    74     if v2 is not None:
    73         return function(v1, v2)
    75         return function(v1, v2)
    74     return v1
    76     return v1
    75 
    77 
    76 """
    78 
    77 Helper class for bounding_box calculation
       
    78 """
       
    79 class rect:
    79 class rect:
       
    80     """
       
    81     Helper class for bounding_box calculation
       
    82     """
    80 
    83 
    81     def __init__(self, x=None, y=None, width=None, height=None):
    84     def __init__(self, x=None, y=None, width=None, height=None):
    82         self.x_min = x
    85         self.x_min = x
    83         self.x_max = None
    86         self.x_max = None
    84         self.y_min = y
    87         self.y_min = y
   106             width = self.x_max - self.x_min
   109             width = self.x_max - self.x_min
   107         if self.y_min is not None and self.y_max is not None:
   110         if self.y_min is not None and self.y_max is not None:
   108             height = self.y_max - self.y_min
   111             height = self.y_max - self.y_min
   109         return self.x_min, self.y_min, width, height
   112         return self.x_min, self.y_min, width, height
   110 
   113 
       
   114 
   111 def TextLenInRowColumn(text):
   115 def TextLenInRowColumn(text):
   112     if text == "":
   116     if text == "":
   113         return (0, 0)
   117         return (0, 0)
   114     lines = text.split("\n")
   118     lines = text.split("\n")
   115     return len(lines) - 1, len(lines[-1])
   119     return len(lines) - 1, len(lines[-1])
       
   120 
   116 
   121 
   117 def CompilePattern(criteria):
   122 def CompilePattern(criteria):
   118     flag = 0 if criteria["case_sensitive"] else re.IGNORECASE
   123     flag = 0 if criteria["case_sensitive"] else re.IGNORECASE
   119     find_pattern = criteria["find_pattern"]
   124     find_pattern = criteria["find_pattern"]
   120     if not criteria["regular_expression"]:
   125     if not criteria["regular_expression"]:
   121         find_pattern = re.escape(find_pattern)
   126         find_pattern = re.escape(find_pattern)
   122     criteria["pattern"] = re.compile(find_pattern, flag)
   127     criteria["pattern"] = re.compile(find_pattern, flag)
       
   128 
   123 
   129 
   124 def TestTextElement(text, criteria):
   130 def TestTextElement(text, criteria):
   125     lines = text.splitlines()
   131     lines = text.splitlines()
   126     test_result = []
   132     test_result = []
   127     result = criteria["pattern"].search(text)
   133     result = criteria["pattern"].search(text)
   132         test_result.append((start, end, "\n".join(lines[start[0]:end[0] + 1])))
   138         test_result.append((start, end, "\n".join(lines[start[0]:end[0] + 1])))
   133         result = criteria["pattern"].search(text, result.end())
   139         result = criteria["pattern"].search(text, result.end())
   134         if result is not None and prev_pos==result.endpos:
   140         if result is not None and prev_pos==result.endpos:
   135             break
   141             break
   136     return test_result
   142     return test_result
       
   143 
   137 
   144 
   138 def TextMatched(str1, str2):
   145 def TextMatched(str1, str2):
   139     return str1 and str2 and (str1.upper() == str2.upper())
   146     return str1 and str2 and (str1.upper() == str2.upper())
   140 
   147 
   141 PLCOpenParser = GenerateParserFromXSD(paths.AbsNeighbourFile(__file__, "tc6_xml_v201.xsd"))
   148 PLCOpenParser = GenerateParserFromXSD(paths.AbsNeighbourFile(__file__, "tc6_xml_v201.xsd"))
   163     <configurations/>
   170     <configurations/>
   164   </instances>
   171   </instances>
   165 </project>
   172 </project>
   166 """
   173 """
   167 
   174 
       
   175 
   168 def LOAD_POU_INSTANCES_PROJECT_TEMPLATE(body_type):
   176 def LOAD_POU_INSTANCES_PROJECT_TEMPLATE(body_type):
   169     return LOAD_POU_PROJECT_TEMPLATE % """
   177     return LOAD_POU_PROJECT_TEMPLATE % """
   170 <pou name="paste_pou" pouType="program">
   178 <pou name="paste_pou" pouType="program">
   171   <body>
   179   <body>
   172     <%(body_type)s>%%s</%(body_type)s>
   180     <%(body_type)s>%%s</%(body_type)s>
   186 ResourceInstancesXpath = PLCOpen_XPath("ppx:pouInstance | ppx:task/ppx:pouInstance")
   194 ResourceInstancesXpath = PLCOpen_XPath("ppx:pouInstance | ppx:task/ppx:pouInstance")
   187 TransitionsConditionXPath = PLCOpen_XPath("ppx:types/ppx:pous/ppx:pou/ppx:body/*/ppx:transition/ppx:condition")
   195 TransitionsConditionXPath = PLCOpen_XPath("ppx:types/ppx:pous/ppx:pou/ppx:body/*/ppx:transition/ppx:condition")
   188 ConditionConnectionsXPath = PLCOpen_XPath("ppx:connection")
   196 ConditionConnectionsXPath = PLCOpen_XPath("ppx:connection")
   189 ActionBlocksXPath = PLCOpen_XPath("ppx:types/ppx:pous/ppx:pou/ppx:body/*/ppx:actionBlock")
   197 ActionBlocksXPath = PLCOpen_XPath("ppx:types/ppx:pous/ppx:pou/ppx:body/*/ppx:actionBlock")
   190 ActionBlocksConnectionPointOutXPath = PLCOpen_XPath("ppx:connectionPointOut")
   198 ActionBlocksConnectionPointOutXPath = PLCOpen_XPath("ppx:connectionPointOut")
       
   199 
   191 
   200 
   192 def LoadProjectXML(project_xml):
   201 def LoadProjectXML(project_xml):
   193     project_xml = project_xml.replace(
   202     project_xml = project_xml.replace(
   194         "http://www.plcopen.org/xml/tc6.xsd",
   203         "http://www.plcopen.org/xml/tc6.xsd",
   195         "http://www.plcopen.org/xml/tc6_0201")
   204         "http://www.plcopen.org/xml/tc6_0201")
   264         return tree, error
   273         return tree, error
   265 
   274 
   266     except Exception, e:
   275     except Exception, e:
   267         return None, e.message
   276         return None, e.message
   268 
   277 
       
   278 
   269 def LoadProject(filepath):
   279 def LoadProject(filepath):
   270     project_file = open(filepath)
   280     project_file = open(filepath)
   271     project_xml = project_file.read()
   281     project_xml = project_file.read()
   272     project_file.close()
   282     project_file.close()
   273     return LoadProjectXML(project_xml)
   283     return LoadProjectXML(project_xml)
   274 
   284 
   275 project_pou_xpath = PLCOpen_XPath("/ppx:project/ppx:types/ppx:pous/ppx:pou")
   285 project_pou_xpath = PLCOpen_XPath("/ppx:project/ppx:types/ppx:pous/ppx:pou")
       
   286 
       
   287 
   276 def LoadPou(xml_string):
   288 def LoadPou(xml_string):
   277     root, error = LoadProjectXML(LOAD_POU_PROJECT_TEMPLATE % xml_string)
   289     root, error = LoadProjectXML(LOAD_POU_PROJECT_TEMPLATE % xml_string)
   278     return project_pou_xpath(root)[0], error
   290     return project_pou_xpath(root)[0], error
   279 
   291 
   280 project_pou_instances_xpath = {
   292 project_pou_instances_xpath = {
   281     body_type: PLCOpen_XPath(
   293     body_type: PLCOpen_XPath(
   282         "/ppx:project/ppx:types/ppx:pous/ppx:pou[@name='paste_pou']/ppx:body/ppx:%s/*" % body_type)
   294         "/ppx:project/ppx:types/ppx:pous/ppx:pou[@name='paste_pou']/ppx:body/ppx:%s/*" % body_type)
   283     for body_type in ["FBD", "LD", "SFC"]}
   295     for body_type in ["FBD", "LD", "SFC"]}
       
   296 
       
   297 
   284 def LoadPouInstances(xml_string, body_type):
   298 def LoadPouInstances(xml_string, body_type):
   285     root, error = LoadProjectXML(
   299     root, error = LoadProjectXML(
   286         LOAD_POU_INSTANCES_PROJECT_TEMPLATE(body_type) % xml_string)
   300         LOAD_POU_INSTANCES_PROJECT_TEMPLATE(body_type) % xml_string)
   287     return project_pou_instances_xpath[body_type](root), error
   301     return project_pou_instances_xpath[body_type](root), error
       
   302 
   288 
   303 
   289 def SaveProject(project, filepath):
   304 def SaveProject(project, filepath):
   290     project_file = open(filepath, 'w')
   305     project_file = open(filepath, 'w')
   291     project_file.write(etree.tostring(
   306     project_file.write(etree.tostring(
   292         project,
   307         project,
   623         elif language == "SFC":
   638         elif language == "SFC":
   624             return self.sfc.scaling.getx(), self.sfc.scaling.gety()
   639             return self.sfc.scaling.getx(), self.sfc.scaling.gety()
   625         return 0, 0
   640         return 0, 0
   626     setattr(cls, "getscaling", getscaling)
   641     setattr(cls, "getscaling", getscaling)
   627 
   642 
       
   643 
   628 def _Search(attributes, criteria, parent_infos):
   644 def _Search(attributes, criteria, parent_infos):
   629     search_result = []
   645     search_result = []
   630     for attr, value in attributes:
   646     for attr, value in attributes:
   631         if value is not None:
   647         if value is not None:
   632             search_result.extend([(tuple(parent_infos + [attr]),) + result for result in TestTextElement(value, criteria)])
   648             search_result.extend([(tuple(parent_infos + [attr]),) + result for result in TestTextElement(value, criteria)])
   633     return search_result
   649     return search_result
       
   650 
   634 
   651 
   635 def _updateConfigurationResourceElementName(self, old_name, new_name):
   652 def _updateConfigurationResourceElementName(self, old_name, new_name):
   636     for varlist in self.getglobalVars():
   653     for varlist in self.getglobalVars():
   637         for var in varlist.getvariable():
   654         for var in varlist.getvariable():
   638             var_address = var.getaddress()
   655             var_address = var.getaddress()
   640                 if TextMatched(var_address, old_name):
   657                 if TextMatched(var_address, old_name):
   641                     var.setaddress(new_name)
   658                     var.setaddress(new_name)
   642                 if TextMatched(var.getname(), old_name):
   659                 if TextMatched(var.getname(), old_name):
   643                     var.setname(new_name)
   660                     var.setname(new_name)
   644 
   661 
       
   662 
   645 def _updateConfigurationResourceElementAddress(self, address_model, new_leading):
   663 def _updateConfigurationResourceElementAddress(self, address_model, new_leading):
   646     for varlist in self.getglobalVars():
   664     for varlist in self.getglobalVars():
   647         for var in varlist.getvariable():
   665         for var in varlist.getvariable():
   648             var_address = var.getaddress()
   666             var_address = var.getaddress()
   649             if var_address is not None:
   667             if var_address is not None:
   650                 var.setaddress(update_address(var_address, address_model, new_leading))
   668                 var.setaddress(update_address(var_address, address_model, new_leading))
   651 
   669 
       
   670 
   652 def _removeConfigurationResourceVariableByAddress(self, address):
   671 def _removeConfigurationResourceVariableByAddress(self, address):
   653     for varlist in self.getglobalVars():
   672     for varlist in self.getglobalVars():
   654         variables = varlist.getvariable()
   673         variables = varlist.getvariable()
   655         for i in xrange(len(variables)-1, -1, -1):
   674         for i in xrange(len(variables)-1, -1, -1):
   656             if variables[i].getaddress() == address:
   675             if variables[i].getaddress() == address:
   657                 variables.remove(variables[i])
   676                 variables.remove(variables[i])
       
   677 
   658 
   678 
   659 def _removeConfigurationResourceVariableByFilter(self, address_model):
   679 def _removeConfigurationResourceVariableByFilter(self, address_model):
   660     for varlist in self.getglobalVars():
   680     for varlist in self.getglobalVars():
   661         variables = varlist.getvariable()
   681         variables = varlist.getvariable()
   662         for i in xrange(len(variables)-1, -1, -1):
   682         for i in xrange(len(variables)-1, -1, -1):
   663             var_address = variables[i].getaddress()
   683             var_address = variables[i].getaddress()
   664             if var_address is not None:
   684             if var_address is not None:
   665                 result = address_model.match(var_address)
   685                 result = address_model.match(var_address)
   666                 if result is not None:
   686                 if result is not None:
   667                     variables.remove(variables[i])
   687                     variables.remove(variables[i])
       
   688 
   668 
   689 
   669 def _SearchInConfigurationResource(self, criteria, parent_infos=[]):
   690 def _SearchInConfigurationResource(self, criteria, parent_infos=[]):
   670     search_result = _Search([("name", self.getname())], criteria, parent_infos)
   691     search_result = _Search([("name", self.getname())], criteria, parent_infos)
   671     var_number = 0
   692     var_number = 0
   672     for varlist in self.getglobalVars():
   693     for varlist in self.getglobalVars():
   934         for pou in self.pous.getpou():
   955         for pou in self.pous.getpou():
   935             search_result.extend(pou.Search(criteria, parent_infos))
   956             search_result.extend(pou.Search(criteria, parent_infos))
   936         return search_result
   957         return search_result
   937     setattr(cls, "Search", Search)
   958     setattr(cls, "Search", Search)
   938 
   959 
       
   960 
   939 def _updateBaseTypeElementName(self, old_name, new_name):
   961 def _updateBaseTypeElementName(self, old_name, new_name):
   940     self.baseType.updateElementName(old_name, new_name)
   962     self.baseType.updateElementName(old_name, new_name)
   941 
   963 
   942 cls = PLCOpenParser.GetElementClass("dataType", "dataTypes")
   964 cls = PLCOpenParser.GetElementClass("dataType", "dataTypes")
   943 if cls:
   965 if cls:
  1004                                           ("upper", dimension.getupper())],
  1026                                           ("upper", dimension.getupper())],
  1005                                          criteria, parent_infos + ["range", i]))
  1027                                          criteria, parent_infos + ["range", i]))
  1006         return search_result
  1028         return search_result
  1007     setattr(cls, "Search", Search)
  1029     setattr(cls, "Search", Search)
  1008 
  1030 
       
  1031 
  1009 def _SearchInSubrange(self, criteria, parent_infos=[]):
  1032 def _SearchInSubrange(self, criteria, parent_infos=[]):
  1010     search_result = self.baseType.Search(criteria, parent_infos)
  1033     search_result = self.baseType.Search(criteria, parent_infos)
  1011     search_result.extend(_Search([("lower", self.range.getlower()),
  1034     search_result.extend(_Search([("lower", self.range.getlower()),
  1012                                   ("upper", self.range.getupper())],
  1035                                   ("upper", self.range.getupper())],
  1013                                  criteria, parent_infos))
  1036                                  criteria, parent_infos))
  1036         for i, value in enumerate(enumerated_datatype_values_xpath(self)):
  1059         for i, value in enumerate(enumerated_datatype_values_xpath(self)):
  1037             for result in TestTextElement(value.getname(), criteria):
  1060             for result in TestTextElement(value.getname(), criteria):
  1038                 search_result.append((tuple(parent_infos + ["value", i]),) + result)
  1061                 search_result.append((tuple(parent_infos + ["value", i]),) + result)
  1039         return search_result
  1062         return search_result
  1040     setattr(cls, "Search", Search)
  1063     setattr(cls, "Search", Search)
       
  1064 
  1041 
  1065 
  1042 def _getvariableTypeinfos(variable_type):
  1066 def _getvariableTypeinfos(variable_type):
  1043     type_content = variable_type.getcontent()
  1067     type_content = variable_type.getcontent()
  1044     type_content_type = type_content.getLocalTag()
  1068     type_content_type = type_content.getLocalTag()
  1045     if type_content_type == "derived":
  1069     if type_content_type == "derived":
  1448             for transition in self.gettransitionList():
  1472             for transition in self.gettransitionList():
  1449                 search_result.extend(transition.Search(criteria, parent_infos))
  1473                 search_result.extend(transition.Search(criteria, parent_infos))
  1450         return search_result
  1474         return search_result
  1451     setattr(cls, "Search", Search)
  1475     setattr(cls, "Search", Search)
  1452 
  1476 
       
  1477 
  1453 def setbodyType(self, body_type):
  1478 def setbodyType(self, body_type):
  1454     if body_type in ["IL", "ST", "LD", "FBD", "SFC"]:
  1479     if body_type in ["IL", "ST", "LD", "FBD", "SFC"]:
  1455         self.body.setcontent(PLCOpenParser.CreateElement(body_type, "body"))
  1480         self.body.setcontent(PLCOpenParser.CreateElement(body_type, "body"))
  1456     else:
  1481     else:
  1457         raise ValueError, "%s isn't a valid body type!" % type
  1482         raise ValueError, "%s isn't a valid body type!" % type
  1458 
  1483 
       
  1484 
  1459 def getbodyType(self):
  1485 def getbodyType(self):
  1460     return self.body.getcontent().getLocalTag()
  1486     return self.body.getcontent().getLocalTag()
  1461 
  1487 
       
  1488 
  1462 def resetexecutionOrder(self):
  1489 def resetexecutionOrder(self):
  1463     self.body.resetexecutionOrder()
  1490     self.body.resetexecutionOrder()
  1464 
  1491 
       
  1492 
  1465 def compileexecutionOrder(self):
  1493 def compileexecutionOrder(self):
  1466     self.body.compileexecutionOrder()
  1494     self.body.compileexecutionOrder()
  1467 
  1495 
       
  1496 
  1468 def setelementExecutionOrder(self, instance, new_executionOrder):
  1497 def setelementExecutionOrder(self, instance, new_executionOrder):
  1469     self.body.setelementExecutionOrder(instance, new_executionOrder)
  1498     self.body.setelementExecutionOrder(instance, new_executionOrder)
  1470 
  1499 
       
  1500 
  1471 def addinstance(self, instance):
  1501 def addinstance(self, instance):
  1472     self.body.appendcontentInstance(instance)
  1502     self.body.appendcontentInstance(instance)
  1473 
  1503 
       
  1504 
  1474 def getinstances(self):
  1505 def getinstances(self):
  1475     return self.body.getcontentInstances()
  1506     return self.body.getcontentInstances()
  1476 
  1507 
       
  1508 
  1477 def getinstance(self, id):
  1509 def getinstance(self, id):
  1478     return self.body.getcontentInstance(id)
  1510     return self.body.getcontentInstance(id)
  1479 
  1511 
       
  1512 
  1480 def getrandomInstance(self, exclude):
  1513 def getrandomInstance(self, exclude):
  1481     return self.body.getcontentRandomInstance(exclude)
  1514     return self.body.getcontentRandomInstance(exclude)
  1482 
  1515 
       
  1516 
  1483 def getinstanceByName(self, name):
  1517 def getinstanceByName(self, name):
  1484     return self.body.getcontentInstanceByName(name)
  1518     return self.body.getcontentInstanceByName(name)
  1485 
  1519 
       
  1520 
  1486 def removeinstance(self, id):
  1521 def removeinstance(self, id):
  1487     self.body.removecontentInstance(id)
  1522     self.body.removecontentInstance(id)
  1488 
  1523 
       
  1524 
  1489 def settext(self, text):
  1525 def settext(self, text):
  1490     self.body.settext(text)
  1526     self.body.settext(text)
  1491 
  1527 
       
  1528 
  1492 def gettext(self):
  1529 def gettext(self):
  1493     return self.body.gettext()
  1530     return self.body.gettext()
       
  1531 
  1494 
  1532 
  1495 def hasblock(self, name=None, block_type=None):
  1533 def hasblock(self, name=None, block_type=None):
  1496     if self.getbodyType() in ["FBD", "LD", "SFC"]:
  1534     if self.getbodyType() in ["FBD", "LD", "SFC"]:
  1497         for instance in self.getinstances():
  1535         for instance in self.getinstances():
  1498             if (isinstance(instance, PLCOpenParser.GetElementClass("block", "fbdObjects")) and
  1536             if (isinstance(instance, PLCOpenParser.GetElementClass("block", "fbdObjects")) and
  1500                 return True
  1538                 return True
  1501     elif block_type is not None:
  1539     elif block_type is not None:
  1502         return self.body.hasblock(block_type)
  1540         return self.body.hasblock(block_type)
  1503     return False
  1541     return False
  1504 
  1542 
       
  1543 
  1505 def updateElementName(self, old_name, new_name):
  1544 def updateElementName(self, old_name, new_name):
  1506     self.body.updateElementName(old_name, new_name)
  1545     self.body.updateElementName(old_name, new_name)
       
  1546 
  1507 
  1547 
  1508 def updateElementAddress(self, address_model, new_leading):
  1548 def updateElementAddress(self, address_model, new_leading):
  1509     self.body.updateElementAddress(address_model, new_leading)
  1549     self.body.updateElementAddress(address_model, new_leading)
  1510 
  1550 
  1511 
  1551 
  1744             for element in self.content.getcontent():
  1784             for element in self.content.getcontent():
  1745                 search_result.extend(element.Search(criteria, parent_infos))
  1785                 search_result.extend(element.Search(criteria, parent_infos))
  1746         return search_result
  1786         return search_result
  1747     setattr(cls, "Search", Search)
  1787     setattr(cls, "Search", Search)
  1748 
  1788 
       
  1789 
  1749 def getx(self):
  1790 def getx(self):
  1750     return self.position.getx()
  1791     return self.position.getx()
  1751 
  1792 
       
  1793 
  1752 def gety(self):
  1794 def gety(self):
  1753     return self.position.gety()
  1795     return self.position.gety()
  1754 
  1796 
       
  1797 
  1755 def setx(self, x):
  1798 def setx(self, x):
  1756     self.position.setx(x)
  1799     self.position.setx(x)
  1757 
  1800 
       
  1801 
  1758 def sety(self, y):
  1802 def sety(self, y):
  1759     self.position.sety(y)
  1803     self.position.sety(y)
  1760 
  1804 
       
  1805 
  1761 def _getBoundingBox(self):
  1806 def _getBoundingBox(self):
  1762     return rect(self.getx(), self.gety(), self.getwidth(), self.getheight())
  1807     return rect(self.getx(), self.gety(), self.getwidth(), self.getheight())
       
  1808 
  1763 
  1809 
  1764 def _getConnectionsBoundingBox(connectionPointIn):
  1810 def _getConnectionsBoundingBox(connectionPointIn):
  1765     bbox = rect()
  1811     bbox = rect()
  1766     connections = connectionPointIn.getconnections()
  1812     connections = connectionPointIn.getconnections()
  1767     if connections is not None:
  1813     if connections is not None:
  1768         for connection in connections:
  1814         for connection in connections:
  1769             for x, y in connection.getpoints():
  1815             for x, y in connection.getpoints():
  1770                 bbox.update(x, y)
  1816                 bbox.update(x, y)
  1771     return bbox
  1817     return bbox
  1772 
  1818 
       
  1819 
  1773 def _getBoundingBoxSingle(self):
  1820 def _getBoundingBoxSingle(self):
  1774     bbox = _getBoundingBox(self)
  1821     bbox = _getBoundingBox(self)
  1775     if self.connectionPointIn is not None:
  1822     if self.connectionPointIn is not None:
  1776         bbox.union(_getConnectionsBoundingBox(self.connectionPointIn))
  1823         bbox.union(_getConnectionsBoundingBox(self.connectionPointIn))
  1777     return bbox
  1824     return bbox
  1778 
  1825 
       
  1826 
  1779 def _getBoundingBoxMultiple(self):
  1827 def _getBoundingBoxMultiple(self):
  1780     bbox = _getBoundingBox(self)
  1828     bbox = _getBoundingBox(self)
  1781     for connectionPointIn in self.getconnectionPointIn():
  1829     for connectionPointIn in self.getconnectionPointIn():
  1782         bbox.union(_getConnectionsBoundingBox(connectionPointIn))
  1830         bbox.union(_getConnectionsBoundingBox(connectionPointIn))
  1783     return bbox
  1831     return bbox
       
  1832 
  1784 
  1833 
  1785 def _filterConnections(connectionPointIn, localId, connections):
  1834 def _filterConnections(connectionPointIn, localId, connections):
  1786     in_connections = connectionPointIn.getconnections()
  1835     in_connections = connectionPointIn.getconnections()
  1787     if in_connections is not None:
  1836     if in_connections is not None:
  1788         for connection in in_connections:
  1837         for connection in in_connections:
  1789             connected = connection.getrefLocalId()
  1838             connected = connection.getrefLocalId()
  1790             if not connections.has_key((localId, connected)) and \
  1839             if not connections.has_key((localId, connected)) and \
  1791                not connections.has_key((connected, localId)):
  1840                not connections.has_key((connected, localId)):
  1792                 connectionPointIn.remove(connection)
  1841                 connectionPointIn.remove(connection)
  1793 
  1842 
       
  1843 
  1794 def _filterConnectionsSingle(self, connections):
  1844 def _filterConnectionsSingle(self, connections):
  1795     if self.connectionPointIn is not None:
  1845     if self.connectionPointIn is not None:
  1796         _filterConnections(self.connectionPointIn, self.localId, connections)
  1846         _filterConnections(self.connectionPointIn, self.localId, connections)
  1797 
  1847 
       
  1848 
  1798 def _filterConnectionsMultiple(self, connections):
  1849 def _filterConnectionsMultiple(self, connections):
  1799     for connectionPointIn in self.getconnectionPointIn():
  1850     for connectionPointIn in self.getconnectionPointIn():
  1800         _filterConnections(connectionPointIn, self.localId, connections)
  1851         _filterConnections(connectionPointIn, self.localId, connections)
  1801 
  1852 
       
  1853 
  1802 def _getconnectionsdefinition(instance, connections_end):
  1854 def _getconnectionsdefinition(instance, connections_end):
  1803     local_id = instance.getlocalId()
  1855     local_id = instance.getlocalId()
  1804     return dict([((local_id, end), True) for end in connections_end])
  1856     return dict([((local_id, end), True) for end in connections_end])
       
  1857 
  1805 
  1858 
  1806 def _updateConnectionsId(connectionPointIn, translation):
  1859 def _updateConnectionsId(connectionPointIn, translation):
  1807     connections_end = []
  1860     connections_end = []
  1808     connections = connectionPointIn.getconnections()
  1861     connections = connectionPointIn.getconnections()
  1809     if connections is not None:
  1862     if connections is not None:
  1812             new_reflocalId = translation.get(refLocalId, refLocalId)
  1865             new_reflocalId = translation.get(refLocalId, refLocalId)
  1813             connection.setrefLocalId(new_reflocalId)
  1866             connection.setrefLocalId(new_reflocalId)
  1814             connections_end.append(new_reflocalId)
  1867             connections_end.append(new_reflocalId)
  1815     return connections_end
  1868     return connections_end
  1816 
  1869 
       
  1870 
  1817 def _updateConnectionsIdSingle(self, translation):
  1871 def _updateConnectionsIdSingle(self, translation):
  1818     connections_end = []
  1872     connections_end = []
  1819     if self.connectionPointIn is not None:
  1873     if self.connectionPointIn is not None:
  1820         connections_end = _updateConnectionsId(self.connectionPointIn, translation)
  1874         connections_end = _updateConnectionsId(self.connectionPointIn, translation)
  1821     return _getconnectionsdefinition(self, connections_end)
  1875     return _getconnectionsdefinition(self, connections_end)
  1822 
  1876 
       
  1877 
  1823 def _updateConnectionsIdMultiple(self, translation):
  1878 def _updateConnectionsIdMultiple(self, translation):
  1824     connections_end = []
  1879     connections_end = []
  1825     for connectionPointIn in self.getconnectionPointIn():
  1880     for connectionPointIn in self.getconnectionPointIn():
  1826         connections_end.extend(_updateConnectionsId(connectionPointIn, translation))
  1881         connections_end.extend(_updateConnectionsId(connectionPointIn, translation))
  1827     return _getconnectionsdefinition(self, connections_end)
  1882     return _getconnectionsdefinition(self, connections_end)
  1828 
  1883 
       
  1884 
  1829 def _translate(self, dx, dy):
  1885 def _translate(self, dx, dy):
  1830     self.setx(self.getx() + dx)
  1886     self.setx(self.getx() + dx)
  1831     self.sety(self.gety() + dy)
  1887     self.sety(self.gety() + dy)
       
  1888 
  1832 
  1889 
  1833 def _translateConnections(connectionPointIn, dx, dy):
  1890 def _translateConnections(connectionPointIn, dx, dy):
  1834     connections = connectionPointIn.getconnections()
  1891     connections = connectionPointIn.getconnections()
  1835     if connections is not None:
  1892     if connections is not None:
  1836         for connection in connections:
  1893         for connection in connections:
  1837             for position in connection.getposition():
  1894             for position in connection.getposition():
  1838                 position.setx(position.getx() + dx)
  1895                 position.setx(position.getx() + dx)
  1839                 position.sety(position.gety() + dy)
  1896                 position.sety(position.gety() + dy)
  1840 
  1897 
       
  1898 
  1841 def _translateSingle(self, dx, dy):
  1899 def _translateSingle(self, dx, dy):
  1842     _translate(self, dx, dy)
  1900     _translate(self, dx, dy)
  1843     if self.connectionPointIn is not None:
  1901     if self.connectionPointIn is not None:
  1844         _translateConnections(self.connectionPointIn, dx, dy)
  1902         _translateConnections(self.connectionPointIn, dx, dy)
  1845 
  1903 
       
  1904 
  1846 def _translateMultiple(self, dx, dy):
  1905 def _translateMultiple(self, dx, dy):
  1847     _translate(self, dx, dy)
  1906     _translate(self, dx, dy)
  1848     for connectionPointIn in self.getconnectionPointIn():
  1907     for connectionPointIn in self.getconnectionPointIn():
  1849         _translateConnections(connectionPointIn, dx, dy)
  1908         _translateConnections(connectionPointIn, dx, dy)
  1850 
  1909 
       
  1910 
  1851 def _updateElementName(self, old_name, new_name):
  1911 def _updateElementName(self, old_name, new_name):
  1852     pass
  1912     pass
  1853 
  1913 
       
  1914 
  1854 def _updateElementAddress(self, address_model, new_leading):
  1915 def _updateElementAddress(self, address_model, new_leading):
  1855     pass
  1916     pass
       
  1917 
  1856 
  1918 
  1857 def _SearchInElement(self, criteria, parent_infos=[]):
  1919 def _SearchInElement(self, criteria, parent_infos=[]):
  1858     return []
  1920     return []
  1859 
  1921 
  1860 _connectionsFunctions = {
  1922 _connectionsFunctions = {
  1869                "multiple": _filterConnectionsMultiple},
  1931                "multiple": _filterConnectionsMultiple},
  1870     "update": {"none": lambda self, translation: {},
  1932     "update": {"none": lambda self, translation: {},
  1871                "single": _updateConnectionsIdSingle,
  1933                "single": _updateConnectionsIdSingle,
  1872                "multiple": _updateConnectionsIdMultiple},
  1934                "multiple": _updateConnectionsIdMultiple},
  1873 }
  1935 }
       
  1936 
  1874 
  1937 
  1875 def _initElementClass(name, parent, connectionPointInType="none"):
  1938 def _initElementClass(name, parent, connectionPointInType="none"):
  1876     cls = PLCOpenParser.GetElementClass(name, parent)
  1939     cls = PLCOpenParser.GetElementClass(name, parent)
  1877     if cls:
  1940     if cls:
  1878         setattr(cls, "getx", getx)
  1941         setattr(cls, "getx", getx)
  1957     setattr(cls, "Search", Search)
  2020     setattr(cls, "Search", Search)
  1958 
  2021 
  1959 _initElementClass("leftPowerRail", "ldObjects")
  2022 _initElementClass("leftPowerRail", "ldObjects")
  1960 _initElementClass("rightPowerRail", "ldObjects", "multiple")
  2023 _initElementClass("rightPowerRail", "ldObjects", "multiple")
  1961 
  2024 
       
  2025 
  1962 def _UpdateLDElementName(self, old_name, new_name):
  2026 def _UpdateLDElementName(self, old_name, new_name):
  1963     if TextMatched(self.variable, old_name):
  2027     if TextMatched(self.variable, old_name):
  1964         self.variable = new_name
  2028         self.variable = new_name
  1965 
  2029 
       
  2030 
  1966 def _UpdateLDElementAddress(self, address_model, new_leading):
  2031 def _UpdateLDElementAddress(self, address_model, new_leading):
  1967     self.variable = update_address(self.variable, address_model, new_leading)
  2032     self.variable = update_address(self.variable, address_model, new_leading)
       
  2033 
  1968 
  2034 
  1969 def _getSearchInLDElement(ld_element_type):
  2035 def _getSearchInLDElement(ld_element_type):
  1970     def SearchInLDElement(self, criteria, parent_infos=[]):
  2036     def SearchInLDElement(self, criteria, parent_infos=[]):
  1971         return _Search([("reference", self.variable)], criteria, parent_infos + [ld_element_type, self.getlocalId()])
  2037         return _Search([("reference", self.variable)], criteria, parent_infos + [ld_element_type, self.getlocalId()])
  1972     return SearchInLDElement
  2038     return SearchInLDElement
  2222         for idx, action in enumerate(self.action):
  2288         for idx, action in enumerate(self.action):
  2223             search_result.extend(action.Search(criteria, parent_infos + ["action", idx]))
  2289             search_result.extend(action.Search(criteria, parent_infos + ["action", idx]))
  2224         return search_result
  2290         return search_result
  2225     setattr(cls, "Search", Search)
  2291     setattr(cls, "Search", Search)
  2226 
  2292 
       
  2293 
  2227 def _SearchInIOVariable(self, criteria, parent_infos=[]):
  2294 def _SearchInIOVariable(self, criteria, parent_infos=[]):
  2228     return _Search([("expression", self.expression)], criteria, parent_infos + ["io_variable", self.getlocalId()])
  2295     return _Search([("expression", self.expression)], criteria, parent_infos + ["io_variable", self.getlocalId()])
       
  2296 
  2229 
  2297 
  2230 def _UpdateIOElementName(self, old_name, new_name):
  2298 def _UpdateIOElementName(self, old_name, new_name):
  2231     if TextMatched(self.expression, old_name):
  2299     if TextMatched(self.expression, old_name):
  2232         self.expression = new_name
  2300         self.expression = new_name
       
  2301 
  2233 
  2302 
  2234 def _UpdateIOElementAddress(self, address_model, new_leading):
  2303 def _UpdateIOElementAddress(self, address_model, new_leading):
  2235     self.expression = update_address(self.expression, address_model, new_leading)
  2304     self.expression = update_address(self.expression, address_model, new_leading)
  2236 
  2305 
  2237 cls = _initElementClass("inVariable", "fbdObjects")
  2306 cls = _initElementClass("inVariable", "fbdObjects")
  2401     setattr(cls, "setvalue", setvalue)
  2470     setattr(cls, "setvalue", setvalue)
  2402 
  2471 
  2403     def getvalue(self):
  2472     def getvalue(self):
  2404         return self.content.getvalue()
  2473         return self.content.getvalue()
  2405     setattr(cls, "getvalue", getvalue)
  2474     setattr(cls, "getvalue", getvalue)
       
  2475 
  2406 
  2476 
  2407 def extractValues(values):
  2477 def extractValues(values):
  2408     items = values.split(",")
  2478     items = values.split(",")
  2409     i = 1
  2479     i = 1
  2410     while i < len(items):
  2480     while i < len(items):