ST code generator: when including PLCopen TC6 XML libraries (for example py_ext/pous.xml or NativeLib.xml), also includes libraries globals in result
--- a/PLCControler.py Tue Nov 29 10:59:53 2022 +0100
+++ b/PLCControler.py Thu Dec 08 11:17:15 2022 +0100
@@ -448,12 +448,12 @@
return len(self.GetInstanceList(pou_infos, name, debug)) > 0
return False
- def GenerateProgram(self, filepath=None):
+ def GenerateProgram(self, filepath=None, **kwargs):
errors = []
warnings = []
if self.Project is not None:
try:
- self.ProgramChunks = GenerateCurrentProgram(self, self.Project, errors, warnings)
+ self.ProgramChunks = GenerateCurrentProgram(self, self.Project, errors, warnings,**kwargs)
self.NextCompiledProject = self.Copy(self.Project)
program_text = "".join([item[0] for item in self.ProgramChunks])
if filepath is not None:
@@ -1147,28 +1147,35 @@
def GetConfigurationExtraVariables(self):
global_vars = []
- for var_name, var_type, var_initial in self.GetConfNodeGlobalInstances():
- tempvar = PLCOpenParser.CreateElement("variable", "globalVars")
- tempvar.setname(var_name)
-
- tempvartype = PLCOpenParser.CreateElement("type", "variable")
- if var_type in self.GetBaseTypes():
- tempvartype.setcontent(PLCOpenParser.CreateElement(
- var_type.lower()
- if var_type in ["STRING", "WSTRING"]
- else var_type, "dataType"))
+ for global_instance in self.GetConfNodeGlobalInstances():
+ if type(global_instance)==tuple:
+ # usual global without modifier from a CTN or a library
+ var_name, var_type, var_initial = global_instance
+ tempvar = PLCOpenParser.CreateElement("variable", "globalVars")
+ tempvar.setname(var_name)
+
+ tempvartype = PLCOpenParser.CreateElement("type", "variable")
+ if var_type in self.GetBaseTypes():
+ tempvartype.setcontent(PLCOpenParser.CreateElement(
+ var_type.lower()
+ if var_type in ["STRING", "WSTRING"]
+ else var_type, "dataType"))
+ else:
+ tempderivedtype = PLCOpenParser.CreateElement("derived", "dataType")
+ tempderivedtype.setname(var_type)
+ tempvartype.setcontent(tempderivedtype)
+ tempvar.settype(tempvartype)
+
+ if var_initial != "":
+ value = PLCOpenParser.CreateElement("initialValue", "variable")
+ value.setvalue(var_initial)
+ tempvar.setinitialValue(value)
+
+ global_vars.append(tempvar)
else:
- tempderivedtype = PLCOpenParser.CreateElement("derived", "dataType")
- tempderivedtype.setname(var_type)
- tempvartype.setcontent(tempderivedtype)
- tempvar.settype(tempvartype)
-
- if var_initial != "":
- value = PLCOpenParser.CreateElement("initialValue", "variable")
- value.setvalue(var_initial)
- tempvar.setinitialValue(value)
-
- global_vars.append(tempvar)
+ # case of varlists from a TC6 library
+ global_vars.append(global_instance)
+
return global_vars
# Function that returns the block definition associated to the block type given
--- a/PLCGenerator.py Tue Nov 29 10:59:53 2022 +0100
+++ b/PLCGenerator.py Thu Dec 08 11:17:15 2022 +0100
@@ -277,21 +277,27 @@
("\n", ())]
var_number = 0
- varlists = [(varlist, varlist.getvariable()[:]) for varlist in configuration.getglobalVars()]
+ varlists = configuration.getglobalVars()[:]
extra_variables = self.Controler.GetConfigurationExtraVariables()
- extra_global_vars = None
- if len(extra_variables) > 0 and len(varlists) == 0:
- extra_global_vars = PLCOpenParser.CreateElement("globalVars", "interface")
- configuration.setglobalVars([extra_global_vars])
- varlists = [(extra_global_vars, [])]
-
- for variable in extra_variables:
- varlists[-1][0].appendvariable(variable)
- varlists[-1][1].append(variable)
+ extra_CTN_globals = []
+
+ for item in extra_variables:
+ if item.getLocalTag() == "globalVars":
+ varlists.append(item)
+ else:
+ extra_CTN_globals.append(item)
+
+ if len(extra_CTN_globals) > 0:
+ extra_varlist = PLCOpenParser.CreateElement("globalVars", "interface")
+
+ for variable in extra_CTN_globals:
+ extra_varlist.appendvariable(variable)
+
+ varlists.append(extra_varlist)
# Generate any global variable in configuration
- for varlist, varlist_variables in varlists:
+ for varlist in varlists:
variable_type = errorVarTypes.get("VAR_GLOBAL", "var_local")
# Generate variable block with modifier
config += [(" VAR_GLOBAL", ())]
@@ -303,7 +309,7 @@
config += [(" NON_RETAIN", (tagname, variable_type, (var_number, var_number + len(varlist.getvariable())), "non_retain"))]
config += [("\n", ())]
# Generate any variable of this block
- for var in varlist_variables:
+ for var in varlist.getvariable():
vartype_content = var.gettype().getcontent()
if vartype_content.getLocalTag() == "derived":
var_type = vartype_content.getname()
@@ -331,12 +337,6 @@
var_number += 1
config += [(" END_VAR\n", ())]
- if extra_global_vars is not None:
- configuration.remove(extra_global_vars)
- else:
- for variable in extra_variables:
- varlists[-1][0].remove(variable)
-
# Generate any resource in the configuration
for resource in configuration.getresource():
config += self.GenerateResource(resource, configuration.getname())
@@ -458,7 +458,7 @@
return resrce
# Generate the entire program for current project
- def GenerateProgram(self, log):
+ def GenerateProgram(self, log, noconfig=False):
log("Collecting data types")
# Find all data types defined
for datatype in self.Project.getdataTypes():
@@ -480,6 +480,8 @@
for pou_name in self.PouComputed.keys():
log("Generate POU %s"%pou_name)
self.GeneratePouProgram(pou_name)
+ if noconfig:
+ return
# Generate every configurations defined
log("Generate Config(s)")
for config in self.Project.getconfigurations():
@@ -1765,7 +1767,7 @@
return program
-def GenerateCurrentProgram(controler, project, errors, warnings):
+def GenerateCurrentProgram(controler, project, errors, warnings, **kwargs):
generator = ProgramGenerator(controler, project, errors, warnings)
if hasattr(controler, "logger"):
def log(txt):
@@ -1774,5 +1776,5 @@
def log(txt):
pass
- generator.GenerateProgram(log)
+ generator.GenerateProgram(log,**kwargs)
return generator.GetGeneratedProgram()
--- a/POULibrary.py Tue Nov 29 10:59:53 2022 +0100
+++ b/POULibrary.py Thu Dec 08 11:17:15 2022 +0100
@@ -44,7 +44,7 @@
def GetSTCode(self):
if not self.program:
- self.program = self.LibraryControler.GenerateProgram()[0]+"\n"
+ self.program = self.LibraryControler.GenerateProgram(noconfig=True)[0]+"\n"
return self.program
def GetName(self):
@@ -65,9 +65,14 @@
def GlobalInstances(self):
"""
- @return: [(instance_name, instance_type),...]
+ @return: [varlist_object, ...]
"""
- return []
+ varlists = []
+ for configuration in self.LibraryControler.Project.getconfigurations():
+ varlist = configuration.getglobalVars()
+ if len(varlist)>0 :
+ varlists += varlist
+ return varlists
def FatalError(self, message):
""" Raise an exception that will trigger error message intended to