node-opcua-address-space 2.70.3 → 2.72.1
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/loader/load_nodeset2.js +18 -14
- package/dist/source/loader/load_nodeset2.js.map +1 -1
- package/dist/source/loader/make_semver_compatible.d.ts +6 -0
- package/dist/source/loader/make_semver_compatible.js +26 -0
- package/dist/source/loader/make_semver_compatible.js.map +1 -0
- package/dist/source/loader/make_xml_extension_object_parser.js +12 -2
- package/dist/source/loader/make_xml_extension_object_parser.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_acknowledgeable_condition_impl.d.ts +3 -1
- package/dist/src/alarms_and_conditions/ua_acknowledgeable_condition_impl.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_alarm_condition_impl.d.ts +12 -6
- package/dist/src/alarms_and_conditions/ua_alarm_condition_impl.js +2 -2
- package/dist/src/alarms_and_conditions/ua_alarm_condition_impl.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_certificate_expiration_alarm_impl.d.ts +18 -3
- package/dist/src/alarms_and_conditions/ua_certificate_expiration_alarm_impl.js +95 -5
- package/dist/src/alarms_and_conditions/ua_certificate_expiration_alarm_impl.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_condition_impl.d.ts +7 -2
- package/dist/src/alarms_and_conditions/ua_condition_impl.js +6 -4
- package/dist/src/alarms_and_conditions/ua_condition_impl.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_discrete_alarm_impl.d.ts +4 -3
- package/dist/src/alarms_and_conditions/ua_discrete_alarm_impl.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_exclusive_deviation_alarm_impl.d.ts +6 -3
- package/dist/src/alarms_and_conditions/ua_exclusive_deviation_alarm_impl.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_exclusive_level_alarm_impl.d.ts +3 -1
- package/dist/src/alarms_and_conditions/ua_exclusive_level_alarm_impl.js +2 -2
- package/dist/src/alarms_and_conditions/ua_exclusive_level_alarm_impl.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_exclusive_limit_alarm_impl.d.ts +5 -3
- package/dist/src/alarms_and_conditions/ua_exclusive_limit_alarm_impl.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_limit_alarm_impl.d.ts +12 -4
- package/dist/src/alarms_and_conditions/ua_limit_alarm_impl.js +3 -3
- package/dist/src/alarms_and_conditions/ua_limit_alarm_impl.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_non_exclusive_deviation_alarm_impl.d.ts +4 -3
- package/dist/src/alarms_and_conditions/ua_non_exclusive_deviation_alarm_impl.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_non_exclusive_limit_alarm_impl.d.ts +4 -3
- package/dist/src/alarms_and_conditions/ua_non_exclusive_limit_alarm_impl.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_off_normal_alarm_impl.d.ts +17 -8
- package/dist/src/alarms_and_conditions/ua_off_normal_alarm_impl.js +45 -19
- package/dist/src/alarms_and_conditions/ua_off_normal_alarm_impl.js.map +1 -1
- package/dist/src/alarms_and_conditions/ua_system_off_normal_alarm_impl.d.ts +4 -3
- package/dist/src/alarms_and_conditions/ua_system_off_normal_alarm_impl.js.map +1 -1
- package/dist/src/ua_object_impl.d.ts +4 -2
- package/dist/src/ua_object_impl.js +7 -1
- package/dist/src/ua_object_impl.js.map +1 -1
- package/dist/src/ua_variable_type_impl.js +8 -2
- package/dist/src/ua_variable_type_impl.js.map +1 -1
- package/dist/src/ua_view_impl.d.ts +6 -2
- package/dist/src/ua_view_impl.js +8 -1
- package/dist/src/ua_view_impl.js.map +1 -1
- package/package.json +38 -38
- package/source/loader/load_nodeset2.ts +21 -17
- package/source/loader/make_semver_compatible.ts +23 -0
- package/source/loader/make_xml_extension_object_parser.ts +16 -6
- package/src/alarms_and_conditions/ua_acknowledgeable_condition_impl.ts +13 -6
- package/src/alarms_and_conditions/ua_alarm_condition_impl.ts +15 -10
- package/src/alarms_and_conditions/ua_certificate_expiration_alarm_impl.ts +126 -10
- package/src/alarms_and_conditions/ua_condition_impl.ts +26 -13
- package/src/alarms_and_conditions/ua_discrete_alarm_impl.ts +10 -4
- package/src/alarms_and_conditions/ua_exclusive_deviation_alarm_impl.ts +7 -6
- package/src/alarms_and_conditions/ua_exclusive_level_alarm_impl.ts +5 -3
- package/src/alarms_and_conditions/ua_exclusive_limit_alarm_impl.ts +7 -6
- package/src/alarms_and_conditions/ua_exclusive_rate_of_change_alarm_impl.ts +1 -1
- package/src/alarms_and_conditions/ua_limit_alarm_impl.ts +23 -13
- package/src/alarms_and_conditions/ua_non_exclusive_deviation_alarm_impl.ts +6 -7
- package/src/alarms_and_conditions/ua_non_exclusive_limit_alarm_impl.ts +6 -7
- package/src/alarms_and_conditions/ua_off_normal_alarm_impl.ts +62 -30
- package/src/alarms_and_conditions/ua_system_off_normal_alarm_impl.ts +5 -5
- package/src/ua_object_impl.ts +11 -3
- package/src/ua_variable_type_impl.ts +11 -4
- package/src/ua_view_impl.ts +6 -4
- package/test_helpers/test_fixtures/dataType_issue.xml +9 -9
- package/test_helpers/test_fixtures/eurange_issue.xml +73 -0
- package/test_helpers/test_fixtures/nodeset_with_guid.xml +1442 -0
- package/test_helpers/test_fixtures/nodeset_with_int64_values.xml +31 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-opcua-address-space",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.72.1",
|
|
4
4
|
"description": "pure nodejs OPCUA SDK - module -address-space",
|
|
5
5
|
"main": "./dist/src/index_current.js",
|
|
6
6
|
"types": "./dist/source/index.d.ts",
|
|
@@ -17,54 +17,54 @@
|
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"@types/lodash": "4.14.182",
|
|
20
|
-
"async": "^3.2.
|
|
20
|
+
"async": "^3.2.4",
|
|
21
21
|
"chalk": "4.1.2",
|
|
22
22
|
"dequeue": "^1.0.5",
|
|
23
23
|
"lodash": "4.17.21",
|
|
24
|
-
"node-opcua-address-space-base": "2.
|
|
24
|
+
"node-opcua-address-space-base": "2.72.1",
|
|
25
25
|
"node-opcua-assert": "2.66.0",
|
|
26
|
-
"node-opcua-basic-types": "2.
|
|
27
|
-
"node-opcua-client-dynamic-extension-object": "2.
|
|
26
|
+
"node-opcua-basic-types": "2.72.1",
|
|
27
|
+
"node-opcua-client-dynamic-extension-object": "2.72.1",
|
|
28
28
|
"node-opcua-constants": "2.70.0",
|
|
29
|
-
"node-opcua-data-access": "2.
|
|
30
|
-
"node-opcua-data-model": "2.
|
|
31
|
-
"node-opcua-data-value": "2.
|
|
32
|
-
"node-opcua-date-time": "2.
|
|
33
|
-
"node-opcua-debug": "2.
|
|
34
|
-
"node-opcua-enum": "2.
|
|
35
|
-
"node-opcua-factory": "2.
|
|
36
|
-
"node-opcua-nodeid": "2.
|
|
37
|
-
"node-opcua-nodeset-ua": "2.
|
|
38
|
-
"node-opcua-numeric-range": "2.
|
|
39
|
-
"node-opcua-object-registry": "2.
|
|
40
|
-
"node-opcua-pseudo-session": "2.
|
|
41
|
-
"node-opcua-schemas": "2.
|
|
42
|
-
"node-opcua-service-browse": "2.
|
|
43
|
-
"node-opcua-service-call": "2.
|
|
44
|
-
"node-opcua-service-filter": "2.
|
|
45
|
-
"node-opcua-service-history": "2.
|
|
46
|
-
"node-opcua-service-translate-browse-path": "2.
|
|
47
|
-
"node-opcua-service-write": "2.
|
|
48
|
-
"node-opcua-status-code": "2.
|
|
49
|
-
"node-opcua-types": "2.
|
|
50
|
-
"node-opcua-utils": "2.
|
|
51
|
-
"node-opcua-variant": "2.
|
|
52
|
-
"node-opcua-xml2json": "2.
|
|
29
|
+
"node-opcua-data-access": "2.72.1",
|
|
30
|
+
"node-opcua-data-model": "2.72.1",
|
|
31
|
+
"node-opcua-data-value": "2.72.1",
|
|
32
|
+
"node-opcua-date-time": "2.71.0",
|
|
33
|
+
"node-opcua-debug": "2.71.0",
|
|
34
|
+
"node-opcua-enum": "2.71.0",
|
|
35
|
+
"node-opcua-factory": "2.72.1",
|
|
36
|
+
"node-opcua-nodeid": "2.71.0",
|
|
37
|
+
"node-opcua-nodeset-ua": "2.72.1",
|
|
38
|
+
"node-opcua-numeric-range": "2.72.1",
|
|
39
|
+
"node-opcua-object-registry": "2.71.0",
|
|
40
|
+
"node-opcua-pseudo-session": "2.72.1",
|
|
41
|
+
"node-opcua-schemas": "2.72.1",
|
|
42
|
+
"node-opcua-service-browse": "2.72.1",
|
|
43
|
+
"node-opcua-service-call": "2.72.1",
|
|
44
|
+
"node-opcua-service-filter": "2.72.1",
|
|
45
|
+
"node-opcua-service-history": "2.72.1",
|
|
46
|
+
"node-opcua-service-translate-browse-path": "2.72.1",
|
|
47
|
+
"node-opcua-service-write": "2.72.1",
|
|
48
|
+
"node-opcua-status-code": "2.71.0",
|
|
49
|
+
"node-opcua-types": "2.72.1",
|
|
50
|
+
"node-opcua-utils": "2.71.0",
|
|
51
|
+
"node-opcua-variant": "2.72.1",
|
|
52
|
+
"node-opcua-xml2json": "2.71.0",
|
|
53
53
|
"semver": "^7.3.7",
|
|
54
54
|
"set-prototype-of": "^1.0.0",
|
|
55
55
|
"thenify": "^3.3.1",
|
|
56
56
|
"xml-writer": "^1.7.0"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
|
-
"@types/semver": "7.3.
|
|
59
|
+
"@types/semver": "7.3.10",
|
|
60
60
|
"humanize": "0.0.9",
|
|
61
|
-
"node-opcua-benchmarker": "2.
|
|
62
|
-
"node-opcua-binary-stream": "2.
|
|
63
|
-
"node-opcua-extension-object": "2.
|
|
64
|
-
"node-opcua-leak-detector": "2.
|
|
65
|
-
"node-opcua-nodesets": "2.
|
|
66
|
-
"node-opcua-packet-analyzer": "2.
|
|
67
|
-
"node-opcua-test-fixtures": "2.
|
|
61
|
+
"node-opcua-benchmarker": "2.71.0",
|
|
62
|
+
"node-opcua-binary-stream": "2.71.0",
|
|
63
|
+
"node-opcua-extension-object": "2.72.1",
|
|
64
|
+
"node-opcua-leak-detector": "2.71.0",
|
|
65
|
+
"node-opcua-nodesets": "2.71.0",
|
|
66
|
+
"node-opcua-packet-analyzer": "2.72.1",
|
|
67
|
+
"node-opcua-test-fixtures": "2.71.0",
|
|
68
68
|
"should": "^13.2.3",
|
|
69
69
|
"sinon": "^14.0.0",
|
|
70
70
|
"source-map-support": "^0.5.21"
|
|
@@ -84,5 +84,5 @@
|
|
|
84
84
|
"internet of things"
|
|
85
85
|
],
|
|
86
86
|
"homepage": "http://node-opcua.github.io/",
|
|
87
|
-
"gitHead": "
|
|
87
|
+
"gitHead": "ba98dd91a9eada9815268c66c98ca5391bc884e7"
|
|
88
88
|
}
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
UAVariableType
|
|
18
18
|
} from "node-opcua-address-space-base";
|
|
19
19
|
import { assert, renderError } from "node-opcua-assert";
|
|
20
|
-
import { isValidGuid, StatusCodes } from "node-opcua-basic-types";
|
|
20
|
+
import { coerceInt64, coerceUInt64, Int64, isValidGuid, StatusCodes, UInt64 } from "node-opcua-basic-types";
|
|
21
21
|
import { EUInformation } from "node-opcua-data-access";
|
|
22
22
|
import {
|
|
23
23
|
AccessLevelFlag,
|
|
@@ -55,6 +55,7 @@ import { NamespacePrivate } from "../../src/namespace_private";
|
|
|
55
55
|
import { promoteObjectsAndVariables } from "./namespace_post_step";
|
|
56
56
|
import { ensureDatatypeExtracted } from "./ensure_datatype_extracted";
|
|
57
57
|
import { decodeXmlExtensionObject } from "./decode_xml_extension_object";
|
|
58
|
+
import { makeSemverCompatible } from "./make_semver_compatible";
|
|
58
59
|
|
|
59
60
|
const doDebug = checkDebugFlag(__filename);
|
|
60
61
|
const debugLog = make_debugLog(__filename);
|
|
@@ -248,20 +249,6 @@ export function makeNodeSetParserEngine(addressSpace: IAddressSpace): NodeSet2Pa
|
|
|
248
249
|
return namespace;
|
|
249
250
|
}
|
|
250
251
|
|
|
251
|
-
/**
|
|
252
|
-
* take a OPCUA version string and make it compliant with the semver specification
|
|
253
|
-
* @param version
|
|
254
|
-
* @returns
|
|
255
|
-
*/
|
|
256
|
-
function makeSemverCompatible(version?: string): string {
|
|
257
|
-
version = version || "0.0.0";
|
|
258
|
-
const version_array = version.split(".").map((a) => parseInt(a, 10));
|
|
259
|
-
|
|
260
|
-
if (version_array.length === 2) {
|
|
261
|
-
version_array.push(0);
|
|
262
|
-
}
|
|
263
|
-
return version_array.map((a) => a.toString()).join(".");
|
|
264
|
-
}
|
|
265
252
|
function _add_namespace(model: Model) {
|
|
266
253
|
if (model.requiredModels.length > 0) {
|
|
267
254
|
// check that required models exist already in the address space
|
|
@@ -276,8 +263,18 @@ export function makeNodeSetParserEngine(addressSpace: IAddressSpace): NodeSet2Pa
|
|
|
276
263
|
);
|
|
277
264
|
throw new Error("LoadNodeSet : Cannot find namespace for " + requiredModel.modelUri);
|
|
278
265
|
}
|
|
279
|
-
|
|
280
|
-
|
|
266
|
+
/**
|
|
267
|
+
* from https://reference.opcfoundation.org/Core/docs/Part6/F.2/
|
|
268
|
+
* The version of the model defined in the UANodeSet.
|
|
269
|
+
* This is a human readable string and not intended for programmatic comparisons.
|
|
270
|
+
*
|
|
271
|
+
*/
|
|
272
|
+
const isLowerVersion = (existingVersion: string, requiredVersion: string): boolean => {
|
|
273
|
+
const existingSemver = makeSemverCompatible(existingVersion);
|
|
274
|
+
const requiredSemver = makeSemverCompatible(requiredVersion);
|
|
275
|
+
return semver.lt(existingSemver, requiredSemver);
|
|
276
|
+
};
|
|
277
|
+
if (isLowerVersion(existingNamespace.version, requiredModel.version)) {
|
|
281
278
|
errorLog(
|
|
282
279
|
"Expecting ",
|
|
283
280
|
requiredModel.modelUri,
|
|
@@ -969,6 +966,7 @@ export function makeNodeSetParserEngine(addressSpace: IAddressSpace): NodeSet2Pa
|
|
|
969
966
|
return {
|
|
970
967
|
finish(this: any) {
|
|
971
968
|
this.parent.parent.obj.value = {
|
|
969
|
+
arrayType: VariantArrayType.Scalar,
|
|
972
970
|
dataType: (DataType as any)[type],
|
|
973
971
|
value: p(this.text)
|
|
974
972
|
};
|
|
@@ -1027,6 +1025,9 @@ export function makeNodeSetParserEngine(addressSpace: IAddressSpace): NodeSet2Pa
|
|
|
1027
1025
|
};
|
|
1028
1026
|
}
|
|
1029
1027
|
|
|
1028
|
+
const parseUInt64 = (str: string): UInt64 => coerceUInt64(str);
|
|
1029
|
+
const parseInt64 = (str: string): Int64 => coerceInt64(str);
|
|
1030
|
+
|
|
1030
1031
|
const state_Variant = {
|
|
1031
1032
|
init: () => {
|
|
1032
1033
|
/* empty */
|
|
@@ -1110,6 +1111,9 @@ export function makeNodeSetParserEngine(addressSpace: IAddressSpace): NodeSet2Pa
|
|
|
1110
1111
|
UInt32: parser2("UInt32", parseInt),
|
|
1111
1112
|
UInt8: parser2("UInt8", parseInt),
|
|
1112
1113
|
|
|
1114
|
+
UInt64: parser2("UInt64", parseUInt64),
|
|
1115
|
+
Int64: parser2("Int64", parseInt64),
|
|
1116
|
+
|
|
1113
1117
|
ByteString: {
|
|
1114
1118
|
init(this: any) {
|
|
1115
1119
|
this.value = null;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* take a OPCUA version string and make it compliant with the semver specification
|
|
3
|
+
* @param version
|
|
4
|
+
* @returns
|
|
5
|
+
*/
|
|
6
|
+
export function makeSemverCompatible(version?: string): string {
|
|
7
|
+
version = version || "0.0.0";
|
|
8
|
+
|
|
9
|
+
const matches = version.match(/[0-9]+(\.[0-9]+(\.[0-9]+)?)?/);
|
|
10
|
+
if (!matches) {
|
|
11
|
+
return "0.0.0";
|
|
12
|
+
}
|
|
13
|
+
version = matches[0];
|
|
14
|
+
const version_array = version.split(".").map((a) => parseInt(a, 10));
|
|
15
|
+
|
|
16
|
+
if (version_array.length === 1) {
|
|
17
|
+
version_array.push(0);
|
|
18
|
+
}
|
|
19
|
+
if (version_array.length === 2) {
|
|
20
|
+
version_array.push(0);
|
|
21
|
+
}
|
|
22
|
+
return version_array.map((a) => a.toString()).join(".");
|
|
23
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Byte, Int16, Int32, Int64, SByte, UAString, UInt16, UInt32 } from "node-opcua-basic-types";
|
|
1
|
+
import { Byte, coerceInt64, coerceUInt64, Int16, Int32, Int64, SByte, UAString, UInt16, UInt32, UInt64 } from "node-opcua-basic-types";
|
|
2
2
|
import { LocalizedTextLike, LocalizedTextOptions } from "node-opcua-data-model";
|
|
3
3
|
import { make_debugLog, make_warningLog } from "node-opcua-debug";
|
|
4
4
|
import { coerceNodeId, NodeId, NodeIdType, resolveNodeId } from "node-opcua-nodeid";
|
|
@@ -82,7 +82,7 @@ const localizedTextReader: ReaderStateParserLike = {
|
|
|
82
82
|
};
|
|
83
83
|
|
|
84
84
|
function clamp(value: number, minValue: number, maxValue: number) {
|
|
85
|
-
if (value
|
|
85
|
+
if (value< minValue) {
|
|
86
86
|
warningLog(`invalid value range : ${value} < ${minValue} but should be [${minValue} , ${maxValue}]`);
|
|
87
87
|
return minValue;
|
|
88
88
|
}
|
|
@@ -95,6 +95,7 @@ function clamp(value: number, minValue: number, maxValue: number) {
|
|
|
95
95
|
|
|
96
96
|
interface Parser<T> {
|
|
97
97
|
value: T | null;
|
|
98
|
+
parent: any;
|
|
98
99
|
text: string;
|
|
99
100
|
}
|
|
100
101
|
const partials: { [key: string]: ReaderStateParserLike } = {
|
|
@@ -105,6 +106,15 @@ const partials: { [key: string]: ReaderStateParserLike } = {
|
|
|
105
106
|
this.value = this.text;
|
|
106
107
|
}
|
|
107
108
|
},
|
|
109
|
+
Guid: {
|
|
110
|
+
parser: {
|
|
111
|
+
String: {
|
|
112
|
+
finish(this: Parser<string>) {
|
|
113
|
+
this.parent.value = this.text;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
},
|
|
108
118
|
|
|
109
119
|
Boolean: {
|
|
110
120
|
finish(this: Parser<boolean>) {
|
|
@@ -161,8 +171,8 @@ const partials: { [key: string]: ReaderStateParserLike } = {
|
|
|
161
171
|
}
|
|
162
172
|
},
|
|
163
173
|
Int64: {
|
|
164
|
-
finish(this: Parser<
|
|
165
|
-
this.value = parseInt(this.text, 10);
|
|
174
|
+
finish(this: Parser<Int64>) {
|
|
175
|
+
this.value = coerceInt64(parseInt(this.text, 10));
|
|
166
176
|
}
|
|
167
177
|
},
|
|
168
178
|
|
|
@@ -185,8 +195,8 @@ const partials: { [key: string]: ReaderStateParserLike } = {
|
|
|
185
195
|
},
|
|
186
196
|
|
|
187
197
|
UInt64: {
|
|
188
|
-
finish(this: Parser<
|
|
189
|
-
this.value = parseInt(this.text, 10);
|
|
198
|
+
finish(this: Parser<UInt64>) {
|
|
199
|
+
this.value = coerceUInt64(parseInt(this.text, 10));
|
|
190
200
|
}
|
|
191
201
|
},
|
|
192
202
|
|
|
@@ -6,7 +6,7 @@ import { assert } from "node-opcua-assert";
|
|
|
6
6
|
import { LocalizedText, LocalizedTextLike } from "node-opcua-data-model";
|
|
7
7
|
import { NodeId } from "node-opcua-nodeid";
|
|
8
8
|
import { CallbackT, StatusCode, StatusCodes } from "node-opcua-status-code";
|
|
9
|
-
import { DataType, VariantLike } from "node-opcua-variant";
|
|
9
|
+
import { DataType, VariantLike, VariantOptions } from "node-opcua-variant";
|
|
10
10
|
import { INamespace, RaiseEventData, ISessionContext, UAEventType, UAMethod } from "node-opcua-address-space-base";
|
|
11
11
|
import { CallMethodResultOptions } from "node-opcua-service-call";
|
|
12
12
|
|
|
@@ -16,6 +16,7 @@ import { _install_TwoStateVariable_machinery } from "../state_machine/ua_two_sta
|
|
|
16
16
|
import { _setAckedState } from "./condition";
|
|
17
17
|
import { ConditionSnapshot } from "./condition_snapshot";
|
|
18
18
|
import { UAConditionHelper, UAConditionImpl, UAConditionEx } from "./ua_condition_impl";
|
|
19
|
+
import { InstantiateAlarmConditionOptions } from "./ua_alarm_condition_impl";
|
|
19
20
|
|
|
20
21
|
export interface UAAcknowledgeableConditionHelper extends UAConditionHelper {
|
|
21
22
|
///
|
|
@@ -53,8 +54,8 @@ export class UAAcknowledgeableConditionImpl extends UAConditionImpl implements U
|
|
|
53
54
|
public static instantiate(
|
|
54
55
|
namespace: INamespace,
|
|
55
56
|
conditionTypeId: UAEventType | NodeId | string,
|
|
56
|
-
options:
|
|
57
|
-
data
|
|
57
|
+
options: InstantiateAlarmConditionOptions,
|
|
58
|
+
data?: Record<string, VariantOptions>
|
|
58
59
|
): UAAcknowledgeableConditionImpl {
|
|
59
60
|
const conditionNode = UAConditionImpl.instantiate(
|
|
60
61
|
namespace,
|
|
@@ -107,7 +108,9 @@ export class UAAcknowledgeableConditionImpl extends UAConditionImpl implements U
|
|
|
107
108
|
}
|
|
108
109
|
|
|
109
110
|
public static install_method_handle_on_type(addressSpace: AddressSpacePrivate): void {
|
|
110
|
-
const acknowledgeableConditionType = addressSpace.findEventType(
|
|
111
|
+
const acknowledgeableConditionType = addressSpace.findEventType(
|
|
112
|
+
"AcknowledgeableConditionType"
|
|
113
|
+
) as unknown as UAAcknowledgeableCondition_Base;
|
|
111
114
|
assert(acknowledgeableConditionType !== null);
|
|
112
115
|
acknowledgeableConditionType.acknowledge.bindMethod(_acknowledge_method);
|
|
113
116
|
acknowledgeableConditionType.confirm?.bindMethod(_confirm_method);
|
|
@@ -297,7 +300,11 @@ export class UAAcknowledgeableConditionImpl extends UAConditionImpl implements U
|
|
|
297
300
|
}
|
|
298
301
|
}
|
|
299
302
|
|
|
300
|
-
function _acknowledge_method(
|
|
303
|
+
function _acknowledge_method(
|
|
304
|
+
inputArguments: VariantLike[],
|
|
305
|
+
context: ISessionContext,
|
|
306
|
+
callback: CallbackT<CallMethodResultOptions>
|
|
307
|
+
) {
|
|
301
308
|
UAConditionImpl.with_condition_method(
|
|
302
309
|
inputArguments,
|
|
303
310
|
context,
|
|
@@ -322,7 +329,7 @@ function _acknowledge_method(inputArguments: VariantLike[], context: ISessionCon
|
|
|
322
329
|
*
|
|
323
330
|
* @private
|
|
324
331
|
*/
|
|
325
|
-
function _confirm_method(inputArguments: VariantLike[], context: ISessionContext,
|
|
332
|
+
function _confirm_method(inputArguments: VariantLike[], context: ISessionContext, callback: CallbackT<CallMethodResultOptions>) {
|
|
326
333
|
UAConditionImpl.with_condition_method(
|
|
327
334
|
inputArguments,
|
|
328
335
|
context,
|
|
@@ -8,10 +8,10 @@ import { NodeClass } from "node-opcua-data-model";
|
|
|
8
8
|
import { DataValue } from "node-opcua-data-value";
|
|
9
9
|
import { NodeId, sameNodeId } from "node-opcua-nodeid";
|
|
10
10
|
import { StatusCodes } from "node-opcua-status-code";
|
|
11
|
-
import { DataType } from "node-opcua-variant";
|
|
11
|
+
import { DataType, VariantOptions } from "node-opcua-variant";
|
|
12
12
|
import { UAAlarmCondition_Base } from "node-opcua-nodeset-ua";
|
|
13
|
+
import { BaseNode, INamespace, UAEventType, UAVariable } from "node-opcua-address-space-base";
|
|
13
14
|
|
|
14
|
-
import { BaseNode, INamespace, UAEventType, UAVariable } from "../../source";
|
|
15
15
|
import { _install_TwoStateVariable_machinery } from "../state_machine/ua_two_state_variable";
|
|
16
16
|
import { UAShelvedStateMachineEx, _clear_timer_if_any } from "../state_machine/ua_shelving_state_machine_ex";
|
|
17
17
|
import { UATwoStateVariableEx } from "../../source/ua_two_state_variable_ex";
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
UAAcknowledgeableConditionHelper,
|
|
24
24
|
UAAcknowledgeableConditionImpl
|
|
25
25
|
} from "./ua_acknowledgeable_condition_impl";
|
|
26
|
+
import { InstantiateConditionOptions } from "./ua_condition_impl";
|
|
26
27
|
|
|
27
28
|
function _update_suppressedOrShelved(alarmNode: UAAlarmConditionImpl) {
|
|
28
29
|
alarmNode.suppressedOrShelved.setValueFromSource({
|
|
@@ -32,7 +33,7 @@ function _update_suppressedOrShelved(alarmNode: UAAlarmConditionImpl) {
|
|
|
32
33
|
}
|
|
33
34
|
export interface UAAlarmConditionHelper extends UAAcknowledgeableConditionHelper {
|
|
34
35
|
activateAlarm(): void;
|
|
35
|
-
deactivateAlarm(): void;
|
|
36
|
+
deactivateAlarm(retain?: boolean): void;
|
|
36
37
|
isSuppressedOrShelved(): boolean;
|
|
37
38
|
getSuppressedOrShelved(): boolean;
|
|
38
39
|
setMaxTimeShelved(duration: number): void;
|
|
@@ -65,14 +66,18 @@ export declare interface UAAlarmConditionImpl extends UAAlarmConditionEx, UAAckn
|
|
|
65
66
|
on(eventName: string, eventHandler: any): this;
|
|
66
67
|
}
|
|
67
68
|
|
|
69
|
+
export interface InstantiateAlarmConditionOptions extends InstantiateConditionOptions {
|
|
70
|
+
maxTimeShelved?: number;
|
|
71
|
+
inputNode: BaseNode | NodeId;
|
|
72
|
+
}
|
|
68
73
|
export class UAAlarmConditionImpl extends UAAcknowledgeableConditionImpl implements UAAlarmConditionEx {
|
|
69
74
|
public static MaxDuration = Math.pow(2, 31);
|
|
70
75
|
|
|
71
76
|
public static instantiate(
|
|
72
77
|
namespace: INamespace,
|
|
73
78
|
alarmConditionTypeId: UAEventType | string | NodeId,
|
|
74
|
-
options:
|
|
75
|
-
data
|
|
79
|
+
options: InstantiateAlarmConditionOptions,
|
|
80
|
+
data?: Record<string, VariantOptions>
|
|
76
81
|
): UAAlarmConditionImpl {
|
|
77
82
|
const addressSpace = namespace.addressSpace;
|
|
78
83
|
// xx assert(Object.prototype.hasOwnProperty.call(options,"conditionOf")); // must provide a conditionOf
|
|
@@ -93,7 +98,7 @@ export class UAAlarmConditionImpl extends UAAcknowledgeableConditionImpl impleme
|
|
|
93
98
|
options.optionals = options.optionals || [];
|
|
94
99
|
if (Object.prototype.hasOwnProperty.call(options, "maxTimeShelved")) {
|
|
95
100
|
options.optionals.push("MaxTimeShelved");
|
|
96
|
-
assert(isFinite(options.maxTimeShelved));
|
|
101
|
+
assert(isFinite(options.maxTimeShelved!));
|
|
97
102
|
}
|
|
98
103
|
|
|
99
104
|
assert(alarmConditionTypeBase === alarmConditionType || alarmConditionType.isSupertypeOf(alarmConditionTypeBase));
|
|
@@ -229,16 +234,16 @@ export class UAAlarmConditionImpl extends UAAcknowledgeableConditionImpl impleme
|
|
|
229
234
|
branch.setAckedState(false);
|
|
230
235
|
}
|
|
231
236
|
|
|
232
|
-
public deactivateAlarm(): void {
|
|
237
|
+
public deactivateAlarm(retain?: boolean): void {
|
|
233
238
|
const branch = this.currentBranch();
|
|
234
|
-
branch.setRetain(true);
|
|
239
|
+
branch.setRetain(retain === undefined ? true : retain);
|
|
235
240
|
branch.setActiveState(false);
|
|
236
241
|
}
|
|
237
242
|
|
|
238
243
|
/**
|
|
239
244
|
* @deprecated use deactivateAlarm instead (with no s after de-activate)
|
|
240
245
|
*/
|
|
241
|
-
|
|
246
|
+
protected desactivateAlarm(): void {
|
|
242
247
|
this.deactivateAlarm();
|
|
243
248
|
}
|
|
244
249
|
|
|
@@ -325,7 +330,7 @@ export class UAAlarmConditionImpl extends UAAcknowledgeableConditionImpl impleme
|
|
|
325
330
|
this._onInputDataValueChange(dataValue);
|
|
326
331
|
}
|
|
327
332
|
|
|
328
|
-
|
|
333
|
+
protected _onInputDataValueChange(newValue: DataValue): void {
|
|
329
334
|
// xx console.log("class=",this.constructor.name,this.browseName.toString());
|
|
330
335
|
// xx throw new Error("_onInputDataValueChange must be overridden");
|
|
331
336
|
}
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module node-opcua-address-space.AlarmsAndConditions
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
4
|
+
import { Certificate, exploreCertificate, makeSHA1Thumbprint } from "node-opcua-crypto";
|
|
5
|
+
import { DateTime, minOPCUADate } from "node-opcua-basic-types";
|
|
6
|
+
import { make_warningLog } from "node-opcua-debug";
|
|
7
|
+
import { DataType, VariantOptions } from "node-opcua-variant";
|
|
8
|
+
import { UACertificateExpirationAlarm_Base } from "node-opcua-nodeset-ua";
|
|
9
|
+
import { INamespace, UAObject } from "node-opcua-address-space-base";
|
|
10
|
+
import { ObjectTypeIds } from "node-opcua-constants";
|
|
11
|
+
import { AccessRestrictionsFlag, makeAccessLevelExFlag } from "node-opcua-data-model";
|
|
12
|
+
import { registerNodePromoter } from "../../source/loader/register_node_promoter";
|
|
13
|
+
import { InstantiateOffNormalAlarmOptions, UAOffNormalAlarmImpl } from "./ua_off_normal_alarm_impl";
|
|
8
14
|
import { UASystemOffNormalAlarmImpl } from "./ua_system_off_normal_alarm_impl";
|
|
9
15
|
|
|
16
|
+
const warningLog = make_warningLog("AlarmsAndConditions");
|
|
17
|
+
|
|
10
18
|
export interface UACertificateExpirationAlarmEx
|
|
11
19
|
extends Omit<
|
|
12
20
|
UACertificateExpirationAlarm_Base,
|
|
@@ -20,7 +28,15 @@ export interface UACertificateExpirationAlarmEx
|
|
|
20
28
|
| "shelvingState"
|
|
21
29
|
| "silenceState"
|
|
22
30
|
| "suppressedState"
|
|
23
|
-
> {
|
|
31
|
+
> {
|
|
32
|
+
getExpirationDate(): DateTime;
|
|
33
|
+
setExpirationDate(value: Date): void;
|
|
34
|
+
getExpirationLimit(): number;
|
|
35
|
+
setExpirationLimit(value: number): void;
|
|
36
|
+
setCertificate(certificate: Certificate | null): void;
|
|
37
|
+
getCertificate(): Certificate | null;
|
|
38
|
+
}
|
|
39
|
+
|
|
24
40
|
export declare interface UACertificateExpirationAlarmImpl extends UACertificateExpirationAlarmEx, UASystemOffNormalAlarmImpl {}
|
|
25
41
|
/**
|
|
26
42
|
* This UACertificateExpirationAlarm (SystemOffNormalAlarmType) is raised by the Server when the Server’s
|
|
@@ -28,23 +44,123 @@ export declare interface UACertificateExpirationAlarmImpl extends UACertificateE
|
|
|
28
44
|
* of expiration. This alarm automatically returns to normal when the certificate is updated.
|
|
29
45
|
*/
|
|
30
46
|
export class UACertificateExpirationAlarmImpl extends UASystemOffNormalAlarmImpl implements UACertificateExpirationAlarmEx {
|
|
31
|
-
public static instantiate(
|
|
32
|
-
|
|
47
|
+
public static instantiate(
|
|
48
|
+
namespace: INamespace,
|
|
49
|
+
alarmType: "CertificateExpirationAlarmType",
|
|
50
|
+
options: InstantiateOffNormalAlarmOptions,
|
|
51
|
+
data?: Record<string, VariantOptions>
|
|
52
|
+
): UACertificateExpirationAlarmImpl {
|
|
53
|
+
const alarm = UASystemOffNormalAlarmImpl.instantiate(
|
|
33
54
|
namespace,
|
|
34
|
-
"CertificateExpirationAlarmType",
|
|
55
|
+
alarmType || "CertificateExpirationAlarmType",
|
|
35
56
|
options,
|
|
36
57
|
data
|
|
37
58
|
) as UACertificateExpirationAlarmImpl;
|
|
59
|
+
Object.setPrototypeOf(alarm, UACertificateExpirationAlarmImpl.prototype);
|
|
60
|
+
alarm._post_initialize();
|
|
61
|
+
return alarm;
|
|
38
62
|
}
|
|
39
63
|
|
|
40
64
|
public getExpirationDate(): DateTime {
|
|
41
65
|
return this.expirationDate.readValue().value.value;
|
|
42
66
|
}
|
|
43
67
|
|
|
44
|
-
public setExpirationDate(
|
|
45
|
-
|
|
68
|
+
public setExpirationDate(expirationDate: Date): void {
|
|
69
|
+
this.expirationDate.setValueFromSource({
|
|
46
70
|
dataType: DataType.DateTime,
|
|
71
|
+
value: expirationDate
|
|
72
|
+
});
|
|
73
|
+
const now = new Date();
|
|
74
|
+
const expirationLimit = this.getExpirationLimit();
|
|
75
|
+
|
|
76
|
+
const checkDate = new Date(now.getTime() + +expirationLimit);
|
|
77
|
+
|
|
78
|
+
const thumbprint = makeSHA1Thumbprint(this.getCertificate() || Buffer.alloc(0)).toString("hex");
|
|
79
|
+
|
|
80
|
+
if (expirationDate.getTime() <= checkDate.getTime()) {
|
|
81
|
+
if (!this.currentBranch().getActiveState()) {
|
|
82
|
+
warningLog(
|
|
83
|
+
`CertificateExpirationAlarm: becomes active, certificate ${thumbprint} endDate ${expirationDate.toUTCString()} checkDate=${checkDate.toUTCString()} expirationLimit=${expirationLimit}`
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
// also raise the event
|
|
87
|
+
if (expirationDate.getTime() <= now.getTime()) {
|
|
88
|
+
this.updateAlarmState(
|
|
89
|
+
true,
|
|
90
|
+
`certificate ${thumbprint} has expired : end date is ${expirationDate.toUTCString()} checkDate=${checkDate.toUTCString()} expirationLimit=${expirationLimit}`
|
|
91
|
+
);
|
|
92
|
+
} else {
|
|
93
|
+
this.updateAlarmState(
|
|
94
|
+
true,
|
|
95
|
+
`certificate ${thumbprint} is about to expire : end date is ${expirationDate.toString()} checkDate=${checkDate.toUTCString()} expirationLimit=${expirationLimit}`
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
} else {
|
|
99
|
+
if (this.currentBranch().getActiveState()) {
|
|
100
|
+
warningLog(
|
|
101
|
+
`CertificateExpirationAlarm: becomes desactivated, certificate ${thumbprint} endDate ${expirationDate.toUTCString()} expirationLimit=${expirationLimit}`
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
// also raise the event
|
|
105
|
+
this.updateAlarmState(
|
|
106
|
+
false,
|
|
107
|
+
`certificate ${thumbprint} end date is OK: ${expirationDate.toString()} , expirationLimit=${expirationLimit}`
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
public getExpirationLimit(): number {
|
|
113
|
+
return (this.expirationLimit?.readValue().value.value as number) || 0;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
public setExpirationLimit(value: number): void {
|
|
117
|
+
this.expirationLimit?.setValueFromSource({
|
|
118
|
+
dataType: DataType.Double,
|
|
47
119
|
value
|
|
48
120
|
});
|
|
49
121
|
}
|
|
122
|
+
|
|
123
|
+
public getCertificate(): Certificate | null {
|
|
124
|
+
return (this.certificate.readValue().value.value as Certificate | null) || null;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
public setCertificate(certificate: Certificate | null): void {
|
|
128
|
+
if (certificate && certificate.length > 0) {
|
|
129
|
+
const info = exploreCertificate(certificate);
|
|
130
|
+
if (info.tbsCertificate.validity.notAfter instanceof Date) {
|
|
131
|
+
this.setExpirationDate(info.tbsCertificate.validity.notAfter);
|
|
132
|
+
} else {
|
|
133
|
+
this.setExpirationDate(minOPCUADate);
|
|
134
|
+
}
|
|
135
|
+
} else {
|
|
136
|
+
this.setExpirationDate(minOPCUADate);
|
|
137
|
+
}
|
|
138
|
+
this.certificate.setValueFromSource({
|
|
139
|
+
dataType: DataType.ByteString,
|
|
140
|
+
value: certificate
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
_post_initialize() {
|
|
145
|
+
if (this.expirationLimit) {
|
|
146
|
+
this.expirationLimit.accessLevel = makeAccessLevelExFlag("CurrentRead | CurrentWrite");
|
|
147
|
+
this.expirationLimit.userAccessLevel = makeAccessLevelExFlag("CurrentRead | CurrentWrite");
|
|
148
|
+
this.expirationLimit.on("value_changed", (dataValue) => {
|
|
149
|
+
// make sure we re-evaluate the certificfate
|
|
150
|
+
const certificate = this.getCertificate();
|
|
151
|
+
this.setCertificate(certificate);
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export function promoteToCertificateExpirationAlarm(node: UAObject): UACertificateExpirationAlarmImpl {
|
|
158
|
+
if (node instanceof UACertificateExpirationAlarmImpl) {
|
|
159
|
+
return node; // already promoted
|
|
160
|
+
}
|
|
161
|
+
Object.setPrototypeOf(node, UACertificateExpirationAlarmImpl.prototype);
|
|
162
|
+
const _node = node as unknown as UACertificateExpirationAlarmImpl;
|
|
163
|
+
_node._post_initialize();
|
|
164
|
+
return _node;
|
|
50
165
|
}
|
|
166
|
+
registerNodePromoter(ObjectTypeIds.CertificateExpirationAlarmType, promoteToCertificateExpirationAlarm);
|