node-opcua-samples 2.56.3 → 2.60.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/LICENSE +20 -20
- package/bin/createOPCUACertificate.cmd +5 -5
- package/bin/create_certificates.js +2 -2
- package/bin/crypto_create_CA.js +2 -2
- package/bin/demo_server_with_alarm.js +51 -51
- package/bin/di_server.js +318 -318
- package/bin/findServersOnNetwork.js +32 -32
- package/bin/interactive_client.js +758 -758
- package/bin/machineryServer.js +83 -83
- package/bin/more.js +40 -40
- package/bin/node-opcua.js +2 -2
- package/bin/opcua_interceptor.js +135 -135
- package/bin/simple_client.js +830 -830
- package/bin/simple_server.js +588 -588
- package/package.json +7 -7
package/bin/di_server.js
CHANGED
|
@@ -1,318 +1,318 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
const chalk = require("chalk");
|
|
4
|
-
const opcua = require("node-opcua");
|
|
5
|
-
const path = require("path");
|
|
6
|
-
const os = require("os");
|
|
7
|
-
|
|
8
|
-
Error.stackTraceLimit = Infinity;
|
|
9
|
-
|
|
10
|
-
function constructFilename(filename) {
|
|
11
|
-
return path.join(__dirname, "../", filename);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const { assert } = require("node-opcua-assert");
|
|
15
|
-
const argv = require("yargs")
|
|
16
|
-
.wrap(132)
|
|
17
|
-
|
|
18
|
-
.string("alternateHostname")
|
|
19
|
-
.describe("alternateHostname")
|
|
20
|
-
.alias("a", "alternateHostname")
|
|
21
|
-
|
|
22
|
-
.string("port")
|
|
23
|
-
.describe("port")
|
|
24
|
-
.alias("p", "port")
|
|
25
|
-
|
|
26
|
-
.number("keySize")
|
|
27
|
-
.describe("keySize", "certificate keySize [1024|2048|3072|4096]")
|
|
28
|
-
.default("keySize", 2048)
|
|
29
|
-
.alias("k", "keySize")
|
|
30
|
-
|
|
31
|
-
.string("discoveryServerEndpointUrl")
|
|
32
|
-
.describe("discoveryServerEndpointUrl", " end point of the discovery server to regiser to")
|
|
33
|
-
.default("discoveryServerEndpointUrl", "opc.tcp://localhost:4840")
|
|
34
|
-
.alias("d", "discoveryServerEndpointUrl")
|
|
35
|
-
.argv;
|
|
36
|
-
|
|
37
|
-
const OPCUAServer = opcua.OPCUAServer;
|
|
38
|
-
const Variant = opcua.Variant;
|
|
39
|
-
const DataType = opcua.DataType;
|
|
40
|
-
|
|
41
|
-
const makeApplicationUrn = opcua.makeApplicationUrn;
|
|
42
|
-
const nodesets = opcua.nodesets;
|
|
43
|
-
|
|
44
|
-
const port = parseInt(argv.port) || 26543;
|
|
45
|
-
|
|
46
|
-
const userManager = {
|
|
47
|
-
isValidUser: function(userName, password) {
|
|
48
|
-
|
|
49
|
-
if (userName === "user1" && password === "password1") {
|
|
50
|
-
return true;
|
|
51
|
-
}
|
|
52
|
-
if (userName === "user2" && password === "password2") {
|
|
53
|
-
return true;
|
|
54
|
-
}
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const keySize = argv.keySize;
|
|
61
|
-
const server_certificate_file = constructFilename("certificates/server_selfsigned_cert_" + keySize + ".pem");
|
|
62
|
-
const server_certificate_privatekey_file = constructFilename("certificates/server_key_" + keySize + ".pem");
|
|
63
|
-
|
|
64
|
-
const server_options = {
|
|
65
|
-
|
|
66
|
-
certificateFile: server_certificate_file,
|
|
67
|
-
privateKeyFile: server_certificate_privatekey_file,
|
|
68
|
-
|
|
69
|
-
port,
|
|
70
|
-
resourcePath: "/UA/Server",
|
|
71
|
-
|
|
72
|
-
maxAllowedSessionNumber: 1500,
|
|
73
|
-
|
|
74
|
-
nodeset_filename: [
|
|
75
|
-
nodesets.standard,
|
|
76
|
-
nodesets.di,
|
|
77
|
-
nodesets.adi
|
|
78
|
-
],
|
|
79
|
-
|
|
80
|
-
serverInfo: {
|
|
81
|
-
applicationUri: makeApplicationUrn(os.hostname(), "NodeOPCUA-SimpleADIDemoServer"),
|
|
82
|
-
productUri: "urn:NodeOPCUA-SimpleADIDemoServer",
|
|
83
|
-
applicationName: { text: "NodeOPCUA-SimpleADIDemoServer" },
|
|
84
|
-
gatewayServerUri: null,
|
|
85
|
-
discoveryProfileUri: null,
|
|
86
|
-
discoveryUrls: []
|
|
87
|
-
},
|
|
88
|
-
buildInfo: {
|
|
89
|
-
buildNumber: "1234"
|
|
90
|
-
},
|
|
91
|
-
serverCapabilities: {
|
|
92
|
-
operationLimits: {
|
|
93
|
-
maxNodesPerRead: 1000,
|
|
94
|
-
maxNodesPerBrowse: 2000
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
userManager: userManager,
|
|
98
|
-
registerServerMethod: opcua.RegisterServerMethod.LDS,
|
|
99
|
-
discoveryServerEndpointUrl: argv.discoveryServerEndpointUrl || "opc.tcp://" + require("os").hostname() + ":4840"
|
|
100
|
-
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
process.title = "Node OPCUA Server on port : " + server_options.port;
|
|
104
|
-
|
|
105
|
-
server_options.alternateHostname = argv.alternateHostname;
|
|
106
|
-
|
|
107
|
-
const server = new OPCUAServer(server_options);
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
const hostname = require("os").hostname();
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
server.on("post_initialize", function() {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const addressSpace = server.engine.addressSpace;
|
|
118
|
-
|
|
119
|
-
const namespace = addressSpace.getOwnNamespace();
|
|
120
|
-
|
|
121
|
-
const rootFolder = addressSpace.findNode("RootFolder");
|
|
122
|
-
assert(rootFolder.browseName.toString() === "Root");
|
|
123
|
-
|
|
124
|
-
const deviceSet = rootFolder.objects.deviceSet;
|
|
125
|
-
assert(deviceSet.browseName.toString() === "2:DeviceSet");
|
|
126
|
-
|
|
127
|
-
const baseObjectType = addressSpace.findObjectType("BaseObjectType");
|
|
128
|
-
|
|
129
|
-
const nsDI = addressSpace.getNamespaceIndex("http://opcfoundation.org/UA/DI/");
|
|
130
|
-
const topologyElementType = addressSpace.findObjectType("TopologyElementType", nsDI);
|
|
131
|
-
|
|
132
|
-
const nsADI = addressSpace.getNamespaceIndex("http://opcfoundation.org/UA/ADI/");
|
|
133
|
-
|
|
134
|
-
const spectrometerDeviceType = addressSpace.findObjectType("SpectrometerDeviceType", nsADI);
|
|
135
|
-
assert(spectrometerDeviceType.browseName.toString() === "3:SpectrometerDeviceType");
|
|
136
|
-
|
|
137
|
-
const analyserChannelType = addressSpace.findObjectType("AnalyserChannelType", nsADI);
|
|
138
|
-
const accessorySlotType = addressSpace.findObjectType("AccessorySlotType", nsADI);
|
|
139
|
-
const functionalGroupType = addressSpace.findObjectType("FunctionalGroupType", nsADI);
|
|
140
|
-
|
|
141
|
-
const checkFunctionAlarmType = addressSpace.findEventType("CheckFunctionAlarmType", nsDI);
|
|
142
|
-
console.log("checkFunctionAlarmType = ", checkFunctionAlarmType.toString());
|
|
143
|
-
|
|
144
|
-
console.log("ADI namespace = ", nsADI);
|
|
145
|
-
console.log("ADI namespace = ", spectrometerDeviceType.browseName.toString());
|
|
146
|
-
console.log("discoveryServerEndpointUrl ", server.discoveryServerEndpointUrl);
|
|
147
|
-
|
|
148
|
-
const mySpectrometer = spectrometerDeviceType.instantiate({ browseName: "MySpectrometer", organizedBy: deviceSet });
|
|
149
|
-
// create a spectro meter
|
|
150
|
-
|
|
151
|
-
function createChannel(options) {
|
|
152
|
-
assert(typeof options.browseName === "string");
|
|
153
|
-
assert(options.componentOf);
|
|
154
|
-
|
|
155
|
-
const channel = analyserChannelType.instantiate({
|
|
156
|
-
browseName: options.browseName,
|
|
157
|
-
componentOf: options.componentOf,
|
|
158
|
-
optionals: ["ParameterSet"]
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
const parameterSet = channel.parameterSet;
|
|
162
|
-
|
|
163
|
-
//var parameterSet = topologyElementType.instantiate({ browseName: "ParameterSet", componentOf: channel });
|
|
164
|
-
/// var methodSet = topologyElementType.instantiate({ browseName: "MethodSet", componentOf: channel });
|
|
165
|
-
|
|
166
|
-
namespace.addVariable({
|
|
167
|
-
componentOf: parameterSet,
|
|
168
|
-
browseName: "MyParameter",
|
|
169
|
-
typeDefinition: "DataItemType",
|
|
170
|
-
dataType: DataType.Double,
|
|
171
|
-
value: new Variant({ dataType: DataType.Double, value: 10.0 })
|
|
172
|
-
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
return channel;
|
|
176
|
-
}
|
|
177
|
-
// add channel 1
|
|
178
|
-
const channel1 = createChannel({ browseName: "Channel1", componentOf: mySpectrometer });
|
|
179
|
-
const channel2 = createChannel({ browseName: "Channel2", componentOf: mySpectrometer });
|
|
180
|
-
|
|
181
|
-
console.log(mySpectrometer.toString());
|
|
182
|
-
|
|
183
|
-
console.log(mySpectrometer.channel1.toString());
|
|
184
|
-
|
|
185
|
-
// var networkSet = rootFolder.networkSet;
|
|
186
|
-
//var networkType = addressSpace.findObjectType("2:NetworkType");
|
|
187
|
-
//var network = networkType.instantiate({ browseName: "MyNetwork", organizedBy: networkSet });
|
|
188
|
-
|
|
189
|
-
//------------------------------------------------------------------------------
|
|
190
|
-
// Add a view
|
|
191
|
-
//------------------------------------------------------------------------------
|
|
192
|
-
const view = namespace.addView({
|
|
193
|
-
organizedBy: rootFolder.views,
|
|
194
|
-
browseName: "MyView"
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
const createBoilerType = opcua.createBoilerType;
|
|
198
|
-
const makeBoiler = opcua.makeBoiler;
|
|
199
|
-
|
|
200
|
-
createBoilerType(namespace);
|
|
201
|
-
makeBoiler(addressSpace, {
|
|
202
|
-
browseName: "Boiler#1"
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
function dumpNode(node) {
|
|
211
|
-
function w(str, width) {
|
|
212
|
-
const tmp = str + " ";
|
|
213
|
-
return tmp.substr(0, width);
|
|
214
|
-
}
|
|
215
|
-
return Object.entries(node).map((key,value) =>
|
|
216
|
-
" " + w(key, 30) + " : " + ((value === null) ? null : value.toString())
|
|
217
|
-
).join("\n");
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
console.log(chalk.yellow(" server PID :"), process.pid);
|
|
222
|
-
|
|
223
|
-
server.start(function(err) {
|
|
224
|
-
if (err) {
|
|
225
|
-
console.log(" Server failed to start ... exiting");
|
|
226
|
-
process.exit(-3);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
const endpointUrl = server.getEndpointUrl();
|
|
230
|
-
|
|
231
|
-
console.log(chalk.yellow(" server on port :"), server.endpoints[0].port.toString());
|
|
232
|
-
console.log(chalk.yellow(" endpointUrl :"), endpointUrl);
|
|
233
|
-
|
|
234
|
-
console.log(chalk.yellow(" serverInfo :"));
|
|
235
|
-
console.log(dumpNode(server.serverInfo));
|
|
236
|
-
console.log(chalk.yellow(" buildInfo :"));
|
|
237
|
-
console.log(dumpNode(server.engine.buildInfo));
|
|
238
|
-
|
|
239
|
-
console.log("Certificate file = ", server.certificateFile);
|
|
240
|
-
console.log(chalk.yellow("\n server now waiting for connections. CTRL+C to stop"));
|
|
241
|
-
|
|
242
|
-
console.log(server.buildInfo.toString());
|
|
243
|
-
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
server.on("create_session", function(session) {
|
|
247
|
-
|
|
248
|
-
console.log(" SESSION CREATED");
|
|
249
|
-
console.log(chalk.cyan(" client application URI: "), session.clientDescription.applicationUri);
|
|
250
|
-
console.log(chalk.cyan(" client product URI: "), session.clientDescription.productUri);
|
|
251
|
-
console.log(chalk.cyan(" client application name: "), session.clientDescription.applicationName.toString());
|
|
252
|
-
console.log(chalk.cyan(" client application type: "), session.clientDescription.applicationType.toString());
|
|
253
|
-
console.log(chalk.cyan(" session name: "), session.sessionName ? session.sessionName.toString() : "<null>");
|
|
254
|
-
console.log(chalk.cyan(" session timeout: "), session.sessionTimeout);
|
|
255
|
-
console.log(chalk.cyan(" session id: "), session.sessionId);
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
server.on("session_closed", function(session, reason) {
|
|
259
|
-
console.log(" SESSION CLOSED :", reason);
|
|
260
|
-
console.log(chalk.cyan(" session name: "), session.sessionName ? session.sessionName.toString() : "<null>");
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
function w(s, w) {
|
|
264
|
-
return ("000" + s).substr(-w);
|
|
265
|
-
}
|
|
266
|
-
function t(d) {
|
|
267
|
-
return w(d.getHours(), 2) + ":" + w(d.getMinutes(), 2) + ":" + w(d.getSeconds(), 2) + ":" + w(d.getMilliseconds(), 3);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
server.on("response", function(response) {
|
|
271
|
-
console.log(t(response.responseHeader.timestamp), response.responseHeader.requestHandle,
|
|
272
|
-
response.schema.name, " status = ", response.responseHeader.serviceResult.toString());
|
|
273
|
-
switch (response.schema.name) {
|
|
274
|
-
case "ModifySubscriptionResponse":
|
|
275
|
-
case "CreateMonitoredItemsResponse":
|
|
276
|
-
case "RepublishResponse":
|
|
277
|
-
case "WriteResponse":
|
|
278
|
-
//xx console.log(response.toString());
|
|
279
|
-
break;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
function indent(str, nb) {
|
|
285
|
-
const spacer = " ".slice(0, nb);
|
|
286
|
-
return str.split("\n").map(function(s) { return spacer + s; }).join("\n");
|
|
287
|
-
}
|
|
288
|
-
server.on("request", function(request, channel) {
|
|
289
|
-
console.log(t(request.requestHeader.timestamp), request.requestHeader.requestHandle,
|
|
290
|
-
request.schema.name, " ID =", channel.channelId.toString());
|
|
291
|
-
switch (request.schema.name) {
|
|
292
|
-
case "ModifySubscriptionRequest":
|
|
293
|
-
case "CreateMonitoredItemsRequest":
|
|
294
|
-
case "RepublishRequest":
|
|
295
|
-
//xx console.log(request.toString());
|
|
296
|
-
break;
|
|
297
|
-
case "ReadRequest":
|
|
298
|
-
break;
|
|
299
|
-
case "WriteRequest":
|
|
300
|
-
break;
|
|
301
|
-
case "TranslateBrowsePathsToNodeIdsRequest":
|
|
302
|
-
break;
|
|
303
|
-
}
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
process.on("SIGINT", function() {
|
|
307
|
-
// only work on linux apparently
|
|
308
|
-
console.log(chalk.red.bold(" Received server interruption from user "));
|
|
309
|
-
console.log(chalk.red.bold(" shutting down ..."));
|
|
310
|
-
server.shutdown(1000, function() {
|
|
311
|
-
console.log(chalk.red.bold(" shutting down completed "));
|
|
312
|
-
console.log(chalk.red.bold(" done "));
|
|
313
|
-
console.log("");
|
|
314
|
-
process.exit(-1);
|
|
315
|
-
});
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
const chalk = require("chalk");
|
|
4
|
+
const opcua = require("node-opcua");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const os = require("os");
|
|
7
|
+
|
|
8
|
+
Error.stackTraceLimit = Infinity;
|
|
9
|
+
|
|
10
|
+
function constructFilename(filename) {
|
|
11
|
+
return path.join(__dirname, "../", filename);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const { assert } = require("node-opcua-assert");
|
|
15
|
+
const argv = require("yargs")
|
|
16
|
+
.wrap(132)
|
|
17
|
+
|
|
18
|
+
.string("alternateHostname")
|
|
19
|
+
.describe("alternateHostname")
|
|
20
|
+
.alias("a", "alternateHostname")
|
|
21
|
+
|
|
22
|
+
.string("port")
|
|
23
|
+
.describe("port")
|
|
24
|
+
.alias("p", "port")
|
|
25
|
+
|
|
26
|
+
.number("keySize")
|
|
27
|
+
.describe("keySize", "certificate keySize [1024|2048|3072|4096]")
|
|
28
|
+
.default("keySize", 2048)
|
|
29
|
+
.alias("k", "keySize")
|
|
30
|
+
|
|
31
|
+
.string("discoveryServerEndpointUrl")
|
|
32
|
+
.describe("discoveryServerEndpointUrl", " end point of the discovery server to regiser to")
|
|
33
|
+
.default("discoveryServerEndpointUrl", "opc.tcp://localhost:4840")
|
|
34
|
+
.alias("d", "discoveryServerEndpointUrl")
|
|
35
|
+
.argv;
|
|
36
|
+
|
|
37
|
+
const OPCUAServer = opcua.OPCUAServer;
|
|
38
|
+
const Variant = opcua.Variant;
|
|
39
|
+
const DataType = opcua.DataType;
|
|
40
|
+
|
|
41
|
+
const makeApplicationUrn = opcua.makeApplicationUrn;
|
|
42
|
+
const nodesets = opcua.nodesets;
|
|
43
|
+
|
|
44
|
+
const port = parseInt(argv.port) || 26543;
|
|
45
|
+
|
|
46
|
+
const userManager = {
|
|
47
|
+
isValidUser: function(userName, password) {
|
|
48
|
+
|
|
49
|
+
if (userName === "user1" && password === "password1") {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
if (userName === "user2" && password === "password2") {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
const keySize = argv.keySize;
|
|
61
|
+
const server_certificate_file = constructFilename("certificates/server_selfsigned_cert_" + keySize + ".pem");
|
|
62
|
+
const server_certificate_privatekey_file = constructFilename("certificates/server_key_" + keySize + ".pem");
|
|
63
|
+
|
|
64
|
+
const server_options = {
|
|
65
|
+
|
|
66
|
+
certificateFile: server_certificate_file,
|
|
67
|
+
privateKeyFile: server_certificate_privatekey_file,
|
|
68
|
+
|
|
69
|
+
port,
|
|
70
|
+
resourcePath: "/UA/Server",
|
|
71
|
+
|
|
72
|
+
maxAllowedSessionNumber: 1500,
|
|
73
|
+
|
|
74
|
+
nodeset_filename: [
|
|
75
|
+
nodesets.standard,
|
|
76
|
+
nodesets.di,
|
|
77
|
+
nodesets.adi
|
|
78
|
+
],
|
|
79
|
+
|
|
80
|
+
serverInfo: {
|
|
81
|
+
applicationUri: makeApplicationUrn(os.hostname(), "NodeOPCUA-SimpleADIDemoServer"),
|
|
82
|
+
productUri: "urn:NodeOPCUA-SimpleADIDemoServer",
|
|
83
|
+
applicationName: { text: "NodeOPCUA-SimpleADIDemoServer" },
|
|
84
|
+
gatewayServerUri: null,
|
|
85
|
+
discoveryProfileUri: null,
|
|
86
|
+
discoveryUrls: []
|
|
87
|
+
},
|
|
88
|
+
buildInfo: {
|
|
89
|
+
buildNumber: "1234"
|
|
90
|
+
},
|
|
91
|
+
serverCapabilities: {
|
|
92
|
+
operationLimits: {
|
|
93
|
+
maxNodesPerRead: 1000,
|
|
94
|
+
maxNodesPerBrowse: 2000
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
userManager: userManager,
|
|
98
|
+
registerServerMethod: opcua.RegisterServerMethod.LDS,
|
|
99
|
+
discoveryServerEndpointUrl: argv.discoveryServerEndpointUrl || "opc.tcp://" + require("os").hostname() + ":4840"
|
|
100
|
+
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
process.title = "Node OPCUA Server on port : " + server_options.port;
|
|
104
|
+
|
|
105
|
+
server_options.alternateHostname = argv.alternateHostname;
|
|
106
|
+
|
|
107
|
+
const server = new OPCUAServer(server_options);
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
const hostname = require("os").hostname();
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
server.on("post_initialize", function() {
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
const addressSpace = server.engine.addressSpace;
|
|
118
|
+
|
|
119
|
+
const namespace = addressSpace.getOwnNamespace();
|
|
120
|
+
|
|
121
|
+
const rootFolder = addressSpace.findNode("RootFolder");
|
|
122
|
+
assert(rootFolder.browseName.toString() === "Root");
|
|
123
|
+
|
|
124
|
+
const deviceSet = rootFolder.objects.deviceSet;
|
|
125
|
+
assert(deviceSet.browseName.toString() === "2:DeviceSet");
|
|
126
|
+
|
|
127
|
+
const baseObjectType = addressSpace.findObjectType("BaseObjectType");
|
|
128
|
+
|
|
129
|
+
const nsDI = addressSpace.getNamespaceIndex("http://opcfoundation.org/UA/DI/");
|
|
130
|
+
const topologyElementType = addressSpace.findObjectType("TopologyElementType", nsDI);
|
|
131
|
+
|
|
132
|
+
const nsADI = addressSpace.getNamespaceIndex("http://opcfoundation.org/UA/ADI/");
|
|
133
|
+
|
|
134
|
+
const spectrometerDeviceType = addressSpace.findObjectType("SpectrometerDeviceType", nsADI);
|
|
135
|
+
assert(spectrometerDeviceType.browseName.toString() === "3:SpectrometerDeviceType");
|
|
136
|
+
|
|
137
|
+
const analyserChannelType = addressSpace.findObjectType("AnalyserChannelType", nsADI);
|
|
138
|
+
const accessorySlotType = addressSpace.findObjectType("AccessorySlotType", nsADI);
|
|
139
|
+
const functionalGroupType = addressSpace.findObjectType("FunctionalGroupType", nsADI);
|
|
140
|
+
|
|
141
|
+
const checkFunctionAlarmType = addressSpace.findEventType("CheckFunctionAlarmType", nsDI);
|
|
142
|
+
console.log("checkFunctionAlarmType = ", checkFunctionAlarmType.toString());
|
|
143
|
+
|
|
144
|
+
console.log("ADI namespace = ", nsADI);
|
|
145
|
+
console.log("ADI namespace = ", spectrometerDeviceType.browseName.toString());
|
|
146
|
+
console.log("discoveryServerEndpointUrl ", server.discoveryServerEndpointUrl);
|
|
147
|
+
|
|
148
|
+
const mySpectrometer = spectrometerDeviceType.instantiate({ browseName: "MySpectrometer", organizedBy: deviceSet });
|
|
149
|
+
// create a spectro meter
|
|
150
|
+
|
|
151
|
+
function createChannel(options) {
|
|
152
|
+
assert(typeof options.browseName === "string");
|
|
153
|
+
assert(options.componentOf);
|
|
154
|
+
|
|
155
|
+
const channel = analyserChannelType.instantiate({
|
|
156
|
+
browseName: options.browseName,
|
|
157
|
+
componentOf: options.componentOf,
|
|
158
|
+
optionals: ["ParameterSet"]
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
const parameterSet = channel.parameterSet;
|
|
162
|
+
|
|
163
|
+
//var parameterSet = topologyElementType.instantiate({ browseName: "ParameterSet", componentOf: channel });
|
|
164
|
+
/// var methodSet = topologyElementType.instantiate({ browseName: "MethodSet", componentOf: channel });
|
|
165
|
+
|
|
166
|
+
namespace.addVariable({
|
|
167
|
+
componentOf: parameterSet,
|
|
168
|
+
browseName: "MyParameter",
|
|
169
|
+
typeDefinition: "DataItemType",
|
|
170
|
+
dataType: DataType.Double,
|
|
171
|
+
value: new Variant({ dataType: DataType.Double, value: 10.0 })
|
|
172
|
+
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
return channel;
|
|
176
|
+
}
|
|
177
|
+
// add channel 1
|
|
178
|
+
const channel1 = createChannel({ browseName: "Channel1", componentOf: mySpectrometer });
|
|
179
|
+
const channel2 = createChannel({ browseName: "Channel2", componentOf: mySpectrometer });
|
|
180
|
+
|
|
181
|
+
console.log(mySpectrometer.toString());
|
|
182
|
+
|
|
183
|
+
console.log(mySpectrometer.channel1.toString());
|
|
184
|
+
|
|
185
|
+
// var networkSet = rootFolder.networkSet;
|
|
186
|
+
//var networkType = addressSpace.findObjectType("2:NetworkType");
|
|
187
|
+
//var network = networkType.instantiate({ browseName: "MyNetwork", organizedBy: networkSet });
|
|
188
|
+
|
|
189
|
+
//------------------------------------------------------------------------------
|
|
190
|
+
// Add a view
|
|
191
|
+
//------------------------------------------------------------------------------
|
|
192
|
+
const view = namespace.addView({
|
|
193
|
+
organizedBy: rootFolder.views,
|
|
194
|
+
browseName: "MyView"
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
const createBoilerType = opcua.createBoilerType;
|
|
198
|
+
const makeBoiler = opcua.makeBoiler;
|
|
199
|
+
|
|
200
|
+
createBoilerType(namespace);
|
|
201
|
+
makeBoiler(addressSpace, {
|
|
202
|
+
browseName: "Boiler#1"
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
function dumpNode(node) {
|
|
211
|
+
function w(str, width) {
|
|
212
|
+
const tmp = str + " ";
|
|
213
|
+
return tmp.substr(0, width);
|
|
214
|
+
}
|
|
215
|
+
return Object.entries(node).map((key,value) =>
|
|
216
|
+
" " + w(key, 30) + " : " + ((value === null) ? null : value.toString())
|
|
217
|
+
).join("\n");
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
console.log(chalk.yellow(" server PID :"), process.pid);
|
|
222
|
+
|
|
223
|
+
server.start(function(err) {
|
|
224
|
+
if (err) {
|
|
225
|
+
console.log(" Server failed to start ... exiting");
|
|
226
|
+
process.exit(-3);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const endpointUrl = server.getEndpointUrl();
|
|
230
|
+
|
|
231
|
+
console.log(chalk.yellow(" server on port :"), server.endpoints[0].port.toString());
|
|
232
|
+
console.log(chalk.yellow(" endpointUrl :"), endpointUrl);
|
|
233
|
+
|
|
234
|
+
console.log(chalk.yellow(" serverInfo :"));
|
|
235
|
+
console.log(dumpNode(server.serverInfo));
|
|
236
|
+
console.log(chalk.yellow(" buildInfo :"));
|
|
237
|
+
console.log(dumpNode(server.engine.buildInfo));
|
|
238
|
+
|
|
239
|
+
console.log("Certificate file = ", server.certificateFile);
|
|
240
|
+
console.log(chalk.yellow("\n server now waiting for connections. CTRL+C to stop"));
|
|
241
|
+
|
|
242
|
+
console.log(server.buildInfo.toString());
|
|
243
|
+
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
server.on("create_session", function(session) {
|
|
247
|
+
|
|
248
|
+
console.log(" SESSION CREATED");
|
|
249
|
+
console.log(chalk.cyan(" client application URI: "), session.clientDescription.applicationUri);
|
|
250
|
+
console.log(chalk.cyan(" client product URI: "), session.clientDescription.productUri);
|
|
251
|
+
console.log(chalk.cyan(" client application name: "), session.clientDescription.applicationName.toString());
|
|
252
|
+
console.log(chalk.cyan(" client application type: "), session.clientDescription.applicationType.toString());
|
|
253
|
+
console.log(chalk.cyan(" session name: "), session.sessionName ? session.sessionName.toString() : "<null>");
|
|
254
|
+
console.log(chalk.cyan(" session timeout: "), session.sessionTimeout);
|
|
255
|
+
console.log(chalk.cyan(" session id: "), session.sessionId);
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
server.on("session_closed", function(session, reason) {
|
|
259
|
+
console.log(" SESSION CLOSED :", reason);
|
|
260
|
+
console.log(chalk.cyan(" session name: "), session.sessionName ? session.sessionName.toString() : "<null>");
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
function w(s, w) {
|
|
264
|
+
return ("000" + s).substr(-w);
|
|
265
|
+
}
|
|
266
|
+
function t(d) {
|
|
267
|
+
return w(d.getHours(), 2) + ":" + w(d.getMinutes(), 2) + ":" + w(d.getSeconds(), 2) + ":" + w(d.getMilliseconds(), 3);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
server.on("response", function(response) {
|
|
271
|
+
console.log(t(response.responseHeader.timestamp), response.responseHeader.requestHandle,
|
|
272
|
+
response.schema.name, " status = ", response.responseHeader.serviceResult.toString());
|
|
273
|
+
switch (response.schema.name) {
|
|
274
|
+
case "ModifySubscriptionResponse":
|
|
275
|
+
case "CreateMonitoredItemsResponse":
|
|
276
|
+
case "RepublishResponse":
|
|
277
|
+
case "WriteResponse":
|
|
278
|
+
//xx console.log(response.toString());
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
function indent(str, nb) {
|
|
285
|
+
const spacer = " ".slice(0, nb);
|
|
286
|
+
return str.split("\n").map(function(s) { return spacer + s; }).join("\n");
|
|
287
|
+
}
|
|
288
|
+
server.on("request", function(request, channel) {
|
|
289
|
+
console.log(t(request.requestHeader.timestamp), request.requestHeader.requestHandle,
|
|
290
|
+
request.schema.name, " ID =", channel.channelId.toString());
|
|
291
|
+
switch (request.schema.name) {
|
|
292
|
+
case "ModifySubscriptionRequest":
|
|
293
|
+
case "CreateMonitoredItemsRequest":
|
|
294
|
+
case "RepublishRequest":
|
|
295
|
+
//xx console.log(request.toString());
|
|
296
|
+
break;
|
|
297
|
+
case "ReadRequest":
|
|
298
|
+
break;
|
|
299
|
+
case "WriteRequest":
|
|
300
|
+
break;
|
|
301
|
+
case "TranslateBrowsePathsToNodeIdsRequest":
|
|
302
|
+
break;
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
process.on("SIGINT", function() {
|
|
307
|
+
// only work on linux apparently
|
|
308
|
+
console.log(chalk.red.bold(" Received server interruption from user "));
|
|
309
|
+
console.log(chalk.red.bold(" shutting down ..."));
|
|
310
|
+
server.shutdown(1000, function() {
|
|
311
|
+
console.log(chalk.red.bold(" shutting down completed "));
|
|
312
|
+
console.log(chalk.red.bold(" done "));
|
|
313
|
+
console.log("");
|
|
314
|
+
process.exit(-1);
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
|