@bitpoolos/edge-bacnet 1.2.6 → 1.2.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/bacnet_client.js +404 -183
- package/bacnet_device.js +52 -0
- package/bacnet_gateway.html +10 -3
- package/bacnet_gateway.js +93 -37
- package/bacnet_read.html +53 -33
- package/bacnet_read.js +8 -2
- package/bacnet_write.html +105 -29
- package/bacnet_write.js +1 -1
- package/common.js +28 -12
- package/package.json +2 -2
- package/resources/icons/icon-read.svg +19 -0
- package/resources/icons/icon-write.svg +16 -0
- package/resources/node-bacstack-ts/dist/lib/client.js +3 -3
- package/resources/style.css +11 -0
package/bacnet_write.html
CHANGED
|
@@ -162,11 +162,27 @@
|
|
|
162
162
|
//update UI
|
|
163
163
|
let parentDeviceName = slotProps.node.parentDevice;
|
|
164
164
|
let foundDeviceIndex = this.writeDevices ? this.writeDevices.findIndex(ele => ele.label == parentDeviceName) : -1;
|
|
165
|
-
let
|
|
165
|
+
let device = this.deviceList.find(ele => ele.deviceName == parentDeviceName);
|
|
166
|
+
let deviceAddress = app.getDeviceAddress(device.address);
|
|
167
|
+
let key = `${deviceAddress}-${device.deviceId}`;
|
|
168
|
+
let parentDevice = this.devices.find(ele => ele.ipAddr == deviceAddress);
|
|
169
|
+
let childDevice;
|
|
170
|
+
if(device.isMstp) {
|
|
171
|
+
let foundChildIndex = parentDevice.children[1].children.findIndex(ele => ele.label == parentDeviceName);
|
|
172
|
+
if(foundChildIndex !== -1) {
|
|
173
|
+
childDevice = parentDevice.children[1].children[foundChildIndex];
|
|
174
|
+
}
|
|
175
|
+
}
|
|
166
176
|
|
|
167
177
|
if (foundDeviceIndex == -1) {
|
|
168
178
|
//no read devices present, add new
|
|
169
|
-
let newReadParent
|
|
179
|
+
let newReadParent;
|
|
180
|
+
if(childDevice) {
|
|
181
|
+
newReadParent = {...childDevice};
|
|
182
|
+
} else {
|
|
183
|
+
newReadParent = {...parentDevice};
|
|
184
|
+
}
|
|
185
|
+
|
|
170
186
|
newReadParent.children = [];
|
|
171
187
|
newReadParent.children.push(slotProps.node);
|
|
172
188
|
|
|
@@ -183,18 +199,12 @@
|
|
|
183
199
|
|
|
184
200
|
slotProps.node.showAdded = true;
|
|
185
201
|
|
|
202
|
+
console.log("write point added, slotProps.node: ", slotProps.node);
|
|
203
|
+
|
|
186
204
|
this.$forceUpdate();
|
|
187
205
|
|
|
188
206
|
//update node-red data structure
|
|
189
|
-
|
|
190
|
-
if(ele.address.address) {
|
|
191
|
-
return ele.address.address == parentDevice.ipAddr && ele.deviceId == parentDevice.deviceId;
|
|
192
|
-
} else {
|
|
193
|
-
return ele.address == parentDevice.ipAddr && ele.deviceId == parentDevice.deviceId;
|
|
194
|
-
}
|
|
195
|
-
});
|
|
196
|
-
let deviceAddress = app.getDeviceAddress(device.address);
|
|
197
|
-
let key = `${deviceAddress}-${device.deviceId}`;
|
|
207
|
+
|
|
198
208
|
let point = this.pointList[key][slotProps.node.pointName];
|
|
199
209
|
point.deviceId = device.deviceId;
|
|
200
210
|
point.deviceAddress = device.address;
|
|
@@ -212,6 +222,8 @@
|
|
|
212
222
|
|
|
213
223
|
if (!found) this.pointsToWrite.push(point);
|
|
214
224
|
|
|
225
|
+
console.log("this.pointsToWrite: ", this.pointsToWrite);
|
|
226
|
+
|
|
215
227
|
//force a deploy state
|
|
216
228
|
node.hiddenDeployToggle = !node.prevHiddenToggleState;
|
|
217
229
|
},
|
|
@@ -365,13 +377,13 @@
|
|
|
365
377
|
<script type="text/html" data-template-name="Bacnet-Write">
|
|
366
378
|
<style>
|
|
367
379
|
.p-treenode-label {
|
|
368
|
-
/* color: white; */
|
|
369
380
|
color: black;
|
|
370
381
|
width: 100%;
|
|
371
382
|
}
|
|
372
383
|
.p-tree {
|
|
373
384
|
background: inherit !important;
|
|
374
385
|
border: inherit !important;
|
|
386
|
+
padding-right: 0px !important;
|
|
375
387
|
}
|
|
376
388
|
.p-button {
|
|
377
389
|
margin-right: .5rem;
|
|
@@ -383,15 +395,11 @@
|
|
|
383
395
|
float: right;
|
|
384
396
|
}
|
|
385
397
|
.addPointButton:hover, .minusPointButton:hover {
|
|
386
|
-
/* background: #282A36 !important; */
|
|
387
398
|
background: #d5d5d5 !important;
|
|
388
399
|
}
|
|
389
400
|
.pointLabel {
|
|
390
401
|
font-weight: 400;
|
|
391
402
|
}
|
|
392
|
-
/* .p-treenode-children {
|
|
393
|
-
background-color: #f0f0f0;
|
|
394
|
-
} */
|
|
395
403
|
.deviceLabel {
|
|
396
404
|
font-weight: 100;
|
|
397
405
|
}
|
|
@@ -404,12 +412,10 @@
|
|
|
404
412
|
.bacnetbutton {
|
|
405
413
|
background: none;
|
|
406
414
|
border: none;
|
|
407
|
-
/* color: white; */
|
|
408
415
|
color: black;
|
|
409
416
|
font-weight: 400;
|
|
410
417
|
}
|
|
411
418
|
.bacnetbutton:hover {
|
|
412
|
-
/* background: #21232e; */
|
|
413
419
|
background: #f0f0f0;
|
|
414
420
|
border-radius: 10px;
|
|
415
421
|
}
|
|
@@ -419,17 +425,13 @@
|
|
|
419
425
|
}
|
|
420
426
|
.p-treenode-children > li > .p-treenode-children > li {
|
|
421
427
|
font-size: 14px;
|
|
422
|
-
height:
|
|
428
|
+
/* height: 35px; */
|
|
423
429
|
color: #b5b5b5 !important;
|
|
424
430
|
}
|
|
425
431
|
.p-treenode-children > li > .p-treenode-children > .p-treenode-label {
|
|
426
432
|
color: #b5b5b5 !important;
|
|
427
433
|
}
|
|
428
|
-
.p-treenode-children > li > .p-treenode-children > li:last-child {
|
|
429
|
-
padding-bottom: 30px;
|
|
430
|
-
}
|
|
431
434
|
.p-tree-toggler:enabled:hover {
|
|
432
|
-
/* background: #21232e !important; */
|
|
433
435
|
background: #d5d5d5 !important;
|
|
434
436
|
}
|
|
435
437
|
.p-tree-toggler:focus {
|
|
@@ -441,14 +443,15 @@
|
|
|
441
443
|
}
|
|
442
444
|
.statusOnline {
|
|
443
445
|
color: #11c511;
|
|
444
|
-
|
|
445
446
|
}
|
|
446
447
|
.statusOffline {
|
|
447
448
|
color: red;
|
|
448
449
|
}
|
|
450
|
+
/*
|
|
449
451
|
.deviceLabel {
|
|
450
|
-
position:
|
|
452
|
+
position: absolute;
|
|
451
453
|
}
|
|
454
|
+
*/
|
|
452
455
|
.objectPropertiesLabel {
|
|
453
456
|
display: flex !important;
|
|
454
457
|
flex-direction: row;
|
|
@@ -457,23 +460,60 @@
|
|
|
457
460
|
.p-tree .p-tree-container .p-treenode .p-treenode-content:focus {
|
|
458
461
|
outline: 0 none !important;
|
|
459
462
|
outline-offset: 0 !important;
|
|
460
|
-
box-shadow: inset 0 0 0
|
|
463
|
+
box-shadow: inset 0 0 0 1px #bdbdbd !important;
|
|
464
|
+
}
|
|
465
|
+
.checkbox-round {
|
|
466
|
+
width: 13px !important;
|
|
467
|
+
height: 13px !important;
|
|
468
|
+
background-color: white;
|
|
469
|
+
border-radius: 50%;
|
|
470
|
+
vertical-align: middle;
|
|
471
|
+
border: 1px solid #ddd;
|
|
472
|
+
appearance: none;
|
|
473
|
+
-webkit-appearance: none;
|
|
474
|
+
outline: none;
|
|
475
|
+
cursor: pointer;
|
|
476
|
+
}
|
|
477
|
+
.checkbox-round:checked {
|
|
478
|
+
background-color: #00AEEF;
|
|
479
|
+
}
|
|
480
|
+
.checkbox-round:focus {
|
|
481
|
+
outline: none !important;
|
|
461
482
|
}
|
|
462
483
|
.p-tree-filter:focus, .p-tree-filter:focus-visible, .p-inputtext:enabled:hover {
|
|
463
|
-
box-shadow: inset 0 0 0 0.15rem #
|
|
484
|
+
box-shadow: inset 0 0 0 0.15rem #dfdcdc !important;
|
|
464
485
|
border-color: transparent !important;
|
|
465
486
|
}
|
|
466
487
|
.bacnetbutton > .pi {
|
|
467
488
|
display: flex;
|
|
468
489
|
}
|
|
490
|
+
.p-tree-container {
|
|
491
|
+
margin: 0 !important;
|
|
492
|
+
}
|
|
469
493
|
.reloadButtonIcon {
|
|
470
494
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !important;
|
|
471
495
|
}
|
|
496
|
+
.removeAllDevicesButton {
|
|
497
|
+
border: none;
|
|
498
|
+
background: none;
|
|
499
|
+
font-size: 14px !important;
|
|
500
|
+
float: right;
|
|
501
|
+
display: flex;
|
|
502
|
+
align-items: center;
|
|
503
|
+
}
|
|
504
|
+
.removeAllDevicesButton:hover {
|
|
505
|
+
background-color: #d5d5d5;
|
|
506
|
+
border-radius: 10px;
|
|
507
|
+
}
|
|
472
508
|
.reloadButton {
|
|
473
509
|
border: none;
|
|
474
510
|
background: none;
|
|
475
|
-
|
|
476
|
-
|
|
511
|
+
font-size: 14px !important;
|
|
512
|
+
float: right;
|
|
513
|
+
}
|
|
514
|
+
.rebuildDataButton {
|
|
515
|
+
border: none;
|
|
516
|
+
background: none;
|
|
477
517
|
font-size: 14px !important;
|
|
478
518
|
float: right;
|
|
479
519
|
}
|
|
@@ -481,11 +521,47 @@
|
|
|
481
521
|
background-color: #d5d5d5;
|
|
482
522
|
border-radius: 10px;
|
|
483
523
|
}
|
|
524
|
+
.rebuildDataButton:hover {
|
|
525
|
+
background-color: #d5d5d5;
|
|
526
|
+
border-radius: 10px;
|
|
527
|
+
}
|
|
528
|
+
.headerDiv {
|
|
529
|
+
display: flex;
|
|
530
|
+
flex-direction: row;
|
|
531
|
+
flex-wrap: nowrap;
|
|
532
|
+
justify-content: space-around;
|
|
533
|
+
height: 20px;
|
|
534
|
+
}
|
|
535
|
+
.msgTypeDiv {
|
|
536
|
+
display: flex;
|
|
537
|
+
align-items: flex-start;
|
|
538
|
+
flex-direction: column;
|
|
539
|
+
}
|
|
540
|
+
.p-progressbar .p-progressbar-value {
|
|
541
|
+
background: #00AEEF !important;
|
|
542
|
+
}
|
|
484
543
|
.p-treenode-label {
|
|
485
544
|
overflow: hidden;
|
|
486
545
|
white-space: nowrap;
|
|
487
546
|
text-overflow: ellipsis;
|
|
488
547
|
}
|
|
548
|
+
.buttonGroup {
|
|
549
|
+
padding-left: 7px;
|
|
550
|
+
}
|
|
551
|
+
#read-readList-tab {
|
|
552
|
+
display: flex;
|
|
553
|
+
flex-direction: column;
|
|
554
|
+
}
|
|
555
|
+
.removeAllDevicesDiv {
|
|
556
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
|
557
|
+
padding-right: 20px;
|
|
558
|
+
}
|
|
559
|
+
.p-tree .p-treenode-children {
|
|
560
|
+
padding: 0 !important;
|
|
561
|
+
}
|
|
562
|
+
.p-tree-toggler .p-link {
|
|
563
|
+
width: 25px !important;
|
|
564
|
+
}
|
|
489
565
|
|
|
490
566
|
</style>
|
|
491
567
|
|
package/bacnet_write.js
CHANGED
|
@@ -15,7 +15,7 @@ module.exports = function (RED) {
|
|
|
15
15
|
|
|
16
16
|
node.on('input', function(msg) {
|
|
17
17
|
|
|
18
|
-
let value = msg.payload == "null" ? null :
|
|
18
|
+
let value = msg.payload == "null" ? null : msg.payload;
|
|
19
19
|
let priority = node.priority == "null" ? null : parseInt(node.priority);
|
|
20
20
|
|
|
21
21
|
let output = {
|
package/common.js
CHANGED
|
@@ -91,7 +91,8 @@ class BacnetClientConfig {
|
|
|
91
91
|
manual_instance_range_start,
|
|
92
92
|
manual_instance_range_end,
|
|
93
93
|
device_read_schedule,
|
|
94
|
-
retries
|
|
94
|
+
retries,
|
|
95
|
+
cacheFileEnabled
|
|
95
96
|
) {
|
|
96
97
|
this.apduTimeout = apduTimeout;
|
|
97
98
|
this.localIpAdrress = localIpAdrress;
|
|
@@ -107,6 +108,7 @@ class BacnetClientConfig {
|
|
|
107
108
|
this.manual_instance_range_end = manual_instance_range_end;
|
|
108
109
|
this.device_read_schedule = device_read_schedule;
|
|
109
110
|
this.retries = retries;
|
|
111
|
+
this.cacheFileEnabled = cacheFileEnabled;
|
|
110
112
|
}
|
|
111
113
|
}
|
|
112
114
|
|
|
@@ -220,17 +222,25 @@ const doNodeRedRestart = function () {
|
|
|
220
222
|
// STORE CONFIG FUNCTION ==========================================================
|
|
221
223
|
//
|
|
222
224
|
// ================================================================================
|
|
223
|
-
|
|
225
|
+
function Store_Config(data) {
|
|
224
226
|
try {
|
|
225
|
-
|
|
226
|
-
if
|
|
227
|
-
console.log("Store_Config
|
|
227
|
+
fs.access("edge-bacnet-datastore.cfg", fs.constants.W_OK, async function(err) {
|
|
228
|
+
if(err){
|
|
229
|
+
console.log("Store_Config writeAccess error found: ", err);
|
|
230
|
+
} else {
|
|
231
|
+
await fs.writeFile("edge-bacnet-datastore.cfg", data, {encoding: "utf8", flag: "w"}, (err) => {
|
|
232
|
+
if (err) {
|
|
233
|
+
console.log("Store_Config writeFile error: ", err);
|
|
234
|
+
}
|
|
235
|
+
});
|
|
228
236
|
}
|
|
229
237
|
});
|
|
230
|
-
} catch
|
|
238
|
+
} catch(e){
|
|
231
239
|
//do nothing
|
|
232
240
|
}
|
|
233
|
-
}
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
|
|
234
244
|
|
|
235
245
|
// READ CONFIG SYNC FUNCTION ======================================================
|
|
236
246
|
//
|
|
@@ -238,14 +248,15 @@ async function Store_Config(data) {
|
|
|
238
248
|
function Read_Config_Sync() {
|
|
239
249
|
var data = "{}";
|
|
240
250
|
try {
|
|
241
|
-
data = fs.readFileSync("edge-bacnet-datastore.cfg", { encoding:
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
|
|
251
|
+
data = fs.readFileSync("edge-bacnet-datastore.cfg", { encoding: 'utf8', flag: 'r' });
|
|
252
|
+
}
|
|
253
|
+
catch (err) {
|
|
254
|
+
console.log("Read_Config_Sync error:", err);
|
|
255
|
+
data = '{}';
|
|
245
256
|
Store_Config(data);
|
|
246
257
|
}
|
|
247
258
|
return data;
|
|
248
|
-
}
|
|
259
|
+
};
|
|
249
260
|
|
|
250
261
|
// STORE CONFIG FUNCTION - BACNET SERVER ==========================================
|
|
251
262
|
//
|
|
@@ -276,6 +287,10 @@ function Read_Config_Sync_Server() {
|
|
|
276
287
|
return data;
|
|
277
288
|
}
|
|
278
289
|
|
|
290
|
+
function isNumber(value) {
|
|
291
|
+
return value != null && typeof value === 'number' && !isNaN(value);
|
|
292
|
+
}
|
|
293
|
+
|
|
279
294
|
module.exports = {
|
|
280
295
|
BacnetConfig,
|
|
281
296
|
BacnetClientConfig,
|
|
@@ -290,4 +305,5 @@ module.exports = {
|
|
|
290
305
|
Read_Config_Sync,
|
|
291
306
|
Store_Config_Server,
|
|
292
307
|
Read_Config_Sync_Server,
|
|
308
|
+
isNumber,
|
|
293
309
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bitpoolos/edge-bacnet",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.7",
|
|
4
4
|
"description": "A bacnet gateway for node-red",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@plus4nodered/ts-node-bacnet": "^1.0.0-beta.2",
|
|
@@ -50,4 +50,4 @@
|
|
|
50
50
|
"type": "github",
|
|
51
51
|
"url": "git+https://github.com/bitpool/edge-bacnet.git"
|
|
52
52
|
}
|
|
53
|
-
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
|
|
3
|
+
<defs>
|
|
4
|
+
<style>
|
|
5
|
+
.cls-1 {
|
|
6
|
+
fill: none;
|
|
7
|
+
stroke: #6c757d;
|
|
8
|
+
stroke-linecap: round;
|
|
9
|
+
stroke-linejoin: round;
|
|
10
|
+
stroke-width: 2px;
|
|
11
|
+
}
|
|
12
|
+
</style>
|
|
13
|
+
</defs>
|
|
14
|
+
<circle class="cls-1" cx="15" cy="15" r="14"/>
|
|
15
|
+
<g>
|
|
16
|
+
<path class="cls-1" d="M11.21,22s0-14,0-14h5.13c1.91,0,3.46,1.55,3.46,3.46v.54c0,1.91-1.55,3.46-3.46,3.46h-5.13"/>
|
|
17
|
+
<line class="cls-1" x1="15.51" y1="15.45" x2="20.03" y2="21.94"/>
|
|
18
|
+
</g>
|
|
19
|
+
</svg>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
|
|
3
|
+
<defs>
|
|
4
|
+
<style>
|
|
5
|
+
.cls-1 {
|
|
6
|
+
fill: none;
|
|
7
|
+
stroke: #6c757d;
|
|
8
|
+
stroke-linecap: round;
|
|
9
|
+
stroke-linejoin: round;
|
|
10
|
+
stroke-width: 2px;
|
|
11
|
+
}
|
|
12
|
+
</style>
|
|
13
|
+
</defs>
|
|
14
|
+
<circle class="cls-1" cx="15" cy="15" r="14"/>
|
|
15
|
+
<polyline class="cls-1" points="22.21 9.75 18.61 21.35 15 9.75 11.39 21.35 7.79 9.75"/>
|
|
16
|
+
</svg>
|
|
@@ -616,7 +616,7 @@ class Client extends events_1.EventEmitter {
|
|
|
616
616
|
const type = baEnum.PduTypes.CONFIRMED_REQUEST | (settings.maxSegments !== baEnum.MaxSegmentsAccepted.SEGMENTS_0 ? baEnum.PduConReqBits.SEGMENTED_RESPONSE_ACCEPTED : 0);
|
|
617
617
|
baApdu.encodeConfirmedServiceRequest(buffer, type, baEnum.ConfirmedServiceChoice.READ_PROPERTY, settings.maxSegments, settings.maxApdu, settings.invokeId, 0, 0);
|
|
618
618
|
baServices.readProperty.encode(buffer, objectId.type, objectId.instance, propertyId, settings.arrayIndex);
|
|
619
|
-
|
|
619
|
+
baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
|
|
620
620
|
this.sendBvlc(address, buffer);
|
|
621
621
|
this._addCallback(settings.invokeId, (err, data) => {
|
|
622
622
|
try{
|
|
@@ -672,7 +672,7 @@ class Client extends events_1.EventEmitter {
|
|
|
672
672
|
baNpdu.encode(buffer, baEnum.NpduControlPriority.NORMAL_MESSAGE | baEnum.NpduControlBits.EXPECTING_REPLY, address, null, DEFAULT_HOP_COUNT, baEnum.NetworkLayerMessageType.WHO_IS_ROUTER_TO_NETWORK, 0);
|
|
673
673
|
baApdu.encodeConfirmedServiceRequest(buffer, baEnum.PduTypes.CONFIRMED_REQUEST, baEnum.ConfirmedServiceChoice.WRITE_PROPERTY, settings.maxSegments, settings.maxApdu, settings.invokeId, 0, 0);
|
|
674
674
|
baServices.writeProperty.encode(buffer, objectId.type, objectId.instance, propertyId, settings.arrayIndex, settings.priority, values);
|
|
675
|
-
|
|
675
|
+
baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
|
|
676
676
|
this.sendBvlc(address, buffer);
|
|
677
677
|
this._addCallback(settings.invokeId, (err) => next(err));
|
|
678
678
|
}
|
|
@@ -714,7 +714,7 @@ class Client extends events_1.EventEmitter {
|
|
|
714
714
|
const type = baEnum.PduTypes.CONFIRMED_REQUEST | (settings.maxSegments !== baEnum.MaxSegmentsAccepted.SEGMENTS_0 ? baEnum.PduConReqBits.SEGMENTED_RESPONSE_ACCEPTED : 0);
|
|
715
715
|
baApdu.encodeConfirmedServiceRequest(buffer, type, baEnum.ConfirmedServiceChoice.READ_PROPERTY_MULTIPLE, settings.maxSegments, settings.maxApdu, settings.invokeId, 0, 0);
|
|
716
716
|
baServices.readPropertyMultiple.encode(buffer, propertiesArray);
|
|
717
|
-
|
|
717
|
+
baBvlc.encode(buffer.buffer, baEnum.BvlcResultPurpose.ORIGINAL_UNICAST_NPDU, buffer.offset);
|
|
718
718
|
this.sendBvlc(address, buffer);
|
|
719
719
|
//this.sendBvlc(address, buffer);
|
|
720
720
|
this._addCallback(settings.invokeId, (err, data) => {
|