29 from copy import deepcopy |
29 from copy import deepcopy |
30 import os |
30 import os |
31 import re |
31 import re |
32 import datetime |
32 import datetime |
33 from time import localtime |
33 from time import localtime |
34 from collections import OrderedDict, namedtuple |
|
35 |
|
36 from lxml import etree |
|
37 |
34 |
38 import util.paths as paths |
35 import util.paths as paths |
39 from plcopen import * |
36 from plcopen import * |
40 from plcopen.types_enums import * |
37 from plcopen.types_enums import * |
41 from plcopen.XSLTModelQuery import _StringValue, _BoolValue, _translate_args |
38 from plcopen.XSLTModelQuery import _StringValue, _BoolValue, _translate_args |
42 from plcopen.InstancesPathCollector import InstancesPathCollector |
39 from plcopen.InstancesPathCollector import InstancesPathCollector |
43 from plcopen.POUVariablesCollector import POUVariablesCollector |
40 from plcopen.POUVariablesCollector import POUVariablesCollector |
44 from plcopen.InstanceTagnameCollector import InstanceTagnameCollector |
41 from plcopen.InstanceTagnameCollector import InstanceTagnameCollector |
|
42 from plcopen.BlockInstanceCollector import BlockInstanceCollector |
45 from plcopen.VariableInfoCollector import VariableInfoCollector |
43 from plcopen.VariableInfoCollector import VariableInfoCollector |
46 from graphics.GraphicCommons import * |
44 from graphics.GraphicCommons import * |
47 from PLCGenerator import * |
45 from PLCGenerator import * |
48 |
46 |
49 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)?") |
47 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)?") |
50 |
48 |
51 ScriptDirectory = paths.AbsDir(__file__) |
49 ScriptDirectory = paths.AbsDir(__file__) |
52 |
50 |
53 # ------------------------------------------------------------------------------- |
|
54 # Helpers object for generating pou block instances list |
|
55 # ------------------------------------------------------------------------------- |
|
56 |
|
57 |
|
58 _Point = namedtuple("Point", ["x", "y"]) |
|
59 |
|
60 _BlockInstanceInfos = namedtuple( |
|
61 "BlockInstanceInfos", |
|
62 ["type", "id", "x", "y", "width", "height", "specific_values", "inputs", "outputs"]) |
|
63 |
|
64 _BlockSpecificValues = ( |
|
65 namedtuple("BlockSpecificValues", |
|
66 ["name", "execution_order"]), |
|
67 [_StringValue, int]) |
|
68 _VariableSpecificValues = ( |
|
69 namedtuple("VariableSpecificValues", |
|
70 ["name", "value_type", "execution_order"]), |
|
71 [_StringValue, _StringValue, int]) |
|
72 _ConnectionSpecificValues = ( |
|
73 namedtuple("ConnectionSpecificValues", ["name"]), |
|
74 [_StringValue]) |
|
75 |
|
76 _PowerRailSpecificValues = ( |
|
77 namedtuple("PowerRailSpecificValues", ["connectors"]), |
|
78 [int]) |
|
79 |
|
80 _LDElementSpecificValues = ( |
|
81 namedtuple("LDElementSpecificValues", |
|
82 ["name", "negated", "edge", "storage", "execution_order"]), |
|
83 [_StringValue, _BoolValue, _StringValue, _StringValue, int]) |
|
84 |
|
85 _DivergenceSpecificValues = ( |
|
86 namedtuple("DivergenceSpecificValues", ["connectors"]), |
|
87 [int]) |
|
88 |
|
89 _SpecificValuesTuples = { |
|
90 "comment": ( |
|
91 namedtuple("CommentSpecificValues", ["content"]), |
|
92 [_StringValue]), |
|
93 "input": _VariableSpecificValues, |
|
94 "output": _VariableSpecificValues, |
|
95 "inout": _VariableSpecificValues, |
|
96 "connector": _ConnectionSpecificValues, |
|
97 "continuation": _ConnectionSpecificValues, |
|
98 "leftPowerRail": _PowerRailSpecificValues, |
|
99 "rightPowerRail": _PowerRailSpecificValues, |
|
100 "contact": _LDElementSpecificValues, |
|
101 "coil": _LDElementSpecificValues, |
|
102 "step": ( |
|
103 namedtuple("StepSpecificValues", ["name", "initial", "action"]), |
|
104 [_StringValue, _BoolValue, lambda x: x]), |
|
105 "transition": ( |
|
106 namedtuple("TransitionSpecificValues", |
|
107 ["priority", "condition_type", "condition", "connection"]), |
|
108 [int, _StringValue, _StringValue, lambda x: x]), |
|
109 "selectionDivergence": _DivergenceSpecificValues, |
|
110 "selectionConvergence": _DivergenceSpecificValues, |
|
111 "simultaneousDivergence": _DivergenceSpecificValues, |
|
112 "simultaneousConvergence": _DivergenceSpecificValues, |
|
113 "jump": ( |
|
114 namedtuple("JumpSpecificValues", ["target"]), |
|
115 [_StringValue]), |
|
116 "actionBlock": ( |
|
117 namedtuple("ActionBlockSpecificValues", ["actions"]), |
|
118 [lambda x: x]), |
|
119 } |
|
120 |
|
121 _InstanceConnectionInfos = namedtuple( |
|
122 "InstanceConnectionInfos", |
|
123 ["name", "negated", "edge", "position", "links"]) |
|
124 |
|
125 _ConnectionLinkInfos = namedtuple( |
|
126 "ConnectionLinkInfos", |
|
127 ["refLocalId", "formalParameter", "points"]) |
|
128 |
|
129 |
|
130 class _ActionInfos(object): |
|
131 __slots__ = ["qualifier", "type", "value", "duration", "indicator"] |
|
132 |
|
133 def __init__(self, *args): |
|
134 for attr, value in zip(self.__slots__, args): |
|
135 setattr(self, attr, value if value is not None else "") |
|
136 |
|
137 def copy(self): |
|
138 return _ActionInfos(*[getattr(self, attr) for attr in self.__slots__]) |
|
139 |
|
140 |
|
141 class BlockInstanceFactory(object): |
|
142 |
|
143 def __init__(self, block_instances): |
|
144 self.BlockInstances = block_instances |
|
145 self.CurrentInstance = None |
|
146 self.SpecificValues = None |
|
147 self.CurrentConnection = None |
|
148 self.CurrentLink = None |
|
149 |
|
150 def SetSpecificValues(self, context, *args): |
|
151 self.SpecificValues = list(args) |
|
152 self.CurrentInstance = None |
|
153 self.CurrentConnection = None |
|
154 self.CurrentLink = None |
|
155 |
|
156 def AddBlockInstance(self, context, *args): |
|
157 specific_values_tuple, specific_values_translation = \ |
|
158 _SpecificValuesTuples.get(args[0][0], _BlockSpecificValues) |
|
159 |
|
160 if args[0][0] == "step" and len(self.SpecificValues) < 3 or \ |
|
161 args[0][0] == "transition" and len(self.SpecificValues) < 4: |
|
162 self.SpecificValues.append([None]) |
|
163 elif args[0][0] == "actionBlock" and len(self.SpecificValues) < 1: |
|
164 self.SpecificValues.append([[]]) |
|
165 specific_values = specific_values_tuple(*_translate_args( |
|
166 specific_values_translation, self.SpecificValues)) |
|
167 self.SpecificValues = None |
|
168 |
|
169 self.CurrentInstance = _BlockInstanceInfos( |
|
170 *(_translate_args([_StringValue, int] + [float] * 4, args) + |
|
171 [specific_values, [], []])) |
|
172 |
|
173 self.BlockInstances[self.CurrentInstance.id] = self.CurrentInstance |
|
174 |
|
175 def AddInstanceConnection(self, context, *args): |
|
176 connection_args = _translate_args( |
|
177 [_StringValue] * 2 + [_BoolValue, _StringValue] + [float] * 2, args) |
|
178 |
|
179 self.CurrentConnection = _InstanceConnectionInfos( |
|
180 *(connection_args[1:4] + [ |
|
181 _Point(*connection_args[4:6]), []])) |
|
182 |
|
183 if self.CurrentInstance is not None: |
|
184 if connection_args[0] == "input": |
|
185 self.CurrentInstance.inputs.append(self.CurrentConnection) |
|
186 else: |
|
187 self.CurrentInstance.outputs.append(self.CurrentConnection) |
|
188 else: |
|
189 self.SpecificValues.append([self.CurrentConnection]) |
|
190 |
|
191 def AddConnectionLink(self, context, *args): |
|
192 self.CurrentLink = _ConnectionLinkInfos( |
|
193 *(_translate_args([int, _StringValue], args) + [[]])) |
|
194 self.CurrentConnection.links.append(self.CurrentLink) |
|
195 |
|
196 def AddLinkPoint(self, context, *args): |
|
197 self.CurrentLink.points.append(_Point( |
|
198 *_translate_args([float] * 2, args))) |
|
199 |
|
200 def AddAction(self, context, *args): |
|
201 if len(self.SpecificValues) == 0: |
|
202 self.SpecificValues.append([[]]) |
|
203 translated_args = _translate_args([_StringValue] * 5, args) |
|
204 self.SpecificValues[0][0].append(_ActionInfos(*translated_args)) |
|
205 |
|
206 |
|
207 pou_block_instances_xslt = etree.parse( |
|
208 os.path.join(ScriptDirectory, "plcopen", "pou_block_instances.xslt")) |
|
209 |
51 |
210 |
52 |
211 # Length of the buffer |
53 # Length of the buffer |
212 UNDO_BUFFER_LENGTH = 20 |
54 UNDO_BUFFER_LENGTH = 20 |
213 |
55 |