@bitpoolos/edge-bacnet 1.3.2 → 1.4.0

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_server.js CHANGED
@@ -2,6 +2,7 @@ const bacnet = require('./resources/node-bacstack-ts/dist/index.js');
2
2
  const pjson = require('./package.json');
3
3
  const baEnum = bacnet.enum;
4
4
  const { Store_Config_Server, Read_Config_Sync_Server } = require('./common');
5
+ const { EventEmitter } = require("events");
5
6
 
6
7
  /**
7
8
  * Class representing a BACnet Server.
@@ -16,9 +17,10 @@ const { Store_Config_Server, Read_Config_Sync_Server } = require('./common');
16
17
  * @param {number} deviceId - The ID of the device.
17
18
  * @param {string} nodeRedVersion - The version of Node-Red.
18
19
  */
19
- class BacnetServer {
20
+ class BacnetServer extends EventEmitter {
20
21
 
21
22
  constructor(client, deviceId, nodeRedVersion) {
23
+ super();
22
24
  let that = this;
23
25
  that.bacnetClient = client;
24
26
 
@@ -175,6 +177,69 @@ class BacnetServer {
175
177
  }
176
178
  });
177
179
 
180
+ that.bacnetClient.client.on('writeProperty', (data) => {
181
+ let objectId = data.request.objectId.type;
182
+ let objectInstance = data.request.objectId.instance;
183
+ let propId = data.request.value.property.id.toString();
184
+ let newValue = data.request.value.value[0].value;
185
+
186
+ if (!that.modifyObject(objectId, propId, objectInstance, newValue)) {
187
+ that.bacnetClient.errorResponse(data.address, data.service, data.invokeId, bacnet.enum.ErrorClass.OBJECT, bacnet.enum.ErrorCode.UNKNOWN_OBJECT);
188
+ }
189
+ that.getServerPoints(objectId, objectInstance).then(function (result) {
190
+ that.bacnetClient.client.simpleAckResponse(data.address, data.service, data.invokeId);
191
+ that.emit("writeProperty", result[0].name, newValue);
192
+ }).catch(function (error) {
193
+ that.bacnetClient.errorResponse(data.address, data.service, data.invokeId, bacnet.enum.ErrorClass.OBJECT, bacnet.enum.ErrorCode.UNKNOWN_OBJECT);
194
+ that.logOut("Error getting server points: ", error);
195
+ });
196
+ });
197
+
198
+ that.bacnetClient.client.on('createObject', (data) => {
199
+ var defaultValue;
200
+ switch (data.request.values[0].value[0].type) {
201
+ case baEnum.ObjectType.CHARACTERSTRING_VALUE:
202
+ defaultValue = "";
203
+ break;
204
+ case baEnum.ObjectType.BINARY_VALUE:
205
+ defaultValue = 0;
206
+ break;
207
+ case baEnum.ObjectType.ANALOG_VALUE:
208
+ defaultValue = false;
209
+ break;
210
+ default:
211
+ defaultValue = 0;
212
+ break;
213
+ }
214
+ that.addObject(data.request.values[0].value[0].value, defaultValue);
215
+ that.bacnetClient.client.simpleAckResponse(data.address, data.service, data.invokeId);
216
+ });
217
+
218
+ that.bacnetClient.client.on('deleteObject', (data) => {
219
+ var type;
220
+ switch (data.request.objectType) {
221
+ case baEnum.ObjectType.CHARACTERSTRING_VALUE:
222
+ type = 'SV';
223
+ break;
224
+ case baEnum.ObjectType.BINARY_VALUE:
225
+ type = 'BV';
226
+ break;
227
+ case baEnum.ObjectType.ANALOG_VALUE:
228
+ type = 'AV';
229
+ break;
230
+ default:
231
+ type = 'AV';
232
+ break;
233
+ }
234
+
235
+ var req = { body: { type: type, instance: data.request.instance } };
236
+ that.clearServerPoint(req).then(function (result) {
237
+ that.bacnetClient.client.simpleAckResponse(data.address, data.service, data.invokeId);
238
+ }).catch(function (error) {
239
+ console.log(error)
240
+ });
241
+ });
242
+
178
243
  //do initial iAm broadcast when BACnet server starts
179
244
  that.bacnetClient.client.iAmResponse(that.deviceId, baEnum.Segmentation.SEGMENTED_BOTH, that.vendorId);
180
245
  }
@@ -336,6 +401,37 @@ class BacnetServer {
336
401
  return null;
337
402
  }
338
403
 
404
+ /**
405
+ * Retrieves a specific property of an object based on the object ID, property ID, and instance number and modify his value.
406
+ *
407
+ * @param {number} objectId - The ID of the object type.
408
+ * @param {number} propId - The ID of the property to retrieve.
409
+ * @param {number} instance - The instance number of the object.
410
+ * @param {number} newValue - The the new value for update.
411
+ * @returns {any} The requested property value if found, otherwise null.
412
+ */
413
+ modifyObject(objectId, propId, instance, newValue) { //TODO factorise with getObject
414
+ let that = this;
415
+ let objectGroup = that.objectStore[objectId];
416
+
417
+ if (Array.isArray(objectGroup)) {
418
+ for (let i = 0; i < objectGroup.length; i++) {
419
+ let object = objectGroup[i];
420
+ if (object[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance == instance) {
421
+ let requestedProperty = object[propId];
422
+ if (requestedProperty !== null && requestedProperty !== undefined && typeof requestedProperty !== "undefined") {
423
+ that.objectStore[objectId][i][propId][0].value = newValue;
424
+ return requestedProperty;
425
+ }
426
+ }
427
+ }
428
+ } else {
429
+ return objectGroup[propId];
430
+ }
431
+
432
+ return null;
433
+ }
434
+
339
435
  /**
340
436
  * Retrieves the properties of a specific object instance from the objectStore based on the provided parameters.
341
437
  *
@@ -503,7 +599,7 @@ class BacnetServer {
503
599
  * @returns {Promise<Array>} A promise that resolves with an array of points sorted by instance number.
504
600
  * @throws {Error} If an error occurs during the retrieval process.
505
601
  */
506
- getServerPoints() {
602
+ getServerPoints(typeFilter = null, instanceFilter = null) {
507
603
  let that = this;
508
604
  let points = [];
509
605
 
@@ -515,11 +611,21 @@ class BacnetServer {
515
611
  let instance = point[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance;
516
612
  let objectName = point[baEnum.PropertyIdentifier.OBJECT_NAME][0].value;
517
613
 
518
- points.push({
519
- name: objectName,
520
- type: "AV",
521
- instance
522
- });
614
+ if (typeFilter === null && instanceFilter === null) {
615
+ points.push({
616
+ name: objectName,
617
+ type: "AV",
618
+ instance
619
+ });
620
+ } else {
621
+ if ((typeFilter === baEnum.ObjectType.ANALOG_VALUE) && (instanceFilter === instance)) {
622
+ points.push({
623
+ name: objectName,
624
+ type: "AV",
625
+ instance
626
+ });
627
+ }
628
+ }
523
629
  });
524
630
  }
525
631
 
@@ -529,11 +635,21 @@ class BacnetServer {
529
635
  let instance = point[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance;
530
636
  let objectName = point[baEnum.PropertyIdentifier.OBJECT_NAME][0].value;
531
637
 
532
- points.push({
533
- name: objectName,
534
- type: "SV",
535
- instance
536
- });
638
+ if (typeFilter === null && instanceFilter === null) {
639
+ points.push({
640
+ name: objectName,
641
+ type: "SV",
642
+ instance
643
+ });
644
+ } else {
645
+ if ((typeFilter === baEnum.ObjectType.CHARACTERSTRING_VALUE) && (instanceFilter === instance)) {
646
+ points.push({
647
+ name: objectName,
648
+ type: "SV",
649
+ instance
650
+ });
651
+ }
652
+ }
537
653
  });
538
654
  }
539
655
 
@@ -543,11 +659,21 @@ class BacnetServer {
543
659
  let instance = point[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance;
544
660
  let objectName = point[baEnum.PropertyIdentifier.OBJECT_NAME][0].value;
545
661
 
546
- points.push({
547
- name: objectName,
548
- type: "BV",
549
- instance
550
- });
662
+ if (typeFilter === null && instanceFilter === null) {
663
+ points.push({
664
+ name: objectName,
665
+ type: "BV",
666
+ instance
667
+ });
668
+ } else {
669
+ if ((typeFilter === baEnum.ObjectType.BINARY_VALUE) && (instanceFilter === instance)) {
670
+ points.push({
671
+ name: objectName,
672
+ type: "BV",
673
+ instance
674
+ });
675
+ }
676
+ }
551
677
  });
552
678
  }
553
679