Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#!/bin/sh
# File/Project has to be the last argument
FILE=${@:$#}
PROJECT_NAME=$(echo "${FILE##*/}" | sed 's/\.[^.]*$//')
SCRIPT=$(readlink -f "$0")
SILECS_VERSION=2.2.0
SILECS_BASE=/common/usr/cscofe/silecs
FESA_VERSION=7.3.0
FESA_BASE=/opt/fesa/fesa-fwk/$FESA_VERSION
N_ARGUMENTS=$#
function help {
echo -e ""
echo -e "Usage: silecs [OPTION] [FILE]"
echo -e ""
echo -e "Script in order to model PLC devices in FESA by using the Silecs framework."
echo -e ""
echo -e "\t -c \t create new .silecsdesign/.silecsdeploy file for the specified FESA .design/.deploy file"
echo -e "\t -v \t validate silecs xml file"
echo -e "\t -g \t generate source code for silecs xml file"
echo -e "\t -d \t start diagnostic tool for silecs xml file"
echo -e "\t -r \t release parameter file to FEC (TODO)"
echo -e "\t -m \t migrate silecs design/deploy file to new silecs version (TODO)"
echo -e "\t -h \t show this help"
echo -e ""
echo -e "Examples:"
echo -e ""
echo -e "\t To create a new file 'MyClass.silecsdesign' for the FESA class."
echo -e "\t\t silces -c ~/workspace/MyClass/src/MyClass.design"
echo -e ""
echo -e "\t To validate 'MyClass.silecsdesign'."
echo -e "\t\t silces -v ~/workspace/MyClass/src/MyClass.silecsdesign"
echo -e ""
echo -e "\t To add missing properties and value-items specified in 'MyClass.silecsdesign' into the FESA document 'MyClass.design'."
echo -e "\t This will as well ate C++ code."
echo -e "\t\t silces -g ~/workspace/MyClass/src/MyClass.silecsdesign"
echo -e ""
echo -e "Check the Silecs Wiki for more info: https://www-acc.gsi.de/wiki/Frontend/SILECS"
echo -e ""
exit 1;
}
if [ $N_ARGUMENTS -lt 1 ]
then
echo "Error: Wrong number of arguments supplied."
help
fi
function assert_n_arguments {
if [ $N_ARGUMENTS -lt $1 ]
then
echo "Error: Wrong number of arguments supplied."
help
fi
}
function silecs_validate {
assert_n_arguments 2
EXTENSION=$(echo "$FILE" | sed 's/^.*\.//')
# Resolve possible relative path
FILE=$(realpath "$FILE" )
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
case $EXTENSION in
silecsdesign)
SCHEMA=$SILECS_BASE/silecs-model/$SILECS_VERSION/xml/DesignSchema.xsd
;;
silecsdeploy)
SCHEMA=$SILECS_BASE/silecs-model/$SILECS_VERSION/xml/DeploySchema.xsd
;;
*)
echo "Error: Passed file for validation needs to have the extension '.silecsdesign' or '.silecsdeploy'"
exit 1
;;
esac
echo "validating $FILE"
echo ""
xmllint --schema $SCHEMA $FILE --noout
RESULT=$?
echo ""
if [ $RESULT -eq 0 ]
then
echo "File is valid"
else
echo "File is not valid. Check errors above."
fi
return $RESULT
# TODO: Implement jave-rules - See here for details: https://gitlab.com/al.schwinn/silecs-cli/-/issues/3
}
function execute_python {
PYTHON_FILE=$1
PYTHON_METHOD=$2
SILECS_CODEGEN_BASE=$SILECS_BASE/silecs-codegen/$SILECS_VERSION/xml/
SILECS_CODEGEN_MIGRATION=$SILECS_BASE/silecs-codegen/$SILECS_VERSION/xml/migration
# TODO: Check for concrete fesa version - See here for details: https://gitlab.com/al.schwinn/silecs-cli/-/issues/4
SILECS_CODEGEN_FESA=$SILECS_BASE/silecs-codegen/$SILECS_VERSION/xml/fesa/fesa_7_3_0/
ARGUMENTS=""
for ((i=3; i<=$#; i++))
do
ARGUMENTS+="'"
ARGUMENTS+=${!i}
ARGUMENTS+="'"
if [ $i -ne $# ]
then
ARGUMENTS+=","
fi
done
#echo $ARGUMENTS
python3 -c "import sys;\
sys.path.append('$SILECS_CODEGEN_BASE');\
sys.path.append('$SILECS_CODEGEN_MIGRATION');\
sys.path.append('$SILECS_CODEGEN_FESA');\
import $PYTHON_FILE;\
$PYTHON_FILE.$PYTHON_METHOD($ARGUMENTS);"
return $?
}
function silecs_generate {
assert_n_arguments 2
silecs_validate
if [ $? -ne 0 ]; then
echo ""
echo "Error: $FILE is not valid. Please fix all xml errors before generating code !"
exit 1
fi
# Resolve possible relative path
FILE=$(realpath "$FILE" )
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
EXTENSION=$(echo "$FILE" | sed 's/^.*\.//')
case $EXTENSION in
silecsdesign)
silecs_generate_silecsdesign
;;
silecsdeploy)
silecs_generate_silecsdeploy
;;
*)
echo "Error: Passed file for code generation needs to have the exctension '.silecsdesign' or '.silecsdeploy'"
exit 1
;;
esac
}
function silecs_generate_silecsdesign {
SILECS_DESIGN_FILE=$FILE
PROJECT_PATH=$(dirname "$(dirname "$FILE")")
WORKSPACE_PATH=$(dirname "$PROJECT_PATH")
SILECS_LIBRARY_BASE=$SILECS_BASE/silecs-communication-cpp/$SILECS_VERSION
FESA_DESIGN_FILE=$PROJECT_PATH/src/$PROJECT_NAME.design
FESA_XSD=$FESA_BASE/fesa-model-gsi/xml/design/design-gsi.xsd
echo "generating code for $PROJECT_NAME ..."
echo ""
if [ -f $FESA_DESIGN_FILE ];
then
echo "Please note that old, obsolete xml-elements are not deleted automatically! Sometimes this can lead to an invalid FESA Design document!"
echo "If this is the case, please remove the obsolete elements by hand."
echo "Creating a backup of the existing FESA file at: $FESA_DESIGN_FILE.backup"
echo ""
cp $FESA_DESIGN_FILE $FESA_DESIGN_FILE.backup
fi
execute_python generateFesaDesign fillDesignFile $FESA_VERSION $PROJECT_NAME $WORKSPACE_PATH $FESA_XSD
execute_python generateSourceCode genCppFiles $PROJECT_NAME $WORKSPACE_PATH $SILECS_DESIGN_FILE
echo ""
echo "Please not that you need to add the dependency to the silecs library to your Makefile."
echo "Here an example: https://www-acc.gsi.de/wiki/Frontend/Silecs_1_0_0_CodeSnippets#Dependency_in_Makefile.specific !"
echo ""
echo "Code generation finished"
}
function silecs_generate_silecsdeploy {
SILECS_DEPLOY_FILE=$FILE
PROJECT_PATH=$(dirname "$(dirname "$FILE")")
WORKSPACE_PATH=$(dirname "$PROJECT_PATH")
SILECS_LIBRARY_BASE=$SILECS_BASE/silecs-communication-cpp/$SILECS_VERSION
FESA_DEPLOY_FILE=$PROJECT_PATH/src/$PROJECT_NAME.deploy
FESA_XSD=$FESA_BASE/fesa-model-gsi/xml/deployment/deployment-gsi.xsd
FESA_GSI_TEMPLATE=$FESA_BASE/fesa-model-gsi/xml/design/templates/GSIClassTemplate.xml
SILECS_DEPLOY_VERSION="unused_parameter"
echo "generating code for $PROJECT_NAME ..."
echo ""
if [ -f $FESA_DESIGN_FILE ];
then
echo "Please note that old, obsolete xml-elements are not deleted automatically! Sometimes this can lead to an invalid FESA document!"
echo "If this is the case, please remove the obsolete elements by hand."
echo "Creating a backup of the existing FESA file at: $FESA_DEPLOY_FILE.backup"
echo ""
cp $FESA_DEPLOY_FILE $FESA_DEPLOY_FILE.backup
fi
execute_python genparam genParam $WORKSPACE_PATH $PROJECT_NAME $SILECS_DEPLOY_VERSION $SILECS_VERSION
execute_python genplcsrc genPlcSrc $WORKSPACE_PATH $PROJECT_NAME $SILECS_VERSION
execute_python genduwrapper genDuWrapper $WORKSPACE_PATH $PROJECT_NAME $SILECS_DEPLOY_VERSION
execute_python fillFESADeployUnit fillDeployUnit $WORKSPACE_PATH $PROJECT_NAME $FESA_XSD $FESA_VERSION
echo ""
echo "Please not that you need to add the dependency to the silecs library to your Makefile."
echo "Here an example: https://www-acc.gsi.de/wiki/Frontend/Silecs_1_0_0_CodeSnippets#Dependency_in_Makefile.specific !"
echo ""
echo "Code generation finished"
}
function silecs_create_design {
NEWFILEPATH=$1
DATE=$(date +%x)
SCHEMA_PATH=$SILECS_BASE/silecs-model/$SILECS_VERSION/xml/DesignSchema.xsd
DESIGN_TEMPLATE='<?xml version="1.0" encoding="UTF-8"?>
<SILECS-Design silecs-version="'$SILECS_VERSION'" created="'$DATE'" updated="'$DATE'"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="'$SCHEMA_PATH'">
<Information>
<Owner user-login="'$USER'"/>
<Editor user-login="'$USER'"/>
</Information>
<SILECS-Class name="'$PROJECT_NAME'" version="0.1.0" domain="OPERATIONAL" >
<Acquisition-Block name="MyBlock" generateFesaProperty="true">
<Acquisition-Register name="myRegister" generateFesaValueItem="true">
<scalar format="int32"/>
</Acquisition-Register>
</Acquisition-Block>
</SILECS-Class>
</SILECS-Design>'
if [ -f $NEWFILEPATH ]; then
echo "Error: There is already a .silecsdesign file available: $NEWFILEPATH"
exit 1
fi
echo $DESIGN_TEMPLATE | xmllint --format - > $NEWFILEPATH
echo ""
echo "created new silecsdesign: $NEW_FILE"
}
function silecs_create_deploy {
NEWFILEPATH=$1
DATE=$(date +%x)
SCHEMA_PATH=$SILECS_BASE/silecs-model/$SILECS_VERSION/xml/DeploySchema.xsd
DEPLOY_TEMPLATE='<?xml version="1.0" encoding="UTF-8"?>
<SILECS-Deploy silecs-version="'$SILECS_VERSION'" created="'$DATE'" updated="'$DATE'"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="'$SCHEMA_PATH'">
<Information>
<Owner user-login="'$USER'"/>
<Editor user-login="'$USER'"/>
</Information>
<Deploy-Unit name="'$PROJECT_NAME'" version="0.1.0"/>
<SilecsDesign silecs-design-name="" silecs-design-version=""/>
<Controller host-name="">
<Siemens-PLC system="TIA-PORTAL" model="SIMATIC_S7-300" protocol="DEVICE_MODE" base-DB-number="1">
<Device silecs-device-label="dev0" silecs-design-ref="" fesa-device-name="" fesa-fec-name=""/>
</Siemens-PLC>
</Controller>
</SILECS-Deploy>'
if [ -f $NEWFILEPATH ]; then
echo "Error: There is already a .silecsdeploy file available: $NEWFILEPATH"
exit 1
fi
echo $DEPLOY_TEMPLATE | xmllint --format - > $NEWFILEPATH
echo ""
echo "created new silecsdeploy: $NEW_FILE"
}
function silecs_create {
assert_n_arguments 2
# Resolve possible relative path
FILE=$(realpath "$FILE" )
EXTENSION=$(echo "$FILE" | sed 's/^.*\.//')
FILE_PATH=$(dirname "$FILE")
case $EXTENSION in
design)
NEW_FILE=$FILE_PATH/$PROJECT_NAME.silecsdesign
silecs_create_design $NEW_FILE
;;
deploy)
NEW_FILE=$FILE_PATH/$PROJECT_NAME.silecsdeploy
silecs_create_deploy $NEW_FILE
;;
*)
echo "Error: Passed FESA file needs to have the extension '.design' or '.deploy'"
exit 1
;;
esac
}
function silecs_open_diag {
assert_n_arguments 2
# Resolve possible relative path
FILE=$(realpath "$FILE" )
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
EXTENSION=$(echo "$FILE" | sed 's/^.*\.//')
if [ $EXTENSION -ne "silecsdeploy"]; then
echo "Error: diag tool only can be opened for a -silecsdeploy file"
fi
SILECS_DIAG_TOOL=$SILECS_BASE/silecs-diagnostic-cpp/$SILECS_VERSION/bin/x86_64/silecs-diagnostic
SNAP7_LIB_FOLDER=$SILECS_BASE/snap7/$SILECS_VERSION/bin/x86_64-linux
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$SNAP7_LIB_FOLDER
$SILECS_DIAG_TOOL -d $FILE
}
function silecs_release_param {
# TODO - See here for details: https://gitlab.com/al.schwinn/silecs-cli/-/issues/5
echo "Not implemented yet .. please copy the param file by hand for now"
}
function silecs_migrate {
# TODO - See here for details: https://gitlab.com/al.schwinn/silecs-cli/-/issues/7
echo "Not implemented yet .. please update/migrate by hand for now"
}
while getopts c:v:g:d:r:m:h flag
do
case "${flag}" in
c ) silecs_create;;
v ) silecs_validate;;
g ) silecs_generate;;
d ) silecs_open_diag;;
r ) silecs_release_param;;
m ) silecs_migrate;;
h ) help;;
esac
done