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.

208 lines (186 loc) 9.51 kB
<script type="text/javascript" src="resources/node-red-contrib-knx-ultimate/htmlUtils.js"></script> <script type="text/javascript"> RED.nodes.registerType('knxUltimateWatchDog', { category: "KNX Ultimate", color: '#C7E9C0', defaults: { server: { type: "knxUltimate-config", required: true }, topic: { value: "12/0/0" }, maxRetry: { value: 6 }, // After this number is reached, throw a connection error retryInterval: { value: 10 }, name: { value: "" }, autoStart: { value: true }, checkLevel: { value: "Ethernet" } }, inputs: 1, outputs: 1, outputLabels: ["Output"], icon: "node-watchdog-icon.svg", label: function () { return ((this.name || "KNX Watchdog") + " " + (this.checkLevel == "Ethernet" ? "Gateway IP" : this.topic)); }, paletteLabel: "KNX WatchDog", oneditprepare: function () { const node = this; const $knxServerInput = $("#node-input-server"); const $gaInput = $("#node-input-topic"); const KNX_EMPTY_VALUES = new Set(['', '_ADD_', '__NONE__', 'none']); // Go to the help panel try { RED.sidebar.show("help"); } catch (error) { } $("#advancedOptionsAccordion").accordion({ header: "h3", heightStyle: "content", collapsible: true, active: false }); const KNX_GA_CACHE = node._knxGaCache || (node._knxGaCache = new Map()); const resolveKnxServerValue = () => { const domValue = $knxServerInput.val(); if (domValue !== undefined && domValue !== null && !KNX_EMPTY_VALUES.has(String(domValue))) { return domValue; } if (node.server !== undefined && node.server !== null && !KNX_EMPTY_VALUES.has(String(node.server))) { return node.server; } return ''; }; const fetchGroupAddresses = (serverId) => { if (!serverId) return Promise.resolve([]); if (KNX_GA_CACHE.has(serverId)) return Promise.resolve(KNX_GA_CACHE.get(serverId)); return new Promise((resolve) => { $.getJSON(`knxUltimatecsv?nodeID=${serverId}&_=${Date.now()}`, (data) => { const list = Array.isArray(data) ? data : []; KNX_GA_CACHE.set(serverId, list); resolve(list); }).fail(() => resolve([])); }); }; const ensureGaAutocomplete = () => { const serverId = resolveKnxServerValue(); if (!serverId) { if ($gaInput.data('ui-autocomplete')) { $gaInput.autocomplete('disable'); } return; } const sourceFn = (request, response) => { fetchGroupAddresses(serverId).then((data) => { const items = []; (data || []).forEach((entry) => { const dpt = typeof entry.dpt === 'string' ? entry.dpt : ''; if (!dpt.startsWith('1.')) return; // Watchdog only accepts boolean GAs const devName = entry.devicename || ''; const searchStr = `${entry.ga} (${devName}) DPT${dpt}`; if (!htmlUtilsfullCSVSearch(searchStr, request.term || '')) return; items.push({ label: `${entry.ga} # ${devName} # ${dpt}`, value: entry.ga }); }); response(items); }); }; if ($gaInput.data('knx-watchdog-ga')) { $gaInput.autocomplete('option', 'source', sourceFn); $gaInput.autocomplete('enable'); } else { $gaInput.autocomplete({ minLength: 0, source: sourceFn, select: function (event, ui) { event.preventDefault(); $(this).val(ui.item.value); const parts = ui.item.label.split('#'); let deviceName = (parts[1] || '').trim().replace(/^\)/, '').trim(); if (deviceName.indexOf('/') > -1) { deviceName = deviceName.split('/').pop().trim(); } const $nameInput = $('#node-input-name'); if (deviceName && $nameInput.length) { $nameInput.val(deviceName); } } }).on('focus.knxUltimateWatchDog click.knxUltimateWatchDog', function () { const currentValue = $(this).val() || ''; try { $(this).autocomplete('search', currentValue ? `${currentValue} exactmatch` : ''); } catch (error) { } }); $gaInput.data('knx-watchdog-ga', true); } try { const srv = RED.nodes.node(serverId); if (srv && srv.id) KNX_enableSecureFormatting($gaInput, srv.id); } catch (error) { } }; $knxServerInput.on('change.knxUltimateWatchDog', () => { KNX_GA_CACHE.clear(); ensureGaAutocomplete(); }); ensureGaAutocomplete(); const syncDivHost = () => { const level = $("#node-input-checkLevel").val() || node.checkLevel || "Ethernet"; if (level === "Ethernet") { $("#divHost").hide(); } else { $("#divHost").show(); } }; $("#node-input-checkLevel").on('change', function () { syncDivHost(); }); syncDivHost(); }, oneditsave: function () { // Return to the info tab try { RED.sidebar.show("info"); } catch (error) { } } }) </script> <script type="text/markdown" data-help-name="knxUltimateWatchDog"></script> <script type="text/html" data-template-name="knxUltimateWatchDog"> <div class="form-row"> <b><span data-i18n="knxUltimateWatchDog.title"></span></b> <br/><br/> <label for="node-input-server"><i class="fa fa-tag"></i> <span data-i18n="knxUltimateWatchDog.properties.node-input-server"></span> </label> <input type="text" id="node-input-server"> </div> <div class="form-row"> <label for="node-input-checkLevel"><i class="fa fa-search"></i> <span data-i18n="knxUltimateWatchDog.properties.node-input-checkLevel"></span> </label> <select id="node-input-checkLevel"> <option value="Ethernet" data-i18n="knxUltimateWatchDog.selectlists.Ethernet"></option> <option value="Eth+KNX" data-i18n="knxUltimateWatchDog.selectlists.EthKNX"></option> </select> </div> <div class="form-row" id="divHost"> <label for="node-input-topic"><i class="fa fa-tasks"></i> <span data-i18n="knxUltimateWatchDog.properties.node-input-topic"></span></label> <input style="width:90px;" type="text" id="node-input-topic" data-i18n="[placeholder]knxUltimateWatchDog.placeholder.monitor"> the DPT must be DPT1.x (Boolean) </div> <div class="form-row"> <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="knxUltimateWatchDog.properties.node-input-name"></span> </label> <input type="text" id="node-input-name" data-i18n="[placeholder]knxUltimateWatchDog.properties.node-input-name" style="flex:1 1 240px; min-width:240px; max-width:240px;"> </div> <div class="form-row"> <input type="checkbox" id="node-input-autoStart" style="display:inline-block; width:auto; vertical-align:top;"> <label style="width:auto" for="node-input-autoStart">&nbsp;&nbsp;<i class="fa fa-play-circle"></i> <span data-i18n="knxUltimateWatchDog.properties.node-input-autoStart"></span> </label> </div> <div id="advancedOptionsAccordion"> <h3><span data-i18n="knxUltimateWatchDog.properties.advancedOptionsAccordion"></span></h3> <div> <p> <div class="form-row"> <label for="node-input-retryInterval"><i class="fa fa-clock-o"></i> <span data-i18n="knxUltimateWatchDog.properties.node-input-retryInterval"></span></label> <input type="text" id="node-input-retryInterval"> </div> <div class="form-row"> <label for="node-input-maxRetry"><i class="fa fa-undo"></i> <span data-i18n="knxUltimateWatchDog.properties.node-input-maxRetry"></span></label> <input type="text" id="node-input-maxRetry"> </div> </p> </div> </div> </script>