@bitpoolos/edge-bacnet 1.2.8 → 1.3.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/CHANGELOG.md +76 -0
- package/README.md +20 -2
- package/bacnet_client.js +592 -760
- package/bacnet_device.js +122 -60
- package/bacnet_gateway.html +91 -75
- package/bacnet_gateway.js +161 -46
- package/bacnet_read.html +1025 -596
- package/bacnet_read.js +68 -84
- package/bacnet_server.js +187 -186
- package/bacnet_write.html +268 -24
- package/common.js +22 -4
- package/package.json +2 -2
- package/resources/bitArray.js +167 -0
- package/resources/node-bacstack-ts/dist/lib/asn1.js +16 -5
- package/resources/node-bacstack-ts/dist/lib/client.js +5 -6
- package/resources/style.css +321 -0
- package/treeBuilder.js +533 -0
package/bacnet_gateway.js
CHANGED
|
@@ -99,8 +99,15 @@ module.exports = function (RED) {
|
|
|
99
99
|
node.bacnetClient.removeAllListeners();
|
|
100
100
|
|
|
101
101
|
// Value response event handler for READ commands
|
|
102
|
-
node.bacnetClient.on("values", (values, outputType, objectPropertyType, readNodeName) => {
|
|
102
|
+
node.bacnetClient.on("values", (values, outputType, objectPropertyType, readNodeName, deviceIndex, devicesToRead) => {
|
|
103
103
|
if (typeof values !== "undefined" && Object.keys(values).length) {
|
|
104
|
+
let publishText = `Publishing ${readNodeName} ${deviceIndex} / ${devicesToRead} `;
|
|
105
|
+
node.status({ fill: "blue", shape: "dot", text: publishText });
|
|
106
|
+
if (deviceIndex == devicesToRead) {
|
|
107
|
+
setTimeout(() => {
|
|
108
|
+
node.status({});
|
|
109
|
+
}, 3000);
|
|
110
|
+
}
|
|
104
111
|
if (outputType.json && !outputType.mqtt) {
|
|
105
112
|
if (objectPropertyType.fullObject && objectPropertyType.simplePayload) {
|
|
106
113
|
sendSimpleJson(values, readNodeName);
|
|
@@ -175,7 +182,7 @@ module.exports = function (RED) {
|
|
|
175
182
|
} else if (msg.doUpdatePriorityDevices == true && msg.priorityDevices !== null) {
|
|
176
183
|
node.bacnetClient
|
|
177
184
|
.updatePriorityQueue(msg.priorityDevices)
|
|
178
|
-
.then(function (result) {})
|
|
185
|
+
.then(function (result) { })
|
|
179
186
|
.catch(function (error) {
|
|
180
187
|
logOut("Error updating priorityQueue: ", error);
|
|
181
188
|
});
|
|
@@ -193,7 +200,6 @@ module.exports = function (RED) {
|
|
|
193
200
|
if (!node.bacnetClient) {
|
|
194
201
|
logOut("Issue with the bacnetClient: ", node.bacnetClient);
|
|
195
202
|
//no bacnet client present
|
|
196
|
-
//node.status({fill:"red",shape:"dot",text:"Please define client"});
|
|
197
203
|
res.send(false);
|
|
198
204
|
} else {
|
|
199
205
|
node.bacnetClient
|
|
@@ -213,7 +219,6 @@ module.exports = function (RED) {
|
|
|
213
219
|
if (!node.bacnetClient) {
|
|
214
220
|
logOut("Issue with the bacnetClient: ", node.bacnetClient);
|
|
215
221
|
//no bacnet client present
|
|
216
|
-
//node.status({fill:"red",shape:"dot",text:"Please define client"});
|
|
217
222
|
res.send(false);
|
|
218
223
|
} else {
|
|
219
224
|
node.bacnetClient
|
|
@@ -312,30 +317,130 @@ module.exports = function (RED) {
|
|
|
312
317
|
}
|
|
313
318
|
});
|
|
314
319
|
|
|
320
|
+
//route handler for purge device
|
|
321
|
+
RED.httpAdmin.post("/bitpool-bacnet-data/purgeDevice", function (req, res) {
|
|
322
|
+
if (!node.bacnetClient) {
|
|
323
|
+
logOut("Issue with the bacnetClient while getting device list: ", node.bacnetClient);
|
|
324
|
+
res.send(false);
|
|
325
|
+
} else {
|
|
326
|
+
node.bacnetClient
|
|
327
|
+
.purgeDevice(req.body.d)
|
|
328
|
+
.then(function (result) {
|
|
329
|
+
res.send(result);
|
|
330
|
+
})
|
|
331
|
+
.catch(function (error) {
|
|
332
|
+
res.send(error);
|
|
333
|
+
logOut("Error purging device: ", error);
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
//route handler for updatePointsForDevice
|
|
339
|
+
RED.httpAdmin.post("/bitpool-bacnet-data/updatePointsForDevice", function (req, res) {
|
|
340
|
+
if (!node.bacnetClient) {
|
|
341
|
+
logOut("Issue with the bacnetClient while updating device points list: ", node.bacnetClient);
|
|
342
|
+
res.send(false);
|
|
343
|
+
} else {
|
|
344
|
+
node.bacnetClient
|
|
345
|
+
.updatePointsForDevice(req.body.d)
|
|
346
|
+
.then(function (result) {
|
|
347
|
+
res.send(result);
|
|
348
|
+
})
|
|
349
|
+
.catch(function (error) {
|
|
350
|
+
res.send(error);
|
|
351
|
+
logOut("Error updating device: ", error);
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
//route handler for setDeviceDisplayName
|
|
357
|
+
RED.httpAdmin.post("/bitpool-bacnet-data/setDeviceDisplayName", function (req, res) {
|
|
358
|
+
if (!node.bacnetClient) {
|
|
359
|
+
logOut("Issue with the bacnetClient while updating device points list: ", node.bacnetClient);
|
|
360
|
+
res.send(false);
|
|
361
|
+
} else {
|
|
362
|
+
node.bacnetClient
|
|
363
|
+
.setDeviceDisplayName(req.body.d, req.body.n)
|
|
364
|
+
.then(function (result) {
|
|
365
|
+
res.send(result);
|
|
366
|
+
})
|
|
367
|
+
.catch(function (error) {
|
|
368
|
+
res.send(error);
|
|
369
|
+
logOut("Error setting device display name: ", error);
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
//route handler for setPointDisplayName
|
|
375
|
+
RED.httpAdmin.post("/bitpool-bacnet-data/setPointDisplayName", function (req, res) {
|
|
376
|
+
if (!node.bacnetClient) {
|
|
377
|
+
logOut("Issue with the bacnetClient while updating point name: ", node.bacnetClient);
|
|
378
|
+
res.send(false);
|
|
379
|
+
} else {
|
|
380
|
+
node.bacnetClient
|
|
381
|
+
.setPointDisplayName(req.body.k, req.body.p, req.body.n)
|
|
382
|
+
.then(function (result) {
|
|
383
|
+
res.send(result);
|
|
384
|
+
})
|
|
385
|
+
.catch(function (error) {
|
|
386
|
+
res.send(error);
|
|
387
|
+
logOut("Error setting device display name: ", error);
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
//route handler for importReadList
|
|
393
|
+
RED.httpAdmin.post("/bitpool-bacnet-data/importReadList", function (req, res) {
|
|
394
|
+
if (!node.bacnetClient) {
|
|
395
|
+
logOut("Issue with the bacnetClient while updating point name: ", node.bacnetClient);
|
|
396
|
+
res.send(false);
|
|
397
|
+
} else {
|
|
398
|
+
node.bacnetClient
|
|
399
|
+
.importReadList(req.body.p)
|
|
400
|
+
.then(function (result) {
|
|
401
|
+
res.send(result);
|
|
402
|
+
})
|
|
403
|
+
.catch(function (error) {
|
|
404
|
+
res.send(error);
|
|
405
|
+
logOut("Error setting device display name: ", error);
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
|
|
315
411
|
function bindEventListeners() {
|
|
316
412
|
// Value response event handler for READ commands
|
|
317
|
-
node.bacnetClient.on("values", (
|
|
318
|
-
if (
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
sendSimpleJson(values, readNodeName);
|
|
413
|
+
node.bacnetClient.on("values", (values, outputType, objectPropertyType, readNodeName, deviceIndex, devicesToRead) => {
|
|
414
|
+
if (typeof values !== "undefined" && Object.keys(values).length) {
|
|
415
|
+
let publishText = `Publishing ${readNodeName} ${deviceIndex} / ${devicesToRead} `;
|
|
416
|
+
node.status({ fill: "blue", shape: "dot", text: publishText });
|
|
417
|
+
if (deviceIndex == devicesToRead) {
|
|
418
|
+
setTimeout(() => {
|
|
419
|
+
node.status({});
|
|
420
|
+
}, 3000);
|
|
326
421
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
422
|
+
if (outputType.json && !outputType.mqtt) {
|
|
423
|
+
if (objectPropertyType.fullObject && objectPropertyType.simplePayload) {
|
|
424
|
+
sendSimpleJson(values, readNodeName);
|
|
425
|
+
sendJsonAsMqtt(values, readNodeName);
|
|
426
|
+
} else if (objectPropertyType.fullObject && !objectPropertyType.simplePayload) {
|
|
427
|
+
sendJsonAsMqtt(values, readNodeName);
|
|
428
|
+
} else if (!objectPropertyType.fullObject && objectPropertyType.simplePayload) {
|
|
429
|
+
sendSimpleJson(values, readNodeName);
|
|
430
|
+
}
|
|
431
|
+
} else if (!outputType.json && outputType.mqtt) {
|
|
432
|
+
if (objectPropertyType.fullObject && objectPropertyType.simplePayload) {
|
|
433
|
+
sendAsMqtt(values, readNodeName);
|
|
434
|
+
sendSimpleMqtt(values, readNodeName);
|
|
435
|
+
} else if (objectPropertyType.fullObject && !objectPropertyType.simplePayload) {
|
|
436
|
+
sendAsMqtt(values, readNodeName);
|
|
437
|
+
} else if (!objectPropertyType.fullObject && objectPropertyType.simplePayload) {
|
|
438
|
+
sendSimpleMqtt(values, readNodeName);
|
|
439
|
+
}
|
|
335
440
|
}
|
|
336
441
|
}
|
|
337
442
|
});
|
|
338
|
-
|
|
443
|
+
|
|
339
444
|
// Who Is / Iam event handler
|
|
340
445
|
node.bacnetClient.on("deviceFound", (device) => {
|
|
341
446
|
if (node.toLogIam) node.warn(`BACnet device found: ${device.deviceId} - ${device.address}`);
|
|
@@ -354,6 +459,13 @@ module.exports = function (RED) {
|
|
|
354
459
|
}
|
|
355
460
|
}
|
|
356
461
|
|
|
462
|
+
function getPointName(object, pointName) {
|
|
463
|
+
if (object.displayName) {
|
|
464
|
+
return object.displayName;
|
|
465
|
+
}
|
|
466
|
+
return pointName;
|
|
467
|
+
}
|
|
468
|
+
|
|
357
469
|
sendSimpleMqtt = function (values, readNodeName) {
|
|
358
470
|
let devices = Object.keys(values);
|
|
359
471
|
devices.forEach(function (device) {
|
|
@@ -361,6 +473,7 @@ module.exports = function (RED) {
|
|
|
361
473
|
let points = values[device];
|
|
362
474
|
for (var point in points) {
|
|
363
475
|
if (points[point]) {
|
|
476
|
+
let pointName = getPointName(points[point], point);
|
|
364
477
|
let pointProps = Object.keys(points[point]);
|
|
365
478
|
pointProps.forEach(function (prop) {
|
|
366
479
|
let msg = {};
|
|
@@ -372,22 +485,22 @@ module.exports = function (RED) {
|
|
|
372
485
|
node.nodeName !== "undefined" &&
|
|
373
486
|
typeof node.nodeName == "string"
|
|
374
487
|
) {
|
|
375
|
-
if(readNodeName !== ''&&
|
|
488
|
+
if (readNodeName !== '' &&
|
|
376
489
|
readNodeName !== null &&
|
|
377
490
|
readNodeName !== undefined
|
|
378
491
|
) {
|
|
379
|
-
msg.topic = `${node.nodeName}/${readNodeName}/${device}/${
|
|
492
|
+
msg.topic = `${node.nodeName}/${readNodeName}/${device}/${pointName}`;
|
|
380
493
|
} else {
|
|
381
|
-
msg.topic = `${node.nodeName}/${device}/${
|
|
494
|
+
msg.topic = `${node.nodeName}/${device}/${pointName}`;
|
|
382
495
|
}
|
|
383
496
|
} else {
|
|
384
|
-
if(readNodeName !== ''&&
|
|
497
|
+
if (readNodeName !== '' &&
|
|
385
498
|
readNodeName !== null &&
|
|
386
499
|
readNodeName !== undefined
|
|
387
500
|
) {
|
|
388
|
-
msg.topic = `BITPOOL_BACNET_GATEWAY/${readNodeName}/${device}/${
|
|
501
|
+
msg.topic = `BITPOOL_BACNET_GATEWAY/${readNodeName}/${device}/${pointName}`;
|
|
389
502
|
} else {
|
|
390
|
-
msg.topic = `BITPOOL_BACNET_GATEWAY/${device}/${
|
|
503
|
+
msg.topic = `BITPOOL_BACNET_GATEWAY/${device}/${pointName}`;
|
|
391
504
|
}
|
|
392
505
|
}
|
|
393
506
|
msg.payload = points[point][prop];
|
|
@@ -408,6 +521,7 @@ module.exports = function (RED) {
|
|
|
408
521
|
let points = values[device];
|
|
409
522
|
for (var point in points) {
|
|
410
523
|
if (points[point]) {
|
|
524
|
+
let pointName = getPointName(points[point], point);
|
|
411
525
|
let pointProps = Object.keys(points[point]);
|
|
412
526
|
pointProps.forEach(function (prop) {
|
|
413
527
|
let msg = {};
|
|
@@ -419,22 +533,22 @@ module.exports = function (RED) {
|
|
|
419
533
|
node.nodeName !== "undefined" &&
|
|
420
534
|
typeof node.nodeName == "string"
|
|
421
535
|
) {
|
|
422
|
-
if(readNodeName !== ''&&
|
|
536
|
+
if (readNodeName !== '' &&
|
|
423
537
|
readNodeName !== null &&
|
|
424
538
|
readNodeName !== undefined
|
|
425
539
|
) {
|
|
426
|
-
msg.topic = `${node.nodeName}/${readNodeName}/${device}/${
|
|
540
|
+
msg.topic = `${node.nodeName}/${readNodeName}/${device}/${pointName}/${prop}`;
|
|
427
541
|
} else {
|
|
428
|
-
msg.topic = `${node.nodeName}/${device}/${
|
|
542
|
+
msg.topic = `${node.nodeName}/${device}/${pointName}/${prop}`;
|
|
429
543
|
}
|
|
430
544
|
} else {
|
|
431
|
-
if(readNodeName !== ''&&
|
|
545
|
+
if (readNodeName !== '' &&
|
|
432
546
|
readNodeName !== null &&
|
|
433
547
|
readNodeName !== undefined
|
|
434
548
|
) {
|
|
435
|
-
msg.topic = `BITPOOL_BACNET_GATEWAY/${readNodeName}/${device}/${
|
|
549
|
+
msg.topic = `BITPOOL_BACNET_GATEWAY/${readNodeName}/${device}/${pointName}/${prop}`;
|
|
436
550
|
} else {
|
|
437
|
-
msg.topic = `BITPOOL_BACNET_GATEWAY/${device}/${
|
|
551
|
+
msg.topic = `BITPOOL_BACNET_GATEWAY/${device}/${pointName}/${prop}`;
|
|
438
552
|
}
|
|
439
553
|
}
|
|
440
554
|
msg.payload = points[point][prop];
|
|
@@ -458,6 +572,7 @@ module.exports = function (RED) {
|
|
|
458
572
|
let points = values[device];
|
|
459
573
|
for (var point in points) {
|
|
460
574
|
if (points[point]) {
|
|
575
|
+
let pointName = getPointName(points[point], point);
|
|
461
576
|
let pointProps = Object.keys(points[point]);
|
|
462
577
|
pointProps.forEach(function (prop) {
|
|
463
578
|
if (prop == "presentValue") {
|
|
@@ -475,18 +590,18 @@ module.exports = function (RED) {
|
|
|
475
590
|
node.nodeName !== "undefined" &&
|
|
476
591
|
typeof node.nodeName == "string"
|
|
477
592
|
) {
|
|
478
|
-
if(readNodeName !== ''&&
|
|
479
|
-
|
|
480
|
-
|
|
593
|
+
if (readNodeName !== '' &&
|
|
594
|
+
readNodeName !== null &&
|
|
595
|
+
readNodeName !== undefined
|
|
481
596
|
) {
|
|
482
597
|
msgg.topic = `${node.nodeName}/${readNodeName}/${device}`;
|
|
483
598
|
} else {
|
|
484
599
|
msgg.topic = `${node.nodeName}/${device}`;
|
|
485
600
|
}
|
|
486
601
|
} else {
|
|
487
|
-
if(readNodeName !== ''&&
|
|
488
|
-
|
|
489
|
-
|
|
602
|
+
if (readNodeName !== '' &&
|
|
603
|
+
readNodeName !== null &&
|
|
604
|
+
readNodeName !== undefined
|
|
490
605
|
) {
|
|
491
606
|
msgg.topic = `BITPOOL_BACNET_GATEWAY/${readNodeName}/${device}`;
|
|
492
607
|
} else {
|
|
@@ -512,18 +627,18 @@ module.exports = function (RED) {
|
|
|
512
627
|
node.nodeName !== "undefined" &&
|
|
513
628
|
typeof node.nodeName == "string"
|
|
514
629
|
) {
|
|
515
|
-
if(readNodeName !== ''&&
|
|
516
|
-
|
|
517
|
-
|
|
630
|
+
if (readNodeName !== '' &&
|
|
631
|
+
readNodeName !== null &&
|
|
632
|
+
readNodeName !== undefined
|
|
518
633
|
) {
|
|
519
634
|
msgg.topic = `${node.nodeName}/${readNodeName}/${key}`;
|
|
520
635
|
} else {
|
|
521
636
|
msgg.topic = `${node.nodeName}/${key}`;
|
|
522
637
|
}
|
|
523
638
|
} else {
|
|
524
|
-
if(readNodeName !== ''&&
|
|
525
|
-
|
|
526
|
-
|
|
639
|
+
if (readNodeName !== '' &&
|
|
640
|
+
readNodeName !== null &&
|
|
641
|
+
readNodeName !== undefined
|
|
527
642
|
) {
|
|
528
643
|
msgg.topic = `BITPOOL_BACNET_GATEWAY/${readNodeName}/${key}`;
|
|
529
644
|
} else {
|