@aryacode/dsh-engineering 0.4.22 → 0.6.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.
Files changed (76) hide show
  1. package/CHANGELOG.md +98 -0
  2. package/README.md +10 -7
  3. package/cordis.patch.yml +1 -1
  4. package/entries/netlogic.js +266 -0
  5. package/entries/optix.js +13 -0
  6. package/package.json +3 -2
  7. package/vendor/ftview/SKILL.md +6 -0
  8. package/vendor/ftview/lib/model.d.ts +8 -3
  9. package/vendor/ftview/lib/model.js +63 -16
  10. package/vendor/l5x/lib/engine/analysis.d.ts +9 -1
  11. package/vendor/l5x/lib/engine/analysis.js +28 -3
  12. package/vendor/l5x/lib/engine/change-set.js +5 -4
  13. package/vendor/l5x/lib/engine/cip-request.d.ts +1 -0
  14. package/vendor/l5x/lib/engine/cip-request.js +71 -26
  15. package/vendor/l5x/lib/engine/direct-polling.js +12 -6
  16. package/vendor/l5x/lib/engine/review.js +12 -1
  17. package/vendor/l5x/lib/engine/studio-sdk.js +24 -6
  18. package/vendor/mwi/code/mw_code.py +4 -1
  19. package/vendor/mwi/legacy/native-variables.js +9 -1
  20. package/vendor/mwi/lib/read/service.d.ts +7 -1
  21. package/vendor/mwi/lib/read/service.js +13 -1
  22. package/vendor/mwi/lib/session/service.js +7 -1
  23. package/vendor/optix/SKILL.md +68 -0
  24. package/vendor/optix/netlogic/SOURCE.json +12 -0
  25. package/vendor/optix/netlogic/index.json +1987 -0
  26. package/vendor/optix/netlogic/pages/accessing-project-nodes.md +113 -0
  27. package/vendor/optix/netlogic/pages/advanced-svg.md +124 -0
  28. package/vendor/optix/netlogic/pages/alarming.md +489 -0
  29. package/vendor/optix/netlogic/pages/async-tasks.md +236 -0
  30. package/vendor/optix/netlogic/pages/audit-signature.md +91 -0
  31. package/vendor/optix/netlogic/pages/colors.md +122 -0
  32. package/vendor/optix/netlogic/pages/companion-specs.md +77 -0
  33. package/vendor/optix/netlogic/pages/creating-objects.md +370 -0
  34. package/vendor/optix/netlogic/pages/database-interaction.md +437 -0
  35. package/vendor/optix/netlogic/pages/datagrids.md +123 -0
  36. package/vendor/optix/netlogic/pages/debugging-tips.md +605 -0
  37. package/vendor/optix/netlogic/pages/designtime-tags-import.md +531 -0
  38. package/vendor/optix/netlogic/pages/dialog-boxes.md +150 -0
  39. package/vendor/optix/netlogic/pages/dispatch-events.md +200 -0
  40. package/vendor/optix/netlogic/pages/dynamic-links.md +825 -0
  41. package/vendor/optix/netlogic/pages/element-access.md +1208 -0
  42. package/vendor/optix/netlogic/pages/engineering-units.md +298 -0
  43. package/vendor/optix/netlogic/pages/events.md +340 -0
  44. package/vendor/optix/netlogic/pages/execute-command.md +202 -0
  45. package/vendor/optix/netlogic/pages/fto-studio-cli.md +99 -0
  46. package/vendor/optix/netlogic/pages/good-practices.md +50 -0
  47. package/vendor/optix/netlogic/pages/information-model.md +89 -0
  48. package/vendor/optix/netlogic/pages/log-output.md +22 -0
  49. package/vendor/optix/netlogic/pages/managing-aliases.md +22 -0
  50. package/vendor/optix/netlogic/pages/manipulate-nodes.md +72 -0
  51. package/vendor/optix/netlogic/pages/mqtt.md +240 -0
  52. package/vendor/optix/netlogic/pages/netlogic-lifecycle.md +270 -0
  53. package/vendor/optix/netlogic/pages/netlogic-overview.md +155 -0
  54. package/vendor/optix/netlogic/pages/opcua.md +325 -0
  55. package/vendor/optix/netlogic/pages/plc-tags.md +219 -0
  56. package/vendor/optix/netlogic/pages/queries.md +1297 -0
  57. package/vendor/optix/netlogic/pages/random-generation.md +90 -0
  58. package/vendor/optix/netlogic/pages/recipes.md +375 -0
  59. package/vendor/optix/netlogic/pages/recipex.md +2383 -0
  60. package/vendor/optix/netlogic/pages/regex.md +15 -0
  61. package/vendor/optix/netlogic/pages/register-observers.md +346 -0
  62. package/vendor/optix/netlogic/pages/reports.md +141 -0
  63. package/vendor/optix/netlogic/pages/resource-uri.md +308 -0
  64. package/vendor/optix/netlogic/pages/runtime-tags-import.md +280 -0
  65. package/vendor/optix/netlogic/pages/serial-port.md +357 -0
  66. package/vendor/optix/netlogic/pages/sessions.md +58 -0
  67. package/vendor/optix/netlogic/pages/system-node.md +153 -0
  68. package/vendor/optix/netlogic/pages/template-library.md +127 -0
  69. package/vendor/optix/netlogic/pages/threading.md +236 -0
  70. package/vendor/optix/netlogic/pages/translations.md +417 -0
  71. package/vendor/optix/netlogic/pages/trends.md +128 -0
  72. package/vendor/optix/netlogic/pages/ui-animations.md +115 -0
  73. package/vendor/optix/netlogic/pages/users-groups.md +416 -0
  74. package/vendor/optix/netlogic/pages/variables-formatting.md +16 -0
  75. package/vendor/optix/netlogic/pages/variables-interaction.md +557 -0
  76. package/vendor/optix/netlogic/pages/variables-structure.md +155 -0
@@ -0,0 +1,200 @@
1
+ # Triggering events to the FactoryTalk Optix core
2
+
3
+ > [!WARNING]
4
+ > This page describes low-level features and should be used with caution as they can potentially lead to unexpected results or even break your project.
5
+ > These features are not officially supported and may be subject to changes in future releases.
6
+
7
+ > [!NOTE]
8
+ > Events can only be dispatched at runtime.
9
+
10
+ ## Introduction to OPC/UA Events
11
+
12
+ OPC Unified Architecture (OPC UA) is a machine-to-machine communication protocol for industrial automation developed by the OPC Foundation. One of the key features of OPC UA is its ability to handle events. Events in OPC UA are notifications about changes or occurrences within the system that are of interest to clients.
13
+
14
+ ### What are OPC/UA Events?
15
+
16
+ OPC UA events provide a mechanism for servers to notify clients about significant changes or occurrences. These events can be anything from simple state changes to complex alarms and conditions. Events are used to inform clients about changes in the system without the need for constant polling, making the communication more efficient.
17
+
18
+ ### Types of Events
19
+
20
+ OPC UA defines several types of events, including:
21
+
22
+ - **Simple Events**: Basic notifications about changes or occurrences.
23
+ - **Condition Events**: Notifications about conditions that have a state and can change over time.
24
+ - **Alarm Events**: Special types of condition events that indicate abnormal or critical conditions.
25
+
26
+ ### Event Model
27
+
28
+ The OPC UA event model is based on the concept of event types and event instances. Event types define the structure and semantics of events, while event instances are actual occurrences of these events. The event model allows for the creation of custom event types to suit specific application needs.
29
+
30
+ ### References to Specifications
31
+
32
+ For more detailed information about OPC UA events, refer to the following OPC Foundation specifications:
33
+
34
+ - [OPC Unified Architecture, Part 3: Address Space Model](https://opcfoundation.org/developer-tools/specifications-unified-architecture/part-3-address-space-model/)
35
+ - [OPC Unified Architecture, Part 5: Information Model](https://opcfoundation.org/developer-tools/specifications-unified-architecture/part-5-information-model/)
36
+ - [OPC Unified Architecture, Part 9: Alarms and Conditions](https://opcfoundation.org/developer-tools/specifications-unified-architecture/part-9-alarms-conditions/)
37
+
38
+ These documents provide comprehensive details on the structure, types, and handling of events in OPC UA.
39
+
40
+ ## Dispatching an OPC/UA event
41
+
42
+ > [!WARNING]
43
+ > Events are not directly supported in the FactoryTalk Optix IDE, and the code provided here is an example of how to manually trigger them using custom logic. This code is for reference only and should be adapted to your specific use case.
44
+
45
+ ### UserSessionEvent
46
+
47
+ This event can be used to trigger custom messages to the UserSessionEvent logger, for example to notify about expiring passwords and more
48
+
49
+ #### 1. Creating the dispatch method
50
+
51
+ ```csharp
52
+ [ExportMethod]
53
+ public void TriggerUserSessionEvent(object[] inputArgs)
54
+ {
55
+ // Convert input arguments to the expected types
56
+ var sourceName = (string) inputArgs[0];
57
+ var sourceNode = (NodeId) inputArgs[1];
58
+ var clientUserId = (string) inputArgs[2];
59
+ var status = (bool) inputArgs[3];
60
+ var message = new LocalizedText((string) inputArgs[4], "en-US");
61
+
62
+ // Get the UserSessionEvent object type
63
+ var userSessionEvent = (IUAObjectType) InformationModel.Get(FTOptix.Core.ObjectTypes.UserSessionEvent);
64
+
65
+ // Create a list to store the event arguments
66
+ List<object> argumentList = [];
67
+ if (userSessionEvent.EventArguments != null)
68
+ {
69
+ argumentList.AddRange(new object[userSessionEvent.EventArguments.GetFields().Count]);
70
+ foreach (var field in userSessionEvent.EventArguments.GetFields())
71
+ {
72
+ // Set the field value based on the field name
73
+ object fieldValue = field switch
74
+ {
75
+ "EventId" => GenerateEventIdFromNodeId((Guid) Session.NodeId.Id),
76
+ "EventType" => FTOptix.Core.ObjectTypes.UserSessionEvent,
77
+ "SourceName" => sourceName,
78
+ "SourceNode" => sourceNode,
79
+ "ClientUserId" => clientUserId,
80
+ "Status" => status,
81
+ "Message" => message,
82
+ "Time" => DateTime.Now,
83
+ "Severity" => new Random().Next(1, 500),
84
+ _ => null
85
+ };
86
+ if (fieldValue != null)
87
+ {
88
+ userSessionEvent.EventArguments.SetFieldValue(argumentList, field, fieldValue);
89
+ }
90
+ }
91
+ // Dispatch the event to the Server object
92
+ LogicObject.Context.GetObject(OpcUa.Objects.Server).DispatchUAEvent(FTOptix.Core.ObjectTypes.UserSessionEvent, argumentList.AsReadOnly());
93
+ }
94
+ }
95
+
96
+ public static ByteString GenerateEventIdFromNodeId(Guid nodeId)
97
+ {
98
+ string baseString = nodeId.ToString() + DateTime.UtcNow.Ticks.ToString();
99
+ using SHA256 sha256 = SHA256.Create();
100
+ byte[] hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(baseString));
101
+ return new ByteString(hashBytes);
102
+ }
103
+ ```
104
+
105
+ #### 2. Triggering the event
106
+
107
+ ```csharp
108
+
109
+ [ExportMethod]
110
+ public void TriggerEvent()
111
+ {
112
+ DispatchEventToCore(Session.User.BrowseName, false, "Custom message triggered from a button");
113
+ }
114
+
115
+ private void DispatchEventToCore(string username, bool successful, string message)
116
+ {
117
+ // Get the EventDispatcher NetLogic
118
+ // This is the NetLogic object that dispatches events to the FactoryTalk Optix core
119
+ // as created in the previous section
120
+ var eventsDispatcherLogic = Project.Current.GetObject("NetLogic/EventsDispatcher");
121
+ if (eventsDispatcherLogic == null)
122
+ {
123
+ Log.Error("LoginButtonLogic", "EventsDispatcher NetLogic not found");
124
+ return;
125
+ }
126
+
127
+ // Create the input arguments for the event
128
+ // The arguments are passed as an object array, to find the list of arguments
129
+ // and the expected values, you can use an EventLogger object and generate
130
+ // an event to see the expected arguments
131
+ var inputArgs = new object[]
132
+ {
133
+ "LoginForm", // SourceName -> The friendly name of the source of the event
134
+ Owner.NodeId, // SourceNode -> The NodeId of the source of the event
135
+ username, // ClientUserId -> The user associated with the event
136
+ successful, // Status -> The status of the event (boolean)
137
+ message // Message -> The message associated with the event
138
+ };
139
+
140
+ // Trigger the event
141
+ eventsDispatcherLogic.ExecuteMethod("TriggerUserSessionEvent", [inputArgs]);
142
+ }
143
+ ```
144
+
145
+ ### AlarmConditionEvent
146
+
147
+ This fires an AlarmConditionEvent with no need to generate the corresponding alarm and can be used to add lines to an AlarmsEventLogger without triggering the actual alarm.
148
+
149
+ ```csharp
150
+ [ExportMethod]
151
+ public void TriggerAlarmConditionEvent(string message, UInt16 severity, string sourceName)
152
+ {
153
+ // Convert input arguments to the expected types
154
+ var sourceNode = LogicObject.NodeId;
155
+ var eventMessage = new LocalizedText(message, "en-US");
156
+
157
+ // Get the UserSessionEvent object type
158
+ var alarmConditionEvent = (IUAObjectType)InformationModel.Get(OpcUa.ObjectTypes.AlarmConditionType);
159
+
160
+ // Create a list to store the event arguments
161
+ List<object> argumentList = [];
162
+ if (alarmConditionEvent.EventArguments != null)
163
+ {
164
+ argumentList.AddRange(new object[alarmConditionEvent.EventArguments.GetFields().Count]);
165
+ foreach (var field in alarmConditionEvent.EventArguments.GetFields())
166
+ {
167
+ // Set the field value based on the field name
168
+ object fieldValue = field switch
169
+ {
170
+ "ActiveState_Id" => true,
171
+ "AckedState_Id" => true,
172
+ "ConfirmedState_Id" => true,
173
+ "EventId" => GenerateEventIdFromNodeId(Guid.NewGuid()),
174
+ "ConditionName" => sourceName, // Column "Name" in the AlarmLogger
175
+ "EnabledState_Id" => false,
176
+ "SourceName" => LogicObject.BrowseName, // Column "Source Variable" in the AlarmLogger
177
+ "Time" => DateTime.UtcNow,
178
+ "Message" => eventMessage, // Column "Message" in the AlarmLogger
179
+ "Severity" => severity, // Column "Severity" in the AlarmLogger
180
+ "ConditionId" => sourceNode,
181
+ _ => null
182
+ };
183
+ if (fieldValue != null)
184
+ {
185
+ alarmConditionEvent.EventArguments.SetFieldValue(argumentList, field, fieldValue);
186
+ }
187
+ }
188
+ // Dispatch the event to the Server object
189
+ LogicObject.Context.GetObject(OpcUa.Objects.Server).DispatchUAEvent(OpcUa.ObjectTypes.AlarmConditionType, argumentList.AsReadOnly());
190
+ }
191
+ }
192
+
193
+ public static ByteString GenerateEventIdFromNodeId(Guid nodeId)
194
+ {
195
+ string baseString = nodeId.ToString() + DateTime.UtcNow.Ticks.ToString();
196
+ using SHA256 sha256 = SHA256.Create();
197
+ byte[] hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(baseString));
198
+ return new ByteString(hashBytes);
199
+ }
200
+ ```