--- a/PLCControler.py Wed Sep 18 15:26:33 2013 +0200
+++ b/PLCControler.py Wed Sep 18 15:30:46 2013 +0200
@@ -140,18 +140,19 @@
class VarTree(etree.XSLTExtension):
- def __init__(self, controller):
+ def __init__(self, controller, debug): etree.XSLTExtension.__init__(self)
self.Controller = controller
def execute(self, context, self_node, input_node, output_parent):
typename = input_node.get("name")
- pou_infos = self.Controller.GetPou(typename)
+ pou_infos = self.Controller.GetPou(typename, self.Debug) if pou_infos is not None:
self.apply_templates(context, pou_infos, output_parent)
- datatype_infos = self.Controller.GetDataType(typename)
+ datatype_infos = self.Controller.GetDataType(typename, self.Debug) if datatype_infos is not None:
self.apply_templates(context, datatype_infos, output_parent)
@@ -164,9 +165,10 @@
#-------------------------------------------------------------------------------
def class_extraction(el, prt):
- return POU_TYPES[el.text]
- elif prt == "variable":
+ if prt in ["pou", "variable"]: + pou_type = POU_TYPES.get(el.text) + if pou_type is not None: return VAR_CLASS_INFOS[el.text][1]
"configuration": ITEM_CONFIGURATION,
@@ -200,10 +202,8 @@
def execute(self, context, self_node, input_node, output_parent):
typename = input_node.get("name")
project = self.Controller.GetProject(self.Debug)
- infos = etree.Element('{http://www.w3.org/1999/XSL/Transform}text')
- infos.text = str(project.getpou(typename) is not None)
- self.process_children(context, infos)
+ output_parent.text = str(project.getpou(typename) is not None) class IsDebugged(etree.XSLTExtension):
def __init__(self, controller, debug):
@@ -223,11 +223,62 @@
if datatype_infos is not None:
self.apply_templates(context, datatype_infos, output_parent)
+ output_parent.text = "False" +class PouVariableClass(etree.XSLTExtension): + def __init__(self, controller, debug): + etree.XSLTExtension.__init__(self) + self.Controller = controller + def execute(self, context, self_node, input_node, output_parent): + pou_infos = self.Controller.GetPou(input_node.get("name"), self.Debug) + if pou_infos is not None: + self.apply_templates(context, pou_infos, output_parent) + self.process_children(context, output_parent) pou_variables_xslt = etree.parse(
os.path.join(ScriptDirectory, "plcopen", "pou_variables.xslt"))
#-------------------------------------------------------------------------------
+# Helpers object for generating instances path list +#------------------------------------------------------------------------------- +class InstanceDefinition(etree.XSLTExtension): + def __init__(self, controller, debug): + etree.XSLTExtension.__init__(self) + self.Controller = controller + def execute(self, context, self_node, input_node, output_parent): + instance_infos = etree.Element('infos') + self.process_children(context, instance_infos) + pou_infos = self.Controller.GetPou(instance_infos.get("name"), self.Debug) + if pou_infos is not None: + pou_instance = etree.Element('pou_instance', + pou_path=instance_infos.get("path")) + pou_instance.append(deepcopy(pou_infos)) + self.apply_templates(context, pou_instance, output_parent) + datatype_infos = self.Controller.GetDataType(instance_infos.get("name"), self.Debug) + if datatype_infos is not None: + datatype_instance = etree.Element('datatype_instance', + datatype_path=instance_infos.get("path")) + datatype_instance.append(deepcopy(datatype_infos)) + self.apply_templates(context, datatype_instance, output_parent) +instances_path_xslt = etree.parse( + os.path.join(ScriptDirectory, "plcopen", "instances_path.xslt")) +#------------------------------------------------------------------------------- # Undo Buffer for PLCOpenEditor
#-------------------------------------------------------------------------------
@@ -525,65 +576,41 @@
pou_variable_xslt_tree = etree.XSLT(
pou_variables_xslt, extensions = {
("pou_vars_ns", "is_edited"): IsEdited(self, debug),
- ("pou_vars_ns", "is_debugged"): IsDebugged(self, debug)})
- return compute_instance_tree(
- pou_variable_xslt_tree(
- self.GetEditedElement(tagname, debug)).getroot())
+ ("pou_vars_ns", "is_debugged"): IsDebugged(self, debug), + ("pou_vars_ns", "pou_class"): PouVariableClass(self, debug)}) + words = tagname.split("::") + obj = self.GetPou(words[1], debug) + obj = self.GetEditedElement(tagname, debug) + return compute_instance_tree( + pou_variable_xslt_tree(obj).getroot()) - def RecursiveSearchPouInstances(self, project, pou_type, parent_path, varlists, debug = False):
- for varlist in varlists:
- for variable in varlist.getvariable():
- vartype_content = variable.gettype().getcontent()
- if vartype_content.getLocalTag() == "derived":
- var_path = "%s.%s" % (parent_path, variable.getname())
- var_type = vartype_content.getname()
- if var_type == pou_type:
- instances.append(var_path)
- pou = project.getpou(var_type)
- if pou is not None:# and project.ElementIsUsedBy(pou_type, var_type):
- self.RecursiveSearchPouInstances(
- project, pou_type, var_path,
- [varlist for type, varlist in pou.getvars()],
+ def GetInstanceList(self, root, name, debug = False): + project = self.GetProject(debug) + if project is not None: + instances_path_xslt_tree = etree.XSLT( + ("instances_ns", "instance_definition"): + InstanceDefinition(self, debug)}) + return instances_path_xslt_tree(root, + instance_type=etree.XSLT.strparam(name)).getroot() def SearchPouInstances(self, tagname, debug = False):
project = self.GetProject(debug)
words = tagname.split("::")
- for config in project.getconfigurations():
- config_name = config.getname()
- self.RecursiveSearchPouInstances(
- project, words[1], config_name,
- config.getglobalVars(), debug))
- for resource in config.getresource():
- res_path = "%s.%s" % (config_name, resource.getname())
- self.RecursiveSearchPouInstances(
- project, words[1], res_path,
- resource.getglobalVars(), debug))
- pou_instances = resource.getpouInstance()[:]
- for task in resource.gettask():
- pou_instances.extend(task.getpouInstance())
- for pou_instance in pou_instances:
- pou_path = "%s.%s" % (res_path, pou_instance.getname())
- pou_type = pou_instance.gettypeName()
- if pou_type == words[1]:
- instances.append(pou_path)
- pou = project.getpou(pou_type)
- if pou is not None:# and project.ElementIsUsedBy(words[1], pou_type):
- self.RecursiveSearchPouInstances(
- project, words[1], pou_path,
- [varlist for type, varlist in pou.getvars()],
+ result = self.GetInstanceList(project, words[1]) + return [instance.get("path") for instance in result] @@ -607,7 +634,7 @@
if vartype_content.getLocalTag() == "derived":
return self.RecursiveGetPouInstanceTagName(
- vartype_content["value"].getname(),
+ vartype_content.getname(), if pou.getbodyType() == "SFC" and len(parts) == 1:
@@ -707,23 +734,23 @@
# Return if data type given by name is used by another data type or pou
def DataTypeIsUsed(self, name, debug = False):
- #project = self.GetProject(debug)
- #if project is not None:
- # return project.ElementIsUsed(name)
+ project = self.GetProject(debug) + if project is not None: + return self.GetInstanceList(project, name, debug) is not None # Return if pou given by name is used by another pou
def PouIsUsed(self, name, debug = False):
- #project = self.GetProject(debug)
- #if project is not None:
- # return project.ElementIsUsed(name)
+ project = self.GetProject(debug) + if project is not None: + return self.GetInstanceList(project, name, debug) is not None # Return if pou given by name is directly or undirectly used by the reference pou
def PouIsUsedBy(self, name, reference, debug = False):
- #project = self.GetProject(debug)
- #if project is not None:
- # return project.ElementIsUsedBy(name, reference)
+ pou_infos = self.GetPou(reference, debug) + if pou_infos is not None: + return self.GetInstanceList(pou_infos, name, debug) is not None def GenerateProgram(self, filepath=None):
@@ -1202,13 +1229,13 @@
current_varlist.appendvariable(tempvar)
- def GetVariableDictionary(self, object_with_vars):
+ def GetVariableDictionary(self, object_with_vars, debug=False): variables_infos_xslt_tree = etree.XSLT(
variables_infos_xslt, extensions = {
("var_infos_ns", "add_variable"): AddVariable(variables),
- ("var_infos_ns", "var_tree"): VarTree(self)})
+ ("var_infos_ns", "var_tree"): VarTree(self, debug)}) variables_infos_xslt_tree(object_with_vars)
@@ -1244,7 +1271,7 @@
configuration = project.getconfiguration(name)
if configuration is not None:
# Extract variables defined in configuration
- return self.GetVariableDictionary(configuration)
+ return self.GetVariableDictionary(configuration, debug) @@ -1281,7 +1308,7 @@
resource = project.getconfigurationResource(config_name, name)
# Extract variables defined in configuration
- return self.GetVariableDictionary(resource)
+ return self.GetVariableDictionary(resource, debug) @@ -1308,7 +1335,7 @@
# Verify that the pou has an interface
if interface is not None:
# Extract variables defined in interface
- return self.GetVariableDictionary(interface)
+ return self.GetVariableDictionary(interface, debug) # Replace the Pou interface by the one given
@@ -1492,24 +1519,29 @@
for category in self.TotalTypes]
blocktypes.append({"name" : USER_DEFINED_POUS,
"list": [pou.getblockInfos()
- for pou in project.getpous(name, filter)]})
+ for pou in project.getpous(name, filter) + self.GetInstanceList(pou, name, debug) is None)]}) # Return Function Block types checking for recursion
def GetFunctionBlockTypes(self, tagname = "", debug = False):
+ project = self.GetProject(debug) + words = tagname.split("::") + if project is not None and words[0] in ["P","T","A"]: for blocks in self.TotalTypesDict.itervalues():
for sectioname,block in blocks:
if block["type"] == "functionBlock":
blocktypes.append(block["name"])
- project = self.GetProject(debug)
- words = tagname.split("::")
blocktypes.extend([pou.getname()
- for pou in project.getpous(
- words[1] if words[0] in ["P","T","A"] else None,
+ for pou in project.getpous(name, ["functionBlock"]) + self.GetInstanceList(pou, name, debug) is None)]) # Return Block types checking for recursion
@@ -1541,7 +1573,9 @@
for datatype in project.getdataTypes(name)
- if not only_locatables or self.IsLocatableDataType(datatype, debug)])
+ if (not only_locatables or self.IsLocatableDataType(datatype, debug)) + self.GetInstanceList(datatype, name, debug) is None)]) for category in self.GetConfNodeDataTypes(name, only_locatables):
datatypes.extend(category["list"])
--- a/plcopen/pou_variables.xslt Wed Sep 18 15:26:33 2013 +0200
+++ b/plcopen/pou_variables.xslt Wed Sep 18 15:30:46 2013 +0200
@@ -102,7 +102,13 @@
<xsl:for-each select="ppx:variable">
<name><xsl:value-of select="@name"/></name>
- <class><xsl:value-of select="$var_class"/></class>
+ <xsl:apply-templates mode="var_class"> + <xsl:with-param name="default_class"> + <xsl:value-of select="$var_class"/> <type><xsl:apply-templates mode="var_type"/></type>
<edit><xsl:apply-templates mode="var_edit"/></edit>
<debug><xsl:apply-templates mode="var_debug"/></debug>
@@ -145,6 +151,20 @@
<debug><xsl:text>True</xsl:text></debug>
+ <xsl:template match="*[self::ppx:type or self::ppx:baseType]/ppx:derived" mode="var_class"> + <xsl:param name="default_class"/> + <xsl:value-of select="$default_class"/> + <xsl:template match="ppx:pou" mode="var_class"> + <xsl:param name="default_class"/> + <xsl:value-of select="@pouType"/> + <xsl:template match="*[self::ppx:type or self::ppx:baseType]/*" mode="var_class"> + <xsl:param name="default_class"/> + <xsl:value-of select="$default_class"/> <xsl:template match="*[self::ppx:type or self::ppx:baseType]/ppx:derived" mode="var_type">
<xsl:value-of select="@name"/>
@@ -178,14 +198,6 @@
<xsl:template match="*[self::ppx:type or self::ppx:baseType]/ppx:derived" mode="var_debug">
- <xsl:when test="count(./*) > 0">
- <xsl:apply-templates mode="var_debug"/>
- <xsl:text>False</xsl:text>
<xsl:template match="ppx:pou" mode="var_debug">
<xsl:text>True</xsl:text>
@@ -200,6 +212,7 @@
<xsl:text>True</xsl:text>
<xsl:template match="text()"/>
+ <xsl:template match="text()" mode="var_class"/> <xsl:template match="text()" mode="var_type"/>
<xsl:template match="text()" mode="var_edit"/>
<xsl:template match="text()" mode="var_debug"/>