@bitpoolos/edge-bacnet 1.6.3 → 1.6.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 +106 -84
- package/bacnet_client.js +5 -20
- package/bacnet_read.html +29 -34
- package/common.js +17 -78
- package/package.json +2 -2
- package/treeBuilder.js +668 -627
package/CHANGELOG.md
CHANGED
|
@@ -1,65 +1,80 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [1.6.
|
|
3
|
+
## [1.6.4] - 02-09-2025
|
|
4
4
|
|
|
5
|
-
Minor feature:
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
Minor feature:
|
|
6
|
+
|
|
7
|
+
- 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.
|
|
8
|
+
|
|
9
|
+
Bug fix:
|
|
10
|
+
|
|
11
|
+
- Some mstp devices were not showing in device list UI tree.
|
|
12
|
+
|
|
13
|
+
## [1.6.3] - 01-06-2025
|
|
14
|
+
|
|
15
|
+
Minor feature:
|
|
16
|
+
|
|
17
|
+
- Device List - new right click option to MSTP NET folders - Update All Devices. Specifically updates the mstp device listed in that selected network
|
|
18
|
+
- Inspector - Added statistic percentages as MQTT output in the Inspector node
|
|
19
|
+
- Inspector - Added online / offline stats and Total points to read as status on node
|
|
20
|
+
- Test Functions - Outputs results to both node-red console and node-red debug window now
|
|
10
21
|
|
|
11
22
|
Minor update / refactor:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
23
|
+
|
|
24
|
+
- Datamodel - Importing and Exporting datamodel displays process status and related stats (file size etc) while importing or exporting, informing the user of current state
|
|
25
|
+
- 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.
|
|
26
|
+
- 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.
|
|
27
|
+
- Device List - right click -> Set Point Name feature refactored, due to many scenarios where it wasnt executing as expected.
|
|
28
|
+
- BACnet read output - error and status field setting optimized
|
|
29
|
+
- Inspector - updated ObjectType column values to show object type enum string instead of integer
|
|
18
30
|
|
|
19
31
|
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
32
|
|
|
25
|
-
|
|
26
|
-
|
|
33
|
+
- Inspector - incorrect percentages, statistics and values in the statistics bar. Fixed and tested to represent site status more accurately
|
|
34
|
+
- Inpsector - not flagging offline points in error statistic and table filter. Now correctly identifies "offline" points as an Error type
|
|
35
|
+
- BACnet read output - was not updating error and status correctly for full object payloads.
|
|
36
|
+
- BACnet Server - was not outputting sucessfull write update MQTT msg after node-red deploy.
|
|
27
37
|
|
|
38
|
+
Updating:
|
|
39
|
+
|
|
40
|
+
- 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
41
|
|
|
29
42
|
## [1.6.2] - 07-05-2025
|
|
30
43
|
|
|
31
|
-
Minor feature:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
44
|
+
Minor feature:
|
|
45
|
+
|
|
46
|
+
- Added "Enable device discovery" check box to gateway settings, discovery tab.
|
|
47
|
+
- This check box controls whether on not the auto point discovery and property discovery is enabled.
|
|
48
|
+
- This can be used to turn off unecessary network traffic once you have discovered all of the desired devices and points.
|
|
49
|
+
- 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.
|
|
50
|
+
- Note - This does not turn off the whoIs task schedule.
|
|
51
|
+
- A user can use Right Click -> Update points on desired deviced in the read node tree if you would like to manually discover devices.
|
|
52
|
+
|
|
53
|
+
Minor update:
|
|
38
54
|
|
|
39
|
-
|
|
40
|
-
- 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.
|
|
55
|
+
- 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.
|
|
41
56
|
|
|
42
|
-
Bug fixes:
|
|
43
|
-
- Inspector:
|
|
44
|
-
- Table resized to avoid scroll bars
|
|
45
|
-
- Percentage rounding to nearest 2 decimal places rather than whole integer for more detailed data.
|
|
46
|
-
- Loading animation added
|
|
47
|
-
- NAN years ago - removed as invalid time differential
|
|
48
|
-
- Last seen for device points adjusted to be more accurate
|
|
57
|
+
Bug fixes:
|
|
49
58
|
|
|
50
|
-
|
|
59
|
+
- Inspector:
|
|
60
|
+
- Table resized to avoid scroll bars
|
|
61
|
+
- Percentage rounding to nearest 2 decimal places rather than whole integer for more detailed data.
|
|
62
|
+
- Loading animation added
|
|
63
|
+
- NAN years ago - removed as invalid time differential
|
|
64
|
+
- Last seen for device points adjusted to be more accurate
|
|
51
65
|
|
|
52
66
|
## [1.6.1] - 14-04-2025
|
|
53
67
|
|
|
54
|
-
Bug fixes:
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
68
|
+
Bug fixes:
|
|
69
|
+
|
|
70
|
+
- Inspector stats were calculating incorrectly in certain scenarios
|
|
71
|
+
- Inspector downloaded HTML files had incorrect stat percentages
|
|
72
|
+
- Inspector Last_Polled_Time stat was always "UNKNOWN", now shows correct date time.
|
|
58
73
|
|
|
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
|
|
74
|
+
Minor updates:
|
|
62
75
|
|
|
76
|
+
- Inspector BACnet main stats now output on msg.type = getBacnetStats inject. Can be set on a scheduled inject.
|
|
77
|
+
- Updated Examples with Inspector
|
|
63
78
|
|
|
64
79
|
## [1.6.0] - 09-04-2025
|
|
65
80
|
|
|
@@ -75,93 +90,99 @@ New features:
|
|
|
75
90
|
- API routes available:
|
|
76
91
|
|
|
77
92
|
- /inspector
|
|
93
|
+
|
|
78
94
|
- view UI in web browser
|
|
79
95
|
|
|
80
96
|
- /inspector-downloadhtml
|
|
97
|
+
|
|
81
98
|
- downloads the html of the inspector in its current state
|
|
82
99
|
|
|
83
100
|
- /inspector-downloadhtml?filter=tableKey&value=value1,value2
|
|
84
|
-
|
|
85
|
-
-
|
|
101
|
+
|
|
102
|
+
- downloads the html of the inspector, but with a applied filter to the table.
|
|
103
|
+
- tableKey in the above example can be any of the table columns, only 1 tableKey may be filtered on:
|
|
86
104
|
deviceID, objectType, objectInstance, presentValue, dataModelStatus, pointName, discoveredBACnetPointName, displayName, deviceName, ipAddress, area, key, topic, lastSeen, error
|
|
87
105
|
- 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:
|
|
106
|
+
- an example filter request may look like:
|
|
89
107
|
/inspector-downloadhtml?filter=dataModelStatus&value=error,missing
|
|
90
108
|
|
|
91
109
|
- /getModelStats
|
|
110
|
+
|
|
92
111
|
- returns JSON data with analysis of the BACnet model
|
|
93
112
|
- contains point status, metrics, and detailed information
|
|
94
113
|
|
|
95
114
|
- /pointstoread
|
|
115
|
+
|
|
96
116
|
- downloads CSV file with all points in the read list
|
|
97
117
|
- format: [siteName]_PointsToRead_[timestamp].csv
|
|
98
118
|
|
|
99
119
|
- /getpointerrors
|
|
100
120
|
- downloads CSV file with all points that have errors
|
|
101
121
|
- format: [siteName]_PointErrors_[timestamp].csv
|
|
102
|
-
|
|
103
122
|
- /getmodelstatscsv
|
|
104
123
|
- downloads CSV file with all model stats data in CSV format
|
|
105
124
|
- format: [siteName]_ModelStats_[timestamp].csv
|
|
106
|
-
|
|
107
125
|
- /publishedpointslist
|
|
126
|
+
|
|
108
127
|
- downloads CSV file with all published points and their current values
|
|
109
128
|
- format: [siteName]_PublishedPointsList_[timestamp].csv
|
|
110
129
|
- outputs mqtt topic and payloads with statistics about the current state of the bacnet network
|
|
111
130
|
- 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:
|
|
131
|
+
EDGE*DEVICE*{IP*ID}/STATUS/LAST_POINT_PUSHED_TIME
|
|
132
|
+
payload: Timestamp of when the last point was pushed (ISO string)
|
|
133
|
+
EDGE_DEVICE*{IP*ID}/STATUS/LAST_STAT_CALC_TIME
|
|
134
|
+
payload: Current timestamp (ISO string)
|
|
135
|
+
EDGE_DEVICE*{IP*ID}/STATUS/UPTIME
|
|
136
|
+
payload: System uptime formatted as string (e.g., "Uptime: 3 days, 5 hours, 12 minutes, 45 seconds")
|
|
137
|
+
EDGE_DEVICE*{IP*ID}/STATUS/ONLINE_POINTS
|
|
138
|
+
payload: Number of online points
|
|
139
|
+
EDGE_DEVICE*{IP*ID}/STATUS/OFFLINE_POINTS
|
|
140
|
+
payload: Number of offline points
|
|
141
|
+
EDGE_DEVICE*{IP*ID}/STATUS/TOTAL_POLLED_POINTS
|
|
142
|
+
payload: Total number of polled points
|
|
143
|
+
EDGE_DEVICE*{IP*ID}/STATUS/AVERAGE_TIME_SINCE_COV_IN_SECONDS
|
|
144
|
+
payload: Average time since last change of value in seconds
|
|
145
|
+
EDGE_DEVICE*{IP*ID}/STATUS/TOTAL_POINTS_TO_READ
|
|
146
|
+
payload: Total number of points to read
|
|
147
|
+
EDGE_DEVICE*{IP*ID}/STATUS/DISCOVERED_POINT_COUNT
|
|
148
|
+
payload: Number of discovered points
|
|
149
|
+
EDGE_DEVICE*{IP_ID}/STATUS/DISCOVERED_DEVICE_COUNT
|
|
150
|
+
payload: Number of discovered devices
|
|
151
|
+
|
|
152
|
+
where {IP_ID} is the IP address of the device with periods removed (e.g., 192.168.1.100 becomes 192168110).
|
|
153
|
+
each of these topics includes the site name as a tag in the message metadata with format geoAddr={siteName}.
|
|
154
|
+
|
|
155
|
+
- Additional input options:
|
|
156
|
+
|
|
137
157
|
- reset - resets the complete data model used for all of the inspector analytics
|
|
158
|
+
|
|
138
159
|
- msg input format: msg.reset = true
|
|
139
160
|
|
|
140
161
|
- sendMqttStats - outputs additional mqtt statistics
|
|
141
|
-
|
|
142
|
-
-
|
|
143
|
-
|
|
162
|
+
|
|
163
|
+
- msg input format: msg.type = sendMqttStats
|
|
164
|
+
- output topics:
|
|
165
|
+
EDGE*DEVICE*{siteName}/BACNETSTATS/ok
|
|
144
166
|
payload: Number of points with OK status
|
|
145
|
-
|
|
167
|
+
EDGE*DEVICE*{siteName}/BACNETSTATS/error
|
|
146
168
|
payload: Number of points with error status
|
|
147
|
-
|
|
169
|
+
EDGE*DEVICE*{siteName}/BACNETSTATS/missing
|
|
148
170
|
payload: Number of missing points
|
|
149
|
-
|
|
171
|
+
EDGE*DEVICE*{siteName}/BACNETSTATS/warnings
|
|
150
172
|
payload: Number of points with warnings
|
|
151
|
-
|
|
173
|
+
EDGE*DEVICE*{siteName}/BACNETSTATS/moved
|
|
152
174
|
payload: Number of points that have moved (e.g changed object instance)
|
|
153
|
-
|
|
175
|
+
EDGE*DEVICE*{siteName}/BACNETSTATS/deviceIdChange
|
|
154
176
|
payload: Number of points with changed device IDs
|
|
155
|
-
|
|
177
|
+
EDGE*DEVICE*{siteName}/BACNETSTATS/deviceIdConflict
|
|
156
178
|
payload: Number of points with conflicting device IDs
|
|
157
|
-
|
|
179
|
+
EDGE*DEVICE*{siteName}/BACNETSTATS/unmapped
|
|
158
180
|
payload: Number of unmapped points
|
|
159
|
-
|
|
181
|
+
EDGE*DEVICE*{siteName}/BACNETSTATS/offlinePercentage
|
|
160
182
|
payload: Percentage of points that are offline
|
|
161
183
|
|
|
162
184
|
where {siteName} is the site name configured in the inspector node.
|
|
163
185
|
|
|
164
|
-
|
|
165
186
|
- Right click -> Update Point on a individual point in the device tree. (Read node UI)
|
|
166
187
|
|
|
167
188
|
- 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 +205,7 @@ New features:
|
|
|
184
205
|
Refactor:
|
|
185
206
|
|
|
186
207
|
- Reading and Writing to the cache file of the datamodel.
|
|
208
|
+
|
|
187
209
|
- write operations are now locked to 1 operation at a time
|
|
188
210
|
- a rolling secondary backup file is now created, which can be used in case of corruption of the primary file
|
|
189
211
|
|
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
|
}
|
|
@@ -905,7 +891,6 @@ class BacnetClient extends EventEmitter {
|
|
|
905
891
|
for (const request of requestArray) {
|
|
906
892
|
const { objectId, pointRef, pointName } = request;
|
|
907
893
|
try {
|
|
908
|
-
|
|
909
894
|
const result = await that.updatePoint(device, pointRef);
|
|
910
895
|
|
|
911
896
|
if (result.objectId.type == objectId.type && result.objectId.instance == objectId.instance) {
|
|
@@ -1005,7 +990,7 @@ class BacnetClient extends EventEmitter {
|
|
|
1005
990
|
|
|
1006
991
|
return true;
|
|
1007
992
|
} catch (e) {
|
|
1008
|
-
throw e
|
|
993
|
+
throw e;
|
|
1009
994
|
}
|
|
1010
995
|
}
|
|
1011
996
|
|
|
@@ -1031,7 +1016,7 @@ class BacnetClient extends EventEmitter {
|
|
|
1031
1016
|
let settings = {
|
|
1032
1017
|
maxSegments: maxSegments,
|
|
1033
1018
|
maxApdu: maxApdu,
|
|
1034
|
-
}
|
|
1019
|
+
};
|
|
1035
1020
|
|
|
1036
1021
|
return new Promise((resolve, reject) => {
|
|
1037
1022
|
that.client.readProperty(
|
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
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
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:
|
|
680
|
-
summary:
|
|
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
|
|
772
|
-
device.ipAddr === ipAddress && device.deviceId.toString() === deviceId)
|
|
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(
|
|
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
|
{{slotProps.node.children ? slotProps.node.children.length : 0}}
|
|
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>
|