@bitpoolos/edge-bacnet 1.4.3 → 1.4.5
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/CHANGELOG.md +24 -0
- package/bacnet_client.js +200 -123
- package/bacnet_gateway.html +141 -135
- package/bacnet_gateway.js +15 -0
- package/bacnet_read.html +45 -42
- package/bacnet_read.js +69 -60
- package/bacnet_write.html +7 -5
- package/bitpool_inject.html +49 -136
- package/package.json +1 -1
- package/resources/style.css +602 -202
- package/treeBuilder.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.4.5] - 16-08-2024
|
|
4
|
+
### Summary
|
|
5
|
+
|
|
6
|
+
User interface redesign and restyle. Predominantly colors, buttons, fonts, and placement of UI components.
|
|
7
|
+
|
|
8
|
+
Added timestamp update, and online/offline status update for points when an error has occured during the network request for present value. Use in Simple with status and Full Object payload types.
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
## [1.4.4] - 08-08-2024
|
|
12
|
+
### Summary
|
|
13
|
+
|
|
14
|
+
Minor updates.
|
|
15
|
+
|
|
16
|
+
Added device details to meta property when full object property type is selected.
|
|
17
|
+
|
|
18
|
+
Implemented applyDisplayName feature. Triggered via:
|
|
19
|
+
```javascript
|
|
20
|
+
applyDisplayNames = true
|
|
21
|
+
```
|
|
22
|
+
property in an inject node, directly linked to a read node. Function flow: inject applyDisplayNames = true to read node -> read node passes msg to gateway node -> gateway node updates bacnet model for device and point display names.
|
|
23
|
+
|
|
24
|
+
This feature is for use in scenarios where the flows.json or node json structure is programattically generated with a prefilled pointsToRead property. Some devices and points may need displayNames updating.
|
|
25
|
+
|
|
26
|
+
|
|
3
27
|
## [1.4.3] - 01-08-2024
|
|
4
28
|
### Summary
|
|
5
29
|
|
package/bacnet_client.js
CHANGED
|
@@ -90,10 +90,8 @@ class BacnetClient extends EventEmitter {
|
|
|
90
90
|
|
|
91
91
|
//buildNetworkTreeData task
|
|
92
92
|
const buildNetworkTree = new Task("simple task", () => {
|
|
93
|
-
|
|
94
93
|
that.doTreeBuilder();
|
|
95
94
|
that.countDevices();
|
|
96
|
-
|
|
97
95
|
});
|
|
98
96
|
|
|
99
97
|
const buildNetworkTreeJob = new SimpleIntervalJob({ seconds: 5 }, buildNetworkTree);
|
|
@@ -213,28 +211,30 @@ class BacnetClient extends EventEmitter {
|
|
|
213
211
|
if (lastIndex) {
|
|
214
212
|
let formattedName = deviceName.substring(0, lastIndex);
|
|
215
213
|
formattedName = `${formattedName.trim()}_Device_${deviceId}`;
|
|
216
|
-
if (
|
|
217
|
-
|
|
214
|
+
if (
|
|
215
|
+
that.networkTree[deviceKey][formattedName] &&
|
|
216
|
+
Object.keys(that.networkTree[deviceKey][formattedName]).length > 0
|
|
217
|
+
) {
|
|
218
218
|
delete that.networkTree[deviceKey]["device"];
|
|
219
219
|
}
|
|
220
220
|
}
|
|
221
221
|
}
|
|
222
222
|
} else {
|
|
223
223
|
const json = {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
}
|
|
224
|
+
objectId: {
|
|
225
|
+
type: 8,
|
|
226
|
+
instance: device.getDeviceId(),
|
|
227
|
+
},
|
|
228
228
|
};
|
|
229
229
|
|
|
230
230
|
if (that.networkTree[deviceKey] && that.networkTree[deviceKey]["device"]) {
|
|
231
231
|
that.networkTree[deviceKey]["device"]["meta"] = json;
|
|
232
232
|
} else {
|
|
233
233
|
that.networkTree[deviceKey] = {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
}
|
|
237
|
-
}
|
|
234
|
+
device: {
|
|
235
|
+
meta: json,
|
|
236
|
+
},
|
|
237
|
+
};
|
|
238
238
|
}
|
|
239
239
|
}
|
|
240
240
|
} catch (e) {
|
|
@@ -262,7 +262,6 @@ class BacnetClient extends EventEmitter {
|
|
|
262
262
|
}
|
|
263
263
|
);
|
|
264
264
|
});
|
|
265
|
-
|
|
266
265
|
}
|
|
267
266
|
|
|
268
267
|
addToParentMstpNetwork(device) {
|
|
@@ -328,12 +327,15 @@ class BacnetClient extends EventEmitter {
|
|
|
328
327
|
await that.updateDeviceName(device);
|
|
329
328
|
|
|
330
329
|
if (device.getIsProtocolServicesSet() == false) {
|
|
331
|
-
that
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
330
|
+
that
|
|
331
|
+
.getProtocolSupported(device)
|
|
332
|
+
.then(function (result) {
|
|
333
|
+
let decodedValues = decodeBitArray(8, result.values[0].originalBitString.value);
|
|
334
|
+
device.setProtocolServicesSupported(decodedValues);
|
|
335
|
+
})
|
|
336
|
+
.catch(function (error) {
|
|
337
|
+
that.logOut("getProtocolSupported error: ", error);
|
|
338
|
+
});
|
|
337
339
|
}
|
|
338
340
|
|
|
339
341
|
that
|
|
@@ -375,16 +377,39 @@ class BacnetClient extends EventEmitter {
|
|
|
375
377
|
});
|
|
376
378
|
}
|
|
377
379
|
|
|
380
|
+
applyDisplayNames(pointsToRead) {
|
|
381
|
+
let that = this;
|
|
382
|
+
return new Promise((resolve, reject) => {
|
|
383
|
+
try {
|
|
384
|
+
for (let key in pointsToRead) {
|
|
385
|
+
let deviceModel = that.findDeviceByKey(key);
|
|
386
|
+
let device = pointsToRead[key];
|
|
387
|
+
for (let pointName in device) {
|
|
388
|
+
let pointObject = device[pointName];
|
|
389
|
+
if (pointName == "deviceName") {
|
|
390
|
+
deviceModel.setDisplayName(pointObject);
|
|
391
|
+
}
|
|
392
|
+
if (that.networkTree[key][pointName]) {
|
|
393
|
+
that.networkTree[key][pointName] = pointObject;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
resolve(true);
|
|
399
|
+
} catch (e) {
|
|
400
|
+
that.logOut("applyDisplayNames error: ", e);
|
|
401
|
+
reject(e);
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
|
|
378
406
|
setDeviceDisplayName(deviceObject, displayName) {
|
|
379
407
|
let that = this;
|
|
380
408
|
return new Promise((resolve, reject) => {
|
|
381
409
|
try {
|
|
382
410
|
let device = that.deviceList.find((ele) => ele.getDeviceId() == deviceObject.deviceId);
|
|
383
|
-
|
|
384
411
|
device.setDisplayName(displayName);
|
|
385
|
-
|
|
386
412
|
that.buildTreeException = true;
|
|
387
|
-
|
|
388
413
|
resolve(true);
|
|
389
414
|
} catch (e) {
|
|
390
415
|
that.logOut("setDeviceDisplayName error: ", e);
|
|
@@ -401,9 +426,7 @@ class BacnetClient extends EventEmitter {
|
|
|
401
426
|
if (that.networkTree[deviceKey][pointName]) {
|
|
402
427
|
that.networkTree[deviceKey][pointName].displayName = pointDisplayName;
|
|
403
428
|
}
|
|
404
|
-
|
|
405
429
|
that.buildTreeException = true;
|
|
406
|
-
|
|
407
430
|
resolve(true);
|
|
408
431
|
} catch (e) {
|
|
409
432
|
that.logOut("setPointDisplayName error: ", e);
|
|
@@ -414,15 +437,13 @@ class BacnetClient extends EventEmitter {
|
|
|
414
437
|
|
|
415
438
|
importReadList(payload) {
|
|
416
439
|
let that = this;
|
|
417
|
-
|
|
418
440
|
return new Promise((resolve, reject) => {
|
|
419
441
|
try {
|
|
420
442
|
that.buildTreeException = true;
|
|
421
|
-
|
|
422
443
|
for (let key in payload) {
|
|
423
444
|
let device = payload[key];
|
|
424
445
|
for (let pointName in device) {
|
|
425
|
-
let pointObject = device[pointName]
|
|
446
|
+
let pointObject = device[pointName];
|
|
426
447
|
if (that.networkTree[key][pointName]) {
|
|
427
448
|
that.networkTree[key][pointName] = pointObject;
|
|
428
449
|
}
|
|
@@ -453,15 +474,17 @@ class BacnetClient extends EventEmitter {
|
|
|
453
474
|
|
|
454
475
|
if (typeof device == "object") {
|
|
455
476
|
if (device.getIsProtocolServicesSet() == false) {
|
|
456
|
-
that
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
477
|
+
that
|
|
478
|
+
.getProtocolSupported(device)
|
|
479
|
+
.then(function (result) {
|
|
480
|
+
let decodedValues = decodeBitArray(8, result.values[0].originalBitString.value);
|
|
481
|
+
device.setProtocolServicesSupported(decodedValues);
|
|
482
|
+
})
|
|
483
|
+
.catch(function (error) {
|
|
484
|
+
that.logOut("getProtocolSupported error: ", error);
|
|
485
|
+
});
|
|
462
486
|
}
|
|
463
487
|
try {
|
|
464
|
-
|
|
465
488
|
if (device.getSegmentation() !== 3) {
|
|
466
489
|
that.updateDeviceName(device);
|
|
467
490
|
that
|
|
@@ -496,9 +519,7 @@ class BacnetClient extends EventEmitter {
|
|
|
496
519
|
query(index);
|
|
497
520
|
});
|
|
498
521
|
});
|
|
499
|
-
|
|
500
522
|
} else if (device.getSegmentation() == 3) {
|
|
501
|
-
|
|
502
523
|
that.updateDeviceName(device);
|
|
503
524
|
that
|
|
504
525
|
.getDevicePointListWithoutObjectList(device)
|
|
@@ -617,8 +638,9 @@ class BacnetClient extends EventEmitter {
|
|
|
617
638
|
return newProps;
|
|
618
639
|
}
|
|
619
640
|
|
|
620
|
-
findDeviceByKey(key
|
|
621
|
-
|
|
641
|
+
findDeviceByKey(key) {
|
|
642
|
+
let that = this;
|
|
643
|
+
return that.deviceList.find((ele) => `${that.getDeviceAddress(ele)}-${ele.getDeviceId()}` === key);
|
|
622
644
|
}
|
|
623
645
|
|
|
624
646
|
getObjectId(pointName, pointConfig, that) {
|
|
@@ -639,7 +661,6 @@ class BacnetClient extends EventEmitter {
|
|
|
639
661
|
}
|
|
640
662
|
}
|
|
641
663
|
|
|
642
|
-
|
|
643
664
|
async doRead(readConfig, outputType, objectPropertyType, readNodeName) {
|
|
644
665
|
const that = this;
|
|
645
666
|
const roundDecimal = readConfig.precision;
|
|
@@ -648,11 +669,10 @@ class BacnetClient extends EventEmitter {
|
|
|
648
669
|
let pendingRequests = 0;
|
|
649
670
|
|
|
650
671
|
try {
|
|
651
|
-
|
|
652
672
|
// Process all devices in sequence
|
|
653
673
|
for (let deviceIndex = 0; deviceIndex < devicesToRead.length; deviceIndex++) {
|
|
654
674
|
const key = devicesToRead[deviceIndex];
|
|
655
|
-
const device = that.findDeviceByKey(key
|
|
675
|
+
const device = that.findDeviceByKey(key);
|
|
656
676
|
if (!device) continue;
|
|
657
677
|
|
|
658
678
|
const deviceName = that.computeDeviceName(device);
|
|
@@ -691,7 +711,7 @@ class BacnetClient extends EventEmitter {
|
|
|
691
711
|
objectId: { type: point.meta.objectId.type, instance: point.meta.objectId.instance },
|
|
692
712
|
properties: [{ id: baEnum.PropertyIdentifier.PRESENT_VALUE }],
|
|
693
713
|
pointRef: point,
|
|
694
|
-
pointName: pointName
|
|
714
|
+
pointName: pointName,
|
|
695
715
|
});
|
|
696
716
|
}
|
|
697
717
|
|
|
@@ -712,9 +732,16 @@ class BacnetClient extends EventEmitter {
|
|
|
712
732
|
if (processedPoints >= totalPoints) {
|
|
713
733
|
pendingRequests++;
|
|
714
734
|
// Emit the `values` event for the current device
|
|
715
|
-
that.emit(
|
|
735
|
+
that.emit(
|
|
736
|
+
"values",
|
|
737
|
+
bacnetResults,
|
|
738
|
+
outputType,
|
|
739
|
+
objectPropertyType,
|
|
740
|
+
readNodeName,
|
|
741
|
+
pendingRequests,
|
|
742
|
+
devicesToRead.length
|
|
743
|
+
);
|
|
716
744
|
delete bacnetResults[deviceName];
|
|
717
|
-
|
|
718
745
|
}
|
|
719
746
|
}
|
|
720
747
|
}
|
|
@@ -730,11 +757,20 @@ class BacnetClient extends EventEmitter {
|
|
|
730
757
|
throw results.error;
|
|
731
758
|
}
|
|
732
759
|
|
|
760
|
+
let deviceMetaInfo = {
|
|
761
|
+
address: device.getAddress(),
|
|
762
|
+
isMstp: device.getIsMstpDevice(),
|
|
763
|
+
deviceId: device.getDeviceId(),
|
|
764
|
+
vendorId: device.getVendorId(),
|
|
765
|
+
deviceName: deviceName,
|
|
766
|
+
};
|
|
767
|
+
|
|
733
768
|
// Process the results of the batch
|
|
734
|
-
results.value.values.forEach(pointResult => {
|
|
735
|
-
const cacheRef = requestArray.find(
|
|
736
|
-
ele
|
|
737
|
-
|
|
769
|
+
results.value.values.forEach((pointResult) => {
|
|
770
|
+
const cacheRef = requestArray.find(
|
|
771
|
+
(ele) =>
|
|
772
|
+
ele.pointRef.meta.objectId.type === pointResult.objectId.type &&
|
|
773
|
+
ele.pointRef.meta.objectId.instance === pointResult.objectId.instance
|
|
738
774
|
);
|
|
739
775
|
|
|
740
776
|
if (cacheRef) {
|
|
@@ -744,7 +780,11 @@ class BacnetClient extends EventEmitter {
|
|
|
744
780
|
|
|
745
781
|
if (isNumber(val)) {
|
|
746
782
|
pointRef.presentValue = roundDecimalPlaces(val, roundDecimal);
|
|
747
|
-
if (
|
|
783
|
+
if (
|
|
784
|
+
pointRef.meta.objectId.type == 19 ||
|
|
785
|
+
pointRef.meta.objectId.type == 13 ||
|
|
786
|
+
pointRef.meta.objectId.type == 14
|
|
787
|
+
) {
|
|
748
788
|
if (pointRef.stateTextArray && typeof pointRef.stateTextArray[0].value !== "object") {
|
|
749
789
|
if (val != 0) {
|
|
750
790
|
pointRef.presentValue = pointRef.stateTextArray[val - 1].value;
|
|
@@ -759,6 +799,7 @@ class BacnetClient extends EventEmitter {
|
|
|
759
799
|
}
|
|
760
800
|
}
|
|
761
801
|
|
|
802
|
+
pointRef.meta["device"] = deviceMetaInfo;
|
|
762
803
|
pointRef.timestamp = Date.now();
|
|
763
804
|
pointRef.status = "online";
|
|
764
805
|
|
|
@@ -769,17 +810,34 @@ class BacnetClient extends EventEmitter {
|
|
|
769
810
|
} catch (err) {
|
|
770
811
|
that.logOut("Error processing batch:", err);
|
|
771
812
|
|
|
772
|
-
|
|
813
|
+
let deviceMetaInfo = {
|
|
814
|
+
address: device.getAddress(),
|
|
815
|
+
isMstp: device.getIsMstpDevice(),
|
|
816
|
+
deviceId: device.getDeviceId(),
|
|
817
|
+
vendorId: device.getVendorId(),
|
|
818
|
+
deviceName: deviceName,
|
|
819
|
+
};
|
|
820
|
+
|
|
821
|
+
requestArray.forEach((request) => {
|
|
773
822
|
let pointRef = request.pointRef;
|
|
774
823
|
pointRef.status = "offline";
|
|
824
|
+
pointRef.timestamp = Date.now();
|
|
825
|
+
pointRef.meta["device"] = deviceMetaInfo;
|
|
775
826
|
|
|
776
827
|
bacnetResults[deviceName][request.pointName] = pointRef;
|
|
777
828
|
});
|
|
778
|
-
|
|
779
829
|
}
|
|
780
830
|
}
|
|
781
831
|
|
|
782
832
|
async processIndividualPoints(device, requestArray, deviceName, bacnetResults, that, roundDecimal) {
|
|
833
|
+
let deviceMetaInfo = {
|
|
834
|
+
address: device.getAddress(),
|
|
835
|
+
isMstp: device.getIsMstpDevice(),
|
|
836
|
+
deviceId: device.getDeviceId(),
|
|
837
|
+
vendorId: device.getVendorId(),
|
|
838
|
+
deviceName: deviceName,
|
|
839
|
+
};
|
|
840
|
+
|
|
783
841
|
for (const request of requestArray) {
|
|
784
842
|
const { objectId, pointRef, pointName } = request;
|
|
785
843
|
try {
|
|
@@ -792,11 +850,17 @@ class BacnetClient extends EventEmitter {
|
|
|
792
850
|
pointRef.presentValue = val;
|
|
793
851
|
}
|
|
794
852
|
|
|
853
|
+
pointRef.meta["device"] = deviceMetaInfo;
|
|
854
|
+
pointRef.timestamp = Date.now();
|
|
855
|
+
pointRef.status = "online";
|
|
856
|
+
|
|
795
857
|
// Store the point data in results
|
|
796
858
|
bacnetResults[deviceName][pointName] = pointRef;
|
|
797
859
|
} catch (err) {
|
|
798
860
|
that.logOut(`Error updating point ${pointName}:`, err);
|
|
799
861
|
|
|
862
|
+
pointRef.meta["device"] = deviceMetaInfo;
|
|
863
|
+
pointRef.timestamp = Date.now();
|
|
800
864
|
pointRef.status = "offline";
|
|
801
865
|
bacnetResults[deviceName][pointName] = pointRef;
|
|
802
866
|
}
|
|
@@ -806,11 +870,14 @@ class BacnetClient extends EventEmitter {
|
|
|
806
870
|
updateManyPoints(device, points) {
|
|
807
871
|
let that = this;
|
|
808
872
|
return new Promise((resolve, reject) => {
|
|
809
|
-
that
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
873
|
+
that
|
|
874
|
+
._readObjectWithRequestArray(device.getAddress(), points, that.readPropertyMultipleOptions)
|
|
875
|
+
.then(function (results) {
|
|
876
|
+
resolve(results);
|
|
877
|
+
})
|
|
878
|
+
.catch(function (err) {
|
|
879
|
+
reject(err);
|
|
880
|
+
});
|
|
814
881
|
});
|
|
815
882
|
}
|
|
816
883
|
|
|
@@ -1078,8 +1145,9 @@ class BacnetClient extends EventEmitter {
|
|
|
1078
1145
|
|
|
1079
1146
|
return new Promise((resolve, reject) => {
|
|
1080
1147
|
// Try to read all properties at once
|
|
1081
|
-
that
|
|
1082
|
-
.
|
|
1148
|
+
that
|
|
1149
|
+
._readObject(deviceAddress, type, instance, [{ id: baEnum.PropertyIdentifier.ALL }], readOptions)
|
|
1150
|
+
.then((result) => {
|
|
1083
1151
|
if (result.value) {
|
|
1084
1152
|
// If the result has value, resolve the promise
|
|
1085
1153
|
resolve(result);
|
|
@@ -1095,30 +1163,33 @@ class BacnetClient extends EventEmitter {
|
|
|
1095
1163
|
|
|
1096
1164
|
// Function to read properties individually
|
|
1097
1165
|
const readPropertiesIndividually = () => {
|
|
1098
|
-
const promises = allProperties.map(
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1166
|
+
const promises = allProperties.map(
|
|
1167
|
+
(property, index) =>
|
|
1168
|
+
new Promise((propertyResolve) => {
|
|
1169
|
+
that.client.readProperty(
|
|
1170
|
+
deviceAddress,
|
|
1171
|
+
{ type: type, instance: instance },
|
|
1172
|
+
property.id,
|
|
1173
|
+
readOptions,
|
|
1174
|
+
(err, value) => {
|
|
1175
|
+
if (err) {
|
|
1176
|
+
propertyResolve(null);
|
|
1177
|
+
} else {
|
|
1178
|
+
propertyResolve({
|
|
1179
|
+
id: property.id,
|
|
1180
|
+
index: value.property.index,
|
|
1181
|
+
value: value.values,
|
|
1182
|
+
});
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
);
|
|
1186
|
+
})
|
|
1187
|
+
);
|
|
1117
1188
|
|
|
1118
1189
|
Promise.all(promises)
|
|
1119
|
-
.then(resultArray => {
|
|
1190
|
+
.then((resultArray) => {
|
|
1120
1191
|
// Filter out null results
|
|
1121
|
-
const validResults = resultArray.filter(result => result !== null);
|
|
1192
|
+
const validResults = resultArray.filter((result) => result !== null);
|
|
1122
1193
|
|
|
1123
1194
|
resolve({
|
|
1124
1195
|
error: null,
|
|
@@ -1140,7 +1211,6 @@ class BacnetClient extends EventEmitter {
|
|
|
1140
1211
|
});
|
|
1141
1212
|
}
|
|
1142
1213
|
|
|
1143
|
-
|
|
1144
1214
|
_readObjectLite(device, deviceAddress, type, instance) {
|
|
1145
1215
|
const that = this;
|
|
1146
1216
|
const readOptions = {
|
|
@@ -1149,15 +1219,13 @@ class BacnetClient extends EventEmitter {
|
|
|
1149
1219
|
};
|
|
1150
1220
|
|
|
1151
1221
|
// Define all properties to be read
|
|
1152
|
-
const allProperties = [
|
|
1153
|
-
{ id: baEnum.PropertyIdentifier.PRESENT_VALUE },
|
|
1154
|
-
{ id: baEnum.PropertyIdentifier.OBJECT_NAME },
|
|
1155
|
-
];
|
|
1222
|
+
const allProperties = [{ id: baEnum.PropertyIdentifier.PRESENT_VALUE }, { id: baEnum.PropertyIdentifier.OBJECT_NAME }];
|
|
1156
1223
|
|
|
1157
1224
|
return new Promise((resolve, reject) => {
|
|
1158
1225
|
// Try to read all properties at once
|
|
1159
|
-
that
|
|
1160
|
-
.
|
|
1226
|
+
that
|
|
1227
|
+
._readObject(deviceAddress, type, instance, allProperties, readOptions)
|
|
1228
|
+
.then((result) => {
|
|
1161
1229
|
if (result.value) {
|
|
1162
1230
|
// If the result has value, resolve the promise
|
|
1163
1231
|
resolve(result);
|
|
@@ -1173,30 +1241,33 @@ class BacnetClient extends EventEmitter {
|
|
|
1173
1241
|
|
|
1174
1242
|
// Function to read properties individually
|
|
1175
1243
|
const readPropertiesIndividually = () => {
|
|
1176
|
-
const promises = allProperties.map(
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1244
|
+
const promises = allProperties.map(
|
|
1245
|
+
(property, index) =>
|
|
1246
|
+
new Promise((propertyResolve) => {
|
|
1247
|
+
that.client.readProperty(
|
|
1248
|
+
deviceAddress,
|
|
1249
|
+
{ type: type, instance: instance },
|
|
1250
|
+
property.id,
|
|
1251
|
+
readOptions,
|
|
1252
|
+
(err, value) => {
|
|
1253
|
+
if (err) {
|
|
1254
|
+
propertyResolve(null);
|
|
1255
|
+
} else {
|
|
1256
|
+
propertyResolve({
|
|
1257
|
+
id: property.id,
|
|
1258
|
+
index: value.property.index,
|
|
1259
|
+
value: value.values,
|
|
1260
|
+
});
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
);
|
|
1264
|
+
})
|
|
1265
|
+
);
|
|
1195
1266
|
|
|
1196
1267
|
Promise.all(promises)
|
|
1197
|
-
.then(resultArray => {
|
|
1268
|
+
.then((resultArray) => {
|
|
1198
1269
|
// Filter out null results
|
|
1199
|
-
const validResults = resultArray.filter(result => result !== null);
|
|
1270
|
+
const validResults = resultArray.filter((result) => result !== null);
|
|
1200
1271
|
|
|
1201
1272
|
resolve({
|
|
1202
1273
|
error: null,
|
|
@@ -1446,7 +1517,7 @@ class BacnetClient extends EventEmitter {
|
|
|
1446
1517
|
}
|
|
1447
1518
|
|
|
1448
1519
|
addUniqueToArray(device, array) {
|
|
1449
|
-
const foundIndex = array.findIndex(ele => ele.getDeviceId() === device.getDeviceId());
|
|
1520
|
+
const foundIndex = array.findIndex((ele) => ele.getDeviceId() === device.getDeviceId());
|
|
1450
1521
|
if (foundIndex === -1) {
|
|
1451
1522
|
array.push(device);
|
|
1452
1523
|
}
|
|
@@ -1459,16 +1530,16 @@ class BacnetClient extends EventEmitter {
|
|
|
1459
1530
|
const device = that.deviceList[i];
|
|
1460
1531
|
if (!device.getIsMstpDevice()) {
|
|
1461
1532
|
//ip device
|
|
1462
|
-
const foundIndex = that.renderList.findIndex(ele => ele.deviceId == device.getDeviceId());
|
|
1533
|
+
const foundIndex = that.renderList.findIndex((ele) => ele.deviceId == device.getDeviceId());
|
|
1463
1534
|
if (foundIndex == -1) {
|
|
1464
1535
|
that.addUniqueToArray(device, missingDevices);
|
|
1465
1536
|
}
|
|
1466
1537
|
} else {
|
|
1467
1538
|
//mstp device
|
|
1468
|
-
const foundParentIndex = that.renderList.findIndex(ele => ele.deviceId == device.getParentDeviceId());
|
|
1539
|
+
const foundParentIndex = that.renderList.findIndex((ele) => ele.deviceId == device.getParentDeviceId());
|
|
1469
1540
|
if (foundParentIndex == -1) {
|
|
1470
1541
|
//parent not existent in tree
|
|
1471
|
-
const parentDeviceIndex = that.deviceList.findIndex(ele => ele.getDeviceId() === device.getParentDeviceId());
|
|
1542
|
+
const parentDeviceIndex = that.deviceList.findIndex((ele) => ele.getDeviceId() === device.getParentDeviceId());
|
|
1472
1543
|
if (parentDeviceIndex !== -1) {
|
|
1473
1544
|
that.addUniqueToArray(that.deviceList[parentDeviceIndex], missingDevices);
|
|
1474
1545
|
}
|
|
@@ -1476,9 +1547,9 @@ class BacnetClient extends EventEmitter {
|
|
|
1476
1547
|
} else {
|
|
1477
1548
|
const parentTreeDevice = that.renderList[foundParentIndex];
|
|
1478
1549
|
let mstpIndex = -1;
|
|
1479
|
-
parentTreeDevice.children.forEach(child => {
|
|
1550
|
+
parentTreeDevice.children.forEach((child) => {
|
|
1480
1551
|
if (child.label.includes("MSTP")) {
|
|
1481
|
-
const tempIndex = child.children.findIndex(ele => ele.deviceId == device.getDeviceId());
|
|
1552
|
+
const tempIndex = child.children.findIndex((ele) => ele.deviceId == device.getDeviceId());
|
|
1482
1553
|
if (tempIndex !== -1) {
|
|
1483
1554
|
mstpIndex = tempIndex;
|
|
1484
1555
|
}
|
|
@@ -1498,7 +1569,13 @@ class BacnetClient extends EventEmitter {
|
|
|
1498
1569
|
async doTreeBuilder() {
|
|
1499
1570
|
let that = this;
|
|
1500
1571
|
|
|
1501
|
-
const treeWorker = new treeBuilder(
|
|
1572
|
+
const treeWorker = new treeBuilder(
|
|
1573
|
+
that.deviceList,
|
|
1574
|
+
that.networkTree,
|
|
1575
|
+
that.renderList,
|
|
1576
|
+
that.renderListCount,
|
|
1577
|
+
that.initialTreeBuild
|
|
1578
|
+
);
|
|
1502
1579
|
|
|
1503
1580
|
treeWorker.cacheData();
|
|
1504
1581
|
|
|
@@ -1595,9 +1672,6 @@ class BacnetClient extends EventEmitter {
|
|
|
1595
1672
|
});
|
|
1596
1673
|
}
|
|
1597
1674
|
});
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
1675
|
} else {
|
|
1602
1676
|
that
|
|
1603
1677
|
._readObjectFull(device, address, point.value.type, point.value.instance)
|
|
@@ -1677,7 +1751,7 @@ class BacnetClient extends EventEmitter {
|
|
|
1677
1751
|
|
|
1678
1752
|
let objectId;
|
|
1679
1753
|
if (objectName !== null && typeof objectName == "string") {
|
|
1680
|
-
objectName = objectName.replace(reg,
|
|
1754
|
+
objectName = objectName.replace(reg, "");
|
|
1681
1755
|
objectId = objectName + "_" + bac_obj + "_" + pointProperty.objectId.instance;
|
|
1682
1756
|
|
|
1683
1757
|
try {
|
|
@@ -1708,7 +1782,8 @@ class BacnetClient extends EventEmitter {
|
|
|
1708
1782
|
if (object.value[0].value == 0) {
|
|
1709
1783
|
values[objectId].presentValue = values[objectId].stateTextArray[object.value[0].value].value;
|
|
1710
1784
|
} else if (object.value[0].value !== 0) {
|
|
1711
|
-
values[objectId].presentValue =
|
|
1785
|
+
values[objectId].presentValue =
|
|
1786
|
+
values[objectId].stateTextArray[object.value[0].value - 1].value;
|
|
1712
1787
|
}
|
|
1713
1788
|
}
|
|
1714
1789
|
} else if (objectType !== 8) {
|
|
@@ -1726,9 +1801,9 @@ class BacnetClient extends EventEmitter {
|
|
|
1726
1801
|
break;
|
|
1727
1802
|
case baEnum.PropertyIdentifier.OBJECT_NAME:
|
|
1728
1803
|
if (object.value[0] && object.value[0].value) {
|
|
1729
|
-
values[objectId].objectName = object.value[0].value.replace(reg,
|
|
1804
|
+
values[objectId].objectName = object.value[0].value.replace(reg, "");
|
|
1730
1805
|
if (!values[objectId].displayName) {
|
|
1731
|
-
values[objectId].displayName = object.value[0].value.replace(reg,
|
|
1806
|
+
values[objectId].displayName = object.value[0].value.replace(reg, "");
|
|
1732
1807
|
}
|
|
1733
1808
|
}
|
|
1734
1809
|
break;
|
|
@@ -1766,9 +1841,11 @@ class BacnetClient extends EventEmitter {
|
|
|
1766
1841
|
case baEnum.PropertyIdentifier.STATE_TEXT:
|
|
1767
1842
|
if (object.value) {
|
|
1768
1843
|
values[objectId].stateTextArray = object.value;
|
|
1769
|
-
if (
|
|
1844
|
+
if (
|
|
1845
|
+
typeof values[objectId].presentValue == "number" &&
|
|
1770
1846
|
values[objectId].presentValue !== null &&
|
|
1771
|
-
values[objectId].presentValue !== undefined
|
|
1847
|
+
values[objectId].presentValue !== undefined
|
|
1848
|
+
) {
|
|
1772
1849
|
const tempIndex = values[objectId].presentValue;
|
|
1773
1850
|
if (tempIndex == 0) {
|
|
1774
1851
|
values[objectId].presentValue = values[objectId].stateTextArray[tempIndex].value;
|