Modular Application Creator Use Case Based Documentation
Loading...
Searching...
No Matches
GenericBlockCreation.cs
1using System;
2using System.IO;
3using System.Linq;
4using MAC_use_cases.TiaImports;
5using Siemens.Automation.ModularApplicationCreator.Tia.Helper;
6using Siemens.Automation.ModularApplicationCreator.Tia.Helper.Create_XML_Block;
7using Siemens.Automation.ModularApplicationCreator.Tia.Helper.Create_XML_Block.XmlBlocks.BlockFrames;
8using Siemens.Automation.ModularApplicationCreator.Tia.Openness;
9using Siemens.Automation.ModularApplicationCreator.Tia.Openness.SoftwareUnit;
10using Siemens.Automation.ModularApplicationCreator.Tia.TiaAttributeFuncs;
11using ProgrammingLanguage =
12 Siemens.Automation.ModularApplicationCreator.Tia.Helper.Create_XML_Block.ProgrammingLanguage;
13
15
20{
24 public static string ParameterName = "myParameterName";
25
52 public static void CreateFunctionBlock(string blockName, string instanceDbName,
53 ProgrammingLanguage programmingLanguage,
54 PlcDevice plcDevice)
55 {
56 // Input validation
57 if (string.IsNullOrEmpty(blockName))
58 {
59 throw new ArgumentNullException(nameof(blockName));
60 }
61
62 if (string.IsNullOrEmpty(instanceDbName))
63 {
64 throw new ArgumentNullException(nameof(instanceDbName));
65 }
66
67 if (plcDevice == null)
68 {
69 throw new ArgumentNullException(nameof(plcDevice));
70 }
71
72 if (programmingLanguage != ProgrammingLanguage.LAD && programmingLanguage != ProgrammingLanguage.FBD &&
73 programmingLanguage != ProgrammingLanguage.SCL)
74 {
75 throw new ArgumentException(nameof(programmingLanguage));
76 }
77
78 // Create block call with default values
79 var fbCall = new BlockCall(instanceDbName, plcDevice) { ["Input1"] = "1", ["Input2"] = "0" };
80
81 // Create and configure network
82 var fbNetwork = new BlockNetwork { NetworkTitles = { [TypeMapper.BaseCulture.Name] = "myFB Network Title" } };
83 fbNetwork.Blocks.Add(fbCall);
84
85 // Create and Configure FB properties
86 var fb = new XmlFB(blockName);
87 fb.Networks.Add(fbNetwork);
88 fb.BlockAttributes.ProgrammingLanguage = programmingLanguage;
89 fb.BlockComments[TypeMapper.BaseCulture.Name] = "myFB Block Comment";
90 fb.BlockTitles[TypeMapper.BaseCulture.Name] = "myFB Block Title";
91
92 // Generate the block in appropriate format
93 if (programmingLanguage == ProgrammingLanguage.SCL)
94 {
95 fb.GenerateSclBlock(plcDevice);
96 }
97 else
98 {
99 fb.GenerateXmlBlock(plcDevice);
100 }
101 }
102
128 public static void CreateFailSafeFunctionBlock(string blockName, string instanceDbName,
129 ProgrammingLanguage programmingLanguage,
130 PlcDevice plcDevice)
131 {
132 // Input validation
133 if (string.IsNullOrEmpty(blockName))
134 {
135 throw new ArgumentNullException(nameof(blockName));
136 }
137
138 if (string.IsNullOrEmpty(instanceDbName))
139 {
140 throw new ArgumentNullException(nameof(instanceDbName));
141 }
142
143 if (plcDevice == null)
144 {
145 throw new ArgumentNullException(nameof(plcDevice));
146 }
147
148 if (programmingLanguage != ProgrammingLanguage.F_LAD && programmingLanguage != ProgrammingLanguage.F_FBD)
149 {
150 throw new ArgumentException(nameof(programmingLanguage));
151 }
152
153 // Create block call with default values
154 var fbCall = new BlockCall(instanceDbName, plcDevice) { ["Input1"] = "1", ["Input2"] = "0" };
155
156 // Create and configure network
157 var fbNetwork = new BlockNetwork { NetworkTitles = { [TypeMapper.BaseCulture.Name] = "myFB Network Title" } };
158 fbNetwork.Blocks.Add(fbCall);
159
160 //Create and configure FB properties
161 var failSafeBlock = new XmlFailSafeFB(blockName);
162 failSafeBlock.Networks.Add(fbNetwork);
163 failSafeBlock.BlockAttributes.ProgrammingLanguage = programmingLanguage;
164 failSafeBlock.BlockComments[TypeMapper.BaseCulture.Name] = "myFB Block Comment";
165 failSafeBlock.BlockTitles[TypeMapper.BaseCulture.Name] = "myFB Block Title";
166
167 // Generate the block in appropriate format
168 failSafeBlock.GenerateXmlBlock(plcDevice, programmingLanguage);
169 }
170
171
180 public static XmlGlobalDB GenerateGlobalDataBlock(string dbName, PlcDevice plcDevice, MAC_use_casesEM module)
181 {
182 var dataBlock = new XmlGlobalDB(dbName);
183 var itf = dataBlock.Interface[InterfaceSections.Static];
184
185 //Create new parameters. The custom parameter means you are using your own user defined data type.
186 var standardParam = new InterfaceParameter(ParameterName, "Int");
187 var customParam1 = new InterfaceParameter("var_struct", "Struct");
188 customParam1.SubParameter.Add(new InterfaceParameter("Var1", "Bool"));
189 customParam1.SubParameter.Add(new InterfaceParameter("Var2", "Int"));
190 var customParam2 = new InterfaceParameter("datatyp_from_lib", "\"" + "myDataType" + "\"");
191
192 //Add your parameters
193 itf.Add(standardParam);
194 itf.Add(customParam1);
195 itf.Add(customParam2);
196
197 dataBlock.GenerateXmlBlock(plcDevice);
198 return dataBlock;
199 }
200
222 public static void CreateFunctionBlockInSoftwareUnit(ISoftwareUnitBase softwareUnitBase, string fbName,
223 ProgrammingLanguage programmingLanguage)
224 {
225 var fb = new XmlFB(fbName);
226
227 fb.Interface[InterfaceSections.Input].Add(new InterfaceParameter("Input_1", "Bool")
228 {
229 Remanence = RemanenceSettings.IgnoreRemanence
230 });
231 fb.Interface[InterfaceSections.Input].Add(new InterfaceParameter("Input_2", "Bool")
232 {
233 Remanence = RemanenceSettings.IgnoreRemanence
234 });
235 fb.Interface[InterfaceSections.Output].Add(new InterfaceParameter("Output", "Bool")
236 {
237 Remanence = RemanenceSettings.IgnoreRemanence
238 });
239
240
241 //here an example how to create a multi instance call in the function block
242 fb.GenerateXmlBlock(softwareUnitBase, programmingLanguage);
243 }
244
252 private static void GenerateBlock(string code, PlcDevice targetDevice, ITarget targetContainer = null,
253 bool isScl = true)
254 {
255 //Get the right file extension depending on the block language
256 var extension = ".scl";
257 if (!isScl)
258 {
259 extension = ".xml";
260 }
261
262 //Create a temporary file
263 var filePath = Path.ChangeExtension(Path.GetTempFileName(), extension);
264
265 //Write the code to this file
266 File.WriteAllText(filePath, code);
267
268 //Create the block on the plc using the file
269 var block = OpennessFuncs.ImportBlockToPlc(filePath, targetDevice, targetContainer);
270
271 //Delete the file
272 File.Delete(filePath);
273 }
274
284 public static void SetDefaultValue(string dbName, string parameterName, TIATYPE dataType, string value,
285 MAC_use_casesEM parent)
286 {
287 var myParameterNameAttribute = TiaAttributeProvider.CreateAttribute(dataType, SOURCETYPE.BLOCKVAR,
288 dbName, parameterName, parent);
289 myParameterNameAttribute.Value = value;
290 }
291
299 public static void GenerateMultiInstanceFB(PlcDevice plcDevice, string languageSettings, MAC_use_casesEM module)
300 {
301 var myFb = new XmlFB("MyFunctionBlock_MultiInstance")
302 {
303 BlockAttributes = { ProgrammingLanguage = ProgrammingLanguage.LAD }
304 };
305
306 var multiInstanceDataBlockName = myFb.Name + "_Instance";
307 var myMultiInstanceFbCall =
308 new MultiInstanceCall(multiInstanceDataBlockName, module.ResourceManagement.MyFunctionBlock.Name, plcDevice)
309 {
310 ["Input1"] = "1", // inputVariable1
311 ["Input2"] = "0" // inputVariable1
312 };
313
314 //manipulate interface
315 var interfaceParameters = myFb.Interface[InterfaceSections.Static];
316
317 //Create new parameters. The custom parameter means you are using your own user defined data type.
318 var customParam =
319 new InterfaceParameter(multiInstanceDataBlockName,
320 module.ResourceManagement.MyFunctionBlock.Name) { Remanence = RemanenceSettings.IgnoreRemanence };
321
322 //Add your parameters
323 interfaceParameters.Add(customParam);
324
325 var networkMultiInstance = new BlockNetwork();
326 networkMultiInstance.Blocks.Add(myMultiInstanceFbCall);
327 networkMultiInstance.GenerationLabel =
328 new GenerationLabel(module.Name, "Generated by MAC", module.ModuleID.ToString());
329 myFb.Networks.Add(networkMultiInstance);
330 AddCodeBlockToOB(myFb, module.ResourceManagement, languageSettings, plcDevice);
331 }
332
341 public static void GenerateOB_Main(string instanceDbName, MAC_use_casesEM module, string languageSettings,
342 PlcDevice plcDevice)
343 {
344 var mainOb = new XmlOB("Main");
345 mainOb.BlockAttributes.ProgrammingLanguage = ProgrammingLanguage.LAD;
346 ((OB_BlockAttributes)mainOb.BlockAttributes).BlockSecondaryType = "ProgramCycle";
347
348 var itf = mainOb.Interface[InterfaceSections.Temp];
349 var temp = new InterfaceParameter("Temp", "Bool");
350 var tempInt = new InterfaceParameter("TempInt", "Int");
351 itf.Add(temp);
352 itf.Add(tempInt);
353
354 //create block call of instance DB
355 var myFBCall = new BlockCall(instanceDbName, plcDevice)
356 {
357 ["Input1"] = "#Temp", // inputVariable1
358 ["Input2"] = "0" // inputVariable1
359 //["Input2"] = "inputVariable1",
360
361 //["Output1"] = "outputVariable1",
362 };
363 var blockNetwork = new BlockNetwork();
364 blockNetwork.Blocks.Add(myFBCall);
365 blockNetwork.GenerationLabel =
366 new GenerationLabel(module.Name, "Generated by MAC", module.ModuleID.ToString());
367 mainOb.Networks.Add(blockNetwork);
368
370 var content = "\"MyDataBlock_Global\".myParameterName := 100;\n";
371 content += "IF #Temp THEN\n";
372 content += "#TempInt := 5;\n";
373 content += "ELSE\n";
374 content += "TempInt := 1;\n";
375 content += "END_IF;\n\n";
376 var sclContent = content;
377 var sclcode_network = ParseSingleSCLCall(sclContent, plcDevice, mainOb);
378 sclcode_network.GenerationLabel =
379 new GenerationLabel(module.Name, "Virtual_Master_scl_code", module.ModuleID.ToString());
380 mainOb.Networks.Add(sclcode_network);
381
382 AddCodeBlockToOB(mainOb, module.ResourceManagement, languageSettings, plcDevice);
383 }
384
393 public static void AddCodeBlockToOB(XmlLogicalBlock codeBlock, ResourceManagement resourceManagement,
394 string languageSettings, PlcDevice plcDevice)
395 {
396 var existingOB = OpennessFuncs.TryGetOBFromPlcDevice(plcDevice, codeBlock.Name);
397 //Create new OB in SCL with calling code
398 if (existingOB == null)
399 {
400 if (codeBlock.BlockAttributes.ProgrammingLanguage == ProgrammingLanguage.SCL)
401 {
402 codeBlock.GenerateSclBlock(plcDevice);
403 }
404 else //insert networks to KOP/FUP
405 {
406 codeBlock.GenerateXmlBlock(plcDevice, null, languageSettings);
407 }
408 }
409 else
410 //Insert Code to existing OB
411 {
412 var blockAsDoc =
413 OpennessFuncs.ExportBlockAsXml(existingOB.Name, plcDevice, OpennessFuncs.CachingOptions.DISABLED);
414 var parser = new Parser();
415 var xmlOB = parser.ParseXml(blockAsDoc);
416 xmlOB.MergeBlock(codeBlock);
417 //add SCL-Code
418 if (xmlOB.BlockAttributes.ProgrammingLanguage == ProgrammingLanguage.SCL)
419 {
420 xmlOB.GenerateSclBlock(plcDevice);
421 }
422 else //insert networks to KOP/FUP
423 {
424 xmlOB.GenerateXmlBlock(plcDevice, null, languageSettings);
425 }
426 }
427 }
428
438 public static void GenerateOBWithMultipleCalls(string name, int numberOfCalls, string languageSettings,
439 PlcDevice plcDevice, MAC_use_casesEM module)
440 {
441 var myOb = new XmlOB(name);
442 myOb.BlockAttributes.BlockAutoNumber = false;
443 myOb.BlockAttributes.BlockNumber = 555.ToString();
444
445 for (var i = 1; i <= numberOfCalls; i++)
446 {
447 var blockName = $"{nameof(module.ResourceManagement.MyFunctionBlock)}DB" + i;
448 IntegrateLibraries.CreateInstanceDataBlock(module, module.ResourceManagement.MyFunctionBlock,
449 blockName, module.ResourceManagement.ModuleBlocksRootGroup);
450 var myOBCall = new BlockCall(blockName, plcDevice)
451 {
452 ["Input1"] = "1", // inputVariable1
453 ["Input2"] = "0" // inputVariable1
454 };
455
456 var myObBlockNetwork = new BlockNetwork();
457 myObBlockNetwork.Blocks.Add(myOBCall);
458 myObBlockNetwork.GenerationLabel = new GenerationLabel(blockName,
459 "Generated by MAC. Blockname: \"" + blockName + "\"", module.ModuleID.ToString());
460 myOb.Networks.Add(myObBlockNetwork);
461 }
462
463 AddCodeBlockToOB(myOb, module.ResourceManagement, languageSettings, plcDevice);
464 }
465
466 private static INetwork ParseSingleSCLCall(string sclCall, PlcDevice plc, XmlBlock xmlBlock)
467 {
468 var parsed = new Parser().ParseSclSnippet(sclCall, xmlBlock, plc, GroupBlockCalls.NOGROUPING)
469 .FirstOrDefault();
470 if (parsed is BlockNetwork blockNetwork)
471 {
472 return blockNetwork;
473 }
474
475 if (parsed is FixNetwork fixNetwork)
476 {
477 return fixNetwork;
478 }
479
480 return null;
481 }
482}
This is the main class in which the workflow starts. Here are all sections for creating or generating...
All the functions to configure and generate Blocks are defined here.
static XmlGlobalDB GenerateGlobalDataBlock(string dbName, PlcDevice plcDevice, MAC_use_casesEM module)
This function creates a Data Block with interface (sub-)parameters in a desired folder....
static void GenerateMultiInstanceFB(PlcDevice plcDevice, string languageSettings, MAC_use_casesEM module)
This function creates an multiInstanceFB.
static void SetDefaultValue(string dbName, string parameterName, TIATYPE dataType, string value, MAC_use_casesEM parent)
This function sets the default value of a parameter in a DB.
static void CreateFunctionBlockInSoftwareUnit(ISoftwareUnitBase softwareUnitBase, string fbName, ProgrammingLanguage programmingLanguage)
Creates a new Function Block (FB) within the specified software unit with predefined interface parame...
static void GenerateOB_Main(string instanceDbName, MAC_use_casesEM module, string languageSettings, PlcDevice plcDevice)
This function generates an OB and creates a block call in FBD and SCL.
static string ParameterName
This is the name of the generated parameter.
static void CreateFailSafeFunctionBlock(string blockName, string instanceDbName, ProgrammingLanguage programmingLanguage, PlcDevice plcDevice)
Creates a Fail-Safe Function Block (F-FB) in the target PLC's program blocks folder.
static void GenerateOBWithMultipleCalls(string name, int numberOfCalls, string languageSettings, PlcDevice plcDevice, MAC_use_casesEM module)
This function Generates the OB with the given number of calls.
static void CreateFunctionBlock(string blockName, string instanceDbName, ProgrammingLanguage programmingLanguage, PlcDevice plcDevice)
Creates a Function Block (FB) in the target PLC's program blocks folder.
static void AddCodeBlockToOB(XmlLogicalBlock codeBlock, ResourceManagement resourceManagement, string languageSettings, PlcDevice plcDevice)
This function checks if OB is already in TIA Project and merge the new one into the existing one depe...
static void GenerateBlock(string code, PlcDevice targetDevice, ITarget targetContainer=null, bool isScl=true)
This function creates a Block on the targetDevice in the targetContainer (folder under program blocks...
All the functions to configure and generate parts of the library are defined here.
static DataBlock CreateInstanceDataBlock(MAC_use_casesEM module, FBMasterCopy masterCopy, string instanceName, BlockGroup target)
This function creates an instance DB in the target folder (folder under program blocks)