branch | 1.1 Korean release |
changeset 1384 | 02fe382c4511 |
parent 1373 | 4278d5c1e414 |
child 1378 | cbc0f64a25eb |
1280:72a826dfcfbb | 1384:02fe382c4511 |
---|---|
22 #License along with this library; if not, write to the Free Software |
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 |
23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
24 |
24 |
25 from xml.dom import minidom |
25 from xml.dom import minidom |
26 from types import StringType, UnicodeType, TupleType |
26 from types import StringType, UnicodeType, TupleType |
27 import cPickle |
27 from lxml import etree |
28 from copy import deepcopy |
|
28 import os,sys,re |
29 import os,sys,re |
29 import datetime |
30 import datetime |
30 from time import localtime |
31 from time import localtime |
31 |
32 from collections import OrderedDict, namedtuple |
32 from plcopen import plcopen |
33 |
33 from plcopen.structures import * |
34 from plcopen import * |
34 from graphics.GraphicCommons import * |
35 from graphics.GraphicCommons import * |
35 from PLCGenerator import * |
36 from PLCGenerator import * |
36 |
37 |
37 duration_model = re.compile("(?:([0-9]{1,2})h)?(?:([0-9]{1,2})m(?!s))?(?:([0-9]{1,2})s)?(?:([0-9]{1,3}(?:\.[0-9]*)?)ms)?") |
38 duration_model = re.compile("(?:([0-9]{1,2})h)?(?:([0-9]{1,2})m(?!s))?(?:([0-9]{1,2})s)?(?:([0-9]{1,3}(?:\.[0-9]*)?)ms)?") |
38 |
39 |
64 ITEM_VAR_INPUT, |
65 ITEM_VAR_INPUT, |
65 ITEM_VAR_OUTPUT, |
66 ITEM_VAR_OUTPUT, |
66 ITEM_VAR_INOUT |
67 ITEM_VAR_INOUT |
67 ] = range(17, 24) |
68 ] = range(17, 24) |
68 |
69 |
69 VAR_CLASS_INFOS = {"Local" : (plcopen.interface_localVars, ITEM_VAR_LOCAL), |
70 VAR_CLASS_INFOS = { |
70 "Global" : (plcopen.interface_globalVars, ITEM_VAR_GLOBAL), |
71 "Local": ("localVars", ITEM_VAR_LOCAL), |
71 "External" : (plcopen.interface_externalVars, ITEM_VAR_EXTERNAL), |
72 "Global": ("globalVars", ITEM_VAR_GLOBAL), |
72 "Temp" : (plcopen.interface_tempVars, ITEM_VAR_TEMP), |
73 "External": ("externalVars", ITEM_VAR_EXTERNAL), |
73 "Input" : (plcopen.interface_inputVars, ITEM_VAR_INPUT), |
74 "Temp": ("tempVars", ITEM_VAR_TEMP), |
74 "Output" : (plcopen.interface_outputVars, ITEM_VAR_OUTPUT), |
75 "Input": ("inputVars", ITEM_VAR_INPUT), |
75 "InOut" : (plcopen.interface_inOutVars, ITEM_VAR_INOUT) |
76 "Output": ("outputVars", ITEM_VAR_OUTPUT), |
76 } |
77 "InOut": ("inOutVars", ITEM_VAR_INOUT)} |
77 |
78 |
78 POU_TYPES = {"program": ITEM_PROGRAM, |
79 POU_TYPES = {"program": ITEM_PROGRAM, |
79 "functionBlock": ITEM_FUNCTIONBLOCK, |
80 "functionBlock": ITEM_FUNCTIONBLOCK, |
80 "function": ITEM_FUNCTION, |
81 "function": ITEM_FUNCTION, |
81 } |
82 } |
96 _("Configurations"), _("Resources"), _("Properties")] |
97 _("Configurations"), _("Resources"), _("Properties")] |
97 UNEDITABLE_NAMES = GetUneditableNames() |
98 UNEDITABLE_NAMES = GetUneditableNames() |
98 [USER_DEFINED_POUS, FUNCTIONS, FUNCTION_BLOCKS, PROGRAMS, |
99 [USER_DEFINED_POUS, FUNCTIONS, FUNCTION_BLOCKS, PROGRAMS, |
99 DATA_TYPES, TRANSITIONS, ACTIONS, CONFIGURATIONS, |
100 DATA_TYPES, TRANSITIONS, ACTIONS, CONFIGURATIONS, |
100 RESOURCES, PROPERTIES] = UNEDITABLE_NAMES |
101 RESOURCES, PROPERTIES] = UNEDITABLE_NAMES |
102 |
|
103 #------------------------------------------------------------------------------- |
|
104 # Helper object for loading library in xslt stylesheets |
|
105 #------------------------------------------------------------------------------- |
|
106 |
|
107 class LibraryResolver(etree.Resolver): |
|
108 |
|
109 def __init__(self, controller, debug=False): |
|
110 self.Controller = controller |
|
111 self.Debug = debug |
|
112 |
|
113 def resolve(self, url, pubid, context): |
|
114 lib_name = os.path.basename(url) |
|
115 if lib_name in ["project", "stdlib", "extensions"]: |
|
116 lib_el = etree.Element(lib_name) |
|
117 if lib_name == "project": |
|
118 lib_el.append(deepcopy(self.Controller.GetProject(self.Debug))) |
|
119 elif lib_name == "stdlib": |
|
120 for lib in [StdBlockLibrary, AddnlBlockLibrary]: |
|
121 lib_el.append(deepcopy(lib)) |
|
122 else: |
|
123 for ctn in self.Controller.ConfNodeTypes: |
|
124 lib_el.append(deepcopy(ctn["types"])) |
|
125 return self.resolve_string(etree.tostring(lib_el), context) |
|
126 |
|
127 #------------------------------------------------------------------------------- |
|
128 # Helpers functions for translating list of arguments |
|
129 # from xslt to valid arguments |
|
130 #------------------------------------------------------------------------------- |
|
131 |
|
132 _BoolValue = lambda x: x in ["true", "0"] |
|
133 |
|
134 def _translate_args(translations, args): |
|
135 return [translate(arg[0]) if len(arg) > 0 else None |
|
136 for translate, arg in |
|
137 zip(translations, args)] |
|
138 |
|
139 #------------------------------------------------------------------------------- |
|
140 # Helpers object for generating pou var list |
|
141 #------------------------------------------------------------------------------- |
|
142 |
|
143 class _VariableInfos(object): |
|
144 __slots__ = ["Name", "Class", "Option", "Location", "InitialValue", |
|
145 "Edit", "Documentation", "Type", "Tree", "Number"] |
|
146 def __init__(self, *args): |
|
147 for attr, value in zip(self.__slots__, args): |
|
148 setattr(self, attr, value if value is not None else "") |
|
149 def copy(self): |
|
150 return _VariableInfos(*[getattr(self, attr) for attr in self.__slots__]) |
|
151 |
|
152 class VariablesInfosFactory: |
|
153 |
|
154 def __init__(self, variables): |
|
155 self.Variables = variables |
|
156 self.TreeStack = [] |
|
157 self.Type = None |
|
158 self.Dimensions = None |
|
159 |
|
160 def SetType(self, context, *args): |
|
161 self.Type = args[0][0] |
|
162 |
|
163 def GetType(self): |
|
164 if len(self.Dimensions) > 0: |
|
165 return ("array", self.Type, self.Dimensions) |
|
166 return self.Type |
|
167 |
|
168 def GetTree(self): |
|
169 return (self.TreeStack.pop(-1), self.Dimensions) |
|
170 |
|
171 def AddDimension(self, context, *args): |
|
172 self.Dimensions.append(tuple( |
|
173 _translate_args([str] * 2, args))) |
|
174 |
|
175 def AddTree(self, context, *args): |
|
176 self.TreeStack.append([]) |
|
177 self.Dimensions = [] |
|
178 |
|
179 def AddVarToTree(self, context, *args): |
|
180 var = (args[0][0], self.Type, self.GetTree()) |
|
181 self.TreeStack[-1].append(var) |
|
182 |
|
183 def AddVariable(self, context, *args): |
|
184 self.Variables.append(_VariableInfos(*(_translate_args( |
|
185 [str] * 5 + [_BoolValue] + [str], args) + |
|
186 [self.GetType(), self.GetTree()]))) |
|
187 |
|
188 #------------------------------------------------------------------------------- |
|
189 # Helpers object for generating pou variable instance list |
|
190 #------------------------------------------------------------------------------- |
|
191 |
|
192 def class_extraction(value): |
|
193 class_type = { |
|
194 "configuration": ITEM_CONFIGURATION, |
|
195 "resource": ITEM_RESOURCE, |
|
196 "action": ITEM_ACTION, |
|
197 "transition": ITEM_TRANSITION, |
|
198 "program": ITEM_PROGRAM}.get(value) |
|
199 if class_type is not None: |
|
200 return class_type |
|
201 |
|
202 pou_type = POU_TYPES.get(value) |
|
203 if pou_type is not None: |
|
204 return pou_type |
|
205 |
|
206 var_type = VAR_CLASS_INFOS.get(value) |
|
207 if var_type is not None: |
|
208 return var_type[1] |
|
209 |
|
210 return None |
|
211 |
|
212 class _VariablesTreeItemInfos(object): |
|
213 __slots__ = ["name", "var_class", "type", "edit", "debug", "variables"] |
|
214 def __init__(self, *args): |
|
215 for attr, value in zip(self.__slots__, args): |
|
216 setattr(self, attr, value if value is not None else "") |
|
217 def copy(self): |
|
218 return _VariableTreeItem(*[getattr(self, attr) for attr in self.__slots__]) |
|
219 |
|
220 class VariablesTreeInfosFactory: |
|
221 |
|
222 def __init__(self): |
|
223 self.Root = None |
|
224 |
|
225 def GetRoot(self): |
|
226 return self.Root |
|
227 |
|
228 def SetRoot(self, context, *args): |
|
229 self.Root = _VariablesTreeItemInfos( |
|
230 *([''] + _translate_args( |
|
231 [class_extraction, str] + [_BoolValue] * 2, |
|
232 args) + [[]])) |
|
233 |
|
234 def AddVariable(self, context, *args): |
|
235 if self.Root is not None: |
|
236 self.Root.variables.append(_VariablesTreeItemInfos( |
|
237 *(_translate_args( |
|
238 [str, class_extraction, str] + [_BoolValue] * 2, |
|
239 args) + [[]]))) |
|
240 |
|
241 #------------------------------------------------------------------------------- |
|
242 # Helpers object for generating instances path list |
|
243 #------------------------------------------------------------------------------- |
|
244 |
|
245 class InstancesPathFactory: |
|
246 |
|
247 def __init__(self, instances): |
|
248 self.Instances = instances |
|
249 |
|
250 def AddInstance(self, context, *args): |
|
251 self.Instances.append(args[0][0]) |
|
252 |
|
253 #------------------------------------------------------------------------------- |
|
254 # Helpers object for generating instance tagname |
|
255 #------------------------------------------------------------------------------- |
|
256 |
|
257 class InstanceTagName: |
|
258 |
|
259 def __init__(self, controller): |
|
260 self.Controller = controller |
|
261 self.TagName = None |
|
262 |
|
263 def GetTagName(self): |
|
264 return self.TagName |
|
265 |
|
266 def ConfigTagName(self, context, *args): |
|
267 self.TagName = self.Controller.ComputeConfigurationName(args[0][0]) |
|
268 |
|
269 def ResourceTagName(self, context, *args): |
|
270 self.TagName = self.Controller.ComputeConfigurationResourceName(args[0][0], args[1][0]) |
|
271 |
|
272 def PouTagName(self, context, *args): |
|
273 self.TagName = self.Controller.ComputePouName(args[0][0]) |
|
274 |
|
275 def ActionTagName(self, context, *args): |
|
276 self.TagName = self.Controller.ComputePouActionName(args[0][0], args[0][1]) |
|
277 |
|
278 def TransitionTagName(self, context, *args): |
|
279 self.TagName = self.Controller.ComputePouTransitionName(args[0][0], args[0][1]) |
|
280 |
|
281 #------------------------------------------------------------------------------- |
|
282 # Helpers object for generating pou block instances list |
|
283 #------------------------------------------------------------------------------- |
|
284 |
|
285 _Point = namedtuple("Point", ["x", "y"]) |
|
286 |
|
287 _BlockInstanceInfos = namedtuple("BlockInstanceInfos", |
|
288 ["type", "id", "x", "y", "width", "height", "specific_values", "inputs", "outputs"]) |
|
289 |
|
290 _BlockSpecificValues = ( |
|
291 namedtuple("BlockSpecificValues", |
|
292 ["name", "execution_order"]), |
|
293 [str, int]) |
|
294 _VariableSpecificValues = ( |
|
295 namedtuple("VariableSpecificValues", |
|
296 ["name", "value_type", "execution_order"]), |
|
297 [str, str, int]) |
|
298 _ConnectionSpecificValues = ( |
|
299 namedtuple("ConnectionSpecificValues", ["name"]), |
|
300 [str]) |
|
301 |
|
302 _PowerRailSpecificValues = ( |
|
303 namedtuple("PowerRailSpecificValues", ["connectors"]), |
|
304 [int]) |
|
305 |
|
306 _LDElementSpecificValues = ( |
|
307 namedtuple("LDElementSpecificValues", |
|
308 ["name", "negated", "edge", "storage", "execution_order"]), |
|
309 [str, _BoolValue, str, str, int]) |
|
310 |
|
311 _DivergenceSpecificValues = ( |
|
312 namedtuple("DivergenceSpecificValues", ["connectors"]), |
|
313 [int]) |
|
314 |
|
315 _SpecificValuesTuples = { |
|
316 "comment": ( |
|
317 namedtuple("CommentSpecificValues", ["content"]), |
|
318 [str]), |
|
319 "input": _VariableSpecificValues, |
|
320 "output": _VariableSpecificValues, |
|
321 "inout": _VariableSpecificValues, |
|
322 "connector": _ConnectionSpecificValues, |
|
323 "continuation": _ConnectionSpecificValues, |
|
324 "leftPowerRail": _PowerRailSpecificValues, |
|
325 "rightPowerRail": _PowerRailSpecificValues, |
|
326 "contact": _LDElementSpecificValues, |
|
327 "coil": _LDElementSpecificValues, |
|
328 "step": ( |
|
329 namedtuple("StepSpecificValues", ["name", "initial", "action"]), |
|
330 [str, _BoolValue, lambda x: x]), |
|
331 "transition": ( |
|
332 namedtuple("TransitionSpecificValues", |
|
333 ["priority", "condition_type", "condition", "connection"]), |
|
334 [int, str, str, lambda x: x]), |
|
335 "selectionDivergence": _DivergenceSpecificValues, |
|
336 "selectionConvergence": _DivergenceSpecificValues, |
|
337 "simultaneousDivergence": _DivergenceSpecificValues, |
|
338 "simultaneousConvergence": _DivergenceSpecificValues, |
|
339 "jump": ( |
|
340 namedtuple("JumpSpecificValues", ["target"]), |
|
341 [str]), |
|
342 "actionBlock": ( |
|
343 namedtuple("ActionBlockSpecificValues", ["actions"]), |
|
344 [lambda x: x]), |
|
345 } |
|
346 |
|
347 _InstanceConnectionInfos = namedtuple("InstanceConnectionInfos", |
|
348 ["name", "negated", "edge", "position", "links"]) |
|
349 |
|
350 _ConnectionLinkInfos = namedtuple("ConnectionLinkInfos", |
|
351 ["refLocalId", "formalParameter", "points"]) |
|
352 |
|
353 class _ActionInfos(object): |
|
354 __slots__ = ["qualifier", "type", "value", "duration", "indicator"] |
|
355 def __init__(self, *args): |
|
356 for attr, value in zip(self.__slots__, args): |
|
357 setattr(self, attr, value if value is not None else "") |
|
358 def copy(self): |
|
359 return _ActionInfos(*[getattr(self, attr) for attr in self.__slots__]) |
|
360 |
|
361 class BlockInstanceFactory: |
|
362 |
|
363 def __init__(self, block_instances): |
|
364 self.BlockInstances = block_instances |
|
365 self.CurrentInstance = None |
|
366 self.SpecificValues = None |
|
367 self.CurrentConnection = None |
|
368 self.CurrentLink = None |
|
369 |
|
370 def SetSpecificValues(self, context, *args): |
|
371 self.SpecificValues = list(args) |
|
372 self.CurrentInstance = None |
|
373 self.CurrentConnection = None |
|
374 self.CurrentLink = None |
|
375 |
|
376 def AddBlockInstance(self, context, *args): |
|
377 specific_values_tuple, specific_values_translation = \ |
|
378 _SpecificValuesTuples.get(args[0][0], _BlockSpecificValues) |
|
379 |
|
380 if (args[0][0] == "step" and len(self.SpecificValues) < 3 or |
|
381 args[0][0] == "transition" and len(self.SpecificValues) < 4): |
|
382 self.SpecificValues.append([None]) |
|
383 elif args[0][0] == "actionBlock" and len(self.SpecificValues) < 1: |
|
384 self.SpecificValues.append([[]]) |
|
385 specific_values = specific_values_tuple(*_translate_args( |
|
386 specific_values_translation, self.SpecificValues)) |
|
387 self.SpecificValues = None |
|
388 |
|
389 self.CurrentInstance = _BlockInstanceInfos( |
|
390 *(_translate_args([str, int] + [float] * 4, args) + |
|
391 [specific_values, [], []])) |
|
392 |
|
393 self.BlockInstances[self.CurrentInstance.id] = self.CurrentInstance |
|
394 |
|
395 def AddInstanceConnection(self, context, *args): |
|
396 connection_args = _translate_args( |
|
397 [str, str, _BoolValue, str, float, float], args) |
|
398 |
|
399 self.CurrentConnection = _InstanceConnectionInfos( |
|
400 *(connection_args[1:4] + [ |
|
401 _Point(*connection_args[4:6]), []])) |
|
402 |
|
403 if self.CurrentInstance is not None: |
|
404 if connection_args[0] == "input": |
|
405 self.CurrentInstance.inputs.append(self.CurrentConnection) |
|
406 else: |
|
407 self.CurrentInstance.outputs.append(self.CurrentConnection) |
|
408 else: |
|
409 self.SpecificValues.append([self.CurrentConnection]) |
|
410 |
|
411 def AddConnectionLink(self, context, *args): |
|
412 self.CurrentLink = _ConnectionLinkInfos( |
|
413 *(_translate_args([int, str], args) + [[]])) |
|
414 self.CurrentConnection.links.append(self.CurrentLink) |
|
415 |
|
416 def AddLinkPoint(self, context, *args): |
|
417 self.CurrentLink.points.append(_Point( |
|
418 *_translate_args([float] * 2, args))) |
|
419 |
|
420 def AddAction(self, context, *args): |
|
421 if len(self.SpecificValues) == 0: |
|
422 self.SpecificValues.append([[]]) |
|
423 translated_args = _translate_args([str] * 5, args) |
|
424 self.SpecificValues[0][0].append(_ActionInfos(*translated_args)) |
|
425 |
|
426 pou_block_instances_xslt = etree.parse( |
|
427 os.path.join(ScriptDirectory, "plcopen", "pou_block_instances.xslt")) |
|
101 |
428 |
102 #------------------------------------------------------------------------------- |
429 #------------------------------------------------------------------------------- |
103 # Undo Buffer for PLCOpenEditor |
430 # Undo Buffer for PLCOpenEditor |
104 #------------------------------------------------------------------------------- |
431 #------------------------------------------------------------------------------- |
105 |
432 |
208 self.ProgramChunks = [] |
535 self.ProgramChunks = [] |
209 self.ProgramOffset = 0 |
536 self.ProgramOffset = 0 |
210 self.NextCompiledProject = None |
537 self.NextCompiledProject = None |
211 self.CurrentCompiledProject = None |
538 self.CurrentCompiledProject = None |
212 self.ConfNodeTypes = [] |
539 self.ConfNodeTypes = [] |
540 self.TotalTypesDict = StdBlckDct.copy() |
|
541 self.TotalTypes = StdBlckLst[:] |
|
213 self.ProgramFilePath = "" |
542 self.ProgramFilePath = "" |
214 |
543 |
215 def GetQualifierTypes(self): |
544 def GetQualifierTypes(self): |
216 return plcopen.QualifierList |
545 return QualifierList |
217 |
546 |
218 def GetProject(self, debug = False): |
547 def GetProject(self, debug = False): |
219 if debug and self.CurrentCompiledProject is not None: |
548 if debug and self.CurrentCompiledProject is not None: |
220 return self.CurrentCompiledProject |
549 return self.CurrentCompiledProject |
221 else: |
550 else: |
230 return self.Project is not None |
559 return self.Project is not None |
231 |
560 |
232 # Create a new project by replacing the current one |
561 # Create a new project by replacing the current one |
233 def CreateNewProject(self, properties): |
562 def CreateNewProject(self, properties): |
234 # Create the project |
563 # Create the project |
235 self.Project = plcopen.project() |
564 self.Project = PLCOpenParser.CreateRoot() |
236 properties["creationDateTime"] = datetime.datetime(*localtime()[:6]) |
565 properties["creationDateTime"] = datetime.datetime(*localtime()[:6]) |
237 self.Project.setfileHeader(properties) |
566 self.Project.setfileHeader(properties) |
238 self.Project.setcontentHeader(properties) |
567 self.Project.setcontentHeader(properties) |
239 self.SetFilePath("") |
568 self.SetFilePath("") |
569 |
|
240 # Initialize the project buffer |
570 # Initialize the project buffer |
241 self.CreateProjectBuffer(False) |
571 self.CreateProjectBuffer(False) |
242 self.ProgramChunks = [] |
572 self.ProgramChunks = [] |
243 self.ProgramOffset = 0 |
573 self.ProgramOffset = 0 |
244 self.NextCompiledProject = self.Copy(self.Project) |
574 self.NextCompiledProject = self.Copy(self.Project) |
271 variables = [] |
601 variables = [] |
272 project = self.GetProject(debug) |
602 project = self.GetProject(debug) |
273 if project is not None: |
603 if project is not None: |
274 for pou in project.getpous(): |
604 for pou in project.getpous(): |
275 if pou_name is None or pou_name == pou.getname(): |
605 if pou_name is None or pou_name == pou.getname(): |
276 variables.extend([var["Name"] for var in self.GetPouInterfaceVars(pou, debug)]) |
606 variables.extend([var.Name for var in self.GetPouInterfaceVars(pou, debug=debug)]) |
277 for transition in pou.gettransitionList(): |
607 for transition in pou.gettransitionList(): |
278 variables.append(transition.getname()) |
608 variables.append(transition.getname()) |
279 for action in pou.getactionList(): |
609 for action in pou.getactionList(): |
280 variables.append(action.getname()) |
610 variables.append(action.getname()) |
281 return variables |
611 return variables |
384 infos["values"] = [datatypes, pou_types["function"], pou_types["functionBlock"], |
714 infos["values"] = [datatypes, pou_types["function"], pou_types["functionBlock"], |
385 pou_types["program"], configurations] |
715 pou_types["program"], configurations] |
386 return infos |
716 return infos |
387 return None |
717 return None |
388 |
718 |
389 def GetPouVariableInfos(self, project, variable, var_class, debug=False): |
|
390 vartype_content = variable.gettype().getcontent() |
|
391 if vartype_content["name"] == "derived": |
|
392 var_type = vartype_content["value"].getname() |
|
393 pou_type = None |
|
394 pou = project.getpou(var_type) |
|
395 if pou is not None: |
|
396 pou_type = pou.getpouType() |
|
397 edit = debug = pou_type is not None |
|
398 if pou_type is None: |
|
399 block_infos = self.GetBlockType(var_type, debug = debug) |
|
400 if block_infos is not None: |
|
401 pou_type = block_infos["type"] |
|
402 if pou_type is not None: |
|
403 var_class = None |
|
404 if pou_type == "program": |
|
405 var_class = ITEM_PROGRAM |
|
406 elif pou_type != "function": |
|
407 var_class = ITEM_FUNCTIONBLOCK |
|
408 if var_class is not None: |
|
409 return {"name": variable.getname(), |
|
410 "type": var_type, |
|
411 "class": var_class, |
|
412 "edit": edit, |
|
413 "debug": debug} |
|
414 elif var_type in self.GetDataTypes(debug = debug): |
|
415 return {"name": variable.getname(), |
|
416 "type": var_type, |
|
417 "class": var_class, |
|
418 "edit": False, |
|
419 "debug": False} |
|
420 elif vartype_content["name"] in ["string", "wstring"]: |
|
421 return {"name": variable.getname(), |
|
422 "type": vartype_content["name"].upper(), |
|
423 "class": var_class, |
|
424 "edit": False, |
|
425 "debug": True} |
|
426 else: |
|
427 return {"name": variable.getname(), |
|
428 "type": vartype_content["name"], |
|
429 "class": var_class, |
|
430 "edit": False, |
|
431 "debug": True} |
|
432 return None |
|
433 |
|
434 def GetPouVariables(self, tagname, debug = False): |
719 def GetPouVariables(self, tagname, debug = False): |
435 vars = [] |
|
436 pou_type = None |
720 pou_type = None |
437 project = self.GetProject(debug) |
721 project = self.GetProject(debug) |
438 if project is not None: |
722 if project is not None: |
723 factory = VariablesTreeInfosFactory() |
|
724 |
|
725 parser = etree.XMLParser() |
|
726 parser.resolvers.add(LibraryResolver(self, debug)) |
|
727 |
|
728 pou_variable_xslt_tree = etree.XSLT( |
|
729 etree.parse( |
|
730 os.path.join(ScriptDirectory, "plcopen", "pou_variables.xslt"), |
|
731 parser), |
|
732 extensions = {("pou_vars_ns", name): getattr(factory, name) |
|
733 for name in ["SetRoot", "AddVariable"]}) |
|
734 |
|
735 obj = None |
|
439 words = tagname.split("::") |
736 words = tagname.split("::") |
440 if words[0] == "P": |
737 if words[0] == "P": |
441 pou = project.getpou(words[1]) |
738 obj = self.GetPou(words[1], debug) |
442 if pou is not None: |
739 elif words[0] != "D": |
443 pou_type = pou.getpouType() |
740 obj = self.GetEditedElement(tagname, debug) |
444 if (pou_type in ["program", "functionBlock"] and |
741 if obj is not None: |
445 pou.interface is not None): |
742 pou_variable_xslt_tree(obj) |
446 # Extract variables from every varLists |
743 return factory.GetRoot() |
447 for varlist_type, varlist in pou.getvars(): |
744 |
448 var_infos = VAR_CLASS_INFOS.get(varlist_type, None) |
|
449 if var_infos is not None: |
|
450 var_class = var_infos[1] |
|
451 else: |
|
452 var_class = ITEM_VAR_LOCAL |
|
453 for variable in varlist.getvariable(): |
|
454 var_infos = self.GetPouVariableInfos(project, variable, var_class, debug) |
|
455 if var_infos is not None: |
|
456 vars.append(var_infos) |
|
457 if pou.getbodyType() == "SFC": |
|
458 for transition in pou.gettransitionList(): |
|
459 vars.append({ |
|
460 "name": transition.getname(), |
|
461 "type": None, |
|
462 "class": ITEM_TRANSITION, |
|
463 "edit": True, |
|
464 "debug": True}) |
|
465 for action in pou.getactionList(): |
|
466 vars.append({ |
|
467 "name": action.getname(), |
|
468 "type": None, |
|
469 "class": ITEM_ACTION, |
|
470 "edit": True, |
|
471 "debug": True}) |
|
472 return {"class": POU_TYPES[pou_type], |
|
473 "type": words[1], |
|
474 "variables": vars, |
|
475 "edit": True, |
|
476 "debug": True} |
|
477 else: |
|
478 block_infos = self.GetBlockType(words[1], debug = debug) |
|
479 if (block_infos is not None and |
|
480 block_infos["type"] in ["program", "functionBlock"]): |
|
481 for varname, vartype, varmodifier in block_infos["inputs"]: |
|
482 vars.append({"name" : varname, |
|
483 "type" : vartype, |
|
484 "class" : ITEM_VAR_INPUT, |
|
485 "edit": False, |
|
486 "debug": True}) |
|
487 for varname, vartype, varmodifier in block_infos["outputs"]: |
|
488 vars.append({"name" : varname, |
|
489 "type" : vartype, |
|
490 "class" : ITEM_VAR_OUTPUT, |
|
491 "edit": False, |
|
492 "debug": True}) |
|
493 return {"class": POU_TYPES[block_infos["type"]], |
|
494 "type": None, |
|
495 "variables": vars, |
|
496 "edit": False, |
|
497 "debug": False} |
|
498 elif words[0] in ['A', 'T']: |
|
499 pou_vars = self.GetPouVariables(self.ComputePouName(words[1]), debug) |
|
500 if pou_vars is not None: |
|
501 if words[0] == 'A': |
|
502 element_type = ITEM_ACTION |
|
503 elif words[0] == 'T': |
|
504 element_type = ITEM_TRANSITION |
|
505 return {"class": element_type, |
|
506 "type": None, |
|
507 "variables": [var for var in pou_vars["variables"] |
|
508 if var["class"] not in [ITEM_ACTION, ITEM_TRANSITION]], |
|
509 "edit": True, |
|
510 "debug": True} |
|
511 elif words[0] in ['C', 'R']: |
|
512 if words[0] == 'C': |
|
513 element_type = ITEM_CONFIGURATION |
|
514 element = project.getconfiguration(words[1]) |
|
515 if element is not None: |
|
516 for resource in element.getresource(): |
|
517 vars.append({"name": resource.getname(), |
|
518 "type": None, |
|
519 "class": ITEM_RESOURCE, |
|
520 "edit": True, |
|
521 "debug": False}) |
|
522 elif words[0] == 'R': |
|
523 element_type = ITEM_RESOURCE |
|
524 element = project.getconfigurationResource(words[1], words[2]) |
|
525 if element is not None: |
|
526 for task in element.gettask(): |
|
527 for pou in task.getpouInstance(): |
|
528 vars.append({"name": pou.getname(), |
|
529 "type": pou.gettypeName(), |
|
530 "class": ITEM_PROGRAM, |
|
531 "edit": True, |
|
532 "debug": True}) |
|
533 for pou in element.getpouInstance(): |
|
534 vars.append({"name": pou.getname(), |
|
535 "type": pou.gettypeName(), |
|
536 "class": ITEM_PROGRAM, |
|
537 "edit": True, |
|
538 "debug": True}) |
|
539 if element is not None: |
|
540 for varlist in element.getglobalVars(): |
|
541 for variable in varlist.getvariable(): |
|
542 var_infos = self.GetPouVariableInfos(project, variable, ITEM_VAR_GLOBAL, debug) |
|
543 if var_infos is not None: |
|
544 vars.append(var_infos) |
|
545 return {"class": element_type, |
|
546 "type": None, |
|
547 "variables": vars, |
|
548 "edit": True, |
|
549 "debug": False} |
|
550 return None |
745 return None |
551 |
746 |
552 def RecursiveSearchPouInstances(self, project, pou_type, parent_path, varlists, debug = False): |
747 def GetInstanceList(self, root, name, debug = False): |
553 instances = [] |
748 instances = [] |
554 for varlist in varlists: |
749 project = self.GetProject(debug) |
555 for variable in varlist.getvariable(): |
750 if project is not None: |
556 vartype_content = variable.gettype().getcontent() |
751 factory = InstancesPathFactory(instances) |
557 if vartype_content["name"] == "derived": |
752 |
558 var_path = "%s.%s" % (parent_path, variable.getname()) |
753 parser = etree.XMLParser() |
559 var_type = vartype_content["value"].getname() |
754 parser.resolvers.add(LibraryResolver(self, debug)) |
560 if var_type == pou_type: |
755 |
561 instances.append(var_path) |
756 instances_path_xslt_tree = etree.XSLT( |
562 else: |
757 etree.parse( |
563 pou = project.getpou(var_type) |
758 os.path.join(ScriptDirectory, "plcopen", "instances_path.xslt"), |
564 if pou is not None and project.ElementIsUsedBy(pou_type, var_type): |
759 parser), |
565 instances.extend( |
760 extensions = { |
566 self.RecursiveSearchPouInstances( |
761 ("instances_ns", "AddInstance"): factory.AddInstance}) |
567 project, pou_type, var_path, |
762 |
568 [varlist for type, varlist in pou.getvars()], |
763 instances_path_xslt_tree(root, |
569 debug)) |
764 instance_type=etree.XSLT.strparam(name)) |
765 |
|
570 return instances |
766 return instances |
571 |
767 |
572 def SearchPouInstances(self, tagname, debug = False): |
768 def SearchPouInstances(self, tagname, debug = False): |
573 project = self.GetProject(debug) |
769 project = self.GetProject(debug) |
574 if project is not None: |
770 if project is not None: |
575 words = tagname.split("::") |
771 words = tagname.split("::") |
576 if words[0] == "P": |
772 if words[0] == "P": |
577 instances = [] |
773 return self.GetInstanceList(project, words[1]) |
578 for config in project.getconfigurations(): |
|
579 config_name = config.getname() |
|
580 instances.extend( |
|
581 self.RecursiveSearchPouInstances( |
|
582 project, words[1], config_name, |
|
583 config.getglobalVars(), debug)) |
|
584 for resource in config.getresource(): |
|
585 res_path = "%s.%s" % (config_name, resource.getname()) |
|
586 instances.extend( |
|
587 self.RecursiveSearchPouInstances( |
|
588 project, words[1], res_path, |
|
589 resource.getglobalVars(), debug)) |
|
590 pou_instances = resource.getpouInstance()[:] |
|
591 for task in resource.gettask(): |
|
592 pou_instances.extend(task.getpouInstance()) |
|
593 for pou_instance in pou_instances: |
|
594 pou_path = "%s.%s" % (res_path, pou_instance.getname()) |
|
595 pou_type = pou_instance.gettypeName() |
|
596 if pou_type == words[1]: |
|
597 instances.append(pou_path) |
|
598 pou = project.getpou(pou_type) |
|
599 if pou is not None and project.ElementIsUsedBy(words[1], pou_type): |
|
600 instances.extend( |
|
601 self.RecursiveSearchPouInstances( |
|
602 project, words[1], pou_path, |
|
603 [varlist for type, varlist in pou.getvars()], |
|
604 debug)) |
|
605 return instances |
|
606 elif words[0] == 'C': |
774 elif words[0] == 'C': |
607 return [words[1]] |
775 return [words[1]] |
608 elif words[0] == 'R': |
776 elif words[0] == 'R': |
609 return ["%s.%s" % (words[1], words[2])] |
777 return ["%s.%s" % (words[1], words[2])] |
610 elif words[0] in ['T', 'A']: |
778 elif words[0] in ['T', 'A']: |
611 return ["%s.%s" % (instance, words[2]) |
779 return ["%s.%s" % (instance, words[2]) |
612 for instance in self.SearchPouInstances( |
780 for instance in self.SearchPouInstances( |
613 self.ComputePouName(words[1]), debug)] |
781 self.ComputePouName(words[1]), debug)] |
614 return [] |
782 return [] |
615 |
783 |
616 def RecursiveGetPouInstanceTagName(self, project, pou_type, parts, debug = False): |
|
617 pou = project.getpou(pou_type) |
|
618 if pou is not None: |
|
619 if len(parts) == 0: |
|
620 return self.ComputePouName(pou_type) |
|
621 |
|
622 for varlist_type, varlist in pou.getvars(): |
|
623 for variable in varlist.getvariable(): |
|
624 if variable.getname() == parts[0]: |
|
625 vartype_content = variable.gettype().getcontent() |
|
626 if vartype_content["name"] == "derived": |
|
627 return self.RecursiveGetPouInstanceTagName( |
|
628 project, |
|
629 vartype_content["value"].getname(), |
|
630 parts[1:], debug) |
|
631 |
|
632 if pou.getbodyType() == "SFC" and len(parts) == 1: |
|
633 for action in pou.getactionList(): |
|
634 if action.getname() == parts[0]: |
|
635 return self.ComputePouActionName(pou_type, parts[0]) |
|
636 for transition in pou.gettransitionList(): |
|
637 if transition.getname() == parts[0]: |
|
638 return self.ComputePouTransitionName(pou_type, parts[0]) |
|
639 else: |
|
640 block_infos = self.GetBlockType(pou_type, debug=debug) |
|
641 if (block_infos is not None and |
|
642 block_infos["type"] in ["program", "functionBlock"]): |
|
643 |
|
644 if len(parts) == 0: |
|
645 return self.ComputePouName(pou_type) |
|
646 |
|
647 for varname, vartype, varmodifier in block_infos["inputs"] + block_infos["outputs"]: |
|
648 if varname == parts[0]: |
|
649 return self.RecursiveGetPouInstanceTagName(project, vartype, parts[1:], debug) |
|
650 return None |
|
651 |
|
652 def GetGlobalInstanceTagName(self, project, element, parts, debug = False): |
|
653 for varlist in element.getglobalVars(): |
|
654 for variable in varlist.getvariable(): |
|
655 if variable.getname() == parts[0]: |
|
656 vartype_content = variable.gettype().getcontent() |
|
657 if vartype_content["name"] == "derived": |
|
658 if len(parts) == 1: |
|
659 return self.ComputePouName( |
|
660 vartype_content["value"].getname()) |
|
661 else: |
|
662 return self.RecursiveGetPouInstanceTagName( |
|
663 project, |
|
664 vartype_content["value"].getname(), |
|
665 parts[1:], debug) |
|
666 return None |
|
667 |
|
668 def GetPouInstanceTagName(self, instance_path, debug = False): |
784 def GetPouInstanceTagName(self, instance_path, debug = False): |
669 project = self.GetProject(debug) |
785 project = self.GetProject(debug) |
670 parts = instance_path.split(".") |
786 factory = InstanceTagName(self) |
671 if len(parts) == 1: |
787 |
672 return self.ComputeConfigurationName(parts[0]) |
788 parser = etree.XMLParser() |
673 elif len(parts) == 2: |
789 parser.resolvers.add(LibraryResolver(self, debug)) |
674 for config in project.getconfigurations(): |
790 |
675 if config.getname() == parts[0]: |
791 instance_tagname_xslt_tree = etree.XSLT( |
676 result = self.GetGlobalInstanceTagName(project, |
792 etree.parse( |
677 config, |
793 os.path.join(ScriptDirectory, "plcopen", "instance_tagname.xslt"), |
678 parts[1:], |
794 parser), |
679 debug) |
795 extensions = {("instance_tagname_ns", name): getattr(factory, name) |
680 if result is not None: |
796 for name in ["ConfigTagName", "ResourceTagName", |
681 return result |
797 "PouTagName", "ActionTagName", |
682 return self.ComputeConfigurationResourceName(parts[0], parts[1]) |
798 "TransitionTagName"]}) |
683 else: |
799 |
684 for config in project.getconfigurations(): |
800 instance_tagname_xslt_tree(project, |
685 if config.getname() == parts[0]: |
801 instance_path=etree.XSLT.strparam(instance_path)) |
686 for resource in config.getresource(): |
802 |
687 if resource.getname() == parts[1]: |
803 return factory.GetTagName() |
688 pou_instances = resource.getpouInstance()[:] |
|
689 for task in resource.gettask(): |
|
690 pou_instances.extend(task.getpouInstance()) |
|
691 for pou_instance in pou_instances: |
|
692 if pou_instance.getname() == parts[2]: |
|
693 if len(parts) == 3: |
|
694 return self.ComputePouName( |
|
695 pou_instance.gettypeName()) |
|
696 else: |
|
697 return self.RecursiveGetPouInstanceTagName( |
|
698 project, |
|
699 pou_instance.gettypeName(), |
|
700 parts[3:], debug) |
|
701 return self.GetGlobalInstanceTagName(project, |
|
702 resource, |
|
703 parts[2:], |
|
704 debug) |
|
705 return self.GetGlobalInstanceTagName(project, |
|
706 config, |
|
707 parts[1:], |
|
708 debug) |
|
709 return None |
|
710 |
804 |
711 def GetInstanceInfos(self, instance_path, debug = False): |
805 def GetInstanceInfos(self, instance_path, debug = False): |
712 tagname = self.GetPouInstanceTagName(instance_path) |
806 tagname = self.GetPouInstanceTagName(instance_path) |
713 if tagname is not None: |
807 if tagname is not None: |
714 infos = self.GetPouVariables(tagname, debug) |
808 infos = self.GetPouVariables(tagname, debug) |
715 infos["type"] = tagname |
809 infos.type = tagname |
716 return infos |
810 return infos |
717 else: |
811 else: |
718 pou_path, var_name = instance_path.rsplit(".", 1) |
812 pou_path, var_name = instance_path.rsplit(".", 1) |
719 tagname = self.GetPouInstanceTagName(pou_path) |
813 tagname = self.GetPouInstanceTagName(pou_path) |
720 if tagname is not None: |
814 if tagname is not None: |
721 pou_infos = self.GetPouVariables(tagname, debug) |
815 pou_infos = self.GetPouVariables(tagname, debug) |
722 for var_infos in pou_infos["variables"]: |
816 for var_infos in pou_infos.variables: |
723 if var_infos["name"] == var_name: |
817 if var_infos.name == var_name: |
724 return var_infos |
818 return var_infos |
725 return None |
819 return None |
726 |
820 |
727 # Return if data type given by name is used by another data type or pou |
821 # Return if data type given by name is used by another data type or pou |
728 def DataTypeIsUsed(self, name, debug = False): |
822 def DataTypeIsUsed(self, name, debug = False): |
729 project = self.GetProject(debug) |
823 project = self.GetProject(debug) |
730 if project is not None: |
824 if project is not None: |
731 return project.ElementIsUsed(name) or project.DataTypeIsDerived(name) |
825 return len(self.GetInstanceList(project, name, debug)) > 0 |
732 return False |
826 return False |
733 |
827 |
734 # Return if pou given by name is used by another pou |
828 # Return if pou given by name is used by another pou |
735 def PouIsUsed(self, name, debug = False): |
829 def PouIsUsed(self, name, debug = False): |
736 project = self.GetProject(debug) |
830 project = self.GetProject(debug) |
737 if project is not None: |
831 if project is not None: |
738 return project.ElementIsUsed(name) |
832 return len(self.GetInstanceList(project, name, debug)) > 0 |
739 return False |
833 return False |
740 |
834 |
741 # Return if pou given by name is directly or undirectly used by the reference pou |
835 # Return if pou given by name is directly or undirectly used by the reference pou |
742 def PouIsUsedBy(self, name, reference, debug = False): |
836 def PouIsUsedBy(self, name, reference, debug = False): |
743 project = self.GetProject(debug) |
837 pou_infos = self.GetPou(reference, debug) |
744 if project is not None: |
838 if pou_infos is not None: |
745 return project.ElementIsUsedBy(name, reference) |
839 return len(self.GetInstanceList(pou_infos, name, debug)) > 0 |
746 return False |
840 return False |
747 |
841 |
748 def GenerateProgram(self, filepath=None): |
842 def GenerateProgram(self, filepath=None): |
749 errors = [] |
843 errors = [] |
750 warnings = [] |
844 warnings = [] |
828 def ProjectChangePouType(self, name, pou_type): |
922 def ProjectChangePouType(self, name, pou_type): |
829 if self.Project is not None: |
923 if self.Project is not None: |
830 pou = self.Project.getpou(name) |
924 pou = self.Project.getpou(name) |
831 if pou is not None: |
925 if pou is not None: |
832 pou.setpouType(pou_type) |
926 pou.setpouType(pou_type) |
833 self.Project.RefreshCustomBlockTypes() |
|
834 self.BufferProject() |
927 self.BufferProject() |
835 |
928 |
836 def GetPouXml(self, pou_name): |
929 def GetPouXml(self, pou_name): |
837 if self.Project is not None: |
930 if self.Project is not None: |
838 pou = self.Project.getpou(pou_name) |
931 pou = self.Project.getpou(pou_name) |
839 if pou is not None: |
932 if pou is not None: |
840 return pou.generateXMLText('pou', 0) |
933 return pou.tostring() |
841 return None |
934 return None |
842 |
935 |
843 def PastePou(self, pou_type, pou_xml): |
936 def PastePou(self, pou_type, pou_xml): |
844 ''' |
937 ''' |
845 Adds the POU defined by 'pou_xml' to the current project with type 'pou_type' |
938 Adds the POU defined by 'pou_xml' to the current project with type 'pou_type' |
846 ''' |
939 ''' |
847 try: |
940 try: |
848 tree = minidom.parseString(pou_xml.encode("utf-8")) |
941 new_pou, error = LoadPou(pou_xml) |
849 root = tree.childNodes[0] |
|
850 except: |
942 except: |
943 error = "" |
|
944 if error is not None: |
|
851 return _("Couldn't paste non-POU object.") |
945 return _("Couldn't paste non-POU object.") |
852 |
946 |
853 if root.nodeName == "pou": |
947 name = new_pou.getname() |
854 new_pou = plcopen.pous_pou() |
948 |
855 new_pou.loadXMLTree(root) |
949 idx = 0 |
856 |
950 new_name = name |
857 name = new_pou.getname() |
951 while self.Project.getpou(new_name): |
952 # a POU with that name already exists. |
|
953 # make a new name and test if a POU with that name exists. |
|
954 # append an incrementing numeric suffix to the POU name. |
|
955 idx += 1 |
|
956 new_name = "%s%d" % (name, idx) |
|
858 |
957 |
859 idx = 0 |
958 # we've found a name that does not already exist, use it |
860 new_name = name |
959 new_pou.setname(new_name) |
861 while self.Project.getpou(new_name): |
960 |
862 # a POU with that name already exists. |
961 if pou_type is not None: |
863 # make a new name and test if a POU with that name exists. |
962 orig_type = new_pou.getpouType() |
864 # append an incrementing numeric suffix to the POU name. |
963 |
865 idx += 1 |
964 # prevent violations of POU content restrictions: |
866 new_name = "%s%d" % (name, idx) |
965 # function blocks cannot be pasted as functions, |
867 |
966 # programs cannot be pasted as functions or function blocks |
868 # we've found a name that does not already exist, use it |
967 if orig_type == 'functionBlock' and pou_type == 'function' or \ |
869 new_pou.setname(new_name) |
968 orig_type == 'program' and pou_type in ['function', 'functionBlock']: |
969 return _('''%s "%s" can't be pasted as a %s.''') % (orig_type, name, pou_type) |
|
870 |
970 |
871 if pou_type is not None: |
971 new_pou.setpouType(pou_type) |
872 orig_type = new_pou.getpouType() |
972 |
873 |
973 self.Project.insertpou(-1, new_pou) |
874 # prevent violations of POU content restrictions: |
974 self.BufferProject() |
875 # function blocks cannot be pasted as functions, |
975 |
876 # programs cannot be pasted as functions or function blocks |
976 return self.ComputePouName(new_name), |
877 if orig_type == 'functionBlock' and pou_type == 'function' or \ |
|
878 orig_type == 'program' and pou_type in ['function', 'functionBlock']: |
|
879 return _('''%s "%s" can't be pasted as a %s.''') % (orig_type, name, pou_type) |
|
880 |
|
881 new_pou.setpouType(pou_type) |
|
882 |
|
883 self.Project.insertpou(-1, new_pou) |
|
884 self.BufferProject() |
|
885 |
|
886 return self.ComputePouName(new_name), |
|
887 else: |
|
888 return _("Couldn't paste non-POU object.") |
|
889 |
977 |
890 # Remove a Pou from project |
978 # Remove a Pou from project |
891 def ProjectRemovePou(self, pou_name): |
979 def ProjectRemovePou(self, pou_name): |
892 if self.Project is not None: |
980 if self.Project is not None: |
893 self.Project.removepou(pou_name) |
981 self.Project.removepou(pou_name) |
978 # Found the pou corresponding to old name and change its name to new name |
1066 # Found the pou corresponding to old name and change its name to new name |
979 datatype = self.Project.getdataType(old_name) |
1067 datatype = self.Project.getdataType(old_name) |
980 if datatype is not None: |
1068 if datatype is not None: |
981 datatype.setname(new_name) |
1069 datatype.setname(new_name) |
982 self.Project.updateElementName(old_name, new_name) |
1070 self.Project.updateElementName(old_name, new_name) |
983 self.Project.RefreshElementUsingTree() |
|
984 self.Project.RefreshDataTypeHierarchy() |
|
985 self.BufferProject() |
1071 self.BufferProject() |
986 |
1072 |
987 # Change the name of a pou |
1073 # Change the name of a pou |
988 def ChangePouName(self, old_name, new_name): |
1074 def ChangePouName(self, old_name, new_name): |
989 if self.Project is not None: |
1075 if self.Project is not None: |
990 # Found the pou corresponding to old name and change its name to new name |
1076 # Found the pou corresponding to old name and change its name to new name |
991 pou = self.Project.getpou(old_name) |
1077 pou = self.Project.getpou(old_name) |
992 if pou is not None: |
1078 if pou is not None: |
993 pou.setname(new_name) |
1079 pou.setname(new_name) |
994 self.Project.updateElementName(old_name, new_name) |
1080 self.Project.updateElementName(old_name, new_name) |
995 self.Project.RefreshElementUsingTree() |
|
996 self.Project.RefreshCustomBlockTypes() |
|
997 self.BufferProject() |
1081 self.BufferProject() |
998 |
1082 |
999 # Change the name of a pou transition |
1083 # Change the name of a pou transition |
1000 def ChangePouTransitionName(self, pou_name, old_name, new_name): |
1084 def ChangePouTransitionName(self, pou_name, old_name, new_name): |
1001 if self.Project is not None: |
1085 if self.Project is not None: |
1028 if pou is not None: |
1112 if pou is not None: |
1029 for type, varlist in pou.getvars(): |
1113 for type, varlist in pou.getvars(): |
1030 for var in varlist.getvariable(): |
1114 for var in varlist.getvariable(): |
1031 if var.getname() == old_name: |
1115 if var.getname() == old_name: |
1032 var.setname(new_name) |
1116 var.setname(new_name) |
1033 self.Project.RefreshCustomBlockTypes() |
|
1034 self.BufferProject() |
1117 self.BufferProject() |
1035 |
1118 |
1036 # Change the name of a configuration |
1119 # Change the name of a configuration |
1037 def ChangeConfigurationName(self, old_name, new_name): |
1120 def ChangeConfigurationName(self, old_name, new_name): |
1038 if self.Project is not None: |
1121 if self.Project is not None: |
1067 if project is not None: |
1150 if project is not None: |
1068 # Found the pou correponding to name and return its type |
1151 # Found the pou correponding to name and return its type |
1069 pou = project.getpou(name) |
1152 pou = project.getpou(name) |
1070 if pou is not None: |
1153 if pou is not None: |
1071 pou.setdescription(description) |
1154 pou.setdescription(description) |
1072 project.RefreshCustomBlockTypes() |
|
1073 self.BufferProject() |
1155 self.BufferProject() |
1074 |
1156 |
1075 # Return the type of the pou given by its name |
1157 # Return the type of the pou given by its name |
1076 def GetPouType(self, name, debug = False): |
1158 def GetPouType(self, name, debug = False): |
1077 project = self.GetProject(debug) |
1159 project = self.GetProject(debug) |
1155 def ExtractVarLists(self, vars): |
1237 def ExtractVarLists(self, vars): |
1156 varlist_list = [] |
1238 varlist_list = [] |
1157 current_varlist = None |
1239 current_varlist = None |
1158 current_type = None |
1240 current_type = None |
1159 for var in vars: |
1241 for var in vars: |
1160 next_type = (var["Class"], |
1242 next_type = (var.Class, |
1161 var["Option"], |
1243 var.Option, |
1162 var["Location"] in ["", None] or |
1244 var.Location in ["", None] or |
1163 # When declaring globals, located |
1245 # When declaring globals, located |
1164 # and not located variables are |
1246 # and not located variables are |
1165 # in the same declaration block |
1247 # in the same declaration block |
1166 var["Class"] == "Global") |
1248 var.Class == "Global") |
1167 if current_type != next_type: |
1249 if current_type != next_type: |
1168 current_type = next_type |
1250 current_type = next_type |
1169 infos = VAR_CLASS_INFOS.get(var["Class"], None) |
1251 infos = VAR_CLASS_INFOS.get(var.Class, None) |
1170 if infos is not None: |
1252 if infos is not None: |
1171 current_varlist = infos[0]() |
1253 current_varlist = PLCOpenParser.CreateElement(infos[0], "interface") |
1172 else: |
1254 else: |
1173 current_varlist = plcopen.varList() |
1255 current_varlist = PLCOpenParser.CreateElement("varList") |
1174 varlist_list.append((var["Class"], current_varlist)) |
1256 varlist_list.append((var.Class, current_varlist)) |
1175 if var["Option"] == "Constant": |
1257 if var.Option == "Constant": |
1176 current_varlist.setconstant(True) |
1258 current_varlist.setconstant(True) |
1177 elif var["Option"] == "Retain": |
1259 elif var.Option == "Retain": |
1178 current_varlist.setretain(True) |
1260 current_varlist.setretain(True) |
1179 elif var["Option"] == "Non-Retain": |
1261 elif var.Option == "Non-Retain": |
1180 current_varlist.setnonretain(True) |
1262 current_varlist.setnonretain(True) |
1181 # Create variable and change its properties |
1263 # Create variable and change its properties |
1182 tempvar = plcopen.varListPlain_variable() |
1264 tempvar = PLCOpenParser.CreateElement("variable", "varListPlain") |
1183 tempvar.setname(var["Name"]) |
1265 tempvar.setname(var.Name) |
1184 |
1266 |
1185 var_type = plcopen.dataType() |
1267 var_type = PLCOpenParser.CreateElement("type", "variable") |
1186 if isinstance(var["Type"], TupleType): |
1268 if isinstance(var.Type, TupleType): |
1187 if var["Type"][0] == "array": |
1269 if var.Type[0] == "array": |
1188 array_type, base_type_name, dimensions = var["Type"] |
1270 array_type, base_type_name, dimensions = var.Type |
1189 array = plcopen.derivedTypes_array() |
1271 array = PLCOpenParser.CreateElement("array", "dataType") |
1272 baseType = PLCOpenParser.CreateElement("baseType", "array") |
|
1273 array.setbaseType(baseType) |
|
1190 for i, dimension in enumerate(dimensions): |
1274 for i, dimension in enumerate(dimensions): |
1191 dimension_range = plcopen.rangeSigned() |
1275 dimension_range = PLCOpenParser.CreateElement("dimension", "array") |
1192 dimension_range.setlower(dimension[0]) |
|
1193 dimension_range.setupper(dimension[1]) |
|
1194 if i == 0: |
1276 if i == 0: |
1195 array.setdimension([dimension_range]) |
1277 array.setdimension([dimension_range]) |
1196 else: |
1278 else: |
1197 array.appenddimension(dimension_range) |
1279 array.appenddimension(dimension_range) |
1280 dimension_range.setlower(dimension[0]) |
|
1281 dimension_range.setupper(dimension[1]) |
|
1198 if base_type_name in self.GetBaseTypes(): |
1282 if base_type_name in self.GetBaseTypes(): |
1199 if base_type_name == "STRING": |
1283 baseType.setcontent(PLCOpenParser.CreateElement( |
1200 array.baseType.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()}) |
1284 base_type_name.lower() |
1201 elif base_type_name == "WSTRING": |
1285 if base_type_name in ["STRING", "WSTRING"] |
1202 array.baseType.setcontent({"name" : "wstring", "value" : plcopen.wstring()}) |
1286 else base_type_name, "dataType")) |
1203 else: |
|
1204 array.baseType.setcontent({"name" : base_type_name, "value" : None}) |
|
1205 else: |
1287 else: |
1206 derived_datatype = plcopen.derivedTypes_derived() |
1288 derived_datatype = PLCOpenParser.CreateElement("derived", "dataType") |
1207 derived_datatype.setname(base_type_name) |
1289 derived_datatype.setname(base_type_name) |
1208 array.baseType.setcontent({"name" : "derived", "value" : derived_datatype}) |
1290 baseType.setcontent(derived_datatype) |
1209 var_type.setcontent({"name" : "array", "value" : array}) |
1291 var_type.setcontent(array) |
1210 elif var["Type"] in self.GetBaseTypes(): |
1292 elif var.Type in self.GetBaseTypes(): |
1211 if var["Type"] == "STRING": |
1293 var_type.setcontent(PLCOpenParser.CreateElement( |
1212 var_type.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()}) |
1294 var.Type.lower() |
1213 elif var["Type"] == "WSTRING": |
1295 if var.Type in ["STRING", "WSTRING"] |
1214 var_type.setcontent({"name" : "wstring", "value" : plcopen.elementaryTypes_wstring()}) |
1296 else var.Type, "dataType")) |
1215 else: |
|
1216 var_type.setcontent({"name" : var["Type"], "value" : None}) |
|
1217 else: |
1297 else: |
1218 derived_type = plcopen.derivedTypes_derived() |
1298 derived_type = PLCOpenParser.CreateElement("derived", "dataType") |
1219 derived_type.setname(var["Type"]) |
1299 derived_type.setname(var.Type) |
1220 var_type.setcontent({"name" : "derived", "value" : derived_type}) |
1300 var_type.setcontent(derived_type) |
1221 tempvar.settype(var_type) |
1301 tempvar.settype(var_type) |
1222 |
1302 |
1223 if var["Initial Value"] != "": |
1303 if var.InitialValue != "": |
1224 value = plcopen.value() |
1304 value = PLCOpenParser.CreateElement("initialValue", "variable") |
1225 value.setvalue(var["Initial Value"]) |
1305 value.setvalue(var.InitialValue) |
1226 tempvar.setinitialValue(value) |
1306 tempvar.setinitialValue(value) |
1227 if var["Location"] != "": |
1307 if var.Location != "": |
1228 tempvar.setaddress(var["Location"]) |
1308 tempvar.setaddress(var.Location) |
1229 else: |
1309 else: |
1230 tempvar.setaddress(None) |
1310 tempvar.setaddress(None) |
1231 if var['Documentation'] != "": |
1311 if var.Documentation != "": |
1232 ft = plcopen.formattedText() |
1312 ft = PLCOpenParser.CreateElement("documentation", "variable") |
1233 ft.settext(var['Documentation']) |
1313 ft.setanyText(var.Documentation) |
1234 tempvar.setdocumentation(ft) |
1314 tempvar.setdocumentation(ft) |
1235 |
1315 |
1236 # Add variable to varList |
1316 # Add variable to varList |
1237 current_varlist.appendvariable(tempvar) |
1317 current_varlist.appendvariable(tempvar) |
1238 return varlist_list |
1318 return varlist_list |
1239 |
1319 |
1240 def GetVariableDictionary(self, varlist, var): |
1320 def GetVariableDictionary(self, object_with_vars, tree=False, debug=False): |
1241 ''' |
1321 variables = [] |
1242 convert a PLC variable to the dictionary representation |
1322 factory = VariablesInfosFactory(variables) |
1243 returned by Get*Vars) |
1323 |
1244 ''' |
1324 parser = etree.XMLParser() |
1245 |
1325 parser.resolvers.add(LibraryResolver(self, debug)) |
1246 tempvar = {"Name": var.getname()} |
1326 |
1247 |
1327 variables_infos_xslt_tree = etree.XSLT( |
1248 vartype_content = var.gettype().getcontent() |
1328 etree.parse( |
1249 if vartype_content["name"] == "derived": |
1329 os.path.join(ScriptDirectory, "plcopen", "variables_infos.xslt"), |
1250 tempvar["Type"] = vartype_content["value"].getname() |
1330 parser), |
1251 elif vartype_content["name"] == "array": |
1331 extensions = {("var_infos_ns", name): getattr(factory, name) |
1252 dimensions = [] |
1332 for name in ["SetType", "AddDimension", "AddTree", |
1253 for dimension in vartype_content["value"].getdimension(): |
1333 "AddVarToTree", "AddVariable"]}) |
1254 dimensions.append((dimension.getlower(), dimension.getupper())) |
1334 variables_infos_xslt_tree(object_with_vars, |
1255 base_type = vartype_content["value"].baseType.getcontent() |
1335 tree=etree.XSLT.strparam(str(tree))) |
1256 if base_type["value"] is None or base_type["name"] in ["string", "wstring"]: |
1336 |
1257 base_type_name = base_type["name"].upper() |
1337 return variables |
1258 else: |
1338 |
1259 base_type_name = base_type["value"].getname() |
|
1260 tempvar["Type"] = ("array", base_type_name, dimensions) |
|
1261 elif vartype_content["name"] in ["string", "wstring"]: |
|
1262 tempvar["Type"] = vartype_content["name"].upper() |
|
1263 else: |
|
1264 tempvar["Type"] = vartype_content["name"] |
|
1265 |
|
1266 tempvar["Edit"] = True |
|
1267 |
|
1268 initial = var.getinitialValue() |
|
1269 if initial: |
|
1270 tempvar["Initial Value"] = initial.getvalue() |
|
1271 else: |
|
1272 tempvar["Initial Value"] = "" |
|
1273 |
|
1274 address = var.getaddress() |
|
1275 if address: |
|
1276 tempvar["Location"] = address |
|
1277 else: |
|
1278 tempvar["Location"] = "" |
|
1279 |
|
1280 if varlist.getconstant(): |
|
1281 tempvar["Option"] = "Constant" |
|
1282 elif varlist.getretain(): |
|
1283 tempvar["Option"] = "Retain" |
|
1284 elif varlist.getnonretain(): |
|
1285 tempvar["Option"] = "Non-Retain" |
|
1286 else: |
|
1287 tempvar["Option"] = "" |
|
1288 |
|
1289 doc = var.getdocumentation() |
|
1290 if doc: |
|
1291 tempvar["Documentation"] = doc.gettext() |
|
1292 else: |
|
1293 tempvar["Documentation"] = "" |
|
1294 |
|
1295 return tempvar |
|
1296 |
|
1297 # Add a global var to configuration to configuration |
1339 # Add a global var to configuration to configuration |
1298 def AddConfigurationGlobalVar(self, config_name, type, var_name, |
1340 def AddConfigurationGlobalVar(self, config_name, var_type, var_name, |
1299 location="", description=""): |
1341 location="", description=""): |
1300 if self.Project is not None: |
1342 if self.Project is not None: |
1301 # Found the configuration corresponding to name |
1343 # Found the configuration corresponding to name |
1302 configuration = self.Project.getconfiguration(config_name) |
1344 configuration = self.Project.getconfiguration(config_name) |
1303 if configuration is not None: |
1345 if configuration is not None: |
1304 # Set configuration global vars |
1346 # Set configuration global vars |
1305 configuration.addglobalVar(type, var_name, location, description) |
1347 configuration.addglobalVar( |
1348 self.GetVarTypeObject(var_type), |
|
1349 var_name, location, description) |
|
1306 |
1350 |
1307 # Replace the configuration globalvars by those given |
1351 # Replace the configuration globalvars by those given |
1308 def SetConfigurationGlobalVars(self, name, vars): |
1352 def SetConfigurationGlobalVars(self, name, vars): |
1309 if self.Project is not None: |
1353 if self.Project is not None: |
1310 # Found the configuration corresponding to name |
1354 # Found the configuration corresponding to name |
1311 configuration = self.Project.getconfiguration(name) |
1355 configuration = self.Project.getconfiguration(name) |
1312 if configuration is not None: |
1356 if configuration is not None: |
1313 # Set configuration global vars |
1357 # Set configuration global vars |
1314 configuration.setglobalVars([]) |
1358 configuration.setglobalVars([ |
1315 for vartype, varlist in self.ExtractVarLists(vars): |
1359 varlist for vartype, varlist |
1316 configuration.globalVars.append(varlist) |
1360 in self.ExtractVarLists(vars)]) |
1317 |
1361 |
1318 # Return the configuration globalvars |
1362 # Return the configuration globalvars |
1319 def GetConfigurationGlobalVars(self, name, debug = False): |
1363 def GetConfigurationGlobalVars(self, name, debug = False): |
1320 vars = [] |
|
1321 project = self.GetProject(debug) |
1364 project = self.GetProject(debug) |
1322 if project is not None: |
1365 if project is not None: |
1323 # Found the configuration corresponding to name |
1366 # Found the configuration corresponding to name |
1324 configuration = project.getconfiguration(name) |
1367 configuration = project.getconfiguration(name) |
1325 if configuration is not None: |
1368 if configuration is not None: |
1326 # Extract variables from every varLists |
1369 # Extract variables defined in configuration |
1327 for varlist in configuration.getglobalVars(): |
1370 return self.GetVariableDictionary(configuration, debug) |
1328 for var in varlist.getvariable(): |
1371 |
1329 tempvar = self.GetVariableDictionary(varlist, var) |
1372 return [] |
1330 tempvar["Class"] = "Global" |
|
1331 vars.append(tempvar) |
|
1332 return vars |
|
1333 |
1373 |
1334 # Return configuration variable names |
1374 # Return configuration variable names |
1335 def GetConfigurationVariableNames(self, config_name = None, debug = False): |
1375 def GetConfigurationVariableNames(self, config_name = None, debug = False): |
1336 variables = [] |
1376 variables = [] |
1337 project = self.GetProject(debug) |
1377 project = self.GetProject(debug) |
1350 if self.Project is not None: |
1390 if self.Project is not None: |
1351 # Found the resource corresponding to name |
1391 # Found the resource corresponding to name |
1352 resource = self.Project.getconfigurationResource(config_name, name) |
1392 resource = self.Project.getconfigurationResource(config_name, name) |
1353 # Set resource global vars |
1393 # Set resource global vars |
1354 if resource is not None: |
1394 if resource is not None: |
1355 resource.setglobalVars([]) |
1395 resource.setglobalVars([ |
1356 for vartype, varlist in self.ExtractVarLists(vars): |
1396 varlist for vartype, varlist |
1357 resource.globalVars.append(varlist) |
1397 in self.ExtractVarLists(vars)]) |
1358 |
1398 |
1359 # Return the resource globalvars |
1399 # Return the resource globalvars |
1360 def GetConfigurationResourceGlobalVars(self, config_name, name, debug = False): |
1400 def GetConfigurationResourceGlobalVars(self, config_name, name, debug = False): |
1361 vars = [] |
|
1362 project = self.GetProject(debug) |
1401 project = self.GetProject(debug) |
1363 if project is not None: |
1402 if project is not None: |
1364 # Found the resource corresponding to name |
1403 # Found the resource corresponding to name |
1365 resource = project.getconfigurationResource(config_name, name) |
1404 resource = project.getconfigurationResource(config_name, name) |
1366 if resource: |
1405 if resource is not None: |
1367 # Extract variables from every varLists |
1406 # Extract variables defined in configuration |
1368 for varlist in resource.getglobalVars(): |
1407 return self.GetVariableDictionary(resource, debug) |
1369 for var in varlist.getvariable(): |
1408 |
1370 tempvar = self.GetVariableDictionary(varlist, var) |
1409 return [] |
1371 tempvar["Class"] = "Global" |
|
1372 vars.append(tempvar) |
|
1373 return vars |
|
1374 |
1410 |
1375 # Return resource variable names |
1411 # Return resource variable names |
1376 def GetConfigurationResourceVariableNames(self, |
1412 def GetConfigurationResourceVariableNames(self, |
1377 config_name = None, resource_name = None, debug = False): |
1413 config_name = None, resource_name = None, debug = False): |
1378 variables = [] |
1414 variables = [] |
1386 [var.getname() for var in reduce( |
1422 [var.getname() for var in reduce( |
1387 lambda x, y: x + y, [varlist.getvariable() |
1423 lambda x, y: x + y, [varlist.getvariable() |
1388 for varlist in resource.globalVars], |
1424 for varlist in resource.globalVars], |
1389 [])]) |
1425 [])]) |
1390 return variables |
1426 return variables |
1391 |
|
1392 # Recursively generate element name tree for a structured variable |
|
1393 def GenerateVarTree(self, typename, debug = False): |
|
1394 project = self.GetProject(debug) |
|
1395 if project is not None: |
|
1396 blocktype = self.GetBlockType(typename, debug = debug) |
|
1397 if blocktype is not None: |
|
1398 tree = [] |
|
1399 en = False |
|
1400 eno = False |
|
1401 for var_name, var_type, var_modifier in blocktype["inputs"] + blocktype["outputs"]: |
|
1402 en |= var_name.upper() == "EN" |
|
1403 eno |= var_name.upper() == "ENO" |
|
1404 tree.append((var_name, var_type, self.GenerateVarTree(var_type, debug))) |
|
1405 if not eno: |
|
1406 tree.insert(0, ("ENO", "BOOL", ([], []))) |
|
1407 if not en: |
|
1408 tree.insert(0, ("EN", "BOOL", ([], []))) |
|
1409 return tree, [] |
|
1410 datatype = project.getdataType(typename) |
|
1411 if datatype is None: |
|
1412 datatype = self.GetConfNodeDataType(typename) |
|
1413 if datatype is not None: |
|
1414 tree = [] |
|
1415 basetype_content = datatype.baseType.getcontent() |
|
1416 if basetype_content["name"] == "derived": |
|
1417 return self.GenerateVarTree(basetype_content["value"].getname()) |
|
1418 elif basetype_content["name"] == "array": |
|
1419 dimensions = [] |
|
1420 base_type = basetype_content["value"].baseType.getcontent() |
|
1421 if base_type["name"] == "derived": |
|
1422 tree = self.GenerateVarTree(base_type["value"].getname()) |
|
1423 if len(tree[1]) == 0: |
|
1424 tree = tree[0] |
|
1425 for dimension in basetype_content["value"].getdimension(): |
|
1426 dimensions.append((dimension.getlower(), dimension.getupper())) |
|
1427 return tree, dimensions |
|
1428 elif basetype_content["name"] == "struct": |
|
1429 for element in basetype_content["value"].getvariable(): |
|
1430 element_type = element.type.getcontent() |
|
1431 if element_type["name"] == "derived": |
|
1432 tree.append((element.getname(), element_type["value"].getname(), self.GenerateVarTree(element_type["value"].getname()))) |
|
1433 else: |
|
1434 tree.append((element.getname(), element_type["name"], ([], []))) |
|
1435 return tree, [] |
|
1436 return [], [] |
|
1437 |
1427 |
1438 # Return the interface for the given pou |
1428 # Return the interface for the given pou |
1439 def GetPouInterfaceVars(self, pou, debug = False): |
1429 def GetPouInterfaceVars(self, pou, tree=False, debug = False): |
1440 vars = [] |
1430 interface = pou.interface |
1441 # Verify that the pou has an interface |
1431 # Verify that the pou has an interface |
1442 if pou.interface is not None: |
1432 if interface is not None: |
1443 # Extract variables from every varLists |
1433 # Extract variables defined in interface |
1444 for type, varlist in pou.getvars(): |
1434 return self.GetVariableDictionary(interface, tree, debug) |
1445 for var in varlist.getvariable(): |
1435 return [] |
1446 tempvar = self.GetVariableDictionary(varlist, var) |
|
1447 |
|
1448 tempvar["Class"] = type |
|
1449 tempvar["Tree"] = ([], []) |
|
1450 |
|
1451 vartype_content = var.gettype().getcontent() |
|
1452 if vartype_content["name"] == "derived": |
|
1453 tempvar["Edit"] = not pou.hasblock(tempvar["Name"]) |
|
1454 tempvar["Tree"] = self.GenerateVarTree(tempvar["Type"], debug) |
|
1455 |
|
1456 vars.append(tempvar) |
|
1457 return vars |
|
1458 |
1436 |
1459 # Replace the Pou interface by the one given |
1437 # Replace the Pou interface by the one given |
1460 def SetPouInterfaceVars(self, name, vars): |
1438 def SetPouInterfaceVars(self, name, vars): |
1461 if self.Project is not None: |
1439 if self.Project is not None: |
1462 # Found the pou corresponding to name and add interface if there isn't one yet |
1440 # Found the pou corresponding to name and add interface if there isn't one yet |
1463 pou = self.Project.getpou(name) |
1441 pou = self.Project.getpou(name) |
1464 if pou is not None: |
1442 if pou is not None: |
1465 if pou.interface is None: |
1443 if pou.interface is None: |
1466 pou.interface = plcopen.pou_interface() |
1444 pou.interface = PLCOpenParser.CreateElement("interface", "pou") |
1467 # Set Pou interface |
1445 # Set Pou interface |
1468 pou.setvars(self.ExtractVarLists(vars)) |
1446 pou.setvars([varlist for varlist_type, varlist in self.ExtractVarLists(vars)]) |
1469 self.Project.RefreshElementUsingTree() |
1447 |
1470 self.Project.RefreshCustomBlockTypes() |
|
1471 |
|
1472 # Replace the return type of the pou given by its name (only for functions) |
1448 # Replace the return type of the pou given by its name (only for functions) |
1473 def SetPouInterfaceReturnType(self, name, type): |
1449 def SetPouInterfaceReturnType(self, name, return_type): |
1474 if self.Project is not None: |
1450 if self.Project is not None: |
1475 pou = self.Project.getpou(name) |
1451 pou = self.Project.getpou(name) |
1476 if pou is not None: |
1452 if pou is not None: |
1477 if pou.interface is None: |
1453 if pou.interface is None: |
1478 pou.interface = plcopen.pou_interface() |
1454 pou.interface = PLCOpenParser.CreateElement("interface", "pou") |
1479 # If there isn't any return type yet, add it |
1455 # If there isn't any return type yet, add it |
1480 return_type = pou.interface.getreturnType() |
1456 return_type_obj = pou.interface.getreturnType() |
1481 if not return_type: |
1457 if return_type_obj is None: |
1482 return_type = plcopen.dataType() |
1458 return_type_obj = PLCOpenParser.CreateElement("returnType", "interface") |
1483 pou.interface.setreturnType(return_type) |
1459 pou.interface.setreturnType(return_type_obj) |
1484 # Change return type |
1460 # Change return type |
1485 if type in self.GetBaseTypes(): |
1461 if return_type in self.GetBaseTypes(): |
1486 if type == "STRING": |
1462 return_type_obj.setcontent(PLCOpenParser.CreateElement( |
1487 return_type.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()}) |
1463 return_type.lower() |
1488 elif type == "WSTRING": |
1464 if return_type in ["STRING", "WSTRING"] |
1489 return_type.setcontent({"name" : "wstring", "value" : plcopen.elementaryTypes_wstring()}) |
1465 else return_type, "dataType")) |
1490 else: |
|
1491 return_type.setcontent({"name" : type, "value" : None}) |
|
1492 else: |
1466 else: |
1493 derived_type = plcopen.derivedTypes_derived() |
1467 derived_type = PLCOpenParser.CreateElement("derived", "dataType") |
1494 derived_type.setname(type) |
1468 derived_type.setname(return_type) |
1495 return_type.setcontent({"name" : "derived", "value" : derived_type}) |
1469 return_type.setcontent(derived_type) |
1496 self.Project.RefreshElementUsingTree() |
1470 |
1497 self.Project.RefreshCustomBlockTypes() |
|
1498 |
|
1499 def UpdateProjectUsedPous(self, old_name, new_name): |
1471 def UpdateProjectUsedPous(self, old_name, new_name): |
1500 if self.Project: |
1472 if self.Project is not None: |
1501 self.Project.updateElementName(old_name, new_name) |
1473 self.Project.updateElementName(old_name, new_name) |
1502 |
1474 |
1503 def UpdateEditedElementUsedVariable(self, tagname, old_name, new_name): |
1475 def UpdateEditedElementUsedVariable(self, tagname, old_name, new_name): |
1504 pou = self.GetEditedElement(tagname) |
1476 pou = self.GetEditedElement(tagname) |
1505 if pou: |
1477 if pou is not None: |
1506 pou.updateElementName(old_name, new_name) |
1478 pou.updateElementName(old_name, new_name) |
1507 |
1479 |
1508 # Return the return type of the pou given by its name |
|
1509 def GetPouInterfaceReturnTypeByName(self, name): |
|
1510 project = self.GetProject(debug) |
|
1511 if project is not None: |
|
1512 # Found the pou correponding to name and return the return type |
|
1513 pou = project.getpou(name) |
|
1514 if pou is not None: |
|
1515 return self.GetPouInterfaceReturnType(pou) |
|
1516 return False |
|
1517 |
|
1518 # Return the return type of the given pou |
1480 # Return the return type of the given pou |
1519 def GetPouInterfaceReturnType(self, pou): |
1481 def GetPouInterfaceReturnType(self, pou, tree=False, debug=False): |
1520 # Verify that the pou has an interface |
1482 # Verify that the pou has an interface |
1521 if pou.interface is not None: |
1483 if pou.interface is not None: |
1522 # Return the return type if there is one |
1484 # Return the return type if there is one |
1523 return_type = pou.interface.getreturnType() |
1485 return_type = pou.interface.getreturnType() |
1524 if return_type: |
1486 if return_type is not None: |
1525 returntype_content = return_type.getcontent() |
1487 factory = VariablesInfosFactory([]) |
1526 if returntype_content["name"] == "derived": |
1488 |
1527 return returntype_content["value"].getname() |
1489 parser = etree.XMLParser() |
1528 elif returntype_content["name"] in ["string", "wstring"]: |
1490 if tree: |
1529 return returntype_content["name"].upper() |
1491 parser.resolvers.add(LibraryResolver(self)) |
1530 else: |
1492 |
1531 return returntype_content["name"] |
1493 return_type_infos_xslt_tree = etree.XSLT( |
1494 etree.parse( |
|
1495 os.path.join(ScriptDirectory, "plcopen", "variables_infos.xslt"), |
|
1496 parser), |
|
1497 extensions = {("var_infos_ns", name): getattr(factory, name) |
|
1498 for name in ["SetType", "AddDimension", |
|
1499 "AddTree", "AddVarToTree"]}) |
|
1500 return_type_infos_xslt_tree(return_type, |
|
1501 tree=etree.XSLT.strparam(str(tree))) |
|
1502 if tree: |
|
1503 return [factory.GetType(), factory.GetTree()] |
|
1504 return factory.GetType() |
|
1505 |
|
1506 if tree: |
|
1507 return [None, ([], [])] |
|
1532 return None |
1508 return None |
1533 |
1509 |
1534 # Function that add a new confnode to the confnode list |
1510 # Function that add a new confnode to the confnode list |
1535 def AddConfNodeTypesList(self, typeslist): |
1511 def AddConfNodeTypesList(self, typeslist): |
1536 self.ConfNodeTypes.extend(typeslist) |
1512 self.ConfNodeTypes.extend(typeslist) |
1513 addedcat = [{"name": _("%s POUs") % confnodetypes["name"], |
|
1514 "list": [pou.getblockInfos() |
|
1515 for pou in confnodetypes["types"].getpous()]} |
|
1516 for confnodetypes in typeslist] |
|
1517 self.TotalTypes.extend(addedcat) |
|
1518 for cat in addedcat: |
|
1519 for desc in cat["list"]: |
|
1520 BlkLst = self.TotalTypesDict.setdefault(desc["name"],[]) |
|
1521 BlkLst.append((section["name"], desc)) |
|
1537 |
1522 |
1538 # Function that clear the confnode list |
1523 # Function that clear the confnode list |
1539 def ClearConfNodeTypes(self): |
1524 def ClearConfNodeTypes(self): |
1540 for i in xrange(len(self.ConfNodeTypes)): |
1525 self.ConfNodeTypes = [] |
1541 self.ConfNodeTypes.pop(0) |
1526 self.TotalTypesDict = StdBlckDct.copy() |
1542 |
1527 self.TotalTypes = StdBlckLst[:] |
1543 def GetConfNodeBlockTypes(self): |
1528 |
1544 return [{"name": _("%s POUs") % confnodetypes["name"], |
1529 def GetConfNodeDataTypes(self, exclude = None, only_locatables = False): |
1545 "list": confnodetypes["types"].GetCustomBlockTypes()} |
1530 return [{"name": _("%s Data Types") % confnodetypes["name"], |
1531 "list": [ |
|
1532 datatype.getname() |
|
1533 for datatype in confnodetypes["types"].getdataTypes() |
|
1534 if not only_locatables or self.IsLocatableDataType(datatype, debug)]} |
|
1546 for confnodetypes in self.ConfNodeTypes] |
1535 for confnodetypes in self.ConfNodeTypes] |
1547 |
|
1548 def GetConfNodeDataTypes(self, exclude = "", only_locatables = False): |
|
1549 return [{"name": _("%s Data Types") % confnodetypes["name"], |
|
1550 "list": [datatype["name"] for datatype in confnodetypes["types"].GetCustomDataTypes(exclude, only_locatables)]} |
|
1551 for confnodetypes in self.ConfNodeTypes] |
|
1552 |
|
1553 def GetConfNodeDataType(self, type): |
|
1554 for confnodetype in self.ConfNodeTypes: |
|
1555 datatype = confnodetype["types"].getdataType(type) |
|
1556 if datatype is not None: |
|
1557 return datatype |
|
1558 return None |
|
1559 |
1536 |
1560 def GetVariableLocationTree(self): |
1537 def GetVariableLocationTree(self): |
1561 return [] |
1538 return [] |
1562 |
1539 |
1563 def GetConfNodeGlobalInstances(self): |
1540 def GetConfNodeGlobalInstances(self): |
1564 return [] |
1541 return [] |
1565 |
1542 |
1566 def GetConfigurationExtraVariables(self): |
1543 def GetConfigurationExtraVariables(self): |
1567 global_vars = [] |
1544 global_vars = [] |
1568 for var_name, var_type, var_initial in self.GetConfNodeGlobalInstances(): |
1545 for var_name, var_type, var_initial in self.GetConfNodeGlobalInstances(): |
1569 tempvar = plcopen.varListPlain_variable() |
1546 tempvar = PLCOpenParser.CreateElement("variable", "globalVars") |
1570 tempvar.setname(var_name) |
1547 tempvar.setname(var_name) |
1571 |
1548 |
1572 tempvartype = plcopen.dataType() |
1549 tempvartype = PLCOpenParser.CreateElement("type", "variable") |
1573 if var_type in self.GetBaseTypes(): |
1550 if var_type in self.GetBaseTypes(): |
1574 if var_type == "STRING": |
1551 tempvartype.setcontent(PLCOpenParser.CreateElement( |
1575 tempvartype.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()}) |
1552 var_type.lower() |
1576 elif var_type == "WSTRING": |
1553 if var_type in ["STRING", "WSTRING"] |
1577 tempvartype.setcontent({"name" : "wstring", "value" : plcopen.elementaryTypes_wstring()}) |
1554 else var_type, "dataType")) |
1578 else: |
|
1579 tempvartype.setcontent({"name" : var_type, "value" : None}) |
|
1580 else: |
1555 else: |
1581 tempderivedtype = plcopen.derivedTypes_derived() |
1556 tempderivedtype = PLCOpenParser.CreateElement("derived", "dataType") |
1582 tempderivedtype.setname(var_type) |
1557 tempderivedtype.setname(var_type) |
1583 tempvartype.setcontent({"name" : "derived", "value" : tempderivedtype}) |
1558 tempvartype.setcontent(tempderivedtype) |
1584 tempvar.settype(tempvartype) |
1559 tempvar.settype(tempvartype) |
1585 |
1560 |
1586 if var_initial != "": |
1561 if var_initial != "": |
1587 value = plcopen.value() |
1562 value = PLCOpenParser.CreateElement("initialValue", "variable") |
1588 value.setvalue(var_initial) |
1563 value.setvalue(var_initial) |
1589 tempvar.setinitialValue(value) |
1564 tempvar.setinitialValue(value) |
1590 |
1565 |
1591 global_vars.append(tempvar) |
1566 global_vars.append(tempvar) |
1592 return global_vars |
1567 return global_vars |
1593 |
1568 |
1594 # Function that returns the block definition associated to the block type given |
1569 # Function that returns the block definition associated to the block type given |
1595 def GetBlockType(self, type, inputs = None, debug = False): |
1570 def GetBlockType(self, typename, inputs = None, debug = False): |
1596 result_blocktype = None |
1571 result_blocktype = None |
1597 for category in BlockTypes + self.GetConfNodeBlockTypes(): |
1572 for sectioname, blocktype in self.TotalTypesDict.get(typename,[]): |
1598 for blocktype in category["list"]: |
1573 if inputs is not None and inputs != "undefined": |
1599 if blocktype["name"] == type: |
1574 block_inputs = tuple([var_type for name, var_type, modifier in blocktype["inputs"]]) |
1600 if inputs is not None and inputs != "undefined": |
1575 if reduce(lambda x, y: x and y, map(lambda x: x[0] == "ANY" or self.IsOfType(*x), zip(inputs, block_inputs)), True): |
1601 block_inputs = tuple([var_type for name, var_type, modifier in blocktype["inputs"]]) |
1576 return blocktype |
1602 if reduce(lambda x, y: x and y, map(lambda x: x[0] == "ANY" or self.IsOfType(*x), zip(inputs, block_inputs)), True): |
1577 else: |
1603 return blocktype |
1578 if result_blocktype is not None: |
1579 if inputs == "undefined": |
|
1580 return None |
|
1604 else: |
1581 else: |
1605 if result_blocktype is not None: |
1582 result_blocktype["inputs"] = [(i[0], "ANY", i[2]) for i in result_blocktype["inputs"]] |
1606 if inputs == "undefined": |
1583 result_blocktype["outputs"] = [(o[0], "ANY", o[2]) for o in result_blocktype["outputs"]] |
1607 return None |
1584 return result_blocktype |
1608 else: |
1585 result_blocktype = blocktype.copy() |
1609 result_blocktype["inputs"] = [(i[0], "ANY", i[2]) for i in result_blocktype["inputs"]] |
|
1610 result_blocktype["outputs"] = [(o[0], "ANY", o[2]) for o in result_blocktype["outputs"]] |
|
1611 return result_blocktype |
|
1612 result_blocktype = blocktype.copy() |
|
1613 if result_blocktype is not None: |
1586 if result_blocktype is not None: |
1614 return result_blocktype |
1587 return result_blocktype |
1615 project = self.GetProject(debug) |
1588 project = self.GetProject(debug) |
1616 if project is not None: |
1589 if project is not None: |
1617 return project.GetCustomBlockType(type, inputs) |
1590 blocktype = project.getpou(typename) |
1591 if blocktype is not None: |
|
1592 blocktype_infos = blocktype.getblockInfos() |
|
1593 if inputs in [None, "undefined"]: |
|
1594 return blocktype_infos |
|
1595 |
|
1596 if inputs == tuple([var_type |
|
1597 for name, var_type, modifier in blocktype_infos["inputs"]]): |
|
1598 return blocktype_infos |
|
1599 |
|
1618 return None |
1600 return None |
1619 |
1601 |
1620 # Return Block types checking for recursion |
1602 # Return Block types checking for recursion |
1621 def GetBlockTypes(self, tagname = "", debug = False): |
1603 def GetBlockTypes(self, tagname = "", debug = False): |
1622 type = None |
1604 typename = None |
1623 words = tagname.split("::") |
1605 words = tagname.split("::") |
1624 if self.Project: |
1606 name = None |
1625 name = "" |
1607 project = self.GetProject(debug) |
1608 if project is not None: |
|
1609 pou_type = None |
|
1626 if words[0] in ["P","T","A"]: |
1610 if words[0] in ["P","T","A"]: |
1627 name = words[1] |
1611 name = words[1] |
1628 type = self.GetPouType(name, debug) |
1612 pou_type = self.GetPouType(name, debug) |
1629 if type == "function": |
1613 filter = (["function"] |
1630 blocktypes = [] |
1614 if pou_type == "function" or words[0] == "T" |
1631 for category in BlockTypes + self.GetConfNodeBlockTypes(): |
1615 else ["functionBlock", "function"]) |
1632 cat = {"name" : category["name"], "list" : []} |
1616 blocktypes = [ |
1633 for block in category["list"]: |
1617 {"name": category["name"], |
1634 if block["type"] == "function": |
1618 "list": [block for block in category["list"] |
1635 cat["list"].append(block) |
1619 if block["type"] in filter]} |
1636 if len(cat["list"]) > 0: |
1620 for category in self.TotalTypes] |
1637 blocktypes.append(cat) |
1621 blocktypes.append({"name" : USER_DEFINED_POUS, |
1638 else: |
1622 "list": [pou.getblockInfos() |
1639 blocktypes = [category for category in BlockTypes + self.GetConfNodeBlockTypes()] |
1623 for pou in project.getpous(name, filter) |
1640 project = self.GetProject(debug) |
1624 if (name is None or |
1641 if project is not None: |
1625 len(self.GetInstanceList(pou, name, debug)) == 0)]}) |
1642 blocktypes.append({"name" : USER_DEFINED_POUS, "list": project.GetCustomBlockTypes(name, type == "function" or words[0] == "T")}) |
1626 return blocktypes |
1643 return blocktypes |
1627 return self.TotalTypes |
1644 |
1628 |
1645 # Return Function Block types checking for recursion |
1629 # Return Function Block types checking for recursion |
1646 def GetFunctionBlockTypes(self, tagname = "", debug = False): |
1630 def GetFunctionBlockTypes(self, tagname = "", debug = False): |
1631 project = self.GetProject(debug) |
|
1632 words = tagname.split("::") |
|
1633 name = None |
|
1634 if project is not None and words[0] in ["P","T","A"]: |
|
1635 name = words[1] |
|
1647 blocktypes = [] |
1636 blocktypes = [] |
1648 for category in BlockTypes + self.GetConfNodeBlockTypes(): |
1637 for blocks in self.TotalTypesDict.itervalues(): |
1649 for block in category["list"]: |
1638 for sectioname,block in blocks: |
1650 if block["type"] == "functionBlock": |
1639 if block["type"] == "functionBlock": |
1651 blocktypes.append(block["name"]) |
1640 blocktypes.append(block["name"]) |
1652 project = self.GetProject(debug) |
1641 if project is not None: |
1653 if project is not None: |
1642 blocktypes.extend([pou.getname() |
1654 name = "" |
1643 for pou in project.getpous(name, ["functionBlock"]) |
1655 words = tagname.split("::") |
1644 if (name is None or |
1656 if words[0] in ["P","T","A"]: |
1645 len(self.GetInstanceList(pou, name, debug)) == 0)]) |
1657 name = words[1] |
|
1658 blocktypes.extend(project.GetCustomFunctionBlockTypes(name)) |
|
1659 return blocktypes |
1646 return blocktypes |
1660 |
1647 |
1661 # Return Block types checking for recursion |
1648 # Return Block types checking for recursion |
1662 def GetBlockResource(self, debug = False): |
1649 def GetBlockResource(self, debug = False): |
1663 blocktypes = [] |
1650 blocktypes = [] |
1664 for category in BlockTypes[:-1]: |
1651 for category in StdBlckLst[:-1]: |
1665 for blocktype in category["list"]: |
1652 for blocktype in category["list"]: |
1666 if blocktype["type"] == "program": |
1653 if blocktype["type"] == "program": |
1667 blocktypes.append(blocktype["name"]) |
1654 blocktypes.append(blocktype["name"]) |
1668 project = self.GetProject(debug) |
1655 project = self.GetProject(debug) |
1669 if project is not None: |
1656 if project is not None: |
1670 blocktypes.extend(project.GetCustomBlockResource()) |
1657 blocktypes.extend( |
1658 [pou.getname() |
|
1659 for pou in project.getpous(filter=["program"])]) |
|
1671 return blocktypes |
1660 return blocktypes |
1672 |
1661 |
1673 # Return Data Types checking for recursion |
1662 # Return Data Types checking for recursion |
1674 def GetDataTypes(self, tagname = "", basetypes = True, confnodetypes = True, only_locatables = False, debug = False): |
1663 def GetDataTypes(self, tagname = "", basetypes = True, confnodetypes = True, only_locatables = False, debug = False): |
1675 if basetypes: |
1664 if basetypes: |
1676 datatypes = self.GetBaseTypes() |
1665 datatypes = self.GetBaseTypes() |
1677 else: |
1666 else: |
1678 datatypes = [] |
1667 datatypes = [] |
1679 project = self.GetProject(debug) |
1668 project = self.GetProject(debug) |
1680 if project is not None: |
1669 name = None |
1681 name = "" |
1670 if project is not None: |
1682 words = tagname.split("::") |
1671 words = tagname.split("::") |
1683 if words[0] in ["D"]: |
1672 if words[0] in ["D"]: |
1684 name = words[1] |
1673 name = words[1] |
1685 datatypes.extend([datatype["name"] for datatype in project.GetCustomDataTypes(name, only_locatables)]) |
1674 datatypes.extend([ |
1675 datatype.getname() |
|
1676 for datatype in project.getdataTypes(name) |
|
1677 if (not only_locatables or self.IsLocatableDataType(datatype, debug)) |
|
1678 and (name is None or |
|
1679 len(self.GetInstanceList(datatype, name, debug)) == 0)]) |
|
1686 if confnodetypes: |
1680 if confnodetypes: |
1687 for category in self.GetConfNodeDataTypes(name, only_locatables): |
1681 for category in self.GetConfNodeDataTypes(name, only_locatables): |
1688 datatypes.extend(category["list"]) |
1682 datatypes.extend(category["list"]) |
1689 return datatypes |
1683 return datatypes |
1690 |
1684 |
1691 # Return Base Type of given possible derived type |
1685 # Return Data Type Object |
1692 def GetBaseType(self, type, debug = False): |
1686 def GetPou(self, typename, debug = False): |
1693 project = self.GetProject(debug) |
1687 project = self.GetProject(debug) |
1694 if project is not None: |
1688 if project is not None: |
1695 result = project.GetBaseType(type) |
1689 result = project.getpou(typename) |
1690 if result is not None: |
|
1691 return result |
|
1692 for standardlibrary in [StdBlockLibrary, AddnlBlockLibrary]: |
|
1693 result = standardlibrary.getpou(typename) |
|
1696 if result is not None: |
1694 if result is not None: |
1697 return result |
1695 return result |
1698 for confnodetype in self.ConfNodeTypes: |
1696 for confnodetype in self.ConfNodeTypes: |
1699 result = confnodetype["types"].GetBaseType(type) |
1697 result = confnodetype["types"].getpou(typename) |
1700 if result is not None: |
1698 if result is not None: |
1701 return result |
1699 return result |
1700 return None |
|
1701 |
|
1702 |
|
1703 # Return Data Type Object |
|
1704 def GetDataType(self, typename, debug = False): |
|
1705 project = self.GetProject(debug) |
|
1706 if project is not None: |
|
1707 result = project.getdataType(typename) |
|
1708 if result is not None: |
|
1709 return result |
|
1710 for confnodetype in self.ConfNodeTypes: |
|
1711 result = confnodetype["types"].getdataType(typename) |
|
1712 if result is not None: |
|
1713 return result |
|
1714 return None |
|
1715 |
|
1716 # Return Data Type Object Base Type |
|
1717 def GetDataTypeBaseType(self, datatype): |
|
1718 basetype_content = datatype.baseType.getcontent() |
|
1719 basetype_content_type = basetype_content.getLocalTag() |
|
1720 if basetype_content_type in ["array", "subrangeSigned", "subrangeUnsigned"]: |
|
1721 basetype = basetype_content.baseType.getcontent() |
|
1722 basetype_type = basetype.getLocalTag() |
|
1723 return (basetype.getname() if basetype_type == "derived" |
|
1724 else basetype_type.upper()) |
|
1725 return (basetype_content.getname() if basetype_content_type == "derived" |
|
1726 else basetype_content_type.upper()) |
|
1727 return None |
|
1728 |
|
1729 # Return Base Type of given possible derived type |
|
1730 def GetBaseType(self, typename, debug = False): |
|
1731 if TypeHierarchy.has_key(typename): |
|
1732 return typename |
|
1733 |
|
1734 datatype = self.GetDataType(typename, debug) |
|
1735 if datatype is not None: |
|
1736 basetype = self.GetDataTypeBaseType(datatype) |
|
1737 if basetype is not None: |
|
1738 return self.GetBaseType(basetype, debug) |
|
1739 return typename |
|
1740 |
|
1702 return None |
1741 return None |
1703 |
1742 |
1704 def GetBaseTypes(self): |
1743 def GetBaseTypes(self): |
1705 ''' |
1744 ''' |
1706 return the list of datatypes defined in IEC 61131-3. |
1745 return the list of datatypes defined in IEC 61131-3. |
1707 TypeHierarchy_list has a rough order to it (e.g. SINT, INT, DINT, ...), |
1746 TypeHierarchy_list has a rough order to it (e.g. SINT, INT, DINT, ...), |
1708 which makes it easy for a user to find a type in a menu. |
1747 which makes it easy for a user to find a type in a menu. |
1709 ''' |
1748 ''' |
1710 return [x for x,y in TypeHierarchy_list if not x.startswith("ANY")] |
1749 return [x for x,y in TypeHierarchy_list if not x.startswith("ANY")] |
1711 |
1750 |
1712 def IsOfType(self, type, reference, debug = False): |
1751 def IsOfType(self, typename, reference, debug = False): |
1713 if reference is None: |
1752 if reference is None or typename == reference: |
1714 return True |
1753 return True |
1715 elif type == reference: |
1754 |
1716 return True |
1755 basetype = TypeHierarchy.get(typename) |
1717 elif type in TypeHierarchy: |
1756 if basetype is not None: |
1718 return self.IsOfType(TypeHierarchy[type], reference) |
1757 return self.IsOfType(basetype, reference) |
1719 else: |
1758 |
1720 project = self.GetProject(debug) |
1759 datatype = self.GetDataType(typename, debug) |
1721 if project is not None and project.IsOfType(type, reference): |
1760 if datatype is not None: |
1722 return True |
1761 basetype = self.GetDataTypeBaseType(datatype) |
1723 for confnodetype in self.ConfNodeTypes: |
1762 if basetype is not None: |
1724 if confnodetype["types"].IsOfType(type, reference): |
1763 return self.IsOfType(basetype, reference, debug) |
1725 return True |
1764 |
1726 return False |
1765 return False |
1727 |
1766 |
1728 def IsEndType(self, type): |
1767 def IsEndType(self, typename): |
1729 if type is not None: |
1768 if typename is not None: |
1730 return not type.startswith("ANY") |
1769 return not typename.startswith("ANY") |
1731 return True |
1770 return True |
1732 |
1771 |
1733 def IsLocatableType(self, type, debug = False): |
1772 def IsLocatableDataType(self, datatype, debug = False): |
1734 if isinstance(type, TupleType): |
1773 basetype_content = datatype.baseType.getcontent() |
1735 return False |
1774 basetype_content_type = basetype_content.getLocalTag() |
1736 if self.GetBlockType(type) is not None: |
1775 if basetype_content_type in ["enum", "struct"]: |
1737 return False |
1776 return False |
1738 project = self.GetProject(debug) |
1777 elif basetype_content_type == "derived": |
1739 if project is not None: |
1778 return self.IsLocatableType(basetype_content.getname()) |
1740 datatype = project.getdataType(type) |
1779 elif basetype_content_type == "array": |
1741 if datatype is None: |
1780 array_base_type = basetype_content.baseType.getcontent() |
1742 datatype = self.GetConfNodeDataType(type) |
1781 if array_base_type.getLocalTag() == "derived": |
1743 if datatype is not None: |
1782 return self.IsLocatableType(array_base_type.getname(), debug) |
1744 return project.IsLocatableType(datatype) |
|
1745 return True |
1783 return True |
1746 |
1784 |
1747 def IsEnumeratedType(self, type, debug = False): |
1785 def IsLocatableType(self, typename, debug = False): |
1748 project = self.GetProject(debug) |
1786 if isinstance(typename, TupleType) or self.GetBlockType(typename) is not None: |
1749 if project is not None: |
1787 return False |
1750 datatype = project.getdataType(type) |
1788 |
1751 if datatype is None: |
1789 datatype = self.GetDataType(typename, debug) |
1752 datatype = self.GetConfNodeDataType(type) |
1790 if datatype is not None: |
1753 if datatype is not None: |
1791 return self.IsLocatableDataType(datatype) |
1754 basetype_content = datatype.baseType.getcontent() |
1792 return True |
1755 return basetype_content["name"] == "enum" |
1793 |
1794 def IsEnumeratedType(self, typename, debug = False): |
|
1795 if isinstance(typename, TupleType): |
|
1796 typename = typename[1] |
|
1797 datatype = self.GetDataType(typename, debug) |
|
1798 if datatype is not None: |
|
1799 basetype_content = datatype.baseType.getcontent() |
|
1800 basetype_content_type = basetype_content.getLocalTag() |
|
1801 if basetype_content_type == "derived": |
|
1802 return self.IsEnumeratedType(basetype_content_type, debug) |
|
1803 return basetype_content_type == "enum" |
|
1756 return False |
1804 return False |
1757 |
1805 |
1758 def IsNumType(self, type, debug = False): |
1806 def IsSubrangeType(self, typename, exclude=None, debug = False): |
1759 return self.IsOfType(type, "ANY_NUM", debug) or\ |
1807 if typename == exclude: |
1760 self.IsOfType(type, "ANY_BIT", debug) |
1808 return False |
1809 if isinstance(typename, TupleType): |
|
1810 typename = typename[1] |
|
1811 datatype = self.GetDataType(typename, debug) |
|
1812 if datatype is not None: |
|
1813 basetype_content = datatype.baseType.getcontent() |
|
1814 basetype_content_type = basetype_content.getLocalTag() |
|
1815 if basetype_content_type == "derived": |
|
1816 return self.IsSubrangeType(basetype_content_type, exclude, debug) |
|
1817 elif basetype_content_type in ["subrangeSigned", "subrangeUnsigned"]: |
|
1818 return not self.IsOfType( |
|
1819 self.GetDataTypeBaseType(datatype), exclude) |
|
1820 return False |
|
1821 |
|
1822 def IsNumType(self, typename, debug = False): |
|
1823 return self.IsOfType(typename, "ANY_NUM", debug) or\ |
|
1824 self.IsOfType(typename, "ANY_BIT", debug) |
|
1761 |
1825 |
1762 def GetDataTypeRange(self, type, debug = False): |
1826 def GetDataTypeRange(self, typename, debug = False): |
1763 if type in DataTypeRange: |
1827 range = DataTypeRange.get(typename) |
1764 return DataTypeRange[type] |
1828 if range is not None: |
1829 return range |
|
1830 datatype = self.GetDataType(typename, debug) |
|
1831 if datatype is not None: |
|
1832 basetype_content = datatype.baseType.getcontent() |
|
1833 basetype_content_type = basetype_content.getLocalTag() |
|
1834 if basetype_content_type in ["subrangeSigned", "subrangeUnsigned"]: |
|
1835 return (basetype_content.range.getlower(), |
|
1836 basetype_content.range.getupper()) |
|
1837 elif basetype_content_type == "derived": |
|
1838 return self.GetDataTypeRange(basetype_content.getname(), debug) |
|
1839 return None |
|
1840 |
|
1841 # Return Subrange types |
|
1842 def GetSubrangeBaseTypes(self, exclude, debug = False): |
|
1843 subrange_basetypes = DataTypeRange.keys() |
|
1844 project = self.GetProject(debug) |
|
1845 if project is not None: |
|
1846 subrange_basetypes.extend( |
|
1847 [datatype.getname() for datatype in project.getdataTypes() |
|
1848 if self.IsSubrangeType(datatype.getname(), exclude, debug)]) |
|
1849 for confnodetype in self.ConfNodeTypes: |
|
1850 subrange_basetypes.extend( |
|
1851 [datatype.getname() for datatype in confnodetype["types"].getdataTypes() |
|
1852 if self.IsSubrangeType(datatype.getname(), exclude, debug)]) |
|
1853 return subrange_basetypes |
|
1854 |
|
1855 # Return Enumerated Values |
|
1856 def GetEnumeratedDataValues(self, typename = None, debug = False): |
|
1857 values = [] |
|
1858 if typename is not None: |
|
1859 datatype_obj = self.GetDataType(typename, debug) |
|
1860 if datatype_obj is not None: |
|
1861 basetype_content = datatype_obj.baseType.getcontent() |
|
1862 basetype_content_type = basetype_content.getLocalTag() |
|
1863 if basetype_content_type == "enum": |
|
1864 return [value.getname() |
|
1865 for value in basetype_content.xpath( |
|
1866 "ppx:values/ppx:value", |
|
1867 namespaces=PLCOpenParser.NSMAP)] |
|
1868 elif basetype_content_type == "derived": |
|
1869 return self.GetEnumeratedDataValues(basetype_content.getname(), debug) |
|
1765 else: |
1870 else: |
1766 project = self.GetProject(debug) |
1871 project = self.GetProject(debug) |
1767 if project is not None: |
1872 if project is not None: |
1768 result = project.GetDataTypeRange(type) |
1873 values.extend(project.GetEnumeratedDataTypeValues()) |
1769 if result is not None: |
|
1770 return result |
|
1771 for confnodetype in self.ConfNodeTypes: |
1874 for confnodetype in self.ConfNodeTypes: |
1772 result = confnodetype["types"].GetDataTypeRange(type) |
1875 values.extend(confnodetype["types"].GetEnumeratedDataTypeValues()) |
1773 if result is not None: |
|
1774 return result |
|
1775 return None |
|
1776 |
|
1777 # Return Subrange types |
|
1778 def GetSubrangeBaseTypes(self, exclude, debug = False): |
|
1779 subrange_basetypes = [] |
|
1780 project = self.GetProject(debug) |
|
1781 if project is not None: |
|
1782 subrange_basetypes.extend(project.GetSubrangeBaseTypes(exclude)) |
|
1783 for confnodetype in self.ConfNodeTypes: |
|
1784 subrange_basetypes.extend(confnodetype["types"].GetSubrangeBaseTypes(exclude)) |
|
1785 return DataTypeRange.keys() + subrange_basetypes |
|
1786 |
|
1787 # Return Enumerated Values |
|
1788 def GetEnumeratedDataValues(self, type = None, debug = False): |
|
1789 values = [] |
|
1790 project = self.GetProject(debug) |
|
1791 if project is not None: |
|
1792 values.extend(project.GetEnumeratedDataTypeValues(type)) |
|
1793 if type is None and len(values) > 0: |
|
1794 return values |
|
1795 for confnodetype in self.ConfNodeTypes: |
|
1796 values.extend(confnodetype["types"].GetEnumeratedDataTypeValues(type)) |
|
1797 if type is None and len(values) > 0: |
|
1798 return values |
|
1799 return values |
1876 return values |
1800 |
1877 |
1801 #------------------------------------------------------------------------------- |
1878 #------------------------------------------------------------------------------- |
1802 # Project Element tag name computation functions |
1879 # Project Element tag name computation functions |
1803 #------------------------------------------------------------------------------- |
1880 #------------------------------------------------------------------------------- |
1845 infos = {} |
1922 infos = {} |
1846 datatype = project.getdataType(words[1]) |
1923 datatype = project.getdataType(words[1]) |
1847 if datatype is None: |
1924 if datatype is None: |
1848 return None |
1925 return None |
1849 basetype_content = datatype.baseType.getcontent() |
1926 basetype_content = datatype.baseType.getcontent() |
1850 if basetype_content["value"] is None or basetype_content["name"] in ["string", "wstring"]: |
1927 basetype_content_type = basetype_content.getLocalTag() |
1851 infos["type"] = "Directly" |
1928 if basetype_content_type in ["subrangeSigned", "subrangeUnsigned"]: |
1852 infos["base_type"] = basetype_content["name"].upper() |
|
1853 elif basetype_content["name"] == "derived": |
|
1854 infos["type"] = "Directly" |
|
1855 infos["base_type"] = basetype_content["value"].getname() |
|
1856 elif basetype_content["name"] in ["subrangeSigned", "subrangeUnsigned"]: |
|
1857 infos["type"] = "Subrange" |
1929 infos["type"] = "Subrange" |
1858 infos["min"] = basetype_content["value"].range.getlower() |
1930 infos["min"] = basetype_content.range.getlower() |
1859 infos["max"] = basetype_content["value"].range.getupper() |
1931 infos["max"] = basetype_content.range.getupper() |
1860 base_type = basetype_content["value"].baseType.getcontent() |
1932 base_type = basetype_content.baseType.getcontent() |
1861 if base_type["value"] is None: |
1933 base_type_type = base_type.getLocalTag() |
1862 infos["base_type"] = base_type["name"] |
1934 infos["base_type"] = (base_type.getname() |
1863 else: |
1935 if base_type_type == "derived" |
1864 infos["base_type"] = base_type["value"].getname() |
1936 else base_type_type) |
1865 elif basetype_content["name"] == "enum": |
1937 elif basetype_content_type == "enum": |
1866 infos["type"] = "Enumerated" |
1938 infos["type"] = "Enumerated" |
1867 infos["values"] = [] |
1939 infos["values"] = [] |
1868 for value in basetype_content["value"].values.getvalue(): |
1940 for value in basetype_content.xpath("ppx:values/ppx:value", namespaces=PLCOpenParser.NSMAP): |
1869 infos["values"].append(value.getname()) |
1941 infos["values"].append(value.getname()) |
1870 elif basetype_content["name"] == "array": |
1942 elif basetype_content_type == "array": |
1871 infos["type"] = "Array" |
1943 infos["type"] = "Array" |
1872 infos["dimensions"] = [] |
1944 infos["dimensions"] = [] |
1873 for dimension in basetype_content["value"].getdimension(): |
1945 for dimension in basetype_content.getdimension(): |
1874 infos["dimensions"].append((dimension.getlower(), dimension.getupper())) |
1946 infos["dimensions"].append((dimension.getlower(), dimension.getupper())) |
1875 base_type = basetype_content["value"].baseType.getcontent() |
1947 base_type = basetype_content.baseType.getcontent() |
1876 if base_type["value"] is None or base_type["name"] in ["string", "wstring"]: |
1948 base_type_type = base_type.getLocalTag() |
1877 infos["base_type"] = base_type["name"].upper() |
1949 infos["base_type"] = (base_type.getname() |
1878 else: |
1950 if base_type_type == "derived" |
1879 infos["base_type"] = base_type["value"].getname() |
1951 else base_type_type.upper()) |
1880 elif basetype_content["name"] == "struct": |
1952 elif basetype_content_type == "struct": |
1881 infos["type"] = "Structure" |
1953 infos["type"] = "Structure" |
1882 infos["elements"] = [] |
1954 infos["elements"] = [] |
1883 for element in basetype_content["value"].getvariable(): |
1955 for element in basetype_content.getvariable(): |
1884 element_infos = {} |
1956 element_infos = {} |
1885 element_infos["Name"] = element.getname() |
1957 element_infos["Name"] = element.getname() |
1886 element_type = element.type.getcontent() |
1958 element_type = element.type.getcontent() |
1887 if element_type["value"] is None or element_type["name"] in ["string", "wstring"]: |
1959 element_type_type = element_type.getLocalTag() |
1888 element_infos["Type"] = element_type["name"].upper() |
1960 if element_type_type == "array": |
1889 elif element_type["name"] == "array": |
|
1890 dimensions = [] |
1961 dimensions = [] |
1891 for dimension in element_type["value"].getdimension(): |
1962 for dimension in element_type.getdimension(): |
1892 dimensions.append((dimension.getlower(), dimension.getupper())) |
1963 dimensions.append((dimension.getlower(), dimension.getupper())) |
1893 base_type = element_type["value"].baseType.getcontent() |
1964 base_type = element_type.baseType.getcontent() |
1894 if base_type["value"] is None or base_type["name"] in ["string", "wstring"]: |
1965 base_type_type = element_type.getLocalTag() |
1895 base_type_name = base_type["name"].upper() |
1966 element_infos["Type"] = ("array", |
1896 else: |
1967 base_type.getname() |
1897 base_type_name = base_type["value"].getname() |
1968 if base_type_type == "derived" |
1898 element_infos["Type"] = ("array", base_type_name, dimensions) |
1969 else base_type_type.upper(), dimensions) |
1970 elif element_type_type == "derived": |
|
1971 element_infos["Type"] = element_type.getname() |
|
1899 else: |
1972 else: |
1900 element_infos["Type"] = element_type["value"].getname() |
1973 element_infos["Type"] = element_type_type.upper() |
1901 if element.initialValue is not None: |
1974 if element.initialValue is not None: |
1902 element_infos["Initial Value"] = str(element.initialValue.getvalue()) |
1975 element_infos["Initial Value"] = str(element.initialValue.getvalue()) |
1903 else: |
1976 else: |
1904 element_infos["Initial Value"] = "" |
1977 element_infos["Initial Value"] = "" |
1905 infos["elements"].append(element_infos) |
1978 infos["elements"].append(element_infos) |
1979 else: |
|
1980 infos["type"] = "Directly" |
|
1981 infos["base_type"] = (basetype_content.getname() |
|
1982 if basetype_content_type == "derived" |
|
1983 else basetype_content_type.upper()) |
|
1984 |
|
1906 if datatype.initialValue is not None: |
1985 if datatype.initialValue is not None: |
1907 infos["initial"] = str(datatype.initialValue.getvalue()) |
1986 infos["initial"] = str(datatype.initialValue.getvalue()) |
1908 else: |
1987 else: |
1909 infos["initial"] = "" |
1988 infos["initial"] = "" |
1910 return infos |
1989 return infos |
1915 words = tagname.split("::") |
1994 words = tagname.split("::") |
1916 if self.Project is not None and words[0] == "D": |
1995 if self.Project is not None and words[0] == "D": |
1917 datatype = self.Project.getdataType(words[1]) |
1996 datatype = self.Project.getdataType(words[1]) |
1918 if infos["type"] == "Directly": |
1997 if infos["type"] == "Directly": |
1919 if infos["base_type"] in self.GetBaseTypes(): |
1998 if infos["base_type"] in self.GetBaseTypes(): |
1920 if infos["base_type"] == "STRING": |
1999 datatype.baseType.setcontent(PLCOpenParser.CreateElement( |
1921 datatype.baseType.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()}) |
2000 infos["base_type"].lower() |
1922 elif infos["base_type"] == "WSTRING": |
2001 if infos["base_type"] in ["STRING", "WSTRING"] |
1923 datatype.baseType.setcontent({"name" : "wstring", "value" : plcopen.elementaryTypes_wstring()}) |
2002 else infos["base_type"], "dataType")) |
1924 else: |
|
1925 datatype.baseType.setcontent({"name" : infos["base_type"], "value" : None}) |
|
1926 else: |
2003 else: |
1927 derived_datatype = plcopen.derivedTypes_derived() |
2004 derived_datatype = PLCOpenParser.CreateElement("derived", "dataType") |
1928 derived_datatype.setname(infos["base_type"]) |
2005 derived_datatype.setname(infos["base_type"]) |
1929 datatype.baseType.setcontent({"name" : "derived", "value" : derived_datatype}) |
2006 datatype.baseType.setcontent(derived_datatype) |
1930 elif infos["type"] == "Subrange": |
2007 elif infos["type"] == "Subrange": |
1931 if infos["base_type"] in GetSubTypes("ANY_UINT"): |
2008 subrange = PLCOpenParser.CreateElement( |
1932 subrange = plcopen.derivedTypes_subrangeUnsigned() |
2009 "subrangeUnsigned" |
1933 datatype.baseType.setcontent({"name" : "subrangeUnsigned", "value" : subrange}) |
2010 if infos["base_type"] in GetSubTypes("ANY_UINT") |
1934 else: |
2011 else "subrangeSigned", "dataType") |
1935 subrange = plcopen.derivedTypes_subrangeSigned() |
2012 datatype.baseType.setcontent(subrange) |
1936 datatype.baseType.setcontent({"name" : "subrangeSigned", "value" : subrange}) |
|
1937 subrange.range.setlower(infos["min"]) |
2013 subrange.range.setlower(infos["min"]) |
1938 subrange.range.setupper(infos["max"]) |
2014 subrange.range.setupper(infos["max"]) |
1939 if infos["base_type"] in self.GetBaseTypes(): |
2015 if infos["base_type"] in self.GetBaseTypes(): |
1940 subrange.baseType.setcontent({"name" : infos["base_type"], "value" : None}) |
2016 subrange.baseType.setcontent( |
2017 PLCOpenParser.CreateElement(infos["base_type"], "dataType")) |
|
1941 else: |
2018 else: |
1942 derived_datatype = plcopen.derivedTypes_derived() |
2019 derived_datatype = PLCOpenParser.CreateElement("derived", "dataType") |
1943 derived_datatype.setname(infos["base_type"]) |
2020 derived_datatype.setname(infos["base_type"]) |
1944 subrange.baseType.setcontent({"name" : "derived", "value" : derived_datatype}) |
2021 subrange.baseType.setcontent(derived_datatype) |
1945 elif infos["type"] == "Enumerated": |
2022 elif infos["type"] == "Enumerated": |
1946 enumerated = plcopen.derivedTypes_enum() |
2023 enumerated = PLCOpenParser.CreateElement("enum", "dataType") |
2024 datatype.baseType.setcontent(enumerated) |
|
2025 values = PLCOpenParser.CreateElement("values", "enum") |
|
2026 enumerated.setvalues(values) |
|
1947 for i, enum_value in enumerate(infos["values"]): |
2027 for i, enum_value in enumerate(infos["values"]): |
1948 value = plcopen.values_value() |
2028 value = PLCOpenParser.CreateElement("value", "values") |
1949 value.setname(enum_value) |
2029 value.setname(enum_value) |
1950 if i == 0: |
2030 if i == 0: |
1951 enumerated.values.setvalue([value]) |
2031 values.setvalue([value]) |
1952 else: |
2032 else: |
1953 enumerated.values.appendvalue(value) |
2033 values.appendvalue(value) |
1954 datatype.baseType.setcontent({"name" : "enum", "value" : enumerated}) |
|
1955 elif infos["type"] == "Array": |
2034 elif infos["type"] == "Array": |
1956 array = plcopen.derivedTypes_array() |
2035 array = PLCOpenParser.CreateElement("array", "dataType") |
2036 datatype.baseType.setcontent(array) |
|
1957 for i, dimension in enumerate(infos["dimensions"]): |
2037 for i, dimension in enumerate(infos["dimensions"]): |
1958 dimension_range = plcopen.rangeSigned() |
2038 dimension_range = PLCOpenParser.CreateElement("dimension", "array") |
1959 dimension_range.setlower(dimension[0]) |
2039 dimension_range.setlower(dimension[0]) |
1960 dimension_range.setupper(dimension[1]) |
2040 dimension_range.setupper(dimension[1]) |
1961 if i == 0: |
2041 if i == 0: |
1962 array.setdimension([dimension_range]) |
2042 array.setdimension([dimension_range]) |
1963 else: |
2043 else: |
1964 array.appenddimension(dimension_range) |
2044 array.appenddimension(dimension_range) |
1965 if infos["base_type"] in self.GetBaseTypes(): |
2045 if infos["base_type"] in self.GetBaseTypes(): |
1966 if infos["base_type"] == "STRING": |
2046 array.baseType.setcontent(PLCOpenParser.CreateElement( |
1967 array.baseType.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()}) |
2047 infos["base_type"].lower() |
1968 elif infos["base_type"] == "WSTRING": |
2048 if infos["base_type"] in ["STRING", "WSTRING"] |
1969 array.baseType.setcontent({"name" : "wstring", "value" : plcopen.wstring()}) |
2049 else infos["base_type"], "dataType")) |
1970 else: |
|
1971 array.baseType.setcontent({"name" : infos["base_type"], "value" : None}) |
|
1972 else: |
2050 else: |
1973 derived_datatype = plcopen.derivedTypes_derived() |
2051 derived_datatype = PLCOpenParser.CreateElement("derived", "dataType") |
1974 derived_datatype.setname(infos["base_type"]) |
2052 derived_datatype.setname(infos["base_type"]) |
1975 array.baseType.setcontent({"name" : "derived", "value" : derived_datatype}) |
2053 array.baseType.setcontent(derived_datatype) |
1976 datatype.baseType.setcontent({"name" : "array", "value" : array}) |
|
1977 elif infos["type"] == "Structure": |
2054 elif infos["type"] == "Structure": |
1978 struct = plcopen.varListPlain() |
2055 struct = PLCOpenParser.CreateElement("struct", "dataType") |
2056 datatype.baseType.setcontent(struct) |
|
1979 for i, element_infos in enumerate(infos["elements"]): |
2057 for i, element_infos in enumerate(infos["elements"]): |
1980 element = plcopen.varListPlain_variable() |
2058 element = PLCOpenParser.CreateElement("variable", "struct") |
1981 element.setname(element_infos["Name"]) |
2059 element.setname(element_infos["Name"]) |
2060 element_type = PLCOpenParser.CreateElement("type", "variable") |
|
1982 if isinstance(element_infos["Type"], TupleType): |
2061 if isinstance(element_infos["Type"], TupleType): |
1983 if element_infos["Type"][0] == "array": |
2062 if element_infos["Type"][0] == "array": |
1984 array_type, base_type_name, dimensions = element_infos["Type"] |
2063 array_type, base_type_name, dimensions = element_infos["Type"] |
1985 array = plcopen.derivedTypes_array() |
2064 array = PLCOpenParser.CreateElement("array", "dataType") |
2065 element_type.setcontent(array) |
|
1986 for j, dimension in enumerate(dimensions): |
2066 for j, dimension in enumerate(dimensions): |
1987 dimension_range = plcopen.rangeSigned() |
2067 dimension_range = PLCOpenParser.CreateElement("dimension", "array") |
1988 dimension_range.setlower(dimension[0]) |
2068 dimension_range.setlower(dimension[0]) |
1989 dimension_range.setupper(dimension[1]) |
2069 dimension_range.setupper(dimension[1]) |
1990 if j == 0: |
2070 if j == 0: |
1991 array.setdimension([dimension_range]) |
2071 array.setdimension([dimension_range]) |
1992 else: |
2072 else: |
1993 array.appenddimension(dimension_range) |
2073 array.appenddimension(dimension_range) |
1994 if base_type_name in self.GetBaseTypes(): |
2074 if base_type_name in self.GetBaseTypes(): |
1995 if base_type_name == "STRING": |
2075 array.baseType.setcontent(PLCOpenParser.CreateElement( |
1996 array.baseType.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()}) |
2076 base_type_name.lower() |
1997 elif base_type_name == "WSTRING": |
2077 if base_type_name in ["STRING", "WSTRING"] |
1998 array.baseType.setcontent({"name" : "wstring", "value" : plcopen.wstring()}) |
2078 else base_type_name, "dataType")) |
1999 else: |
|
2000 array.baseType.setcontent({"name" : base_type_name, "value" : None}) |
|
2001 else: |
2079 else: |
2002 derived_datatype = plcopen.derivedTypes_derived() |
2080 derived_datatype = PLCOpenParser.CreateElement("derived", "dataType") |
2003 derived_datatype.setname(base_type_name) |
2081 derived_datatype.setname(base_type_name) |
2004 array.baseType.setcontent({"name" : "derived", "value" : derived_datatype}) |
2082 array.baseType.setcontent(derived_datatype) |
2005 element.type.setcontent({"name" : "array", "value" : array}) |
|
2006 elif element_infos["Type"] in self.GetBaseTypes(): |
2083 elif element_infos["Type"] in self.GetBaseTypes(): |
2007 if element_infos["Type"] == "STRING": |
2084 element_type.setcontent( |
2008 element.type.setcontent({"name" : "string", "value" : plcopen.elementaryTypes_string()}) |
2085 PLCOpenParser.CreateElement( |
2009 elif element_infos["Type"] == "WSTRING": |
2086 element_infos["Type"].lower() |
2010 element.type.setcontent({"name" : "wstring", "value" : plcopen.wstring()}) |
2087 if element_infos["Type"] in ["STRING", "WSTRING"] |
2011 else: |
2088 else element_infos["Type"], "dataType")) |
2012 element.type.setcontent({"name" : element_infos["Type"], "value" : None}) |
|
2013 else: |
2089 else: |
2014 derived_datatype = plcopen.derivedTypes_derived() |
2090 derived_datatype = PLCOpenParser.CreateElement("derived", "dataType") |
2015 derived_datatype.setname(element_infos["Type"]) |
2091 derived_datatype.setname(element_infos["Type"]) |
2016 element.type.setcontent({"name" : "derived", "value" : derived_datatype}) |
2092 element_type.setcontent(derived_datatype) |
2093 element.settype(element_type) |
|
2017 if element_infos["Initial Value"] != "": |
2094 if element_infos["Initial Value"] != "": |
2018 value = plcopen.value() |
2095 value = PLCOpenParser.CreateElement("initialValue", "variable") |
2019 value.setvalue(element_infos["Initial Value"]) |
2096 value.setvalue(element_infos["Initial Value"]) |
2020 element.setinitialValue(value) |
2097 element.setinitialValue(value) |
2021 if i == 0: |
2098 if i == 0: |
2022 struct.setvariable([element]) |
2099 struct.setvariable([element]) |
2023 else: |
2100 else: |
2024 struct.appendvariable(element) |
2101 struct.appendvariable(element) |
2025 datatype.baseType.setcontent({"name" : "struct", "value" : struct}) |
|
2026 if infos["initial"] != "": |
2102 if infos["initial"] != "": |
2027 if datatype.initialValue is None: |
2103 if datatype.initialValue is None: |
2028 datatype.initialValue = plcopen.value() |
2104 datatype.initialValue = PLCOpenParser.CreateElement("initialValue", "dataType") |
2029 datatype.initialValue.setvalue(infos["initial"]) |
2105 datatype.initialValue.setvalue(infos["initial"]) |
2030 else: |
2106 else: |
2031 datatype.initialValue = None |
2107 datatype.initialValue = None |
2032 self.Project.RefreshDataTypeHierarchy() |
|
2033 self.Project.RefreshElementUsingTree() |
|
2034 self.BufferProject() |
2108 self.BufferProject() |
2035 |
2109 |
2036 #------------------------------------------------------------------------------- |
2110 #------------------------------------------------------------------------------- |
2037 # Project opened Pous management functions |
2111 # Project opened Pous management functions |
2038 #------------------------------------------------------------------------------- |
2112 #------------------------------------------------------------------------------- |
2085 elif words[0] == 'A': |
2159 elif words[0] == 'A': |
2086 return self.GetActionBodyType(words[1], words[2], debug) |
2160 return self.GetActionBodyType(words[1], words[2], debug) |
2087 return None |
2161 return None |
2088 |
2162 |
2089 # Return the edited element variables |
2163 # Return the edited element variables |
2090 def GetEditedElementInterfaceVars(self, tagname, debug = False): |
2164 def GetEditedElementInterfaceVars(self, tagname, tree=False, debug = False): |
2091 words = tagname.split("::") |
2165 words = tagname.split("::") |
2092 if words[0] in ["P","T","A"]: |
2166 if words[0] in ["P","T","A"]: |
2093 project = self.GetProject(debug) |
2167 project = self.GetProject(debug) |
2094 if project is not None: |
2168 if project is not None: |
2095 pou = project.getpou(words[1]) |
2169 pou = project.getpou(words[1]) |
2096 if pou is not None: |
2170 if pou is not None: |
2097 return self.GetPouInterfaceVars(pou, debug) |
2171 return self.GetPouInterfaceVars(pou, tree, debug) |
2098 return [] |
2172 return [] |
2099 |
2173 |
2100 # Return the edited element return type |
2174 # Return the edited element return type |
2101 def GetEditedElementInterfaceReturnType(self, tagname, debug = False): |
2175 def GetEditedElementInterfaceReturnType(self, tagname, tree=False, debug = False): |
2102 words = tagname.split("::") |
2176 words = tagname.split("::") |
2103 if words[0] == "P": |
2177 if words[0] == "P": |
2104 project = self.GetProject(debug) |
2178 project = self.GetProject(debug) |
2105 if project is not None: |
2179 if project is not None: |
2106 pou = self.Project.getpou(words[1]) |
2180 pou = self.Project.getpou(words[1]) |
2107 if pou is not None: |
2181 if pou is not None: |
2108 return self.GetPouInterfaceReturnType(pou) |
2182 return self.GetPouInterfaceReturnType(pou, tree, debug) |
2109 elif words[0] == 'T': |
2183 elif words[0] == 'T': |
2110 return "BOOL" |
2184 return "BOOL" |
2111 return None |
2185 return None |
2112 |
2186 |
2113 # Change the edited element text |
2187 # Change the edited element text |
2114 def SetEditedElementText(self, tagname, text): |
2188 def SetEditedElementText(self, tagname, text): |
2115 if self.Project is not None: |
2189 if self.Project is not None: |
2116 element = self.GetEditedElement(tagname) |
2190 element = self.GetEditedElement(tagname) |
2117 if element is not None: |
2191 if element is not None: |
2118 element.settext(text) |
2192 element.settext(text) |
2119 self.Project.RefreshElementUsingTree() |
|
2120 |
2193 |
2121 # Return the edited element text |
2194 # Return the edited element text |
2122 def GetEditedElementText(self, tagname, debug = False): |
2195 def GetEditedElementText(self, tagname, debug = False): |
2123 element = self.GetEditedElement(tagname, debug) |
2196 element = self.GetEditedElement(tagname, debug) |
2124 if element is not None: |
2197 if element is not None: |
2159 return [] |
2232 return [] |
2160 |
2233 |
2161 def GetEditedElementCopy(self, tagname, debug = False): |
2234 def GetEditedElementCopy(self, tagname, debug = False): |
2162 element = self.GetEditedElement(tagname, debug) |
2235 element = self.GetEditedElement(tagname, debug) |
2163 if element is not None: |
2236 if element is not None: |
2164 name = element.__class__.__name__ |
2237 return element.tostring() |
2165 return element.generateXMLText(name.split("_")[-1], 0) |
|
2166 return "" |
2238 return "" |
2167 |
2239 |
2168 def GetEditedElementInstancesCopy(self, tagname, blocks_id = None, wires = None, debug = False): |
2240 def GetEditedElementInstancesCopy(self, tagname, blocks_id = None, wires = None, debug = False): |
2169 element = self.GetEditedElement(tagname, debug) |
2241 element = self.GetEditedElement(tagname, debug) |
2170 text = "" |
2242 text = "" |
2171 if element is not None: |
2243 if element is not None: |
2172 wires = dict([(wire, True) for wire in wires if wire[0] in blocks_id and wire[1] in blocks_id]) |
2244 wires = dict([(wire, True) |
2245 for wire in wires |
|
2246 if wire[0] in blocks_id and wire[1] in blocks_id]) |
|
2247 copy_body = PLCOpenParser.CreateElement("body", "pou") |
|
2248 element.append(copy_body) |
|
2249 copy_body.setcontent( |
|
2250 PLCOpenParser.CreateElement(element.getbodyType(), "body")) |
|
2173 for id in blocks_id: |
2251 for id in blocks_id: |
2174 instance = element.getinstance(id) |
2252 instance = element.getinstance(id) |
2175 if instance is not None: |
2253 if instance is not None: |
2176 instance_copy = self.Copy(instance) |
2254 copy_body.appendcontentInstance(self.Copy(instance)) |
2255 instance_copy = copy_body.getcontentInstance(id) |
|
2177 instance_copy.filterConnections(wires) |
2256 instance_copy.filterConnections(wires) |
2178 name = instance_copy.__class__.__name__ |
2257 text += instance_copy.tostring() |
2179 text += instance_copy.generateXMLText(name.split("_")[-1], 0) |
2258 element.remove(copy_body) |
2180 return text |
2259 return text |
2181 |
2260 |
2182 def GenerateNewName(self, tagname, name, format, start_idx=0, exclude={}, debug=False): |
2261 def GenerateNewName(self, tagname, name, format, start_idx=0, exclude={}, debug=False): |
2183 names = exclude.copy() |
2262 names = exclude.copy() |
2184 if tagname is not None: |
2263 if tagname is not None: |
2187 words = tagname.split("::") |
2266 words = tagname.split("::") |
2188 if words[0] in ["P","T","A"]: |
2267 if words[0] in ["P","T","A"]: |
2189 element = self.GetEditedElement(tagname, debug) |
2268 element = self.GetEditedElement(tagname, debug) |
2190 if element is not None and element.getbodyType() not in ["ST", "IL"]: |
2269 if element is not None and element.getbodyType() not in ["ST", "IL"]: |
2191 for instance in element.getinstances(): |
2270 for instance in element.getinstances(): |
2192 if isinstance(instance, (plcopen.sfcObjects_step, |
2271 if isinstance(instance, |
2193 plcopen.commonObjects_connector, |
2272 (PLCOpenParser.GetElementClass("step", "sfcObjects"), |
2194 plcopen.commonObjects_continuation)): |
2273 PLCOpenParser.GetElementClass("connector", "commonObjects"), |
2274 PLCOpenParser.GetElementClass("continuation", "commonObjects"))): |
|
2195 names[instance.getname().upper()] = True |
2275 names[instance.getname().upper()] = True |
2196 else: |
2276 else: |
2197 project = self.GetProject(debug) |
2277 project = self.GetProject(debug) |
2198 if project is not None: |
2278 if project is not None: |
2199 for datatype in project.getdataTypes(): |
2279 for datatype in project.getdataTypes(): |
2200 names[datatype.getname().upper()] = True |
2280 names[datatype.getname().upper()] = True |
2201 for pou in project.getpous(): |
2281 for pou in project.getpous(): |
2202 names[pou.getname().upper()] = True |
2282 names[pou.getname().upper()] = True |
2203 for var in self.GetPouInterfaceVars(pou, debug): |
2283 for var in self.GetPouInterfaceVars(pou, debug=debug): |
2204 names[var["Name"].upper()] = True |
2284 names[var.Name.upper()] = True |
2205 for transition in pou.gettransitionList(): |
2285 for transition in pou.gettransitionList(): |
2206 names[transition.getname().upper()] = True |
2286 names[transition.getname().upper()] = True |
2207 for action in pou.getactionList(): |
2287 for action in pou.getactionList(): |
2208 names[action.getname().upper()] = True |
2288 names[action.getname().upper()] = True |
2209 for config in project.getconfigurations(): |
2289 for config in project.getconfigurations(): |
2214 i = start_idx |
2294 i = start_idx |
2215 while name is None or names.get(name.upper(), False): |
2295 while name is None or names.get(name.upper(), False): |
2216 name = (format%i) |
2296 name = (format%i) |
2217 i += 1 |
2297 i += 1 |
2218 return name |
2298 return name |
2219 |
|
2220 CheckPasteCompatibility = {"SFC": lambda name: True, |
|
2221 "LD": lambda name: not name.startswith("sfcObjects"), |
|
2222 "FBD": lambda name: name.startswith("fbdObjects") or name.startswith("commonObjects")} |
|
2223 |
2299 |
2224 def PasteEditedElementInstances(self, tagname, text, new_pos, middle=False, debug=False): |
2300 def PasteEditedElementInstances(self, tagname, text, new_pos, middle=False, debug=False): |
2225 element = self.GetEditedElement(tagname, debug) |
2301 element = self.GetEditedElement(tagname, debug) |
2226 element_name, element_type = self.GetEditedElementType(tagname, debug) |
2302 element_name, element_type = self.GetEditedElementType(tagname, debug) |
2227 if element is not None: |
2303 if element is not None: |
2236 |
2312 |
2237 # Get ids already by all the instances in edited element |
2313 # Get ids already by all the instances in edited element |
2238 used_id = dict([(instance.getlocalId(), True) for instance in element.getinstances()]) |
2314 used_id = dict([(instance.getlocalId(), True) for instance in element.getinstances()]) |
2239 new_id = {} |
2315 new_id = {} |
2240 |
2316 |
2241 text = "<paste>%s</paste>"%text |
2317 try: |
2318 instances, error = LoadPouInstances(text.encode("utf-8"), bodytype) |
|
2319 except: |
|
2320 instances, error = [], "" |
|
2321 if error is not None or len(instances) == 0: |
|
2322 return _("Invalid plcopen element(s)!!!") |
|
2242 |
2323 |
2243 try: |
|
2244 tree = minidom.parseString(text.encode("utf-8")) |
|
2245 except: |
|
2246 return _("Invalid plcopen element(s)!!!") |
|
2247 instances = [] |
|
2248 exclude = {} |
2324 exclude = {} |
2249 for root in tree.childNodes: |
2325 for instance in instances: |
2250 if root.nodeType == tree.ELEMENT_NODE and root.nodeName == "paste": |
2326 element.addinstance(instance) |
2251 for child in root.childNodes: |
2327 instance_type = instance.getLocalTag() |
2252 if child.nodeType == tree.ELEMENT_NODE: |
2328 if instance_type == "block": |
2253 if not child.nodeName in plcopen.ElementNameToClass: |
2329 blocktype = instance.gettypeName() |
2254 return _("\"%s\" element can't be pasted here!!!")%child.nodeName |
2330 blocktype_infos = self.GetBlockType(blocktype) |
2255 |
2331 blockname = instance.getinstanceName() |
2256 classname = plcopen.ElementNameToClass[child.nodeName] |
2332 if blocktype_infos["type"] != "function" and blockname is not None: |
2257 if not self.CheckPasteCompatibility[bodytype](classname): |
2333 if element_type == "function": |
2258 return _("\"%s\" element can't be pasted here!!!")%child.nodeName |
2334 return _("FunctionBlock \"%s\" can't be pasted in a Function!!!")%blocktype |
2259 |
2335 blockname = self.GenerateNewName(tagname, |
2260 classobj = getattr(plcopen, classname, None) |
2336 blockname, |
2261 if classobj is not None: |
2337 "%s%%d"%blocktype, |
2262 instance = classobj() |
2338 debug=debug) |
2263 instance.loadXMLTree(child) |
2339 exclude[blockname] = True |
2264 if child.nodeName == "block": |
2340 instance.setinstanceName(blockname) |
2265 blockname = instance.getinstanceName() |
2341 self.AddEditedElementPouVar(tagname, blocktype, blockname) |
2266 if blockname is not None: |
2342 elif instance_type == "step": |
2267 blocktype = instance.gettypeName() |
2343 stepname = self.GenerateNewName(tagname, |
2268 if element_type == "function": |
2344 instance.getname(), |
2269 return _("FunctionBlock \"%s\" can't be pasted in a Function!!!")%blocktype |
2345 "Step%d", |
2270 blockname = self.GenerateNewName(tagname, |
2346 exclude=exclude, |
2271 blockname, |
2347 debug=debug) |
2272 "%s%%d"%blocktype, |
2348 exclude[stepname] = True |
2273 debug=debug) |
2349 instance.setname(stepname) |
2274 exclude[blockname] = True |
2350 localid = instance.getlocalId() |
2275 instance.setinstanceName(blockname) |
2351 if not used_id.has_key(localid): |
2276 self.AddEditedElementPouVar(tagname, blocktype, blockname) |
2352 new_id[localid] = True |
2277 elif child.nodeName == "step": |
|
2278 stepname = self.GenerateNewName(tagname, |
|
2279 instance.getname(), |
|
2280 "Step%d", |
|
2281 exclude=exclude, |
|
2282 debug=debug) |
|
2283 exclude[stepname] = True |
|
2284 instance.setname(stepname) |
|
2285 localid = instance.getlocalId() |
|
2286 if not used_id.has_key(localid): |
|
2287 new_id[localid] = True |
|
2288 instances.append((child.nodeName, instance)) |
|
2289 |
|
2290 if len(instances) == 0: |
|
2291 return _("Invalid plcopen element(s)!!!") |
|
2292 |
2353 |
2293 idx = 1 |
2354 idx = 1 |
2294 translate_id = {} |
2355 translate_id = {} |
2295 bbox = plcopen.rect() |
2356 bbox = rect() |
2296 for name, instance in instances: |
2357 for instance in instances: |
2297 localId = instance.getlocalId() |
2358 localId = instance.getlocalId() |
2298 bbox.union(instance.getBoundingBox()) |
2359 bbox.union(instance.getBoundingBox()) |
2299 if used_id.has_key(localId): |
2360 if used_id.has_key(localId): |
2300 while used_id.has_key(idx) or new_id.has_key(idx): |
2361 while used_id.has_key(idx) or new_id.has_key(idx): |
2301 idx += 1 |
2362 idx += 1 |
2321 miny *= scaling[1] |
2382 miny *= scaling[1] |
2322 new_pos = (max(minx, round(new_pos[0] / scaling[0]) * scaling[0]), |
2383 new_pos = (max(minx, round(new_pos[0] / scaling[0]) * scaling[0]), |
2323 max(miny, round(new_pos[1] / scaling[1]) * scaling[1])) |
2384 max(miny, round(new_pos[1] / scaling[1]) * scaling[1])) |
2324 else: |
2385 else: |
2325 new_pos = (max(30, new_pos[0]), max(30, new_pos[1])) |
2386 new_pos = (max(30, new_pos[0]), max(30, new_pos[1])) |
2326 diff = (new_pos[0] - x, new_pos[1] - y) |
2387 diff = (int(new_pos[0] - x), int(new_pos[1] - y)) |
2327 |
2388 |
2328 connections = {} |
2389 connections = {} |
2329 for name, instance in instances: |
2390 for instance in instances: |
2330 connections.update(instance.updateConnectionsId(translate_id)) |
2391 connections.update(instance.updateConnectionsId(translate_id)) |
2331 if getattr(instance, "setexecutionOrderId", None) is not None: |
2392 if getattr(instance, "setexecutionOrderId", None) is not None: |
2332 instance.setexecutionOrderId(0) |
2393 instance.setexecutionOrderId(0) |
2333 instance.translate(*diff) |
2394 instance.translate(*diff) |
2334 element.addinstance(name, instance) |
|
2335 |
2395 |
2336 return new_id, connections |
2396 return new_id, connections |
2337 |
2397 |
2338 # Return the current pou editing informations |
2398 def GetEditedElementInstancesInfos(self, tagname, debug = False): |
2339 def GetEditedElementInstanceInfos(self, tagname, id = None, exclude = [], debug = False): |
2399 element_instances = OrderedDict() |
2340 infos = {} |
|
2341 instance = None |
|
2342 element = self.GetEditedElement(tagname, debug) |
2400 element = self.GetEditedElement(tagname, debug) |
2343 if element is not None: |
2401 if element is not None: |
2344 # if id is defined |
2402 factory = BlockInstanceFactory(element_instances) |
2345 if id is not None: |
2403 |
2346 instance = element.getinstance(id) |
2404 pou_block_instances_xslt_tree = etree.XSLT( |
2347 else: |
2405 pou_block_instances_xslt, |
2348 instance = element.getrandomInstance(exclude) |
2406 extensions = { |
2349 if instance is not None: |
2407 ("pou_block_instances_ns", name): getattr(factory, name) |
2350 infos = instance.getinfos() |
2408 for name in ["AddBlockInstance", "SetSpecificValues", |
2351 if infos["type"] in ["input", "output", "inout"]: |
2409 "AddInstanceConnection", "AddConnectionLink", |
2352 var_type = self.GetEditedElementVarValueType(tagname, infos["specific_values"]["name"], debug) |
2410 "AddLinkPoint", "AddAction"]}) |
2353 infos["specific_values"]["value_type"] = var_type |
2411 |
2354 return infos |
2412 pou_block_instances_xslt_tree(element) |
2355 return None |
2413 return element_instances |
2356 |
2414 |
2357 def ClearEditedElementExecutionOrder(self, tagname): |
2415 def ClearEditedElementExecutionOrder(self, tagname): |
2358 element = self.GetEditedElement(tagname) |
2416 element = self.GetEditedElement(tagname) |
2359 if element is not None: |
2417 if element is not None: |
2360 element.resetexecutionOrder() |
2418 element.resetexecutionOrder() |
2361 |
2419 |
2362 def ResetEditedElementExecutionOrder(self, tagname): |
2420 def ResetEditedElementExecutionOrder(self, tagname): |
2363 element = self.GetEditedElement(tagname) |
2421 element = self.GetEditedElement(tagname) |
2364 if element is not None: |
2422 if element is not None: |
2365 element.compileexecutionOrder() |
2423 element.compileexecutionOrder() |
2366 |
|
2367 # Return the variable type of the given pou |
|
2368 def GetEditedElementVarValueType(self, tagname, varname, debug = False): |
|
2369 project = self.GetProject(debug) |
|
2370 if project is not None: |
|
2371 words = tagname.split("::") |
|
2372 if words[0] in ["P","T","A"]: |
|
2373 pou = self.Project.getpou(words[1]) |
|
2374 if pou is not None: |
|
2375 if words[0] == "T" and varname == words[2]: |
|
2376 return "BOOL" |
|
2377 if words[1] == varname: |
|
2378 return self.GetPouInterfaceReturnType(pou) |
|
2379 for type, varlist in pou.getvars(): |
|
2380 for var in varlist.getvariable(): |
|
2381 if var.getname() == varname: |
|
2382 vartype_content = var.gettype().getcontent() |
|
2383 if vartype_content["name"] == "derived": |
|
2384 return vartype_content["value"].getname() |
|
2385 elif vartype_content["name"] in ["string", "wstring"]: |
|
2386 return vartype_content["name"].upper() |
|
2387 else: |
|
2388 return vartype_content["name"] |
|
2389 return None |
|
2390 |
2424 |
2391 def SetConnectionWires(self, connection, connector): |
2425 def SetConnectionWires(self, connection, connector): |
2392 wires = connector.GetWires() |
2426 wires = connector.GetWires() |
2393 idx = 0 |
2427 idx = 0 |
2394 for wire, handle in wires: |
2428 for wire, handle in wires: |
2408 connection.setconnectionParameter(idx, formalParameter) |
2442 connection.setconnectionParameter(idx, formalParameter) |
2409 else: |
2443 else: |
2410 connection.setconnectionParameter(idx, None) |
2444 connection.setconnectionParameter(idx, None) |
2411 idx += 1 |
2445 idx += 1 |
2412 |
2446 |
2413 def AddEditedElementPouVar(self, tagname, type, name, location="", description=""): |
2447 def GetVarTypeObject(self, var_type): |
2448 var_type_obj = PLCOpenParser.CreateElement("type", "variable") |
|
2449 if not var_type.startswith("ANY") and TypeHierarchy.get(var_type): |
|
2450 var_type_obj.setcontent(PLCOpenParser.CreateElement( |
|
2451 var_type.lower() if var_type in ["STRING", "WSTRING"] |
|
2452 else var_type, "dataType")) |
|
2453 else: |
|
2454 derived_type = PLCOpenParser.CreateElement("derived", "dataType") |
|
2455 derived_type.setname(var_type) |
|
2456 var_type_obj.setcontent(derived_type) |
|
2457 return var_type_obj |
|
2458 |
|
2459 def AddEditedElementPouVar(self, tagname, var_type, name, location="", description=""): |
|
2414 if self.Project is not None: |
2460 if self.Project is not None: |
2415 words = tagname.split("::") |
2461 words = tagname.split("::") |
2416 if words[0] in ['P', 'T', 'A']: |
2462 if words[0] in ['P', 'T', 'A']: |
2417 pou = self.Project.getpou(words[1]) |
2463 pou = self.Project.getpou(words[1]) |
2418 if pou is not None: |
2464 if pou is not None: |
2419 pou.addpouLocalVar(type, name, location, description) |
2465 pou.addpouLocalVar( |
2420 |
2466 self.GetVarTypeObject(var_type), |
2421 def AddEditedElementPouExternalVar(self, tagname, type, name): |
2467 name, location, description) |
2468 |
|
2469 def AddEditedElementPouExternalVar(self, tagname, var_type, name): |
|
2422 if self.Project is not None: |
2470 if self.Project is not None: |
2423 words = tagname.split("::") |
2471 words = tagname.split("::") |
2424 if words[0] in ['P', 'T', 'A']: |
2472 if words[0] in ['P', 'T', 'A']: |
2425 pou = self.Project.getpou(words[1]) |
2473 pou = self.Project.getpou(words[1]) |
2426 if pou is not None: |
2474 if pou is not None: |
2427 pou.addpouExternalVar(type, name) |
2475 pou.addpouExternalVar( |
2476 self.GetVarTypeObject(var_type), name) |
|
2428 |
2477 |
2429 def ChangeEditedElementPouVar(self, tagname, old_type, old_name, new_type, new_name): |
2478 def ChangeEditedElementPouVar(self, tagname, old_type, old_name, new_type, new_name): |
2430 if self.Project is not None: |
2479 if self.Project is not None: |
2431 words = tagname.split("::") |
2480 words = tagname.split("::") |
2432 if words[0] in ['P', 'T', 'A']: |
2481 if words[0] in ['P', 'T', 'A']: |
2443 pou.removepouVar(type, name) |
2492 pou.removepouVar(type, name) |
2444 |
2493 |
2445 def AddEditedElementBlock(self, tagname, id, blocktype, blockname = None): |
2494 def AddEditedElementBlock(self, tagname, id, blocktype, blockname = None): |
2446 element = self.GetEditedElement(tagname) |
2495 element = self.GetEditedElement(tagname) |
2447 if element is not None: |
2496 if element is not None: |
2448 block = plcopen.fbdObjects_block() |
2497 block = PLCOpenParser.CreateElement("block", "fbdObjects") |
2449 block.setlocalId(id) |
2498 block.setlocalId(id) |
2450 block.settypeName(blocktype) |
2499 block.settypeName(blocktype) |
2451 blocktype_infos = self.GetBlockType(blocktype) |
2500 blocktype_infos = self.GetBlockType(blocktype) |
2452 if blocktype_infos["type"] != "function" and blockname is not None: |
2501 if blocktype_infos["type"] != "function" and blockname is not None: |
2453 block.setinstanceName(blockname) |
2502 block.setinstanceName(blockname) |
2454 self.AddEditedElementPouVar(tagname, blocktype, blockname) |
2503 self.AddEditedElementPouVar(tagname, blocktype, blockname) |
2455 element.addinstance("block", block) |
2504 element.addinstance(block) |
2456 self.Project.RefreshElementUsingTree() |
|
2457 |
2505 |
2458 def SetEditedElementBlockInfos(self, tagname, id, infos): |
2506 def SetEditedElementBlockInfos(self, tagname, id, infos): |
2459 element = self.GetEditedElement(tagname) |
2507 element = self.GetEditedElement(tagname) |
2460 if element is not None: |
2508 if element is not None: |
2461 block = element.getinstance(id) |
2509 block = element.getinstance(id) |
2479 self.ChangeEditedElementPouVar(tagname, old_type, old_name, new_type, new_name) |
2527 self.ChangeEditedElementPouVar(tagname, old_type, old_name, new_type, new_name) |
2480 elif new_name != old_name: |
2528 elif new_name != old_name: |
2481 self.ChangeEditedElementPouVar(tagname, old_type, old_name, new_type, new_name) |
2529 self.ChangeEditedElementPouVar(tagname, old_type, old_name, new_type, new_name) |
2482 for param, value in infos.items(): |
2530 for param, value in infos.items(): |
2483 if param == "name": |
2531 if param == "name": |
2484 block.setinstanceName(value) |
2532 if value != "": |
2533 block.setinstanceName(value) |
|
2534 else: |
|
2535 block.attrib.pop("instanceName", None) |
|
2485 elif param == "type": |
2536 elif param == "type": |
2486 block.settypeName(value) |
2537 block.settypeName(value) |
2487 elif param == "executionOrder" and block.getexecutionOrderId() != value: |
2538 elif param == "executionOrder" and block.getexecutionOrderId() != value: |
2488 element.setelementExecutionOrder(block, value) |
2539 element.setelementExecutionOrder(block, value) |
2489 elif param == "height": |
2540 elif param == "height": |
2496 block.sety(value) |
2547 block.sety(value) |
2497 elif param == "connectors": |
2548 elif param == "connectors": |
2498 block.inputVariables.setvariable([]) |
2549 block.inputVariables.setvariable([]) |
2499 block.outputVariables.setvariable([]) |
2550 block.outputVariables.setvariable([]) |
2500 for connector in value["inputs"]: |
2551 for connector in value["inputs"]: |
2501 variable = plcopen.inputVariables_variable() |
2552 variable = PLCOpenParser.CreateElement("variable", "inputVariables") |
2553 block.inputVariables.appendvariable(variable) |
|
2502 variable.setformalParameter(connector.GetName()) |
2554 variable.setformalParameter(connector.GetName()) |
2503 if connector.IsNegated(): |
2555 if connector.IsNegated(): |
2504 variable.setnegated(True) |
2556 variable.setnegated(True) |
2505 if connector.GetEdge() != "none": |
2557 if connector.GetEdge() != "none": |
2506 variable.setedge(connector.GetEdge()) |
2558 variable.setedge(connector.GetEdge()) |
2507 position = connector.GetRelPosition() |
2559 position = connector.GetRelPosition() |
2508 variable.connectionPointIn.setrelPositionXY(position.x, position.y) |
2560 variable.connectionPointIn.setrelPositionXY(position.x, position.y) |
2509 self.SetConnectionWires(variable.connectionPointIn, connector) |
2561 self.SetConnectionWires(variable.connectionPointIn, connector) |
2510 block.inputVariables.appendvariable(variable) |
|
2511 for connector in value["outputs"]: |
2562 for connector in value["outputs"]: |
2512 variable = plcopen.outputVariables_variable() |
2563 variable = PLCOpenParser.CreateElement("variable", "outputVariables") |
2564 block.outputVariables.appendvariable(variable) |
|
2513 variable.setformalParameter(connector.GetName()) |
2565 variable.setformalParameter(connector.GetName()) |
2514 if connector.IsNegated(): |
2566 if connector.IsNegated(): |
2515 variable.setnegated(True) |
2567 variable.setnegated(True) |
2516 if connector.GetEdge() != "none": |
2568 if connector.GetEdge() != "none": |
2517 variable.setedge(connector.GetEdge()) |
2569 variable.setedge(connector.GetEdge()) |
2518 position = connector.GetRelPosition() |
2570 position = connector.GetRelPosition() |
2519 variable.addconnectionPointOut() |
2571 variable.addconnectionPointOut() |
2520 variable.connectionPointOut.setrelPositionXY(position.x, position.y) |
2572 variable.connectionPointOut.setrelPositionXY(position.x, position.y) |
2521 block.outputVariables.appendvariable(variable) |
2573 block.tostring() |
2522 self.Project.RefreshElementUsingTree() |
2574 |
2523 |
2575 def AddEditedElementVariable(self, tagname, id, var_type): |
2524 def AddEditedElementVariable(self, tagname, id, type): |
|
2525 element = self.GetEditedElement(tagname) |
2576 element = self.GetEditedElement(tagname) |
2526 if element is not None: |
2577 if element is not None: |
2527 if type == INPUT: |
2578 variable = PLCOpenParser.CreateElement( |
2528 name = "inVariable" |
2579 {INPUT: "inVariable", |
2529 variable = plcopen.fbdObjects_inVariable() |
2580 OUTPUT: "outVariable", |
2530 elif type == OUTPUT: |
2581 INOUT: "inOutVariable"}[var_type], "fbdObjects") |
2531 name = "outVariable" |
|
2532 variable = plcopen.fbdObjects_outVariable() |
|
2533 elif type == INOUT: |
|
2534 name = "inOutVariable" |
|
2535 variable = plcopen.fbdObjects_inOutVariable() |
|
2536 variable.setlocalId(id) |
2582 variable.setlocalId(id) |
2537 element.addinstance(name, variable) |
2583 element.addinstance(variable) |
2538 |
2584 |
2539 def SetEditedElementVariableInfos(self, tagname, id, infos): |
2585 def SetEditedElementVariableInfos(self, tagname, id, infos): |
2540 element = self.GetEditedElement(tagname) |
2586 element = self.GetEditedElement(tagname) |
2541 if element is not None: |
2587 if element is not None: |
2542 variable = element.getinstance(id) |
2588 variable = element.getinstance(id) |
2543 if variable is None: |
2589 if variable is None: |
2544 return |
2590 return |
2545 for param, value in infos.items(): |
2591 for param, value in infos.items(): |
2546 if param == "name": |
2592 if param == "name": |
2547 variable.setexpression(value) |
2593 variable.setexpression(value) |
2548 elif param == "executionOrder" and variable.getexecutionOrderId() != value: |
2594 elif param == "executionOrder" and variable.getexecutionOrderId() != value: |
2549 element.setelementExecutionOrder(variable, value) |
2595 element.setelementExecutionOrder(variable, value) |
2550 elif param == "height": |
2596 elif param == "height": |
2551 variable.setheight(value) |
2597 variable.setheight(value) |
2552 elif param == "width": |
2598 elif param == "width": |
2578 position = input.GetRelPosition() |
2624 position = input.GetRelPosition() |
2579 variable.addconnectionPointIn() |
2625 variable.addconnectionPointIn() |
2580 variable.connectionPointIn.setrelPositionXY(position.x, position.y) |
2626 variable.connectionPointIn.setrelPositionXY(position.x, position.y) |
2581 self.SetConnectionWires(variable.connectionPointIn, input) |
2627 self.SetConnectionWires(variable.connectionPointIn, input) |
2582 |
2628 |
2583 def AddEditedElementConnection(self, tagname, id, type): |
2629 def AddEditedElementConnection(self, tagname, id, connection_type): |
2584 element = self.GetEditedElement(tagname) |
2630 element = self.GetEditedElement(tagname) |
2585 if element is not None: |
2631 if element is not None: |
2586 if type == CONNECTOR: |
2632 connection = PLCOpenParser.CreateElement( |
2587 name = "connector" |
2633 {CONNECTOR: "connector", |
2588 connection = plcopen.commonObjects_connector() |
2634 CONTINUATION: "continuation"}[connection_type], "commonObjects") |
2589 elif type == CONTINUATION: |
|
2590 name = "continuation" |
|
2591 connection = plcopen.commonObjects_continuation() |
|
2592 connection.setlocalId(id) |
2635 connection.setlocalId(id) |
2593 element.addinstance(name, connection) |
2636 element.addinstance(connection) |
2594 |
2637 |
2595 def SetEditedElementConnectionInfos(self, tagname, id, infos): |
2638 def SetEditedElementConnectionInfos(self, tagname, id, infos): |
2596 element = self.GetEditedElement(tagname) |
2639 element = self.GetEditedElement(tagname) |
2597 if element is not None: |
2640 if element is not None: |
2598 connection = element.getinstance(id) |
2641 connection = element.getinstance(id) |
2609 connection.setx(value) |
2652 connection.setx(value) |
2610 elif param == "y": |
2653 elif param == "y": |
2611 connection.sety(value) |
2654 connection.sety(value) |
2612 elif param == "connector": |
2655 elif param == "connector": |
2613 position = value.GetRelPosition() |
2656 position = value.GetRelPosition() |
2614 if isinstance(connection, plcopen.commonObjects_continuation): |
2657 if isinstance(connection, PLCOpenParser.GetElementClass("continuation", "commonObjects")): |
2615 connection.addconnectionPointOut() |
2658 connection.addconnectionPointOut() |
2616 connection.connectionPointOut.setrelPositionXY(position.x, position.y) |
2659 connection.connectionPointOut.setrelPositionXY(position.x, position.y) |
2617 elif isinstance(connection, plcopen.commonObjects_connector): |
2660 elif isinstance(connection, PLCOpenParser.GetElementClass("connector", "commonObjects")): |
2618 connection.addconnectionPointIn() |
2661 connection.addconnectionPointIn() |
2619 connection.connectionPointIn.setrelPositionXY(position.x, position.y) |
2662 connection.connectionPointIn.setrelPositionXY(position.x, position.y) |
2620 self.SetConnectionWires(connection.connectionPointIn, value) |
2663 self.SetConnectionWires(connection.connectionPointIn, value) |
2621 |
2664 |
2622 def AddEditedElementComment(self, tagname, id): |
2665 def AddEditedElementComment(self, tagname, id): |
2623 element = self.GetEditedElement(tagname) |
2666 element = self.GetEditedElement(tagname) |
2624 if element is not None: |
2667 if element is not None: |
2625 comment = plcopen.commonObjects_comment() |
2668 comment = PLCOpenParser.CreateElement("comment", "commonObjects") |
2626 comment.setlocalId(id) |
2669 comment.setlocalId(id) |
2627 element.addinstance("comment", comment) |
2670 element.addinstance(comment) |
2628 |
2671 |
2629 def SetEditedElementCommentInfos(self, tagname, id, infos): |
2672 def SetEditedElementCommentInfos(self, tagname, id, infos): |
2630 element = self.GetEditedElement(tagname) |
2673 element = self.GetEditedElement(tagname) |
2631 if element is not None: |
2674 if element is not None: |
2632 comment = element.getinstance(id) |
2675 comment = element.getinstance(id) |
2640 elif param == "x": |
2683 elif param == "x": |
2641 comment.setx(value) |
2684 comment.setx(value) |
2642 elif param == "y": |
2685 elif param == "y": |
2643 comment.sety(value) |
2686 comment.sety(value) |
2644 |
2687 |
2645 def AddEditedElementPowerRail(self, tagname, id, type): |
2688 def AddEditedElementPowerRail(self, tagname, id, powerrail_type): |
2646 element = self.GetEditedElement(tagname) |
2689 element = self.GetEditedElement(tagname) |
2647 if element is not None: |
2690 if element is not None: |
2648 if type == LEFTRAIL: |
2691 powerrail = PLCOpenParser.CreateElement( |
2649 name = "leftPowerRail" |
2692 {LEFTRAIL: "leftPowerRail", |
2650 powerrail = plcopen.ldObjects_leftPowerRail() |
2693 RIGHTRAIL: "rightPowerRail"}[powerrail_type], "ldObjects") |
2651 elif type == RIGHTRAIL: |
|
2652 name = "rightPowerRail" |
|
2653 powerrail = plcopen.ldObjects_rightPowerRail() |
|
2654 powerrail.setlocalId(id) |
2694 powerrail.setlocalId(id) |
2655 element.addinstance(name, powerrail) |
2695 element.addinstance(powerrail) |
2656 |
2696 |
2657 def SetEditedElementPowerRailInfos(self, tagname, id, infos): |
2697 def SetEditedElementPowerRailInfos(self, tagname, id, infos): |
2658 element = self.GetEditedElement(tagname) |
2698 element = self.GetEditedElement(tagname) |
2659 if element is not None: |
2699 if element is not None: |
2660 powerrail = element.getinstance(id) |
2700 powerrail = element.getinstance(id) |
2668 elif param == "x": |
2708 elif param == "x": |
2669 powerrail.setx(value) |
2709 powerrail.setx(value) |
2670 elif param == "y": |
2710 elif param == "y": |
2671 powerrail.sety(value) |
2711 powerrail.sety(value) |
2672 elif param == "connectors": |
2712 elif param == "connectors": |
2673 if isinstance(powerrail, plcopen.ldObjects_leftPowerRail): |
2713 if isinstance(powerrail, PLCOpenParser.GetElementClass("leftPowerRail", "ldObjects")): |
2674 powerrail.setconnectionPointOut([]) |
2714 powerrail.setconnectionPointOut([]) |
2675 for connector in value["outputs"]: |
2715 for connector in value["outputs"]: |
2676 position = connector.GetRelPosition() |
2716 position = connector.GetRelPosition() |
2677 connection = plcopen.leftPowerRail_connectionPointOut() |
2717 connection = PLCOpenParser.CreateElement("connectionPointOut", "leftPowerRail") |
2718 powerrail.appendconnectionPointOut(connection) |
|
2678 connection.setrelPositionXY(position.x, position.y) |
2719 connection.setrelPositionXY(position.x, position.y) |
2679 powerrail.connectionPointOut.append(connection) |
2720 elif isinstance(powerrail, PLCOpenParser.GetElementClass("rightPowerRail", "ldObjects")): |
2680 elif isinstance(powerrail, plcopen.ldObjects_rightPowerRail): |
|
2681 powerrail.setconnectionPointIn([]) |
2721 powerrail.setconnectionPointIn([]) |
2682 for connector in value["inputs"]: |
2722 for connector in value["inputs"]: |
2683 position = connector.GetRelPosition() |
2723 position = connector.GetRelPosition() |
2684 connection = plcopen.connectionPointIn() |
2724 connection = PLCOpenParser.CreateElement("connectionPointIn", "rightPowerRail") |
2725 powerrail.appendconnectionPointIn(connection) |
|
2685 connection.setrelPositionXY(position.x, position.y) |
2726 connection.setrelPositionXY(position.x, position.y) |
2686 self.SetConnectionWires(connection, connector) |
2727 self.SetConnectionWires(connection, connector) |
2687 powerrail.connectionPointIn.append(connection) |
2728 |
2688 |
|
2689 def AddEditedElementContact(self, tagname, id): |
2729 def AddEditedElementContact(self, tagname, id): |
2690 element = self.GetEditedElement(tagname) |
2730 element = self.GetEditedElement(tagname) |
2691 if element is not None: |
2731 if element is not None: |
2692 contact = plcopen.ldObjects_contact() |
2732 contact = PLCOpenParser.CreateElement("contact", "ldObjects") |
2693 contact.setlocalId(id) |
2733 contact.setlocalId(id) |
2694 element.addinstance("contact", contact) |
2734 element.addinstance(contact) |
2695 |
2735 |
2696 def SetEditedElementContactInfos(self, tagname, id, infos): |
2736 def SetEditedElementContactInfos(self, tagname, id, infos): |
2697 element = self.GetEditedElement(tagname) |
2737 element = self.GetEditedElement(tagname) |
2698 if element is not None: |
2738 if element is not None: |
2699 contact = element.getinstance(id) |
2739 contact = element.getinstance(id) |
2701 return |
2741 return |
2702 for param, value in infos.items(): |
2742 for param, value in infos.items(): |
2703 if param == "name": |
2743 if param == "name": |
2704 contact.setvariable(value) |
2744 contact.setvariable(value) |
2705 elif param == "type": |
2745 elif param == "type": |
2706 if value == CONTACT_NORMAL: |
2746 negated, edge = { |
2707 contact.setnegated(False) |
2747 CONTACT_NORMAL: (False, "none"), |
2708 contact.setedge("none") |
2748 CONTACT_REVERSE: (True, "none"), |
2709 elif value == CONTACT_REVERSE: |
2749 CONTACT_RISING: (False, "rising"), |
2710 contact.setnegated(True) |
2750 CONTACT_FALLING: (False, "falling")}[value] |
2711 contact.setedge("none") |
2751 contact.setnegated(negated) |
2712 elif value == CONTACT_RISING: |
2752 contact.setedge(edge) |
2713 contact.setnegated(False) |
|
2714 contact.setedge("rising") |
|
2715 elif value == CONTACT_FALLING: |
|
2716 contact.setnegated(False) |
|
2717 contact.setedge("falling") |
|
2718 elif param == "height": |
2753 elif param == "height": |
2719 contact.setheight(value) |
2754 contact.setheight(value) |
2720 elif param == "width": |
2755 elif param == "width": |
2721 contact.setwidth(value) |
2756 contact.setwidth(value) |
2722 elif param == "x": |
2757 elif param == "x": |
2735 contact.connectionPointOut.setrelPositionXY(position.x, position.y) |
2770 contact.connectionPointOut.setrelPositionXY(position.x, position.y) |
2736 |
2771 |
2737 def AddEditedElementCoil(self, tagname, id): |
2772 def AddEditedElementCoil(self, tagname, id): |
2738 element = self.GetEditedElement(tagname) |
2773 element = self.GetEditedElement(tagname) |
2739 if element is not None: |
2774 if element is not None: |
2740 coil = plcopen.ldObjects_coil() |
2775 coil = PLCOpenParser.CreateElement("coil", "ldObjects") |
2741 coil.setlocalId(id) |
2776 coil.setlocalId(id) |
2742 element.addinstance("coil", coil) |
2777 element.addinstance(coil) |
2743 |
2778 |
2744 def SetEditedElementCoilInfos(self, tagname, id, infos): |
2779 def SetEditedElementCoilInfos(self, tagname, id, infos): |
2745 element = self.GetEditedElement(tagname) |
2780 element = self.GetEditedElement(tagname) |
2746 if element is not None: |
2781 if element is not None: |
2747 coil = element.getinstance(id) |
2782 coil = element.getinstance(id) |
2749 return |
2784 return |
2750 for param, value in infos.items(): |
2785 for param, value in infos.items(): |
2751 if param == "name": |
2786 if param == "name": |
2752 coil.setvariable(value) |
2787 coil.setvariable(value) |
2753 elif param == "type": |
2788 elif param == "type": |
2754 if value == COIL_NORMAL: |
2789 negated, storage, edge = { |
2755 coil.setnegated(False) |
2790 COIL_NORMAL: (False, "none", "none"), |
2756 coil.setstorage("none") |
2791 COIL_REVERSE: (True, "none", "none"), |
2757 coil.setedge("none") |
2792 COIL_SET: (False, "set", "none"), |
2758 elif value == COIL_REVERSE: |
2793 COIL_RESET: (False, "reset", "none"), |
2759 coil.setnegated(True) |
2794 COIL_RISING: (False, "none", "rising"), |
2760 coil.setstorage("none") |
2795 COIL_FALLING: (False, "none", "falling")}[value] |
2761 coil.setedge("none") |
2796 coil.setnegated(negated) |
2762 elif value == COIL_SET: |
2797 coil.setstorage(storage) |
2763 coil.setnegated(False) |
2798 coil.setedge(edge) |
2764 coil.setstorage("set") |
|
2765 coil.setedge("none") |
|
2766 elif value == COIL_RESET: |
|
2767 coil.setnegated(False) |
|
2768 coil.setstorage("reset") |
|
2769 coil.setedge("none") |
|
2770 elif value == COIL_RISING: |
|
2771 coil.setnegated(False) |
|
2772 coil.setstorage("none") |
|
2773 coil.setedge("rising") |
|
2774 elif value == COIL_FALLING: |
|
2775 coil.setnegated(False) |
|
2776 coil.setstorage("none") |
|
2777 coil.setedge("falling") |
|
2778 elif param == "height": |
2799 elif param == "height": |
2779 coil.setheight(value) |
2800 coil.setheight(value) |
2780 elif param == "width": |
2801 elif param == "width": |
2781 coil.setwidth(value) |
2802 coil.setwidth(value) |
2782 elif param == "x": |
2803 elif param == "x": |
2795 coil.connectionPointOut.setrelPositionXY(position.x, position.y) |
2816 coil.connectionPointOut.setrelPositionXY(position.x, position.y) |
2796 |
2817 |
2797 def AddEditedElementStep(self, tagname, id): |
2818 def AddEditedElementStep(self, tagname, id): |
2798 element = self.GetEditedElement(tagname) |
2819 element = self.GetEditedElement(tagname) |
2799 if element is not None: |
2820 if element is not None: |
2800 step = plcopen.sfcObjects_step() |
2821 step = PLCOpenParser.CreateElement("step", "sfcObjects") |
2801 step.setlocalId(id) |
2822 step.setlocalId(id) |
2802 element.addinstance("step", step) |
2823 element.addinstance(step) |
2803 |
2824 |
2804 def SetEditedElementStepInfos(self, tagname, id, infos): |
2825 def SetEditedElementStepInfos(self, tagname, id, infos): |
2805 element = self.GetEditedElement(tagname) |
2826 element = self.GetEditedElement(tagname) |
2806 if element is not None: |
2827 if element is not None: |
2807 step = element.getinstance(id) |
2828 step = element.getinstance(id) |
2845 step.deleteconnectionPointOutAction() |
2866 step.deleteconnectionPointOutAction() |
2846 |
2867 |
2847 def AddEditedElementTransition(self, tagname, id): |
2868 def AddEditedElementTransition(self, tagname, id): |
2848 element = self.GetEditedElement(tagname) |
2869 element = self.GetEditedElement(tagname) |
2849 if element is not None: |
2870 if element is not None: |
2850 transition = plcopen.sfcObjects_transition() |
2871 transition = PLCOpenParser.CreateElement("transition", "sfcObjects") |
2851 transition.setlocalId(id) |
2872 transition.setlocalId(id) |
2852 element.addinstance("transition", transition) |
2873 element.addinstance(transition) |
2853 |
2874 |
2854 def SetEditedElementTransitionInfos(self, tagname, id, infos): |
2875 def SetEditedElementTransitionInfos(self, tagname, id, infos): |
2855 element = self.GetEditedElement(tagname) |
2876 element = self.GetEditedElement(tagname) |
2856 if element is not None: |
2877 if element is not None: |
2857 transition = element.getinstance(id) |
2878 transition = element.getinstance(id) |
2883 position = output_connector.GetRelPosition() |
2904 position = output_connector.GetRelPosition() |
2884 transition.addconnectionPointOut() |
2905 transition.addconnectionPointOut() |
2885 transition.connectionPointOut.setrelPositionXY(position.x, position.y) |
2906 transition.connectionPointOut.setrelPositionXY(position.x, position.y) |
2886 elif infos.get("type", None) == "connection" and param == "connection" and value: |
2907 elif infos.get("type", None) == "connection" and param == "connection" and value: |
2887 transition.setconditionContent("connection", None) |
2908 transition.setconditionContent("connection", None) |
2888 self.SetConnectionWires(transition.condition.content["value"], value) |
2909 self.SetConnectionWires(transition.condition.content, value) |
2889 |
2910 |
2890 def AddEditedElementDivergence(self, tagname, id, type): |
2911 def AddEditedElementDivergence(self, tagname, id, divergence_type): |
2891 element = self.GetEditedElement(tagname) |
2912 element = self.GetEditedElement(tagname) |
2892 if element is not None: |
2913 if element is not None: |
2893 if type == SELECTION_DIVERGENCE: |
2914 divergence = PLCOpenParser.CreateElement( |
2894 name = "selectionDivergence" |
2915 {SELECTION_DIVERGENCE: "selectionDivergence", |
2895 divergence = plcopen.sfcObjects_selectionDivergence() |
2916 SELECTION_CONVERGENCE: "selectionConvergence", |
2896 elif type == SELECTION_CONVERGENCE: |
2917 SIMULTANEOUS_DIVERGENCE: "simultaneousDivergence", |
2897 name = "selectionConvergence" |
2918 SIMULTANEOUS_CONVERGENCE: "simultaneousConvergence"}.get( |
2898 divergence = plcopen.sfcObjects_selectionConvergence() |
2919 divergence_type), "sfcObjects") |
2899 elif type == SIMULTANEOUS_DIVERGENCE: |
|
2900 name = "simultaneousDivergence" |
|
2901 divergence = plcopen.sfcObjects_simultaneousDivergence() |
|
2902 elif type == SIMULTANEOUS_CONVERGENCE: |
|
2903 name = "simultaneousConvergence" |
|
2904 divergence = plcopen.sfcObjects_simultaneousConvergence() |
|
2905 divergence.setlocalId(id) |
2920 divergence.setlocalId(id) |
2906 element.addinstance(name, divergence) |
2921 element.addinstance(divergence) |
2922 |
|
2923 DivergenceTypes = [ |
|
2924 (divergence_type, |
|
2925 PLCOpenParser.GetElementClass(divergence_type, "sfcObjects")) |
|
2926 for divergence_type in ["selectionDivergence", "simultaneousDivergence", |
|
2927 "selectionConvergence", "simultaneousConvergence"]] |
|
2928 |
|
2929 def GetDivergenceType(self, divergence): |
|
2930 for divergence_type, divergence_class in self.DivergenceTypes: |
|
2931 if isinstance(divergence, divergence_class): |
|
2932 return divergence_type |
|
2933 return None |
|
2907 |
2934 |
2908 def SetEditedElementDivergenceInfos(self, tagname, id, infos): |
2935 def SetEditedElementDivergenceInfos(self, tagname, id, infos): |
2909 element = self.GetEditedElement(tagname) |
2936 element = self.GetEditedElement(tagname) |
2910 if element is not None: |
2937 if element is not None: |
2911 divergence = element.getinstance(id) |
2938 divergence = element.getinstance(id) |
2920 divergence.setx(value) |
2947 divergence.setx(value) |
2921 elif param == "y": |
2948 elif param == "y": |
2922 divergence.sety(value) |
2949 divergence.sety(value) |
2923 elif param == "connectors": |
2950 elif param == "connectors": |
2924 input_connectors = value["inputs"] |
2951 input_connectors = value["inputs"] |
2925 if isinstance(divergence, (plcopen.sfcObjects_selectionDivergence, plcopen.sfcObjects_simultaneousDivergence)): |
2952 divergence_type = self.GetDivergenceType(divergence) |
2953 if divergence_type in ["selectionDivergence", "simultaneousDivergence"]: |
|
2926 position = input_connectors[0].GetRelPosition() |
2954 position = input_connectors[0].GetRelPosition() |
2927 divergence.addconnectionPointIn() |
2955 divergence.addconnectionPointIn() |
2928 divergence.connectionPointIn.setrelPositionXY(position.x, position.y) |
2956 divergence.connectionPointIn.setrelPositionXY(position.x, position.y) |
2929 self.SetConnectionWires(divergence.connectionPointIn, input_connectors[0]) |
2957 self.SetConnectionWires(divergence.connectionPointIn, input_connectors[0]) |
2930 else: |
2958 else: |
2931 divergence.setconnectionPointIn([]) |
2959 divergence.setconnectionPointIn([]) |
2932 for input_connector in input_connectors: |
2960 for input_connector in input_connectors: |
2933 position = input_connector.GetRelPosition() |
2961 position = input_connector.GetRelPosition() |
2934 if isinstance(divergence, plcopen.sfcObjects_selectionConvergence): |
2962 connection = PLCOpenParser.CreateElement("connectionPointIn", divergence_type) |
2935 connection = plcopen.selectionConvergence_connectionPointIn() |
2963 divergence.appendconnectionPointIn(connection) |
2936 else: |
|
2937 connection = plcopen.connectionPointIn() |
|
2938 connection.setrelPositionXY(position.x, position.y) |
2964 connection.setrelPositionXY(position.x, position.y) |
2939 self.SetConnectionWires(connection, input_connector) |
2965 self.SetConnectionWires(connection, input_connector) |
2940 divergence.appendconnectionPointIn(connection) |
|
2941 output_connectors = value["outputs"] |
2966 output_connectors = value["outputs"] |
2942 if isinstance(divergence, (plcopen.sfcObjects_selectionConvergence, plcopen.sfcObjects_simultaneousConvergence)): |
2967 if divergence_type in ["selectionConvergence", "simultaneousConvergence"]: |
2943 position = output_connectors[0].GetRelPosition() |
2968 position = output_connectors[0].GetRelPosition() |
2944 divergence.addconnectionPointOut() |
2969 divergence.addconnectionPointOut() |
2945 divergence.connectionPointOut.setrelPositionXY(position.x, position.y) |
2970 divergence.connectionPointOut.setrelPositionXY(position.x, position.y) |
2946 else: |
2971 else: |
2947 divergence.setconnectionPointOut([]) |
2972 divergence.setconnectionPointOut([]) |
2948 for output_connector in output_connectors: |
2973 for output_connector in output_connectors: |
2949 position = output_connector.GetRelPosition() |
2974 position = output_connector.GetRelPosition() |
2950 if isinstance(divergence, plcopen.sfcObjects_selectionDivergence): |
2975 connection = PLCOpenParser.CreateElement("connectionPointOut", divergence_type) |
2951 connection = plcopen.selectionDivergence_connectionPointOut() |
2976 divergence.appendconnectionPointOut(connection) |
2952 else: |
|
2953 connection = plcopen.simultaneousDivergence_connectionPointOut() |
|
2954 connection.setrelPositionXY(position.x, position.y) |
2977 connection.setrelPositionXY(position.x, position.y) |
2955 divergence.appendconnectionPointOut(connection) |
2978 |
2956 |
|
2957 def AddEditedElementJump(self, tagname, id): |
2979 def AddEditedElementJump(self, tagname, id): |
2958 element = self.GetEditedElement(tagname) |
2980 element = self.GetEditedElement(tagname) |
2959 if element is not None: |
2981 if element is not None: |
2960 jump = plcopen.sfcObjects_jumpStep() |
2982 jump = PLCOpenParser.CreateElement("jumpStep", "sfcObjects") |
2961 jump.setlocalId(id) |
2983 jump.setlocalId(id) |
2962 element.addinstance("jumpStep", jump) |
2984 element.addinstance(jump) |
2963 |
2985 |
2964 def SetEditedElementJumpInfos(self, tagname, id, infos): |
2986 def SetEditedElementJumpInfos(self, tagname, id, infos): |
2965 element = self.GetEditedElement(tagname) |
2987 element = self.GetEditedElement(tagname) |
2966 if element is not None: |
2988 if element is not None: |
2967 jump = element.getinstance(id) |
2989 jump = element.getinstance(id) |
2985 self.SetConnectionWires(jump.connectionPointIn, value) |
3007 self.SetConnectionWires(jump.connectionPointIn, value) |
2986 |
3008 |
2987 def AddEditedElementActionBlock(self, tagname, id): |
3009 def AddEditedElementActionBlock(self, tagname, id): |
2988 element = self.GetEditedElement(tagname) |
3010 element = self.GetEditedElement(tagname) |
2989 if element is not None: |
3011 if element is not None: |
2990 actionBlock = plcopen.commonObjects_actionBlock() |
3012 actionBlock = PLCOpenParser.CreateElement("actionBlock", "commonObjects") |
2991 actionBlock.setlocalId(id) |
3013 actionBlock.setlocalId(id) |
2992 element.addinstance("actionBlock", actionBlock) |
3014 element.addinstance(actionBlock) |
2993 |
3015 |
2994 def SetEditedElementActionBlockInfos(self, tagname, id, infos): |
3016 def SetEditedElementActionBlockInfos(self, tagname, id, infos): |
2995 element = self.GetEditedElement(tagname) |
3017 element = self.GetEditedElement(tagname) |
2996 if element is not None: |
3018 if element is not None: |
2997 actionBlock = element.getinstance(id) |
3019 actionBlock = element.getinstance(id) |
3016 |
3038 |
3017 def RemoveEditedElementInstance(self, tagname, id): |
3039 def RemoveEditedElementInstance(self, tagname, id): |
3018 element = self.GetEditedElement(tagname) |
3040 element = self.GetEditedElement(tagname) |
3019 if element is not None: |
3041 if element is not None: |
3020 instance = element.getinstance(id) |
3042 instance = element.getinstance(id) |
3021 if isinstance(instance, plcopen.fbdObjects_block): |
3043 if isinstance(instance, PLCOpenParser.GetElementClass("block", "fbdObjects")): |
3022 self.RemoveEditedElementPouVar(tagname, instance.gettypeName(), instance.getinstanceName()) |
3044 self.RemoveEditedElementPouVar(tagname, instance.gettypeName(), instance.getinstanceName()) |
3023 element.removeinstance(id) |
3045 element.removeinstance(id) |
3024 self.Project.RefreshElementUsingTree() |
|
3025 |
3046 |
3026 def GetEditedResourceVariables(self, tagname, debug = False): |
3047 def GetEditedResourceVariables(self, tagname, debug = False): |
3027 varlist = [] |
3048 varlist = [] |
3028 words = tagname.split("::") |
3049 words = tagname.split("::") |
3029 for var in self.GetConfigurationGlobalVars(words[1], debug): |
3050 for var in self.GetConfigurationGlobalVars(words[1], debug): |
3030 if var["Type"] == "BOOL": |
3051 if var.Type == "BOOL": |
3031 varlist.append(var["Name"]) |
3052 varlist.append(var.Name) |
3032 for var in self.GetConfigurationResourceGlobalVars(words[1], words[2], debug): |
3053 for var in self.GetConfigurationResourceGlobalVars(words[1], words[2], debug): |
3033 if var["Type"] == "BOOL": |
3054 if var.Type == "BOOL": |
3034 varlist.append(var["Name"]) |
3055 varlist.append(var.Name) |
3035 return varlist |
3056 return varlist |
3036 |
3057 |
3037 def SetEditedResourceInfos(self, tagname, tasks, instances): |
3058 def SetEditedResourceInfos(self, tagname, tasks, instances): |
3038 resource = self.GetEditedElement(tagname) |
3059 resource = self.GetEditedElement(tagname) |
3039 if resource is not None: |
3060 if resource is not None: |
3040 resource.settask([]) |
3061 resource.settask([]) |
3041 resource.setpouInstance([]) |
3062 resource.setpouInstance([]) |
3042 task_list = {} |
3063 task_list = {} |
3043 for task in tasks: |
3064 for task in tasks: |
3044 new_task = plcopen.resource_task() |
3065 new_task = PLCOpenParser.CreateElement("task", "resource") |
3066 resource.appendtask(new_task) |
|
3045 new_task.setname(task["Name"]) |
3067 new_task.setname(task["Name"]) |
3046 if task["Triggering"] == "Interrupt": |
3068 if task["Triggering"] == "Interrupt": |
3047 new_task.setsingle(task["Single"]) |
3069 new_task.setsingle(task["Single"]) |
3048 ## result = duration_model.match(task["Interval"]).groups() |
3070 ## result = duration_model.match(task["Interval"]).groups() |
3049 ## if reduce(lambda x, y: x or y != None, result): |
3071 ## if reduce(lambda x, y: x or y != None, result): |
3059 if task["Triggering"] == "Cyclic": |
3081 if task["Triggering"] == "Cyclic": |
3060 new_task.setinterval(task["Interval"]) |
3082 new_task.setinterval(task["Interval"]) |
3061 new_task.setpriority(int(task["Priority"])) |
3083 new_task.setpriority(int(task["Priority"])) |
3062 if task["Name"] != "": |
3084 if task["Name"] != "": |
3063 task_list[task["Name"]] = new_task |
3085 task_list[task["Name"]] = new_task |
3064 resource.appendtask(new_task) |
|
3065 for instance in instances: |
3086 for instance in instances: |
3066 new_instance = plcopen.pouInstance() |
3087 task = task_list.get(instance["Task"]) |
3088 if task is not None: |
|
3089 new_instance = PLCOpenParser.CreateElement("pouInstance", "task") |
|
3090 task.appendpouInstance(new_instance) |
|
3091 else: |
|
3092 new_instance = PLCOpenParser.CreateElement("pouInstance", "resource") |
|
3093 resource.appendpouInstance(new_instance) |
|
3067 new_instance.setname(instance["Name"]) |
3094 new_instance.setname(instance["Name"]) |
3068 new_instance.settypeName(instance["Type"]) |
3095 new_instance.settypeName(instance["Type"]) |
3069 task_list.get(instance["Task"], resource).appendpouInstance(new_instance) |
|
3070 |
3096 |
3071 def GetEditedResourceInfos(self, tagname, debug = False): |
3097 def GetEditedResourceInfos(self, tagname, debug = False): |
3072 resource = self.GetEditedElement(tagname, debug) |
3098 resource = self.GetEditedElement(tagname, debug) |
3073 if resource is not None: |
3099 if resource is not None: |
3074 tasks = resource.gettask() |
3100 tasks = resource.gettask() |
3122 new_instance["Task"] = "" |
3148 new_instance["Task"] = "" |
3123 instances_data.append(new_instance) |
3149 instances_data.append(new_instance) |
3124 return tasks_data, instances_data |
3150 return tasks_data, instances_data |
3125 |
3151 |
3126 def OpenXMLFile(self, filepath): |
3152 def OpenXMLFile(self, filepath): |
3127 xmlfile = open(filepath, 'r') |
3153 self.Project, error = LoadProject(filepath) |
3128 tree = minidom.parse(xmlfile) |
3154 if self.Project is None: |
3129 xmlfile.close() |
3155 return _("Project file syntax error:\n\n") + error |
3130 |
3156 self.SetFilePath(filepath) |
3131 self.Project = plcopen.project() |
3157 self.CreateProjectBuffer(True) |
3132 for child in tree.childNodes: |
3158 self.ProgramChunks = [] |
3133 if child.nodeType == tree.ELEMENT_NODE and child.nodeName == "project": |
3159 self.ProgramOffset = 0 |
3134 try: |
3160 self.NextCompiledProject = self.Copy(self.Project) |
3135 result = self.Project.loadXMLTree(child) |
3161 self.CurrentCompiledProject = None |
3136 except ValueError, e: |
3162 self.Buffering = False |
3137 return _("Project file syntax error:\n\n") + str(e) |
3163 self.CurrentElementEditing = None |
3138 self.SetFilePath(filepath) |
3164 return error |
3139 self.Project.RefreshElementUsingTree() |
3165 |
3140 self.Project.RefreshDataTypeHierarchy() |
|
3141 self.Project.RefreshCustomBlockTypes() |
|
3142 self.CreateProjectBuffer(True) |
|
3143 self.ProgramChunks = [] |
|
3144 self.ProgramOffset = 0 |
|
3145 self.NextCompiledProject = self.Copy(self.Project) |
|
3146 self.CurrentCompiledProject = None |
|
3147 self.Buffering = False |
|
3148 self.CurrentElementEditing = None |
|
3149 return None |
|
3150 return _("No PLC project found") |
|
3151 |
|
3152 def SaveXMLFile(self, filepath = None): |
3166 def SaveXMLFile(self, filepath = None): |
3153 if not filepath and self.FilePath == "": |
3167 if not filepath and self.FilePath == "": |
3154 return False |
3168 return False |
3155 else: |
3169 else: |
3156 contentheader = {"modificationDateTime": datetime.datetime(*localtime()[:6])} |
3170 contentheader = {"modificationDateTime": datetime.datetime(*localtime()[:6])} |
3157 self.Project.setcontentHeader(contentheader) |
3171 self.Project.setcontentHeader(contentheader) |
3158 |
3172 |
3159 text = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" |
3173 if filepath: |
3160 extras = {"xmlns" : "http://www.plcopen.org/xml/tc6.xsd", |
3174 SaveProject(self.Project, filepath) |
3161 "xmlns:xhtml" : "http://www.w3.org/1999/xhtml", |
3175 else: |
3162 "xmlns:xsi" : "http://www.w3.org/2001/XMLSchema-instance", |
3176 SaveProject(self.Project, self.FilePath) |
3163 "xsi:schemaLocation" : "http://www.plcopen.org/xml/tc6.xsd"} |
|
3164 text += self.Project.generateXMLText("project", 0, extras) |
|
3165 |
3177 |
3166 if filepath: |
|
3167 xmlfile = open(filepath,"w") |
|
3168 else: |
|
3169 xmlfile = open(self.FilePath,"w") |
|
3170 xmlfile.write(text.encode("utf-8")) |
|
3171 xmlfile.close() |
|
3172 self.MarkProjectAsSaved() |
3178 self.MarkProjectAsSaved() |
3173 if filepath: |
3179 if filepath: |
3174 self.SetFilePath(filepath) |
3180 self.SetFilePath(filepath) |
3175 return True |
3181 return True |
3176 |
3182 |
3193 |
3199 |
3194 """ |
3200 """ |
3195 Return a copy of the project |
3201 Return a copy of the project |
3196 """ |
3202 """ |
3197 def Copy(self, model): |
3203 def Copy(self, model): |
3198 return cPickle.loads(cPickle.dumps(model)) |
3204 return deepcopy(model) |
3199 |
3205 |
3200 def CreateProjectBuffer(self, saved): |
3206 def CreateProjectBuffer(self, saved): |
3201 if self.ProjectBufferEnabled: |
3207 if self.ProjectBufferEnabled: |
3202 self.ProjectBuffer = UndoBuffer(cPickle.dumps(self.Project), saved) |
3208 self.ProjectBuffer = UndoBuffer(PLCOpenParser.Dumps(self.Project), saved) |
3203 else: |
3209 else: |
3204 self.ProjectBuffer = None |
3210 self.ProjectBuffer = None |
3205 self.ProjectSaved = saved |
3211 self.ProjectSaved = saved |
3206 |
3212 |
3207 def IsProjectBufferEnabled(self): |
3213 def IsProjectBufferEnabled(self): |
3216 current_saved = self.ProjectBuffer.IsCurrentSaved() |
3222 current_saved = self.ProjectBuffer.IsCurrentSaved() |
3217 self.CreateProjectBuffer(current_saved) |
3223 self.CreateProjectBuffer(current_saved) |
3218 |
3224 |
3219 def BufferProject(self): |
3225 def BufferProject(self): |
3220 if self.ProjectBuffer is not None: |
3226 if self.ProjectBuffer is not None: |
3221 self.ProjectBuffer.Buffering(cPickle.dumps(self.Project)) |
3227 self.ProjectBuffer.Buffering(PLCOpenParser.Dumps(self.Project)) |
3222 else: |
3228 else: |
3223 self.ProjectSaved = False |
3229 self.ProjectSaved = False |
3224 |
3230 |
3225 def StartBuffering(self): |
3231 def StartBuffering(self): |
3226 if self.ProjectBuffer is not None: |
3232 if self.ProjectBuffer is not None: |
3228 else: |
3234 else: |
3229 self.ProjectSaved = False |
3235 self.ProjectSaved = False |
3230 |
3236 |
3231 def EndBuffering(self): |
3237 def EndBuffering(self): |
3232 if self.ProjectBuffer is not None and self.Buffering: |
3238 if self.ProjectBuffer is not None and self.Buffering: |
3233 self.ProjectBuffer.Buffering(cPickle.dumps(self.Project)) |
3239 self.ProjectBuffer.Buffering(PLCOpenParser.Dumps(self.Project)) |
3234 self.Buffering = False |
3240 self.Buffering = False |
3235 |
3241 |
3236 def MarkProjectAsSaved(self): |
3242 def MarkProjectAsSaved(self): |
3237 self.EndBuffering() |
3243 self.EndBuffering() |
3238 if self.ProjectBuffer is not None: |
3244 if self.ProjectBuffer is not None: |
3248 return self.ProjectSaved |
3254 return self.ProjectSaved |
3249 |
3255 |
3250 def LoadPrevious(self): |
3256 def LoadPrevious(self): |
3251 self.EndBuffering() |
3257 self.EndBuffering() |
3252 if self.ProjectBuffer is not None: |
3258 if self.ProjectBuffer is not None: |
3253 self.Project = cPickle.loads(self.ProjectBuffer.Previous()) |
3259 self.Project = PLCOpenParser.Loads(self.ProjectBuffer.Previous()) |
3254 |
3260 |
3255 def LoadNext(self): |
3261 def LoadNext(self): |
3256 if self.ProjectBuffer is not None: |
3262 if self.ProjectBuffer is not None: |
3257 self.Project = cPickle.loads(self.ProjectBuffer.Next()) |
3263 self.Project = PLCOpenParser.Loads(self.ProjectBuffer.Next()) |
3258 |
3264 |
3259 def GetBufferState(self): |
3265 def GetBufferState(self): |
3260 if self.ProjectBuffer is not None: |
3266 if self.ProjectBuffer is not None: |
3261 first = self.ProjectBuffer.IsFirst() and not self.Buffering |
3267 first = self.ProjectBuffer.IsFirst() and not self.Buffering |
3262 last = self.ProjectBuffer.IsLast() |
3268 last = self.ProjectBuffer.IsLast() |