@bitpoolos/edge-bacnet 1.6.0 → 1.6.1

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,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.6.1] - 14-04-2025
4
+
5
+ Bug fixes:
6
+ - Inspector stats were calculating incorrectly in certain scenarios
7
+ - Inspector downloaded HTML files had incorrect stat percentages
8
+ - Inspector Last_Polled_Time stat was always "UNKNOWN", now shows correct date time.
9
+
10
+ Minor updates:
11
+ - Inspector BACnet main stats now output on msg.type = getBacnetStats inject. Can be set on a scheduled inject.
12
+ - Updated Examples with Inspector
13
+
14
+
3
15
  ## [1.6.0] - 09-04-2025
4
16
 
5
17
  New features:
@@ -115,10 +115,6 @@ module.exports = function (RED) {
115
115
  this.batchInterval = setInterval(processBatch, BATCH_PROCESS_INTERVAL);
116
116
  this.syncInterval = setInterval(syncWithFlowContext, SYNC_INTERVAL);
117
117
 
118
- const debouncedGetBacnetStats = debounce((node, context, msg) => {
119
- getModelStats();
120
- }, 3000);
121
-
122
118
  // Function to sync cache to flow context
123
119
  function syncWithFlowContext() {
124
120
  const flow = context.flow;
@@ -187,7 +183,7 @@ module.exports = function (RED) {
187
183
 
188
184
  node.on("input", function (msg, send, done) {
189
185
  if (msg.type === "getBacnetStats") {
190
- processMessage(msg, send, done);
186
+ getPublishedPointsList();
191
187
  } else if (msg.type === "Read") {
192
188
  calculateCombinedReadList(node, msg);
193
189
  if (done) done();
@@ -197,7 +193,6 @@ module.exports = function (RED) {
197
193
  if (done) done();
198
194
  } else if (msg.payload && msg.topic) {
199
195
  //regular bacnet output
200
- debouncedGetBacnetStats(node, context, msg);
201
196
  // Queue the message for batch processing instead of immediate processing
202
197
  messageQueue.push({ msg, send, done });
203
198
  if (messageQueue.length >= MAX_BATCH_SIZE) {
@@ -218,6 +213,7 @@ module.exports = function (RED) {
218
213
  }
219
214
  if (done) done();
220
215
  });
216
+
221
217
  } else if (msg.reset === true) {
222
218
  node.status({ text: "Resetting..." });
223
219
 
@@ -249,17 +245,6 @@ module.exports = function (RED) {
249
245
  }
250
246
  });
251
247
 
252
- // Process individual messages that shouldn't be batched
253
- function processMessage(msg, send, done) {
254
- try {
255
- getBacnetStats(node, context, msg);
256
- if (done) done();
257
- } catch (error) {
258
- console.error("Error processing message:", error);
259
- if (done) done(error);
260
- }
261
- }
262
-
263
248
  // Process a batch of messages efficiently
264
249
  function processBatch() {
265
250
  if (messageQueue.length === 0) return;
@@ -293,6 +278,10 @@ module.exports = function (RED) {
293
278
 
294
279
  // Use cached data instead of flow context
295
280
  const now = new Date();
281
+ const flow = context.flow;
282
+
283
+ // Set the last point pushed time
284
+ flow.set("Last_Point_Pushed_Time", now.toISOString());
296
285
 
297
286
  // Process all messages in the batch
298
287
  messages.forEach((msg) => {
@@ -449,6 +438,13 @@ module.exports = function (RED) {
449
438
 
450
439
  // Update the node status
451
440
  node.status({ text: "Points Online: " + cachedData.onlineCount + "/" + cachedData.totalUniquePolledCount });
441
+
442
+ // Periodically call getModelStats to keep model stats updated
443
+ // Use a debounce pattern to avoid calling it too frequently
444
+ if (!processBatchData.lastModelStatsUpdate || (now - processBatchData.lastModelStatsUpdate) > 3000) {
445
+ getModelStats();
446
+ processBatchData.lastModelStatsUpdate = now;
447
+ }
452
448
  }
453
449
 
454
450
  //API Request Handlers Start
@@ -925,146 +921,6 @@ module.exports = function (RED) {
925
921
  return msg;
926
922
  }
927
923
 
928
- //calculates bacnet stats on correctly injected msg to inspector node
929
- //fired on every valid bacnet output
930
- function getBacnetStats(node, context, msg) {
931
- let flow = context.flow;
932
- let now = new Date(); // Create a new Date object
933
-
934
- // Initialize or retrieve the current list of unique topics and the count from the context context
935
- let uniqueTopics = flow.get("uniqueReadTopics") || [];
936
- let topicStatusMap = flow.get("topicStatusMap") || {}; // Store status per topic
937
- let topicDataMap = flow.get("topicDataMap") || {}; // Store presentValue, timestamp, and last value change time per topic
938
- let totalUniqueCount = flow.get("totalUniquePolledCount") || 0;
939
- let onlineCount = flow.get("onlineCount") || 0;
940
- let offlineCount = flow.get("offlineCount") || 0;
941
-
942
- flow.set("site_Name", node.siteName);
943
-
944
- // Calculate the IP address of the edge device
945
- var IP_Add = getIPAddresses(); // Get the IP address of the current device
946
- var IP_Str = "NA";
947
- if (IP_Add[0]) {
948
- IP_Str = IP_Add[0].replace(/\./g, "");
949
- } // If an IP address of the first network adapter exists remove the full stops
950
-
951
- // Get the current message's topic, status, presentValue, and timestamp
952
- let topic = msg.topic;
953
- let status = msg.payload.status;
954
- let error = msg.payload.error;
955
- let presentValue = msg.payload.presentValue;
956
- let timestamp = msg.payload.timestamp;
957
-
958
- // Extract properties only if they exist
959
- let deviceID = msg.payload.meta?.device?.deviceId;
960
- let objectType = msg.payload.meta?.objectId?.type;
961
- let objectInstance = msg.payload.meta?.objectId?.instance;
962
- let pointName = msg.payload?.objectName;
963
-
964
- if (pointName !== undefined) {
965
- pointName = pointName + "_" + getObjectType(objectType) + "_" + objectInstance;
966
- }
967
-
968
- let displayName = msg.payload?.displayName;
969
- let deviceName = msg.payload.meta?.device?.deviceName;
970
-
971
- let ipAddress =
972
- typeof msg.payload.meta?.device?.address === "object"
973
- ? msg.payload.meta.device.address.address
974
- : msg.payload.meta?.device?.address;
975
-
976
- // Only proceed if the status key exists
977
- if (status !== undefined) {
978
- // Check if the topic is already in the unique topics list
979
- if (!uniqueTopics.includes(topic)) {
980
- uniqueTopics.push(topic);
981
- totalUniqueCount++;
982
- }
983
-
984
- // Update the status in the topicStatusMap
985
- if (topicStatusMap[topic] !== status) {
986
- // Adjust counts based on the previous status
987
- if (topicStatusMap[topic] === "online") {
988
- onlineCount--;
989
- } else if (topicStatusMap[topic] === "offline") {
990
- offlineCount--;
991
- }
992
-
993
- // Update with the new status
994
- topicStatusMap[topic] = status;
995
-
996
- // Adjust counts based on the new status
997
- if (status === "online") {
998
- onlineCount++;
999
- } else if (status === "offline") {
1000
- offlineCount++;
1001
- }
1002
- }
1003
-
1004
- // Create an entry in the data map if it doesn't already exist
1005
- if (!topicDataMap[topic]) {
1006
- topicDataMap[topic] = {
1007
- presentValue: presentValue,
1008
- status: status,
1009
- bacnetLastSeen: timestamp,
1010
- lastCOVTime: now.getTime(), // Initialize last value change time
1011
- };
1012
-
1013
- // Add properties conditionally if they exist or are explicitly set to 0
1014
- if (deviceID !== undefined) topicDataMap[topic].deviceID = deviceID;
1015
- if (objectType !== undefined) topicDataMap[topic].objectType = objectType;
1016
- if (objectInstance !== undefined) topicDataMap[topic].objectInstance = objectInstance;
1017
- if (pointName !== undefined) topicDataMap[topic].pointName = pointName;
1018
- if (displayName !== undefined) topicDataMap[topic].displayName = displayName;
1019
- if (deviceName !== undefined) topicDataMap[topic].deviceName = deviceName;
1020
- if (ipAddress !== undefined) topicDataMap[topic].ipAddress = ipAddress;
1021
- if (error !== undefined) topicDataMap[topic].error = error;
1022
- topicDataMap[topic].key =
1023
- topicDataMap[topic].deviceID + ":" + topicDataMap[topic].objectType + ":" + topicDataMap[topic].objectInstance;
1024
- } else {
1025
- // If the entry already exists
1026
-
1027
- if (presentValue != topicDataMap[topic].presentValue) {
1028
- // If the present value has changed
1029
- topicDataMap[topic].lastCOVTime = now.getTime(); // Update last value change time
1030
- }
1031
-
1032
- topicDataMap[topic].presentValue = presentValue; // Update the existing timestamp and present value
1033
- topicDataMap[topic].bacnetLastSeen = timestamp; // Update timestamp
1034
-
1035
- // Update properties conditionally if they exist or are explicitly set to 0
1036
- if (deviceID !== undefined) topicDataMap[topic].deviceID = deviceID;
1037
- if (objectType !== undefined) topicDataMap[topic].objectType = objectType;
1038
- if (objectInstance !== undefined) topicDataMap[topic].objectInstance = objectInstance;
1039
- if (pointName !== undefined) topicDataMap[topic].pointName = pointName;
1040
- if (displayName !== undefined) topicDataMap[topic].displayName = displayName;
1041
- if (deviceName !== undefined) topicDataMap[topic].deviceName = deviceName;
1042
- if (ipAddress !== undefined) topicDataMap[topic].ipAddress = ipAddress;
1043
- if (error !== undefined) topicDataMap[topic].error = error;
1044
- topicDataMap[topic].key =
1045
- topicDataMap[topic].deviceID + ":" + topicDataMap[topic].objectType + ":" + topicDataMap[topic].objectInstance;
1046
- }
1047
- } else {
1048
- node.warn("Status key is missing for topic: " + topic);
1049
- }
1050
-
1051
- let offlinePercentage = (offlineCount / (onlineCount + offlineCount)) * 100;
1052
-
1053
- node.statBlock.offlinePercentage = offlinePercentage;
1054
-
1055
- // Store the updated unique topics, status map, topic data map, and counts back in the context context
1056
- flow.set("uniqueTopics", uniqueTopics);
1057
- flow.set("topicStatusMap", topicStatusMap);
1058
- flow.set("topicDataMap", topicDataMap);
1059
- flow.set("totalUniquePolledCount", totalUniqueCount);
1060
- flow.set("onlineCount", onlineCount);
1061
- flow.set("offlineCount", offlineCount);
1062
- flow.set("offlinePercentage", offlinePercentage);
1063
-
1064
- // Update the node status
1065
- node.status({ text: "Points Online: " + onlineCount + "/" + totalUniqueCount });
1066
- }
1067
-
1068
924
  function makeGetRequest(route) {
1069
925
  return new Promise((resolve, reject) => {
1070
926
  try {
@@ -367,7 +367,7 @@ function processModelStats(data) {
367
367
  }
368
368
 
369
369
  // Update statBlock
370
- statBlock.missing = pointMatchDiscoveryNotPublishingCount;
370
+ statBlock.missing = pointNotInDiscoveryCount;
371
371
  statBlock.warnings = pointMatchDiscoveryNotPublishingCount;
372
372
  statBlock.unmapped = unmappedCount;
373
373
 
@@ -1 +1,170 @@
1
- [{"id":"a19aaf3c40f060de","type":"Bacnet-Gateway","z":"1bc98a48ab9b3af5","name":"","local_device_address":"","apduTimeout":6000,"roundDecimal":2,"local_device_port":47808,"apduSize":"5","maxSegments":"0x50","retries":"5","broadCastAddr":"255.255.255.255","toLogIam":true,"discover_polling_schedule":"120","discover_polling_schedule_value":"2","discover_polling_schedule_options":"Minutes","device_id_range_enabled":false,"device_id_range_start":"","device_id_range_end":"","deviceId":"817001","manual_instance_range_enabled":false,"manual_instance_range_start":"","manual_instance_range_end":"","logErrorToConsole":false,"serverEnabled":false,"device_read_schedule":"60","device_read_schedule_value":"1","device_read_schedule_options":"Minutes","x":660,"y":420,"wires":[["9d8b6ea1f9d11977"]]},{"id":"3e5f5a6efe7bf8cd","type":"Bitpool-Inject","z":"1bc98a48ab9b3af5","name":"Discover","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","doPoll":false,"doDiscover":true,"x":480,"y":420,"wires":[["a19aaf3c40f060de"]]},{"id":"1774359e5a636b58","type":"Bitpool-Inject","z":"1bc98a48ab9b3af5","name":"Poll","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","doPoll":true,"doDiscover":false,"x":310,"y":360,"wires":[["bfec7e0b535bef97"]]},{"id":"9d8b6ea1f9d11977","type":"debug","z":"1bc98a48ab9b3af5","name":"debug 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":840,"y":420,"wires":[]},{"id":"bfec7e0b535bef97","type":"Bacnet-Discovery","z":"1bc98a48ab9b3af5","name":"","events":true,"json":false,"mqtt":true,"hiddenDeployToggle":false,"prevHiddenToggleState":false,"roundDecimal":2,"pointsToRead":{},"readDevices":[],"object_property_simplePayload":true,"object_property_fullObject":false,"x":490,"y":360,"wires":[["a19aaf3c40f060de"]]}]
1
+ [
2
+ {
3
+ "id": "ba92a36a18ffdfac",
4
+ "type": "Bacnet-Gateway",
5
+ "z": "f1fc21f44027188c",
6
+ "name": "",
7
+ "local_device_address": "",
8
+ "local_interface_name": "",
9
+ "apduTimeout": 6000,
10
+ "roundDecimal": 2,
11
+ "local_device_port": 47808,
12
+ "apduSize": "5",
13
+ "maxSegments": "0x50",
14
+ "retries": "5",
15
+ "broadCastAddr": "255.255.255.255",
16
+ "toLogIam": false,
17
+ "discover_polling_schedule": "900",
18
+ "discover_polling_schedule_value": "15",
19
+ "discover_polling_schedule_options": "Minutes",
20
+ "deviceId": 817001,
21
+ "logErrorToConsole": false,
22
+ "serverEnabled": true,
23
+ "device_read_schedule": "900",
24
+ "device_read_schedule_value": "15",
25
+ "device_read_schedule_options": "Minutes",
26
+ "deviceRangeRegisters": [
27
+ {
28
+ "enabled": true,
29
+ "start": "0",
30
+ "end": "4194303"
31
+ }
32
+ ],
33
+ "portRangeRegisters": [
34
+ {
35
+ "enabled": true,
36
+ "start": "47808",
37
+ "end": "47808"
38
+ }
39
+ ],
40
+ "cacheFileEnabled": false,
41
+ "sanitise_device_schedule": "3600",
42
+ "sanitise_device_schedule_value": "1",
43
+ "sanitise_device_schedule_options": "Hours",
44
+ "x": 800,
45
+ "y": 460,
46
+ "wires": [
47
+ [
48
+ "0688901dadf6d984"
49
+ ]
50
+ ]
51
+ },
52
+ {
53
+ "id": "c404d53530d50ce9",
54
+ "type": "Bacnet-Discovery",
55
+ "z": "f1fc21f44027188c",
56
+ "name": "",
57
+ "events": true,
58
+ "json": true,
59
+ "mqtt": false,
60
+ "pointJson": false,
61
+ "hiddenDeployToggle": false,
62
+ "prevHiddenToggleState": false,
63
+ "roundDecimal": 2,
64
+ "pointsToRead": {},
65
+ "readDevices": [],
66
+ "object_property_simplePayload": false,
67
+ "object_property_simpleWithStatus": false,
68
+ "object_property_fullObject": true,
69
+ "useDeviceName": true,
70
+ "x": 630,
71
+ "y": 400,
72
+ "wires": [
73
+ [
74
+ "ba92a36a18ffdfac"
75
+ ]
76
+ ]
77
+ },
78
+ {
79
+ "id": "d89267e068e24882",
80
+ "type": "Bitpool-Inject",
81
+ "z": "f1fc21f44027188c",
82
+ "name": "Poll",
83
+ "props": [
84
+ {
85
+ "p": "payload"
86
+ },
87
+ {
88
+ "p": "topic",
89
+ "vt": "str"
90
+ }
91
+ ],
92
+ "repeat": "",
93
+ "crontab": "",
94
+ "once": false,
95
+ "onceDelay": 0.1,
96
+ "topic": "",
97
+ "payload": "",
98
+ "payloadType": "date",
99
+ "doPoll": true,
100
+ "doDiscover": false,
101
+ "json": false,
102
+ "mqtt": false,
103
+ "pointJson": true,
104
+ "object_property_simplePayload": false,
105
+ "object_property_simpleWithStatus": false,
106
+ "object_property_fullObject": true,
107
+ "useDeviceName": true,
108
+ "x": 470,
109
+ "y": 400,
110
+ "wires": [
111
+ [
112
+ "c404d53530d50ce9"
113
+ ]
114
+ ]
115
+ },
116
+ {
117
+ "id": "5f5537b37018ec25",
118
+ "type": "Bitpool-Inject",
119
+ "z": "f1fc21f44027188c",
120
+ "name": "Discover",
121
+ "props": [
122
+ {
123
+ "p": "payload"
124
+ },
125
+ {
126
+ "p": "topic",
127
+ "vt": "str"
128
+ }
129
+ ],
130
+ "repeat": "",
131
+ "crontab": "",
132
+ "once": false,
133
+ "onceDelay": 0.1,
134
+ "topic": "",
135
+ "payload": "",
136
+ "payloadType": "date",
137
+ "doPoll": false,
138
+ "doDiscover": true,
139
+ "json": false,
140
+ "mqtt": false,
141
+ "pointJson": true,
142
+ "object_property_simplePayload": false,
143
+ "object_property_simpleWithStatus": false,
144
+ "object_property_fullObject": true,
145
+ "useDeviceName": true,
146
+ "x": 620,
147
+ "y": 460,
148
+ "wires": [
149
+ [
150
+ "ba92a36a18ffdfac"
151
+ ]
152
+ ]
153
+ },
154
+ {
155
+ "id": "0688901dadf6d984",
156
+ "type": "debug",
157
+ "z": "f1fc21f44027188c",
158
+ "name": "debug 1",
159
+ "active": true,
160
+ "tosidebar": true,
161
+ "console": false,
162
+ "tostatus": false,
163
+ "complete": "false",
164
+ "statusVal": "",
165
+ "statusType": "auto",
166
+ "x": 1000,
167
+ "y": 460,
168
+ "wires": []
169
+ }
170
+ ]
@@ -1 +1,164 @@
1
- [{"id":"e478e80571442399","type":"Bacnet-Gateway","z":"1bc98a48ab9b3af5","name":"","local_device_address":"","apduTimeout":6000,"roundDecimal":2,"local_device_port":47808,"apduSize":"5","maxSegments":"0x50","retries":"5","broadCastAddr":"255.255.255.255","toLogIam":true,"discover_polling_schedule":"60","discover_polling_schedule_value":"1","discover_polling_schedule_options":"Minutes","device_id_range_enabled":false,"device_id_range_start":"","device_id_range_end":"","deviceId":"817001","manual_instance_range_enabled":false,"manual_instance_range_start":"","manual_instance_range_end":"","logErrorToConsole":false,"serverEnabled":false,"device_read_schedule":"60","device_read_schedule_value":"1","device_read_schedule_options":"Minutes","x":700,"y":320,"wires":[["0313b7ee1cfa6b42"]]},{"id":"c2e012301c4a6af4","type":"Bitpool-Inject","z":"1bc98a48ab9b3af5","name":"Discover","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","doPoll":false,"doDiscover":true,"x":520,"y":320,"wires":[["e478e80571442399"]]},{"id":"8172620e7be7b505","type":"Bitpool-Inject","z":"1bc98a48ab9b3af5","name":"Poll","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","doPoll":true,"doDiscover":false,"x":370,"y":400,"wires":[["b3293195b7c5bd9d"]]},{"id":"0313b7ee1cfa6b42","type":"debug","z":"1bc98a48ab9b3af5","name":"debug 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":880,"y":320,"wires":[]},{"id":"b3293195b7c5bd9d","type":"Bacnet-Write","z":"1bc98a48ab9b3af5","name":"","applicationTag":"4","priority":"16","pointsToWrite":[],"writeDevices":[],"hiddenDeployToggle":false,"prevHiddenToggleState":false,"x":530,"y":400,"wires":[["e478e80571442399"]]}]
1
+ [
2
+ {
3
+ "id": "25ee9078510fe398",
4
+ "type": "Bacnet-Gateway",
5
+ "z": "f1fc21f44027188c",
6
+ "name": "",
7
+ "local_device_address": "",
8
+ "local_interface_name": "",
9
+ "apduTimeout": 6000,
10
+ "roundDecimal": 2,
11
+ "local_device_port": 47808,
12
+ "apduSize": "5",
13
+ "maxSegments": "0x50",
14
+ "retries": "5",
15
+ "broadCastAddr": "255.255.255.255",
16
+ "toLogIam": false,
17
+ "discover_polling_schedule": "900",
18
+ "discover_polling_schedule_value": "15",
19
+ "discover_polling_schedule_options": "Minutes",
20
+ "deviceId": 817001,
21
+ "logErrorToConsole": false,
22
+ "serverEnabled": true,
23
+ "device_read_schedule": "900",
24
+ "device_read_schedule_value": "15",
25
+ "device_read_schedule_options": "Minutes",
26
+ "deviceRangeRegisters": [
27
+ {
28
+ "enabled": true,
29
+ "start": "0",
30
+ "end": "4194303"
31
+ }
32
+ ],
33
+ "portRangeRegisters": [
34
+ {
35
+ "enabled": true,
36
+ "start": "47808",
37
+ "end": "47808"
38
+ }
39
+ ],
40
+ "cacheFileEnabled": true,
41
+ "sanitise_device_schedule": "3600",
42
+ "sanitise_device_schedule_value": "1",
43
+ "sanitise_device_schedule_options": "Hours",
44
+ "x": 840,
45
+ "y": 420,
46
+ "wires": [
47
+ [
48
+ "f41ef6737463370e"
49
+ ]
50
+ ]
51
+ },
52
+ {
53
+ "id": "0f90856ca1808ee7",
54
+ "type": "Bitpool-Inject",
55
+ "z": "f1fc21f44027188c",
56
+ "name": "Discover",
57
+ "props": [
58
+ {
59
+ "p": "payload"
60
+ },
61
+ {
62
+ "p": "topic",
63
+ "vt": "str"
64
+ }
65
+ ],
66
+ "repeat": "",
67
+ "crontab": "",
68
+ "once": false,
69
+ "onceDelay": 0.1,
70
+ "topic": "",
71
+ "payload": "",
72
+ "payloadType": "date",
73
+ "doPoll": false,
74
+ "doDiscover": true,
75
+ "json": false,
76
+ "mqtt": false,
77
+ "pointJson": true,
78
+ "object_property_simplePayload": false,
79
+ "object_property_simpleWithStatus": false,
80
+ "object_property_fullObject": true,
81
+ "useDeviceName": true,
82
+ "x": 660,
83
+ "y": 420,
84
+ "wires": [
85
+ [
86
+ "25ee9078510fe398"
87
+ ]
88
+ ]
89
+ },
90
+ {
91
+ "id": "c7f1aa7764f29aa1",
92
+ "type": "Bacnet-Write",
93
+ "z": "f1fc21f44027188c",
94
+ "name": "",
95
+ "applicationTag": "4",
96
+ "priority": "16",
97
+ "pointsToWrite": [],
98
+ "writeDevices": [],
99
+ "hiddenDeployToggle": false,
100
+ "prevHiddenToggleState": false,
101
+ "x": 670,
102
+ "y": 500,
103
+ "wires": [
104
+ [
105
+ "25ee9078510fe398"
106
+ ]
107
+ ]
108
+ },
109
+ {
110
+ "id": "c97fbed9db70de7f",
111
+ "type": "Bitpool-Inject",
112
+ "z": "f1fc21f44027188c",
113
+ "name": "Poll",
114
+ "props": [
115
+ {
116
+ "p": "payload"
117
+ },
118
+ {
119
+ "p": "topic",
120
+ "vt": "str"
121
+ }
122
+ ],
123
+ "repeat": "",
124
+ "crontab": "",
125
+ "once": false,
126
+ "onceDelay": 0.1,
127
+ "topic": "",
128
+ "payload": "",
129
+ "payloadType": "date",
130
+ "doPoll": true,
131
+ "doDiscover": false,
132
+ "json": false,
133
+ "mqtt": false,
134
+ "pointJson": true,
135
+ "object_property_simplePayload": false,
136
+ "object_property_simpleWithStatus": false,
137
+ "object_property_fullObject": true,
138
+ "useDeviceName": true,
139
+ "x": 490,
140
+ "y": 500,
141
+ "wires": [
142
+ [
143
+ "c7f1aa7764f29aa1"
144
+ ]
145
+ ]
146
+ },
147
+ {
148
+ "id": "f41ef6737463370e",
149
+ "type": "debug",
150
+ "z": "f1fc21f44027188c",
151
+ "name": "debug 1",
152
+ "active": true,
153
+ "tosidebar": true,
154
+ "console": false,
155
+ "tostatus": false,
156
+ "complete": "true",
157
+ "targetType": "full",
158
+ "statusVal": "",
159
+ "statusType": "auto",
160
+ "x": 1040,
161
+ "y": 420,
162
+ "wires": []
163
+ }
164
+ ]
@@ -1 +1,227 @@
1
- [{"id":"e6ef82c5497d2d12","type":"Bacnet-Gateway","z":"1bc98a48ab9b3af5","name":"","local_device_address":"","apduTimeout":6000,"roundDecimal":2,"local_device_port":47808,"apduSize":"5","maxSegments":"0x50","retries":"5","broadCastAddr":"255.255.255.255","toLogIam":true,"discover_polling_schedule":"60","discover_polling_schedule_value":"1","discover_polling_schedule_options":"Minutes","device_id_range_enabled":false,"device_id_range_start":"","device_id_range_end":"","deviceId":"817001","manual_instance_range_enabled":false,"manual_instance_range_start":"","manual_instance_range_end":"","logErrorToConsole":false,"serverEnabled":false,"device_read_schedule":"60","device_read_schedule_value":"1","device_read_schedule_options":"Minutes","x":740,"y":340,"wires":[["13c868a66ecd17df"]]},{"id":"4df39409775f724e","type":"Bitpool-Inject","z":"1bc98a48ab9b3af5","name":"Discover","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","doPoll":false,"doDiscover":true,"x":560,"y":340,"wires":[["e6ef82c5497d2d12"]]},{"id":"67e4f714757a028e","type":"Bitpool-Inject","z":"1bc98a48ab9b3af5","name":"Poll","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","doPoll":true,"doDiscover":false,"x":410,"y":420,"wires":[["b8931cb1a1c69ffb"]]},{"id":"13c868a66ecd17df","type":"debug","z":"1bc98a48ab9b3af5","name":"debug 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":920,"y":340,"wires":[]},{"id":"b8931cb1a1c69ffb","type":"Bacnet-Write","z":"1bc98a48ab9b3af5","name":"","applicationTag":"4","priority":"16","pointsToWrite":[],"writeDevices":[],"hiddenDeployToggle":false,"prevHiddenToggleState":false,"x":570,"y":420,"wires":[["e6ef82c5497d2d12"]]},{"id":"a95e261a4cc2662b","type":"Bitpool-Inject","z":"1bc98a48ab9b3af5","name":"Poll","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","doPoll":true,"doDiscover":false,"x":410,"y":280,"wires":[["08df19608ade8576"]]},{"id":"08df19608ade8576","type":"Bacnet-Discovery","z":"1bc98a48ab9b3af5","name":"","events":true,"json":false,"mqtt":true,"hiddenDeployToggle":false,"prevHiddenToggleState":false,"roundDecimal":2,"pointsToRead":{},"readDevices":[],"object_property_simplePayload":true,"object_property_fullObject":false,"x":570,"y":280,"wires":[["e6ef82c5497d2d12"]]}]
1
+ [
2
+ {
3
+ "id": "1617c14c07ac6e16",
4
+ "type": "Bacnet-Gateway",
5
+ "z": "f1fc21f44027188c",
6
+ "name": "",
7
+ "local_device_address": "",
8
+ "local_interface_name": "",
9
+ "apduTimeout": 6000,
10
+ "roundDecimal": 2,
11
+ "local_device_port": 47808,
12
+ "apduSize": "5",
13
+ "maxSegments": "0x50",
14
+ "retries": "5",
15
+ "broadCastAddr": "255.255.255.255",
16
+ "toLogIam": false,
17
+ "discover_polling_schedule": "900",
18
+ "discover_polling_schedule_value": "15",
19
+ "discover_polling_schedule_options": "Minutes",
20
+ "deviceId": 817001,
21
+ "logErrorToConsole": false,
22
+ "serverEnabled": true,
23
+ "device_read_schedule": "900",
24
+ "device_read_schedule_value": "15",
25
+ "device_read_schedule_options": "Minutes",
26
+ "deviceRangeRegisters": [
27
+ {
28
+ "enabled": true,
29
+ "start": "0",
30
+ "end": "4194303"
31
+ }
32
+ ],
33
+ "portRangeRegisters": [
34
+ {
35
+ "enabled": true,
36
+ "start": "47808",
37
+ "end": "47808"
38
+ }
39
+ ],
40
+ "cacheFileEnabled": true,
41
+ "sanitise_device_schedule": "3600",
42
+ "sanitise_device_schedule_value": "1",
43
+ "sanitise_device_schedule_options": "Hours",
44
+ "x": 840,
45
+ "y": 440,
46
+ "wires": [
47
+ [
48
+ "8db122ce13172090"
49
+ ]
50
+ ]
51
+ },
52
+ {
53
+ "id": "3dbfbb72574a201c",
54
+ "type": "Bacnet-Discovery",
55
+ "z": "f1fc21f44027188c",
56
+ "name": "",
57
+ "events": true,
58
+ "json": true,
59
+ "mqtt": false,
60
+ "pointJson": false,
61
+ "hiddenDeployToggle": false,
62
+ "prevHiddenToggleState": false,
63
+ "roundDecimal": 2,
64
+ "pointsToRead": {},
65
+ "readDevices": [],
66
+ "object_property_simplePayload": false,
67
+ "object_property_simpleWithStatus": false,
68
+ "object_property_fullObject": true,
69
+ "useDeviceName": true,
70
+ "x": 670,
71
+ "y": 360,
72
+ "wires": [
73
+ [
74
+ "1617c14c07ac6e16"
75
+ ]
76
+ ]
77
+ },
78
+ {
79
+ "id": "ae5c90c50e252352",
80
+ "type": "Bacnet-Write",
81
+ "z": "f1fc21f44027188c",
82
+ "name": "",
83
+ "applicationTag": "4",
84
+ "priority": "16",
85
+ "pointsToWrite": [],
86
+ "writeDevices": [],
87
+ "hiddenDeployToggle": false,
88
+ "prevHiddenToggleState": false,
89
+ "x": 670,
90
+ "y": 520,
91
+ "wires": [
92
+ [
93
+ "1617c14c07ac6e16"
94
+ ]
95
+ ]
96
+ },
97
+ {
98
+ "id": "e4837a22dc540343",
99
+ "type": "Bitpool-Inject",
100
+ "z": "f1fc21f44027188c",
101
+ "name": "Discover",
102
+ "props": [
103
+ {
104
+ "p": "payload"
105
+ },
106
+ {
107
+ "p": "topic",
108
+ "vt": "str"
109
+ }
110
+ ],
111
+ "repeat": "",
112
+ "crontab": "",
113
+ "once": false,
114
+ "onceDelay": 0.1,
115
+ "topic": "",
116
+ "payload": "",
117
+ "payloadType": "date",
118
+ "doPoll": false,
119
+ "doDiscover": true,
120
+ "json": false,
121
+ "mqtt": false,
122
+ "pointJson": true,
123
+ "object_property_simplePayload": false,
124
+ "object_property_simpleWithStatus": false,
125
+ "object_property_fullObject": true,
126
+ "useDeviceName": true,
127
+ "x": 660,
128
+ "y": 440,
129
+ "wires": [
130
+ [
131
+ "1617c14c07ac6e16"
132
+ ]
133
+ ]
134
+ },
135
+ {
136
+ "id": "67bd88188ddd1166",
137
+ "type": "Bitpool-Inject",
138
+ "z": "f1fc21f44027188c",
139
+ "name": "Poll",
140
+ "props": [
141
+ {
142
+ "p": "payload"
143
+ },
144
+ {
145
+ "p": "topic",
146
+ "vt": "str"
147
+ }
148
+ ],
149
+ "repeat": "",
150
+ "crontab": "",
151
+ "once": false,
152
+ "onceDelay": 0.1,
153
+ "topic": "",
154
+ "payload": "",
155
+ "payloadType": "date",
156
+ "doPoll": true,
157
+ "doDiscover": false,
158
+ "json": false,
159
+ "mqtt": false,
160
+ "pointJson": true,
161
+ "object_property_simplePayload": false,
162
+ "object_property_simpleWithStatus": false,
163
+ "object_property_fullObject": true,
164
+ "useDeviceName": true,
165
+ "x": 490,
166
+ "y": 520,
167
+ "wires": [
168
+ [
169
+ "ae5c90c50e252352"
170
+ ]
171
+ ]
172
+ },
173
+ {
174
+ "id": "6d1719920e0c3838",
175
+ "type": "Bitpool-Inject",
176
+ "z": "f1fc21f44027188c",
177
+ "name": "Poll",
178
+ "props": [
179
+ {
180
+ "p": "payload"
181
+ },
182
+ {
183
+ "p": "topic",
184
+ "vt": "str"
185
+ }
186
+ ],
187
+ "repeat": "",
188
+ "crontab": "",
189
+ "once": false,
190
+ "onceDelay": 0.1,
191
+ "topic": "",
192
+ "payload": "",
193
+ "payloadType": "date",
194
+ "doPoll": true,
195
+ "doDiscover": false,
196
+ "json": false,
197
+ "mqtt": false,
198
+ "pointJson": true,
199
+ "object_property_simplePayload": false,
200
+ "object_property_simpleWithStatus": false,
201
+ "object_property_fullObject": true,
202
+ "useDeviceName": true,
203
+ "x": 490,
204
+ "y": 360,
205
+ "wires": [
206
+ [
207
+ "3dbfbb72574a201c"
208
+ ]
209
+ ]
210
+ },
211
+ {
212
+ "id": "8db122ce13172090",
213
+ "type": "debug",
214
+ "z": "f1fc21f44027188c",
215
+ "name": "debug 1",
216
+ "active": true,
217
+ "tosidebar": true,
218
+ "console": false,
219
+ "tostatus": false,
220
+ "complete": "false",
221
+ "statusVal": "",
222
+ "statusType": "auto",
223
+ "x": 1040,
224
+ "y": 440,
225
+ "wires": []
226
+ }
227
+ ]
@@ -0,0 +1,368 @@
1
+ [
2
+ {
3
+ "id": "1617c14c07ac6e16",
4
+ "type": "Bacnet-Gateway",
5
+ "z": "f1fc21f44027188c",
6
+ "name": "",
7
+ "local_device_address": "",
8
+ "local_interface_name": "",
9
+ "apduTimeout": 6000,
10
+ "roundDecimal": 2,
11
+ "local_device_port": 47808,
12
+ "apduSize": "5",
13
+ "maxSegments": "0x50",
14
+ "retries": "5",
15
+ "broadCastAddr": "255.255.255.255",
16
+ "toLogIam": false,
17
+ "discover_polling_schedule": "900",
18
+ "discover_polling_schedule_value": "15",
19
+ "discover_polling_schedule_options": "Minutes",
20
+ "deviceId": 817001,
21
+ "logErrorToConsole": false,
22
+ "serverEnabled": true,
23
+ "device_read_schedule": "900",
24
+ "device_read_schedule_value": "15",
25
+ "device_read_schedule_options": "Minutes",
26
+ "deviceRangeRegisters": [
27
+ {
28
+ "enabled": true,
29
+ "start": "0",
30
+ "end": "4194303"
31
+ }
32
+ ],
33
+ "portRangeRegisters": [
34
+ {
35
+ "enabled": true,
36
+ "start": "47808",
37
+ "end": "47808"
38
+ }
39
+ ],
40
+ "cacheFileEnabled": true,
41
+ "sanitise_device_schedule": "3600",
42
+ "sanitise_device_schedule_value": "1",
43
+ "sanitise_device_schedule_options": "Hours",
44
+ "x": 840,
45
+ "y": 440,
46
+ "wires": [
47
+ [
48
+ "8db122ce13172090",
49
+ "df826da5f464306c"
50
+ ]
51
+ ]
52
+ },
53
+ {
54
+ "id": "3dbfbb72574a201c",
55
+ "type": "Bacnet-Discovery",
56
+ "z": "f1fc21f44027188c",
57
+ "name": "",
58
+ "events": true,
59
+ "json": true,
60
+ "mqtt": false,
61
+ "pointJson": false,
62
+ "hiddenDeployToggle": false,
63
+ "prevHiddenToggleState": false,
64
+ "roundDecimal": 2,
65
+ "pointsToRead": {},
66
+ "readDevices": [],
67
+ "object_property_simplePayload": false,
68
+ "object_property_simpleWithStatus": false,
69
+ "object_property_fullObject": true,
70
+ "useDeviceName": true,
71
+ "x": 670,
72
+ "y": 360,
73
+ "wires": [
74
+ [
75
+ "1617c14c07ac6e16",
76
+ "df826da5f464306c"
77
+ ]
78
+ ]
79
+ },
80
+ {
81
+ "id": "ae5c90c50e252352",
82
+ "type": "Bacnet-Write",
83
+ "z": "f1fc21f44027188c",
84
+ "name": "",
85
+ "applicationTag": "4",
86
+ "priority": "16",
87
+ "pointsToWrite": [],
88
+ "writeDevices": [],
89
+ "hiddenDeployToggle": false,
90
+ "prevHiddenToggleState": false,
91
+ "x": 670,
92
+ "y": 520,
93
+ "wires": [
94
+ [
95
+ "1617c14c07ac6e16"
96
+ ]
97
+ ]
98
+ },
99
+ {
100
+ "id": "e4837a22dc540343",
101
+ "type": "Bitpool-Inject",
102
+ "z": "f1fc21f44027188c",
103
+ "name": "Discover",
104
+ "props": [
105
+ {
106
+ "p": "payload"
107
+ },
108
+ {
109
+ "p": "topic",
110
+ "vt": "str"
111
+ }
112
+ ],
113
+ "repeat": "",
114
+ "crontab": "",
115
+ "once": false,
116
+ "onceDelay": 0.1,
117
+ "topic": "",
118
+ "payload": "",
119
+ "payloadType": "date",
120
+ "doPoll": false,
121
+ "doDiscover": true,
122
+ "json": false,
123
+ "mqtt": false,
124
+ "pointJson": true,
125
+ "object_property_simplePayload": false,
126
+ "object_property_simpleWithStatus": false,
127
+ "object_property_fullObject": true,
128
+ "useDeviceName": true,
129
+ "x": 660,
130
+ "y": 440,
131
+ "wires": [
132
+ [
133
+ "1617c14c07ac6e16"
134
+ ]
135
+ ]
136
+ },
137
+ {
138
+ "id": "67bd88188ddd1166",
139
+ "type": "Bitpool-Inject",
140
+ "z": "f1fc21f44027188c",
141
+ "name": "Poll",
142
+ "props": [
143
+ {
144
+ "p": "payload"
145
+ },
146
+ {
147
+ "p": "topic",
148
+ "vt": "str"
149
+ }
150
+ ],
151
+ "repeat": "",
152
+ "crontab": "",
153
+ "once": false,
154
+ "onceDelay": 0.1,
155
+ "topic": "",
156
+ "payload": "",
157
+ "payloadType": "date",
158
+ "doPoll": true,
159
+ "doDiscover": false,
160
+ "json": false,
161
+ "mqtt": false,
162
+ "pointJson": true,
163
+ "object_property_simplePayload": false,
164
+ "object_property_simpleWithStatus": false,
165
+ "object_property_fullObject": true,
166
+ "useDeviceName": true,
167
+ "x": 490,
168
+ "y": 520,
169
+ "wires": [
170
+ [
171
+ "ae5c90c50e252352"
172
+ ]
173
+ ]
174
+ },
175
+ {
176
+ "id": "6d1719920e0c3838",
177
+ "type": "Bitpool-Inject",
178
+ "z": "f1fc21f44027188c",
179
+ "name": "Poll",
180
+ "props": [
181
+ {
182
+ "p": "payload"
183
+ },
184
+ {
185
+ "p": "topic",
186
+ "vt": "str"
187
+ }
188
+ ],
189
+ "repeat": "",
190
+ "crontab": "",
191
+ "once": false,
192
+ "onceDelay": 0.1,
193
+ "topic": "",
194
+ "payload": "",
195
+ "payloadType": "date",
196
+ "doPoll": true,
197
+ "doDiscover": false,
198
+ "json": false,
199
+ "mqtt": false,
200
+ "pointJson": true,
201
+ "object_property_simplePayload": false,
202
+ "object_property_simpleWithStatus": false,
203
+ "object_property_fullObject": true,
204
+ "useDeviceName": true,
205
+ "x": 490,
206
+ "y": 360,
207
+ "wires": [
208
+ [
209
+ "3dbfbb72574a201c"
210
+ ]
211
+ ]
212
+ },
213
+ {
214
+ "id": "8db122ce13172090",
215
+ "type": "debug",
216
+ "z": "f1fc21f44027188c",
217
+ "name": "debug 1",
218
+ "active": true,
219
+ "tosidebar": true,
220
+ "console": false,
221
+ "tostatus": false,
222
+ "complete": "true",
223
+ "targetType": "full",
224
+ "statusVal": "",
225
+ "statusType": "auto",
226
+ "x": 1040,
227
+ "y": 440,
228
+ "wires": []
229
+ },
230
+ {
231
+ "id": "df826da5f464306c",
232
+ "type": "Bacnet-Inspector",
233
+ "z": "f1fc21f44027188c",
234
+ "name": "",
235
+ "siteName": "INSPECTOR_SITE_NAME",
236
+ "totalUniqueReadCount": 0,
237
+ "x": 1070,
238
+ "y": 360,
239
+ "wires": [
240
+ [
241
+ "6eeed73a4976730b"
242
+ ]
243
+ ]
244
+ },
245
+ {
246
+ "id": "6eeed73a4976730b",
247
+ "type": "debug",
248
+ "z": "f1fc21f44027188c",
249
+ "name": "debug 2",
250
+ "active": true,
251
+ "tosidebar": true,
252
+ "console": false,
253
+ "tostatus": false,
254
+ "complete": "true",
255
+ "targetType": "full",
256
+ "statusVal": "",
257
+ "statusType": "auto",
258
+ "x": 1300,
259
+ "y": 360,
260
+ "wires": []
261
+ },
262
+ {
263
+ "id": "70b41e715ed44733",
264
+ "type": "Bitpool-Inject",
265
+ "z": "f1fc21f44027188c",
266
+ "name": "sendMqttStats",
267
+ "props": [
268
+ {
269
+ "p": "type",
270
+ "v": "sendMqttStats",
271
+ "vt": "str"
272
+ }
273
+ ],
274
+ "repeat": "",
275
+ "crontab": "",
276
+ "once": false,
277
+ "onceDelay": 0.1,
278
+ "topic": "",
279
+ "doPoll": true,
280
+ "doDiscover": false,
281
+ "json": false,
282
+ "mqtt": false,
283
+ "pointJson": true,
284
+ "object_property_simplePayload": false,
285
+ "object_property_simpleWithStatus": false,
286
+ "object_property_fullObject": true,
287
+ "useDeviceName": true,
288
+ "x": 870,
289
+ "y": 240,
290
+ "wires": [
291
+ [
292
+ "df826da5f464306c"
293
+ ]
294
+ ]
295
+ },
296
+ {
297
+ "id": "031ec232c48e17de",
298
+ "type": "Bitpool-Inject",
299
+ "z": "f1fc21f44027188c",
300
+ "name": "getBacnetStats",
301
+ "props": [
302
+ {
303
+ "p": "type",
304
+ "v": "getBacnetStats",
305
+ "vt": "str"
306
+ }
307
+ ],
308
+ "repeat": "",
309
+ "crontab": "",
310
+ "once": false,
311
+ "onceDelay": 0.1,
312
+ "topic": "",
313
+ "doPoll": true,
314
+ "doDiscover": false,
315
+ "json": false,
316
+ "mqtt": false,
317
+ "pointJson": true,
318
+ "object_property_simplePayload": false,
319
+ "object_property_simpleWithStatus": false,
320
+ "object_property_fullObject": true,
321
+ "useDeviceName": true,
322
+ "x": 860,
323
+ "y": 300,
324
+ "wires": [
325
+ [
326
+ "df826da5f464306c"
327
+ ]
328
+ ]
329
+ },
330
+ {
331
+ "id": "74e1dd56bce21e2f",
332
+ "type": "Bitpool-Inject",
333
+ "z": "f1fc21f44027188c",
334
+ "name": "reset",
335
+ "props": [
336
+ {
337
+ "p": "reset",
338
+ "v": "true",
339
+ "vt": "bool"
340
+ },
341
+ {
342
+ "p": "topic",
343
+ "vt": "str"
344
+ }
345
+ ],
346
+ "repeat": "",
347
+ "crontab": "",
348
+ "once": false,
349
+ "onceDelay": 0.1,
350
+ "topic": "",
351
+ "doPoll": true,
352
+ "doDiscover": false,
353
+ "json": false,
354
+ "mqtt": false,
355
+ "pointJson": true,
356
+ "object_property_simplePayload": false,
357
+ "object_property_simpleWithStatus": false,
358
+ "object_property_fullObject": true,
359
+ "useDeviceName": true,
360
+ "x": 890,
361
+ "y": 180,
362
+ "wires": [
363
+ [
364
+ "df826da5f464306c"
365
+ ]
366
+ ]
367
+ }
368
+ ]
package/inspector.html CHANGED
@@ -35,8 +35,8 @@
35
35
  </span>
36
36
  <div class="status-text">
37
37
  <span class="statBlockValue">
38
- {{statCounts?.readCount}}
39
- <span class="stat-percentage">{{statPercentages.readCount}}%</span>
38
+ {{statCounts?.statBlock.ok}}
39
+ <span class="stat-percentage">{{statPercentages.ok}}%</span>
40
40
  </span>
41
41
  <span class="statBlockKey">Points OK</span>
42
42
  </div>
@@ -244,6 +244,7 @@
244
244
  selectedColumns: [],
245
245
  statPercentages: {
246
246
  readCount: 0,
247
+ ok: 0,
247
248
  error: 0,
248
249
  missing: 0,
249
250
  warnings: 0,
@@ -288,6 +289,7 @@
288
289
  const total = tableData.length || 1; // Avoid division by zero
289
290
  app.statPercentages = {
290
291
  readCount: Math.round((data.statCounts.readCount / total) * 100),
292
+ ok: Math.round((data.statCounts.statBlock.ok / total) * 100),
291
293
  error: Math.round((data.statCounts.statBlock.error / total) * 100),
292
294
  missing: Math.round((data.statCounts.statBlock.missing / total) * 100),
293
295
  warnings: Math.round((data.statCounts.statBlock.warnings / total) * 100),
@@ -401,14 +403,6 @@
401
403
  if (!this.selectedColumns) return false;
402
404
  return this.selectedColumns.some((item) => item.field === option.field);
403
405
  },
404
- getRowClass(rowData) {
405
- console.log("rowData", rowData);
406
- if (rowData.dataModelStatus.includes("Point OK")) return "row-ok";
407
- if (rowData.dataModelStatus.includes("Point Error")) return "row-error";
408
- if (rowData.dataModelStatus.includes("Point Warning")) return "row-warning";
409
- if (rowData.dataModelStatus.includes("Point Missing")) return "row-missing";
410
- return ""; // Default, no class
411
- },
412
406
  downloadCSV() {
413
407
  window.location.href = "/getmodelstatscsv";
414
408
  },
@@ -423,6 +417,7 @@
423
417
  filters: this.filters,
424
418
  selectedColumns: this.selectedColumns,
425
419
  allColumns: this.allColumns,
420
+ statPercentages: this.statPercentages // Include the calculated percentages
426
421
  };
427
422
  downloadPrimeVueAppAsHtml(filename, data);
428
423
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bitpoolos/edge-bacnet",
3
- "version": "1.6.0",
3
+ "version": "1.6.1",
4
4
  "description": "A bacnet gateway for node-red",
5
5
  "dependencies": {
6
6
  "@plus4nodered/ts-node-bacnet": "^1.0.0-beta.2",
@@ -125,6 +125,7 @@ async function processPrimeVueHtml(appData) {
125
125
  selectedColumnValues: CAPTURED_APP_DATA.selectedColumnValues || [],
126
126
  statPercentages: CAPTURED_APP_DATA.statPercentages || {
127
127
  readCount: 0,
128
+ ok: 0,
128
129
  error: 0,
129
130
  missing: 0,
130
131
  warnings: 0,
@@ -146,6 +147,7 @@ async function processPrimeVueHtml(appData) {
146
147
  const total = this.tableData.length || 1; // Avoid division by zero
147
148
  this.statPercentages = {
148
149
  readCount: Math.round((this.statCounts.readCount / total) * 100),
150
+ ok: Math.round((this.statCounts.statBlock.ok / total) * 100),
149
151
  error: Math.round((this.statCounts.statBlock.error / total) * 100),
150
152
  missing: Math.round((this.statCounts.statBlock.missing / total) * 100),
151
153
  warnings: Math.round((this.statCounts.statBlock.warnings / total) * 100),
@@ -285,8 +287,8 @@ async function processPrimeVueHtml(appData) {
285
287
  </span>
286
288
  <div class="status-text">
287
289
  <span class="statBlockValue">
288
- {{statCounts?.readCount}}
289
- <span class="stat-percentage">{{statPercentages.readCount}}%</span>
290
+ {{statCounts?.statBlock.ok}}
291
+ <span class="stat-percentage">{{statPercentages.ok}}%</span>
290
292
  </span>
291
293
  <span class="statBlockKey">Points OK</span>
292
294
  </div>
@@ -475,4 +475,29 @@ body {
475
475
  box-sizing: border-box;
476
476
  max-height: 80vh;
477
477
  overflow-y: auto;
478
+ }
479
+
480
+ .p-datatable-scrollable-body {
481
+ min-height: 576px !important;
482
+ }
483
+
484
+ /* Set consistent row heights */
485
+ .p-datatable .p-datatable-tbody>tr {
486
+ height: 48px !important;
487
+ min-height: 48px !important;
488
+ max-height: 48px !important;
489
+ }
490
+
491
+ /* Make sure content in cells doesn't expand the row */
492
+ .p-datatable .p-datatable-tbody>tr>td {
493
+ height: 48px !important;
494
+ padding: 0.5rem 1rem;
495
+ white-space: nowrap;
496
+ overflow: hidden;
497
+ text-overflow: ellipsis;
498
+ }
499
+
500
+ /* Ensure table takes minimum space when empty */
501
+ .p-datatable-empty-message {
502
+ height: 576px !important;
478
503
  }
@@ -52,8 +52,8 @@ async function generatePrimeVueAppHtmlStatic(appData, filename = "bacnet-inspect
52
52
  </span>
53
53
  <div class="status-text">
54
54
  <span class="statBlockValue">
55
- {{statCounts?.readCount}}
56
- <span class="stat-percentage">{{statPercentages.readCount}}%</span>
55
+ {{statCounts?.statBlock.ok}}
56
+ <span class="stat-percentage">{{statPercentages.ok}}%</span>
57
57
  </span>
58
58
  <span class="statBlockKey">Points OK</span>
59
59
  </div>
@@ -258,6 +258,7 @@ async function generatePrimeVueAppHtmlStatic(appData, filename = "bacnet-inspect
258
258
  selectedColumns: [],
259
259
  statPercentages: {
260
260
  readCount: 0,
261
+ ok: 0,
261
262
  error: 0,
262
263
  missing: 0,
263
264
  warnings: 0,
@@ -278,6 +279,7 @@ async function generatePrimeVueAppHtmlStatic(appData, filename = "bacnet-inspect
278
279
  const total = this.tableData.length || 1; // Avoid division by zero
279
280
  this.statPercentages = {
280
281
  readCount: Math.round((this.statCounts.readCount / total) * 100) || 0,
282
+ ok: Math.round((this.statCounts.statBlock?.ok / total) * 100) || 0,
281
283
  error: Math.round((this.statCounts.statBlock?.error / total) * 100) || 0,
282
284
  missing: Math.round((this.statCounts.statBlock?.missing / total) * 100) || 0,
283
285
  warnings: Math.round((this.statCounts.statBlock?.warnings / total) * 100) || 0,