PLCControler.py
changeset 1768 691083b5682a
parent 1767 c74815729afd
child 1773 38fde37c3766
equal deleted inserted replaced
1767:c74815729afd 1768:691083b5682a
   309 #-------------------------------------------------------------------------------
   309 #-------------------------------------------------------------------------------
   310 
   310 
   311 
   311 
   312 _Point = namedtuple("Point", ["x", "y"])
   312 _Point = namedtuple("Point", ["x", "y"])
   313 
   313 
   314 _BlockInstanceInfos = namedtuple("BlockInstanceInfos",
   314 _BlockInstanceInfos = namedtuple(
       
   315     "BlockInstanceInfos",
   315     ["type", "id", "x", "y", "width", "height", "specific_values", "inputs", "outputs"])
   316     ["type", "id", "x", "y", "width", "height", "specific_values", "inputs", "outputs"])
   316 
   317 
   317 _BlockSpecificValues = (
   318 _BlockSpecificValues = (
   318     namedtuple("BlockSpecificValues",
   319     namedtuple("BlockSpecificValues",
   319                ["name", "execution_order"]),
   320                ["name", "execution_order"]),
   369     "actionBlock": (
   370     "actionBlock": (
   370         namedtuple("ActionBlockSpecificValues", ["actions"]),
   371         namedtuple("ActionBlockSpecificValues", ["actions"]),
   371         [lambda x: x]),
   372         [lambda x: x]),
   372 }
   373 }
   373 
   374 
   374 _InstanceConnectionInfos = namedtuple("InstanceConnectionInfos",
   375 _InstanceConnectionInfos = namedtuple(
       
   376     "InstanceConnectionInfos",
   375     ["name", "negated", "edge", "position", "links"])
   377     ["name", "negated", "edge", "position", "links"])
   376 
   378 
   377 _ConnectionLinkInfos = namedtuple("ConnectionLinkInfos",
   379 _ConnectionLinkInfos = namedtuple(
       
   380     "ConnectionLinkInfos",
   378     ["refLocalId", "formalParameter", "points"])
   381     ["refLocalId", "formalParameter", "points"])
   379 
   382 
   380 
   383 
   381 class _ActionInfos(object):
   384 class _ActionInfos(object):
   382     __slots__ = ["qualifier", "type", "value", "duration", "indicator"]
   385     __slots__ = ["qualifier", "type", "value", "duration", "indicator"]
   708         project = self.GetProject(debug)
   711         project = self.GetProject(debug)
   709         if project is not None:
   712         if project is not None:
   710             infos = {"name": project.getname(), "type": ITEM_PROJECT}
   713             infos = {"name": project.getname(), "type": ITEM_PROJECT}
   711             datatypes = {"name": DATA_TYPES, "type": ITEM_DATATYPES, "values": []}
   714             datatypes = {"name": DATA_TYPES, "type": ITEM_DATATYPES, "values": []}
   712             for datatype in project.getdataTypes():
   715             for datatype in project.getdataTypes():
   713                 datatypes["values"].append({"name": datatype.getname(), "type": ITEM_DATATYPE,
   716                 datatypes["values"].append({
   714                     "tagname": self.ComputeDataTypeName(datatype.getname()), "values": []})
   717                     "name": datatype.getname(),
       
   718                     "type": ITEM_DATATYPE,
       
   719                     "tagname": self.ComputeDataTypeName(datatype.getname()),
       
   720                     "values": []})
   715             pou_types = {
   721             pou_types = {
   716                 "function": {
   722                 "function": {
   717                     "name":   FUNCTIONS,
   723                     "name":   FUNCTIONS,
   718                     "type":   ITEM_FUNCTION,
   724                     "type":   ITEM_FUNCTION,
   719                     "values": []
   725                     "values": []
   735                              "tagname": self.ComputePouName(pou.getname())}
   741                              "tagname": self.ComputePouName(pou.getname())}
   736                 pou_values = []
   742                 pou_values = []
   737                 if pou.getbodyType() == "SFC":
   743                 if pou.getbodyType() == "SFC":
   738                     transitions = []
   744                     transitions = []
   739                     for transition in pou.gettransitionList():
   745                     for transition in pou.gettransitionList():
   740                         transitions.append({"name": transition.getname(), "type": ITEM_TRANSITION,
   746                         transitions.append({
       
   747                             "name": transition.getname(),
       
   748                             "type": ITEM_TRANSITION,
   741                             "tagname": self.ComputePouTransitionName(pou.getname(), transition.getname()),
   749                             "tagname": self.ComputePouTransitionName(pou.getname(), transition.getname()),
   742                             "values": []})
   750                             "values": []})
   743                     pou_values.append({"name": TRANSITIONS, "type": ITEM_TRANSITIONS, "values": transitions})
   751                     pou_values.append({"name": TRANSITIONS, "type": ITEM_TRANSITIONS, "values": transitions})
   744                     actions = []
   752                     actions = []
   745                     for action in pou.getactionList():
   753                     for action in pou.getactionList():
   746                         actions.append({"name": action.getname(), "type": ITEM_ACTION,
   754                         actions.append({
       
   755                             "name": action.getname(),
       
   756                             "type": ITEM_ACTION,
   747                             "tagname": self.ComputePouActionName(pou.getname(), action.getname()),
   757                             "tagname": self.ComputePouActionName(pou.getname(), action.getname()),
   748                             "values": []})
   758                             "values": []})
   749                     pou_values.append({"name": ACTIONS, "type": ITEM_ACTIONS, "values": actions})
   759                     pou_values.append({"name": ACTIONS, "type": ITEM_ACTIONS, "values": actions})
   750                 if pou_type in pou_types:
   760                 if pou_type in pou_types:
   751                     pou_infos["values"] = pou_values
   761                     pou_infos["values"] = pou_values
   752                     pou_types[pou_type]["values"].append(pou_infos)
   762                     pou_types[pou_type]["values"].append(pou_infos)
   753             configurations = {"name": CONFIGURATIONS, "type": ITEM_CONFIGURATIONS, "values": []}
   763             configurations = {"name": CONFIGURATIONS, "type": ITEM_CONFIGURATIONS, "values": []}
   754             for config in project.getconfigurations():
   764             for config in project.getconfigurations():
   755                 config_name = config.getname()
   765                 config_name = config.getname()
   756                 config_infos = {"name": config_name, "type": ITEM_CONFIGURATION,
   766                 config_infos = {
       
   767                     "name": config_name,
       
   768                     "type": ITEM_CONFIGURATION,
   757                     "tagname": self.ComputeConfigurationName(config.getname()),
   769                     "tagname": self.ComputeConfigurationName(config.getname()),
   758                     "values": []}
   770                     "values": []}
   759                 resources = {"name": RESOURCES, "type": ITEM_RESOURCES, "values": []}
   771                 resources = {"name": RESOURCES, "type": ITEM_RESOURCES, "values": []}
   760                 for resource in config.getresource():
   772                 for resource in config.getresource():
   761                     resource_name = resource.getname()
   773                     resource_name = resource.getname()
   762                     resource_infos = {"name": resource_name, "type": ITEM_RESOURCE,
   774                     resource_infos = {
       
   775                         "name": resource_name,
       
   776                         "type": ITEM_RESOURCE,
   763                         "tagname": self.ComputeConfigurationResourceName(config.getname(), resource.getname()),
   777                         "tagname": self.ComputeConfigurationResourceName(config.getname(), resource.getname()),
   764                         "values": []}
   778                         "values": []}
   765                     resources["values"].append(resource_infos)
   779                     resources["values"].append(resource_infos)
   766                 config_infos["values"] = [resources]
   780                 config_infos["values"] = [resources]
   767                 configurations["values"].append(config_infos)
   781                 configurations["values"].append(config_infos)
   812                     os.path.join(ScriptDirectory, "plcopen", "instances_path.xslt"),
   826                     os.path.join(ScriptDirectory, "plcopen", "instances_path.xslt"),
   813                     parser),
   827                     parser),
   814                 extensions={
   828                 extensions={
   815                     ("instances_ns", "AddInstance"): factory.AddInstance})
   829                     ("instances_ns", "AddInstance"): factory.AddInstance})
   816 
   830 
   817             instances_path_xslt_tree(root,
   831             instances_path_xslt_tree(
   818                 instance_type=etree.XSLT.strparam(name))
   832                 root, instance_type=etree.XSLT.strparam(name))
   819 
   833 
   820         return instances
   834         return instances
   821 
   835 
   822     def SearchPouInstances(self, tagname, debug=False):
   836     def SearchPouInstances(self, tagname, debug=False):
   823         project = self.GetProject(debug)
   837         project = self.GetProject(debug)
   851                                      "ResourceTagName",
   865                                      "ResourceTagName",
   852                                      "PouTagName",
   866                                      "PouTagName",
   853                                      "ActionTagName",
   867                                      "ActionTagName",
   854                                      "TransitionTagName"]})
   868                                      "TransitionTagName"]})
   855 
   869 
   856         instance_tagname_xslt_tree(project,
   870         instance_tagname_xslt_tree(
   857             instance_path=etree.XSLT.strparam(instance_path))
   871             project, instance_path=etree.XSLT.strparam(instance_path))
   858 
   872 
   859         return factory.GetTagName()
   873         return factory.GetTagName()
   860 
   874 
   861     def GetInstanceInfos(self, instance_path, debug=False):
   875     def GetInstanceInfos(self, instance_path, debug=False):
   862         tagname = self.GetPouInstanceTagName(instance_path)
   876         tagname = self.GetPouInstanceTagName(instance_path)
  1384         variables_infos_xslt_tree = etree.XSLT(
  1398         variables_infos_xslt_tree = etree.XSLT(
  1385             etree.parse(
  1399             etree.parse(
  1386                 os.path.join(ScriptDirectory, "plcopen", "variables_infos.xslt"),
  1400                 os.path.join(ScriptDirectory, "plcopen", "variables_infos.xslt"),
  1387                 parser),
  1401                 parser),
  1388             extensions={("var_infos_ns", name): getattr(factory, name)
  1402             extensions={("var_infos_ns", name): getattr(factory, name)
  1389                 for name in ["SetType", "AddDimension", "AddTree",
  1403                         for name in ["SetType", "AddDimension", "AddTree",
  1390                              "AddVarToTree", "AddVariable"]})
  1404                                      "AddVarToTree", "AddVariable"]})
  1391         variables_infos_xslt_tree(object_with_vars,
  1405         variables_infos_xslt_tree(
  1392             tree=etree.XSLT.strparam(str(tree)))
  1406             object_with_vars, tree=etree.XSLT.strparam(str(tree)))
  1393 
  1407 
  1394         return variables
  1408         return variables
  1395 
  1409 
  1396     # Add a global var to configuration to configuration
  1410     # Add a global var to configuration to configuration
  1397     def AddConfigurationGlobalVar(self, config_name, var_type, var_name,
  1411     def AddConfigurationGlobalVar(self, config_name, var_type, var_name,
  1435         if project is not None:
  1449         if project is not None:
  1436             for configuration in self.Project.getconfigurations():
  1450             for configuration in self.Project.getconfigurations():
  1437                 if config_name is None or config_name == configuration.getname():
  1451                 if config_name is None or config_name == configuration.getname():
  1438                     variables.extend(
  1452                     variables.extend(
  1439                         [var.getname() for var in reduce(
  1453                         [var.getname() for var in reduce(
  1440                             lambda x, y: x + y, [varlist.getvariable()
  1454                             lambda x, y: x + y, [
       
  1455                                 varlist.getvariable()
  1441                                 for varlist in configuration.globalVars],
  1456                                 for varlist in configuration.globalVars],
  1442                             [])])
  1457                             [])])
  1443         return variables
  1458         return variables
  1444 
  1459 
  1445     # Replace the resource globalvars by those given
  1460     # Replace the resource globalvars by those given
  1464                 return self.GetVariableDictionary(resource, debug)
  1479                 return self.GetVariableDictionary(resource, debug)
  1465 
  1480 
  1466         return []
  1481         return []
  1467 
  1482 
  1468     # Return resource variable names
  1483     # Return resource variable names
  1469     def GetConfigurationResourceVariableNames(self,
  1484     def GetConfigurationResourceVariableNames(
  1470                 config_name=None, resource_name=None, debug=False):
  1485             self, config_name=None, resource_name=None, debug=False):
  1471         variables = []
  1486         variables = []
  1472         project = self.GetProject(debug)
  1487         project = self.GetProject(debug)
  1473         if project is not None:
  1488         if project is not None:
  1474             for configuration in self.Project.getconfigurations():
  1489             for configuration in self.Project.getconfigurations():
  1475                 if config_name is None or config_name == configuration.getname():
  1490                 if config_name is None or config_name == configuration.getname():
  1476                     for resource in configuration.getresource():
  1491                     for resource in configuration.getresource():
  1477                         if resource_name is None or resource.getname() == resource_name:
  1492                         if resource_name is None or resource.getname() == resource_name:
  1478                             variables.extend(
  1493                             variables.extend(
  1479                                 [var.getname() for var in reduce(
  1494                                 [var.getname() for var in reduce(
  1480                                     lambda x, y: x + y, [varlist.getvariable()
  1495                                     lambda x, y: x + y, [
       
  1496                                         varlist.getvariable()
  1481                                         for varlist in resource.globalVars],
  1497                                         for varlist in resource.globalVars],
  1482                                     [])])
  1498                                     [])])
  1483         return variables
  1499         return variables
  1484 
  1500 
  1485     # Return the interface for the given pou
  1501     # Return the interface for the given pou
  1551                         os.path.join(ScriptDirectory, "plcopen", "variables_infos.xslt"),
  1567                         os.path.join(ScriptDirectory, "plcopen", "variables_infos.xslt"),
  1552                         parser),
  1568                         parser),
  1553                     extensions={("var_infos_ns", name): getattr(factory, name)
  1569                     extensions={("var_infos_ns", name): getattr(factory, name)
  1554                                 for name in ["SetType", "AddDimension",
  1570                                 for name in ["SetType", "AddDimension",
  1555                                              "AddTree", "AddVarToTree"]})
  1571                                              "AddTree", "AddVarToTree"]})
  1556                 return_type_infos_xslt_tree(return_type,
  1572                 return_type_infos_xslt_tree(
  1557                     tree=etree.XSLT.strparam(str(tree)))
  1573                     return_type, tree=etree.XSLT.strparam(str(tree)))
  1558                 if tree:
  1574                 if tree:
  1559                     return [factory.GetType(), factory.GetTree()]
  1575                     return [factory.GetType(), factory.GetTree()]
  1560                 return factory.GetType()
  1576                 return factory.GetType()
  1561 
  1577 
  1562         if tree:
  1578         if tree:
  1648                 blocktype_infos = blocktype.getblockInfos()
  1664                 blocktype_infos = blocktype.getblockInfos()
  1649                 if inputs in [None, "undefined"]:
  1665                 if inputs in [None, "undefined"]:
  1650                     return blocktype_infos
  1666                     return blocktype_infos
  1651 
  1667 
  1652                 if inputs == tuple([var_type
  1668                 if inputs == tuple([var_type
  1653                     for name, var_type, modifier in blocktype_infos["inputs"]]):
  1669                                     for name, var_type, modifier in blocktype_infos["inputs"]]):
  1654                     return blocktype_infos
  1670                     return blocktype_infos
  1655 
  1671 
  1656         return None
  1672         return None
  1657 
  1673 
  1658     # Return Block types checking for recursion
  1674     # Return Block types checking for recursion
  1672             blocktypes = [
  1688             blocktypes = [
  1673                 {"name": category["name"],
  1689                 {"name": category["name"],
  1674                  "list": [block for block in category["list"]
  1690                  "list": [block for block in category["list"]
  1675                           if block["type"] in filter]}
  1691                           if block["type"] in filter]}
  1676                 for category in self.TotalTypes]
  1692                 for category in self.TotalTypes]
  1677             blocktypes.append({"name": USER_DEFINED_POUS,
  1693             blocktypes.append({
       
  1694                 "name": USER_DEFINED_POUS,
  1678                 "list": [pou.getblockInfos()
  1695                 "list": [pou.getblockInfos()
  1679                          for pou in project.getpous(name, filter)
  1696                          for pou in project.getpous(name, filter)
  1680                          if (name is None or
  1697                          if (name is None or
  1681                              len(self.GetInstanceList(pou, name, debug)) == 0)]})
  1698                              len(self.GetInstanceList(pou, name, debug)) == 0)]
       
  1699             })
  1682             return blocktypes
  1700             return blocktypes
  1683         return self.TotalTypes
  1701         return self.TotalTypes
  1684 
  1702 
  1685     # Return Function Block types checking for recursion
  1703     # Return Function Block types checking for recursion
  1686     def GetFunctionBlockTypes(self, tagname="", debug=False):
  1704     def GetFunctionBlockTypes(self, tagname="", debug=False):
  1693         for blocks in self.TotalTypesDict.itervalues():
  1711         for blocks in self.TotalTypesDict.itervalues():
  1694             for sectioname, block in blocks:
  1712             for sectioname, block in blocks:
  1695                 if block["type"] == "functionBlock":
  1713                 if block["type"] == "functionBlock":
  1696                     blocktypes.append(block["name"])
  1714                     blocktypes.append(block["name"])
  1697         if project is not None:
  1715         if project is not None:
  1698             blocktypes.extend([pou.getname()
  1716             blocktypes.extend([
       
  1717                 pou.getname()
  1699                 for pou in project.getpous(name, ["functionBlock"])
  1718                 for pou in project.getpous(name, ["functionBlock"])
  1700                 if (name is None or
  1719                 if (name is None or
  1701                     len(self.GetInstanceList(pou, name, debug)) == 0)])
  1720                     len(self.GetInstanceList(pou, name, debug)) == 0)])
  1702         return blocktypes
  1721         return blocktypes
  1703 
  1722 
  1994                     infos["min"] = basetype_content.range.getlower()
  2013                     infos["min"] = basetype_content.range.getlower()
  1995                     infos["max"] = basetype_content.range.getupper()
  2014                     infos["max"] = basetype_content.range.getupper()
  1996                     base_type = basetype_content.baseType.getcontent()
  2015                     base_type = basetype_content.baseType.getcontent()
  1997                     base_type_type = base_type.getLocalTag()
  2016                     base_type_type = base_type.getLocalTag()
  1998                     infos["base_type"] = (base_type.getname()
  2017                     infos["base_type"] = (base_type.getname()
  1999                         if base_type_type == "derived"
  2018                                           if base_type_type == "derived"
  2000                         else base_type_type)
  2019                                           else base_type_type)
  2001                 elif basetype_content_type == "enum":
  2020                 elif basetype_content_type == "enum":
  2002                     infos["type"] = "Enumerated"
  2021                     infos["type"] = "Enumerated"
  2003                     infos["values"] = []
  2022                     infos["values"] = []
  2004                     for value in basetype_content.xpath("ppx:values/ppx:value", namespaces=PLCOpenParser.NSMAP):
  2023                     for value in basetype_content.xpath("ppx:values/ppx:value", namespaces=PLCOpenParser.NSMAP):
  2005                         infos["values"].append(value.getname())
  2024                         infos["values"].append(value.getname())
  2009                     for dimension in basetype_content.getdimension():
  2028                     for dimension in basetype_content.getdimension():
  2010                         infos["dimensions"].append((dimension.getlower(), dimension.getupper()))
  2029                         infos["dimensions"].append((dimension.getlower(), dimension.getupper()))
  2011                     base_type = basetype_content.baseType.getcontent()
  2030                     base_type = basetype_content.baseType.getcontent()
  2012                     base_type_type = base_type.getLocalTag()
  2031                     base_type_type = base_type.getLocalTag()
  2013                     infos["base_type"] = (base_type.getname()
  2032                     infos["base_type"] = (base_type.getname()
  2014                         if base_type_type == "derived"
  2033                                           if base_type_type == "derived"
  2015                         else base_type_type.upper())
  2034                                           else base_type_type.upper())
  2016                 elif basetype_content_type == "struct":
  2035                 elif basetype_content_type == "struct":
  2017                     infos["type"] = "Structure"
  2036                     infos["type"] = "Structure"
  2018                     infos["elements"] = []
  2037                     infos["elements"] = []
  2019                     for element in basetype_content.getvariable():
  2038                     for element in basetype_content.getvariable():
  2020                         element_infos = {}
  2039                         element_infos = {}
  2026                             for dimension in element_type.getdimension():
  2045                             for dimension in element_type.getdimension():
  2027                                 dimensions.append((dimension.getlower(), dimension.getupper()))
  2046                                 dimensions.append((dimension.getlower(), dimension.getupper()))
  2028                             base_type = element_type.baseType.getcontent()
  2047                             base_type = element_type.baseType.getcontent()
  2029                             base_type_type = base_type.getLocalTag()
  2048                             base_type_type = base_type.getLocalTag()
  2030                             element_infos["Type"] = ("array",
  2049                             element_infos["Type"] = ("array",
  2031                                 base_type.getname()
  2050                                                      base_type.getname()
  2032                                 if base_type_type == "derived"
  2051                                                      if base_type_type == "derived"
  2033                                 else base_type_type.upper(), dimensions)
  2052                                                      else base_type_type.upper(),
       
  2053                                                      dimensions)
  2034                         elif element_type_type == "derived":
  2054                         elif element_type_type == "derived":
  2035                             element_infos["Type"] = element_type.getname()
  2055                             element_infos["Type"] = element_type.getname()
  2036                         else:
  2056                         else:
  2037                             element_infos["Type"] = element_type_type.upper()
  2057                             element_infos["Type"] = element_type_type.upper()
  2038                         if element.initialValue is not None:
  2058                         if element.initialValue is not None:
  2041                             element_infos["Initial Value"] = ""
  2061                             element_infos["Initial Value"] = ""
  2042                         infos["elements"].append(element_infos)
  2062                         infos["elements"].append(element_infos)
  2043                 else:
  2063                 else:
  2044                     infos["type"] = "Directly"
  2064                     infos["type"] = "Directly"
  2045                     infos["base_type"] = (basetype_content.getname()
  2065                     infos["base_type"] = (basetype_content.getname()
  2046                         if basetype_content_type == "derived"
  2066                                           if basetype_content_type == "derived"
  2047                         else basetype_content_type.upper())
  2067                                           else basetype_content_type.upper())
  2048 
  2068 
  2049                 if datatype.initialValue is not None:
  2069                 if datatype.initialValue is not None:
  2050                     infos["initial"] = datatype.initialValue.getvalue()
  2070                     infos["initial"] = datatype.initialValue.getvalue()
  2051                 else:
  2071                 else:
  2052                     infos["initial"] = ""
  2072                     infos["initial"] = ""
  2332             words = tagname.split("::")
  2352             words = tagname.split("::")
  2333             if words[0] in ["P", "T", "A"]:
  2353             if words[0] in ["P", "T", "A"]:
  2334                 element = self.GetEditedElement(tagname, debug)
  2354                 element = self.GetEditedElement(tagname, debug)
  2335                 if element is not None and element.getbodyType() not in ["ST", "IL"]:
  2355                 if element is not None and element.getbodyType() not in ["ST", "IL"]:
  2336                     for instance in element.getinstances():
  2356                     for instance in element.getinstances():
  2337                         if isinstance(instance,
  2357                         if isinstance(
  2338                             (PLCOpenParser.GetElementClass("step", "sfcObjects"),
  2358                                 instance,
  2339                              PLCOpenParser.GetElementClass("connector", "commonObjects"),
  2359                                 (PLCOpenParser.GetElementClass("step",         "sfcObjects"),
  2340                              PLCOpenParser.GetElementClass("continuation", "commonObjects"))):
  2360                                  PLCOpenParser.GetElementClass("connector",    "commonObjects"),
       
  2361                                  PLCOpenParser.GetElementClass("continuation", "commonObjects"))):
  2341                             names[instance.getname().upper()] = True
  2362                             names[instance.getname().upper()] = True
  2342         else:
  2363         else:
  2343             project = self.GetProject(debug)
  2364             project = self.GetProject(debug)
  2344             if project is not None:
  2365             if project is not None:
  2345                 for datatype in project.getdataTypes():
  2366                 for datatype in project.getdataTypes():