@bitpoolos/edge-bacnet 1.6.4 → 1.6.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 CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.6.5] - 09-10-2025
4
+
5
+ Bug fix:
6
+
7
+ - Specific users found issues of spiking values. Results after a read query are now force ordered. An adjustment made to the bacnet stack _getInvokeId function as it was running out of array space to process a high volume of request responses.
8
+
9
+
3
10
  ## [1.6.4] - 02-09-2025
4
11
 
5
12
  Minor feature:
package/bacnet_client.js CHANGED
@@ -827,16 +827,12 @@ class BacnetClient extends EventEmitter {
827
827
  };
828
828
 
829
829
  // Process the results of the batch
830
- results.value.values.forEach((pointResult) => {
831
- const cacheRef = requestArray.find(
832
- (ele) =>
833
- ele.pointRef.meta.objectId.type === pointResult.objectId.type &&
834
- ele.pointRef.meta.objectId.instance === pointResult.objectId.instance
835
- );
830
+ results.value.values.forEach((pointResult, index) => {
831
+ const cacheRef = requestArray[index];
832
+ const pointRef = cacheRef.pointRef;
833
+ const pointNameRef = cacheRef.pointName;
836
834
 
837
- if (cacheRef) {
838
- const pointRef = cacheRef.pointRef;
839
- const pointNameRef = cacheRef.pointName;
835
+ if (pointResult.values[0].value.length > 0) {
840
836
  const val = pointResult.values[0].value[0].value;
841
837
 
842
838
  if (isNumber(val)) {
@@ -865,13 +861,12 @@ class BacnetClient extends EventEmitter {
865
861
  pointRef.status = "online";
866
862
  }
867
863
  }
868
-
869
- pointRef.meta["device"] = deviceMetaInfo;
870
- pointRef.timestamp = Date.now();
871
-
872
- // Store the point data in results
873
- bacnetResults[deviceName][pointNameRef] = pointRef;
874
864
  }
865
+ pointRef.meta["device"] = deviceMetaInfo;
866
+ pointRef.timestamp = Date.now();
867
+
868
+ // Store the point data in results
869
+ bacnetResults[deviceName][pointNameRef] = pointRef;
875
870
  });
876
871
  } catch (err) {
877
872
  that.logOut("Error processing batch:", err);
@@ -1217,6 +1212,32 @@ class BacnetClient extends EventEmitter {
1217
1212
  };
1218
1213
  return new Promise((resolve, reject) => {
1219
1214
  that.client.readPropertyMultiple(addressObject, requestArray, readOptions, (error, value) => {
1215
+ if (value && value.values) {
1216
+ const reorderedValues = requestArray.map((req) => {
1217
+ const foundValue = value.values.find(
1218
+ (val) => val.objectId.type === req.objectId.type && val.objectId.instance === req.objectId.instance
1219
+ );
1220
+ return (
1221
+ foundValue || {
1222
+ objectId: req.objectId,
1223
+ values: [
1224
+ {
1225
+ value: [
1226
+ {
1227
+ value: {
1228
+ errorClass: baEnum.ErrorClass.PROPERTY,
1229
+ errorCode: baEnum.ErrorCode.UNKNOWN_PROPERTY,
1230
+ },
1231
+ },
1232
+ ],
1233
+ },
1234
+ ],
1235
+ }
1236
+ );
1237
+ });
1238
+ value.values = reorderedValues;
1239
+ }
1240
+
1220
1241
  resolve({
1221
1242
  error: error,
1222
1243
  value: value,
package/bacnet_gateway.js CHANGED
@@ -212,14 +212,10 @@ module.exports = function (RED) {
212
212
  }
213
213
  }
214
214
 
215
- if (
216
- node.bacnetServerEnabled == true &&
217
- node.bacnetClient &&
218
- node.bacnetServer
219
- ) {
215
+ if (node.bacnetServerEnabled == true && node.bacnetClient && node.bacnetServer) {
220
216
  try {
221
217
  // Clean up any existing listeners to prevent stale references
222
- node.bacnetServer.removeAllListeners('writeProperty');
218
+ node.bacnetServer.removeAllListeners("writeProperty");
223
219
 
224
220
  // Store the event handler function so we can clean it up later
225
221
  node.writePropertyHandler = (topic, newValue) => {
@@ -269,7 +265,7 @@ module.exports = function (RED) {
269
265
  } else if (msg.doUpdatePriorityDevices == true && msg.priorityDevices !== null) {
270
266
  node.bacnetClient
271
267
  .updatePriorityQueue(msg.priorityDevices)
272
- .then(function (result) { })
268
+ .then(function (result) {})
273
269
  .catch(function (error) {
274
270
  logOut("Error updating priorityQueue: ", error);
275
271
  });
@@ -283,7 +279,7 @@ module.exports = function (RED) {
283
279
 
284
280
  node.bacnetClient
285
281
  .applyDisplayNames(msg.pointsToRead)
286
- .then(function (result) { })
282
+ .then(function (result) {})
287
283
  .catch(function (error) {
288
284
  logOut("Error in applyDisplayNames: ", error);
289
285
  });
@@ -306,7 +302,7 @@ module.exports = function (RED) {
306
302
  node.on("close", function () {
307
303
  // Clean up the writeProperty event listener
308
304
  if (node.bacnetServer && node.writePropertyHandler) {
309
- node.bacnetServer.removeListener('writeProperty', node.writePropertyHandler);
305
+ node.bacnetServer.removeListener("writeProperty", node.writePropertyHandler);
310
306
  node.writePropertyHandler = null;
311
307
  }
312
308
 
@@ -794,7 +790,6 @@ module.exports = function (RED) {
794
790
  if (points[point] && "presentValue" in points[point]) {
795
791
  let pointName = getPointName(points[point], point);
796
792
  let topic = getTopicString("sendSimpleWithStatus", useDeviceName, readNodeName, device, pointName);
797
-
798
793
  msgg.topic = topic;
799
794
  let payload = {
800
795
  presentValue: points[point]["presentValue"],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bitpoolos/edge-bacnet",
3
- "version": "1.6.4",
3
+ "version": "1.6.5",
4
4
  "description": "A bacnet gateway for node-red",
5
5
  "dependencies": {
6
6
  "@plus4nodered/ts-node-bacnet": "^1.0.0-beta.2",
@@ -54,4 +54,4 @@
54
54
  "type": "github",
55
55
  "url": "git+https://github.com/bitpool/edge-bacnet.git"
56
56
  }
57
- }
57
+ }
@@ -67,9 +67,23 @@ class Client extends events_1.EventEmitter {
67
67
  }
68
68
  // Helper utils
69
69
  _getInvokeId() {
70
+ // Try up to 256 times to find an unused invoke ID
71
+ for (let attempts = 0; attempts < 256; attempts++) {
72
+ const id = this._invokeCounter++;
73
+ if (id >= 256) this._invokeCounter = 1;
74
+
75
+ const invokeId = id - 1;
76
+
77
+ // If this invoke ID is not currently in use, return it
78
+ if (!this._invokeStore[invokeId]) {
79
+ return invokeId;
80
+ }
81
+ }
82
+
83
+ // Edge case: if all 256 invoke IDs are in use, fall back to original behavior
84
+ // This prevents infinite loops while maintaining backwards compatibility
70
85
  const id = this._invokeCounter++;
71
- if (id >= 256)
72
- this._invokeCounter = 1;
86
+ if (id >= 256) this._invokeCounter = 1;
73
87
  return id - 1;
74
88
  }
75
89
  _invokeCallback(id, err, result) {