@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/CHANGELOG.md +113 -84
- package/bacnet_client.js +41 -35
- package/bacnet_gateway.js +5 -10
- package/bacnet_read.html +29 -34
- package/common.js +17 -78
- package/package.json +1 -1
- package/resources/node-bacstack-ts/dist/lib/client.js +16 -2
- package/treeBuilder.js +668 -627
package/CHANGELOG.md
CHANGED
|
@@ -1,65 +1,87 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [1.6.
|
|
3
|
+
## [1.6.5] - 09-10-2025
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
+
|
|
10
|
+
## [1.6.4] - 02-09-2025
|
|
11
|
+
|
|
12
|
+
Minor feature:
|
|
13
|
+
|
|
14
|
+
- Small update to file read / write logic for database files. Some deployments require a different storage location outside of the default. If a nodejs environment variable of BACNET_STORAGE_PATH is defined and set for that deployment, it will prefix that location to the file path, otherwise functionality will remain the same.
|
|
15
|
+
|
|
16
|
+
Bug fix:
|
|
17
|
+
|
|
18
|
+
- Some mstp devices were not showing in device list UI tree.
|
|
19
|
+
|
|
20
|
+
## [1.6.3] - 01-06-2025
|
|
21
|
+
|
|
22
|
+
Minor feature:
|
|
23
|
+
|
|
24
|
+
- Device List - new right click option to MSTP NET folders - Update All Devices. Specifically updates the mstp device listed in that selected network
|
|
25
|
+
- Inspector - Added statistic percentages as MQTT output in the Inspector node
|
|
26
|
+
- Inspector - Added online / offline stats and Total points to read as status on node
|
|
27
|
+
- Test Functions - Outputs results to both node-red console and node-red debug window now
|
|
10
28
|
|
|
11
29
|
Minor update / refactor:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
30
|
+
|
|
31
|
+
- Datamodel - Importing and Exporting datamodel displays process status and related stats (file size etc) while importing or exporting, informing the user of current state
|
|
32
|
+
- Device List - UI tree no longer stored in datamodel, as it is generated dynamically on a schedule. This significantly reduces datamodel file size, read / write time, system start up processes.
|
|
33
|
+
- Datamodel - writes to file system for persistance and backup was being executed more often than needed. Process schedule is now on a larger interval, and write algorithm refactored and optimized.
|
|
34
|
+
- Device List - right click -> Set Point Name feature refactored, due to many scenarios where it wasnt executing as expected.
|
|
35
|
+
- BACnet read output - error and status field setting optimized
|
|
36
|
+
- Inspector - updated ObjectType column values to show object type enum string instead of integer
|
|
18
37
|
|
|
19
38
|
Bug fixes:
|
|
20
|
-
- Inspector - incorrect percentages, statistics and values in the statistics bar. Fixed and tested to represent site status more accurately
|
|
21
|
-
- Inpsector - not flagging offline points in error statistic and table filter. Now correctly identifies "offline" points as an Error type
|
|
22
|
-
- BACnet read output - was not updating error and status correctly for full object payloads.
|
|
23
|
-
- BACnet Server - was not outputting sucessfull write update MQTT msg after node-red deploy.
|
|
24
39
|
|
|
25
|
-
|
|
26
|
-
|
|
40
|
+
- Inspector - incorrect percentages, statistics and values in the statistics bar. Fixed and tested to represent site status more accurately
|
|
41
|
+
- Inpsector - not flagging offline points in error statistic and table filter. Now correctly identifies "offline" points as an Error type
|
|
42
|
+
- BACnet read output - was not updating error and status correctly for full object payloads.
|
|
43
|
+
- BACnet Server - was not outputting sucessfull write update MQTT msg after node-red deploy.
|
|
44
|
+
|
|
45
|
+
Updating:
|
|
27
46
|
|
|
47
|
+
- There shouldnt be a need for users to remove nodes or do any specific action when updating to this version, however backing up a datamodel export is advised.
|
|
28
48
|
|
|
29
49
|
## [1.6.2] - 07-05-2025
|
|
30
50
|
|
|
31
|
-
Minor feature:
|
|
32
|
-
- Added "Enable device discovery" check box to gateway settings, discovery tab.
|
|
33
|
-
- This check box controls whether on not the auto point discovery and property discovery is enabled.
|
|
34
|
-
- This can be used to turn off unecessary network traffic once you have discovered all of the desired devices and points.
|
|
35
|
-
- IMPORTANT - if you are updating a existing deployment, the new property will be unticked, however new installs / dragging from the pallete will by default have the option checked. So if you want to keep this enabled on an existing deployment, please check the setting.
|
|
36
|
-
- Note - This does not turn off the whoIs task schedule.
|
|
37
|
-
- A user can use Right Click -> Update points on desired deviced in the read node tree if you would like to manually discover devices.
|
|
51
|
+
Minor feature:
|
|
38
52
|
|
|
39
|
-
|
|
40
|
-
-
|
|
53
|
+
- Added "Enable device discovery" check box to gateway settings, discovery tab.
|
|
54
|
+
- This check box controls whether on not the auto point discovery and property discovery is enabled.
|
|
55
|
+
- This can be used to turn off unecessary network traffic once you have discovered all of the desired devices and points.
|
|
56
|
+
- IMPORTANT - if you are updating a existing deployment, the new property will be unticked, however new installs / dragging from the pallete will by default have the option checked. So if you want to keep this enabled on an existing deployment, please check the setting.
|
|
57
|
+
- Note - This does not turn off the whoIs task schedule.
|
|
58
|
+
- A user can use Right Click -> Update points on desired deviced in the read node tree if you would like to manually discover devices.
|
|
41
59
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
- NAN years ago - removed as invalid time differential
|
|
48
|
-
- Last seen for device points adjusted to be more accurate
|
|
60
|
+
Minor update:
|
|
61
|
+
|
|
62
|
+
- Adjusted initial whoIs broadcast delay from 5seconds to 15seconds after node-red is started with a deployed gateway. This is to ensure large cached files are completely read and loaded.
|
|
63
|
+
|
|
64
|
+
Bug fixes:
|
|
49
65
|
|
|
50
|
-
|
|
66
|
+
- Inspector:
|
|
67
|
+
- Table resized to avoid scroll bars
|
|
68
|
+
- Percentage rounding to nearest 2 decimal places rather than whole integer for more detailed data.
|
|
69
|
+
- Loading animation added
|
|
70
|
+
- NAN years ago - removed as invalid time differential
|
|
71
|
+
- Last seen for device points adjusted to be more accurate
|
|
51
72
|
|
|
52
73
|
## [1.6.1] - 14-04-2025
|
|
53
74
|
|
|
54
|
-
Bug fixes:
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
75
|
+
Bug fixes:
|
|
76
|
+
|
|
77
|
+
- Inspector stats were calculating incorrectly in certain scenarios
|
|
78
|
+
- Inspector downloaded HTML files had incorrect stat percentages
|
|
79
|
+
- Inspector Last_Polled_Time stat was always "UNKNOWN", now shows correct date time.
|
|
58
80
|
|
|
59
|
-
Minor updates:
|
|
60
|
-
- Inspector BACnet main stats now output on msg.type = getBacnetStats inject. Can be set on a scheduled inject.
|
|
61
|
-
- Updated Examples with Inspector
|
|
81
|
+
Minor updates:
|
|
62
82
|
|
|
83
|
+
- Inspector BACnet main stats now output on msg.type = getBacnetStats inject. Can be set on a scheduled inject.
|
|
84
|
+
- Updated Examples with Inspector
|
|
63
85
|
|
|
64
86
|
## [1.6.0] - 09-04-2025
|
|
65
87
|
|
|
@@ -75,93 +97,99 @@ New features:
|
|
|
75
97
|
- API routes available:
|
|
76
98
|
|
|
77
99
|
- /inspector
|
|
100
|
+
|
|
78
101
|
- view UI in web browser
|
|
79
102
|
|
|
80
103
|
- /inspector-downloadhtml
|
|
104
|
+
|
|
81
105
|
- downloads the html of the inspector in its current state
|
|
82
106
|
|
|
83
107
|
- /inspector-downloadhtml?filter=tableKey&value=value1,value2
|
|
84
|
-
|
|
85
|
-
-
|
|
108
|
+
|
|
109
|
+
- downloads the html of the inspector, but with a applied filter to the table.
|
|
110
|
+
- tableKey in the above example can be any of the table columns, only 1 tableKey may be filtered on:
|
|
86
111
|
deviceID, objectType, objectInstance, presentValue, dataModelStatus, pointName, discoveredBACnetPointName, displayName, deviceName, ipAddress, area, key, topic, lastSeen, error
|
|
87
112
|
- value=value1,value2 etc can be any value that the tableKey can contain. This parameter can accept many comma separated values
|
|
88
|
-
- an example filter request may look like:
|
|
113
|
+
- an example filter request may look like:
|
|
89
114
|
/inspector-downloadhtml?filter=dataModelStatus&value=error,missing
|
|
90
115
|
|
|
91
116
|
- /getModelStats
|
|
117
|
+
|
|
92
118
|
- returns JSON data with analysis of the BACnet model
|
|
93
119
|
- contains point status, metrics, and detailed information
|
|
94
120
|
|
|
95
121
|
- /pointstoread
|
|
122
|
+
|
|
96
123
|
- downloads CSV file with all points in the read list
|
|
97
124
|
- format: [siteName]_PointsToRead_[timestamp].csv
|
|
98
125
|
|
|
99
126
|
- /getpointerrors
|
|
100
127
|
- downloads CSV file with all points that have errors
|
|
101
128
|
- format: [siteName]_PointErrors_[timestamp].csv
|
|
102
|
-
|
|
103
129
|
- /getmodelstatscsv
|
|
104
130
|
- downloads CSV file with all model stats data in CSV format
|
|
105
131
|
- format: [siteName]_ModelStats_[timestamp].csv
|
|
106
|
-
|
|
107
132
|
- /publishedpointslist
|
|
133
|
+
|
|
108
134
|
- downloads CSV file with all published points and their current values
|
|
109
135
|
- format: [siteName]_PublishedPointsList_[timestamp].csv
|
|
110
136
|
- outputs mqtt topic and payloads with statistics about the current state of the bacnet network
|
|
111
137
|
- output topics:
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
- Additional input options:
|
|
138
|
+
EDGE*DEVICE*{IP*ID}/STATUS/LAST_POINT_PUSHED_TIME
|
|
139
|
+
payload: Timestamp of when the last point was pushed (ISO string)
|
|
140
|
+
EDGE_DEVICE*{IP*ID}/STATUS/LAST_STAT_CALC_TIME
|
|
141
|
+
payload: Current timestamp (ISO string)
|
|
142
|
+
EDGE_DEVICE*{IP*ID}/STATUS/UPTIME
|
|
143
|
+
payload: System uptime formatted as string (e.g., "Uptime: 3 days, 5 hours, 12 minutes, 45 seconds")
|
|
144
|
+
EDGE_DEVICE*{IP*ID}/STATUS/ONLINE_POINTS
|
|
145
|
+
payload: Number of online points
|
|
146
|
+
EDGE_DEVICE*{IP*ID}/STATUS/OFFLINE_POINTS
|
|
147
|
+
payload: Number of offline points
|
|
148
|
+
EDGE_DEVICE*{IP*ID}/STATUS/TOTAL_POLLED_POINTS
|
|
149
|
+
payload: Total number of polled points
|
|
150
|
+
EDGE_DEVICE*{IP*ID}/STATUS/AVERAGE_TIME_SINCE_COV_IN_SECONDS
|
|
151
|
+
payload: Average time since last change of value in seconds
|
|
152
|
+
EDGE_DEVICE*{IP*ID}/STATUS/TOTAL_POINTS_TO_READ
|
|
153
|
+
payload: Total number of points to read
|
|
154
|
+
EDGE_DEVICE*{IP*ID}/STATUS/DISCOVERED_POINT_COUNT
|
|
155
|
+
payload: Number of discovered points
|
|
156
|
+
EDGE_DEVICE*{IP_ID}/STATUS/DISCOVERED_DEVICE_COUNT
|
|
157
|
+
payload: Number of discovered devices
|
|
158
|
+
|
|
159
|
+
where {IP_ID} is the IP address of the device with periods removed (e.g., 192.168.1.100 becomes 192168110).
|
|
160
|
+
each of these topics includes the site name as a tag in the message metadata with format geoAddr={siteName}.
|
|
161
|
+
|
|
162
|
+
- Additional input options:
|
|
163
|
+
|
|
137
164
|
- reset - resets the complete data model used for all of the inspector analytics
|
|
165
|
+
|
|
138
166
|
- msg input format: msg.reset = true
|
|
139
167
|
|
|
140
168
|
- sendMqttStats - outputs additional mqtt statistics
|
|
141
|
-
|
|
142
|
-
-
|
|
143
|
-
|
|
169
|
+
|
|
170
|
+
- msg input format: msg.type = sendMqttStats
|
|
171
|
+
- output topics:
|
|
172
|
+
EDGE*DEVICE*{siteName}/BACNETSTATS/ok
|
|
144
173
|
payload: Number of points with OK status
|
|
145
|
-
|
|
174
|
+
EDGE*DEVICE*{siteName}/BACNETSTATS/error
|
|
146
175
|
payload: Number of points with error status
|
|
147
|
-
|
|
176
|
+
EDGE*DEVICE*{siteName}/BACNETSTATS/missing
|
|
148
177
|
payload: Number of missing points
|
|
149
|
-
|
|
178
|
+
EDGE*DEVICE*{siteName}/BACNETSTATS/warnings
|
|
150
179
|
payload: Number of points with warnings
|
|
151
|
-
|
|
180
|
+
EDGE*DEVICE*{siteName}/BACNETSTATS/moved
|
|
152
181
|
payload: Number of points that have moved (e.g changed object instance)
|
|
153
|
-
|
|
182
|
+
EDGE*DEVICE*{siteName}/BACNETSTATS/deviceIdChange
|
|
154
183
|
payload: Number of points with changed device IDs
|
|
155
|
-
|
|
184
|
+
EDGE*DEVICE*{siteName}/BACNETSTATS/deviceIdConflict
|
|
156
185
|
payload: Number of points with conflicting device IDs
|
|
157
|
-
|
|
186
|
+
EDGE*DEVICE*{siteName}/BACNETSTATS/unmapped
|
|
158
187
|
payload: Number of unmapped points
|
|
159
|
-
|
|
188
|
+
EDGE*DEVICE*{siteName}/BACNETSTATS/offlinePercentage
|
|
160
189
|
payload: Percentage of points that are offline
|
|
161
190
|
|
|
162
191
|
where {siteName} is the site name configured in the inspector node.
|
|
163
192
|
|
|
164
|
-
|
|
165
193
|
- Right click -> Update Point on a individual point in the device tree. (Read node UI)
|
|
166
194
|
|
|
167
195
|
- Added programmatic reinitialize/clear points on BACnet server via injecting { msg.reinitializeBacnetServer: true } into the gateway node. Optionally can include a msg.responseTopic string to get a confrimation published to that topic output from the gateway node on sucessfull reinitialize.
|
|
@@ -184,6 +212,7 @@ New features:
|
|
|
184
212
|
Refactor:
|
|
185
213
|
|
|
186
214
|
- Reading and Writing to the cache file of the datamodel.
|
|
215
|
+
|
|
187
216
|
- write operations are now locked to 1 operation at a time
|
|
188
217
|
- a rolling secondary backup file is now created, which can be used in case of corruption of the primary file
|
|
189
218
|
|
package/bacnet_client.js
CHANGED
|
@@ -11,7 +11,6 @@ const {
|
|
|
11
11
|
parseBacnetError,
|
|
12
12
|
getBacnetErrorString,
|
|
13
13
|
Read_Config_Async,
|
|
14
|
-
Read_Config_Sync,
|
|
15
14
|
isNumber,
|
|
16
15
|
decodeBitArray,
|
|
17
16
|
} = require("./common");
|
|
@@ -20,7 +19,6 @@ const { BacnetDevice } = require("./bacnet_device");
|
|
|
20
19
|
const { Mutex } = require("async-mutex");
|
|
21
20
|
const { treeBuilder } = require("./treeBuilder.js");
|
|
22
21
|
|
|
23
|
-
|
|
24
22
|
class BacnetClient extends EventEmitter {
|
|
25
23
|
//client constructor
|
|
26
24
|
constructor(config) {
|
|
@@ -43,7 +41,6 @@ class BacnetClient extends EventEmitter {
|
|
|
43
41
|
that.portRangeMatrix = config.portRangeMatrix;
|
|
44
42
|
|
|
45
43
|
try {
|
|
46
|
-
|
|
47
44
|
that.roundDecimal = config.roundDecimal;
|
|
48
45
|
that.apduSize = config.apduSize;
|
|
49
46
|
that.maxSegments = config.maxSegments;
|
|
@@ -118,13 +115,11 @@ class BacnetClient extends EventEmitter {
|
|
|
118
115
|
}
|
|
119
116
|
}, "4000");
|
|
120
117
|
}, "15000");
|
|
121
|
-
|
|
122
118
|
} catch (e) {
|
|
123
119
|
that.logOut("Issue initializing client: ", e);
|
|
124
120
|
}
|
|
125
121
|
|
|
126
122
|
try {
|
|
127
|
-
|
|
128
123
|
//who is callback
|
|
129
124
|
that.client.on("iAm", (device) => {
|
|
130
125
|
if (device.address !== that.config.localIpAdrress) {
|
|
@@ -791,7 +786,7 @@ class BacnetClient extends EventEmitter {
|
|
|
791
786
|
deviceName,
|
|
792
787
|
results: bacnetResults,
|
|
793
788
|
deviceIndex: deviceIndex + 1,
|
|
794
|
-
totalDevices: devicesToRead.length
|
|
789
|
+
totalDevices: devicesToRead.length,
|
|
795
790
|
};
|
|
796
791
|
});
|
|
797
792
|
|
|
@@ -799,27 +794,18 @@ class BacnetClient extends EventEmitter {
|
|
|
799
794
|
const results = await Promise.allSettled(devicePromises);
|
|
800
795
|
|
|
801
796
|
results.forEach((result, index) => {
|
|
802
|
-
if (result.status ===
|
|
797
|
+
if (result.status === "fulfilled" && result.value) {
|
|
803
798
|
completedDevices++;
|
|
804
799
|
const { deviceName, results: bacnetResults, deviceIndex, totalDevices } = result.value;
|
|
805
800
|
|
|
806
801
|
// Emit the `values` event for this device immediately
|
|
807
|
-
that.emit(
|
|
808
|
-
"values",
|
|
809
|
-
bacnetResults,
|
|
810
|
-
outputType,
|
|
811
|
-
objectPropertyType,
|
|
812
|
-
readNodeName,
|
|
813
|
-
completedDevices,
|
|
814
|
-
totalDevices
|
|
815
|
-
);
|
|
802
|
+
that.emit("values", bacnetResults, outputType, objectPropertyType, readNodeName, completedDevices, totalDevices);
|
|
816
803
|
} else {
|
|
817
804
|
// Handle failed device (offline/error)
|
|
818
805
|
completedDevices++;
|
|
819
806
|
that.logOut(`Device ${devicesToRead[index]} failed:`, result.reason);
|
|
820
807
|
}
|
|
821
808
|
});
|
|
822
|
-
|
|
823
809
|
} catch (error) {
|
|
824
810
|
that.logOut("doRead error: ", error);
|
|
825
811
|
}
|
|
@@ -841,16 +827,12 @@ class BacnetClient extends EventEmitter {
|
|
|
841
827
|
};
|
|
842
828
|
|
|
843
829
|
// Process the results of the batch
|
|
844
|
-
results.value.values.forEach((pointResult) => {
|
|
845
|
-
const cacheRef = requestArray
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
ele.pointRef.meta.objectId.instance === pointResult.objectId.instance
|
|
849
|
-
);
|
|
830
|
+
results.value.values.forEach((pointResult, index) => {
|
|
831
|
+
const cacheRef = requestArray[index];
|
|
832
|
+
const pointRef = cacheRef.pointRef;
|
|
833
|
+
const pointNameRef = cacheRef.pointName;
|
|
850
834
|
|
|
851
|
-
if (
|
|
852
|
-
const pointRef = cacheRef.pointRef;
|
|
853
|
-
const pointNameRef = cacheRef.pointName;
|
|
835
|
+
if (pointResult.values[0].value.length > 0) {
|
|
854
836
|
const val = pointResult.values[0].value[0].value;
|
|
855
837
|
|
|
856
838
|
if (isNumber(val)) {
|
|
@@ -879,13 +861,12 @@ class BacnetClient extends EventEmitter {
|
|
|
879
861
|
pointRef.status = "online";
|
|
880
862
|
}
|
|
881
863
|
}
|
|
882
|
-
|
|
883
|
-
pointRef.meta["device"] = deviceMetaInfo;
|
|
884
|
-
pointRef.timestamp = Date.now();
|
|
885
|
-
|
|
886
|
-
// Store the point data in results
|
|
887
|
-
bacnetResults[deviceName][pointNameRef] = pointRef;
|
|
888
864
|
}
|
|
865
|
+
pointRef.meta["device"] = deviceMetaInfo;
|
|
866
|
+
pointRef.timestamp = Date.now();
|
|
867
|
+
|
|
868
|
+
// Store the point data in results
|
|
869
|
+
bacnetResults[deviceName][pointNameRef] = pointRef;
|
|
889
870
|
});
|
|
890
871
|
} catch (err) {
|
|
891
872
|
that.logOut("Error processing batch:", err);
|
|
@@ -905,7 +886,6 @@ class BacnetClient extends EventEmitter {
|
|
|
905
886
|
for (const request of requestArray) {
|
|
906
887
|
const { objectId, pointRef, pointName } = request;
|
|
907
888
|
try {
|
|
908
|
-
|
|
909
889
|
const result = await that.updatePoint(device, pointRef);
|
|
910
890
|
|
|
911
891
|
if (result.objectId.type == objectId.type && result.objectId.instance == objectId.instance) {
|
|
@@ -1005,7 +985,7 @@ class BacnetClient extends EventEmitter {
|
|
|
1005
985
|
|
|
1006
986
|
return true;
|
|
1007
987
|
} catch (e) {
|
|
1008
|
-
throw e
|
|
988
|
+
throw e;
|
|
1009
989
|
}
|
|
1010
990
|
}
|
|
1011
991
|
|
|
@@ -1031,7 +1011,7 @@ class BacnetClient extends EventEmitter {
|
|
|
1031
1011
|
let settings = {
|
|
1032
1012
|
maxSegments: maxSegments,
|
|
1033
1013
|
maxApdu: maxApdu,
|
|
1034
|
-
}
|
|
1014
|
+
};
|
|
1035
1015
|
|
|
1036
1016
|
return new Promise((resolve, reject) => {
|
|
1037
1017
|
that.client.readProperty(
|
|
@@ -1232,6 +1212,32 @@ class BacnetClient extends EventEmitter {
|
|
|
1232
1212
|
};
|
|
1233
1213
|
return new Promise((resolve, reject) => {
|
|
1234
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
|
+
|
|
1235
1241
|
resolve({
|
|
1236
1242
|
error: error,
|
|
1237
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(
|
|
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(
|
|
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"],
|