node-opcua-address-space 2.66.2 → 2.68.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 (34) hide show
  1. package/dist/source/address_space_ts.d.ts +0 -2
  2. package/dist/source/address_space_ts.js.map +1 -1
  3. package/dist/source/continuation_points/continuation_point_manager.js +6 -3
  4. package/dist/source/continuation_points/continuation_point_manager.js.map +1 -1
  5. package/dist/source/loader/make_xml_extension_object_parser.js +28 -9
  6. package/dist/source/loader/make_xml_extension_object_parser.js.map +1 -1
  7. package/dist/src/base_node_impl.js +1 -1
  8. package/dist/src/base_node_impl.js.map +1 -1
  9. package/dist/src/extension_object_array_node.js +31 -22
  10. package/dist/src/extension_object_array_node.js.map +1 -1
  11. package/dist/src/historical_access/address_space_historical_data_node.js +3 -3
  12. package/dist/src/historical_access/address_space_historical_data_node.js.map +1 -1
  13. package/dist/src/reference_impl.js +1 -1
  14. package/dist/src/reference_impl.js.map +1 -1
  15. package/dist/src/ua_variable_impl.d.ts +9 -8
  16. package/dist/src/ua_variable_impl.js +56 -313
  17. package/dist/src/ua_variable_impl.js.map +1 -1
  18. package/dist/src/ua_variable_impl_ext_obj.d.ts +17 -0
  19. package/dist/src/ua_variable_impl_ext_obj.js +393 -0
  20. package/dist/src/ua_variable_impl_ext_obj.js.map +1 -0
  21. package/distNodeJS/generate_address_space.js +1 -1
  22. package/package.json +36 -36
  23. package/source/address_space_ts.ts +0 -2
  24. package/source/continuation_points/continuation_point_manager.ts +11 -9
  25. package/source/loader/make_xml_extension_object_parser.ts +32 -11
  26. package/source_nodejs/generate_address_space.ts +1 -1
  27. package/src/base_node_impl.ts +1 -1
  28. package/src/extension_object_array_node.ts +43 -28
  29. package/src/historical_access/address_space_historical_data_node.ts +3 -3
  30. package/src/reference_impl.ts +1 -1
  31. package/src/ua_variable_impl.ts +68 -381
  32. package/src/ua_variable_impl_ext_obj.ts +472 -0
  33. package/test_helpers/test_fixtures/issue_1132_variable_with_nodeid_value.xml +68 -0
  34. package/test_helpers/test_fixtures/nodeset_with_utf8_special_characters.xml +20 -0
@@ -0,0 +1,472 @@
1
+ import * as chalk from "chalk";
2
+ import assert from "node-opcua-assert";
3
+ import { BindExtensionObjectOptions, UADataType, UAVariable, UAVariableType } from "node-opcua-address-space-base";
4
+ import { NodeClass } from "node-opcua-data-model";
5
+ import { getCurrentClock, PreciseClock } from "node-opcua-date-time";
6
+ import { DataValue } from "node-opcua-data-value";
7
+ import { make_debugLog, make_warningLog, checkDebugFlag, make_errorLog } from "node-opcua-debug";
8
+ import { ExtensionObject } from "node-opcua-extension-object";
9
+ import { NodeId } from "node-opcua-nodeid";
10
+ import { StatusCodes, CallbackT, StatusCode } from "node-opcua-status-code";
11
+ import { StructureField } from "node-opcua-types";
12
+ import { lowerFirstLetter } from "node-opcua-utils";
13
+ import { DataType, Variant, VariantLike } from "node-opcua-variant";
14
+
15
+ import { valueRankToString } from "./base_node_private";
16
+ import { UAVariableImpl } from "./ua_variable_impl";
17
+ import { UADataTypeImpl } from "./ua_data_type_impl";
18
+
19
+ const doDebug = checkDebugFlag(__filename);
20
+ const debugLog = make_debugLog(__filename);
21
+ // const doDebug = true; // checkDebugFlag(__filename);
22
+ // const debugLog = make_warningLog(__filename);
23
+ const warningLog = make_warningLog(__filename);
24
+ const errorLog = make_errorLog(__filename);
25
+
26
+ function w(str: string, n: number): string {
27
+ return str.padEnd(n).substring(n);
28
+ }
29
+
30
+ function isProxy(ext: any) {
31
+ return ext.$isProxy ? true : false;
32
+ }
33
+
34
+ function getProxyTarget(ext: any) {
35
+ assert(isProxy(ext));
36
+ return ext.$proxyTarget;
37
+ }
38
+
39
+ function unProxy(ext: ExtensionObject) {
40
+ return isProxy(ext) ? getProxyTarget(ext) : ext;
41
+ }
42
+
43
+ function _extensionObjectFieldGetter(target: any, key: string /*, receiver*/) {
44
+ if (key === "$isProxy") {
45
+ return true;
46
+ }
47
+ if (key === "$proxyTarget") {
48
+ return target;
49
+ }
50
+ if (target[key] === undefined) {
51
+ return undefined;
52
+ }
53
+ return target[key];
54
+ }
55
+
56
+ function _extensionObjectFieldSetter(variable: UAVariable, target: any, key: string, value: any /*, receiver*/): boolean {
57
+ target[key] = value;
58
+ const child = (variable as any)[key] as UAVariable | null;
59
+ if (child && child.touchValue) {
60
+ child.touchValue();
61
+ }
62
+ return true; // true means the set operation has succeeded
63
+ }
64
+
65
+ function makeHandler(variable: UAVariable) {
66
+ const handler = {
67
+ get: _extensionObjectFieldGetter,
68
+ set: _extensionObjectFieldSetter.bind(null, variable)
69
+ };
70
+ return handler;
71
+ }
72
+
73
+ /**
74
+ * inconditionnaly change the time stamp of the variable
75
+ * if the variable is being listened to, and if the minimumSamplingInterval is exactly zero,
76
+ * then the change will be reported to the observer
77
+ *
78
+ */
79
+ export function _touchValue(property: UAVariableImpl, now: PreciseClock): void {
80
+
81
+ property.$dataValue.sourceTimestamp = now.timestamp;
82
+ property.$dataValue.sourcePicoseconds = now.picoseconds;
83
+ property.$dataValue.serverTimestamp = now.timestamp;
84
+ property.$dataValue.serverPicoseconds = now.picoseconds;
85
+ property.$dataValue.statusCode = StatusCodes.Good;
86
+
87
+ if (property.minimumSamplingInterval === 0) {
88
+ if (property.listenerCount("value_changed") > 0) {
89
+ const clonedDataValue = property.readValue();
90
+ property.emit("value_changed", clonedDataValue);
91
+ }
92
+ }
93
+ }
94
+
95
+ export function propagateTouchValueUpward(self: UAVariableImpl, now: PreciseClock): void {
96
+ _touchValue(self, now);
97
+ if (self.parent && self.parent.nodeClass === NodeClass.Variable) {
98
+ const parentVar = self.parent as UAVariableImpl;
99
+ if (!parentVar.isExtensionObject()) return;
100
+ propagateTouchValueUpward(parentVar, now);
101
+ }
102
+ }
103
+
104
+ function propagateTouchValueDownward(self: UAVariableImpl, now: PreciseClock): void {
105
+ if (!self.isExtensionObject()) return;
106
+ // also propagate changes to embeded variables
107
+ const dataTypeNode = self.getDataTypeNode();
108
+ const definition = dataTypeNode.getStructureDefinition();
109
+ for (const field of definition.fields || []) {
110
+ const property = self.getChildByName(field.name!) as UAVariableImpl;
111
+ if (property) {
112
+ _touchValue(property, now);
113
+ // to do cascade recursivelly ?
114
+ }
115
+ }
116
+ }
117
+
118
+ export function _setExtensionObject(self: UAVariableImpl, ext: ExtensionObject): void {
119
+ // assert(!(ext as any).$isProxy, "internal error ! ExtensionObject has already been proxied !");
120
+ ext = unProxy(ext);
121
+ self.$extensionObject = new Proxy(ext, makeHandler(self));
122
+ self.$dataValue.value.dataType = DataType.ExtensionObject;
123
+ self.$dataValue.value.value = self.$extensionObject;
124
+ self.$dataValue.statusCode = StatusCodes.Good;
125
+
126
+ const now = getCurrentClock();
127
+ propagateTouchValueUpward(self, now);
128
+ propagateTouchValueDownward(self, now);
129
+ }
130
+
131
+ export function setExtensionObjectValue(node: UAVariableImpl, partialObject: any) {
132
+ const extensionObject = node.$extensionObject;
133
+ if (!extensionObject) {
134
+ throw new Error("setExtensionObjectValue node has no extension object " + node.browseName.toString());
135
+ }
136
+
137
+ function _update_extension_object(extObject: any, partialObject1: any) {
138
+ const keys = Object.keys(partialObject1);
139
+ for (const prop of keys) {
140
+ if (extObject[prop] instanceof Object) {
141
+ _update_extension_object(extObject[prop], partialObject1[prop]);
142
+ } else {
143
+ extObject[prop] = partialObject1[prop];
144
+ }
145
+ }
146
+ }
147
+
148
+ _update_extension_object(extensionObject, partialObject);
149
+ }
150
+
151
+ function getOrCreateProperty(
152
+ variableNode: UAVariableImpl,
153
+ field: StructureField,
154
+ options: BindExtensionObjectOptions
155
+ ): UAVariableImpl | null {
156
+ const dt = variableNode.getDataTypeNode();
157
+ // the namespace for the structure browse name elements
158
+ const structureNamespace = dt.nodeId.namespace;
159
+
160
+ const components = variableNode.getComponents();
161
+ let property: UAVariableImpl;
162
+ const selectedComponents = components.filter(
163
+ (f) => f instanceof UAVariableImpl && f.browseName.name!.toString() === field.name
164
+ );
165
+
166
+ // istanbul ignore next
167
+ if (field.dataType.value === DataType.Variant) {
168
+ warningLog("Warning : variant is not supported in ExtensionObject");
169
+ }
170
+
171
+ if (selectedComponents.length === 1) {
172
+ property = selectedComponents[0] as UAVariableImpl;
173
+ /* istanbul ignore next */
174
+ } else {
175
+ if (!options!.createMissingProp) {
176
+ return null;
177
+ }
178
+ debugLog("adding missing array variable", field.name, variableNode.browseName.toString(), variableNode.nodeId.toString());
179
+ // todo: Handle array appropriately...
180
+ assert(selectedComponents.length === 0);
181
+ // create a variable (Note we may use ns=1;s=parentName/0:PropertyName)
182
+ property = variableNode.namespace.addVariable({
183
+ browseName: { namespaceIndex: structureNamespace, name: field.name!.toString() },
184
+ componentOf: variableNode,
185
+ dataType: field.dataType,
186
+ minimumSamplingInterval: variableNode.minimumSamplingInterval
187
+ }) as UAVariableImpl;
188
+ assert(property.minimumSamplingInterval === variableNode.minimumSamplingInterval);
189
+ }
190
+ return property;
191
+ }
192
+
193
+ function prepareVariantValue(dataType: DataType, value: VariantLike): VariantLike {
194
+ if ((dataType === DataType.Int32 || dataType === DataType.UInt32) && value && (value as { key?: unknown }).key) {
195
+ value = value.value;
196
+ }
197
+ return value;
198
+ }
199
+
200
+ function bindProperty(variableNode: UAVariableImpl, propertyNode: UAVariableImpl, name: string, dataType: DataType) {
201
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
202
+ propertyNode.bindVariable(
203
+ {
204
+ timestamped_get: () => {
205
+ const propertyValue = variableNode.$extensionObject[name];
206
+ if (propertyValue === undefined) {
207
+ propertyNode.$dataValue.value.dataType = DataType.Null;
208
+ propertyNode.$dataValue.statusCode = StatusCodes.Good;
209
+ propertyNode.$dataValue.value.value = null;
210
+ return new DataValue(propertyNode.$dataValue);
211
+ }
212
+ const value = prepareVariantValue(dataType, propertyValue);
213
+ propertyNode.$dataValue.statusCode = StatusCodes.Good;
214
+ propertyNode.$dataValue.value.dataType = dataType;
215
+ propertyNode.$dataValue.value.value = value;
216
+ return new DataValue(propertyNode.$dataValue);
217
+ },
218
+ timestamped_set: (_dataValue: DataValue, callback: CallbackT<StatusCode>) => {
219
+ callback(null, StatusCodes.BadNotWritable);
220
+ }
221
+ },
222
+ true
223
+ );
224
+ }
225
+
226
+ export function _installExtensionObjectBindingOnProperties(
227
+ variableNode: UAVariableImpl,
228
+ options: BindExtensionObjectOptions
229
+ ): void {
230
+ const addressSpace = variableNode.addressSpace;
231
+ const dt = variableNode.getDataTypeNode();
232
+ const definition = dt.getStructureDefinition();
233
+
234
+ for (const field of definition.fields || []) {
235
+ // istanbul ignore next
236
+ if (NodeId.sameNodeId(NodeId.nullNodeId, field.dataType)) {
237
+ warningLog("field.dataType is null ! ", field.name, NodeId.nullNodeId.toString());
238
+ warningLog(field.toString());
239
+ warningLog(" dataType replaced with BaseDataType ");
240
+ warningLog(definition.toString());
241
+ field.dataType = variableNode.resolveNodeId("BaseDataType");
242
+ }
243
+
244
+ const propertyNode = getOrCreateProperty(variableNode, field, options);
245
+ if (!propertyNode) {
246
+ continue;
247
+ }
248
+ propertyNode.$dataValue.statusCode = StatusCodes.Good;
249
+ propertyNode.touchValue();
250
+
251
+ const basicDataType = addressSpace.findCorrespondingBasicDataType(field.dataType);
252
+
253
+ // istanbul ignore next
254
+ if (doDebug) {
255
+ const x = addressSpace.findNode(field.dataType)!.browseName.toString();
256
+ debugLog(
257
+ chalk.cyan("xxx"),
258
+ " dataType",
259
+ w(field.dataType.toString(), 8),
260
+ w(field.name!, 25),
261
+ "valueRank",
262
+ chalk.cyan(w(valueRankToString(field.valueRank), 10)),
263
+ chalk.green(w(x, 15)),
264
+ "basicType = ",
265
+ chalk.yellow(w(basicDataType.toString(), 20)),
266
+ propertyNode.nodeId.toString(),
267
+ propertyNode.readValue().statusCode.toString()
268
+ );
269
+ }
270
+
271
+ const camelCaseName = lowerFirstLetter(field.name!);
272
+ assert(Object.prototype.hasOwnProperty.call(variableNode.$extensionObject, camelCaseName));
273
+
274
+ if (variableNode.$extensionObject[camelCaseName] !== undefined && basicDataType === DataType.ExtensionObject) {
275
+ propertyNode.bindExtensionObject(variableNode.$extensionObject[camelCaseName], { ...options, force: true });
276
+ // replace upwards
277
+ variableNode.$extensionObject[camelCaseName] = propertyNode.$extensionObject;
278
+ } else {
279
+ const prop = variableNode.$extensionObject[camelCaseName];
280
+ if (prop === undefined) {
281
+ propertyNode._internal_set_value(
282
+ new Variant({
283
+ dataType: DataType.Null
284
+ })
285
+ );
286
+ } else {
287
+ const preparedValue = prepareVariantValue(basicDataType, prop);
288
+ propertyNode._internal_set_value(
289
+ new Variant({
290
+ dataType: basicDataType,
291
+ value: preparedValue
292
+ })
293
+ );
294
+ }
295
+
296
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
297
+
298
+ // property.camelCaseName = camelCaseName;
299
+ propertyNode.setValueFromSource = function (this: UAVariableImpl, variant: VariantLike) {
300
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
301
+ const inner_this = this;
302
+ const variant1 = Variant.coerce(variant);
303
+ inner_this.verifyVariantCompatibility(variant1);
304
+
305
+ // because self.$extensionObject is a Proxy with handlers that
306
+ // cascade the chagne we do not need to call touchValue() here
307
+ variableNode.$extensionObject[camelCaseName] = variant1.value;
308
+ };
309
+ }
310
+ assert(propertyNode.readValue().statusCode.equals(StatusCodes.Good));
311
+ bindProperty(variableNode, propertyNode, camelCaseName, basicDataType);
312
+ }
313
+ }
314
+
315
+ export function _bindExtensionObject(
316
+ self: UAVariableImpl,
317
+ optionalExtensionObject?: ExtensionObject,
318
+ options?: BindExtensionObjectOptions
319
+ ) {
320
+ options = options || { createMissingProp: false };
321
+
322
+ const addressSpace = self.addressSpace;
323
+ const structure = addressSpace.findDataType("Structure");
324
+ let extensionObject_;
325
+
326
+ if (!structure) {
327
+ // the addressSpace is limited and doesn't provide extension object
328
+ // bindExtensionObject cannot be performed and shall finish here.
329
+ return null;
330
+ }
331
+
332
+ assert(structure.browseName.toString() === "Structure", "expecting DataType Structure to be in IAddressSpace");
333
+
334
+ const dt = self.getDataTypeNode() as UADataTypeImpl;
335
+ if (!dt.isSupertypeOf(structure)) {
336
+ return null;
337
+ }
338
+ // istanbul ignore next
339
+ if (doDebug) {
340
+ debugLog(" ------------------------------ binding ", self.browseName.toString(), self.nodeId.toString());
341
+ }
342
+
343
+ // ignore bindExtensionObject on sub extension object, bindExtensionObject has to be called from the top most object
344
+ if (
345
+ !options.force &&
346
+ self.parent &&
347
+ (self.parent.nodeClass === NodeClass.Variable || self.parent.nodeClass === NodeClass.VariableType)
348
+ ) {
349
+ const parentDataType = (self.parent as UAVariable | UAVariableType).dataType;
350
+ const dataTypeNode = addressSpace.findNode(parentDataType) as UADataType;
351
+ // istanbul ignore next
352
+ if (dataTypeNode && dataTypeNode.isSupertypeOf(structure)) {
353
+ // warningLog(
354
+ // "Ignoring bindExtensionObject on sub extension object",
355
+ // "child=",
356
+ // self.browseName.toString(),
357
+ // "parent=",
358
+ // self.parent.browseName.toString()
359
+ // );
360
+ return null;
361
+ }
362
+ }
363
+
364
+ // -------------------- make sure we do not bind a variable twice ....
365
+ if (self.$extensionObject && !optionalExtensionObject) {
366
+ // istanbul ignore next
367
+ if (!self.checkExtensionObjectIsCorrect(self.$extensionObject!)) {
368
+ warningLog(
369
+ "on node : ",
370
+ self.browseName.toString(),
371
+ self.nodeId.toString(),
372
+ "dataType=",
373
+ self.dataType.toString({ addressSpace: self.addressSpace })
374
+ );
375
+ warningLog(self.$extensionObject?.toString());
376
+ throw new Error(
377
+ "bindExtensionObject: $extensionObject is incorrect: we are expecting a " +
378
+ self.dataType.toString({ addressSpace: self.addressSpace }) +
379
+ " but we got a " +
380
+ self.$extensionObject?.constructor.name
381
+ );
382
+ }
383
+ return self.$extensionObject;
384
+ // throw new Error("Variable already bound");
385
+ }
386
+
387
+ // ------------------------------------------------------
388
+ // make sure we have a structure
389
+ // ------------------------------------------------------
390
+ const s = self.readValue();
391
+
392
+ // istanbul ignore next
393
+ if (self.dataTypeObj.isAbstract) {
394
+ warningLog("Warning the DataType associated with this Variable is abstract ", self.dataTypeObj.browseName.toString());
395
+ warningLog("You need to provide a extension object yourself ");
396
+ throw new Error("bindExtensionObject requires a extensionObject as associated dataType is only abstract");
397
+ }
398
+
399
+ if (s.value && s.value.dataType === DataType.ExtensionObject && s.value.value && optionalExtensionObject) {
400
+ // we want to replace the extension object
401
+ s.value.value = null;
402
+ }
403
+ innerBindExtensionObject();
404
+ assert(self.$extensionObject instanceof Object);
405
+ return self.$extensionObject;
406
+
407
+ function innerBindExtensionObject() {
408
+ if (s.value && (s.value.dataType === DataType.Null || (s.value.dataType === DataType.ExtensionObject && !s.value.value))) {
409
+ // create a structure and bind it
410
+ extensionObject_ = optionalExtensionObject || addressSpace.constructExtensionObject(self.dataType, {});
411
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
412
+ self.bindVariable(
413
+ {
414
+ timestamped_get() {
415
+ const d = new DataValue(self.$dataValue);
416
+ d.value.value = self.$extensionObject ? self.$extensionObject.clone() : null;
417
+ return d;
418
+ },
419
+ timestamped_set(dataValue: DataValue, callback: CallbackT<StatusCode>) {
420
+ const ext = dataValue.value.value;
421
+ if (!self.checkExtensionObjectIsCorrect(ext)) {
422
+ return callback(null, StatusCodes.BadInvalidArgument);
423
+ }
424
+ _setExtensionObject(self, ext);
425
+ callback(null, StatusCodes.Good);
426
+ }
427
+ },
428
+ true
429
+ );
430
+ _setExtensionObject(self, extensionObject_);
431
+ } else {
432
+ // verify that variant has the correct type
433
+ assert(s.value.dataType === DataType.ExtensionObject);
434
+ self.$extensionObject = s.value.value;
435
+ assert(self.checkExtensionObjectIsCorrect(self.$extensionObject!));
436
+ assert(s.statusCode.equals(StatusCodes.Good));
437
+ }
438
+ _installExtensionObjectBindingOnProperties(self, options!);
439
+ }
440
+ }
441
+
442
+ export function extractPartialData(path: string | string[], extensionObject: ExtensionObject) {
443
+ let name;
444
+ if (typeof path === "string") {
445
+ path = path.split(".");
446
+ }
447
+ assert(path instanceof Array);
448
+ let i;
449
+ // read partial value
450
+ const partialData: any = {};
451
+ let p: any = partialData;
452
+ for (i = 0; i < path.length - 1; i++) {
453
+ name = path[i];
454
+ p[name] = {};
455
+ p = p[name];
456
+ }
457
+ name = path[path.length - 1];
458
+ p[name] = 0;
459
+
460
+ let c1 = partialData;
461
+ let c2: any = extensionObject;
462
+
463
+ for (i = 0; i < path.length - 1; i++) {
464
+ name = path[i];
465
+ c1 = partialData[name];
466
+ c2 = (extensionObject as any)[name];
467
+ }
468
+ name = path[path.length - 1];
469
+ c1[name] = c2[name];
470
+ c1[name] += 1;
471
+ return partialData;
472
+ }
@@ -0,0 +1,68 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <UANodeSet>
3
+ <NamespaceUris>
4
+ <Uri>http://mynamespace</Uri>
5
+ </NamespaceUris>
6
+ <Aliases>
7
+ <Alias Alias="NodeId">i=17</Alias>
8
+ </Aliases>
9
+ <UAVariable NodeId="ns=1;i=1545" BrowseName="SessionId" DataType="NodeId">
10
+ <DisplayName>SessionId</DisplayName>
11
+ <References>
12
+ <Reference ReferenceType="HasTypeDefinition">i=63</Reference>
13
+ </References>
14
+ <Value>
15
+ <NodeId>
16
+ <Identifier>ns=1;g=24DCB865-2F12-3048-FC3F-213B8DE57128</Identifier>
17
+ </NodeId>
18
+ </Value>
19
+ </UAVariable>
20
+ <UAVariable NodeId="ns=1;i=1272" BrowseName="1:869582" AccessLevel="3" DataType="SubscriptionDiagnosticsDataType">
21
+ <DisplayName>869582</DisplayName>
22
+ <Value>
23
+ <ExtensionObject>
24
+ <TypeId>
25
+ <Identifier>i=875</Identifier>
26
+ </TypeId>
27
+ <Body>
28
+ <SubscriptionDiagnosticsDataType>
29
+ <SessionId>
30
+ <Identifier>ns=1;g=7BC32991-2103-2344-DE12-84ED18A855B4</Identifier>
31
+ </SessionId>
32
+ <SubscriptionId>869582</SubscriptionId>
33
+ <Priority>0</Priority>
34
+ <PublishingInterval>100</PublishingInterval>
35
+ <MaxKeepAliveCount>50</MaxKeepAliveCount>
36
+ <MaxLifetimeCount>12000</MaxLifetimeCount>
37
+ <MaxNotificationsPerPublish>1000</MaxNotificationsPerPublish>
38
+ <PublishingEnabled>true</PublishingEnabled>
39
+ <ModifyCount>0</ModifyCount>
40
+ <EnableCount>0</EnableCount>
41
+ <DisableCount>0</DisableCount>
42
+ <RepublishRequestCount>1</RepublishRequestCount>
43
+ <RepublishMessageRequestCount>1</RepublishMessageRequestCount>
44
+ <RepublishMessageCount>0</RepublishMessageCount>
45
+ <TransferRequestCount>0</TransferRequestCount>
46
+ <TransferredToAltClientCount>0</TransferredToAltClientCount>
47
+ <TransferredToSameClientCount>0</TransferredToSameClientCount>
48
+ <PublishRequestCount>0</PublishRequestCount>
49
+ <DataChangeNotificationsCount>0</DataChangeNotificationsCount>
50
+ <EventNotificationsCount>0</EventNotificationsCount>
51
+ <NotificationsCount>0</NotificationsCount>
52
+ <LatePublishRequestCount>0</LatePublishRequestCount>
53
+ <CurrentKeepAliveCount>0</CurrentKeepAliveCount>
54
+ <CurrentLifetimeCount>0</CurrentLifetimeCount>
55
+ <UnacknowledgedMessageCount>0</UnacknowledgedMessageCount>
56
+ <DiscardedMessageCount>0</DiscardedMessageCount>
57
+ <MonitoredItemCount>1</MonitoredItemCount>
58
+ <DisabledMonitoredItemCount>0</DisabledMonitoredItemCount>
59
+ <MonitoringQueueOverflowCount>0</MonitoringQueueOverflowCount>
60
+ <NextSequenceNumber>1</NextSequenceNumber>
61
+ <EventQueueOverFlowCount>0</EventQueueOverFlowCount>
62
+ </SubscriptionDiagnosticsDataType>
63
+ </Body>
64
+ </ExtensionObject>
65
+ </Value>
66
+ </UAVariable>
67
+
68
+ </UANodeSet>
@@ -0,0 +1,20 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <UANodeSet>
3
+ <NamespaceUris>
4
+ <Uri>uri://mynamespace</Uri>
5
+ </NamespaceUris>
6
+ <Models>
7
+ <Model ModelUri="uri://mynamespace" PublicationDate="2022-04-21T00:00:00Z" Version="1.00">
8
+ <RequiredModel ModelUri="http://opcfoundation.org/UA/" PublicationDate="2021-09-15T00:00:00Z" Version="1.04.10"/>
9
+ </Model>
10
+ </Models>
11
+ <Aliases>
12
+ </Aliases>
13
+ <UAObject BrowseName="Noël" NodeId="ns=1;i=1001"/>
14
+ <UAObject BrowseName="Strauß" NodeId="ns=1;i=1002"/>
15
+ <UAObject BrowseName="Bjørn Ødger Åse" NodeId="ns=1;i=1003"/>
16
+ <UAObject BrowseName="Günter Альберт" NodeId="ns=1;i=1004"/>
17
+ <UAObject BrowseName="Мир во всём ми́ре" NodeId="ns=1;i=1005"/>
18
+ <UAObject BrowseName="صلح در زمین" NodeId="ns=1;i=1006"/>
19
+
20
+ </UANodeSet>