@aryacode/dsh-engineering 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +52 -0
- package/README.md +9 -8
- package/cordis.patch.yml +1 -1
- package/entries/netlogic.js +266 -0
- package/entries/optix.js +13 -0
- package/package.json +10 -10
- package/vendor/l5x/SKILL.md +27 -7
- package/vendor/l5x/lib/engine/change-set.d.ts +9 -1
- package/vendor/l5x/lib/engine/change-set.js +32 -7
- package/vendor/l5x/lib/engine/documentation.d.ts +58 -0
- package/vendor/l5x/lib/engine/documentation.js +237 -0
- package/vendor/l5x/lib/engine/instructions.d.ts +50 -0
- package/vendor/l5x/lib/engine/instructions.js +107 -0
- package/vendor/l5x/lib/engine/ladder.d.ts +74 -0
- package/vendor/l5x/lib/engine/ladder.js +209 -0
- package/vendor/l5x/lib/index.d.ts +1 -0
- package/vendor/l5x/lib/index.js +3 -1
- package/vendor/l5x/lib/model/routines.js +6 -1
- package/vendor/l5x/lib/session.d.ts +20 -0
- package/vendor/l5x/lib/session.js +36 -0
- package/vendor/l5x/lib/tools/document.d.ts +18 -0
- package/vendor/l5x/lib/tools/document.js +119 -0
- package/vendor/l5x/lib/tools/drafts.js +109 -3
- package/vendor/optix/SKILL.md +68 -0
- package/vendor/optix/netlogic/SOURCE.json +12 -0
- package/vendor/optix/netlogic/index.json +1987 -0
- package/vendor/optix/netlogic/pages/accessing-project-nodes.md +113 -0
- package/vendor/optix/netlogic/pages/advanced-svg.md +124 -0
- package/vendor/optix/netlogic/pages/alarming.md +489 -0
- package/vendor/optix/netlogic/pages/async-tasks.md +236 -0
- package/vendor/optix/netlogic/pages/audit-signature.md +91 -0
- package/vendor/optix/netlogic/pages/colors.md +122 -0
- package/vendor/optix/netlogic/pages/companion-specs.md +77 -0
- package/vendor/optix/netlogic/pages/creating-objects.md +370 -0
- package/vendor/optix/netlogic/pages/database-interaction.md +437 -0
- package/vendor/optix/netlogic/pages/datagrids.md +123 -0
- package/vendor/optix/netlogic/pages/debugging-tips.md +605 -0
- package/vendor/optix/netlogic/pages/designtime-tags-import.md +531 -0
- package/vendor/optix/netlogic/pages/dialog-boxes.md +150 -0
- package/vendor/optix/netlogic/pages/dispatch-events.md +200 -0
- package/vendor/optix/netlogic/pages/dynamic-links.md +825 -0
- package/vendor/optix/netlogic/pages/element-access.md +1208 -0
- package/vendor/optix/netlogic/pages/engineering-units.md +298 -0
- package/vendor/optix/netlogic/pages/events.md +340 -0
- package/vendor/optix/netlogic/pages/execute-command.md +202 -0
- package/vendor/optix/netlogic/pages/fto-studio-cli.md +99 -0
- package/vendor/optix/netlogic/pages/good-practices.md +50 -0
- package/vendor/optix/netlogic/pages/information-model.md +89 -0
- package/vendor/optix/netlogic/pages/log-output.md +22 -0
- package/vendor/optix/netlogic/pages/managing-aliases.md +22 -0
- package/vendor/optix/netlogic/pages/manipulate-nodes.md +72 -0
- package/vendor/optix/netlogic/pages/mqtt.md +240 -0
- package/vendor/optix/netlogic/pages/netlogic-lifecycle.md +270 -0
- package/vendor/optix/netlogic/pages/netlogic-overview.md +155 -0
- package/vendor/optix/netlogic/pages/opcua.md +325 -0
- package/vendor/optix/netlogic/pages/plc-tags.md +219 -0
- package/vendor/optix/netlogic/pages/queries.md +1297 -0
- package/vendor/optix/netlogic/pages/random-generation.md +90 -0
- package/vendor/optix/netlogic/pages/recipes.md +375 -0
- package/vendor/optix/netlogic/pages/recipex.md +2383 -0
- package/vendor/optix/netlogic/pages/regex.md +15 -0
- package/vendor/optix/netlogic/pages/register-observers.md +346 -0
- package/vendor/optix/netlogic/pages/reports.md +141 -0
- package/vendor/optix/netlogic/pages/resource-uri.md +308 -0
- package/vendor/optix/netlogic/pages/runtime-tags-import.md +280 -0
- package/vendor/optix/netlogic/pages/serial-port.md +357 -0
- package/vendor/optix/netlogic/pages/sessions.md +58 -0
- package/vendor/optix/netlogic/pages/system-node.md +153 -0
- package/vendor/optix/netlogic/pages/template-library.md +127 -0
- package/vendor/optix/netlogic/pages/threading.md +236 -0
- package/vendor/optix/netlogic/pages/translations.md +417 -0
- package/vendor/optix/netlogic/pages/trends.md +128 -0
- package/vendor/optix/netlogic/pages/ui-animations.md +115 -0
- package/vendor/optix/netlogic/pages/users-groups.md +416 -0
- package/vendor/optix/netlogic/pages/variables-formatting.md +16 -0
- package/vendor/optix/netlogic/pages/variables-interaction.md +557 -0
- package/vendor/optix/netlogic/pages/variables-structure.md +155 -0
|
@@ -0,0 +1,531 @@
|
|
|
1
|
+
# Design time import of PLC tags
|
|
2
|
+
|
|
3
|
+
This feature is only supported for TwinCAT and RA Ethernet/IP drivers, and allows you to programmatically import tags from a PLC project file. This can be useful in scenarios where you have to import a determined set of tags from a large PLC project, or when you want to automate the import process as part of your project setup.
|
|
4
|
+
|
|
5
|
+
> [!NOTE]
|
|
6
|
+
> This feature is only available at DesignTime, so it cannot be used in a running application.
|
|
7
|
+
|
|
8
|
+
## TwinCAT
|
|
9
|
+
|
|
10
|
+
>[!NOTE]
|
|
11
|
+
> This feature is available starting from FactoryTalk Optix 1.7.x
|
|
12
|
+
|
|
13
|
+
To import tags from a TwinCAT PLC, you can use the `TwinCAT` driver. The import process allows you to filter tags based on specific criteria, such as tag name or data type.
|
|
14
|
+
|
|
15
|
+
```csharp
|
|
16
|
+
#region Using directives
|
|
17
|
+
using System;
|
|
18
|
+
using UAManagedCore;
|
|
19
|
+
using OpcUa = UAManagedCore.OpcUa;
|
|
20
|
+
using FTOptix.UI;
|
|
21
|
+
using FTOptix.HMIProject;
|
|
22
|
+
using FTOptix.NativeUI;
|
|
23
|
+
using FTOptix.Retentivity;
|
|
24
|
+
using FTOptix.CoreBase;
|
|
25
|
+
using FTOptix.Core;
|
|
26
|
+
using FTOptix.NetLogic;
|
|
27
|
+
using FTOptix.TwinCAT;
|
|
28
|
+
using FTOptix.CommunicationDriver;
|
|
29
|
+
using static UAManagedCore.TagImporterAPI;
|
|
30
|
+
using System.Threading.Tasks;
|
|
31
|
+
#endregion
|
|
32
|
+
|
|
33
|
+
public class DesignTimeNetLogic1 : BaseNetLogic
|
|
34
|
+
{
|
|
35
|
+
[ExportMethod]
|
|
36
|
+
public void OfflineImport()
|
|
37
|
+
{
|
|
38
|
+
// First get the existing TwinCAT station from the project
|
|
39
|
+
var station = Project.Current.Get<FTOptix.TwinCAT.Station>("CommDrivers/TwinCATDriver1/TwinCATStation1");
|
|
40
|
+
|
|
41
|
+
// Then get the tag importer node from the station
|
|
42
|
+
var tagImporter = station.TagImporter;
|
|
43
|
+
|
|
44
|
+
// Set the file path to the TwinCAT TPY file you want to import
|
|
45
|
+
tagImporter.FilePath = ResourceUri.FromAbsoluteFilePath("D:\\test\\Optix\\Tools\\TwinCAT\\tpy\\AllSimpleType.tpy");
|
|
46
|
+
tagImporter.Mode = FetchMode.Offline;
|
|
47
|
+
|
|
48
|
+
// Fire and forget, import is run in a background thread
|
|
49
|
+
_ = tagImporter.Import();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
[ExportMethod]
|
|
53
|
+
public void OfflineImportWithContinuation()
|
|
54
|
+
{
|
|
55
|
+
var station = Project.Current.Get<FTOptix.TwinCAT.Station>("CommDrivers/TwinCATDriver1/TwinCATStation1");
|
|
56
|
+
var tagImporter = station.TagImporter;
|
|
57
|
+
|
|
58
|
+
tagImporter.FilePath = ResourceUri.FromAbsoluteFilePath("D:\\test\\Optix\\Tools\\TwinCAT\\tpy\\AllSimpleType.tpy");
|
|
59
|
+
tagImporter.Mode = FetchMode.Offline;
|
|
60
|
+
|
|
61
|
+
// Import is started in a background thread,
|
|
62
|
+
// continuation is run in the current thread after the import is completed
|
|
63
|
+
var task = tagImporter.Import(Filter);
|
|
64
|
+
task.ContinueWith((t) =>
|
|
65
|
+
{
|
|
66
|
+
if (t.IsFaulted)
|
|
67
|
+
{
|
|
68
|
+
Log.Error("Import task failed: " + t.Exception?.GetBaseException().Message);
|
|
69
|
+
}
|
|
70
|
+
else if (t.IsCanceled)
|
|
71
|
+
{
|
|
72
|
+
Log.Info("Import task was canceled.");
|
|
73
|
+
}
|
|
74
|
+
else
|
|
75
|
+
{
|
|
76
|
+
Log.Info("Import task completed successfully.");
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
[ExportMethod]
|
|
82
|
+
public void OnlineImport()
|
|
83
|
+
{
|
|
84
|
+
var station = Project.Current.Get<FTOptix.TwinCAT.Station>("CommDrivers/TwinCATDriver1/TwinCATStation1");
|
|
85
|
+
var tagImporter = station.TagImporter;
|
|
86
|
+
|
|
87
|
+
tagImporter.Mode = FetchMode.Online;
|
|
88
|
+
_ = tagImporter.Import(Filter);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
private bool Filter(string tag, string type)
|
|
93
|
+
{
|
|
94
|
+
// Filter by tag name
|
|
95
|
+
return tag.Contains("int");
|
|
96
|
+
|
|
97
|
+
// or
|
|
98
|
+
|
|
99
|
+
// Filter by type
|
|
100
|
+
// return type == "INT";
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
An example of TPY file that can be used for testing:
|
|
106
|
+
|
|
107
|
+
```xml
|
|
108
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
109
|
+
<PlcProjectInfo>
|
|
110
|
+
<ProjectInfo>
|
|
111
|
+
<Path>C:\Users\asem\Desktop\TestTwinCAT\TwinCAT Project1\TwinCAT Project1\Untitled1\Untitled1.plcproj</Path>
|
|
112
|
+
<ChangeDate>2018-02-11T04:39:01</ChangeDate>
|
|
113
|
+
<Library>
|
|
114
|
+
<Name>tc2_standard, 3.3.2.0 (beckhoff automation gmbh)</Name>
|
|
115
|
+
</Library>
|
|
116
|
+
<Library>
|
|
117
|
+
<Name>tc2_system, 3.4.17.0 (beckhoff automation gmbh)</Name>
|
|
118
|
+
</Library>
|
|
119
|
+
<Library>
|
|
120
|
+
<Name>tc3_module, 3.3.17.0 (beckhoff automation gmbh)</Name>
|
|
121
|
+
</Library>
|
|
122
|
+
</ProjectInfo>
|
|
123
|
+
<RoutingInfo>
|
|
124
|
+
<AdsInfo>
|
|
125
|
+
<NetId>172.17.17.35.1.1</NetId>
|
|
126
|
+
<Port>851</Port>
|
|
127
|
+
<TargetName>Untitled1</TargetName>
|
|
128
|
+
</AdsInfo>
|
|
129
|
+
</RoutingInfo>
|
|
130
|
+
<CompilerInfo>
|
|
131
|
+
<CpuFamily>Intel X86</CpuFamily>
|
|
132
|
+
<CompilerVersion>3.5.10.20</CompilerVersion>
|
|
133
|
+
<TwinCATVersion>3.4.0.0</TwinCATVersion>
|
|
134
|
+
<TCatPlcCtrlVersion>3.4.0.0</TCatPlcCtrlVersion>
|
|
135
|
+
</CompilerInfo>
|
|
136
|
+
<TargetInfo>
|
|
137
|
+
<CpuFamily>Intel X86</CpuFamily>
|
|
138
|
+
<DataAreaInfo>
|
|
139
|
+
<DataSize>10485760</DataSize>
|
|
140
|
+
<RetainSize>128000</RetainSize>
|
|
141
|
+
<MAreaSize>128000</MAreaSize>
|
|
142
|
+
<InputSize>128000</InputSize>
|
|
143
|
+
<OutputSize>128000</OutputSize>
|
|
144
|
+
</DataAreaInfo>
|
|
145
|
+
</TargetInfo>
|
|
146
|
+
<DataTypes>
|
|
147
|
+
</DataTypes>
|
|
148
|
+
<Symbols>
|
|
149
|
+
<Symbol>
|
|
150
|
+
<Name>MAIN.VarBit</Name>
|
|
151
|
+
<Type>BIT</Type>
|
|
152
|
+
<IGroup>16448</IGroup>
|
|
153
|
+
<IOffset>512508</IOffset>
|
|
154
|
+
<BitSize>8</BitSize>
|
|
155
|
+
</Symbol>
|
|
156
|
+
<Symbol>
|
|
157
|
+
<Name>MAIN.VarDateAndTime</Name>
|
|
158
|
+
<Type>DATE_AND_TIME</Type>
|
|
159
|
+
<IGroup>16448</IGroup>
|
|
160
|
+
<IOffset>512512</IOffset>
|
|
161
|
+
<BitSize>32</BitSize>
|
|
162
|
+
</Symbol>
|
|
163
|
+
<Symbol>
|
|
164
|
+
<Name>MAIN.VarLTime</Name>
|
|
165
|
+
<Type>LTIME</Type>
|
|
166
|
+
<IGroup>16448</IGroup>
|
|
167
|
+
<IOffset>512520</IOffset>
|
|
168
|
+
<BitSize>64</BitSize>
|
|
169
|
+
</Symbol>
|
|
170
|
+
<Symbol>
|
|
171
|
+
<Name>MAIN.VarTime</Name>
|
|
172
|
+
<Type>TIME</Type>
|
|
173
|
+
<IGroup>16448</IGroup>
|
|
174
|
+
<IOffset>512528</IOffset>
|
|
175
|
+
<BitSize>32</BitSize>
|
|
176
|
+
</Symbol>
|
|
177
|
+
<Symbol>
|
|
178
|
+
<Name>MAIN.VarTod</Name>
|
|
179
|
+
<Type>TOD</Type>
|
|
180
|
+
<IGroup>16448</IGroup>
|
|
181
|
+
<IOffset>512532</IOffset>
|
|
182
|
+
<BitSize>32</BitSize>
|
|
183
|
+
</Symbol>
|
|
184
|
+
<Symbol>
|
|
185
|
+
<Name>MAIN.VarDate</Name>
|
|
186
|
+
<Type>DATE</Type>
|
|
187
|
+
<IGroup>16448</IGroup>
|
|
188
|
+
<IOffset>512536</IOffset>
|
|
189
|
+
<BitSize>32</BitSize>
|
|
190
|
+
</Symbol>
|
|
191
|
+
<Symbol>
|
|
192
|
+
<Name>MAIN.VarDT</Name>
|
|
193
|
+
<Type>DT</Type>
|
|
194
|
+
<IGroup>16448</IGroup>
|
|
195
|
+
<IOffset>512540</IOffset>
|
|
196
|
+
<BitSize>32</BitSize>
|
|
197
|
+
</Symbol>
|
|
198
|
+
<Symbol>
|
|
199
|
+
<Name>MAIN.VarBool</Name>
|
|
200
|
+
<Type>BOOL</Type>
|
|
201
|
+
<IGroup>16448</IGroup>
|
|
202
|
+
<IOffset>512594</IOffset>
|
|
203
|
+
<BitSize>8</BitSize>
|
|
204
|
+
</Symbol>
|
|
205
|
+
<Symbol>
|
|
206
|
+
<Name>MAIN.VarByte</Name>
|
|
207
|
+
<Type>BYTE</Type>
|
|
208
|
+
<IGroup>16448</IGroup>
|
|
209
|
+
<IOffset>512595</IOffset>
|
|
210
|
+
<BitSize>8</BitSize>
|
|
211
|
+
</Symbol>
|
|
212
|
+
<Symbol>
|
|
213
|
+
<Name>MAIN.VarDint</Name>
|
|
214
|
+
<Type>DINT</Type>
|
|
215
|
+
<IGroup>16448</IGroup>
|
|
216
|
+
<IOffset>536300</IOffset>
|
|
217
|
+
<BitSize>32</BitSize>
|
|
218
|
+
</Symbol>
|
|
219
|
+
<Symbol>
|
|
220
|
+
<Name>MAIN.VarDword</Name>
|
|
221
|
+
<Type>DWORD</Type>
|
|
222
|
+
<IGroup>16448</IGroup>
|
|
223
|
+
<IOffset>536304</IOffset>
|
|
224
|
+
<BitSize>32</BitSize>
|
|
225
|
+
</Symbol>
|
|
226
|
+
<Symbol>
|
|
227
|
+
<Name>MAIN.VarInt</Name>
|
|
228
|
+
<Type>INT</Type>
|
|
229
|
+
<IGroup>16448</IGroup>
|
|
230
|
+
<IOffset>536308</IOffset>
|
|
231
|
+
<BitSize>16</BitSize>
|
|
232
|
+
</Symbol>
|
|
233
|
+
<Symbol>
|
|
234
|
+
<Name>MAIN.VarSint</Name>
|
|
235
|
+
<Type>SINT</Type>
|
|
236
|
+
<IGroup>16448</IGroup>
|
|
237
|
+
<IOffset>536310</IOffset>
|
|
238
|
+
<BitSize>8</BitSize>
|
|
239
|
+
</Symbol>
|
|
240
|
+
<Symbol>
|
|
241
|
+
<Name>MAIN.VarUsint</Name>
|
|
242
|
+
<Type>USINT</Type>
|
|
243
|
+
<IGroup>16448</IGroup>
|
|
244
|
+
<IOffset>536311</IOffset>
|
|
245
|
+
<BitSize>8</BitSize>
|
|
246
|
+
</Symbol>
|
|
247
|
+
<Symbol>
|
|
248
|
+
<Name>MAIN.VarLint</Name>
|
|
249
|
+
<Type>LINT</Type>
|
|
250
|
+
<IGroup>16448</IGroup>
|
|
251
|
+
<IOffset>536312</IOffset>
|
|
252
|
+
<BitSize>64</BitSize>
|
|
253
|
+
</Symbol>
|
|
254
|
+
<Symbol>
|
|
255
|
+
<Name>MAIN.VarLreal</Name>
|
|
256
|
+
<Type>LREAL</Type>
|
|
257
|
+
<IGroup>16448</IGroup>
|
|
258
|
+
<IOffset>536320</IOffset>
|
|
259
|
+
<BitSize>64</BitSize>
|
|
260
|
+
</Symbol>
|
|
261
|
+
<Symbol>
|
|
262
|
+
<Name>MAIN.VarLWord</Name>
|
|
263
|
+
<Type>LWORD</Type>
|
|
264
|
+
<IGroup>16448</IGroup>
|
|
265
|
+
<IOffset>536328</IOffset>
|
|
266
|
+
<BitSize>64</BitSize>
|
|
267
|
+
</Symbol>
|
|
268
|
+
<Symbol>
|
|
269
|
+
<Name>MAIN.VarReal</Name>
|
|
270
|
+
<Type>REAL</Type>
|
|
271
|
+
<IGroup>16448</IGroup>
|
|
272
|
+
<IOffset>536336</IOffset>
|
|
273
|
+
<BitSize>32</BitSize>
|
|
274
|
+
</Symbol>
|
|
275
|
+
<Symbol>
|
|
276
|
+
<Name>MAIN.VarUint</Name>
|
|
277
|
+
<Type>UINT</Type>
|
|
278
|
+
<IGroup>16448</IGroup>
|
|
279
|
+
<IOffset>536422</IOffset>
|
|
280
|
+
<BitSize>16</BitSize>
|
|
281
|
+
</Symbol>
|
|
282
|
+
<Symbol>
|
|
283
|
+
<Name>MAIN.VarTimOfDay</Name>
|
|
284
|
+
<Type>TIME_OF_DAY</Type>
|
|
285
|
+
<IGroup>16448</IGroup>
|
|
286
|
+
<IOffset>536424</IOffset>
|
|
287
|
+
<BitSize>32</BitSize>
|
|
288
|
+
</Symbol>
|
|
289
|
+
<Symbol>
|
|
290
|
+
<Name>MAIN.VarUdint</Name>
|
|
291
|
+
<Type>UDINT</Type>
|
|
292
|
+
<IGroup>16448</IGroup>
|
|
293
|
+
<IOffset>536428</IOffset>
|
|
294
|
+
<BitSize>32</BitSize>
|
|
295
|
+
</Symbol>
|
|
296
|
+
<Symbol>
|
|
297
|
+
<Name>MAIN.VarUlint</Name>
|
|
298
|
+
<Type>ULINT</Type>
|
|
299
|
+
<IGroup>16448</IGroup>
|
|
300
|
+
<IOffset>536432</IOffset>
|
|
301
|
+
<BitSize>64</BitSize>
|
|
302
|
+
</Symbol>
|
|
303
|
+
<Symbol>
|
|
304
|
+
<Name>MAIN.VarWord</Name>
|
|
305
|
+
<Type>WORD</Type>
|
|
306
|
+
<IGroup>16448</IGroup>
|
|
307
|
+
<IOffset>536440</IOffset>
|
|
308
|
+
<BitSize>16</BitSize>
|
|
309
|
+
</Symbol>
|
|
310
|
+
<Symbol>
|
|
311
|
+
<Name>MAIN.VarWstring</Name>
|
|
312
|
+
<Type>WSTRING(80)</Type>
|
|
313
|
+
<IGroup>16448</IGroup>
|
|
314
|
+
<IOffset>536442</IOffset>
|
|
315
|
+
<BitSize>1296</BitSize>
|
|
316
|
+
</Symbol>
|
|
317
|
+
<Symbol>
|
|
318
|
+
<Name>MAIN.VarString</Name>
|
|
319
|
+
<Type Decoration="40000050">STRING(80)</Type>
|
|
320
|
+
<IGroup>16448</IGroup>
|
|
321
|
+
<IOffset>537880</IOffset>
|
|
322
|
+
<BitSize>648</BitSize>
|
|
323
|
+
</Symbol>
|
|
324
|
+
</Symbols>
|
|
325
|
+
</PlcProjectInfo>
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
## RA Ethernet/IP
|
|
329
|
+
|
|
330
|
+
>[!NOTE]
|
|
331
|
+
> This feature is available starting from FactoryTalk Optix 1.8.x
|
|
332
|
+
|
|
333
|
+
To import tags from an Allen-Bradley PLC, you can use the `RA EtherNetIP` driver. The import process allows you to filter tags based on specific criteria, such as tag name or data type.
|
|
334
|
+
|
|
335
|
+
```csharp
|
|
336
|
+
#region Using directives
|
|
337
|
+
using System;
|
|
338
|
+
using UAManagedCore;
|
|
339
|
+
using OpcUa = UAManagedCore.OpcUa;
|
|
340
|
+
using FTOptix.UI;
|
|
341
|
+
using FTOptix.HMIProject;
|
|
342
|
+
using FTOptix.NativeUI;
|
|
343
|
+
using FTOptix.Retentivity;
|
|
344
|
+
using FTOptix.CoreBase;
|
|
345
|
+
using FTOptix.Core;
|
|
346
|
+
using FTOptix.NetLogic;
|
|
347
|
+
using FTOptix.RAEtherNetIP;
|
|
348
|
+
using FTOptix.CommunicationDriver;
|
|
349
|
+
using static UAManagedCore.TagImporterAPI;
|
|
350
|
+
using System.Threading.Tasks;
|
|
351
|
+
#endregion
|
|
352
|
+
|
|
353
|
+
public class DesignTimeNetLogic1 : BaseNetLogic
|
|
354
|
+
{
|
|
355
|
+
[ExportMethod]
|
|
356
|
+
public void OfflineImport()
|
|
357
|
+
{
|
|
358
|
+
// First get the existing RA EtherNet/IP station from the project
|
|
359
|
+
var station = plcStation;
|
|
360
|
+
|
|
361
|
+
// Then get the tag importer node from the station
|
|
362
|
+
var tagImporter = station.TagImporter;
|
|
363
|
+
|
|
364
|
+
// Set the file path to the L5X file you want to import
|
|
365
|
+
tagImporter.FilePath = filePath;
|
|
366
|
+
tagImporter.Mode = FetchMode.Offline;
|
|
367
|
+
|
|
368
|
+
// Fire and forget, import is run in a background thread
|
|
369
|
+
_ = tagImporter.Import();
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
[ExportMethod]
|
|
373
|
+
public void OfflineImportWithContinuation()
|
|
374
|
+
{
|
|
375
|
+
var station = plcStation;
|
|
376
|
+
var tagImporter = station.TagImporter;
|
|
377
|
+
|
|
378
|
+
tagImporter.FilePath = filePath;
|
|
379
|
+
tagImporter.Mode = FetchMode.Offline;
|
|
380
|
+
|
|
381
|
+
// Import is started in a background thread,
|
|
382
|
+
// continuation is run in the current thread after the import is completed
|
|
383
|
+
var task = tagImporter.Import(Filter);
|
|
384
|
+
task.ContinueWith((t) =>
|
|
385
|
+
{
|
|
386
|
+
if (t.IsFaulted)
|
|
387
|
+
{
|
|
388
|
+
Log.Error("Import task failed: " + t.Exception?.GetBaseException().Message);
|
|
389
|
+
}
|
|
390
|
+
else if (t.IsCanceled)
|
|
391
|
+
{
|
|
392
|
+
Log.Info("Import task was canceled.");
|
|
393
|
+
}
|
|
394
|
+
else
|
|
395
|
+
{
|
|
396
|
+
Log.Info("Import task completed successfully.");
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
[ExportMethod]
|
|
402
|
+
public void OnlineImport()
|
|
403
|
+
{
|
|
404
|
+
var station = plcStation;
|
|
405
|
+
var tagImporter = station.TagImporter;
|
|
406
|
+
|
|
407
|
+
tagImporter.Mode = FetchMode.Online;
|
|
408
|
+
_ = tagImporter.Import(Filter);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
private bool Filter(string symbolName, string type)
|
|
412
|
+
{
|
|
413
|
+
// List of tags to import (supports partial path matching for parent/child nodes)
|
|
414
|
+
var tagsToImport = new string[]
|
|
415
|
+
{
|
|
416
|
+
"Motor.Status.Running",
|
|
417
|
+
"Integer_tag",
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
foreach (var tagToImport in tagsToImport)
|
|
421
|
+
{
|
|
422
|
+
if (IsTagToImport(symbolName, tagToImport))
|
|
423
|
+
return true;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
return false;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
private bool IsTagToImport(string symbolName, string tagToImport)
|
|
430
|
+
{
|
|
431
|
+
// Match if the symbol is an exact match, a parent, or a child of the target tag
|
|
432
|
+
return symbolName == tagToImport ||
|
|
433
|
+
tagToImport.StartsWith(symbolName) ||
|
|
434
|
+
symbolName.StartsWith(tagToImport);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
private FTOptix.RAEtherNetIP.Station plcStation = Project.Current.Get<FTOptix.RAEtherNetIP.Station>("CommDrivers/RAEtherNetIPDriver1/RAEtherNet_IPStation1");
|
|
438
|
+
private ResourceUri filePath = ResourceUri.FromAbsoluteFilePath("D:\\test\\Optix\\Tools\\RAEtherNetIP\\controller.L5X");
|
|
439
|
+
}
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
An example of L5X file that can be used for testing:
|
|
443
|
+
|
|
444
|
+
```xml
|
|
445
|
+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
446
|
+
<RSLogix5000Content SchemaRevision="1.0" SoftwareRevision="38.00" TargetName="test" TargetType="Controller" ContainsContext="false" ExportDate="Wed Mar 11 10:37:10 2026" ExportOptions="NoRawData L5KData DecoratedData ForceProtectedEncoding AllProjDocTrans">
|
|
447
|
+
<Controller Use="Target" Name="test" ProcessorType="1756-L81E" MajorRev="38" MinorRev="11" ProjectCreationDate="Wed Mar 11 10:35:13 2026" LastModifiedDate="Wed Mar 11 10:36:56 2026" SFCExecutionControl="CurrentActive" SFCRestartPosition="MostRecent" SFCLastScan="DontScan" ProjectSN="16#0000_0000"
|
|
448
|
+
MatchProjectToController="false" CanUseRPIFromProducer="false" InhibitAutomaticFirmwareUpdate="0" PassThroughConfiguration="EnabledWithAppend" DownloadProjectDocumentationAndExtendedProperties="true" DownloadProjectCustomProperties="true" ReportMinorOverflow="false" AutoDiagsEnabled="true" WebServerEnabled="false" DataExchangeId="{7815DD91-43A8-4001-B823-F3594DA6D3FC}">
|
|
449
|
+
<RedundancyInfo Enabled="false" KeepTestEditsOnSwitchOver="false"/>
|
|
450
|
+
<Security Code="0" ChangesToDetect="16#ffff_ffff_ffff_ffff"/>
|
|
451
|
+
<SafetyInfo/>
|
|
452
|
+
<DataTypes>
|
|
453
|
+
<DataType Name="Motor" Family="NoFamily" Class="User">
|
|
454
|
+
<Members>
|
|
455
|
+
<Member Name="Status" DataType="Status" Dimension="0" Radix="NullType" Hidden="false" ExternalAccess="Read/Write"/>
|
|
456
|
+
<Member Name="Speed" DataType="INT" Dimension="0" Radix="Decimal" Hidden="false" ExternalAccess="Read/Write"/>
|
|
457
|
+
</Members>
|
|
458
|
+
</DataType>
|
|
459
|
+
<DataType Name="Status" Family="NoFamily" Class="User">
|
|
460
|
+
<Members>
|
|
461
|
+
<Member Name="ZZZZZZZZZZStatus0" DataType="SINT" Dimension="0" Radix="Decimal" Hidden="true" ExternalAccess="Read/Write"/>
|
|
462
|
+
<Member Name="Running" DataType="BIT" Dimension="0" Radix="Decimal" Hidden="false" Target="ZZZZZZZZZZStatus0" BitNumber="0" ExternalAccess="Read/Write"/>
|
|
463
|
+
<Member Name="Faulty" DataType="BIT" Dimension="0" Radix="Decimal" Hidden="false" Target="ZZZZZZZZZZStatus0" BitNumber="1" ExternalAccess="Read/Write"/>
|
|
464
|
+
</Members>
|
|
465
|
+
</DataType>
|
|
466
|
+
</DataTypes>
|
|
467
|
+
<Modules>
|
|
468
|
+
<Module Name="Local" CatalogNumber="1756-L81E" Vendor="1" ProductType="14" ProductCode="164" Major="38" Minor="11" ParentModule="Local" ParentModPortId="1" Inhibited="false" MajorFault="true"
|
|
469
|
+
>
|
|
470
|
+
<EKey State="Disabled"/>
|
|
471
|
+
<Ports>
|
|
472
|
+
<Port Id="1" Address="0" Type="ICP" Upstream="false">
|
|
473
|
+
<Bus Size="7"/>
|
|
474
|
+
</Port>
|
|
475
|
+
<Port Id="2" Type="Ethernet" Upstream="false">
|
|
476
|
+
<Bus/>
|
|
477
|
+
</Port>
|
|
478
|
+
</Ports>
|
|
479
|
+
</Module>
|
|
480
|
+
</Modules>
|
|
481
|
+
<AddOnInstructionDefinitions/>
|
|
482
|
+
<Tags>
|
|
483
|
+
<Tag Name="Integer_tag" TagType="Base" DataType="DINT" Radix="Decimal" Constant="false" ExternalAccess="Read Only" OpcUaAccess="None">
|
|
484
|
+
<Data Format="L5K">
|
|
485
|
+
<![CDATA[0]]>
|
|
486
|
+
</Data>
|
|
487
|
+
<Data Format="Decorated">
|
|
488
|
+
<DataValue DataType="DINT" Radix="Decimal" Value="0"/>
|
|
489
|
+
</Data>
|
|
490
|
+
</Tag>
|
|
491
|
+
<Tag Name="Motor1" TagType="Base" DataType="Motor" Constant="false" ExternalAccess="Read Only" OpcUaAccess="None">
|
|
492
|
+
<Data Format="L5K">
|
|
493
|
+
<![CDATA[[[0],0]]]>
|
|
494
|
+
</Data>
|
|
495
|
+
<Data Format="Decorated">
|
|
496
|
+
<Structure DataType="Motor">
|
|
497
|
+
<StructureMember Name="Status" DataType="Status">
|
|
498
|
+
<DataValueMember Name="Running" DataType="BOOL" Value="0"/>
|
|
499
|
+
<DataValueMember Name="Faulty" DataType="BOOL" Value="0"/>
|
|
500
|
+
</StructureMember>
|
|
501
|
+
<DataValueMember Name="Speed" DataType="INT" Radix="Decimal" Value="0"/>
|
|
502
|
+
</Structure>
|
|
503
|
+
</Data>
|
|
504
|
+
</Tag>
|
|
505
|
+
</Tags>
|
|
506
|
+
<Programs>
|
|
507
|
+
<Program Name="MainProgram" TestEdits="false" MainRoutineName="MainRoutine" Disabled="false" UseAsFolder="false">
|
|
508
|
+
<Tags/>
|
|
509
|
+
<Routines>
|
|
510
|
+
<Routine Name="MainRoutine" Type="RLL"/>
|
|
511
|
+
</Routines>
|
|
512
|
+
</Program>
|
|
513
|
+
</Programs>
|
|
514
|
+
<Tasks>
|
|
515
|
+
<Task Name="MainTask" Type="CONTINUOUS" Priority="10" Watchdog="500" DisableUpdateOutputs="false" InhibitTask="false" SynchronizeRedundancyDataDisabled="false">
|
|
516
|
+
<ScheduledPrograms>
|
|
517
|
+
<ScheduledProgram Name="MainProgram"/>
|
|
518
|
+
</ScheduledPrograms>
|
|
519
|
+
</Task>
|
|
520
|
+
</Tasks>
|
|
521
|
+
<CST MasterID="0"/>
|
|
522
|
+
<WallClockTime LocalTimeAdjustment="0" TimeZone="0"/>
|
|
523
|
+
<Trends/>
|
|
524
|
+
<TimeSynchronize Priority1="128" Priority2="128" PTPEnable="false"/>
|
|
525
|
+
<EthernetPorts>
|
|
526
|
+
<EthernetPort Port="1" Label="1" PortEnabled="true"/>
|
|
527
|
+
</EthernetPorts>
|
|
528
|
+
<OpcUaInfo EnabledPorts=""/>
|
|
529
|
+
</Controller>
|
|
530
|
+
</RSLogix5000Content>
|
|
531
|
+
```
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# DialogBox
|
|
2
|
+
|
|
3
|
+
DialogBoxes are windows that can be opened from a UI session to display additional information, gather user input, or provide configuration options. They are defined as `DialogType` objects in the project and can be opened using the `UICommands.OpenDialog()` method.
|
|
4
|
+
|
|
5
|
+
> [!NOTE]
|
|
6
|
+
> DialogBoxes can only be displayed at runtime.
|
|
7
|
+
|
|
8
|
+
## Opening a DialogBox
|
|
9
|
+
|
|
10
|
+
The `UICommands.OpenDialog()` method opens a dialog (modal window) and associates it with a specific UI session. It has two overloads:
|
|
11
|
+
- `OpenDialog(IUANode parentItem, DialogType dialogType, NodeId aliasNode = null)` - opens a dialog and binds a single alias node
|
|
12
|
+
- `OpenDialog(IUANode parentItem, DialogType dialogType, NodeId[] aliasNodes)` - opens a dialog and binds multiple alias nodes
|
|
13
|
+
|
|
14
|
+
The `parentItem` must be a UI `Item` or `Window` to determine which session receives the dialog.
|
|
15
|
+
|
|
16
|
+
### Basic Example
|
|
17
|
+
|
|
18
|
+
```csharp
|
|
19
|
+
[ExportMethod]
|
|
20
|
+
public void OpenMyDialogBox()
|
|
21
|
+
{
|
|
22
|
+
// Get the DialogBox type definition
|
|
23
|
+
var myDialogType = (DialogType)Project.Current.Get("UI/Templates/DialogBox1");
|
|
24
|
+
|
|
25
|
+
// DialogBoxes need a graphical container as parent to bind to the correct session
|
|
26
|
+
var parentPanel = (FTOptix.UI.Panel)Owner;
|
|
27
|
+
|
|
28
|
+
// Open the dialog without alias bindings
|
|
29
|
+
UICommands.OpenDialog(parentPanel, myDialogType);
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Pass a Single Alias Node
|
|
34
|
+
|
|
35
|
+
Alias nodes are OPC UA references that the dialog can use to access objects. This is useful for passing data or objects to the dialog.
|
|
36
|
+
|
|
37
|
+
```csharp
|
|
38
|
+
[ExportMethod]
|
|
39
|
+
public void OpenDialogWithAlias()
|
|
40
|
+
{
|
|
41
|
+
var dialogType = (DialogType)Project.Current.Get("UI/Templates/ConfigDialog");
|
|
42
|
+
var configObject = Project.Current.Get("Objects/CurrentConfig");
|
|
43
|
+
|
|
44
|
+
// Bind a single alias node - the dialog can access it through the alias
|
|
45
|
+
UICommands.OpenDialog((FTOptix.UI.Panel)Owner, dialogType, configObject.NodeId);
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Pass Multiple Alias Nodes
|
|
50
|
+
|
|
51
|
+
You can pass an array of alias nodes to provide the dialog with access to multiple objects.
|
|
52
|
+
|
|
53
|
+
```csharp
|
|
54
|
+
[ExportMethod]
|
|
55
|
+
public void OpenDialogWithMultipleAliases()
|
|
56
|
+
{
|
|
57
|
+
var dialogType = (DialogType)Project.Current.Get("UI/Templates/DetailDialog");
|
|
58
|
+
var primaryData = Project.Current.Get("Objects/PrimaryData");
|
|
59
|
+
var secondaryData = Project.Current.Get("Objects/SecondaryData");
|
|
60
|
+
var settings = Project.Current.Get("Objects/Settings");
|
|
61
|
+
|
|
62
|
+
// Create an array of alias nodes
|
|
63
|
+
NodeId[] aliasNodes = new NodeId[]
|
|
64
|
+
{
|
|
65
|
+
primaryData.NodeId,
|
|
66
|
+
secondaryData.NodeId,
|
|
67
|
+
settings.NodeId
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// Open the dialog with multiple alias bindings
|
|
71
|
+
UICommands.OpenDialog((FTOptix.UI.Panel)Owner, dialogType, aliasNodes);
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Open a DialogBox on all sessions (native and web)
|
|
76
|
+
|
|
77
|
+
```csharp
|
|
78
|
+
[ExportMethod]
|
|
79
|
+
public void OpenDialogBox(string DialogBoxName, NodeId[] AliasArray = null)
|
|
80
|
+
{
|
|
81
|
+
DialogType dialogBox = (DialogType)Project.Current.Get($"UI/Screens/{DialogBoxName}");
|
|
82
|
+
|
|
83
|
+
// Open dialog on Native Presentation Engine
|
|
84
|
+
var nativePresentationEngine = Project.Current.Get("UI/NativePresentationEngine");
|
|
85
|
+
var nativePresentationEngineSessions = nativePresentationEngine.Get("Sessions");
|
|
86
|
+
var nativePresentationEngineSession = nativePresentationEngineSessions.Children[0]; // Native PE only has one session, so get the first one
|
|
87
|
+
var nativePresentationEngineWindow = nativePresentationEngineSession.Get("UIRoot");
|
|
88
|
+
UICommands.OpenDialog(nativePresentationEngineWindow, dialogBox, AliasArray);
|
|
89
|
+
|
|
90
|
+
// Open dialog on Web Presentation Engine (may have multiple sessions)
|
|
91
|
+
var webPresentationEngine = Project.Current.Get("UI/WebPresentationEngine");
|
|
92
|
+
var webPresentationEngineSessions = webPresentationEngine.Get("Sessions");
|
|
93
|
+
foreach (var webPresentationEngineSession in webPresentationEngineSessions.Children)
|
|
94
|
+
{
|
|
95
|
+
var webPresentationEngineWindow = webPresentationEngineSession.Get("UIRoot");
|
|
96
|
+
if (webPresentationEngineWindow != null)
|
|
97
|
+
{
|
|
98
|
+
UICommands.OpenDialog(webPresentationEngineWindow, dialogBox, AliasArray);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Closing a DialogBox
|
|
105
|
+
|
|
106
|
+
### Close all DialogBoxes in the current session
|
|
107
|
+
|
|
108
|
+
> [!TIP]
|
|
109
|
+
> The following snippet must be placed in a session-based object (e.g. the `MainWindow` of a project).
|
|
110
|
+
|
|
111
|
+
```csharp
|
|
112
|
+
[ExportMethod]
|
|
113
|
+
public void CloseAllDialogs()
|
|
114
|
+
{
|
|
115
|
+
// DialogBoxes are children of the current Session, so iterate through
|
|
116
|
+
// the children of UIRoot to find and close all open dialogs
|
|
117
|
+
var uiRoot = Session.Get("UIRoot");
|
|
118
|
+
foreach (Dialog dialog in uiRoot.Children.OfType<Dialog>().ToList())
|
|
119
|
+
{
|
|
120
|
+
dialog.Close();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Close a specific DialogBox
|
|
126
|
+
|
|
127
|
+
```csharp
|
|
128
|
+
[ExportMethod]
|
|
129
|
+
public void CloseMyDialog()
|
|
130
|
+
{
|
|
131
|
+
// Get reference to a specific dialog and close it
|
|
132
|
+
var myDialog = (Dialog)Session.Get("UIRoot/MyDialogBox");
|
|
133
|
+
if (myDialog != null)
|
|
134
|
+
{
|
|
135
|
+
myDialog.Close();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Close a DropDownButton
|
|
141
|
+
|
|
142
|
+
```csharp
|
|
143
|
+
/// <summary>
|
|
144
|
+
/// Close a DropDownButton UI widget by calling its Close method.
|
|
145
|
+
/// Input: assume `Owner` is the DropDownButton or that the code can access it via Owner.
|
|
146
|
+
/// </summary>
|
|
147
|
+
var dropDownButton = (DropDownButton)Owner;
|
|
148
|
+
// Call the Close method exposed by the widget
|
|
149
|
+
dropDownButton.ExecuteMethod("Close");
|
|
150
|
+
```
|