|
1 #!/usr/bin/env python |
|
2 # -*- coding: utf-8 -*- |
|
3 |
|
4 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor |
|
5 #based on the plcopen standard. |
|
6 # |
|
7 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD |
|
8 # |
|
9 #See COPYING file for copyrights details. |
|
10 # |
|
11 #This library is free software; you can redistribute it and/or |
|
12 #modify it under the terms of the GNU General Public |
|
13 #License as published by the Free Software Foundation; either |
|
14 #version 2.1 of the License, or (at your option) any later version. |
|
15 # |
|
16 #This library is distributed in the hope that it will be useful, |
|
17 #but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
18 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
19 #General Public License for more details. |
|
20 # |
|
21 #You should have received a copy of the GNU General Public |
|
22 #License along with this library; if not, write to the Free Software |
|
23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
24 |
|
25 from xmlclass import * |
|
26 from structures import * |
|
27 from types import * |
|
28 import os, re |
|
29 |
|
30 """ |
|
31 Dictionary that makes the relation between var names in plcopen and displayed values |
|
32 """ |
|
33 VarTypes = {"Local" : "localVars", "Temp" : "tempVars", "Input" : "inputVars", |
|
34 "Output" : "outputVars", "InOut" : "inOutVars", "External" : "externalVars", |
|
35 "Global" : "globalVars", "Access" : "accessVars"} |
|
36 |
|
37 searchResultVarTypes = { |
|
38 "inputVars": "var_input", |
|
39 "outputVars": "var_output", |
|
40 "inOutVars": "var_inout" |
|
41 } |
|
42 |
|
43 """ |
|
44 Define in which order var types must be displayed |
|
45 """ |
|
46 VarOrder = ["Local","Temp","Input","Output","InOut","External","Global","Access"] |
|
47 |
|
48 """ |
|
49 Define which action qualifier must be associated with a duration |
|
50 """ |
|
51 QualifierList = {"N" : False, "R" : False, "S" : False, "L" : True, "D" : True, |
|
52 "P" : False, "P0" : False, "P1" : False, "SD" : True, "DS" : True, "SL" : True} |
|
53 |
|
54 |
|
55 FILTER_ADDRESS_MODEL = "(%%[IQM](?:[XBWDL])?)(%s)((?:\.[0-9]+)*)" |
|
56 |
|
57 def update_address(address, address_model, new_leading): |
|
58 result = address_model.match(address) |
|
59 if result is None: |
|
60 return address |
|
61 groups = result.groups() |
|
62 return groups[0] + new_leading + groups[2] |
|
63 |
|
64 def _init_and_compare(function, v1, v2): |
|
65 if v1 is None: |
|
66 return v2 |
|
67 if v2 is not None: |
|
68 return function(v1, v2) |
|
69 return v1 |
|
70 |
|
71 """ |
|
72 Helper class for bounding_box calculation |
|
73 """ |
|
74 class rect: |
|
75 |
|
76 def __init__(self, x=None, y=None, width=None, height=None): |
|
77 self.x_min = x |
|
78 self.x_max = None |
|
79 self.y_min = y |
|
80 self.y_max = None |
|
81 if width is not None and x is not None: |
|
82 self.x_max = x + width |
|
83 if height is not None and y is not None: |
|
84 self.y_max = y + height |
|
85 |
|
86 def update(self, x, y): |
|
87 self.x_min = _init_and_compare(min, self.x_min, x) |
|
88 self.x_max = _init_and_compare(max, self.x_max, x) |
|
89 self.y_min = _init_and_compare(min, self.y_min, y) |
|
90 self.y_max = _init_and_compare(max, self.y_max, y) |
|
91 |
|
92 def union(self, rect): |
|
93 self.x_min = _init_and_compare(min, self.x_min, rect.x_min) |
|
94 self.x_max = _init_and_compare(max, self.x_max, rect.x_max) |
|
95 self.y_min = _init_and_compare(min, self.y_min, rect.y_min) |
|
96 self.y_max = _init_and_compare(max, self.y_max, rect.y_max) |
|
97 |
|
98 def bounding_box(self): |
|
99 width = height = None |
|
100 if self.x_min is not None and self.x_max is not None: |
|
101 width = self.x_max - self.x_min |
|
102 if self.y_min is not None and self.y_max is not None: |
|
103 height = self.y_max - self.y_min |
|
104 return self.x_min, self.y_min, width, height |
|
105 |
|
106 def TextLenInRowColumn(text): |
|
107 if text == "": |
|
108 return (0, 0) |
|
109 lines = text.split("\n") |
|
110 return len(lines) - 1, len(lines[-1]) |
|
111 |
|
112 def TestTextElement(text, criteria): |
|
113 lines = text.splitlines() |
|
114 if not criteria["case_sensitive"]: |
|
115 text = text.upper() |
|
116 test_result = [] |
|
117 result = criteria["pattern"].search(text) |
|
118 while result is not None: |
|
119 start = TextLenInRowColumn(text[:result.start()]) |
|
120 end = TextLenInRowColumn(text[:result.end() - 1]) |
|
121 test_result.append((start, end, "\n".join(lines[start[0]:end[0] + 1]))) |
|
122 result = criteria["pattern"].search(text, result.end()) |
|
123 return test_result |
|
124 |
|
125 PLCOpenClasses = GenerateClassesFromXSD(os.path.join(os.path.split(__file__)[0], "tc6_xml_v201.xsd")) |
|
126 |
|
127 ElementNameToClass = {} |
|
128 |
|
129 cls = PLCOpenClasses.get("formattedText", None) |
|
130 if cls: |
|
131 def updateElementName(self, old_name, new_name): |
|
132 text = self.text.decode("utf-8") |
|
133 index = text.find(old_name) |
|
134 while index != -1: |
|
135 if index > 0 and (text[index - 1].isalnum() or text[index - 1] == "_"): |
|
136 index = text.find(old_name, index + len(old_name)) |
|
137 elif index < len(text) - len(old_name) and (text[index + len(old_name)].isalnum() or text[index + len(old_name)] == "_"): |
|
138 index = text.find(old_name, index + len(old_name)) |
|
139 else: |
|
140 text = text[:index] + new_name + text[index + len(old_name):] |
|
141 index = text.find(old_name, index + len(new_name)) |
|
142 self.text = text.encode("utf-8") |
|
143 setattr(cls, "updateElementName", updateElementName) |
|
144 |
|
145 def updateElementAddress(self, address_model, new_leading): |
|
146 text = self.text.decode("utf-8") |
|
147 startpos = 0 |
|
148 result = address_model.search(text, startpos) |
|
149 while result is not None: |
|
150 groups = result.groups() |
|
151 new_address = groups[0] + new_leading + groups[2] |
|
152 text = text[:result.start()] + new_address + text[result.end():] |
|
153 startpos = result.start() + len(new_address) |
|
154 result = address_model.search(self.text, startpos) |
|
155 self.text = text.encode("utf-8") |
|
156 setattr(cls, "updateElementAddress", updateElementAddress) |
|
157 |
|
158 def Search(self, criteria, parent_infos): |
|
159 return [(tuple(parent_infos),) + result for result in TestTextElement(self.gettext(), criteria)] |
|
160 setattr(cls, "Search", Search) |
|
161 |
|
162 cls = PLCOpenClasses.get("project", None) |
|
163 if cls: |
|
164 cls.singleLineAttributes = False |
|
165 cls.EnumeratedDataTypeValues = {} |
|
166 cls.CustomDataTypeRange = {} |
|
167 cls.CustomTypeHierarchy = {} |
|
168 cls.ElementUsingTree = {} |
|
169 cls.CustomBlockTypes = [] |
|
170 |
|
171 def setname(self, name): |
|
172 self.contentHeader.setname(name) |
|
173 setattr(cls, "setname", setname) |
|
174 |
|
175 def getname(self): |
|
176 return self.contentHeader.getname() |
|
177 setattr(cls, "getname", getname) |
|
178 |
|
179 def getfileHeader(self): |
|
180 fileheader = {} |
|
181 for name, value in [("companyName", self.fileHeader.getcompanyName()), |
|
182 ("companyURL", self.fileHeader.getcompanyURL()), |
|
183 ("productName", self.fileHeader.getproductName()), |
|
184 ("productVersion", self.fileHeader.getproductVersion()), |
|
185 ("productRelease", self.fileHeader.getproductRelease()), |
|
186 ("creationDateTime", self.fileHeader.getcreationDateTime()), |
|
187 ("contentDescription", self.fileHeader.getcontentDescription())]: |
|
188 if value is not None: |
|
189 fileheader[name] = value |
|
190 else: |
|
191 fileheader[name] = "" |
|
192 return fileheader |
|
193 setattr(cls, "getfileHeader", getfileHeader) |
|
194 |
|
195 def setfileHeader(self, fileheader): |
|
196 if fileheader.has_key("companyName"): |
|
197 self.fileHeader.setcompanyName(fileheader["companyName"]) |
|
198 if fileheader.has_key("companyURL"): |
|
199 self.fileHeader.setcompanyURL(fileheader["companyURL"]) |
|
200 if fileheader.has_key("productName"): |
|
201 self.fileHeader.setproductName(fileheader["productName"]) |
|
202 if fileheader.has_key("productVersion"): |
|
203 self.fileHeader.setproductVersion(fileheader["productVersion"]) |
|
204 if fileheader.has_key("productRelease"): |
|
205 self.fileHeader.setproductRelease(fileheader["productRelease"]) |
|
206 if fileheader.has_key("creationDateTime"): |
|
207 self.fileHeader.setcreationDateTime(fileheader["creationDateTime"]) |
|
208 if fileheader.has_key("contentDescription"): |
|
209 self.fileHeader.setcontentDescription(fileheader["contentDescription"]) |
|
210 setattr(cls, "setfileHeader", setfileHeader) |
|
211 |
|
212 def getcontentHeader(self): |
|
213 contentheader = {} |
|
214 for name, value in [("projectName", self.contentHeader.getname()), |
|
215 ("projectVersion", self.contentHeader.getversion()), |
|
216 ("modificationDateTime", self.contentHeader.getmodificationDateTime()), |
|
217 ("organization", self.contentHeader.getorganization()), |
|
218 ("authorName", self.contentHeader.getauthor()), |
|
219 ("language", self.contentHeader.getlanguage())]: |
|
220 if value is not None: |
|
221 contentheader[name] = value |
|
222 else: |
|
223 contentheader[name] = "" |
|
224 contentheader["pageSize"] = self.contentHeader.getpageSize() |
|
225 contentheader["scaling"] = self.contentHeader.getscaling() |
|
226 return contentheader |
|
227 setattr(cls, "getcontentHeader", getcontentHeader) |
|
228 |
|
229 def setcontentHeader(self, contentheader): |
|
230 if contentheader.has_key("projectName"): |
|
231 self.contentHeader.setname(contentheader["projectName"]) |
|
232 if contentheader.has_key("projectVersion"): |
|
233 self.contentHeader.setversion(contentheader["projectVersion"]) |
|
234 if contentheader.has_key("modificationDateTime"): |
|
235 self.contentHeader.setmodificationDateTime(contentheader["modificationDateTime"]) |
|
236 if contentheader.has_key("organization"): |
|
237 self.contentHeader.setorganization(contentheader["organization"]) |
|
238 if contentheader.has_key("authorName"): |
|
239 self.contentHeader.setauthor(contentheader["authorName"]) |
|
240 if contentheader.has_key("language"): |
|
241 self.contentHeader.setlanguage(contentheader["language"]) |
|
242 if contentheader.has_key("pageSize"): |
|
243 self.contentHeader.setpageSize(*contentheader["pageSize"]) |
|
244 if contentheader.has_key("scaling"): |
|
245 self.contentHeader.setscaling(contentheader["scaling"]) |
|
246 setattr(cls, "setcontentHeader", setcontentHeader) |
|
247 |
|
248 def getdataTypes(self): |
|
249 return self.types.getdataTypeElements() |
|
250 setattr(cls, "getdataTypes", getdataTypes) |
|
251 |
|
252 def getdataType(self, name): |
|
253 return self.types.getdataTypeElement(name) |
|
254 setattr(cls, "getdataType", getdataType) |
|
255 |
|
256 def appenddataType(self, name): |
|
257 if self.CustomTypeHierarchy.has_key(name): |
|
258 raise ValueError, "\"%s\" Data Type already exists !!!"%name |
|
259 self.types.appenddataTypeElement(name) |
|
260 self.AddCustomDataType(self.getdataType(name)) |
|
261 setattr(cls, "appenddataType", appenddataType) |
|
262 |
|
263 def insertdataType(self, index, datatype): |
|
264 self.types.insertdataTypeElement(index, datatype) |
|
265 self.AddCustomDataType(datatype) |
|
266 setattr(cls, "insertdataType", insertdataType) |
|
267 |
|
268 def removedataType(self, name): |
|
269 self.types.removedataTypeElement(name) |
|
270 self.RefreshDataTypeHierarchy() |
|
271 self.RefreshElementUsingTree() |
|
272 setattr(cls, "removedataType", removedataType) |
|
273 |
|
274 def getpous(self): |
|
275 return self.types.getpouElements() |
|
276 setattr(cls, "getpous", getpous) |
|
277 |
|
278 def getpou(self, name): |
|
279 return self.types.getpouElement(name) |
|
280 setattr(cls, "getpou", getpou) |
|
281 |
|
282 def appendpou(self, name, pou_type, body_type): |
|
283 self.types.appendpouElement(name, pou_type, body_type) |
|
284 self.AddCustomBlockType(self.getpou(name)) |
|
285 setattr(cls, "appendpou", appendpou) |
|
286 |
|
287 def insertpou(self, index, pou): |
|
288 self.types.insertpouElement(index, pou) |
|
289 self.AddCustomBlockType(pou) |
|
290 setattr(cls, "insertpou", insertpou) |
|
291 |
|
292 def removepou(self, name): |
|
293 self.types.removepouElement(name) |
|
294 self.RefreshCustomBlockTypes() |
|
295 self.RefreshElementUsingTree() |
|
296 setattr(cls, "removepou", removepou) |
|
297 |
|
298 def getconfigurations(self): |
|
299 configurations = self.instances.configurations.getconfiguration() |
|
300 if configurations: |
|
301 return configurations |
|
302 return [] |
|
303 setattr(cls, "getconfigurations", getconfigurations) |
|
304 |
|
305 def getconfiguration(self, name): |
|
306 for configuration in self.instances.configurations.getconfiguration(): |
|
307 if configuration.getname() == name: |
|
308 return configuration |
|
309 return None |
|
310 setattr(cls, "getconfiguration", getconfiguration) |
|
311 |
|
312 def addconfiguration(self, name): |
|
313 for configuration in self.instances.configurations.getconfiguration(): |
|
314 if configuration.getname() == name: |
|
315 raise ValueError, _("\"%s\" configuration already exists !!!")%name |
|
316 new_configuration = PLCOpenClasses["configurations_configuration"]() |
|
317 new_configuration.setname(name) |
|
318 self.instances.configurations.appendconfiguration(new_configuration) |
|
319 setattr(cls, "addconfiguration", addconfiguration) |
|
320 |
|
321 def removeconfiguration(self, name): |
|
322 found = False |
|
323 for idx, configuration in enumerate(self.instances.configurations.getconfiguration()): |
|
324 if configuration.getname() == name: |
|
325 self.instances.configurations.removeconfiguration(idx) |
|
326 found = True |
|
327 break |
|
328 if not found: |
|
329 raise ValueError, ("\"%s\" configuration doesn't exist !!!")%name |
|
330 setattr(cls, "removeconfiguration", removeconfiguration) |
|
331 |
|
332 def getconfigurationResource(self, config_name, name): |
|
333 configuration = self.getconfiguration(config_name) |
|
334 if configuration: |
|
335 for resource in configuration.getresource(): |
|
336 if resource.getname() == name: |
|
337 return resource |
|
338 return None |
|
339 setattr(cls, "getconfigurationResource", getconfigurationResource) |
|
340 |
|
341 def addconfigurationResource(self, config_name, name): |
|
342 configuration = self.getconfiguration(config_name) |
|
343 if configuration: |
|
344 for resource in configuration.getresource(): |
|
345 if resource.getname() == name: |
|
346 raise ValueError, _("\"%s\" resource already exists in \"%s\" configuration !!!")%(name, config_name) |
|
347 new_resource = PLCOpenClasses["configuration_resource"]() |
|
348 new_resource.setname(name) |
|
349 configuration.appendresource(new_resource) |
|
350 setattr(cls, "addconfigurationResource", addconfigurationResource) |
|
351 |
|
352 def removeconfigurationResource(self, config_name, name): |
|
353 configuration = self.getconfiguration(config_name) |
|
354 if configuration: |
|
355 found = False |
|
356 for idx, resource in enumerate(configuration.getresource()): |
|
357 if resource.getname() == name: |
|
358 configuration.removeresource(idx) |
|
359 found = True |
|
360 break |
|
361 if not found: |
|
362 raise ValueError, _("\"%s\" resource doesn't exist in \"%s\" configuration !!!")%(name, config_name) |
|
363 setattr(cls, "removeconfigurationResource", removeconfigurationResource) |
|
364 |
|
365 def updateElementName(self, old_name, new_name): |
|
366 for datatype in self.types.getdataTypeElements(): |
|
367 datatype.updateElementName(old_name, new_name) |
|
368 for pou in self.types.getpouElements(): |
|
369 pou.updateElementName(old_name, new_name) |
|
370 for configuration in self.instances.configurations.getconfiguration(): |
|
371 configuration.updateElementName(old_name, new_name) |
|
372 setattr(cls, "updateElementName", updateElementName) |
|
373 |
|
374 def updateElementAddress(self, old_leading, new_leading): |
|
375 address_model = re.compile(FILTER_ADDRESS_MODEL % old_leading) |
|
376 for pou in self.types.getpouElements(): |
|
377 pou.updateElementAddress(address_model, new_leading) |
|
378 for configuration in self.instances.configurations.getconfiguration(): |
|
379 configuration.updateElementAddress(address_model, new_leading) |
|
380 setattr(cls, "updateElementAddress", updateElementAddress) |
|
381 |
|
382 def removeVariableByAddress(self, address): |
|
383 for pou in self.types.getpouElements(): |
|
384 pou.removeVariableByAddress(address) |
|
385 for configuration in self.instances.configurations.getconfiguration(): |
|
386 configuration.removeVariableByAddress(address) |
|
387 setattr(cls, "removeVariableByAddress", removeVariableByAddress) |
|
388 |
|
389 def removeVariableByFilter(self, leading): |
|
390 address_model = re.compile(FILTER_ADDRESS_MODEL % leading) |
|
391 for pou in self.types.getpouElements(): |
|
392 pou.removeVariableByFilter(address_model) |
|
393 for configuration in self.instances.configurations.getconfiguration(): |
|
394 configuration.removeVariableByFilter(address_model) |
|
395 setattr(cls, "removeVariableByFilter", removeVariableByFilter) |
|
396 |
|
397 def RefreshDataTypeHierarchy(self): |
|
398 self.EnumeratedDataTypeValues = {} |
|
399 self.CustomDataTypeRange = {} |
|
400 self.CustomTypeHierarchy = {} |
|
401 for datatype in self.getdataTypes(): |
|
402 self.AddCustomDataType(datatype) |
|
403 setattr(cls, "RefreshDataTypeHierarchy", RefreshDataTypeHierarchy) |
|
404 |
|
405 def AddCustomDataType(self, datatype): |
|
406 name = datatype.getname() |
|
407 basetype_content = datatype.getbaseType().getcontent() |
|
408 if basetype_content["value"] is None: |
|
409 self.CustomTypeHierarchy[name] = basetype_content["name"] |
|
410 elif basetype_content["name"] in ["string", "wstring"]: |
|
411 self.CustomTypeHierarchy[name] = basetype_content["name"].upper() |
|
412 elif basetype_content["name"] == "derived": |
|
413 self.CustomTypeHierarchy[name] = basetype_content["value"].getname() |
|
414 elif basetype_content["name"] in ["subrangeSigned", "subrangeUnsigned"]: |
|
415 range = (basetype_content["value"].range.getlower(), |
|
416 basetype_content["value"].range.getupper()) |
|
417 self.CustomDataTypeRange[name] = range |
|
418 base_type = basetype_content["value"].baseType.getcontent() |
|
419 if base_type["value"] is None: |
|
420 self.CustomTypeHierarchy[name] = base_type["name"] |
|
421 else: |
|
422 self.CustomTypeHierarchy[name] = base_type["value"].getname() |
|
423 else: |
|
424 if basetype_content["name"] == "enum": |
|
425 values = [] |
|
426 for value in basetype_content["value"].values.getvalue(): |
|
427 values.append(value.getname()) |
|
428 self.EnumeratedDataTypeValues[name] = values |
|
429 self.CustomTypeHierarchy[name] = "ANY_DERIVED" |
|
430 setattr(cls, "AddCustomDataType", AddCustomDataType) |
|
431 |
|
432 # Update Block types with user-defined pou added |
|
433 def RefreshCustomBlockTypes(self): |
|
434 # Reset the tree of user-defined pou cross-use |
|
435 self.CustomBlockTypes = [] |
|
436 for pou in self.getpous(): |
|
437 self.AddCustomBlockType(pou) |
|
438 setattr(cls, "RefreshCustomBlockTypes", RefreshCustomBlockTypes) |
|
439 |
|
440 def AddCustomBlockType(self, pou): |
|
441 pou_name = pou.getname() |
|
442 pou_type = pou.getpouType() |
|
443 block_infos = {"name" : pou_name, "type" : pou_type, "extensible" : False, |
|
444 "inputs" : [], "outputs" : [], "comment" : pou.getdescription(), |
|
445 "generate" : generate_block, "initialise" : initialise_block} |
|
446 if pou.getinterface(): |
|
447 return_type = pou.interface.getreturnType() |
|
448 if return_type: |
|
449 var_type = return_type.getcontent() |
|
450 if var_type["name"] == "derived": |
|
451 block_infos["outputs"].append(("", var_type["value"].getname(), "none")) |
|
452 elif var_type["name"] in ["string", "wstring"]: |
|
453 block_infos["outputs"].append(("", var_type["name"].upper(), "none")) |
|
454 else: |
|
455 block_infos["outputs"].append(("", var_type["name"], "none")) |
|
456 for type, varlist in pou.getvars(): |
|
457 if type == "InOut": |
|
458 for var in varlist.getvariable(): |
|
459 var_type = var.type.getcontent() |
|
460 if var_type["name"] == "derived": |
|
461 block_infos["inputs"].append((var.getname(), var_type["value"].getname(), "none")) |
|
462 block_infos["outputs"].append((var.getname(), var_type["value"].getname(), "none")) |
|
463 elif var_type["name"] in ["string", "wstring"]: |
|
464 block_infos["inputs"].append((var.getname(), var_type["name"].upper(), "none")) |
|
465 block_infos["outputs"].append((var.getname(), var_type["name"].upper(), "none")) |
|
466 else: |
|
467 block_infos["inputs"].append((var.getname(), var_type["name"], "none")) |
|
468 block_infos["outputs"].append((var.getname(), var_type["name"], "none")) |
|
469 elif type == "Input": |
|
470 for var in varlist.getvariable(): |
|
471 var_type = var.type.getcontent() |
|
472 if var_type["name"] == "derived": |
|
473 block_infos["inputs"].append((var.getname(), var_type["value"].getname(), "none")) |
|
474 elif var_type["name"] in ["string", "wstring"]: |
|
475 block_infos["inputs"].append((var.getname(), var_type["name"].upper(), "none")) |
|
476 else: |
|
477 block_infos["inputs"].append((var.getname(), var_type["name"], "none")) |
|
478 elif type == "Output": |
|
479 for var in varlist.getvariable(): |
|
480 var_type = var.type.getcontent() |
|
481 if var_type["name"] == "derived": |
|
482 block_infos["outputs"].append((var.getname(), var_type["value"].getname(), "none")) |
|
483 elif var_type["name"] in ["string", "wstring"]: |
|
484 block_infos["outputs"].append((var.getname(), var_type["name"].upper(), "none")) |
|
485 else: |
|
486 block_infos["outputs"].append((var.getname(), var_type["name"], "none")) |
|
487 block_infos["usage"] = "\n (%s) => (%s)" % (", ".join(["%s:%s" % (input[1], input[0]) for input in block_infos["inputs"]]), |
|
488 ", ".join(["%s:%s" % (output[1], output[0]) for output in block_infos["outputs"]])) |
|
489 self.CustomBlockTypes.append(block_infos) |
|
490 setattr(cls, "AddCustomBlockType", AddCustomBlockType) |
|
491 |
|
492 def RefreshElementUsingTree(self): |
|
493 # Reset the tree of user-defined element cross-use |
|
494 self.ElementUsingTree = {} |
|
495 pous = self.getpous() |
|
496 datatypes = self.getdataTypes() |
|
497 # Reference all the user-defined elementu names and initialize the tree of |
|
498 # user-defined elemnt cross-use |
|
499 elementnames = [datatype.getname() for datatype in datatypes] + \ |
|
500 [pou.getname() for pou in pous] |
|
501 for name in elementnames: |
|
502 self.ElementUsingTree[name] = [] |
|
503 # Analyze each datatype |
|
504 for datatype in datatypes: |
|
505 name = datatype.getname() |
|
506 basetype_content = datatype.baseType.getcontent() |
|
507 if basetype_content["name"] == "derived": |
|
508 typename = basetype_content["value"].getname() |
|
509 if name in self.ElementUsingTree[typename]: |
|
510 self.ElementUsingTree[typename].append(name) |
|
511 elif basetype_content["name"] in ["subrangeSigned", "subrangeUnsigned", "array"]: |
|
512 base_type = basetype_content["value"].baseType.getcontent() |
|
513 if base_type["name"] == "derived": |
|
514 typename = base_type["value"].getname() |
|
515 if self.ElementUsingTree.has_key(typename) and name not in self.ElementUsingTree[typename]: |
|
516 self.ElementUsingTree[typename].append(name) |
|
517 elif basetype_content["name"] == "struct": |
|
518 for element in basetype_content["value"].getvariable(): |
|
519 type_content = element.type.getcontent() |
|
520 if type_content["name"] == "derived": |
|
521 typename = type_content["value"].getname() |
|
522 if self.ElementUsingTree.has_key(typename) and name not in self.ElementUsingTree[typename]: |
|
523 self.ElementUsingTree[typename].append(name) |
|
524 # Analyze each pou |
|
525 for pou in pous: |
|
526 name = pou.getname() |
|
527 if pou.interface: |
|
528 # Extract variables from every varLists |
|
529 for type, varlist in pou.getvars(): |
|
530 for var in varlist.getvariable(): |
|
531 vartype_content = var.gettype().getcontent() |
|
532 if vartype_content["name"] == "derived": |
|
533 typename = vartype_content["value"].getname() |
|
534 if self.ElementUsingTree.has_key(typename) and name not in self.ElementUsingTree[typename]: |
|
535 self.ElementUsingTree[typename].append(name) |
|
536 setattr(cls, "RefreshElementUsingTree", RefreshElementUsingTree) |
|
537 |
|
538 def GetParentType(self, type): |
|
539 if self.CustomTypeHierarchy.has_key(type): |
|
540 return self.CustomTypeHierarchy[type] |
|
541 elif TypeHierarchy.has_key(type): |
|
542 return TypeHierarchy[type] |
|
543 return None |
|
544 setattr(cls, "GetParentType", GetParentType) |
|
545 |
|
546 def GetBaseType(self, type): |
|
547 parent_type = self.GetParentType(type) |
|
548 if parent_type is not None: |
|
549 if parent_type.startswith("ANY"): |
|
550 return type |
|
551 else: |
|
552 return self.GetBaseType(parent_type) |
|
553 return None |
|
554 setattr(cls, "GetBaseType", GetBaseType) |
|
555 |
|
556 def GetSubrangeBaseTypes(self, exclude): |
|
557 derived = [] |
|
558 for type in self.CustomTypeHierarchy.keys(): |
|
559 for base_type in DataTypeRange.keys(): |
|
560 if self.IsOfType(type, base_type) and not self.IsOfType(type, exclude): |
|
561 derived.append(type) |
|
562 break |
|
563 return derived |
|
564 setattr(cls, "GetSubrangeBaseTypes", GetSubrangeBaseTypes) |
|
565 |
|
566 """ |
|
567 returns true if the given data type is the same that "reference" meta-type or one of its types. |
|
568 """ |
|
569 def IsOfType(self, type, reference): |
|
570 if reference is None: |
|
571 return True |
|
572 elif type == reference: |
|
573 return True |
|
574 else: |
|
575 parent_type = self.GetParentType(type) |
|
576 if parent_type is not None: |
|
577 return self.IsOfType(parent_type, reference) |
|
578 return False |
|
579 setattr(cls, "IsOfType", IsOfType) |
|
580 |
|
581 # Return if pou given by name is used by another pou |
|
582 def ElementIsUsed(self, name): |
|
583 if self.ElementUsingTree.has_key(name): |
|
584 return len(self.ElementUsingTree[name]) > 0 |
|
585 return False |
|
586 setattr(cls, "ElementIsUsed", ElementIsUsed) |
|
587 |
|
588 def DataTypeIsDerived(self, name): |
|
589 return name in self.CustomTypeHierarchy.values() |
|
590 setattr(cls, "DataTypeIsDerived", DataTypeIsDerived) |
|
591 |
|
592 # Return if pou given by name is directly or undirectly used by the reference pou |
|
593 def ElementIsUsedBy(self, name, reference): |
|
594 if self.ElementUsingTree.has_key(name): |
|
595 list = self.ElementUsingTree[name] |
|
596 # Test if pou is directly used by reference |
|
597 if reference in list: |
|
598 return True |
|
599 else: |
|
600 # Test if pou is undirectly used by reference, by testing if pous |
|
601 # that directly use pou is directly or undirectly used by reference |
|
602 used = False |
|
603 for element in list: |
|
604 used |= self.ElementIsUsedBy(element, reference) |
|
605 return used |
|
606 return False |
|
607 setattr(cls, "ElementIsUsedBy", ElementIsUsedBy) |
|
608 |
|
609 def GetDataTypeRange(self, type): |
|
610 if self.CustomDataTypeRange.has_key(type): |
|
611 return self.CustomDataTypeRange[type] |
|
612 elif DataTypeRange.has_key(type): |
|
613 return DataTypeRange[type] |
|
614 else: |
|
615 parent_type = self.GetParentType(type) |
|
616 if parent_type is not None: |
|
617 return self.GetDataTypeRange(parent_type) |
|
618 return None |
|
619 setattr(cls, "GetDataTypeRange", GetDataTypeRange) |
|
620 |
|
621 def GetEnumeratedDataTypeValues(self, type = None): |
|
622 if type is None: |
|
623 all_values = [] |
|
624 for values in self.EnumeratedDataTypeValues.values(): |
|
625 all_values.extend(values) |
|
626 return all_values |
|
627 elif self.EnumeratedDataTypeValues.has_key(type): |
|
628 return self.EnumeratedDataTypeValues[type] |
|
629 return [] |
|
630 setattr(cls, "GetEnumeratedDataTypeValues", GetEnumeratedDataTypeValues) |
|
631 |
|
632 # Function that returns the block definition associated to the block type given |
|
633 def GetCustomBlockType(self, type, inputs = None): |
|
634 for customblocktype in self.CustomBlockTypes: |
|
635 if inputs is not None and inputs != "undefined": |
|
636 customblock_inputs = tuple([var_type for name, var_type, modifier in customblocktype["inputs"]]) |
|
637 same_inputs = inputs == customblock_inputs |
|
638 else: |
|
639 same_inputs = True |
|
640 if customblocktype["name"] == type and same_inputs: |
|
641 return customblocktype |
|
642 return None |
|
643 setattr(cls, "GetCustomBlockType", GetCustomBlockType) |
|
644 |
|
645 # Return Block types checking for recursion |
|
646 def GetCustomBlockTypes(self, exclude = "", onlyfunctions = False): |
|
647 type = None |
|
648 if exclude != "": |
|
649 pou = self.getpou(exclude) |
|
650 if pou is not None: |
|
651 type = pou.getpouType() |
|
652 customblocktypes = [] |
|
653 for customblocktype in self.CustomBlockTypes: |
|
654 if customblocktype["type"] != "program" and customblocktype["name"] != exclude and not self.ElementIsUsedBy(exclude, customblocktype["name"]) and not (onlyfunctions and customblocktype["type"] != "function"): |
|
655 customblocktypes.append(customblocktype) |
|
656 return customblocktypes |
|
657 setattr(cls, "GetCustomBlockTypes", GetCustomBlockTypes) |
|
658 |
|
659 # Return Function Block types checking for recursion |
|
660 def GetCustomFunctionBlockTypes(self, exclude = ""): |
|
661 customblocktypes = [] |
|
662 for customblocktype in self.CustomBlockTypes: |
|
663 if customblocktype["type"] == "functionBlock" and customblocktype["name"] != exclude and not self.ElementIsUsedBy(exclude, customblocktype["name"]): |
|
664 customblocktypes.append(customblocktype["name"]) |
|
665 return customblocktypes |
|
666 setattr(cls, "GetCustomFunctionBlockTypes", GetCustomFunctionBlockTypes) |
|
667 |
|
668 # Return Block types checking for recursion |
|
669 def GetCustomBlockResource(self): |
|
670 customblocktypes = [] |
|
671 for customblocktype in self.CustomBlockTypes: |
|
672 if customblocktype["type"] == "program": |
|
673 customblocktypes.append(customblocktype["name"]) |
|
674 return customblocktypes |
|
675 setattr(cls, "GetCustomBlockResource", GetCustomBlockResource) |
|
676 |
|
677 # Return Data Types checking for recursion |
|
678 def GetCustomDataTypes(self, exclude = "", only_locatable = False): |
|
679 customdatatypes = [] |
|
680 for customdatatype in self.getdataTypes(): |
|
681 if not only_locatable or self.IsLocatableType(customdatatype): |
|
682 customdatatype_name = customdatatype.getname() |
|
683 if customdatatype_name != exclude and not self.ElementIsUsedBy(exclude, customdatatype_name): |
|
684 customdatatypes.append({"name": customdatatype_name, "infos": customdatatype}) |
|
685 return customdatatypes |
|
686 setattr(cls, "GetCustomDataTypes", GetCustomDataTypes) |
|
687 |
|
688 # Return if Data Type can be used for located variables |
|
689 def IsLocatableType(self, datatype): |
|
690 basetype_content = datatype.baseType.getcontent() |
|
691 if basetype_content["name"] in ["enum", "struct"]: |
|
692 return False |
|
693 elif basetype_content["name"] == "derived": |
|
694 base_type = self.getdataType(basetype_content["value"].getname()) |
|
695 if base_type is not None: |
|
696 return self.IsLocatableType(base_type) |
|
697 elif basetype_content["name"] == "array": |
|
698 array_base_type = basetype_content["value"].baseType.getcontent() |
|
699 if array_base_type["value"] is not None and array_base_type["name"] not in ["string", "wstring"]: |
|
700 base_type = self.getdataType(array_base_type["value"].getname()) |
|
701 if base_type is not None: |
|
702 return self.IsLocatableType(base_type) |
|
703 return True |
|
704 setattr(cls, "IsLocatableType", IsLocatableType) |
|
705 |
|
706 def Search(self, criteria, parent_infos=[]): |
|
707 result = self.types.Search(criteria, parent_infos) |
|
708 for configuration in self.instances.configurations.getconfiguration(): |
|
709 result.extend(configuration.Search(criteria, parent_infos)) |
|
710 return result |
|
711 setattr(cls, "Search", Search) |
|
712 |
|
713 cls = PLCOpenClasses.get("project_fileHeader", None) |
|
714 if cls: |
|
715 cls.singleLineAttributes = False |
|
716 |
|
717 cls = PLCOpenClasses.get("project_contentHeader", None) |
|
718 if cls: |
|
719 cls.singleLineAttributes = False |
|
720 |
|
721 def setpageSize(self, width, height): |
|
722 self.coordinateInfo.setpageSize(width, height) |
|
723 setattr(cls, "setpageSize", setpageSize) |
|
724 |
|
725 def getpageSize(self): |
|
726 return self.coordinateInfo.getpageSize() |
|
727 setattr(cls, "getpageSize", getpageSize) |
|
728 |
|
729 def setscaling(self, scaling): |
|
730 for language, (x, y) in scaling.items(): |
|
731 self.coordinateInfo.setscaling(language, x, y) |
|
732 setattr(cls, "setscaling", setscaling) |
|
733 |
|
734 def getscaling(self): |
|
735 scaling = {} |
|
736 scaling["FBD"] = self.coordinateInfo.getscaling("FBD") |
|
737 scaling["LD"] = self.coordinateInfo.getscaling("LD") |
|
738 scaling["SFC"] = self.coordinateInfo.getscaling("SFC") |
|
739 return scaling |
|
740 setattr(cls, "getscaling", getscaling) |
|
741 |
|
742 cls = PLCOpenClasses.get("contentHeader_coordinateInfo", None) |
|
743 if cls: |
|
744 def setpageSize(self, width, height): |
|
745 if width == 0 and height == 0: |
|
746 self.deletepageSize() |
|
747 else: |
|
748 if self.pageSize is None: |
|
749 self.addpageSize() |
|
750 self.pageSize.setx(width) |
|
751 self.pageSize.sety(height) |
|
752 setattr(cls, "setpageSize", setpageSize) |
|
753 |
|
754 def getpageSize(self): |
|
755 if self.pageSize is not None: |
|
756 return self.pageSize.getx(), self.pageSize.gety() |
|
757 return 0, 0 |
|
758 setattr(cls, "getpageSize", getpageSize) |
|
759 |
|
760 def setscaling(self, language, x, y): |
|
761 if language == "FBD": |
|
762 self.fbd.scaling.setx(x) |
|
763 self.fbd.scaling.sety(y) |
|
764 elif language == "LD": |
|
765 self.ld.scaling.setx(x) |
|
766 self.ld.scaling.sety(y) |
|
767 elif language == "SFC": |
|
768 self.sfc.scaling.setx(x) |
|
769 self.sfc.scaling.sety(y) |
|
770 setattr(cls, "setscaling", setscaling) |
|
771 |
|
772 def getscaling(self, language): |
|
773 if language == "FBD": |
|
774 return self.fbd.scaling.getx(), self.fbd.scaling.gety() |
|
775 elif language == "LD": |
|
776 return self.ld.scaling.getx(), self.ld.scaling.gety() |
|
777 elif language == "SFC": |
|
778 return self.sfc.scaling.getx(), self.sfc.scaling.gety() |
|
779 return 0, 0 |
|
780 setattr(cls, "getscaling", getscaling) |
|
781 |
|
782 def _Search(attributes, criteria, parent_infos): |
|
783 search_result = [] |
|
784 for attr, value in attributes: |
|
785 if value is not None: |
|
786 search_result.extend([(tuple(parent_infos + [attr]),) + result for result in TestTextElement(value, criteria)]) |
|
787 return search_result |
|
788 |
|
789 def _updateConfigurationResourceElementName(self, old_name, new_name): |
|
790 for varlist in self.getglobalVars(): |
|
791 for var in varlist.getvariable(): |
|
792 var_address = var.getaddress() |
|
793 if var_address is not None: |
|
794 if var_address == old_name: |
|
795 var.setaddress(new_name) |
|
796 if var.getname() == old_name: |
|
797 var.setname(new_name) |
|
798 |
|
799 def _updateConfigurationResourceElementAddress(self, address_model, new_leading): |
|
800 for varlist in self.getglobalVars(): |
|
801 for var in varlist.getvariable(): |
|
802 var_address = var.getaddress() |
|
803 if var_address is not None: |
|
804 var.setaddress(update_address(var_address, address_model, new_leading)) |
|
805 |
|
806 def _removeConfigurationResourceVariableByAddress(self, address): |
|
807 for varlist in self.getglobalVars(): |
|
808 variables = varlist.getvariable() |
|
809 for i in xrange(len(variables)-1, -1, -1): |
|
810 if variables[i].getaddress() == address: |
|
811 variables.pop(i) |
|
812 |
|
813 def _removeConfigurationResourceVariableByFilter(self, address_model): |
|
814 for varlist in self.getglobalVars(): |
|
815 variables = varlist.getvariable() |
|
816 for i in xrange(len(variables)-1, -1, -1): |
|
817 var_address = variables[i].getaddress() |
|
818 if var_address is not None: |
|
819 result = address_model.match(var_address) |
|
820 if result is not None: |
|
821 variables.pop(i) |
|
822 |
|
823 def _SearchInConfigurationResource(self, criteria, parent_infos=[]): |
|
824 search_result = _Search([("name", self.getname())], criteria, parent_infos) |
|
825 var_number = 0 |
|
826 for varlist in self.getglobalVars(): |
|
827 variable_type = searchResultVarTypes.get("globalVars", "var_local") |
|
828 variables = varlist.getvariable() |
|
829 for modifier, has_modifier in [("constant", varlist.getconstant()), |
|
830 ("retain", varlist.getretain()), |
|
831 ("non_retain", varlist.getnonretain())]: |
|
832 if has_modifier: |
|
833 for result in TestTextElement(modifier, criteria): |
|
834 search_result.append((tuple(parent_infos + [variable_type, (var_number, var_number + len(variables)), modifier]),) + result) |
|
835 break |
|
836 for variable in variables: |
|
837 search_result.extend(variable.Search(criteria, parent_infos + [variable_type, var_number])) |
|
838 var_number += 1 |
|
839 return search_result |
|
840 |
|
841 cls = PLCOpenClasses.get("configurations_configuration", None) |
|
842 if cls: |
|
843 def updateElementName(self, old_name, new_name): |
|
844 _updateConfigurationResourceElementName(self, old_name, new_name) |
|
845 for resource in self.getresource(): |
|
846 resource.updateElementName(old_name, new_name) |
|
847 setattr(cls, "updateElementName", updateElementName) |
|
848 |
|
849 def updateElementAddress(self, address_model, new_leading): |
|
850 _updateConfigurationResourceElementAddress(self, address_model, new_leading) |
|
851 for resource in self.getresource(): |
|
852 resource.updateElementAddress(address_model, new_leading) |
|
853 setattr(cls, "updateElementAddress", updateElementAddress) |
|
854 |
|
855 setattr(cls, "removeVariableByAddress", _removeConfigurationResourceVariableByAddress) |
|
856 setattr(cls, "removeVariableByFilter", _removeConfigurationResourceVariableByFilter) |
|
857 |
|
858 def Search(self, criteria, parent_infos=[]): |
|
859 search_result = [] |
|
860 parent_infos = parent_infos + ["C::%s" % self.getname()] |
|
861 filter = criteria["filter"] |
|
862 if filter == "all" or "configuration" in filter: |
|
863 search_result = _SearchInConfigurationResource(self, criteria, parent_infos) |
|
864 for resource in self.getresource(): |
|
865 search_result.extend(resource.Search(criteria, parent_infos)) |
|
866 return search_result |
|
867 setattr(cls, "Search", Search) |
|
868 |
|
869 cls = PLCOpenClasses.get("configuration_resource", None) |
|
870 if cls: |
|
871 def updateElementName(self, old_name, new_name): |
|
872 _updateConfigurationResourceElementName(self, old_name, new_name) |
|
873 for instance in self.getpouInstance(): |
|
874 instance.updateElementName(old_name, new_name) |
|
875 for task in self.gettask(): |
|
876 task.updateElementName(old_name, new_name) |
|
877 setattr(cls, "updateElementName", updateElementName) |
|
878 |
|
879 def updateElementAddress(self, address_model, new_leading): |
|
880 _updateConfigurationResourceElementAddress(self, address_model, new_leading) |
|
881 for task in self.gettask(): |
|
882 task.updateElementAddress(address_model, new_leading) |
|
883 setattr(cls, "updateElementAddress", updateElementAddress) |
|
884 |
|
885 setattr(cls, "removeVariableByAddress", _removeConfigurationResourceVariableByAddress) |
|
886 setattr(cls, "removeVariableByFilter", _removeConfigurationResourceVariableByFilter) |
|
887 |
|
888 def Search(self, criteria, parent_infos=[]): |
|
889 parent_infos = parent_infos[:-1] + ["R::%s::%s" % (parent_infos[-1].split("::")[1], self.getname())] |
|
890 search_result = _SearchInConfigurationResource(self, criteria, parent_infos) |
|
891 task_number = 0 |
|
892 instance_number = 0 |
|
893 for task in self.gettask(): |
|
894 results = TestTextElement(task.getname(), criteria) |
|
895 for result in results: |
|
896 search_result.append((tuple(parent_infos + ["task", task_number, "name"]),) + result) |
|
897 search_result.extend(task.Search(criteria, parent_infos + ["task", task_number])) |
|
898 task_number += 1 |
|
899 for instance in task.getpouInstance(): |
|
900 search_result.extend(task.Search(criteria, parent_infos + ["instance", instance_number])) |
|
901 for result in results: |
|
902 search_result.append((tuple(parent_infos + ["instance", instance_number, "task"]),) + result) |
|
903 instance_number += 1 |
|
904 for instance in self.getpouInstance(): |
|
905 search_result.extend(instance.Search(criteria, parent_infos + ["instance", instance_number])) |
|
906 instance_number += 1 |
|
907 return search_result |
|
908 setattr(cls, "Search", Search) |
|
909 |
|
910 cls = PLCOpenClasses.get("resource_task", None) |
|
911 if cls: |
|
912 def compatibility(self, tree): |
|
913 if tree.hasAttribute("interval"): |
|
914 interval = GetAttributeValue(tree._attrs["interval"]) |
|
915 result = time_model.match(interval) |
|
916 if result is not None: |
|
917 values = result.groups() |
|
918 time_values = [int(v) for v in values[:2]] |
|
919 seconds = float(values[2]) |
|
920 time_values.extend([int(seconds), int((seconds % 1) * 1000000)]) |
|
921 text = "t#" |
|
922 if time_values[0] != 0: |
|
923 text += "%dh"%time_values[0] |
|
924 if time_values[1] != 0: |
|
925 text += "%dm"%time_values[1] |
|
926 if time_values[2] != 0: |
|
927 text += "%ds"%time_values[2] |
|
928 if time_values[3] != 0: |
|
929 if time_values[3] % 1000 != 0: |
|
930 text += "%.3fms"%(float(time_values[3]) / 1000) |
|
931 else: |
|
932 text += "%dms"%(time_values[3] / 1000) |
|
933 NodeSetAttr(tree, "interval", text) |
|
934 setattr(cls, "compatibility", compatibility) |
|
935 |
|
936 def updateElementName(self, old_name, new_name): |
|
937 if self.single == old_name: |
|
938 self.single = new_name |
|
939 if self.interval == old_name: |
|
940 self.interval = new_name |
|
941 for instance in self.getpouInstance(): |
|
942 instance.updateElementName(old_name, new_name) |
|
943 setattr(cls, "updateElementName", updateElementName) |
|
944 |
|
945 def updateElementAddress(self, address_model, new_leading): |
|
946 if self.single is not None: |
|
947 self.single = update_address(self.single, address_model, new_leading) |
|
948 if self.interval is not None: |
|
949 self.interval = update_address(self.interval, address_model, new_leading) |
|
950 setattr(cls, "updateElementAddress", updateElementAddress) |
|
951 |
|
952 def Search(self, criteria, parent_infos=[]): |
|
953 return _Search([("single", self.getsingle()), |
|
954 ("interval", self.getinterval()), |
|
955 ("priority", str(self.getpriority()))], |
|
956 criteria, parent_infos) |
|
957 setattr(cls, "Search", Search) |
|
958 |
|
959 cls = PLCOpenClasses.get("pouInstance", None) |
|
960 if cls: |
|
961 def compatibility(self, tree): |
|
962 if tree.hasAttribute("type"): |
|
963 NodeRenameAttr(tree, "type", "typeName") |
|
964 setattr(cls, "compatibility", compatibility) |
|
965 |
|
966 def updateElementName(self, old_name, new_name): |
|
967 if self.typeName == old_name: |
|
968 self.typeName = new_name |
|
969 setattr(cls, "updateElementName", updateElementName) |
|
970 |
|
971 def Search(self, criteria, parent_infos=[]): |
|
972 return _Search([("name", self.getname()), |
|
973 ("type", self.gettypeName())], |
|
974 criteria, parent_infos) |
|
975 setattr(cls, "Search", Search) |
|
976 |
|
977 cls = PLCOpenClasses.get("varListPlain_variable", None) |
|
978 if cls: |
|
979 def gettypeAsText(self): |
|
980 vartype_content = self.gettype().getcontent() |
|
981 # Variable type is a user data type |
|
982 if vartype_content["name"] == "derived": |
|
983 return vartype_content["value"].getname() |
|
984 # Variable type is a string type |
|
985 elif vartype_content["name"] in ["string", "wstring"]: |
|
986 return vartype_content["name"].upper() |
|
987 # Variable type is an array |
|
988 elif vartype_content["name"] == "array": |
|
989 base_type = vartype_content["value"].baseType.getcontent() |
|
990 # Array derived directly from a user defined type |
|
991 if base_type["name"] == "derived": |
|
992 basetype_name = base_type["value"].getname() |
|
993 # Array derived directly from a string type |
|
994 elif base_type["name"] in ["string", "wstring"]: |
|
995 basetype_name = base_type["name"].upper() |
|
996 # Array derived directly from an elementary type |
|
997 else: |
|
998 basetype_name = base_type["name"] |
|
999 return "ARRAY [%s] OF %s" % (",".join(map(lambda x : "%s..%s" % (x.getlower(), x.getupper()), vartype_content["value"].getdimension())), basetype_name) |
|
1000 # Variable type is an elementary type |
|
1001 return vartype_content["name"] |
|
1002 setattr(cls, "gettypeAsText", gettypeAsText) |
|
1003 |
|
1004 def Search(self, criteria, parent_infos=[]): |
|
1005 search_result = _Search([("name", self.getname()), |
|
1006 ("type", self.gettypeAsText()), |
|
1007 ("location", self.getaddress())], |
|
1008 criteria, parent_infos) |
|
1009 initial = self.getinitialValue() |
|
1010 if initial is not None: |
|
1011 search_result.extend(_Search([("initial value", initial.getvalue())], criteria, parent_infos)) |
|
1012 doc = self.getdocumentation() |
|
1013 if doc is not None: |
|
1014 search_result.extend(doc.Search(criteria, parent_infos + ["documentation"])) |
|
1015 return search_result |
|
1016 setattr(cls, "Search", Search) |
|
1017 |
|
1018 cls = PLCOpenClasses.get("project_types", None) |
|
1019 if cls: |
|
1020 def getdataTypeElements(self): |
|
1021 return self.dataTypes.getdataType() |
|
1022 setattr(cls, "getdataTypeElements", getdataTypeElements) |
|
1023 |
|
1024 def getdataTypeElement(self, name): |
|
1025 elements = self.dataTypes.getdataType() |
|
1026 for element in elements: |
|
1027 if element.getname() == name: |
|
1028 return element |
|
1029 return None |
|
1030 setattr(cls, "getdataTypeElement", getdataTypeElement) |
|
1031 |
|
1032 def appenddataTypeElement(self, name): |
|
1033 new_datatype = PLCOpenClasses["dataTypes_dataType"]() |
|
1034 new_datatype.setname(name) |
|
1035 new_datatype.baseType.setcontent({"name" : "BOOL", "value" : None}) |
|
1036 self.dataTypes.appenddataType(new_datatype) |
|
1037 setattr(cls, "appenddataTypeElement", appenddataTypeElement) |
|
1038 |
|
1039 def insertdataTypeElement(self, index, dataType): |
|
1040 self.dataTypes.insertdataType(index, dataType) |
|
1041 setattr(cls, "insertdataTypeElement", insertdataTypeElement) |
|
1042 |
|
1043 def removedataTypeElement(self, name): |
|
1044 found = False |
|
1045 for idx, element in enumerate(self.dataTypes.getdataType()): |
|
1046 if element.getname() == name: |
|
1047 self.dataTypes.removedataType(idx) |
|
1048 found = True |
|
1049 break |
|
1050 if not found: |
|
1051 raise ValueError, _("\"%s\" Data Type doesn't exist !!!")%name |
|
1052 setattr(cls, "removedataTypeElement", removedataTypeElement) |
|
1053 |
|
1054 def getpouElements(self): |
|
1055 return self.pous.getpou() |
|
1056 setattr(cls, "getpouElements", getpouElements) |
|
1057 |
|
1058 def getpouElement(self, name): |
|
1059 elements = self.pous.getpou() |
|
1060 for element in elements: |
|
1061 if element.getname() == name: |
|
1062 return element |
|
1063 return None |
|
1064 setattr(cls, "getpouElement", getpouElement) |
|
1065 |
|
1066 def appendpouElement(self, name, pou_type, body_type): |
|
1067 for element in self.pous.getpou(): |
|
1068 if element.getname() == name: |
|
1069 raise ValueError, _("\"%s\" POU already exists !!!")%name |
|
1070 new_pou = PLCOpenClasses["pous_pou"]() |
|
1071 new_pou.setname(name) |
|
1072 new_pou.setpouType(pou_type) |
|
1073 new_pou.appendbody(PLCOpenClasses["body"]()) |
|
1074 new_pou.setbodyType(body_type) |
|
1075 self.pous.appendpou(new_pou) |
|
1076 setattr(cls, "appendpouElement", appendpouElement) |
|
1077 |
|
1078 def insertpouElement(self, index, pou): |
|
1079 self.pous.insertpou(index, pou) |
|
1080 setattr(cls, "insertpouElement", insertpouElement) |
|
1081 |
|
1082 def removepouElement(self, name): |
|
1083 found = False |
|
1084 for idx, element in enumerate(self.pous.getpou()): |
|
1085 if element.getname() == name: |
|
1086 self.pous.removepou(idx) |
|
1087 found = True |
|
1088 break |
|
1089 if not found: |
|
1090 raise ValueError, _("\"%s\" POU doesn't exist !!!")%name |
|
1091 setattr(cls, "removepouElement", removepouElement) |
|
1092 |
|
1093 def Search(self, criteria, parent_infos=[]): |
|
1094 search_result = [] |
|
1095 filter = criteria["filter"] |
|
1096 for datatype in self.dataTypes.getdataType(): |
|
1097 search_result.extend(datatype.Search(criteria, parent_infos)) |
|
1098 for pou in self.pous.getpou(): |
|
1099 search_result.extend(pou.Search(criteria, parent_infos)) |
|
1100 return search_result |
|
1101 setattr(cls, "Search", Search) |
|
1102 |
|
1103 def _updateBaseTypeElementName(self, old_name, new_name): |
|
1104 self.baseType.updateElementName(old_name, new_name) |
|
1105 |
|
1106 cls = PLCOpenClasses.get("dataTypes_dataType", None) |
|
1107 if cls: |
|
1108 setattr(cls, "updateElementName", _updateBaseTypeElementName) |
|
1109 |
|
1110 def Search(self, criteria, parent_infos=[]): |
|
1111 search_result = [] |
|
1112 filter = criteria["filter"] |
|
1113 if filter == "all" or "datatype" in filter: |
|
1114 parent_infos = parent_infos + ["D::%s" % self.getname()] |
|
1115 search_result.extend(_Search([("name", self.getname())], criteria, parent_infos)) |
|
1116 search_result.extend(self.baseType.Search(criteria, parent_infos)) |
|
1117 if self.initialValue is not None: |
|
1118 search_result.extend(_Search([("initial", self.initialValue.getvalue())], criteria, parent_infos)) |
|
1119 return search_result |
|
1120 setattr(cls, "Search", Search) |
|
1121 |
|
1122 cls = PLCOpenClasses.get("dataType", None) |
|
1123 if cls: |
|
1124 |
|
1125 def updateElementName(self, old_name, new_name): |
|
1126 if self.content["name"] in ["derived", "array", "subrangeSigned", "subrangeUnsigned"]: |
|
1127 self.content["value"].updateElementName(old_name, new_name) |
|
1128 elif self.content["name"] == "struct": |
|
1129 for element in self.content["value"].getvariable(): |
|
1130 element_type = element.type.updateElementName(old_name, new_name) |
|
1131 setattr(cls, "updateElementName", updateElementName) |
|
1132 |
|
1133 def Search(self, criteria, parent_infos=[]): |
|
1134 search_result = [] |
|
1135 if self.content["name"] in ["derived", "array", "enum", "subrangeSigned", "subrangeUnsigned"]: |
|
1136 search_result.extend(self.content["value"].Search(criteria, parent_infos)) |
|
1137 elif self.content["name"] == "struct": |
|
1138 for i, element in enumerate(self.content["value"].getvariable()): |
|
1139 search_result.extend(element.Search(criteria, parent_infos + ["struct", i])) |
|
1140 else: |
|
1141 basetype = self.content["name"] |
|
1142 if basetype in ["string", "wstring"]: |
|
1143 basetype = basetype.upper() |
|
1144 search_result.extend(_Search([("base", basetype)], criteria, parent_infos)) |
|
1145 return search_result |
|
1146 setattr(cls, "Search", Search) |
|
1147 |
|
1148 cls = PLCOpenClasses.get("derivedTypes_array", None) |
|
1149 if cls: |
|
1150 setattr(cls, "updateElementName", _updateBaseTypeElementName) |
|
1151 |
|
1152 def Search(self, criteria, parent_infos=[]): |
|
1153 search_result = self.baseType.Search(criteria, parent_infos) |
|
1154 for i, dimension in enumerate(self.getdimension()): |
|
1155 search_result.extend(_Search([("lower", dimension.getlower()), |
|
1156 ("upper", dimension.getupper())], |
|
1157 criteria, parent_infos + ["range", i])) |
|
1158 return search_result |
|
1159 setattr(cls, "Search", Search) |
|
1160 |
|
1161 def _SearchInSubrange(self, criteria, parent_infos=[]): |
|
1162 search_result = self.baseType.Search(criteria, parent_infos) |
|
1163 search_result.extend(_Search([("lower", self.range.getlower()), |
|
1164 ("upper", self.range.getupper())], |
|
1165 criteria, parent_infos)) |
|
1166 return search_result |
|
1167 |
|
1168 cls = PLCOpenClasses.get("derivedTypes_subrangeSigned", None) |
|
1169 if cls: |
|
1170 setattr(cls, "updateElementName", _updateBaseTypeElementName) |
|
1171 setattr(cls, "Search", _SearchInSubrange) |
|
1172 |
|
1173 cls = PLCOpenClasses.get("derivedTypes_subrangeUnsigned", None) |
|
1174 if cls: |
|
1175 setattr(cls, "updateElementName", _updateBaseTypeElementName) |
|
1176 setattr(cls, "Search", _SearchInSubrange) |
|
1177 |
|
1178 cls = PLCOpenClasses.get("derivedTypes_enum", None) |
|
1179 if cls: |
|
1180 |
|
1181 def updateElementName(self, old_name, new_name): |
|
1182 pass |
|
1183 setattr(cls, "updateElementName", updateElementName) |
|
1184 |
|
1185 def Search(self, criteria, parent_infos=[]): |
|
1186 search_result = [] |
|
1187 for i, value in enumerate(self.values.getvalue()): |
|
1188 for result in TestTextElement(value.getname(), criteria): |
|
1189 search_result.append((tuple(parent_infos + ["value", i]),) + result) |
|
1190 return search_result |
|
1191 setattr(cls, "Search", Search) |
|
1192 |
|
1193 cls = PLCOpenClasses.get("pous_pou", None) |
|
1194 if cls: |
|
1195 |
|
1196 def setdescription(self, description): |
|
1197 doc = self.getdocumentation() |
|
1198 if doc is None: |
|
1199 doc = PLCOpenClasses["formattedText"]() |
|
1200 self.setdocumentation(doc) |
|
1201 doc.settext(description) |
|
1202 setattr(cls, "setdescription", setdescription) |
|
1203 |
|
1204 def getdescription(self): |
|
1205 doc = self.getdocumentation() |
|
1206 if doc is not None: |
|
1207 return doc.gettext() |
|
1208 return "" |
|
1209 setattr(cls, "getdescription", getdescription) |
|
1210 |
|
1211 def setbodyType(self, type): |
|
1212 if len(self.body) > 0: |
|
1213 if type == "IL": |
|
1214 self.body[0].setcontent({"name" : "IL", "value" : PLCOpenClasses["formattedText"]()}) |
|
1215 elif type == "ST": |
|
1216 self.body[0].setcontent({"name" : "ST", "value" : PLCOpenClasses["formattedText"]()}) |
|
1217 elif type == "LD": |
|
1218 self.body[0].setcontent({"name" : "LD", "value" : PLCOpenClasses["body_LD"]()}) |
|
1219 elif type == "FBD": |
|
1220 self.body[0].setcontent({"name" : "FBD", "value" : PLCOpenClasses["body_FBD"]()}) |
|
1221 elif type == "SFC": |
|
1222 self.body[0].setcontent({"name" : "SFC", "value" : PLCOpenClasses["body_SFC"]()}) |
|
1223 else: |
|
1224 raise ValueError, "%s isn't a valid body type!"%type |
|
1225 setattr(cls, "setbodyType", setbodyType) |
|
1226 |
|
1227 def getbodyType(self): |
|
1228 if len(self.body) > 0: |
|
1229 return self.body[0].getcontent()["name"] |
|
1230 setattr(cls, "getbodyType", getbodyType) |
|
1231 |
|
1232 def resetexecutionOrder(self): |
|
1233 if len(self.body) > 0: |
|
1234 self.body[0].resetexecutionOrder() |
|
1235 setattr(cls, "resetexecutionOrder", resetexecutionOrder) |
|
1236 |
|
1237 def compileexecutionOrder(self): |
|
1238 if len(self.body) > 0: |
|
1239 self.body[0].compileexecutionOrder() |
|
1240 setattr(cls, "compileexecutionOrder", compileexecutionOrder) |
|
1241 |
|
1242 def setelementExecutionOrder(self, instance, new_executionOrder): |
|
1243 if len(self.body) > 0: |
|
1244 self.body[0].setelementExecutionOrder(instance, new_executionOrder) |
|
1245 setattr(cls, "setelementExecutionOrder", setelementExecutionOrder) |
|
1246 |
|
1247 def addinstance(self, name, instance): |
|
1248 if len(self.body) > 0: |
|
1249 self.body[0].appendcontentInstance(name, instance) |
|
1250 setattr(cls, "addinstance", addinstance) |
|
1251 |
|
1252 def getinstances(self): |
|
1253 if len(self.body) > 0: |
|
1254 return self.body[0].getcontentInstances() |
|
1255 return [] |
|
1256 setattr(cls, "getinstances", getinstances) |
|
1257 |
|
1258 def getinstance(self, id): |
|
1259 if len(self.body) > 0: |
|
1260 return self.body[0].getcontentInstance(id) |
|
1261 return None |
|
1262 setattr(cls, "getinstance", getinstance) |
|
1263 |
|
1264 def getrandomInstance(self, exclude): |
|
1265 if len(self.body) > 0: |
|
1266 return self.body[0].getcontentRandomInstance(exclude) |
|
1267 return None |
|
1268 setattr(cls, "getrandomInstance", getrandomInstance) |
|
1269 |
|
1270 def getinstanceByName(self, name): |
|
1271 if len(self.body) > 0: |
|
1272 return self.body[0].getcontentInstanceByName(name) |
|
1273 return None |
|
1274 setattr(cls, "getinstanceByName", getinstanceByName) |
|
1275 |
|
1276 def removeinstance(self, id): |
|
1277 if len(self.body) > 0: |
|
1278 self.body[0].removecontentInstance(id) |
|
1279 setattr(cls, "removeinstance", removeinstance) |
|
1280 |
|
1281 def settext(self, text): |
|
1282 if len(self.body) > 0: |
|
1283 self.body[0].settext(text) |
|
1284 setattr(cls, "settext", settext) |
|
1285 |
|
1286 def gettext(self): |
|
1287 if len(self.body) > 0: |
|
1288 return self.body[0].gettext() |
|
1289 return "" |
|
1290 setattr(cls, "gettext", gettext) |
|
1291 |
|
1292 def getvars(self): |
|
1293 vars = [] |
|
1294 if self.interface is not None: |
|
1295 reverse_types = {} |
|
1296 for name, value in VarTypes.items(): |
|
1297 reverse_types[value] = name |
|
1298 for varlist in self.interface.getcontent(): |
|
1299 vars.append((reverse_types[varlist["name"]], varlist["value"])) |
|
1300 return vars |
|
1301 setattr(cls, "getvars", getvars) |
|
1302 |
|
1303 def setvars(self, vars): |
|
1304 if self.interface is None: |
|
1305 self.interface = PLCOpenClasses["pou_interface"]() |
|
1306 self.interface.setcontent([]) |
|
1307 for vartype, varlist in vars: |
|
1308 self.interface.appendcontent({"name" : VarTypes[vartype], "value" : varlist}) |
|
1309 setattr(cls, "setvars", setvars) |
|
1310 |
|
1311 def addpouLocalVar(self, type, name, location="", description=""): |
|
1312 self.addpouVar(type, name, location=location, description=description) |
|
1313 setattr(cls, "addpouLocalVar", addpouLocalVar) |
|
1314 |
|
1315 def addpouExternalVar(self, type, name): |
|
1316 self.addpouVar(type, name, "externalVars") |
|
1317 setattr(cls, "addpouExternalVar", addpouExternalVar) |
|
1318 |
|
1319 def addpouVar(self, type, name, var_class="localVars", location="", description=""): |
|
1320 if self.interface is None: |
|
1321 self.interface = PLCOpenClasses["pou_interface"]() |
|
1322 content = self.interface.getcontent() |
|
1323 if len(content) == 0 or content[-1]["name"] != var_class: |
|
1324 content.append({"name" : var_class, "value" : PLCOpenClasses["interface_%s" % var_class]()}) |
|
1325 else: |
|
1326 varlist = content[-1]["value"] |
|
1327 variables = varlist.getvariable() |
|
1328 if varlist.getconstant() or varlist.getretain() or len(variables) > 0 and variables[0].getaddress(): |
|
1329 content.append({"name" : var_class, "value" : PLCOpenClasses["interface_%s" % var_class]()}) |
|
1330 var = PLCOpenClasses["varListPlain_variable"]() |
|
1331 var.setname(name) |
|
1332 var_type = PLCOpenClasses["dataType"]() |
|
1333 if type in [x for x,y in TypeHierarchy_list if not x.startswith("ANY")]: |
|
1334 if type == "STRING": |
|
1335 var_type.setcontent({"name" : "string", "value" : PLCOpenClasses["elementaryTypes_string"]()}) |
|
1336 elif type == "WSTRING": |
|
1337 var_type.setcontent({"name" : "wstring", "value" : PLCOpenClasses["elementaryTypes_wstring"]()}) |
|
1338 else: |
|
1339 var_type.setcontent({"name" : type, "value" : None}) |
|
1340 else: |
|
1341 derived_type = PLCOpenClasses["derivedTypes_derived"]() |
|
1342 derived_type.setname(type) |
|
1343 var_type.setcontent({"name" : "derived", "value" : derived_type}) |
|
1344 var.settype(var_type) |
|
1345 if location != "": |
|
1346 var.setaddress(location) |
|
1347 if description != "": |
|
1348 ft = PLCOpenClasses["formattedText"]() |
|
1349 ft.settext(description) |
|
1350 var.setdocumentation(ft) |
|
1351 |
|
1352 content[-1]["value"].appendvariable(var) |
|
1353 setattr(cls, "addpouVar", addpouVar) |
|
1354 |
|
1355 def changepouVar(self, old_type, old_name, new_type, new_name): |
|
1356 if self.interface is not None: |
|
1357 content = self.interface.getcontent() |
|
1358 for varlist in content: |
|
1359 variables = varlist["value"].getvariable() |
|
1360 for var in variables: |
|
1361 if var.getname() == old_name: |
|
1362 vartype_content = var.gettype().getcontent() |
|
1363 if vartype_content["name"] == "derived" and vartype_content["value"].getname() == old_type: |
|
1364 var.setname(new_name) |
|
1365 vartype_content["value"].setname(new_type) |
|
1366 return |
|
1367 setattr(cls, "changepouVar", changepouVar) |
|
1368 |
|
1369 def removepouVar(self, type, name): |
|
1370 if self.interface is not None: |
|
1371 content = self.interface.getcontent() |
|
1372 for varlist in content: |
|
1373 variables = varlist["value"].getvariable() |
|
1374 for var in variables: |
|
1375 if var.getname() == name: |
|
1376 vartype_content = var.gettype().getcontent() |
|
1377 if vartype_content["name"] == "derived" and vartype_content["value"].getname() == type: |
|
1378 variables.remove(var) |
|
1379 break |
|
1380 if len(varlist["value"].getvariable()) == 0: |
|
1381 content.remove(varlist) |
|
1382 break |
|
1383 setattr(cls, "removepouVar", removepouVar) |
|
1384 |
|
1385 def hasblock(self, name): |
|
1386 if self.getbodyType() in ["FBD", "LD", "SFC"]: |
|
1387 for instance in self.getinstances(): |
|
1388 if isinstance(instance, PLCOpenClasses["fbdObjects_block"]) and instance.getinstanceName() == name: |
|
1389 return True |
|
1390 if self.transitions: |
|
1391 for transition in self.transitions.gettransition(): |
|
1392 result = transition.hasblock(name) |
|
1393 if result: |
|
1394 return result |
|
1395 if self.actions: |
|
1396 for action in self.actions.getaction(): |
|
1397 result = action.hasblock(name) |
|
1398 if result: |
|
1399 return result |
|
1400 return False |
|
1401 setattr(cls, "hasblock", hasblock) |
|
1402 |
|
1403 def addtransition(self, name, type): |
|
1404 if not self.transitions: |
|
1405 self.addtransitions() |
|
1406 self.transitions.settransition([]) |
|
1407 transition = PLCOpenClasses["transitions_transition"]() |
|
1408 transition.setname(name) |
|
1409 transition.setbodyType(type) |
|
1410 if type == "ST": |
|
1411 transition.settext(":= ;") |
|
1412 elif type == "IL": |
|
1413 transition.settext("\tST\t%s"%name) |
|
1414 self.transitions.appendtransition(transition) |
|
1415 setattr(cls, "addtransition", addtransition) |
|
1416 |
|
1417 def gettransition(self, name): |
|
1418 if self.transitions: |
|
1419 for transition in self.transitions.gettransition(): |
|
1420 if transition.getname() == name: |
|
1421 return transition |
|
1422 return None |
|
1423 setattr(cls, "gettransition", gettransition) |
|
1424 |
|
1425 def gettransitionList(self): |
|
1426 if self.transitions: |
|
1427 return self.transitions.gettransition() |
|
1428 return [] |
|
1429 setattr(cls, "gettransitionList", gettransitionList) |
|
1430 |
|
1431 def removetransition(self, name): |
|
1432 if self.transitions: |
|
1433 transitions = self.transitions.gettransition() |
|
1434 i = 0 |
|
1435 removed = False |
|
1436 while i < len(transitions) and not removed: |
|
1437 if transitions[i].getname() == name: |
|
1438 transitions.pop(i) |
|
1439 removed = True |
|
1440 i += 1 |
|
1441 if not removed: |
|
1442 raise ValueError, _("Transition with name %s doesn't exist!")%name |
|
1443 setattr(cls, "removetransition", removetransition) |
|
1444 |
|
1445 def addaction(self, name, type): |
|
1446 if not self.actions: |
|
1447 self.addactions() |
|
1448 self.actions.setaction([]) |
|
1449 action = PLCOpenClasses["actions_action"]() |
|
1450 action.setname(name) |
|
1451 action.setbodyType(type) |
|
1452 self.actions.appendaction(action) |
|
1453 setattr(cls, "addaction", addaction) |
|
1454 |
|
1455 def getaction(self, name): |
|
1456 if self.actions: |
|
1457 for action in self.actions.getaction(): |
|
1458 if action.getname() == name: |
|
1459 return action |
|
1460 return None |
|
1461 setattr(cls, "getaction", getaction) |
|
1462 |
|
1463 def getactionList(self): |
|
1464 if self.actions: |
|
1465 return self.actions.getaction() |
|
1466 return [] |
|
1467 setattr(cls, "getactionList", getactionList) |
|
1468 |
|
1469 def removeaction(self, name): |
|
1470 if self.actions: |
|
1471 actions = self.actions.getaction() |
|
1472 i = 0 |
|
1473 removed = False |
|
1474 while i < len(actions) and not removed: |
|
1475 if actions[i].getname() == name: |
|
1476 actions.pop(i) |
|
1477 removed = True |
|
1478 i += 1 |
|
1479 if not removed: |
|
1480 raise ValueError, _("Action with name %s doesn't exist!")%name |
|
1481 setattr(cls, "removeaction", removeaction) |
|
1482 |
|
1483 def updateElementName(self, old_name, new_name): |
|
1484 if self.interface: |
|
1485 for content in self.interface.getcontent(): |
|
1486 for var in content["value"].getvariable(): |
|
1487 var_address = var.getaddress() |
|
1488 if var_address is not None: |
|
1489 if var_address == old_name: |
|
1490 var.setaddress(new_name) |
|
1491 if var.getname() == old_name: |
|
1492 var.setname(new_name) |
|
1493 var_type_content = var.gettype().getcontent() |
|
1494 if var_type_content["name"] == "derived": |
|
1495 if var_type_content["value"].getname() == old_name: |
|
1496 var_type_content["value"].setname(new_name) |
|
1497 self.body[0].updateElementName(old_name, new_name) |
|
1498 for action in self.getactionList(): |
|
1499 action.updateElementName(old_name, new_name) |
|
1500 for transition in self.gettransitionList(): |
|
1501 transition.updateElementName(old_name, new_name) |
|
1502 setattr(cls, "updateElementName", updateElementName) |
|
1503 |
|
1504 def updateElementAddress(self, address_model, new_leading): |
|
1505 if self.interface: |
|
1506 for content in self.interface.getcontent(): |
|
1507 for var in content["value"].getvariable(): |
|
1508 var_address = var.getaddress() |
|
1509 if var_address is not None: |
|
1510 var.setaddress(update_address(var_address, address_model, new_leading)) |
|
1511 self.body[0].updateElementAddress(address_model, new_leading) |
|
1512 for action in self.getactionList(): |
|
1513 action.updateElementAddress(address_model, new_leading) |
|
1514 for transition in self.gettransitionList(): |
|
1515 transition.updateElementAddress(address_model, new_leading) |
|
1516 setattr(cls, "updateElementAddress", updateElementAddress) |
|
1517 |
|
1518 def removeVariableByAddress(self, address): |
|
1519 if self.interface: |
|
1520 for content in self.interface.getcontent(): |
|
1521 variables = content["value"].getvariable() |
|
1522 for i in xrange(len(variables)-1, -1, -1): |
|
1523 if variables[i].getaddress() == address: |
|
1524 variables.pop(i) |
|
1525 setattr(cls, "removeVariableByAddress", removeVariableByAddress) |
|
1526 |
|
1527 def removeVariableByFilter(self, address_model): |
|
1528 if self.interface: |
|
1529 for content in self.interface.getcontent(): |
|
1530 variables = content["value"].getvariable() |
|
1531 for i in xrange(len(variables)-1, -1, -1): |
|
1532 var_address = variables[i].getaddress() |
|
1533 if var_address is not None: |
|
1534 result = address_model.match(var_address) |
|
1535 if result is not None: |
|
1536 variables.pop(i) |
|
1537 setattr(cls, "removeVariableByFilter", removeVariableByFilter) |
|
1538 |
|
1539 def Search(self, criteria, parent_infos=[]): |
|
1540 search_result = [] |
|
1541 filter = criteria["filter"] |
|
1542 if filter == "all" or self.getpouType() in filter: |
|
1543 parent_infos = parent_infos + ["P::%s" % self.getname()] |
|
1544 search_result.extend(_Search([("name", self.getname())], criteria, parent_infos)) |
|
1545 if self.interface is not None: |
|
1546 var_number = 0 |
|
1547 for content in self.interface.getcontent(): |
|
1548 variable_type = searchResultVarTypes.get(content["value"], "var_local") |
|
1549 variables = content["value"].getvariable() |
|
1550 for modifier, has_modifier in [("constant", content["value"].getconstant()), |
|
1551 ("retain", content["value"].getretain()), |
|
1552 ("non_retain", content["value"].getnonretain())]: |
|
1553 if has_modifier: |
|
1554 for result in TestTextElement(modifier, criteria): |
|
1555 search_result.append((tuple(parent_infos + [variable_type, (var_number, var_number + len(variables)), modifier]),) + result) |
|
1556 break |
|
1557 for variable in variables: |
|
1558 search_result.extend(variable.Search(criteria, parent_infos + [variable_type, var_number])) |
|
1559 var_number += 1 |
|
1560 if len(self.body) > 0: |
|
1561 search_result.extend(self.body[0].Search(criteria, parent_infos)) |
|
1562 for action in self.getactionList(): |
|
1563 search_result.extend(action.Search(criteria, parent_infos)) |
|
1564 for transition in self.gettransitionList(): |
|
1565 search_result.extend(transition.Search(criteria, parent_infos)) |
|
1566 return search_result |
|
1567 setattr(cls, "Search", Search) |
|
1568 |
|
1569 def setbodyType(self, type): |
|
1570 if type == "IL": |
|
1571 self.body.setcontent({"name" : "IL", "value" : PLCOpenClasses["formattedText"]()}) |
|
1572 elif type == "ST": |
|
1573 self.body.setcontent({"name" : "ST", "value" : PLCOpenClasses["formattedText"]()}) |
|
1574 elif type == "LD": |
|
1575 self.body.setcontent({"name" : "LD", "value" : PLCOpenClasses["body_LD"]()}) |
|
1576 elif type == "FBD": |
|
1577 self.body.setcontent({"name" : "FBD", "value" : PLCOpenClasses["body_FBD"]()}) |
|
1578 elif type == "SFC": |
|
1579 self.body.setcontent({"name" : "SFC", "value" : PLCOpenClasses["body_SFC"]()}) |
|
1580 else: |
|
1581 raise ValueError, "%s isn't a valid body type!"%type |
|
1582 |
|
1583 def getbodyType(self): |
|
1584 return self.body.getcontent()["name"] |
|
1585 |
|
1586 def resetexecutionOrder(self): |
|
1587 self.body.resetexecutionOrder() |
|
1588 |
|
1589 def compileexecutionOrder(self): |
|
1590 self.body.compileexecutionOrder() |
|
1591 |
|
1592 def setelementExecutionOrder(self, instance, new_executionOrder): |
|
1593 self.body.setelementExecutionOrder(instance, new_executionOrder) |
|
1594 |
|
1595 def addinstance(self, name, instance): |
|
1596 self.body.appendcontentInstance(name, instance) |
|
1597 |
|
1598 def getinstances(self): |
|
1599 return self.body.getcontentInstances() |
|
1600 |
|
1601 def getinstance(self, id): |
|
1602 return self.body.getcontentInstance(id) |
|
1603 |
|
1604 def getrandomInstance(self, exclude): |
|
1605 return self.body.getcontentRandomInstance(exclude) |
|
1606 |
|
1607 def getinstanceByName(self, name): |
|
1608 return self.body.getcontentInstanceByName(name) |
|
1609 |
|
1610 def removeinstance(self, id): |
|
1611 self.body.removecontentInstance(id) |
|
1612 |
|
1613 def settext(self, text): |
|
1614 self.body.settext(text) |
|
1615 |
|
1616 def gettext(self): |
|
1617 return self.body.gettext() |
|
1618 |
|
1619 cls = PLCOpenClasses.get("transitions_transition", None) |
|
1620 if cls: |
|
1621 setattr(cls, "setbodyType", setbodyType) |
|
1622 setattr(cls, "getbodyType", getbodyType) |
|
1623 setattr(cls, "resetexecutionOrder", resetexecutionOrder) |
|
1624 setattr(cls, "compileexecutionOrder", compileexecutionOrder) |
|
1625 setattr(cls, "setelementExecutionOrder", setelementExecutionOrder) |
|
1626 setattr(cls, "addinstance", addinstance) |
|
1627 setattr(cls, "getinstances", getinstances) |
|
1628 setattr(cls, "getinstance", getinstance) |
|
1629 setattr(cls, "getrandomInstance", getrandomInstance) |
|
1630 setattr(cls, "getinstanceByName", getinstanceByName) |
|
1631 setattr(cls, "removeinstance", removeinstance) |
|
1632 setattr(cls, "settext", settext) |
|
1633 setattr(cls, "gettext", gettext) |
|
1634 |
|
1635 def updateElementName(self, old_name, new_name): |
|
1636 self.body.updateElementName(old_name, new_name) |
|
1637 setattr(cls, "updateElementName", updateElementName) |
|
1638 |
|
1639 def updateElementAddress(self, address_model, new_leading): |
|
1640 self.body.updateElementAddress(address_model, new_leading) |
|
1641 setattr(cls, "updateElementAddress", updateElementAddress) |
|
1642 |
|
1643 def hasblock(self, name): |
|
1644 if self.getbodyType() in ["FBD", "LD", "SFC"]: |
|
1645 for instance in self.getinstances(): |
|
1646 if isinstance(instance, PLCOpenClasses["fbdObjects_block"]) and instance.getinstanceName() == name: |
|
1647 return True |
|
1648 return False |
|
1649 setattr(cls, "hasblock", hasblock) |
|
1650 |
|
1651 def Search(self, criteria, parent_infos): |
|
1652 search_result = [] |
|
1653 parent_infos = parent_infos[:-1] + ["T::%s::%s" % (parent_infos[-1].split("::")[1], self.getname())] |
|
1654 for result in TestTextElement(self.getname(), criteria): |
|
1655 search_result.append((tuple(parent_infos + ["name"]),) + result) |
|
1656 search_result.extend(self.body.Search(criteria, parent_infos)) |
|
1657 return search_result |
|
1658 setattr(cls, "Search", Search) |
|
1659 |
|
1660 cls = PLCOpenClasses.get("actions_action", None) |
|
1661 if cls: |
|
1662 setattr(cls, "setbodyType", setbodyType) |
|
1663 setattr(cls, "getbodyType", getbodyType) |
|
1664 setattr(cls, "resetexecutionOrder", resetexecutionOrder) |
|
1665 setattr(cls, "compileexecutionOrder", compileexecutionOrder) |
|
1666 setattr(cls, "setelementExecutionOrder", setelementExecutionOrder) |
|
1667 setattr(cls, "addinstance", addinstance) |
|
1668 setattr(cls, "getinstances", getinstances) |
|
1669 setattr(cls, "getinstance", getinstance) |
|
1670 setattr(cls, "getrandomInstance", getrandomInstance) |
|
1671 setattr(cls, "getinstanceByName", getinstanceByName) |
|
1672 setattr(cls, "removeinstance", removeinstance) |
|
1673 setattr(cls, "settext", settext) |
|
1674 setattr(cls, "gettext", gettext) |
|
1675 |
|
1676 def updateElementName(self, old_name, new_name): |
|
1677 self.body.updateElementName(old_name, new_name) |
|
1678 setattr(cls, "updateElementName", updateElementName) |
|
1679 |
|
1680 def updateElementAddress(self, address_model, new_leading): |
|
1681 self.body.updateElementAddress(address_model, new_leading) |
|
1682 setattr(cls, "updateElementAddress", updateElementAddress) |
|
1683 |
|
1684 def hasblock(self, name): |
|
1685 if self.getbodyType() in ["FBD", "LD", "SFC"]: |
|
1686 for instance in self.getinstances(): |
|
1687 if isinstance(instance, PLCOpenClasses["fbdObjects_block"]) and instance.getinstanceName() == name: |
|
1688 return True |
|
1689 return False |
|
1690 setattr(cls, "hasblock", hasblock) |
|
1691 |
|
1692 def Search(self, criteria, parent_infos): |
|
1693 search_result = [] |
|
1694 parent_infos = parent_infos[:-1] + ["A::%s::%s" % (parent_infos[-1].split("::")[1], self.getname())] |
|
1695 for result in TestTextElement(self.getname(), criteria): |
|
1696 search_result.append((tuple(parent_infos + ["name"]),) + result) |
|
1697 search_result.extend(self.body.Search(criteria, parent_infos)) |
|
1698 return search_result |
|
1699 setattr(cls, "Search", Search) |
|
1700 |
|
1701 cls = PLCOpenClasses.get("body", None) |
|
1702 if cls: |
|
1703 cls.currentExecutionOrderId = 0 |
|
1704 |
|
1705 def resetcurrentExecutionOrderId(self): |
|
1706 object.__setattr__(self, "currentExecutionOrderId", 0) |
|
1707 setattr(cls, "resetcurrentExecutionOrderId", resetcurrentExecutionOrderId) |
|
1708 |
|
1709 def getnewExecutionOrderId(self): |
|
1710 object.__setattr__(self, "currentExecutionOrderId", self.currentExecutionOrderId + 1) |
|
1711 return self.currentExecutionOrderId |
|
1712 setattr(cls, "getnewExecutionOrderId", getnewExecutionOrderId) |
|
1713 |
|
1714 def resetexecutionOrder(self): |
|
1715 if self.content["name"] == "FBD": |
|
1716 for element in self.content["value"].getcontent(): |
|
1717 if not isinstance(element["value"], (PLCOpenClasses.get("commonObjects_comment", None), |
|
1718 PLCOpenClasses.get("commonObjects_connector", None), |
|
1719 PLCOpenClasses.get("commonObjects_continuation", None))): |
|
1720 element["value"].setexecutionOrderId(0) |
|
1721 else: |
|
1722 raise TypeError, _("Can only generate execution order on FBD networks!") |
|
1723 setattr(cls, "resetexecutionOrder", resetexecutionOrder) |
|
1724 |
|
1725 def compileexecutionOrder(self): |
|
1726 if self.content["name"] == "FBD": |
|
1727 self.resetexecutionOrder() |
|
1728 self.resetcurrentExecutionOrderId() |
|
1729 for element in self.content["value"].getcontent(): |
|
1730 if isinstance(element["value"], PLCOpenClasses.get("fbdObjects_outVariable", None)) and element["value"].getexecutionOrderId() == 0: |
|
1731 connections = element["value"].connectionPointIn.getconnections() |
|
1732 if connections and len(connections) == 1: |
|
1733 self.compileelementExecutionOrder(connections[0]) |
|
1734 element["value"].setexecutionOrderId(self.getnewExecutionOrderId()) |
|
1735 else: |
|
1736 raise TypeError, _("Can only generate execution order on FBD networks!") |
|
1737 setattr(cls, "compileexecutionOrder", compileexecutionOrder) |
|
1738 |
|
1739 def compileelementExecutionOrder(self, link): |
|
1740 if self.content["name"] == "FBD": |
|
1741 localid = link.getrefLocalId() |
|
1742 instance = self.getcontentInstance(localid) |
|
1743 if isinstance(instance, PLCOpenClasses.get("fbdObjects_block", None)) and instance.getexecutionOrderId() == 0: |
|
1744 for variable in instance.inputVariables.getvariable(): |
|
1745 connections = variable.connectionPointIn.getconnections() |
|
1746 if connections and len(connections) == 1: |
|
1747 self.compileelementExecutionOrder(connections[0]) |
|
1748 instance.setexecutionOrderId(self.getnewExecutionOrderId()) |
|
1749 elif isinstance(instance, PLCOpenClasses.get("commonObjects_continuation", None)) and instance.getexecutionOrderId() == 0: |
|
1750 name = instance.getname() |
|
1751 for tmp_instance in self.getcontentInstances(): |
|
1752 if isinstance(tmp_instance, PLCOpenClasses.get("commonObjects_connector", None)) and tmp_instance.getname() == name and tmp_instance.getexecutionOrderId() == 0: |
|
1753 connections = tmp_instance.connectionPointIn.getconnections() |
|
1754 if connections and len(connections) == 1: |
|
1755 self.compileelementExecutionOrder(connections[0]) |
|
1756 else: |
|
1757 raise TypeError, _("Can only generate execution order on FBD networks!") |
|
1758 setattr(cls, "compileelementExecutionOrder", compileelementExecutionOrder) |
|
1759 |
|
1760 def setelementExecutionOrder(self, instance, new_executionOrder): |
|
1761 if self.content["name"] == "FBD": |
|
1762 old_executionOrder = instance.getexecutionOrderId() |
|
1763 if old_executionOrder is not None and old_executionOrder != 0 and new_executionOrder != 0: |
|
1764 for element in self.content["value"].getcontent(): |
|
1765 if element["value"] != instance and not isinstance(element["value"], PLCOpenClasses.get("commonObjects_comment", None)): |
|
1766 element_executionOrder = element["value"].getexecutionOrderId() |
|
1767 if old_executionOrder <= element_executionOrder <= new_executionOrder: |
|
1768 element["value"].setexecutionOrderId(element_executionOrder - 1) |
|
1769 if new_executionOrder <= element_executionOrder <= old_executionOrder: |
|
1770 element["value"].setexecutionOrderId(element_executionOrder + 1) |
|
1771 instance.setexecutionOrderId(new_executionOrder) |
|
1772 else: |
|
1773 raise TypeError, _("Can only generate execution order on FBD networks!") |
|
1774 setattr(cls, "setelementExecutionOrder", setelementExecutionOrder) |
|
1775 |
|
1776 def appendcontentInstance(self, name, instance): |
|
1777 if self.content["name"] in ["LD","FBD","SFC"]: |
|
1778 self.content["value"].appendcontent({"name" : name, "value" : instance}) |
|
1779 else: |
|
1780 raise TypeError, _("%s body don't have instances!")%self.content["name"] |
|
1781 setattr(cls, "appendcontentInstance", appendcontentInstance) |
|
1782 |
|
1783 def getcontentInstances(self): |
|
1784 if self.content["name"] in ["LD","FBD","SFC"]: |
|
1785 instances = [] |
|
1786 for element in self.content["value"].getcontent(): |
|
1787 instances.append(element["value"]) |
|
1788 return instances |
|
1789 else: |
|
1790 raise TypeError, _("%s body don't have instances!")%self.content["name"] |
|
1791 setattr(cls, "getcontentInstances", getcontentInstances) |
|
1792 |
|
1793 def getcontentInstance(self, id): |
|
1794 if self.content["name"] in ["LD","FBD","SFC"]: |
|
1795 for element in self.content["value"].getcontent(): |
|
1796 if element["value"].getlocalId() == id: |
|
1797 return element["value"] |
|
1798 return None |
|
1799 else: |
|
1800 raise TypeError, _("%s body don't have instances!")%self.content["name"] |
|
1801 setattr(cls, "getcontentInstance", getcontentInstance) |
|
1802 |
|
1803 def getcontentRandomInstance(self, exclude): |
|
1804 if self.content["name"] in ["LD","FBD","SFC"]: |
|
1805 for element in self.content["value"].getcontent(): |
|
1806 if element["value"].getlocalId() not in exclude: |
|
1807 return element["value"] |
|
1808 return None |
|
1809 else: |
|
1810 raise TypeError, _("%s body don't have instances!")%self.content["name"] |
|
1811 setattr(cls, "getcontentRandomInstance", getcontentRandomInstance) |
|
1812 |
|
1813 def getcontentInstanceByName(self, name): |
|
1814 if self.content["name"] in ["LD","FBD","SFC"]: |
|
1815 for element in self.content["value"].getcontent(): |
|
1816 if isinstance(element["value"], PLCOpenClasses.get("fbdObjects_block", None)) and element["value"].getinstanceName() == name: |
|
1817 return element["value"] |
|
1818 else: |
|
1819 raise TypeError, _("%s body don't have instances!")%self.content["name"] |
|
1820 setattr(cls, "getcontentInstanceByName", getcontentInstanceByName) |
|
1821 |
|
1822 def removecontentInstance(self, id): |
|
1823 if self.content["name"] in ["LD","FBD","SFC"]: |
|
1824 i = 0 |
|
1825 removed = False |
|
1826 elements = self.content["value"].getcontent() |
|
1827 while i < len(elements) and not removed: |
|
1828 if elements[i]["value"].getlocalId() == id: |
|
1829 self.content["value"].removecontent(i) |
|
1830 removed = True |
|
1831 i += 1 |
|
1832 if not removed: |
|
1833 raise ValueError, _("Instance with id %d doesn't exist!")%id |
|
1834 else: |
|
1835 raise TypeError, "%s body don't have instances!"%self.content["name"] |
|
1836 setattr(cls, "removecontentInstance", removecontentInstance) |
|
1837 |
|
1838 def settext(self, text): |
|
1839 if self.content["name"] in ["IL","ST"]: |
|
1840 self.content["value"].settext(text) |
|
1841 else: |
|
1842 raise TypeError, _("%s body don't have text!")%self.content["name"] |
|
1843 setattr(cls, "settext", settext) |
|
1844 |
|
1845 def gettext(self): |
|
1846 if self.content["name"] in ["IL","ST"]: |
|
1847 return self.content["value"].gettext() |
|
1848 else: |
|
1849 raise TypeError, _("%s body don't have text!")%self.content["name"] |
|
1850 setattr(cls, "gettext", gettext) |
|
1851 |
|
1852 def updateElementName(self, old_name, new_name): |
|
1853 if self.content["name"] in ["IL", "ST"]: |
|
1854 self.content["value"].updateElementName(old_name, new_name) |
|
1855 else: |
|
1856 for element in self.content["value"].getcontent(): |
|
1857 element["value"].updateElementName(old_name, new_name) |
|
1858 setattr(cls, "updateElementName", updateElementName) |
|
1859 |
|
1860 def updateElementAddress(self, address_model, new_leading): |
|
1861 if self.content["name"] in ["IL", "ST"]: |
|
1862 self.content["value"].updateElementAddress(address_model, new_leading) |
|
1863 else: |
|
1864 for element in self.content["value"].getcontent(): |
|
1865 element["value"].updateElementAddress(address_model, new_leading) |
|
1866 setattr(cls, "updateElementAddress", updateElementAddress) |
|
1867 |
|
1868 def Search(self, criteria, parent_infos=[]): |
|
1869 if self.content["name"] in ["IL", "ST"]: |
|
1870 search_result = self.content["value"].Search(criteria, parent_infos + ["body", 0]) |
|
1871 else: |
|
1872 search_result = [] |
|
1873 for element in self.content["value"].getcontent(): |
|
1874 search_result.extend(element["value"].Search(criteria, parent_infos)) |
|
1875 return search_result |
|
1876 setattr(cls, "Search", Search) |
|
1877 |
|
1878 def getx(self): |
|
1879 return self.position.getx() |
|
1880 |
|
1881 def gety(self): |
|
1882 return self.position.gety() |
|
1883 |
|
1884 def setx(self, x): |
|
1885 self.position.setx(x) |
|
1886 |
|
1887 def sety(self, y): |
|
1888 self.position.sety(y) |
|
1889 |
|
1890 def _getBoundingBox(self): |
|
1891 return rect(self.getx(), self.gety(), self.getwidth(), self.getheight()) |
|
1892 |
|
1893 def _getConnectionsBoundingBox(connectionPointIn): |
|
1894 bbox = rect() |
|
1895 connections = connectionPointIn.getconnections() |
|
1896 if connections is not None: |
|
1897 for connection in connections: |
|
1898 for x, y in connection.getpoints(): |
|
1899 bbox.update(x, y) |
|
1900 return bbox |
|
1901 |
|
1902 def _getBoundingBoxSingle(self): |
|
1903 bbox = _getBoundingBox(self) |
|
1904 if self.connectionPointIn is not None: |
|
1905 bbox.union(_getConnectionsBoundingBox(self.connectionPointIn)) |
|
1906 return bbox |
|
1907 |
|
1908 def _getBoundingBoxMultiple(self): |
|
1909 bbox = _getBoundingBox(self) |
|
1910 for connectionPointIn in self.getconnectionPointIn(): |
|
1911 bbox.union(_getConnectionsBoundingBox(connectionPointIn)) |
|
1912 return bbox |
|
1913 |
|
1914 def _filterConnections(connectionPointIn, localId, connections): |
|
1915 in_connections = connectionPointIn.getconnections() |
|
1916 if in_connections is not None: |
|
1917 to_delete = [] |
|
1918 for i, connection in enumerate(in_connections): |
|
1919 connected = connection.getrefLocalId() |
|
1920 if not connections.has_key((localId, connected)) and \ |
|
1921 not connections.has_key((connected, localId)): |
|
1922 to_delete.append(i) |
|
1923 to_delete.reverse() |
|
1924 for i in to_delete: |
|
1925 connectionPointIn.removeconnection(i) |
|
1926 |
|
1927 def _filterConnectionsSingle(self, connections): |
|
1928 if self.connectionPointIn is not None: |
|
1929 _filterConnections(self.connectionPointIn, self.localId, connections) |
|
1930 |
|
1931 def _filterConnectionsMultiple(self, connections): |
|
1932 for connectionPointIn in self.getconnectionPointIn(): |
|
1933 _filterConnections(connectionPointIn, self.localId, connections) |
|
1934 |
|
1935 def _getconnectionsdefinition(instance, connections_end): |
|
1936 id = instance.getlocalId() |
|
1937 return dict([((id, end), True) for end in connections_end]) |
|
1938 |
|
1939 def _updateConnectionsId(connectionPointIn, translation): |
|
1940 connections_end = [] |
|
1941 connections = connectionPointIn.getconnections() |
|
1942 if connections is not None: |
|
1943 for connection in connections: |
|
1944 refLocalId = connection.getrefLocalId() |
|
1945 new_reflocalId = translation.get(refLocalId, refLocalId) |
|
1946 connection.setrefLocalId(new_reflocalId) |
|
1947 connections_end.append(new_reflocalId) |
|
1948 return connections_end |
|
1949 |
|
1950 def _updateConnectionsIdSingle(self, translation): |
|
1951 connections_end = [] |
|
1952 if self.connectionPointIn is not None: |
|
1953 connections_end = _updateConnectionsId(self.connectionPointIn, translation) |
|
1954 return _getconnectionsdefinition(self, connections_end) |
|
1955 |
|
1956 def _updateConnectionsIdMultiple(self, translation): |
|
1957 connections_end = [] |
|
1958 for connectionPointIn in self.getconnectionPointIn(): |
|
1959 connections_end.extend(_updateConnectionsId(connectionPointIn, translation)) |
|
1960 return _getconnectionsdefinition(self, connections_end) |
|
1961 |
|
1962 def _translate(self, dx, dy): |
|
1963 self.setx(self.getx() + dx) |
|
1964 self.sety(self.gety() + dy) |
|
1965 |
|
1966 def _translateConnections(connectionPointIn, dx, dy): |
|
1967 connections = connectionPointIn.getconnections() |
|
1968 if connections is not None: |
|
1969 for connection in connections: |
|
1970 for position in connection.getposition(): |
|
1971 position.setx(position.getx() + dx) |
|
1972 position.sety(position.gety() + dy) |
|
1973 |
|
1974 def _translateSingle(self, dx, dy): |
|
1975 _translate(self, dx, dy) |
|
1976 if self.connectionPointIn is not None: |
|
1977 _translateConnections(self.connectionPointIn, dx, dy) |
|
1978 |
|
1979 def _translateMultiple(self, dx, dy): |
|
1980 _translate(self, dx, dy) |
|
1981 for connectionPointIn in self.getconnectionPointIn(): |
|
1982 _translateConnections(connectionPointIn, dx, dy) |
|
1983 |
|
1984 def _updateElementName(self, old_name, new_name): |
|
1985 pass |
|
1986 |
|
1987 def _updateElementAddress(self, address_model, new_leading): |
|
1988 pass |
|
1989 |
|
1990 def _SearchInElement(self, criteria, parent_infos=[]): |
|
1991 return [] |
|
1992 |
|
1993 _connectionsFunctions = { |
|
1994 "bbox": {"none": _getBoundingBox, |
|
1995 "single": _getBoundingBoxSingle, |
|
1996 "multiple": _getBoundingBoxMultiple}, |
|
1997 "translate": {"none": _translate, |
|
1998 "single": _translateSingle, |
|
1999 "multiple": _translateMultiple}, |
|
2000 "filter": {"none": lambda self, connections: None, |
|
2001 "single": _filterConnectionsSingle, |
|
2002 "multiple": _filterConnectionsMultiple}, |
|
2003 "update": {"none": lambda self, translation: {}, |
|
2004 "single": _updateConnectionsIdSingle, |
|
2005 "multiple": _updateConnectionsIdMultiple}, |
|
2006 } |
|
2007 |
|
2008 def _initElementClass(name, classname, connectionPointInType="none"): |
|
2009 ElementNameToClass[name] = classname |
|
2010 cls = PLCOpenClasses.get(classname, None) |
|
2011 if cls: |
|
2012 setattr(cls, "getx", getx) |
|
2013 setattr(cls, "gety", gety) |
|
2014 setattr(cls, "setx", setx) |
|
2015 setattr(cls, "sety", sety) |
|
2016 setattr(cls, "updateElementName", _updateElementName) |
|
2017 setattr(cls, "updateElementAddress", _updateElementAddress) |
|
2018 setattr(cls, "getBoundingBox", _connectionsFunctions["bbox"][connectionPointInType]) |
|
2019 setattr(cls, "translate", _connectionsFunctions["translate"][connectionPointInType]) |
|
2020 setattr(cls, "filterConnections", _connectionsFunctions["filter"][connectionPointInType]) |
|
2021 setattr(cls, "updateConnectionsId", _connectionsFunctions["update"][connectionPointInType]) |
|
2022 setattr(cls, "Search", _SearchInElement) |
|
2023 return cls |
|
2024 |
|
2025 def _getexecutionOrder(instance, specific_values): |
|
2026 executionOrder = instance.getexecutionOrderId() |
|
2027 if executionOrder is None: |
|
2028 executionOrder = 0 |
|
2029 specific_values["executionOrder"] = executionOrder |
|
2030 |
|
2031 def _getdefaultmodifiers(instance, infos): |
|
2032 infos["negated"] = instance.getnegated() |
|
2033 infos["edge"] = instance.getedge() |
|
2034 |
|
2035 def _getinputmodifiers(instance, infos): |
|
2036 infos["negated"] = instance.getnegatedIn() |
|
2037 infos["edge"] = instance.getedgeIn() |
|
2038 |
|
2039 def _getoutputmodifiers(instance, infos): |
|
2040 infos["negated"] = instance.getnegatedOut() |
|
2041 infos["edge"] = instance.getedgeOut() |
|
2042 |
|
2043 MODIFIERS_FUNCTIONS = {"default": _getdefaultmodifiers, |
|
2044 "input": _getinputmodifiers, |
|
2045 "output": _getoutputmodifiers} |
|
2046 |
|
2047 def _getconnectioninfos(instance, connection, links=False, modifiers=None, parameter=False): |
|
2048 infos = {"position": connection.getrelPositionXY()} |
|
2049 if parameter: |
|
2050 infos["name"] = instance.getformalParameter() |
|
2051 MODIFIERS_FUNCTIONS.get(modifiers, lambda x, y: None)(instance, infos) |
|
2052 if links: |
|
2053 infos["links"] = [] |
|
2054 connections = connection.getconnections() |
|
2055 if connections is not None: |
|
2056 for link in connections: |
|
2057 dic = {"refLocalId": link.getrefLocalId(), |
|
2058 "points": link.getpoints(), |
|
2059 "formalParameter": link.getformalParameter()} |
|
2060 infos["links"].append(dic) |
|
2061 return infos |
|
2062 |
|
2063 def _getelementinfos(instance): |
|
2064 return {"id": instance.getlocalId(), |
|
2065 "x": instance.getx(), |
|
2066 "y": instance.gety(), |
|
2067 "height": instance.getheight(), |
|
2068 "width": instance.getwidth(), |
|
2069 "specific_values": {}, |
|
2070 "inputs": [], |
|
2071 "outputs": []} |
|
2072 |
|
2073 def _getvariableinfosFunction(type, input, output): |
|
2074 def getvariableinfos(self): |
|
2075 infos = _getelementinfos(self) |
|
2076 infos["type"] = type |
|
2077 specific_values = infos["specific_values"] |
|
2078 specific_values["name"] = self.getexpression() |
|
2079 _getexecutionOrder(self, specific_values) |
|
2080 if input and output: |
|
2081 infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True, "input")) |
|
2082 infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut, False, "output")) |
|
2083 elif input: |
|
2084 infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True, "default")) |
|
2085 elif output: |
|
2086 infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut, False, "default")) |
|
2087 return infos |
|
2088 return getvariableinfos |
|
2089 |
|
2090 def _getconnectorinfosFunction(type): |
|
2091 def getvariableinfos(self): |
|
2092 infos = _getelementinfos(self) |
|
2093 infos["type"] = type |
|
2094 infos["specific_values"]["name"] = self.getname() |
|
2095 if type == "connector": |
|
2096 infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True)) |
|
2097 elif type == "continuation": |
|
2098 infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut)) |
|
2099 return infos |
|
2100 return getvariableinfos |
|
2101 |
|
2102 def _getpowerrailinfosFunction(type): |
|
2103 def getpowerrailinfos(self): |
|
2104 infos = _getelementinfos(self) |
|
2105 infos["type"] = type |
|
2106 if type == "rightPowerRail": |
|
2107 for connectionPointIn in self.getconnectionPointIn(): |
|
2108 infos["inputs"].append(_getconnectioninfos(self, connectionPointIn, True)) |
|
2109 infos["specific_values"]["connectors"] = len(infos["inputs"]) |
|
2110 elif type == "leftPowerRail": |
|
2111 for connectionPointOut in self.getconnectionPointOut(): |
|
2112 infos["outputs"].append(_getconnectioninfos(self, connectionPointOut)) |
|
2113 infos["specific_values"]["connectors"] = len(infos["outputs"]) |
|
2114 return infos |
|
2115 return getpowerrailinfos |
|
2116 |
|
2117 def _getldelementinfosFunction(type): |
|
2118 def getldelementinfos(self): |
|
2119 infos = _getelementinfos(self) |
|
2120 infos["type"] = type |
|
2121 specific_values = infos["specific_values"] |
|
2122 specific_values["name"] = self.getvariable() |
|
2123 _getexecutionOrder(self, specific_values) |
|
2124 specific_values["negated"] = self.getnegated() |
|
2125 specific_values["edge"] = self.getedge() |
|
2126 if type == "coil": |
|
2127 specific_values["storage"] = self.getstorage() |
|
2128 infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True)) |
|
2129 infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut)) |
|
2130 return infos |
|
2131 return getldelementinfos |
|
2132 |
|
2133 DIVERGENCE_TYPES = {(True, True): "simultaneousDivergence", |
|
2134 (True, False): "selectionDivergence", |
|
2135 (False, True): "simultaneousConvergence", |
|
2136 (False, False): "selectionConvergence"} |
|
2137 |
|
2138 def _getdivergenceinfosFunction(divergence, simultaneous): |
|
2139 def getdivergenceinfos(self): |
|
2140 infos = _getelementinfos(self) |
|
2141 infos["type"] = DIVERGENCE_TYPES[(divergence, simultaneous)] |
|
2142 if divergence: |
|
2143 infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True)) |
|
2144 for connectionPointOut in self.getconnectionPointOut(): |
|
2145 infos["outputs"].append(_getconnectioninfos(self, connectionPointOut)) |
|
2146 infos["specific_values"]["connectors"] = len(infos["outputs"]) |
|
2147 else: |
|
2148 for connectionPointIn in self.getconnectionPointIn(): |
|
2149 infos["inputs"].append(_getconnectioninfos(self, connectionPointIn, True)) |
|
2150 infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut)) |
|
2151 infos["specific_values"]["connectors"] = len(infos["inputs"]) |
|
2152 return infos |
|
2153 return getdivergenceinfos |
|
2154 |
|
2155 cls = _initElementClass("comment", "commonObjects_comment") |
|
2156 if cls: |
|
2157 def getinfos(self): |
|
2158 infos = _getelementinfos(self) |
|
2159 infos["type"] = "comment" |
|
2160 infos["specific_values"]["content"] = self.getcontentText() |
|
2161 return infos |
|
2162 setattr(cls, "getinfos", getinfos) |
|
2163 |
|
2164 def setcontentText(self, text): |
|
2165 self.content.settext(text) |
|
2166 setattr(cls, "setcontentText", setcontentText) |
|
2167 |
|
2168 def getcontentText(self): |
|
2169 return self.content.gettext() |
|
2170 setattr(cls, "getcontentText", getcontentText) |
|
2171 |
|
2172 def updateElementName(self, old_name, new_name): |
|
2173 self.content.updateElementName(old_name, new_name) |
|
2174 setattr(cls, "updateElementName", updateElementName) |
|
2175 |
|
2176 def updateElementAddress(self, address_model, new_leading): |
|
2177 self.content.updateElementAddress(address_model, new_leading) |
|
2178 setattr(cls, "updateElementAddress", updateElementAddress) |
|
2179 |
|
2180 def Search(self, criteria, parent_infos=[]): |
|
2181 return self.content.Search(criteria, parent_infos + ["comment", self.getlocalId(), "content"]) |
|
2182 setattr(cls, "Search", Search) |
|
2183 |
|
2184 cls = _initElementClass("block", "fbdObjects_block") |
|
2185 if cls: |
|
2186 def getBoundingBox(self): |
|
2187 bbox = _getBoundingBox(self) |
|
2188 for input in self.inputVariables.getvariable(): |
|
2189 bbox.union(_getConnectionsBoundingBox(input.connectionPointIn)) |
|
2190 return bbox |
|
2191 setattr(cls, "getBoundingBox", getBoundingBox) |
|
2192 |
|
2193 def getinfos(self): |
|
2194 infos = _getelementinfos(self) |
|
2195 infos["type"] = self.gettypeName() |
|
2196 specific_values = infos["specific_values"] |
|
2197 specific_values["name"] = self.getinstanceName() |
|
2198 _getexecutionOrder(self, specific_values) |
|
2199 for variable in self.inputVariables.getvariable(): |
|
2200 infos["inputs"].append(_getconnectioninfos(variable, variable.connectionPointIn, True, "default", True)) |
|
2201 for variable in self.outputVariables.getvariable(): |
|
2202 infos["outputs"].append(_getconnectioninfos(variable, variable.connectionPointOut, False, "default", True)) |
|
2203 return infos |
|
2204 setattr(cls, "getinfos", getinfos) |
|
2205 |
|
2206 def updateElementName(self, old_name, new_name): |
|
2207 if self.typeName == old_name: |
|
2208 self.typeName = new_name |
|
2209 setattr(cls, "updateElementName", updateElementName) |
|
2210 |
|
2211 def filterConnections(self, connections): |
|
2212 for input in self.inputVariables.getvariable(): |
|
2213 _filterConnections(input.connectionPointIn, self.localId, connections) |
|
2214 setattr(cls, "filterConnections", filterConnections) |
|
2215 |
|
2216 def updateConnectionsId(self, translation): |
|
2217 connections_end = [] |
|
2218 for input in self.inputVariables.getvariable(): |
|
2219 connections_end.extend(_updateConnectionsId(input.connectionPointIn, translation)) |
|
2220 return _getconnectionsdefinition(self, connections_end) |
|
2221 setattr(cls, "updateConnectionsId", updateConnectionsId) |
|
2222 |
|
2223 def translate(self, dx, dy): |
|
2224 _translate(self, dx, dy) |
|
2225 for input in self.inputVariables.getvariable(): |
|
2226 _translateConnections(input.connectionPointIn, dx, dy) |
|
2227 setattr(cls, "translate", translate) |
|
2228 |
|
2229 def Search(self, criteria, parent_infos=[]): |
|
2230 parent_infos = parent_infos + ["block", self.getlocalId()] |
|
2231 search_result = _Search([("name", self.getinstanceName()), |
|
2232 ("type", self.gettypeName())], |
|
2233 criteria, parent_infos) |
|
2234 for i, variable in enumerate(self.inputVariables.getvariable()): |
|
2235 for result in TestTextElement(variable.getformalParameter(), criteria): |
|
2236 search_result.append((tuple(parent_infos + ["input", i]),) + result) |
|
2237 for i, variable in enumerate(self.outputVariables.getvariable()): |
|
2238 for result in TestTextElement(variable.getformalParameter(), criteria): |
|
2239 search_result.append((tuple(parent_infos + ["output", i]),) + result) |
|
2240 return search_result |
|
2241 setattr(cls, "Search", Search) |
|
2242 |
|
2243 cls = _initElementClass("leftPowerRail", "ldObjects_leftPowerRail") |
|
2244 if cls: |
|
2245 setattr(cls, "getinfos", _getpowerrailinfosFunction("leftPowerRail")) |
|
2246 |
|
2247 cls = _initElementClass("rightPowerRail", "ldObjects_rightPowerRail", "multiple") |
|
2248 if cls: |
|
2249 setattr(cls, "getinfos", _getpowerrailinfosFunction("rightPowerRail")) |
|
2250 |
|
2251 cls = _initElementClass("contact", "ldObjects_contact", "single") |
|
2252 if cls: |
|
2253 setattr(cls, "getinfos", _getldelementinfosFunction("contact")) |
|
2254 |
|
2255 def updateElementName(self, old_name, new_name): |
|
2256 if self.variable == old_name: |
|
2257 self.variable = new_name |
|
2258 setattr(cls, "updateElementName", updateElementName) |
|
2259 |
|
2260 def updateElementAddress(self, address_model, new_leading): |
|
2261 self.variable = update_address(self.variable, address_model, new_leading) |
|
2262 setattr(cls, "updateElementAddress", updateElementAddress) |
|
2263 |
|
2264 def Search(self, criteria, parent_infos=[]): |
|
2265 return _Search([("reference", self.getvariable())], criteria, parent_infos + ["contact", self.getlocalId()]) |
|
2266 setattr(cls, "Search", Search) |
|
2267 |
|
2268 cls = _initElementClass("coil", "ldObjects_coil", "single") |
|
2269 if cls: |
|
2270 setattr(cls, "getinfos", _getldelementinfosFunction("coil")) |
|
2271 |
|
2272 def updateElementName(self, old_name, new_name): |
|
2273 if self.variable == old_name: |
|
2274 self.variable = new_name |
|
2275 setattr(cls, "updateElementName", updateElementName) |
|
2276 |
|
2277 def updateElementAddress(self, address_model, new_leading): |
|
2278 self.variable = update_address(self.variable, address_model, new_leading) |
|
2279 setattr(cls, "updateElementAddress", updateElementAddress) |
|
2280 |
|
2281 def Search(self, criteria, parent_infos=[]): |
|
2282 return _Search([("reference", self.getvariable())], criteria, parent_infos + ["coil", self.getlocalId()]) |
|
2283 setattr(cls, "Search", Search) |
|
2284 |
|
2285 cls = _initElementClass("step", "sfcObjects_step", "single") |
|
2286 if cls: |
|
2287 def getinfos(self): |
|
2288 infos = _getelementinfos(self) |
|
2289 infos["type"] = "step" |
|
2290 specific_values = infos["specific_values"] |
|
2291 specific_values["name"] = self.getname() |
|
2292 specific_values["initial"] = self.getinitialStep() |
|
2293 if self.connectionPointIn: |
|
2294 infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True)) |
|
2295 if self.connectionPointOut: |
|
2296 infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut)) |
|
2297 if self.connectionPointOutAction: |
|
2298 specific_values["action"] = _getconnectioninfos(self, self.connectionPointOutAction) |
|
2299 return infos |
|
2300 setattr(cls, "getinfos", getinfos) |
|
2301 |
|
2302 def Search(self, criteria, parent_infos=[]): |
|
2303 return _Search([("name", self.getname())], criteria, parent_infos + ["step", self.getlocalId()]) |
|
2304 setattr(cls, "Search", Search) |
|
2305 |
|
2306 cls = PLCOpenClasses.get("transition_condition", None) |
|
2307 if cls: |
|
2308 def compatibility(self, tree): |
|
2309 connections = [] |
|
2310 for child in tree.childNodes: |
|
2311 if child.nodeName == "connection": |
|
2312 connections.append(child) |
|
2313 if len(connections) > 0: |
|
2314 node = CreateNode("connectionPointIn") |
|
2315 relPosition = CreateNode("relPosition") |
|
2316 NodeSetAttr(relPosition, "x", "0") |
|
2317 NodeSetAttr(relPosition, "y", "0") |
|
2318 node.childNodes.append(relPosition) |
|
2319 node.childNodes.extend(connections) |
|
2320 tree.childNodes = [node] |
|
2321 setattr(cls, "compatibility", compatibility) |
|
2322 |
|
2323 cls = _initElementClass("transition", "sfcObjects_transition", "single") |
|
2324 if cls: |
|
2325 def getinfos(self): |
|
2326 infos = _getelementinfos(self) |
|
2327 infos["type"] = "transition" |
|
2328 specific_values = infos["specific_values"] |
|
2329 priority = self.getpriority() |
|
2330 if priority is None: |
|
2331 priority = 0 |
|
2332 specific_values["priority"] = priority |
|
2333 condition = self.getconditionContent() |
|
2334 specific_values["condition_type"] = condition["type"] |
|
2335 if specific_values["condition_type"] == "connection": |
|
2336 specific_values["connection"] = _getconnectioninfos(self, condition["value"], True) |
|
2337 else: |
|
2338 specific_values["condition"] = condition["value"] |
|
2339 infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True)) |
|
2340 infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut)) |
|
2341 return infos |
|
2342 setattr(cls, "getinfos", getinfos) |
|
2343 |
|
2344 def setconditionContent(self, type, value): |
|
2345 if not self.condition: |
|
2346 self.addcondition() |
|
2347 if type == "reference": |
|
2348 condition = PLCOpenClasses["condition_reference"]() |
|
2349 condition.setname(value) |
|
2350 elif type == "inline": |
|
2351 condition = PLCOpenClasses["condition_inline"]() |
|
2352 condition.setcontent({"name" : "ST", "value" : PLCOpenClasses["formattedText"]()}) |
|
2353 condition.settext(value) |
|
2354 elif type == "connection": |
|
2355 type = "connectionPointIn" |
|
2356 condition = PLCOpenClasses["connectionPointIn"]() |
|
2357 self.condition.setcontent({"name" : type, "value" : condition}) |
|
2358 setattr(cls, "setconditionContent", setconditionContent) |
|
2359 |
|
2360 def getconditionContent(self): |
|
2361 if self.condition: |
|
2362 content = self.condition.getcontent() |
|
2363 values = {"type" : content["name"]} |
|
2364 if values["type"] == "reference": |
|
2365 values["value"] = content["value"].getname() |
|
2366 elif values["type"] == "inline": |
|
2367 values["value"] = content["value"].gettext() |
|
2368 elif values["type"] == "connectionPointIn": |
|
2369 values["type"] = "connection" |
|
2370 values["value"] = content["value"] |
|
2371 return values |
|
2372 return "" |
|
2373 setattr(cls, "getconditionContent", getconditionContent) |
|
2374 |
|
2375 def updateElementName(self, old_name, new_name): |
|
2376 if self.condition: |
|
2377 content = self.condition.getcontent() |
|
2378 if content["name"] == "reference": |
|
2379 if content["value"].getname() == old_name: |
|
2380 content["value"].setname(new_name) |
|
2381 elif content["name"] == "inline": |
|
2382 content["value"].updateElementName(old_name, new_name) |
|
2383 setattr(cls, "updateElementName", updateElementName) |
|
2384 |
|
2385 def updateElementAddress(self, address_model, new_leading): |
|
2386 if self.condition: |
|
2387 content = self.condition.getcontent() |
|
2388 if content["name"] == "reference": |
|
2389 content["value"].setname(update_address(content["value"].getname(), address_model, new_leading)) |
|
2390 elif content["name"] == "inline": |
|
2391 content["value"].updateElementAddress(address_model, new_leading) |
|
2392 setattr(cls, "updateElementAddress", updateElementAddress) |
|
2393 |
|
2394 def getconnections(self): |
|
2395 if self.condition: |
|
2396 content = self.condition.getcontent() |
|
2397 if content["name"] == "connectionPointIn": |
|
2398 return content["value"].getconnections() |
|
2399 setattr(cls, "getconnections", getconnections) |
|
2400 |
|
2401 def Search(self, criteria, parent_infos=[]): |
|
2402 parent_infos = parent_infos + ["transition", self.getlocalId()] |
|
2403 search_result = [] |
|
2404 content = self.condition.getcontent() |
|
2405 if content["name"] == "reference": |
|
2406 search_result.extend(_Search([("reference", content["value"].getname())], criteria, parent_infos)) |
|
2407 elif content["name"] == "inline": |
|
2408 search_result.extend(content["value"].Search(criteria, parent_infos + ["inline"])) |
|
2409 return search_result |
|
2410 setattr(cls, "Search", Search) |
|
2411 |
|
2412 cls = _initElementClass("selectionDivergence", "sfcObjects_selectionDivergence", "single") |
|
2413 if cls: |
|
2414 setattr(cls, "getinfos", _getdivergenceinfosFunction(True, False)) |
|
2415 |
|
2416 cls = _initElementClass("selectionConvergence", "sfcObjects_selectionConvergence", "multiple") |
|
2417 if cls: |
|
2418 setattr(cls, "getinfos", _getdivergenceinfosFunction(False, False)) |
|
2419 |
|
2420 cls = _initElementClass("simultaneousDivergence", "sfcObjects_simultaneousDivergence", "single") |
|
2421 if cls: |
|
2422 setattr(cls, "getinfos", _getdivergenceinfosFunction(True, True)) |
|
2423 |
|
2424 cls = _initElementClass("simultaneousConvergence", "sfcObjects_simultaneousConvergence", "multiple") |
|
2425 if cls: |
|
2426 setattr(cls, "getinfos", _getdivergenceinfosFunction(False, True)) |
|
2427 |
|
2428 cls = _initElementClass("jumpStep", "sfcObjects_jumpStep", "single") |
|
2429 if cls: |
|
2430 def getinfos(self): |
|
2431 infos = _getelementinfos(self) |
|
2432 infos["type"] = "jump" |
|
2433 infos["specific_values"]["target"] = self.gettargetName() |
|
2434 infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True)) |
|
2435 return infos |
|
2436 setattr(cls, "getinfos", getinfos) |
|
2437 |
|
2438 def Search(self, criteria, parent_infos): |
|
2439 return _Search([("target", self.gettargetName())], criteria, parent_infos + ["jump", self.getlocalId()]) |
|
2440 setattr(cls, "Search", Search) |
|
2441 |
|
2442 cls = PLCOpenClasses.get("actionBlock_action", None) |
|
2443 if cls: |
|
2444 def compatibility(self, tree): |
|
2445 relPosition = reduce(lambda x, y: x | (y.nodeName == "relPosition"), tree.childNodes, False) |
|
2446 if not tree.hasAttribute("localId"): |
|
2447 NodeSetAttr(tree, "localId", "0") |
|
2448 if not relPosition: |
|
2449 node = CreateNode("relPosition") |
|
2450 NodeSetAttr(node, "x", "0") |
|
2451 NodeSetAttr(node, "y", "0") |
|
2452 tree.childNodes.insert(0, node) |
|
2453 setattr(cls, "compatibility", compatibility) |
|
2454 |
|
2455 def setreferenceName(self, name): |
|
2456 if self.reference: |
|
2457 self.reference.setname(name) |
|
2458 setattr(cls, "setreferenceName", setreferenceName) |
|
2459 |
|
2460 def getreferenceName(self): |
|
2461 if self.reference: |
|
2462 return self.reference.getname() |
|
2463 return None |
|
2464 setattr(cls, "getreferenceName", getreferenceName) |
|
2465 |
|
2466 def setinlineContent(self, content): |
|
2467 if self.inline: |
|
2468 self.inline.setcontent({"name" : "ST", "value" : PLCOpenClasses["formattedText"]()}) |
|
2469 self.inline.settext(content) |
|
2470 setattr(cls, "setinlineContent", setinlineContent) |
|
2471 |
|
2472 def getinlineContent(self): |
|
2473 if self.inline: |
|
2474 return self.inline.gettext() |
|
2475 return None |
|
2476 setattr(cls, "getinlineContent", getinlineContent) |
|
2477 |
|
2478 def updateElementName(self, old_name, new_name): |
|
2479 if self.reference and self.reference.getname() == old_name: |
|
2480 self.reference.setname(new_name) |
|
2481 if self.inline: |
|
2482 self.inline.updateElementName(old_name, new_name) |
|
2483 setattr(cls, "updateElementName", updateElementName) |
|
2484 |
|
2485 def updateElementAddress(self, address_model, new_leading): |
|
2486 if self.reference: |
|
2487 self.reference.setname(update_address(self.reference.getname(), address_model, new_leading)) |
|
2488 if self.inline: |
|
2489 self.inline.updateElementAddress(address_model, new_leading) |
|
2490 setattr(cls, "updateElementAddress", updateElementAddress) |
|
2491 |
|
2492 def Search(self, criteria, parent_infos=[]): |
|
2493 qualifier = self.getqualifier() |
|
2494 if qualifier is None: |
|
2495 qualifier = "N" |
|
2496 return _Search([("inline", self.getinlineContent()), |
|
2497 ("reference", self.getreferenceName()), |
|
2498 ("qualifier", qualifier), |
|
2499 ("duration", self.getduration()), |
|
2500 ("indicator", self.getindicator())], |
|
2501 criteria, parent_infos) |
|
2502 setattr(cls, "Search", Search) |
|
2503 |
|
2504 cls = _initElementClass("actionBlock", "commonObjects_actionBlock", "single") |
|
2505 if cls: |
|
2506 def compatibility(self, tree): |
|
2507 for child in tree.childNodes[:]: |
|
2508 if child.nodeName == "connectionPointOut": |
|
2509 tree.childNodes.remove(child) |
|
2510 setattr(cls, "compatibility", compatibility) |
|
2511 |
|
2512 def getinfos(self): |
|
2513 infos = _getelementinfos(self) |
|
2514 infos["type"] = "actionBlock" |
|
2515 infos["specific_values"]["actions"] = self.getactions() |
|
2516 infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True)) |
|
2517 return infos |
|
2518 setattr(cls, "getinfos", getinfos) |
|
2519 |
|
2520 def setactions(self, actions): |
|
2521 self.action = [] |
|
2522 for params in actions: |
|
2523 action = PLCOpenClasses["actionBlock_action"]() |
|
2524 action.setqualifier(params["qualifier"]) |
|
2525 if params["type"] == "reference": |
|
2526 action.addreference() |
|
2527 action.setreferenceName(params["value"]) |
|
2528 else: |
|
2529 action.addinline() |
|
2530 action.setinlineContent(params["value"]) |
|
2531 if params.has_key("duration"): |
|
2532 action.setduration(params["duration"]) |
|
2533 if params.has_key("indicator"): |
|
2534 action.setindicator(params["indicator"]) |
|
2535 self.action.append(action) |
|
2536 setattr(cls, "setactions", setactions) |
|
2537 |
|
2538 def getactions(self): |
|
2539 actions = [] |
|
2540 for action in self.action: |
|
2541 params = {} |
|
2542 params["qualifier"] = action.getqualifier() |
|
2543 if params["qualifier"] is None: |
|
2544 params["qualifier"] = "N" |
|
2545 if action.getreference(): |
|
2546 params["type"] = "reference" |
|
2547 params["value"] = action.getreferenceName() |
|
2548 elif action.getinline(): |
|
2549 params["type"] = "inline" |
|
2550 params["value"] = action.getinlineContent() |
|
2551 duration = action.getduration() |
|
2552 if duration: |
|
2553 params["duration"] = duration |
|
2554 indicator = action.getindicator() |
|
2555 if indicator: |
|
2556 params["indicator"] = indicator |
|
2557 actions.append(params) |
|
2558 return actions |
|
2559 setattr(cls, "getactions", getactions) |
|
2560 |
|
2561 def updateElementName(self, old_name, new_name): |
|
2562 for action in self.action: |
|
2563 action.updateElementName(old_name, new_name) |
|
2564 setattr(cls, "updateElementName", updateElementName) |
|
2565 |
|
2566 def updateElementAddress(self, address_model, new_leading): |
|
2567 for action in self.action: |
|
2568 action.updateElementAddress(address_model, new_leading) |
|
2569 setattr(cls, "updateElementAddress", updateElementAddress) |
|
2570 |
|
2571 def Search(self, criteria, parent_infos=[]): |
|
2572 parent_infos = parent_infos + ["action_block", self.getlocalId()] |
|
2573 search_result = [] |
|
2574 for idx, action in enumerate(self.action): |
|
2575 search_result.extend(action.Search(criteria, parent_infos + ["action", idx])) |
|
2576 return search_result |
|
2577 setattr(cls, "Search", Search) |
|
2578 |
|
2579 def _SearchInIOVariable(self, criteria, parent_infos=[]): |
|
2580 return _Search([("expression", self.getexpression())], criteria, parent_infos + ["io_variable", self.getlocalId()]) |
|
2581 |
|
2582 cls = _initElementClass("inVariable", "fbdObjects_inVariable") |
|
2583 if cls: |
|
2584 setattr(cls, "getinfos", _getvariableinfosFunction("input", False, True)) |
|
2585 |
|
2586 def updateElementName(self, old_name, new_name): |
|
2587 if self.expression == old_name: |
|
2588 self.expression = new_name |
|
2589 setattr(cls, "updateElementName", updateElementName) |
|
2590 |
|
2591 def updateElementAddress(self, address_model, new_leading): |
|
2592 self.expression = update_address(self.expression, address_model, new_leading) |
|
2593 setattr(cls, "updateElementAddress", updateElementAddress) |
|
2594 |
|
2595 setattr(cls, "Search", _SearchInIOVariable) |
|
2596 |
|
2597 cls = _initElementClass("outVariable", "fbdObjects_outVariable", "single") |
|
2598 if cls: |
|
2599 setattr(cls, "getinfos", _getvariableinfosFunction("output", True, False)) |
|
2600 |
|
2601 def updateElementName(self, old_name, new_name): |
|
2602 if self.expression == old_name: |
|
2603 self.expression = new_name |
|
2604 setattr(cls, "updateElementName", updateElementName) |
|
2605 |
|
2606 def updateElementAddress(self, address_model, new_leading): |
|
2607 self.expression = update_address(self.expression, address_model, new_leading) |
|
2608 setattr(cls, "updateElementAddress", updateElementAddress) |
|
2609 |
|
2610 setattr(cls, "Search", _SearchInIOVariable) |
|
2611 |
|
2612 cls = _initElementClass("inOutVariable", "fbdObjects_inOutVariable", "single") |
|
2613 if cls: |
|
2614 setattr(cls, "getinfos", _getvariableinfosFunction("inout", True, True)) |
|
2615 |
|
2616 def updateElementName(self, old_name, new_name): |
|
2617 if self.expression == old_name: |
|
2618 self.expression = new_name |
|
2619 setattr(cls, "updateElementName", updateElementName) |
|
2620 |
|
2621 def updateElementAddress(self, address_model, new_leading): |
|
2622 self.expression = update_address(self.expression, address_model, new_leading) |
|
2623 setattr(cls, "updateElementAddress", updateElementAddress) |
|
2624 |
|
2625 setattr(cls, "Search", _SearchInIOVariable) |
|
2626 |
|
2627 |
|
2628 def _SearchInConnector(self, criteria, parent_infos=[]): |
|
2629 return _Search([("name", self.getname())], criteria, parent_infos + ["connector", self.getlocalId()]) |
|
2630 |
|
2631 cls = _initElementClass("continuation", "commonObjects_continuation") |
|
2632 if cls: |
|
2633 setattr(cls, "getinfos", _getconnectorinfosFunction("continuation")) |
|
2634 setattr(cls, "Search", _SearchInConnector) |
|
2635 |
|
2636 def updateElementName(self, old_name, new_name): |
|
2637 if self.name == old_name: |
|
2638 self.name = new_name |
|
2639 setattr(cls, "updateElementName", updateElementName) |
|
2640 |
|
2641 cls = _initElementClass("connector", "commonObjects_connector", "single") |
|
2642 if cls: |
|
2643 setattr(cls, "getinfos", _getconnectorinfosFunction("connector")) |
|
2644 setattr(cls, "Search", _SearchInConnector) |
|
2645 |
|
2646 def updateElementName(self, old_name, new_name): |
|
2647 if self.name == old_name: |
|
2648 self.name = new_name |
|
2649 setattr(cls, "updateElementName", updateElementName) |
|
2650 |
|
2651 cls = PLCOpenClasses.get("connection", None) |
|
2652 if cls: |
|
2653 def setpoints(self, points): |
|
2654 self.position = [] |
|
2655 for point in points: |
|
2656 position = PLCOpenClasses["position"]() |
|
2657 position.setx(point.x) |
|
2658 position.sety(point.y) |
|
2659 self.position.append(position) |
|
2660 setattr(cls, "setpoints", setpoints) |
|
2661 |
|
2662 def getpoints(self): |
|
2663 points = [] |
|
2664 for position in self.position: |
|
2665 points.append((position.getx(),position.gety())) |
|
2666 return points |
|
2667 setattr(cls, "getpoints", getpoints) |
|
2668 |
|
2669 cls = PLCOpenClasses.get("connectionPointIn", None) |
|
2670 if cls: |
|
2671 def setrelPositionXY(self, x, y): |
|
2672 self.relPosition = PLCOpenClasses["position"]() |
|
2673 self.relPosition.setx(x) |
|
2674 self.relPosition.sety(y) |
|
2675 setattr(cls, "setrelPositionXY", setrelPositionXY) |
|
2676 |
|
2677 def getrelPositionXY(self): |
|
2678 if self.relPosition: |
|
2679 return self.relPosition.getx(), self.relPosition.gety() |
|
2680 else: |
|
2681 return self.relPosition |
|
2682 setattr(cls, "getrelPositionXY", getrelPositionXY) |
|
2683 |
|
2684 def addconnection(self): |
|
2685 if not self.content: |
|
2686 self.content = {"name" : "connection", "value" : [PLCOpenClasses["connection"]()]} |
|
2687 else: |
|
2688 self.content["value"].append(PLCOpenClasses["connection"]()) |
|
2689 setattr(cls, "addconnection", addconnection) |
|
2690 |
|
2691 def removeconnection(self, idx): |
|
2692 if self.content: |
|
2693 self.content["value"].pop(idx) |
|
2694 if len(self.content["value"]) == 0: |
|
2695 self.content = None |
|
2696 setattr(cls, "removeconnection", removeconnection) |
|
2697 |
|
2698 def removeconnections(self): |
|
2699 if self.content: |
|
2700 self.content = None |
|
2701 setattr(cls, "removeconnections", removeconnections) |
|
2702 |
|
2703 def getconnections(self): |
|
2704 if self.content: |
|
2705 return self.content["value"] |
|
2706 setattr(cls, "getconnections", getconnections) |
|
2707 |
|
2708 def setconnectionId(self, idx, id): |
|
2709 if self.content: |
|
2710 self.content["value"][idx].setrefLocalId(id) |
|
2711 setattr(cls, "setconnectionId", setconnectionId) |
|
2712 |
|
2713 def getconnectionId(self, idx): |
|
2714 if self.content: |
|
2715 return self.content["value"][idx].getrefLocalId() |
|
2716 return None |
|
2717 setattr(cls, "getconnectionId", getconnectionId) |
|
2718 |
|
2719 def setconnectionPoints(self, idx, points): |
|
2720 if self.content: |
|
2721 self.content["value"][idx].setpoints(points) |
|
2722 setattr(cls, "setconnectionPoints", setconnectionPoints) |
|
2723 |
|
2724 def getconnectionPoints(self, idx): |
|
2725 if self.content: |
|
2726 return self.content["value"][idx].getpoints() |
|
2727 return None |
|
2728 setattr(cls, "getconnectionPoints", getconnectionPoints) |
|
2729 |
|
2730 def setconnectionParameter(self, idx, parameter): |
|
2731 if self.content: |
|
2732 self.content["value"][idx].setformalParameter(parameter) |
|
2733 setattr(cls, "setconnectionParameter", setconnectionParameter) |
|
2734 |
|
2735 def getconnectionParameter(self, idx): |
|
2736 if self.content: |
|
2737 return self.content["value"][idx].getformalParameter() |
|
2738 return None |
|
2739 setattr(cls, "getconnectionParameter", getconnectionParameter) |
|
2740 |
|
2741 cls = PLCOpenClasses.get("connectionPointOut", None) |
|
2742 if cls: |
|
2743 def setrelPositionXY(self, x, y): |
|
2744 self.relPosition = PLCOpenClasses["position"]() |
|
2745 self.relPosition.setx(x) |
|
2746 self.relPosition.sety(y) |
|
2747 setattr(cls, "setrelPositionXY", setrelPositionXY) |
|
2748 |
|
2749 def getrelPositionXY(self): |
|
2750 if self.relPosition: |
|
2751 return self.relPosition.getx(), self.relPosition.gety() |
|
2752 return self.relPosition |
|
2753 setattr(cls, "getrelPositionXY", getrelPositionXY) |
|
2754 |
|
2755 cls = PLCOpenClasses.get("value", None) |
|
2756 if cls: |
|
2757 def setvalue(self, value): |
|
2758 value = value.strip() |
|
2759 if value.startswith("[") and value.endswith("]"): |
|
2760 arrayValue = PLCOpenClasses["value_arrayValue"]() |
|
2761 self.content = {"name" : "arrayValue", "value" : arrayValue} |
|
2762 elif value.startswith("(") and value.endswith(")"): |
|
2763 structValue = PLCOpenClasses["value_structValue"]() |
|
2764 self.content = {"name" : "structValue", "value" : structValue} |
|
2765 else: |
|
2766 simpleValue = PLCOpenClasses["value_simpleValue"]() |
|
2767 self.content = {"name" : "simpleValue", "value": simpleValue} |
|
2768 self.content["value"].setvalue(value) |
|
2769 setattr(cls, "setvalue", setvalue) |
|
2770 |
|
2771 def getvalue(self): |
|
2772 return self.content["value"].getvalue() |
|
2773 setattr(cls, "getvalue", getvalue) |
|
2774 |
|
2775 def extractValues(values): |
|
2776 items = values.split(",") |
|
2777 i = 1 |
|
2778 while i < len(items): |
|
2779 opened = items[i - 1].count("(") + items[i - 1].count("[") |
|
2780 closed = items[i - 1].count(")") + items[i - 1].count("]") |
|
2781 if opened > closed: |
|
2782 items[i - 1] = ','.join([items[i - 1], items.pop(i)]) |
|
2783 elif opened == closed: |
|
2784 i += 1 |
|
2785 else: |
|
2786 raise ValueError, _("\"%s\" is an invalid value!")%value |
|
2787 return items |
|
2788 |
|
2789 cls = PLCOpenClasses.get("value_arrayValue", None) |
|
2790 if cls: |
|
2791 arrayValue_model = re.compile("([0-9]*)\((.*)\)$") |
|
2792 |
|
2793 def setvalue(self, value): |
|
2794 self.value = [] |
|
2795 for item in extractValues(value[1:-1]): |
|
2796 item = item.strip() |
|
2797 element = PLCOpenClasses["arrayValue_value"]() |
|
2798 result = arrayValue_model.match(item) |
|
2799 if result is not None: |
|
2800 groups = result.groups() |
|
2801 element.setrepetitionValue(groups[0]) |
|
2802 element.setvalue(groups[1].strip()) |
|
2803 else: |
|
2804 element.setvalue(item) |
|
2805 self.value.append(element) |
|
2806 setattr(cls, "setvalue", setvalue) |
|
2807 |
|
2808 def getvalue(self): |
|
2809 values = [] |
|
2810 for element in self.value: |
|
2811 repetition = element.getrepetitionValue() |
|
2812 if repetition is not None and int(repetition) > 1: |
|
2813 value = element.getvalue() |
|
2814 if value is None: |
|
2815 value = "" |
|
2816 values.append("%s(%s)"%(repetition, value)) |
|
2817 else: |
|
2818 values.append(element.getvalue()) |
|
2819 return "[%s]"%", ".join(values) |
|
2820 setattr(cls, "getvalue", getvalue) |
|
2821 |
|
2822 cls = PLCOpenClasses.get("value_structValue", None) |
|
2823 if cls: |
|
2824 structValue_model = re.compile("(.*):=(.*)") |
|
2825 |
|
2826 def setvalue(self, value): |
|
2827 self.value = [] |
|
2828 for item in extractValues(value[1:-1]): |
|
2829 result = structValue_model.match(item) |
|
2830 if result is not None: |
|
2831 groups = result.groups() |
|
2832 element = PLCOpenClasses["structValue_value"]() |
|
2833 element.setmember(groups[0].strip()) |
|
2834 element.setvalue(groups[1].strip()) |
|
2835 self.value.append(element) |
|
2836 setattr(cls, "setvalue", setvalue) |
|
2837 |
|
2838 def getvalue(self): |
|
2839 values = [] |
|
2840 for element in self.value: |
|
2841 values.append("%s := %s"%(element.getmember(), element.getvalue())) |
|
2842 return "(%s)"%", ".join(values) |
|
2843 setattr(cls, "getvalue", getvalue) |