@bitpoolos/edge-bacnet 1.2.5 → 1.2.7

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_read.html CHANGED
@@ -106,7 +106,7 @@
106
106
  app.pollFrequency = parseInt(result.pollFrequency);
107
107
  app.deviceCount = result.deviceList.length;
108
108
  //progress bar percentage
109
- let progressVal = parseInt((result.renderList.length / result.deviceList.length) * 100);
109
+ let progressVal = parseInt((result.renderListCount / result.deviceList.length) * 100);
110
110
  if(typeof progressVal == "number" && !isNaN(progressVal)) {
111
111
  app.progressBarValue = progressVal;
112
112
  } else {
@@ -231,7 +231,7 @@
231
231
  node.hiddenDeployToggle = !node.prevHiddenToggleState;
232
232
 
233
233
  } catch(e) {
234
- console.log("removeAllClicked error: ", e);
234
+ //do nothing
235
235
  }
236
236
 
237
237
  app.$forceUpdate();
@@ -241,11 +241,26 @@
241
241
  //update UI
242
242
  let parentDeviceName = slotProps.node.parentDevice;
243
243
  let foundDeviceIndex = this.readDevices ? this.readDevices.findIndex(ele => ele.label == parentDeviceName) : -1;
244
- let parentDevice = this.devices.find(ele => ele.label == parentDeviceName);
244
+ let device = this.deviceList.find(ele => ele.deviceName == parentDeviceName);
245
+ let deviceAddress = app.getDeviceAddress(device.address);
246
+ let key = `${deviceAddress}-${device.deviceId}`;
247
+ let parentDevice = this.devices.find(ele => ele.ipAddr == deviceAddress);
248
+ let childDevice;
249
+ if(device.isMstp){
250
+ let foundChildIndex = parentDevice.children[1].children.findIndex(ele => ele.label == parentDeviceName);
251
+ if(foundChildIndex !== -1) {
252
+ childDevice = parentDevice.children[1].children[foundChildIndex];
253
+ }
254
+ }
245
255
 
246
256
  if (foundDeviceIndex == -1) {
247
257
  //no read devices present, add new
248
- let newReadParent = {...parentDevice};
258
+ let newReadParent;
259
+ if(childDevice) {
260
+ newReadParent = {...childDevice};
261
+ } else{
262
+ newReadParent = {...parentDevice};
263
+ }
249
264
  newReadParent.children = [];
250
265
  newReadParent.children.push(slotProps.node);
251
266
 
@@ -260,22 +275,10 @@
260
275
  }
261
276
 
262
277
  //set show added to true
263
- let slot = parentDevice.children.find(ele => ele.pointName == slotProps.node.pointName);
264
- slot.showAdded = true;
265
-
278
+ slotProps.node.showAdded = true;
266
279
  this.$forceUpdate();
267
280
 
268
281
  //update node-red data structure
269
- let device = this.deviceList.find(ele => {
270
- if(ele.address.address) {
271
- return ele.address.address == parentDevice.ipAddr && ele.deviceId == parentDevice.deviceId;
272
- } else {
273
- return ele.address == parentDevice.ipAddr && ele.deviceId == parentDevice.deviceId;
274
- }
275
- });
276
- let deviceAddress = app.getDeviceAddress(device.address);
277
- let key = `${deviceAddress}-${device.deviceId}`;
278
-
279
282
  if (!this.pointsToRead[key]) {
280
283
  this.pointsToRead[key] = {};
281
284
  }
@@ -294,6 +297,9 @@
294
297
  let parentDeviceName = slotProps.node.parentDevice;
295
298
  let foundDeviceIndex = this.readDevices ? this.readDevices.findIndex(ele => ele.label == parentDeviceName) : -1;
296
299
  let parentDevice = this.devices.find(ele => ele.label == parentDeviceName);
300
+ let device = this.deviceList.find(ele => ele.deviceName == parentDeviceName);
301
+ let deviceAddress = app.getDeviceAddress(device.address);
302
+ let key = `${deviceAddress}-${device.deviceId}`;
297
303
 
298
304
  if (foundDeviceIndex !== -1) {
299
305
  let foundIndex = this.readDevices[foundDeviceIndex].children.findIndex(ele => ele.key == slotProps.node.key && ele.pointName == slotProps.node.pointName);
@@ -304,21 +310,10 @@
304
310
  }
305
311
 
306
312
  //set show added to true
307
- let slot = parentDevice.showAdded ? slotProps.node : parentDevice.children.find(ele => ele.pointName == slotProps.node.pointName);
308
- slot.showAdded = false;
309
313
  slotProps.node.showAdded = false;
310
314
  this.$forceUpdate();
311
315
 
312
316
  //update node-red data stucture
313
- let device = this.deviceList.find(ele => {
314
- if(ele.address.address) {
315
- return ele.address.address == parentDevice.ipAddr && ele.deviceId == parentDevice.deviceId;
316
- } else {
317
- return ele.address == parentDevice.ipAddr && ele.deviceId == parentDevice.deviceId;
318
- }
319
- });
320
- let deviceAddress = app.getDeviceAddress(device.address);
321
- let key = `${deviceAddress}-${device.deviceId}`;
322
317
  let point = this.pointList[key][slotProps.node.pointName];
323
318
  if (this.pointsToRead[key][point.objectName]) delete this.pointsToRead[key][point.objectName];
324
319
  //if last point is removed, deleted whole entry
@@ -460,12 +455,22 @@
460
455
  if (node.vm.$data.devices) node.devices = node.vm.$data.devices;
461
456
  if (node.vm.$data.readDevices) node.readDevices = node.vm.$data.readDevices;
462
457
  if (node.vm.$data.pointsToRead) node.pointsToRead = node.vm.$data.pointsToRead;
458
+ //clear reload data function
459
+ if(node.reloadTimer) {
460
+ clearInterval(node.reloadTimer);
461
+ node.reloadTimer = null;
462
+ }
463
463
  },
464
464
  oneditcancel: function () {
465
465
  let node = this;
466
466
  if (node.vm.$data.devices) node.devices = node.vm.$data.devices;
467
467
  if (node.vm.$data.readDevices) node.readDevices = node.vm.$data.readDevices;
468
468
  if (node.vm.$data.pointsToRead) node.pointsToRead = node.vm.$data.pointsToRead;
469
+ //clear reload data function
470
+ if(node.reloadTimer) {
471
+ clearInterval(node.reloadTimer);
472
+ node.reloadTimer = null;
473
+ }
469
474
  }
470
475
  });
471
476
 
@@ -498,9 +503,6 @@
498
503
  .pointLabel {
499
504
  font-weight: 400;
500
505
  }
501
- /* .p-treenode-children {
502
- background-color: #f0f0f0;
503
- } */
504
506
  .deviceLabel {
505
507
  font-weight: 100;
506
508
  }
@@ -526,15 +528,17 @@
526
528
  }
527
529
  .p-treenode-children > li > .p-treenode-children > li {
528
530
  font-size: 14px;
529
- height: 25px;
531
+ /* height: 35px; */
530
532
  color: #b5b5b5 !important;
531
533
  }
532
534
  .p-treenode-children > li > .p-treenode-children > .p-treenode-label {
533
535
  color: #b5b5b5 !important;
534
536
  }
537
+ /*
535
538
  .p-treenode-children > li > .p-treenode-children > li:last-child {
536
- padding-bottom: 30px;
539
+ padding-bottom: 30px;
537
540
  }
541
+ */
538
542
  .p-tree-toggler:enabled:hover {
539
543
  background: #d5d5d5 !important;
540
544
  }
@@ -551,6 +555,7 @@
551
555
  .statusOffline {
552
556
  color: red;
553
557
  }
558
+
554
559
  .deviceLabel {
555
560
  position: absolute;
556
561
  }
@@ -659,6 +664,22 @@
659
664
  padding-right: 20px;
660
665
  }
661
666
 
667
+ .p-tree .p-treenode-children {
668
+ padding: 0 !important;
669
+ }
670
+
671
+ .p-tree-toggler .p-link {
672
+ width: 25px !important;
673
+ }
674
+
675
+
676
+ /*
677
+ .p-treenode-content {
678
+ height: 15px;
679
+ }
680
+ */
681
+
682
+
662
683
  </style>
663
684
 
664
685
  <div class="form-row">
@@ -701,7 +722,7 @@
701
722
 
702
723
 
703
724
  <div id="deviceListApp">
704
- <p-tree :value="devices" selectable="false" :filter="true" filterMode="lenient" filterPlaceholder="No results found." v-if="hasData()">
725
+ <p-tree :value="devices" selectable="false" :filter="true" filterMode="lenient" filterPlaceholder="No results found." v-if="hasData()">
705
726
  <template #device="slotProps">
706
727
  <div v-if="isDeviceActive(slotProps)" class="deviceLabelParent">
707
728
  <b class="deviceLabel">{{slotProps.node.label}} <b class="statusOnline deviceStatus">Online</b></b>
@@ -726,6 +747,15 @@
726
747
  </button>
727
748
  </template>
728
749
 
750
+ <!-- <template #pointFolder="slotProps">
751
+
752
+ </template>
753
+
754
+
755
+ <template #deviceFolder="slotProps">
756
+
757
+ </template> -->
758
+
729
759
  <template #point="slotProps" v-model:class="pointContent">
730
760
  <b class="pointLabel">{{slotProps.node.label}}</b>
731
761
 
package/bacnet_read.js CHANGED
@@ -5,7 +5,6 @@
5
5
 
6
6
 
7
7
  module.exports = function (RED) {
8
- const fetch = require('node-fetch');
9
8
  const http = require("http");
10
9
  const { ReadCommandConfig } = require('./common');
11
10
  const baEnum = require('./resources/node-bacstack-ts/dist/index.js').enum;
@@ -20,6 +19,7 @@ module.exports = function (RED) {
20
19
  this.pointsToRead = config.pointsToRead;
21
20
  this.readDevices = config.readDevices;
22
21
  this.id = config.id;
22
+ this.nodeName = config.name;
23
23
 
24
24
  this.object_property_simplePayload = config.object_property_simplePayload;
25
25
  this.object_property_fullObject = config.object_property_fullObject;
@@ -68,12 +68,13 @@ module.exports = function (RED) {
68
68
  node.send(priorityDevicesMsg);
69
69
 
70
70
  node.on('input', function(msg) {
71
+ node.status({ fill: "blue", shape: "dot", text: "Reading values" });
71
72
 
72
73
  let readConfig = new ReadCommandConfig(node.pointsToRead, node.object_props, node.roundDecimal);
73
-
74
74
  let output = {
75
75
  type: "Read",
76
76
  id: node.id,
77
+ readNodeName: node.nodeName,
77
78
  options: readConfig,
78
79
  objectPropertyType: {
79
80
  simplePayload: node.object_property_simplePayload,
@@ -84,9 +85,13 @@ module.exports = function (RED) {
84
85
  mqtt: node.mqtt
85
86
  }
86
87
  };
87
-
88
+
88
89
  node.send(output);
89
90
 
91
+ setTimeout(() => {
92
+ node.status({});
93
+ }, 3000);
94
+
90
95
  });
91
96
 
92
97
  };
package/bacnet_server.js CHANGED
@@ -8,7 +8,13 @@ class BacnetServer {
8
8
  constructor(client, deviceId, nodeRedVersion) {
9
9
  let that = this;
10
10
  that.bacnetClient = client;
11
- that.objectIdNumber = 1;
11
+
12
+ // object identifier init
13
+ that.objectIdNumber = {};
14
+ that.objectIdNumber[baEnum.ObjectType.ANALOG_VALUE] = 0;
15
+ that.objectIdNumber[baEnum.ObjectType.CHARACTERSTRING_VALUE] = 0;
16
+ that.objectIdNumber[baEnum.ObjectType.BINARY_VALUE] = 0;
17
+
12
18
  that.nodeRedVersion = nodeRedVersion;
13
19
  that.deviceId = deviceId;
14
20
  that.vendorId = 1401;
@@ -63,7 +69,8 @@ class BacnetServer {
63
69
  ],
64
70
  },
65
71
  [baEnum.ObjectType.ANALOG_VALUE]: [],
66
- [baEnum.ObjectType.CHARACTERSTRING_VALUE]: []
72
+ [baEnum.ObjectType.CHARACTERSTRING_VALUE]: [],
73
+ [baEnum.ObjectType.BINARY_VALUE]: []
67
74
  };
68
75
 
69
76
  try {
@@ -74,6 +81,7 @@ class BacnetServer {
74
81
  if(cachedData.objectStore) {
75
82
  that.objectStore[baEnum.ObjectType.ANALOG_VALUE] = cachedData.objectStore[baEnum.ObjectType.ANALOG_VALUE];
76
83
  that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE] = cachedData.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE];
84
+ that.objectStore[baEnum.ObjectType.BINARY_VALUE] = cachedData.objectStore[baEnum.ObjectType.BINARY_VALUE];
77
85
  }
78
86
  }
79
87
  } catch (error) {
@@ -121,8 +129,6 @@ class BacnetServer {
121
129
  }
122
130
 
123
131
  } catch(e) {
124
- console.log("Bacnet server readPropertyMultiple error: ", e);
125
-
126
132
  that.bacnetClient.client.errorResponse(
127
133
  data.address,
128
134
  baEnum.ConfirmedServiceChoice.READ_PROPERTY_MULTIPLE,
@@ -160,7 +166,7 @@ class BacnetServer {
160
166
  );
161
167
  }
162
168
  } catch(e) {
163
- console.log("Local BACnet device readProperty error: ", e);
169
+ //console.log("Local BACnet device readProperty error: ", e);
164
170
  }
165
171
 
166
172
  });
@@ -180,55 +186,87 @@ class BacnetServer {
180
186
  let that = this;
181
187
  let objectType = that.getBacnetObjectType(value);
182
188
  if(name && objectType) {
189
+ let instanceNumber;
190
+ if (name.includes('|')) {
191
+ // split name, assign last part to instanceNumber and the rest to name
192
+ let nameParts = name.split('|');
193
+ instanceNumber = nameParts[nameParts.length - 1];
194
+ nameParts.pop();
195
+ name = nameParts.join('|');
196
+ }
183
197
  let formattedName = name.replaceAll('.', '_');
184
198
  formattedName = formattedName.replaceAll('/', '_');
185
199
  if(objectType == "number") {
186
200
  let foundIndex = that.objectStore[baEnum.ObjectType.ANALOG_VALUE].findIndex(ele => ele[baEnum.PropertyIdentifier.OBJECT_NAME][0].value == formattedName);
187
201
  if(foundIndex == -1) {
188
- let objectId = that.getObjectIdentifier();
189
- that.objectStore[baEnum.ObjectType.ANALOG_VALUE].push({
202
+ let objectId = that.getObjectIdentifier(baEnum.ObjectType.ANALOG_VALUE, instanceNumber);
203
+ that.objectStore[baEnum.ObjectType.ANALOG_VALUE].push({
204
+ [baEnum.PropertyIdentifier.OBJECT_NAME]: [{value: formattedName, type: 7}],
205
+ [baEnum.PropertyIdentifier.OBJECT_TYPE]: [{value: baEnum.ObjectType.ANALOG_VALUE, type: 9}],
206
+ [baEnum.PropertyIdentifier.DESCRIPTION]: [{value: '', type: 7}],
207
+ [baEnum.PropertyIdentifier.OBJECT_IDENTIFIER]: [{value: {type: baEnum.ObjectType.ANALOG_VALUE, instance: objectId}, type: 12}],
208
+ [baEnum.PropertyIdentifier.PRESENT_VALUE]: [{value: value, type: 4}],
209
+ [baEnum.PropertyIdentifier.STATUS_FLAGS]: [{value: 0, type: 8}],
210
+ [baEnum.PropertyIdentifier.EVENT_STATE]: [{value: 0, type: 9}],
211
+ [baEnum.PropertyIdentifier.OUT_OF_SERVICE]: [{value: 0, type: 9}],
212
+ [baEnum.PropertyIdentifier.UNITS]: [{value: 95, type: 9}],
213
+ [baEnum.PropertyIdentifier.PRIORITY_ARRAY]: [{value: 0, type: 9}],
214
+ [baEnum.PropertyIdentifier.MAX_PRES_VALUE]: [{value: value, type: 4}],
215
+ [baEnum.PropertyIdentifier.MIN_PRES_VALUE]: [{value: value, type: 4}],
216
+ [baEnum.PropertyIdentifier.RESOLUTION]: [{value: 0, type: 4}],
217
+ [baEnum.PropertyIdentifier.PROPERTY_LIST]:
218
+ [
219
+ {value: baEnum.PropertyIdentifier.OBJECT_NAME, type: 9 },
220
+ {value: baEnum.PropertyIdentifier.OBJECT_TYPE, type: 9 },
221
+ {value: baEnum.PropertyIdentifier.DESCRIPTION, type: 9 },
222
+ {value: baEnum.PropertyIdentifier.OBJECT_IDENTIFIER, type: 9 },
223
+ {value: baEnum.PropertyIdentifier.PRESENT_VALUE, type: 9 },
224
+ {value: baEnum.PropertyIdentifier.STATUS_FLAGS, type: 9 },
225
+ {value: baEnum.PropertyIdentifier.EVENT_STATE, type: 9 },
226
+ {value: baEnum.PropertyIdentifier.OUT_OF_SERVICE, type: 9 },
227
+ {value: baEnum.PropertyIdentifier.UNITS, type: 9 },
228
+ {value: baEnum.PropertyIdentifier.PRIORITY_ARRAY, type: 9 },
229
+ {value: baEnum.PropertyIdentifier.MAX_PRES_VALUE, type: 9 },
230
+ {value: baEnum.PropertyIdentifier.MIN_PRES_VALUE, type: 9 },
231
+ {value: baEnum.PropertyIdentifier.RESOLUTION, type: 9 },
232
+ ],
233
+ });
234
+
235
+ that.objectList.push({value: {type: baEnum.ObjectType.ANALOG_VALUE, instance: objectId}, type: 12})
236
+ that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_LIST] = that.objectList;
237
+ } else if(foundIndex !== -1) {
238
+ let foundObject = that.objectStore[baEnum.ObjectType.ANALOG_VALUE][foundIndex];
239
+ foundObject[baEnum.PropertyIdentifier.PRESENT_VALUE][0].value = value;
240
+ that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_LIST] = that.objectList;
241
+ }
242
+ } else if (objectType == "boolean") {
243
+ let foundIndex = that.objectStore[baEnum.ObjectType.BINARY_VALUE].findIndex(ele => ele[baEnum.PropertyIdentifier.OBJECT_NAME][0].value == formattedName);
244
+ if(foundIndex == -1) {
245
+ let objectId = that.getObjectIdentifier(baEnum.ObjectType.BINARY_VALUE);
246
+ that.objectStore[baEnum.ObjectType.BINARY_VALUE].push({
190
247
  [baEnum.PropertyIdentifier.OBJECT_NAME]: [{value: formattedName, type: 7}],
191
- [baEnum.PropertyIdentifier.OBJECT_TYPE]: [{value: baEnum.ObjectType.ANALOG_VALUE, type: 9}],
248
+ [baEnum.PropertyIdentifier.OBJECT_TYPE]: [{value: baEnum.ObjectType.BINARY_VALUE, type: 9}],
192
249
  [baEnum.PropertyIdentifier.DESCRIPTION]: [{value: '', type: 7}],
193
- [baEnum.PropertyIdentifier.OBJECT_IDENTIFIER]: [{value: {type: baEnum.ObjectType.ANALOG_VALUE, instance: objectId}, type: 12}],
194
- [baEnum.PropertyIdentifier.PRESENT_VALUE]: [{value: value, type: 4}],
250
+ [baEnum.PropertyIdentifier.OBJECT_IDENTIFIER]: [{value: {type: baEnum.ObjectType.BINARY_VALUE, instance: objectId}, type: 12}],
251
+ [baEnum.PropertyIdentifier.PRESENT_VALUE]: [{value: value, type: 1}],
195
252
  [baEnum.PropertyIdentifier.STATUS_FLAGS]: [{value: 0, type: 8}],
196
253
  [baEnum.PropertyIdentifier.EVENT_STATE]: [{value: 0, type: 9}],
197
254
  [baEnum.PropertyIdentifier.OUT_OF_SERVICE]: [{value: 0, type: 9}],
198
- [baEnum.PropertyIdentifier.UNITS]: [{value: 95, type: 9}],
199
- [baEnum.PropertyIdentifier.PRIORITY_ARRAY]: [{value: 0, type: 9}],
200
- [baEnum.PropertyIdentifier.MAX_PRES_VALUE]: [{value: value, type: 4}],
201
- [baEnum.PropertyIdentifier.MIN_PRES_VALUE]: [{value: value, type: 4}],
202
- [baEnum.PropertyIdentifier.RESOLUTION]: [{value: 0, type: 4}],
203
- [baEnum.PropertyIdentifier.PROPERTY_LIST]:
204
- [
205
- {value: baEnum.PropertyIdentifier.OBJECT_NAME, type: 9 },
206
- {value: baEnum.PropertyIdentifier.OBJECT_TYPE, type: 9 },
207
- {value: baEnum.PropertyIdentifier.DESCRIPTION, type: 9 },
208
- {value: baEnum.PropertyIdentifier.OBJECT_IDENTIFIER, type: 9 },
209
- {value: baEnum.PropertyIdentifier.PRESENT_VALUE, type: 9 },
210
- {value: baEnum.PropertyIdentifier.STATUS_FLAGS, type: 9 },
211
- {value: baEnum.PropertyIdentifier.EVENT_STATE, type: 9 },
212
- {value: baEnum.PropertyIdentifier.OUT_OF_SERVICE, type: 9 },
213
- {value: baEnum.PropertyIdentifier.UNITS, type: 9 },
214
- {value: baEnum.PropertyIdentifier.PRIORITY_ARRAY, type: 9 },
215
- {value: baEnum.PropertyIdentifier.MAX_PRES_VALUE, type: 9 },
216
- {value: baEnum.PropertyIdentifier.MIN_PRES_VALUE, type: 9 },
217
- {value: baEnum.PropertyIdentifier.RESOLUTION, type: 9 },
218
- ],
255
+ [baEnum.PropertyIdentifier.ACTIVE_TEXT]: [{value: 'ACTIVE', type: 7}],
256
+ [baEnum.PropertyIdentifier.INACTIVE_TEXT]: [{value: 'INACTIVE', type: 7}],
219
257
  });
220
258
 
221
- that.objectList.push({value: {type: baEnum.ObjectType.ANALOG_VALUE, instance: objectId}, type: 12})
259
+ that.objectList.push({value: {type: baEnum.ObjectType.BINARY_VALUE, instance: objectId}, type: 12})
222
260
  that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_LIST] = that.objectList;
223
261
  } else if(foundIndex !== -1) {
224
- let foundObject = that.objectStore[baEnum.ObjectType.ANALOG_VALUE][foundIndex];
262
+ let foundObject = that.objectStore[baEnum.ObjectType.BINARY_VALUE][foundIndex];
225
263
  foundObject[baEnum.PropertyIdentifier.PRESENT_VALUE][0].value = value;
226
264
  that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_LIST] = that.objectList;
227
265
  }
228
266
  } else if(objectType == "string") {
229
267
  let foundIndex = that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE].findIndex(ele => ele[baEnum.PropertyIdentifier.OBJECT_NAME][0].value == formattedName);
230
268
  if(foundIndex == -1) {
231
- let objectId = that.getObjectIdentifier();
269
+ let objectId = that.getObjectIdentifier(baEnum.ObjectType.CHARACTERSTRING_VALUE);
232
270
  that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE].push({
233
271
  [baEnum.PropertyIdentifier.OBJECT_NAME]: [{value: formattedName, type: 7}],
234
272
  [baEnum.PropertyIdentifier.OBJECT_TYPE]: [{value: baEnum.ObjectType.CHARACTERSTRING_VALUE, type: 9}],
@@ -350,11 +388,119 @@ class BacnetServer {
350
388
  that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE] = [];
351
389
  that.objectStore[baEnum.ObjectType.ANALOG_VALUE] = [];
352
390
 
353
- that.objectIdNumber = 1;
391
+ that.objectIdNumber = {};
392
+ that.objectIdNumber[baEnum.ObjectType.ANALOG_VALUE] = 0;
393
+ that.objectIdNumber[baEnum.ObjectType.CHARACTERSTRING_VALUE] = 0;
394
+ that.objectIdNumber[baEnum.ObjectType.BINARY_VALUE] = 0;
354
395
 
355
396
  Store_Config_Server(JSON.stringify({objectList: that.objectList, objectStore: that.objectStore}));
356
397
  }
357
398
 
399
+ clearServerPoint(json) {
400
+ let that = this;
401
+ return new Promise(async function (resolve, reject) {
402
+ try {
403
+ let type;
404
+ switch (json.body.type) {
405
+ case 'SV':
406
+ type = baEnum.ObjectType.CHARACTERSTRING_VALUE;
407
+ break;
408
+ case 'BV':
409
+ type = baEnum.ObjectType.BINARY_VALUE;
410
+ break;
411
+ default:
412
+ type = baEnum.ObjectType.ANALOG_VALUE;
413
+ break;
414
+ }
415
+
416
+ // remove object from objectStore
417
+ let objectGroup = that.objectStore[type];
418
+ if (Array.isArray(objectGroup)) {
419
+ for (let i = 0; i < objectGroup.length; i++) {
420
+ let object = objectGroup[i];
421
+ if (object[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance == json.body.instance) {
422
+ that.objectStore[type].splice(i, 1);
423
+ break;
424
+ }
425
+ }
426
+ } else {
427
+ delete that.objectStore[type];
428
+ }
429
+
430
+ // remove object from objectList
431
+ let objectIndex = that.objectList.findIndex(ele =>
432
+ ele.value.instance == json.body.instance && ele.value.type == type);
433
+ if (objectIndex !== -1) {
434
+ that.objectList.splice(objectIndex, 1);
435
+ }
436
+
437
+ // update objectList in device object
438
+ that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_LIST] = that.objectList;
439
+
440
+ Store_Config_Server(JSON.stringify({ objectList: that.objectList, objectStore: that.objectStore }));
441
+
442
+ resolve(true);
443
+ } catch (e) {
444
+ reject(e);
445
+ }
446
+ });
447
+ }
448
+
449
+ getServerPoints() {
450
+ let that = this;
451
+ let points = [];
452
+
453
+ return new Promise(async function (resolve, reject) {
454
+ try {
455
+ // iterate analog value objects
456
+ if(that.objectStore[baEnum.ObjectType.ANALOG_VALUE] && that.objectStore[baEnum.ObjectType.ANALOG_VALUE].length > 0) {
457
+ that.objectStore[baEnum.ObjectType.ANALOG_VALUE].forEach((point) => {
458
+ let instance = point[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance;
459
+ let objectName = point[baEnum.PropertyIdentifier.OBJECT_NAME][0].value;
460
+
461
+ points.push({
462
+ name: objectName,
463
+ type: "AV",
464
+ instance
465
+ });
466
+ });
467
+ }
468
+
469
+ // iterate character string value objects
470
+ if(that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE] && that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE].length > 0) {
471
+ that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE].forEach((point) => {
472
+ let instance = point[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance;
473
+ let objectName = point[baEnum.PropertyIdentifier.OBJECT_NAME][0].value;
474
+
475
+ points.push({
476
+ name: objectName,
477
+ type: "SV",
478
+ instance
479
+ });
480
+ });
481
+ }
482
+
483
+ // iterate binary value objects
484
+ if(that.objectStore[baEnum.ObjectType.BINARY_VALUE] && that.objectStore[baEnum.ObjectType.BINARY_VALUE].length > 0) {
485
+ that.objectStore[baEnum.ObjectType.BINARY_VALUE].forEach((point) => {
486
+ let instance = point[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance;
487
+ let objectName = point[baEnum.PropertyIdentifier.OBJECT_NAME][0].value;
488
+
489
+ points.push({
490
+ name: objectName,
491
+ type: "BV",
492
+ instance
493
+ });
494
+ });
495
+ }
496
+
497
+ resolve(points.sort((a, b) => (a.instance > b.instance) ? 1 : -1));
498
+ } catch (e) {
499
+ reject(e);
500
+ }
501
+ });
502
+ }
503
+
358
504
  getRandomArbitrary(min, max) {
359
505
  return Math.random() * (max - min) + min;
360
506
  }
@@ -367,16 +513,23 @@ class BacnetServer {
367
513
  return "string"
368
514
  case "number":
369
515
  return "number"
516
+ case "boolean":
517
+ return "boolean"
370
518
  default:
371
519
  return null
372
520
  }
373
521
  }
374
522
 
375
- getObjectIdentifier() {
376
- let that = this;
377
- let objectId = that.objectIdNumber;
378
- that.objectIdNumber++;
379
-
523
+ getObjectIdentifier(type, instanceNumber) {
524
+ let that = this;
525
+ // manual instance numbering
526
+ if (instanceNumber) {
527
+ that.objectIdNumber[type] = instanceNumber + 1;
528
+ return instanceNumber;
529
+ }
530
+ // auto instance numbering
531
+ let objectId = that.objectIdNumber[type];
532
+ that.objectIdNumber[type]++;
380
533
  return objectId;
381
534
  }
382
535