@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,155 @@
|
|
|
1
|
+
# Variables structures
|
|
2
|
+
|
|
3
|
+
Struct variables represent complex data types composed of multiple fields, allowing you to work with structured data from OPC-UA servers or other data sources. This snippet collections covers how to handle, read, and modify struct variables in FactoryTalk Optix NetLogic.
|
|
4
|
+
|
|
5
|
+
## Handle Struct Variables
|
|
6
|
+
|
|
7
|
+
When connecting to an OPC-UA server from another vendor, Optix can resolve structures as Struct variables (or arrays of structs). At the code level, this type of variable is read-only. To modify the values within it, you must extract its content (which is always expressed as an array of objects), modify the array, and then recreate a new Struct.
|
|
8
|
+
|
|
9
|
+
```csharp
|
|
10
|
+
[ExportMethod]
|
|
11
|
+
public void ModifyStructVariable (NodeId opcuaStructVariableNodeId, int indexToModify, string value)
|
|
12
|
+
{
|
|
13
|
+
// Get the variable to modify
|
|
14
|
+
IUAVariable opcUaVariable = InformationModel.GetVariable(opcuaStructVariableNodeId);
|
|
15
|
+
// Read the value from the field (assuming we use a PLC/OPCUA client)
|
|
16
|
+
Struct structureVariable = opcUaVariable.RemoteRead();
|
|
17
|
+
// Prepare the structure to be modified
|
|
18
|
+
object[] newValues = structureVariable.Values as object[];
|
|
19
|
+
newValues[indexToModify] = value;
|
|
20
|
+
// Set the new content for the structure
|
|
21
|
+
Struct newStructureToWrite = structureVariable.HasDataTypeId ? new Struct(structureVariable.DataTypeId, newValues) : new Struct(newValues);
|
|
22
|
+
// Write the value to the field
|
|
23
|
+
opcUaVariable.RemoteWrite(newStructureToWrite);
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Reading a Structure Member
|
|
28
|
+
|
|
29
|
+
Since a struct in the .NET environment is a simple array of objects, you can retrieve the index of your structure's field by accessing the StructDefinition of the datatype.
|
|
30
|
+
|
|
31
|
+
```csharp
|
|
32
|
+
/// <summary>
|
|
33
|
+
/// Retrieves the value of a specific field from a UA Struct variable by field name.
|
|
34
|
+
/// </summary>
|
|
35
|
+
/// <param name="structVariable">The structure variable</param>
|
|
36
|
+
/// <param name="fieldName">The name of the field to retrieve</param>
|
|
37
|
+
/// <returns>The field value, or null if not found or on error</returns>
|
|
38
|
+
private object GetStructFieldValue(IUAVariable structVariable, string fieldName)
|
|
39
|
+
{
|
|
40
|
+
// Validate that the variable's value is a Struct
|
|
41
|
+
if (structVariable.Value.Value is not Struct structValue)
|
|
42
|
+
{
|
|
43
|
+
Log.Warning($"Variable {structVariable.BrowseName} is not a Structure.");
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Verify that the struct has a DataTypeId to look up its definition
|
|
48
|
+
if (!structValue.HasDataTypeId)
|
|
49
|
+
{
|
|
50
|
+
Log.Warning($"Structure variable {structVariable.BrowseName} does not have a DataTypeId.");
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Retrieve the DataType definition to access the field names and their order
|
|
55
|
+
if (InformationModel.Get<IUADataType>(structValue.DataTypeId) is not IUADataType dataType)
|
|
56
|
+
{
|
|
57
|
+
Log.Warning($"DataTypeId {structValue.DataTypeId} of variable {structVariable.BrowseName} is not a valid DataType.");
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Find the index of the field by name in the StructDefinition.Fields list
|
|
62
|
+
// The index corresponds to the position in the Values array
|
|
63
|
+
var index = dataType.StructDefinition.Fields.ToList().FindIndex(f => f.Name == fieldName);
|
|
64
|
+
if (index == -1)
|
|
65
|
+
{
|
|
66
|
+
Log.Warning($"Field {fieldName} not found in Structure variable {structVariable.BrowseName}.");
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Return the field value from the Values array using the found index
|
|
71
|
+
return structValue.Values[index];
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Writing a Structure Member
|
|
76
|
+
|
|
77
|
+
Like reading, writing requires an additional step: you must extract the entire Struct and regenerate it with the new values (see ModifyStructVariable).
|
|
78
|
+
|
|
79
|
+
```csharp
|
|
80
|
+
/// <summary>
|
|
81
|
+
/// Sets the value of a specific field in a UA Struct variable by field name.
|
|
82
|
+
/// </summary>
|
|
83
|
+
/// <param name="structIUAVariable">The UA variable containing the struct</param>
|
|
84
|
+
/// <param name="fieldName">The name of the field to set</param>
|
|
85
|
+
/// <param name="value">The new value for the field</param>
|
|
86
|
+
/// <returns>True if the field was successfully set, false if not found or on error</returns>
|
|
87
|
+
private bool SetStructFieldValue(IUAVariable structIUAVariable, string fieldName, object value)
|
|
88
|
+
{
|
|
89
|
+
// Validate that the variable's value is a Struct
|
|
90
|
+
if (structIUAVariable.Value.Value is not Struct structureVariable)
|
|
91
|
+
{
|
|
92
|
+
Log.Warning(LogicObject.BrowseName, $"Variable {structIUAVariable.BrowseName} is not a Structure.");
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Verify that the struct has a DataTypeId to look up its definition
|
|
97
|
+
if (!structureVariable.HasDataTypeId)
|
|
98
|
+
{
|
|
99
|
+
Log.Warning(LogicObject.BrowseName, $"Structure variable {structIUAVariable.BrowseName} does not have a DataTypeId.");
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Retrieve the DataType definition to access the field names and their order
|
|
104
|
+
if (InformationModel.Get<IUADataType>(structureVariable.DataTypeId) is not IUADataType dataType)
|
|
105
|
+
{
|
|
106
|
+
Log.Warning(LogicObject.BrowseName, $"DataTypeId {structureVariable.DataTypeId} of variable {structIUAVariable.BrowseName} is not a valid DataType.");
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Find the index of the field by name in the StructDefinition.Fields list
|
|
111
|
+
// The index corresponds to the position in the Values array
|
|
112
|
+
var index = dataType.StructDefinition.Fields.ToList().FindIndex(f => f.Name == fieldName);
|
|
113
|
+
if (index == -1)
|
|
114
|
+
{
|
|
115
|
+
Log.Warning(LogicObject.BrowseName, $"Field {fieldName} not found in Structure variable {structIUAVariable.BrowseName}.");
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Update the field value in the Values array using the found index and write it back to the variable
|
|
120
|
+
var values = structureVariable.Values.ToArray();
|
|
121
|
+
values[index] = value;
|
|
122
|
+
structIUAVariable.Value = new Struct(structureVariable.DataTypeId, values);
|
|
123
|
+
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Creating TagStructure
|
|
129
|
+
|
|
130
|
+
```csharp
|
|
131
|
+
// Create a new TagStructure variable
|
|
132
|
+
var tagStructure = InformationModel.MakeVariable<FTOptix.CommunicationDriver.TagStructure>("FanArray", OpcUa.DataTypes.Structure, new[] { 11u });
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Generic method to retrive the index of a field
|
|
136
|
+
|
|
137
|
+
```csharp
|
|
138
|
+
/// <summary>
|
|
139
|
+
/// Finds the index of a specific field in a UA Struct DataType definition by field name.
|
|
140
|
+
/// </summary>
|
|
141
|
+
/// <param name="dataType">The UA DataType containing the struct definition</param>
|
|
142
|
+
/// <param name="fieldName">The name of the field to find</param>
|
|
143
|
+
/// <returns>The index of the field, or -1 if not found</returns>
|
|
144
|
+
private int GetFieldIndex(IUADataType dataType, string fieldName)
|
|
145
|
+
{
|
|
146
|
+
// Find the index of the field by name in the StructDefinition.Fields list
|
|
147
|
+
// The index corresponds to the position in the Values array
|
|
148
|
+
var index = dataType.StructDefinition.Fields.ToList().FindIndex(f => f.Name == fieldName);
|
|
149
|
+
if (index == -1)
|
|
150
|
+
{
|
|
151
|
+
Log.Warning(LogicObject.BrowseName, $"Field {fieldName} not found in DataType {dataType.BrowseName}.");
|
|
152
|
+
}
|
|
153
|
+
return index;
|
|
154
|
+
}
|
|
155
|
+
```
|