node-opcua-address-space 2.66.2 → 2.67.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/address_space_ts.d.ts +0 -2
- package/dist/source/address_space_ts.js.map +1 -1
- package/dist/source/continuation_points/continuation_point_manager.js +3 -0
- package/dist/source/continuation_points/continuation_point_manager.js.map +1 -1
- package/dist/source/index.js +1 -5
- package/dist/source/index.js.map +1 -1
- package/dist/source/loader/make_xml_extension_object_parser.js +28 -9
- package/dist/source/loader/make_xml_extension_object_parser.js.map +1 -1
- package/dist/source/session_context.js +0 -1
- package/dist/source/session_context.js.map +1 -1
- package/dist/src/address_space.js +2 -1
- package/dist/src/address_space.js.map +1 -1
- package/dist/src/alarms_and_conditions/index.js +1 -5
- package/dist/src/alarms_and_conditions/index.js.map +1 -1
- package/dist/src/base_node_impl.js +1 -1
- package/dist/src/base_node_impl.js.map +1 -1
- package/dist/src/extension_object_array_node.js +31 -22
- package/dist/src/extension_object_array_node.js.map +1 -1
- package/dist/src/index_current.js +1 -5
- package/dist/src/index_current.js.map +1 -1
- package/dist/src/reference_impl.js +1 -1
- package/dist/src/reference_impl.js.map +1 -1
- package/dist/src/ua_variable_impl.d.ts +9 -8
- package/dist/src/ua_variable_impl.js +56 -312
- package/dist/src/ua_variable_impl.js.map +1 -1
- package/dist/src/ua_variable_impl_ext_obj.d.ts +17 -0
- package/dist/src/ua_variable_impl_ext_obj.js +393 -0
- package/dist/src/ua_variable_impl_ext_obj.js.map +1 -0
- package/distHelpers/index.js +1 -5
- package/distHelpers/index.js.map +1 -1
- package/distNodeJS/index.js +1 -5
- package/distNodeJS/index.js.map +1 -1
- package/package.json +37 -37
- package/source/address_space_ts.ts +0 -2
- package/source/continuation_points/continuation_point_manager.ts +8 -6
- package/source/loader/make_xml_extension_object_parser.ts +32 -11
- package/src/base_node_impl.ts +1 -1
- package/src/extension_object_array_node.ts +43 -28
- package/src/reference_impl.ts +1 -1
- package/src/ua_variable_impl.ts +66 -379
- package/src/ua_variable_impl_ext_obj.ts +472 -0
- package/test_helpers/test_fixtures/issue_1132_variable_with_nodeid_value.xml +68 -0
|
@@ -22,7 +22,6 @@ const node_opcua_service_write_1 = require("node-opcua-service-write");
|
|
|
22
22
|
const node_opcua_status_code_1 = require("node-opcua-status-code");
|
|
23
23
|
const node_opcua_types_1 = require("node-opcua-types");
|
|
24
24
|
const utils = require("node-opcua-utils");
|
|
25
|
-
const node_opcua_utils_1 = require("node-opcua-utils");
|
|
26
25
|
const node_opcua_variant_1 = require("node-opcua-variant");
|
|
27
26
|
const session_context_1 = require("../source/session_context");
|
|
28
27
|
const multiform_func_1 = require("../source/helpers/multiform_func");
|
|
@@ -30,6 +29,7 @@ const base_node_impl_1 = require("./base_node_impl");
|
|
|
30
29
|
const base_node_private_1 = require("./base_node_private");
|
|
31
30
|
const ua_data_type_impl_1 = require("./ua_data_type_impl");
|
|
32
31
|
const apply_condition_refresh_1 = require("./apply_condition_refresh");
|
|
32
|
+
const ua_variable_impl_ext_obj_1 = require("./ua_variable_impl_ext_obj");
|
|
33
33
|
const debugLog = (0, node_opcua_debug_1.make_debugLog)(__filename);
|
|
34
34
|
const warningLog = (0, node_opcua_debug_1.make_warningLog)(__filename);
|
|
35
35
|
const doDebug = (0, node_opcua_debug_1.checkDebugFlag)(__filename);
|
|
@@ -460,6 +460,7 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
460
460
|
return (0, node_opcua_variant_1.adjustVariant)(variant, this.valueRank, this.getBasicDataType());
|
|
461
461
|
}
|
|
462
462
|
verifyVariantCompatibility(variant) {
|
|
463
|
+
var _a;
|
|
463
464
|
try {
|
|
464
465
|
// istanbul ignore next
|
|
465
466
|
if (Object.prototype.hasOwnProperty.call(variant, "value")) {
|
|
@@ -478,7 +479,8 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
478
479
|
}
|
|
479
480
|
if (this.dataType.namespace === 0 &&
|
|
480
481
|
this.dataType.value === node_opcua_variant_1.DataType.LocalizedText &&
|
|
481
|
-
variant.dataType !== node_opcua_variant_1.DataType.LocalizedText &&
|
|
482
|
+
variant.dataType !== node_opcua_variant_1.DataType.LocalizedText &&
|
|
483
|
+
variant.dataType !== node_opcua_variant_1.DataType.Null) {
|
|
482
484
|
throw new Error("Variant must provide a valid LocalizedText : variant = " +
|
|
483
485
|
variant.toString() +
|
|
484
486
|
" this.dataType= " +
|
|
@@ -516,7 +518,7 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
516
518
|
}
|
|
517
519
|
}
|
|
518
520
|
catch (err) {
|
|
519
|
-
errorLog("UAVariable ", err === null ||
|
|
521
|
+
errorLog("UAVariable ", (_a = err) === null || _a === void 0 ? void 0 : _a.message, this.browseName.toString(), " nodeId=", this.nodeId.toString());
|
|
520
522
|
errorLog(err.message);
|
|
521
523
|
errorLog(err.stack);
|
|
522
524
|
throw err;
|
|
@@ -547,7 +549,21 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
547
549
|
dataValue.sourceTimestamp = now.timestamp;
|
|
548
550
|
dataValue.statusCode = statusCode;
|
|
549
551
|
dataValue.value = variant1;
|
|
550
|
-
|
|
552
|
+
if (dataValue.value.dataType === node_opcua_variant_1.DataType.ExtensionObject) {
|
|
553
|
+
this.$dataValue = dataValue;
|
|
554
|
+
(0, node_opcua_assert_1.assert)(this.checkExtensionObjectIsCorrect(dataValue.value.value));
|
|
555
|
+
// ----------------------------------
|
|
556
|
+
if (this.$extensionObject) {
|
|
557
|
+
// we have an extension object already bound to this node
|
|
558
|
+
// the client is asking us to replace the object entierly by a new one
|
|
559
|
+
const ext = dataValue.value.value;
|
|
560
|
+
(0, ua_variable_impl_ext_obj_1._setExtensionObject)(this, ext);
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
else {
|
|
565
|
+
this._internal_set_dataValue(dataValue);
|
|
566
|
+
}
|
|
551
567
|
}
|
|
552
568
|
catch (err) {
|
|
553
569
|
errorLog("UAVariable#setValueFromString Error : ", this.browseName.toString(), this.nodeId.toString());
|
|
@@ -730,30 +746,12 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
730
746
|
return node_opcua_status_code_1.StatusCodes.Good;
|
|
731
747
|
}
|
|
732
748
|
/**
|
|
733
|
-
* @method touchValue
|
|
734
749
|
* touch the source timestamp of a Variable and cascade up the change
|
|
735
750
|
* to the parent variable if any.
|
|
736
|
-
*
|
|
737
|
-
* @param [optionalNow=null] {Object}
|
|
738
|
-
* @param optionalNow.timestamp {Date}
|
|
739
|
-
* @param optionalNow.picoseconds {Number}
|
|
740
751
|
*/
|
|
741
752
|
touchValue(optionalNow) {
|
|
742
753
|
const now = optionalNow || (0, node_opcua_date_time_1.getCurrentClock)();
|
|
743
|
-
this
|
|
744
|
-
this.$dataValue.sourcePicoseconds = now.picoseconds;
|
|
745
|
-
this.$dataValue.serverTimestamp = now.timestamp;
|
|
746
|
-
this.$dataValue.serverPicoseconds = now.picoseconds;
|
|
747
|
-
this.$dataValue.statusCode = node_opcua_status_code_1.StatusCodes.Good;
|
|
748
|
-
if (this.minimumSamplingInterval === 0) {
|
|
749
|
-
if (this.listenerCount("value_changed") > 0) {
|
|
750
|
-
const clonedDataValue = this.readValue();
|
|
751
|
-
this.emit("value_changed", clonedDataValue);
|
|
752
|
-
}
|
|
753
|
-
}
|
|
754
|
-
if (this.parent && this.parent.nodeClass === node_opcua_data_model_1.NodeClass.Variable) {
|
|
755
|
-
this.parent.touchValue(now);
|
|
756
|
-
}
|
|
754
|
+
(0, ua_variable_impl_ext_obj_1.propagateTouchValueUpward)(this, now);
|
|
757
755
|
}
|
|
758
756
|
/**
|
|
759
757
|
* bind a variable with a get and set functions.
|
|
@@ -972,6 +970,11 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
972
970
|
(0, node_opcua_assert_1.assert)(typeof newVariable._timestamped_set_func === "function");
|
|
973
971
|
(0, node_opcua_assert_1.assert)(newVariable.dataType === this.dataType);
|
|
974
972
|
newVariable.$dataValue = this.$dataValue.clone();
|
|
973
|
+
// also bind extension object
|
|
974
|
+
const v = newVariable.$dataValue.value;
|
|
975
|
+
if (v.dataType === node_opcua_variant_1.DataType.ExtensionObject && v.value && v.arrayType === node_opcua_variant_1.VariantArrayType.Scalar) {
|
|
976
|
+
newVariable.bindExtensionObject(newVariable.$dataValue.value.value);
|
|
977
|
+
}
|
|
975
978
|
return newVariable;
|
|
976
979
|
}
|
|
977
980
|
getDataTypeNode() {
|
|
@@ -1026,262 +1029,37 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
1026
1029
|
}
|
|
1027
1030
|
}
|
|
1028
1031
|
/**
|
|
1029
|
-
* @
|
|
1030
|
-
*
|
|
1032
|
+
* @private
|
|
1033
|
+
* install UAVariable to exposed th
|
|
1034
|
+
*
|
|
1035
|
+
* precondition:
|
|
1031
1036
|
*/
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
const
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
// bindExtensionObject cannot be performed and shall finish here.
|
|
1040
|
-
return null;
|
|
1041
|
-
}
|
|
1042
|
-
// istanbul ignore next
|
|
1043
|
-
if (doDebug) {
|
|
1044
|
-
debugLog(" ------------------------------ binding ", this.browseName.toString(), this.nodeId.toString());
|
|
1045
|
-
}
|
|
1046
|
-
(0, node_opcua_assert_1.assert)(structure && structure.browseName.toString() === "Structure", "expecting DataType Structure to be in IAddressSpace");
|
|
1047
|
-
const dt = this.getDataTypeNode();
|
|
1048
|
-
if (!dt.isSupertypeOf(structure)) {
|
|
1049
|
-
return null;
|
|
1050
|
-
}
|
|
1051
|
-
// the namespace for the structure browse name elements
|
|
1052
|
-
const structureNamespace = dt.nodeId.namespace;
|
|
1053
|
-
// -------------------- make sure we do not bind a variable twice ....
|
|
1054
|
-
if (this.$extensionObject) {
|
|
1055
|
-
// istanbul ignore next
|
|
1056
|
-
// if (!force && !utils.isNullOrUndefined(optionalExtensionObject)) {
|
|
1057
|
-
// throw new Error(
|
|
1058
|
-
// "bindExtensionObject: unsupported case : $extensionObject already exists on " +
|
|
1059
|
-
// this.browseName.toString() +
|
|
1060
|
-
// " " +
|
|
1061
|
-
// this.nodeId.toString()
|
|
1062
|
-
// );
|
|
1063
|
-
// }
|
|
1064
|
-
// istanbul ignore next
|
|
1065
|
-
if (!this.checkExtensionObjectIsCorrect(this.$extensionObject)) {
|
|
1066
|
-
warningLog("on node : ", this.browseName.toString(), this.nodeId.toString(), "dataType=", this.dataType.toString({ addressSpace: this.addressSpace }));
|
|
1067
|
-
warningLog((_a = this.$extensionObject) === null || _a === void 0 ? void 0 : _a.toString());
|
|
1068
|
-
throw new Error("bindExtensionObject: $extensionObject is incorrect: we are expecting a " +
|
|
1069
|
-
this.dataType.toString({ addressSpace: this.addressSpace }) +
|
|
1070
|
-
" but we got a " +
|
|
1071
|
-
((_b = this.$extensionObject) === null || _b === void 0 ? void 0 : _b.constructor.name));
|
|
1072
|
-
}
|
|
1073
|
-
return this.$extensionObject;
|
|
1074
|
-
// throw new Error("Variable already bound");
|
|
1075
|
-
}
|
|
1076
|
-
this.$extensionObject = optionalExtensionObject;
|
|
1077
|
-
// ------------------------------------------------------------------
|
|
1078
|
-
function prepareVariantValue(dataType, value) {
|
|
1079
|
-
if ((dataType === node_opcua_variant_1.DataType.Int32 || dataType === node_opcua_variant_1.DataType.UInt32) && value && value.key) {
|
|
1080
|
-
value = value.value;
|
|
1081
|
-
}
|
|
1082
|
-
return value;
|
|
1083
|
-
}
|
|
1084
|
-
const bindProperty = (propertyNode, name, extensionObject, dataType) => {
|
|
1085
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
1086
|
-
const self = this;
|
|
1087
|
-
propertyNode.bindVariable({
|
|
1088
|
-
timestamped_get: () => {
|
|
1089
|
-
const propertyValue = self.$extensionObject[name];
|
|
1090
|
-
if (propertyValue === undefined) {
|
|
1091
|
-
propertyNode.$dataValue.value.dataType = node_opcua_variant_1.DataType.Null;
|
|
1092
|
-
propertyNode.$dataValue.statusCode = node_opcua_status_code_1.StatusCodes.Good;
|
|
1093
|
-
propertyNode.$dataValue.value.value = null;
|
|
1094
|
-
return new node_opcua_data_value_1.DataValue(propertyNode.$dataValue);
|
|
1095
|
-
}
|
|
1096
|
-
const value = prepareVariantValue(dataType, propertyValue);
|
|
1097
|
-
propertyNode.$dataValue.statusCode = node_opcua_status_code_1.StatusCodes.Good;
|
|
1098
|
-
propertyNode.$dataValue.value.dataType = dataType;
|
|
1099
|
-
propertyNode.$dataValue.value.value = value;
|
|
1100
|
-
return new node_opcua_data_value_1.DataValue(propertyNode.$dataValue);
|
|
1101
|
-
},
|
|
1102
|
-
timestamped_set: (dataValue, callback) => {
|
|
1103
|
-
dataValue;
|
|
1104
|
-
callback(null, node_opcua_status_code_1.StatusCodes.BadNotWritable);
|
|
1105
|
-
}
|
|
1106
|
-
}, true);
|
|
1107
|
-
};
|
|
1108
|
-
const components = this.getComponents();
|
|
1109
|
-
// ------------------------------------------------------
|
|
1110
|
-
// make sure we have a structure
|
|
1111
|
-
// ------------------------------------------------------
|
|
1112
|
-
const s = this.readValue();
|
|
1113
|
-
// istanbul ignore next
|
|
1114
|
-
if (this.dataTypeObj.isAbstract) {
|
|
1115
|
-
warningLog("Warning the DataType associated with this Variable is abstract ", this.dataTypeObj.browseName.toString());
|
|
1116
|
-
warningLog("You need to provide a extension object yourself ");
|
|
1117
|
-
throw new Error("bindExtensionObject requires a extensionObject as associated dataType is only abstract");
|
|
1118
|
-
}
|
|
1119
|
-
if (s.value && (s.value.dataType === node_opcua_variant_1.DataType.Null || (s.value.dataType === node_opcua_variant_1.DataType.ExtensionObject && !s.value.value))) {
|
|
1120
|
-
// create a structure and bind it
|
|
1121
|
-
extensionObject_ = this.$extensionObject || addressSpace.constructExtensionObject(this.dataType, {});
|
|
1122
|
-
extensionObject_ = new Proxy(extensionObject_, makeHandler(this));
|
|
1123
|
-
this.$extensionObject = extensionObject_;
|
|
1124
|
-
const theValue = new node_opcua_variant_1.Variant({
|
|
1125
|
-
dataType: node_opcua_variant_1.DataType.ExtensionObject,
|
|
1126
|
-
value: this.$extensionObject
|
|
1127
|
-
});
|
|
1128
|
-
this.setValueFromSource(theValue, node_opcua_status_code_1.StatusCodes.Good);
|
|
1129
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
1130
|
-
const self = this;
|
|
1131
|
-
this.bindVariable({
|
|
1132
|
-
timestamped_get() {
|
|
1133
|
-
self.$dataValue.value.value = self.$extensionObject;
|
|
1134
|
-
const d = new node_opcua_data_value_1.DataValue(self.$dataValue);
|
|
1135
|
-
d.value = new node_opcua_variant_1.Variant(d.value);
|
|
1136
|
-
return d;
|
|
1137
|
-
},
|
|
1138
|
-
timestamped_set(dataValue, callback) {
|
|
1139
|
-
const ext = dataValue.value.value;
|
|
1140
|
-
if (!self.checkExtensionObjectIsCorrect(ext)) {
|
|
1141
|
-
return callback(null, node_opcua_status_code_1.StatusCodes.BadInvalidArgument);
|
|
1142
|
-
}
|
|
1143
|
-
self.$extensionObject = new Proxy(ext, makeHandler(self));
|
|
1144
|
-
self.touchValue();
|
|
1145
|
-
callback(null, node_opcua_status_code_1.StatusCodes.Good);
|
|
1146
|
-
}
|
|
1147
|
-
}, true);
|
|
1148
|
-
}
|
|
1149
|
-
else {
|
|
1150
|
-
// verify that variant has the correct type
|
|
1151
|
-
(0, node_opcua_assert_1.assert)(s.value.dataType === node_opcua_variant_1.DataType.ExtensionObject);
|
|
1152
|
-
this.$extensionObject = s.value.value;
|
|
1153
|
-
(0, node_opcua_assert_1.assert)(this.checkExtensionObjectIsCorrect(this.$extensionObject));
|
|
1154
|
-
(0, node_opcua_assert_1.assert)(s.statusCode.equals(node_opcua_status_code_1.StatusCodes.Good));
|
|
1155
|
-
}
|
|
1156
|
-
// ------------------------------------------------------
|
|
1157
|
-
// now bind each member
|
|
1158
|
-
// ------------------------------------------------------
|
|
1159
|
-
const definition = dt._getDefinition();
|
|
1160
|
-
// istanbul ignore next
|
|
1161
|
-
if (!definition) {
|
|
1162
|
-
throw new Error("xx definition missing in " + dt.toString());
|
|
1163
|
-
}
|
|
1164
|
-
const getOrCreateProperty = (field) => {
|
|
1165
|
-
let property;
|
|
1166
|
-
const selectedComponents = components.filter((f) => f instanceof UAVariableImpl && f.browseName.name.toString() === field.name);
|
|
1167
|
-
if (field.dataType.value === node_opcua_variant_1.DataType.Variant) {
|
|
1168
|
-
warningLog("Warning : variant is not supported in ExtensionObject");
|
|
1169
|
-
}
|
|
1170
|
-
if (selectedComponents.length === 1) {
|
|
1171
|
-
property = selectedComponents[0];
|
|
1172
|
-
/* istanbul ignore next */
|
|
1173
|
-
}
|
|
1174
|
-
else {
|
|
1175
|
-
debugLog("adding missing array variable", field.name, this.browseName.toString(), this.nodeId.toString());
|
|
1176
|
-
// todo: Handle array appropriately...
|
|
1177
|
-
(0, node_opcua_assert_1.assert)(selectedComponents.length === 0);
|
|
1178
|
-
// create a variable (Note we may use ns=1;s=parentName/0:PropertyName)
|
|
1179
|
-
property = this.namespace.addVariable({
|
|
1180
|
-
browseName: { namespaceIndex: structureNamespace, name: field.name.toString() },
|
|
1181
|
-
componentOf: this,
|
|
1182
|
-
dataType: field.dataType,
|
|
1183
|
-
minimumSamplingInterval: this.minimumSamplingInterval
|
|
1184
|
-
});
|
|
1185
|
-
(0, node_opcua_assert_1.assert)(property.minimumSamplingInterval === this.minimumSamplingInterval);
|
|
1186
|
-
}
|
|
1187
|
-
return property;
|
|
1188
|
-
};
|
|
1189
|
-
for (const field of definition.fields || []) {
|
|
1190
|
-
if (node_opcua_nodeid_1.NodeId.sameNodeId(node_opcua_nodeid_1.NodeId.nullNodeId, field.dataType)) {
|
|
1191
|
-
warningLog("field.dataType is null ! ", field.toString(), node_opcua_nodeid_1.NodeId.nullNodeId.toString());
|
|
1192
|
-
warningLog(" dataType replaced with BaseDataType ");
|
|
1193
|
-
warningLog(definition.toString());
|
|
1194
|
-
field.dataType = this.resolveNodeId("BaseDataType");
|
|
1195
|
-
}
|
|
1196
|
-
const camelCaseName = (0, node_opcua_utils_1.lowerFirstLetter)(field.name);
|
|
1197
|
-
(0, node_opcua_assert_1.assert)(Object.prototype.hasOwnProperty.call(this.$extensionObject, camelCaseName));
|
|
1198
|
-
const propertyNode = getOrCreateProperty(field);
|
|
1199
|
-
propertyNode.$dataValue.statusCode = node_opcua_status_code_1.StatusCodes.Good;
|
|
1200
|
-
propertyNode.touchValue();
|
|
1201
|
-
const basicDataType = addressSpace.findCorrespondingBasicDataType(field.dataType);
|
|
1202
|
-
// istanbul ignore next
|
|
1203
|
-
if (doDebug) {
|
|
1204
|
-
const x = addressSpace.findNode(field.dataType).browseName.toString();
|
|
1205
|
-
debugLog(chalk.cyan("xxx"), " dataType", w(field.dataType.toString(), 8), w(field.name, 35), "valueRank", chalk.cyan(w((0, base_node_private_1.valueRankToString)(field.valueRank), 10)), chalk.green(w(x, 25)), "basicType = ", chalk.yellow(w(basicDataType.toString(), 20)), propertyNode.nodeId.toString(), propertyNode.readValue().statusCode.toString());
|
|
1206
|
-
}
|
|
1207
|
-
if (this.$extensionObject[camelCaseName] !== undefined && basicDataType === node_opcua_variant_1.DataType.ExtensionObject) {
|
|
1208
|
-
(0, node_opcua_assert_1.assert)(this.$extensionObject[camelCaseName] instanceof Object);
|
|
1209
|
-
this.$extensionObject[camelCaseName] = new Proxy(this.$extensionObject[camelCaseName], makeHandler(propertyNode));
|
|
1210
|
-
propertyNode._internal_set_value(new node_opcua_variant_1.Variant({
|
|
1211
|
-
dataType: node_opcua_variant_1.DataType.ExtensionObject,
|
|
1212
|
-
value: this.$extensionObject[camelCaseName]
|
|
1213
|
-
}));
|
|
1214
|
-
propertyNode.bindExtensionObject();
|
|
1215
|
-
propertyNode.$extensionObject = this.$extensionObject[camelCaseName];
|
|
1216
|
-
}
|
|
1217
|
-
else {
|
|
1218
|
-
const prop = this.$extensionObject[camelCaseName];
|
|
1219
|
-
if (prop === undefined) {
|
|
1220
|
-
propertyNode._internal_set_value(new node_opcua_variant_1.Variant({
|
|
1221
|
-
dataType: node_opcua_variant_1.DataType.Null
|
|
1222
|
-
}));
|
|
1223
|
-
}
|
|
1224
|
-
else {
|
|
1225
|
-
const preparedValue = prepareVariantValue(basicDataType, prop);
|
|
1226
|
-
propertyNode._internal_set_value(new node_opcua_variant_1.Variant({
|
|
1227
|
-
dataType: basicDataType,
|
|
1228
|
-
value: preparedValue
|
|
1229
|
-
}));
|
|
1037
|
+
installExtensionObjectVariables() {
|
|
1038
|
+
(0, ua_variable_impl_ext_obj_1._installExtensionObjectBindingOnProperties)(this, { createMissingProp: true });
|
|
1039
|
+
// now recursively install extension object on children
|
|
1040
|
+
for (const child of this.getComponents()) {
|
|
1041
|
+
if (child.nodeClass === node_opcua_data_model_1.NodeClass.Variable && child instanceof UAVariableImpl) {
|
|
1042
|
+
if (child.isExtensionObject()) {
|
|
1043
|
+
child.installExtensionObjectVariables();
|
|
1230
1044
|
}
|
|
1231
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
1232
|
-
const self = this;
|
|
1233
|
-
// property.camelCaseName = camelCaseName;
|
|
1234
|
-
propertyNode.setValueFromSource = function (variant) {
|
|
1235
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
1236
|
-
const inner_this = this;
|
|
1237
|
-
const variant1 = node_opcua_variant_1.Variant.coerce(variant);
|
|
1238
|
-
inner_this.verifyVariantCompatibility(variant1);
|
|
1239
|
-
self.$extensionObject[camelCaseName] = variant1.value;
|
|
1240
|
-
self.touchValue();
|
|
1241
|
-
};
|
|
1242
1045
|
}
|
|
1243
|
-
(0, node_opcua_assert_1.assert)(propertyNode.readValue().statusCode.equals(node_opcua_status_code_1.StatusCodes.Good));
|
|
1244
|
-
bindProperty(propertyNode, camelCaseName, this.$extensionObject, basicDataType);
|
|
1245
1046
|
}
|
|
1246
|
-
|
|
1247
|
-
|
|
1047
|
+
}
|
|
1048
|
+
/**
|
|
1049
|
+
* @method bindExtensionObject
|
|
1050
|
+
* @return {ExtensionObject}
|
|
1051
|
+
*/
|
|
1052
|
+
bindExtensionObject(optionalExtensionObject, options) {
|
|
1053
|
+
return (0, ua_variable_impl_ext_obj_1._bindExtensionObject)(this, optionalExtensionObject, options);
|
|
1248
1054
|
}
|
|
1249
1055
|
updateExtensionObjectPartial(partialExtensionObject) {
|
|
1250
|
-
setExtensionObjectValue(this, partialExtensionObject);
|
|
1056
|
+
(0, ua_variable_impl_ext_obj_1.setExtensionObjectValue)(this, partialExtensionObject);
|
|
1251
1057
|
return this.$extensionObject;
|
|
1252
1058
|
}
|
|
1253
1059
|
incrementExtensionObjectPartial(path) {
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
}
|
|
1258
|
-
(0, node_opcua_assert_1.assert)(path instanceof Array);
|
|
1259
|
-
const extensionObject = this.constructExtensionObjectFromComponents();
|
|
1260
|
-
let i;
|
|
1261
|
-
// read partial value
|
|
1262
|
-
const partialData = {};
|
|
1263
|
-
let p = partialData;
|
|
1264
|
-
for (i = 0; i < path.length - 1; i++) {
|
|
1265
|
-
name = path[i];
|
|
1266
|
-
p[name] = {};
|
|
1267
|
-
p = p[name];
|
|
1268
|
-
}
|
|
1269
|
-
name = path[path.length - 1];
|
|
1270
|
-
p[name] = 0;
|
|
1271
|
-
let c1 = partialData;
|
|
1272
|
-
let c2 = extensionObject;
|
|
1273
|
-
for (i = 0; i < path.length - 1; i++) {
|
|
1274
|
-
name = path[i];
|
|
1275
|
-
c1 = partialData[name];
|
|
1276
|
-
c2 = extensionObject[name];
|
|
1277
|
-
}
|
|
1278
|
-
name = path[path.length - 1];
|
|
1279
|
-
c1[name] = c2[name];
|
|
1280
|
-
c1[name] += 1;
|
|
1281
|
-
setExtensionObjectValue(this, partialData);
|
|
1282
|
-
}
|
|
1283
|
-
constructExtensionObjectFromComponents() {
|
|
1284
|
-
return this.readValue().value.value;
|
|
1060
|
+
const extensionObject = this.readValue().value.value;
|
|
1061
|
+
const partialData = (0, ua_variable_impl_ext_obj_1.extractPartialData)(path, extensionObject);
|
|
1062
|
+
(0, ua_variable_impl_ext_obj_1.setExtensionObjectValue)(this, partialData);
|
|
1285
1063
|
}
|
|
1286
1064
|
toString() {
|
|
1287
1065
|
const options = new base_node_private_1.ToStringBuilder();
|
|
@@ -1356,6 +1134,14 @@ class UAVariableImpl extends base_node_impl_1.BaseNodeImpl {
|
|
|
1356
1134
|
warningLog(dataValue.toString());
|
|
1357
1135
|
throw new Error("Invalid Extension Object on nodeId =" + this.nodeId.toString());
|
|
1358
1136
|
}
|
|
1137
|
+
// ----------------------------------
|
|
1138
|
+
// if (this.$extensionObject) {
|
|
1139
|
+
// // we have an extension object already bound to this node
|
|
1140
|
+
// // the client is asking us to replace the object entierly by a new one
|
|
1141
|
+
// const ext = dataValue.value.value;
|
|
1142
|
+
// _setExtensionObject(this, ext);
|
|
1143
|
+
// return;
|
|
1144
|
+
// }
|
|
1359
1145
|
}
|
|
1360
1146
|
// // istanbul ignore next
|
|
1361
1147
|
// if (this.dataType.namespace === 0) {
|
|
@@ -1750,48 +1536,6 @@ function bind_getter(options) {
|
|
|
1750
1536
|
}
|
|
1751
1537
|
}
|
|
1752
1538
|
}
|
|
1753
|
-
function w(str, n) {
|
|
1754
|
-
return (str + " ").substr(0, n);
|
|
1755
|
-
}
|
|
1756
|
-
function _getter(target, key /*, receiver*/) {
|
|
1757
|
-
if (target[key] === undefined) {
|
|
1758
|
-
return undefined;
|
|
1759
|
-
}
|
|
1760
|
-
return target[key];
|
|
1761
|
-
}
|
|
1762
|
-
function _setter(variable, target, key, value /*, receiver*/) {
|
|
1763
|
-
target[key] = value;
|
|
1764
|
-
const child = variable[key];
|
|
1765
|
-
if (child && child.touchValue) {
|
|
1766
|
-
child.touchValue();
|
|
1767
|
-
}
|
|
1768
|
-
return true; // true means the set operation has succeeded
|
|
1769
|
-
}
|
|
1770
|
-
function makeHandler(variable) {
|
|
1771
|
-
const handler = {
|
|
1772
|
-
get: _getter,
|
|
1773
|
-
set: _setter.bind(null, variable)
|
|
1774
|
-
};
|
|
1775
|
-
return handler;
|
|
1776
|
-
}
|
|
1777
|
-
function setExtensionObjectValue(node, partialObject) {
|
|
1778
|
-
const extensionObject = node.$extensionObject;
|
|
1779
|
-
if (!extensionObject) {
|
|
1780
|
-
throw new Error("setExtensionObjectValue node has no extension object " + node.browseName.toString());
|
|
1781
|
-
}
|
|
1782
|
-
function _update_extension_object(extObject, partialObject1) {
|
|
1783
|
-
const keys = Object.keys(partialObject1);
|
|
1784
|
-
for (const prop of keys) {
|
|
1785
|
-
if (extObject[prop] instanceof Object) {
|
|
1786
|
-
_update_extension_object(extObject[prop], partialObject1[prop]);
|
|
1787
|
-
}
|
|
1788
|
-
else {
|
|
1789
|
-
extObject[prop] = partialObject1[prop];
|
|
1790
|
-
}
|
|
1791
|
-
}
|
|
1792
|
-
}
|
|
1793
|
-
_update_extension_object(extensionObject, partialObject);
|
|
1794
|
-
}
|
|
1795
1539
|
class UAVariableImplT extends UAVariableImpl {
|
|
1796
1540
|
}
|
|
1797
1541
|
exports.UAVariableImplT = UAVariableImplT;
|