@bitpoolos/edge-bacnet 1.4.3 → 1.4.4
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 +16 -0
- package/bacnet_client.js +60 -10
- package/bacnet_gateway.js +15 -0
- package/bacnet_read.js +69 -60
- package/package.json +1 -1
- package/treeBuilder.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.4.4] - 08-08-2024
|
|
4
|
+
### Summary
|
|
5
|
+
|
|
6
|
+
Minor updates.
|
|
7
|
+
|
|
8
|
+
Added device details to meta property when full object property type is selected.
|
|
9
|
+
|
|
10
|
+
Implemented applyDisplayName feature. Triggered via:
|
|
11
|
+
```javascript
|
|
12
|
+
applyDisplayNames = true
|
|
13
|
+
```
|
|
14
|
+
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.
|
|
15
|
+
|
|
16
|
+
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.
|
|
17
|
+
|
|
18
|
+
|
|
3
19
|
## [1.4.3] - 01-08-2024
|
|
4
20
|
### Summary
|
|
5
21
|
|
package/bacnet_client.js
CHANGED
|
@@ -375,16 +375,39 @@ class BacnetClient extends EventEmitter {
|
|
|
375
375
|
});
|
|
376
376
|
}
|
|
377
377
|
|
|
378
|
+
applyDisplayNames(pointsToRead) {
|
|
379
|
+
let that = this;
|
|
380
|
+
return new Promise((resolve, reject) => {
|
|
381
|
+
try {
|
|
382
|
+
for (let key in pointsToRead) {
|
|
383
|
+
let deviceModel = that.findDeviceByKey(key);
|
|
384
|
+
let device = pointsToRead[key];
|
|
385
|
+
for (let pointName in device) {
|
|
386
|
+
let pointObject = device[pointName];
|
|
387
|
+
if (pointName == "deviceName") {
|
|
388
|
+
deviceModel.setDisplayName(pointObject);
|
|
389
|
+
}
|
|
390
|
+
if (that.networkTree[key][pointName]) {
|
|
391
|
+
that.networkTree[key][pointName] = pointObject;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
resolve(true);
|
|
397
|
+
} catch (e) {
|
|
398
|
+
that.logOut("applyDisplayNames error: ", e);
|
|
399
|
+
reject(e);
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
|
|
378
404
|
setDeviceDisplayName(deviceObject, displayName) {
|
|
379
405
|
let that = this;
|
|
380
406
|
return new Promise((resolve, reject) => {
|
|
381
407
|
try {
|
|
382
408
|
let device = that.deviceList.find((ele) => ele.getDeviceId() == deviceObject.deviceId);
|
|
383
|
-
|
|
384
409
|
device.setDisplayName(displayName);
|
|
385
|
-
|
|
386
410
|
that.buildTreeException = true;
|
|
387
|
-
|
|
388
411
|
resolve(true);
|
|
389
412
|
} catch (e) {
|
|
390
413
|
that.logOut("setDeviceDisplayName error: ", e);
|
|
@@ -401,9 +424,7 @@ class BacnetClient extends EventEmitter {
|
|
|
401
424
|
if (that.networkTree[deviceKey][pointName]) {
|
|
402
425
|
that.networkTree[deviceKey][pointName].displayName = pointDisplayName;
|
|
403
426
|
}
|
|
404
|
-
|
|
405
427
|
that.buildTreeException = true;
|
|
406
|
-
|
|
407
428
|
resolve(true);
|
|
408
429
|
} catch (e) {
|
|
409
430
|
that.logOut("setPointDisplayName error: ", e);
|
|
@@ -414,11 +435,9 @@ class BacnetClient extends EventEmitter {
|
|
|
414
435
|
|
|
415
436
|
importReadList(payload) {
|
|
416
437
|
let that = this;
|
|
417
|
-
|
|
418
438
|
return new Promise((resolve, reject) => {
|
|
419
439
|
try {
|
|
420
440
|
that.buildTreeException = true;
|
|
421
|
-
|
|
422
441
|
for (let key in payload) {
|
|
423
442
|
let device = payload[key];
|
|
424
443
|
for (let pointName in device) {
|
|
@@ -617,8 +636,9 @@ class BacnetClient extends EventEmitter {
|
|
|
617
636
|
return newProps;
|
|
618
637
|
}
|
|
619
638
|
|
|
620
|
-
findDeviceByKey(key
|
|
621
|
-
|
|
639
|
+
findDeviceByKey(key) {
|
|
640
|
+
let that = this;
|
|
641
|
+
return that.deviceList.find(ele => `${that.getDeviceAddress(ele)}-${ele.getDeviceId()}` === key);
|
|
622
642
|
}
|
|
623
643
|
|
|
624
644
|
getObjectId(pointName, pointConfig, that) {
|
|
@@ -652,7 +672,7 @@ class BacnetClient extends EventEmitter {
|
|
|
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);
|
|
@@ -730,6 +750,14 @@ class BacnetClient extends EventEmitter {
|
|
|
730
750
|
throw results.error;
|
|
731
751
|
}
|
|
732
752
|
|
|
753
|
+
let deviceMetaInfo = {
|
|
754
|
+
"address": device.getAddress(),
|
|
755
|
+
"isMstp": device.getIsMstpDevice(),
|
|
756
|
+
"deviceId": device.getDeviceId(),
|
|
757
|
+
"vendorId": device.getVendorId(),
|
|
758
|
+
"deviceName": deviceName
|
|
759
|
+
};
|
|
760
|
+
|
|
733
761
|
// Process the results of the batch
|
|
734
762
|
results.value.values.forEach(pointResult => {
|
|
735
763
|
const cacheRef = requestArray.find(ele =>
|
|
@@ -759,6 +787,7 @@ class BacnetClient extends EventEmitter {
|
|
|
759
787
|
}
|
|
760
788
|
}
|
|
761
789
|
|
|
790
|
+
pointRef.meta["device"] = deviceMetaInfo;
|
|
762
791
|
pointRef.timestamp = Date.now();
|
|
763
792
|
pointRef.status = "online";
|
|
764
793
|
|
|
@@ -769,9 +798,18 @@ class BacnetClient extends EventEmitter {
|
|
|
769
798
|
} catch (err) {
|
|
770
799
|
that.logOut("Error processing batch:", err);
|
|
771
800
|
|
|
801
|
+
let deviceMetaInfo = {
|
|
802
|
+
"address": device.getAddress(),
|
|
803
|
+
"isMstp": device.getIsMstpDevice(),
|
|
804
|
+
"deviceId": device.getDeviceId(),
|
|
805
|
+
"vendorId": device.getVendorId(),
|
|
806
|
+
"deviceName": deviceName
|
|
807
|
+
};
|
|
808
|
+
|
|
772
809
|
requestArray.forEach(request => {
|
|
773
810
|
let pointRef = request.pointRef;
|
|
774
811
|
pointRef.status = "offline";
|
|
812
|
+
pointRef.meta["device"] = deviceMetaInfo;
|
|
775
813
|
|
|
776
814
|
bacnetResults[deviceName][request.pointName] = pointRef;
|
|
777
815
|
});
|
|
@@ -780,6 +818,14 @@ class BacnetClient extends EventEmitter {
|
|
|
780
818
|
}
|
|
781
819
|
|
|
782
820
|
async processIndividualPoints(device, requestArray, deviceName, bacnetResults, that, roundDecimal) {
|
|
821
|
+
let deviceMetaInfo = {
|
|
822
|
+
"address": device.getAddress(),
|
|
823
|
+
"isMstp": device.getIsMstpDevice(),
|
|
824
|
+
"deviceId": device.getDeviceId(),
|
|
825
|
+
"vendorId": device.getVendorId(),
|
|
826
|
+
"deviceName": deviceName
|
|
827
|
+
};
|
|
828
|
+
|
|
783
829
|
for (const request of requestArray) {
|
|
784
830
|
const { objectId, pointRef, pointName } = request;
|
|
785
831
|
try {
|
|
@@ -792,11 +838,15 @@ class BacnetClient extends EventEmitter {
|
|
|
792
838
|
pointRef.presentValue = val;
|
|
793
839
|
}
|
|
794
840
|
|
|
841
|
+
pointRef.meta["device"] = deviceMetaInfo;
|
|
842
|
+
|
|
795
843
|
// Store the point data in results
|
|
796
844
|
bacnetResults[deviceName][pointName] = pointRef;
|
|
797
845
|
} catch (err) {
|
|
798
846
|
that.logOut(`Error updating point ${pointName}:`, err);
|
|
799
847
|
|
|
848
|
+
pointRef.meta["device"] = deviceMetaInfo;
|
|
849
|
+
|
|
800
850
|
pointRef.status = "offline";
|
|
801
851
|
bacnetResults[deviceName][pointName] = pointRef;
|
|
802
852
|
}
|
package/bacnet_gateway.js
CHANGED
|
@@ -226,6 +226,21 @@ module.exports = function (RED) {
|
|
|
226
226
|
});
|
|
227
227
|
} else if (msg.testFunc == true) {
|
|
228
228
|
node.bacnetClient.testFunction(msg.address, msg.type, msg.instance, msg.property);
|
|
229
|
+
} else if (msg.applyDisplayNames) {
|
|
230
|
+
|
|
231
|
+
node.status({ fill: "blue", shape: "dot", text: "Updating display names" });
|
|
232
|
+
|
|
233
|
+
setTimeout(() => {
|
|
234
|
+
node.status({});
|
|
235
|
+
}, 2000);
|
|
236
|
+
|
|
237
|
+
node.bacnetClient
|
|
238
|
+
.applyDisplayNames(msg.pointsToRead)
|
|
239
|
+
.then(function (result) {
|
|
240
|
+
}).catch(function (error) {
|
|
241
|
+
logOut("Error in applyDisplayNames: ", error);
|
|
242
|
+
});
|
|
243
|
+
|
|
229
244
|
}
|
|
230
245
|
});
|
|
231
246
|
|
package/bacnet_read.js
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
module.exports = function (RED) {
|
|
8
|
-
const http = require("http");
|
|
9
8
|
const { ReadCommandConfig } = require('./common');
|
|
10
9
|
const baEnum = require('./resources/node-bacstack-ts/dist/index.js').enum;
|
|
11
10
|
|
|
@@ -54,72 +53,82 @@ module.exports = function (RED) {
|
|
|
54
53
|
};
|
|
55
54
|
|
|
56
55
|
node.on('input', function (msg) {
|
|
57
|
-
node.status({ fill: "blue", shape: "dot", text: "Reading values" });
|
|
58
|
-
|
|
59
|
-
let object_property_simplePayload = false;
|
|
60
|
-
let object_property_simpleWithStatus = false;
|
|
61
|
-
let object_property_fullObject = false;
|
|
62
|
-
|
|
63
|
-
let jsonType = false;
|
|
64
|
-
let mqttType = false;
|
|
65
|
-
let pointJsonType = false;
|
|
66
|
-
let useDeviceName = false;
|
|
67
|
-
|
|
68
|
-
if (msg.simplePayload) {
|
|
69
|
-
object_property_simplePayload = msg.simplePayload;
|
|
70
|
-
} else if (msg.simpleWithStatus) {
|
|
71
|
-
object_property_simpleWithStatus = msg.simpleWithStatus;
|
|
72
|
-
} else if (msg.fullObject) {
|
|
73
|
-
object_property_fullObject = msg.fullObject;
|
|
74
|
-
} else {
|
|
75
|
-
object_property_simplePayload = node.object_property_simplePayload;
|
|
76
|
-
object_property_simpleWithStatus = node.object_property_simpleWithStatus;
|
|
77
|
-
object_property_fullObject = node.object_property_fullObject;
|
|
78
|
-
}
|
|
79
56
|
|
|
80
|
-
if (msg.
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
} else if (msg.pointJson) {
|
|
85
|
-
pointJsonType = msg.pointJson;
|
|
86
|
-
} else {
|
|
87
|
-
jsonType = node.json;
|
|
88
|
-
mqttType = node.mqtt;
|
|
89
|
-
pointJsonType = node.pointJson
|
|
90
|
-
}
|
|
57
|
+
if (msg.applyDisplayNames) {
|
|
58
|
+
|
|
59
|
+
msg.pointsToRead = node.pointsToRead;
|
|
60
|
+
node.send(msg);
|
|
91
61
|
|
|
92
|
-
if (msg.useDeviceName) {
|
|
93
|
-
useDeviceName = msg.useDeviceName;
|
|
94
62
|
} else {
|
|
95
|
-
useDeviceName = node.useDeviceName;
|
|
96
|
-
}
|
|
97
63
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
64
|
+
node.status({ fill: "blue", shape: "dot", text: "Reading values" });
|
|
65
|
+
|
|
66
|
+
let object_property_simplePayload = false;
|
|
67
|
+
let object_property_simpleWithStatus = false;
|
|
68
|
+
let object_property_fullObject = false;
|
|
69
|
+
|
|
70
|
+
let jsonType = false;
|
|
71
|
+
let mqttType = false;
|
|
72
|
+
let pointJsonType = false;
|
|
73
|
+
let useDeviceName = false;
|
|
74
|
+
|
|
75
|
+
if (msg.simplePayload) {
|
|
76
|
+
object_property_simplePayload = msg.simplePayload;
|
|
77
|
+
} else if (msg.simpleWithStatus) {
|
|
78
|
+
object_property_simpleWithStatus = msg.simpleWithStatus;
|
|
79
|
+
} else if (msg.fullObject) {
|
|
80
|
+
object_property_fullObject = msg.fullObject;
|
|
81
|
+
} else {
|
|
82
|
+
object_property_simplePayload = node.object_property_simplePayload;
|
|
83
|
+
object_property_simpleWithStatus = node.object_property_simpleWithStatus;
|
|
84
|
+
object_property_fullObject = node.object_property_fullObject;
|
|
115
85
|
}
|
|
116
|
-
};
|
|
117
86
|
|
|
118
|
-
|
|
87
|
+
if (msg.json) {
|
|
88
|
+
jsonType = msg.json;
|
|
89
|
+
} else if (msg.mqtt) {
|
|
90
|
+
mqttType = msg.mqtt;
|
|
91
|
+
} else if (msg.pointJson) {
|
|
92
|
+
pointJsonType = msg.pointJson;
|
|
93
|
+
} else {
|
|
94
|
+
jsonType = node.json;
|
|
95
|
+
mqttType = node.mqtt;
|
|
96
|
+
pointJsonType = node.pointJson
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (msg.useDeviceName) {
|
|
100
|
+
useDeviceName = msg.useDeviceName;
|
|
101
|
+
} else {
|
|
102
|
+
useDeviceName = node.useDeviceName;
|
|
103
|
+
}
|
|
119
104
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
105
|
+
let readConfig = new ReadCommandConfig(node.pointsToRead, node.object_props, node.roundDecimal);
|
|
106
|
+
|
|
107
|
+
let output = {
|
|
108
|
+
type: "Read",
|
|
109
|
+
id: node.id,
|
|
110
|
+
readNodeName: node.nodeName,
|
|
111
|
+
options: readConfig,
|
|
112
|
+
objectPropertyType: {
|
|
113
|
+
simplePayload: object_property_simplePayload,
|
|
114
|
+
simpleWithStatus: object_property_simpleWithStatus,
|
|
115
|
+
fullObject: object_property_fullObject
|
|
116
|
+
},
|
|
117
|
+
outputType: {
|
|
118
|
+
json: jsonType,
|
|
119
|
+
mqtt: mqttType,
|
|
120
|
+
pointJson: pointJsonType,
|
|
121
|
+
useDeviceName: useDeviceName
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
node.send(output);
|
|
126
|
+
|
|
127
|
+
setTimeout(() => {
|
|
128
|
+
node.status({});
|
|
129
|
+
}, 3000);
|
|
130
|
+
|
|
131
|
+
}
|
|
123
132
|
|
|
124
133
|
});
|
|
125
134
|
|
package/package.json
CHANGED
package/treeBuilder.js
CHANGED
|
@@ -63,7 +63,6 @@ class treeBuilder {
|
|
|
63
63
|
// Check if the device object exists and the device name is valid
|
|
64
64
|
if (deviceObject) {
|
|
65
65
|
await this.processDevicePoints(device, deviceObject, deviceName, ipAddress, deviceId, index);
|
|
66
|
-
|
|
67
66
|
} else {
|
|
68
67
|
//console.log("Unable to find device object");
|
|
69
68
|
}
|