node-opcua-address-space 2.101.0 → 2.103.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/loader/load_nodeset2.js +1 -1
- package/dist/source/loader/load_nodeset2.js.map +1 -1
- package/dist/source/namespace_data_access.d.ts +20 -1
- package/dist/source/pseudo_session.js +11 -2
- package/dist/source/pseudo_session.js.map +1 -1
- package/dist/source/session_context.js +3 -0
- package/dist/source/session_context.js.map +1 -1
- package/dist/src/data_access/adjust_datavalue_status_code.d.ts +4 -0
- package/dist/src/data_access/adjust_datavalue_status_code.js +30 -0
- package/dist/src/data_access/adjust_datavalue_status_code.js.map +1 -0
- package/dist/src/index_current.d.ts +1 -1
- package/dist/src/index_current.js +1 -1
- package/dist/src/index_current.js.map +1 -1
- package/dist/src/namespace_impl.js +3 -1
- package/dist/src/namespace_impl.js.map +1 -1
- package/dist/src/nodeset_tools/nodeset_to_xml.js +2 -1
- package/dist/src/nodeset_tools/nodeset_to_xml.js.map +1 -1
- package/dist/src/ua_method_impl.js +1 -1
- package/dist/src/ua_method_impl.js.map +1 -1
- package/dist/src/ua_variable_impl.d.ts +1 -0
- package/dist/src/ua_variable_impl.js +28 -8
- package/dist/src/ua_variable_impl.js.map +1 -1
- package/dist/tsconfig_common.tsbuildinfo +1 -1
- package/package.json +22 -22
- package/source/loader/load_nodeset2.ts +2 -2
- package/source/namespace_data_access.ts +27 -2
- package/source/pseudo_session.ts +12 -4
- package/source/session_context.ts +1 -0
- package/src/data_access/adjust_datavalue_status_code.ts +36 -0
- package/src/index_current.ts +1 -1
- package/src/namespace_impl.ts +36 -30
- package/src/nodeset_tools/nodeset_to_xml.ts +2 -1
- package/src/ua_method_impl.ts +2 -2
- package/src/ua_variable_impl.ts +29 -8
- package/src/data_access/check_variant_compatibility_ua_analog_item.ts +0 -38
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-opcua-address-space",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.103.0",
|
|
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",
|
|
@@ -22,36 +22,36 @@
|
|
|
22
22
|
"chalk": "4.1.2",
|
|
23
23
|
"dequeue": "^1.0.5",
|
|
24
24
|
"lodash": "4.17.21",
|
|
25
|
-
"node-opcua-address-space-base": "2.
|
|
25
|
+
"node-opcua-address-space-base": "2.103.0",
|
|
26
26
|
"node-opcua-assert": "2.98.1",
|
|
27
27
|
"node-opcua-basic-types": "2.99.0",
|
|
28
28
|
"node-opcua-binary-stream": "2.98.1",
|
|
29
|
-
"node-opcua-client-dynamic-extension-object": "2.
|
|
29
|
+
"node-opcua-client-dynamic-extension-object": "2.103.0",
|
|
30
30
|
"node-opcua-constants": "2.98.1",
|
|
31
31
|
"node-opcua-crypto": "^2.1.2",
|
|
32
|
-
"node-opcua-data-access": "2.
|
|
33
|
-
"node-opcua-data-model": "2.
|
|
34
|
-
"node-opcua-data-value": "2.
|
|
32
|
+
"node-opcua-data-access": "2.103.0",
|
|
33
|
+
"node-opcua-data-model": "2.102.0",
|
|
34
|
+
"node-opcua-data-value": "2.102.0",
|
|
35
35
|
"node-opcua-date-time": "2.99.0",
|
|
36
36
|
"node-opcua-debug": "2.99.0",
|
|
37
37
|
"node-opcua-enum": "2.98.1",
|
|
38
38
|
"node-opcua-extension-object": "2.99.0",
|
|
39
39
|
"node-opcua-factory": "2.99.0",
|
|
40
40
|
"node-opcua-nodeid": "2.99.0",
|
|
41
|
-
"node-opcua-nodeset-ua": "2.
|
|
42
|
-
"node-opcua-numeric-range": "2.
|
|
41
|
+
"node-opcua-nodeset-ua": "2.103.0",
|
|
42
|
+
"node-opcua-numeric-range": "2.102.0",
|
|
43
43
|
"node-opcua-object-registry": "2.99.0",
|
|
44
|
-
"node-opcua-pseudo-session": "2.
|
|
45
|
-
"node-opcua-service-browse": "2.
|
|
46
|
-
"node-opcua-service-call": "2.
|
|
47
|
-
"node-opcua-service-history": "2.
|
|
48
|
-
"node-opcua-service-translate-browse-path": "2.
|
|
49
|
-
"node-opcua-service-write": "2.
|
|
44
|
+
"node-opcua-pseudo-session": "2.103.0",
|
|
45
|
+
"node-opcua-service-browse": "2.103.0",
|
|
46
|
+
"node-opcua-service-call": "2.103.0",
|
|
47
|
+
"node-opcua-service-history": "2.103.0",
|
|
48
|
+
"node-opcua-service-translate-browse-path": "2.103.0",
|
|
49
|
+
"node-opcua-service-write": "2.103.0",
|
|
50
50
|
"node-opcua-status-code": "2.98.1",
|
|
51
|
-
"node-opcua-types": "2.
|
|
51
|
+
"node-opcua-types": "2.103.0",
|
|
52
52
|
"node-opcua-utils": "2.98.1",
|
|
53
|
-
"node-opcua-variant": "2.
|
|
54
|
-
"node-opcua-xml2json": "2.
|
|
53
|
+
"node-opcua-variant": "2.102.0",
|
|
54
|
+
"node-opcua-xml2json": "2.103.0",
|
|
55
55
|
"semver": "^7.3.8",
|
|
56
56
|
"set-prototype-of": "^1.0.0",
|
|
57
57
|
"thenify": "^3.3.1",
|
|
@@ -61,10 +61,10 @@
|
|
|
61
61
|
"mocha": "^10.2.0",
|
|
62
62
|
"node-opcua-benchmarker": "2.98.1",
|
|
63
63
|
"node-opcua-leak-detector": "2.99.0",
|
|
64
|
-
"node-opcua-nodesets": "2.
|
|
65
|
-
"node-opcua-packet-analyzer": "2.
|
|
66
|
-
"node-opcua-service-filter": "2.
|
|
67
|
-
"node-opcua-test-fixtures": "2.
|
|
64
|
+
"node-opcua-nodesets": "2.103.0",
|
|
65
|
+
"node-opcua-packet-analyzer": "2.102.0",
|
|
66
|
+
"node-opcua-service-filter": "2.103.0",
|
|
67
|
+
"node-opcua-test-fixtures": "2.103.0",
|
|
68
68
|
"should": "^13.2.3",
|
|
69
69
|
"sinon": "^15.0.3",
|
|
70
70
|
"source-map-support": "^0.5.21"
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"internet of things"
|
|
85
85
|
],
|
|
86
86
|
"homepage": "http://node-opcua.github.io/",
|
|
87
|
-
"gitHead": "
|
|
87
|
+
"gitHead": "e206cac2daf39bd07e5ac6cbd744f966bb54759e",
|
|
88
88
|
"files": [
|
|
89
89
|
"dist",
|
|
90
90
|
"distHelpers",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* @module node-opcua-address-space
|
|
4
4
|
*/
|
|
5
|
-
import { promisify } from "util";
|
|
5
|
+
import { promisify, types } from "util";
|
|
6
6
|
import * as chalk from "chalk";
|
|
7
7
|
|
|
8
8
|
import * as ec from "node-opcua-basic-types";
|
|
@@ -1698,7 +1698,7 @@ function makeNodeSetParserEngine(addressSpace: IAddressSpace, options: NodeSetLo
|
|
|
1698
1698
|
} catch (err) {
|
|
1699
1699
|
// istanbul ignore next
|
|
1700
1700
|
// tslint:disable:no-console
|
|
1701
|
-
if (err
|
|
1701
|
+
if (types.isNativeError(err)) {
|
|
1702
1702
|
console.log(" performPostLoadingTasks Err => ", err.message, "\n", err);
|
|
1703
1703
|
}
|
|
1704
1704
|
await task(addressSpace1);
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
AddVariableOptionsWithoutValue,
|
|
3
|
+
AddYArrayItemOptions,
|
|
4
|
+
BindVariableOptions,
|
|
5
|
+
UADataType
|
|
6
|
+
} from "node-opcua-address-space-base";
|
|
2
7
|
import { NodeIdLike } from "node-opcua-nodeid";
|
|
3
8
|
import { UAAnalogItem, UADataItem } from "node-opcua-nodeset-ua";
|
|
4
9
|
import { EUInformation, EUInformationOptions } from "node-opcua-types";
|
|
@@ -40,11 +45,31 @@ export interface AddAnalogDataItemOptions extends AddDataItemOptions {
|
|
|
40
45
|
engineeringUnits?: EUInformationOptions | EUInformation;
|
|
41
46
|
minimumSamplingInterval?: number;
|
|
42
47
|
dataType?: string | NodeIdLike | UADataType;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* the acceptValueOutOfRange property indicates whether the write operation will accept or reject a value which
|
|
51
|
+
* is out of range of the instrumentRange.
|
|
52
|
+
*
|
|
53
|
+
* **if true**: during a writeOperation by a client if the dataValue that is outside of the instrumentRange
|
|
54
|
+
* it will be recorded database and the statusCode will be set to BadOutOfRange, and
|
|
55
|
+
* the write operation will return Good. If the variable supports historizing, the value will be recorded in the history database.
|
|
56
|
+
* as well.
|
|
57
|
+
*
|
|
58
|
+
* **if false**: during a writeOperation by a client, if the dataValue that is outside of the instrumentRange
|
|
59
|
+
* it will be denied and the write operation will return BadOutOfRange.
|
|
60
|
+
*
|
|
61
|
+
* @default undefined (false)
|
|
62
|
+
*
|
|
63
|
+
*/
|
|
64
|
+
acceptValueOutOfRange?: boolean;
|
|
43
65
|
}
|
|
44
66
|
|
|
67
|
+
export interface UAAnalogItemEx<T, DT extends DataType> extends UAAnalogItem<T, DT> {
|
|
68
|
+
acceptValueOutOfRange?: boolean;
|
|
69
|
+
}
|
|
45
70
|
export interface INamespaceDataAccess {
|
|
46
71
|
addDataItem<T, DT extends DataType>(options: AddDataItemOptions): UADataItem<T, DT>;
|
|
47
|
-
addAnalogDataItem<T, DT extends DataType>(options: AddAnalogDataItemOptions):
|
|
72
|
+
addAnalogDataItem<T, DT extends DataType>(options: AddAnalogDataItemOptions): UAAnalogItemEx<T, DT>;
|
|
48
73
|
|
|
49
74
|
addYArrayItem<DT extends DataType.Double | DataType.Float>(options: AddYArrayItemOptions): UAYArrayItemEx<DT>;
|
|
50
75
|
|
package/source/pseudo_session.ts
CHANGED
|
@@ -352,11 +352,19 @@ export class PseudoSession implements IBasicSession {
|
|
|
352
352
|
if (!obj) {
|
|
353
353
|
return StatusCodes.BadNodeIdUnknown;
|
|
354
354
|
}
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
355
|
+
try {
|
|
356
|
+
return promisify(obj.writeAttribute).call(obj, context, nodeToWrite);
|
|
357
|
+
} catch (err) {
|
|
358
|
+
return StatusCodes.BadInternalError;
|
|
359
|
+
}
|
|
359
360
|
});
|
|
361
|
+
Promise.all(statusCodesPromises)
|
|
362
|
+
.then((statusCodes) => {
|
|
363
|
+
callback!(null, isArray ? statusCodes : statusCodes[0]);
|
|
364
|
+
})
|
|
365
|
+
.catch((err) => {
|
|
366
|
+
callback!(err);
|
|
367
|
+
});
|
|
360
368
|
});
|
|
361
369
|
}
|
|
362
370
|
}
|
|
@@ -305,6 +305,7 @@ export class SessionContext implements ISessionContext {
|
|
|
305
305
|
return true;
|
|
306
306
|
}
|
|
307
307
|
}
|
|
308
|
+
if (!this.session ) { return false; }
|
|
308
309
|
const securityMode = this.session?.channel?.securityMode;
|
|
309
310
|
if (accessRestrictions & AccessRestrictionsFlag.SigningRequired) {
|
|
310
311
|
if (securityMode !== MessageSecurityMode.Sign && securityMode !== MessageSecurityMode.SignAndEncrypt) {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module node-opcua-address-space.DataAccess
|
|
3
|
+
*/
|
|
4
|
+
import { StatusCodes } from "node-opcua-status-code";
|
|
5
|
+
import { StatusCode } from "node-opcua-status-code";
|
|
6
|
+
import { Range } from "node-opcua-types";
|
|
7
|
+
import { UAVariable } from "node-opcua-address-space-base";
|
|
8
|
+
import { NodeClass } from "node-opcua-data-model";
|
|
9
|
+
import { DataValue } from "node-opcua-data-value";
|
|
10
|
+
import { Variant } from "node-opcua-variant";
|
|
11
|
+
import { UAVariableImpl } from "../ua_variable_impl";
|
|
12
|
+
|
|
13
|
+
function validate_value_range(range: Range, variant: Variant) {
|
|
14
|
+
if (variant.value < range.low || variant.value > range.high) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function adjustDataValueStatusCode(
|
|
21
|
+
variable: UAVariableImpl,
|
|
22
|
+
dataValue: DataValue,
|
|
23
|
+
acceptValueOutOfRange: boolean
|
|
24
|
+
): StatusCode {
|
|
25
|
+
const instrumentRange = variable.getChildByName("InstrumentRange") as UAVariable | null;
|
|
26
|
+
if (instrumentRange && instrumentRange.nodeClass === NodeClass.Variable) {
|
|
27
|
+
if (!validate_value_range(instrumentRange.readValue().value.value as Range, dataValue.value)) {
|
|
28
|
+
if (!acceptValueOutOfRange) {
|
|
29
|
+
return StatusCodes.BadOutOfRange;
|
|
30
|
+
} else {
|
|
31
|
+
dataValue.statusCode = StatusCodes.BadOutOfRange;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return StatusCodes.Good;
|
|
36
|
+
}
|
package/src/index_current.ts
CHANGED
|
@@ -43,7 +43,7 @@ export { adjustNamespaceArray } from "./nodeset_tools/adjust_namespace_array";
|
|
|
43
43
|
export { makeAttributeEventName } from "./base_node_impl";
|
|
44
44
|
export { resolveReferenceNode, resolveReferenceType } from "./reference_impl";
|
|
45
45
|
|
|
46
|
-
export * from "./data_access/
|
|
46
|
+
export * from "./data_access/adjust_datavalue_status_code";
|
|
47
47
|
export * from "./data_access/add_dataItem_stuff";
|
|
48
48
|
export * from "./data_access/ua_multistate_discrete_impl";
|
|
49
49
|
export * from "./data_access/ua_multistate_value_discrete_impl";
|
package/src/namespace_impl.ts
CHANGED
|
@@ -76,7 +76,7 @@ import {
|
|
|
76
76
|
UATwoStateDiscreteEx,
|
|
77
77
|
UAYArrayItemEx
|
|
78
78
|
} from "../source";
|
|
79
|
-
import { AddAnalogDataItemOptions, AddDataItemOptions } from "../source/namespace_data_access";
|
|
79
|
+
import { AddAnalogDataItemOptions, AddDataItemOptions, UAAnalogItemEx } from "../source/namespace_data_access";
|
|
80
80
|
import { UATwoStateVariableEx } from "../source/ua_two_state_variable_ex";
|
|
81
81
|
import { UAMultiStateValueDiscreteEx } from "../source/interfaces/data_access/ua_multistate_value_discrete_ex";
|
|
82
82
|
import { UAAlarmConditionEx } from "../source/interfaces/alarms_and_conditions/ua_alarm_condition_ex";
|
|
@@ -125,7 +125,6 @@ import { UAViewImpl } from "./ua_view_impl";
|
|
|
125
125
|
import { UAStateMachineImpl, UATransitionImpl } from "./state_machine/finite_state_machine";
|
|
126
126
|
import { _addMultiStateValueDiscrete } from "./data_access/ua_multistate_value_discrete_impl";
|
|
127
127
|
|
|
128
|
-
|
|
129
128
|
function _makeHashKey(nodeId: NodeId): string | number {
|
|
130
129
|
switch (nodeId.identifierType) {
|
|
131
130
|
case NodeIdType.STRING:
|
|
@@ -931,6 +930,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
931
930
|
|
|
932
931
|
instrumentRange.on("value_changed", handler);
|
|
933
932
|
}
|
|
933
|
+
(variable as any).acceptValueOutOfRange = options.acceptValueOutOfRange;
|
|
934
934
|
|
|
935
935
|
if (Object.prototype.hasOwnProperty.call(options, "engineeringUnits")) {
|
|
936
936
|
const engineeringUnits = new EUInformation(options.engineeringUnits);
|
|
@@ -1445,7 +1445,7 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1445
1445
|
const _component = component as UAStateMachineImpl;
|
|
1446
1446
|
|
|
1447
1447
|
assert(_component.nodeClass === NodeClass.Object || _component.nodeClass === NodeClass.ObjectType);
|
|
1448
|
-
|
|
1448
|
+
|
|
1449
1449
|
const initialStateType = addressSpace.findObjectType("InitialStateType")!;
|
|
1450
1450
|
const stateType = addressSpace.findObjectType("StateType")!;
|
|
1451
1451
|
|
|
@@ -1662,24 +1662,24 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1662
1662
|
|
|
1663
1663
|
// istanbul ignore next
|
|
1664
1664
|
if (this._nodeid_index.has(hashKey)) {
|
|
1665
|
-
|
|
1666
1665
|
const exstingNode = this.findNode(node.nodeId)!;
|
|
1667
1666
|
throw new Error(
|
|
1668
1667
|
"node " +
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1668
|
+
node.browseName.toString() +
|
|
1669
|
+
" nodeId = " +
|
|
1670
|
+
node.nodeId.displayText() +
|
|
1671
|
+
" already registered " +
|
|
1672
|
+
node.nodeId.toString() +
|
|
1673
|
+
"\n" +
|
|
1674
|
+
" in namespace " +
|
|
1675
|
+
this.namespaceUri +
|
|
1676
|
+
" index = " +
|
|
1677
|
+
this.index +
|
|
1678
|
+
"\n" +
|
|
1679
|
+
"existing node = " +
|
|
1680
|
+
exstingNode.toString() +
|
|
1681
|
+
"this parent : " +
|
|
1682
|
+
node.parentNodeId?.toString()
|
|
1683
1683
|
);
|
|
1684
1684
|
}
|
|
1685
1685
|
|
|
@@ -1742,15 +1742,15 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1742
1742
|
errorLog(
|
|
1743
1743
|
chalk.red.bold(
|
|
1744
1744
|
"Error: namespace index used at the front of the browseName " +
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1745
|
+
indexVerif +
|
|
1746
|
+
" do not match the index of the current namespace (" +
|
|
1747
|
+
this.index +
|
|
1748
|
+
")"
|
|
1749
1749
|
)
|
|
1750
1750
|
);
|
|
1751
1751
|
errorLog(
|
|
1752
1752
|
" Please fix your code so that the created node is inserted in the correct namespace," +
|
|
1753
|
-
|
|
1753
|
+
" please refer to the NodeOPCUA documentation"
|
|
1754
1754
|
);
|
|
1755
1755
|
}
|
|
1756
1756
|
}
|
|
@@ -1990,13 +1990,16 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
1990
1990
|
|
|
1991
1991
|
// -----------------------------------------------------
|
|
1992
1992
|
const hasGetter = (options: AddVariableOptions2) => {
|
|
1993
|
-
return typeof options.value?.get === "function" || typeof options.value?.timestamped_get === "function"
|
|
1994
|
-
}
|
|
1993
|
+
return typeof options.value?.get === "function" || typeof options.value?.timestamped_get === "function";
|
|
1994
|
+
};
|
|
1995
1995
|
|
|
1996
1996
|
// istanbul ignore next
|
|
1997
1997
|
if (options.minimumSamplingInterval === undefined && hasGetter(options)) {
|
|
1998
1998
|
// a getter has been specified and no options.minimumSamplingInterval has been specified
|
|
1999
|
-
warningLog(
|
|
1999
|
+
warningLog(
|
|
2000
|
+
"[NODE-OPCUA-W30",
|
|
2001
|
+
"namespace#addVariable a getter has been specified and minimumSamplingInterval is missing.\nMinimumSamplingInterval has been adjusted to 1000 ms"
|
|
2002
|
+
);
|
|
2000
2003
|
options.minimumSamplingInterval = 1000;
|
|
2001
2004
|
}
|
|
2002
2005
|
|
|
@@ -2004,7 +2007,10 @@ export class NamespaceImpl implements NamespacePrivate {
|
|
|
2004
2007
|
|
|
2005
2008
|
// istanbul ignore next
|
|
2006
2009
|
if (options.minimumSamplingInterval === 0 && hasGetter(options)) {
|
|
2007
|
-
warningLog(
|
|
2010
|
+
warningLog(
|
|
2011
|
+
"[NODE-OPCUA-W31",
|
|
2012
|
+
"namespace#addVariable a getter has been specified and minimumSamplingInterval is 0.\nThis may conduct to an unpredicable behavior.\nPlease specify a non zero minimum sampling interval"
|
|
2013
|
+
);
|
|
2008
2014
|
}
|
|
2009
2015
|
|
|
2010
2016
|
let references = options.references || ([] as AddReferenceOpts[]);
|
|
@@ -2209,15 +2215,15 @@ export function isNonEmptyQualifiedName(browseName?: null | string | QualifiedNa
|
|
|
2209
2215
|
return browseName.name!.length > 0;
|
|
2210
2216
|
}
|
|
2211
2217
|
|
|
2212
|
-
function _create_node_version_if_needed(node: BaseNode, options: {nodeVersion: boolean}) {
|
|
2218
|
+
function _create_node_version_if_needed(node: BaseNode, options: { nodeVersion: boolean }) {
|
|
2213
2219
|
assert(options);
|
|
2214
2220
|
if (options.nodeVersion) {
|
|
2215
2221
|
assert(node.nodeClass === NodeClass.Variable || node.nodeClass === NodeClass.Object);
|
|
2216
2222
|
// istanbul ignore next
|
|
2217
|
-
if (node.getChildByName("NodeVersion"))
|
|
2223
|
+
if (node.getChildByName("NodeVersion")) {
|
|
2218
2224
|
return; // already exists
|
|
2219
2225
|
}
|
|
2220
|
-
const namespace
|
|
2226
|
+
const namespace = node.addressSpace.getOwnNamespace();
|
|
2221
2227
|
const nodeVersion = namespace.addVariable({
|
|
2222
2228
|
browseName: "NodeVersion",
|
|
2223
2229
|
dataType: "String",
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* @module node-opcua-address-space
|
|
4
4
|
*/
|
|
5
5
|
// produce nodeset xml files
|
|
6
|
+
import { types } from "util";
|
|
6
7
|
import { assert } from "node-opcua-assert";
|
|
7
8
|
import { ObjectIds, VariableIds } from "node-opcua-constants";
|
|
8
9
|
import { make_debugLog, make_errorLog, make_warningLog } from "node-opcua-debug";
|
|
@@ -368,7 +369,7 @@ function _dumpVariantInnerExtensionObject(
|
|
|
368
369
|
}
|
|
369
370
|
} catch (err) {
|
|
370
371
|
// eslint-disable-next-line max-depth
|
|
371
|
-
if (err
|
|
372
|
+
if (types.isNativeError(err)) {
|
|
372
373
|
errorLog("Error in _dumpVariantExtensionObjectValue_Body !!!", err.message);
|
|
373
374
|
}
|
|
374
375
|
console.log(name);
|
package/src/ua_method_impl.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module node-opcua-address-space
|
|
3
3
|
*/
|
|
4
|
-
import { callbackify } from "util";
|
|
4
|
+
import { callbackify, types } from "util";
|
|
5
5
|
import * as chalk from "chalk";
|
|
6
6
|
import { assert } from "node-opcua-assert";
|
|
7
7
|
|
|
@@ -243,7 +243,7 @@ export class UAMethodImpl extends BaseNodeImpl implements UAMethod {
|
|
|
243
243
|
}
|
|
244
244
|
);
|
|
245
245
|
} catch (err) {
|
|
246
|
-
if (err
|
|
246
|
+
if (types.isNativeError(err)) {
|
|
247
247
|
warningLog(chalk.red("ERR in method handler"), err.message);
|
|
248
248
|
warningLog(err.stack);
|
|
249
249
|
}
|
package/src/ua_variable_impl.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
// tslint:disable:no-bitwise
|
|
7
7
|
// tslint:disable:no-console
|
|
8
8
|
// tslint:disable:max-line-length
|
|
9
|
+
import { types } from "util";
|
|
9
10
|
import * as chalk from "chalk";
|
|
10
11
|
|
|
11
12
|
import {
|
|
@@ -95,6 +96,7 @@ import {
|
|
|
95
96
|
_installExtensionObjectBindingOnProperties,
|
|
96
97
|
_touchValue
|
|
97
98
|
} from "./ua_variable_impl_ext_obj";
|
|
99
|
+
import { adjustDataValueStatusCode } from "./data_access/adjust_datavalue_status_code";
|
|
98
100
|
|
|
99
101
|
const debugLog = make_debugLog(__filename);
|
|
100
102
|
const warningLog = make_warningLog(__filename);
|
|
@@ -848,7 +850,7 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
|
|
|
848
850
|
// ----------------------------------
|
|
849
851
|
if (this.$extensionObject || this.$$extensionObjectArray) {
|
|
850
852
|
// we have an extension object already bound to this node
|
|
851
|
-
// the client is asking us to replace the object
|
|
853
|
+
// the client is asking us to replace the object entirely by a new one
|
|
852
854
|
// const ext = dataValue.value.value;
|
|
853
855
|
this._internal_set_dataValue(dataValue);
|
|
854
856
|
return;
|
|
@@ -866,6 +868,11 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
|
|
|
866
868
|
}
|
|
867
869
|
}
|
|
868
870
|
|
|
871
|
+
private adjustDataValueStatusCode(dataValue: DataValue): StatusCode {
|
|
872
|
+
const statusCode = adjustDataValueStatusCode(this, dataValue, (this as any).acceptValueOutOfRange || false);
|
|
873
|
+
return statusCode;
|
|
874
|
+
}
|
|
875
|
+
|
|
869
876
|
public writeValue(
|
|
870
877
|
context: ISessionContext,
|
|
871
878
|
dataValue: DataValue,
|
|
@@ -938,6 +945,12 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
|
|
|
938
945
|
return callback!(null, statusCode);
|
|
939
946
|
}
|
|
940
947
|
|
|
948
|
+
// adjust dataValue.statusCode based on InstrumentRange and EngineeringUnits
|
|
949
|
+
const statusCode2 = this.adjustDataValueStatusCode(dataValue);
|
|
950
|
+
if (statusCode2.isNotGood()) {
|
|
951
|
+
return callback!(null, statusCode2);
|
|
952
|
+
}
|
|
953
|
+
|
|
941
954
|
const write_func = this._timestamped_set_func || default_func;
|
|
942
955
|
|
|
943
956
|
if (!write_func) {
|
|
@@ -1003,7 +1016,7 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
|
|
|
1003
1016
|
try {
|
|
1004
1017
|
this._internal_set_dataValue(dataValue, indexRange);
|
|
1005
1018
|
} catch (err) {
|
|
1006
|
-
if (err
|
|
1019
|
+
if (types.isNativeError(err)) {
|
|
1007
1020
|
warningLog(err.message);
|
|
1008
1021
|
}
|
|
1009
1022
|
return callback!(null, StatusCodes.BadInternalError);
|
|
@@ -1280,7 +1293,7 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
|
|
|
1280
1293
|
|
|
1281
1294
|
const readImmediate = (innerCallback: (err: Error | null, dataValue: DataValue) => void) => {
|
|
1282
1295
|
assert(this.$dataValue instanceof DataValue);
|
|
1283
|
-
const dataValue = this.readValue();
|
|
1296
|
+
const dataValue = this.readValue(context);
|
|
1284
1297
|
innerCallback(null, dataValue);
|
|
1285
1298
|
};
|
|
1286
1299
|
|
|
@@ -1322,7 +1335,7 @@ export class UAVariableImpl extends BaseNodeImpl implements UAVariable {
|
|
|
1322
1335
|
// istanbul ignore next
|
|
1323
1336
|
if (doDebug) {
|
|
1324
1337
|
debugLog(chalk.red("func readValueAsync has failed "));
|
|
1325
|
-
if (err
|
|
1338
|
+
if (types.isNativeError(err)) {
|
|
1326
1339
|
debugLog(" stack", err.stack);
|
|
1327
1340
|
}
|
|
1328
1341
|
}
|
|
@@ -2045,10 +2058,14 @@ function _default_writable_timestamped_set_func(
|
|
|
2045
2058
|
function turn_sync_to_async<T, D, R>(f: (this: T, data: D) => R, numberOfArgs: number) {
|
|
2046
2059
|
if (f.length <= numberOfArgs) {
|
|
2047
2060
|
return function (this: T, data: D, callback: (err: Error | null, r?: R) => void) {
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2061
|
+
try {
|
|
2062
|
+
const r = f.call(this, data);
|
|
2063
|
+
setImmediate(() => {
|
|
2064
|
+
return callback(null, r);
|
|
2065
|
+
});
|
|
2066
|
+
} catch (err) {
|
|
2067
|
+
return callback(err as Error);
|
|
2068
|
+
}
|
|
2052
2069
|
};
|
|
2053
2070
|
} else {
|
|
2054
2071
|
assert(f.length === numberOfArgs + 1);
|
|
@@ -2208,6 +2225,10 @@ function _Variable_bind_with_simple_set(this: UAVariableImpl, options: any) {
|
|
|
2208
2225
|
errorLog(chalk.yellow("StatusCode.Good is assumed"));
|
|
2209
2226
|
return callback(err, StatusCodes.Good, timestamped_value);
|
|
2210
2227
|
}
|
|
2228
|
+
if (statusCode && statusCode.isNotGood()) {
|
|
2229
|
+
// record the value but still record the statusCode !
|
|
2230
|
+
timestamped_value.statusCode = statusCode;
|
|
2231
|
+
}
|
|
2211
2232
|
callback(err, statusCode, timestamped_value);
|
|
2212
2233
|
});
|
|
2213
2234
|
};
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module node-opcua-address-space.DataAccess
|
|
3
|
-
*/
|
|
4
|
-
import { assert } from "node-opcua-assert";
|
|
5
|
-
import { UAAnalogItem } from "node-opcua-nodeset-ua";
|
|
6
|
-
import { StatusCodes } from "node-opcua-status-code";
|
|
7
|
-
import { StatusCode } from "node-opcua-status-code";
|
|
8
|
-
import { Range } from "node-opcua-types";
|
|
9
|
-
import { DataType, Variant } from "node-opcua-variant";
|
|
10
|
-
import { UAVariableImpl } from "../ua_variable_impl";
|
|
11
|
-
|
|
12
|
-
function validate_value_range(range: Range, variant: Variant) {
|
|
13
|
-
if (variant.value < range.low || variant.value > range.high) {
|
|
14
|
-
return false;
|
|
15
|
-
}
|
|
16
|
-
return true;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function checkVariantCompatibilityUAAnalogItem(this: UAVariableImpl, value: Variant): StatusCode {
|
|
20
|
-
assert(value instanceof Variant);
|
|
21
|
-
// test dataType
|
|
22
|
-
if (!this._validate_DataType(value.dataType)) {
|
|
23
|
-
return StatusCodes.BadTypeMismatch;
|
|
24
|
-
}
|
|
25
|
-
const analogItem = this as unknown as UAAnalogItem<any, any>;
|
|
26
|
-
// AnalogDataItem
|
|
27
|
-
if (analogItem.instrumentRange) {
|
|
28
|
-
if (!validate_value_range(analogItem.instrumentRange.readValue().value.value as Range, value)) {
|
|
29
|
-
return StatusCodes.BadOutOfRange;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
return StatusCodes.Good;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* extend default checkVariantCompatibility on base class with this one
|
|
37
|
-
*/
|
|
38
|
-
UAVariableImpl.prototype.checkVariantCompatibility = checkVariantCompatibilityUAAnalogItem;
|