@tier0/node-opc-da 1.0.7
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/LICENSE +201 -0
- package/README.md +171 -0
- package/docs/opcda.idl +1166 -0
- package/package.json +30 -0
- package/src/constants.js +212 -0
- package/src/enumString.js +161 -0
- package/src/filetime.js +79 -0
- package/src/index.js +62 -0
- package/src/opcAsyncIO.js +102 -0
- package/src/opcBrowser.js +285 -0
- package/src/opcCommon.js +84 -0
- package/src/opcGroupStateManager.js +248 -0
- package/src/opcItemIO.js +60 -0
- package/src/opcItemManager.js +415 -0
- package/src/opcItemProperties.js +102 -0
- package/src/opcServer.js +447 -0
- package/src/opcSyncIO.js +213 -0
- package/src/opctypes.js +116 -0
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
//@ts-check
|
|
2
|
+
/*
|
|
3
|
+
Copyright: (c) 2019, Guilherme Francescon Cittolin <gfcittolin@gmail.com>
|
|
4
|
+
GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const constants = require('./constants.js');
|
|
8
|
+
const util = require('util');
|
|
9
|
+
const debug = util.debuglog('node-opc-da');
|
|
10
|
+
|
|
11
|
+
const { CallBuilder, ComArray, ComString, ComValue, Flags, Pointer, Struct, Variant, Types } = require('node-dcom');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {object} ItemStruct
|
|
15
|
+
* @property {string} itemID
|
|
16
|
+
* @property {number} clientHandle
|
|
17
|
+
* @property {string} [accessPath]
|
|
18
|
+
* @property {boolean} [active]
|
|
19
|
+
* @property {number} [requestedDataType]
|
|
20
|
+
* @property {number} [reserved]
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @typedef {object} ItemResponse
|
|
25
|
+
* @property {string} itemID
|
|
26
|
+
* @property {number} serverHandle
|
|
27
|
+
* @property {number} cannonicalDataType
|
|
28
|
+
* @property {number} reserved
|
|
29
|
+
* @property {number} accessRights
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
*
|
|
34
|
+
* @param {ItemStruct} item
|
|
35
|
+
* @returns {Struct}
|
|
36
|
+
*/
|
|
37
|
+
function getItemDefStruct(item) {
|
|
38
|
+
|
|
39
|
+
let itemID, clientHandle, accessPath, active, requestedDataType, reserved;
|
|
40
|
+
|
|
41
|
+
if (item.itemID === null || item.itemID === undefined) {
|
|
42
|
+
throw new Error("Missing required itemID")
|
|
43
|
+
}
|
|
44
|
+
itemID = item.itemID;
|
|
45
|
+
clientHandle = item.clientHandle || Math.random() * 0xffffffff;
|
|
46
|
+
accessPath = item.accessPath || '';
|
|
47
|
+
active = item.active !== undefined ? item.active : true;
|
|
48
|
+
requestedDataType = item.requestedDataType || 0;
|
|
49
|
+
reserved = item.reserved || 0;
|
|
50
|
+
|
|
51
|
+
let struct = new Struct();
|
|
52
|
+
struct.addMember(new ComValue(new ComString(accessPath, Flags.FLAG_REPRESENTATION_STRING_LPWSTR), Types.COMSTRING));
|
|
53
|
+
struct.addMember(new ComValue(new ComString(itemID, Flags.FLAG_REPRESENTATION_STRING_LPWSTR), Types.COMSTRING));
|
|
54
|
+
struct.addMember(new ComValue(active ? 1 : 0, Types.INTEGER));
|
|
55
|
+
struct.addMember(new ComValue(clientHandle, Types.INTEGER));
|
|
56
|
+
struct.addMember(new ComValue(0, Types.INTEGER)); //blob size
|
|
57
|
+
struct.addMember(new ComValue(new Pointer(null), Types.POINTER)); // blob
|
|
58
|
+
struct.addMember(new ComValue(requestedDataType, Types.SHORT));
|
|
59
|
+
struct.addMember(new ComValue(reserved, Types.SHORT));
|
|
60
|
+
|
|
61
|
+
return struct;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @returns {Struct}
|
|
66
|
+
*/
|
|
67
|
+
function getItemResultStruct() {
|
|
68
|
+
let struct = new Struct();
|
|
69
|
+
|
|
70
|
+
struct.addMember(new ComValue(null, Types.INTEGER)); // Server handle
|
|
71
|
+
struct.addMember(new ComValue(null, Types.SHORT)); // data type
|
|
72
|
+
struct.addMember(new ComValue(null, Types.SHORT)); // reserved
|
|
73
|
+
struct.addMember(new ComValue(null, Types.INTEGER)); // access rights
|
|
74
|
+
struct.addMember(new ComValue(null, Types.INTEGER)); // blob size
|
|
75
|
+
struct.addMember(new ComValue(new Pointer(new ComValue(new ComArray(new ComValue(null, Types.BYTE), null, 1, true, false), Types.COMARRAY)), Types.POINTER)); // blob size
|
|
76
|
+
|
|
77
|
+
return struct;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Represents an OPC Server
|
|
82
|
+
*/
|
|
83
|
+
class OPCItemManager {
|
|
84
|
+
|
|
85
|
+
constructor() {
|
|
86
|
+
this._comObj = null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
*
|
|
91
|
+
* @param {*} unknown
|
|
92
|
+
* @returns {Promise<void>}
|
|
93
|
+
*/
|
|
94
|
+
async init(unknown) {
|
|
95
|
+
debug("Initing ItemManager...");
|
|
96
|
+
if (this._comObj) throw new Error("Already initialized");
|
|
97
|
+
|
|
98
|
+
this._comObj = await unknown.queryInterface(constants.iid.IOPCItemMgt_IID);
|
|
99
|
+
debug("ItemManager successfully initted");
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* @returns {Promise<void>}
|
|
104
|
+
*/
|
|
105
|
+
async end() {
|
|
106
|
+
debug("Destroyin ItemManager...");
|
|
107
|
+
if (!this._comObj) return;
|
|
108
|
+
|
|
109
|
+
let obj = this._comObj;
|
|
110
|
+
this._comObj = null;
|
|
111
|
+
await obj.release();
|
|
112
|
+
debug("ItemManager successfully destroyed.");
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
*
|
|
117
|
+
* @param {Array<ItemStruct>} items
|
|
118
|
+
* @returns {Promise<Array<Array<number,ItemResponse>>>}
|
|
119
|
+
* @opNum 0
|
|
120
|
+
*/
|
|
121
|
+
async add(items) {
|
|
122
|
+
debug("Adding " + items.length + " to the current group: ");
|
|
123
|
+
for (let i = 0; i < items.length; i++)
|
|
124
|
+
debug(items[i].itemID);
|
|
125
|
+
|
|
126
|
+
if (!this._comObj) throw new Error("Not initialized");
|
|
127
|
+
|
|
128
|
+
if (!(items.length > 0)) return [];
|
|
129
|
+
|
|
130
|
+
let structs = [];
|
|
131
|
+
for (const item of items) {
|
|
132
|
+
structs.push(new ComValue(getItemDefStruct(item), Types.STRUCT));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
let itemArray = new ComArray(new ComValue(structs, Types.STRUCT), true);
|
|
136
|
+
|
|
137
|
+
let callObject = new CallBuilder(true);
|
|
138
|
+
callObject.setOpnum(0);
|
|
139
|
+
|
|
140
|
+
callObject.addInParamAsInt(items.length, Flags.FLAG_NULL);
|
|
141
|
+
callObject.addInParamAsArray(itemArray, Flags.FLAG_NULL);
|
|
142
|
+
let resStructArray = new ComArray(new ComValue(getItemResultStruct(), Types.STRUCT), null, 1, true)
|
|
143
|
+
let errCodesArray = new ComArray(new ComValue(null, Types.INTEGER), null, 1, true)
|
|
144
|
+
callObject.addOutParamAsObject(new ComValue(new Pointer(new ComValue(resStructArray, Types.COMARRAY)), Types.POINTER), Flags.FLAG_NULL);
|
|
145
|
+
callObject.addOutParamAsObject(new ComValue(new Pointer(new ComValue(errCodesArray, Types.COMARRAY)), Types.POINTER), Flags.FLAG_NULL);
|
|
146
|
+
|
|
147
|
+
let resultObj = await this._comObj.call(callObject);
|
|
148
|
+
|
|
149
|
+
let hresult = resultObj.hresult;
|
|
150
|
+
let result = resultObj.getResults();
|
|
151
|
+
if (hresult != 0) {
|
|
152
|
+
if (result.lenght == 0)
|
|
153
|
+
throw new Error(String(hresult));
|
|
154
|
+
else
|
|
155
|
+
debug(new Error(String(hresult)));
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
let results = result[0].getValue().getReferent().getArrayInstance();
|
|
159
|
+
let errorCodes = result[1].getValue().getReferent().getArrayInstance();
|
|
160
|
+
|
|
161
|
+
let res = [];
|
|
162
|
+
let failed = [];
|
|
163
|
+
for (let i = 0; i < items.length; i++) {
|
|
164
|
+
let resObj = {
|
|
165
|
+
itemID: items[i].itemID,
|
|
166
|
+
serverHandle: results[i].getValue().getMember(0).getValue(),
|
|
167
|
+
cannonicalDataType: results[i].getValue().getMember(1).getValue(),
|
|
168
|
+
reserved: results[i].getValue().getMember(2).getValue(),
|
|
169
|
+
accessRights: results[i].getValue().getMember(3).getValue()
|
|
170
|
+
|
|
171
|
+
};
|
|
172
|
+
res.push([errorCodes[i].getValue(), resObj]);
|
|
173
|
+
if (errorCodes[i].getValue() != 0)
|
|
174
|
+
failed.push([errorCodes[i].getValue(), resObj.itemID]);
|
|
175
|
+
}
|
|
176
|
+
debug("A total of " + (res.length - failed.length) + " items were successfully added to the group.");
|
|
177
|
+
if (failed.length > 0) {
|
|
178
|
+
debug("The following items were not added: ");
|
|
179
|
+
for (let i = 0; i < failed.length; i++)
|
|
180
|
+
debug("Item: " + failed[i][0] + " ErrorCode: " + failed[i][1]);
|
|
181
|
+
}
|
|
182
|
+
return res;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
*
|
|
187
|
+
* @param {Array<ItemStruct>} items
|
|
188
|
+
* @returns {Promise<Array<Array<number,ItemResponse>>>}
|
|
189
|
+
* @opNum 1
|
|
190
|
+
*/
|
|
191
|
+
async validate(items) {
|
|
192
|
+
debug("Querying server to validade " + items.length + " items: ");
|
|
193
|
+
for (let i = 0; i < items.length; i++)
|
|
194
|
+
debug(items[i].itemID);
|
|
195
|
+
|
|
196
|
+
if (!this._comObj) throw new Error("Not initialized");
|
|
197
|
+
|
|
198
|
+
if (!(items.length > 0)) return [];
|
|
199
|
+
|
|
200
|
+
let structs = [];
|
|
201
|
+
for (const item of items) {
|
|
202
|
+
structs.push(new ComValue(getItemDefStruct(item), Types.STRUCT));
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
let itemArray = new ComArray(new ComValue(structs, Types.STRUCT), true);
|
|
206
|
+
|
|
207
|
+
let callObject = new CallBuilder(true);
|
|
208
|
+
callObject.setOpnum(1);
|
|
209
|
+
|
|
210
|
+
callObject.addInParamAsInt(items.length, Flags.FLAG_NULL);
|
|
211
|
+
callObject.addInParamAsArray(itemArray, Flags.FLAG_NULL);
|
|
212
|
+
callObject.addInParamAsInt(0, Flags.FLAG_NULL); // don't update blobs
|
|
213
|
+
let resStructArray = new ComArray(new ComValue(getItemResultStruct(), Types.STRUCT), null, 1, true)
|
|
214
|
+
let errCodesArray = new ComArray(new ComValue(null, Types.INTEGER), null, 1, true)
|
|
215
|
+
callObject.addOutParamAsObject(new ComValue(new Pointer(new ComValue(resStructArray, Types.COMARRAY)), Types.POINTER), Flags.FLAG_NULL);
|
|
216
|
+
callObject.addOutParamAsObject(new ComValue(new Pointer(new ComValue(errCodesArray, Types.COMARRAY)), Types.POINTER), Flags.FLAG_NULL);
|
|
217
|
+
|
|
218
|
+
let resultObj = await this._comObj.call(callObject);
|
|
219
|
+
|
|
220
|
+
let hresult = resultObj.hresult;
|
|
221
|
+
let result = resultObj.getResults();
|
|
222
|
+
if (hresult != 0) {
|
|
223
|
+
if (result.lenght == 0)
|
|
224
|
+
throw new Error(String(hresult));
|
|
225
|
+
else
|
|
226
|
+
debug(new Error(String(hresult)));
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
let results = result[0].getValue().getReferent().getArrayInstance();
|
|
230
|
+
let errorCodes = result[1].getValue().getReferent().getArrayInstance();
|
|
231
|
+
|
|
232
|
+
let res = [];
|
|
233
|
+
let failed = []
|
|
234
|
+
for (let i = 0; i < items.length; i++) {
|
|
235
|
+
let resObj = {
|
|
236
|
+
itemID: items[i].itemID,
|
|
237
|
+
serverHandle: results[i].getValue().getMember(0),
|
|
238
|
+
cannonicalDataType: results[i].getValue().getMember(1),
|
|
239
|
+
reserved: results[i].getValue().getMember(2),
|
|
240
|
+
accessRights: results[i].getValue().getMember(3),
|
|
241
|
+
errorCode: errorCodes[i].getValue()
|
|
242
|
+
};
|
|
243
|
+
res.push([errorCodes[i], resObj]);
|
|
244
|
+
if (errorCodes[i].getValue() != 0) {
|
|
245
|
+
failed.push([errorCodes[i].getValue(), resObj.itemID])
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
debug("A total of " + res.length + " were successfully validated.");
|
|
249
|
+
if (failed.length > 0) {
|
|
250
|
+
debug("The following items were not added: ");
|
|
251
|
+
for (let i = 0; i < failed.length; i++)
|
|
252
|
+
debug("Item: " + failed[i][0] + " ErrorCode: " + failed[i][1]);
|
|
253
|
+
}
|
|
254
|
+
return res;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
*
|
|
259
|
+
* @param {Array<number>} items array of server handles
|
|
260
|
+
* @returns {Promise<Array<object>>}
|
|
261
|
+
* @opNum 2
|
|
262
|
+
*/
|
|
263
|
+
async remove(items) {
|
|
264
|
+
debug("Removing " + items.length + "items: ");
|
|
265
|
+
for (let i = 0; i < items.length; i++)
|
|
266
|
+
debug(String(items[i]));
|
|
267
|
+
if (!this._comObj) throw new Error("Not initialized");
|
|
268
|
+
|
|
269
|
+
if (!(items.length > 0)) return [];
|
|
270
|
+
|
|
271
|
+
let temporary = new Array();
|
|
272
|
+
for (let i = 0; i < items.length; i++) {
|
|
273
|
+
temporary.push(new ComValue(items[i], Types.INTEGER));
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
let itemArray = new ComArray(new ComValue(temporary, Types.INTEGER), true);
|
|
277
|
+
|
|
278
|
+
let callObject = new CallBuilder(true);
|
|
279
|
+
callObject.setOpnum(2);
|
|
280
|
+
|
|
281
|
+
callObject.addInParamAsInt(items.length, Flags.FLAG_NULL);
|
|
282
|
+
callObject.addInParamAsArray(itemArray, Flags.FLAG_NULL);
|
|
283
|
+
let errCodesArray = new ComArray(new ComValue(null, Types.INTEGER), null, 1, true)
|
|
284
|
+
callObject.addOutParamAsObject(new ComValue(new Pointer(new ComValue(errCodesArray, Types.COMARRAY)), Types.POINTER), Flags.FLAG_NULL);
|
|
285
|
+
|
|
286
|
+
let resultObj = await this._comObj.call(callObject);
|
|
287
|
+
|
|
288
|
+
let hresult = resultObj.hresult;
|
|
289
|
+
let result = resultObj.getResults();
|
|
290
|
+
if (hresult != 0) {
|
|
291
|
+
if (result.lenght == 0)
|
|
292
|
+
throw new Error(String(hresult));
|
|
293
|
+
else
|
|
294
|
+
debug(new Error(String(hresult)));
|
|
295
|
+
}
|
|
296
|
+
debug("Items successfully removed.");
|
|
297
|
+
return result[0].getValue().getReferent().getArrayInstance();
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
*
|
|
302
|
+
* @param {boolean} state
|
|
303
|
+
* @param {Array<number>} items
|
|
304
|
+
* @returns {Promise<Array<number>>}
|
|
305
|
+
* @opNum 3
|
|
306
|
+
*/
|
|
307
|
+
async setActiveState(state, items) {
|
|
308
|
+
debug("Changing the active state of " + items.length + "items: ");
|
|
309
|
+
for (let i = 0; i < items.length; i++)
|
|
310
|
+
debug(String(items[i]), state[i]);
|
|
311
|
+
|
|
312
|
+
if (!this._comObj) throw new Error("Not initialized");
|
|
313
|
+
|
|
314
|
+
if (!(items.length > 0)) return [];
|
|
315
|
+
|
|
316
|
+
let temporary = new Array();
|
|
317
|
+
for (let i = 0; i < items.length; i++)
|
|
318
|
+
temporary.push(new ComValue(items[i], Types.INTEGER));
|
|
319
|
+
|
|
320
|
+
let itemArray = new ComArray(new ComValue(temporary, Types.INTEGER), true);
|
|
321
|
+
|
|
322
|
+
let callObject = new CallBuilder(true);
|
|
323
|
+
callObject.setOpnum(3);
|
|
324
|
+
|
|
325
|
+
callObject.addInParamAsInt(items.length, Flags.FLAG_NULL);
|
|
326
|
+
callObject.addInParamAsArray(itemArray, Flags.FLAG_NULL);
|
|
327
|
+
callObject.addInParamAsInt(state ? 1 : 0, Flags.FLAG_NULL);
|
|
328
|
+
let errCodesArray = new ComArray(new ComValue(null, Types.INTEGER), null, 1, true)
|
|
329
|
+
callObject.addOutParamAsObject(new ComValue(new Pointer(new ComValue(errCodesArray, Types.COMARRAY)), Types.POINTER), Flags.FLAG_NULL);
|
|
330
|
+
|
|
331
|
+
let resultObj = await this._comObj.call(callObject);
|
|
332
|
+
|
|
333
|
+
let hresult = resultObj.hresult;
|
|
334
|
+
let result = resultObj.getResults();
|
|
335
|
+
if (hresult != 0) {
|
|
336
|
+
if (result.lenght == 0)
|
|
337
|
+
throw new Error(String(hresult));
|
|
338
|
+
else
|
|
339
|
+
debugg(new Error(String(hresult)));
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
let errorCodes = result[0].getValue().getReferent().getArrayInstance();
|
|
343
|
+
let results = new Array();
|
|
344
|
+
let failed = new Array();
|
|
345
|
+
for (let i = 0; i < items.length; i++) {
|
|
346
|
+
results.push({value: items[i], errorCode: errorCodes[i]});
|
|
347
|
+
if (errorCodes[i].getValue() != 0) {
|
|
348
|
+
failed.push([errorCodes[i].getValue(), items[i]]);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
debug("A total of " + (results.length - failed.length) + " had their active status setted to " + state + ".");
|
|
353
|
+
if (failed.length > 0) {
|
|
354
|
+
debug("The following items were not added: ");
|
|
355
|
+
for (let i = 0; i < failed.length; i++)
|
|
356
|
+
debug("Item: " + failed[i][0] + " ErrorCode: " + failed[i][1]);
|
|
357
|
+
}
|
|
358
|
+
return results;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
*
|
|
363
|
+
* @param {Array<number>} items array of server handles
|
|
364
|
+
* @param {Array<number>} handles array of client handles
|
|
365
|
+
* @returns {Promise<Array<number>>}
|
|
366
|
+
* @opNum 4
|
|
367
|
+
*/
|
|
368
|
+
async setClientHandles(items, handles) {
|
|
369
|
+
debug("Setting the handle of " + items.length + "items: ");
|
|
370
|
+
for (let i = 0; i < items.length; i++)
|
|
371
|
+
debug(String(items[i]), handles[i]);
|
|
372
|
+
|
|
373
|
+
if (!this._comObj) throw new Error("Not initialized");
|
|
374
|
+
|
|
375
|
+
if (items.length !== handles.length) throw new Error("Array sizes must be the same");
|
|
376
|
+
|
|
377
|
+
if (!(items.length > 0)) return [];
|
|
378
|
+
|
|
379
|
+
let temporaryItems = new Array();
|
|
380
|
+
for (let i = 0; i < items.length; i++)
|
|
381
|
+
temporaryItems.push(new ComValue(items[i], Types.INTEGER));
|
|
382
|
+
|
|
383
|
+
let temporaryHandles = new Array();
|
|
384
|
+
for (let i = 0; i < handles.length; i++)
|
|
385
|
+
temporaryHandles.push(new ComValue(handles[i], Types.INTEGER));
|
|
386
|
+
|
|
387
|
+
let itemArray = new ComArray(new ComValue(temporaryItems, Types.INTEGER), true);
|
|
388
|
+
let handlesArray = new ComArray(new ComValue(temporaryHandles, Types.INTEGER), true);
|
|
389
|
+
|
|
390
|
+
let callObject = new CallBuilder(true);
|
|
391
|
+
callObject.setOpnum(4);
|
|
392
|
+
|
|
393
|
+
callObject.addInParamAsInt(items.length, Flags.FLAG_NULL);
|
|
394
|
+
callObject.addInParamAsArray(itemArray, Flags.FLAG_NULL);
|
|
395
|
+
callObject.addInParamAsArray(handlesArray, Flags.FLAG_NULL);
|
|
396
|
+
let errCodesArray = new ComArray(new ComValue(null, Types.INTEGER), null, 1, true)
|
|
397
|
+
callObject.addOutParamAsObject(new ComValue(new Pointer(new ComValue(errCodesArray, Types.COMARRAY)), Types.POINTER), Flags.FLAG_NULL);
|
|
398
|
+
|
|
399
|
+
let resultObj = await this._comObj.call(callObject);
|
|
400
|
+
|
|
401
|
+
let hresult = resultObj.hresult;
|
|
402
|
+
let result = resultObj.getResults();
|
|
403
|
+
if (hresult != 0) {
|
|
404
|
+
if (result.lenght == 0)
|
|
405
|
+
throw new Error(String(hresult));
|
|
406
|
+
else
|
|
407
|
+
debug(new Error(String(hresult)));
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
debug("Clients handles setted.");
|
|
411
|
+
return result[0].getValue().getReferent().getArrayInstance();
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
module.exports = OPCItemManager;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
//@ts-check
|
|
2
|
+
/*
|
|
3
|
+
Copyright: (c) 2019, Guilherme Francescon Cittolin <gfcittolin@gmail.com>
|
|
4
|
+
GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const constants = require('./constants.js');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Represents an OPC Item I/O object
|
|
11
|
+
*/
|
|
12
|
+
class OPCItemProperties {
|
|
13
|
+
|
|
14
|
+
constructor() {
|
|
15
|
+
this._comObj = null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
*
|
|
20
|
+
* @param {*} unknown
|
|
21
|
+
* @returns {Promise<?>}
|
|
22
|
+
*/
|
|
23
|
+
async init(unknown) {
|
|
24
|
+
if (this._comObj) throw new Error("Already initialized");
|
|
25
|
+
|
|
26
|
+
this._comObj = await unknown.queryInterface(constants.iid.IOPCItemProperties_IID);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async end() {
|
|
30
|
+
if (!this._comObj) return;
|
|
31
|
+
|
|
32
|
+
let obj = this._comObj;
|
|
33
|
+
this._comObj = null;
|
|
34
|
+
await obj.release();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
*
|
|
39
|
+
* @param {string} itemID
|
|
40
|
+
* @returns {Promise<Array<object>>} the item's properties
|
|
41
|
+
* @opNum 0
|
|
42
|
+
*/
|
|
43
|
+
async queryAvailableProperties(itemID) {
|
|
44
|
+
if (!this._comObj) throw new Error("Not initialized");
|
|
45
|
+
|
|
46
|
+
//should return array of {id, description, varType}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
*
|
|
51
|
+
* @param {string} itemID
|
|
52
|
+
* @param {number[]} props
|
|
53
|
+
* @returns {Promise<Array<object>>}
|
|
54
|
+
* @opNum 1
|
|
55
|
+
*/
|
|
56
|
+
async getItemProperties(itemID, props) {
|
|
57
|
+
if (!this._comObj) throw new Error("Not initialized");
|
|
58
|
+
|
|
59
|
+
// should return array of {id, value, errorCode}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
*
|
|
64
|
+
* @param {string} itemID
|
|
65
|
+
* @param {number[]} props
|
|
66
|
+
* @returns {Promise<object>}
|
|
67
|
+
* @opNum 2
|
|
68
|
+
*/
|
|
69
|
+
async lookupItemIDs(itemID, props) {
|
|
70
|
+
if (!this._comObj) throw new Error("Not initialized");
|
|
71
|
+
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// --------
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
*
|
|
78
|
+
* @param {string} itemID
|
|
79
|
+
* @returns {Promise<Array<object>}
|
|
80
|
+
*/
|
|
81
|
+
async getAllItemProperties(itemID){
|
|
82
|
+
let props = await this.queryAvailableProperties(itemID);
|
|
83
|
+
let propIDs = props.map(elm => elm.id)
|
|
84
|
+
let propVals = await this.getItemProperties(itemID, propIDs);
|
|
85
|
+
let result = [];
|
|
86
|
+
|
|
87
|
+
for(let i = 0; i < propIDs.length; i++){
|
|
88
|
+
result.push({
|
|
89
|
+
id: props[i].id,
|
|
90
|
+
description: props[i].description,
|
|
91
|
+
varType: props[i].varType,
|
|
92
|
+
value: propVals[i].value,
|
|
93
|
+
errorCode: propVals[i].errorCode
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
module.exports = OPCItemProperties;
|