@bitpoolos/edge-bacnet 1.6.8 → 1.6.10
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 +32 -4
- package/bacnet_device.js +16 -15
- package/package.json +1 -1
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -41
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.6.10] - 01-07-2026
|
|
4
|
+
|
|
5
|
+
Bug fix:
|
|
6
|
+
|
|
7
|
+
- Packaging fix to ensure all required runtime files are included in the published package. Recommended upgrade for anyone on 1.6.9. Also carries the discovery fixes listed under 1.6.9.
|
|
8
|
+
|
|
9
|
+
## [1.6.9] - 01-07-2026
|
|
10
|
+
|
|
11
|
+
Bug fix:
|
|
12
|
+
|
|
13
|
+
- Recover missing points during discovery on small MSTP devices (e.g. RC FlexOne) that reject ReadProperty(ALL). When the "read all" attempt fails, discovery now tries a single targeted ReadPropertyMultiple for the required properties before falling back to per-property reads. This avoids the request storm that could cause the device to reject reads and silently drop Analog/Binary Output points from the model.
|
|
14
|
+
|
|
15
|
+
- Fixed object-type whitelist filter leaking non-whitelisted objects (e.g. trend-logs) into the model. A malformed object-list entry could throw and abort the filter, leaving the point list unfiltered. The filter is now null-safe, so it always applies and only whitelisted object types are kept.
|
|
16
|
+
|
|
17
|
+
- Added a discovery log when an object is dropped because no OBJECT_NAME was returned (read likely rejected), to aid diagnosis.
|
|
18
|
+
|
|
3
19
|
## [1.6.8] - 10-03-2026
|
|
4
20
|
|
|
5
21
|
Bug fix:
|
package/bacnet_client.js
CHANGED
|
@@ -1521,6 +1521,26 @@ class BacnetClient extends EventEmitter {
|
|
|
1521
1521
|
.catch(reject);
|
|
1522
1522
|
};
|
|
1523
1523
|
|
|
1524
|
+
// Targeted middle tier: request the needed properties in ONE ReadPropertyMultiple.
|
|
1525
|
+
// Used when ALL is rejected (e.g. RC FlexOne / small MSTP that don't support reading
|
|
1526
|
+
// the ALL pseudo-property). Same property set as the per-property fallback, so stored
|
|
1527
|
+
// data is identical - just one request instead of ~12. Falls through to the
|
|
1528
|
+
// per-property reads only if this targeted read also fails.
|
|
1529
|
+
const readTargetedMultiple = (resolve, reject) => {
|
|
1530
|
+
that
|
|
1531
|
+
._readObject(addressObject, type, instance, propertiesToRead, readOptions)
|
|
1532
|
+
.then((result) => {
|
|
1533
|
+
if (result.value) {
|
|
1534
|
+
resolve(result);
|
|
1535
|
+
} else {
|
|
1536
|
+
readPropertiesIndividually(resolve, reject);
|
|
1537
|
+
}
|
|
1538
|
+
})
|
|
1539
|
+
.catch(() => {
|
|
1540
|
+
readPropertiesIndividually(resolve, reject);
|
|
1541
|
+
});
|
|
1542
|
+
};
|
|
1543
|
+
|
|
1524
1544
|
return new Promise((resolve, reject) => {
|
|
1525
1545
|
// For Device objects (type 8), skip ALL attempt - many MSTP devices don't support it
|
|
1526
1546
|
// Go straight to reading individual properties for better reliability
|
|
@@ -1537,13 +1557,15 @@ class BacnetClient extends EventEmitter {
|
|
|
1537
1557
|
// If the result has value, resolve the promise
|
|
1538
1558
|
resolve(result);
|
|
1539
1559
|
} else {
|
|
1540
|
-
//
|
|
1541
|
-
|
|
1560
|
+
// ALL returned no value - try the targeted multi-property RPM before
|
|
1561
|
+
// falling back to the per-property storm.
|
|
1562
|
+
readTargetedMultiple(resolve, reject);
|
|
1542
1563
|
}
|
|
1543
1564
|
})
|
|
1544
1565
|
.catch(() => {
|
|
1545
|
-
//
|
|
1546
|
-
|
|
1566
|
+
// ALL errored - try the targeted multi-property RPM before falling back
|
|
1567
|
+
// to the per-property storm.
|
|
1568
|
+
readTargetedMultiple(resolve, reject);
|
|
1547
1569
|
});
|
|
1548
1570
|
});
|
|
1549
1571
|
}
|
|
@@ -2237,6 +2259,12 @@ class BacnetClient extends EventEmitter {
|
|
|
2237
2259
|
that.logOut("issue resolving bacnet payload, see error: ", e);
|
|
2238
2260
|
reject(e);
|
|
2239
2261
|
}
|
|
2262
|
+
} else {
|
|
2263
|
+
that.logOut(
|
|
2264
|
+
"[discovery] dropped " + bac_obj + ":" + pointProperty.objectId.instance +
|
|
2265
|
+
" on device " + device.getDeviceId() +
|
|
2266
|
+
" - no OBJECT_NAME returned (read likely rejected)"
|
|
2267
|
+
);
|
|
2240
2268
|
}
|
|
2241
2269
|
});
|
|
2242
2270
|
} else {
|
package/bacnet_device.js
CHANGED
|
@@ -268,10 +268,20 @@ class BacnetDevice {
|
|
|
268
268
|
}
|
|
269
269
|
|
|
270
270
|
setPointsList(newPoints) {
|
|
271
|
+
// Whitelisted object types kept in the model:
|
|
272
|
+
// DEVICE(8) AI(0) AO(1) AV(2) BI(3) BO(4) BV(5) MSI(13) MSO(14) MSV(19) CS(40)
|
|
273
|
+
const allowedTypes = new Set([8, 0, 1, 2, 3, 4, 5, 13, 14, 19, 40]);
|
|
274
|
+
|
|
271
275
|
for (let index = 0; index < newPoints.length; index++) {
|
|
272
276
|
let newPoint = newPoints[index];
|
|
273
|
-
|
|
274
|
-
|
|
277
|
+
// Guard against malformed entries (e.g. a bad object-list read with no .value):
|
|
278
|
+
// skip them here so they never enter pointsList and can't throw the dedup below.
|
|
279
|
+
if (newPoint && newPoint.value && newPoint.value.type !== undefined) {
|
|
280
|
+
let foundIndex = this.pointsList.findIndex(
|
|
281
|
+
ele => ele && ele.value &&
|
|
282
|
+
ele.value.type == newPoint.value.type &&
|
|
283
|
+
ele.value.instance == newPoint.value.instance
|
|
284
|
+
);
|
|
275
285
|
if (foundIndex == -1) {
|
|
276
286
|
//not found
|
|
277
287
|
this.pointsList.push(newPoint);
|
|
@@ -279,19 +289,10 @@ class BacnetDevice {
|
|
|
279
289
|
}
|
|
280
290
|
}
|
|
281
291
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
point.value.type == 2 || //AO
|
|
287
|
-
point.value.type == 3 || //BI
|
|
288
|
-
point.value.type == 4 || //BV
|
|
289
|
-
point.value.type == 5 || //BO
|
|
290
|
-
point.value.type == 13 || //MSI
|
|
291
|
-
point.value.type == 14 || //MSO
|
|
292
|
-
point.value.type == 19 || //MSV
|
|
293
|
-
point.value.type == 40 //CS
|
|
294
|
-
);
|
|
292
|
+
// Optional chaining so a malformed element is EXCLUDED (allowedTypes.has(undefined) === false)
|
|
293
|
+
// instead of throwing and aborting the filter, which previously left pointsList unfiltered
|
|
294
|
+
// and leaked non-whitelisted types (trend-logs etc.) into the model.
|
|
295
|
+
this.pointsList = this.pointsList.filter(point => allowedTypes.has(point?.value?.type));
|
|
295
296
|
}
|
|
296
297
|
|
|
297
298
|
getDevicePoints() {
|
package/package.json
CHANGED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: Bug report
|
|
3
|
-
about: Create a report to help us improve
|
|
4
|
-
title: ''
|
|
5
|
-
labels: ''
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
**Describe the bug**
|
|
10
|
-
A clear and concise description of what the bug is.
|
|
11
|
-
|
|
12
|
-
**To Reproduce**
|
|
13
|
-
Steps to reproduce the behavior:
|
|
14
|
-
1. Go to '...'
|
|
15
|
-
2. Click on '....'
|
|
16
|
-
3. Scroll down to '....'
|
|
17
|
-
4. See error
|
|
18
|
-
|
|
19
|
-
**Expected behavior**
|
|
20
|
-
A clear and concise description of what you expected to happen.
|
|
21
|
-
|
|
22
|
-
**Screenshots**
|
|
23
|
-
If applicable, add screenshots to help explain your problem.
|
|
24
|
-
|
|
25
|
-
**System Information (please complete the following information):**
|
|
26
|
-
- OS: [e.g. iOS]
|
|
27
|
-
- Browser [e.g. chrome, safari]
|
|
28
|
-
- Version [e.g. 1.2]
|
|
29
|
-
- Node-RED version:
|
|
30
|
-
- NodeJS version:
|
|
31
|
-
|
|
32
|
-
**Are you running Node-RED in a docker container or directly on the operating system or virtual machine?**
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
**Please provide a dump of the Node-RED error log with the Error logging and Device Found check box options enabled (found in _gateway_ node - _Discovery_ tab) if applicable:**
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
**Additional context**
|
|
41
|
-
Add any other context about the problem here.
|