@vitormnm/node-red-simple-opcua 1.6.3 → 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 +104 -136
- package/client/lib/opcua-client-browser.js +254 -11
- package/client/lib/opcua-client-method-service.js +1 -1
- package/client/lib/opcua-client-subscription-service.js +0 -2
- package/client/lib/opcua-client-write-service.js +14 -4
- package/client/opcua-client-config.html +118 -1
- package/client/opcua-client-config.js +112 -9
- package/client/opcua-client-help.html +6 -0
- package/client/opcua-client-utils.js +158 -10
- package/client/opcua-client.html +8 -0
- package/client/opcua-client.js +97 -1
- package/client/view/opcua-client.js +106 -14
- package/examples/flows_simple_opc.json +1 -1
- package/package.json +2 -2
- package/server/lib/opcua-address-space-alarm.js +95 -32
- package/server/lib/opcua-address-space-builder.js +717 -59
- package/server/lib/opcua-config.js +110 -35
- package/server/lib/opcua-server-events-child.js +31 -5
- package/server/lib/opcua-server-runtime-child.js +424 -27
- package/server/lib/opcua-server-runtime.js +52 -5
- package/server/lib/opcua-server-status-child.js +46 -15
- package/server/nodered/simple_opcua/server/certificates/mutex +0 -0
- package/server/nodered/simple_opcua/server/certificates/own/certs/server_selfsigned_cert_2048.pem +25 -0
- package/server/nodered/simple_opcua/server/certificates/own/certs/server_selfsigned_cert_2048.pem.mutex +0 -0
- package/server/nodered/simple_opcua/server/certificates/own/openssl.cnf +72 -0
- package/server/nodered/simple_opcua/server/certificates/own/private/private_key.pem +28 -0
- package/server/nodered/simple_opcua/server/certificates/trusted/certs/NodeOPCUA-Client@tuf[c5a9e20a8b680cdff76aaf0165bb3c9318da37a5].pem +25 -0
- package/server/nodered/simple_opcua/server/myServer1/mutex +0 -0
- package/server/nodered/simple_opcua/server/myServer1/own/certs/server_selfsigned_cert_2048.pem +25 -0
- package/server/nodered/simple_opcua/server/myServer1/own/certs/server_selfsigned_cert_2048.pem.mutex +0 -0
- package/server/nodered/simple_opcua/server/myServer1/own/openssl.cnf +72 -0
- package/server/nodered/simple_opcua/server/myServer1/own/private/private_key.pem +28 -0
- package/server/nodered/simple_opcua/server/myServer1/trusted/certs/NodeOPCUA-Client@tuf[91e520c64ff891c67168f08a46dd194071e15dae].pem +25 -0
- package/server/nodered/simple_opcua/server/myServer1/trusted/certs/NodeOPCUA-Client@tuf[98ae95da627cea4c500753c319161a3554ee38d7].pem +25 -0
- package/server/nodered/simple_opcua/server/myServer1/trusted/certs/NodeOPCUA-Client@tuf[aef8d7a1cfba13d84189a0bcf1694208fc51a7f9].pem +25 -0
- package/server/nodered/simple_opcua/server/myServer1/trusted/certs/NodeOPCUA-Client@tuf[c5a9e20a8b680cdff76aaf0165bb3c9318da37a5].pem +25 -0
- package/server/nodered/simple_opcua/server/myServer1/trusted/certs/NodeOPCUA-Client@tuf[ebdf9acf1d02e347917a14108d3144799c638ea3].pem +25 -0
- package/server/opcua-server-io.html +93 -1
- package/server/opcua-server-io.js +153 -29
- package/server/opcua-server-registry.js +8 -2
- package/server/opcua-server.css +64 -0
- package/server/opcua-server.html +168 -44
- package/server/opcua-server.js +115 -5
- package/server/view/opcua-server.css +100 -6
- package/server/view/opcua-server.js +746 -48
|
@@ -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) {
|
|
@@ -94,6 +90,7 @@ class OpcUaAddressSpaceAlarm {
|
|
|
94
90
|
value: sourceName
|
|
95
91
|
});
|
|
96
92
|
|
|
93
|
+
alarmNode.alarmConfig = alarmConfig;
|
|
97
94
|
return alarmNode;
|
|
98
95
|
} catch (error) {
|
|
99
96
|
console.error("createAlarm");
|
|
@@ -101,21 +98,21 @@ class OpcUaAddressSpaceAlarm {
|
|
|
101
98
|
}
|
|
102
99
|
}
|
|
103
100
|
|
|
104
|
-
checkAlarm(alarm, variableValue) {
|
|
101
|
+
checkAlarm(alarm, variableValue, context = null) {
|
|
105
102
|
if (alarm) {
|
|
106
103
|
const alarmConfig = alarm.alarmConfig;
|
|
107
104
|
const type = alarmConfig.type;
|
|
108
105
|
|
|
109
106
|
if (type === "levelAlarm") {
|
|
110
|
-
this.levelAlarm(alarm, variableValue);
|
|
107
|
+
this.levelAlarm(alarm, variableValue, context);
|
|
111
108
|
}
|
|
112
109
|
if (type === "digitalAlarm") {
|
|
113
|
-
this.digitalAlarm(alarm, variableValue);
|
|
110
|
+
this.digitalAlarm(alarm, variableValue, context);
|
|
114
111
|
}
|
|
115
112
|
}
|
|
116
113
|
}
|
|
117
114
|
|
|
118
|
-
levelAlarm(alarm, variableValue) {
|
|
115
|
+
levelAlarm(alarm, variableValue, context = null) {
|
|
119
116
|
const alarmNode = alarm.node;
|
|
120
117
|
const alarmConfig = alarm.alarmConfig;
|
|
121
118
|
|
|
@@ -128,38 +125,41 @@ class OpcUaAddressSpaceAlarm {
|
|
|
128
125
|
let lastMessage = null;
|
|
129
126
|
let message = null;
|
|
130
127
|
|
|
128
|
+
const sendValue = alarmConfig.sendValue !== false;
|
|
129
|
+
|
|
131
130
|
if (variableValue >= highHighSp && enabled) {
|
|
132
|
-
message = alarmConfig.highHighMessage + ": " + variableValue;
|
|
133
|
-
this.raiseAlarm(alarmNode, message, alarmConfig.severity);
|
|
131
|
+
message = sendValue ? (alarmConfig.highHighMessage + ": " + variableValue) : alarmConfig.highHighMessage;
|
|
132
|
+
this.raiseAlarm(alarmNode, message, alarmConfig.severity, true, context);
|
|
134
133
|
lastMessage = message;
|
|
135
134
|
} else if (variableValue >= highSp && enabled) {
|
|
136
|
-
message = alarmConfig.highMessage + ": " + variableValue;
|
|
137
|
-
this.raiseAlarm(alarmNode, message, alarmConfig.severity);
|
|
135
|
+
message = sendValue ? (alarmConfig.highMessage + ": " + variableValue) : alarmConfig.highMessage;
|
|
136
|
+
this.raiseAlarm(alarmNode, message, alarmConfig.severity, true, context);
|
|
138
137
|
lastMessage = message;
|
|
139
138
|
} else if (variableValue <= lowLowSp && enabled) {
|
|
140
|
-
message = alarmConfig.lowLowMessage + ": " + variableValue;
|
|
141
|
-
this.raiseAlarm(alarmNode, message, alarmConfig.severity);
|
|
139
|
+
message = sendValue ? (alarmConfig.lowLowMessage + ": " + variableValue) : alarmConfig.lowLowMessage;
|
|
140
|
+
this.raiseAlarm(alarmNode, message, alarmConfig.severity, true, context);
|
|
142
141
|
lastMessage = message;
|
|
143
142
|
} else if (variableValue <= lowSp && enabled) {
|
|
144
|
-
message = alarmConfig.lowMessage + ": " + variableValue;
|
|
145
|
-
this.raiseAlarm(alarmNode, message, alarmConfig.severity);
|
|
143
|
+
message = sendValue ? (alarmConfig.lowMessage + ": " + variableValue) : alarmConfig.lowMessage;
|
|
144
|
+
this.raiseAlarm(alarmNode, message, alarmConfig.severity, true, context);
|
|
146
145
|
lastMessage = message;
|
|
147
146
|
} else if (isActive) {
|
|
148
|
-
|
|
147
|
+
message = sendValue ? (alarmConfig.normalMessage + ": " + variableValue) : alarmConfig.normalMessage;
|
|
148
|
+
this.clearAlarm(alarmNode, lastMessage || message, alarmConfig.severity, context);
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
this.alarmMethods(alarmNode);
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
-
digitalAlarm(alarm, variableValue) {
|
|
154
|
+
digitalAlarm(alarm, variableValue, context = null) {
|
|
155
155
|
const alarmNode = alarm.node;
|
|
156
156
|
const alarmConfig = alarm.alarmConfig;
|
|
157
157
|
const enabled = alarmNode.getPropertyByName("enabled").readValue().value.value;
|
|
158
158
|
|
|
159
159
|
if (variableValue && enabled) {
|
|
160
|
-
this.raiseAlarm(alarmNode, alarmConfig.digitalMessage, alarmConfig.severity);
|
|
160
|
+
this.raiseAlarm(alarmNode, alarmConfig.digitalMessage, alarmConfig.severity, true, context);
|
|
161
161
|
} else {
|
|
162
|
-
this.clearAlarm(alarmNode, alarmConfig.digitalMessage, alarmConfig.severity);
|
|
162
|
+
this.clearAlarm(alarmNode, alarmConfig.digitalMessage, alarmConfig.severity, context);
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
this.alarmMethods(alarmNode);
|
|
@@ -181,9 +181,9 @@ class OpcUaAddressSpaceAlarm {
|
|
|
181
181
|
retain: false
|
|
182
182
|
});
|
|
183
183
|
|
|
184
|
-
this.raiseNewConditionAlarm(alarm, message, severity, false);
|
|
184
|
+
this.raiseNewConditionAlarm(alarm, message, severity, false, context);
|
|
185
185
|
} else {
|
|
186
|
-
this.raiseNewConditionAlarm(alarm, message, severity, true);
|
|
186
|
+
this.raiseNewConditionAlarm(alarm, message, severity, true, context);
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
callback(null, {
|
|
@@ -199,7 +199,7 @@ class OpcUaAddressSpaceAlarm {
|
|
|
199
199
|
alarm.ackedState.setValue(true);
|
|
200
200
|
alarm.confirmedState.setValue(false);
|
|
201
201
|
|
|
202
|
-
this.raiseNewConditionAlarm(alarm, message, severity, true);
|
|
202
|
+
this.raiseNewConditionAlarm(alarm, message, severity, true, context);
|
|
203
203
|
|
|
204
204
|
callback(null, {
|
|
205
205
|
statusCode: StatusCodes.Good,
|
|
@@ -222,16 +222,16 @@ class OpcUaAddressSpaceAlarm {
|
|
|
222
222
|
});
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
-
clearAlarm(alarmNode, message, severity) {
|
|
225
|
+
clearAlarm(alarmNode, message, severity, context = null) {
|
|
226
226
|
const isAcked = !alarmNode.ackedState.id.readValue().value.value;
|
|
227
227
|
|
|
228
228
|
alarmNode.activeState.setValue(false);
|
|
229
229
|
alarmNode.raiseNewCondition({ message, severity: severity, isAcked });
|
|
230
230
|
|
|
231
|
-
this.raiseNewConditionAlarm(alarmNode, message, severity, isAcked);
|
|
231
|
+
this.raiseNewConditionAlarm(alarmNode, message, severity, isAcked, context);
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
-
raiseAlarm(alarmNode, message, severity, retain = true) {
|
|
234
|
+
raiseAlarm(alarmNode, message, severity, retain = true, context = null) {
|
|
235
235
|
const isActive = alarmNode.activeState.id.readValue().value.value;
|
|
236
236
|
const isAcked = alarmNode.ackedState.id.readValue().value.value;
|
|
237
237
|
if (isActive && isAcked) {
|
|
@@ -244,20 +244,83 @@ class OpcUaAddressSpaceAlarm {
|
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
alarmNode.activeState.setValue(true);
|
|
247
|
-
this.raiseNewConditionAlarm(alarmNode, message, severity, retain);
|
|
247
|
+
this.raiseNewConditionAlarm(alarmNode, message, severity, retain, context);
|
|
248
|
+
}
|
|
249
|
+
|
|
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
|
+
: [];
|
|
248
265
|
}
|
|
249
266
|
|
|
250
|
-
raiseNewConditionAlarm(alarmNode, message, severity, retain) {
|
|
267
|
+
raiseNewConditionAlarm(alarmNode, message, severity, retain, context = null) {
|
|
251
268
|
alarmNode.raiseNewCondition({ message, severity, retain });
|
|
252
269
|
|
|
253
270
|
this.registry.registerActiveAlarms(alarmNode, message, severity, retain, this.node);
|
|
254
271
|
|
|
272
|
+
const alarmConfig = alarmNode.alarmConfig || {};
|
|
273
|
+
const sendValue = alarmConfig.sendValue !== false;
|
|
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
|
+
|
|
255
301
|
this.emitTagAccess("alarm", {
|
|
302
|
+
path: alarmNode.path || alarmNode.browseName.name,
|
|
303
|
+
nodeID: alarmNode.nodeId.toString(),
|
|
304
|
+
browseName: alarmNode.browseName.name,
|
|
256
305
|
message: message,
|
|
257
306
|
severity: severity,
|
|
258
307
|
retain: retain,
|
|
259
308
|
dataType: "alarm",
|
|
260
|
-
value: "highHighSp"
|
|
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
|
+
}
|
|
261
324
|
});
|
|
262
325
|
}
|
|
263
326
|
|