node-red-contrib-knx-ultimate 3.1.2 → 3.1.4

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 CHANGED
@@ -6,6 +6,16 @@
6
6
 
7
7
  # CHANGELOG
8
8
 
9
+ **Version 3.1.4** - August 2024<br/>
10
+ - KNX Node: added a group address search helper in the KNX Function TAB.<br/>
11
+ - Updated documentation.<br/>
12
+
13
+ **Version 3.1.3** - August 2024<br/>
14
+ - KNX Node: now the property page opens directly on KNX Function tab, if js code is present. CAUTION, KNX FUNCTION IS STILL IN BETA AND SUBJECT TO CHANGES.<br/>
15
+ - KNX Node: Universal mode is now selectable in the dropdown list of GA Types.<br/>
16
+ - KNX Node: better UI controls placements.<br/>
17
+ - Updated documentation.<br/>
18
+
9
19
  **Version 3.1.2** - August 2024<br/>
10
20
  - NEW: KNX Function code editor: minor fixes. CAUTION, KNX FUNCTION IS STILL IN BETA AND SUBJECT TO CHANGES.<br/>
11
21
 
@@ -21,7 +21,6 @@
21
21
  notifywrite: { value: true },
22
22
  notifyreadrequestalsorespondtobus: { value: false },
23
23
  notifyreadrequestalsorespondtobusdefaultvalueifnotinitialized: { value: "0" },
24
- listenallga: { value: false },
25
24
  name: { value: "" },
26
25
  outputtype: { value: "write" },
27
26
  outputRBE: { value: "true" },
@@ -31,7 +30,8 @@
31
30
  formatdecimalsvalue: { value: 999 },
32
31
  passthrough: { value: "no" },
33
32
  sendMsgToKNXCode: { value: "" },
34
- receiveMsgFromKNXCode: { value: "" }
33
+ receiveMsgFromKNXCode: { value: "" },
34
+ listenallga: { value: "" }
35
35
  },
36
36
  inputs: 1,
37
37
  outputs: 1,
@@ -39,7 +39,7 @@
39
39
  label: function () {
40
40
  const functionSendMsgToKNXCode = (this.sendMsgToKNXCode !== undefined && this.sendMsgToKNXCode !== '') ? "f(x) " : "";
41
41
  const functionreceiveMsgFromKNXCode = (this.receiveMsgFromKNXCode !== undefined && this.receiveMsgFromKNXCode !== '') ? " f(x)" : "";
42
- return ((this.outputRBE === "true" || this.outputRBE === true) ? "|rbe| " : "") + functionSendMsgToKNXCode + (this.name || this.topic || "KNX Device") + (this.setTopicType === 'str' || this.setTopicType === undefined ? '' : ' [' + this.setTopicType + ']') + functionreceiveMsgFromKNXCode + ((this.inputRBE === "true" || this.inputRBE === true) ? " |rbe|" : "")
42
+ return ((this.outputRBE === "true" || this.outputRBE === true) ? "|rbe| " : "") + functionSendMsgToKNXCode + (this.name || this.topic || "KNX Device") + (this.setTopicType === 'str' || this.setTopicType === undefined ? '' : ' [' + (this.setTopicType === 'listenAllGA' ? 'Universal' : this.setTopicType) + ']') + functionreceiveMsgFromKNXCode + ((this.inputRBE === "true" || this.inputRBE === true) ? " |rbe|" : "")
43
43
  },
44
44
  paletteLabel: "KNX DEVICE",
45
45
  // button: {
@@ -156,11 +156,14 @@
156
156
  try {
157
157
  if (typeof oNodeServer.csv !== "undefined" && oNodeServer.csv !== "") {
158
158
  $("#isETSFileLoaded").val("si");
159
+ $("#divknxFunctionHelperGAList").show();
159
160
  } else {
160
161
  $("#isETSFileLoaded").val("no");
162
+ $("#divknxFunctionHelperGAList").hide();
161
163
  }
162
164
  } catch (error) {
163
165
  $("#isETSFileLoaded").val("no");
166
+ $("#divknxFunctionHelperGAList").hide();
164
167
  }
165
168
  if (oNodeServer.knxSecureSelected) {
166
169
  $("#divknxsecure").show();
@@ -198,7 +201,7 @@
198
201
 
199
202
  $("#node-input-notifyreadrequest").on('change', function () {
200
203
  if ($("#node-input-notifyreadrequest").is(":checked")) {
201
- if ($("#node-input-listenallga").is(":checked")) {
204
+ if ($("#node-input-setTopicType").val() === "listenAllGA") {
202
205
  } else {
203
206
  $("#divnotifyreadrequestautoreact").show();
204
207
  }
@@ -207,66 +210,47 @@
207
210
  }
208
211
  })
209
212
 
210
- $("#node-input-listenallga").on('change', function () {
211
- if ($("#node-input-listenallga").is(":checked")) {
212
- $("#GAandDPT").hide()
213
- $("#divOutputRBE").hide()
214
- $("#node-input-outputRBE").val("false")
215
- $("#divInputRBE").hide()
216
- $("#node-input-inputRBE").val("false")
217
- $("#divnotifyreadrequestautoreact").hide();
218
- $("#helpallga").show();
219
- $("#divTopic").hide()
220
-
221
- // Call a fake datapoint to load a sample "Universal Node"
222
- knxUltimateDptsGetHelp("0.000", true); // 15/09/2020 Supergiovane, load sample help
223
-
224
- if ($("#helpallga").html == "") {
225
- // There is a ETS csv file, show the init read option
226
- $("#divNode-input-initialread").show()
227
- } else {
228
- // There isn't a ETS csv file, hide and deselect the init read option
229
- $("#divNode-input-initialread").hide();
230
- $("#node-input-initialread").val(0);
231
- }
232
- } else {
233
-
234
- // 15/09/2020 Supergiovane, load the help sample of the current datapoint
235
- knxUltimateDptsGetHelp($("#node-input-dpt").val(), false); // 15/09/2020 Supergiovane, load sample help
236
-
237
- $("#GAandDPT").show()
238
- $("#divOutputRBE").show()
239
- $("#divInputRBE").show()
240
- $("#divTopic").show()
241
- if ($("#node-input-notifyreadrequest").is(":checked")) {
242
- $("#divnotifyreadrequestautoreact").show();
243
- } else {
244
- $("#divnotifyreadrequestautoreact").hide();
245
- }
246
- $("#helpallga").hide()
247
- $("#divNode-input-initialread").show();
248
- }
249
- })
250
-
251
213
  // Set the group address type
252
214
  if (node.setTopicType === undefined) {
253
215
  node.setTopicType = 'str';
254
216
  $("#node-input-setTopicType").val('str');
255
217
  }
256
- // $("#node-input-topic").typedInput(
257
- // {
258
- // default: node.setTopicType || 'str',
259
- // types: [{ value: 'str', label: "str", icon: 'red/images/typedInput/az.svg', autocomplete: autoCompleteGA }, 'flow', 'global', 'env'],
260
- // typeField: "#node-input-setTopicType"
261
- // });
262
- // var autoCompleteGA = function () {
263
- // alert(value)
264
- // return [{ value: "Ciso", label: "maso" }]
265
- // }
218
+
219
+ // KNX Function helper: search for a GA and devicename
220
+ // ----------------------------------------------------------
221
+ try {
222
+ $("#node-input-knxFunctionHelperGAList").autocomplete('destroy');
223
+ $("#node-input-knxFunctionHelperGAList").removeClass(); // Rimuove eventuali classi aggiunte dall'autocompletamento
224
+ } catch (error) { }
225
+ $("#node-input-knxFunctionHelperGAList").off(); // Rimuovi tutti gli eventi associati
226
+ $("#node-input-knxFunctionHelperGAList").val(''); // Pulisce il valore del campo di input, se necessario
227
+ $("#node-input-knxFunctionHelperGAList").autocomplete({
228
+ minLength: 0,
229
+ source: function (request, response) {
230
+ $.getJSON("knxUltimatecsv?nodeID=" + oNodeServer.id + "&" + { _: new Date().getTime() }, (data) => {
231
+ response($.map(data, function (value, key) {
232
+ var sSearch = (value.ga + " (" + value.devicename + ") DPT" + value.dpt);
233
+ if (htmlUtilsfullCSVSearch(sSearch, request.term)) {
234
+ return {
235
+ label: value.ga + " # " + value.devicename + " # " + value.dpt, // Label for Display
236
+ value: value.ga + " " + value.devicename // Value
237
+ }
238
+ } else {
239
+ return null;
240
+ }
241
+ }));
242
+ });
243
+ }, select: function (event, ui) {
244
+ }
245
+ }).focus(function () {
246
+ $(this).autocomplete('search', $(this).val() + 'exactmatch');
247
+ });
248
+ // ----------------------------------------------------------
266
249
 
267
250
 
268
251
  $("#node-input-setTopicType").on('change', function () {
269
252
  try {
253
+ $("#node-input-topic").show();
270
254
  $("#node-input-topic").autocomplete('destroy');
271
255
  $("#node-input-topic").off(); // Rimuovi tutti gli eventi associati
272
256
  $("#node-input-topic").val(''); // Pulisce il valore del campo di input, se necessario
@@ -310,7 +294,45 @@
310
294
  $(this).autocomplete('search', $(this).val() + 'exactmatch');
311
295
  });
312
296
  $("#divDatapointSelection").show();
297
+ } else if ($("#node-input-setTopicType").val() === 'listenAllGA') {
298
+ $("#node-input-topic").hide();
299
+ $("#GAandDPT").hide()
300
+ $("#divOutputRBE").hide()
301
+ $("#node-input-outputRBE").val("false")
302
+ $("#divInputRBE").hide()
303
+ $("#node-input-inputRBE").val("false")
304
+ $("#divnotifyreadrequestautoreact").hide();
305
+ $("#helpallga").show();
306
+ $("#divTopic").hide()
307
+
308
+ // Call a fake datapoint to load a sample "Universal Node"
309
+ knxUltimateDptsGetHelp("0.000", true); // 15/09/2020 Supergiovane, load sample help
310
+
311
+ if ($("#helpallga").html == "") {
312
+ // There is a ETS csv file, show the init read option
313
+ $("#divNode-input-initialread").show()
314
+ } else {
315
+ // There isn't a ETS csv file, hide and deselect the init read option
316
+ $("#divNode-input-initialread").hide();
317
+ $("#node-input-initialread").val(0);
318
+ }
313
319
  } else {
320
+
321
+ // 15/09/2020 Supergiovane, load the help sample of the current datapoint
322
+ knxUltimateDptsGetHelp($("#node-input-dpt").val(), false); // 15/09/2020 Supergiovane, load sample help
323
+
324
+ $("#GAandDPT").show()
325
+ $("#divOutputRBE").show()
326
+ $("#divInputRBE").show()
327
+ $("#divTopic").show()
328
+ if ($("#node-input-notifyreadrequest").is(":checked")) {
329
+ $("#divnotifyreadrequestautoreact").show();
330
+ } else {
331
+ $("#divnotifyreadrequestautoreact").hide();
332
+ }
333
+ $("#helpallga").hide()
334
+ $("#divNode-input-initialread").show();
335
+
314
336
  $("#node-input-topic").prop('placeholder', $("#node-input-setTopicType").val());
315
337
  if ($("#node-input-topic").val() === '') $("#node-input-topic").val('MyVariable');
316
338
  $("#divDatapointSelection").hide();
@@ -327,7 +349,7 @@
327
349
  } else {
328
350
  // 25/10/2019 Warn user that the node will node encode/decode datagram, if Listen All GA's if the config node doesn't contain the csv
329
351
  $("#helpallga").html("<i> " + node._("knxUltimate.advanced.noETSWarning") + " </i>");
330
- if ($("#node-input-listenallga").is(":checked")) {
352
+ if ($("#node-input-setTopicType").val() === 'listenAllGA') {
331
353
  // There isn't a ETS csv file, hide and deselect the init read option
332
354
  $("#divNode-input-initialread").hide();
333
355
  $("#node-input-initialread").val(0);
@@ -336,7 +358,7 @@
336
358
  }
337
359
  }
338
360
  } else {
339
- $("#node-input-listenallga").prop("checked", false)
361
+ $("#node-input-setTopicType").val('str')
340
362
  $("#divTopic").show()
341
363
  $("#GAandDPT").show()
342
364
  $("#divOutputRBE").show()
@@ -348,7 +370,7 @@
348
370
  // *****************************
349
371
 
350
372
  setTimeout(() => {
351
- if (node.listenallga === true) {
373
+ if ($("#node-input-setTopicType").val() === 'listenAllGA') {
352
374
  // Call a fake datapoint to load a sample "Universal Node"
353
375
  knxUltimateDptsGetHelp("0.000", true); // 15/09/2020 Supergiovane, load sample help
354
376
  }
@@ -365,6 +387,17 @@
365
387
  });
366
388
  // ###########################
367
389
 
390
+ // If KNX Function is populated, set focus on the KNX Function tab.
391
+ if (this.sendMsgToKNXCodeEditor.getValue() !== '' || this.receiveMsgFromKNXCodeEditor.getValue()) {
392
+ $("#tabs").tabs(
393
+ { active: 1 }
394
+ );
395
+ }
396
+
397
+ // Backwart compatibility listenAllGA
398
+ if (node.listenallga === true) {
399
+ $("#node-input-setTopicType").val('listenAllGA');
400
+ }
368
401
 
369
402
  // 19/02/2020 Used to alert the user if the CSV file has not been loaded and to get the server sooner als deploy
370
403
  // ###########################
@@ -378,12 +411,17 @@
378
411
  var node = this;
379
412
  this.sendMsgToKNXCode = this.sendMsgToKNXCodeEditor.getValue();
380
413
  this.receiveMsgFromKNXCode = this.receiveMsgFromKNXCodeEditor.getValue();
414
+ if ($("#node-input-setTopicType").val() === "listenAllGA") {
415
+ this.listenallga = true;
416
+ } else {
417
+ this.listenallga = false;
418
+ }
381
419
  //this.propertyType = $("#node-input-property").typedInput('type');
382
420
 
383
421
  // 19/02/2020 Warn user that the node will node encode/decode datagram, if Listen All GA's if the config node doesn't contain the csv
384
422
  if ($("#isETSFileLoaded").val() === "no") {
385
423
  // Notify the user
386
- if ($("#node-input-listenallga").is(":checked")) {
424
+ if ($("#node-input-setTopicType").val() === 'listenAllGA') {
387
425
  var checkResult = node._("knxUltimate.advanced.notify-NoETSFile");
388
426
  var myNotification = RED.notify(checkResult,
389
427
  {
@@ -458,22 +496,22 @@
458
496
 
459
497
  <div id="divMain">
460
498
 
461
- <div id="GAandDPT">
462
-
463
- <div class="form-row">
464
- <label for="node-input-topic">
465
- <img
466
- src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAACXBIWXMAAB7CAAAewgFu0HU+AAAF6WlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDggNzkuMTY0MDM2LCAyMDE5LzA4LzEzLTAxOjA2OjU3ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjEuMSAoTWFjaW50b3NoKSIgeG1wOkNyZWF0ZURhdGU9IjIwMjAtMDMtMjNUMTY6MjE6MDkrMDE6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDIwLTAzLTIzVDE2OjI4OjI3KzAxOjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIwLTAzLTIzVDE2OjI4OjI3KzAxOjAwIiBkYzpmb3JtYXQ9ImltYWdlL3BuZyIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgcGhvdG9zaG9wOklDQ1Byb2ZpbGU9InNSR0IgSUVDNjE5NjYtMi4xIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjc4M2I5OWIxLTkwMjYtNGQ2OC05N2FmLTRkM2E2ZWY4Zjk2OCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo4N2E3YTg0NS0xMDljLTRkMTMtOGEzOS04OWVhOTMyMDQ0ZWMiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo4N2E3YTg0NS0xMDljLTRkMTMtOGEzOS04OWVhOTMyMDQ0ZWMiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjg3YTdhODQ1LTEwOWMtNGQxMy04YTM5LTg5ZWE5MzIwNDRlYyIgc3RFdnQ6d2hlbj0iMjAyMC0wMy0yM1QxNjoyMTowOSswMTowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDIxLjEgKE1hY2ludG9zaCkiLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjc4M2I5OWIxLTkwMjYtNGQ2OC05N2FmLTRkM2E2ZWY4Zjk2OCIgc3RFdnQ6d2hlbj0iMjAyMC0wMy0yM1QxNjoyODoyNyswMTowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDIxLjEgKE1hY2ludG9zaCkiIHN0RXZ0OmNoYW5nZWQ9Ii8iLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+DGyPFQAAAE9JREFUKJG1UEEOACAIgub/v2yHalnJVoe4uIEKSgccJ9jroVmjA0+ujZtWku3DgZmgBiT4egN9CmmEAAfA/5HUW0OQu7dKmOCzmM3k9YYKZv8ZEZ/YgNsAAAAASUVORK5CYII="></img>
467
- Group Addr.</label>
468
- <select id="node-input-setTopicType" style="width:120px">
469
- <option value="str">3-Levels</option>
470
- <option value="flow">Flow</option>
471
- <option value="global">Gobal</option>
472
- <option value="env">$Env variable</option>
473
- </select>
474
- <input type="text" id="node-input-topic" placeholder="Start typing to search" style="width:180px" />
475
- </div>
499
+ <div class="form-row">
500
+ <label for="node-input-topic">
501
+ <img
502
+ src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAACXBIWXMAAB7CAAAewgFu0HU+AAAF6WlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDggNzkuMTY0MDM2LCAyMDE5LzA4LzEzLTAxOjA2OjU3ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjEuMSAoTWFjaW50b3NoKSIgeG1wOkNyZWF0ZURhdGU9IjIwMjAtMDMtMjNUMTY6MjE6MDkrMDE6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDIwLTAzLTIzVDE2OjI4OjI3KzAxOjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIwLTAzLTIzVDE2OjI4OjI3KzAxOjAwIiBkYzpmb3JtYXQ9ImltYWdlL3BuZyIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgcGhvdG9zaG9wOklDQ1Byb2ZpbGU9InNSR0IgSUVDNjE5NjYtMi4xIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjc4M2I5OWIxLTkwMjYtNGQ2OC05N2FmLTRkM2E2ZWY4Zjk2OCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo4N2E3YTg0NS0xMDljLTRkMTMtOGEzOS04OWVhOTMyMDQ0ZWMiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo4N2E3YTg0NS0xMDljLTRkMTMtOGEzOS04OWVhOTMyMDQ0ZWMiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjg3YTdhODQ1LTEwOWMtNGQxMy04YTM5LTg5ZWE5MzIwNDRlYyIgc3RFdnQ6d2hlbj0iMjAyMC0wMy0yM1QxNjoyMTowOSswMTowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDIxLjEgKE1hY2ludG9zaCkiLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjc4M2I5OWIxLTkwMjYtNGQ2OC05N2FmLTRkM2E2ZWY4Zjk2OCIgc3RFdnQ6d2hlbj0iMjAyMC0wMy0yM1QxNjoyODoyNyswMTowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDIxLjEgKE1hY2ludG9zaCkiIHN0RXZ0OmNoYW5nZWQ9Ii8iLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+DGyPFQAAAE9JREFUKJG1UEEOACAIgub/v2yHalnJVoe4uIEKSgccJ9jroVmjA0+ujZtWku3DgZmgBiT4egN9CmmEAAfA/5HUW0OQu7dKmOCzmM3k9YYKZv8ZEZ/YgNsAAAAASUVORK5CYII="></img>
503
+ Group Addr.</label>
504
+ <select id="node-input-setTopicType" style="width:120px">
505
+ <option value="str">3-Levels</option>
506
+ <option value="listenAllGA">Universal mode (listen to all Group Addresses)</option>
507
+ <option value="flow">Flow</option>
508
+ <option value="global">Gobal</option>
509
+ <option value="env">$Env variable</option>
510
+ </select>
511
+ <input type="text" id="node-input-topic" placeholder="Start typing to search" style="width:180px" />
512
+ </div>
476
513
 
514
+ <div id="GAandDPT">
477
515
  <div class="form-row" id="divDatapointSelection">
478
516
  <label for="node-input-dpt">
479
517
  <img
@@ -484,32 +522,7 @@
484
522
  <span id="sampleCodeEditor" style="color:red;" />
485
523
  </div>
486
524
  </div>
487
- <div class="form-row">
488
- <label for="node-input-name">
489
- <i class="fa fa-tag"></i>
490
- <span data-i18n="knxUltimate.properties.node-input-name"></span>
491
- </label>
492
- <input type="text" id="node-input-name" data-i18n="[placeholder]knxUltimate.properties.node-input-name" />
493
- </div>
494
- <div class="form-row" id="divTopic">
495
- <label for="node-input-outputtopic">
496
- <i class="fa fa-tasks"></i>
497
- <span data-i18n="knxUltimate.properties.node-input-outputtopic"></span>
498
- </label>
499
- <input type="text" id="node-input-outputtopic" data-i18n="[placeholder]knxUltimate.placeholder.leaveempty" />
500
- </div>
501
- <div class="form-row">
502
- <label for="node-input-passthrough">
503
- <i class="fa fa-long-arrow-right"></i> Passthrough
504
- </label>
505
- <select id="node-input-passthrough">
506
- <option value="no">No</option>
507
- <option value="yes">Yes, pass the input msg to the output msg</option>
508
- <option value="yesownprop">Yes, but put the input msg into msg.inputmessage property of the output msg
509
- </option>
510
- </select>
511
- </div>
512
- <div class="form-row">
525
+ <!-- <div class="form-row">
513
526
  <input type="checkbox" id="node-input-listenallga"
514
527
  style="display:inline-block; width:auto; vertical-align:top;" />
515
528
  <label style="width:auto" for="node-input-listenallga">
@@ -517,8 +530,7 @@
517
530
  src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAACXBIWXMAAB7CAAAewgFu0HU+AAAFGmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDggNzkuMTY0MDM2LCAyMDE5LzA4LzEzLTAxOjA2OjU3ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjEuMSAoTWFjaW50b3NoKSIgeG1wOkNyZWF0ZURhdGU9IjIwMjAtMDMtMjNUMTY6MjM6MjMrMDE6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDIwLTAzLTIzVDE2OjI1OjM0KzAxOjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIwLTAzLTIzVDE2OjI1OjM0KzAxOjAwIiBkYzpmb3JtYXQ9ImltYWdlL3BuZyIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgcGhvdG9zaG9wOklDQ1Byb2ZpbGU9InNSR0IgSUVDNjE5NjYtMi4xIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOmJmNGM3NWVjLTIwNGYtNGY1YS05YTMxLTQ5NTU5YWJmZDE4NSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpiZjRjNzVlYy0yMDRmLTRmNWEtOWEzMS00OTU1OWFiZmQxODUiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpiZjRjNzVlYy0yMDRmLTRmNWEtOWEzMS00OTU1OWFiZmQxODUiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOmJmNGM3NWVjLTIwNGYtNGY1YS05YTMxLTQ5NTU5YWJmZDE4NSIgc3RFdnQ6d2hlbj0iMjAyMC0wMy0yM1QxNjoyMzoyMyswMTowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDIxLjEgKE1hY2ludG9zaCkiLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+nhtLUgAAAE9JREFUKJG1UMsOACAIgub//7IdqvVQtjrExU1EEQLuiGCvgTNgl5D74MmVZPu4wIxQAgm+/sDec2VhgQPgf0sq1unjMlYJE/3MZrvy+kMFZQkZEWfC7ikAAAAASUVORK5CYII="></img>
518
531
  <span data-i18n="knxUltimate.properties.node-input-listenallga"></span>
519
532
  </label>
520
- <!-- <div id="helpallga">Some Content Here</div> -->
521
- </div>
533
+ </div> -->
522
534
  <div id="tabs">
523
535
  <ul>
524
536
  <li><a href="#tabs-1"><i class="fa fa-braille"></i> Advanced options</a></li>
@@ -527,6 +539,40 @@
527
539
  </ul>
528
540
  <div id="tabs-1">
529
541
  <div class="form-row" style="padding:10px">
542
+ <div class="form-row">
543
+ <dt>
544
+ <i class="fa fa-desktop"></i> General properties
545
+ </dt>
546
+ </div>
547
+ <div class="form-row">
548
+ <label for="node-input-name">
549
+ <i class="fa fa-tag"></i>
550
+ <span data-i18n="knxUltimate.properties.node-input-name"></span>
551
+ </label>
552
+ <input type="text" id="node-input-name"
553
+ data-i18n="[placeholder]knxUltimate.properties.node-input-name" />
554
+ </div>
555
+ <div class="form-row" id="divTopic">
556
+ <label for="node-input-outputtopic">
557
+ <i class="fa fa-tasks"></i>
558
+ <span data-i18n="knxUltimate.properties.node-input-outputtopic"></span>
559
+ </label>
560
+ <input type="text" id="node-input-outputtopic"
561
+ data-i18n="[placeholder]knxUltimate.placeholder.leaveempty" />
562
+ </div>
563
+ <div class="form-row">
564
+ <label for="node-input-passthrough">
565
+ <i class="fa fa-long-arrow-right"></i> Passthrough
566
+ </label>
567
+ <select id="node-input-passthrough">
568
+ <option value="no">No</option>
569
+ <option value="yes">Yes, pass the input msg to the output msg</option>
570
+ <option value="yesownprop">Yes, but put the input msg into msg.inputmessage property of the
571
+ output msg
572
+ </option>
573
+ </select>
574
+ </div>
575
+ <hr>
530
576
  <div class="form-row">
531
577
  <dt>
532
578
  <i class="fa fa-arrow-right"></i>| From node's INPUT PIN to KNX BUS
@@ -671,6 +717,15 @@
671
717
 
672
718
  <div id="tabs-2">
673
719
  <div class="form-row" style="padding:10px">
720
+
721
+ <div class="form-row" id="divknxFunctionHelperGAList">
722
+ <label for="node-input-knxFunctionHelperGAList">
723
+ <i class="fa fa-search"></i> Search GA
724
+ </label>
725
+ <input type="text" id="node-input-knxFunctionHelperGAList" placeholder="Start typing to search" />
726
+ </div>
727
+
728
+
674
729
  <div class="form-row">
675
730
  <dt>
676
731
  <i class="fa fa-arrow-right"></i>| From node's INPUT PIN to KNX BUS
@@ -723,13 +778,9 @@
723
778
  |Property|Description|
724
779
  |--|--|
725
780
  | Gateway | Select the KNX gateway to be used |
726
- | GA Type dropdown list | The group address type. **3-Levels** is the default, where you can type the *3 level group address* or the *group address name* (if you've upload the ETS file), or **Global**, for reading the GA at startup from a global variable, or **Flow** that do the same as the *Global*, but at flow level. Select **$Env variable** to read the group address from an environment variable. |
781
+ | GA Type dropdown list | The group address type. **3-Levels** is the default, where you can type the *3 level group address* or the *group address name* (if you've upload the ETS file), or **Global**, for reading the GA at startup from a global variable, or **Flow** that do the same as the *Global*, but at flow level. Select **$Env variable** to read the group address from an environment variable. Select **Universal mode (listen to all Group Addresses)** to react to ALL group addresses.|
727
782
  | Group Addr. | The KNX Group Address you want to control. If you've imported the ETS group addresses file, you can just start typing in your device name. You can leave it empty if you wish set it with *msg.setConfig* input message. |
728
783
  | Datapoint | The datapoint belonging to your node.|
729
- | Node name | Self explaining. |
730
- | Topic | The msg output topic. Leave it blank to have it set to your Group Address. |
731
- | Passthrough | If set, you can pass the input mgs to the output msg. |
732
- | Universal mode (listen to all Group Addresses) | By setting this, the node will read and control ALL group addresses. |
733
784
 
734
785
  <br/>
735
786
  <br/>
@@ -737,6 +788,10 @@
737
788
  **Advanced options**
738
789
  |Property|Description|
739
790
  |--|--|
791
+ ||**General properties**|
792
+ | Node name | Self explaining. |
793
+ | Topic | The msg output topic. Leave it blank to have it set to your Group Address. |
794
+ | Passthrough | If set, you can pass the input mgs to the output msg. |
740
795
  ||**From node's INPUT PIN to KNX BUS**|
741
796
  | Telegram type | *write* to send write telegram (usually, you want that), otherwise you can choose the telegram's type to react to. |
742
797
  | RBE filter | *Report by change* filter. If set, only the msg input (from the Flow) having different values each time, will be sent to the KNX bus. If you intend to send everytime the same value, turn it off. If enabled, "rbe" indication will be added to node's name.|
@@ -760,12 +815,18 @@ The embedded code editor provides useful objects and functions to retrieve the v
760
815
  The script is called everytime the node receives a msg from the flow or a telegram from the KNX BUS.
761
816
  If enabled, "f(x)" indication will be added to node's name.
762
817
 
818
+ |Property|Description|
819
+ |--|--|
820
+ | Search GA | It's a helper only avaiable if the ETS file has been imported. Start typing and select the group address you wish to add to the code. Then copy the full field and paste it into the getGAValue function. <br/> **getGAValue('0/0/1 table nord lamp')** |
821
+
822
+ <br/>
823
+
763
824
  ### From KNX BUS to node's OUTPUT PIN
764
825
 
765
826
  List of object and functions you can use in the code
766
827
 
767
828
  : msg (object) : The current msg object received by the node from the flow.
768
- : getGAValue (GA as string, DPT as string) : Function. Get the specified GA's value, for example '1/0/1'. **DPT** is optional if you've imported the ETS file, otherwise you must specify it, for example '1.001'.
829
+ : getGAValue (string GA , optional string DPT) : The function to get the specified GA's value, for example **'1/0/1'**, or also **'1/0/1 Bed table light'** (All text after a blank space will be ignored by the function. This is useful if you want to add the GA name as a reminder. With the ETS file imported, you can also copy and paste the GA and GA Name directly from the **Search GA** field.). **DPT** is optional if you've imported the ETS file, otherwise you must specify it, for example '1.001'.
769
830
  : node (object) : The node object.
770
831
  : RED (Node-Red object) : The Node-Red's RED object.
771
832
  : return (msg) : Mandatory `return msg;`, if you want to emit the msg to the KNX BUS. Otherwise, using `return;` will not emit any message.
@@ -787,7 +848,7 @@ if (msg.payload !== statusGA){ // "!==" means "not equal"
787
848
  List of object and functions you can use in the code
788
849
 
789
850
  : msg (object) : The current msg object received by the node from the KNX BUS.
790
- : getGAValue (GA as string, DPT as string) : Function. Get the specified GA's value, for example '1/0/1'. **DPT** is optional if you've imported the ETS file, otherwise you must specify it, for example '1.001'.
851
+ : getGAValue (string GA , optional string DPT) : The function to get the specified GA's value, for example **'1/0/1'**, or also **'1/0/1 Bed table light'** (All text after a blank space will be ignored by the function. This is useful if you want to add the GA name as a reminder. With the ETS file imported, you can also copy and paste the GA and GA Name directly from the **Search GA** field.). **DPT** is optional if you've imported the ETS file, otherwise you must specify it, for example '1.001'.
791
852
  : node (object) : The node object.
792
853
  : RED (Node-Red object) : The Node-Red's RED object.
793
854
  : return (msg) : Mandatory `return msg;`, if you want to emit the msg to the flow. Otherwise, using `return;` will not emit any message.
@@ -136,11 +136,15 @@ module.exports = function (RED) {
136
136
  }
137
137
 
138
138
  // Used in the KNX Function TAB
139
- let getGAValue = function getGAValue(ga = undefined, _dpt = undefined) {
139
+ let getGAValue = function getGAValue(_ga = undefined, _dpt = undefined) {
140
140
  try {
141
- if (ga === undefined) return;
141
+ if (_ga === undefined) return;
142
+ // The GA can have the devicename as well, separated by a blank space (1/1/0 light table ovest),
143
+ // I must take the GA only
144
+ const blankSpacePosition = _ga.indexOf(" ");
145
+ if (blankSpacePosition > -1) _ga = _ga.substring(0, blankSpacePosition);
142
146
  // Is there a GA in the server's exposedGAs?
143
- const found = node.server.exposedGAs.find(a => a.ga === ga);
147
+ const found = node.server.exposedGAs.find(a => a.ga === _ga);
144
148
  if (found !== undefined) {
145
149
  if (_dpt === undefined && found.dpt === undefined) throw new Error('No CSV file imported. Please provide the dpt manually.');
146
150
  return dptlib.fromBuffer(found.rawValue, dptlib.resolve(_dpt || found.dpt));
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "engines": {
4
4
  "node": ">=16.0.0"
5
5
  },
6
- "version": "3.1.2",
6
+ "version": "3.1.4",
7
7
  "description": "Control your KNX intallation via Node-Red! A bunch of KNX nodes, with integrated Philips HUE control and ETS group address importer. Easy to use and highly configurable.",
8
8
  "dependencies": {
9
9
  "binary-parser": "2.2.1",
@@ -39,5 +39,5 @@ return msg`;
39
39
 
40
40
  const KNXFunctionSnippetThree = `// @ts-nocheck
41
41
  // The current msg contains the internal temperature in the "msg.payload" property, but we want to emit the external temperature as well.
42
- msg.externalTemperature = getGAValue('0/0/10'); // In case the ETS file is missing, you must specify the dpt as well: getGAValue('0/0/10','9.001')
42
+ msg.externalTemperature = getGAValue('0/0/10 Garden temperature sensor'); // In case the ETS file is missing, you must specify the dpt as well: getGAValue('0/0/10','9.001')
43
43
  return msg;`;