@vitormnm/node-red-simple-opcua 1.7.0 → 1.8.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/README.md +17 -2
- package/client/lib/opcua-client-browser.js +19 -4
- package/client/lib/opcua-client-write-service.js +14 -4
- package/client/opcua-client-config.js +38 -1
- package/client/opcua-client-utils.js +124 -0
- package/client/opcua-client.html +1 -0
- package/client/view/opcua-client.js +106 -14
- package/package.json +2 -2
- package/server/lib/opcua-address-space-alarm.js +85 -28
- package/server/lib/opcua-address-space-builder.js +653 -45
- package/server/lib/opcua-config.js +29 -12
- package/server/lib/opcua-server-events-child.js +30 -4
- package/server/lib/opcua-server-runtime-child.js +141 -9
- package/server/lib/opcua-server-runtime.js +3 -0
- package/server/lib/opcua-server-status-child.js +32 -1
- package/server/opcua-server-io.html +21 -5
- package/server/opcua-server-io.js +23 -2
- package/server/opcua-server-registry.js +8 -2
- package/server/opcua-server.css +12 -0
- package/server/opcua-server.html +2 -0
- package/server/view/opcua-server.css +11 -0
- package/server/view/opcua-server.js +240 -23
|
@@ -15,18 +15,14 @@ class OpcUaAddressSpaceAlarm {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
emitTagAccess(operation, details) {
|
|
18
|
-
this.registry.emitTagAccess({
|
|
18
|
+
this.registry.emitTagAccess(Object.assign({
|
|
19
19
|
operation,
|
|
20
20
|
serverId: this.node.id,
|
|
21
21
|
serverNodeName: this.node.name || "",
|
|
22
22
|
serverName: this.serverName,
|
|
23
23
|
timestamp: new Date().toISOString(),
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
browseName: details.browseName,
|
|
27
|
-
dataType: details.dataType,
|
|
28
|
-
value: details.value
|
|
29
|
-
});
|
|
24
|
+
users: []
|
|
25
|
+
}, details));
|
|
30
26
|
}
|
|
31
27
|
|
|
32
28
|
createAlarm(namespace, browseName, parentNode, inputNode, conditionName, nodeId, sourceName, alarmConfig) {
|
|
@@ -102,21 +98,21 @@ class OpcUaAddressSpaceAlarm {
|
|
|
102
98
|
}
|
|
103
99
|
}
|
|
104
100
|
|
|
105
|
-
checkAlarm(alarm, variableValue) {
|
|
101
|
+
checkAlarm(alarm, variableValue, context = null) {
|
|
106
102
|
if (alarm) {
|
|
107
103
|
const alarmConfig = alarm.alarmConfig;
|
|
108
104
|
const type = alarmConfig.type;
|
|
109
105
|
|
|
110
106
|
if (type === "levelAlarm") {
|
|
111
|
-
this.levelAlarm(alarm, variableValue);
|
|
107
|
+
this.levelAlarm(alarm, variableValue, context);
|
|
112
108
|
}
|
|
113
109
|
if (type === "digitalAlarm") {
|
|
114
|
-
this.digitalAlarm(alarm, variableValue);
|
|
110
|
+
this.digitalAlarm(alarm, variableValue, context);
|
|
115
111
|
}
|
|
116
112
|
}
|
|
117
113
|
}
|
|
118
114
|
|
|
119
|
-
levelAlarm(alarm, variableValue) {
|
|
115
|
+
levelAlarm(alarm, variableValue, context = null) {
|
|
120
116
|
const alarmNode = alarm.node;
|
|
121
117
|
const alarmConfig = alarm.alarmConfig;
|
|
122
118
|
|
|
@@ -133,36 +129,37 @@ class OpcUaAddressSpaceAlarm {
|
|
|
133
129
|
|
|
134
130
|
if (variableValue >= highHighSp && enabled) {
|
|
135
131
|
message = sendValue ? (alarmConfig.highHighMessage + ": " + variableValue) : alarmConfig.highHighMessage;
|
|
136
|
-
this.raiseAlarm(alarmNode, message, alarmConfig.severity);
|
|
132
|
+
this.raiseAlarm(alarmNode, message, alarmConfig.severity, true, context);
|
|
137
133
|
lastMessage = message;
|
|
138
134
|
} else if (variableValue >= highSp && enabled) {
|
|
139
135
|
message = sendValue ? (alarmConfig.highMessage + ": " + variableValue) : alarmConfig.highMessage;
|
|
140
|
-
this.raiseAlarm(alarmNode, message, alarmConfig.severity);
|
|
136
|
+
this.raiseAlarm(alarmNode, message, alarmConfig.severity, true, context);
|
|
141
137
|
lastMessage = message;
|
|
142
138
|
} else if (variableValue <= lowLowSp && enabled) {
|
|
143
139
|
message = sendValue ? (alarmConfig.lowLowMessage + ": " + variableValue) : alarmConfig.lowLowMessage;
|
|
144
|
-
this.raiseAlarm(alarmNode, message, alarmConfig.severity);
|
|
140
|
+
this.raiseAlarm(alarmNode, message, alarmConfig.severity, true, context);
|
|
145
141
|
lastMessage = message;
|
|
146
142
|
} else if (variableValue <= lowSp && enabled) {
|
|
147
143
|
message = sendValue ? (alarmConfig.lowMessage + ": " + variableValue) : alarmConfig.lowMessage;
|
|
148
|
-
this.raiseAlarm(alarmNode, message, alarmConfig.severity);
|
|
144
|
+
this.raiseAlarm(alarmNode, message, alarmConfig.severity, true, context);
|
|
149
145
|
lastMessage = message;
|
|
150
146
|
} else if (isActive) {
|
|
151
|
-
|
|
147
|
+
message = sendValue ? (alarmConfig.normalMessage + ": " + variableValue) : alarmConfig.normalMessage;
|
|
148
|
+
this.clearAlarm(alarmNode, lastMessage || message, alarmConfig.severity, context);
|
|
152
149
|
}
|
|
153
150
|
|
|
154
151
|
this.alarmMethods(alarmNode);
|
|
155
152
|
}
|
|
156
153
|
|
|
157
|
-
digitalAlarm(alarm, variableValue) {
|
|
154
|
+
digitalAlarm(alarm, variableValue, context = null) {
|
|
158
155
|
const alarmNode = alarm.node;
|
|
159
156
|
const alarmConfig = alarm.alarmConfig;
|
|
160
157
|
const enabled = alarmNode.getPropertyByName("enabled").readValue().value.value;
|
|
161
158
|
|
|
162
159
|
if (variableValue && enabled) {
|
|
163
|
-
this.raiseAlarm(alarmNode, alarmConfig.digitalMessage, alarmConfig.severity);
|
|
160
|
+
this.raiseAlarm(alarmNode, alarmConfig.digitalMessage, alarmConfig.severity, true, context);
|
|
164
161
|
} else {
|
|
165
|
-
this.clearAlarm(alarmNode, alarmConfig.digitalMessage, alarmConfig.severity);
|
|
162
|
+
this.clearAlarm(alarmNode, alarmConfig.digitalMessage, alarmConfig.severity, context);
|
|
166
163
|
}
|
|
167
164
|
|
|
168
165
|
this.alarmMethods(alarmNode);
|
|
@@ -184,9 +181,9 @@ class OpcUaAddressSpaceAlarm {
|
|
|
184
181
|
retain: false
|
|
185
182
|
});
|
|
186
183
|
|
|
187
|
-
this.raiseNewConditionAlarm(alarm, message, severity, false);
|
|
184
|
+
this.raiseNewConditionAlarm(alarm, message, severity, false, context);
|
|
188
185
|
} else {
|
|
189
|
-
this.raiseNewConditionAlarm(alarm, message, severity, true);
|
|
186
|
+
this.raiseNewConditionAlarm(alarm, message, severity, true, context);
|
|
190
187
|
}
|
|
191
188
|
|
|
192
189
|
callback(null, {
|
|
@@ -202,7 +199,7 @@ class OpcUaAddressSpaceAlarm {
|
|
|
202
199
|
alarm.ackedState.setValue(true);
|
|
203
200
|
alarm.confirmedState.setValue(false);
|
|
204
201
|
|
|
205
|
-
this.raiseNewConditionAlarm(alarm, message, severity, true);
|
|
202
|
+
this.raiseNewConditionAlarm(alarm, message, severity, true, context);
|
|
206
203
|
|
|
207
204
|
callback(null, {
|
|
208
205
|
statusCode: StatusCodes.Good,
|
|
@@ -225,16 +222,16 @@ class OpcUaAddressSpaceAlarm {
|
|
|
225
222
|
});
|
|
226
223
|
}
|
|
227
224
|
|
|
228
|
-
clearAlarm(alarmNode, message, severity) {
|
|
225
|
+
clearAlarm(alarmNode, message, severity, context = null) {
|
|
229
226
|
const isAcked = !alarmNode.ackedState.id.readValue().value.value;
|
|
230
227
|
|
|
231
228
|
alarmNode.activeState.setValue(false);
|
|
232
229
|
alarmNode.raiseNewCondition({ message, severity: severity, isAcked });
|
|
233
230
|
|
|
234
|
-
this.raiseNewConditionAlarm(alarmNode, message, severity, isAcked);
|
|
231
|
+
this.raiseNewConditionAlarm(alarmNode, message, severity, isAcked, context);
|
|
235
232
|
}
|
|
236
233
|
|
|
237
|
-
raiseAlarm(alarmNode, message, severity, retain = true) {
|
|
234
|
+
raiseAlarm(alarmNode, message, severity, retain = true, context = null) {
|
|
238
235
|
const isActive = alarmNode.activeState.id.readValue().value.value;
|
|
239
236
|
const isAcked = alarmNode.ackedState.id.readValue().value.value;
|
|
240
237
|
if (isActive && isAcked) {
|
|
@@ -247,10 +244,27 @@ class OpcUaAddressSpaceAlarm {
|
|
|
247
244
|
}
|
|
248
245
|
|
|
249
246
|
alarmNode.activeState.setValue(true);
|
|
250
|
-
this.raiseNewConditionAlarm(alarmNode, message, severity, retain);
|
|
247
|
+
this.raiseNewConditionAlarm(alarmNode, message, severity, retain, context);
|
|
251
248
|
}
|
|
252
249
|
|
|
253
|
-
|
|
250
|
+
getUserGroups(username) {
|
|
251
|
+
const normalized = String(username || "").trim();
|
|
252
|
+
if (!normalized || normalized.toLowerCase() === "anonymous") {
|
|
253
|
+
return [];
|
|
254
|
+
}
|
|
255
|
+
const users = (this.node && this.node.runtime && this.node.runtime.users) || [];
|
|
256
|
+
const user = users.find(u => u && u.username === normalized);
|
|
257
|
+
if (!user) {
|
|
258
|
+
return [];
|
|
259
|
+
}
|
|
260
|
+
return typeof user.group === "string"
|
|
261
|
+
? user.group.split(",").map(g => g.trim()).filter(Boolean)
|
|
262
|
+
: Array.isArray(user.group)
|
|
263
|
+
? user.group
|
|
264
|
+
: [];
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
raiseNewConditionAlarm(alarmNode, message, severity, retain, context = null) {
|
|
254
268
|
alarmNode.raiseNewCondition({ message, severity, retain });
|
|
255
269
|
|
|
256
270
|
this.registry.registerActiveAlarms(alarmNode, message, severity, retain, this.node);
|
|
@@ -258,12 +272,55 @@ class OpcUaAddressSpaceAlarm {
|
|
|
258
272
|
const alarmConfig = alarmNode.alarmConfig || {};
|
|
259
273
|
const sendValue = alarmConfig.sendValue !== false;
|
|
260
274
|
|
|
275
|
+
const ConditionName = alarmNode.getPropertyByName("ConditionName").readValue().value.value;
|
|
276
|
+
const SourceName = alarmNode.getPropertyByName("SourceName").readValue().value.value;
|
|
277
|
+
const isActive = alarmNode.activeState.id.readValue().value.value;
|
|
278
|
+
const isAcked = alarmNode.ackedState.id.readValue().value.value;
|
|
279
|
+
const ConfirmedState = alarmNode.confirmedState.id.readValue().value.value;
|
|
280
|
+
|
|
281
|
+
const activeContext = context || this.registry.activeWriteContext;
|
|
282
|
+
|
|
283
|
+
const users = [];
|
|
284
|
+
if (activeContext && activeContext.session) {
|
|
285
|
+
const session = activeContext.session;
|
|
286
|
+
const username = (session.userIdentityToken && session.userIdentityToken.userName)
|
|
287
|
+
? session.userIdentityToken.userName
|
|
288
|
+
: "anonymous";
|
|
289
|
+
const groups = this.getUserGroups(username);
|
|
290
|
+
users.push({
|
|
291
|
+
name: username,
|
|
292
|
+
groups: groups
|
|
293
|
+
});
|
|
294
|
+
} else {
|
|
295
|
+
users.push({
|
|
296
|
+
name: "anonymous",
|
|
297
|
+
groups: []
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
|
|
261
301
|
this.emitTagAccess("alarm", {
|
|
302
|
+
path: alarmNode.path || alarmNode.browseName.name,
|
|
303
|
+
nodeID: alarmNode.nodeId.toString(),
|
|
304
|
+
browseName: alarmNode.browseName.name,
|
|
262
305
|
message: message,
|
|
263
306
|
severity: severity,
|
|
264
307
|
retain: retain,
|
|
265
308
|
dataType: "alarm",
|
|
266
|
-
value: sendValue ? "highHighSp" : null
|
|
309
|
+
value: sendValue ? "highHighSp" : null,
|
|
310
|
+
activeState: isActive,
|
|
311
|
+
sourceName: SourceName,
|
|
312
|
+
conditionName: ConditionName,
|
|
313
|
+
ConfirmedState: ConfirmedState,
|
|
314
|
+
ackedState: isAcked,
|
|
315
|
+
users: users,
|
|
316
|
+
alarmNode: {
|
|
317
|
+
nodeId: alarmNode.nodeId,
|
|
318
|
+
browseName: alarmNode.browseName,
|
|
319
|
+
displayName: alarmNode.displayName,
|
|
320
|
+
description: alarmNode.description,
|
|
321
|
+
nodeClass: alarmNode.nodeClass,
|
|
322
|
+
typeDefinition: alarmNode.typeDefinition
|
|
323
|
+
}
|
|
267
324
|
});
|
|
268
325
|
}
|
|
269
326
|
|