node-opcua-address-space 2.59.0 → 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/dist/source/address_space_ts.d.ts +0 -2
- package/dist/source/helpers/argument_list.js +12 -1
- package/dist/source/helpers/argument_list.js.map +1 -1
- package/dist/source/loader/load_nodeset2.js +47 -64
- package/dist/source/loader/load_nodeset2.js.map +1 -1
- package/dist/source/set_namespace_meta_data.js +1 -1
- package/dist/src/address_space.js +8 -5
- package/dist/src/address_space.js.map +1 -1
- package/dist/src/alarms_and_conditions/condition_snapshot.js +3 -3
- package/dist/src/alarms_and_conditions/condition_snapshot.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_alarm_condition_impl.js +1 -1
- package/dist/src/alarms_and_conditions/ua_alarm_condition_impl.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_condition_impl.js +8 -6
- package/dist/src/alarms_and_conditions/ua_condition_impl.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_off_normal_alarm_impl.js +1 -1
- package/dist/src/alarms_and_conditions/ua_off_normal_alarm_impl.js.map +1 -1
- package/dist/src/base_node_private.js +2 -2
- package/dist/src/base_node_private.js.map +1 -1
- package/dist/src/event_data.js +1 -1
- package/dist/src/event_data.js.map +1 -1
- package/dist/src/namespace_impl.js +5 -5
- package/dist/src/namespace_impl.js.map +1 -1
- package/dist/src/nodeset_tools/nodeset_to_xml.js +15 -9
- package/dist/src/nodeset_tools/nodeset_to_xml.js.map +1 -1
- package/dist/src/nodeset_tools/typedictionary_to_xml.js +17 -10
- package/dist/src/nodeset_tools/typedictionary_to_xml.js.map +1 -1
- package/dist/src/state_machine/ua_shelving_state_machine_ex.js +20 -13
- package/dist/src/state_machine/ua_shelving_state_machine_ex.js.map +1 -1
- package/dist/src/ua_data_type_impl.d.ts +15 -5
- package/dist/src/ua_data_type_impl.js +129 -51
- package/dist/src/ua_data_type_impl.js.map +1 -1
- package/dist/src/ua_variable_impl.d.ts +6 -6
- package/dist/src/ua_variable_impl.js +236 -188
- package/dist/src/ua_variable_impl.js.map +1 -1
- package/dist/src/ua_variable_type_impl.d.ts +3 -4
- package/dist/src/ua_variable_type_impl.js +13 -18
- package/dist/src/ua_variable_type_impl.js.map +1 -1
- package/distHelpers/mock_session.js +1 -1
- package/distHelpers/mock_session.js.map +1 -1
- package/package.json +35 -35
- package/source/address_space_ts.ts +0 -1
- package/source/helpers/argument_list.ts +13 -3
- package/source/loader/load_nodeset2.ts +64 -80
- package/source/set_namespace_meta_data.ts +1 -1
- package/src/address_space.ts +15 -9
- package/src/alarms_and_conditions/condition_snapshot.ts +4 -4
- package/src/alarms_and_conditions/ua_alarm_condition_impl.ts +2 -2
- package/src/alarms_and_conditions/ua_condition_impl.ts +18 -8
- package/src/alarms_and_conditions/ua_off_normal_alarm_impl.ts +1 -1
- package/src/base_node_private.ts +6 -2
- package/src/event_data.ts +1 -1
- package/src/namespace_impl.ts +6 -6
- package/src/nodeset_tools/nodeset_to_xml.ts +20 -10
- package/src/nodeset_tools/typedictionary_to_xml.ts +17 -7
- package/src/state_machine/ua_shelving_state_machine_ex.ts +28 -16
- package/src/ua_data_type_impl.ts +168 -61
- package/src/ua_variable_impl.ts +290 -218
- package/src/ua_variable_type_impl.ts +9 -15
- package/test_helpers/mock_session.ts +1 -1
- package/test_helpers/test_fixtures/fixture_simple_statemachine_nodeset2.xml +9 -0
- package/test_helpers/test_fixtures/mini.Node.Set2.xml +14 -0
|
@@ -6,13 +6,13 @@ import * as ec from "node-opcua-basic-types";
|
|
|
6
6
|
import { BinaryStream, BinaryStreamSizeCalculator, OutputBinaryStream } from "node-opcua-binary-stream";
|
|
7
7
|
import { checkDebugFlag, make_debugLog, make_warningLog } from "node-opcua-debug";
|
|
8
8
|
import * as factories from "node-opcua-factory";
|
|
9
|
-
import { NodeId, resolveNodeId } from "node-opcua-nodeid";
|
|
9
|
+
import { coerceNodeId, NodeId, resolveNodeId } from "node-opcua-nodeid";
|
|
10
10
|
import { Argument } from "node-opcua-service-call";
|
|
11
11
|
import { StatusCode, StatusCodes } from "node-opcua-status-code";
|
|
12
12
|
import { Variant } from "node-opcua-variant";
|
|
13
13
|
import { DataType } from "node-opcua-variant";
|
|
14
14
|
import { VariantArrayType } from "node-opcua-variant";
|
|
15
|
-
|
|
15
|
+
import { DataTypeIds } from "node-opcua-constants";
|
|
16
16
|
import { NodeClass } from "node-opcua-data-model";
|
|
17
17
|
import { IAddressSpace, UAMethod, UAObject } from "node-opcua-address-space-base";
|
|
18
18
|
|
|
@@ -181,7 +181,17 @@ function isArgumentValid(addressSpace: IAddressSpace, argDefinition: Argument, a
|
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
// check that dataType is of the same type (derived )
|
|
184
|
-
|
|
184
|
+
if (argDefDataType.isSupertypeOf(argDataType)) {
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
// special case for Enumeration
|
|
188
|
+
if (arg.dataType === DataType.Int32) {
|
|
189
|
+
const enumDataType = addressSpace.findDataType(coerceNodeId(DataTypeIds.Enumeration))!;
|
|
190
|
+
if (argDefDataType.isSupertypeOf(enumDataType)) {
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return false;
|
|
185
195
|
}
|
|
186
196
|
|
|
187
197
|
/**
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
UAVariableType
|
|
16
16
|
} from "node-opcua-address-space-base";
|
|
17
17
|
import { assert, renderError } from "node-opcua-assert";
|
|
18
|
-
import { isValidGuid, StatusCodes } from "node-opcua-basic-types";
|
|
18
|
+
import { Int64, isValidGuid, StatusCodes } from "node-opcua-basic-types";
|
|
19
19
|
import { ExtraDataTypeManager, populateDataTypeManager } from "node-opcua-client-dynamic-extension-object";
|
|
20
20
|
import { EUInformation } from "node-opcua-data-access";
|
|
21
21
|
import {
|
|
@@ -27,13 +27,21 @@ import {
|
|
|
27
27
|
QualifiedNameOptions,
|
|
28
28
|
stringToQualifiedName
|
|
29
29
|
} from "node-opcua-data-model";
|
|
30
|
-
import { checkDebugFlag, make_debugLog } from "node-opcua-debug";
|
|
30
|
+
import { checkDebugFlag, make_debugLog, make_errorLog } from "node-opcua-debug";
|
|
31
31
|
import { ExtensionObject } from "node-opcua-extension-object";
|
|
32
32
|
import { DataTypeFactory, findSimpleType, getStandardDataTypeFactory } from "node-opcua-factory";
|
|
33
33
|
import { NodeId, resolveNodeId } from "node-opcua-nodeid";
|
|
34
34
|
import { Argument } from "node-opcua-service-call";
|
|
35
35
|
import { CallbackT, ErrorCallback } from "node-opcua-status-code";
|
|
36
|
-
import {
|
|
36
|
+
import {
|
|
37
|
+
EnumDefinition,
|
|
38
|
+
EnumFieldOptions,
|
|
39
|
+
EnumValueType,
|
|
40
|
+
Range,
|
|
41
|
+
StructureDefinition,
|
|
42
|
+
StructureFieldOptions,
|
|
43
|
+
StructureType
|
|
44
|
+
} from "node-opcua-types";
|
|
37
45
|
import { DataType, Variant, VariantArrayType, VariantOptions } from "node-opcua-variant";
|
|
38
46
|
import {
|
|
39
47
|
_definitionParser,
|
|
@@ -56,6 +64,7 @@ import { promoteObjectsAndVariables } from "./namespace_post_step";
|
|
|
56
64
|
|
|
57
65
|
const doDebug = checkDebugFlag(__filename);
|
|
58
66
|
const debugLog = make_debugLog(__filename);
|
|
67
|
+
const errorLog = make_errorLog(__filename);
|
|
59
68
|
|
|
60
69
|
export async function ensureDatatypeExtracted(addressSpace: IAddressSpace): Promise<ExtraDataTypeManager> {
|
|
61
70
|
const addressSpacePriv: any = addressSpace as AddressSpacePrivate;
|
|
@@ -151,39 +160,6 @@ async function decodeXmlObject(
|
|
|
151
160
|
return userDefinedExtensionObject;
|
|
152
161
|
}
|
|
153
162
|
|
|
154
|
-
function makeEnumDefinition(definitionFields: any[]) {
|
|
155
|
-
return new EnumDefinition({
|
|
156
|
-
fields: definitionFields.map((x) => ({
|
|
157
|
-
description: {
|
|
158
|
-
text: x.description
|
|
159
|
-
},
|
|
160
|
-
name: x.name,
|
|
161
|
-
value: x.value
|
|
162
|
-
}))
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
function makeStructureDefinition(name: string, definitionFields: StructureFieldOptions[], isUnion: boolean): StructureDefinition {
|
|
166
|
-
// Structure = 0,
|
|
167
|
-
// StructureWithOptionalFields = 1,
|
|
168
|
-
// Union = 2,
|
|
169
|
-
const hasOptionalFields = definitionFields.filter((field) => field.isOptional).length > 0;
|
|
170
|
-
|
|
171
|
-
const structureType = isUnion
|
|
172
|
-
? StructureType.Union
|
|
173
|
-
: hasOptionalFields
|
|
174
|
-
? StructureType.StructureWithOptionalFields
|
|
175
|
-
: StructureType.Structure;
|
|
176
|
-
|
|
177
|
-
const sd = new StructureDefinition({
|
|
178
|
-
baseDataType: undefined,
|
|
179
|
-
defaultEncodingId: undefined,
|
|
180
|
-
fields: definitionFields,
|
|
181
|
-
structureType
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
return sd;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
163
|
function __make_back_references(namespace: INamespace) {
|
|
188
164
|
const namespaceP = namespace as NamespacePrivate;
|
|
189
165
|
for (const node of namespaceP.nodeIterator()) {
|
|
@@ -219,14 +195,21 @@ function makeDefaultVariant2(addressSpace: IAddressSpace, dataTypeNode: NodeId,
|
|
|
219
195
|
function makeDefaultVariant(addressSpace: IAddressSpace, dataTypeNode: NodeId, valueRank: number): VariantOptions | undefined {
|
|
220
196
|
let variant: VariantOptions = { dataType: DataType.Null };
|
|
221
197
|
|
|
222
|
-
const nodeDataType = addressSpace.findNode(dataTypeNode);
|
|
198
|
+
const nodeDataType = addressSpace.findNode(dataTypeNode) as UADataType;
|
|
223
199
|
if (nodeDataType) {
|
|
224
|
-
|
|
225
|
-
|
|
200
|
+
|
|
201
|
+
const basicDataType = nodeDataType.basicDataType;
|
|
202
|
+
if (basicDataType === DataType.Variant) {
|
|
203
|
+
/// we don't now what is the variant
|
|
204
|
+
return undefined
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// addressSpace.findCorrespondingBasicDataType(dataTypeNode);
|
|
208
|
+
if (basicDataType === DataType.ExtensionObject) {
|
|
226
209
|
// console.log("xxxxxxxxxx ", dataTypeNode.toString(addressSpace as any));
|
|
227
210
|
return { dataType: DataType.ExtensionObject, value: null };
|
|
228
211
|
}
|
|
229
|
-
const dv = findSimpleType(DataType[
|
|
212
|
+
const dv = findSimpleType(DataType[basicDataType]).defaultValue;
|
|
230
213
|
if (dv === undefined || dv === null) {
|
|
231
214
|
// return
|
|
232
215
|
return { dataType: DataType.Null };
|
|
@@ -247,16 +230,16 @@ function makeDefaultVariant(addressSpace: IAddressSpace, dataTypeNode: NodeId, v
|
|
|
247
230
|
case -2: // any
|
|
248
231
|
case -1:
|
|
249
232
|
arrayType = VariantArrayType.Scalar;
|
|
250
|
-
variant = { dataType, value, arrayType };
|
|
233
|
+
variant = { dataType: basicDataType, value, arrayType };
|
|
251
234
|
break;
|
|
252
235
|
case 0: // one or more dimension
|
|
253
236
|
case 1: // one dimension
|
|
254
237
|
arrayType = VariantArrayType.Array;
|
|
255
|
-
variant = { dataType, value: [], arrayType };
|
|
238
|
+
variant = { dataType: basicDataType, value: [], arrayType };
|
|
256
239
|
break;
|
|
257
240
|
default:
|
|
258
241
|
arrayType = VariantArrayType.Matrix;
|
|
259
|
-
variant = { dataType, value: [], arrayType, dimensions: [] };
|
|
242
|
+
variant = { dataType: basicDataType, value: [], arrayType, dimensions: [] };
|
|
260
243
|
break;
|
|
261
244
|
}
|
|
262
245
|
// console.log(variant, DataType[dataType], valueRank);
|
|
@@ -445,7 +428,6 @@ export function makeStuff(addressSpace: IAddressSpace): any {
|
|
|
445
428
|
|
|
446
429
|
this.isDraft = attrs.ReleaseStatus === "Draft";
|
|
447
430
|
this.obj.isDeprecated = attrs.ReleaseStatus === "Deprecated";
|
|
448
|
-
|
|
449
431
|
},
|
|
450
432
|
finish(this: any) {
|
|
451
433
|
if (this.isDraft || this.isDeprecated) {
|
|
@@ -558,49 +540,52 @@ export function makeStuff(addressSpace: IAddressSpace): any {
|
|
|
558
540
|
debugLog("Ignoring Draft/Deprecated dataType =", this.obj.browseName.toString());
|
|
559
541
|
return;
|
|
560
542
|
}
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
543
|
+
/*
|
|
544
|
+
export interface StructureFieldOptions {
|
|
545
|
+
name?: UAString ; // **
|
|
546
|
+
description?: (LocalizedTextLike | null); // **
|
|
547
|
+
dataType?: (NodeIdLike | null);
|
|
548
|
+
valueRank?: Int32 ;
|
|
549
|
+
arrayDimensions?: UInt32 [] | null;
|
|
550
|
+
maxStringLength?: UInt32 ;
|
|
551
|
+
isOptional?: UABoolean ;
|
|
552
|
+
}
|
|
553
|
+
export interface EnumValueTypeOptions {
|
|
554
|
+
value?: Int64 ;
|
|
555
|
+
displayName?: (LocalizedTextLike | null);
|
|
556
|
+
description?: (LocalizedTextLike | null); // **
|
|
557
|
+
}
|
|
558
|
+
export interface EnumFieldOptions extends EnumValueTypeOptions {
|
|
559
|
+
name?: UAString ; // **
|
|
560
|
+
}
|
|
561
|
+
*/
|
|
562
|
+
|
|
563
|
+
const definitionFields = this.definitionFields as StructureFieldOptions[] | EnumFieldOptions[];
|
|
564
|
+
|
|
565
|
+
// replace DataType with nodeId, and description to LocalizedText
|
|
566
|
+
definitionFields.map((x: any) => {
|
|
567
|
+
if (x.description) {
|
|
568
|
+
x.description = { text: x.description };
|
|
569
|
+
}
|
|
570
|
+
if (x.displayName) {
|
|
571
|
+
x.displayName = { text: x.displayName };
|
|
572
|
+
}
|
|
564
573
|
if (x.dataType) {
|
|
565
574
|
x.dataType = convertToNodeId(x.dataType);
|
|
566
575
|
}
|
|
567
576
|
return x;
|
|
568
577
|
});
|
|
569
|
-
|
|
578
|
+
this.obj.partialDefinition = definitionFields;
|
|
579
|
+
|
|
570
580
|
const dataTypeNode = _internal_createNode(this.obj) as UADataType;
|
|
571
581
|
assert(addressSpace1.findNode(this.obj.nodeId));
|
|
572
582
|
const definitionName = dataTypeNode.browseName.name!;
|
|
573
583
|
|
|
574
|
-
let alreadyCalled = false;
|
|
575
584
|
const processBasicDataType = async (addressSpace2: IAddressSpace) => {
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
const structure = addressSpace2.findDataType("Structure");
|
|
581
|
-
const union = addressSpace2.findDataType("Union");
|
|
582
|
-
|
|
583
|
-
// we have a data type from a companion specification
|
|
584
|
-
// let's see if this data type need to be registered
|
|
585
|
-
const isEnumeration = enumeration && dataTypeNode.isSupertypeOf(enumeration);
|
|
586
|
-
const isStructure = structure && dataTypeNode.isSupertypeOf(structure);
|
|
587
|
-
const isUnion = !!(structure && union && dataTypeNode.isSupertypeOf(union!));
|
|
588
|
-
|
|
589
|
-
if (definitionFields.length) {
|
|
590
|
-
// remove <namespace>:
|
|
591
|
-
const nameWithoutNamespace = definitionName.split(":").slice(-1)[0];
|
|
592
|
-
|
|
593
|
-
if (isStructure /*&& dataTypeNode.nodeId.namespace !== 0*/) {
|
|
594
|
-
// note: at this stage, structure definition will be incomplete as we do not know
|
|
595
|
-
// what is the subType yet, encodings are also unknown...
|
|
596
|
-
// structureType may also be inaccurate
|
|
597
|
-
debugLog("setting structure $definition for ", definitionName, nameWithoutNamespace);
|
|
598
|
-
(dataTypeNode as any).$definition = makeStructureDefinition(definitionName, definitionFields, isUnion);
|
|
599
|
-
} else if (isEnumeration /* && dataTypeNode.nodeId.namespace !== 0 */) {
|
|
600
|
-
(dataTypeNode as any).$definition = makeEnumDefinition(definitionFields);
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
if (!isEnumeration && !isStructure && this.obj.nodeId.namespace !== 0) {
|
|
585
|
+
const isStructure = dataTypeNode.isStructure();
|
|
586
|
+
const isEnumeration = dataTypeNode.isEnumeration();
|
|
587
|
+
if (!isEnumeration && !isStructure && dataTypeNode.nodeId.namespace !== 0) {
|
|
588
|
+
// add a custom basic type that is not a structure nor a enumeration
|
|
604
589
|
pendingSimpleTypeToRegister.push({ name: definitionName, dataTypeNodeId: dataTypeNode.nodeId });
|
|
605
590
|
}
|
|
606
591
|
};
|
|
@@ -1289,7 +1274,6 @@ export function makeStuff(addressSpace: IAddressSpace): any {
|
|
|
1289
1274
|
|
|
1290
1275
|
this.isDraft = attrs.ReleaseStatus === "Draft";
|
|
1291
1276
|
this.isDeprecated = attrs.ReleaseStatus === "Deprecated";
|
|
1292
|
-
|
|
1293
1277
|
},
|
|
1294
1278
|
finish(this: any) {
|
|
1295
1279
|
if (this.isDraft || this.isDeprecated) {
|
|
@@ -1316,6 +1300,8 @@ export function makeStuff(addressSpace: IAddressSpace): any {
|
|
|
1316
1300
|
};
|
|
1317
1301
|
postTaskInitializeVariable.push(task);
|
|
1318
1302
|
} else {
|
|
1303
|
+
const captureName = this.obj.browseName.toString();
|
|
1304
|
+
const captureNodeId = this.obj.nodeId;
|
|
1319
1305
|
const task = async (addressSpace2: IAddressSpace) => {
|
|
1320
1306
|
const dataTypeNode = variable.dataType;
|
|
1321
1307
|
const valueRank = variable.valueRank;
|
|
@@ -1374,7 +1360,6 @@ export function makeStuff(addressSpace: IAddressSpace): any {
|
|
|
1374
1360
|
|
|
1375
1361
|
this.isDraft = attrs.ReleaseStatus === "Draft";
|
|
1376
1362
|
this.isDeprecated = attrs.ReleaseStatus === "Deprecated";
|
|
1377
|
-
|
|
1378
1363
|
},
|
|
1379
1364
|
finish(this: any) {
|
|
1380
1365
|
if (this.isDraft || this.isDeprecated) {
|
|
@@ -1420,7 +1405,6 @@ export function makeStuff(addressSpace: IAddressSpace): any {
|
|
|
1420
1405
|
|
|
1421
1406
|
this.isDraft = attrs.ReleaseStatus === "Draft";
|
|
1422
1407
|
this.isDeprecated = attrs.ReleaseStatus === "Deprecated";
|
|
1423
|
-
|
|
1424
1408
|
},
|
|
1425
1409
|
finish(this: any) {
|
|
1426
1410
|
if (this.isDraft || this.isDeprecated) {
|
package/src/address_space.ts
CHANGED
|
@@ -10,7 +10,7 @@ import { ExtraDataTypeManager } from "node-opcua-client-dynamic-extension-object
|
|
|
10
10
|
import { DataTypeIds, VariableTypeIds } from "node-opcua-constants";
|
|
11
11
|
import { BrowseDirection, NodeClass, QualifiedName } from "node-opcua-data-model";
|
|
12
12
|
import { ExtensionObject } from "node-opcua-extension-object";
|
|
13
|
-
import { coerceExpandedNodeId, makeNodeId, NodeId, NodeIdLike, resolveNodeId, sameNodeId } from "node-opcua-nodeid";
|
|
13
|
+
import { coerceExpandedNodeId, coerceNodeId, makeNodeId, NodeId, NodeIdLike, resolveNodeId, sameNodeId } from "node-opcua-nodeid";
|
|
14
14
|
import { ObjectRegistry } from "node-opcua-object-registry";
|
|
15
15
|
import { BrowseResult } from "node-opcua-service-browse";
|
|
16
16
|
import { StatusCodes } from "node-opcua-status-code";
|
|
@@ -69,7 +69,8 @@ const doDebug = false;
|
|
|
69
69
|
const Dequeue = require("dequeue");
|
|
70
70
|
|
|
71
71
|
const regexNumberColumnString = /^([0-9]+):(.*)/;
|
|
72
|
-
|
|
72
|
+
const enumerationTypeNodeId = coerceNodeId(DataTypeIds.Enumeration);
|
|
73
|
+
|
|
73
74
|
function _extract_namespace_and_browse_name_as_string(
|
|
74
75
|
addressSpace: AddressSpace,
|
|
75
76
|
browseName: NodeIdLike | QualifiedName,
|
|
@@ -472,10 +473,8 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
472
473
|
dataTypeNode.constructor.name
|
|
473
474
|
);
|
|
474
475
|
}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
const enumerationType = this.findDataType("Enumeration")!;
|
|
478
|
-
if (sameNodeId(enumerationType.nodeId, dataTypeNode!.nodeId)) {
|
|
476
|
+
|
|
477
|
+
if (sameNodeId(enumerationTypeNodeId, dataTypeNode!.nodeId)) {
|
|
479
478
|
return DataType.Int32;
|
|
480
479
|
}
|
|
481
480
|
|
|
@@ -483,11 +482,18 @@ export class AddressSpace implements AddressSpacePrivate {
|
|
|
483
482
|
// Number
|
|
484
483
|
return DataType.Null; //which one ?
|
|
485
484
|
}
|
|
486
|
-
|
|
487
|
-
if (dataTypeNode.nodeId.namespace === 0 &&
|
|
485
|
+
|
|
486
|
+
if (dataTypeNode.nodeId.namespace === 0 && dataTypeNode.nodeId.value === 0) {
|
|
487
|
+
return DataType.Null;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
if (dataTypeNode.nodeId.namespace === 0 && dataTypeNode.nodeId.value <= 25) {
|
|
488
491
|
return dataTypeNode.nodeId.value as DataType;
|
|
489
492
|
}
|
|
490
|
-
|
|
493
|
+
|
|
494
|
+
const result = this.findCorrespondingBasicDataType(dataTypeNode.subtypeOfObj as UADataType);
|
|
495
|
+
|
|
496
|
+
return result;
|
|
491
497
|
}
|
|
492
498
|
|
|
493
499
|
/**
|
|
@@ -9,7 +9,7 @@ import { UInt16 } from "node-opcua-basic-types";
|
|
|
9
9
|
import { coerceLocalizedText, LocalizedText, LocalizedTextLike, NodeClass } from "node-opcua-data-model";
|
|
10
10
|
import { DataValue } from "node-opcua-data-value";
|
|
11
11
|
import { checkDebugFlag, make_debugLog } from "node-opcua-debug";
|
|
12
|
-
import { NodeId } from "node-opcua-nodeid";
|
|
12
|
+
import { NodeId, sameNodeId } from "node-opcua-nodeid";
|
|
13
13
|
import { UAAcknowledgeableCondition } from "node-opcua-nodeset-ua";
|
|
14
14
|
import { StatusCode, StatusCodes } from "node-opcua-status-code";
|
|
15
15
|
import { SimpleAttributeOperand, TimeZoneDataType } from "node-opcua-types";
|
|
@@ -175,14 +175,14 @@ export class ConditionSnapshot extends EventEmitter {
|
|
|
175
175
|
// a nodeId/Variant map
|
|
176
176
|
_record_condition_state(this, condition);
|
|
177
177
|
|
|
178
|
-
if (branchId
|
|
178
|
+
if (sameNodeId(branchId, NodeId.nullNodeId)) {
|
|
179
179
|
_installOnChangeEventHandlers(this, condition, "");
|
|
180
180
|
}
|
|
181
181
|
this._set_var("branchId", DataType.NodeId, branchId);
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
public _constructEventData(): IEventData {
|
|
185
|
-
if (this.branchId
|
|
185
|
+
if (this.branchId && sameNodeId(this.branchId, NodeId.nullNodeId)) {
|
|
186
186
|
_ensure_condition_values_correctness(this, this.condition!, "", []);
|
|
187
187
|
}
|
|
188
188
|
const c = this.condition as UAConditionImpl;
|
|
@@ -594,7 +594,7 @@ export class ConditionSnapshot extends EventEmitter {
|
|
|
594
594
|
}
|
|
595
595
|
|
|
596
596
|
public isCurrentBranch(): boolean {
|
|
597
|
-
return this._get_var("branchId")
|
|
597
|
+
return sameNodeId(this._get_var("branchId"), NodeId.nullNodeId);
|
|
598
598
|
}
|
|
599
599
|
|
|
600
600
|
// -- ACKNOWLEDGEABLE -------------------------------------------------------------------
|
|
@@ -6,7 +6,7 @@ import { isEqual } from "lodash";
|
|
|
6
6
|
import { assert } from "node-opcua-assert";
|
|
7
7
|
import { NodeClass } from "node-opcua-data-model";
|
|
8
8
|
import { DataValue } from "node-opcua-data-value";
|
|
9
|
-
import { NodeId } from "node-opcua-nodeid";
|
|
9
|
+
import { NodeId, sameNodeId } from "node-opcua-nodeid";
|
|
10
10
|
import { StatusCodes } from "node-opcua-status-code";
|
|
11
11
|
import { DataType } from "node-opcua-variant";
|
|
12
12
|
import { UAAlarmCondition_Base } from "node-opcua-nodeset-ua";
|
|
@@ -498,7 +498,7 @@ export class UAAlarmConditionImpl extends UAAcknowledgeableConditionImpl impleme
|
|
|
498
498
|
if (this.currentBranch().getRetain()) {
|
|
499
499
|
// we need to create a new branch so the previous state could be acknowledged
|
|
500
500
|
const newBranch = this.createBranch();
|
|
501
|
-
assert(newBranch.getBranchId()
|
|
501
|
+
assert(!sameNodeId(newBranch.getBranchId(), NodeId.nullNodeId));
|
|
502
502
|
// also raised a new Event for the new branch as branchId has changed
|
|
503
503
|
this.raiseNewBranchState(newBranch);
|
|
504
504
|
}
|
|
@@ -238,7 +238,7 @@ export class UAConditionImpl extends UABaseEventImpl implements UAConditionEx {
|
|
|
238
238
|
*/
|
|
239
239
|
public post_initialize(): void {
|
|
240
240
|
assert(!this._branch0);
|
|
241
|
-
this._branch0 = new ConditionSnapshot(this, NodeId
|
|
241
|
+
this._branch0 = new ConditionSnapshot(this, new NodeId());
|
|
242
242
|
|
|
243
243
|
// the condition OPCUA object alway reflects the default branch states
|
|
244
244
|
// so we set a mechanism that automatically keeps self in sync
|
|
@@ -284,7 +284,7 @@ export class UAConditionImpl extends UABaseEventImpl implements UAConditionEx {
|
|
|
284
284
|
*/
|
|
285
285
|
public deleteBranch(branch: ConditionSnapshot): void {
|
|
286
286
|
const key = branch.getBranchId().toString();
|
|
287
|
-
assert(branch.getBranchId()
|
|
287
|
+
assert(!sameNodeId(branch.getBranchId(), NodeId.nullNodeId), "cannot delete branch zero");
|
|
288
288
|
assert(Object.prototype.hasOwnProperty.call(this._branches, key));
|
|
289
289
|
delete this._branches[key];
|
|
290
290
|
this.emit("branch_deleted", key);
|
|
@@ -560,7 +560,7 @@ export class UAConditionImpl extends UABaseEventImpl implements UAConditionEx {
|
|
|
560
560
|
public raiseNewBranchState(branch: ConditionSnapshot): void {
|
|
561
561
|
this.raiseConditionEvent(branch, true);
|
|
562
562
|
|
|
563
|
-
if (branch.getBranchId()
|
|
563
|
+
if (!sameNodeId(branch.getBranchId(), NodeId.nullNodeId) && !branch.getRetain()) {
|
|
564
564
|
// xx console.log(" Deleting not longer needed branch ", branch.getBranchId().toString());
|
|
565
565
|
// branch can be deleted
|
|
566
566
|
this.deleteBranch(branch);
|
|
@@ -789,7 +789,7 @@ function UACondition_instantiate(
|
|
|
789
789
|
// install initial branch ID (null NodeId);
|
|
790
790
|
conditionNode.branchId.setValueFromSource({
|
|
791
791
|
dataType: DataType.NodeId,
|
|
792
|
-
value: NodeId
|
|
792
|
+
value: new NodeId()
|
|
793
793
|
});
|
|
794
794
|
|
|
795
795
|
// install 'Comment' condition variable
|
|
@@ -920,7 +920,9 @@ function UACondition_instantiate(
|
|
|
920
920
|
conditionNode.sourceNode.setValueFromSource(conditionSourceNode.readAttribute(null, AttributeIds.NodeId).value);
|
|
921
921
|
|
|
922
922
|
// set source Name (defined in UABaseEventType)
|
|
923
|
-
|
|
923
|
+
const displayName: LocalizedText = conditionSourceNode.readAttribute(null, AttributeIds.DisplayName).value
|
|
924
|
+
.value as LocalizedText;
|
|
925
|
+
conditionNode.sourceName.setValueFromSource({ dataType: DataType.String, value: displayName.text });
|
|
924
926
|
}
|
|
925
927
|
}
|
|
926
928
|
|
|
@@ -953,7 +955,7 @@ function UACondition_instantiate(
|
|
|
953
955
|
*/
|
|
954
956
|
const baseConditionClassType = addressSpace.findObjectType("ProcessConditionClassType");
|
|
955
957
|
// assert(baseConditionClassType,"Expecting BaseConditionClassType to be in addressSpace");
|
|
956
|
-
let conditionClassId = baseConditionClassType ? baseConditionClassType.nodeId : NodeId
|
|
958
|
+
let conditionClassId = baseConditionClassType ? baseConditionClassType.nodeId : new NodeId();
|
|
957
959
|
let conditionClassName = baseConditionClassType ? baseConditionClassType.displayName[0] : "";
|
|
958
960
|
if (options.conditionClass) {
|
|
959
961
|
if (typeof options.conditionClass === "string") {
|
|
@@ -1123,7 +1125,11 @@ function _perform_condition_refresh(addressSpace: AddressSpacePrivate, inputArgu
|
|
|
1123
1125
|
return StatusCodes.Good;
|
|
1124
1126
|
}
|
|
1125
1127
|
|
|
1126
|
-
function _condition_refresh2_method(
|
|
1128
|
+
function _condition_refresh2_method(
|
|
1129
|
+
inputArguments: VariantLike[],
|
|
1130
|
+
context: ISessionContext,
|
|
1131
|
+
callback: CallbackT<CallMethodResultOptions>
|
|
1132
|
+
) {
|
|
1127
1133
|
// arguments : IntegerId SubscriptionId
|
|
1128
1134
|
// arguments : IntegerId MonitoredItemId
|
|
1129
1135
|
assert(inputArguments.length === 2);
|
|
@@ -1146,7 +1152,11 @@ function _condition_refresh2_method(inputArguments: VariantLike[], context: ISes
|
|
|
1146
1152
|
});
|
|
1147
1153
|
}
|
|
1148
1154
|
|
|
1149
|
-
function _add_comment_method(
|
|
1155
|
+
function _add_comment_method(
|
|
1156
|
+
inputArguments: VariantLike[],
|
|
1157
|
+
context: ISessionContext,
|
|
1158
|
+
callback: CallbackT<CallMethodResultOptions>
|
|
1159
|
+
) {
|
|
1150
1160
|
//
|
|
1151
1161
|
// The AddComment Method is used to apply a comment to a specific state of a Condition
|
|
1152
1162
|
// instance. Normally, the NodeId of the object instance as the ObjectId is passed to the Call
|
|
@@ -79,7 +79,7 @@ export class UAOffNormalAlarmImpl extends UADiscreteAlarmImpl implements UAOffNo
|
|
|
79
79
|
const normalState = addressSpace._coerceNode(options.normalState)! as UAVariable;
|
|
80
80
|
// assert(normalState, "Expecting a valid normalState node");
|
|
81
81
|
|
|
82
|
-
const normalStateNodeId = normalState ? normalState.nodeId : NodeId
|
|
82
|
+
const normalStateNodeId = normalState ? normalState.nodeId : new NodeId();
|
|
83
83
|
alarmNode.normalState.setValueFromSource({ dataType: DataType.NodeId, value: normalStateNodeId });
|
|
84
84
|
|
|
85
85
|
if (inputNode) {
|
package/src/base_node_private.ts
CHANGED
|
@@ -343,6 +343,10 @@ function AccessLevelFlags_toString(this: UAVariable, options: ToStringOption) {
|
|
|
343
343
|
);
|
|
344
344
|
}
|
|
345
345
|
}
|
|
346
|
+
|
|
347
|
+
interface WithDataValue {
|
|
348
|
+
$dataValue?: DataValue;
|
|
349
|
+
}
|
|
346
350
|
export function VariableOrVariableType_toString(this: UAVariableType | UAVariable, options: ToStringOption): void {
|
|
347
351
|
assert(options);
|
|
348
352
|
if (this.dataType) {
|
|
@@ -352,7 +356,7 @@ export function VariableOrVariableType_toString(this: UAVariableType | UAVariabl
|
|
|
352
356
|
options.add(options.padding + chalk.yellow(" dataType : ") + this.dataType + " " + n);
|
|
353
357
|
}
|
|
354
358
|
if (this.nodeClass === NodeClass.Variable) {
|
|
355
|
-
const _dataValue = (<
|
|
359
|
+
const _dataValue = (<WithDataValue>this).$dataValue as DataValue | undefined;
|
|
356
360
|
if (_dataValue) {
|
|
357
361
|
options.add(
|
|
358
362
|
options.padding +
|
|
@@ -622,7 +626,7 @@ function _makeReferenceDescription(addressSpace: IAddressSpace, reference: UARef
|
|
|
622
626
|
};
|
|
623
627
|
}
|
|
624
628
|
if (data.typeDefinition === null) {
|
|
625
|
-
data.typeDefinition = NodeId
|
|
629
|
+
data.typeDefinition = new NodeId();
|
|
626
630
|
}
|
|
627
631
|
const referenceDescription = new ReferenceDescription(data);
|
|
628
632
|
return referenceDescription;
|
package/src/event_data.ts
CHANGED
package/src/namespace_impl.ts
CHANGED
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
RolePermissionTypeOptions
|
|
29
29
|
} from "node-opcua-types";
|
|
30
30
|
import * as utils from "node-opcua-utils";
|
|
31
|
-
import { DataType, Variant, VariantArrayType } from "node-opcua-variant";
|
|
31
|
+
import { DataType, Variant, VariantArrayType, verifyRankAndDimensions } from "node-opcua-variant";
|
|
32
32
|
import {
|
|
33
33
|
AddBaseNodeOptions,
|
|
34
34
|
AddEnumerationTypeOptions,
|
|
@@ -100,7 +100,7 @@ import { _install_TwoStateVariable_machinery, _addTwoStateVariable } from "./sta
|
|
|
100
100
|
//
|
|
101
101
|
import { NamespacePrivate, UANamespace_process_modelling_rule } from "./namespace_private";
|
|
102
102
|
import { BaseNodeImpl } from "./base_node_impl";
|
|
103
|
-
import { UAVariableImpl
|
|
103
|
+
import { UAVariableImpl } from "./ua_variable_impl";
|
|
104
104
|
|
|
105
105
|
import { ConstructNodeIdOptions, NodeIdManager } from "./nodeid_manager";
|
|
106
106
|
import { _addTwoStateDiscrete } from "./data_access/ua_two_state_discrete";
|
|
@@ -238,7 +238,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
238
238
|
}
|
|
239
239
|
|
|
240
240
|
public getDefaultNamespace(): NamespacePrivate {
|
|
241
|
-
return this.index === 0 ? this :
|
|
241
|
+
return this.index === 0 ? this : this.addressSpace.getDefaultNamespace();
|
|
242
242
|
}
|
|
243
243
|
|
|
244
244
|
public dispose(): void {
|
|
@@ -656,7 +656,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
656
656
|
*/
|
|
657
657
|
public deleteNode(nodeOrNodeId: NodeId | BaseNode): void {
|
|
658
658
|
let node: BaseNode | null = null;
|
|
659
|
-
let nodeId: NodeId = NodeId
|
|
659
|
+
let nodeId: NodeId = new NodeId();
|
|
660
660
|
if (nodeOrNodeId instanceof NodeId) {
|
|
661
661
|
nodeId = nodeOrNodeId;
|
|
662
662
|
node = this.findNode(nodeId);
|
|
@@ -1337,7 +1337,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1337
1337
|
// or OptionSet DataType. It is derived from the DataType EnumValueType. If used for an
|
|
1338
1338
|
// OptionSet, the corresponding Value in the base type contains the number of the bit associated
|
|
1339
1339
|
// with the field. The EnumField is formally defined in Table 37.
|
|
1340
|
-
(enumType as any).$
|
|
1340
|
+
(enumType as any).$fullDefinition = new EnumDefinition({
|
|
1341
1341
|
fields: enumeration.map(
|
|
1342
1342
|
(x: string, index: number) =>
|
|
1343
1343
|
new EnumField({
|
|
@@ -1376,7 +1376,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1376
1376
|
});
|
|
1377
1377
|
assert(enumValues.browseName.toString() === "EnumValues");
|
|
1378
1378
|
|
|
1379
|
-
(enumType as any).$
|
|
1379
|
+
(enumType as any).$fullDefinition = new EnumDefinition({
|
|
1380
1380
|
fields: enumeration.map(
|
|
1381
1381
|
(x: EnumerationItem, index: number) =>
|
|
1382
1382
|
new EnumField({
|
|
@@ -592,7 +592,7 @@ function _dumpValue(xw: XmlWriter, node: UAVariable | UAVariableType, value: Var
|
|
|
592
592
|
|
|
593
593
|
function _dumpArrayDimensionsAttribute(xw: XmlWriter, node: UAVariableType | UAVariable) {
|
|
594
594
|
if (node.arrayDimensions) {
|
|
595
|
-
if (node.arrayDimensions.length === 1 && node.arrayDimensions[0] === 0) {
|
|
595
|
+
if (node.valueRank === -1 || (node.arrayDimensions.length === 1 && node.arrayDimensions[0] === 0)) {
|
|
596
596
|
return;
|
|
597
597
|
}
|
|
598
598
|
xw.writeAttribute("ArrayDimensions", node.arrayDimensions.join(","));
|
|
@@ -749,7 +749,11 @@ function _dumpEnumDefinition(xw: XmlWriter, enumDefinition: EnumDefinition) {
|
|
|
749
749
|
xw.endElement();
|
|
750
750
|
}
|
|
751
751
|
}
|
|
752
|
-
function _dumpStructureDefinition(
|
|
752
|
+
function _dumpStructureDefinition(
|
|
753
|
+
xw: XmlWriter,
|
|
754
|
+
structureDefinition: StructureDefinition,
|
|
755
|
+
baseStructureDefinition: StructureDefinition | null | undefined
|
|
756
|
+
) {
|
|
753
757
|
/*
|
|
754
758
|
* note: baseDataType and defaultEncodingId are implicit and not stored in the XML file ??
|
|
755
759
|
*
|
|
@@ -757,8 +761,12 @@ function _dumpStructureDefinition(xw: XmlWriter, structureDefinition: StructureD
|
|
|
757
761
|
const baseDataType = structureDefinition.baseDataType;
|
|
758
762
|
const defaultEncodingId = structureDefinition.defaultEncodingId;
|
|
759
763
|
|
|
760
|
-
|
|
761
|
-
|
|
764
|
+
// do not repeat elements that are already defined in base structure in the xml ouput!
|
|
765
|
+
const fields = structureDefinition.fields || [];
|
|
766
|
+
const nbFieldsInBase: number = baseStructureDefinition ? baseStructureDefinition.fields?.length || 0 : 0;
|
|
767
|
+
|
|
768
|
+
for(let index = nbFieldsInBase; index <fields.length; index++ ) {
|
|
769
|
+
const defItem = fields[index];
|
|
762
770
|
xw.startElement("Field");
|
|
763
771
|
xw.writeAttribute("Name", defItem.name!);
|
|
764
772
|
|
|
@@ -788,27 +796,29 @@ function _dumpStructureDefinition(xw: XmlWriter, structureDefinition: StructureD
|
|
|
788
796
|
xw.endElement();
|
|
789
797
|
}
|
|
790
798
|
}
|
|
791
|
-
function _dumpUADataTypeDefinition(xw: XmlWriter,
|
|
799
|
+
function _dumpUADataTypeDefinition(xw: XmlWriter, uaDataType: UADataType) {
|
|
792
800
|
// to do remove DataType from base class
|
|
793
|
-
|
|
794
|
-
const definition =
|
|
801
|
+
const uaDataTypeBase = uaDataType.subtypeOfObj;
|
|
802
|
+
const definition = uaDataType.getDefinition();
|
|
795
803
|
if (!definition) {
|
|
796
804
|
return;
|
|
797
805
|
}
|
|
798
806
|
if (definition instanceof EnumDefinition) {
|
|
799
807
|
xw.startElement("Definition");
|
|
800
|
-
xw.writeAttribute("Name",
|
|
808
|
+
xw.writeAttribute("Name", uaDataType.browseName.name!);
|
|
801
809
|
_dumpEnumDefinition(xw, definition);
|
|
802
810
|
xw.endElement();
|
|
803
811
|
return;
|
|
804
812
|
}
|
|
805
813
|
if (definition instanceof StructureDefinition) {
|
|
814
|
+
const baseDefinition = uaDataTypeBase ? (uaDataTypeBase.getDefinition() as StructureDefinition | null) : null;
|
|
815
|
+
|
|
806
816
|
xw.startElement("Definition");
|
|
807
|
-
xw.writeAttribute("Name",
|
|
817
|
+
xw.writeAttribute("Name", uaDataType.browseName.name!);
|
|
808
818
|
if (definition.structureType === StructureType.Union) {
|
|
809
819
|
xw.writeAttribute("IsUnion", "true");
|
|
810
820
|
}
|
|
811
|
-
_dumpStructureDefinition(xw, definition);
|
|
821
|
+
_dumpStructureDefinition(xw, definition, baseDefinition);
|
|
812
822
|
xw.endElement();
|
|
813
823
|
return;
|
|
814
824
|
}
|