node-red-contrib-knx-ultimate 2.2.4 → 2.2.5
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 +7 -4
- package/nodes/hue-config.js +6 -0
- package/nodes/knxUltimate-config.js +2 -2
- package/nodes/knxUltimate.html +44 -66
- package/nodes/knxUltimate.js +5 -5
- package/nodes/knxUltimateAlerter.js +190 -190
- package/nodes/knxUltimateHueBattery.js +2 -5
- package/nodes/knxUltimateHueButton.js +1 -0
- package/nodes/knxUltimateHueLight.js +2 -8
- package/nodes/knxUltimateHueLightSensor.js +2 -5
- package/nodes/knxUltimateHueMotion.js +1 -0
- package/nodes/knxUltimateHueScene.js +1 -0
- package/nodes/knxUltimateHueTapDial.js +1 -0
- package/nodes/knxUltimateHueTemperatureSensor.js +2 -3
- package/nodes/knxUltimateLoadControl.js +1 -1
- package/nodes/locales/en-US/knxUltimate.json +11 -11
- package/nodes/locales/en-US/knxUltimateSceneController.html +3 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
|
|
7
7
|
# CHANGELOG
|
|
8
8
|
|
|
9
|
+
<b>Version 2.2.5</b> - October 2023<br/>
|
|
10
|
+
- Fix: fixed some HUE nodes not able to register to the event notification service.<br/>
|
|
11
|
+
</p>
|
|
9
12
|
<b>Version 2.2.4</b> - October 2023<br/>
|
|
10
13
|
- HUE Light: fixed some status hiccups and better handling of async hue bridge functions.<br/>
|
|
11
14
|
</p>
|
|
@@ -765,7 +768,7 @@
|
|
|
765
768
|
</p>
|
|
766
769
|
<p>
|
|
767
770
|
<b>Version 1.2.33</b> - May 2021<br/>
|
|
768
|
-
- Gateway configuration -> Advanced Options -> Node list in all flows: added more infos to each node in the list, to allow more control on the nodes overview. The options are: "No Initial Read, React to Write, React to Response, No React to Read, No Autorespond to Read Requests,
|
|
771
|
+
- Gateway configuration -> Advanced Options -> Node list in all flows: added more infos to each node in the list, to allow more control on the nodes overview. The options are: "No Initial Read, React to Write, React to Response, No React to Read, No Autorespond to Read Requests, Telegram type write, No RBE on Output to Bus, No RBE on Input from Bus"<br/>
|
|
769
772
|
</p>
|
|
770
773
|
<p>
|
|
771
774
|
<b>Version 1.2.32</b> - May 2021<br/>
|
|
@@ -1067,7 +1070,7 @@
|
|
|
1067
1070
|
</p>
|
|
1068
1071
|
<p>
|
|
1069
1072
|
<b>Version 1.1.64</b> - April 2020<br/>
|
|
1070
|
-
- NEW: Added
|
|
1073
|
+
- NEW: Added Telegram type "Read", to issue a read by simply pass a payload to the node. Thanks @waldbaer for the suggestion.<br/>
|
|
1071
1074
|
</p>
|
|
1072
1075
|
<p>
|
|
1073
1076
|
<b>Version 1.1.63</b> - April 2020<br/>
|
|
@@ -1304,7 +1307,7 @@
|
|
|
1304
1307
|
</p>
|
|
1305
1308
|
<p>
|
|
1306
1309
|
<b>Version 1.1.10</b><br/>
|
|
1307
|
-
- Auto send node value as response to the KNX Bus. It works in conjunction with React to
|
|
1310
|
+
- Auto send node value as response to the KNX Bus. It works in conjunction with React to read telegrams. When checked, whenever the node receives a read request from bus, it sends a response to the KNX Bus with the stored payload value.<br/>
|
|
1308
1311
|
- Fixed an issue where if you have a node set to Universal mode (listen to all Group Addresses) (with ETS CSV File set) and you create a new node having a Group Addr. not in the ETS CSV file, an exception is raised but not caught and the nodes may not receive the values from KNX BUS.<br/>
|
|
1309
1312
|
</p>
|
|
1310
1313
|
<p>
|
|
@@ -1413,7 +1416,7 @@
|
|
|
1413
1416
|
</p>
|
|
1414
1417
|
<p>
|
|
1415
1418
|
<b>Version 0.0.6 BETA</b><br/>
|
|
1416
|
-
- Fixed
|
|
1419
|
+
- Fixed Telegram type unable to be set<br/>
|
|
1417
1420
|
- Added node status for response (blue) and read (grey)<br/>
|
|
1418
1421
|
</p>
|
|
1419
1422
|
<p>
|
package/nodes/hue-config.js
CHANGED
|
@@ -122,6 +122,12 @@ module.exports = (RED) => {
|
|
|
122
122
|
if (nodeClient.hueDevice !== undefined) {
|
|
123
123
|
const oHUEDevice = node.hueAllResources.filter((a) => a.id === nodeClient.hueDevice)[0];
|
|
124
124
|
if (oHUEDevice !== undefined) {
|
|
125
|
+
// Add _Node to the clients array
|
|
126
|
+
nodeClient.setNodeStatusHue({
|
|
127
|
+
fill: "green",
|
|
128
|
+
shape: "ring",
|
|
129
|
+
text: "Ready :-)",
|
|
130
|
+
});
|
|
125
131
|
nodeClient.currentHUEDevice = oHUEDevice;
|
|
126
132
|
nodeClient.handleSendHUE(oHUEDevice);
|
|
127
133
|
}
|
|
@@ -74,8 +74,8 @@ module.exports = (RED) => {
|
|
|
74
74
|
help: `// KNX-Ultimate set as UNIVERSAL NODE
|
|
75
75
|
// Example of a function that sends a message to the KNX-Ultimate
|
|
76
76
|
msg.destination = "0/0/1"; // Set the destination
|
|
77
|
-
msg.payload = false; // issues a write or response (based on the options
|
|
78
|
-
msg.event = "GroupValue_Write"; // "GroupValue_Write" or "GroupValue_Response", overrides the option
|
|
77
|
+
msg.payload = false; // issues a write or response (based on the options Telegram type above) to the KNX bus
|
|
78
|
+
msg.event = "GroupValue_Write"; // "GroupValue_Write" or "GroupValue_Response", overrides the option Telegram type above.
|
|
79
79
|
msg.dpt = "1.001"; // for example "1.001", overrides the Datapoint option. (Datapoints can be sent as 9 , "9" , "9.001" or "DPT9.001")
|
|
80
80
|
return msg;`,
|
|
81
81
|
helplink: "https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki",
|
package/nodes/knxUltimate.html
CHANGED
|
@@ -337,10 +337,7 @@
|
|
|
337
337
|
<br />
|
|
338
338
|
|
|
339
339
|
<label for="node-input-server">
|
|
340
|
-
<
|
|
341
|
-
<font color="green" size="4px"><i class="fa fa-shield" aria-hidden="true"></i></font>
|
|
342
|
-
</span> <span><i class="fa fa-circle-o" aria-hidden="true"></i></font></span>
|
|
343
|
-
<span data-i18n="knxUltimate.properties.node-input-server"></span>
|
|
340
|
+
<i class="fa fa-circle-o"></i> Gateway
|
|
344
341
|
</label>
|
|
345
342
|
<input type="text" id="node-input-server" />
|
|
346
343
|
</div>
|
|
@@ -354,17 +351,16 @@
|
|
|
354
351
|
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAACXBIWXMAAB7CAAAewgFu0HU+AAAF6WlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDggNzkuMTY0MDM2LCAyMDE5LzA4LzEzLTAxOjA2OjU3ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjEuMSAoTWFjaW50b3NoKSIgeG1wOkNyZWF0ZURhdGU9IjIwMjAtMDMtMjNUMTY6MjE6MDkrMDE6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDIwLTAzLTIzVDE2OjI4OjI3KzAxOjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIwLTAzLTIzVDE2OjI4OjI3KzAxOjAwIiBkYzpmb3JtYXQ9ImltYWdlL3BuZyIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgcGhvdG9zaG9wOklDQ1Byb2ZpbGU9InNSR0IgSUVDNjE5NjYtMi4xIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjc4M2I5OWIxLTkwMjYtNGQ2OC05N2FmLTRkM2E2ZWY4Zjk2OCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo4N2E3YTg0NS0xMDljLTRkMTMtOGEzOS04OWVhOTMyMDQ0ZWMiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo4N2E3YTg0NS0xMDljLTRkMTMtOGEzOS04OWVhOTMyMDQ0ZWMiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjg3YTdhODQ1LTEwOWMtNGQxMy04YTM5LTg5ZWE5MzIwNDRlYyIgc3RFdnQ6d2hlbj0iMjAyMC0wMy0yM1QxNjoyMTowOSswMTowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDIxLjEgKE1hY2ludG9zaCkiLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjc4M2I5OWIxLTkwMjYtNGQ2OC05N2FmLTRkM2E2ZWY4Zjk2OCIgc3RFdnQ6d2hlbj0iMjAyMC0wMy0yM1QxNjoyODoyNyswMTowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDIxLjEgKE1hY2ludG9zaCkiIHN0RXZ0OmNoYW5nZWQ9Ii8iLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+DGyPFQAAAE9JREFUKJG1UEEOACAIgub/v2yHalnJVoe4uIEKSgccJ9jroVmjA0+ujZtWku3DgZmgBiT4egN9CmmEAAfA/5HUW0OQu7dKmOCzmM3k9YYKZv8ZEZ/YgNsAAAAASUVORK5CYII="></img>
|
|
355
352
|
<span data-i18n="knxUltimate.properties.node-input-topic"></span>
|
|
356
353
|
</label>
|
|
357
|
-
<input
|
|
354
|
+
<input type="text" id="node-input-topic" placeholder="Sample: Dinning light" />
|
|
358
355
|
</div>
|
|
359
356
|
<div class="form-row">
|
|
360
357
|
<label for="node-input-dpt">
|
|
361
358
|
<img
|
|
362
359
|
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAKRGlDQ1BJQ0MgUHJvZmlsZQAAeAGdlndUFNcXx9/MbC+0XZYiZem9twWkLr1IlSYKy+4CS1nWZRewN0QFIoqICFYkKGLAaCgSK6JYCAgW7AEJIkoMRhEVlczGHPX3Oyf5/U7eH3c+8333nnfn3vvOGQAoASECYQ6sAEC2UCKO9PdmxsUnMPG9AAZEgAM2AHC4uaLQKL9ogK5AXzYzF3WS8V8LAuD1LYBaAK5bBIQzmX/p/+9DkSsSSwCAwtEAOx4/l4tyIcpZ+RKRTJ9EmZ6SKWMYI2MxmiDKqjJO+8Tmf/p8Yk8Z87KFPNRHlrOIl82TcRfKG/OkfJSREJSL8gT8fJRvoKyfJc0WoPwGZXo2n5MLAIYi0yV8bjrK1ihTxNGRbJTnAkCgpH3FKV+xhF+A5gkAO0e0RCxIS5cwjbkmTBtnZxYzgJ+fxZdILMI53EyOmMdk52SLOMIlAHz6ZlkUUJLVlokW2dHG2dHRwtYSLf/n9Y+bn73+GWS9/eTxMuLPnkGMni/al9gvWk4tAKwptDZbvmgpOwFoWw+A6t0vmv4+AOQLAWjt++p7GLJ5SZdIRC5WVvn5+ZYCPtdSVtDP6386fPb8e/jqPEvZeZ9rx/Thp3KkWRKmrKjcnKwcqZiZK+Jw+UyL/x7ifx34VVpf5WEeyU/li/lC9KgYdMoEwjS03UKeQCLIETIFwr/r8L8M+yoHGX6aaxRodR8BPckSKPTRAfJrD8DQyABJ3IPuQJ/7FkKMAbKbF6s99mnuUUb3/7T/YeAy9BXOFaQxZTI7MprJlYrzZIzeCZnBAhKQB3SgBrSAHjAGFsAWOAFX4Al8QRAIA9EgHiwCXJAOsoEY5IPlYA0oAiVgC9gOqsFeUAcaQBM4BtrASXAOXARXwTVwE9wDQ2AUPAOT4DWYgSAID1EhGqQGaUMGkBlkC7Egd8gXCoEioXgoGUqDhJAUWg6tg0qgcqga2g81QN9DJ6Bz0GWoH7oDDUPj0O/QOxiBKTAd1oQNYSuYBXvBwXA0vBBOgxfDS+FCeDNcBdfCR+BW+Bx8Fb4JD8HP4CkEIGSEgeggFggLYSNhSAKSioiRlUgxUonUIk1IB9KNXEeGkAnkLQaHoWGYGAuMKyYAMx/DxSzGrMSUYqoxhzCtmC7MdcwwZhLzEUvFamDNsC7YQGwcNg2bjy3CVmLrsS3YC9ib2FHsaxwOx8AZ4ZxwAbh4XAZuGa4UtxvXjDuL68eN4KbweLwa3gzvhg/Dc/ASfBF+J/4I/gx+AD+Kf0MgE7QJtgQ/QgJBSFhLqCQcJpwmDBDGCDNEBaIB0YUYRuQRlxDLiHXEDmIfcZQ4Q1IkGZHcSNGkDNIaUhWpiXSBdJ/0kkwm65KdyRFkAXk1uYp8lHyJPEx+S1GimFLYlESKlLKZcpBylnKH8pJKpRpSPakJVAl1M7WBep76kPpGjiZnKRcox5NbJVcj1yo3IPdcnihvIO8lv0h+qXyl/HH5PvkJBaKCoQJbgaOwUqFG4YTCoMKUIk3RRjFMMVuxVPGw4mXFJ0p4JUMlXyWeUqHSAaXzSiM0hKZHY9O4tHW0OtoF2igdRzeiB9Iz6CX07+i99EllJWV75RjlAuUa5VPKQwyEYcgIZGQxyhjHGLcY71Q0VbxU+CqbVJpUBlSmVeeoeqryVYtVm1Vvqr5TY6r5qmWqbVVrU3ugjlE3VY9Qz1ffo35BfWIOfY7rHO6c4jnH5tzVgDVMNSI1lmkc0OjRmNLU0vTXFGnu1DyvOaHF0PLUytCq0DqtNa5N03bXFmhXaJ/RfspUZnoxs5hVzC7mpI6GToCOVGe/Tq/OjK6R7nzdtbrNug/0SHosvVS9Cr1OvUl9bf1Q/eX6jfp3DYgGLIN0gx0G3QbThkaGsYYbDNsMnxipGgUaLTVqNLpvTDX2MF5sXGt8wwRnwjLJNNltcs0UNnUwTTetMe0zg80czQRmu836zbHmzuZC81rzQQuKhZdFnkWjxbAlwzLEcq1lm+VzK32rBKutVt1WH60drLOs66zv2SjZBNmstemw+d3W1JZrW2N7w45q52e3yq7d7oW9mT3ffo/9bQeaQ6jDBodOhw+OTo5ixybHcSd9p2SnXU6DLDornFXKuuSMdfZ2XuV80vmti6OLxOWYy2+uFq6Zroddn8w1msufWzd3xE3XjeO2323Ineme7L7PfchDx4PjUevxyFPPk+dZ7znmZeKV4XXE67m3tbfYu8V7mu3CXsE+64P4+PsU+/T6KvnO9632fein65fm1+g36e/gv8z/bAA2IDhga8BgoGYgN7AhcDLIKWhFUFcwJTgquDr4UYhpiDikIxQODQrdFnp/nsE84by2MBAWGLYt7EG4Ufji8B8jcBHhETURjyNtIpdHdkfRopKiDke9jvaOLou+N994vnR+Z4x8TGJMQ8x0rE9seexQnFXcirir8erxgvj2BHxCTEJ9wtQC3wXbF4wmOiQWJd5aaLSwYOHlReqLshadSpJP4iQdT8YmxyYfTn7PCePUcqZSAlN2pUxy2dwd3Gc8T14Fb5zvxi/nj6W6pZanPklzS9uWNp7ukV6ZPiFgC6oFLzICMvZmTGeGZR7MnM2KzWrOJmQnZ58QKgkzhV05WjkFOf0iM1GRaGixy+LtiyfFweL6XCh3YW67hI7+TPVIjaXrpcN57nk1eW/yY/KPFygWCAt6lpgu2bRkbKnf0m+XYZZxl3Uu11m+ZvnwCq8V+1dCK1NWdq7SW1W4anS1/+pDa0hrMtf8tNZ6bfnaV+ti13UUahauLhxZ77++sUiuSFw0uMF1w96NmI2Cjb2b7Dbt3PSxmFd8pcS6pLLkfSm39Mo3Nt9UfTO7OXVzb5lj2Z4tuC3CLbe2emw9VK5YvrR8ZFvottYKZkVxxavtSdsvV9pX7t1B2iHdMVQVUtW+U3/nlp3vq9Orb9Z41zTv0ti1adf0bt7ugT2ee5r2au4t2ftun2Df7f3++1trDWsrD+AO5B14XBdT1/0t69uGevX6kvoPB4UHhw5FHupqcGpoOKxxuKwRbpQ2jh9JPHLtO5/v2pssmvY3M5pLjoKj0qNPv0/+/tax4GOdx1nHm34w+GFXC62luBVqXdI62ZbeNtQe395/IuhEZ4drR8uPlj8ePKlzsuaU8qmy06TThadnzyw9M3VWdHbiXNq5kc6kznvn487f6Iro6r0QfOHSRb+L57u9us9ccrt08rLL5RNXWFfarjpebe1x6Gn5yeGnll7H3tY+p772a87XOvrn9p8e8Bg4d93n+sUbgTeu3px3s//W/Fu3BxMHh27zbj+5k3Xnxd28uzP3Vt/H3i9+oPCg8qHGw9qfTX5uHnIcOjXsM9zzKOrRvRHuyLNfcn95P1r4mPq4ckx7rOGJ7ZOT437j154ueDr6TPRsZqLoV8Vfdz03fv7Db56/9UzGTY6+EL+Y/b30pdrLg6/sX3VOhU89fJ39ema6+I3am0NvWW+738W+G5vJf49/X/XB5EPHx+CP92ezZ2f/AAOY8/xJsCmYAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAfklEQVQ4EaWTwQnAIAxFU3AYnclVHNQtFPTgrcWC8JNL2sSL+fjz1BiJnOM6+THG+8R/5oDmUgpKyjkzLUVKiRhgrSU9qmaAOaeaIA0MMMaQ66pmgN67miANAatvAiCxtYbyUxxqrW8v7JOYALiN+wpugPsZLY3k/kxYQ1P8AA+YKsRd6CkwAAAAAElFTkSuQmCC"></img>
|
|
363
|
-
|
|
360
|
+
Datapoint
|
|
364
361
|
</label>
|
|
365
|
-
<select
|
|
362
|
+
<select id="node-input-dpt"></select>
|
|
366
363
|
<span id="sampleCodeEditor" style="color:red;" />
|
|
367
|
-
|
|
368
364
|
</div>
|
|
369
365
|
</div>
|
|
370
366
|
<div class="form-row">
|
|
@@ -395,45 +391,30 @@
|
|
|
395
391
|
|
|
396
392
|
<div id="tabs">
|
|
397
393
|
<ul>
|
|
398
|
-
<li><a href="#tabs-1"><i class="fa fa-
|
|
399
|
-
<li><a href="#tabs-2"><i class="fa fa-
|
|
400
|
-
<li><a href="#tabs-3"><i class="fa fa-
|
|
394
|
+
<li><a href="#tabs-1"><i class="fa fa-braille"></i> Advanced options</a></li>
|
|
395
|
+
<li><a href="#tabs-2"><i class="fa fa-list-ol"></i> Format input</a></li>
|
|
396
|
+
<li><a href="#tabs-3"><i class="fa fa-code"></i> Payload Sample</a></li>
|
|
401
397
|
</ul>
|
|
402
398
|
<div id="tabs-1">
|
|
403
|
-
<p>
|
|
404
|
-
<div style="height:200px;min-height:150px;padding:0px;">
|
|
405
|
-
<div style="height:100%;width:100%;padding:0px;" class="node-text-editor" id="example-editor"></div>
|
|
406
|
-
</div>
|
|
407
|
-
</p>
|
|
408
|
-
</div>
|
|
409
|
-
|
|
410
|
-
<div id="tabs-2">
|
|
411
|
-
<p>
|
|
412
|
-
|
|
413
|
-
|
|
414
399
|
<div class="form-row" style="padding:10px">
|
|
415
400
|
<div class="form-row">
|
|
416
|
-
<label style="width:
|
|
417
|
-
<i class="fa fa-long-arrow-right"></i>
|
|
418
|
-
<span data-i18n="knxUltimate.properties.node-input-passthrough"></span>
|
|
401
|
+
<label style="width:180px" for="node-input-passthrough">
|
|
402
|
+
<i class="fa fa-long-arrow-right"></i> Msg passthrough
|
|
419
403
|
</label>
|
|
420
|
-
<select
|
|
404
|
+
<select id="node-input-passthrough">
|
|
421
405
|
<option value="no" data-i18n="knxUltimate.selectlists.passthrough_No"></option>
|
|
422
406
|
<option value="yes" data-i18n="knxUltimate.selectlists.passthrough_Leave"></option>
|
|
423
407
|
<option value="yesownprop" data-i18n="knxUltimate.selectlists.passthrough_OwnProp"></option>
|
|
424
408
|
</select>
|
|
425
409
|
</div>
|
|
426
|
-
<br />
|
|
427
410
|
<div class="form-row">
|
|
428
411
|
<dt>
|
|
429
|
-
<i class="fa fa-arrow-right"></i
|
|
430
|
-
<span data-i18n="knxUltimate.advanced.OUTPUT"></span>
|
|
412
|
+
<i class="fa fa-arrow-right"></i> CONTROL (payload to KNX bus)
|
|
431
413
|
</dt>
|
|
432
414
|
</div>
|
|
433
415
|
<div class="form-row">
|
|
434
|
-
|
|
435
|
-
<i class="fa fa-paper-plane-o"></i>
|
|
436
|
-
<span data-i18n="knxUltimate.properties.node-input-outputtype"></span>
|
|
416
|
+
<label style="width:180px" for="node-input-outputtype">
|
|
417
|
+
<i class="fa fa-paper-plane-o"></i> Telegram type
|
|
437
418
|
</label>
|
|
438
419
|
<select id="node-input-outputtype">
|
|
439
420
|
<option value="write" data-i18n="knxUltimate.selectlists.Output_write"></option>
|
|
@@ -443,25 +424,23 @@
|
|
|
443
424
|
</select>
|
|
444
425
|
</div>
|
|
445
426
|
<div class="form-row" id="divOutputRBE">
|
|
446
|
-
|
|
427
|
+
<input type="checkbox" id="node-input-outputRBE"
|
|
447
428
|
style="display:inline-block; width:auto; vertical-align:top;" />
|
|
448
429
|
<label style="width:85%" for="node-input-outputRBE">
|
|
449
|
-
<i class="fa fa-filter"></i>
|
|
450
|
-
<span data-i18n="knxUltimate.properties.node-input-outputRBE"></span>
|
|
430
|
+
<i class="fa fa-filter"></i> Send payload to KNX only if changed (RBE filter)
|
|
451
431
|
</label>
|
|
452
432
|
</div>
|
|
453
433
|
<br />
|
|
454
434
|
<div class="form-row">
|
|
455
435
|
<dt>
|
|
456
|
-
|<i class="fa fa-arrow-right"></i>
|
|
457
|
-
<span data-i18n="knxUltimate.advanced.INPUT"></span>
|
|
436
|
+
|<i class="fa fa-arrow-right"></i> STATUS (payload from KNX BUS)
|
|
458
437
|
</dt>
|
|
459
438
|
</div>
|
|
460
439
|
<div class="form-row" id="divNode-input-initialread">
|
|
461
|
-
|
|
462
|
-
<i class="fa fa-question-circle-o"></i> Read status
|
|
440
|
+
<label style="width:180px" for="node-input-initialread">
|
|
441
|
+
<i class="fa fa-question-circle-o"></i> Read status on start
|
|
463
442
|
</label>
|
|
464
|
-
<select
|
|
443
|
+
<select id="node-input-initialread">
|
|
465
444
|
<option value=0 data-i18n="knxUltimate.properties.node-input-initialread0"></option>
|
|
466
445
|
<option value=1 data-i18n="knxUltimate.properties.node-input-initialread1"></option>
|
|
467
446
|
<option value=2 data-i18n="knxUltimate.properties.node-input-initialread2"></option>
|
|
@@ -470,42 +449,38 @@
|
|
|
470
449
|
|
|
471
450
|
</div>
|
|
472
451
|
<div class="form-row" id="divInputRBE">
|
|
473
|
-
|
|
452
|
+
<input type="checkbox" id="node-input-inputRBE"
|
|
474
453
|
style="display:inline-block; width:auto; vertical-align:top;" />
|
|
475
454
|
<label style="width:85%" for="node-input-inputRBE">
|
|
476
|
-
<i class="fa fa-filter"></i>
|
|
477
|
-
<span data-i18n="knxUltimate.properties.node-input-inputRBE"></span>
|
|
455
|
+
<i class="fa fa-filter"></i> React only by changed payload (RBE filter)
|
|
478
456
|
</label>
|
|
479
457
|
</div>
|
|
480
458
|
<div class="form-row">
|
|
481
|
-
|
|
459
|
+
<input type="checkbox" id="node-input-notifywrite"
|
|
482
460
|
style="display:inline-block; width:auto; vertical-align:top;" />
|
|
483
461
|
<label style="width:85%" for="node-input-notifywrite">
|
|
484
|
-
<i class="fa fa-sign-in"></i>
|
|
485
|
-
<span data-i18n="knxUltimate.properties.node-input-notifywrite"></span>
|
|
462
|
+
<i class="fa fa-sign-in"></i> React to write telegrams
|
|
486
463
|
</label>
|
|
487
464
|
</div>
|
|
488
465
|
<div class="form-row">
|
|
489
|
-
|
|
466
|
+
<input type="checkbox" id="node-input-notifyresponse"
|
|
490
467
|
style="display:inline-block; width:auto; vertical-align:top;" />
|
|
491
468
|
<label style="width:85%" for="node-input-notifyresponse">
|
|
492
|
-
<i class="fa fa-sign-in"></i>
|
|
493
|
-
<span data-i18n="knxUltimate.properties.node-input-notifyresponse"></span>
|
|
469
|
+
<i class="fa fa-sign-in"></i> React to response telegrams
|
|
494
470
|
</label>
|
|
495
471
|
</div>
|
|
496
472
|
<div class="form-row">
|
|
497
|
-
|
|
473
|
+
<input type="checkbox" id="node-input-notifyreadrequest"
|
|
498
474
|
style="display:inline-block; width:auto; vertical-align:top;" />
|
|
499
475
|
<label style="width:85%" for="node-input-notifyreadrequest">
|
|
500
|
-
<i class="fa fa-sign-in"></i>
|
|
501
|
-
<span data-i18n="knxUltimate.properties.node-input-notifyreadrequest"></span>
|
|
476
|
+
<i class="fa fa-sign-in"></i> React to read telegrams
|
|
502
477
|
</label>
|
|
503
478
|
</div>
|
|
504
479
|
|
|
505
480
|
<div id="divnotifyreadrequestautoreact">
|
|
506
481
|
<dd>
|
|
507
482
|
<div class="form-row">
|
|
508
|
-
|
|
483
|
+
<input type="checkbox" id="node-input-notifyreadrequestalsorespondtobus"
|
|
509
484
|
style="display:inline-block; width:auto; vertical-align:top;" />
|
|
510
485
|
<label style="width:85%" for="node-input-notifyreadrequestalsorespondtobus">
|
|
511
486
|
<span
|
|
@@ -513,7 +488,7 @@
|
|
|
513
488
|
</label>
|
|
514
489
|
</div>
|
|
515
490
|
<div class="form-row">
|
|
516
|
-
 
|
|
491
|
+
<label style="width:auto">
|
|
517
492
|
<span
|
|
518
493
|
data-i18n="knxUltimate.properties.node-input-notifyreadrequestalsorespondtobusdefaultvalueifnotinitialized"></span>
|
|
519
494
|
</label>
|
|
@@ -524,11 +499,9 @@
|
|
|
524
499
|
</dd>
|
|
525
500
|
</div>
|
|
526
501
|
</div>
|
|
527
|
-
|
|
528
|
-
</p>
|
|
529
502
|
</div>
|
|
530
|
-
|
|
531
|
-
|
|
503
|
+
|
|
504
|
+
<div id="tabs-2">
|
|
532
505
|
<div class="form-row" style="padding:10px">
|
|
533
506
|
<div class="form-row">
|
|
534
507
|
<dt>
|
|
@@ -577,7 +550,12 @@
|
|
|
577
550
|
</select>
|
|
578
551
|
</div>
|
|
579
552
|
</div>
|
|
580
|
-
|
|
553
|
+
|
|
554
|
+
</div>
|
|
555
|
+
<div id="tabs-3">
|
|
556
|
+
<div style="height:200px;min-height:150px;padding:0px;">
|
|
557
|
+
<div style="height:100%;width:100%;padding:0px;" class="node-text-editor" id="example-editor"></div>
|
|
558
|
+
</div>
|
|
581
559
|
</div>
|
|
582
560
|
</div>
|
|
583
561
|
|
|
@@ -607,13 +585,13 @@
|
|
|
607
585
|
| Universal mode (listen to all Group Addresses) | By setting this, the node will read and control ALL group addresses. |
|
|
608
586
|
| Sample Function | This will give it a hint on what to write in a function, if you want to control the node via a Node-Red function node. |
|
|
609
587
|
| Input msg passthrough | If set, you can pass the input mgs to the output msg. |
|
|
610
|
-
|
|
|
611
|
-
| Send payload to
|
|
612
|
-
| Read status
|
|
613
|
-
| React only
|
|
614
|
-
| React to
|
|
615
|
-
| React to
|
|
616
|
-
| React to
|
|
588
|
+
| Telegram type | *write* to send write telegram (usually, you want that), otherwise you can choose the telegram's type to react to. |
|
|
589
|
+
| Send payload to KNX only if changed (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. |
|
|
590
|
+
| Read status on start | Read group address status, every time Node-Red starts and at every reconnection to the KNX Gateway. The node stores all group address values to a file, so you can choose wether to read from file or from the KNX bus. |
|
|
591
|
+
| React only by changed payload (RBE filter) | *Report by change* filter. If set, only the msg output (to KNX bus) having different values each time, will be sent to the msg output's flow. If you intend to send everytime the same value, leave it off. |
|
|
592
|
+
| React to write telegrams | The node will react (will send a msg to the flow) each time it receives a *write* telegram from the KNX bus. Usually, you want that. |
|
|
593
|
+
| React to response telegrams | The node will react (will send a msg to the flow) each time it receives a *response* telegram from the KNX bus. Usually, you want that for particular scenarios. |
|
|
594
|
+
| React to read telegrams | The node will react (will send a msg to the flow) each time it receives a *read* telegram from the KNX bus. Usually, you want that if you're want to send a custom value to the KNX BUS. |
|
|
617
595
|
| Format input | Allow you to format numeric values received from the KNX Bus. |
|
|
618
596
|
|
|
619
597
|
<br/>
|
package/nodes/knxUltimate.js
CHANGED
|
@@ -146,7 +146,7 @@ module.exports = function (RED) {
|
|
|
146
146
|
node.inputmessage = RED.util.cloneMessage(msg); // 28/03/2020 Store the message to be passed through.
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
// 25/07/2019 if payload is read or the
|
|
149
|
+
// 25/07/2019 if payload is read or the Telegram type is set to "read", do a read, otherwise, write to the bus
|
|
150
150
|
if ((msg.hasOwnProperty('readstatus') && msg.readstatus === true) || node.outputtype === 'read') {
|
|
151
151
|
// READ: Send a Read request to the bus
|
|
152
152
|
let grpaddr = '';
|
|
@@ -156,7 +156,7 @@ module.exports = function (RED) {
|
|
|
156
156
|
// 29/12/2020 Protection over circular references (for example, if you link two Ultimate Nodes toghether with the same group address), to prevent infinite loops
|
|
157
157
|
if (msg.hasOwnProperty('knx')) {
|
|
158
158
|
if (msg.knx.destination == grpaddr && ((msg.knx.event === 'GroupValue_Response' || msg.knx.event === 'GroupValue_Read'))) {
|
|
159
|
-
if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`knxUltimate: Circular reference protection during READ. The node ${node.id} has been temporary disabled. Two nodes with same group address and reaction/
|
|
159
|
+
if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`knxUltimate: Circular reference protection during READ. The node ${node.id} has been temporary disabled. Two nodes with same group address and reaction/Telegram type are linked. See the FAQ in the Wiki. Msg:${JSON.stringify(msg)}`);
|
|
160
160
|
const t = setTimeout(() => { // 21/03/2022 fixed possible memory leak. Previously was setTimeout without "let t = ".
|
|
161
161
|
node.setNodeStatus({
|
|
162
162
|
fill: 'red', shape: 'ring', text: `DISABLED due to a circulare reference while READ (${grpaddr}).`, payload: '', GA: '', dpt: '', devicename: '',
|
|
@@ -178,7 +178,7 @@ module.exports = function (RED) {
|
|
|
178
178
|
// 29/12/2020 Protection over circular references (for example, if you link two Ultimate Nodes toghether with the same group address), to prevent infinite loops
|
|
179
179
|
if (msg.hasOwnProperty('knx')) {
|
|
180
180
|
if (msg.knx.destination == grpaddr && ((msg.knx.event === 'GroupValue_Response' || msg.knx.event === 'GroupValue_Read'))) {
|
|
181
|
-
if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`knxUltimate: Circular reference protection during READ-2. The node ${node.id} has been temporary disabled. Two nodes with same group address and reaction/
|
|
181
|
+
if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`knxUltimate: Circular reference protection during READ-2. The node ${node.id} has been temporary disabled. Two nodes with same group address and reaction/Telegram type are linked. See the FAQ in the Wiki. Msg:${JSON.stringify(msg)}`);
|
|
182
182
|
const t = setTimeout(() => { // 21/03/2022 fixed possible memory leak. Previously was setTimeout without "let t = ".
|
|
183
183
|
node.setNodeStatus({
|
|
184
184
|
fill: 'red', shape: 'ring', text: `DISABLED due to a circulare reference while READ-2 (${grpaddr}).`, payload: '', GA: '', dpt: '', devicename: '',
|
|
@@ -201,7 +201,7 @@ module.exports = function (RED) {
|
|
|
201
201
|
// 29/12/2020 Protection over circular references (for example, if you link two Ultimate Nodes toghether with the same group address), to prevent infinite loops
|
|
202
202
|
if (msg.hasOwnProperty('knx')) {
|
|
203
203
|
if (msg.knx.destination == grpaddr && ((msg.knx.event === 'GroupValue_Response' || msg.knx.event === 'GroupValue_Read'))) {
|
|
204
|
-
if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`knxUltimate: Circular reference protection during READ-3. Node ${node.id} The read request hasn't been sent. Two nodes with same group address and reaction/
|
|
204
|
+
if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`knxUltimate: Circular reference protection during READ-3. Node ${node.id} The read request hasn't been sent. Two nodes with same group address and reaction/Telegram type are linked. See the FAQ in the Wiki. Msg:${JSON.stringify(msg)}`);
|
|
205
205
|
node.setNodeStatus({
|
|
206
206
|
fill: 'red', shape: 'ring', text: `NOT SENT due to a circulare reference while READ-3 (${grpaddr}).`, payload: '', GA: '', dpt: '', devicename: '',
|
|
207
207
|
});
|
|
@@ -322,7 +322,7 @@ module.exports = function (RED) {
|
|
|
322
322
|
// Protection over circular references (for example, if you link two Ultimate Nodes toghether with the same group address), to prevent infinite loops
|
|
323
323
|
if (msg.hasOwnProperty('knx')) {
|
|
324
324
|
if (msg.knx.destination == grpaddr && ((msg.knx.event === 'GroupValue_Write' && outputtype === 'write') || (msg.knx.event === 'GroupValue_Response' && outputtype === 'response') || (msg.knx.event === 'GroupValue_Response' && outputtype === 'read') || (msg.knx.event === 'GroupValue_Read' && outputtype === 'read'))) {
|
|
325
|
-
if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`knxUltimate: Circular reference protection. The node ${node.id} has been temporarely disabled. Two nodes with same group address and reaction/
|
|
325
|
+
if (node.sysLogger !== undefined && node.sysLogger !== null) node.sysLogger.error(`knxUltimate: Circular reference protection. The node ${node.id} has been temporarely disabled. Two nodes with same group address and reaction/Telegram type are linked. See the FAQ in the Wiki. Msg:${JSON.stringify(msg)}`);
|
|
326
326
|
const t = setTimeout(() => { // 21/03/2022 fixed possible memory leak. Previously was setTimeout without "let t = ".
|
|
327
327
|
node.setNodeStatus({
|
|
328
328
|
fill: 'red', shape: 'ring', text: `DISABLED due to a circulare reference (${grpaddr}).`, payload: '', GA: '', dpt: '', devicename: '',
|
|
@@ -54,233 +54,233 @@ module.exports = function (RED) {
|
|
|
54
54
|
dpt = (typeof dpt === 'undefined' || dpt == '') ? '' : ' DPT' + dpt
|
|
55
55
|
payload = typeof payload === 'object' ? JSON.stringify(payload) : payload
|
|
56
56
|
node.status({ fill, shape, text: GA + payload + (node.listenallga === true ? ' ' + devicename : '') + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ' ' + text })
|
|
57
|
-
|
|
58
|
-
}
|
|
57
|
+
} catch (error) {
|
|
59
58
|
}
|
|
59
|
+
}
|
|
60
60
|
|
|
61
61
|
// Used to call the status update from the config node.
|
|
62
62
|
node.setLocalStatus = ({ fill, shape, text, payload, GA, dpt, devicename }) => {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
63
|
+
const dDate = new Date()
|
|
64
|
+
// 30/08/2019 Display only the things selected in the config
|
|
65
|
+
GA = (typeof GA === 'undefined' || GA == '') ? '' : '(' + GA + ') '
|
|
66
|
+
devicename = devicename || ''
|
|
67
|
+
dpt = (typeof dpt === 'undefined' || dpt == '') ? '' : ' DPT' + dpt
|
|
68
|
+
try {
|
|
69
|
+
node.status({ fill, shape, text: GA + payload + (node.listenallga === true ? ' ' + devicename : '') + ' (' + dDate.getDate() + ', ' + dDate.toLocaleTimeString() + ' ' + text })
|
|
70
|
+
} catch (error) {
|
|
72
71
|
}
|
|
72
|
+
}
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
74
|
+
// This function is called by the knx-ultimate config node, to output a msg.payload.
|
|
75
|
+
node.handleSend = msg => {
|
|
76
|
+
try {
|
|
77
|
+
if (!msg.knx.dpt.startsWith('1.')) return
|
|
78
|
+
} catch (error) {
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
let bFound = false // 24/04/2021 true if the cycle below found a match, otherwise false
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
node.setLocalStatus({ fill: 'red', shape: 'dot', text: 'Alert', payload: '', GA: msg.topic, dpt: '', devicename: rule.devicename })
|
|
97
|
-
} else {
|
|
98
|
-
// Remove the device from the array
|
|
99
|
-
node.alertedDevices = node.alertedDevices.filter(a => a.topic !== msg.topic)
|
|
100
|
-
node.setLocalStatus({ fill: 'green', shape: 'dot', text: 'Restore', payload: '', GA: msg.topic, dpt: '', devicename: rule.devicename })
|
|
83
|
+
// Update the node.rules with the values taken from the file, if any, otherwise leave the default value
|
|
84
|
+
for (let i = 0; i < node.rules.length; i++) {
|
|
85
|
+
// rule is { topic: rowRuleTopic, devicename: rowRuleDeviceName, longdevicename: rowRuleLongDeviceName}
|
|
86
|
+
var rule = node.rules[i]
|
|
87
|
+
if (msg.topic === rule.topic) {
|
|
88
|
+
if (msg.payload == true) {
|
|
89
|
+
bFound = true
|
|
90
|
+
// Add the device to the array of alertedDevices
|
|
91
|
+
const oTrovato = node.alertedDevices.find(a => a.topic === rule.topic)
|
|
92
|
+
if (oTrovato === undefined) {
|
|
93
|
+
node.alertedDevices.unshift({ topic: rule.topic, devicename: rule.devicename, longdevicename: rule.longdevicename }) // Add to the begin of array
|
|
94
|
+
if (node.whentostart === 'ifnewalert') node.send([null, null, node.getThirdPinMSG()])
|
|
101
95
|
}
|
|
96
|
+
node.setLocalStatus({ fill: 'red', shape: 'dot', text: 'Alert', payload: '', GA: msg.topic, dpt: '', devicename: rule.devicename })
|
|
97
|
+
} else {
|
|
98
|
+
// Remove the device from the array
|
|
99
|
+
node.alertedDevices = node.alertedDevices.filter(a => a.topic !== msg.topic)
|
|
100
|
+
node.setLocalStatus({ fill: 'green', shape: 'dot', text: 'Restore', payload: '', GA: msg.topic, dpt: '', devicename: rule.devicename })
|
|
102
101
|
}
|
|
103
102
|
}
|
|
104
|
-
|
|
105
|
-
// If there's some device to alert, stop current timer and restart
|
|
106
|
-
// This allow the last alerted device to be outputted immediately
|
|
107
|
-
if (bFound && node.whentostart === 'ifnewalert' && node.alertedDevices.length > 0) {
|
|
108
|
-
clearTimeout(node.timerSend)
|
|
109
|
-
// Send directly the second and third message PIN
|
|
110
|
-
node.send([null, node.getSecondPinMSG(), null])
|
|
111
|
-
node.curIndexAlertedDevice = 0 // Restart form the beginning
|
|
112
|
-
node.startTimer()
|
|
113
|
-
}
|
|
114
103
|
}
|
|
115
104
|
|
|
116
|
-
//
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
sTopic += item.topic + ', '
|
|
125
|
-
if (item.devicename !== undefined && item.devicename !== '') sRet += item.devicename + ', '
|
|
126
|
-
if (item.longdevicename !== undefined && item.longdevicename !== '') sRetLong += item.longdevicename + ', '
|
|
127
|
-
})
|
|
128
|
-
sTopic = sTopic.slice(0, -2)
|
|
129
|
-
if (sRet.length > 2) sRet = sRet.slice(0, -2)
|
|
130
|
-
if (sRetLong.length > 2) sRetLong = sRetLong.slice(0, -2)
|
|
131
|
-
msg.topic = sTopic
|
|
132
|
-
msg.devicename = sRet
|
|
133
|
-
msg.longdevicename = sRetLong
|
|
134
|
-
msg.count = node.alertedDevices.length
|
|
135
|
-
msg.payload = true
|
|
136
|
-
return msg
|
|
137
|
-
}
|
|
105
|
+
// If there's some device to alert, stop current timer and restart
|
|
106
|
+
// This allow the last alerted device to be outputted immediately
|
|
107
|
+
if (bFound && node.whentostart === 'ifnewalert' && node.alertedDevices.length > 0) {
|
|
108
|
+
clearTimeout(node.timerSend)
|
|
109
|
+
// Send directly the second and third message PIN
|
|
110
|
+
node.send([null, node.getSecondPinMSG(), null])
|
|
111
|
+
node.curIndexAlertedDevice = 0 // Restart form the beginning
|
|
112
|
+
node.startTimer()
|
|
138
113
|
}
|
|
114
|
+
}
|
|
139
115
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
sTopic
|
|
149
|
-
if (item.devicename !== undefined && item.devicename !== '') sRet
|
|
150
|
-
if (item.longdevicename !== undefined && item.longdevicename !== '') sRetLong
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
116
|
+
// Get the msg to be outputted on second PIN
|
|
117
|
+
node.getSecondPinMSG = () => {
|
|
118
|
+
if (node.alertedDevices.length > 0) {
|
|
119
|
+
const msg = {}
|
|
120
|
+
let sRet = ''
|
|
121
|
+
let sRetLong = ''
|
|
122
|
+
let sTopic = ''
|
|
123
|
+
node.alertedDevices.forEach(function (item) {
|
|
124
|
+
sTopic += item.topic + ', '
|
|
125
|
+
if (item.devicename !== undefined && item.devicename !== '') sRet += item.devicename + ', '
|
|
126
|
+
if (item.longdevicename !== undefined && item.longdevicename !== '') sRetLong += item.longdevicename + ', '
|
|
127
|
+
})
|
|
128
|
+
sTopic = sTopic.slice(0, -2)
|
|
129
|
+
if (sRet.length > 2) sRet = sRet.slice(0, -2)
|
|
130
|
+
if (sRetLong.length > 2) sRetLong = sRetLong.slice(0, -2)
|
|
131
|
+
msg.topic = sTopic
|
|
132
|
+
msg.devicename = sRet
|
|
133
|
+
msg.longdevicename = sRetLong
|
|
134
|
+
msg.count = node.alertedDevices.length
|
|
135
|
+
msg.payload = true
|
|
136
|
+
return msg
|
|
158
137
|
}
|
|
138
|
+
}
|
|
159
139
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
}
|
|
178
|
-
} else {
|
|
179
|
-
node.setLocalStatus({ fill: 'red', shape: 'ring', text: 'No gateway selected. Unable to read from KNX bus', payload: '', GA: '', dpt: '', devicename: '' })
|
|
180
|
-
}
|
|
140
|
+
// Get the msg to be outputted on third PIN
|
|
141
|
+
node.getThirdPinMSG = () => {
|
|
142
|
+
if (node.alertedDevices.length > 0) {
|
|
143
|
+
const msg = {}
|
|
144
|
+
let sRet = ''
|
|
145
|
+
let sRetLong = ''
|
|
146
|
+
let sTopic = ''
|
|
147
|
+
const item = node.alertedDevices[0] // Pick the last alerted device
|
|
148
|
+
sTopic = item.topic
|
|
149
|
+
if (item.devicename !== undefined && item.devicename !== '') sRet = item.devicename
|
|
150
|
+
if (item.longdevicename !== undefined && item.longdevicename !== '') sRetLong = item.longdevicename
|
|
151
|
+
msg.topic = sTopic
|
|
152
|
+
msg.devicename = sRet
|
|
153
|
+
msg.longdevicename = sRetLong
|
|
154
|
+
msg.count = node.alertedDevices.length
|
|
155
|
+
msg.payload = true
|
|
156
|
+
return msg
|
|
181
157
|
}
|
|
158
|
+
}
|
|
182
159
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
160
|
+
// 24/04/2021 perform a read on all GA in the rule list. Called both from node.on("input") and knxUltimate-config
|
|
161
|
+
node.initialReadAllDevicesInRules = () => {
|
|
162
|
+
if (node.server) {
|
|
163
|
+
let grpaddr = ''
|
|
164
|
+
for (let i = 0; i < node.rules.length; i++) {
|
|
165
|
+
// rule is { topic: rowRuleTopic, devicename: rowRuleDeviceName, longdevicename: rowRuleLongDeviceName}
|
|
166
|
+
const rule = node.rules[i]
|
|
167
|
+
// READ: Send a Read request to the bus
|
|
168
|
+
grpaddr = rule.topic
|
|
169
|
+
try {
|
|
170
|
+
// Check if it's a group address
|
|
171
|
+
// const ret = Address.KNXAddress.createFromString(grpaddr, Address.KNXAddress.TYPE_GROUP)
|
|
172
|
+
node.setLocalStatus({ fill: 'grey', shape: 'dot', text: 'Read', payload: '', GA: grpaddr, dpt: '', devicename: rule.devicename })
|
|
173
|
+
node.server.writeQueueAdd({ grpaddr, payload: '', dpt: '', outputtype: 'read', nodecallerid: node.id })
|
|
174
|
+
} catch (error) {
|
|
175
|
+
node.setLocalStatus({ fill: 'grey', shape: 'dot', text: 'Not a KNX GA ' + error.message, payload: '', GA: grpaddr, dpt: '', devicename: rule.devicename })
|
|
194
176
|
}
|
|
195
|
-
return
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
// 24/04/2021 if payload is read or the output type is set to "read", do a read
|
|
199
|
-
if ((msg.hasOwnProperty('readstatus') && msg.readstatus === true)) {
|
|
200
|
-
node.initialReadAllDevicesInRules()
|
|
201
|
-
return
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
if (msg.topic === undefined) {
|
|
205
|
-
node.setLocalStatus({ fill: 'grey', shape: 'dot', text: 'ERROR: You must provide a msg.topic', payload: '', GA: '', dpt: '', devicename: '' })
|
|
206
|
-
return
|
|
207
177
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
msg.knx = { dpt: '1.001' }
|
|
213
|
-
node.handleSend(msg)
|
|
214
|
-
})
|
|
178
|
+
} else {
|
|
179
|
+
node.setLocalStatus({ fill: 'red', shape: 'ring', text: 'No gateway selected. Unable to read from KNX bus', payload: '', GA: '', dpt: '', devicename: '' })
|
|
180
|
+
}
|
|
181
|
+
}
|
|
215
182
|
|
|
216
|
-
|
|
183
|
+
node.on('input', function (msg) {
|
|
184
|
+
if (typeof msg === 'undefined') return
|
|
185
|
+
if (msg.hasOwnProperty('start')) {
|
|
217
186
|
clearTimeout(node.timerSend)
|
|
218
|
-
|
|
219
|
-
node.server.removeClient(node)
|
|
220
|
-
}
|
|
221
|
-
done()
|
|
222
|
-
})
|
|
223
|
-
|
|
224
|
-
node.handleTimer = () => {
|
|
187
|
+
node.curIndexAlertedDevice = 0 // Restart form the beginning
|
|
225
188
|
if (node.alertedDevices.length > 0) {
|
|
226
|
-
|
|
227
|
-
if (node.curIndexAlertedDevice > count - 1) {
|
|
228
|
-
node.curIndexAlertedDevice = 0
|
|
229
|
-
if (node.whentostart === 'manualstart') {
|
|
230
|
-
node.curIndexAlertedDevice = 0 // Restart form the beginning
|
|
231
|
-
return
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
// Create output message
|
|
235
|
-
try {
|
|
236
|
-
const curDev = node.alertedDevices[node.curIndexAlertedDevice] // is { topic: rule.topic, devicename: rule.devicename }
|
|
237
|
-
const msg = {}
|
|
238
|
-
msg.topic = curDev.topic
|
|
239
|
-
msg.count = count
|
|
240
|
-
msg.devicename = curDev.devicename
|
|
241
|
-
msg.longdevicename = curDev.longdevicename
|
|
242
|
-
msg.payload = true
|
|
243
|
-
node.send([msg, null, null])
|
|
244
|
-
} catch (error) {
|
|
245
|
-
}
|
|
246
|
-
node.curIndexAlertedDevice += 1
|
|
247
|
-
// Restart timer
|
|
189
|
+
node.send([null, node.getSecondPinMSG(), node.getThirdPinMSG()])
|
|
248
190
|
node.startTimer()
|
|
249
191
|
} else {
|
|
250
192
|
// Nothing more to output
|
|
251
193
|
node.sendNoMoreDevices()
|
|
252
194
|
}
|
|
195
|
+
return
|
|
253
196
|
}
|
|
254
197
|
|
|
255
|
-
//
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
node.handleTimer()
|
|
260
|
-
}, node.timerinterval * 1000)
|
|
198
|
+
// 24/04/2021 if payload is read or the Telegram type is set to "read", do a read
|
|
199
|
+
if ((msg.hasOwnProperty('readstatus') && msg.readstatus === true)) {
|
|
200
|
+
node.initialReadAllDevicesInRules()
|
|
201
|
+
return
|
|
261
202
|
}
|
|
262
203
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
msg.topic = ''
|
|
267
|
-
msg.count = 0
|
|
268
|
-
msg.devicename = ''
|
|
269
|
-
msg.longdevicename = ''
|
|
270
|
-
msg.payload = false
|
|
271
|
-
node.send([msg, msg, msg])
|
|
204
|
+
if (msg.topic === undefined) {
|
|
205
|
+
node.setLocalStatus({ fill: 'grey', shape: 'dot', text: 'ERROR: You must provide a msg.topic', payload: '', GA: '', dpt: '', devicename: '' })
|
|
206
|
+
return
|
|
272
207
|
}
|
|
208
|
+
if (msg.payload === undefined) {
|
|
209
|
+
node.setLocalStatus({ fill: 'grey', shape: 'dot', text: 'ERROR: You must provide payload (true/false)', payload: '', GA: '', dpt: '', devicename: '' })
|
|
210
|
+
return
|
|
211
|
+
}
|
|
212
|
+
msg.knx = { dpt: '1.001' }
|
|
213
|
+
node.handleSend(msg)
|
|
214
|
+
})
|
|
273
215
|
|
|
274
|
-
|
|
275
|
-
node.
|
|
276
|
-
|
|
277
|
-
// On each deploy, unsubscribe+resubscribe
|
|
216
|
+
node.on('close', function (done) {
|
|
217
|
+
clearTimeout(node.timerSend)
|
|
278
218
|
if (node.server) {
|
|
279
219
|
node.server.removeClient(node)
|
|
280
|
-
|
|
281
|
-
|
|
220
|
+
}
|
|
221
|
+
done()
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
node.handleTimer = () => {
|
|
225
|
+
if (node.alertedDevices.length > 0) {
|
|
226
|
+
const count = node.alertedDevices.length
|
|
227
|
+
if (node.curIndexAlertedDevice > count - 1) {
|
|
228
|
+
node.curIndexAlertedDevice = 0
|
|
229
|
+
if (node.whentostart === 'manualstart') {
|
|
230
|
+
node.curIndexAlertedDevice = 0 // Restart form the beginning
|
|
231
|
+
return
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
// Create output message
|
|
235
|
+
try {
|
|
236
|
+
const curDev = node.alertedDevices[node.curIndexAlertedDevice] // is { topic: rule.topic, devicename: rule.devicename }
|
|
237
|
+
const msg = {}
|
|
238
|
+
msg.topic = curDev.topic
|
|
239
|
+
msg.count = count
|
|
240
|
+
msg.devicename = curDev.devicename
|
|
241
|
+
msg.longdevicename = curDev.longdevicename
|
|
242
|
+
msg.payload = true
|
|
243
|
+
node.send([msg, null, null])
|
|
244
|
+
} catch (error) {
|
|
282
245
|
}
|
|
246
|
+
node.curIndexAlertedDevice += 1
|
|
247
|
+
// Restart timer
|
|
248
|
+
node.startTimer()
|
|
249
|
+
} else {
|
|
250
|
+
// Nothing more to output
|
|
251
|
+
node.sendNoMoreDevices()
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Start timer
|
|
256
|
+
node.startTimer = () => {
|
|
257
|
+
clearTimeout(node.timerSend)
|
|
258
|
+
node.timerSend = setTimeout(() => {
|
|
259
|
+
node.handleTimer()
|
|
260
|
+
}, node.timerinterval * 1000)
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// As soon as there no more devices..
|
|
264
|
+
node.sendNoMoreDevices = () => {
|
|
265
|
+
const msg = {}
|
|
266
|
+
msg.topic = ''
|
|
267
|
+
msg.count = 0
|
|
268
|
+
msg.devicename = ''
|
|
269
|
+
msg.longdevicename = ''
|
|
270
|
+
msg.payload = false
|
|
271
|
+
node.send([msg, msg, msg])
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Init
|
|
275
|
+
node.sendNoMoreDevices()
|
|
276
|
+
|
|
277
|
+
// On each deploy, unsubscribe+resubscribe
|
|
278
|
+
if (node.server) {
|
|
279
|
+
node.server.removeClient(node)
|
|
280
|
+
if (node.topic !== '' || node.topicSave !== '') {
|
|
281
|
+
node.server.addClient(node)
|
|
283
282
|
}
|
|
284
283
|
}
|
|
285
|
-
RED.nodes.registerType('knxUltimateAlerter', knxUltimateAlerter)
|
|
286
284
|
}
|
|
285
|
+
RED.nodes.registerType('knxUltimateAlerter', knxUltimateAlerter)
|
|
286
|
+
}
|
|
@@ -22,6 +22,7 @@ module.exports = function (RED) {
|
|
|
22
22
|
node.formatmultiplyvalue = 1;
|
|
23
23
|
node.formatnegativevalue = 'leave';
|
|
24
24
|
node.formatdecimalsvalue = 2;
|
|
25
|
+
node.hueDevice = config.hueDevice;
|
|
25
26
|
|
|
26
27
|
// Used to call the status update from the config node.
|
|
27
28
|
node.setNodeStatus = ({
|
|
@@ -83,11 +84,7 @@ module.exports = function (RED) {
|
|
|
83
84
|
}
|
|
84
85
|
if (node.serverHue) {
|
|
85
86
|
node.serverHue.removeClient(node);
|
|
86
|
-
|
|
87
|
-
// I queue the state request, by passing the callback to call whenever the HUE bridge send me the light status async
|
|
88
|
-
if (node.serverHue !== null && node.serverHue.hueManager !== null) {
|
|
89
|
-
node.serverHue.addClient(node);
|
|
90
|
-
}
|
|
87
|
+
node.serverHue.addClient(node);
|
|
91
88
|
}
|
|
92
89
|
|
|
93
90
|
node.on('input', (msg) => {
|
|
@@ -26,6 +26,7 @@ module.exports = function (RED) {
|
|
|
26
26
|
node.formatdecimalsvalue = 2;
|
|
27
27
|
node.short_releaseValue = false;
|
|
28
28
|
node.isTimerDimStopRunning = false;
|
|
29
|
+
node.hueDevice = config.hueDevice;
|
|
29
30
|
|
|
30
31
|
// Used to call the status update from the config node.
|
|
31
32
|
node.setNodeStatus = ({
|
|
@@ -58,7 +58,7 @@ module.exports = function (RED) {
|
|
|
58
58
|
node.handleSend = (msg) => {
|
|
59
59
|
if (node.currentHUEDevice === undefined) {
|
|
60
60
|
node.setNodeStatusHue({
|
|
61
|
-
fill: "
|
|
61
|
+
fill: "red",
|
|
62
62
|
shape: "ring",
|
|
63
63
|
text: "Currently not ready.",
|
|
64
64
|
payload: "",
|
|
@@ -621,13 +621,7 @@ module.exports = function (RED) {
|
|
|
621
621
|
}
|
|
622
622
|
if (node.serverHue) {
|
|
623
623
|
node.serverHue.removeClient(node);
|
|
624
|
-
|
|
625
|
-
try {
|
|
626
|
-
node.serverHue.addClient(node);
|
|
627
|
-
} catch (err) {
|
|
628
|
-
RED.log.error(`Errore knxUltimateHueLight node.currentHUEDevice ${err.message}`);
|
|
629
|
-
}
|
|
630
|
-
}
|
|
624
|
+
node.serverHue.addClient(node);
|
|
631
625
|
}
|
|
632
626
|
|
|
633
627
|
node.on("input", (msg) => { });
|
|
@@ -22,6 +22,7 @@ module.exports = function (RED) {
|
|
|
22
22
|
node.formatmultiplyvalue = 1;
|
|
23
23
|
node.formatnegativevalue = 'leave';
|
|
24
24
|
node.formatdecimalsvalue = 2;
|
|
25
|
+
node.hueDevice = config.hueDevice;
|
|
25
26
|
|
|
26
27
|
// Used to call the status update from the config node.
|
|
27
28
|
node.setNodeStatus = ({ fill, shape, text, payload }) => {
|
|
@@ -76,11 +77,7 @@ module.exports = function (RED) {
|
|
|
76
77
|
}
|
|
77
78
|
if (node.serverHue) {
|
|
78
79
|
node.serverHue.removeClient(node);
|
|
79
|
-
|
|
80
|
-
// I queue the state request, by passing the callback to call whenever the HUE bridge send me the light status async
|
|
81
|
-
if (node.serverHue !== null && node.serverHue.hueManager !== null) {
|
|
82
|
-
node.serverHue.addClient(node);
|
|
83
|
-
}
|
|
80
|
+
node.serverHue.addClient(node);
|
|
84
81
|
}
|
|
85
82
|
|
|
86
83
|
node.on('input', function (msg) {
|
|
@@ -22,6 +22,7 @@ module.exports = function (RED) {
|
|
|
22
22
|
node.formatmultiplyvalue = 1;
|
|
23
23
|
node.formatnegativevalue = "leave";
|
|
24
24
|
node.formatdecimalsvalue = 2;
|
|
25
|
+
node.hueDevice = config.hueDevice;
|
|
25
26
|
|
|
26
27
|
// Used to call the status update from the config node.
|
|
27
28
|
node.setNodeStatus = ({ fill, shape, text, payload }) => { };
|
|
@@ -24,6 +24,7 @@ module.exports = function (RED) {
|
|
|
24
24
|
node.formatmultiplyvalue = 1;
|
|
25
25
|
node.formatnegativevalue = 'leave';
|
|
26
26
|
node.formatdecimalsvalue = 2;
|
|
27
|
+
node.hueDevice = config.hueDevice;
|
|
27
28
|
|
|
28
29
|
// Used to call the status update from the config node.
|
|
29
30
|
node.setNodeStatus = ({ fill, shape, text, payload }) => {
|
|
@@ -22,6 +22,7 @@ module.exports = function (RED) {
|
|
|
22
22
|
node.formatmultiplyvalue = 1;
|
|
23
23
|
node.formatnegativevalue = 'leave';
|
|
24
24
|
node.formatdecimalsvalue = 2;
|
|
25
|
+
node.hueDevice = config.hueDevice;
|
|
25
26
|
|
|
26
27
|
// Used to call the status update from the config node.
|
|
27
28
|
node.setNodeStatus = ({
|
|
@@ -84,9 +85,7 @@ module.exports = function (RED) {
|
|
|
84
85
|
}
|
|
85
86
|
if (node.serverHue) {
|
|
86
87
|
node.serverHue.removeClient(node);
|
|
87
|
-
|
|
88
|
-
node.serverHue.addClient(node);
|
|
89
|
-
}
|
|
88
|
+
node.serverHue.addClient(node);
|
|
90
89
|
}
|
|
91
90
|
|
|
92
91
|
node.on('input', (msg) => {
|
|
@@ -334,7 +334,7 @@ module.exports = function (RED) {
|
|
|
334
334
|
node.send({ topic: node.name || node.topic, operation: 'Enabled', payload: node.sheddingStage })
|
|
335
335
|
}
|
|
336
336
|
|
|
337
|
-
// 24/04/2021 if payload is read or the
|
|
337
|
+
// 24/04/2021 if payload is read or the Telegram type is set to "read", do a read
|
|
338
338
|
if ((msg.hasOwnProperty('readstatus') && msg.readstatus === true)) {
|
|
339
339
|
node.initialReadAllDevicesInRules()
|
|
340
340
|
}
|
|
@@ -8,21 +8,21 @@
|
|
|
8
8
|
"node-input-topic": "Group Addr.",
|
|
9
9
|
"node-input-outputtopic": "Topic",
|
|
10
10
|
"node-input-dpt": "Datapoint",
|
|
11
|
-
"node-input-initialread": "Read status
|
|
11
|
+
"node-input-initialread": "Read status on start",
|
|
12
12
|
"node-input-initialread0": "No",
|
|
13
|
-
"node-input-initialread1": "Read from KNX BUS (to receive the response from BUS, enable also -React to
|
|
13
|
+
"node-input-initialread1": "Read from KNX BUS (to receive the response from BUS, enable also -React to response telegrams-)",
|
|
14
14
|
"node-input-initialread2": "Read the last value saved to file prior to disconnection",
|
|
15
|
-
"node-input-initialread3": "Read the last value saved to file prior to disconnection. If the file is missing, read from KNX BUS (to receive the response from BUS, enable also -React to
|
|
16
|
-
"node-input-notifyreadrequest": "React to
|
|
17
|
-
"node-input-notifyresponse": "React to
|
|
18
|
-
"node-input-notifywrite": "React to
|
|
15
|
+
"node-input-initialread3": "Read the last value saved to file prior to disconnection. If the file is missing, read from KNX BUS (to receive the response from BUS, enable also -React to response telegrams-)",
|
|
16
|
+
"node-input-notifyreadrequest": "React to read telegrams",
|
|
17
|
+
"node-input-notifyresponse": "React to response telegrams",
|
|
18
|
+
"node-input-notifywrite": "React to write telegrams",
|
|
19
19
|
"node-input-notifyreadrequestalsorespondtobus": "Auto send node value as response to the BUS",
|
|
20
20
|
"node-input-notifyreadrequestalsorespondtobusdefaultvalueifnotinitialized": "If value is undefined, send",
|
|
21
21
|
"node-input-listenallga": "Universal mode (listen to all Group Addresses)",
|
|
22
22
|
"node-input-name": "Node Name",
|
|
23
|
-
"node-input-outputtype": "
|
|
24
|
-
"node-input-outputRBE": "Send payload to
|
|
25
|
-
"node-input-inputRBE": "React only
|
|
23
|
+
"node-input-outputtype": "Telegram type",
|
|
24
|
+
"node-input-outputRBE": "Send payload to KNX only if changed (RBE filter)",
|
|
25
|
+
"node-input-inputRBE": "React only by changed payload (RBE filter)",
|
|
26
26
|
"node-input-formatmultiplyvalue": "Multiply",
|
|
27
27
|
"node-input-formatnegativevalue": "Negatives",
|
|
28
28
|
"node-input-formatdecimalsvalue": "Decimals",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"Advancedoptions": "Advanced options",
|
|
37
37
|
"Formatting": "Format INPUT (datagram coming from the KNX BUS)",
|
|
38
38
|
"Operations": "NUMERIC VALUES (operations are performed in order)",
|
|
39
|
-
"OUTPUT": "
|
|
40
|
-
"INPUT": "
|
|
39
|
+
"OUTPUT": "CONTROL (payload to KNX bus)",
|
|
40
|
+
"INPUT": "STATUS (payload from KNX BUS)",
|
|
41
41
|
"NUMERICVALUES": "NUMERIC VALUES (operations are performed in order)",
|
|
42
42
|
"noETSWarning": "You haven't imported the ETS csv file. <br/> The node will work as blind transmitter/receiver. <a href=\"https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/2.-Node-Configuration\" target='_blank'>Click here for help about that</a>.",
|
|
43
43
|
"notify-DPT3007": "You selected a relative DIM. Please <a target='_blank' href='https://github.com/Supergiovane/node-red-contrib-knx-ultimate/wiki/-Sample---Dimming'>click here to view this sample</a> and learn how to handle such payload.",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
<table style="font-size:12px">
|
|
12
12
|
<tr>
|
|
13
13
|
<td><img src="https://raw.githubusercontent.com/Supergiovane/node-red-contrib-knx-ultimate/master/img/greendot.png"></img></td>
|
|
14
|
-
<td>React to
|
|
14
|
+
<td>React to write telegrams</td>
|
|
15
15
|
</tr>
|
|
16
16
|
<tr>
|
|
17
17
|
<td><img src="https://raw.githubusercontent.com/Supergiovane/node-red-contrib-knx-ultimate/master/img/greenring.png"></img></td>
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
</tr>
|
|
20
20
|
<tr>
|
|
21
21
|
<td><img src="https://raw.githubusercontent.com/Supergiovane/node-red-contrib-knx-ultimate/master/img/bluedot.png"></img></td>
|
|
22
|
-
<td>React to
|
|
22
|
+
<td>React to response telegrams.</td>
|
|
23
23
|
</tr>
|
|
24
24
|
<tr>
|
|
25
25
|
<td><img src="https://raw.githubusercontent.com/Supergiovane/node-red-contrib-knx-ultimate/master/img/bluering.png"></img></td>
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
</tr>
|
|
28
28
|
<tr>
|
|
29
29
|
<td><img src="https://raw.githubusercontent.com/Supergiovane/node-red-contrib-knx-ultimate/master/img/greudot.png"></img></td>
|
|
30
|
-
<td>React to
|
|
30
|
+
<td>React to read telegrams.</td>
|
|
31
31
|
</tr>
|
|
32
32
|
<tr>
|
|
33
33
|
<td><img src="https://raw.githubusercontent.com/Supergiovane/node-red-contrib-knx-ultimate/master/img/greyring.png"></img></td>
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"engines": {
|
|
4
4
|
"node": ">=16.0.0"
|
|
5
5
|
},
|
|
6
|
-
"version": "2.2.
|
|
6
|
+
"version": "2.2.5",
|
|
7
7
|
"description": "Control your KNX intallation via Node-Red! Single Node KNX IN/OUT with optional ETS group address importer. Easy to use and highly configurable. With integrated Philips HUE devices control.",
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"binary-parser": "2.2.1",
|