PLCControler.py
changeset 1319 748347102c97
parent 1316 df9d02bd3eb7
child 1321 83f41ea00b97
equal deleted inserted replaced
1318:758801f4b296 1319:748347102c97
   138         self.Variables.append(
   138         self.Variables.append(
   139             {el.tag.replace("_", " "): extract_param(el) for el in infos})
   139             {el.tag.replace("_", " "): extract_param(el) for el in infos})
   140 
   140 
   141 class VarTree(etree.XSLTExtension):
   141 class VarTree(etree.XSLTExtension):
   142     
   142     
   143     def __init__(self, controller):
   143     def __init__(self, controller, debug):
   144         etree.XSLTExtension.__init__(self)
   144         etree.XSLTExtension.__init__(self)
   145         self.Controller = controller
   145         self.Controller = controller
       
   146         self.Debug = debug
   146     
   147     
   147     def execute(self, context, self_node, input_node, output_parent):
   148     def execute(self, context, self_node, input_node, output_parent):
   148         typename = input_node.get("name")
   149         typename = input_node.get("name")
   149         pou_infos = self.Controller.GetPou(typename)
   150         pou_infos = self.Controller.GetPou(typename, self.Debug)
   150         if pou_infos is not None:
   151         if pou_infos is not None:
   151             self.apply_templates(context, pou_infos, output_parent)
   152             self.apply_templates(context, pou_infos, output_parent)
   152             return
   153             return
   153         
   154         
   154         datatype_infos = self.Controller.GetDataType(typename)
   155         datatype_infos = self.Controller.GetDataType(typename, self.Debug)
   155         if datatype_infos is not None:
   156         if datatype_infos is not None:
   156             self.apply_templates(context, datatype_infos, output_parent)
   157             self.apply_templates(context, datatype_infos, output_parent)
   157             return
   158             return
   158 
   159 
   159 variables_infos_xslt = etree.parse(
   160 variables_infos_xslt = etree.parse(
   162 #-------------------------------------------------------------------------------
   163 #-------------------------------------------------------------------------------
   163 #            Helpers object for generating pou variable instance list
   164 #            Helpers object for generating pou variable instance list
   164 #-------------------------------------------------------------------------------
   165 #-------------------------------------------------------------------------------
   165 
   166 
   166 def class_extraction(el, prt):
   167 def class_extraction(el, prt):
   167     if prt == "pou":
   168     if prt in ["pou", "variable"]:
   168         return POU_TYPES[el.text]
   169         pou_type = POU_TYPES.get(el.text)
   169     elif prt == "variable":
   170         if pou_type is not None:
       
   171             return pou_type
   170         return VAR_CLASS_INFOS[el.text][1]
   172         return VAR_CLASS_INFOS[el.text][1]
   171     return {
   173     return {
   172         "configuration": ITEM_CONFIGURATION,
   174         "configuration": ITEM_CONFIGURATION,
   173         "resource": ITEM_RESOURCE,
   175         "resource": ITEM_RESOURCE,
   174         "action": ITEM_ACTION,
   176         "action": ITEM_ACTION,
   198         self.Debug = debug
   200         self.Debug = debug
   199     
   201     
   200     def execute(self, context, self_node, input_node, output_parent):
   202     def execute(self, context, self_node, input_node, output_parent):
   201         typename = input_node.get("name")
   203         typename = input_node.get("name")
   202         project = self.Controller.GetProject(self.Debug)
   204         project = self.Controller.GetProject(self.Debug)
   203         infos = etree.Element('{http://www.w3.org/1999/XSL/Transform}text')
   205         output_parent.text = str(project.getpou(typename) is not None)
   204         infos.text = str(project.getpou(typename) is not None)
   206         
   205         self.process_children(context, infos)
       
   206 
       
   207 class IsDebugged(etree.XSLTExtension):
   207 class IsDebugged(etree.XSLTExtension):
   208     
   208     
   209     def __init__(self, controller, debug):
   209     def __init__(self, controller, debug):
   210         etree.XSLTExtension.__init__(self)
   210         etree.XSLTExtension.__init__(self)
   211         self.Controller = controller
   211         self.Controller = controller
   221         
   221         
   222         datatype_infos = self.Controller.GetDataType(typename, self.Debug)
   222         datatype_infos = self.Controller.GetDataType(typename, self.Debug)
   223         if datatype_infos is not None:
   223         if datatype_infos is not None:
   224             self.apply_templates(context, datatype_infos, output_parent)
   224             self.apply_templates(context, datatype_infos, output_parent)
   225             return
   225             return
   226 
   226         
       
   227         output_parent.text = "False"
       
   228         
       
   229 class PouVariableClass(etree.XSLTExtension):
       
   230     
       
   231     def __init__(self, controller, debug):
       
   232         etree.XSLTExtension.__init__(self)
       
   233         self.Controller = controller
       
   234         self.Debug = debug
       
   235     
       
   236     def execute(self, context, self_node, input_node, output_parent):
       
   237         pou_infos = self.Controller.GetPou(input_node.get("name"), self.Debug)
       
   238         if pou_infos is not None:
       
   239             self.apply_templates(context, pou_infos, output_parent)
       
   240             return
       
   241         
       
   242         self.process_children(context, output_parent)
       
   243         
   227 pou_variables_xslt = etree.parse(
   244 pou_variables_xslt = etree.parse(
   228     os.path.join(ScriptDirectory, "plcopen", "pou_variables.xslt"))
   245     os.path.join(ScriptDirectory, "plcopen", "pou_variables.xslt"))
       
   246 
       
   247 #-------------------------------------------------------------------------------
       
   248 #            Helpers object for generating instances path list
       
   249 #-------------------------------------------------------------------------------
       
   250 
       
   251 class InstanceDefinition(etree.XSLTExtension):
       
   252     
       
   253     def __init__(self, controller, debug):
       
   254         etree.XSLTExtension.__init__(self)
       
   255         self.Controller = controller
       
   256         self.Debug = debug
       
   257     
       
   258     def execute(self, context, self_node, input_node, output_parent):
       
   259         instance_infos = etree.Element('infos')
       
   260         self.process_children(context, instance_infos)
       
   261         
       
   262         pou_infos = self.Controller.GetPou(instance_infos.get("name"), self.Debug)
       
   263         if pou_infos is not None:
       
   264             pou_instance = etree.Element('pou_instance',
       
   265                 pou_path=instance_infos.get("path"))
       
   266             pou_instance.append(deepcopy(pou_infos))
       
   267             self.apply_templates(context, pou_instance, output_parent)
       
   268             return
       
   269             
       
   270         datatype_infos = self.Controller.GetDataType(instance_infos.get("name"), self.Debug)
       
   271         if datatype_infos is not None:
       
   272             datatype_instance = etree.Element('datatype_instance',
       
   273                 datatype_path=instance_infos.get("path"))
       
   274             datatype_instance.append(deepcopy(datatype_infos))
       
   275             self.apply_templates(context, datatype_instance, output_parent)
       
   276             return
       
   277 
       
   278 instances_path_xslt = etree.parse(
       
   279     os.path.join(ScriptDirectory, "plcopen", "instances_path.xslt"))
   229 
   280 
   230 #-------------------------------------------------------------------------------
   281 #-------------------------------------------------------------------------------
   231 #                         Undo Buffer for PLCOpenEditor
   282 #                         Undo Buffer for PLCOpenEditor
   232 #-------------------------------------------------------------------------------
   283 #-------------------------------------------------------------------------------
   233 
   284 
   523         project = self.GetProject(debug)
   574         project = self.GetProject(debug)
   524         if project is not None:
   575         if project is not None:
   525             pou_variable_xslt_tree = etree.XSLT(
   576             pou_variable_xslt_tree = etree.XSLT(
   526                 pou_variables_xslt, extensions = {
   577                 pou_variables_xslt, extensions = {
   527                     ("pou_vars_ns", "is_edited"): IsEdited(self, debug),
   578                     ("pou_vars_ns", "is_edited"): IsEdited(self, debug),
   528                     ("pou_vars_ns", "is_debugged"): IsDebugged(self, debug)})
   579                     ("pou_vars_ns", "is_debugged"): IsDebugged(self, debug),
   529             return compute_instance_tree(
   580                     ("pou_vars_ns", "pou_class"): PouVariableClass(self, debug)})
   530                 pou_variable_xslt_tree(
   581             
   531                     self.GetEditedElement(tagname, debug)).getroot())
       
   532 
       
   533     def RecursiveSearchPouInstances(self, project, pou_type, parent_path, varlists, debug = False):
       
   534         instances = []
       
   535         for varlist in varlists:
       
   536             for variable in varlist.getvariable():
       
   537                 vartype_content = variable.gettype().getcontent()
       
   538                 if vartype_content.getLocalTag() == "derived":
       
   539                     var_path = "%s.%s" % (parent_path, variable.getname())
       
   540                     var_type = vartype_content.getname()
       
   541                     if var_type == pou_type:
       
   542                         instances.append(var_path)
       
   543                     else:
       
   544                         pou = project.getpou(var_type)
       
   545                         if pou is not None:# and project.ElementIsUsedBy(pou_type, var_type):
       
   546                             instances.extend(
       
   547                                 self.RecursiveSearchPouInstances(
       
   548                                     project, pou_type, var_path, 
       
   549                                     [varlist for type, varlist in pou.getvars()], 
       
   550                                     debug))
       
   551         return instances
       
   552                         
       
   553     def SearchPouInstances(self, tagname, debug = False):
       
   554         project = self.GetProject(debug)
       
   555         if project is not None:
       
   556             words = tagname.split("::")
   582             words = tagname.split("::")
   557             if words[0] == "P":
   583             if words[0] == "P":
   558                 instances = []
   584                 obj = self.GetPou(words[1], debug)
   559                 for config in project.getconfigurations():
   585             else:
   560                     config_name = config.getname()
   586                 obj = self.GetEditedElement(tagname, debug)
   561                     instances.extend(
   587             if obj is not None:
   562                         self.RecursiveSearchPouInstances(
   588                 return compute_instance_tree(
   563                             project, words[1], config_name, 
   589                         pou_variable_xslt_tree(obj).getroot())
   564                             config.getglobalVars(), debug))
   590         return []
   565                     for resource in config.getresource():
   591 
   566                         res_path = "%s.%s" % (config_name, resource.getname())
   592     def GetInstanceList(self, root, name, debug = False):
   567                         instances.extend(
   593         project = self.GetProject(debug)
   568                             self.RecursiveSearchPouInstances(
   594         if project is not None:
   569                                 project, words[1], res_path, 
   595             instances_path_xslt_tree = etree.XSLT(
   570                                 resource.getglobalVars(), debug))
   596                 instances_path_xslt, 
   571                         pou_instances = resource.getpouInstance()[:]
   597                 extensions = {
   572                         for task in resource.gettask():
   598                     ("instances_ns", "instance_definition"): 
   573                             pou_instances.extend(task.getpouInstance())
   599                     InstanceDefinition(self, debug)})
   574                         for pou_instance in pou_instances:
   600             
   575                             pou_path = "%s.%s" % (res_path, pou_instance.getname())
   601             return instances_path_xslt_tree(root, 
   576                             pou_type = pou_instance.gettypeName()
   602                 instance_type=etree.XSLT.strparam(name)).getroot()
   577                             if pou_type == words[1]:
   603         return None
   578                                 instances.append(pou_path)
   604 
   579                             pou = project.getpou(pou_type)
   605     def SearchPouInstances(self, tagname, debug = False):
   580                             if pou is not None:# and project.ElementIsUsedBy(words[1], pou_type):
   606         project = self.GetProject(debug)
   581                                 instances.extend(
   607         if project is not None:
   582                                     self.RecursiveSearchPouInstances(
   608             words = tagname.split("::")
   583                                         project, words[1], pou_path, 
   609             if words[0] == "P":
   584                                         [varlist for type, varlist in pou.getvars()], 
   610                 result = self.GetInstanceList(project, words[1])
   585                                         debug))
   611                 if result is not None:
   586                 return instances
   612                     return [instance.get("path") for instance in result]
       
   613                 return []
   587             elif words[0] == 'C':
   614             elif words[0] == 'C':
   588                 return [words[1]]
   615                 return [words[1]]
   589             elif words[0] == 'R':
   616             elif words[0] == 'R':
   590                 return ["%s.%s" % (words[1], words[2])]
   617                 return ["%s.%s" % (words[1], words[2])]
   591             elif words[0] in ['T', 'A']:
   618             elif words[0] in ['T', 'A']:
   605                     if variable.getname() == parts[0]:
   632                     if variable.getname() == parts[0]:
   606                         vartype_content = variable.gettype().getcontent()
   633                         vartype_content = variable.gettype().getcontent()
   607                         if vartype_content.getLocalTag() == "derived":
   634                         if vartype_content.getLocalTag() == "derived":
   608                             return self.RecursiveGetPouInstanceTagName(
   635                             return self.RecursiveGetPouInstanceTagName(
   609                                             project, 
   636                                             project, 
   610                                             vartype_content["value"].getname(),
   637                                             vartype_content.getname(),
   611                                             parts[1:], debug)
   638                                             parts[1:], debug)
   612             
   639             
   613             if pou.getbodyType() == "SFC" and len(parts) == 1:
   640             if pou.getbodyType() == "SFC" and len(parts) == 1:
   614                 for action in pou.getactionList():
   641                 for action in pou.getactionList():
   615                     if action.getname() == parts[0]:
   642                     if action.getname() == parts[0]:
   705                         return var_infos
   732                         return var_infos
   706         return None
   733         return None
   707     
   734     
   708     # Return if data type given by name is used by another data type or pou
   735     # Return if data type given by name is used by another data type or pou
   709     def DataTypeIsUsed(self, name, debug = False):
   736     def DataTypeIsUsed(self, name, debug = False):
   710         #project = self.GetProject(debug)
   737         project = self.GetProject(debug)
   711         #if project is not None:
   738         if project is not None:
   712         #    return project.ElementIsUsed(name)
   739             return self.GetInstanceList(project, name, debug) is not None
   713         return False
   740         return False
   714 
   741 
   715     # Return if pou given by name is used by another pou
   742     # Return if pou given by name is used by another pou
   716     def PouIsUsed(self, name, debug = False):
   743     def PouIsUsed(self, name, debug = False):
   717         #project = self.GetProject(debug)
   744         project = self.GetProject(debug)
   718         #if project is not None:
   745         if project is not None:
   719         #    return project.ElementIsUsed(name)
   746             return self.GetInstanceList(project, name, debug) is not None
   720         return False
   747         return False
   721 
   748 
   722     # Return if pou given by name is directly or undirectly used by the reference pou
   749     # Return if pou given by name is directly or undirectly used by the reference pou
   723     def PouIsUsedBy(self, name, reference, debug = False):
   750     def PouIsUsedBy(self, name, reference, debug = False):
   724         #project = self.GetProject(debug)
   751         pou_infos = self.GetPou(reference, debug)
   725         #if project is not None:
   752         if pou_infos is not None:
   726         #    return project.ElementIsUsedBy(name, reference)
   753             return self.GetInstanceList(pou_infos, name, debug) is not None
   727         return False
   754         return False
   728 
   755 
   729     def GenerateProgram(self, filepath=None):
   756     def GenerateProgram(self, filepath=None):
   730         errors = []
   757         errors = []
   731         warnings = []
   758         warnings = []
  1200 
  1227 
  1201             # Add variable to varList
  1228             # Add variable to varList
  1202             current_varlist.appendvariable(tempvar)
  1229             current_varlist.appendvariable(tempvar)
  1203         return varlist_list
  1230         return varlist_list
  1204     
  1231     
  1205     def GetVariableDictionary(self, object_with_vars):
  1232     def GetVariableDictionary(self, object_with_vars, debug=False):
  1206         variables = []
  1233         variables = []
  1207         
  1234         
  1208         variables_infos_xslt_tree = etree.XSLT(
  1235         variables_infos_xslt_tree = etree.XSLT(
  1209             variables_infos_xslt, extensions = {
  1236             variables_infos_xslt, extensions = {
  1210                 ("var_infos_ns", "add_variable"): AddVariable(variables),
  1237                 ("var_infos_ns", "add_variable"): AddVariable(variables),
  1211                 ("var_infos_ns", "var_tree"): VarTree(self)})
  1238                 ("var_infos_ns", "var_tree"): VarTree(self, debug)})
  1212         variables_infos_xslt_tree(object_with_vars)
  1239         variables_infos_xslt_tree(object_with_vars)
  1213         
  1240         
  1214         return variables
  1241         return variables
  1215             
  1242             
  1216     # Add a global var to configuration to configuration
  1243     # Add a global var to configuration to configuration
  1242         if project is not None:
  1269         if project is not None:
  1243             # Found the configuration corresponding to name
  1270             # Found the configuration corresponding to name
  1244             configuration = project.getconfiguration(name)
  1271             configuration = project.getconfiguration(name)
  1245             if configuration is not None:
  1272             if configuration is not None:
  1246                 # Extract variables defined in configuration
  1273                 # Extract variables defined in configuration
  1247                 return self.GetVariableDictionary(configuration)
  1274                 return self.GetVariableDictionary(configuration, debug)
  1248         
  1275         
  1249         return []
  1276         return []
  1250 
  1277 
  1251     # Return configuration variable names
  1278     # Return configuration variable names
  1252     def GetConfigurationVariableNames(self, config_name = None, debug = False):
  1279     def GetConfigurationVariableNames(self, config_name = None, debug = False):
  1279         if project is not None:
  1306         if project is not None:
  1280             # Found the resource corresponding to name
  1307             # Found the resource corresponding to name
  1281             resource = project.getconfigurationResource(config_name, name)
  1308             resource = project.getconfigurationResource(config_name, name)
  1282             if resource is not None:
  1309             if resource is not None:
  1283                 # Extract variables defined in configuration
  1310                 # Extract variables defined in configuration
  1284                 return self.GetVariableDictionary(resource)
  1311                 return self.GetVariableDictionary(resource, debug)
  1285         
  1312         
  1286         return []
  1313         return []
  1287     
  1314     
  1288     # Return resource variable names
  1315     # Return resource variable names
  1289     def GetConfigurationResourceVariableNames(self, 
  1316     def GetConfigurationResourceVariableNames(self, 
  1306     def GetPouInterfaceVars(self, pou, debug = False):
  1333     def GetPouInterfaceVars(self, pou, debug = False):
  1307         interface = pou.interface
  1334         interface = pou.interface
  1308         # Verify that the pou has an interface
  1335         # Verify that the pou has an interface
  1309         if interface is not None:
  1336         if interface is not None:
  1310             # Extract variables defined in interface
  1337             # Extract variables defined in interface
  1311             return self.GetVariableDictionary(interface)
  1338             return self.GetVariableDictionary(interface, debug)
  1312         return []
  1339         return []
  1313 
  1340 
  1314     # Replace the Pou interface by the one given
  1341     # Replace the Pou interface by the one given
  1315     def SetPouInterfaceVars(self, name, vars):
  1342     def SetPouInterfaceVars(self, name, vars):
  1316         if self.Project is not None:
  1343         if self.Project is not None:
  1490                  "list": [block for block in category["list"]
  1517                  "list": [block for block in category["list"]
  1491                           if block["type"] in filter]}
  1518                           if block["type"] in filter]}
  1492                 for category in self.TotalTypes]
  1519                 for category in self.TotalTypes]
  1493             blocktypes.append({"name" : USER_DEFINED_POUS, 
  1520             blocktypes.append({"name" : USER_DEFINED_POUS, 
  1494                 "list": [pou.getblockInfos()
  1521                 "list": [pou.getblockInfos()
  1495                          for pou in project.getpous(name, filter)]})
  1522                          for pou in project.getpous(name, filter)
       
  1523                          if (name is None or 
       
  1524                              self.GetInstanceList(pou, name, debug) is None)]})
  1496             return blocktypes
  1525             return blocktypes
  1497         return self.TotalTypes
  1526         return self.TotalTypes
  1498 
  1527 
  1499     # Return Function Block types checking for recursion
  1528     # Return Function Block types checking for recursion
  1500     def GetFunctionBlockTypes(self, tagname = "", debug = False):
  1529     def GetFunctionBlockTypes(self, tagname = "", debug = False):
       
  1530         project = self.GetProject(debug)
       
  1531         words = tagname.split("::")
       
  1532         name = None
       
  1533         if project is not None and words[0] in ["P","T","A"]:
       
  1534             name = words[1]
  1501         blocktypes = []
  1535         blocktypes = []
  1502         for blocks in self.TotalTypesDict.itervalues():
  1536         for blocks in self.TotalTypesDict.itervalues():
  1503             for sectioname,block in blocks:
  1537             for sectioname,block in blocks:
  1504                 if block["type"] == "functionBlock":
  1538                 if block["type"] == "functionBlock":
  1505                     blocktypes.append(block["name"])
  1539                     blocktypes.append(block["name"])
  1506         project = self.GetProject(debug)
  1540         if project is not None:
  1507         if project is not None:
       
  1508             words = tagname.split("::")
       
  1509             blocktypes.extend([pou.getname()
  1541             blocktypes.extend([pou.getname()
  1510                 for pou in project.getpous(
  1542                 for pou in project.getpous(name, ["functionBlock"])
  1511                     words[1] if words[0] in ["P","T","A"] else None,
  1543                 if (name is None or 
  1512                     ["functionBlock"])])
  1544                     self.GetInstanceList(pou, name, debug) is None)])
  1513         return blocktypes
  1545         return blocktypes
  1514 
  1546 
  1515     # Return Block types checking for recursion
  1547     # Return Block types checking for recursion
  1516     def GetBlockResource(self, debug = False):
  1548     def GetBlockResource(self, debug = False):
  1517         blocktypes = []
  1549         blocktypes = []
  1539             if words[0] in ["D"]:
  1571             if words[0] in ["D"]:
  1540                 name = words[1]
  1572                 name = words[1]
  1541             datatypes.extend([
  1573             datatypes.extend([
  1542                 datatype.getname() 
  1574                 datatype.getname() 
  1543                 for datatype in project.getdataTypes(name)
  1575                 for datatype in project.getdataTypes(name)
  1544                 if not only_locatables or self.IsLocatableDataType(datatype, debug)])
  1576                 if (not only_locatables or self.IsLocatableDataType(datatype, debug))
       
  1577                     and (name is None or 
       
  1578                          self.GetInstanceList(datatype, name, debug) is None)])
  1545         if confnodetypes:
  1579         if confnodetypes:
  1546             for category in self.GetConfNodeDataTypes(name, only_locatables):
  1580             for category in self.GetConfNodeDataTypes(name, only_locatables):
  1547                 datatypes.extend(category["list"])
  1581                 datatypes.extend(category["list"])
  1548         return datatypes
  1582         return datatypes
  1549 
  1583