@bitpoolos/edge-bacnet 1.3.2 → 1.4.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 +41 -0
- package/bacnet_client.js +27 -33
- package/bacnet_gateway.js +140 -21
- package/bacnet_read.html +61 -60
- package/bacnet_read.js +2 -0
- package/bacnet_server.js +146 -18
- package/bitpool_inject.html +492 -462
- package/common.js +0 -29
- package/package.json +1 -1
- package/treeBuilder.js +0 -7
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
|
|
|
@@ -171,12 +173,77 @@ class BacnetServer {
|
|
|
171
173
|
);
|
|
172
174
|
}
|
|
173
175
|
} catch (e) {
|
|
174
|
-
console.log("Local BACnet device readProperty error: ", e);
|
|
176
|
+
//console.log("Local BACnet device readProperty error: ", e);
|
|
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);
|
|
245
|
+
|
|
246
|
+
that.setMaxListeners(2);
|
|
180
247
|
}
|
|
181
248
|
|
|
182
249
|
/**
|
|
@@ -336,6 +403,37 @@ class BacnetServer {
|
|
|
336
403
|
return null;
|
|
337
404
|
}
|
|
338
405
|
|
|
406
|
+
/**
|
|
407
|
+
* Retrieves a specific property of an object based on the object ID, property ID, and instance number and modify his value.
|
|
408
|
+
*
|
|
409
|
+
* @param {number} objectId - The ID of the object type.
|
|
410
|
+
* @param {number} propId - The ID of the property to retrieve.
|
|
411
|
+
* @param {number} instance - The instance number of the object.
|
|
412
|
+
* @param {number} newValue - The the new value for update.
|
|
413
|
+
* @returns {any} The requested property value if found, otherwise null.
|
|
414
|
+
*/
|
|
415
|
+
modifyObject(objectId, propId, instance, newValue) { //TODO factorise with getObject
|
|
416
|
+
let that = this;
|
|
417
|
+
let objectGroup = that.objectStore[objectId];
|
|
418
|
+
|
|
419
|
+
if (Array.isArray(objectGroup)) {
|
|
420
|
+
for (let i = 0; i < objectGroup.length; i++) {
|
|
421
|
+
let object = objectGroup[i];
|
|
422
|
+
if (object[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance == instance) {
|
|
423
|
+
let requestedProperty = object[propId];
|
|
424
|
+
if (requestedProperty !== null && requestedProperty !== undefined && typeof requestedProperty !== "undefined") {
|
|
425
|
+
that.objectStore[objectId][i][propId][0].value = newValue;
|
|
426
|
+
return requestedProperty;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
} else {
|
|
431
|
+
return objectGroup[propId];
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
return null;
|
|
435
|
+
}
|
|
436
|
+
|
|
339
437
|
/**
|
|
340
438
|
* Retrieves the properties of a specific object instance from the objectStore based on the provided parameters.
|
|
341
439
|
*
|
|
@@ -503,7 +601,7 @@ class BacnetServer {
|
|
|
503
601
|
* @returns {Promise<Array>} A promise that resolves with an array of points sorted by instance number.
|
|
504
602
|
* @throws {Error} If an error occurs during the retrieval process.
|
|
505
603
|
*/
|
|
506
|
-
getServerPoints() {
|
|
604
|
+
getServerPoints(typeFilter = null, instanceFilter = null) {
|
|
507
605
|
let that = this;
|
|
508
606
|
let points = [];
|
|
509
607
|
|
|
@@ -515,11 +613,21 @@ class BacnetServer {
|
|
|
515
613
|
let instance = point[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance;
|
|
516
614
|
let objectName = point[baEnum.PropertyIdentifier.OBJECT_NAME][0].value;
|
|
517
615
|
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
616
|
+
if (typeFilter === null && instanceFilter === null) {
|
|
617
|
+
points.push({
|
|
618
|
+
name: objectName,
|
|
619
|
+
type: "AV",
|
|
620
|
+
instance
|
|
621
|
+
});
|
|
622
|
+
} else {
|
|
623
|
+
if ((typeFilter === baEnum.ObjectType.ANALOG_VALUE) && (instanceFilter === instance)) {
|
|
624
|
+
points.push({
|
|
625
|
+
name: objectName,
|
|
626
|
+
type: "AV",
|
|
627
|
+
instance
|
|
628
|
+
});
|
|
629
|
+
}
|
|
630
|
+
}
|
|
523
631
|
});
|
|
524
632
|
}
|
|
525
633
|
|
|
@@ -529,11 +637,21 @@ class BacnetServer {
|
|
|
529
637
|
let instance = point[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance;
|
|
530
638
|
let objectName = point[baEnum.PropertyIdentifier.OBJECT_NAME][0].value;
|
|
531
639
|
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
640
|
+
if (typeFilter === null && instanceFilter === null) {
|
|
641
|
+
points.push({
|
|
642
|
+
name: objectName,
|
|
643
|
+
type: "SV",
|
|
644
|
+
instance
|
|
645
|
+
});
|
|
646
|
+
} else {
|
|
647
|
+
if ((typeFilter === baEnum.ObjectType.CHARACTERSTRING_VALUE) && (instanceFilter === instance)) {
|
|
648
|
+
points.push({
|
|
649
|
+
name: objectName,
|
|
650
|
+
type: "SV",
|
|
651
|
+
instance
|
|
652
|
+
});
|
|
653
|
+
}
|
|
654
|
+
}
|
|
537
655
|
});
|
|
538
656
|
}
|
|
539
657
|
|
|
@@ -543,11 +661,21 @@ class BacnetServer {
|
|
|
543
661
|
let instance = point[baEnum.PropertyIdentifier.OBJECT_IDENTIFIER][0].value.instance;
|
|
544
662
|
let objectName = point[baEnum.PropertyIdentifier.OBJECT_NAME][0].value;
|
|
545
663
|
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
664
|
+
if (typeFilter === null && instanceFilter === null) {
|
|
665
|
+
points.push({
|
|
666
|
+
name: objectName,
|
|
667
|
+
type: "BV",
|
|
668
|
+
instance
|
|
669
|
+
});
|
|
670
|
+
} else {
|
|
671
|
+
if ((typeFilter === baEnum.ObjectType.BINARY_VALUE) && (instanceFilter === instance)) {
|
|
672
|
+
points.push({
|
|
673
|
+
name: objectName,
|
|
674
|
+
type: "BV",
|
|
675
|
+
instance
|
|
676
|
+
});
|
|
677
|
+
}
|
|
678
|
+
}
|
|
551
679
|
});
|
|
552
680
|
}
|
|
553
681
|
|