--- a/PLCControler.py Mon Sep 21 12:06:51 2009 +0200
+++ b/PLCControler.py Tue Sep 22 09:56:02 2009 +0200
@@ -251,7 +251,7 @@
def GetProjectConfigNames(self, debug = False):
project = self.GetProject(debug)
if project is not None:
- return [config.getName() for config in project.getconfigurations()]
+ return [config.getname() for config in project.getconfigurations()]
return []
# Return project pou variables
@@ -599,6 +599,51 @@
self.Project.insertpou(-1, new_pou)
self.BufferProject()
+ def PastePou(self, pou_type, pou_xml):
+ '''
+ Adds the POU defined by 'pou_xml' to the current project with type 'pou_type'
+ '''
+ try:
+ tree = minidom.parseString(pou_xml)
+ root = tree.childNodes[0]
+ except:
+ return _("Couldn't paste non-POU object.")
+
+ if root.nodeName == "pou":
+ new_pou = plcopen.pous_pou()
+ new_pou.loadXMLTree(root)
+
+ name = new_pou.getname()
+ orig_type = new_pou.getpouType()
+
+ # prevent violations of POU content restrictions:
+ # function blocks cannot be pasted as functions,
+ # programs cannot be pasted as functions or function blocks
+ if orig_type == 'functionBlock' and pou_type == 'function' or \
+ orig_type == 'program' and pou_type in ['function', 'functionBlock']:
+ return _('''%s "%s" can't be pasted as a %s.''') % (orig_type, name, pou_type)
+
+ while self.Project.getpou(name):
+ # a POU with that name already exists.
+ # make a new name and test if a POU with that name exists.
+
+ # append an incrementing numeric suffix to the POU name. it
+ # doesn't count up perfectly, but as long as it's unique who cares?
+ if name[-1] >= '0' and name[-1] <= '9':
+ last_digit = int(name[-1])
+ name = name[0:-1] + str(last_digit+1)
+ else:
+ name = name + '1'
+
+ # we've found a name that does not already exist, use it
+ new_pou.setname(name)
+ new_pou.setpouType(pou_type)
+
+ self.Project.insertpou(-1, new_pou)
+ self.BufferProject()
+ else:
+ return _("Couldn't paste non-POU object.")
+
# Remove a Pou from project
def ProjectRemovePou(self, pou_name):
if self.Project is not None:
@@ -737,9 +782,9 @@
def ChangeConfigurationResourceName(self, config_name, old_name, new_name):
if self.Project is not None:
# Found the resource corresponding to old name and change its name to new name
- resource = self.Project.getconfigurationResource(config_name)
+ resource = self.Project.getconfigurationResource(config_name, old_name)
if resource is not None:
- resource.setName(new_name)
+ resource.setname(new_name)
self.BufferProject()
# Return the type of the pou given by its name
@@ -850,6 +895,7 @@
# Create variable and change its properties
tempvar = plcopen.varListPlain_variable()
tempvar.setname(var["Name"])
+
var_type = plcopen.dataType()
if var["Type"] in self.GetBaseTypes():
if var["Type"] == "STRING":
@@ -863,6 +909,7 @@
derived_type.setname(var["Type"])
var_type.setcontent({"name" : "derived", "value" : derived_type})
tempvar.settype(var_type)
+
if var["Initial Value"] != "":
value = plcopen.value()
value.setvalue(var["Initial Value"])
@@ -871,9 +918,62 @@
tempvar.setaddress(var["Location"])
else:
tempvar.setaddress(None)
+ if var['Documentation'] != "":
+ ft = plcopen.formattedText()
+ ft.settext(var['Documentation'])
+ tempvar.setdocumentation(ft)
+
# Add variable to varList
current_varlist.appendvariable(tempvar)
return varlist_list
+
+ def GetVariableDictionary(self, varlist, var):
+ '''
+ convert a PLC variable to the dictionary representation
+ returned by Get*Vars)
+ '''
+
+ tempvar = {"Name" : var.getname()}
+
+ vartype_content = var.gettype().getcontent()
+ if vartype_content["name"] == "derived":
+ tempvar["Type"] = vartype_content["value"].getname()
+ elif vartype_content["name"] in ["string", "wstring"]:
+ tempvar["Type"] = vartype_content["name"].upper()
+ else:
+ tempvar["Type"] = vartype_content["name"]
+
+ tempvar["Edit"] = True
+
+ initial = var.getinitialValue()
+ if initial:
+ tempvar["Initial Value"] = initial.getvalue()
+ else:
+ tempvar["Initial Value"] = ""
+
+ address = var.getaddress()
+ if address:
+ tempvar["Location"] = address
+ else:
+ tempvar["Location"] = ""
+
+ if varlist.getretain():
+ tempvar["Retain"] = "Yes"
+ else:
+ tempvar["Retain"] = "No"
+
+ if varlist.getconstant():
+ tempvar["Constant"] = "Yes"
+ else:
+ tempvar["Constant"] = "No"
+
+ doc = var.getdocumentation()
+ if doc:
+ tempvar["Documentation"] = doc.gettext()
+ else:
+ tempvar["Documentation"] = ""
+
+ return tempvar
# Replace the configuration globalvars by those given
def SetConfigurationGlobalVars(self, name, vars):
@@ -897,33 +997,8 @@
# Extract variables from every varLists
for varlist in configuration.getglobalVars():
for var in varlist.getvariable():
- tempvar = {"Name" : var.getname(), "Class" : "Global"}
- vartype_content = var.gettype().getcontent()
- if vartype_content["name"] == "derived":
- tempvar["Type"] = vartype_content["value"].getname()
- elif vartype_content["name"] in ["string", "wstring"]:
- tempvar["Type"] = vartype_content["name"].upper()
- else:
- tempvar["Type"] = vartype_content["name"]
- tempvar["Edit"] = True
- initial = var.getinitialValue()
- if initial:
- tempvar["Initial Value"] = initial.getvalue()
- else:
- tempvar["Initial Value"] = ""
- address = var.getaddress()
- if address:
- tempvar["Location"] = address
- else:
- tempvar["Location"] = ""
- if varlist.getretain():
- tempvar["Retain"] = "Yes"
- else:
- tempvar["Retain"] = "No"
- if varlist.getconstant():
- tempvar["Constant"] = "Yes"
- else:
- tempvar["Constant"] = "No"
+ tempvar = self.GetVariableDictionary(varlist, var)
+ tempvar["Class"] = "Global"
vars.append(tempvar)
return vars
@@ -949,33 +1024,8 @@
# Extract variables from every varLists
for varlist in resource.getglobalVars():
for var in varlist.getvariable():
- tempvar = {"Name" : var.getname(), "Class" : "Global"}
- vartype_content = var.gettype().getcontent()
- if vartype_content["name"] == "derived":
- tempvar["Type"] = vartype_content["value"].getname()
- elif vartype_content["name"] in ["string", "wstring"]:
- tempvar["Type"] = vartype_content["name"].upper()
- else:
- tempvar["Type"] = vartype_content["name"]
- tempvar["Edit"] = True
- initial = var.getinitialValue()
- if initial:
- tempvar["Initial Value"] = initial.getvalue()
- else:
- tempvar["Initial Value"] = ""
- address = var.getaddress()
- if address:
- tempvar["Location"] = address
- else:
- tempvar["Location"] = ""
- if varlist.getretain():
- tempvar["Retain"] = "Yes"
- else:
- tempvar["Retain"] = "No"
- if varlist.getconstant():
- tempvar["Constant"] = "Yes"
- else:
- tempvar["Constant"] = "No"
+ tempvar = self.GetVariableDictionary(varlist, var)
+ tempvar["Class"] = "Global"
vars.append(tempvar)
return vars
@@ -1014,7 +1064,7 @@
tree.append((element.getname(), element_type["name"], ([], [])))
return tree, []
return [], []
-
+
# Return the interface for the given pou
def GetPouInterfaceVars(self, pou, debug = False):
vars = []
@@ -1023,36 +1073,16 @@
# Extract variables from every varLists
for type, varlist in pou.getvars():
for var in varlist.getvariable():
- tempvar = {"Name" : var.getname(), "Class" : type, "Tree" : ([], [])}
+ tempvar = self.GetVariableDictionary(varlist, var)
+
+ tempvar["Class"] = type
+ tempvar["Tree"] = ([], [])
+
vartype_content = var.gettype().getcontent()
if vartype_content["name"] == "derived":
- tempvar["Type"] = vartype_content["value"].getname()
tempvar["Edit"] = not pou.hasblock(tempvar["Name"])
tempvar["Tree"] = self.GenerateVarTree(tempvar["Type"], debug)
- else:
- if vartype_content["name"] in ["string", "wstring"]:
- tempvar["Type"] = vartype_content["name"].upper()
- else:
- tempvar["Type"] = vartype_content["name"]
- tempvar["Edit"] = True
- initial = var.getinitialValue()
- if initial:
- tempvar["Initial Value"] = initial.getvalue()
- else:
- tempvar["Initial Value"] = ""
- address = var.getaddress()
- if address:
- tempvar["Location"] = address
- else:
- tempvar["Location"] = ""
- if varlist.getretain():
- tempvar["Retain"] = "Yes"
- else:
- tempvar["Retain"] = "No"
- if varlist.getconstant():
- tempvar["Constant"] = "Yes"
- else:
- tempvar["Constant"] = "No"
+
vars.append(tempvar)
return vars
@@ -1231,9 +1261,13 @@
return project.GetBaseType(type)
return None
- # Return Base Types
def GetBaseTypes(self):
- return [value for value in TypeHierarchy.keys() if not value.startswith("ANY")]
+ '''
+ return the list of datatypes defined in IEC 61131-3.
+ TypeHierarchy_list has a rough order to it (e.g. SINT, INT, DINT, ...),
+ which makes it easy for a user to find a type in a menu.
+ '''
+ return [x for x,y in TypeHierarchy_list if not x.startswith("ANY")]
def IsOfType(self, type, reference, debug = False):
project = self.GetProject(debug)
@@ -1661,9 +1695,13 @@
if root.nodeType == tree.ELEMENT_NODE and root.nodeName == "paste":
for child in root.childNodes:
if child.nodeType == tree.ELEMENT_NODE:
+ if not child.nodeName in plcopen.ElementNameToClass:
+ return _("\"%s\" element can't be pasted here!!!")%child.nodeName
+
classname = plcopen.ElementNameToClass[child.nodeName]
if not self.CheckPasteCompatibility[bodytype](classname):
- return _("\"%s\" element can't be paste here!!!")%child.nodeName
+ return _("\"%s\" element can't be pasted here!!!")%child.nodeName
+
classobj = getattr(plcopen, classname, None)
if classobj is not None:
instance = classobj()
@@ -1673,7 +1711,7 @@
if blockname is not None:
blocktype = instance.gettypeName()
if element_type == "function":
- return _("FunctionBlock \"%s\" can't be paste in a Function!!!")%blocktype
+ return _("FunctionBlock \"%s\" can't be pasted in a Function!!!")%blocktype
blockname = self.GenerateNewName(tagname, blockname, "Block%d", debug=debug)
exclude[blockname] = True
instance.setinstanceName(blockname)