@bitpoolos/edge-bacnet 1.4.7 → 1.5.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.
@@ -161,6 +161,7 @@
161
161
  device_read_schedule_value: { value: "15", required: true },
162
162
  device_read_schedule_options: { value: "Minutes", required: true },
163
163
  deviceRangeRegisters: { value: [] },
164
+ portRangeRegisters: { value: [] },
164
165
  cacheFileEnabled: { value: false, required: true },
165
166
  sanitise_device_schedule: { value: "60", required: false },
166
167
  sanitise_device_schedule_value: { value: "1", required: false },
@@ -237,14 +238,15 @@
237
238
 
238
239
  queryAdapters();
239
240
 
240
- if (node.vm1 == undefined) {
241
+ window.confirmDialogExists = window.confirmDialogExists || false;
242
+
243
+ if (node.vm1 == undefined && !window.confirmDialogExists) {
241
244
  const confirmDialog = document.createElement("p-confirm-dialog");
242
245
  document.getElementById("serverParent").appendChild(confirmDialog);
246
+ window.confirmDialogExists = true;
243
247
  }
244
248
 
245
249
  const { createApp, ref, onMounted } = Vue;
246
- const ConfirmDialog = primevue.confirmdialog;
247
- const ConfirmationService = primevue.confirmationservice;
248
250
  const ListBox = primevue.listbox;
249
251
 
250
252
  //prime vue app
@@ -347,7 +349,7 @@
347
349
  contentType: "application/json",
348
350
  data: JSON.stringify(jsonPayload),
349
351
  success: function (result) { },
350
- timeout: 10000,
352
+ timeout: 15000,
351
353
  });
352
354
  };
353
355
 
@@ -368,7 +370,8 @@
368
370
  });
369
371
  });
370
372
 
371
- //device scan range matrix
373
+ //start device scan range matrix
374
+
372
375
  $("#node-input-deviceIdRangeMatrix-container")
373
376
  .css("min-width", "350px")
374
377
  .editableList({
@@ -402,12 +405,13 @@
402
405
 
403
406
  $(htmlRow).appendTo(fragment);
404
407
  row[0].appendChild(fragment);
405
- document.getElementById("node-input-reg-block-count").innerHTML = $(
408
+
409
+ document.getElementById("node-input-reg-block-count-deviceIdRangeMatrix").innerHTML = $(
406
410
  "#node-input-deviceIdRangeMatrix-container"
407
411
  ).editableList("length");
408
412
  },
409
413
  removeItem: function (data) {
410
- document.getElementById("node-input-reg-block-count").innerHTML = $(
414
+ document.getElementById("node-input-reg-block-count-deviceIdRangeMatrix").innerHTML = $(
411
415
  "#node-input-deviceIdRangeMatrix-container"
412
416
  ).editableList("length");
413
417
  },
@@ -415,7 +419,7 @@
415
419
  scrollOnAdd: false,
416
420
  header: $("<div style='display:flex; padding:10px 10px 0px 5px; column-gap: 10px'>").append(
417
421
  $.parseHTML(
418
- "<div><span class='bp-matrix-heading'>Device ID Range(s)</span> </div><div class='bp-matrix-count' style='color: gray'><label id='node-input-reg-block-count' >0</label> </div>"
422
+ "<div><span class='bp-matrix-heading'>Device ID Range(s)</span> </div><div class='bp-matrix-count' style='color: gray'><label id='node-input-reg-block-count-deviceIdRangeMatrix' >0</label> </div>"
419
423
  )
420
424
  ),
421
425
  buttons: [
@@ -454,7 +458,7 @@
454
458
  title: "Delete all registers",
455
459
  click: function (evt) {
456
460
  $("#node-input-deviceIdRangeMatrix-container").editableList("empty");
457
- document.getElementById("node-input-reg-block-count").innerHTML = 0;
461
+ document.getElementById("node-input-reg-block-count-deviceIdRangeMatrix").innerHTML = 0;
458
462
  },
459
463
  },
460
464
  ],
@@ -472,7 +476,117 @@
472
476
  });
473
477
  }
474
478
 
475
- document.getElementById("node-input-reg-block-count").innerHTML = node.deviceRangeRegisters.length;
479
+ document.getElementById("node-input-reg-block-count-deviceIdRangeMatrix").innerHTML = node.deviceRangeRegisters.length;
480
+
481
+ //end device id range matrix
482
+
483
+ //start port range matrix
484
+
485
+ $("#node-input-portRangeMatrix-container")
486
+ .css("min-width", "350px")
487
+ .editableList({
488
+ addItem: function (row, index, data) {
489
+ row.css({ overflow: "none", whiteSpace: "nowrap" });
490
+ let rowData = {};
491
+ if (data && typeof data.enabled == "boolean" && typeof data.start == "string" && typeof data.end == "string") {
492
+ if (data.enabled === true) {
493
+ rowData.enabled = "checked";
494
+ } else if (data.enabled === false) {
495
+ rowData.enabled = "";
496
+ }
497
+ rowData.start = data.start;
498
+ rowData.end = data.end;
499
+ } else {
500
+ rowData.enabled = "";
501
+ rowData.start = "";
502
+ rowData.end = "";
503
+ }
504
+
505
+ let itemNumber = index + 1;
506
+ let fragment = document.createDocumentFragment();
507
+ let htmlRow = `
508
+ <div class="form-row" id="node-input-port_range">
509
+ <span class='bp-matrix-itemIndex'> ${itemNumber} </span>
510
+ <a style="padding-left: 60px;">Start: </a><input type="number" id="node-input-port_range_entry_start" style="width: 125px;" min="0" max="64738" value="${rowData.start}" />
511
+ <a style="padding-left: 35px;">End: </a><input type="number" id="node-input-port_range_entry_end" style="width: 125px;" min="1" max="64738" value="${rowData.end}" />
512
+ <label class='bp-matrix-enable' for="node-input-port_range_entry"><i class="icon-tag"></i><span data-i18n="bitpool-bacnet.label.port_range_entry"></span>
513
+ <input type="checkbox" id="node-input-port_range_entry_enabled" style="width: auto;" ${rowData.enabled} /> </label>
514
+ </div>`;
515
+
516
+ $(htmlRow).appendTo(fragment);
517
+ row[0].appendChild(fragment);
518
+ document.getElementById("node-input-reg-block-count-portRangeMatrix").innerHTML = $(
519
+ "#node-input-portRangeMatrix-container"
520
+ ).editableList("length");
521
+ },
522
+ removeItem: function (data) {
523
+ document.getElementById("node-input-reg-block-count-portRangeMatrix").innerHTML = $(
524
+ "#node-input-portRangeMatrix-container"
525
+ ).editableList("length");
526
+ },
527
+ removable: true,
528
+ scrollOnAdd: false,
529
+ header: $("<div style='display:flex; padding:10px 10px 0px 5px; column-gap: 10px'>").append(
530
+ $.parseHTML(
531
+ "<div><span class='bp-matrix-heading'>Port Range(s)</span> </div><div class='bp-matrix-count' style='color: gray'><label id='node-input-reg-block-count-portRangeMatrix' >0</label> </div>"
532
+ )
533
+ ),
534
+ buttons: [
535
+ {
536
+ label: "json",
537
+ icon: "fa fa-share",
538
+ title: "Export tags as JSON to browser",
539
+ click: function (evt) {
540
+ var portRangeRegisters = $("#node-input-portRangeMatrix-container").editableList("items");
541
+ var mapItems = [];
542
+ portRangeRegisters.each(function (i) {
543
+ var registerMap = $(this);
544
+ var mapItem = {
545
+ enabled: registerMap.find("#node-input-port_range_entry_enabled").val(),
546
+ start: registerMap.find("#node-input-port_range_entry_start").val(),
547
+ end: registerMap.find("#node-input-port_range_entry_end").val(),
548
+ };
549
+ mapItems.push(mapItem);
550
+ });
551
+ var oMyBlob = new Blob(
552
+ [
553
+ JSON.stringify(mapItems, null, 0)
554
+ .replaceAll(/\[{/gi, "[\n{")
555
+ .replaceAll(/}\]/gi, "}\n]")
556
+ .replaceAll(/},/gi, "},\n")
557
+ .replaceAll(/{/gi, " {"),
558
+ ],
559
+ { type: "text/json" }
560
+ );
561
+ window.open(URL.createObjectURL(oMyBlob));
562
+ },
563
+ },
564
+ {
565
+ label: "delete",
566
+ icon: "fa-regular fa-trash-can",
567
+ title: "Delete all registers",
568
+ click: function (evt) {
569
+ $("#node-input-portRangeMatrix-container").editableList("empty");
570
+ document.getElementById("node-input-reg-block-count-portRangeMatrix").innerHTML = 0;
571
+ },
572
+ },
573
+ ],
574
+ });
575
+
576
+ if (node.portRangeRegisters.length > 0) {
577
+ for (var i = 0; i < node.portRangeRegisters.length; i++) {
578
+ $("#node-input-portRangeMatrix-container").editableList("addItem", node.portRangeRegisters[i]);
579
+ }
580
+ } else {
581
+ $("#node-input-portRangeMatrix-container").editableList("addItem", {
582
+ enabled: true,
583
+ start: "47808",
584
+ end: "47808",
585
+ });
586
+ }
587
+
588
+ document.getElementById("node-input-reg-block-count-portRangeMatrix").innerHTML = node.portRangeRegisters.length;
589
+ //end port range matrix
476
590
  },
477
591
  oneditsave: function () {
478
592
  let node = this;
@@ -503,6 +617,18 @@
503
617
  };
504
618
  node.deviceRangeRegisters.push(mapItem);
505
619
  });
620
+
621
+ node.portRangeRegisters = [];
622
+ let portRanges = $("#node-input-portRangeMatrix-container").editableList("items");
623
+ portRanges.each(function (i) {
624
+ let map = $(this);
625
+ let mapItem = {
626
+ enabled: map.find("#node-input-port_range_entry_enabled").is(":checked"),
627
+ start: map.find("#node-input-port_range_entry_start").val(),
628
+ end: map.find("#node-input-port_range_entry_end").val(),
629
+ };
630
+ node.portRangeRegisters.push(mapItem);
631
+ });
506
632
  },
507
633
  });
508
634
 
@@ -551,10 +677,6 @@
551
677
  margin-top: 20px;
552
678
  margin-left: 50px;
553
679
  }
554
- .p-confirm-dialog-accept > .p-button-label,
555
- .bacnetServerRebuildSchedule_clearButton > .p-button-label {
556
- color: white;
557
- }
558
680
  .red-ui-editor label {
559
681
  font-size: 12px;
560
682
  }
@@ -632,8 +754,7 @@
632
754
 
633
755
  <div class="form-row bp-row" id="networkInterfaceDiv">
634
756
  <label for="node-input-local_device_address"
635
- ><i class="icon-tag"></i><span data-i18n="bitpool-bacnet.label.local_device_address"></span> Network
636
- Interface</label
757
+ ><i class="icon-tag"></i><span data-i18n="bitpool-bacnet.label.local_device_address"></span> Network Interface</label
637
758
  >
638
759
  <select id="node-input-local_device_address"></select>
639
760
  </div>
@@ -652,6 +773,10 @@
652
773
  <input type="text" id="node-input-local_device_port" placeholder="47808" />
653
774
  </div>
654
775
 
776
+ <div class="form-row node-input-portRangeMatrix-container-row bp-row">
777
+ <ol id="node-input-portRangeMatrix-container"></ol>
778
+ </div>
779
+
655
780
  <div class="form-row bp-row">
656
781
  <label for="node-input-deviceId"
657
782
  ><i class="icon-tag"></i><span data-i18n="bitpool-bacnet.label.deviceId"></span> Device ID
@@ -764,8 +889,8 @@
764
889
 
765
890
  <div class="form-row bp-row" style="align-items: center; display: none;">
766
891
  <label for="node-input-sanitise_device_schedule_value"
767
- ><i class="icon-tag"></i> <span data-i18n="bitpool-bacnet.label.sanitise_device_schedule"></span>Device
768
- Sanitisation Frequency</label
892
+ ><i class="icon-tag"></i> <span data-i18n="bitpool-bacnet.label.sanitise_device_schedule"></span>Device Sanitisation
893
+ Frequency</label
769
894
  >
770
895
  <p style="margin-right: 5px; margin-bottom: 0px; padding-left: 7px;">Every</p>
771
896
  <input type="text" id="node-input-sanitise_device_schedule" style="display: none;" />
@@ -783,17 +908,17 @@
783
908
  </div>
784
909
 
785
910
  <div class="form-row bp-checkbox-row">
786
- <input type="checkbox" id="node-input-cacheFileEnabled" class="bp-checkbox"/>
911
+ <input type="checkbox" id="node-input-cacheFileEnabled" class="bp-checkbox" />
787
912
  <label for="node-input-cacheFileEnabled"> Enable cache file </label>
788
913
  </div>
789
914
 
790
915
  <div class="form-row bp-checkbox-row">
791
- <input type="checkbox" id="node-input-toLogIam" class="bp-checkbox"/>
916
+ <input type="checkbox" id="node-input-toLogIam" class="bp-checkbox" />
792
917
  <label for="node-input-toLogIam"> Log found device </label>
793
918
  </div>
794
919
 
795
920
  <div class="form-row bp-checkbox-row" style="border-bottom: 1px solid #cbcbcb; padding-bottom: 20px;">
796
- <input type="checkbox" id="node-input-logErrorToConsole" class="bp-checkbox"/>
921
+ <input type="checkbox" id="node-input-logErrorToConsole" class="bp-checkbox" />
797
922
  <label for="node-input-logErrorToConsole"> Log BACnet errors to console </label>
798
923
  </div>
799
924
 
@@ -815,15 +940,12 @@
815
940
 
816
941
  <div id="read-server-tab" style="display:none">
817
942
  <div class="form-row bp-checkbox-row">
818
- <input type="checkbox" id="node-input-serverEnabled" class="bp-checkbox"/>
943
+ <input type="checkbox" id="node-input-serverEnabled" class="bp-checkbox" />
819
944
  <label for="node-input-serverEnabled"> Enable Server </label>
820
945
  </div>
821
946
 
822
947
  <div class="read_server_parent_div" id="serverParent">
823
- <div
824
- class="form-row bp-row clearServerContainer"
825
- id="clearServerContainer"
826
- style="align-items: center; display: flex;">
948
+ <div class="form-row bp-row clearServerContainer" id="clearServerContainer" style="align-items: center; display: flex;">
827
949
  <p-button class="bacnetServerRebuildSchedule_clearButton" @click="confirmAll($event)" label="Reinitialize Server">
828
950
  </p-button>
829
951
  </div>
@@ -856,8 +978,8 @@
856
978
  <h3><strong>Gateway Tab</strong></h3>
857
979
  <ul class="node-ports">
858
980
  <li>
859
- Network Interface - the desired interface for the bacstack client to bind to. This interface must not have any other
860
- BACnet clients bound to it.
981
+ Network Interface - the desired interface for the bacstack client to bind to. This interface must not have any other BACnet
982
+ clients bound to it.
861
983
  </li>
862
984
  <li>
863
985
  Broadcast Address - the desired subnet for global msgs to be broadcast and recieved on. This should be as strict as
@@ -872,13 +994,13 @@
872
994
  <li>Max APDU Size - BACnet max apdu size</li>
873
995
  <li>Max Segments - BACnet max segments</li>
874
996
  <li>
875
- Global Discover Frequency - the frequency at which the gateway issues global WhoIs BACnet commands. This should be
876
- limited to the least amount possible, as over-loading a network can be a serious issue with BACnet commmunications.
997
+ Global Discover Frequency - the frequency at which the gateway issues global WhoIs BACnet commands. This should be limited
998
+ to the least amount possible, as over-loading a network can be a serious issue with BACnet commmunications.
877
999
  </li>
878
1000
  <li>
879
- Manual Point Discovery Instance Range - if a BACnet device doesnt have a Object list (BACnet objectType:propertyId -
880
- 8:76), the this bacnet client will enter into manual discovery mode, where it iterates through types and instnace
881
- ranges. This range can be used to limit this manual scanning
1001
+ Manual Point Discovery Instance Range - if a BACnet device doesnt have a Object list (BACnet objectType:propertyId - 8:76),
1002
+ the this bacnet client will enter into manual discovery mode, where it iterates through types and instnace ranges. This
1003
+ range can be used to limit this manual scanning
882
1004
  </li>
883
1005
  <li>Log Device Found - toggles logging of found devices to the node-red debug tab.</li>
884
1006
  <li>Log BACnet Errors to Console - toggles logging of BACnet related errors to the node-red console</li>
@@ -891,20 +1013,18 @@
891
1013
  devices via BACnet/IP
892
1014
  </p>
893
1015
  <p>
894
- This node only supports 2 BACnet object types, Analog Value - to show numeric data, and a Character String - to show
895
- string data.
1016
+ This node only supports 2 BACnet object types, Analog Value - to show numeric data, and a Character String - to show string
1017
+ data.
896
1018
  </p>
897
1019
  <ul class="node-ports">
898
1020
  <li>Enabled - toggles whether or not the local BACnet server is started or not.</li>
899
- <li>
900
- Clear Server Points - a schedule for the locally generated BACnet points to get cleared from the node object store
901
- </li>
1021
+ <li>Clear Server Points - a schedule for the locally generated BACnet points to get cleared from the node object store</li>
902
1022
  </ul>
903
1023
 
904
1024
  <h3><strong>Examples</strong></h3>
905
1025
  <p>
906
- For example flows, please use the examples section for this node. These examples can be found at: Node-red hamburger menu
907
- on top right -> Import -> Examples -> @bitpoolos/edge-bacnet
1026
+ For example flows, please use the examples section for this node. These examples can be found at: Node-red hamburger menu on
1027
+ top right -> Import -> Examples -> @bitpoolos/edge-bacnet
908
1028
  </p>
909
1029
  <p>
910
1030
  To find captured examples of settings and flows, please go to our wiki
package/bacnet_gateway.js CHANGED
@@ -33,6 +33,7 @@ module.exports = function (RED) {
33
33
  this.retries = config.retries;
34
34
  this.bacnetServer = nodeContext.get("bacnetServer") || null;
35
35
  this.deviceRangeRegisters = config.deviceRangeRegisters;
36
+ this.portRangeRegisters = config.portRangeRegisters;
36
37
  this.cacheFileEnabled = config.cacheFileEnabled;
37
38
  this.sanitise_device_schedule = config.sanitise_device_schedule;
38
39
 
@@ -61,7 +62,8 @@ module.exports = function (RED) {
61
62
  node.device_read_schedule,
62
63
  node.retries,
63
64
  node.cacheFileEnabled,
64
- node.sanitise_device_schedule
65
+ node.sanitise_device_schedule,
66
+ node.portRangeRegisters.filter((ele) => ele.enabled === true)
65
67
  );
66
68
 
67
69
  nodeContext.set("bacnetConfig", node.bacnetConfig);
@@ -225,11 +227,9 @@ module.exports = function (RED) {
225
227
  logOut("Error updating priorityQueue: ", error);
226
228
  });
227
229
  } else if (msg.testFunc == true) {
228
- node.bacnetClient.testFunction(msg.address, msg.type, msg.instance, msg.property);
230
+ node.bacnetClient.testFunction(msg.address, msg.port, msg.type, msg.instance, msg.property);
229
231
  } else if (msg.applyDisplayNames) {
230
-
231
232
  node.status({ fill: "blue", shape: "dot", text: "Updating display names" });
232
-
233
233
  setTimeout(() => {
234
234
  node.status({});
235
235
  }, 2000);
@@ -240,7 +240,6 @@ module.exports = function (RED) {
240
240
  }).catch(function (error) {
241
241
  logOut("Error in applyDisplayNames: ", error);
242
242
  });
243
-
244
243
  }
245
244
  });
246
245