@bitpoolos/edge-bacnet 1.6.3 → 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/bacnet_read.html CHANGED
@@ -131,10 +131,7 @@
131
131
  getData(initial) {
132
132
  let app = this;
133
133
  this.nodeService.getNetworkData().then(function (result) {
134
- //remove after below fixed
135
134
  app.devices = result.renderList;
136
- //end remove
137
-
138
135
  app.deviceList = result.deviceList;
139
136
  app.pointList = result.pointList;
140
137
  app.pollFrequency = parseInt(result.pollFrequency);
@@ -665,21 +662,24 @@
665
662
  // Find the device in the device list
666
663
  let device = app.getDeviceFromDeviceList(mstpDevice.ipAddr, mstpDevice.deviceId);
667
664
  if (device) {
668
- app.nodeService.updatePointsForDevice(device).then(function (result) {
669
- updatedCount++;
670
- }).catch(function (error) {
671
- // Handle error silently
672
- });
665
+ app.nodeService
666
+ .updatePointsForDevice(device)
667
+ .then(function (result) {
668
+ updatedCount++;
669
+ })
670
+ .catch(function (error) {
671
+ // Handle error silently
672
+ });
673
673
  }
674
674
  });
675
675
 
676
676
  // Show user feedback
677
677
  if (mstpDevices.length > 0) {
678
678
  app.$toast?.add({
679
- severity: 'info',
680
- summary: 'Update Started',
679
+ severity: "info",
680
+ summary: "Update Started",
681
681
  detail: `Updating points for ${mstpDevices.length} devices in ${slotProps.node.label}`,
682
- life: 3000
682
+ life: 3000,
683
683
  });
684
684
  }
685
685
  },
@@ -687,14 +687,14 @@
687
687
  let app = this;
688
688
  let device = app.getDeviceFromDeviceList(slotProps.node.ipAddr, slotProps.node.deviceId);
689
689
  if (device) {
690
- app.nodeService.purgeDevice(device).then(function (result) { });
690
+ app.nodeService.purgeDevice(device).then(function (result) {});
691
691
  }
692
692
  },
693
693
  updatePointsForDevice(slotProps) {
694
694
  let app = this;
695
695
  let device = app.getDeviceFromDeviceList(slotProps.node.ipAddr, slotProps.node.deviceId);
696
696
  if (device) {
697
- app.nodeService.updatePointsForDevice(device).then(function (result) { });
697
+ app.nodeService.updatePointsForDevice(device).then(function (result) {});
698
698
  }
699
699
  },
700
700
  updatePoint(slotProps) {
@@ -705,7 +705,7 @@
705
705
  });
706
706
  const deviceKey = `${app.getDeviceAddress(device.address)}-${device.deviceId}`;
707
707
  if (device) {
708
- app.nodeService.updatePoint(deviceKey, pointKey).then(function (result) { });
708
+ app.nodeService.updatePoint(deviceKey, pointKey).then(function (result) {});
709
709
  }
710
710
  },
711
711
  setDeviceName() {
@@ -765,27 +765,26 @@
765
765
  // NEW: Update display name in main devices tree
766
766
  updatePointDisplayNameInDevicesTree(deviceKey, pointName, newDisplayName) {
767
767
  let app = this;
768
- let [ipAddress, deviceId] = deviceKey.split('-');
768
+ let [ipAddress, deviceId] = deviceKey.split("-");
769
769
 
770
770
  // Find the device in main tree
771
- let deviceIndex = app.devices ? app.devices.findIndex(device =>
772
- device.ipAddr === ipAddress && device.deviceId.toString() === deviceId) : -1;
771
+ let deviceIndex = app.devices
772
+ ? app.devices.findIndex((device) => device.ipAddr === ipAddress && device.deviceId.toString() === deviceId)
773
+ : -1;
773
774
 
774
775
  if (deviceIndex !== -1) {
775
776
  // Update direct device points
776
- let pointIndex = app.devices[deviceIndex].children[0].children.findIndex(point =>
777
- point.pointName === pointName);
777
+ let pointIndex = app.devices[deviceIndex].children[0].children.findIndex((point) => point.pointName === pointName);
778
778
  if (pointIndex !== -1) {
779
779
  app.devices[deviceIndex].children[0].children[pointIndex].label = newDisplayName;
780
780
  }
781
781
 
782
782
  // Update MSTP device points if applicable
783
- app.devices[deviceIndex].children.forEach(child => {
783
+ app.devices[deviceIndex].children.forEach((child) => {
784
784
  if (child.label && child.label.includes("MSTP") && child.children) {
785
- child.children.forEach(mstpDevice => {
785
+ child.children.forEach((mstpDevice) => {
786
786
  if (mstpDevice.deviceId.toString() === deviceId) {
787
- let mstpPointIndex = mstpDevice.children[0].children.findIndex(point =>
788
- point.pointName === pointName);
787
+ let mstpPointIndex = mstpDevice.children[0].children.findIndex((point) => point.pointName === pointName);
789
788
  if (mstpPointIndex !== -1) {
790
789
  mstpDevice.children[0].children[mstpPointIndex].label = newDisplayName;
791
790
  }
@@ -798,17 +797,17 @@
798
797
  // NEW: Update display name in read devices tree
799
798
  updatePointDisplayNameInReadDevicesTree(deviceKey, pointName, newDisplayName) {
800
799
  let app = this;
801
- let [ipAddress, deviceId] = deviceKey.split('-');
800
+ let [ipAddress, deviceId] = deviceKey.split("-");
802
801
 
803
802
  if (!app.readDevices) return;
804
803
 
805
804
  // Find the device in read devices tree
806
- let readDeviceIndex = app.readDevices.findIndex(device =>
807
- device.deviceId.toString() === deviceId);
805
+ let readDeviceIndex = app.readDevices.findIndex((device) => device.deviceId.toString() === deviceId);
808
806
 
809
807
  if (readDeviceIndex !== -1) {
810
- let pointIndex = app.readDevices[readDeviceIndex].children[0].children.findIndex(point =>
811
- point.pointName === pointName);
808
+ let pointIndex = app.readDevices[readDeviceIndex].children[0].children.findIndex(
809
+ (point) => point.pointName === pointName
810
+ );
812
811
  if (pointIndex !== -1) {
813
812
  app.readDevices[readDeviceIndex].children[0].children[pointIndex].label = newDisplayName;
814
813
  }
@@ -1097,7 +1096,6 @@
1097
1096
  let count = 0;
1098
1097
  return count;
1099
1098
  },
1100
-
1101
1099
  },
1102
1100
  components: {
1103
1101
  "p-tree": primevue.tree,
@@ -1399,7 +1397,6 @@
1399
1397
  filterMode="lenient"
1400
1398
  filterPlaceholder="No results found."
1401
1399
  v-if="hasData()">
1402
-
1403
1400
  <template #device="slotProps">
1404
1401
  <div @contextmenu="onDeviceRightClick(slotProps, $event)" class="p-treenode-label">
1405
1402
  <div v-if="isDeviceActive(slotProps)" class="deviceLabelParent">
@@ -1439,13 +1436,12 @@
1439
1436
  </div>
1440
1437
  </template>
1441
1438
 
1442
-
1443
1439
  <template #mstpfolder="slotProps">
1444
1440
  <div @contextmenu="onMstpFolderRightClick(slotProps, $event)" class="p-treenode-label">
1445
1441
  <div class="deviceLabelParent">
1446
1442
  <b class="mstpLabel">
1447
1443
  <span>{{slotProps.node.label}}</span>
1448
- <span class="mstpDeviceCount" >
1444
+ <span class="mstpDeviceCount">
1449
1445
  &nbsp; {{slotProps.node.children ? slotProps.node.children.length : 0}} &nbsp;
1450
1446
  </span>
1451
1447
  </b>
@@ -1473,7 +1469,6 @@
1473
1469
  </button>
1474
1470
  </div>
1475
1471
  </template>
1476
-
1477
1472
  </p-tree>
1478
1473
  <div v-else style="text-align: center; padding-top: 20px;">
1479
1474
  <a>Building Tree...</a>
@@ -1713,4 +1708,4 @@
1713
1708
  <li><a href="https://wiki.bitpool.com/">wiki.bitpool.com</a> - find more documentation.</li>
1714
1709
  <li><a href="https://bacnet.org/">BACnet</a> - find more about the protocol.</li>
1715
1710
  </ul>
1716
- </script>
1711
+ </script>
package/common.js CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  const { randomUUID } = require("crypto");
6
6
  const os = require("os");
7
+ const path = require("path");
7
8
  const baEnum = require("./resources/node-bacstack-ts/dist/index.js").enum;
8
9
  const fs = require("fs");
9
10
  const fs2 = require("fs").promises;
@@ -189,27 +190,16 @@ const roundDecimalPlaces = function (value, decimals) {
189
190
  return value;
190
191
  };
191
192
 
192
- // STORE CONFIG FUNCTION ==========================================================
193
- //
194
- // ================================================================================
195
-
196
- /*
197
-
198
- async function Store_Config(data) {
199
- try {
200
- await fs.writeFile("edge-bacnet-datastore.cfg", data, { encoding: "utf8", flag: "w" }, (err) => {
201
- if (err) {
202
- console.log("Store_Config writeFile error: ", err);
203
- }
204
- });
205
- } catch (e) {
206
- //do nothing
193
+ const getStoragePath = (fileName) => {
194
+ const storagePath = process.env.BACNET_STORAGE_PATH;
195
+ if (storagePath) {
196
+ if (!fs.existsSync(storagePath)) {
197
+ fs.mkdirSync(storagePath, { recursive: true });
198
+ }
199
+ return path.join(storagePath, fileName);
207
200
  }
208
- }
209
-
210
- */
211
-
212
- // refactor:
201
+ return fileName;
202
+ };
213
203
 
214
204
  let storeQueue = [];
215
205
  let isStoreProcessing = false;
@@ -235,9 +225,9 @@ async function queueConfigStore(data) {
235
225
  }
236
226
 
237
227
  async function Store_Config(data) {
238
- const mainFile = "edge-bacnet-datastore.cfg";
239
- const tempFile = "edge-bacnet-datastore.cfg.tmp";
240
- const backupFile = "edge-bacnet-datastore.cfg.bak";
228
+ const mainFile = getStoragePath("edge-bacnet-datastore.cfg");
229
+ const tempFile = getStoragePath("edge-bacnet-datastore.cfg.tmp");
230
+ const backupFile = getStoragePath("edge-bacnet-datastore.cfg.bak");
241
231
 
242
232
  try {
243
233
  // First validate the JSON to ensure it's valid before writing
@@ -295,54 +285,10 @@ async function Store_Config(data) {
295
285
  }
296
286
  }
297
287
 
298
- // READ CONFIG SYNC FUNCTION ======================================================
299
- //
300
- // ================================================================================
301
-
302
- function Read_Config_Sync() {
303
- const mainFile = "edge-bacnet-datastore.cfg";
304
- const backupFile = "edge-bacnet-datastore.cfg.bak";
305
- const defaultData = "{}";
306
-
307
- try {
308
- // Try to read the main file
309
- let data = fsSync.readFileSync(mainFile, { encoding: "utf8" });
310
-
311
- // Validate JSON
312
- try {
313
- JSON.parse(data);
314
- return data;
315
- } catch (jsonError) {
316
- console.error("Main file contains invalid JSON, attempting backup recovery");
317
-
318
- // Try to read backup file
319
- try {
320
- const backupData = fsSync.readFileSync(backupFile, { encoding: "utf8" });
321
- JSON.parse(backupData); // Validate backup JSON
322
-
323
- // Restore from backup
324
- fsSync.copyFileSync(backupFile, mainFile);
325
- console.log("Successfully restored from backup file");
326
- return backupData;
327
- } catch (backupError) {
328
- console.error("Backup recovery failed, creating new file");
329
- fsSync.writeFileSync(mainFile, defaultData, { encoding: "utf8" });
330
- return defaultData;
331
- }
332
- }
333
- } catch (error) {
334
- console.error("Error reading config:", error);
335
- fsSync.writeFileSync(mainFile, defaultData, { encoding: "utf8" });
336
- return defaultData;
337
- }
338
- }
339
-
340
- // refactor:
341
-
342
288
  async function Read_Config_Async() {
343
289
  // todo rename function, not using sync
344
- const mainFile = "edge-bacnet-datastore.cfg";
345
- const backupFile = "edge-bacnet-datastore.cfg.bak";
290
+ const mainFile = getStoragePath("edge-bacnet-datastore.cfg");
291
+ const backupFile = getStoragePath("edge-bacnet-datastore.cfg.bak");
346
292
  const defaultData = "{}";
347
293
 
348
294
  try {
@@ -366,15 +312,11 @@ async function Read_Config_Async() {
366
312
  await fs.copyFile(backupFile, mainFile);
367
313
  console.log("Successfully restored from backup file");
368
314
 
369
- console.log("log2");
370
-
371
315
  return backupData;
372
316
  } catch (backupError) {
373
317
  console.error("Backup recovery failed, creating new file");
374
318
  await Store_Config(defaultData);
375
319
 
376
- console.log("log3");
377
-
378
320
  return defaultData;
379
321
  }
380
322
  }
@@ -382,8 +324,6 @@ async function Read_Config_Async() {
382
324
  console.error("Error reading config:", error);
383
325
  await Store_Config(defaultData);
384
326
 
385
- console.log("log4");
386
-
387
327
  return defaultData;
388
328
  }
389
329
  }
@@ -393,7 +333,7 @@ async function Read_Config_Async() {
393
333
  // ================================================================================
394
334
  async function Store_Config_Server(data) {
395
335
  try {
396
- await fs.writeFile("edge-bacnet-server-datastore.cfg", data, (err) => {
336
+ await fs.writeFile(getStoragePath("edge-bacnet-server-datastore.cfg"), data, (err) => {
397
337
  if (err) {
398
338
  //console.log("Store_Config_Server writeFile error: ", err);
399
339
  }
@@ -407,7 +347,7 @@ async function Store_Config_Server(data) {
407
347
  function Read_Config_Sync_Server() {
408
348
  var data = "{}";
409
349
  try {
410
- data = fs.readFileSync("edge-bacnet-server-datastore.cfg", { encoding: "utf8", flag: "r" });
350
+ data = fs.readFileSync(getStoragePath("edge-bacnet-server-datastore.cfg"), { encoding: "utf8", flag: "r" });
411
351
  } catch (err) {
412
352
  if (err.errno == -4058) {
413
353
  data = "{}";
@@ -485,7 +425,6 @@ module.exports = {
485
425
  roundDecimalPlaces,
486
426
  queueConfigStore,
487
427
  Store_Config,
488
- Read_Config_Sync,
489
428
  Read_Config_Async,
490
429
  Store_Config_Server,
491
430
  Read_Config_Sync_Server,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bitpoolos/edge-bacnet",
3
- "version": "1.6.3",
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",
@@ -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) {