author | Edouard Tisserant <edouard.tisserant@gmail.com> |
Thu, 02 Feb 2023 17:17:04 +0100 | |
branch | wxPython4 |
changeset 3720 | d0a9c01ee7a5 |
parent 3704 | c17fac18c663 |
child 3750 | f62625418bff |
permissions | -rw-r--r-- |
814 | 1 |
#!/usr/bin/env python |
2 |
# -*- coding: utf-8 -*- |
|
3 |
||
1571
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1450
diff
changeset
|
4 |
# This file is part of Beremiz, a Integrated Development Environment for |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1450
diff
changeset
|
5 |
# programming IEC 61131-3 automates supporting plcopen standard and CanFestival. |
814 | 6 |
# |
1571
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1450
diff
changeset
|
7 |
# Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD |
814 | 8 |
# |
1571
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1450
diff
changeset
|
9 |
# See COPYING file for copyrights details. |
814 | 10 |
# |
1571
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1450
diff
changeset
|
11 |
# This program is free software; you can redistribute it and/or |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1450
diff
changeset
|
12 |
# modify it under the terms of the GNU General Public License |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1450
diff
changeset
|
13 |
# as published by the Free Software Foundation; either version 2 |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1450
diff
changeset
|
14 |
# of the License, or (at your option) any later version. |
814 | 15 |
# |
1571
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1450
diff
changeset
|
16 |
# This program is distributed in the hope that it will be useful, |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1450
diff
changeset
|
17 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1450
diff
changeset
|
18 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1450
diff
changeset
|
19 |
# GNU General Public License for more details. |
814 | 20 |
# |
1571
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1450
diff
changeset
|
21 |
# You should have received a copy of the GNU General Public License |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1450
diff
changeset
|
22 |
# along with this program; if not, write to the Free Software |
486f94a8032c
fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1450
diff
changeset
|
23 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
814 | 24 |
|
1832
0f1081928d65
fix wrong-import-order. first standard modules are imported, then others
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1831
diff
changeset
|
25 |
|
1881
091005ec69c4
fix pylint py3k conversion warning: "(no-absolute-import) import missing `from __future__ import absolute_import`"
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1878
diff
changeset
|
26 |
from __future__ import absolute_import |
1832
0f1081928d65
fix wrong-import-order. first standard modules are imported, then others
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1831
diff
changeset
|
27 |
import re |
2456
7373e3048167
python3 support: pylint,W1610 # (reduce-builtin) reduce built-in referenced
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2450
diff
changeset
|
28 |
from functools import reduce |
2432
dbc065a2f7a5
python3 support: pylint, W1613 # (xrange-builtin) xrange built-in referenced
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2418
diff
changeset
|
29 |
from six.moves import xrange |
dbc065a2f7a5
python3 support: pylint, W1613 # (xrange-builtin) xrange built-in referenced
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2418
diff
changeset
|
30 |
|
1297 | 31 |
from plcopen import PLCOpenParser |
814 | 32 |
from plcopen.structures import * |
1948
b9a3f771aaab
Moved some definitions away from controller class, and adaped references them through all code.
Edouard Tisserant
parents:
1881
diff
changeset
|
33 |
from plcopen.types_enums import * |
1832
0f1081928d65
fix wrong-import-order. first standard modules are imported, then others
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1831
diff
changeset
|
34 |
|
814 | 35 |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
36 |
# Dictionary associating PLCOpen variable categories to the corresponding |
814 | 37 |
# IEC 61131-3 variable categories |
1739
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1736
diff
changeset
|
38 |
varTypeNames = {"localVars": "VAR", "tempVars": "VAR_TEMP", "inputVars": "VAR_INPUT", |
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1736
diff
changeset
|
39 |
"outputVars": "VAR_OUTPUT", "inOutVars": "VAR_IN_OUT", "externalVars": "VAR_EXTERNAL", |
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1736
diff
changeset
|
40 |
"globalVars": "VAR_GLOBAL", "accessVars": "VAR_ACCESS"} |
814 | 41 |
|
42 |
||
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
43 |
# Dictionary associating PLCOpen POU categories to the corresponding |
814 | 44 |
# IEC 61131-3 POU categories |
1739
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1736
diff
changeset
|
45 |
pouTypeNames = {"function": "FUNCTION", "functionBlock": "FUNCTION_BLOCK", "program": "PROGRAM"} |
814 | 46 |
|
47 |
||
48 |
errorVarTypes = { |
|
49 |
"VAR_INPUT": "var_input", |
|
50 |
"VAR_OUTPUT": "var_output", |
|
51 |
"VAR_INOUT": "var_inout", |
|
52 |
} |
|
53 |
||
1736
7e61baa047f0
clean-up: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset
|
54 |
|
814 | 55 |
def ReIndentText(text, nb_spaces): |
1736
7e61baa047f0
clean-up: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset
|
56 |
""" Helper function for reindenting text """ |
814 | 57 |
compute = "" |
58 |
lines = text.splitlines() |
|
59 |
if len(lines) > 0: |
|
60 |
line_num = 0 |
|
61 |
while line_num < len(lines) and len(lines[line_num].strip()) == 0: |
|
62 |
line_num += 1 |
|
63 |
if line_num < len(lines): |
|
64 |
spaces = 0 |
|
65 |
while lines[line_num][spaces] == " ": |
|
66 |
spaces += 1 |
|
67 |
indent = "" |
|
1847
6198190bc121
explicitly mark unused variables found by pylint with _ or dummy
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1846
diff
changeset
|
68 |
for dummy in xrange(spaces, nb_spaces): |
814 | 69 |
indent += " " |
70 |
for line in lines: |
|
71 |
if line != "": |
|
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
72 |
compute += "%s%s\n" % (indent, line) |
814 | 73 |
else: |
74 |
compute += "\n" |
|
75 |
return compute |
|
76 |
||
1736
7e61baa047f0
clean-up: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset
|
77 |
|
814 | 78 |
def SortInstances(a, b): |
79 |
ax, ay = int(a.getx()), int(a.gety()) |
|
80 |
bx, by = int(b.getx()), int(b.gety()) |
|
81 |
if abs(ay - by) < 10: |
|
82 |
return cmp(ax, bx) |
|
83 |
else: |
|
84 |
return cmp(ay, by) |
|
85 |
||
1736
7e61baa047f0
clean-up: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset
|
86 |
|
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
87 |
def JoinList(separator, mylist): |
1736
7e61baa047f0
clean-up: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset
|
88 |
""" Helper for emulate join on element list """ |
1739
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1736
diff
changeset
|
89 |
if len(mylist) > 0: |
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
90 |
return reduce(lambda x, y: x + separator + y, mylist) |
1739
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1736
diff
changeset
|
91 |
else: |
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
92 |
return mylist |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
93 |
|
1782
5b6ad7a7fd9d
clean-up: fix PEP8 E265 block comment should start with '# '
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1775
diff
changeset
|
94 |
# ------------------------------------------------------------------------------- |
814 | 95 |
# Specific exception for PLC generating errors |
1782
5b6ad7a7fd9d
clean-up: fix PEP8 E265 block comment should start with '# '
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1775
diff
changeset
|
96 |
# ------------------------------------------------------------------------------- |
814 | 97 |
|
98 |
||
99 |
class PLCGenException(Exception): |
|
100 |
pass |
|
101 |
||
102 |
||
1782
5b6ad7a7fd9d
clean-up: fix PEP8 E265 block comment should start with '# '
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1775
diff
changeset
|
103 |
# ------------------------------------------------------------------------------- |
814 | 104 |
# Generator of PLC program |
1782
5b6ad7a7fd9d
clean-up: fix PEP8 E265 block comment should start with '# '
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1775
diff
changeset
|
105 |
# ------------------------------------------------------------------------------- |
814 | 106 |
|
107 |
||
1831
56b48961cc68
fix (old-style-class) Old-style class defined error for most parts of
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1782
diff
changeset
|
108 |
class ProgramGenerator(object): |
814 | 109 |
|
110 |
# Create a new PCL program generator |
|
111 |
def __init__(self, controler, project, errors, warnings): |
|
112 |
# Keep reference of the controler and project |
|
113 |
self.Controler = controler |
|
114 |
self.Project = project |
|
115 |
# Reset the internal variables used to generate PLC programs |
|
116 |
self.Program = [] |
|
117 |
self.DatatypeComputed = {} |
|
118 |
self.PouComputed = {} |
|
119 |
self.Errors = errors |
|
120 |
self.Warnings = warnings |
|
121 |
||
122 |
# Compute value according to type given |
|
123 |
def ComputeValue(self, value, var_type): |
|
124 |
base_type = self.Controler.GetBaseType(var_type) |
|
1032
c4989e53f9c3
Fix bug defining string initial value using quotes
Laurent Bessard
parents:
893
diff
changeset
|
125 |
if base_type == "STRING" and not value.startswith("'") and not value.endswith("'"): |
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
126 |
return "'%s'" % value |
1032
c4989e53f9c3
Fix bug defining string initial value using quotes
Laurent Bessard
parents:
893
diff
changeset
|
127 |
elif base_type == "WSTRING" and not value.startswith('"') and not value.endswith('"'): |
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
128 |
return "\"%s\"" % value |
814 | 129 |
return value |
130 |
||
131 |
# Generate a data type from its name |
|
132 |
def GenerateDataType(self, datatype_name): |
|
133 |
# Verify that data type hasn't been generated yet |
|
134 |
if not self.DatatypeComputed.get(datatype_name, True): |
|
135 |
# If not mark data type as computed |
|
136 |
self.DatatypeComputed[datatype_name] = True |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
137 |
|
814 | 138 |
# Getting datatype model from project |
139 |
datatype = self.Project.getdataType(datatype_name) |
|
1948
b9a3f771aaab
Moved some definitions away from controller class, and adaped references them through all code.
Edouard Tisserant
parents:
1881
diff
changeset
|
140 |
tagname = ComputeDataTypeName(datatype.getname()) |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
141 |
datatype_def = [(" ", ()), |
814 | 142 |
(datatype.getname(), (tagname, "name")), |
143 |
(" : ", ())] |
|
144 |
basetype_content = datatype.baseType.getcontent() |
|
1297 | 145 |
basetype_content_type = basetype_content.getLocalTag() |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
146 |
# Data type derived directly from a user defined type |
1297 | 147 |
if basetype_content_type == "derived": |
148 |
basetype_name = basetype_content.getname() |
|
814 | 149 |
self.GenerateDataType(basetype_name) |
150 |
datatype_def += [(basetype_name, (tagname, "base"))] |
|
151 |
# Data type is a subrange |
|
1297 | 152 |
elif basetype_content_type in ["subrangeSigned", "subrangeUnsigned"]: |
153 |
base_type = basetype_content.baseType.getcontent() |
|
154 |
base_type_type = base_type.getLocalTag() |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
155 |
# Subrange derived directly from a user defined type |
1297 | 156 |
if base_type_type == "derived": |
157 |
basetype_name = base_type_type.getname() |
|
814 | 158 |
self.GenerateDataType(basetype_name) |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
159 |
# Subrange derived directly from an elementary type |
814 | 160 |
else: |
1297 | 161 |
basetype_name = base_type_type |
162 |
min_value = basetype_content.range.getlower() |
|
163 |
max_value = basetype_content.range.getupper() |
|
814 | 164 |
datatype_def += [(basetype_name, (tagname, "base")), |
165 |
(" (", ()), |
|
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
166 |
("%s" % min_value, (tagname, "lower")), |
814 | 167 |
("..", ()), |
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
168 |
("%s" % max_value, (tagname, "upper")), |
1740
b789b695b5c6
clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1739
diff
changeset
|
169 |
(")", ())] |
814 | 170 |
# Data type is an enumerated type |
1297 | 171 |
elif basetype_content_type == "enum": |
814 | 172 |
values = [[(value.getname(), (tagname, "value", i))] |
1297 | 173 |
for i, value in enumerate( |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
174 |
basetype_content.xpath("ppx:values/ppx:value", |
1768
691083b5682a
clean-up: fix PEP8 E128 continuation line under-indented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset
|
175 |
namespaces=PLCOpenParser.NSMAP))] |
814 | 176 |
datatype_def += [("(", ())] |
177 |
datatype_def += JoinList([(", ", ())], values) |
|
178 |
datatype_def += [(")", ())] |
|
179 |
# Data type is an array |
|
1297 | 180 |
elif basetype_content_type == "array": |
181 |
base_type = basetype_content.baseType.getcontent() |
|
182 |
base_type_type = base_type.getLocalTag() |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
183 |
# Array derived directly from a user defined type |
1297 | 184 |
if base_type_type == "derived": |
185 |
basetype_name = base_type.getname() |
|
814 | 186 |
self.GenerateDataType(basetype_name) |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
187 |
# Array derived directly from an elementary type |
814 | 188 |
else: |
1297 | 189 |
basetype_name = base_type_type.upper() |
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
190 |
dimensions = [[("%s" % dimension.getlower(), (tagname, "range", i, "lower")), |
814 | 191 |
("..", ()), |
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
192 |
("%s" % dimension.getupper(), (tagname, "range", i, "upper"))] |
1297 | 193 |
for i, dimension in enumerate(basetype_content.getdimension())] |
814 | 194 |
datatype_def += [("ARRAY [", ())] |
195 |
datatype_def += JoinList([(",", ())], dimensions) |
|
1739
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1736
diff
changeset
|
196 |
datatype_def += [("] OF ", ()), |
814 | 197 |
(basetype_name, (tagname, "base"))] |
198 |
# Data type is a structure |
|
1297 | 199 |
elif basetype_content_type == "struct": |
814 | 200 |
elements = [] |
1297 | 201 |
for i, element in enumerate(basetype_content.getvariable()): |
814 | 202 |
element_type = element.type.getcontent() |
1297 | 203 |
element_type_type = element_type.getLocalTag() |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
204 |
# Structure element derived directly from a user defined type |
1297 | 205 |
if element_type_type == "derived": |
206 |
elementtype_name = element_type.getname() |
|
814 | 207 |
self.GenerateDataType(elementtype_name) |
1297 | 208 |
elif element_type_type == "array": |
209 |
base_type = element_type.baseType.getcontent() |
|
210 |
base_type_type = base_type.getLocalTag() |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
211 |
# Array derived directly from a user defined type |
1297 | 212 |
if base_type_type == "derived": |
213 |
basetype_name = base_type.getname() |
|
864
bf4f7f0801b9
Adding support for direct array declaration in structure element declaration
Laurent Bessard
parents:
854
diff
changeset
|
214 |
self.GenerateDataType(basetype_name) |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
215 |
# Array derived directly from an elementary type |
864
bf4f7f0801b9
Adding support for direct array declaration in structure element declaration
Laurent Bessard
parents:
854
diff
changeset
|
216 |
else: |
1297 | 217 |
basetype_name = base_type_type.upper() |
864
bf4f7f0801b9
Adding support for direct array declaration in structure element declaration
Laurent Bessard
parents:
854
diff
changeset
|
218 |
dimensions = ["%s..%s" % (dimension.getlower(), dimension.getupper()) |
1297 | 219 |
for dimension in element_type.getdimension()] |
864
bf4f7f0801b9
Adding support for direct array declaration in structure element declaration
Laurent Bessard
parents:
854
diff
changeset
|
220 |
elementtype_name = "ARRAY [%s] OF %s" % (",".join(dimensions), basetype_name) |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
221 |
# Structure element derived directly from an elementary type |
814 | 222 |
else: |
1297 | 223 |
elementtype_name = element_type_type.upper() |
814 | 224 |
element_text = [("\n ", ()), |
225 |
(element.getname(), (tagname, "struct", i, "name")), |
|
226 |
(" : ", ()), |
|
227 |
(elementtype_name, (tagname, "struct", i, "type"))] |
|
228 |
if element.initialValue is not None: |
|
229 |
element_text.extend([(" := ", ()), |
|
230 |
(self.ComputeValue(element.initialValue.getvalue(), elementtype_name), (tagname, "struct", i, "initial value"))]) |
|
231 |
element_text.append((";", ())) |
|
232 |
elements.append(element_text) |
|
233 |
datatype_def += [("STRUCT", ())] |
|
234 |
datatype_def += JoinList([("", ())], elements) |
|
235 |
datatype_def += [("\n END_STRUCT", ())] |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
236 |
# Data type derived directly from a elementary type |
814 | 237 |
else: |
1297 | 238 |
datatype_def += [(basetype_content_type.upper(), (tagname, "base"))] |
814 | 239 |
# Data type has an initial value |
240 |
if datatype.initialValue is not None: |
|
241 |
datatype_def += [(" := ", ()), |
|
242 |
(self.ComputeValue(datatype.initialValue.getvalue(), datatype_name), (tagname, "initial value"))] |
|
243 |
datatype_def += [(";\n", ())] |
|
244 |
self.Program += datatype_def |
|
245 |
||
246 |
# Generate a POU from its name |
|
247 |
def GeneratePouProgram(self, pou_name): |
|
248 |
# Verify that POU hasn't been generated yet |
|
249 |
if not self.PouComputed.get(pou_name, True): |
|
250 |
# If not mark POU as computed |
|
251 |
self.PouComputed[pou_name] = True |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
252 |
|
814 | 253 |
# Getting POU model from project |
254 |
pou = self.Project.getpou(pou_name) |
|
255 |
pou_type = pou.getpouType() |
|
256 |
# Verify that POU type exists |
|
1763
bcc07ff2362c
clean-up: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1753
diff
changeset
|
257 |
if pou_type in pouTypeNames: |
814 | 258 |
# Create a POU program generator |
259 |
pou_program = PouProgramGenerator(self, pou.getname(), pouTypeNames[pou_type], self.Errors, self.Warnings) |
|
260 |
program = pou_program.GenerateProgram(pou) |
|
261 |
self.Program += program |
|
262 |
else: |
|
1765
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
263 |
raise PLCGenException(_("Undefined pou type \"%s\"") % pou_type) |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
264 |
|
814 | 265 |
# Generate a POU defined and used in text |
266 |
def GeneratePouProgramInText(self, text): |
|
267 |
for pou_name in self.PouComputed.keys(): |
|
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
268 |
model = re.compile("(?:^|[^0-9^A-Z])%s(?:$|[^0-9^A-Z])" % pou_name.upper()) |
814 | 269 |
if model.search(text) is not None: |
270 |
self.GeneratePouProgram(pou_name) |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
271 |
|
814 | 272 |
# Generate a configuration from its model |
273 |
def GenerateConfiguration(self, configuration): |
|
1948
b9a3f771aaab
Moved some definitions away from controller class, and adaped references them through all code.
Edouard Tisserant
parents:
1881
diff
changeset
|
274 |
tagname = ComputeConfigurationName(configuration.getname()) |
814 | 275 |
config = [("\nCONFIGURATION ", ()), |
276 |
(configuration.getname(), (tagname, "name")), |
|
277 |
("\n", ())] |
|
278 |
var_number = 0 |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
279 |
|
3704
c17fac18c663
ST code generator: when including PLCopen TC6 XML libraries (for example py_ext/pous.xml or NativeLib.xml), also includes libraries globals in result
Edouard Tisserant
parents:
2727
diff
changeset
|
280 |
varlists = configuration.getglobalVars()[:] |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
281 |
|
883
235a9ec83b95
Adding support for defining specific global variables for ConfTreeNodes
Laurent Bessard
parents:
864
diff
changeset
|
282 |
extra_variables = self.Controler.GetConfigurationExtraVariables() |
3704
c17fac18c663
ST code generator: when including PLCopen TC6 XML libraries (for example py_ext/pous.xml or NativeLib.xml), also includes libraries globals in result
Edouard Tisserant
parents:
2727
diff
changeset
|
283 |
extra_CTN_globals = [] |
c17fac18c663
ST code generator: when including PLCopen TC6 XML libraries (for example py_ext/pous.xml or NativeLib.xml), also includes libraries globals in result
Edouard Tisserant
parents:
2727
diff
changeset
|
284 |
|
c17fac18c663
ST code generator: when including PLCopen TC6 XML libraries (for example py_ext/pous.xml or NativeLib.xml), also includes libraries globals in result
Edouard Tisserant
parents:
2727
diff
changeset
|
285 |
for item in extra_variables: |
c17fac18c663
ST code generator: when including PLCopen TC6 XML libraries (for example py_ext/pous.xml or NativeLib.xml), also includes libraries globals in result
Edouard Tisserant
parents:
2727
diff
changeset
|
286 |
if item.getLocalTag() == "globalVars": |
c17fac18c663
ST code generator: when including PLCopen TC6 XML libraries (for example py_ext/pous.xml or NativeLib.xml), also includes libraries globals in result
Edouard Tisserant
parents:
2727
diff
changeset
|
287 |
varlists.append(item) |
c17fac18c663
ST code generator: when including PLCopen TC6 XML libraries (for example py_ext/pous.xml or NativeLib.xml), also includes libraries globals in result
Edouard Tisserant
parents:
2727
diff
changeset
|
288 |
else: |
c17fac18c663
ST code generator: when including PLCopen TC6 XML libraries (for example py_ext/pous.xml or NativeLib.xml), also includes libraries globals in result
Edouard Tisserant
parents:
2727
diff
changeset
|
289 |
extra_CTN_globals.append(item) |
c17fac18c663
ST code generator: when including PLCopen TC6 XML libraries (for example py_ext/pous.xml or NativeLib.xml), also includes libraries globals in result
Edouard Tisserant
parents:
2727
diff
changeset
|
290 |
|
c17fac18c663
ST code generator: when including PLCopen TC6 XML libraries (for example py_ext/pous.xml or NativeLib.xml), also includes libraries globals in result
Edouard Tisserant
parents:
2727
diff
changeset
|
291 |
if len(extra_CTN_globals) > 0: |
c17fac18c663
ST code generator: when including PLCopen TC6 XML libraries (for example py_ext/pous.xml or NativeLib.xml), also includes libraries globals in result
Edouard Tisserant
parents:
2727
diff
changeset
|
292 |
extra_varlist = PLCOpenParser.CreateElement("globalVars", "interface") |
c17fac18c663
ST code generator: when including PLCopen TC6 XML libraries (for example py_ext/pous.xml or NativeLib.xml), also includes libraries globals in result
Edouard Tisserant
parents:
2727
diff
changeset
|
293 |
|
c17fac18c663
ST code generator: when including PLCopen TC6 XML libraries (for example py_ext/pous.xml or NativeLib.xml), also includes libraries globals in result
Edouard Tisserant
parents:
2727
diff
changeset
|
294 |
for variable in extra_CTN_globals: |
c17fac18c663
ST code generator: when including PLCopen TC6 XML libraries (for example py_ext/pous.xml or NativeLib.xml), also includes libraries globals in result
Edouard Tisserant
parents:
2727
diff
changeset
|
295 |
extra_varlist.appendvariable(variable) |
c17fac18c663
ST code generator: when including PLCopen TC6 XML libraries (for example py_ext/pous.xml or NativeLib.xml), also includes libraries globals in result
Edouard Tisserant
parents:
2727
diff
changeset
|
296 |
|
c17fac18c663
ST code generator: when including PLCopen TC6 XML libraries (for example py_ext/pous.xml or NativeLib.xml), also includes libraries globals in result
Edouard Tisserant
parents:
2727
diff
changeset
|
297 |
varlists.append(extra_varlist) |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
298 |
|
814 | 299 |
# Generate any global variable in configuration |
3704
c17fac18c663
ST code generator: when including PLCopen TC6 XML libraries (for example py_ext/pous.xml or NativeLib.xml), also includes libraries globals in result
Edouard Tisserant
parents:
2727
diff
changeset
|
300 |
for varlist in varlists: |
814 | 301 |
variable_type = errorVarTypes.get("VAR_GLOBAL", "var_local") |
302 |
# Generate variable block with modifier |
|
303 |
config += [(" VAR_GLOBAL", ())] |
|
304 |
if varlist.getconstant(): |
|
305 |
config += [(" CONSTANT", (tagname, variable_type, (var_number, var_number + len(varlist.getvariable())), "constant"))] |
|
306 |
elif varlist.getretain(): |
|
307 |
config += [(" RETAIN", (tagname, variable_type, (var_number, var_number + len(varlist.getvariable())), "retain"))] |
|
308 |
elif varlist.getnonretain(): |
|
309 |
config += [(" NON_RETAIN", (tagname, variable_type, (var_number, var_number + len(varlist.getvariable())), "non_retain"))] |
|
310 |
config += [("\n", ())] |
|
311 |
# Generate any variable of this block |
|
3704
c17fac18c663
ST code generator: when including PLCopen TC6 XML libraries (for example py_ext/pous.xml or NativeLib.xml), also includes libraries globals in result
Edouard Tisserant
parents:
2727
diff
changeset
|
312 |
for var in varlist.getvariable(): |
814 | 313 |
vartype_content = var.gettype().getcontent() |
1297 | 314 |
if vartype_content.getLocalTag() == "derived": |
315 |
var_type = vartype_content.getname() |
|
814 | 316 |
self.GenerateDataType(var_type) |
317 |
else: |
|
318 |
var_type = var.gettypeAsText() |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
319 |
|
814 | 320 |
config += [(" ", ()), |
321 |
(var.getname(), (tagname, variable_type, var_number, "name")), |
|
322 |
(" ", ())] |
|
323 |
# Generate variable address if exists |
|
324 |
address = var.getaddress() |
|
325 |
if address: |
|
326 |
config += [("AT ", ()), |
|
327 |
(address, (tagname, variable_type, var_number, "location")), |
|
328 |
(" ", ())] |
|
329 |
config += [(": ", ()), |
|
330 |
(var.gettypeAsText(), (tagname, variable_type, var_number, "type"))] |
|
331 |
# Generate variable initial value if exists |
|
332 |
initial = var.getinitialValue() |
|
1315
ff14a66bbd12
Fixed Beremiz for working with new xmlclass support using lxml
Laurent Bessard
parents:
1310
diff
changeset
|
333 |
if initial is not None: |
814 | 334 |
config += [(" := ", ()), |
335 |
(self.ComputeValue(initial.getvalue(), var_type), (tagname, variable_type, var_number, "initial value"))] |
|
336 |
config += [(";\n", ())] |
|
337 |
var_number += 1 |
|
338 |
config += [(" END_VAR\n", ())] |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
339 |
|
814 | 340 |
# Generate any resource in the configuration |
341 |
for resource in configuration.getresource(): |
|
342 |
config += self.GenerateResource(resource, configuration.getname()) |
|
343 |
config += [("END_CONFIGURATION\n", ())] |
|
344 |
return config |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
345 |
|
814 | 346 |
# Generate a resource from its model |
347 |
def GenerateResource(self, resource, config_name): |
|
1948
b9a3f771aaab
Moved some definitions away from controller class, and adaped references them through all code.
Edouard Tisserant
parents:
1881
diff
changeset
|
348 |
tagname = ComputeConfigurationResourceName(config_name, resource.getname()) |
814 | 349 |
resrce = [("\n RESOURCE ", ()), |
350 |
(resource.getname(), (tagname, "name")), |
|
351 |
(" ON PLC\n", ())] |
|
352 |
var_number = 0 |
|
353 |
# Generate any global variable in configuration |
|
354 |
for varlist in resource.getglobalVars(): |
|
355 |
variable_type = errorVarTypes.get("VAR_GLOBAL", "var_local") |
|
356 |
# Generate variable block with modifier |
|
357 |
resrce += [(" VAR_GLOBAL", ())] |
|
358 |
if varlist.getconstant(): |
|
359 |
resrce += [(" CONSTANT", (tagname, variable_type, (var_number, var_number + len(varlist.getvariable())), "constant"))] |
|
360 |
elif varlist.getretain(): |
|
361 |
resrce += [(" RETAIN", (tagname, variable_type, (var_number, var_number + len(varlist.getvariable())), "retain"))] |
|
362 |
elif varlist.getnonretain(): |
|
363 |
resrce += [(" NON_RETAIN", (tagname, variable_type, (var_number, var_number + len(varlist.getvariable())), "non_retain"))] |
|
364 |
resrce += [("\n", ())] |
|
365 |
# Generate any variable of this block |
|
366 |
for var in varlist.getvariable(): |
|
367 |
vartype_content = var.gettype().getcontent() |
|
1297 | 368 |
if vartype_content.getLocalTag() == "derived": |
369 |
var_type = vartype_content.getname() |
|
814 | 370 |
self.GenerateDataType(var_type) |
371 |
else: |
|
372 |
var_type = var.gettypeAsText() |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
373 |
|
814 | 374 |
resrce += [(" ", ()), |
375 |
(var.getname(), (tagname, variable_type, var_number, "name")), |
|
376 |
(" ", ())] |
|
377 |
address = var.getaddress() |
|
378 |
# Generate variable address if exists |
|
379 |
if address: |
|
380 |
resrce += [("AT ", ()), |
|
381 |
(address, (tagname, variable_type, var_number, "location")), |
|
382 |
(" ", ())] |
|
383 |
resrce += [(": ", ()), |
|
384 |
(var.gettypeAsText(), (tagname, variable_type, var_number, "type"))] |
|
385 |
# Generate variable initial value if exists |
|
386 |
initial = var.getinitialValue() |
|
1315
ff14a66bbd12
Fixed Beremiz for working with new xmlclass support using lxml
Laurent Bessard
parents:
1310
diff
changeset
|
387 |
if initial is not None: |
814 | 388 |
resrce += [(" := ", ()), |
389 |
(self.ComputeValue(initial.getvalue(), var_type), (tagname, variable_type, var_number, "initial value"))] |
|
390 |
resrce += [(";\n", ())] |
|
391 |
var_number += 1 |
|
392 |
resrce += [(" END_VAR\n", ())] |
|
393 |
# Generate any task in the resource |
|
394 |
tasks = resource.gettask() |
|
395 |
task_number = 0 |
|
396 |
for task in tasks: |
|
397 |
# Task declaration |
|
398 |
resrce += [(" TASK ", ()), |
|
399 |
(task.getname(), (tagname, "task", task_number, "name")), |
|
400 |
("(", ())] |
|
401 |
single = task.getsingle() |
|
402 |
# Single argument if exists |
|
1315
ff14a66bbd12
Fixed Beremiz for working with new xmlclass support using lxml
Laurent Bessard
parents:
1310
diff
changeset
|
403 |
if single is not None: |
1614
f8f05f849831
check during program generation whether source signal is defined for single task
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1603
diff
changeset
|
404 |
if len(single) == 0: |
1765
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
405 |
raise PLCGenException( |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
406 |
_("Source signal has to be defined for single task '{a1}' in resource '{a2}.{a3}'."). |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
407 |
format(a1=task.getname(), a2=config_name, a3=resource.getname())) |
1614
f8f05f849831
check during program generation whether source signal is defined for single task
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1603
diff
changeset
|
408 |
|
1742
92932cd370a4
clean-up: fix PEP8 E225 missing whitespace around operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1740
diff
changeset
|
409 |
if single[0] == '[' and single[-1] == ']': |
1420
71b1545d746f
Enable overloading of task triggerring source cell editor (SINGLE) in resource editor. PLCGenerator now generates MULTI keywork instead of SINGLE when task's activation is surroundes with square brackets
Edouard Tisserant
parents:
1418
diff
changeset
|
410 |
SNGLKW = "MULTI" |
71b1545d746f
Enable overloading of task triggerring source cell editor (SINGLE) in resource editor. PLCGenerator now generates MULTI keywork instead of SINGLE when task's activation is surroundes with square brackets
Edouard Tisserant
parents:
1418
diff
changeset
|
411 |
else: |
71b1545d746f
Enable overloading of task triggerring source cell editor (SINGLE) in resource editor. PLCGenerator now generates MULTI keywork instead of SINGLE when task's activation is surroundes with square brackets
Edouard Tisserant
parents:
1418
diff
changeset
|
412 |
SNGLKW = "SINGLE" |
71b1545d746f
Enable overloading of task triggerring source cell editor (SINGLE) in resource editor. PLCGenerator now generates MULTI keywork instead of SINGLE when task's activation is surroundes with square brackets
Edouard Tisserant
parents:
1418
diff
changeset
|
413 |
resrce += [(SNGLKW + " := ", ()), |
814 | 414 |
(single, (tagname, "task", task_number, "single")), |
415 |
(",", ())] |
|
416 |
# Interval argument if exists |
|
417 |
interval = task.getinterval() |
|
1315
ff14a66bbd12
Fixed Beremiz for working with new xmlclass support using lxml
Laurent Bessard
parents:
1310
diff
changeset
|
418 |
if interval is not None: |
814 | 419 |
resrce += [("INTERVAL := ", ()), |
420 |
(interval, (tagname, "task", task_number, "interval")), |
|
421 |
(",", ())] |
|
1753
19f19c66b67e
clean-up: fix most PEP8 E266 too many leading '#' for block comment
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1751
diff
changeset
|
422 |
# resrce += [("INTERVAL := t#", ())] |
19f19c66b67e
clean-up: fix most PEP8 E266 too many leading '#' for block comment
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1751
diff
changeset
|
423 |
# if interval.hour != 0: |
19f19c66b67e
clean-up: fix most PEP8 E266 too many leading '#' for block comment
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1751
diff
changeset
|
424 |
# resrce += [("%dh"%interval.hour, (tagname, "task", task_number, "interval", "hour"))] |
19f19c66b67e
clean-up: fix most PEP8 E266 too many leading '#' for block comment
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1751
diff
changeset
|
425 |
# if interval.minute != 0: |
19f19c66b67e
clean-up: fix most PEP8 E266 too many leading '#' for block comment
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1751
diff
changeset
|
426 |
# resrce += [("%dm"%interval.minute, (tagname, "task", task_number, "interval", "minute"))] |
19f19c66b67e
clean-up: fix most PEP8 E266 too many leading '#' for block comment
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1751
diff
changeset
|
427 |
# if interval.second != 0: |
19f19c66b67e
clean-up: fix most PEP8 E266 too many leading '#' for block comment
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1751
diff
changeset
|
428 |
# resrce += [("%ds"%interval.second, (tagname, "task", task_number, "interval", "second"))] |
19f19c66b67e
clean-up: fix most PEP8 E266 too many leading '#' for block comment
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1751
diff
changeset
|
429 |
# if interval.microsecond != 0: |
19f19c66b67e
clean-up: fix most PEP8 E266 too many leading '#' for block comment
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1751
diff
changeset
|
430 |
# resrce += [("%dms"%(interval.microsecond / 1000), (tagname, "task", task_number, "interval", "millisecond"))] |
19f19c66b67e
clean-up: fix most PEP8 E266 too many leading '#' for block comment
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1751
diff
changeset
|
431 |
# resrce += [(",", ())] |
814 | 432 |
# Priority argument |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
433 |
resrce += [("PRIORITY := ", ()), |
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
434 |
("%d" % task.getpriority(), (tagname, "task", task_number, "priority")), |
814 | 435 |
(");\n", ())] |
436 |
task_number += 1 |
|
437 |
instance_number = 0 |
|
438 |
# Generate any program assign to each task |
|
439 |
for task in tasks: |
|
440 |
for instance in task.getpouInstance(): |
|
441 |
resrce += [(" PROGRAM ", ()), |
|
442 |
(instance.getname(), (tagname, "instance", instance_number, "name")), |
|
443 |
(" WITH ", ()), |
|
444 |
(task.getname(), (tagname, "instance", instance_number, "task")), |
|
445 |
(" : ", ()), |
|
446 |
(instance.gettypeName(), (tagname, "instance", instance_number, "type")), |
|
447 |
(";\n", ())] |
|
448 |
instance_number += 1 |
|
449 |
# Generate any program assign to no task |
|
450 |
for instance in resource.getpouInstance(): |
|
451 |
resrce += [(" PROGRAM ", ()), |
|
1767
c74815729afd
clean-up: fix PEP8 E127 continuation line over-indented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1766
diff
changeset
|
452 |
(instance.getname(), (tagname, "instance", instance_number, "name")), |
c74815729afd
clean-up: fix PEP8 E127 continuation line over-indented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1766
diff
changeset
|
453 |
(" : ", ()), |
c74815729afd
clean-up: fix PEP8 E127 continuation line over-indented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1766
diff
changeset
|
454 |
(instance.gettypeName(), (tagname, "instance", instance_number, "type")), |
c74815729afd
clean-up: fix PEP8 E127 continuation line over-indented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1766
diff
changeset
|
455 |
(";\n", ())] |
814 | 456 |
instance_number += 1 |
457 |
resrce += [(" END_RESOURCE\n", ())] |
|
458 |
return resrce |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
459 |
|
814 | 460 |
# Generate the entire program for current project |
3704
c17fac18c663
ST code generator: when including PLCopen TC6 XML libraries (for example py_ext/pous.xml or NativeLib.xml), also includes libraries globals in result
Edouard Tisserant
parents:
2727
diff
changeset
|
461 |
def GenerateProgram(self, log, noconfig=False): |
2727
6330e6bb345d
IDE: Make ST code generation more verbose, since it can be really long in case of big programs, and it is better to let the user know build is still in progress.
Edouard Tisserant
parents:
2633
diff
changeset
|
462 |
log("Collecting data types") |
814 | 463 |
# Find all data types defined |
464 |
for datatype in self.Project.getdataTypes(): |
|
465 |
self.DatatypeComputed[datatype.getname()] = False |
|
2727
6330e6bb345d
IDE: Make ST code generation more verbose, since it can be really long in case of big programs, and it is better to let the user know build is still in progress.
Edouard Tisserant
parents:
2633
diff
changeset
|
466 |
log("Collecting POUs") |
814 | 467 |
# Find all data types defined |
468 |
for pou in self.Project.getpous(): |
|
469 |
self.PouComputed[pou.getname()] = False |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
470 |
# Generate data type declaration structure if there is at least one data |
814 | 471 |
# type defined |
472 |
if len(self.DatatypeComputed) > 0: |
|
473 |
self.Program += [("TYPE\n", ())] |
|
474 |
# Generate every data types defined |
|
475 |
for datatype_name in self.DatatypeComputed.keys(): |
|
2727
6330e6bb345d
IDE: Make ST code generation more verbose, since it can be really long in case of big programs, and it is better to let the user know build is still in progress.
Edouard Tisserant
parents:
2633
diff
changeset
|
476 |
log("Generate Data Type %s"%datatype_name) |
814 | 477 |
self.GenerateDataType(datatype_name) |
478 |
self.Program += [("END_TYPE\n\n", ())] |
|
479 |
# Generate every POUs defined |
|
480 |
for pou_name in self.PouComputed.keys(): |
|
2727
6330e6bb345d
IDE: Make ST code generation more verbose, since it can be really long in case of big programs, and it is better to let the user know build is still in progress.
Edouard Tisserant
parents:
2633
diff
changeset
|
481 |
log("Generate POU %s"%pou_name) |
814 | 482 |
self.GeneratePouProgram(pou_name) |
3704
c17fac18c663
ST code generator: when including PLCopen TC6 XML libraries (for example py_ext/pous.xml or NativeLib.xml), also includes libraries globals in result
Edouard Tisserant
parents:
2727
diff
changeset
|
483 |
if noconfig: |
c17fac18c663
ST code generator: when including PLCopen TC6 XML libraries (for example py_ext/pous.xml or NativeLib.xml), also includes libraries globals in result
Edouard Tisserant
parents:
2727
diff
changeset
|
484 |
return |
814 | 485 |
# Generate every configurations defined |
2727
6330e6bb345d
IDE: Make ST code generation more verbose, since it can be really long in case of big programs, and it is better to let the user know build is still in progress.
Edouard Tisserant
parents:
2633
diff
changeset
|
486 |
log("Generate Config(s)") |
814 | 487 |
for config in self.Project.getconfigurations(): |
488 |
self.Program += self.GenerateConfiguration(config) |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
489 |
|
814 | 490 |
# Return generated program |
491 |
def GetGeneratedProgram(self): |
|
492 |
return self.Program |
|
493 |
||
494 |
||
1782
5b6ad7a7fd9d
clean-up: fix PEP8 E265 block comment should start with '# '
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1775
diff
changeset
|
495 |
# ------------------------------------------------------------------------------- |
814 | 496 |
# Generator of POU programs |
1782
5b6ad7a7fd9d
clean-up: fix PEP8 E265 block comment should start with '# '
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1775
diff
changeset
|
497 |
# ------------------------------------------------------------------------------- |
814 | 498 |
|
1297 | 499 |
[ConnectorClass, ContinuationClass, ActionBlockClass] = [ |
500 |
PLCOpenParser.GetElementClass(instance_name, "commonObjects") |
|
501 |
for instance_name in ["connector", "continuation", "actionBlock"]] |
|
502 |
[InVariableClass, InOutVariableClass, OutVariableClass, BlockClass] = [ |
|
503 |
PLCOpenParser.GetElementClass(instance_name, "fbdObjects") |
|
504 |
for instance_name in ["inVariable", "inOutVariable", "outVariable", "block"]] |
|
505 |
[ContactClass, CoilClass, LeftPowerRailClass, RightPowerRailClass] = [ |
|
506 |
PLCOpenParser.GetElementClass(instance_name, "ldObjects") |
|
507 |
for instance_name in ["contact", "coil", "leftPowerRail", "rightPowerRail"]] |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
508 |
[StepClass, TransitionClass, JumpStepClass, |
1297 | 509 |
SelectionConvergenceClass, SelectionDivergenceClass, |
510 |
SimultaneousConvergenceClass, SimultaneousDivergenceClass] = [ |
|
1878
fb73a6b6622d
fix pylint warning '(bad-continuation) Wrong hanging indentation before block'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1864
diff
changeset
|
511 |
PLCOpenParser.GetElementClass(instance_name, "sfcObjects") |
fb73a6b6622d
fix pylint warning '(bad-continuation) Wrong hanging indentation before block'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1864
diff
changeset
|
512 |
for instance_name in ["step", |
fb73a6b6622d
fix pylint warning '(bad-continuation) Wrong hanging indentation before block'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1864
diff
changeset
|
513 |
"transition", |
fb73a6b6622d
fix pylint warning '(bad-continuation) Wrong hanging indentation before block'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1864
diff
changeset
|
514 |
"jumpStep", |
fb73a6b6622d
fix pylint warning '(bad-continuation) Wrong hanging indentation before block'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1864
diff
changeset
|
515 |
"selectionConvergence", |
fb73a6b6622d
fix pylint warning '(bad-continuation) Wrong hanging indentation before block'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1864
diff
changeset
|
516 |
"selectionDivergence", |
fb73a6b6622d
fix pylint warning '(bad-continuation) Wrong hanging indentation before block'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1864
diff
changeset
|
517 |
"simultaneousConvergence", |
fb73a6b6622d
fix pylint warning '(bad-continuation) Wrong hanging indentation before block'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1864
diff
changeset
|
518 |
"simultaneousDivergence"]] |
1297 | 519 |
TransitionObjClass = PLCOpenParser.GetElementClass("transition", "transitions") |
520 |
ActionObjClass = PLCOpenParser.GetElementClass("action", "actions") |
|
814 | 521 |
|
1736
7e61baa047f0
clean-up: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset
|
522 |
|
1831
56b48961cc68
fix (old-style-class) Old-style class defined error for most parts of
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1782
diff
changeset
|
523 |
class PouProgramGenerator(object): |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
524 |
|
814 | 525 |
# Create a new POU program generator |
526 |
def __init__(self, parent, name, type, errors, warnings): |
|
527 |
# Keep Reference to the parent generator |
|
528 |
self.ParentGenerator = parent |
|
529 |
self.Name = name |
|
530 |
self.Type = type |
|
1948
b9a3f771aaab
Moved some definitions away from controller class, and adaped references them through all code.
Edouard Tisserant
parents:
1881
diff
changeset
|
531 |
self.TagName = ComputePouName(name) |
814 | 532 |
self.CurrentIndent = " " |
533 |
self.ReturnType = None |
|
534 |
self.Interface = [] |
|
535 |
self.InitialSteps = [] |
|
536 |
self.ComputedBlocks = {} |
|
537 |
self.ComputedConnectors = {} |
|
538 |
self.ConnectionTypes = {} |
|
539 |
self.RelatedConnections = [] |
|
1740
b789b695b5c6
clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1739
diff
changeset
|
540 |
self.SFCNetworks = {"Steps": {}, "Transitions": {}, "Actions": {}} |
814 | 541 |
self.SFCComputedBlocks = [] |
542 |
self.ActionNumber = 0 |
|
543 |
self.Program = [] |
|
544 |
self.Errors = errors |
|
545 |
self.Warnings = warnings |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
546 |
|
814 | 547 |
def GetBlockType(self, type, inputs=None): |
548 |
return self.ParentGenerator.Controler.GetBlockType(type, inputs) |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
549 |
|
814 | 550 |
def IndentLeft(self): |
551 |
if len(self.CurrentIndent) >= 2: |
|
552 |
self.CurrentIndent = self.CurrentIndent[:-2] |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
553 |
|
814 | 554 |
def IndentRight(self): |
555 |
self.CurrentIndent += " " |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
556 |
|
814 | 557 |
# Generator of unique ID for inline actions |
558 |
def GetActionNumber(self): |
|
559 |
self.ActionNumber += 1 |
|
560 |
return self.ActionNumber |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
561 |
|
814 | 562 |
# Test if a variable has already been defined |
563 |
def IsAlreadyDefined(self, name): |
|
1847
6198190bc121
explicitly mark unused variables found by pylint with _ or dummy
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1846
diff
changeset
|
564 |
for _list_type, _option, _located, vars in self.Interface: |
6198190bc121
explicitly mark unused variables found by pylint with _ or dummy
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1846
diff
changeset
|
565 |
for _var_type, var_name, _var_address, _var_initial in vars: |
814 | 566 |
if name == var_name: |
567 |
return True |
|
568 |
return False |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
569 |
|
814 | 570 |
# Return the type of a variable defined in interface |
571 |
def GetVariableType(self, name): |
|
572 |
parts = name.split('.') |
|
573 |
current_type = None |
|
574 |
if len(parts) > 0: |
|
575 |
name = parts.pop(0) |
|
1847
6198190bc121
explicitly mark unused variables found by pylint with _ or dummy
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1846
diff
changeset
|
576 |
for _list_type, _option, _located, vars in self.Interface: |
6198190bc121
explicitly mark unused variables found by pylint with _ or dummy
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1846
diff
changeset
|
577 |
for var_type, var_name, _var_address, _var_initial in vars: |
814 | 578 |
if name == var_name: |
579 |
current_type = var_type |
|
580 |
break |
|
581 |
while current_type is not None and len(parts) > 0: |
|
883
235a9ec83b95
Adding support for defining specific global variables for ConfTreeNodes
Laurent Bessard
parents:
864
diff
changeset
|
582 |
blocktype = self.ParentGenerator.Controler.GetBlockType(current_type) |
235a9ec83b95
Adding support for defining specific global variables for ConfTreeNodes
Laurent Bessard
parents:
864
diff
changeset
|
583 |
if blocktype is not None: |
235a9ec83b95
Adding support for defining specific global variables for ConfTreeNodes
Laurent Bessard
parents:
864
diff
changeset
|
584 |
name = parts.pop(0) |
235a9ec83b95
Adding support for defining specific global variables for ConfTreeNodes
Laurent Bessard
parents:
864
diff
changeset
|
585 |
current_type = None |
1847
6198190bc121
explicitly mark unused variables found by pylint with _ or dummy
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1846
diff
changeset
|
586 |
for var_name, var_type, _var_modifier in blocktype["inputs"] + blocktype["outputs"]: |
883
235a9ec83b95
Adding support for defining specific global variables for ConfTreeNodes
Laurent Bessard
parents:
864
diff
changeset
|
587 |
if var_name == name: |
235a9ec83b95
Adding support for defining specific global variables for ConfTreeNodes
Laurent Bessard
parents:
864
diff
changeset
|
588 |
current_type = var_type |
814 | 589 |
break |
883
235a9ec83b95
Adding support for defining specific global variables for ConfTreeNodes
Laurent Bessard
parents:
864
diff
changeset
|
590 |
else: |
1948
b9a3f771aaab
Moved some definitions away from controller class, and adaped references them through all code.
Edouard Tisserant
parents:
1881
diff
changeset
|
591 |
tagname = ComputeDataTypeName(current_type) |
883
235a9ec83b95
Adding support for defining specific global variables for ConfTreeNodes
Laurent Bessard
parents:
864
diff
changeset
|
592 |
infos = self.ParentGenerator.Controler.GetDataTypeInfos(tagname) |
235a9ec83b95
Adding support for defining specific global variables for ConfTreeNodes
Laurent Bessard
parents:
864
diff
changeset
|
593 |
if infos is not None and infos["type"] == "Structure": |
235a9ec83b95
Adding support for defining specific global variables for ConfTreeNodes
Laurent Bessard
parents:
864
diff
changeset
|
594 |
name = parts.pop(0) |
235a9ec83b95
Adding support for defining specific global variables for ConfTreeNodes
Laurent Bessard
parents:
864
diff
changeset
|
595 |
current_type = None |
235a9ec83b95
Adding support for defining specific global variables for ConfTreeNodes
Laurent Bessard
parents:
864
diff
changeset
|
596 |
for element in infos["elements"]: |
235a9ec83b95
Adding support for defining specific global variables for ConfTreeNodes
Laurent Bessard
parents:
864
diff
changeset
|
597 |
if element["Name"] == name: |
235a9ec83b95
Adding support for defining specific global variables for ConfTreeNodes
Laurent Bessard
parents:
864
diff
changeset
|
598 |
current_type = element["Type"] |
235a9ec83b95
Adding support for defining specific global variables for ConfTreeNodes
Laurent Bessard
parents:
864
diff
changeset
|
599 |
break |
814 | 600 |
return current_type |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
601 |
|
814 | 602 |
# Return connectors linked by a connection to the given connector |
603 |
def GetConnectedConnector(self, connector, body): |
|
604 |
links = connector.getconnections() |
|
1298
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
605 |
if links is not None and len(links) == 1: |
814 | 606 |
return self.GetLinkedConnector(links[0], body) |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
607 |
return None |
814 | 608 |
|
609 |
def GetLinkedConnector(self, link, body): |
|
610 |
parameter = link.getformalParameter() |
|
611 |
instance = body.getcontentInstance(link.getrefLocalId()) |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
612 |
if isinstance(instance, (InVariableClass, InOutVariableClass, |
1768
691083b5682a
clean-up: fix PEP8 E128 continuation line under-indented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset
|
613 |
ContinuationClass, ContactClass, CoilClass)): |
814 | 614 |
return instance.connectionPointOut |
1297 | 615 |
elif isinstance(instance, BlockClass): |
814 | 616 |
outputvariables = instance.outputVariables.getvariable() |
617 |
if len(outputvariables) == 1: |
|
618 |
return outputvariables[0].connectionPointOut |
|
619 |
elif parameter: |
|
620 |
for variable in outputvariables: |
|
621 |
if variable.getformalParameter() == parameter: |
|
622 |
return variable.connectionPointOut |
|
623 |
else: |
|
624 |
point = link.getposition()[-1] |
|
625 |
for variable in outputvariables: |
|
626 |
relposition = variable.connectionPointOut.getrelPositionXY() |
|
627 |
blockposition = instance.getposition() |
|
628 |
if point.x == blockposition.x + relposition[0] and point.y == blockposition.y + relposition[1]: |
|
629 |
return variable.connectionPointOut |
|
1297 | 630 |
elif isinstance(instance, LeftPowerRailClass): |
814 | 631 |
outputconnections = instance.getconnectionPointOut() |
632 |
if len(outputconnections) == 1: |
|
633 |
return outputconnections[0] |
|
634 |
else: |
|
635 |
point = link.getposition()[-1] |
|
636 |
for outputconnection in outputconnections: |
|
637 |
relposition = outputconnection.getrelPositionXY() |
|
638 |
powerrailposition = instance.getposition() |
|
639 |
if point.x == powerrailposition.x + relposition[0] and point.y == powerrailposition.y + relposition[1]: |
|
640 |
return outputconnection |
|
641 |
return None |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
642 |
|
814 | 643 |
def ExtractRelatedConnections(self, connection): |
644 |
for i, related in enumerate(self.RelatedConnections): |
|
645 |
if connection in related: |
|
646 |
return self.RelatedConnections.pop(i) |
|
647 |
return [connection] |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
648 |
|
814 | 649 |
def ComputeInterface(self, pou): |
650 |
interface = pou.getinterface() |
|
651 |
if interface is not None: |
|
652 |
if self.Type == "FUNCTION": |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
653 |
returntype_content = interface.getreturnType()[0] |
1297 | 654 |
returntype_content_type = returntype_content.getLocalTag() |
655 |
if returntype_content_type == "derived": |
|
656 |
self.ReturnType = returntype_content.getname() |
|
657 |
else: |
|
658 |
self.ReturnType = returntype_content_type.upper() |
|
814 | 659 |
for varlist in interface.getcontent(): |
660 |
variables = [] |
|
661 |
located = [] |
|
1297 | 662 |
varlist_type = varlist.getLocalTag() |
663 |
for var in varlist.getvariable(): |
|
814 | 664 |
vartype_content = var.gettype().getcontent() |
1297 | 665 |
if vartype_content.getLocalTag() == "derived": |
666 |
var_type = vartype_content.getname() |
|
814 | 667 |
blocktype = self.GetBlockType(var_type) |
668 |
if blocktype is not None: |
|
669 |
self.ParentGenerator.GeneratePouProgram(var_type) |
|
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
670 |
variables.append((var_type, var.getname(), None, None)) |
814 | 671 |
else: |
672 |
self.ParentGenerator.GenerateDataType(var_type) |
|
673 |
initial = var.getinitialValue() |
|
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
674 |
if initial is not None: |
814 | 675 |
initial_value = initial.getvalue() |
676 |
else: |
|
677 |
initial_value = None |
|
678 |
address = var.getaddress() |
|
679 |
if address is not None: |
|
1297 | 680 |
located.append((vartype_content.getname(), var.getname(), address, initial_value)) |
814 | 681 |
else: |
1297 | 682 |
variables.append((vartype_content.getname(), var.getname(), None, initial_value)) |
814 | 683 |
else: |
684 |
var_type = var.gettypeAsText() |
|
685 |
initial = var.getinitialValue() |
|
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
686 |
if initial is not None: |
814 | 687 |
initial_value = initial.getvalue() |
688 |
else: |
|
689 |
initial_value = None |
|
690 |
address = var.getaddress() |
|
691 |
if address is not None: |
|
692 |
located.append((var_type, var.getname(), address, initial_value)) |
|
693 |
else: |
|
694 |
variables.append((var_type, var.getname(), None, initial_value)) |
|
1297 | 695 |
if varlist.getconstant(): |
814 | 696 |
option = "CONSTANT" |
1297 | 697 |
elif varlist.getretain(): |
814 | 698 |
option = "RETAIN" |
1297 | 699 |
elif varlist.getnonretain(): |
814 | 700 |
option = "NON_RETAIN" |
701 |
else: |
|
702 |
option = None |
|
703 |
if len(variables) > 0: |
|
1297 | 704 |
self.Interface.append((varTypeNames[varlist_type], option, False, variables)) |
814 | 705 |
if len(located) > 0: |
1297 | 706 |
self.Interface.append((varTypeNames[varlist_type], option, True, located)) |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
707 |
|
1181
21e6db77eb29
Fixed bug in PLC code generated with binary, octal and hexadecimal literals
Laurent Bessard
parents:
1134
diff
changeset
|
708 |
LITERAL_TYPES = { |
1751
c28db6f7616b
clean-up: fix PEP8 E301 expected 1 blank line, found 0
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1747
diff
changeset
|
709 |
"T": "TIME", |
c28db6f7616b
clean-up: fix PEP8 E301 expected 1 blank line, found 0
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1747
diff
changeset
|
710 |
"D": "DATE", |
1181
21e6db77eb29
Fixed bug in PLC code generated with binary, octal and hexadecimal literals
Laurent Bessard
parents:
1134
diff
changeset
|
711 |
"TOD": "TIME_OF_DAY", |
1751
c28db6f7616b
clean-up: fix PEP8 E301 expected 1 blank line, found 0
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1747
diff
changeset
|
712 |
"DT": "DATE_AND_TIME", |
c28db6f7616b
clean-up: fix PEP8 E301 expected 1 blank line, found 0
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1747
diff
changeset
|
713 |
"2": None, |
c28db6f7616b
clean-up: fix PEP8 E301 expected 1 blank line, found 0
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1747
diff
changeset
|
714 |
"8": None, |
c28db6f7616b
clean-up: fix PEP8 E301 expected 1 blank line, found 0
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1747
diff
changeset
|
715 |
"16": None, |
1181
21e6db77eb29
Fixed bug in PLC code generated with binary, octal and hexadecimal literals
Laurent Bessard
parents:
1134
diff
changeset
|
716 |
} |
1751
c28db6f7616b
clean-up: fix PEP8 E301 expected 1 blank line, found 0
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1747
diff
changeset
|
717 |
|
814 | 718 |
def ComputeConnectionTypes(self, pou): |
719 |
body = pou.getbody() |
|
2450
5024c19ca8f0
python3 support: pylint, W1652 # (deprecated-types-field) Accessing a deprecated fields on the types module
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2447
diff
changeset
|
720 |
if isinstance(body, list): |
814 | 721 |
body = body[0] |
722 |
body_content = body.getcontent() |
|
1297 | 723 |
body_type = body_content.getLocalTag() |
814 | 724 |
if body_type in ["FBD", "LD", "SFC"]: |
725 |
undefined_blocks = [] |
|
726 |
for instance in body.getcontentInstances(): |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
727 |
if isinstance(instance, (InVariableClass, OutVariableClass, |
1297 | 728 |
InOutVariableClass)): |
1322
0a9227f743b3
Fixed xmlclass for working with included files, adding support for SimpleType elements and solving ambiguity in extension class when different elements share the same name and parent name
Laurent Bessard
parents:
1315
diff
changeset
|
729 |
expression = instance.getexpression() |
814 | 730 |
var_type = self.GetVariableType(expression) |
1766
c1e5b9f19483
clean-up: fix PEP8 E129 visually indented line with same indent as next logical line
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1765
diff
changeset
|
731 |
if isinstance(pou, TransitionObjClass) and expression == pou.getname(): |
822
050045c32d98
Fix bug in PLCGenerator connection types not computed for SFC actions and transitions body
laurent
parents:
814
diff
changeset
|
732 |
var_type = "BOOL" |
1297 | 733 |
elif (not isinstance(pou, (TransitionObjClass, ActionObjClass)) and |
822
050045c32d98
Fix bug in PLCGenerator connection types not computed for SFC actions and transitions body
laurent
parents:
814
diff
changeset
|
734 |
pou.getpouType() == "function" and expression == pou.getname()): |
814 | 735 |
returntype_content = pou.interface.getreturnType().getcontent() |
1297 | 736 |
returntype_content_type = returntype_content.getLocalTag() |
737 |
if returntype_content_type == "derived": |
|
738 |
var_type = returntype_content.getname() |
|
814 | 739 |
else: |
1297 | 740 |
var_type = returntype_content_type.upper() |
814 | 741 |
elif var_type is None: |
742 |
parts = expression.split("#") |
|
743 |
if len(parts) > 1: |
|
1181
21e6db77eb29
Fixed bug in PLC code generated with binary, octal and hexadecimal literals
Laurent Bessard
parents:
1134
diff
changeset
|
744 |
literal_prefix = parts[0].upper() |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
745 |
var_type = self.LITERAL_TYPES.get(literal_prefix, |
1181
21e6db77eb29
Fixed bug in PLC code generated with binary, octal and hexadecimal literals
Laurent Bessard
parents:
1134
diff
changeset
|
746 |
literal_prefix) |
814 | 747 |
elif expression.startswith("'"): |
748 |
var_type = "STRING" |
|
749 |
elif expression.startswith('"'): |
|
750 |
var_type = "WSTRING" |
|
751 |
if var_type is not None: |
|
1297 | 752 |
if isinstance(instance, (InVariableClass, InOutVariableClass)): |
814 | 753 |
for connection in self.ExtractRelatedConnections(instance.connectionPointOut): |
754 |
self.ConnectionTypes[connection] = var_type |
|
1297 | 755 |
if isinstance(instance, (OutVariableClass, InOutVariableClass)): |
814 | 756 |
self.ConnectionTypes[instance.connectionPointIn] = var_type |
757 |
connected = self.GetConnectedConnector(instance.connectionPointIn, body) |
|
1775
b45f2768fab1
clean-up: fix PEP8 E713 test for membership should be 'not in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1769
diff
changeset
|
758 |
if connected is not None and connected not in self.ConnectionTypes: |
1298
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
759 |
for related in self.ExtractRelatedConnections(connected): |
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
760 |
self.ConnectionTypes[related] = var_type |
1297 | 761 |
elif isinstance(instance, (ContactClass, CoilClass)): |
814 | 762 |
for connection in self.ExtractRelatedConnections(instance.connectionPointOut): |
763 |
self.ConnectionTypes[connection] = "BOOL" |
|
764 |
self.ConnectionTypes[instance.connectionPointIn] = "BOOL" |
|
1298
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
765 |
for link in instance.connectionPointIn.getconnections(): |
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
766 |
connected = self.GetLinkedConnector(link, body) |
1775
b45f2768fab1
clean-up: fix PEP8 E713 test for membership should be 'not in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1769
diff
changeset
|
767 |
if connected is not None and connected not in self.ConnectionTypes: |
1298
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
768 |
for related in self.ExtractRelatedConnections(connected): |
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
769 |
self.ConnectionTypes[related] = "BOOL" |
1297 | 770 |
elif isinstance(instance, LeftPowerRailClass): |
814 | 771 |
for connection in instance.getconnectionPointOut(): |
772 |
for related in self.ExtractRelatedConnections(connection): |
|
773 |
self.ConnectionTypes[related] = "BOOL" |
|
1297 | 774 |
elif isinstance(instance, RightPowerRailClass): |
814 | 775 |
for connection in instance.getconnectionPointIn(): |
776 |
self.ConnectionTypes[connection] = "BOOL" |
|
1298
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
777 |
for link in connection.getconnections(): |
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
778 |
connected = self.GetLinkedConnector(link, body) |
1775
b45f2768fab1
clean-up: fix PEP8 E713 test for membership should be 'not in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1769
diff
changeset
|
779 |
if connected is not None and connected not in self.ConnectionTypes: |
1298
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
780 |
for related in self.ExtractRelatedConnections(connected): |
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
781 |
self.ConnectionTypes[related] = "BOOL" |
1297 | 782 |
elif isinstance(instance, TransitionClass): |
783 |
content = instance.getconditionContent() |
|
784 |
if content["type"] == "connection": |
|
1298
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
785 |
self.ConnectionTypes[content["value"]] = "BOOL" |
1603
18279f12a6be
fix issue with compiling SFC POU with non-connected transition (type "connection")
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1581
diff
changeset
|
786 |
connections = content["value"].getconnections() |
18279f12a6be
fix issue with compiling SFC POU with non-connected transition (type "connection")
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1581
diff
changeset
|
787 |
if not connections: |
1765
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
788 |
raise PLCGenException( |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
789 |
_("SFC transition in POU \"%s\" must be connected.") % self.Name) |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
790 |
|
1730
64d8f52bc8c8
clean-up for PEP8: fix W291 trailing whitespace
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1626
diff
changeset
|
791 |
for link in connections: |
1298
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
792 |
connected = self.GetLinkedConnector(link, body) |
1775
b45f2768fab1
clean-up: fix PEP8 E713 test for membership should be 'not in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1769
diff
changeset
|
793 |
if connected is not None and connected not in self.ConnectionTypes: |
1298
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
794 |
for related in self.ExtractRelatedConnections(connected): |
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
795 |
self.ConnectionTypes[related] = "BOOL" |
1297 | 796 |
elif isinstance(instance, ContinuationClass): |
814 | 797 |
name = instance.getname() |
798 |
connector = None |
|
799 |
var_type = "ANY" |
|
800 |
for element in body.getcontentInstances(): |
|
1297 | 801 |
if isinstance(element, ConnectorClass) and element.getname() == name: |
814 | 802 |
if connector is not None: |
1765
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
803 |
raise PLCGenException( |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
804 |
_("More than one connector found corresponding to \"{a1}\" continuation in \"{a2}\" POU"). |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
805 |
format(a1=name, a2=self.Name)) |
814 | 806 |
connector = element |
807 |
if connector is not None: |
|
808 |
undefined = [instance.connectionPointOut, connector.connectionPointIn] |
|
809 |
connected = self.GetConnectedConnector(connector.connectionPointIn, body) |
|
1298
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
810 |
if connected is not None: |
814 | 811 |
undefined.append(connected) |
812 |
related = [] |
|
813 |
for connection in undefined: |
|
1763
bcc07ff2362c
clean-up: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1753
diff
changeset
|
814 |
if connection in self.ConnectionTypes: |
814 | 815 |
var_type = self.ConnectionTypes[connection] |
816 |
else: |
|
817 |
related.extend(self.ExtractRelatedConnections(connection)) |
|
818 |
if var_type.startswith("ANY") and len(related) > 0: |
|
819 |
self.RelatedConnections.append(related) |
|
820 |
else: |
|
821 |
for connection in related: |
|
822 |
self.ConnectionTypes[connection] = var_type |
|
823 |
else: |
|
1765
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
824 |
raise PLCGenException( |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
825 |
_("No connector found corresponding to \"{a1}\" continuation in \"{a2}\" POU"). |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
826 |
format(a1=name, a2=self.Name)) |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
827 |
|
1297 | 828 |
elif isinstance(instance, BlockClass): |
814 | 829 |
block_infos = self.GetBlockType(instance.gettypeName(), "undefined") |
830 |
if block_infos is not None: |
|
831 |
self.ComputeBlockInputTypes(instance, block_infos, body) |
|
832 |
else: |
|
833 |
for variable in instance.inputVariables.getvariable(): |
|
834 |
connected = self.GetConnectedConnector(variable.connectionPointIn, body) |
|
835 |
if connected is not None: |
|
836 |
var_type = self.ConnectionTypes.get(connected, None) |
|
837 |
if var_type is not None: |
|
838 |
self.ConnectionTypes[variable.connectionPointIn] = var_type |
|
839 |
else: |
|
840 |
related = self.ExtractRelatedConnections(connected) |
|
841 |
related.append(variable.connectionPointIn) |
|
842 |
self.RelatedConnections.append(related) |
|
843 |
undefined_blocks.append(instance) |
|
844 |
for instance in undefined_blocks: |
|
845 |
block_infos = self.GetBlockType(instance.gettypeName(), tuple([self.ConnectionTypes.get(variable.connectionPointIn, "ANY") for variable in instance.inputVariables.getvariable() if variable.getformalParameter() != "EN"])) |
|
846 |
if block_infos is not None: |
|
847 |
self.ComputeBlockInputTypes(instance, block_infos, body) |
|
848 |
else: |
|
1765
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
849 |
raise PLCGenException( |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
850 |
_("No informations found for \"%s\" block") % (instance.gettypeName())) |
822
050045c32d98
Fix bug in PLCGenerator connection types not computed for SFC actions and transitions body
laurent
parents:
814
diff
changeset
|
851 |
if body_type == "SFC": |
050045c32d98
Fix bug in PLCGenerator connection types not computed for SFC actions and transitions body
laurent
parents:
814
diff
changeset
|
852 |
previous_tagname = self.TagName |
050045c32d98
Fix bug in PLCGenerator connection types not computed for SFC actions and transitions body
laurent
parents:
814
diff
changeset
|
853 |
for action in pou.getactionList(): |
1948
b9a3f771aaab
Moved some definitions away from controller class, and adaped references them through all code.
Edouard Tisserant
parents:
1881
diff
changeset
|
854 |
self.TagName = ComputePouActionName(self.Name, action.getname()) |
822
050045c32d98
Fix bug in PLCGenerator connection types not computed for SFC actions and transitions body
laurent
parents:
814
diff
changeset
|
855 |
self.ComputeConnectionTypes(action) |
050045c32d98
Fix bug in PLCGenerator connection types not computed for SFC actions and transitions body
laurent
parents:
814
diff
changeset
|
856 |
for transition in pou.gettransitionList(): |
1948
b9a3f771aaab
Moved some definitions away from controller class, and adaped references them through all code.
Edouard Tisserant
parents:
1881
diff
changeset
|
857 |
self.TagName = ComputePouTransitionName(self.Name, transition.getname()) |
822
050045c32d98
Fix bug in PLCGenerator connection types not computed for SFC actions and transitions body
laurent
parents:
814
diff
changeset
|
858 |
self.ComputeConnectionTypes(transition) |
050045c32d98
Fix bug in PLCGenerator connection types not computed for SFC actions and transitions body
laurent
parents:
814
diff
changeset
|
859 |
self.TagName = previous_tagname |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
860 |
|
814 | 861 |
def ComputeBlockInputTypes(self, instance, block_infos, body): |
862 |
undefined = {} |
|
863 |
for variable in instance.outputVariables.getvariable(): |
|
864 |
output_name = variable.getformalParameter() |
|
865 |
if output_name == "ENO": |
|
866 |
for connection in self.ExtractRelatedConnections(variable.connectionPointOut): |
|
867 |
self.ConnectionTypes[connection] = "BOOL" |
|
868 |
else: |
|
1847
6198190bc121
explicitly mark unused variables found by pylint with _ or dummy
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1846
diff
changeset
|
869 |
for oname, otype, _oqualifier in block_infos["outputs"]: |
814 | 870 |
if output_name == oname: |
871 |
if otype.startswith("ANY"): |
|
1775
b45f2768fab1
clean-up: fix PEP8 E713 test for membership should be 'not in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1769
diff
changeset
|
872 |
if otype not in undefined: |
814 | 873 |
undefined[otype] = [] |
874 |
undefined[otype].append(variable.connectionPointOut) |
|
1775
b45f2768fab1
clean-up: fix PEP8 E713 test for membership should be 'not in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1769
diff
changeset
|
875 |
elif variable.connectionPointOut not in self.ConnectionTypes: |
814 | 876 |
for connection in self.ExtractRelatedConnections(variable.connectionPointOut): |
877 |
self.ConnectionTypes[connection] = otype |
|
878 |
for variable in instance.inputVariables.getvariable(): |
|
879 |
input_name = variable.getformalParameter() |
|
880 |
if input_name == "EN": |
|
881 |
for connection in self.ExtractRelatedConnections(variable.connectionPointIn): |
|
882 |
self.ConnectionTypes[connection] = "BOOL" |
|
883 |
else: |
|
1847
6198190bc121
explicitly mark unused variables found by pylint with _ or dummy
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1846
diff
changeset
|
884 |
for iname, itype, _iqualifier in block_infos["inputs"]: |
814 | 885 |
if input_name == iname: |
886 |
connected = self.GetConnectedConnector(variable.connectionPointIn, body) |
|
887 |
if itype.startswith("ANY"): |
|
1775
b45f2768fab1
clean-up: fix PEP8 E713 test for membership should be 'not in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1769
diff
changeset
|
888 |
if itype not in undefined: |
814 | 889 |
undefined[itype] = [] |
890 |
undefined[itype].append(variable.connectionPointIn) |
|
1298
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
891 |
if connected is not None: |
814 | 892 |
undefined[itype].append(connected) |
893 |
else: |
|
894 |
self.ConnectionTypes[variable.connectionPointIn] = itype |
|
1775
b45f2768fab1
clean-up: fix PEP8 E713 test for membership should be 'not in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1769
diff
changeset
|
895 |
if connected is not None and connected not in self.ConnectionTypes: |
814 | 896 |
for connection in self.ExtractRelatedConnections(connected): |
897 |
self.ConnectionTypes[connection] = itype |
|
898 |
for var_type, connections in undefined.items(): |
|
899 |
related = [] |
|
900 |
for connection in connections: |
|
854
c10f2092c43a
Fixing bug in PLCGenerator with user defined functions and standard overloaded function
Laurent Bessard
parents:
822
diff
changeset
|
901 |
connection_type = self.ConnectionTypes.get(connection) |
c10f2092c43a
Fixing bug in PLCGenerator with user defined functions and standard overloaded function
Laurent Bessard
parents:
822
diff
changeset
|
902 |
if connection_type and not connection_type.startswith("ANY"): |
c10f2092c43a
Fixing bug in PLCGenerator with user defined functions and standard overloaded function
Laurent Bessard
parents:
822
diff
changeset
|
903 |
var_type = connection_type |
814 | 904 |
else: |
905 |
related.extend(self.ExtractRelatedConnections(connection)) |
|
906 |
if var_type.startswith("ANY") and len(related) > 0: |
|
907 |
self.RelatedConnections.append(related) |
|
908 |
else: |
|
909 |
for connection in related: |
|
910 |
self.ConnectionTypes[connection] = var_type |
|
911 |
||
2258
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
912 |
def GetUsedEno(self, body, connections): |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
913 |
""" |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
914 |
Function checks whether value on given connection |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
915 |
comes from block, that has used EN input and |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
916 |
returns variable name for ENO output. |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
917 |
|
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
918 |
This is needed to avoid value propagation from blocks |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
919 |
with false signal on EN input. |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
920 |
|
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
921 |
:param body: |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
922 |
body of the block for that program is currently generated |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
923 |
:param connections: |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
924 |
connection, that's source is checked for EN/ENO usage |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
925 |
:return: |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
926 |
if EN/ENO are not used, then None is returned |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
927 |
Otherwise BOOL variable corresponding to ENO |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
928 |
output is returned. |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
929 |
""" |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
930 |
|
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
931 |
if len(connections) != 1: |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
932 |
return None |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
933 |
ref_local_id = connections[0].getrefLocalId() |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
934 |
blk = body.getcontentInstance(ref_local_id) |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
935 |
if blk is None: |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
936 |
return None |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
937 |
|
2275
1bb8afa02409
Improve fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2258
diff
changeset
|
938 |
if not hasattr(blk, "inputVariables"): |
1bb8afa02409
Improve fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2258
diff
changeset
|
939 |
return None |
1bb8afa02409
Improve fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2258
diff
changeset
|
940 |
|
2258
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
941 |
for invar in blk.inputVariables.getvariable(): |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
942 |
if invar.getformalParameter() == "EN": |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
943 |
if len(invar.getconnectionPointIn().getconnections()) > 0: |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
944 |
if blk.getinstanceName() is None: |
2633
fecdb71e7514
Fixed sequel of earlier commit in PLCGenerator.py. Some ref to temporary variables are still not using the _TMP_ prefix. They are quite hard to find, so to be continued...
Edouard Tisserant
parents:
2629
diff
changeset
|
945 |
var_name = "_TMP_%s%d_ENO" % (blk.gettypeName(), blk.getlocalId()) |
2258
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
946 |
else: |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
947 |
var_name = "%s.ENO" % blk.getinstanceName() |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
948 |
return var_name |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
949 |
return None |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
950 |
|
814 | 951 |
def ComputeProgram(self, pou): |
952 |
body = pou.getbody() |
|
2450
5024c19ca8f0
python3 support: pylint, W1652 # (deprecated-types-field) Accessing a deprecated fields on the types module
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2447
diff
changeset
|
953 |
if isinstance(body, list): |
814 | 954 |
body = body[0] |
955 |
body_content = body.getcontent() |
|
1297 | 956 |
body_type = body_content.getLocalTag() |
1740
b789b695b5c6
clean-up: fix PEP8 E231 missing whitespace after ':' or ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1739
diff
changeset
|
957 |
if body_type in ["IL", "ST"]: |
1297 | 958 |
text = body_content.getanyText() |
814 | 959 |
self.ParentGenerator.GeneratePouProgramInText(text.upper()) |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
960 |
self.Program = [(ReIndentText(text, len(self.CurrentIndent)), |
1878
fb73a6b6622d
fix pylint warning '(bad-continuation) Wrong hanging indentation before block'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1864
diff
changeset
|
961 |
(self.TagName, "body", len(self.CurrentIndent)))] |
814 | 962 |
elif body_type == "SFC": |
963 |
self.IndentRight() |
|
964 |
for instance in body.getcontentInstances(): |
|
1297 | 965 |
if isinstance(instance, StepClass): |
814 | 966 |
self.GenerateSFCStep(instance, pou) |
1297 | 967 |
elif isinstance(instance, ActionBlockClass): |
814 | 968 |
self.GenerateSFCStepActions(instance, pou) |
1297 | 969 |
elif isinstance(instance, TransitionClass): |
814 | 970 |
self.GenerateSFCTransition(instance, pou) |
1298
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
971 |
elif isinstance(instance, JumpStepClass): |
814 | 972 |
self.GenerateSFCJump(instance, pou) |
973 |
if len(self.InitialSteps) > 0 and len(self.SFCComputedBlocks) > 0: |
|
974 |
action_name = "COMPUTE_FUNCTION_BLOCKS" |
|
1739
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1736
diff
changeset
|
975 |
action_infos = {"qualifier": "S", "content": action_name} |
814 | 976 |
self.SFCNetworks["Steps"][self.InitialSteps[0]]["actions"].append(action_infos) |
977 |
self.SFCNetworks["Actions"][action_name] = (self.SFCComputedBlocks, ()) |
|
978 |
self.Program = [] |
|
979 |
self.IndentLeft() |
|
980 |
for initialstep in self.InitialSteps: |
|
981 |
self.ComputeSFCStep(initialstep) |
|
982 |
else: |
|
1739
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1736
diff
changeset
|
983 |
otherInstances = {"outVariables&coils": [], "blocks": [], "connectors": []} |
814 | 984 |
orderedInstances = [] |
985 |
for instance in body.getcontentInstances(): |
|
1297 | 986 |
if isinstance(instance, (OutVariableClass, InOutVariableClass, BlockClass)): |
814 | 987 |
executionOrderId = instance.getexecutionOrderId() |
988 |
if executionOrderId > 0: |
|
989 |
orderedInstances.append((executionOrderId, instance)) |
|
1297 | 990 |
elif isinstance(instance, (OutVariableClass, InOutVariableClass)): |
814 | 991 |
otherInstances["outVariables&coils"].append(instance) |
1297 | 992 |
elif isinstance(instance, BlockClass): |
814 | 993 |
otherInstances["blocks"].append(instance) |
1297 | 994 |
elif isinstance(instance, ConnectorClass): |
814 | 995 |
otherInstances["connectors"].append(instance) |
1297 | 996 |
elif isinstance(instance, CoilClass): |
814 | 997 |
otherInstances["outVariables&coils"].append(instance) |
998 |
orderedInstances.sort() |
|
999 |
otherInstances["outVariables&coils"].sort(SortInstances) |
|
1000 |
otherInstances["blocks"].sort(SortInstances) |
|
1001 |
instances = [instance for (executionOrderId, instance) in orderedInstances] |
|
1048
b450202605ab
Fixed bug in program elements computation order in PLCGenerator
Laurent Bessard
parents:
1032
diff
changeset
|
1002 |
instances.extend(otherInstances["outVariables&coils"] + otherInstances["blocks"] + otherInstances["connectors"]) |
814 | 1003 |
for instance in instances: |
1297 | 1004 |
if isinstance(instance, (OutVariableClass, InOutVariableClass)): |
814 | 1005 |
connections = instance.connectionPointIn.getconnections() |
1006 |
if connections is not None: |
|
1007 |
expression = self.ComputeExpression(body, connections) |
|
1239
d1f6ea56555d
Fixed bug when generating ST code and connection is broken in POU using graphical language
Laurent Bessard
parents:
1183
diff
changeset
|
1008 |
if expression is not None: |
2258
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
1009 |
eno_var = self.GetUsedEno(body, connections) |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
1010 |
if eno_var is not None: |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
1011 |
self.Program += [(self.CurrentIndent + "IF %s" % eno_var, ())] |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
1012 |
self.Program += [(" THEN\n ", ())] |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
1013 |
self.IndentRight() |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
1014 |
|
1239
d1f6ea56555d
Fixed bug when generating ST code and connection is broken in POU using graphical language
Laurent Bessard
parents:
1183
diff
changeset
|
1015 |
self.Program += [(self.CurrentIndent, ()), |
1322
0a9227f743b3
Fixed xmlclass for working with included files, adding support for SimpleType elements and solving ambiguity in extension class when different elements share the same name and parent name
Laurent Bessard
parents:
1315
diff
changeset
|
1016 |
(instance.getexpression(), (self.TagName, "io_variable", instance.getlocalId(), "expression")), |
1239
d1f6ea56555d
Fixed bug when generating ST code and connection is broken in POU using graphical language
Laurent Bessard
parents:
1183
diff
changeset
|
1017 |
(" := ", ())] |
d1f6ea56555d
Fixed bug when generating ST code and connection is broken in POU using graphical language
Laurent Bessard
parents:
1183
diff
changeset
|
1018 |
self.Program += expression |
d1f6ea56555d
Fixed bug when generating ST code and connection is broken in POU using graphical language
Laurent Bessard
parents:
1183
diff
changeset
|
1019 |
self.Program += [(";\n", ())] |
2258
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
1020 |
|
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
1021 |
if eno_var is not None: |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
1022 |
self.IndentLeft() |
c9915bc620cd
Fix wrong code generation if EN/ENO are used in FBD/LD/SFC
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1948
diff
changeset
|
1023 |
self.Program += [(self.CurrentIndent + "END_IF;\n", ())] |
1297 | 1024 |
elif isinstance(instance, BlockClass): |
814 | 1025 |
block_type = instance.gettypeName() |
1026 |
self.ParentGenerator.GeneratePouProgram(block_type) |
|
1027 |
block_infos = self.GetBlockType(block_type, tuple([self.ConnectionTypes.get(variable.connectionPointIn, "ANY") for variable in instance.inputVariables.getvariable() if variable.getformalParameter() != "EN"])) |
|
1028 |
if block_infos is None: |
|
1029 |
block_infos = self.GetBlockType(block_type) |
|
1030 |
if block_infos is None: |
|
1765
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1031 |
raise PLCGenException( |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1032 |
_("Undefined block type \"{a1}\" in \"{a2}\" POU"). |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1033 |
format(a1=block_type, a2=self.Name)) |
1134
1c7a4ad86aa1
Fixed PLC code generator when interface of an already used POU has changed
Laurent Bessard
parents:
1048
diff
changeset
|
1034 |
try: |
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1035 |
self.GenerateBlock(instance, block_infos, body, None) |
2418
5587c490a070
Use python 3 compatible exception syntax everywhere
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2277
diff
changeset
|
1036 |
except ValueError as e: |
2447
1c04a50dc7ff
python3 support: pylint, W1645 # (exception-message-attribute) Exception.message removed in Python 3
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2432
diff
changeset
|
1037 |
raise PLCGenException(str(e)) |
1297 | 1038 |
elif isinstance(instance, ConnectorClass): |
814 | 1039 |
connector = instance.getname() |
1040 |
if self.ComputedConnectors.get(connector, None): |
|
1239
d1f6ea56555d
Fixed bug when generating ST code and connection is broken in POU using graphical language
Laurent Bessard
parents:
1183
diff
changeset
|
1041 |
continue |
d1f6ea56555d
Fixed bug when generating ST code and connection is broken in POU using graphical language
Laurent Bessard
parents:
1183
diff
changeset
|
1042 |
expression = self.ComputeExpression(body, instance.connectionPointIn.getconnections()) |
d1f6ea56555d
Fixed bug when generating ST code and connection is broken in POU using graphical language
Laurent Bessard
parents:
1183
diff
changeset
|
1043 |
if expression is not None: |
d1f6ea56555d
Fixed bug when generating ST code and connection is broken in POU using graphical language
Laurent Bessard
parents:
1183
diff
changeset
|
1044 |
self.ComputedConnectors[connector] = expression |
1297 | 1045 |
elif isinstance(instance, CoilClass): |
814 | 1046 |
connections = instance.connectionPointIn.getconnections() |
1047 |
if connections is not None: |
|
1048 |
coil_info = (self.TagName, "coil", instance.getlocalId()) |
|
1239
d1f6ea56555d
Fixed bug when generating ST code and connection is broken in POU using graphical language
Laurent Bessard
parents:
1183
diff
changeset
|
1049 |
expression = self.ComputeExpression(body, connections) |
d1f6ea56555d
Fixed bug when generating ST code and connection is broken in POU using graphical language
Laurent Bessard
parents:
1183
diff
changeset
|
1050 |
if expression is not None: |
d1f6ea56555d
Fixed bug when generating ST code and connection is broken in POU using graphical language
Laurent Bessard
parents:
1183
diff
changeset
|
1051 |
expression = self.ExtractModifier(instance, expression, coil_info) |
d1f6ea56555d
Fixed bug when generating ST code and connection is broken in POU using graphical language
Laurent Bessard
parents:
1183
diff
changeset
|
1052 |
self.Program += [(self.CurrentIndent, ())] |
1322
0a9227f743b3
Fixed xmlclass for working with included files, adding support for SimpleType elements and solving ambiguity in extension class when different elements share the same name and parent name
Laurent Bessard
parents:
1315
diff
changeset
|
1053 |
self.Program += [(instance.getvariable(), coil_info + ("reference",))] |
1239
d1f6ea56555d
Fixed bug when generating ST code and connection is broken in POU using graphical language
Laurent Bessard
parents:
1183
diff
changeset
|
1054 |
self.Program += [(" := ", ())] + expression + [(";\n", ())] |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
1055 |
|
814 | 1056 |
def FactorizePaths(self, paths): |
1057 |
same_paths = {} |
|
1058 |
uncomputed_index = range(len(paths)) |
|
1059 |
factorized_paths = [] |
|
1060 |
for num, path in enumerate(paths): |
|
2450
5024c19ca8f0
python3 support: pylint, W1652 # (deprecated-types-field) Accessing a deprecated fields on the types module
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2447
diff
changeset
|
1061 |
if isinstance(path, list): |
814 | 1062 |
if len(path) > 1: |
1063 |
str_path = str(path[-1:]) |
|
1064 |
same_paths.setdefault(str_path, []) |
|
1065 |
same_paths[str_path].append((path[:-1], num)) |
|
1066 |
else: |
|
1067 |
factorized_paths.append(path) |
|
1068 |
uncomputed_index.remove(num) |
|
1069 |
for same_path, elements in same_paths.items(): |
|
1070 |
if len(elements) > 1: |
|
1071 |
elements_paths = self.FactorizePaths([path for path, num in elements]) |
|
1072 |
if len(elements_paths) > 1: |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
1073 |
factorized_paths.append([tuple(elements_paths)] + eval(same_path)) |
814 | 1074 |
else: |
1075 |
factorized_paths.append(elements_paths + eval(same_path)) |
|
1076 |
for path, num in elements: |
|
1077 |
uncomputed_index.remove(num) |
|
1078 |
for num in uncomputed_index: |
|
1079 |
factorized_paths.append(paths[num]) |
|
1080 |
factorized_paths.sort() |
|
1081 |
return factorized_paths |
|
1082 |
||
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1083 |
def GenerateBlock(self, block, block_infos, body, link, order=False, to_inout=False): |
1864
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1084 |
|
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1085 |
def _GetBlockName(name, type): |
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1086 |
"""function returns name of function or function block instance""" |
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1087 |
if name: |
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1088 |
# function blocks |
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1089 |
blockname = "{a1}({a2})".format(a1=name, a2=type) |
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1090 |
else: |
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1091 |
# functions |
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1092 |
blockname = type |
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1093 |
return blockname |
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1094 |
|
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1095 |
def _RaiseUnconnectedInOutError(name, type, parameter, place): |
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1096 |
blockname = _GetBlockName(name, type) |
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1097 |
raise ValueError( |
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1098 |
_("InOut variable {a1} in block {a2} in POU {a3} must be connected."). |
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1099 |
format(a1=parameter, a2=blockname, a3=place)) |
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1100 |
|
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1101 |
name = block.getinstanceName() |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1102 |
type = block.gettypeName() |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1103 |
executionOrderId = block.getexecutionOrderId() |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1104 |
input_variables = block.inputVariables.getvariable() |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1105 |
output_variables = block.outputVariables.getvariable() |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1106 |
inout_variables = {} |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1107 |
for input_variable in input_variables: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1108 |
for output_variable in output_variables: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1109 |
if input_variable.getformalParameter() == output_variable.getformalParameter(): |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1110 |
inout_variables[input_variable.getformalParameter()] = "" |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1111 |
input_names = [input[0] for input in block_infos["inputs"]] |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1112 |
output_names = [output[0] for output in block_infos["outputs"]] |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1113 |
if block_infos["type"] == "function": |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1114 |
if not self.ComputedBlocks.get(block, False) and not order: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1115 |
self.ComputedBlocks[block] = True |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1116 |
connected_vars = [] |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1117 |
if not block_infos["extensible"]: |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
1118 |
input_connected = dict([("EN", None)] + |
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1119 |
[(input_name, None) for input_name in input_names]) |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1120 |
for variable in input_variables: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1121 |
parameter = variable.getformalParameter() |
1763
bcc07ff2362c
clean-up: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1753
diff
changeset
|
1122 |
if parameter in input_connected: |
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1123 |
input_connected[parameter] = variable |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1124 |
if input_connected["EN"] is None: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1125 |
input_connected.pop("EN") |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1126 |
input_parameters = input_names |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1127 |
else: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1128 |
input_parameters = ["EN"] + input_names |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1129 |
else: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1130 |
input_connected = dict([(variable.getformalParameter(), variable) |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1131 |
for variable in input_variables]) |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1132 |
input_parameters = [variable.getformalParameter() |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1133 |
for variable in input_variables] |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1134 |
one_input_connected = False |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1135 |
all_input_connected = True |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1136 |
for i, parameter in enumerate(input_parameters): |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1137 |
variable = input_connected.get(parameter) |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1138 |
if variable is not None: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1139 |
input_info = (self.TagName, "block", block.getlocalId(), "input", i) |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1140 |
connections = variable.connectionPointIn.getconnections() |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1141 |
if connections is not None: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1142 |
if parameter != "EN": |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1143 |
one_input_connected = True |
1763
bcc07ff2362c
clean-up: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1753
diff
changeset
|
1144 |
if parameter in inout_variables: |
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1145 |
expression = self.ComputeExpression(body, connections, executionOrderId > 0, True) |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1146 |
if expression is not None: |
1863
46d9955e1101
fix error for functions with VAR_IN_OUT
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1862
diff
changeset
|
1147 |
inout_variables[parameter] = expression |
1864
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1148 |
else: |
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1149 |
_RaiseUnconnectedInOutError(name, type, parameter, self.Name) |
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1150 |
else: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1151 |
expression = self.ComputeExpression(body, connections, executionOrderId > 0) |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1152 |
if expression is not None: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1153 |
connected_vars.append(([(parameter, input_info), (" := ", ())], |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1154 |
self.ExtractModifier(variable, expression, input_info))) |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1155 |
else: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1156 |
all_input_connected = False |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1157 |
else: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1158 |
all_input_connected = False |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1159 |
if len(output_variables) > 1 or not all_input_connected: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1160 |
vars = [name + value for name, value in connected_vars] |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1161 |
else: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1162 |
vars = [value for name, value in connected_vars] |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1163 |
if one_input_connected: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1164 |
for i, variable in enumerate(output_variables): |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1165 |
parameter = variable.getformalParameter() |
1775
b45f2768fab1
clean-up: fix PEP8 E713 test for membership should be 'not in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1769
diff
changeset
|
1166 |
if parameter not in inout_variables and parameter in output_names + ["", "ENO"]: |
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1167 |
if variable.getformalParameter() == "": |
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
1168 |
variable_name = "%s%d" % (type, block.getlocalId()) |
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1169 |
else: |
2629
caa43c61f90c
Add marker to temporary variables created while generating ST code out of FBD, so that they can be recognized as such.
Edouard Tisserant
parents:
2521
diff
changeset
|
1170 |
variable_name = "_TMP_%s%d_%s" % (type, block.getlocalId(), parameter) |
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1171 |
if self.Interface[-1][0] != "VAR" or self.Interface[-1][1] is not None or self.Interface[-1][2]: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1172 |
self.Interface.append(("VAR", None, False, [])) |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1173 |
if variable.connectionPointOut in self.ConnectionTypes: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1174 |
self.Interface[-1][3].append((self.ConnectionTypes[variable.connectionPointOut], variable_name, None, None)) |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1175 |
else: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1176 |
self.Interface[-1][3].append(("ANY", variable_name, None, None)) |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1177 |
if len(output_variables) > 1 and parameter not in ["", "OUT"]: |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
1178 |
vars.append([(parameter, (self.TagName, "block", block.getlocalId(), "output", i)), |
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
1179 |
(" => %s" % variable_name, ())]) |
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1180 |
else: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1181 |
output_info = (self.TagName, "block", block.getlocalId(), "output", i) |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1182 |
output_name = variable_name |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1183 |
self.Program += [(self.CurrentIndent, ()), |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1184 |
(output_name, output_info), |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1185 |
(" := ", ()), |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1186 |
(type, (self.TagName, "block", block.getlocalId(), "type")), |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1187 |
("(", ())] |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1188 |
self.Program += JoinList([(", ", ())], vars) |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1189 |
self.Program += [(");\n", ())] |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1190 |
else: |
1744
69dfdb26f600
clean-up: fix PEP8 E251 unexpected spaces around keyword / parameter equals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1743
diff
changeset
|
1191 |
msg = _("\"{a1}\" function cancelled in \"{a2}\" POU: No input connected").format(a1=type, a2=self.TagName.split("::")[-1]) |
1581
2295fdc5c271
fix translation strings with multiple parameters
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1571
diff
changeset
|
1192 |
self.Warnings.append(msg) |
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1193 |
elif block_infos["type"] == "functionBlock": |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1194 |
if not self.ComputedBlocks.get(block, False) and not order: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1195 |
self.ComputedBlocks[block] = True |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1196 |
vars = [] |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1197 |
offset_idx = 0 |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1198 |
for variable in input_variables: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1199 |
parameter = variable.getformalParameter() |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1200 |
if parameter in input_names or parameter == "EN": |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1201 |
if parameter == "EN": |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1202 |
input_idx = 0 |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1203 |
offset_idx = 1 |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1204 |
else: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1205 |
input_idx = offset_idx + input_names.index(parameter) |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1206 |
input_info = (self.TagName, "block", block.getlocalId(), "input", input_idx) |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1207 |
connections = variable.connectionPointIn.getconnections() |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1208 |
if connections is not None: |
1763
bcc07ff2362c
clean-up: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1753
diff
changeset
|
1209 |
expression = self.ComputeExpression(body, connections, executionOrderId > 0, parameter in inout_variables) |
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1210 |
if expression is not None: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1211 |
vars.append([(parameter, input_info), |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1212 |
(" := ", ())] + self.ExtractModifier(variable, expression, input_info)) |
1864
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1213 |
elif parameter in inout_variables: |
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1214 |
_RaiseUnconnectedInOutError(name, type, parameter, self.Name) |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
1215 |
self.Program += [(self.CurrentIndent, ()), |
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1216 |
(name, (self.TagName, "block", block.getlocalId(), "name")), |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1217 |
("(", ())] |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1218 |
self.Program += JoinList([(", ", ())], vars) |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1219 |
self.Program += [(");\n", ())] |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
1220 |
|
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1221 |
if link is not None: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1222 |
connectionPoint = link.getposition()[-1] |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1223 |
output_parameter = link.getformalParameter() |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1224 |
else: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1225 |
connectionPoint = None |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1226 |
output_parameter = None |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
1227 |
|
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1228 |
output_variable = None |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1229 |
output_idx = 0 |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1230 |
if output_parameter is not None: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1231 |
if output_parameter in output_names or output_parameter == "ENO": |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1232 |
for variable in output_variables: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1233 |
if variable.getformalParameter() == output_parameter: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1234 |
output_variable = variable |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1235 |
if output_parameter != "ENO": |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1236 |
output_idx = output_names.index(output_parameter) |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1237 |
else: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1238 |
for i, variable in enumerate(output_variables): |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1239 |
blockPointx, blockPointy = variable.connectionPointOut.getrelPositionXY() |
1766
c1e5b9f19483
clean-up: fix PEP8 E129 visually indented line with same indent as next logical line
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1765
diff
changeset
|
1240 |
if connectionPoint is None or \ |
c1e5b9f19483
clean-up: fix PEP8 E129 visually indented line with same indent as next logical line
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1765
diff
changeset
|
1241 |
block.getx() + blockPointx == connectionPoint.getx() and \ |
c1e5b9f19483
clean-up: fix PEP8 E129 visually indented line with same indent as next logical line
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1765
diff
changeset
|
1242 |
block.gety() + blockPointy == connectionPoint.gety(): |
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1243 |
output_variable = variable |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1244 |
output_parameter = variable.getformalParameter() |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1245 |
output_idx = i |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
1246 |
|
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1247 |
if output_variable is not None: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1248 |
if block_infos["type"] == "function": |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1249 |
output_info = (self.TagName, "block", block.getlocalId(), "output", output_idx) |
1763
bcc07ff2362c
clean-up: fix PEP8 W601 .has_key() is deprecated, use 'in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1753
diff
changeset
|
1250 |
if output_parameter in inout_variables: |
1864
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1251 |
for variable in input_variables: |
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1252 |
if variable.getformalParameter() == output_parameter: |
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1253 |
connections = variable.connectionPointIn.getconnections() |
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1254 |
if connections is not None: |
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1255 |
expression = self.ComputeExpression( |
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1256 |
body, connections, executionOrderId > 0, True) |
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1257 |
output_value = expression |
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1258 |
break |
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1259 |
else: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1260 |
if output_parameter == "": |
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
1261 |
output_name = "%s%d" % (type, block.getlocalId()) |
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1262 |
else: |
2629
caa43c61f90c
Add marker to temporary variables created while generating ST code out of FBD, so that they can be recognized as such.
Edouard Tisserant
parents:
2521
diff
changeset
|
1263 |
output_name = "_TMP_%s%d_%s" % (type, block.getlocalId(), output_parameter) |
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1264 |
output_value = [(output_name, output_info)] |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1265 |
return self.ExtractModifier(output_variable, output_value, output_info) |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1266 |
if block_infos["type"] == "functionBlock": |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1267 |
output_info = (self.TagName, "block", block.getlocalId(), "output", output_idx) |
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
1268 |
output_name = self.ExtractModifier(output_variable, [("%s.%s" % (name, output_parameter), output_info)], output_info) |
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1269 |
if to_inout: |
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
1270 |
variable_name = "%s_%s" % (name, output_parameter) |
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1271 |
if not self.IsAlreadyDefined(variable_name): |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1272 |
if self.Interface[-1][0] != "VAR" or self.Interface[-1][1] is not None or self.Interface[-1][2]: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1273 |
self.Interface.append(("VAR", None, False, [])) |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1274 |
if variable.connectionPointOut in self.ConnectionTypes: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1275 |
self.Interface[-1][3].append( |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1276 |
(self.ConnectionTypes[output_variable.connectionPointOut], variable_name, None, None)) |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1277 |
else: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1278 |
self.Interface[-1][3].append(("ANY", variable_name, None, None)) |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1279 |
self.Program += [(self.CurrentIndent, ()), |
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
1280 |
("%s := " % variable_name, ())] |
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1281 |
self.Program += output_name |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1282 |
self.Program += [(";\n", ())] |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1283 |
return [(variable_name, ())] |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
1284 |
return output_name |
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1285 |
if link is not None: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1286 |
if output_parameter is None: |
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1287 |
output_parameter = "" |
1864
9e64afb38963
fix problems with unconnected input of InOut function variables and
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1863
diff
changeset
|
1288 |
blockname = _GetBlockName(name, type) |
1765
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1289 |
raise ValueError( |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1290 |
_("No output {a1} variable found in block {a2} in POU {a3}. Connection must be broken"). |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1291 |
format(a1=output_parameter, a2=blockname, a3=self.Name)) |
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1292 |
|
1744
69dfdb26f600
clean-up: fix PEP8 E251 unexpected spaces around keyword / parameter equals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1743
diff
changeset
|
1293 |
def GeneratePaths(self, connections, body, order=False, to_inout=False): |
814 | 1294 |
paths = [] |
1295 |
for connection in connections: |
|
1296 |
localId = connection.getrefLocalId() |
|
1297 |
next = body.getcontentInstance(localId) |
|
1297 | 1298 |
if isinstance(next, LeftPowerRailClass): |
814 | 1299 |
paths.append(None) |
1297 | 1300 |
elif isinstance(next, (InVariableClass, InOutVariableClass)): |
1322
0a9227f743b3
Fixed xmlclass for working with included files, adding support for SimpleType elements and solving ambiguity in extension class when different elements share the same name and parent name
Laurent Bessard
parents:
1315
diff
changeset
|
1301 |
paths.append(str([(next.getexpression(), (self.TagName, "io_variable", localId, "expression"))])) |
1297 | 1302 |
elif isinstance(next, BlockClass): |
814 | 1303 |
block_type = next.gettypeName() |
1304 |
self.ParentGenerator.GeneratePouProgram(block_type) |
|
1305 |
block_infos = self.GetBlockType(block_type, tuple([self.ConnectionTypes.get(variable.connectionPointIn, "ANY") for variable in next.inputVariables.getvariable() if variable.getformalParameter() != "EN"])) |
|
1306 |
if block_infos is None: |
|
1307 |
block_infos = self.GetBlockType(block_type) |
|
1308 |
if block_infos is None: |
|
1765
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1309 |
raise PLCGenException( |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1310 |
_("Undefined block type \"{a1}\" in \"{a2}\" POU"). |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1311 |
format(a1=block_type, a2=self.Name)) |
1134
1c7a4ad86aa1
Fixed PLC code generator when interface of an already used POU has changed
Laurent Bessard
parents:
1048
diff
changeset
|
1312 |
try: |
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1313 |
paths.append(str(self.GenerateBlock(next, block_infos, body, connection, order, to_inout))) |
2418
5587c490a070
Use python 3 compatible exception syntax everywhere
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2277
diff
changeset
|
1314 |
except ValueError as e: |
2447
1c04a50dc7ff
python3 support: pylint, W1645 # (exception-message-attribute) Exception.message removed in Python 3
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2432
diff
changeset
|
1315 |
raise PLCGenException(str(e)) |
1297 | 1316 |
elif isinstance(next, ContinuationClass): |
814 | 1317 |
name = next.getname() |
1318 |
computed_value = self.ComputedConnectors.get(name, None) |
|
1743
c3c3d1318130
clean-up: fix PEP8 E711 comparison to None should be 'if cond is not None:'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1742
diff
changeset
|
1319 |
if computed_value is not None: |
814 | 1320 |
paths.append(str(computed_value)) |
1321 |
else: |
|
1322 |
connector = None |
|
1323 |
for instance in body.getcontentInstances(): |
|
1297 | 1324 |
if isinstance(instance, ConnectorClass) and instance.getname() == name: |
814 | 1325 |
if connector is not None: |
1765
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1326 |
raise PLCGenException( |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1327 |
_("More than one connector found corresponding to \"{a1}\" continuation in \"{a2}\" POU"). |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1328 |
format(a1=name, a2=self.Name)) |
814 | 1329 |
connector = instance |
1330 |
if connector is not None: |
|
1331 |
connections = connector.connectionPointIn.getconnections() |
|
1332 |
if connections is not None: |
|
1333 |
expression = self.ComputeExpression(body, connections, order) |
|
1239
d1f6ea56555d
Fixed bug when generating ST code and connection is broken in POU using graphical language
Laurent Bessard
parents:
1183
diff
changeset
|
1334 |
if expression is not None: |
d1f6ea56555d
Fixed bug when generating ST code and connection is broken in POU using graphical language
Laurent Bessard
parents:
1183
diff
changeset
|
1335 |
self.ComputedConnectors[name] = expression |
d1f6ea56555d
Fixed bug when generating ST code and connection is broken in POU using graphical language
Laurent Bessard
parents:
1183
diff
changeset
|
1336 |
paths.append(str(expression)) |
814 | 1337 |
else: |
1765
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1338 |
raise PLCGenException( |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1339 |
_("No connector found corresponding to \"{a1}\" continuation in \"{a2}\" POU"). |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1340 |
format(a1=name, a2=self.Name)) |
1297 | 1341 |
elif isinstance(next, ContactClass): |
814 | 1342 |
contact_info = (self.TagName, "contact", next.getlocalId()) |
1322
0a9227f743b3
Fixed xmlclass for working with included files, adding support for SimpleType elements and solving ambiguity in extension class when different elements share the same name and parent name
Laurent Bessard
parents:
1315
diff
changeset
|
1343 |
variable = str(self.ExtractModifier(next, [(next.getvariable(), contact_info + ("reference",))], contact_info)) |
814 | 1344 |
result = self.GeneratePaths(next.connectionPointIn.getconnections(), body, order) |
2519
27955f010b23
Fix crash if LD input contact isn't connected
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2456
diff
changeset
|
1345 |
if len(result) == 0: |
27955f010b23
Fix crash if LD input contact isn't connected
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2456
diff
changeset
|
1346 |
raise PLCGenException(_("Contact \"{a1}\" in POU \"{a2}\" must be connected."). |
27955f010b23
Fix crash if LD input contact isn't connected
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2456
diff
changeset
|
1347 |
format(a1=next.getvariable(), a2=self.Name)) |
814 | 1348 |
if len(result) > 1: |
1349 |
factorized_paths = self.FactorizePaths(result) |
|
1350 |
if len(factorized_paths) > 1: |
|
1351 |
paths.append([variable, tuple(factorized_paths)]) |
|
1352 |
else: |
|
1353 |
paths.append([variable] + factorized_paths) |
|
2450
5024c19ca8f0
python3 support: pylint, W1652 # (deprecated-types-field) Accessing a deprecated fields on the types module
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2447
diff
changeset
|
1354 |
elif isinstance(result[0], list): |
814 | 1355 |
paths.append([variable] + result[0]) |
1356 |
elif result[0] is not None: |
|
1357 |
paths.append([variable, result[0]]) |
|
1358 |
else: |
|
1359 |
paths.append(variable) |
|
1297 | 1360 |
elif isinstance(next, CoilClass): |
2277
068ccc02f5f2
Fix wrong ST code generation in case of several coils connected to each other.
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2275
diff
changeset
|
1361 |
paths.append(self.GeneratePaths(next.connectionPointIn.getconnections(), body, order)) |
814 | 1362 |
return paths |
1363 |
||
1744
69dfdb26f600
clean-up: fix PEP8 E251 unexpected spaces around keyword / parameter equals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1743
diff
changeset
|
1364 |
def ComputePaths(self, paths, first=False): |
2450
5024c19ca8f0
python3 support: pylint, W1652 # (deprecated-types-field) Accessing a deprecated fields on the types module
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2447
diff
changeset
|
1365 |
if isinstance(paths, tuple): |
814 | 1366 |
if None in paths: |
1367 |
return [("TRUE", ())] |
|
1368 |
else: |
|
1369 |
vars = [self.ComputePaths(path) for path in paths] |
|
1370 |
if first: |
|
1371 |
return JoinList([(" OR ", ())], vars) |
|
1372 |
else: |
|
1373 |
return [("(", ())] + JoinList([(" OR ", ())], vars) + [(")", ())] |
|
2450
5024c19ca8f0
python3 support: pylint, W1652 # (deprecated-types-field) Accessing a deprecated fields on the types module
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2447
diff
changeset
|
1374 |
elif isinstance(paths, list): |
814 | 1375 |
vars = [self.ComputePaths(path) for path in paths] |
1376 |
return JoinList([(" AND ", ())], vars) |
|
1377 |
elif paths is None: |
|
1378 |
return [("TRUE", ())] |
|
1379 |
else: |
|
1380 |
return eval(paths) |
|
1381 |
||
1744
69dfdb26f600
clean-up: fix PEP8 E251 unexpected spaces around keyword / parameter equals
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1743
diff
changeset
|
1382 |
def ComputeExpression(self, body, connections, order=False, to_inout=False): |
814 | 1383 |
paths = self.GeneratePaths(connections, body, order, to_inout) |
1239
d1f6ea56555d
Fixed bug when generating ST code and connection is broken in POU using graphical language
Laurent Bessard
parents:
1183
diff
changeset
|
1384 |
if len(paths) == 0: |
d1f6ea56555d
Fixed bug when generating ST code and connection is broken in POU using graphical language
Laurent Bessard
parents:
1183
diff
changeset
|
1385 |
return None |
814 | 1386 |
if len(paths) > 1: |
1387 |
factorized_paths = self.FactorizePaths(paths) |
|
1388 |
if len(factorized_paths) > 1: |
|
1389 |
paths = tuple(factorized_paths) |
|
1390 |
else: |
|
1391 |
paths = factorized_paths[0] |
|
1392 |
else: |
|
1393 |
paths = paths[0] |
|
1394 |
return self.ComputePaths(paths, True) |
|
1395 |
||
1396 |
def ExtractModifier(self, variable, expression, var_info): |
|
1397 |
if variable.getnegated(): |
|
1398 |
return [("NOT(", var_info + ("negated",))] + expression + [(")", ())] |
|
1399 |
else: |
|
1400 |
storage = variable.getstorage() |
|
1401 |
if storage in ["set", "reset"]: |
|
1402 |
self.Program += [(self.CurrentIndent + "IF ", var_info + (storage,))] + expression |
|
1403 |
self.Program += [(" THEN\n ", ())] |
|
1404 |
if storage == "set": |
|
1405 |
return [("TRUE; (*set*)\n" + self.CurrentIndent + "END_IF", ())] |
|
1406 |
else: |
|
1407 |
return [("FALSE; (*reset*)\n" + self.CurrentIndent + "END_IF", ())] |
|
1408 |
edge = variable.getedge() |
|
1409 |
if edge == "rising": |
|
1410 |
return self.AddTrigger("R_TRIG", expression, var_info + ("rising",)) |
|
1411 |
elif edge == "falling": |
|
1412 |
return self.AddTrigger("F_TRIG", expression, var_info + ("falling",)) |
|
1413 |
return expression |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
1414 |
|
814 | 1415 |
def AddTrigger(self, edge, expression, var_info): |
1416 |
if self.Interface[-1][0] != "VAR" or self.Interface[-1][1] is not None or self.Interface[-1][2]: |
|
1417 |
self.Interface.append(("VAR", None, False, [])) |
|
1418 |
i = 1 |
|
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
1419 |
name = "%s%d" % (edge, i) |
814 | 1420 |
while self.IsAlreadyDefined(name): |
1421 |
i += 1 |
|
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
1422 |
name = "%s%d" % (edge, i) |
814 | 1423 |
self.Interface[-1][3].append((edge, name, None, None)) |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
1424 |
self.Program += [(self.CurrentIndent, ()), (name, var_info), ("(CLK := ", ())] |
814 | 1425 |
self.Program += expression |
1426 |
self.Program += [(");\n", ())] |
|
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
1427 |
return [("%s.Q" % name, var_info)] |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
1428 |
|
814 | 1429 |
def ExtractDivergenceInput(self, divergence, pou): |
1430 |
connectionPointIn = divergence.getconnectionPointIn() |
|
1298
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
1431 |
if connectionPointIn is not None: |
814 | 1432 |
connections = connectionPointIn.getconnections() |
1433 |
if connections is not None and len(connections) == 1: |
|
1434 |
instanceLocalId = connections[0].getrefLocalId() |
|
1435 |
body = pou.getbody() |
|
2450
5024c19ca8f0
python3 support: pylint, W1652 # (deprecated-types-field) Accessing a deprecated fields on the types module
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2447
diff
changeset
|
1436 |
if isinstance(body, list): |
814 | 1437 |
body = body[0] |
1438 |
return body.getcontentInstance(instanceLocalId) |
|
1439 |
return None |
|
1440 |
||
1441 |
def ExtractConvergenceInputs(self, convergence, pou): |
|
1442 |
instances = [] |
|
1443 |
for connectionPointIn in convergence.getconnectionPointIn(): |
|
1444 |
connections = connectionPointIn.getconnections() |
|
1445 |
if connections is not None and len(connections) == 1: |
|
1446 |
instanceLocalId = connections[0].getrefLocalId() |
|
1447 |
body = pou.getbody() |
|
2450
5024c19ca8f0
python3 support: pylint, W1652 # (deprecated-types-field) Accessing a deprecated fields on the types module
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2447
diff
changeset
|
1448 |
if isinstance(body, list): |
814 | 1449 |
body = body[0] |
1450 |
instances.append(body.getcontentInstance(instanceLocalId)) |
|
1451 |
return instances |
|
1452 |
||
1453 |
def GenerateSFCStep(self, step, pou): |
|
1454 |
step_name = step.getname() |
|
1455 |
if step_name not in self.SFCNetworks["Steps"].keys(): |
|
1456 |
if step.getinitialStep(): |
|
1457 |
self.InitialSteps.append(step_name) |
|
1739
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1736
diff
changeset
|
1458 |
step_infos = {"id": step.getlocalId(), |
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1736
diff
changeset
|
1459 |
"initial": step.getinitialStep(), |
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1736
diff
changeset
|
1460 |
"transitions": [], |
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1736
diff
changeset
|
1461 |
"actions": []} |
889
ac18acb6917f
Fix bug when using feedback loop in SFC program instead of jump
Laurent Bessard
parents:
883
diff
changeset
|
1462 |
self.SFCNetworks["Steps"][step_name] = step_infos |
1298
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
1463 |
if step.connectionPointIn is not None: |
814 | 1464 |
instances = [] |
1465 |
connections = step.connectionPointIn.getconnections() |
|
1466 |
if connections is not None and len(connections) == 1: |
|
1467 |
instanceLocalId = connections[0].getrefLocalId() |
|
1468 |
body = pou.getbody() |
|
2450
5024c19ca8f0
python3 support: pylint, W1652 # (deprecated-types-field) Accessing a deprecated fields on the types module
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2447
diff
changeset
|
1469 |
if isinstance(body, list): |
814 | 1470 |
body = body[0] |
1471 |
instance = body.getcontentInstance(instanceLocalId) |
|
1297 | 1472 |
if isinstance(instance, TransitionClass): |
814 | 1473 |
instances.append(instance) |
1297 | 1474 |
elif isinstance(instance, SelectionConvergenceClass): |
814 | 1475 |
instances.extend(self.ExtractConvergenceInputs(instance, pou)) |
1297 | 1476 |
elif isinstance(instance, SimultaneousDivergenceClass): |
814 | 1477 |
transition = self.ExtractDivergenceInput(instance, pou) |
1298
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
1478 |
if transition is not None: |
1297 | 1479 |
if isinstance(transition, TransitionClass): |
814 | 1480 |
instances.append(transition) |
1297 | 1481 |
elif isinstance(transition, SelectionConvergenceClass): |
814 | 1482 |
instances.extend(self.ExtractConvergenceInputs(transition, pou)) |
1483 |
for instance in instances: |
|
1484 |
self.GenerateSFCTransition(instance, pou) |
|
1485 |
if instance in self.SFCNetworks["Transitions"].keys(): |
|
1486 |
target_info = (self.TagName, "transition", instance.getlocalId(), "to", step_infos["id"]) |
|
1487 |
self.SFCNetworks["Transitions"][instance]["to"].append([(step_name, target_info)]) |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
1488 |
|
814 | 1489 |
def GenerateSFCJump(self, jump, pou): |
1490 |
jump_target = jump.gettargetName() |
|
1626
0779c1b18c01
check before program generation whether SFC step, that is referenced
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1614
diff
changeset
|
1491 |
if not pou.hasstep(jump_target): |
0779c1b18c01
check before program generation whether SFC step, that is referenced
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1614
diff
changeset
|
1492 |
pname = pou.getname() |
1765
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1493 |
raise PLCGenException( |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1494 |
_("SFC jump in pou \"{a1}\" refers to non-existent SFC step \"{a2}\""). |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1495 |
format(a1=pname, a2=jump_target)) |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1496 |
|
1298
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
1497 |
if jump.connectionPointIn is not None: |
814 | 1498 |
instances = [] |
1499 |
connections = jump.connectionPointIn.getconnections() |
|
1500 |
if connections is not None and len(connections) == 1: |
|
1501 |
instanceLocalId = connections[0].getrefLocalId() |
|
1502 |
body = pou.getbody() |
|
2450
5024c19ca8f0
python3 support: pylint, W1652 # (deprecated-types-field) Accessing a deprecated fields on the types module
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2447
diff
changeset
|
1503 |
if isinstance(body, list): |
814 | 1504 |
body = body[0] |
1505 |
instance = body.getcontentInstance(instanceLocalId) |
|
1297 | 1506 |
if isinstance(instance, TransitionClass): |
814 | 1507 |
instances.append(instance) |
1297 | 1508 |
elif isinstance(instance, SelectionConvergenceClass): |
814 | 1509 |
instances.extend(self.ExtractConvergenceInputs(instance, pou)) |
1297 | 1510 |
elif isinstance(instance, SimultaneousDivergenceClass): |
814 | 1511 |
transition = self.ExtractDivergenceInput(instance, pou) |
1298
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
1512 |
if transition is not None: |
1297 | 1513 |
if isinstance(transition, TransitionClass): |
814 | 1514 |
instances.append(transition) |
1297 | 1515 |
elif isinstance(transition, SelectionConvergenceClass): |
814 | 1516 |
instances.extend(self.ExtractConvergenceInputs(transition, pou)) |
1517 |
for instance in instances: |
|
1518 |
self.GenerateSFCTransition(instance, pou) |
|
1519 |
if instance in self.SFCNetworks["Transitions"].keys(): |
|
1520 |
target_info = (self.TagName, "jump", jump.getlocalId(), "target") |
|
1521 |
self.SFCNetworks["Transitions"][instance]["to"].append([(jump_target, target_info)]) |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
1522 |
|
814 | 1523 |
def GenerateSFCStepActions(self, actionBlock, pou): |
1524 |
connections = actionBlock.connectionPointIn.getconnections() |
|
1525 |
if connections is not None and len(connections) == 1: |
|
1526 |
stepLocalId = connections[0].getrefLocalId() |
|
1527 |
body = pou.getbody() |
|
2450
5024c19ca8f0
python3 support: pylint, W1652 # (deprecated-types-field) Accessing a deprecated fields on the types module
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2447
diff
changeset
|
1528 |
if isinstance(body, list): |
814 | 1529 |
body = body[0] |
1530 |
step = body.getcontentInstance(stepLocalId) |
|
1531 |
self.GenerateSFCStep(step, pou) |
|
1532 |
step_name = step.getname() |
|
1533 |
if step_name in self.SFCNetworks["Steps"].keys(): |
|
1534 |
actions = actionBlock.getactions() |
|
1535 |
for i, action in enumerate(actions): |
|
1739
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1736
diff
changeset
|
1536 |
action_infos = {"id": actionBlock.getlocalId(), |
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1736
diff
changeset
|
1537 |
"qualifier": action["qualifier"], |
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1736
diff
changeset
|
1538 |
"content": action["value"], |
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1736
diff
changeset
|
1539 |
"num": i} |
814 | 1540 |
if "duration" in action: |
1541 |
action_infos["duration"] = action["duration"] |
|
1542 |
if "indicator" in action: |
|
1543 |
action_infos["indicator"] = action["indicator"] |
|
1544 |
if action["type"] == "reference": |
|
1545 |
self.GenerateSFCAction(action["value"], pou) |
|
1546 |
else: |
|
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
1547 |
action_name = "%s_INLINE%d" % (step_name.upper(), self.GetActionNumber()) |
1768
691083b5682a
clean-up: fix PEP8 E128 continuation line under-indented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset
|
1548 |
self.SFCNetworks["Actions"][action_name] = ([ |
691083b5682a
clean-up: fix PEP8 E128 continuation line under-indented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset
|
1549 |
(self.CurrentIndent, ()), |
691083b5682a
clean-up: fix PEP8 E128 continuation line under-indented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset
|
1550 |
(action["value"], ( |
691083b5682a
clean-up: fix PEP8 E128 continuation line under-indented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset
|
1551 |
self.TagName, "action_block", action_infos["id"], |
691083b5682a
clean-up: fix PEP8 E128 continuation line under-indented for visual indent
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1767
diff
changeset
|
1552 |
"action", i, "inline")), |
814 | 1553 |
("\n", ())], ()) |
1554 |
action_infos["content"] = action_name |
|
1555 |
self.SFCNetworks["Steps"][step_name]["actions"].append(action_infos) |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
1556 |
|
814 | 1557 |
def GenerateSFCAction(self, action_name, pou): |
1558 |
if action_name not in self.SFCNetworks["Actions"].keys(): |
|
1559 |
actionContent = pou.getaction(action_name) |
|
1298
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
1560 |
if actionContent is not None: |
814 | 1561 |
previous_tagname = self.TagName |
1948
b9a3f771aaab
Moved some definitions away from controller class, and adaped references them through all code.
Edouard Tisserant
parents:
1881
diff
changeset
|
1562 |
self.TagName = ComputePouActionName(self.Name, action_name) |
814 | 1563 |
self.ComputeProgram(actionContent) |
1564 |
self.SFCNetworks["Actions"][action_name] = (self.Program, (self.TagName, "name")) |
|
1565 |
self.Program = [] |
|
1566 |
self.TagName = previous_tagname |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
1567 |
|
814 | 1568 |
def GenerateSFCTransition(self, transition, pou): |
1569 |
if transition not in self.SFCNetworks["Transitions"].keys(): |
|
1570 |
steps = [] |
|
1571 |
connections = transition.connectionPointIn.getconnections() |
|
1572 |
if connections is not None and len(connections) == 1: |
|
1573 |
instanceLocalId = connections[0].getrefLocalId() |
|
1574 |
body = pou.getbody() |
|
2450
5024c19ca8f0
python3 support: pylint, W1652 # (deprecated-types-field) Accessing a deprecated fields on the types module
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2447
diff
changeset
|
1575 |
if isinstance(body, list): |
814 | 1576 |
body = body[0] |
1577 |
instance = body.getcontentInstance(instanceLocalId) |
|
1297 | 1578 |
if isinstance(instance, StepClass): |
814 | 1579 |
steps.append(instance) |
1297 | 1580 |
elif isinstance(instance, SelectionDivergenceClass): |
814 | 1581 |
step = self.ExtractDivergenceInput(instance, pou) |
1298
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
1582 |
if step is not None: |
1297 | 1583 |
if isinstance(step, StepClass): |
814 | 1584 |
steps.append(step) |
1297 | 1585 |
elif isinstance(step, SimultaneousConvergenceClass): |
814 | 1586 |
steps.extend(self.ExtractConvergenceInputs(step, pou)) |
1297 | 1587 |
elif isinstance(instance, SimultaneousConvergenceClass): |
814 | 1588 |
steps.extend(self.ExtractConvergenceInputs(instance, pou)) |
1739
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1736
diff
changeset
|
1589 |
transition_infos = {"id": transition.getlocalId(), |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
1590 |
"priority": transition.getpriority(), |
1739
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1736
diff
changeset
|
1591 |
"from": [], |
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1736
diff
changeset
|
1592 |
"to": [], |
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1736
diff
changeset
|
1593 |
"content": []} |
889
ac18acb6917f
Fix bug when using feedback loop in SFC program instead of jump
Laurent Bessard
parents:
883
diff
changeset
|
1594 |
self.SFCNetworks["Transitions"][transition] = transition_infos |
814 | 1595 |
transitionValues = transition.getconditionContent() |
1596 |
if transitionValues["type"] == "inline": |
|
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
1597 |
transition_infos["content"] = [("\n%s:= " % self.CurrentIndent, ()), |
814 | 1598 |
(transitionValues["value"], (self.TagName, "transition", transition.getlocalId(), "inline")), |
1599 |
(";\n", ())] |
|
1600 |
elif transitionValues["type"] == "reference": |
|
1601 |
transitionContent = pou.gettransition(transitionValues["value"]) |
|
1602 |
transitionType = transitionContent.getbodyType() |
|
1603 |
transitionBody = transitionContent.getbody() |
|
1604 |
previous_tagname = self.TagName |
|
1948
b9a3f771aaab
Moved some definitions away from controller class, and adaped references them through all code.
Edouard Tisserant
parents:
1881
diff
changeset
|
1605 |
self.TagName = ComputePouTransitionName(self.Name, transitionValues["value"]) |
814 | 1606 |
if transitionType == "IL": |
1607 |
transition_infos["content"] = [(":\n", ()), |
|
1450
44bf0ba866e9
Fixed SFC code generation bug detected by Mario
Edouard Tisserant
parents:
1420
diff
changeset
|
1608 |
(ReIndentText(transitionBody.getcontent().getanyText(), len(self.CurrentIndent)), (self.TagName, "body", len(self.CurrentIndent)))] |
814 | 1609 |
elif transitionType == "ST": |
1610 |
transition_infos["content"] = [("\n", ()), |
|
1450
44bf0ba866e9
Fixed SFC code generation bug detected by Mario
Edouard Tisserant
parents:
1420
diff
changeset
|
1611 |
(ReIndentText(transitionBody.getcontent().getanyText(), len(self.CurrentIndent)), (self.TagName, "body", len(self.CurrentIndent)))] |
814 | 1612 |
else: |
1613 |
for instance in transitionBody.getcontentInstances(): |
|
1769
4665ba25a0ba
clean-up: fix PEP8 E125 continuation line with same indent as next logical line
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1768
diff
changeset
|
1614 |
if isinstance(instance, OutVariableClass) and instance.getexpression() == transitionValues["value"] or \ |
4665ba25a0ba
clean-up: fix PEP8 E125 continuation line with same indent as next logical line
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1768
diff
changeset
|
1615 |
isinstance(instance, CoilClass) and instance.getvariable() == transitionValues["value"]: |
814 | 1616 |
connections = instance.connectionPointIn.getconnections() |
1617 |
if connections is not None: |
|
1618 |
expression = self.ComputeExpression(transitionBody, connections) |
|
1239
d1f6ea56555d
Fixed bug when generating ST code and connection is broken in POU using graphical language
Laurent Bessard
parents:
1183
diff
changeset
|
1619 |
if expression is not None: |
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
1620 |
transition_infos["content"] = [("\n%s:= " % self.CurrentIndent, ())] + expression + [(";\n", ())] |
1239
d1f6ea56555d
Fixed bug when generating ST code and connection is broken in POU using graphical language
Laurent Bessard
parents:
1183
diff
changeset
|
1621 |
self.SFCComputedBlocks += self.Program |
d1f6ea56555d
Fixed bug when generating ST code and connection is broken in POU using graphical language
Laurent Bessard
parents:
1183
diff
changeset
|
1622 |
self.Program = [] |
1775
b45f2768fab1
clean-up: fix PEP8 E713 test for membership should be 'not in'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1769
diff
changeset
|
1623 |
if "content" not in transition_infos: |
1765
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1624 |
raise PLCGenException( |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1625 |
_("Transition \"%s\" body must contain an output variable or coil referring to its name") |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1626 |
% transitionValues["value"]) |
814 | 1627 |
self.TagName = previous_tagname |
1628 |
elif transitionValues["type"] == "connection": |
|
1629 |
body = pou.getbody() |
|
2450
5024c19ca8f0
python3 support: pylint, W1652 # (deprecated-types-field) Accessing a deprecated fields on the types module
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
2447
diff
changeset
|
1630 |
if isinstance(body, list): |
814 | 1631 |
body = body[0] |
1298
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
1632 |
connections = transitionValues["value"].getconnections() |
814 | 1633 |
if connections is not None: |
1634 |
expression = self.ComputeExpression(body, connections) |
|
1239
d1f6ea56555d
Fixed bug when generating ST code and connection is broken in POU using graphical language
Laurent Bessard
parents:
1183
diff
changeset
|
1635 |
if expression is not None: |
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
1636 |
transition_infos["content"] = [("\n%s:= " % self.CurrentIndent, ())] + expression + [(";\n", ())] |
1239
d1f6ea56555d
Fixed bug when generating ST code and connection is broken in POU using graphical language
Laurent Bessard
parents:
1183
diff
changeset
|
1637 |
self.SFCComputedBlocks += self.Program |
d1f6ea56555d
Fixed bug when generating ST code and connection is broken in POU using graphical language
Laurent Bessard
parents:
1183
diff
changeset
|
1638 |
self.Program = [] |
814 | 1639 |
for step in steps: |
1640 |
self.GenerateSFCStep(step, pou) |
|
1641 |
step_name = step.getname() |
|
1642 |
if step_name in self.SFCNetworks["Steps"].keys(): |
|
1643 |
transition_infos["from"].append([(step_name, (self.TagName, "transition", transition.getlocalId(), "from", step.getlocalId()))]) |
|
1644 |
self.SFCNetworks["Steps"][step_name]["transitions"].append(transition) |
|
1645 |
||
1646 |
def ComputeSFCStep(self, step_name): |
|
1647 |
if step_name in self.SFCNetworks["Steps"].keys(): |
|
1648 |
step_infos = self.SFCNetworks["Steps"].pop(step_name) |
|
1649 |
self.Program += [(self.CurrentIndent, ())] |
|
1650 |
if step_infos["initial"]: |
|
1651 |
self.Program += [("INITIAL_", ())] |
|
1652 |
self.Program += [("STEP ", ()), |
|
1653 |
(step_name, (self.TagName, "step", step_infos["id"], "name")), |
|
1654 |
(":\n", ())] |
|
1655 |
actions = [] |
|
1656 |
self.IndentRight() |
|
1657 |
for action_infos in step_infos["actions"]: |
|
1658 |
if action_infos.get("id", None) is not None: |
|
1659 |
action_info = (self.TagName, "action_block", action_infos["id"], "action", action_infos["num"]) |
|
1660 |
else: |
|
1661 |
action_info = () |
|
1662 |
actions.append(action_infos["content"]) |
|
1663 |
self.Program += [(self.CurrentIndent, ()), |
|
1664 |
(action_infos["content"], action_info + ("reference",)), |
|
1665 |
("(", ()), |
|
1666 |
(action_infos["qualifier"], action_info + ("qualifier",))] |
|
1667 |
if "duration" in action_infos: |
|
1668 |
self.Program += [(", ", ()), |
|
1669 |
(action_infos["duration"], action_info + ("duration",))] |
|
1670 |
if "indicator" in action_infos: |
|
1671 |
self.Program += [(", ", ()), |
|
1672 |
(action_infos["indicator"], action_info + ("indicator",))] |
|
1673 |
self.Program += [(");\n", ())] |
|
1674 |
self.IndentLeft() |
|
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
1675 |
self.Program += [("%sEND_STEP\n\n" % self.CurrentIndent, ())] |
814 | 1676 |
for action in actions: |
1677 |
self.ComputeSFCAction(action) |
|
1678 |
for transition in step_infos["transitions"]: |
|
1679 |
self.ComputeSFCTransition(transition) |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
1680 |
|
814 | 1681 |
def ComputeSFCAction(self, action_name): |
1682 |
if action_name in self.SFCNetworks["Actions"].keys(): |
|
1683 |
action_content, action_info = self.SFCNetworks["Actions"].pop(action_name) |
|
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
1684 |
self.Program += [("%sACTION " % self.CurrentIndent, ()), |
814 | 1685 |
(action_name, action_info), |
1298
f034fb2b1aab
Fixed SFC block edition and SFC to SFC_textual code generating
Laurent Bessard
parents:
1297
diff
changeset
|
1686 |
(":\n", ())] |
814 | 1687 |
self.Program += action_content |
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
1688 |
self.Program += [("%sEND_ACTION\n\n" % self.CurrentIndent, ())] |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
1689 |
|
814 | 1690 |
def ComputeSFCTransition(self, transition): |
1691 |
if transition in self.SFCNetworks["Transitions"].keys(): |
|
1692 |
transition_infos = self.SFCNetworks["Transitions"].pop(transition) |
|
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
1693 |
self.Program += [("%sTRANSITION" % self.CurrentIndent, ())] |
1743
c3c3d1318130
clean-up: fix PEP8 E711 comparison to None should be 'if cond is not None:'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1742
diff
changeset
|
1694 |
if transition_infos["priority"] is not None: |
814 | 1695 |
self.Program += [(" (PRIORITY := ", ()), |
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
1696 |
("%d" % transition_infos["priority"], (self.TagName, "transition", transition_infos["id"], "priority")), |
814 | 1697 |
(")", ())] |
1698 |
self.Program += [(" FROM ", ())] |
|
1699 |
if len(transition_infos["from"]) > 1: |
|
1700 |
self.Program += [("(", ())] |
|
1701 |
self.Program += JoinList([(", ", ())], transition_infos["from"]) |
|
1702 |
self.Program += [(")", ())] |
|
1703 |
elif len(transition_infos["from"]) == 1: |
|
1704 |
self.Program += transition_infos["from"][0] |
|
1705 |
else: |
|
1765
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1706 |
raise PLCGenException( |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1707 |
_("Transition with content \"{a1}\" not connected to a previous step in \"{a2}\" POU"). |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1708 |
format(a1=transition_infos["content"], a2=self.Name)) |
814 | 1709 |
self.Program += [(" TO ", ())] |
1710 |
if len(transition_infos["to"]) > 1: |
|
1711 |
self.Program += [("(", ())] |
|
1712 |
self.Program += JoinList([(", ", ())], transition_infos["to"]) |
|
1713 |
self.Program += [(")", ())] |
|
1714 |
elif len(transition_infos["to"]) == 1: |
|
1715 |
self.Program += transition_infos["to"][0] |
|
1716 |
else: |
|
1765
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1717 |
raise PLCGenException( |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1718 |
_("Transition with content \"{a1}\" not connected to a next step in \"{a2}\" POU"). |
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1719 |
format(a1=transition_infos["content"], a2=self.Name)) |
814 | 1720 |
self.Program += transition_infos["content"] |
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
1721 |
self.Program += [("%sEND_TRANSITION\n\n" % self.CurrentIndent, ())] |
1847
6198190bc121
explicitly mark unused variables found by pylint with _ or dummy
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1846
diff
changeset
|
1722 |
for [(step_name, _step_infos)] in transition_infos["to"]: |
814 | 1723 |
self.ComputeSFCStep(step_name) |
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
1724 |
|
814 | 1725 |
def GenerateProgram(self, pou): |
1726 |
self.ComputeInterface(pou) |
|
1727 |
self.ComputeConnectionTypes(pou) |
|
1728 |
self.ComputeProgram(pou) |
|
1418
c97dc5281419
Fixed declaration and ST code gen for IEC function that return derivated types
Edouard Tisserant
parents:
1358
diff
changeset
|
1729 |
|
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
1730 |
program = [("%s " % self.Type, ()), |
814 | 1731 |
(self.Name, (self.TagName, "name"))] |
1310
3d7fa2257b24
Removed obsolete process for customizing block code generated in extensions
Laurent Bessard
parents:
1298
diff
changeset
|
1732 |
if self.ReturnType is not None: |
814 | 1733 |
program += [(" : ", ()), |
1734 |
(self.ReturnType, (self.TagName, "return"))] |
|
1735 |
program += [("\n", ())] |
|
1736 |
if len(self.Interface) == 0: |
|
1765
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1737 |
raise PLCGenException(_("No variable defined in \"%s\" POU") % self.Name) |
1739
ec153828ded2
clean-up: fix PEP8 E203 whitespace before ':' and whitespace before ','
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1736
diff
changeset
|
1738 |
if len(self.Program) == 0: |
1765
ccf59c1f0b45
clean-up: fix PEP8 W602 deprecated form of raising exception
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1763
diff
changeset
|
1739 |
raise PLCGenException(_("No body defined in \"%s\" POU") % self.Name) |
814 | 1740 |
var_number = 0 |
1847
6198190bc121
explicitly mark unused variables found by pylint with _ or dummy
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1846
diff
changeset
|
1741 |
for list_type, option, _located, variables in self.Interface: |
814 | 1742 |
variable_type = errorVarTypes.get(list_type, "var_local") |
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
1743 |
program += [(" %s" % list_type, ())] |
814 | 1744 |
if option is not None: |
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
1745 |
program += [(" %s" % option, (self.TagName, variable_type, (var_number, var_number + len(variables)), option.lower()))] |
814 | 1746 |
program += [("\n", ())] |
1747 |
for var_type, var_name, var_address, var_initial in variables: |
|
1748 |
program += [(" ", ())] |
|
1749 |
if var_name: |
|
1750 |
program += [(var_name, (self.TagName, variable_type, var_number, "name")), |
|
1751 |
(" ", ())] |
|
1743
c3c3d1318130
clean-up: fix PEP8 E711 comparison to None should be 'if cond is not None:'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1742
diff
changeset
|
1752 |
if var_address is not None: |
814 | 1753 |
program += [("AT ", ()), |
1754 |
(var_address, (self.TagName, variable_type, var_number, "location")), |
|
1755 |
(" ", ())] |
|
1756 |
program += [(": ", ()), |
|
1757 |
(var_type, (self.TagName, variable_type, var_number, "type"))] |
|
1743
c3c3d1318130
clean-up: fix PEP8 E711 comparison to None should be 'if cond is not None:'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1742
diff
changeset
|
1758 |
if var_initial is not None: |
814 | 1759 |
program += [(" := ", ()), |
1760 |
(self.ParentGenerator.ComputeValue(var_initial, var_type), (self.TagName, variable_type, var_number, "initial value"))] |
|
1761 |
program += [(";\n", ())] |
|
1762 |
var_number += 1 |
|
1763 |
program += [(" END_VAR\n", ())] |
|
1764 |
program += [("\n", ())] |
|
1765 |
program += self.Program |
|
1734
750eeb7230a1
clean-up: fix some PEP8 E228 missing whitespace around modulo operator
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1730
diff
changeset
|
1766 |
program += [("END_%s\n\n" % self.Type, ())] |
814 | 1767 |
return program |
1768 |
||
1736
7e61baa047f0
clean-up: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents:
1734
diff
changeset
|
1769 |
|
3704
c17fac18c663
ST code generator: when including PLCopen TC6 XML libraries (for example py_ext/pous.xml or NativeLib.xml), also includes libraries globals in result
Edouard Tisserant
parents:
2727
diff
changeset
|
1770 |
def GenerateCurrentProgram(controler, project, errors, warnings, **kwargs): |
814 | 1771 |
generator = ProgramGenerator(controler, project, errors, warnings) |
2727
6330e6bb345d
IDE: Make ST code generation more verbose, since it can be really long in case of big programs, and it is better to let the user know build is still in progress.
Edouard Tisserant
parents:
2633
diff
changeset
|
1772 |
if hasattr(controler, "logger"): |
6330e6bb345d
IDE: Make ST code generation more verbose, since it can be really long in case of big programs, and it is better to let the user know build is still in progress.
Edouard Tisserant
parents:
2633
diff
changeset
|
1773 |
def log(txt): |
6330e6bb345d
IDE: Make ST code generation more verbose, since it can be really long in case of big programs, and it is better to let the user know build is still in progress.
Edouard Tisserant
parents:
2633
diff
changeset
|
1774 |
controler.logger.write(" "+txt+"\n") |
6330e6bb345d
IDE: Make ST code generation more verbose, since it can be really long in case of big programs, and it is better to let the user know build is still in progress.
Edouard Tisserant
parents:
2633
diff
changeset
|
1775 |
else: |
6330e6bb345d
IDE: Make ST code generation more verbose, since it can be really long in case of big programs, and it is better to let the user know build is still in progress.
Edouard Tisserant
parents:
2633
diff
changeset
|
1776 |
def log(txt): |
6330e6bb345d
IDE: Make ST code generation more verbose, since it can be really long in case of big programs, and it is better to let the user know build is still in progress.
Edouard Tisserant
parents:
2633
diff
changeset
|
1777 |
pass |
6330e6bb345d
IDE: Make ST code generation more verbose, since it can be really long in case of big programs, and it is better to let the user know build is still in progress.
Edouard Tisserant
parents:
2633
diff
changeset
|
1778 |
|
3704
c17fac18c663
ST code generator: when including PLCopen TC6 XML libraries (for example py_ext/pous.xml or NativeLib.xml), also includes libraries globals in result
Edouard Tisserant
parents:
2727
diff
changeset
|
1779 |
generator.GenerateProgram(log,**kwargs) |
814 | 1780 |
return generator.GetGeneratedProgram() |