node-opcua-address-space 2.88.0 → 2.89.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 +4 -4
- package/dist/source/address_space_ts.js +3 -3
- package/dist/source/address_space_ts.js.map +1 -1
- package/dist/source/helpers/argument_list.js +8 -12
- package/dist/source/helpers/argument_list.js.map +1 -1
- package/dist/source/helpers/call_helpers.d.ts +1 -1
- package/dist/source/helpers/multiform_func.d.ts +8 -8
- package/dist/source/interfaces/alarms_and_conditions/ua_condition_ex.d.ts +1 -1
- package/dist/source/interfaces/extension_object_constructor.d.ts +1 -1
- package/dist/source/interfaces/state_machine/ua_state_machine_type.d.ts +2 -2
- package/dist/source/loader/generateAddressSpaceRaw.d.ts +2 -2
- package/dist/source/loader/make_xml_extension_object_parser.d.ts +1 -1
- package/dist/source/loader/namespace_post_step.d.ts +1 -1
- package/dist/source/session_context.d.ts +1 -1
- package/dist/src/address_space.js +11 -11
- package/dist/src/address_space.js.map +1 -1
- package/dist/src/apply_condition_refresh.d.ts +1 -1
- package/dist/src/base_node_impl.js +44 -44
- package/dist/src/base_node_impl.js.map +1 -1
- package/dist/src/event_data.d.ts +2 -2
- package/dist/src/extension_object_array_node.d.ts +1 -1
- package/dist/src/extension_object_array_node.js +11 -9
- package/dist/src/extension_object_array_node.js.map +1 -1
- package/dist/src/nodeid_manager.d.ts +3 -3
- package/dist/src/nodeset_tools/nodeset_to_xml.d.ts +1 -1
- package/dist/src/reference_impl.js +6 -6
- package/dist/src/reference_impl.js.map +1 -1
- package/dist/src/tool_isSupertypeOf.d.ts +4 -4
- package/dist/src/ua_data_type_impl.js +12 -12
- package/dist/src/ua_data_type_impl.js.map +1 -1
- package/dist/src/ua_method_impl.js +6 -6
- package/dist/src/ua_method_impl.js.map +1 -1
- package/dist/src/ua_object_impl.js +7 -7
- package/dist/src/ua_object_impl.js.map +1 -1
- package/dist/src/ua_object_type_impl.js +6 -6
- package/dist/src/ua_object_type_impl.js.map +1 -1
- package/dist/src/ua_reference_type_impl.js +6 -6
- package/dist/src/ua_reference_type_impl.js.map +1 -1
- package/dist/src/ua_variable_impl.d.ts +4 -0
- package/dist/src/ua_variable_impl.js +41 -54
- package/dist/src/ua_variable_impl.js.map +1 -1
- package/dist/src/ua_variable_impl_ext_obj.d.ts +10 -8
- package/dist/src/ua_variable_impl_ext_obj.js +287 -240
- package/dist/src/ua_variable_impl_ext_obj.js.map +1 -1
- package/dist/src/ua_variable_type_impl.js +7 -7
- package/dist/src/ua_variable_type_impl.js.map +1 -1
- package/dist/src/ua_view_impl.js +3 -3
- package/dist/src/ua_view_impl.js.map +1 -1
- package/package.json +26 -26
- package/source/address_space_ts.ts +1 -1
- package/source/helpers/argument_list.ts +26 -26
- package/src/extension_object_array_node.ts +11 -10
- package/src/ua_variable_impl.ts +40 -51
- package/src/ua_variable_impl_ext_obj.ts +333 -288
- package/src/ua_variable_type_impl.ts +4 -4
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.extractPartialData = exports.
|
|
4
|
-
const chalk = require("chalk");
|
|
3
|
+
exports.extractPartialData = exports.incrementElement = exports.setElement = exports.getElement = exports._bindExtensionObjectArrayOrMatrix = exports._bindExtensionObject = exports._installExtensionObjectBindingOnProperties = exports.setExtensionObjectPartialValue = exports.propagateTouchValueUpward = exports._touchValue = exports.getProxyTarget = void 0;
|
|
5
4
|
const node_opcua_assert_1 = require("node-opcua-assert");
|
|
6
5
|
const node_opcua_data_model_1 = require("node-opcua-data-model");
|
|
7
6
|
const node_opcua_date_time_1 = require("node-opcua-date-time");
|
|
8
|
-
const node_opcua_data_value_1 = require("node-opcua-data-value");
|
|
9
7
|
const node_opcua_debug_1 = require("node-opcua-debug");
|
|
10
8
|
const node_opcua_extension_object_1 = require("node-opcua-extension-object");
|
|
11
9
|
const node_opcua_nodeid_1 = require("node-opcua-nodeid");
|
|
12
10
|
const node_opcua_status_code_1 = require("node-opcua-status-code");
|
|
13
11
|
const node_opcua_utils_1 = require("node-opcua-utils");
|
|
14
12
|
const node_opcua_variant_1 = require("node-opcua-variant");
|
|
15
|
-
const base_node_private_1 = require("./base_node_private");
|
|
16
13
|
const ua_variable_impl_1 = require("./ua_variable_impl");
|
|
17
14
|
const idx_iterator_1 = require("./idx_iterator");
|
|
18
15
|
const doDebug = (0, node_opcua_debug_1.checkDebugFlag)(__filename);
|
|
@@ -27,37 +24,61 @@ function w(str, n) {
|
|
|
27
24
|
function isProxy(ext) {
|
|
28
25
|
return ext.$isProxy ? true : false;
|
|
29
26
|
}
|
|
27
|
+
function getProxyVariable(ext) {
|
|
28
|
+
(0, node_opcua_assert_1.default)(isProxy(ext));
|
|
29
|
+
return ext.$variable;
|
|
30
|
+
}
|
|
31
|
+
function getProxyVariableForProp(ext, prop) {
|
|
32
|
+
const uaVariable = getProxyVariable(ext);
|
|
33
|
+
if (!uaVariable)
|
|
34
|
+
return undefined;
|
|
35
|
+
return uaVariable[prop];
|
|
36
|
+
}
|
|
30
37
|
function getProxyTarget(ext) {
|
|
31
38
|
(0, node_opcua_assert_1.default)(isProxy(ext));
|
|
32
|
-
|
|
39
|
+
const target = ext.$proxyTarget;
|
|
40
|
+
if (target && isProxy(target)) {
|
|
41
|
+
return getProxyTarget(target);
|
|
42
|
+
}
|
|
43
|
+
return target;
|
|
33
44
|
}
|
|
45
|
+
exports.getProxyTarget = getProxyTarget;
|
|
34
46
|
function unProxy(ext) {
|
|
35
47
|
return isProxy(ext) ? getProxyTarget(ext) : ext;
|
|
36
48
|
}
|
|
37
|
-
function _extensionObjectFieldGetter(target, key /*, receiver*/) {
|
|
49
|
+
function _extensionObjectFieldGetter(getVariable, target, key /*, receiver*/) {
|
|
38
50
|
if (key === "$isProxy") {
|
|
39
51
|
return true;
|
|
40
52
|
}
|
|
41
53
|
if (key === "$proxyTarget") {
|
|
42
54
|
return target;
|
|
43
55
|
}
|
|
56
|
+
if (key === "$variable") {
|
|
57
|
+
return getVariable();
|
|
58
|
+
}
|
|
44
59
|
if (target[key] === undefined) {
|
|
45
60
|
return undefined;
|
|
46
61
|
}
|
|
47
62
|
return target[key];
|
|
48
63
|
}
|
|
49
|
-
function _extensionObjectFieldSetter(
|
|
64
|
+
function _extensionObjectFieldSetter(getVariable, target, key, value /*, receiver*/) {
|
|
50
65
|
target[key] = value;
|
|
51
|
-
|
|
66
|
+
if (isProxy(target)) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
const uaVariable = getVariable();
|
|
70
|
+
if (!uaVariable)
|
|
71
|
+
return true;
|
|
72
|
+
const child = uaVariable[key];
|
|
52
73
|
if (child && child.touchValue) {
|
|
53
74
|
child.touchValue();
|
|
54
75
|
}
|
|
55
76
|
return true; // true means the set operation has succeeded
|
|
56
77
|
}
|
|
57
|
-
function makeHandler(
|
|
78
|
+
function makeHandler(getVariable) {
|
|
58
79
|
const handler = {
|
|
59
|
-
get: _extensionObjectFieldGetter,
|
|
60
|
-
set: _extensionObjectFieldSetter.bind(null,
|
|
80
|
+
get: _extensionObjectFieldGetter.bind(null, getVariable),
|
|
81
|
+
set: _extensionObjectFieldSetter.bind(null, getVariable)
|
|
61
82
|
};
|
|
62
83
|
return handler;
|
|
63
84
|
}
|
|
@@ -81,17 +102,22 @@ function _touchValue(property, now) {
|
|
|
81
102
|
}
|
|
82
103
|
}
|
|
83
104
|
exports._touchValue = _touchValue;
|
|
84
|
-
function propagateTouchValueUpward(self, now) {
|
|
105
|
+
function propagateTouchValueUpward(self, now, cache) {
|
|
85
106
|
_touchValue(self, now);
|
|
86
107
|
if (self.parent && self.parent.nodeClass === node_opcua_data_model_1.NodeClass.Variable) {
|
|
87
108
|
const parentVar = self.parent;
|
|
88
109
|
if (!parentVar.isExtensionObject())
|
|
89
110
|
return;
|
|
90
|
-
|
|
111
|
+
if (cache) {
|
|
112
|
+
if (cache.has(parentVar))
|
|
113
|
+
return;
|
|
114
|
+
cache.add(parentVar);
|
|
115
|
+
}
|
|
116
|
+
propagateTouchValueUpward(parentVar, now, cache);
|
|
91
117
|
}
|
|
92
118
|
}
|
|
93
119
|
exports.propagateTouchValueUpward = propagateTouchValueUpward;
|
|
94
|
-
function propagateTouchValueDownward(self, now) {
|
|
120
|
+
function propagateTouchValueDownward(self, now, cache) {
|
|
95
121
|
if (!self.isExtensionObject())
|
|
96
122
|
return;
|
|
97
123
|
// also propagate changes to embeded variables
|
|
@@ -100,36 +126,19 @@ function propagateTouchValueDownward(self, now) {
|
|
|
100
126
|
for (const field of definition.fields || []) {
|
|
101
127
|
const property = self.getChildByName(field.name);
|
|
102
128
|
if (property) {
|
|
129
|
+
if (cache) {
|
|
130
|
+
if (cache.has(property)) {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
cache.add(property);
|
|
134
|
+
}
|
|
103
135
|
_touchValue(property, now);
|
|
104
136
|
// to do cascade recursivelly ?
|
|
105
137
|
}
|
|
106
138
|
}
|
|
107
139
|
}
|
|
108
|
-
function
|
|
109
|
-
|
|
110
|
-
if (Array.isArray(ext)) {
|
|
111
|
-
(0, node_opcua_assert_1.default)(self.valueRank === 1, "Only Array is supported for the time being");
|
|
112
|
-
ext = ext.map((e) => unProxy(e));
|
|
113
|
-
self.$dataValue.value.arrayType = node_opcua_variant_1.VariantArrayType.Array;
|
|
114
|
-
self.$extensionObject = ext.map((e) => new Proxy(e, makeHandler(self)));
|
|
115
|
-
self.$dataValue.value.dataType = node_opcua_variant_1.DataType.ExtensionObject;
|
|
116
|
-
self.$dataValue.value.value = self.$extensionObject;
|
|
117
|
-
self.$dataValue.statusCode = node_opcua_status_code_1.StatusCodes.Good;
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
else {
|
|
121
|
-
ext = unProxy(ext);
|
|
122
|
-
self.$extensionObject = new Proxy(ext, makeHandler(self));
|
|
123
|
-
self.$dataValue.value.dataType = node_opcua_variant_1.DataType.ExtensionObject;
|
|
124
|
-
self.$dataValue.value.value = self.$extensionObject;
|
|
125
|
-
self.$dataValue.statusCode = node_opcua_status_code_1.StatusCodes.Good;
|
|
126
|
-
}
|
|
127
|
-
const now = sourceTimestamp || (0, node_opcua_date_time_1.getCurrentClock)();
|
|
128
|
-
propagateTouchValueUpward(self, now);
|
|
129
|
-
propagateTouchValueDownward(self, now);
|
|
130
|
-
}
|
|
131
|
-
exports._setExtensionObject = _setExtensionObject;
|
|
132
|
-
function setExtensionObjectValue(node, partialObject) {
|
|
140
|
+
function setExtensionObjectPartialValue(node, partialObject, sourceTimestamp) {
|
|
141
|
+
const variablesToUpdate = new Set();
|
|
133
142
|
const extensionObject = node.$extensionObject;
|
|
134
143
|
if (!extensionObject) {
|
|
135
144
|
throw new Error("setExtensionObjectValue node has no extension object " + node.browseName.toString());
|
|
@@ -141,13 +150,32 @@ function setExtensionObjectValue(node, partialObject) {
|
|
|
141
150
|
_update_extension_object(extObject[prop], partialObject1[prop]);
|
|
142
151
|
}
|
|
143
152
|
else {
|
|
144
|
-
extObject
|
|
153
|
+
if (isProxy(extObject)) {
|
|
154
|
+
// collect element we have to update
|
|
155
|
+
const target = getProxyTarget(extObject);
|
|
156
|
+
(0, node_opcua_assert_1.default)(!isProxy(target), "something wierd!");
|
|
157
|
+
target[prop] = partialObject1[prop];
|
|
158
|
+
const variable = getProxyVariableForProp(extObject, prop);
|
|
159
|
+
variable && variablesToUpdate.add(variable);
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
extObject[prop] = partialObject1[prop];
|
|
163
|
+
}
|
|
145
164
|
}
|
|
146
165
|
}
|
|
147
166
|
}
|
|
148
167
|
_update_extension_object(extensionObject, partialObject);
|
|
168
|
+
const now = sourceTimestamp || (0, node_opcua_date_time_1.getCurrentClock)();
|
|
169
|
+
const cache = new Set();
|
|
170
|
+
for (const c of variablesToUpdate) {
|
|
171
|
+
if (cache.has(c))
|
|
172
|
+
continue;
|
|
173
|
+
propagateTouchValueUpward(c, now, cache);
|
|
174
|
+
propagateTouchValueDownward(c, now, cache);
|
|
175
|
+
cache.add(c);
|
|
176
|
+
}
|
|
149
177
|
}
|
|
150
|
-
exports.
|
|
178
|
+
exports.setExtensionObjectPartialValue = setExtensionObjectPartialValue;
|
|
151
179
|
function getOrCreateProperty(variableNode, field, options) {
|
|
152
180
|
const dt = variableNode.getDataTypeNode();
|
|
153
181
|
// the namespace for the structure browse name elements
|
|
@@ -190,125 +218,120 @@ function prepareVariantValue(dataType, value) {
|
|
|
190
218
|
}
|
|
191
219
|
return value;
|
|
192
220
|
}
|
|
193
|
-
function
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
221
|
+
function installExt(uaVariable, ext) {
|
|
222
|
+
ext = unProxy(ext);
|
|
223
|
+
uaVariable.$extensionObject = new Proxy(ext, makeHandler(() => uaVariable));
|
|
224
|
+
const addressSpace = uaVariable.addressSpace;
|
|
225
|
+
const definition = uaVariable.dataTypeObj.getStructureDefinition();
|
|
226
|
+
const structure = addressSpace.findDataType("Structure");
|
|
227
|
+
for (const field of definition.fields || []) {
|
|
228
|
+
if (field.dataType) {
|
|
229
|
+
const dataTypeNode = addressSpace.findDataType(field.dataType);
|
|
230
|
+
// istanbul ignore next
|
|
231
|
+
if (dataTypeNode && dataTypeNode.isSupertypeOf(structure)) {
|
|
232
|
+
// sub structure .. let make an handler too
|
|
233
|
+
const camelCaseName = (0, node_opcua_utils_1.lowerFirstLetter)(field.name);
|
|
234
|
+
const subExtObj = uaVariable.$extensionObject[camelCaseName];
|
|
235
|
+
if (subExtObj) {
|
|
236
|
+
uaVariable.$extensionObject[camelCaseName] = new Proxy(subExtObj, makeHandler(() => {
|
|
237
|
+
return uaVariable.getComponentByName(field.name);
|
|
238
|
+
}));
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
warningLog("extension object is null");
|
|
242
|
+
}
|
|
203
243
|
}
|
|
204
|
-
const value = prepareVariantValue(dataType, propertyValue);
|
|
205
|
-
propertyNode.$dataValue.statusCode = node_opcua_status_code_1.StatusCodes.Good;
|
|
206
|
-
propertyNode.$dataValue.value.dataType = dataType;
|
|
207
|
-
propertyNode.$dataValue.value.value = value;
|
|
208
|
-
return new node_opcua_data_value_1.DataValue(propertyNode.$dataValue);
|
|
209
|
-
},
|
|
210
|
-
timestamped_set: (_dataValue, callback) => {
|
|
211
|
-
propertyNode.setValueFromSource(_dataValue.value, _dataValue.statusCode, _dataValue.sourceTimestamp || new Date());
|
|
212
|
-
// callback(null, StatusCodes.BadNotWritable);
|
|
213
|
-
callback(null, node_opcua_status_code_1.StatusCodes.Good);
|
|
214
244
|
}
|
|
215
|
-
}
|
|
245
|
+
}
|
|
216
246
|
}
|
|
217
|
-
function
|
|
218
|
-
|
|
247
|
+
function _installExtensionObjectBindingOnProperties(uaVariable, options) {
|
|
248
|
+
// may be extension object mechanism has alreday been install
|
|
249
|
+
// in this case we just need to rebind the properties...
|
|
250
|
+
if (uaVariable.$extensionObject) {
|
|
251
|
+
const extObj = uaVariable.$extensionObject;
|
|
252
|
+
uaVariable.bindExtensionObject(extObj, { createMissingProp: true, force: true });
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
if (uaVariable.$$extensionObjectArray) {
|
|
256
|
+
const extObj = uaVariable.$$extensionObjectArray;
|
|
257
|
+
_bindExtensionObjectArrayOrMatrix(uaVariable, extObj, { createMissingProp: true, force: true });
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
const dataValue = uaVariable.readValue();
|
|
219
261
|
const extObj = dataValue.value.value;
|
|
220
262
|
if (extObj instanceof node_opcua_extension_object_1.ExtensionObject) {
|
|
221
|
-
|
|
263
|
+
uaVariable.bindExtensionObject(extObj, { createMissingProp: true, force: true });
|
|
222
264
|
}
|
|
223
265
|
else if (extObj instanceof Array) {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
else if (dataValue.value.arrayType === node_opcua_variant_1.VariantArrayType.Matrix) {
|
|
228
|
-
_bindExtensionObjectMatrix(variableNode, extObj, { createMissingProp: true, force: true });
|
|
266
|
+
// istanbul ignore else
|
|
267
|
+
if (dataValue.value.arrayType === node_opcua_variant_1.VariantArrayType.Array || dataValue.value.arrayType === node_opcua_variant_1.VariantArrayType.Matrix) {
|
|
268
|
+
_bindExtensionObjectArrayOrMatrix(uaVariable, extObj, { createMissingProp: true, force: true });
|
|
229
269
|
}
|
|
230
270
|
else {
|
|
231
271
|
throw new Error("Internal Error, unexpected case");
|
|
232
272
|
}
|
|
233
273
|
}
|
|
234
|
-
else {
|
|
235
|
-
const msg = `variableNode ${variableNode.browseName.toString()} doesn't have $extensionObject property`;
|
|
236
|
-
errorLog(msg);
|
|
237
|
-
errorLog(dataValue.toString());
|
|
238
|
-
throw new Error(msg);
|
|
239
|
-
}
|
|
240
274
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
}
|
|
246
|
-
const addressSpace = variableNode.addressSpace;
|
|
247
|
-
const dt = variableNode.getDataTypeNode();
|
|
275
|
+
exports._installExtensionObjectBindingOnProperties = _installExtensionObjectBindingOnProperties;
|
|
276
|
+
function _installFields2(uaVariable, { get, set }, options) {
|
|
277
|
+
options = options || { createMissingProp: false };
|
|
278
|
+
const dt = uaVariable.getDataTypeNode();
|
|
248
279
|
const definition = dt.getStructureDefinition();
|
|
249
280
|
for (const field of definition.fields || []) {
|
|
250
|
-
// istanbul ignore next
|
|
251
281
|
if (node_opcua_nodeid_1.NodeId.sameNodeId(node_opcua_nodeid_1.NodeId.nullNodeId, field.dataType)) {
|
|
252
282
|
warningLog("field.dataType is null ! ", field.name, node_opcua_nodeid_1.NodeId.nullNodeId.toString());
|
|
253
283
|
warningLog(field.toString());
|
|
254
284
|
warningLog(" dataType replaced with BaseDataType ");
|
|
255
285
|
warningLog(definition.toString());
|
|
256
|
-
field.dataType =
|
|
286
|
+
field.dataType = uaVariable.resolveNodeId("BaseDataType");
|
|
257
287
|
}
|
|
258
|
-
const propertyNode = getOrCreateProperty(
|
|
288
|
+
const propertyNode = getOrCreateProperty(uaVariable, field, options);
|
|
259
289
|
if (!propertyNode) {
|
|
260
290
|
continue;
|
|
261
291
|
}
|
|
262
292
|
propertyNode.$dataValue.statusCode = node_opcua_status_code_1.StatusCodes.Good;
|
|
263
|
-
propertyNode.$dataValue.sourceTimestamp =
|
|
264
|
-
propertyNode.$dataValue.sourcePicoseconds =
|
|
265
|
-
propertyNode.$dataValue.serverTimestamp =
|
|
266
|
-
propertyNode.$dataValue.serverPicoseconds =
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
propertyNode._internal_set_value(new node_opcua_variant_1.Variant({
|
|
291
|
-
dataType: basicDataType,
|
|
292
|
-
value: preparedValue
|
|
293
|
-
}));
|
|
294
|
-
}
|
|
295
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
296
|
-
// property.camelCaseName = camelCaseName;
|
|
297
|
-
propertyNode.setValueFromSource = function (variant) {
|
|
298
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
299
|
-
const inner_this = this;
|
|
300
|
-
const variant1 = node_opcua_variant_1.Variant.coerce(variant);
|
|
301
|
-
inner_this.verifyVariantCompatibility(variant1);
|
|
302
|
-
// because self.$extensionObject is a Proxy with handlers that
|
|
303
|
-
// cascade the chagne we do not need to call touchValue() here
|
|
304
|
-
variableNode.$extensionObject[camelCaseName] = variant1.value;
|
|
305
|
-
};
|
|
293
|
+
propertyNode.$dataValue.sourceTimestamp = uaVariable.$dataValue.sourceTimestamp;
|
|
294
|
+
propertyNode.$dataValue.sourcePicoseconds = uaVariable.$dataValue.sourcePicoseconds;
|
|
295
|
+
propertyNode.$dataValue.serverTimestamp = uaVariable.$dataValue.serverTimestamp;
|
|
296
|
+
propertyNode.$dataValue.serverPicoseconds = uaVariable.$dataValue.serverPicoseconds;
|
|
297
|
+
propertyNode.$dataValue.value.dataType = propertyNode.dataTypeObj.basicDataType;
|
|
298
|
+
propertyNode.$dataValue.value.arrayType = propertyNode.valueRank === -1 ? node_opcua_variant_1.VariantArrayType.Scalar : (propertyNode.valueRank === 1 ? node_opcua_variant_1.VariantArrayType.Array : node_opcua_variant_1.VariantArrayType.Matrix);
|
|
299
|
+
propertyNode.$dataValue.value.dimensions = propertyNode.valueRank > 1 ? propertyNode.arrayDimensions : null;
|
|
300
|
+
const fieldName = field.name;
|
|
301
|
+
installDataValueGetter(propertyNode, () => get(fieldName));
|
|
302
|
+
(0, node_opcua_assert_1.default)(propertyNode._inner_replace_dataValue);
|
|
303
|
+
propertyNode._inner_replace_dataValue = (dataValue, indexRange) => {
|
|
304
|
+
/** */
|
|
305
|
+
const sourceTime = (0, node_opcua_date_time_1.coerceClock)(dataValue.sourceTimestamp, dataValue.sourcePicoseconds);
|
|
306
|
+
const value = dataValue.value.value;
|
|
307
|
+
set(field.name, value, sourceTime);
|
|
308
|
+
};
|
|
309
|
+
if (propertyNode.dataTypeObj.basicDataType === node_opcua_variant_1.DataType.ExtensionObject) {
|
|
310
|
+
_installFields2(propertyNode, {
|
|
311
|
+
get: (fieldName) => {
|
|
312
|
+
const mainFieldName = field.name;
|
|
313
|
+
return get(mainFieldName)[(0, node_opcua_utils_1.lowerFirstLetter)(fieldName)];
|
|
314
|
+
},
|
|
315
|
+
set: (fieldName, value, sourceTime) => {
|
|
316
|
+
const mainFieldName = field.name;
|
|
317
|
+
get(mainFieldName)[(0, node_opcua_utils_1.lowerFirstLetter)(fieldName)] = value;
|
|
318
|
+
}
|
|
319
|
+
}, options);
|
|
306
320
|
}
|
|
307
|
-
(0, node_opcua_assert_1.default)(propertyNode.readValue().statusCode.equals(node_opcua_status_code_1.StatusCodes.Good));
|
|
308
|
-
bindProperty(variableNode, propertyNode, camelCaseName, basicDataType);
|
|
309
321
|
}
|
|
310
322
|
}
|
|
311
|
-
|
|
323
|
+
function installDataValueGetter(propertyNode, get) {
|
|
324
|
+
Object.defineProperty(propertyNode.$dataValue.value, "value", { get });
|
|
325
|
+
const $ = propertyNode.$dataValue;
|
|
326
|
+
Object.defineProperty(propertyNode, "$dataValue", {
|
|
327
|
+
get() {
|
|
328
|
+
return $;
|
|
329
|
+
},
|
|
330
|
+
set: (value) => {
|
|
331
|
+
throw new Error("$dataValue is now frozen and should not be modified this way !\n contact sterfive.com");
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
}
|
|
312
335
|
function isVariableContainingExtensionObject(uaVariable) {
|
|
313
336
|
const addressSpace = uaVariable.addressSpace;
|
|
314
337
|
const structure = addressSpace.findDataType("Structure");
|
|
@@ -324,27 +347,53 @@ function isVariableContainingExtensionObject(uaVariable) {
|
|
|
324
347
|
}
|
|
325
348
|
return true;
|
|
326
349
|
}
|
|
327
|
-
|
|
328
|
-
|
|
350
|
+
function _innerBindExtensionObjectScalar(uaVariable, { get, set }, options) {
|
|
351
|
+
uaVariable.$dataValue.statusCode = node_opcua_status_code_1.StatusCodes.Good;
|
|
352
|
+
uaVariable.$dataValue.value.dataType = node_opcua_variant_1.DataType.ExtensionObject;
|
|
353
|
+
uaVariable.$dataValue.value.arrayType = node_opcua_variant_1.VariantArrayType.Scalar;
|
|
354
|
+
uaVariable.setValueFromSource = function (variant) {
|
|
355
|
+
setExtensionObjectPartialValue(this, variant.value);
|
|
356
|
+
};
|
|
357
|
+
installDataValueGetter(uaVariable, get);
|
|
358
|
+
(0, node_opcua_assert_1.default)(uaVariable._inner_replace_dataValue);
|
|
359
|
+
uaVariable._inner_replace_dataValue = (dataValue, indexRange) => {
|
|
360
|
+
/** */
|
|
361
|
+
const ext = dataValue.value.value;
|
|
362
|
+
const sourceTime = (0, node_opcua_date_time_1.coerceClock)(dataValue.sourceTimestamp, dataValue.sourcePicoseconds);
|
|
363
|
+
set(ext, sourceTime);
|
|
364
|
+
};
|
|
365
|
+
_installFields2(uaVariable, {
|
|
366
|
+
get: (fieldName) => {
|
|
367
|
+
const extObj = get();
|
|
368
|
+
return extObj[(0, node_opcua_utils_1.lowerFirstLetter)(fieldName)];
|
|
369
|
+
},
|
|
370
|
+
set: (fieldName, value, sourceTime) => {
|
|
371
|
+
const extObj = get();
|
|
372
|
+
extObj[(0, node_opcua_utils_1.lowerFirstLetter)(fieldName)] = value;
|
|
373
|
+
//1 propagateTouchValueDownward(uaVariable, sourceTime);
|
|
374
|
+
//1 propagateTouchValueUpward(uaVariable, sourceTime);
|
|
375
|
+
}
|
|
376
|
+
}, options);
|
|
377
|
+
}
|
|
378
|
+
function _bindExtensionObject(uaVariable, optionalExtensionObject, options) {
|
|
329
379
|
var _a, _b;
|
|
330
380
|
options = options || { createMissingProp: false };
|
|
331
|
-
if (!isVariableContainingExtensionObject(
|
|
381
|
+
if (!isVariableContainingExtensionObject(uaVariable)) {
|
|
332
382
|
return null;
|
|
333
383
|
}
|
|
334
|
-
const addressSpace =
|
|
384
|
+
const addressSpace = uaVariable.addressSpace;
|
|
335
385
|
let extensionObject_;
|
|
336
|
-
|
|
386
|
+
// istanbul ignore next
|
|
387
|
+
if (uaVariable.valueRank !== -1 && uaVariable.valueRank !== 1) {
|
|
337
388
|
throw new Error("Cannot bind an extension object here, valueRank must be scalar (-1) or one-dimensional (1)");
|
|
338
389
|
}
|
|
339
390
|
// istanbul ignore next
|
|
340
|
-
|
|
341
|
-
debugLog(" ------------------------------ binding ", self.browseName.toString(), self.nodeId.toString());
|
|
342
|
-
}
|
|
391
|
+
doDebug && debugLog(" ------------------------------ binding ", uaVariable.browseName.toString(), uaVariable.nodeId.toString());
|
|
343
392
|
// ignore bindExtensionObject on sub extension object, bindExtensionObject has to be called from the top most object
|
|
344
393
|
if (!options.force &&
|
|
345
|
-
|
|
346
|
-
(
|
|
347
|
-
const parentDataType =
|
|
394
|
+
uaVariable.parent &&
|
|
395
|
+
(uaVariable.parent.nodeClass === node_opcua_data_model_1.NodeClass.Variable || uaVariable.parent.nodeClass === node_opcua_data_model_1.NodeClass.VariableType)) {
|
|
396
|
+
const parentDataType = uaVariable.parent.dataType;
|
|
348
397
|
const dataTypeNode = addressSpace.findNode(parentDataType);
|
|
349
398
|
const structure = addressSpace.findDataType("Structure");
|
|
350
399
|
// istanbul ignore next
|
|
@@ -360,100 +409,60 @@ function _bindExtensionObject(self, optionalExtensionObject, options) {
|
|
|
360
409
|
}
|
|
361
410
|
}
|
|
362
411
|
// -------------------- make sure we do not bind a variable twice ....
|
|
363
|
-
if (
|
|
412
|
+
if (uaVariable.$extensionObject && !optionalExtensionObject) {
|
|
364
413
|
// istanbul ignore next
|
|
365
|
-
if (!
|
|
366
|
-
warningLog("on node : ",
|
|
367
|
-
warningLog((_a =
|
|
414
|
+
if (!uaVariable.checkExtensionObjectIsCorrect(uaVariable.$extensionObject)) {
|
|
415
|
+
warningLog("on node : ", uaVariable.browseName.toString(), uaVariable.nodeId.toString(), "dataType=", uaVariable.dataType.toString({ addressSpace: uaVariable.addressSpace }));
|
|
416
|
+
warningLog((_a = uaVariable.$extensionObject) === null || _a === void 0 ? void 0 : _a.toString());
|
|
368
417
|
throw new Error("bindExtensionObject: $extensionObject is incorrect: we are expecting a " +
|
|
369
|
-
|
|
418
|
+
uaVariable.dataType.toString({ addressSpace: uaVariable.addressSpace }) +
|
|
370
419
|
" but we got a " +
|
|
371
|
-
((_b =
|
|
420
|
+
((_b = uaVariable.$extensionObject) === null || _b === void 0 ? void 0 : _b.constructor.name));
|
|
372
421
|
}
|
|
373
|
-
return
|
|
374
|
-
// throw new Error("Variable already bound");
|
|
422
|
+
return uaVariable.$extensionObject;
|
|
375
423
|
}
|
|
376
|
-
// ------------------------------------------------------
|
|
377
|
-
// make sure we have a structure
|
|
378
|
-
// ------------------------------------------------------
|
|
379
|
-
const s = self.readValue();
|
|
380
424
|
// istanbul ignore next
|
|
381
|
-
if (
|
|
382
|
-
warningLog("Warning the DataType associated with this Variable is abstract ",
|
|
425
|
+
if (uaVariable.dataTypeObj.isAbstract) {
|
|
426
|
+
warningLog("Warning the DataType associated with this Variable is abstract ", uaVariable.dataTypeObj.browseName.toString());
|
|
383
427
|
warningLog("You need to provide a extension object yourself ");
|
|
384
428
|
throw new Error("bindExtensionObject requires a extensionObject as associated dataType is only abstract");
|
|
385
429
|
}
|
|
430
|
+
const s = uaVariable.readValue();
|
|
386
431
|
if (s.value && s.value.dataType === node_opcua_variant_1.DataType.ExtensionObject && s.value.value && optionalExtensionObject) {
|
|
387
432
|
// we want to replace the extension object
|
|
388
433
|
s.value.value = null;
|
|
389
434
|
}
|
|
390
435
|
innerBindExtensionObject();
|
|
391
|
-
(0, node_opcua_assert_1.default)(
|
|
392
|
-
return
|
|
436
|
+
(0, node_opcua_assert_1.default)(uaVariable.$extensionObject instanceof Object);
|
|
437
|
+
return uaVariable.$extensionObject;
|
|
393
438
|
function innerBindExtensionObject() {
|
|
394
|
-
const makePreciseClock = (sourceTimestamp, picoseconds) => ({ timestamp: sourceTimestamp, picoseconds: picoseconds || 0 });
|
|
395
439
|
if (s.value && (s.value.dataType === node_opcua_variant_1.DataType.Null || (s.value.dataType === node_opcua_variant_1.DataType.ExtensionObject && !s.value.value))) {
|
|
396
|
-
if (
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
return d;
|
|
405
|
-
},
|
|
406
|
-
timestamped_set(dataValue, callback) {
|
|
407
|
-
const ext = dataValue.value.value;
|
|
408
|
-
if (!self.checkExtensionObjectIsCorrect(ext)) {
|
|
409
|
-
return callback(null, node_opcua_status_code_1.StatusCodes.BadInvalidArgument);
|
|
410
|
-
}
|
|
411
|
-
const sourceTime = (0, node_opcua_date_time_1.coerceClock)(dataValue.sourceTimestamp, dataValue.sourcePicoseconds);
|
|
412
|
-
_setExtensionObject(self, ext, sourceTime);
|
|
413
|
-
callback(null, node_opcua_status_code_1.StatusCodes.Good);
|
|
414
|
-
}
|
|
415
|
-
}, true);
|
|
416
|
-
const sourceTime = (0, node_opcua_date_time_1.coerceClock)(self.$dataValue.sourceTimestamp, self.$dataValue.sourcePicoseconds);
|
|
417
|
-
_setExtensionObject(self, extensionObject_, sourceTime);
|
|
440
|
+
if (uaVariable.valueRank === -1 /** Scalar */) {
|
|
441
|
+
extensionObject_ = optionalExtensionObject || addressSpace.constructExtensionObject(uaVariable.dataType, {});
|
|
442
|
+
installExt(uaVariable, extensionObject_);
|
|
443
|
+
_innerBindExtensionObjectScalar(uaVariable, {
|
|
444
|
+
get: () => uaVariable.$extensionObject,
|
|
445
|
+
set: (value) => installExt(uaVariable, value)
|
|
446
|
+
}, options);
|
|
447
|
+
return;
|
|
418
448
|
}
|
|
419
|
-
else if (
|
|
420
|
-
|
|
421
|
-
extensionObject_ = optionalExtensionObject || [];
|
|
422
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
423
|
-
self.bindVariable({
|
|
424
|
-
timestamped_get() {
|
|
425
|
-
const d = new node_opcua_data_value_1.DataValue(self.$dataValue);
|
|
426
|
-
d.value.value = self.$extensionObject
|
|
427
|
-
? self.$extensionObject.map((e) => e.clone())
|
|
428
|
-
: null;
|
|
429
|
-
return d;
|
|
430
|
-
},
|
|
431
|
-
timestamped_set(dataValue, callback) {
|
|
432
|
-
const extensionObjectArray = dataValue.value.value;
|
|
433
|
-
if (!self.checkExtensionObjectIsCorrect(extensionObjectArray)) {
|
|
434
|
-
return callback(null, node_opcua_status_code_1.StatusCodes.BadInvalidArgument);
|
|
435
|
-
}
|
|
436
|
-
const sourceTime = (0, node_opcua_date_time_1.coerceClock)(dataValue.sourceTimestamp, dataValue.sourcePicoseconds);
|
|
437
|
-
_setExtensionObject(self, extensionObjectArray, sourceTime);
|
|
438
|
-
callback(null, node_opcua_status_code_1.StatusCodes.Good);
|
|
439
|
-
}
|
|
440
|
-
}, true);
|
|
441
|
-
const sourceTime = (0, node_opcua_date_time_1.coerceClock)(self.$dataValue.sourceTimestamp, self.$dataValue.sourcePicoseconds);
|
|
442
|
-
_setExtensionObject(self, extensionObject_, sourceTime);
|
|
449
|
+
else if (uaVariable.valueRank === 1 /** Array */) {
|
|
450
|
+
throw new Error("Should not get there ! Please fix me");
|
|
443
451
|
}
|
|
444
452
|
else {
|
|
445
|
-
errorLog(
|
|
446
|
-
errorLog("Unsupported case ! valueRank= ",
|
|
453
|
+
errorLog(uaVariable.toString());
|
|
454
|
+
errorLog("Unsupported case ! valueRank= ", uaVariable.valueRank);
|
|
447
455
|
}
|
|
448
456
|
}
|
|
449
457
|
else {
|
|
450
458
|
// verify that variant has the correct type
|
|
451
459
|
(0, node_opcua_assert_1.default)(s.value.dataType === node_opcua_variant_1.DataType.ExtensionObject);
|
|
452
|
-
|
|
453
|
-
(
|
|
454
|
-
|
|
460
|
+
installExt(uaVariable, s.value.value);
|
|
461
|
+
_innerBindExtensionObjectScalar(uaVariable, {
|
|
462
|
+
get: () => uaVariable.$extensionObject,
|
|
463
|
+
set: (value) => installExt(uaVariable, value)
|
|
464
|
+
}, options);
|
|
455
465
|
}
|
|
456
|
-
_installExtensionObjectBindingOnProperties(self, options);
|
|
457
466
|
}
|
|
458
467
|
}
|
|
459
468
|
exports._bindExtensionObject = _bindExtensionObject;
|
|
@@ -471,15 +480,14 @@ const composeBrowseNameAndNodeId = (uaVariable, indexes) => {
|
|
|
471
480
|
}
|
|
472
481
|
return { browseName, nodeId };
|
|
473
482
|
};
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
exports._bindExtensionObjectArray = _bindExtensionObjectArray;
|
|
478
|
-
function _bindExtensionObjectMatrix(uaVariable, optionalExtensionObjectArray, options) {
|
|
483
|
+
// eslint-disable-next-line max-statements
|
|
484
|
+
function _bindExtensionObjectArrayOrMatrix(uaVariable, optionalExtensionObjectArray, options) {
|
|
485
|
+
// istanbul ignore next
|
|
479
486
|
if (uaVariable.valueRank < 1) {
|
|
480
487
|
throw new Error("Variable must be a MultiDimensional array");
|
|
481
488
|
}
|
|
482
489
|
const arrayDimensions = uaVariable.arrayDimensions || [];
|
|
490
|
+
// istanbul ignore next
|
|
483
491
|
if (!isVariableContainingExtensionObject(uaVariable)) {
|
|
484
492
|
return [];
|
|
485
493
|
}
|
|
@@ -502,41 +510,81 @@ function _bindExtensionObjectMatrix(uaVariable, optionalExtensionObjectArray, op
|
|
|
502
510
|
}
|
|
503
511
|
}
|
|
504
512
|
uaVariable.$$extensionObjectArray = optionalExtensionObjectArray;
|
|
505
|
-
|
|
513
|
+
uaVariable.$dataValue.value.arrayType = uaVariable.valueRank === 1 ? node_opcua_variant_1.VariantArrayType.Array : node_opcua_variant_1.VariantArrayType.Matrix;
|
|
514
|
+
uaVariable.$dataValue.value.dimensions = uaVariable.valueRank === 1 ? null : (uaVariable.arrayDimensions || []);
|
|
515
|
+
uaVariable.$dataValue.value.dataType = node_opcua_variant_1.DataType.ExtensionObject;
|
|
516
|
+
uaVariable.$dataValue.value.value = uaVariable.$$extensionObjectArray;
|
|
506
517
|
uaVariable.bindVariable({
|
|
507
|
-
get: () =>
|
|
508
|
-
arrayType: node_opcua_variant_1.VariantArrayType.Array,
|
|
509
|
-
dataType: node_opcua_variant_1.DataType.ExtensionObject,
|
|
510
|
-
value: uaVariable.$$extensionObjectArray
|
|
511
|
-
})
|
|
518
|
+
get: () => uaVariable.$dataValue.value
|
|
512
519
|
}, true);
|
|
513
520
|
const namespace = uaVariable.namespace;
|
|
514
521
|
const indexIterator = new idx_iterator_1.IndexIterator(arrayDimensions);
|
|
515
522
|
for (let i = 0; i < totalLength; i++) {
|
|
516
523
|
const index = indexIterator.next();
|
|
517
524
|
const { browseName, nodeId } = composeBrowseNameAndNodeId(uaVariable, index);
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
525
|
+
let uaElement = uaVariable.getComponentByName(browseName);
|
|
526
|
+
if (!uaElement) {
|
|
527
|
+
uaElement = namespace.addVariable({
|
|
528
|
+
browseName,
|
|
529
|
+
nodeId,
|
|
530
|
+
componentOf: uaVariable,
|
|
531
|
+
dataType: uaVariable.dataType,
|
|
532
|
+
valueRank: -1,
|
|
533
|
+
accessLevel: uaVariable.accessLevel
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
uaElement.$dataValue.value.dataType = node_opcua_variant_1.DataType.ExtensionObject;
|
|
537
|
+
uaElement.$dataValue.statusCode = node_opcua_status_code_1.StatusCodes.Good;
|
|
538
|
+
uaElement.$dataValue.sourceTimestamp = uaVariable.$dataValue.sourceTimestamp;
|
|
539
|
+
uaElement.$dataValue.sourcePicoseconds = uaVariable.$dataValue.sourcePicoseconds;
|
|
540
|
+
uaElement.$dataValue.serverTimestamp = uaVariable.$dataValue.serverTimestamp;
|
|
541
|
+
uaElement.$dataValue.serverPicoseconds = uaVariable.$dataValue.serverPicoseconds;
|
|
542
|
+
uaElement.$dataValue.value.dataType = node_opcua_variant_1.DataType.ExtensionObject;
|
|
543
|
+
uaElement.$dataValue.value.arrayType = node_opcua_variant_1.VariantArrayType.Scalar;
|
|
526
544
|
{
|
|
527
545
|
const capturedIndex = i;
|
|
528
|
-
uaElement
|
|
529
|
-
get: () =>
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
546
|
+
_innerBindExtensionObjectScalar(uaElement, {
|
|
547
|
+
get: () => uaVariable.$$extensionObjectArray[capturedIndex],
|
|
548
|
+
set: (newValue, sourceTimestamp) => {
|
|
549
|
+
uaVariable.$$extensionObjectArray[capturedIndex] = newValue;
|
|
550
|
+
uaVariable.touchValue();
|
|
551
|
+
propagateTouchValueDownward(uaVariable, sourceTimestamp);
|
|
552
|
+
propagateTouchValueUpward(uaVariable, sourceTimestamp);
|
|
553
|
+
},
|
|
554
|
+
}, Object.assign(Object.assign({}, options), { force: true }));
|
|
535
555
|
}
|
|
536
556
|
}
|
|
537
557
|
return uaVariable.$$extensionObjectArray;
|
|
538
558
|
}
|
|
539
|
-
exports.
|
|
559
|
+
exports._bindExtensionObjectArrayOrMatrix = _bindExtensionObjectArrayOrMatrix;
|
|
560
|
+
function getElement(path, data) {
|
|
561
|
+
if (typeof path === "string") {
|
|
562
|
+
path = path.split(".");
|
|
563
|
+
}
|
|
564
|
+
let a = data;
|
|
565
|
+
for (const e of path) {
|
|
566
|
+
a = a[e];
|
|
567
|
+
}
|
|
568
|
+
return a;
|
|
569
|
+
}
|
|
570
|
+
exports.getElement = getElement;
|
|
571
|
+
function setElement(path, data, value) {
|
|
572
|
+
if (typeof path === "string") {
|
|
573
|
+
path = path.split(".");
|
|
574
|
+
}
|
|
575
|
+
const last = path.pop();
|
|
576
|
+
let a = data;
|
|
577
|
+
for (const e of path) {
|
|
578
|
+
a = a[e];
|
|
579
|
+
}
|
|
580
|
+
a[last] = value;
|
|
581
|
+
}
|
|
582
|
+
exports.setElement = setElement;
|
|
583
|
+
function incrementElement(path, data) {
|
|
584
|
+
const value = getElement(path, data);
|
|
585
|
+
setElement(path, data, value + 1);
|
|
586
|
+
}
|
|
587
|
+
exports.incrementElement = incrementElement;
|
|
540
588
|
function extractPartialData(path, extensionObject) {
|
|
541
589
|
let name;
|
|
542
590
|
if (typeof path === "string") {
|
|
@@ -563,7 +611,6 @@ function extractPartialData(path, extensionObject) {
|
|
|
563
611
|
}
|
|
564
612
|
name = path[path.length - 1];
|
|
565
613
|
c1[name] = c2[name];
|
|
566
|
-
c1[name] += 1;
|
|
567
614
|
return partialData;
|
|
568
615
|
}
|
|
569
616
|
exports.extractPartialData = extractPartialData;
|