UNPKG

node-red-contrib-knx-ultimate

Version:

Control your KNX and KNX Secure 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.

465 lines (407 loc) 23.8 kB
<script type="text/javascript" src="resources/node-red-contrib-knx-ultimate/11f26b4500.js"></script> <script type="text/javascript" src="resources/node-red-contrib-knx-ultimate/htmlUtils.js"></script> <script type="text/javascript"> RED.nodes.registerType('knxUltimateHueButton', { category: "KNX Ultimate", color: '#C0C7E9', defaults: { //buttonState: {value: true}, server: { type: "knxUltimate-config", required: false }, serverHue: { type: "hue-config", required: true }, name: { value: "" }, nameDim: { value: "" }, GArepeat: { value: "" }, dptrepeat: { value: "3.007" }, nameshort_release: { value: "" }, GAshort_release: { value: "" }, dptshort_release: { value: "1.001" }, nameshort_releaseStatus: { value: "" }, GAshort_releaseStatus: { value: "" }, dptshort_releaseStatus: { value: "1.001" }, toggleValues: { value: true }, hueDevice: { value: "" }, switchSend: { value: true }, dimSend: { value: "up" }, }, inputs: 0, outputs: 1, icon: "node-hue-icon.svg", label: function () { return (this.name); }, paletteLabel: "Hue Button", // button: { // enabled: function() { // // return whether or not the button is enabled, based on the current // // configuration of the node // return !this.changed // }, // visible: function() { // // return whether or not the button is visible, based on the current // // configuration of the node // return this.hasButton // }, // //toggle: "buttonState", // onclick: function() {} // }, oneditprepare: function () { // Go to the help panel try { RED.sidebar.show("help"); } catch (error) { } var node = this; var oNodeServer = RED.nodes.node($("#node-input-server").val()); // Store the config-node var oNodeServerHue = RED.nodes.node($("#node-input-serverHue").val()); // Store the config-node // 19/02/2020 Used to get the server sooner als deploy. $("#node-input-server").change(function () { try { oNodeServer = RED.nodes.node($(this).val()); } catch (error) { } }); // 19/02/2020 Used to get the server sooner als deploy. $("#node-input-serverHue").change(function () { try { oNodeServerHue = RED.nodes.node($(this).val()); } catch (error) { } }); $("#node-input-toggleValues").change(function () { if ($("#node-input-toggleValues").is(":checked")) { $("#divFixedValue").hide(); $("#divStatus").show(); } else { $("#divFixedValue").show(); $("#divStatus").hide(); } }); // Testing typedInput how it works $("#node-input-switchSend").typedInput({ type: 'bool', types: ['bool'] }) $("#node-input-dimSend").typedInput({ type: "direction", types: [{ value: "direction", options: [ { value: "up", label: "Up" }, { value: "down", label: "Down" }, { value: "stop", label: "Stop" }, ] }] }) // DPT Dim // ######################## $.getJSON('knxUltimateDpts?serverId=' + $("#node-input-server").val(), (data) => { data.forEach(dpt => { if (dpt.value.startsWith("3.007")) { $("#node-input-dptrepeat").append($("<option></option>") .attr("value", dpt.value) .text(dpt.text)) } }); $("#node-input-dptrepeat").val(this.dptrepeat) }) // Autocomplete suggestion with ETS csv File $("#node-input-GArepeat").autocomplete({ minLength: 0, source: function (request, response) { $.getJSON("knxUltimatecsv?nodeID=" + oNodeServer.id, (data) => { response($.map(data, function (value, key) { var sSearch = (value.ga + " (" + value.devicename + ") DPT" + value.dpt); if (htmlUtilsfullCSVSearch(sSearch, request.term)) { if (value.dpt.startsWith('3.007')) { return { label: value.ga + " # " + value.devicename + " # " + value.dpt, // Label for Display value: value.ga // Value } } else { return null; } } else { return null; } })); }); }, select: function (event, ui) { // Sets Datapoint and device name automatically var sDevName = ui.item.label.split("#")[1].trim(); try { sDevName = sDevName.substr(sDevName.indexOf(")") + 1).trim(); } catch (error) { } $('#node-input-nameDim').val(sDevName); var optVal = $("#node-input-dptrepeat option:contains('" + ui.item.label.split("#")[2].trim() + "')").attr('value'); // Select the option value $("#node-input-dptrepeat").val(optVal); } }).focus(function () { $(this).autocomplete('search', $(this).val() + 'exactmatch'); }); // DPT dptshort_release // ######################## $.getJSON('knxUltimateDpts?serverId=' + $("#node-input-server").val(), (data) => { data.forEach(dpt => { if (dpt.value.startsWith('1.')) { $("#node-input-dptshort_release").append($("<option></option>") .attr("value", dpt.value) .text(dpt.text)) $("#node-input-dptshort_releaseStatus").append($("<option></option>") .attr("value", dpt.value) .text(dpt.text)) } }); $("#node-input-dptshort_release").val(this.dptshort_release) }) // Autocomplete suggestion with ETS csv File $("#node-input-GAshort_release").autocomplete({ minLength: 0, source: function (request, response) { $.getJSON("knxUltimatecsv?nodeID=" + oNodeServer.id, (data) => { response($.map(data, function (value, key) { var sSearch = (value.ga + " (" + value.devicename + ") DPT" + value.dpt); if (htmlUtilsfullCSVSearch(sSearch, request.term + " 1.")) { return { label: value.ga + " # " + value.devicename + " # " + value.dpt, // Label for Display value: value.ga // Value } } else { return null; } })); }); }, select: function (event, ui) { // Sets Datapoint and device name automatically var sDevName = ui.item.label.split("#")[1].trim(); try { sDevName = sDevName.substr(sDevName.indexOf(")") + 1).trim(); } catch (error) { } $('#node-input-nameshort_release').val(sDevName); var optVal = $("#node-input-dptshort_release option:contains('" + ui.item.label.split("#")[2].trim() + "')").attr('value'); // Select the option value $("#node-input-dptshort_release").val(optVal); } }).focus(function () { $(this).autocomplete('search', $(this).val() + 'exactmatch'); }); // Autocomplete suggestion with ETS csv File $("#node-input-GAshort_releaseStatus").autocomplete({ minLength: 0, source: function (request, response) { $.getJSON("knxUltimatecsv?nodeID=" + oNodeServer.id, (data) => { response($.map(data, function (value, key) { var sSearch = (value.ga + " (" + value.devicename + ") DPT" + value.dpt); if (htmlUtilsfullCSVSearch(sSearch, request.term + " 1.")) { return { label: value.ga + " # " + value.devicename + " # " + value.dpt, // Label for Display value: value.ga // Value } } else { return null; } })); }); }, select: function (event, ui) { // Sets Datapoint and device name automatically var sDevName = ui.item.label.split("#")[1].trim(); try { sDevName = sDevName.substr(sDevName.indexOf(")") + 1).trim(); } catch (error) { } $('#node-input-nameshort_releaseStatus').val(sDevName); var optVal = $("#node-input-dptshort_releaseStatus option:contains('" + ui.item.label.split("#")[2].trim() + "')").attr('value'); // Select the option value $("#node-input-dptshort_releaseStatus").val(optVal); } }).focus(function () { $(this).autocomplete('search', $(this).val() + 'exactmatch'); }); // Autocomplete suggestion with ETS csv File $("#node-input-GAdouble_short_release").autocomplete({ minLength: 0, source: function (request, response) { $.getJSON("knxUltimatecsv?nodeID=" + oNodeServer.id, (data) => { response($.map(data, function (value, key) { var sSearch = (value.ga + " (" + value.devicename + ") DPT" + value.dpt); if (htmlUtilsfullCSVSearch(sSearch, request.term + " 1.")) { return { label: value.ga + " # " + value.devicename + " # " + value.dpt, // Label for Display value: value.ga // Value } } else { return null; } })); }); }, select: function (event, ui) { // Sets Datapoint and device name automatically var sDevName = ui.item.label.split("#")[1].trim(); try { sDevName = sDevName.substr(sDevName.indexOf(")") + 1).trim(); } catch (error) { } $('#node-input-namedouble_short_release').val(sDevName); var optVal = $("#node-input-dptdouble_short_release option:contains('" + ui.item.label.split("#")[2].trim() + "')").attr('value'); // Select the option value $("#node-input-dptdouble_short_release").val(optVal); } }).focus(function () { $(this).autocomplete('search', $(this).val() + 'exactmatch'); }); // Autocomplete suggestion with ETS csv File $("#node-input-GAdouble_short_releaseStatus").autocomplete({ minLength: 0, source: function (request, response) { $.getJSON("knxUltimatecsv?nodeID=" + oNodeServer.id, (data) => { response($.map(data, function (value, key) { var sSearch = (value.ga + " (" + value.devicename + ") DPT" + value.dpt); if (htmlUtilsfullCSVSearch(sSearch, request.term + " 1.")) { return { label: value.ga + " # " + value.devicename + " # " + value.dpt, // Label for Display value: value.ga // Value } } else { return null; } })); }); }, select: function (event, ui) { // Sets Datapoint and device name automatically var sDevName = ui.item.label.split("#")[1].trim(); try { sDevName = sDevName.substr(sDevName.indexOf(")") + 1).trim(); } catch (error) { } $('#node-input-namedouble_short_releaseStatus').val(sDevName); var optVal = $("#node-input-dptdouble_short_releaseStatus option:contains('" + ui.item.label.split("#")[2].trim() + "')").attr('value'); // Select the option value $("#node-input-dptdouble_short_releaseStatus").val(optVal); } }).focus(function () { $(this).autocomplete('search', $(this).val() + 'exactmatch'); }); // Autocomplete suggestion with HUE $("#node-input-name").autocomplete({ minLength: 0, source: function (request, response) { $.getJSON("KNXUltimateGetResourcesHUE?rtype=button&serverId=" + oNodeServerHue.id, (data) => { response($.map(data.devices, function (value, key) { //alert(JSON.stringify(value) + " "+ key) var sSearch = (value.name); if (htmlUtilsfullCSVSearch(sSearch, request.term)) { return { hueDevice: value.id, // Label for Display value: value.name // Value } } else { return null; } })); }); }, select: function (event, ui) { // Sets the fields $('#node-input-hueDevice').val(ui.item.hueDevice) } }).focus(function () { $(this).autocomplete('search', $(this).val() + 'exactmatch'); }); // ######################## }, oneditsave: function () { // Return to the info tab try { RED.sidebar.show("info"); } catch (error) { } }, oneditcancel: function () { // Return to the info tab try { RED.sidebar.show("info"); } catch (error) { } } }) </script> <script type="text/html" data-template-name="knxUltimateHueButton"> <div class="form-row"> <b>HUE Button node</b>&nbsp&nbsp<span style="color:red" &nbsp<i class="fa fa-youtube"></i></span>&nbsp<a target="_blank" href="https://youtu.be/jjEUI1J8bkA"><u>Youtube sample</u></a> <br /> <br /> <p align="center"> <i class="fa-regular fa-circle-dot fa-beat-fade fa-4x"></i> </p> <br /> <label for="node-input-server" > <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAKnRFWHRDcmVhdGlvbiBUaW1lAEZyIDYgQXVnIDIwMTAgMjE6NTI6MTkgKzAxMDD84aS8AAAAB3RJTUUH3gYYCicNV+4WIQAAAAlwSFlzAAALEgAACxIB0t1+/AAAAARnQU1BAACxjwv8YQUAAACUSURBVHjaY2CgFZg5c+Z/ZEyWAZ8+f/6/ZsWs/xoamqMGkGrA6Wla/1+fVARjEBuGsSoGmY4eZSCNL59d/g8DIDbIAHR14OgFGQByKjIGKX5+6/T///8gGMQGiV1+/B0Fg70GIkD+RMYgxf/O5/7//2MSmAZhkBi6OrgB6Bg5DGB4ajr3f2xqsYYLSDE2THJUDg0AAAqyDVd4tp4YAAAAAElFTkSuQmCC"></img> KNX GW </label> <input type="text" id="node-input-server" /> </div> <div class="form-row"> <label for="node-input-serverHue"> <img src="data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAEKADAAQAAAABAAAAEAAAAAA0VXHyAAABFUlEQVQ4EZWSsWoCQRCG1yiENEFEi6QSkjqWWoqFoBYJ+Br6JHkMn8Iibd4ihQpaJIhWNkry/ZtdGZY78Qa+m39nZ+dm9s4550awglNBluS/gVtAX6KgDclf68w2OThgfR9iT/jnoEv4TtByDThWTCDKW4SSZTf/zj9/eZbN+izTDuKGimu0vPF8B/YN8aC8LmcOj/AAn9CFTEs70Js/oGqy79C69bqJ5XbQI2kGO5N8QL9D08S8zBtBF5ZaVsznpCMoqJnVdjTpb1Db0fwIWmQV6BLXzFOYgA6/gDVfQN9bBWp2J2hdWDPoBV5FrKnAJutHikk/CHHR8i7x4iG7qQ720IYvu3GFbpHjx3pFrOFYkA354z/5bkK826phyAAAAABJRU5ErkJggg=="/> HUE Bridge </label> <input type="text" id="node-input-serverHue" /> </div> <br/> <p> <b>Philips HUE</b> </p> <div class="form-row"> <label for="node-input-hueDevice" > <i class="fa fa-play-circle"></i>&nbspHue Button</label> <input type="text" id="node-input-name" placeholder="Enter your hue device name" /> <input type="hidden" id="node-input-hueDevice" /> </div> <br/> <p> <b>KNX</b> </p> <div class="form-row"> <label for="node-input-nameshort_release" style="width:100px;"><i class="fa fa-play-circle-o"></i> Switch</label> <label for="node-input-GAhort_release" style="width:20px;"><span data-i18n="common.ga"></span></label> <input type="text" id="node-input-GAshort_release" placeholder="Ex: 1/1/1" style="width:70px;margin-left: 5px; text-align: left;"> <label for="node-input-dptshort_release" style="width:40px; margin-left: 0px; text-align: right;"><span data-i18n="common.dpt"></span></label> <select id="node-input-dptshort_release" style="width:140px;"></select> <label for="node-input-nameshort_release" style="width:50px; margin-left: 0px; text-align: right;"><span data-i18n="common.name"></span></label> <input type="text" id="node-input-nameshort_release" style="width:200px;margin-left: 5px; text-align: left;"> </div> <div class="form-row" id="divStatus"> <label style="width:100px;"><i class="fa fa-question-circle"></i> Switch Status</label> <label for="node-input-GAshort_releaseStatus" style="width:20px;"><span data-i18n="common.ga"></span></label> <input type="text" id="node-input-GAshort_releaseStatus" placeholder="Ex: 1/1/1" style="width:70px;margin-left: 5px; text-align: left;"> <label for="node-input-dptshort_releaseStatus" style="width:40px; margin-left: 0px; text-align: right;"><span data-i18n="common.dpt"></span></label> <select id="node-input-dptshort_releaseStatus" style="width:140px;"></select> <label for="node-input-nameshort_releaseStatus" style="width:50px; margin-left: 0px; text-align: right;"><span data-i18n="common.name"></span></label> <input type="text" id="node-input-nameshort_releaseStatus" style="width:200px;margin-left: 5px; text-align: left;"> <br/> </div> <div class="form-row"> <label style="width:100px;"><i class="fa fa-play-circle-o"></i> Dim</span></label> <label for="node-input-GArepeat" style="width:20px;"><span data-i18n="common.ga"></span></label> <input type="text" id="node-input-GArepeat" placeholder="Ex: 1/1/1" style="width:70px;margin-left: 5px; text-align: left;"> <label for="node-input-dptrepeat" style="width:40px; margin-left: 0px; text-align: right;"><span data-i18n="common.dpt"></span></label> <select id="node-input-dptrepeat" style="width:140px;"></select> <label for="node-input-nameDim" style="width:50px; margin-left: 0px; text-align: right;"><span data-i18n="common.name"></span></label> <input type="text" id="node-input-nameDim" style="width:200px;margin-left: 5px; text-align: left;"> </div> <br/> <div class="form-row"> <input type="checkbox" id="node-input-toggleValues" style="display:inline-block; width:auto; vertical-align:top;" /> <label style="width:auto" for="node-input-toggleValues"> <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAACXBIWXMAAB7CAAAewgFu0HU+AAAFGmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDggNzkuMTY0MDM2LCAyMDE5LzA4LzEzLTAxOjA2OjU3ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjEuMSAoTWFjaW50b3NoKSIgeG1wOkNyZWF0ZURhdGU9IjIwMjAtMDMtMjNUMTY6MjM6MjMrMDE6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDIwLTAzLTIzVDE2OjI1OjM0KzAxOjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIwLTAzLTIzVDE2OjI1OjM0KzAxOjAwIiBkYzpmb3JtYXQ9ImltYWdlL3BuZyIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgcGhvdG9zaG9wOklDQ1Byb2ZpbGU9InNSR0IgSUVDNjE5NjYtMi4xIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOmJmNGM3NWVjLTIwNGYtNGY1YS05YTMxLTQ5NTU5YWJmZDE4NSIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpiZjRjNzVlYy0yMDRmLTRmNWEtOWEzMS00OTU1OWFiZmQxODUiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpiZjRjNzVlYy0yMDRmLTRmNWEtOWEzMS00OTU1OWFiZmQxODUiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOmJmNGM3NWVjLTIwNGYtNGY1YS05YTMxLTQ5NTU5YWJmZDE4NSIgc3RFdnQ6d2hlbj0iMjAyMC0wMy0yM1QxNjoyMzoyMyswMTowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDIxLjEgKE1hY2ludG9zaCkiLz4gPC9yZGY6U2VxPiA8L3htcE1NOkhpc3Rvcnk+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+nhtLUgAAAE9JREFUKJG1UMsOACAIgub//7IdqvVQtjrExU1EEQLuiGCvgTNgl5D74MmVZPu4wIxQAgm+/sDec2VhgQPgf0sq1unjMlYJE/3MZrvy+kMFZQkZEWfC7ikAAAAASUVORK5CYII="></img> Toggle values </label> </div> <div id="divFixedValue" hidden> <div class="form-row" > <label for="node-input-switchSend" style="width:100px;"><i class="fa fa-play-circle-o"></i> Switch send</span></label> <input type="text" id="node-input-switchSend"> </div> <div class="form-row" > <label for="node-input-dimSend" style="width:100px;"><i class="fa fa-play-circle-o"></i> Dim send</span></label> <input type="text" id="node-input-dimSend"> </div> </div> <br/> <br/> </script>