@bitpoolos/edge-bacnet 1.4.1 → 1.4.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_read.html CHANGED
@@ -11,6 +11,7 @@
11
11
  events: { value: true },
12
12
  json: { value: true },
13
13
  mqtt: { value: false },
14
+ pointJson: { value: false },
14
15
  hiddenDeployToggle: { value: false },
15
16
  prevHiddenToggleState: { value: false },
16
17
  roundDecimal: { value: 2 },
@@ -21,6 +22,7 @@
21
22
  object_property_simplePayload: { value: false },
22
23
  object_property_simpleWithStatus: { value: false },
23
24
  object_property_fullObject: { value: true },
25
+ useDeviceName: { value: true },
24
26
  },
25
27
  inputs: 1,
26
28
  outputs: 1,
@@ -725,75 +727,21 @@
725
727
  if (pointName == "deviceName") {
726
728
  app.nodeService.setDeviceDisplayName(device, point);
727
729
  treeDevice.label = point;
728
- }
729
- let pointInTree = treeDevice.children[0].children.find(
730
- (ele) => ele.data == pointName && ele.bacnetType == point.meta.objectId.type
731
- );
732
-
733
- if (pointInTree) {
734
- pointInTree.label = point.displayName;
735
-
736
- const isDeviceInReadList = app.readDevices
737
- ? app.readDevices.findIndex((ele) => ele.deviceId == treeDevice.deviceId)
738
- : -1;
739
-
740
- if (isDeviceInReadList == -1) {
741
- //no read devices present, add new
742
- let newReadParent = JSON.parse(JSON.stringify(treeDevice));
743
- newReadParent.children[0].children = [];
744
- newReadParent.children[0].children.push(pointInTree);
745
- if (app.readDevices) {
746
- app.readDevices.push(newReadParent);
747
- } else {
748
- app.readDevices = [newReadParent];
749
- }
750
- } else {
751
- // read device found, add point to existing
752
- let pointIndex = app.readDevices[isDeviceInReadList].children[0].children.findIndex(
753
- (ele) => ele.data == point.objectName
754
- );
755
- if (pointIndex == -1) {
756
- app.readDevices[isDeviceInReadList].children[0].children.push(pointInTree);
757
- } else {
758
- app.readDevices[isDeviceInReadList].children[0].children[pointIndex] = pointInTree;
759
- }
760
- }
761
- }
762
- }
763
- } else {
764
- //search mstp devices
765
- let mstpIndex = app.devices[foundIndex].children[1].children.findIndex((ele) => ele.deviceId == id);
766
-
767
- if (mstpIndex !== -1) {
768
- let mstpDevice = app.devices[foundIndex].children[1].children[mstpIndex];
769
- let device = app.deviceList.find((ele) => {
770
- if (ele.address.address) {
771
- return ele.address.address == ip && ele.deviceId == id;
772
- } else {
773
- return ele.address == ip && ele.deviceId == id;
774
- }
775
- });
776
-
777
- for (let pointName in importedDevice) {
778
- let point = importedDevice[pointName];
779
- if (pointName == "deviceName") {
780
- app.nodeService.setDeviceDisplayName(device, point);
781
- mstpDevice.label = point;
782
- }
783
- let pointInTree = mstpDevice.children[0].children.find(
784
- (ele) => ele.data == pointName && ele.bacnetType == point.meta.objectId.type
730
+ } else {
731
+ let pointInTree = treeDevice.children[0].children.find(
732
+ (ele) => ele.bacnetInstance == point.meta.objectId.instance && ele.bacnetType == point.meta.objectId.type
785
733
  );
786
734
 
787
735
  if (pointInTree) {
788
736
  pointInTree.label = point.displayName;
789
737
 
790
738
  const isDeviceInReadList = app.readDevices
791
- ? app.readDevices.findIndex((ele) => ele.deviceId == mstpDevice.deviceId)
739
+ ? app.readDevices.findIndex((ele) => ele.deviceId == treeDevice.deviceId)
792
740
  : -1;
793
741
 
794
742
  if (isDeviceInReadList == -1) {
795
743
  //no read devices present, add new
796
- let newReadParent = JSON.parse(JSON.stringify(mstpDevice));
744
+ let newReadParent = JSON.parse(JSON.stringify(treeDevice));
797
745
  newReadParent.children[0].children = [];
798
746
  newReadParent.children[0].children.push(pointInTree);
799
747
  if (app.readDevices) {
@@ -814,6 +762,74 @@
814
762
  }
815
763
  }
816
764
  }
765
+ }
766
+ } else {
767
+ //search mstp devices
768
+ let mstpIndex = -1;
769
+ let folderIndex = -1;
770
+
771
+ app.devices[foundIndex].children.forEach(function (child, index) {
772
+ let temporaryIndex = -1;
773
+ if (child.label.includes("MSTP")) {
774
+ temporaryIndex = child.children.findIndex((ele) => ele.deviceId == id);
775
+ }
776
+ if (temporaryIndex !== -1) {
777
+ mstpIndex = temporaryIndex;
778
+ folderIndex = index;
779
+ }
780
+ });
781
+
782
+ if (mstpIndex !== -1 && folderIndex !== -1) {
783
+ let mstpDevice = app.devices[foundIndex].children[folderIndex].children[mstpIndex];
784
+ let device = app.deviceList.find((ele) => {
785
+ if (ele.address.address) {
786
+ return ele.address.address == ip && ele.deviceId == id;
787
+ } else {
788
+ return ele.address == ip && ele.deviceId == id;
789
+ }
790
+ });
791
+
792
+ for (let pointName in importedDevice) {
793
+ let point = importedDevice[pointName];
794
+ if (pointName == "deviceName") {
795
+ app.nodeService.setDeviceDisplayName(device, point);
796
+ mstpDevice.label = point;
797
+ } else {
798
+ let pointInTree = mstpDevice.children[0].children.find(
799
+ (ele) => ele.bacnetInstance == point.meta.objectId.instance && ele.bacnetType == point.meta.objectId.type
800
+ );
801
+
802
+ if (pointInTree) {
803
+ pointInTree.label = point.displayName;
804
+
805
+ const isDeviceInReadList = app.readDevices
806
+ ? app.readDevices.findIndex((ele) => ele.deviceId == mstpDevice.deviceId)
807
+ : -1;
808
+
809
+ if (isDeviceInReadList == -1) {
810
+ //no read devices present, add new
811
+ let newReadParent = JSON.parse(JSON.stringify(mstpDevice));
812
+ newReadParent.children[0].children = [];
813
+ newReadParent.children[0].children.push(pointInTree);
814
+ if (app.readDevices) {
815
+ app.readDevices.push(newReadParent);
816
+ } else {
817
+ app.readDevices = [newReadParent];
818
+ }
819
+ } else {
820
+ // read device found, add point to existing
821
+ let pointIndex = app.readDevices[isDeviceInReadList].children[0].children.findIndex(
822
+ (ele) => ele.data == point.objectName
823
+ );
824
+ if (pointIndex == -1) {
825
+ app.readDevices[isDeviceInReadList].children[0].children.push(pointInTree);
826
+ } else {
827
+ app.readDevices[isDeviceInReadList].children[0].children[pointIndex] = pointInTree;
828
+ }
829
+ }
830
+ }
831
+ }
832
+ }
817
833
  } else {
818
834
  // not part of device list at all, notify user
819
835
  }
@@ -823,6 +839,9 @@
823
839
 
824
840
  app.$forceUpdate();
825
841
  },
842
+ refreshReadListTree() {
843
+ this.addToReadDevices(this.pointsToRead);
844
+ },
826
845
  calculateMstpCount(slotProps) {
827
846
  let count = 0;
828
847
  slotProps.node.children.forEach(function (child) {
@@ -876,6 +895,10 @@
876
895
  document.getElementById("node-input-json").onclick = handleMsgTypeClick;
877
896
  document.getElementById("node-input-mqtt").checked = node.mqtt;
878
897
  document.getElementById("node-input-mqtt").onclick = handleMsgTypeClick;
898
+ document.getElementById("node-input-pointJson").checked = node.pointJson;
899
+ document.getElementById("node-input-pointJson").onclick = handleMsgTypeClick;
900
+
901
+ document.getElementById("node-input-useDeviceName").checked = node.useDeviceName;
879
902
 
880
903
  var menu = document.querySelector(".context-menu");
881
904
  window.addEventListener("click", (event) => {
@@ -904,10 +927,16 @@
904
927
 
905
928
  function handleMsgTypeClick() {
906
929
  if (this.id == "node-input-json") {
907
- document.getElementById("node-input-mqtt").checked = !document.getElementById("node-input-mqtt").checked;
930
+ document.getElementById("node-input-mqtt").checked = false;
931
+ document.getElementById("node-input-pointJson").checked = false;
908
932
  }
909
933
  if (this.id == "node-input-mqtt") {
910
- document.getElementById("node-input-json").checked = !document.getElementById("node-input-json").checked;
934
+ document.getElementById("node-input-json").checked = false;
935
+ document.getElementById("node-input-pointJson").checked = false;
936
+ }
937
+ if (this.id == "node-input-pointJson") {
938
+ document.getElementById("node-input-json").checked = false;
939
+ document.getElementById("node-input-mqtt").checked = false;
911
940
  }
912
941
  }
913
942
 
@@ -1195,8 +1224,11 @@
1195
1224
  <input type="file" id="readlist-file-upload" accept="application/JSON" class="inputStyle" style="display: none;" />
1196
1225
 
1197
1226
  <button @click="removeAllDevices()" class="removeAllDevicesButton" title="Remove all devices">
1198
- <i class="pi pi-minus-circle" style="color: #ff0000; padding-right: 5px;"> </i
1199
- ><a style="color: #ff0000;">Remove All Devices</a>
1227
+ <a style="color: #ff0000;">Remove All Devices</a>
1228
+ </button>
1229
+
1230
+ <button @click="refreshReadListTree()" class="refreshReadListButton" title="Refresh tree">
1231
+ <i class="pi pi-refresh" style="color: #00AEEF;"> </i>
1200
1232
  </button>
1201
1233
  </div>
1202
1234
 
@@ -1312,9 +1344,36 @@
1312
1344
  >Individual msgs</label
1313
1345
  >
1314
1346
  </div>
1347
+ <div style="display: flex; flex-direction: row; align-items: flex-start;">
1348
+ <input
1349
+ class="checkbox-round"
1350
+ type="checkbox"
1351
+ id="node-input-pointJson"
1352
+ style="width: 13px; margin-left: 5px;" /><label
1353
+ for="node-input-pointJson"
1354
+ style="padding-left: 20px; width: fit-content;"
1355
+ >Individual JSON</label
1356
+ >
1357
+ </div>
1315
1358
  </div>
1316
1359
  </div>
1317
1360
 
1361
+ <hr />
1362
+
1363
+ <div class="objectPropertiesLabel" style="margin-top: 20px; margin-bottom: 20px;">
1364
+ <label
1365
+ for="node-input-useDeviceName"
1366
+ style="width: auto; align-items: start;"
1367
+ class="objectPropertiesLabel">
1368
+ <i class="icon-tag"></i> <span data-i18n="bitpool-bacnet.label.useDeviceName"></span>
1369
+ <input
1370
+ class=" objectProp"
1371
+ type="checkbox"
1372
+ id="node-input-useDeviceName" />
1373
+ <a style="white-space: nowrap; padding-left: 20px;">Use device name in topic</a>
1374
+ </label>
1375
+ </div>
1376
+
1318
1377
  <div class="form-row">
1319
1378
  <label for="node-input-roundDecimal"> Decimal place precision </label>
1320
1379
  <input type="number" id="node-input-roundDecimal" placeholder="None" />
package/bacnet_read.js CHANGED
@@ -15,6 +15,7 @@ module.exports = function (RED) {
15
15
 
16
16
  this.json = config.json;
17
17
  this.mqtt = config.mqtt;
18
+ this.pointJson = config.pointJson;
18
19
  this.roundDecimal = config.roundDecimal;
19
20
  this.pointsToRead = config.pointsToRead;
20
21
  this.readDevices = config.readDevices;
@@ -25,7 +26,7 @@ module.exports = function (RED) {
25
26
  this.object_property_simpleWithStatus = config.object_property_simpleWithStatus;
26
27
  this.object_property_fullObject = config.object_property_fullObject;
27
28
 
28
-
29
+ this.useDeviceName = config.useDeviceName;
29
30
 
30
31
  this.object_props = getObjectProps(this);
31
32
 
@@ -55,20 +56,62 @@ module.exports = function (RED) {
55
56
  node.on('input', function (msg) {
56
57
  node.status({ fill: "blue", shape: "dot", text: "Reading values" });
57
58
 
59
+ let object_property_simplePayload = false;
60
+ let object_property_simpleWithStatus = false;
61
+ let object_property_fullObject = false;
62
+
63
+ let jsonType = false;
64
+ let mqttType = false;
65
+ let pointJsonType = false;
66
+ let useDeviceName = false;
67
+
68
+ if (msg.simplePayload) {
69
+ object_property_simplePayload = msg.simplePayload;
70
+ } else if (msg.simpleWithStatus) {
71
+ object_property_simpleWithStatus = msg.simpleWithStatus;
72
+ } else if (msg.fullObject) {
73
+ object_property_fullObject = msg.fullObject;
74
+ } else {
75
+ object_property_simplePayload = node.object_property_simplePayload;
76
+ object_property_simpleWithStatus = node.object_property_simpleWithStatus;
77
+ object_property_fullObject = node.object_property_fullObject;
78
+ }
79
+
80
+ if (msg.json) {
81
+ jsonType = msg.json;
82
+ } else if (msg.mqtt) {
83
+ mqttType = msg.mqtt;
84
+ } else if (msg.pointJson) {
85
+ pointJsonType = msg.pointJson;
86
+ } else {
87
+ jsonType = node.json;
88
+ mqttType = node.mqtt;
89
+ pointJsonType = node.pointJson
90
+ }
91
+
92
+ if (msg.useDeviceName) {
93
+ useDeviceName = msg.useDeviceName;
94
+ } else {
95
+ useDeviceName = node.useDeviceName;
96
+ }
97
+
58
98
  let readConfig = new ReadCommandConfig(node.pointsToRead, node.object_props, node.roundDecimal);
99
+
59
100
  let output = {
60
101
  type: "Read",
61
102
  id: node.id,
62
103
  readNodeName: node.nodeName,
63
104
  options: readConfig,
64
105
  objectPropertyType: {
65
- simplePayload: node.object_property_simplePayload,
66
- simpleWithStatus: node.object_property_simpleWithStatus,
67
- fullObject: node.object_property_fullObject
106
+ simplePayload: object_property_simplePayload,
107
+ simpleWithStatus: object_property_simpleWithStatus,
108
+ fullObject: object_property_fullObject
68
109
  },
69
110
  outputType: {
70
- json: node.json,
71
- mqtt: node.mqtt
111
+ json: jsonType,
112
+ mqtt: mqttType,
113
+ pointJson: pointJsonType,
114
+ useDeviceName: useDeviceName
72
115
  }
73
116
  };
74
117
 
package/bacnet_server.js CHANGED
@@ -6,12 +6,12 @@ const { EventEmitter } = require("events");
6
6
 
7
7
  /**
8
8
  * Class representing a BACnet Server.
9
- *
9
+ *
10
10
  * This class initializes a BACnet server with specified client, device ID, and Node-Red version.
11
11
  * It provides methods to set device name, add objects, retrieve objects, clear server points, clear server point, and get server points.
12
- *
12
+ *
13
13
  * Simulates a BACnet IP device on a regular IP network
14
- *
14
+ *
15
15
  * @constructor
16
16
  * @param {Object} client - The BACnet client object.
17
17
  * @param {number} deviceId - The ID of the device.
@@ -248,7 +248,7 @@ class BacnetServer extends EventEmitter {
248
248
 
249
249
  /**
250
250
  * Set the name of the device.
251
- *
251
+ *
252
252
  * @param {string} nodeName - The new name for the device.
253
253
  */
254
254
  setDeviceName(nodeName) {
@@ -259,116 +259,85 @@ class BacnetServer extends EventEmitter {
259
259
  }
260
260
 
261
261
  /**
262
- * Adds a new object to the BacnetServer's object store based on the provided name and value.
263
- *
262
+ * Adds a new object to the BacnetServer's object store based on the provided name and payload.
263
+ *
264
264
  * @param {string} name - The name of the object to be added.
265
- * @param {number|boolean|string} value - The value of the object to be added.
265
+ * @param {number|boolean|string|object} payload - The payload of the object to be added.
266
266
  * @returns {void}
267
267
  */
268
- addObject(name, value) {
268
+ addObject(name, payload) {
269
269
  let that = this;
270
- let objectType = that.getBacnetObjectType(value);
270
+ let objectType = that.getBacnetObjectType(payload.value ?? payload);
271
271
  if (name && objectType) {
272
272
  let instanceNumber;
273
273
  if (name.includes('|')) {
274
274
  // split name, assign last part to instanceNumber and the rest to name
275
275
  let nameParts = name.split('|');
276
- instanceNumber = nameParts[nameParts.length - 1];
277
- nameParts.pop();
276
+ instanceNumber = nameParts.pop();
278
277
  name = nameParts.join('|');
279
278
  }
280
- let formattedName = name.replaceAll('.', '_');
281
- formattedName = formattedName.replaceAll('/', '_');
282
- if (objectType == "number") {
283
- let foundIndex = that.objectStore[baEnum.ObjectType.ANALOG_VALUE].findIndex(ele => ele[baEnum.PropertyIdentifier.OBJECT_NAME][0].value == formattedName);
284
- if (foundIndex == -1) {
285
- let objectId = that.getObjectIdentifier(baEnum.ObjectType.ANALOG_VALUE, instanceNumber);
286
- that.objectStore[baEnum.ObjectType.ANALOG_VALUE].push({
287
- [baEnum.PropertyIdentifier.OBJECT_NAME]: [{ value: formattedName, type: 7 }],
288
- [baEnum.PropertyIdentifier.OBJECT_TYPE]: [{ value: baEnum.ObjectType.ANALOG_VALUE, type: 9 }],
289
- [baEnum.PropertyIdentifier.DESCRIPTION]: [{ value: '', type: 7 }],
290
- [baEnum.PropertyIdentifier.OBJECT_IDENTIFIER]: [{ value: { type: baEnum.ObjectType.ANALOG_VALUE, instance: objectId }, type: 12 }],
291
- [baEnum.PropertyIdentifier.PRESENT_VALUE]: [{ value: value, type: 4 }],
292
- [baEnum.PropertyIdentifier.STATUS_FLAGS]: [{ value: 0, type: 8 }],
293
- [baEnum.PropertyIdentifier.EVENT_STATE]: [{ value: 0, type: 9 }],
294
- [baEnum.PropertyIdentifier.OUT_OF_SERVICE]: [{ value: 0, type: 9 }],
295
- [baEnum.PropertyIdentifier.UNITS]: [{ value: 95, type: 9 }],
296
- [baEnum.PropertyIdentifier.PRIORITY_ARRAY]: [{ value: 0, type: 9 }],
297
- [baEnum.PropertyIdentifier.MAX_PRES_VALUE]: [{ value: value, type: 4 }],
298
- [baEnum.PropertyIdentifier.MIN_PRES_VALUE]: [{ value: value, type: 4 }],
299
- [baEnum.PropertyIdentifier.RESOLUTION]: [{ value: 0, type: 4 }],
300
- [baEnum.PropertyIdentifier.PROPERTY_LIST]:
301
- [
302
- { value: baEnum.PropertyIdentifier.OBJECT_NAME, type: 9 },
303
- { value: baEnum.PropertyIdentifier.OBJECT_TYPE, type: 9 },
304
- { value: baEnum.PropertyIdentifier.DESCRIPTION, type: 9 },
305
- { value: baEnum.PropertyIdentifier.OBJECT_IDENTIFIER, type: 9 },
306
- { value: baEnum.PropertyIdentifier.PRESENT_VALUE, type: 9 },
307
- { value: baEnum.PropertyIdentifier.STATUS_FLAGS, type: 9 },
308
- { value: baEnum.PropertyIdentifier.EVENT_STATE, type: 9 },
309
- { value: baEnum.PropertyIdentifier.OUT_OF_SERVICE, type: 9 },
310
- { value: baEnum.PropertyIdentifier.UNITS, type: 9 },
311
- { value: baEnum.PropertyIdentifier.PRIORITY_ARRAY, type: 9 },
312
- { value: baEnum.PropertyIdentifier.MAX_PRES_VALUE, type: 9 },
313
- { value: baEnum.PropertyIdentifier.MIN_PRES_VALUE, type: 9 },
314
- { value: baEnum.PropertyIdentifier.RESOLUTION, type: 9 },
315
- ],
316
- });
317
-
318
- that.objectList.push({ value: { type: baEnum.ObjectType.ANALOG_VALUE, instance: objectId }, type: 12 })
319
- that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_LIST] = that.objectList;
320
- } else if (foundIndex !== -1) {
321
- let foundObject = that.objectStore[baEnum.ObjectType.ANALOG_VALUE][foundIndex];
322
- foundObject[baEnum.PropertyIdentifier.PRESENT_VALUE][0].value = value;
323
- that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_LIST] = that.objectList;
324
- }
325
- } else if (objectType == "boolean") {
326
- let foundIndex = that.objectStore[baEnum.ObjectType.BINARY_VALUE].findIndex(ele => ele[baEnum.PropertyIdentifier.OBJECT_NAME][0].value == formattedName);
327
- if (foundIndex == -1) {
328
- let objectId = that.getObjectIdentifier(baEnum.ObjectType.BINARY_VALUE);
329
- that.objectStore[baEnum.ObjectType.BINARY_VALUE].push({
330
- [baEnum.PropertyIdentifier.OBJECT_NAME]: [{ value: formattedName, type: 7 }],
331
- [baEnum.PropertyIdentifier.OBJECT_TYPE]: [{ value: baEnum.ObjectType.BINARY_VALUE, type: 9 }],
332
- [baEnum.PropertyIdentifier.DESCRIPTION]: [{ value: '', type: 7 }],
333
- [baEnum.PropertyIdentifier.OBJECT_IDENTIFIER]: [{ value: { type: baEnum.ObjectType.BINARY_VALUE, instance: objectId }, type: 12 }],
334
- [baEnum.PropertyIdentifier.PRESENT_VALUE]: [{ value: value, type: 1 }],
335
- [baEnum.PropertyIdentifier.STATUS_FLAGS]: [{ value: 0, type: 8 }],
336
- [baEnum.PropertyIdentifier.EVENT_STATE]: [{ value: 0, type: 9 }],
337
- [baEnum.PropertyIdentifier.OUT_OF_SERVICE]: [{ value: 0, type: 9 }],
338
- [baEnum.PropertyIdentifier.ACTIVE_TEXT]: [{ value: 'ACTIVE', type: 7 }],
339
- [baEnum.PropertyIdentifier.INACTIVE_TEXT]: [{ value: 'INACTIVE', type: 7 }],
340
- });
279
+ let formattedName = name.replaceAll('.', '_').replaceAll('/', '_');
280
+
281
+ const getCommonProperties = (type, valueType) => ({
282
+ [baEnum.PropertyIdentifier.OBJECT_NAME]: [{ value: formattedName, type: 7 }],
283
+ [baEnum.PropertyIdentifier.OBJECT_TYPE]: [{ value: type, type: 9 }],
284
+ [baEnum.PropertyIdentifier.DESCRIPTION]: [{ value: payload.description ?? '', type: 7 }],
285
+ [baEnum.PropertyIdentifier.OBJECT_IDENTIFIER]: [{ value: { type: type, instance: that.getObjectIdentifier(type, instanceNumber) }, type: 12 }],
286
+ [baEnum.PropertyIdentifier.PRESENT_VALUE]: [{ value: payload.value ?? payload, type: valueType }],
287
+ [baEnum.PropertyIdentifier.STATUS_FLAGS]: [{ value: payload.statusFlags ?? 0, type: 8 }],
288
+ [baEnum.PropertyIdentifier.EVENT_STATE]: [{ value: payload.eventState ?? 0, type: 9 }],
289
+ [baEnum.PropertyIdentifier.OUT_OF_SERVICE]: [{ value: payload.outOfService ?? 0, type: 9 }],
290
+ });
341
291
 
342
- that.objectList.push({ value: { type: baEnum.ObjectType.BINARY_VALUE, instance: objectId }, type: 12 })
343
- that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_LIST] = that.objectList;
344
- } else if (foundIndex !== -1) {
345
- let foundObject = that.objectStore[baEnum.ObjectType.BINARY_VALUE][foundIndex];
346
- foundObject[baEnum.PropertyIdentifier.PRESENT_VALUE][0].value = value;
347
- that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_LIST] = that.objectList;
348
- }
349
- } else if (objectType == "string") {
350
- let foundIndex = that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE].findIndex(ele => ele[baEnum.PropertyIdentifier.OBJECT_NAME][0].value == formattedName);
292
+ const addObjectToStore = (type, valueType, extraProperties = {}) => {
293
+ let foundIndex = that.objectStore[type].findIndex(ele => ele[baEnum.PropertyIdentifier.OBJECT_NAME][0].value == formattedName);
351
294
  if (foundIndex == -1) {
352
- let objectId = that.getObjectIdentifier(baEnum.ObjectType.CHARACTERSTRING_VALUE);
353
- that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE].push({
354
- [baEnum.PropertyIdentifier.OBJECT_NAME]: [{ value: formattedName, type: 7 }],
355
- [baEnum.PropertyIdentifier.OBJECT_TYPE]: [{ value: baEnum.ObjectType.CHARACTERSTRING_VALUE, type: 9 }],
356
- [baEnum.PropertyIdentifier.DESCRIPTION]: [{ value: '', type: 7 }],
357
- [baEnum.PropertyIdentifier.OBJECT_IDENTIFIER]: [{ value: { type: baEnum.ObjectType.CHARACTERSTRING_VALUE, instance: objectId }, type: 12 }],
358
- [baEnum.PropertyIdentifier.PRESENT_VALUE]: [{ value: value, type: 7 }],
359
- [baEnum.PropertyIdentifier.STATUS_FLAGS]: [{ value: 0, type: 8 }],
360
- [baEnum.PropertyIdentifier.EVENT_STATE]: [{ value: 0, type: 9 }],
361
- [baEnum.PropertyIdentifier.OUT_OF_SERVICE]: [{ value: 0, type: 9 }],
362
- [baEnum.PropertyIdentifier.UNITS]: [{ value: 95, type: 9 }]
363
- });
364
-
365
- that.objectList.push({ value: { type: baEnum.ObjectType.CHARACTERSTRING_VALUE, instance: objectId }, type: 12 })
295
+ let newObject = {
296
+ ...getCommonProperties(type, valueType),
297
+ ...extraProperties
298
+ };
299
+ that.objectStore[type].push(newObject);
300
+ that.objectList.push({ value: { type: type, instance: newObject[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance }, type: 12 });
366
301
  that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_LIST] = that.objectList;
367
- } else if (foundIndex !== -1) {
368
- let foundObject = that.objectStore[baEnum.ObjectType.CHARACTERSTRING_VALUE][foundIndex];
369
- foundObject[baEnum.PropertyIdentifier.PRESENT_VALUE][0].value = value;
302
+ } else {
303
+ let foundObject = that.objectStore[type][foundIndex];
304
+ foundObject[baEnum.PropertyIdentifier.PRESENT_VALUE][0].value = payload.value ?? payload;
370
305
  that.objectStore[baEnum.ObjectType.DEVICE][baEnum.PropertyIdentifier.OBJECT_LIST] = that.objectList;
371
306
  }
307
+ };
308
+
309
+ if (objectType === "number") {
310
+ addObjectToStore(baEnum.ObjectType.ANALOG_VALUE, 4, {
311
+ [baEnum.PropertyIdentifier.UNITS]: [{ value: payload.units ?? 95, type: 9 }],
312
+ [baEnum.PropertyIdentifier.MAX_PRES_VALUE]: [{ value: payload.value ?? payload, type: 4 }],
313
+ [baEnum.PropertyIdentifier.MIN_PRES_VALUE]: [{ value: payload.value ?? payload, type: 4 }],
314
+ [baEnum.PropertyIdentifier.RESOLUTION]: [{ value: payload.resolution ?? 0, type: 4 }],
315
+ [baEnum.PropertyIdentifier.PRIORITY_ARRAY]: [{ value: payload.priorityArray ?? 0, type: 9 }],
316
+ [baEnum.PropertyIdentifier.PROPERTY_LIST]: [
317
+ { value: baEnum.PropertyIdentifier.OBJECT_NAME, type: 9 },
318
+ { value: baEnum.PropertyIdentifier.OBJECT_TYPE, type: 9 },
319
+ { value: baEnum.PropertyIdentifier.DESCRIPTION, type: 9 },
320
+ { value: baEnum.PropertyIdentifier.OBJECT_IDENTIFIER, type: 9 },
321
+ { value: baEnum.PropertyIdentifier.PRESENT_VALUE, type: 9 },
322
+ { value: baEnum.PropertyIdentifier.STATUS_FLAGS, type: 9 },
323
+ { value: baEnum.PropertyIdentifier.EVENT_STATE, type: 9 },
324
+ { value: baEnum.PropertyIdentifier.OUT_OF_SERVICE, type: 9 },
325
+ { value: baEnum.PropertyIdentifier.UNITS, type: 9 },
326
+ { value: baEnum.PropertyIdentifier.PRIORITY_ARRAY, type: 9 },
327
+ { value: baEnum.PropertyIdentifier.MAX_PRES_VALUE, type: 9 },
328
+ { value: baEnum.PropertyIdentifier.MIN_PRES_VALUE, type: 9 },
329
+ { value: baEnum.PropertyIdentifier.RESOLUTION, type: 9 },
330
+ ]
331
+ });
332
+ } else if (objectType === "boolean") {
333
+ addObjectToStore(baEnum.ObjectType.BINARY_VALUE, 1, {
334
+ [baEnum.PropertyIdentifier.ACTIVE_TEXT]: [{ value: 'ACTIVE', type: 7 }],
335
+ [baEnum.PropertyIdentifier.INACTIVE_TEXT]: [{ value: 'INACTIVE', type: 7 }]
336
+ });
337
+ } else if (objectType === "string") {
338
+ addObjectToStore(baEnum.ObjectType.CHARACTERSTRING_VALUE, 7, {
339
+ [baEnum.PropertyIdentifier.UNITS]: [{ value: payload.units ?? 95, type: 9 }]
340
+ });
372
341
  }
373
342
  }
374
343
  Store_Config_Server(JSON.stringify({ objectList: that.objectList, objectStore: that.objectStore }));
@@ -376,7 +345,7 @@ class BacnetServer extends EventEmitter {
376
345
 
377
346
  /**
378
347
  * Retrieves a specific property of an object based on the object ID, property ID, and instance number.
379
- *
348
+ *
380
349
  * @param {number} objectId - The ID of the object type.
381
350
  * @param {number} propId - The ID of the property to retrieve.
382
351
  * @param {number} instance - The instance number of the object.
@@ -405,7 +374,7 @@ class BacnetServer extends EventEmitter {
405
374
 
406
375
  /**
407
376
  * Retrieves a specific property of an object based on the object ID, property ID, and instance number and modify his value.
408
- *
377
+ *
409
378
  * @param {number} objectId - The ID of the object type.
410
379
  * @param {number} propId - The ID of the property to retrieve.
411
380
  * @param {number} instance - The instance number of the object.
@@ -436,7 +405,7 @@ class BacnetServer extends EventEmitter {
436
405
 
437
406
  /**
438
407
  * Retrieves the properties of a specific object instance from the objectStore based on the provided parameters.
439
- *
408
+ *
440
409
  * @param {number} objectId - The type of the object to retrieve.
441
410
  * @param {number} propId - The property identifier to retrieve.
442
411
  * @param {number} instance - The instance number of the object to retrieve.
@@ -534,7 +503,7 @@ class BacnetServer extends EventEmitter {
534
503
 
535
504
  /**
536
505
  * Removes a server point from the objectStore and objectList based on the provided JSON data.
537
- *
506
+ *
538
507
  * @param {Object} json - The JSON data containing information about the server point to be removed.
539
508
  * @param {string} json.body.type - The type of the server point ('SV' for CharacterString, 'BV' for BinaryValue, default is AnalogValue).
540
509
  * @param {number} json.body.instance - The instance number of the server point to be removed.
@@ -597,7 +566,7 @@ class BacnetServer extends EventEmitter {
597
566
  * - name: The name of the object.
598
567
  * - type: The type of the object (AV for Analog Value, SV for Character String Value, BV for Binary Value).
599
568
  * - instance: The instance number of the object.
600
- *
569
+ *
601
570
  * @returns {Promise<Array>} A promise that resolves with an array of points sorted by instance number.
602
571
  * @throws {Error} If an error occurs during the retrieval process.
603
572
  */
@@ -688,7 +657,7 @@ class BacnetServer extends EventEmitter {
688
657
 
689
658
  /**
690
659
  * Determines the BACnet object type based on the provided value.
691
- *
660
+ *
692
661
  * @param {any} value - The value to determine the BACnet object type for.
693
662
  * @returns {string|null} The BACnet object type as a string ('string', 'number', 'boolean') or null if the type is not recognized.
694
663
  */
@@ -702,6 +671,8 @@ class BacnetServer extends EventEmitter {
702
671
  return "number"
703
672
  case "boolean":
704
673
  return "boolean"
674
+ case "object":
675
+ return "object"
705
676
  default:
706
677
  return null
707
678
  }
@@ -709,7 +680,7 @@ class BacnetServer extends EventEmitter {
709
680
 
710
681
  /**
711
682
  * Returns the object identifier for the given type and instance number.
712
- *
683
+ *
713
684
  * @param {string} type - The type of the object.
714
685
  * @param {number} instanceNumber - The instance number of the object.
715
686
  * @returns {number} The object identifier.
@@ -728,4 +699,4 @@ class BacnetServer extends EventEmitter {
728
699
  }
729
700
  }
730
701
 
731
- module.exports = { BacnetServer };
702
+ module.exports = { BacnetServer };