25 |
25 |
26 from xml.dom import minidom |
26 from xml.dom import minidom |
27 from types import StringType, UnicodeType, TupleType |
27 from types import StringType, UnicodeType, TupleType |
28 from lxml import etree |
28 from lxml import etree |
29 from copy import deepcopy |
29 from copy import deepcopy |
30 import os,sys,re |
30 import os |
|
31 import sys |
|
32 import re |
31 import datetime |
33 import datetime |
32 import util.paths as paths |
34 import util.paths as paths |
33 from time import localtime |
35 from time import localtime |
34 from collections import OrderedDict, namedtuple |
36 from collections import OrderedDict, namedtuple |
35 |
37 from util.TranslationCatalogs import NoTranslate |
36 from plcopen import * |
38 from plcopen import * |
37 from graphics.GraphicCommons import * |
39 from graphics.GraphicCommons import * |
38 from PLCGenerator import * |
40 from PLCGenerator import * |
39 |
41 |
40 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)?") |
42 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)?") |
41 |
43 |
42 ITEMS_EDITABLE = [ITEM_PROJECT, |
44 ITEMS_EDITABLE = [ |
43 ITEM_POU, |
45 ITEM_PROJECT, |
44 ITEM_VARIABLE, |
46 ITEM_POU, |
45 ITEM_TRANSITION, |
47 ITEM_VARIABLE, |
46 ITEM_ACTION, |
48 ITEM_TRANSITION, |
47 ITEM_CONFIGURATION, |
49 ITEM_ACTION, |
48 ITEM_RESOURCE, |
50 ITEM_CONFIGURATION, |
49 ITEM_DATATYPE |
51 ITEM_RESOURCE, |
50 ] = range(8) |
52 ITEM_DATATYPE |
51 |
53 ] = range(8) |
52 ITEMS_UNEDITABLE = [ITEM_DATATYPES, |
54 |
53 ITEM_FUNCTION, |
55 ITEMS_UNEDITABLE = [ |
54 ITEM_FUNCTIONBLOCK, |
56 ITEM_DATATYPES, |
55 ITEM_PROGRAM, |
57 ITEM_FUNCTION, |
56 ITEM_TRANSITIONS, |
58 ITEM_FUNCTIONBLOCK, |
57 ITEM_ACTIONS, |
59 ITEM_PROGRAM, |
58 ITEM_CONFIGURATIONS, |
60 ITEM_TRANSITIONS, |
59 ITEM_RESOURCES, |
61 ITEM_ACTIONS, |
60 ITEM_PROPERTIES |
62 ITEM_CONFIGURATIONS, |
61 ] = range(8, 17) |
63 ITEM_RESOURCES, |
62 |
64 ITEM_PROPERTIES |
63 ITEMS_VARIABLE = [ITEM_VAR_LOCAL, |
65 ] = range(8, 17) |
64 ITEM_VAR_GLOBAL, |
66 |
65 ITEM_VAR_EXTERNAL, |
67 ITEMS_VARIABLE = [ |
66 ITEM_VAR_TEMP, |
68 ITEM_VAR_LOCAL, |
67 ITEM_VAR_INPUT, |
69 ITEM_VAR_GLOBAL, |
68 ITEM_VAR_OUTPUT, |
70 ITEM_VAR_EXTERNAL, |
69 ITEM_VAR_INOUT |
71 ITEM_VAR_TEMP, |
70 ] = range(17, 24) |
72 ITEM_VAR_INPUT, |
|
73 ITEM_VAR_OUTPUT, |
|
74 ITEM_VAR_INOUT |
|
75 ] = range(17, 24) |
71 |
76 |
72 VAR_CLASS_INFOS = { |
77 VAR_CLASS_INFOS = { |
73 "Local": ("localVars", ITEM_VAR_LOCAL), |
78 "Local": ("localVars", ITEM_VAR_LOCAL), |
74 "Global": ("globalVars", ITEM_VAR_GLOBAL), |
79 "Global": ("globalVars", ITEM_VAR_GLOBAL), |
75 "External": ("externalVars", ITEM_VAR_EXTERNAL), |
80 "External": ("externalVars", ITEM_VAR_EXTERNAL), |
76 "Temp": ("tempVars", ITEM_VAR_TEMP), |
81 "Temp": ("tempVars", ITEM_VAR_TEMP), |
77 "Input": ("inputVars", ITEM_VAR_INPUT), |
82 "Input": ("inputVars", ITEM_VAR_INPUT), |
78 "Output": ("outputVars", ITEM_VAR_OUTPUT), |
83 "Output": ("outputVars", ITEM_VAR_OUTPUT), |
79 "InOut": ("inOutVars", ITEM_VAR_INOUT)} |
84 "InOut": ("inOutVars", ITEM_VAR_INOUT)} |
80 |
85 |
81 POU_TYPES = {"program": ITEM_PROGRAM, |
86 POU_TYPES = { |
82 "functionBlock": ITEM_FUNCTIONBLOCK, |
87 "program": ITEM_PROGRAM, |
83 "function": ITEM_FUNCTION, |
88 "functionBlock": ITEM_FUNCTIONBLOCK, |
84 } |
89 "function": ITEM_FUNCTION, |
|
90 } |
85 |
91 |
86 LOCATIONS_ITEMS = [LOCATION_CONFNODE, |
92 LOCATIONS_ITEMS = [LOCATION_CONFNODE, |
87 LOCATION_MODULE, |
93 LOCATION_MODULE, |
88 LOCATION_GROUP, |
94 LOCATION_GROUP, |
89 LOCATION_VAR_INPUT, |
95 LOCATION_VAR_INPUT, |
90 LOCATION_VAR_OUTPUT, |
96 LOCATION_VAR_OUTPUT, |
91 LOCATION_VAR_MEMORY] = range(6) |
97 LOCATION_VAR_MEMORY] = range(6) |
92 |
98 |
93 ScriptDirectory = paths.AbsDir(__file__) |
99 ScriptDirectory = paths.AbsDir(__file__) |
94 |
100 |
|
101 |
95 def GetUneditableNames(): |
102 def GetUneditableNames(): |
96 _ = lambda x:x |
103 _ = NoTranslate |
97 return [_("User-defined POUs"), _("Functions"), _("Function Blocks"), |
104 return [_("User-defined POUs"), _("Functions"), _("Function Blocks"), |
98 _("Programs"), _("Data Types"), _("Transitions"), _("Actions"), |
105 _("Programs"), _("Data Types"), _("Transitions"), _("Actions"), |
99 _("Configurations"), _("Resources"), _("Properties")] |
106 _("Configurations"), _("Resources"), _("Properties")] |
|
107 |
|
108 |
100 UNEDITABLE_NAMES = GetUneditableNames() |
109 UNEDITABLE_NAMES = GetUneditableNames() |
101 [USER_DEFINED_POUS, FUNCTIONS, FUNCTION_BLOCKS, PROGRAMS, |
110 [USER_DEFINED_POUS, FUNCTIONS, FUNCTION_BLOCKS, PROGRAMS, |
102 DATA_TYPES, TRANSITIONS, ACTIONS, CONFIGURATIONS, |
111 DATA_TYPES, TRANSITIONS, ACTIONS, CONFIGURATIONS, |
103 RESOURCES, PROPERTIES] = UNEDITABLE_NAMES |
112 RESOURCES, PROPERTIES] = UNEDITABLE_NAMES |
104 |
113 |
105 #------------------------------------------------------------------------------- |
|
106 # Helper object for loading library in xslt stylesheets |
|
107 #------------------------------------------------------------------------------- |
|
108 |
114 |
109 class LibraryResolver(etree.Resolver): |
115 class LibraryResolver(etree.Resolver): |
|
116 """Helper object for loading library in xslt stylesheets""" |
110 |
117 |
111 def __init__(self, controller, debug=False): |
118 def __init__(self, controller, debug=False): |
112 self.Controller = controller |
119 self.Controller = controller |
113 self.Debug = debug |
120 self.Debug = debug |
114 |
121 |
124 else: |
131 else: |
125 for ctn in self.Controller.ConfNodeTypes: |
132 for ctn in self.Controller.ConfNodeTypes: |
126 lib_el.append(deepcopy(ctn["types"])) |
133 lib_el.append(deepcopy(ctn["types"])) |
127 return self.resolve_string(etree.tostring(lib_el), context) |
134 return self.resolve_string(etree.tostring(lib_el), context) |
128 |
135 |
129 #------------------------------------------------------------------------------- |
136 # ------------------------------------------------------------------------------- |
130 # Helpers functions for translating list of arguments |
137 # Helpers functions for translating list of arguments |
131 # from xslt to valid arguments |
138 # from xslt to valid arguments |
132 #------------------------------------------------------------------------------- |
139 # ------------------------------------------------------------------------------- |
133 |
140 |
134 _StringValue = lambda x: x |
141 |
135 _BoolValue = lambda x: x in ["true", "0"] |
142 def _StringValue(x): |
|
143 return x |
|
144 |
|
145 |
|
146 def _BoolValue(x): |
|
147 return x in ["true", "0"] |
|
148 |
136 |
149 |
137 def _translate_args(translations, args): |
150 def _translate_args(translations, args): |
138 return [translate(arg[0]) if len(arg) > 0 else None |
151 return [translate(arg[0]) if len(arg) > 0 else None |
139 for translate, arg in |
152 for translate, arg in |
140 zip(translations, args)] |
153 zip(translations, args)] |
141 |
154 |
142 #------------------------------------------------------------------------------- |
155 # ------------------------------------------------------------------------------- |
143 # Helpers object for generating pou var list |
156 # Helpers object for generating pou var list |
144 #------------------------------------------------------------------------------- |
157 # ------------------------------------------------------------------------------- |
|
158 |
145 |
159 |
146 class _VariableInfos(object): |
160 class _VariableInfos(object): |
147 __slots__ = ["Name", "Class", "Option", "Location", "InitialValue", |
161 __slots__ = ["Name", "Class", "Option", "Location", "InitialValue", |
148 "Edit", "Documentation", "Type", "Tree", "Number"] |
162 "Edit", "Documentation", "Type", "Tree", "Number"] |
|
163 |
149 def __init__(self, *args): |
164 def __init__(self, *args): |
150 for attr, value in zip(self.__slots__, args): |
165 for attr, value in zip(self.__slots__, args): |
151 setattr(self, attr, value if value is not None else "") |
166 setattr(self, attr, value if value is not None else "") |
|
167 |
152 def copy(self): |
168 def copy(self): |
153 return _VariableInfos(*[getattr(self, attr) for attr in self.__slots__]) |
169 return _VariableInfos(*[getattr(self, attr) for attr in self.__slots__]) |
|
170 |
154 |
171 |
155 class VariablesInfosFactory: |
172 class VariablesInfosFactory: |
156 |
173 |
157 def __init__(self, variables): |
174 def __init__(self, variables): |
158 self.Variables = variables |
175 self.Variables = variables |
239 self.Root.variables.append(_VariablesTreeItemInfos( |
261 self.Root.variables.append(_VariablesTreeItemInfos( |
240 *(_translate_args( |
262 *(_translate_args( |
241 [_StringValue, class_extraction, _StringValue] + |
263 [_StringValue, class_extraction, _StringValue] + |
242 [_BoolValue] * 2, args) + [[]]))) |
264 [_BoolValue] * 2, args) + [[]]))) |
243 |
265 |
244 #------------------------------------------------------------------------------- |
|
245 # Helpers object for generating instances path list |
|
246 #------------------------------------------------------------------------------- |
|
247 |
266 |
248 class InstancesPathFactory: |
267 class InstancesPathFactory: |
249 |
268 """Helpers object for generating instances path list""" |
250 def __init__(self, instances): |
269 def __init__(self, instances): |
251 self.Instances = instances |
270 self.Instances = instances |
252 |
271 |
253 def AddInstance(self, context, *args): |
272 def AddInstance(self, context, *args): |
254 self.Instances.append(args[0][0]) |
273 self.Instances.append(args[0][0]) |
255 |
274 |
256 #------------------------------------------------------------------------------- |
|
257 # Helpers object for generating instance tagname |
|
258 #------------------------------------------------------------------------------- |
|
259 |
275 |
260 class InstanceTagName: |
276 class InstanceTagName: |
|
277 """Helpers object for generating instance tagname""" |
261 |
278 |
262 def __init__(self, controller): |
279 def __init__(self, controller): |
263 self.Controller = controller |
280 self.Controller = controller |
264 self.TagName = None |
281 self.TagName = None |
265 |
282 |
279 self.TagName = self.Controller.ComputePouActionName(args[0][0], args[0][1]) |
296 self.TagName = self.Controller.ComputePouActionName(args[0][0], args[0][1]) |
280 |
297 |
281 def TransitionTagName(self, context, *args): |
298 def TransitionTagName(self, context, *args): |
282 self.TagName = self.Controller.ComputePouTransitionName(args[0][0], args[0][1]) |
299 self.TagName = self.Controller.ComputePouTransitionName(args[0][0], args[0][1]) |
283 |
300 |
284 #------------------------------------------------------------------------------- |
301 |
|
302 # ------------------------------------------------------------------------------- |
285 # Helpers object for generating pou block instances list |
303 # Helpers object for generating pou block instances list |
286 #------------------------------------------------------------------------------- |
304 # ------------------------------------------------------------------------------- |
|
305 |
287 |
306 |
288 _Point = namedtuple("Point", ["x", "y"]) |
307 _Point = namedtuple("Point", ["x", "y"]) |
289 |
308 |
290 _BlockInstanceInfos = namedtuple("BlockInstanceInfos", |
309 _BlockInstanceInfos = namedtuple( |
|
310 "BlockInstanceInfos", |
291 ["type", "id", "x", "y", "width", "height", "specific_values", "inputs", "outputs"]) |
311 ["type", "id", "x", "y", "width", "height", "specific_values", "inputs", "outputs"]) |
292 |
312 |
293 _BlockSpecificValues = ( |
313 _BlockSpecificValues = ( |
294 namedtuple("BlockSpecificValues", |
314 namedtuple("BlockSpecificValues", |
295 ["name", "execution_order"]), |
315 ["name", "execution_order"]), |
345 "actionBlock": ( |
365 "actionBlock": ( |
346 namedtuple("ActionBlockSpecificValues", ["actions"]), |
366 namedtuple("ActionBlockSpecificValues", ["actions"]), |
347 [lambda x: x]), |
367 [lambda x: x]), |
348 } |
368 } |
349 |
369 |
350 _InstanceConnectionInfos = namedtuple("InstanceConnectionInfos", |
370 _InstanceConnectionInfos = namedtuple( |
|
371 "InstanceConnectionInfos", |
351 ["name", "negated", "edge", "position", "links"]) |
372 ["name", "negated", "edge", "position", "links"]) |
352 |
373 |
353 _ConnectionLinkInfos = namedtuple("ConnectionLinkInfos", |
374 _ConnectionLinkInfos = namedtuple( |
|
375 "ConnectionLinkInfos", |
354 ["refLocalId", "formalParameter", "points"]) |
376 ["refLocalId", "formalParameter", "points"]) |
|
377 |
355 |
378 |
356 class _ActionInfos(object): |
379 class _ActionInfos(object): |
357 __slots__ = ["qualifier", "type", "value", "duration", "indicator"] |
380 __slots__ = ["qualifier", "type", "value", "duration", "indicator"] |
|
381 |
358 def __init__(self, *args): |
382 def __init__(self, *args): |
359 for attr, value in zip(self.__slots__, args): |
383 for attr, value in zip(self.__slots__, args): |
360 setattr(self, attr, value if value is not None else "") |
384 setattr(self, attr, value if value is not None else "") |
|
385 |
361 def copy(self): |
386 def copy(self): |
362 return _ActionInfos(*[getattr(self, attr) for attr in self.__slots__]) |
387 return _ActionInfos(*[getattr(self, attr) for attr in self.__slots__]) |
|
388 |
363 |
389 |
364 class BlockInstanceFactory: |
390 class BlockInstanceFactory: |
365 |
391 |
366 def __init__(self, block_instances): |
392 def __init__(self, block_instances): |
367 self.BlockInstances = block_instances |
393 self.BlockInstances = block_instances |
424 if len(self.SpecificValues) == 0: |
450 if len(self.SpecificValues) == 0: |
425 self.SpecificValues.append([[]]) |
451 self.SpecificValues.append([[]]) |
426 translated_args = _translate_args([_StringValue] * 5, args) |
452 translated_args = _translate_args([_StringValue] * 5, args) |
427 self.SpecificValues[0][0].append(_ActionInfos(*translated_args)) |
453 self.SpecificValues[0][0].append(_ActionInfos(*translated_args)) |
428 |
454 |
|
455 |
429 pou_block_instances_xslt = etree.parse( |
456 pou_block_instances_xslt = etree.parse( |
430 os.path.join(ScriptDirectory, "plcopen", "pou_block_instances.xslt")) |
457 os.path.join(ScriptDirectory, "plcopen", "pou_block_instances.xslt")) |
431 |
458 |
432 #------------------------------------------------------------------------------- |
|
433 # Undo Buffer for PLCOpenEditor |
|
434 #------------------------------------------------------------------------------- |
|
435 |
459 |
436 # Length of the buffer |
460 # Length of the buffer |
437 UNDO_BUFFER_LENGTH = 20 |
461 UNDO_BUFFER_LENGTH = 20 |
438 |
462 |
439 """ |
463 |
440 Class implementing a buffer of changes made on the current editing model |
|
441 """ |
|
442 class UndoBuffer: |
464 class UndoBuffer: |
443 |
465 """ |
444 # Constructor initialising buffer |
466 Undo Buffer for PLCOpenEditor |
445 def __init__(self, currentstate, issaved = False): |
467 Class implementing a buffer of changes made on the current editing model |
|
468 """ |
|
469 |
|
470 def __init__(self, currentstate, issaved=False): |
|
471 """ |
|
472 Constructor initialising buffer |
|
473 """ |
446 self.Buffer = [] |
474 self.Buffer = [] |
447 self.CurrentIndex = -1 |
475 self.CurrentIndex = -1 |
448 self.MinIndex = -1 |
476 self.MinIndex = -1 |
449 self.MaxIndex = -1 |
477 self.MaxIndex = -1 |
450 # if current state is defined |
478 # if current state is defined |
577 self.NextCompiledProject = self.Copy(self.Project) |
606 self.NextCompiledProject = self.Copy(self.Project) |
578 self.CurrentCompiledProject = None |
607 self.CurrentCompiledProject = None |
579 self.Buffering = False |
608 self.Buffering = False |
580 |
609 |
581 # Return project data type names |
610 # Return project data type names |
582 def GetProjectDataTypeNames(self, debug = False): |
611 def GetProjectDataTypeNames(self, debug=False): |
583 project = self.GetProject(debug) |
612 project = self.GetProject(debug) |
584 if project is not None: |
613 if project is not None: |
585 return [datatype.getname() for datatype in project.getdataTypes()] |
614 return [datatype.getname() for datatype in project.getdataTypes()] |
586 return [] |
615 return [] |
587 |
616 |
588 # Return project pou names |
617 # Return project pou names |
589 def GetProjectPouNames(self, debug = False): |
618 def GetProjectPouNames(self, debug=False): |
590 project = self.GetProject(debug) |
619 project = self.GetProject(debug) |
591 if project is not None: |
620 if project is not None: |
592 return [pou.getname() for pou in project.getpous()] |
621 return [pou.getname() for pou in project.getpous()] |
593 return [] |
622 return [] |
594 |
623 |
595 # Return project pou names |
624 # Return project pou names |
596 def GetProjectConfigNames(self, debug = False): |
625 def GetProjectConfigNames(self, debug=False): |
597 project = self.GetProject(debug) |
626 project = self.GetProject(debug) |
598 if project is not None: |
627 if project is not None: |
599 return [config.getname() for config in project.getconfigurations()] |
628 return [config.getname() for config in project.getconfigurations()] |
600 return [] |
629 return [] |
601 |
630 |
602 # Return project pou variable names |
631 # Return project pou variable names |
603 def GetProjectPouVariableNames(self, pou_name = None, debug = False): |
632 def GetProjectPouVariableNames(self, pou_name=None, debug=False): |
604 variables = [] |
633 variables = [] |
605 project = self.GetProject(debug) |
634 project = self.GetProject(debug) |
606 if project is not None: |
635 if project is not None: |
607 for pou in project.getpous(): |
636 for pou in project.getpous(): |
608 if pou_name is None or pou_name == pou.getname(): |
637 if pou_name is None or pou_name == pou.getname(): |
625 def GetFilename(self): |
654 def GetFilename(self): |
626 if self.Project is not None: |
655 if self.Project is not None: |
627 if self.ProjectIsSaved(): |
656 if self.ProjectIsSaved(): |
628 return self.FileName |
657 return self.FileName |
629 else: |
658 else: |
630 return "~%s~"%self.FileName |
659 return "~%s~" % self.FileName |
631 return "" |
660 return "" |
632 |
661 |
633 # Change file path and save file name or create a default one if file path not defined |
662 # Change file path and save file name or create a default one if file path not defined |
634 def SetFilePath(self, filepath): |
663 def SetFilePath(self, filepath): |
635 self.FilePath = filepath |
664 self.FilePath = filepath |
636 if filepath == "": |
665 if filepath == "": |
637 self.LastNewIndex += 1 |
666 self.LastNewIndex += 1 |
638 self.FileName = _("Unnamed%d")%self.LastNewIndex |
667 self.FileName = _("Unnamed%d") % self.LastNewIndex |
639 else: |
668 else: |
640 self.FileName = os.path.splitext(os.path.basename(filepath))[0] |
669 self.FileName = os.path.splitext(os.path.basename(filepath))[0] |
641 |
670 |
642 # Change project properties |
671 # Change project properties |
643 def SetProjectProperties(self, name = None, properties = None, buffer = True): |
672 def SetProjectProperties(self, name=None, properties=None, buffer=True): |
644 if self.Project is not None: |
673 if self.Project is not None: |
645 if name is not None: |
674 if name is not None: |
646 self.Project.setname(name) |
675 self.Project.setname(name) |
647 if properties is not None: |
676 if properties is not None: |
648 self.Project.setfileHeader(properties) |
677 self.Project.setfileHeader(properties) |
656 if project is not None: |
685 if project is not None: |
657 return project.getname() |
686 return project.getname() |
658 return None |
687 return None |
659 |
688 |
660 # Return project properties |
689 # Return project properties |
661 def GetProjectProperties(self, debug = False): |
690 def GetProjectProperties(self, debug=False): |
662 project = self.GetProject(debug) |
691 project = self.GetProject(debug) |
663 if project is not None: |
692 if project is not None: |
664 properties = project.getfileHeader() |
693 properties = project.getfileHeader() |
665 properties.update(project.getcontentHeader()) |
694 properties.update(project.getcontentHeader()) |
666 return properties |
695 return properties |
667 return None |
696 return None |
668 |
697 |
669 # Return project informations |
698 # Return project informations |
670 def GetProjectInfos(self, debug = False): |
699 def GetProjectInfos(self, debug=False): |
671 project = self.GetProject(debug) |
700 project = self.GetProject(debug) |
672 if project is not None: |
701 if project is not None: |
673 infos = {"name": project.getname(), "type": ITEM_PROJECT} |
702 infos = {"name": project.getname(), "type": ITEM_PROJECT} |
674 datatypes = {"name": DATA_TYPES, "type": ITEM_DATATYPES, "values":[]} |
703 datatypes = {"name": DATA_TYPES, "type": ITEM_DATATYPES, "values": []} |
675 for datatype in project.getdataTypes(): |
704 for datatype in project.getdataTypes(): |
676 datatypes["values"].append({"name": datatype.getname(), "type": ITEM_DATATYPE, |
705 datatypes["values"].append({ |
677 "tagname": self.ComputeDataTypeName(datatype.getname()), "values": []}) |
706 "name": datatype.getname(), |
678 pou_types = {"function": {"name": FUNCTIONS, "type": ITEM_FUNCTION, "values":[]}, |
707 "type": ITEM_DATATYPE, |
679 "functionBlock": {"name": FUNCTION_BLOCKS, "type": ITEM_FUNCTIONBLOCK, "values":[]}, |
708 "tagname": self.ComputeDataTypeName(datatype.getname()), |
680 "program": {"name": PROGRAMS, "type": ITEM_PROGRAM, "values":[]}} |
709 "values": []}) |
|
710 pou_types = { |
|
711 "function": { |
|
712 "name": FUNCTIONS, |
|
713 "type": ITEM_FUNCTION, |
|
714 "values": [] |
|
715 }, |
|
716 "functionBlock": { |
|
717 "name": FUNCTION_BLOCKS, |
|
718 "type": ITEM_FUNCTIONBLOCK, |
|
719 "values": [] |
|
720 }, |
|
721 "program": { |
|
722 "name": PROGRAMS, |
|
723 "type": ITEM_PROGRAM, |
|
724 "values": [] |
|
725 } |
|
726 } |
681 for pou in project.getpous(): |
727 for pou in project.getpous(): |
682 pou_type = pou.getpouType() |
728 pou_type = pou.getpouType() |
683 pou_infos = {"name": pou.getname(), "type": ITEM_POU, |
729 pou_infos = {"name": pou.getname(), "type": ITEM_POU, |
684 "tagname": self.ComputePouName(pou.getname())} |
730 "tagname": self.ComputePouName(pou.getname())} |
685 pou_values = [] |
731 pou_values = [] |
686 if pou.getbodyType() == "SFC": |
732 if pou.getbodyType() == "SFC": |
687 transitions = [] |
733 transitions = [] |
688 for transition in pou.gettransitionList(): |
734 for transition in pou.gettransitionList(): |
689 transitions.append({"name": transition.getname(), "type": ITEM_TRANSITION, |
735 transitions.append({ |
|
736 "name": transition.getname(), |
|
737 "type": ITEM_TRANSITION, |
690 "tagname": self.ComputePouTransitionName(pou.getname(), transition.getname()), |
738 "tagname": self.ComputePouTransitionName(pou.getname(), transition.getname()), |
691 "values": []}) |
739 "values": []}) |
692 pou_values.append({"name": TRANSITIONS, "type": ITEM_TRANSITIONS, "values": transitions}) |
740 pou_values.append({"name": TRANSITIONS, "type": ITEM_TRANSITIONS, "values": transitions}) |
693 actions = [] |
741 actions = [] |
694 for action in pou.getactionList(): |
742 for action in pou.getactionList(): |
695 actions.append({"name": action.getname(), "type": ITEM_ACTION, |
743 actions.append({ |
|
744 "name": action.getname(), |
|
745 "type": ITEM_ACTION, |
696 "tagname": self.ComputePouActionName(pou.getname(), action.getname()), |
746 "tagname": self.ComputePouActionName(pou.getname(), action.getname()), |
697 "values": []}) |
747 "values": []}) |
698 pou_values.append({"name": ACTIONS, "type": ITEM_ACTIONS, "values": actions}) |
748 pou_values.append({"name": ACTIONS, "type": ITEM_ACTIONS, "values": actions}) |
699 if pou_type in pou_types: |
749 if pou_type in pou_types: |
700 pou_infos["values"] = pou_values |
750 pou_infos["values"] = pou_values |
701 pou_types[pou_type]["values"].append(pou_infos) |
751 pou_types[pou_type]["values"].append(pou_infos) |
702 configurations = {"name": CONFIGURATIONS, "type": ITEM_CONFIGURATIONS, "values": []} |
752 configurations = {"name": CONFIGURATIONS, "type": ITEM_CONFIGURATIONS, "values": []} |
703 for config in project.getconfigurations(): |
753 for config in project.getconfigurations(): |
704 config_name = config.getname() |
754 config_name = config.getname() |
705 config_infos = {"name": config_name, "type": ITEM_CONFIGURATION, |
755 config_infos = { |
|
756 "name": config_name, |
|
757 "type": ITEM_CONFIGURATION, |
706 "tagname": self.ComputeConfigurationName(config.getname()), |
758 "tagname": self.ComputeConfigurationName(config.getname()), |
707 "values": []} |
759 "values": []} |
708 resources = {"name": RESOURCES, "type": ITEM_RESOURCES, "values": []} |
760 resources = {"name": RESOURCES, "type": ITEM_RESOURCES, "values": []} |
709 for resource in config.getresource(): |
761 for resource in config.getresource(): |
710 resource_name = resource.getname() |
762 resource_name = resource.getname() |
711 resource_infos = {"name": resource_name, "type": ITEM_RESOURCE, |
763 resource_infos = { |
|
764 "name": resource_name, |
|
765 "type": ITEM_RESOURCE, |
712 "tagname": self.ComputeConfigurationResourceName(config.getname(), resource.getname()), |
766 "tagname": self.ComputeConfigurationResourceName(config.getname(), resource.getname()), |
713 "values": []} |
767 "values": []} |
714 resources["values"].append(resource_infos) |
768 resources["values"].append(resource_infos) |
715 config_infos["values"] = [resources] |
769 config_infos["values"] = [resources] |
716 configurations["values"].append(config_infos) |
770 configurations["values"].append(config_infos) |
717 infos["values"] = [datatypes, pou_types["function"], pou_types["functionBlock"], |
771 infos["values"] = [datatypes, pou_types["function"], pou_types["functionBlock"], |
718 pou_types["program"], configurations] |
772 pou_types["program"], configurations] |
719 return infos |
773 return infos |
720 return None |
774 return None |
721 |
775 |
722 def GetPouVariables(self, tagname, debug = False): |
776 def GetPouVariables(self, tagname, debug=False): |
723 pou_type = None |
777 pou_type = None |
724 project = self.GetProject(debug) |
778 project = self.GetProject(debug) |
725 if project is not None: |
779 if project is not None: |
726 factory = VariablesTreeInfosFactory() |
780 factory = VariablesTreeInfosFactory() |
727 |
781 |
782 return ["%s.%s" % (instance, words[2]) |
836 return ["%s.%s" % (instance, words[2]) |
783 for instance in self.SearchPouInstances( |
837 for instance in self.SearchPouInstances( |
784 self.ComputePouName(words[1]), debug)] |
838 self.ComputePouName(words[1]), debug)] |
785 return [] |
839 return [] |
786 |
840 |
787 def GetPouInstanceTagName(self, instance_path, debug = False): |
841 def GetPouInstanceTagName(self, instance_path, debug=False): |
788 project = self.GetProject(debug) |
842 project = self.GetProject(debug) |
789 factory = InstanceTagName(self) |
843 factory = InstanceTagName(self) |
790 |
844 |
791 parser = etree.XMLParser() |
845 parser = etree.XMLParser() |
792 parser.resolvers.add(LibraryResolver(self, debug)) |
846 parser.resolvers.add(LibraryResolver(self, debug)) |
793 |
847 |
794 instance_tagname_xslt_tree = etree.XSLT( |
848 instance_tagname_xslt_tree = etree.XSLT( |
795 etree.parse( |
849 etree.parse( |
796 os.path.join(ScriptDirectory, "plcopen", "instance_tagname.xslt"), |
850 os.path.join(ScriptDirectory, "plcopen", "instance_tagname.xslt"), |
797 parser), |
851 parser), |
798 extensions = {("instance_tagname_ns", name): getattr(factory, name) |
852 extensions={("instance_tagname_ns", name): getattr(factory, name) |
799 for name in ["ConfigTagName", "ResourceTagName", |
853 for name in ["ConfigTagName", |
800 "PouTagName", "ActionTagName", |
854 "ResourceTagName", |
801 "TransitionTagName"]}) |
855 "PouTagName", |
802 |
856 "ActionTagName", |
803 instance_tagname_xslt_tree(project, |
857 "TransitionTagName"]}) |
804 instance_path=etree.XSLT.strparam(instance_path)) |
858 |
|
859 instance_tagname_xslt_tree( |
|
860 project, instance_path=etree.XSLT.strparam(instance_path)) |
805 |
861 |
806 return factory.GetTagName() |
862 return factory.GetTagName() |
807 |
863 |
808 def GetInstanceInfos(self, instance_path, debug = False): |
864 def GetInstanceInfos(self, instance_path, debug=False): |
809 tagname = self.GetPouInstanceTagName(instance_path) |
865 tagname = self.GetPouInstanceTagName(instance_path) |
810 if tagname is not None: |
866 if tagname is not None: |
811 infos = self.GetPouVariables(tagname, debug) |
867 infos = self.GetPouVariables(tagname, debug) |
812 infos.type = tagname |
868 infos.type = tagname |
813 return infos |
869 return infos |
820 if var_infos.name == var_name: |
876 if var_infos.name == var_name: |
821 return var_infos |
877 return var_infos |
822 return None |
878 return None |
823 |
879 |
824 # Return if data type given by name is used by another data type or pou |
880 # Return if data type given by name is used by another data type or pou |
825 def DataTypeIsUsed(self, name, debug = False): |
881 def DataTypeIsUsed(self, name, debug=False): |
826 project = self.GetProject(debug) |
882 project = self.GetProject(debug) |
827 if project is not None: |
883 if project is not None: |
828 return len(self.GetInstanceList(project, name, debug)) > 0 |
884 return len(self.GetInstanceList(project, name, debug)) > 0 |
829 return False |
885 return False |
830 |
886 |
831 # Return if pou given by name is used by another pou |
887 # Return if pou given by name is used by another pou |
832 def PouIsUsed(self, name, debug = False): |
888 def PouIsUsed(self, name, debug=False): |
833 project = self.GetProject(debug) |
889 project = self.GetProject(debug) |
834 if project is not None: |
890 if project is not None: |
835 return len(self.GetInstanceList(project, name, debug)) > 0 |
891 return len(self.GetInstanceList(project, name, debug)) > 0 |
836 return False |
892 return False |
837 |
893 |
838 # Return if pou given by name is directly or undirectly used by the reference pou |
894 # Return if pou given by name is directly or undirectly used by the reference pou |
839 def PouIsUsedBy(self, name, reference, debug = False): |
895 def PouIsUsedBy(self, name, reference, debug=False): |
840 pou_infos = self.GetPou(reference, debug) |
896 pou_infos = self.GetPou(reference, debug) |
841 if pou_infos is not None: |
897 if pou_infos is not None: |
842 return len(self.GetInstanceList(pou_infos, name, debug)) > 0 |
898 return len(self.GetInstanceList(pou_infos, name, debug)) > 0 |
843 return False |
899 return False |
844 |
900 |
1137 if resource is not None: |
1193 if resource is not None: |
1138 resource.setname(new_name) |
1194 resource.setname(new_name) |
1139 self.BufferProject() |
1195 self.BufferProject() |
1140 |
1196 |
1141 # Return the description of the pou given by its name |
1197 # Return the description of the pou given by its name |
1142 def GetPouDescription(self, name, debug = False): |
1198 def GetPouDescription(self, name, debug=False): |
1143 project = self.GetProject(debug) |
1199 project = self.GetProject(debug) |
1144 if project is not None: |
1200 if project is not None: |
1145 # Found the pou correponding to name and return its type |
1201 # Found the pou correponding to name and return its type |
1146 pou = project.getpou(name) |
1202 pou = project.getpou(name) |
1147 if pou is not None: |
1203 if pou is not None: |
1148 return pou.getdescription() |
1204 return pou.getdescription() |
1149 return "" |
1205 return "" |
1150 |
1206 |
1151 # Return the description of the pou given by its name |
1207 # Return the description of the pou given by its name |
1152 def SetPouDescription(self, name, description, debug = False): |
1208 def SetPouDescription(self, name, description, debug=False): |
1153 project = self.GetProject(debug) |
1209 project = self.GetProject(debug) |
1154 if project is not None: |
1210 if project is not None: |
1155 # Found the pou correponding to name and return its type |
1211 # Found the pou correponding to name and return its type |
1156 pou = project.getpou(name) |
1212 pou = project.getpou(name) |
1157 if pou is not None: |
1213 if pou is not None: |
1158 pou.setdescription(description) |
1214 pou.setdescription(description) |
1159 self.BufferProject() |
1215 self.BufferProject() |
1160 |
1216 |
1161 # Return the type of the pou given by its name |
1217 # Return the type of the pou given by its name |
1162 def GetPouType(self, name, debug = False): |
1218 def GetPouType(self, name, debug=False): |
1163 project = self.GetProject(debug) |
1219 project = self.GetProject(debug) |
1164 if project is not None: |
1220 if project is not None: |
1165 # Found the pou correponding to name and return its type |
1221 # Found the pou correponding to name and return its type |
1166 pou = project.getpou(name) |
1222 pou = project.getpou(name) |
1167 if pou is not None: |
1223 if pou is not None: |
1168 return pou.getpouType() |
1224 return pou.getpouType() |
1169 return None |
1225 return None |
1170 |
1226 |
1171 # Return pous with SFC language |
1227 # Return pous with SFC language |
1172 def GetSFCPous(self, debug = False): |
1228 def GetSFCPous(self, debug=False): |
1173 list = [] |
1229 list = [] |
1174 project = self.GetProject(debug) |
1230 project = self.GetProject(debug) |
1175 if project is not None: |
1231 if project is not None: |
1176 for pou in project.getpous(): |
1232 for pou in project.getpous(): |
1177 if pou.getBodyType() == "SFC": |
1233 if pou.getBodyType() == "SFC": |
1178 list.append(pou.getname()) |
1234 list.append(pou.getname()) |
1179 return list |
1235 return list |
1180 |
1236 |
1181 # Return the body language of the pou given by its name |
1237 # Return the body language of the pou given by its name |
1182 def GetPouBodyType(self, name, debug = False): |
1238 def GetPouBodyType(self, name, debug=False): |
1183 project = self.GetProject(debug) |
1239 project = self.GetProject(debug) |
1184 if project is not None: |
1240 if project is not None: |
1185 # Found the pou correponding to name and return its body language |
1241 # Found the pou correponding to name and return its body language |
1186 pou = project.getpou(name) |
1242 pou = project.getpou(name) |
1187 if pou is not None: |
1243 if pou is not None: |
1188 return pou.getbodyType() |
1244 return pou.getbodyType() |
1189 return None |
1245 return None |
1190 |
1246 |
1191 # Return the actions of a pou |
1247 # Return the actions of a pou |
1192 def GetPouTransitions(self, pou_name, debug = False): |
1248 def GetPouTransitions(self, pou_name, debug=False): |
1193 transitions = [] |
1249 transitions = [] |
1194 project = self.GetProject(debug) |
1250 project = self.GetProject(debug) |
1195 if project is not None: |
1251 if project is not None: |
1196 # Found the pou correponding to name and return its transitions if SFC |
1252 # Found the pou correponding to name and return its transitions if SFC |
1197 pou = project.getpou(pou_name) |
1253 pou = project.getpou(pou_name) |
1330 |
1386 |
1331 variables_infos_xslt_tree = etree.XSLT( |
1387 variables_infos_xslt_tree = etree.XSLT( |
1332 etree.parse( |
1388 etree.parse( |
1333 os.path.join(ScriptDirectory, "plcopen", "variables_infos.xslt"), |
1389 os.path.join(ScriptDirectory, "plcopen", "variables_infos.xslt"), |
1334 parser), |
1390 parser), |
1335 extensions = {("var_infos_ns", name): getattr(factory, name) |
1391 extensions={("var_infos_ns", name): getattr(factory, name) |
1336 for name in ["SetType", "AddDimension", "AddTree", |
1392 for name in ["SetType", "AddDimension", "AddTree", |
1337 "AddVarToTree", "AddVariable"]}) |
1393 "AddVarToTree", "AddVariable"]}) |
1338 variables_infos_xslt_tree(object_with_vars, |
1394 variables_infos_xslt_tree( |
1339 tree=etree.XSLT.strparam(str(tree))) |
1395 object_with_vars, tree=etree.XSLT.strparam(str(tree))) |
1340 |
1396 |
1341 return variables |
1397 return variables |
1342 |
1398 |
1343 # Add a global var to configuration to configuration |
1399 # Add a global var to configuration to configuration |
1344 def AddConfigurationGlobalVar(self, config_name, var_type, var_name, |
1400 def AddConfigurationGlobalVar(self, config_name, var_type, var_name, |
1345 location="", description=""): |
1401 location="", description=""): |
1346 if self.Project is not None: |
1402 if self.Project is not None: |
1347 # Found the configuration corresponding to name |
1403 # Found the configuration corresponding to name |
1348 configuration = self.Project.getconfiguration(config_name) |
1404 configuration = self.Project.getconfiguration(config_name) |
1349 if configuration is not None: |
1405 if configuration is not None: |
1350 # Set configuration global vars |
1406 # Set configuration global vars |
1411 return self.GetVariableDictionary(resource, debug) |
1468 return self.GetVariableDictionary(resource, debug) |
1412 |
1469 |
1413 return [] |
1470 return [] |
1414 |
1471 |
1415 # Return resource variable names |
1472 # Return resource variable names |
1416 def GetConfigurationResourceVariableNames(self, |
1473 def GetConfigurationResourceVariableNames( |
1417 config_name = None, resource_name = None, debug = False): |
1474 self, config_name=None, resource_name=None, debug=False): |
1418 variables = [] |
1475 variables = [] |
1419 project = self.GetProject(debug) |
1476 project = self.GetProject(debug) |
1420 if project is not None: |
1477 if project is not None: |
1421 for configuration in self.Project.getconfigurations(): |
1478 for configuration in self.Project.getconfigurations(): |
1422 if config_name is None or config_name == configuration.getname(): |
1479 if config_name is None or config_name == configuration.getname(): |
1423 for resource in configuration.getresource(): |
1480 for resource in configuration.getresource(): |
1424 if resource_name is None or resource.getname() == resource_name: |
1481 if resource_name is None or resource.getname() == resource_name: |
1425 variables.extend( |
1482 variables.extend( |
1426 [var.getname() for var in reduce( |
1483 [var.getname() for var in reduce( |
1427 lambda x, y: x + y, [varlist.getvariable() |
1484 lambda x, y: x + y, [ |
|
1485 varlist.getvariable() |
1428 for varlist in resource.globalVars], |
1486 for varlist in resource.globalVars], |
1429 [])]) |
1487 [])]) |
1430 return variables |
1488 return variables |
1431 |
1489 |
1432 # Return the interface for the given pou |
1490 # Return the interface for the given pou |
1433 def GetPouInterfaceVars(self, pou, tree=False, debug = False): |
1491 def GetPouInterfaceVars(self, pou, tree=False, debug=False): |
1434 interface = pou.interface |
1492 interface = pou.interface |
1435 # Verify that the pou has an interface |
1493 # Verify that the pou has an interface |
1436 if interface is not None: |
1494 if interface is not None: |
1437 # Extract variables defined in interface |
1495 # Extract variables defined in interface |
1438 return self.GetVariableDictionary(interface, tree, debug) |
1496 return self.GetVariableDictionary(interface, tree, debug) |
1514 def AddConfNodeTypesList(self, typeslist): |
1572 def AddConfNodeTypesList(self, typeslist): |
1515 self.ConfNodeTypes.extend(typeslist) |
1573 self.ConfNodeTypes.extend(typeslist) |
1516 addedcat = [{"name": _("%s POUs") % confnodetypes["name"], |
1574 addedcat = [{"name": _("%s POUs") % confnodetypes["name"], |
1517 "list": [pou.getblockInfos() |
1575 "list": [pou.getblockInfos() |
1518 for pou in confnodetypes["types"].getpous()]} |
1576 for pou in confnodetypes["types"].getpous()]} |
1519 for confnodetypes in typeslist] |
1577 for confnodetypes in typeslist] |
1520 self.TotalTypes.extend(addedcat) |
1578 self.TotalTypes.extend(addedcat) |
1521 for cat in addedcat: |
1579 for cat in addedcat: |
1522 for desc in cat["list"]: |
1580 for desc in cat["list"]: |
1523 BlkLst = self.TotalTypesDict.setdefault(desc["name"],[]) |
1581 BlkLst = self.TotalTypesDict.setdefault(desc["name"], []) |
1524 BlkLst.append((section["name"], desc)) |
1582 BlkLst.append((section["name"], desc)) |
1525 |
1583 |
1526 # Function that clear the confnode list |
1584 # Function that clear the confnode list |
1527 def ClearConfNodeTypes(self): |
1585 def ClearConfNodeTypes(self): |
1528 self.ConfNodeTypes = [] |
1586 self.ConfNodeTypes = [] |
1529 self.TotalTypesDict = StdBlckDct.copy() |
1587 self.TotalTypesDict = StdBlckDct.copy() |
1530 self.TotalTypes = StdBlckLst[:] |
1588 self.TotalTypes = StdBlckLst[:] |
1531 |
1589 |
1532 def GetConfNodeDataTypes(self, exclude = None, only_locatables = False): |
1590 def GetConfNodeDataTypes(self, exclude=None, only_locatables=False): |
1533 return [{"name": _("%s Data Types") % confnodetypes["name"], |
1591 return [{"name": _("%s Data Types") % confnodetypes["name"], |
1534 "list": [ |
1592 "list": [ |
1535 datatype.getname() |
1593 datatype.getname() |
1536 for datatype in confnodetypes["types"].getdataTypes() |
1594 for datatype in confnodetypes["types"].getdataTypes() |
1537 if not only_locatables or self.IsLocatableDataType(datatype, debug)]} |
1595 if not only_locatables or self.IsLocatableDataType(datatype, debug)]} |
1595 blocktype_infos = blocktype.getblockInfos() |
1653 blocktype_infos = blocktype.getblockInfos() |
1596 if inputs in [None, "undefined"]: |
1654 if inputs in [None, "undefined"]: |
1597 return blocktype_infos |
1655 return blocktype_infos |
1598 |
1656 |
1599 if inputs == tuple([var_type |
1657 if inputs == tuple([var_type |
1600 for name, var_type, modifier in blocktype_infos["inputs"]]): |
1658 for name, var_type, modifier in blocktype_infos["inputs"]]): |
1601 return blocktype_infos |
1659 return blocktype_infos |
1602 |
1660 |
1603 return None |
1661 return None |
1604 |
1662 |
1605 # Return Block types checking for recursion |
1663 # Return Block types checking for recursion |
1606 def GetBlockTypes(self, tagname = "", debug = False): |
1664 def GetBlockTypes(self, tagname="", debug=False): |
1607 typename = None |
1665 typename = None |
1608 words = tagname.split("::") |
1666 words = tagname.split("::") |
1609 name = None |
1667 name = None |
1610 project = self.GetProject(debug) |
1668 project = self.GetProject(debug) |
1611 if project is not None: |
1669 if project is not None: |
1612 pou_type = None |
1670 pou_type = None |
1613 if words[0] in ["P","T","A"]: |
1671 if words[0] in ["P", "T", "A"]: |
1614 name = words[1] |
1672 name = words[1] |
1615 pou_type = self.GetPouType(name, debug) |
1673 pou_type = self.GetPouType(name, debug) |
1616 filter = (["function"] |
1674 filter = (["function"] |
1617 if pou_type == "function" or words[0] == "T" |
1675 if pou_type == "function" or words[0] == "T" |
1618 else ["functionBlock", "function"]) |
1676 else ["functionBlock", "function"]) |
1619 blocktypes = [ |
1677 blocktypes = [ |
1620 {"name": category["name"], |
1678 {"name": category["name"], |
1621 "list": [block for block in category["list"] |
1679 "list": [block for block in category["list"] |
1622 if block["type"] in filter]} |
1680 if block["type"] in filter]} |
1623 for category in self.TotalTypes] |
1681 for category in self.TotalTypes] |
1624 blocktypes.append({"name" : USER_DEFINED_POUS, |
1682 blocktypes.append({ |
|
1683 "name": USER_DEFINED_POUS, |
1625 "list": [pou.getblockInfos() |
1684 "list": [pou.getblockInfos() |
1626 for pou in project.getpous(name, filter) |
1685 for pou in project.getpous(name, filter) |
1627 if (name is None or |
1686 if (name is None or |
1628 len(self.GetInstanceList(pou, name, debug)) == 0)]}) |
1687 len(self.GetInstanceList(pou, name, debug)) == 0)] |
|
1688 }) |
1629 return blocktypes |
1689 return blocktypes |
1630 return self.TotalTypes |
1690 return self.TotalTypes |
1631 |
1691 |
1632 # Return Function Block types checking for recursion |
1692 # Return Function Block types checking for recursion |
1633 def GetFunctionBlockTypes(self, tagname = "", debug = False): |
1693 def GetFunctionBlockTypes(self, tagname="", debug=False): |
1634 project = self.GetProject(debug) |
1694 project = self.GetProject(debug) |
1635 words = tagname.split("::") |
1695 words = tagname.split("::") |
1636 name = None |
1696 name = None |
1637 if project is not None and words[0] in ["P","T","A"]: |
1697 if project is not None and words[0] in ["P", "T", "A"]: |
1638 name = words[1] |
1698 name = words[1] |
1639 blocktypes = [] |
1699 blocktypes = [] |
1640 for blocks in self.TotalTypesDict.itervalues(): |
1700 for blocks in self.TotalTypesDict.itervalues(): |
1641 for sectioname,block in blocks: |
1701 for sectioname, block in blocks: |
1642 if block["type"] == "functionBlock": |
1702 if block["type"] == "functionBlock": |
1643 blocktypes.append(block["name"]) |
1703 blocktypes.append(block["name"]) |
1644 if project is not None: |
1704 if project is not None: |
1645 blocktypes.extend([pou.getname() |
1705 blocktypes.extend([ |
|
1706 pou.getname() |
1646 for pou in project.getpous(name, ["functionBlock"]) |
1707 for pou in project.getpous(name, ["functionBlock"]) |
1647 if (name is None or |
1708 if (name is None or |
1648 len(self.GetInstanceList(pou, name, debug)) == 0)]) |
1709 len(self.GetInstanceList(pou, name, debug)) == 0)]) |
1649 return blocktypes |
1710 return blocktypes |
1650 |
1711 |
1651 # Return Block types checking for recursion |
1712 # Return Block types checking for recursion |
1652 def GetBlockResource(self, debug = False): |
1713 def GetBlockResource(self, debug=False): |
1653 blocktypes = [] |
1714 blocktypes = [] |
1654 for category in StdBlckLst[:-1]: |
1715 for category in StdBlckLst[:-1]: |
1655 for blocktype in category["list"]: |
1716 for blocktype in category["list"]: |
1656 if blocktype["type"] == "program": |
1717 if blocktype["type"] == "program": |
1657 blocktypes.append(blocktype["name"]) |
1718 blocktypes.append(blocktype["name"]) |
1783 array_base_type = basetype_content.baseType.getcontent() |
1843 array_base_type = basetype_content.baseType.getcontent() |
1784 if array_base_type.getLocalTag() == "derived": |
1844 if array_base_type.getLocalTag() == "derived": |
1785 return self.IsLocatableType(array_base_type.getname(), debug) |
1845 return self.IsLocatableType(array_base_type.getname(), debug) |
1786 return True |
1846 return True |
1787 |
1847 |
1788 def IsLocatableType(self, typename, debug = False): |
1848 def IsLocatableType(self, typename, debug=False): |
1789 if isinstance(typename, TupleType) or self.GetBlockType(typename) is not None: |
1849 if isinstance(typename, TupleType) or self.GetBlockType(typename) is not None: |
1790 return False |
1850 return False |
1791 |
1851 |
1792 # the size of these types is implementation dependend |
1852 # the size of these types is implementation dependend |
1793 if typename in ["TIME", "DATE", "DT", "TOD"]: |
1853 if typename in ["TIME", "DATE", "DT", "TOD"]: |
1794 return False |
1854 return False |
1795 |
1855 |
1796 datatype = self.GetDataType(typename, debug) |
1856 datatype = self.GetDataType(typename, debug) |
1797 if datatype is not None: |
1857 if datatype is not None: |
1798 return self.IsLocatableDataType(datatype) |
1858 return self.IsLocatableDataType(datatype) |
1799 return True |
1859 return True |
1800 |
1860 |
1801 def IsEnumeratedType(self, typename, debug = False): |
1861 def IsEnumeratedType(self, typename, debug=False): |
1802 if isinstance(typename, TupleType): |
1862 if isinstance(typename, TupleType): |
1803 typename = typename[1] |
1863 typename = typename[1] |
1804 datatype = self.GetDataType(typename, debug) |
1864 datatype = self.GetDataType(typename, debug) |
1805 if datatype is not None: |
1865 if datatype is not None: |
1806 basetype_content = datatype.baseType.getcontent() |
1866 basetype_content = datatype.baseType.getcontent() |
1910 def ComputeConfigurationResourceName(self, config, resource): |
1970 def ComputeConfigurationResourceName(self, config, resource): |
1911 return "R::%s::%s" % (config, resource) |
1971 return "R::%s::%s" % (config, resource) |
1912 |
1972 |
1913 def GetElementType(self, tagname): |
1973 def GetElementType(self, tagname): |
1914 words = tagname.split("::") |
1974 words = tagname.split("::") |
1915 return {"D" : ITEM_DATATYPE, "P" : ITEM_POU, |
1975 return { |
1916 "T" : ITEM_TRANSITION, "A" : ITEM_ACTION, |
1976 "D": ITEM_DATATYPE, |
1917 "C" : ITEM_CONFIGURATION, "R" : ITEM_RESOURCE}[words[0]] |
1977 "P": ITEM_POU, |
1918 |
1978 "T": ITEM_TRANSITION, |
1919 #------------------------------------------------------------------------------- |
1979 "A": ITEM_ACTION, |
1920 # Project opened Data types management functions |
1980 "C": ITEM_CONFIGURATION, |
1921 #------------------------------------------------------------------------------- |
1981 "R": ITEM_RESOURCE |
|
1982 }[words[0]] |
|
1983 |
|
1984 # ------------------------------------------------------------------------------- |
|
1985 # Project opened Data types management functions |
|
1986 # ------------------------------------------------------------------------------- |
1922 |
1987 |
1923 # Return the data type informations |
1988 # Return the data type informations |
1924 def GetDataTypeInfos(self, tagname, debug = False): |
1989 def GetDataTypeInfos(self, tagname, debug=False): |
1925 project = self.GetProject(debug) |
1990 project = self.GetProject(debug) |
1926 if project is not None: |
1991 if project is not None: |
1927 words = tagname.split("::") |
1992 words = tagname.split("::") |
1928 if words[0] == "D": |
1993 if words[0] == "D": |
1929 infos = {} |
1994 infos = {} |
2143 return None |
2209 return None |
2144 |
2210 |
2145 # Return edited element name |
2211 # Return edited element name |
2146 def GetEditedElementName(self, tagname): |
2212 def GetEditedElementName(self, tagname): |
2147 words = tagname.split("::") |
2213 words = tagname.split("::") |
2148 if words[0] in ["P","C","D"]: |
2214 if words[0] in ["P", "C", "D"]: |
2149 return words[1] |
2215 return words[1] |
2150 else: |
2216 else: |
2151 return words[2] |
2217 return words[2] |
2152 return None |
2218 return None |
2153 |
2219 |
2154 # Return edited element name and type |
2220 # Return edited element name and type |
2155 def GetEditedElementType(self, tagname, debug = False): |
2221 def GetEditedElementType(self, tagname, debug=False): |
2156 words = tagname.split("::") |
2222 words = tagname.split("::") |
2157 if words[0] in ["P","T","A"]: |
2223 if words[0] in ["P", "T", "A"]: |
2158 return words[1], self.GetPouType(words[1], debug) |
2224 return words[1], self.GetPouType(words[1], debug) |
2159 return None, None |
2225 return None, None |
2160 |
2226 |
2161 # Return language in which edited element is written |
2227 # Return language in which edited element is written |
2162 def GetEditedElementBodyType(self, tagname, debug = False): |
2228 def GetEditedElementBodyType(self, tagname, debug=False): |
2163 words = tagname.split("::") |
2229 words = tagname.split("::") |
2164 if words[0] == "P": |
2230 if words[0] == "P": |
2165 return self.GetPouBodyType(words[1], debug) |
2231 return self.GetPouBodyType(words[1], debug) |
2166 elif words[0] == 'T': |
2232 elif words[0] == 'T': |
2167 return self.GetTransitionBodyType(words[1], words[2], debug) |
2233 return self.GetTransitionBodyType(words[1], words[2], debug) |
2168 elif words[0] == 'A': |
2234 elif words[0] == 'A': |
2169 return self.GetActionBodyType(words[1], words[2], debug) |
2235 return self.GetActionBodyType(words[1], words[2], debug) |
2170 return None |
2236 return None |
2171 |
2237 |
2172 # Return the edited element variables |
2238 # Return the edited element variables |
2173 def GetEditedElementInterfaceVars(self, tagname, tree=False, debug = False): |
2239 def GetEditedElementInterfaceVars(self, tagname, tree=False, debug=False): |
2174 words = tagname.split("::") |
2240 words = tagname.split("::") |
2175 if words[0] in ["P","T","A"]: |
2241 if words[0] in ["P", "T", "A"]: |
2176 project = self.GetProject(debug) |
2242 project = self.GetProject(debug) |
2177 if project is not None: |
2243 if project is not None: |
2178 pou = project.getpou(words[1]) |
2244 pou = project.getpou(words[1]) |
2179 if pou is not None: |
2245 if pou is not None: |
2180 return self.GetPouInterfaceVars(pou, tree, debug) |
2246 return self.GetPouInterfaceVars(pou, tree, debug) |
2181 return [] |
2247 return [] |
2182 |
2248 |
2183 # Return the edited element return type |
2249 # Return the edited element return type |
2184 def GetEditedElementInterfaceReturnType(self, tagname, tree=False, debug = False): |
2250 def GetEditedElementInterfaceReturnType(self, tagname, tree=False, debug=False): |
2185 words = tagname.split("::") |
2251 words = tagname.split("::") |
2186 if words[0] == "P": |
2252 if words[0] == "P": |
2187 project = self.GetProject(debug) |
2253 project = self.GetProject(debug) |
2188 if project is not None: |
2254 if project is not None: |
2189 pou = self.Project.getpou(words[1]) |
2255 pou = self.Project.getpou(words[1]) |
2199 element = self.GetEditedElement(tagname) |
2265 element = self.GetEditedElement(tagname) |
2200 if element is not None: |
2266 if element is not None: |
2201 element.settext(text) |
2267 element.settext(text) |
2202 |
2268 |
2203 # Return the edited element text |
2269 # Return the edited element text |
2204 def GetEditedElementText(self, tagname, debug = False): |
2270 def GetEditedElementText(self, tagname, debug=False): |
2205 element = self.GetEditedElement(tagname, debug) |
2271 element = self.GetEditedElement(tagname, debug) |
2206 if element is not None: |
2272 if element is not None: |
2207 return element.gettext() |
2273 return element.gettext() |
2208 return "" |
2274 return "" |
2209 |
2275 |
2210 # Return the edited element transitions |
2276 # Return the edited element transitions |
2211 def GetEditedElementTransitions(self, tagname, debug = False): |
2277 def GetEditedElementTransitions(self, tagname, debug=False): |
2212 pou = self.GetEditedElement(tagname, debug) |
2278 pou = self.GetEditedElement(tagname, debug) |
2213 if pou is not None and pou.getbodyType() == "SFC": |
2279 if pou is not None and pou.getbodyType() == "SFC": |
2214 transitions = [] |
2280 transitions = [] |
2215 for transition in pou.gettransitionList(): |
2281 for transition in pou.gettransitionList(): |
2216 transitions.append(transition.getname()) |
2282 transitions.append(transition.getname()) |
2217 return transitions |
2283 return transitions |
2218 return [] |
2284 return [] |
2219 |
2285 |
2220 # Return edited element transitions |
2286 # Return edited element transitions |
2221 def GetEditedElementActions(self, tagname, debug = False): |
2287 def GetEditedElementActions(self, tagname, debug=False): |
2222 pou = self.GetEditedElement(tagname, debug) |
2288 pou = self.GetEditedElement(tagname, debug) |
2223 if pou is not None and pou.getbodyType() == "SFC": |
2289 if pou is not None and pou.getbodyType() == "SFC": |
2224 actions = [] |
2290 actions = [] |
2225 for action in pou.getactionList(): |
2291 for action in pou.getactionList(): |
2226 actions.append(action.getname()) |
2292 actions.append(action.getname()) |
2227 return actions |
2293 return actions |
2228 return [] |
2294 return [] |
2229 |
2295 |
2230 # Return the names of the pou elements |
2296 # Return the names of the pou elements |
2231 def GetEditedElementVariables(self, tagname, debug = False): |
2297 def GetEditedElementVariables(self, tagname, debug=False): |
2232 words = tagname.split("::") |
2298 words = tagname.split("::") |
2233 if words[0] in ["P","T","A"]: |
2299 if words[0] in ["P", "T", "A"]: |
2234 return self.GetProjectPouVariableNames(words[1], debug) |
2300 return self.GetProjectPouVariableNames(words[1], debug) |
2235 elif words[0] in ["C", "R"]: |
2301 elif words[0] in ["C", "R"]: |
2236 names = self.GetConfigurationVariableNames(words[1], debug) |
2302 names = self.GetConfigurationVariableNames(words[1], debug) |
2237 if words[0] == "R": |
2303 if words[0] == "R": |
2238 names.extend(self.GetConfigurationResourceVariableNames( |
2304 names.extend(self.GetConfigurationResourceVariableNames( |
2239 words[1], words[2], debug)) |
2305 words[1], words[2], debug)) |
2240 return names |
2306 return names |
2241 return [] |
2307 return [] |
2242 |
2308 |
2243 def GetEditedElementCopy(self, tagname, debug = False): |
2309 def GetEditedElementCopy(self, tagname, debug=False): |
2244 element = self.GetEditedElement(tagname, debug) |
2310 element = self.GetEditedElement(tagname, debug) |
2245 if element is not None: |
2311 if element is not None: |
2246 return element.tostring() |
2312 return element.tostring() |
2247 return "" |
2313 return "" |
2248 |
2314 |
2249 def GetEditedElementInstancesCopy(self, tagname, blocks_id = None, wires = None, debug = False): |
2315 def GetEditedElementInstancesCopy(self, tagname, blocks_id=None, wires=None, debug=False): |
2250 element = self.GetEditedElement(tagname, debug) |
2316 element = self.GetEditedElement(tagname, debug) |
2251 text = "" |
2317 text = "" |
2252 if element is not None: |
2318 if element is not None: |
2253 wires = dict([(wire, True) |
2319 wires = dict([(wire, True) |
2254 for wire in wires |
2320 for wire in wires |
2271 names = exclude.copy() |
2337 names = exclude.copy() |
2272 if tagname is not None: |
2338 if tagname is not None: |
2273 names.update(dict([(varname.upper(), True) |
2339 names.update(dict([(varname.upper(), True) |
2274 for varname in self.GetEditedElementVariables(tagname, debug)])) |
2340 for varname in self.GetEditedElementVariables(tagname, debug)])) |
2275 words = tagname.split("::") |
2341 words = tagname.split("::") |
2276 if words[0] in ["P","T","A"]: |
2342 if words[0] in ["P", "T", "A"]: |
2277 element = self.GetEditedElement(tagname, debug) |
2343 element = self.GetEditedElement(tagname, debug) |
2278 if element is not None and element.getbodyType() not in ["ST", "IL"]: |
2344 if element is not None and element.getbodyType() not in ["ST", "IL"]: |
2279 for instance in element.getinstances(): |
2345 for instance in element.getinstances(): |
2280 if isinstance(instance, |
2346 if isinstance( |
2281 (PLCOpenParser.GetElementClass("step", "sfcObjects"), |
2347 instance, |
2282 PLCOpenParser.GetElementClass("connector", "commonObjects"), |
2348 (PLCOpenParser.GetElementClass("step", "sfcObjects"), |
2283 PLCOpenParser.GetElementClass("continuation", "commonObjects"))): |
2349 PLCOpenParser.GetElementClass("connector", "commonObjects"), |
|
2350 PLCOpenParser.GetElementClass("continuation", "commonObjects"))): |
2284 names[instance.getname().upper()] = True |
2351 names[instance.getname().upper()] = True |
2285 else: |
2352 else: |
2286 project = self.GetProject(debug) |
2353 project = self.GetProject(debug) |
2287 if project is not None: |
2354 if project is not None: |
2288 for datatype in project.getdataTypes(): |
2355 for datatype in project.getdataTypes(): |
2402 instance.setexecutionOrderId(0) |
2469 instance.setexecutionOrderId(0) |
2403 instance.translate(*diff) |
2470 instance.translate(*diff) |
2404 |
2471 |
2405 return new_id, connections |
2472 return new_id, connections |
2406 |
2473 |
2407 def GetEditedElementInstancesInfos(self, tagname, debug = False): |
2474 def GetEditedElementInstancesInfos(self, tagname, debug=False): |
2408 element_instances = OrderedDict() |
2475 element_instances = OrderedDict() |
2409 element = self.GetEditedElement(tagname, debug) |
2476 element = self.GetEditedElement(tagname, debug) |
2410 if element is not None: |
2477 if element is not None: |
2411 factory = BlockInstanceFactory(element_instances) |
2478 factory = BlockInstanceFactory(element_instances) |
2412 |
2479 |
2413 pou_block_instances_xslt_tree = etree.XSLT( |
2480 pou_block_instances_xslt_tree = etree.XSLT( |
2414 pou_block_instances_xslt, |
2481 pou_block_instances_xslt, |
2415 extensions = { |
2482 extensions={ |
2416 ("pou_block_instances_ns", name): getattr(factory, name) |
2483 ("pou_block_instances_ns", name): getattr(factory, name) |
2417 for name in ["AddBlockInstance", "SetSpecificValues", |
2484 for name in ["AddBlockInstance", "SetSpecificValues", |
2418 "AddInstanceConnection", "AddConnectionLink", |
2485 "AddInstanceConnection", "AddConnectionLink", |
2419 "AddLinkPoint", "AddAction"]}) |
2486 "AddLinkPoint", "AddAction"]}) |
2420 |
2487 |
3074 new_task = PLCOpenParser.CreateElement("task", "resource") |
3141 new_task = PLCOpenParser.CreateElement("task", "resource") |
3075 resource.appendtask(new_task) |
3142 resource.appendtask(new_task) |
3076 new_task.setname(task["Name"]) |
3143 new_task.setname(task["Name"]) |
3077 if task["Triggering"] == "Interrupt": |
3144 if task["Triggering"] == "Interrupt": |
3078 new_task.setsingle(task["Single"]) |
3145 new_task.setsingle(task["Single"]) |
3079 ## result = duration_model.match(task["Interval"]).groups() |
3146 # result = duration_model.match(task["Interval"]).groups() |
3080 ## if reduce(lambda x, y: x or y != None, result): |
3147 # if reduce(lambda x, y: x or y != None, result): |
3081 ## values = [] |
3148 # values = [] |
3082 ## for value in result[:-1]: |
3149 # for value in result[:-1]: |
3083 ## if value != None: |
3150 # if value != None: |
3084 ## values.append(int(value)) |
3151 # values.append(int(value)) |
3085 ## else: |
3152 # else: |
3086 ## values.append(0) |
3153 # values.append(0) |
3087 ## if result[-1] is not None: |
3154 # if result[-1] is not None: |
3088 ## values.append(int(float(result[-1]) * 1000)) |
3155 # values.append(int(float(result[-1]) * 1000)) |
3089 ## new_task.setinterval(datetime.time(*values)) |
3156 # new_task.setinterval(datetime.time(*values)) |
3090 if task["Triggering"] == "Cyclic": |
3157 if task["Triggering"] == "Cyclic": |
3091 new_task.setinterval(task["Interval"]) |
3158 new_task.setinterval(task["Interval"]) |
3092 new_task.setpriority(int(task["Priority"])) |
3159 new_task.setpriority(int(task["Priority"])) |
3093 if task["Name"] != "": |
3160 if task["Name"] != "": |
3094 task_list[task["Name"]] = new_task |
3161 task_list[task["Name"]] = new_task |
3118 new_task["Single"] = single |
3185 new_task["Single"] = single |
3119 else: |
3186 else: |
3120 new_task["Single"] = "" |
3187 new_task["Single"] = "" |
3121 interval = task.getinterval() |
3188 interval = task.getinterval() |
3122 if interval is not None: |
3189 if interval is not None: |
3123 ## text = "" |
3190 # text = "" |
3124 ## if interval.hour != 0: |
3191 # if interval.hour != 0: |
3125 ## text += "%dh"%interval.hour |
3192 # text += "%dh"%interval.hour |
3126 ## if interval.minute != 0: |
3193 # if interval.minute != 0: |
3127 ## text += "%dm"%interval.minute |
3194 # text += "%dm"%interval.minute |
3128 ## if interval.second != 0: |
3195 # if interval.second != 0: |
3129 ## text += "%ds"%interval.second |
3196 # text += "%ds"%interval.second |
3130 ## if interval.microsecond != 0: |
3197 # if interval.microsecond != 0: |
3131 ## if interval.microsecond % 1000 != 0: |
3198 # if interval.microsecond % 1000 != 0: |
3132 ## text += "%.3fms"%(float(interval.microsecond) / 1000) |
3199 # text += "%.3fms"%(float(interval.microsecond) / 1000) |
3133 ## else: |
3200 # else: |
3134 ## text += "%dms"%(interval.microsecond / 1000) |
3201 # text += "%dms"%(interval.microsecond / 1000) |
3135 ## new_task["Interval"] = text |
3202 # new_task["Interval"] = text |
3136 new_task["Interval"] = interval |
3203 new_task["Interval"] = interval |
3137 else: |
3204 else: |
3138 new_task["Interval"] = "" |
3205 new_task["Interval"] = "" |
3139 if single is not None and interval is None: |
3206 if single is not None and interval is None: |
3140 new_task["Triggering"] = "Interrupt" |
3207 new_task["Triggering"] = "Interrupt" |
3207 if infos[1] in ["var_local", "var_input", "var_output", "var_inout"]: |
3274 if infos[1] in ["var_local", "var_input", "var_output", "var_inout"]: |
3208 search_results.append((infos, start, end, text)) |
3275 search_results.append((infos, start, end, text)) |
3209 return search_results |
3276 return search_results |
3210 return [] |
3277 return [] |
3211 |
3278 |
3212 #------------------------------------------------------------------------------- |
3279 # ------------------------------------------------------------------------------- |
3213 # Current Buffering Management Functions |
3280 # Current Buffering Management Functions |
3214 #------------------------------------------------------------------------------- |
3281 # ------------------------------------------------------------------------------- |
3215 |
3282 |
3216 """ |
|
3217 Return a copy of the project |
|
3218 """ |
|
3219 def Copy(self, model): |
3283 def Copy(self, model): |
|
3284 """Return a copy of the project""" |
3220 return deepcopy(model) |
3285 return deepcopy(model) |
3221 |
3286 |
3222 def CreateProjectBuffer(self, saved): |
3287 def CreateProjectBuffer(self, saved): |
3223 if self.ProjectBufferEnabled: |
3288 if self.ProjectBufferEnabled: |
3224 self.ProjectBuffer = UndoBuffer(PLCOpenParser.Dumps(self.Project), saved) |
3289 self.ProjectBuffer = UndoBuffer(PLCOpenParser.Dumps(self.Project), saved) |