@bitpoolos/edge-bacnet 1.2.2 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bacnet_client.js CHANGED
@@ -80,7 +80,6 @@ class BacnetClient extends EventEmitter {
80
80
  const queryDevices = new Task('simple task', () => {
81
81
  if(!that.pollInProgress) that.queryDevices();
82
82
  that.sanitizeDeviceList();
83
- //that.queryDevicesManually();
84
83
  });
85
84
 
86
85
  const queryJob = new SimpleIntervalJob({ seconds: parseInt(that.device_read_schedule), }, queryDevices)
@@ -199,90 +198,138 @@ class BacnetClient extends EventEmitter {
199
198
  query(index);
200
199
 
201
200
  function query(index) {
202
- let device = that.deviceList[index];
201
+ that.queryPriorityDevices().then(function() {
203
202
 
204
- if(index < that.deviceList.length) {
205
- index++;
206
-
207
- if(typeof device == "object") {
208
- if(!device.getManualDiscoveryMode()) {
209
- try {
210
- that.getDevicePointList(device).then(function() {
211
- that.removeDeviceFromManualQueue(device);
212
- that.buildJsonObject(device).then(function() {
213
- query(index);
203
+ let device = that.deviceList[index];
204
+
205
+ if(index < that.deviceList.length) {
206
+ index++;
207
+
208
+ if(typeof device == "object") {
209
+ if(!device.getManualDiscoveryMode()) {
210
+ try {
211
+ that.getDevicePointList(device).then(function() {
212
+ that.removeDeviceFromManualQueue(device);
213
+ that.buildJsonObject(device, null).then(function() {
214
+ query(index);
215
+ }).catch(function(e) {
216
+ that.logOut(`getDevicePointList error: ${device.getAddress()}`, e);
217
+ query(index);
218
+ });
214
219
  }).catch(function(e) {
215
220
  that.logOut(`getDevicePointList error: ${device.getAddress()}`, e);
221
+ that.addDeviceToManualQueue(device);
216
222
  query(index);
217
223
  });
218
- }).catch(function(e) {
219
- that.logOut(`getDevicePointList error: ${device.getAddress()}`, e);
220
- that.addDeviceToManualQueue(device);
224
+ } catch(e) {
225
+ that.logOut("Error while querying devices: ", e);
221
226
  query(index);
222
- });
223
- } catch(e) {
224
- that.logOut("Error while querying devices: ", e);
227
+ }
228
+ } else {
225
229
  query(index);
226
230
  }
227
231
  } else {
232
+ that.logOut("queryDevices: invalid device found: ", device);
228
233
  query(index);
229
234
  }
230
- } else {
231
- that.logOut("queryDevices: invalid device found: ", device);
232
- query(index);
233
- }
234
- } else if(index == that.deviceList.length) {
235
+ } else if(index == that.deviceList.length) {
235
236
 
236
- if(that.manualDiscoverQueue.length > 0) {
237
- that.queryDevicesManually();
238
- } else {
239
- that.pollInProgress = false;
237
+ if(that.manualDiscoverQueue.length > 0) {
238
+ that.queryDevicesManually();
239
+ } else {
240
+ that.pollInProgress = false;
241
+ }
242
+
240
243
  }
241
-
242
- }
244
+ });
243
245
  }
244
246
  }
245
247
 
246
248
  queryDevicesManually() {
247
249
  let that = this;
248
-
249
250
  let index = 0;
250
-
251
251
  query(index);
252
252
 
253
253
  function query(index) {
254
- let device = that.manualDiscoverQueue[index];
254
+ that.queryPriorityDevices().then(function() {
255
+ let device = that.manualDiscoverQueue[index];
256
+ if(index < that.manualDiscoverQueue.length) {
257
+ index++;
258
+ if(typeof device == "object") {
259
+ try {
260
+ if(device.shouldBeInManualMode()) {
261
+ that.getDevicePointListWithoutObjectList(device).then(function() {
262
+ that.buildJsonObject(device, null).then(function() {
263
+ query(index);
264
+ }).catch(function(e) {
265
+ that.logOut(`getDevicePointList error: ${device.getAddress()}`, e);
266
+ query(index);
267
+ });
268
+ }).catch(function(e){
269
+ query(index);
270
+ });
271
+ } else {
272
+ that.removeDeviceFromManualQueue(device);
273
+ query(index);
274
+ }
275
+ } catch(e) {
276
+ query(index);
277
+ }
278
+ } else {
279
+ query(index);
280
+ }
281
+ } else if(index == that.manualDiscoverQueue.length) {
282
+ that.pollInProgress = false;
283
+ }
284
+ });
285
+ }
286
+ }
255
287
 
256
- if(index < that.manualDiscoverQueue.length) {
257
- index++;
258
-
259
- if(typeof device == "object") {
260
- try {
261
- if(device.shouldBeInManualMode()) {
262
- that.getDevicePointListWithoutObjectList(device).then(function() {
263
- that.buildJsonObject(device).then(function() {
288
+ queryPriorityDevices() {
289
+ let that = this;
290
+ return new Promise((resolve, reject) => {
291
+ let priorityDevices = that.getPriorityDevices();
292
+
293
+ if(priorityDevices.length > 0) {
294
+ let index = 0;
295
+
296
+ query(index);
297
+
298
+ function query(index) {
299
+ let device = priorityDevices[index];
300
+
301
+ if(index < priorityDevices.length) {
302
+ index++;
303
+
304
+ if(typeof device == "object" && ((Date.now() - device.getLastPriorityQueueTS()) / 1000) > parseInt(that.device_read_schedule) ) {
305
+
306
+ try {
307
+ let points = device.getPriorityQueue();
308
+ that.buildJsonObject(device, points).then(function() {
309
+ device.setLastPriorityQueueTS();
264
310
  query(index);
265
311
  }).catch(function(e) {
266
- that.logOut(`getDevicePointList error: ${device.getAddress()}`, e);
312
+ that.logOut(`queryPriorityDevices error: ${device.getAddress()}`, e);
267
313
  query(index);
268
314
  });
269
- }).catch(function(e){
315
+
316
+ } catch(e) {
317
+ that.logOut("Error while querying priority devices: ", e);
270
318
  query(index);
271
- });
319
+ }
320
+
272
321
  } else {
273
- that.removeDeviceFromManualQueue(device);
322
+ that.logOut("queryPriorityDevices: invalid device found: ", device);
274
323
  query(index);
275
324
  }
276
- } catch(e) {
277
- query(index);
325
+ } else if(index == priorityDevices.length) {
326
+ resolve()
278
327
  }
279
- } else {
280
- query(index);
281
328
  }
282
- } else if(index == that.manualDiscoverQueue.length) {
283
- that.pollInProgress = false;
329
+ } else if(priorityDevices.length == 0) {
330
+ resolve()
284
331
  }
285
- }
332
+ });
286
333
  }
287
334
 
288
335
  addDeviceToManualQueue(device) {
@@ -316,7 +363,7 @@ class BacnetClient extends EventEmitter {
316
363
  let timeoutThreshold = parseInt(that.discover_polling_schedule);
317
364
 
318
365
  that.deviceList.forEach(function(device, index) {
319
- if(((Date.now() - device.lastSeen) / 1000) > timeoutThreshold) {
366
+ if(((Date.now() - device.getLastSeen()) / 1000) > timeoutThreshold && device.getPriorityQueueIsActive() == false) {
320
367
  //render device hasnt responded to whoIs for over an hour
321
368
 
322
369
  let renderListIndex = that.renderList.findIndex(ele => ele.deviceId == device.getDeviceId());
@@ -326,9 +373,7 @@ class BacnetClient extends EventEmitter {
326
373
 
327
374
  delete that.networkTree[deviceKey];
328
375
 
329
- if(((Date.now() - device.getLastSeen()) / 1000) > timeoutThreshold) {
330
- that.renderList.splice(renderListIndex, 1);
331
- }
376
+ that.renderList.splice(renderListIndex, 1);
332
377
 
333
378
  that.deviceList.splice(index, 1);
334
379
  }
@@ -943,6 +988,40 @@ class BacnetClient extends EventEmitter {
943
988
  });
944
989
  }
945
990
 
991
+ updatePriorityQueue(req) {
992
+ let that = this;
993
+ return new Promise(async function(resolve, reject) {
994
+ try {
995
+ let keys = Object.keys(req.body);
996
+ if(keys.length > 0) {
997
+ keys.forEach(function(key) {
998
+ let device = that.deviceList.find(ele => `${that.getDeviceAddress(ele)}-${ele.getDeviceId()}` == key);
999
+ let points = req.body[key];
1000
+ device.setPriorityQueue(points);
1001
+ });
1002
+ } else if(keys.length == 0) {
1003
+ that.clearPriorityQueues();
1004
+ }
1005
+ resolve(true);
1006
+ } catch(e){
1007
+ reject(e);
1008
+ }
1009
+ });
1010
+ }
1011
+
1012
+ clearPriorityQueues() {
1013
+ let that = this;
1014
+ that.deviceList.forEach(function(device) {
1015
+ device.clearPriorityQueue();
1016
+ });
1017
+ }
1018
+
1019
+ getPriorityDevices() {
1020
+ let that = this;
1021
+ let priorityDevices = that.deviceList.filter(device => device.getPriorityQueueIsActive() == true);
1022
+ return priorityDevices;
1023
+ }
1024
+
946
1025
  sortDevices(a, b) {
947
1026
  if (a.deviceId < b.deviceId) {
948
1027
  return -1;
@@ -1065,21 +1144,10 @@ class BacnetClient extends EventEmitter {
1065
1144
  });
1066
1145
  }
1067
1146
 
1068
- buildObjects() {
1069
- let that = this;
1070
-
1071
- that.deviceList.forEach(function(device) {
1072
- that.buildJsonObject(device).then(function() {
1073
- }).catch(function(e) {
1074
- that.logOut(device.getAddress(), e)
1075
- });
1076
- });
1077
- }
1078
-
1079
- buildJsonObject(device) {
1147
+ buildJsonObject(device, priorityQueue) {
1080
1148
  let that = this;
1081
1149
  let address = device.address;
1082
- let pointList = device.getPointsList();
1150
+ let pointList = priorityQueue !== null ? priorityQueue : device.getPointsList();
1083
1151
  let requestMutex = new Mutex();
1084
1152
 
1085
1153
  return new Promise(function(resolve, reject) {
package/bacnet_device.js CHANGED
@@ -16,6 +16,9 @@ class BacnetDevice {
16
16
  that.manualDiscoveryMode = config.manualDiscoveryMode;
17
17
  that.mDiscoverInstanceRange = config.mDiscoverInstanceRange;
18
18
  that.pointListRetryCount = config.pointListRetryCount;
19
+ that.priorityQueueIsActive = config.priorityQueueIsActive;
20
+ that.priorityQueue = config.priorityQueue;
21
+ that.lastPriorityQueueTS = config.lastPriorityQueueTS;
19
22
 
20
23
  } else if(fromImport == false) {
21
24
  if(config.net && config.adr) {
@@ -36,9 +39,67 @@ class BacnetDevice {
36
39
  that.manualDiscoveryMode = false;
37
40
  that.mDiscoverInstanceRange = {start: 0, end: 100};
38
41
  that.pointListRetryCount = 0;
42
+ that.priorityQueueIsActive = false;
43
+ that.priorityQueue = [];
44
+ that.lastPriorityQueueTS = null;
39
45
  }
40
46
  }
41
47
 
48
+ setLastPriorityQueueTS() {
49
+ this.lastPriorityQueueTS = Date.now();
50
+ }
51
+
52
+ getLastPriorityQueueTS() {
53
+ return this.lastPriorityQueueTS;
54
+ }
55
+
56
+ setPriorityQueueIsActive(bool) {
57
+ this.priorityQueueIsActive = bool;
58
+ }
59
+
60
+ getPriorityQueueIsActive() {
61
+ return this.priorityQueueIsActive;
62
+ }
63
+
64
+ updatePriorityQueue(point) {
65
+ let foundIndex = this.priorityQueue.findIndex(ele => ele.value.type == point.value.type && ele.value.instance == point.value.instance);
66
+ if(foundIndex == -1 ) {
67
+ //not found
68
+ this.priorityQueue.push(point);
69
+ }
70
+
71
+ if(this.priorityQueue.length > 0) {
72
+ this.setPriorityQueueIsActive(true);
73
+ } else if(this.priorityQueue.length == 0) {
74
+ this.setPriorityQueueIsActive(false);
75
+ }
76
+ }
77
+
78
+ setPriorityQueue(points) {
79
+ let queue = [];
80
+ let keys = Object.keys(points);
81
+ if(keys.length > 0) {
82
+ keys.forEach(function(key) {
83
+ let point = points[key];
84
+ let pointRequestObject = {type: 12, value: point.meta.objectId}
85
+ queue.push(pointRequestObject);
86
+ });
87
+ this.priorityQueue = queue;
88
+ this.setPriorityQueueIsActive(true);
89
+ } else if(keys.length == 0) {
90
+ this.setPriorityQueueIsActive(false);
91
+ }
92
+ }
93
+
94
+ getPriorityQueue(){
95
+ return this.priorityQueue;
96
+ }
97
+
98
+ clearPriorityQueue() {
99
+ this.priorityQueue = [];
100
+ this.setPriorityQueueIsActive(false);
101
+ }
102
+
42
103
  updateDeviceConfig(config) {
43
104
  if(config.address !== "" && config.address !== null && config.address !== "undefined") {
44
105
  if(config.net && config.adr) {
package/bacnet_gateway.js CHANGED
@@ -264,6 +264,21 @@ module.exports = function (RED) {
264
264
  }
265
265
  });
266
266
 
267
+ //route handler for priority queue
268
+ RED.httpAdmin.post('/bitpool-bacnet-data/priorityQueue', function (req, res) {
269
+ if (!node.bacnetClient) {
270
+ logOut("Issue with the bacnetClient while getting device list: ", node.bacnetClient);
271
+ res.send(false);
272
+ } else {
273
+ node.bacnetClient.updatePriorityQueue(req).then(function (result) {
274
+ res.send(result);
275
+ }).catch(function (error) {
276
+ res.send(error);
277
+ logOut("Error updating priorityQueue: ", error);
278
+ });
279
+ }
280
+ });
281
+
267
282
  node.on('close', function () {
268
283
  //do nothing
269
284
  });
package/bacnet_read.html CHANGED
@@ -436,21 +436,12 @@
436
436
  if (node.vm.$data.devices) node.devices = node.vm.$data.devices;
437
437
  if (node.vm.$data.readDevices) node.readDevices = node.vm.$data.readDevices;
438
438
  if (node.vm.$data.pointsToRead) node.pointsToRead = node.vm.$data.pointsToRead;
439
-
440
- // if (node.vm.$data.devices && node.vm.$data.devices.length > 0) node.devices = node.vm.$data.devices;
441
- // if (node.vm.$data.readDevices && node.vm.$data.readDevices.length > 0) node.readDevices = node.vm.$data.readDevices;
442
- // if (node.vm.$data.pointsToRead && node.vm.$data.pointsToRead.length > 0) node.pointsToRead = node.vm.$data.pointsToRead;
443
-
444
439
  },
445
440
  oneditcancel: function () {
446
441
  let node = this;
447
442
  if (node.vm.$data.devices) node.devices = node.vm.$data.devices;
448
443
  if (node.vm.$data.readDevices) node.readDevices = node.vm.$data.readDevices;
449
444
  if (node.vm.$data.pointsToRead) node.pointsToRead = node.vm.$data.pointsToRead;
450
-
451
- // if (node.vm.$data.devices && node.vm.$data.devices.length > 0) node.devices = node.vm.$data.devices;
452
- // if (node.vm.$data.readDevices && node.vm.$data.readDevices.length > 0) node.readDevices = node.vm.$data.readDevices;
453
- // if (node.vm.$data.pointsToRead && node.vm.$data.pointsToRead.length > 0) node.pointsToRead = node.vm.$data.pointsToRead;
454
445
  }
455
446
  });
456
447
 
package/bacnet_read.js CHANGED
@@ -5,6 +5,8 @@
5
5
 
6
6
 
7
7
  module.exports = function (RED) {
8
+ const fetch = require('node-fetch');
9
+ const http = require("http");
8
10
  const { ReadCommandConfig } = require('./common');
9
11
  const baEnum = require('./resources/node-bacstack-ts/dist/index.js').enum;
10
12
 
@@ -49,7 +51,23 @@ module.exports = function (RED) {
49
51
  return propArr;
50
52
  };
51
53
 
52
- var nodeContext = this.context().flow;
54
+ //send point list status for device priority queue
55
+ let headers = {
56
+ 'Content-Type' : "application/json"
57
+ };
58
+
59
+ const agent = new http.Agent({
60
+ rejectUnauthorized: false
61
+ });
62
+
63
+ fetch('http://localhost:1880/bitpool-bacnet-data/priorityQueue', {method: 'POST', headers: headers, agent: agent, body: JSON.stringify(node.pointsToRead)})
64
+ .then(function(res) {
65
+ //do nothing
66
+ }).catch(function(error) {
67
+ //do nothing
68
+ });
69
+
70
+
53
71
 
54
72
  node.on('input', function(msg) {
55
73
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bitpoolos/edge-bacnet",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
4
  "description": "A bacnet gateway for node-red",
5
5
  "dependencies": {
6
6
  "@plus4nodered/ts-node-bacnet": "^1.0.0-beta.2",
@@ -8,6 +8,7 @@
8
8
  "cronosjs": "^1.7.1",
9
9
  "debug": "^4.1.1",
10
10
  "iconv-lite": "^0.5.1",
11
+ "node-fetch": "^2.6.1",
11
12
  "toad-scheduler": "^1.6.0",
12
13
  "underscore": "^1.10.2",
13
14
  "winston": "^3.2.1"