UNPKG

@metz-connect/node-red-ewio2

Version:

Provides nodes to access EWIO2 interfaces like IOs and metering - from Node-RED

238 lines (231 loc) 13.1 kB
<script type="text/javascript"> /** * Stores IO information of connected EWIO2, that the current value and pulse counter is available if IO port in config menu is changed. * Object is deleted when EWIO2 is changed (changed by selecting another element in dropdown or opening configuration menu). * @memberof digitalInNode */ var digitalIns = {}; /** * Receives an object with all values of an digital IN pin. If it is the currently selected digital IN pin, the settings in digital IN configuration menu are updated. * @memberof digitalInNode */ RED.comms.subscribe("publish/ewio2/config/di/#", function (topic, msg) { const recvPrevIoPort = topic.split("/")[5]; const recvNodeId = topic.split("/")[4]; const ioType = topic.split("/")[3]; // get ewio2 id of disabled select var ewio2Id =$("#node-input-ewio2 option").eq($("#node-input-ewio2").prop("selectedIndex")).val(); // message was received for the currently selected EWIO2 if(ewio2Id == recvNodeId) { // only add options for the choosen type if(msg.ioType == ioType) { // the msg must contain at least 7 elemtens (7 for e.g. setValue response; 8 for livedata (contains also moduleName)) if(Object.keys(msg).length >= 7) { const dropdownValue = JSON.stringify({"nodeId": recvNodeId, "host": msg.host, "addr": msg.address}); if(!optionExists(dropdownValue, "#node-input-ioportDi")) { const moduleName = ((msg.moduleName) && (msg.moduleName != "")) ? " @ " + msg.moduleName : ""; $("#node-input-ioportDi").append($('<option>', { value: dropdownValue, text: msg.name + moduleName })); } // temporarilly store received msgs (only for this EWIO2), to have the current value and pulse counter value and flag digitalIns[dropdownValue] = msg; // set value and pulse counter radio button (true / false) of the choosen and received IO port let selectedIoPort = $('#node-input-ioportDi').val(); log("selected: " + selectedIoPort + "; recvPrevIoPort: " + recvPrevIoPort); if(recvPrevIoPort != "undefined") { const recvPrevIoPortObj = JSON.parse(recvPrevIoPort); const configNode = RED.nodes.node(ewio2Id); if (configNode && recvPrevIoPortObj.nodeId === ewio2Id && recvPrevIoPortObj.host == configNode.host) { selectedIoPort = recvPrevIoPort; } } // set "last" value as selected value in dropdown $('#node-input-ioportDi').val(selectedIoPort); // trigger ioport change, to set correct prevIoPort $('#node-input-ioportDi').trigger("change"); // enable all html elements on valid digital IN values enableHtmlElements(true, "ioportDi"); // enable digital in specific html elements enableDiSpecificElements(true); // enable topic html element enableTopicElement(true); } } } }); /** * Frontend part of digital IN node. * @memberof digitalInNode */ RED.nodes.registerType('EWIO2 - Digital IN', { category: 'METZ CONNECT', color: '#4682B4', defaults: { ewio2: { value: "", type: "EWIO2" }, name: { value: "" }, ioportDi: { value: "", required: true }, value: { value: "" }, valueText: { value: "" }, pulseCntr: { value: "" }, inputSignal: { value: "" }, risingEdge: { value: "" }, fallingEdge: { value: "" }, outputTopic: { value: "" } }, // set pulse counter value input inputs:1, outputs:1, icon: "ewio2-digital-input.svg", label: function() { return this.name||"EWIO2 - Digital IN"; }, oneditprepare: function() { let prevIoPort = this.ioportDi; const nodeId = this.id; const node = this; let prevEwio2Data = getConfigNodeDataStructure(this.ewio2, nodeId); // save the current selected EWIO2, when configuration menu item "ewio2" gets focus. Forward to Node-RED runtime, to be able to publish value again to Node-RED editor. $("#node-input-ewio2").focus(function () { prevEwio2Data = getConfigNodeDataStructure(this.value, nodeId); }) // whenever EWIO2 configuration is changed, async function is called (to "await" for connection) $("#node-input-ewio2").change(async function () { log("onchange ewio2: prev: " + prevEwio2Data.data.configNodeId + "; current: " + this.value); // clear IO-Port dropdown and locally stored data $("#node-input-ioportDi option").remove(); digitalIns = {}; // clear value $("#node-input-value").prop("checked", false); $("#node-input-valueText").val("0"); // clear pulse counter $("#node-input-pulseCntr").prop("checked", false); // clear and hide error msg $('#label-error-status').text(""); $('#section-error-status').hide(); // disable IO port for every selected EWIO2 configuration node enableIoPortElement("ioportDi", false); // disable digital in specific html elements enableDiSpecificElements(false); // disable topic html element enableTopicElement(false); let configNodeId = this.value; if (!configNodeId || configNodeId == "_ADD_") { return; } // disable all html elements only when a valid EWIO2 configuration node is available enableHtmlElements(false, "ioportDi"); try { // one EWIO2 is selected in configuration menu and customer changes to another EWIO2 > close websocket connection of "unselected" EWIO2 if (prevEwio2Data.data.configNodeId != "" && prevEwio2Data.data.configNodeId != "_ADD_") { const selectedEwio2Data = getConfigNodeDataStructure(this.value, nodeId); if (JSON.stringify(prevEwio2Data.data) !== JSON.stringify(selectedEwio2Data.data)) { log(prevEwio2Data.data.configNodeId + " deselected -> close websocket connection"); await closeDeleteWebsocket(prevEwio2Data.data, nodeId); log("close websocket done"); } } // reset prevIoPort, if another EWIO2 is choosen log(prevIoPort + " typeof: " + typeof prevIoPort); if (prevIoPort) { log("prevIoPort-nodeId: " + JSON.parse(prevIoPort).nodeId + "; current EWIO2 id: " + this.value); if (JSON.parse(prevIoPort).nodeId != this.value) { prevIoPort = ""; log("reset prevIoPort to ''"); } } log("prevIoPort to send: " + prevIoPort); await getEwio2ConfigData(getConfigNodeDataStructure(configNodeId, nodeId), "di", prevIoPort, nodeId, undefined); prevEwio2Data = getConfigNodeDataStructure(this.value, nodeId); } catch (error) { log("digital in onchange EWIO2 error"); log(error); } }); $("#node-input-ioportDi").change(async function () { prevIoPort = this.value; log("onchange ioport: " + prevIoPort); // only save value, if a value is choosen. Nothing choosen not possible, due to dropdown if(this.value != "") { // set value and manual mode radio button (true / false) of the newly choosen IO port const receivedValue = digitalIns[this.value].value; $("#node-input-value").prop("checked", (receivedValue === "1") ? true : false ); const receivedPulseCntr = digitalIns[this.value].pulseCntrChecked; $("#node-input-pulseCntr").prop("checked", (receivedPulseCntr === "1") ? true : false ); toggleDiPulseCntrStatusValue(digitalIns[this.value].pulseCntrValue, digitalIns[this.value].pulseCntrChecked, node); } }); }, oneditsave: async function() { log("digital IN: oneditsave"); let configNodeId = $("#node-input-ewio2").val() || this.ewio2; await prepareCloseWebsocket(configNodeId, this.id); }, oneditcancel: async function() { log("digital IN: oneditcancel"); let configNodeId = $("#node-input-ewio2").val() || this.ewio2; await prepareCloseWebsocket(configNodeId, this.id); }, oneditdelete: async function() { log("digital IN: oneditdelete; node-ID: " + this.id); let configNodeId = $("#node-input-ewio2").val() || this.ewio2; await prepareCloseWebsocket(configNodeId, this.id); } }); </script> <script type="text/html" data-template-name="EWIO2 - Digital IN"> <div id="section-error-status" class="form-row" hidden> <label id="label-error-status" style="color:red; width:inherit"><i class="fa fa-warning"></i> Error</label> </div> <div class="form-row"> <label for="node-input-ewio2"><i class="fa fa-microchip"></i> EWIO2</label> <input type="text" id="node-input-ewio2"> </div> <div class="form-row"> <label for="node-input-ioportDi"><i class="fa fa-wrench"></i> <span data-i18n="@metz-connect/node-red-ewio2/ewio2:label.port"></label> <select id="node-input-ioportDi" style="width:70%"></select> </div> <div id="section-value" class="form-row"> <label for="node-input-value"><i class="fa fa-bullseye"></i> <span data-i18n="@metz-connect/node-red-ewio2/ewio2:label.status"></label> <input type="radio" id="node-input-value" disabled style="display: inline-block; width: auto; vertical-align: top;"> </div> <div id="section-valueText" class="form-row" hidden> <label for="node-input-valueText"><i class="fa fa-bullseye"></i> <span data-i18n="@metz-connect/node-red-ewio2/ewio2:label.value"></label> <input type="text" id="node-input-valueText" disabled> </div> <div class="form-row"> <label for="node-input-pulseCntr"><i class="fa fa-arrow-circle-o-up"></i> <span data-i18n="@metz-connect/node-red-ewio2/ewio2:label.pulseCntr"></label> <input type="radio" id="node-input-pulseCntr" disabled style="display: inline-block; width: auto; vertical-align: top;"> </div> <hr> <div class="form-row"> <h4><span data-i18n="@metz-connect/node-red-ewio2/ewio2:label.trigger"></h4> </div> <div class="form-row"> <input type="checkbox" id="node-input-inputSignal" style="display: inline-block; width: auto; vertical-align: top;"> <label for="node-input-inputSignal" style="width: auto" data-i18n="@metz-connect/node-red-ewio2/ewio2:label.inputSignal"></label> </div> <div class="form-row"> <input type="checkbox" id="node-input-risingEdge" style="display: inline-block; width: auto; vertical-align: top;"> <label for="node-input-risingEdge" style="width: auto" id="lbl-risingEdge" data-i18n="@metz-connect/node-red-ewio2/ewio2:label.risingEdge"></label> </div> <div id="section-fallingEdge" class="form-row"> <input type="checkbox" id="node-input-fallingEdge" style="display: inline-block; width: auto; vertical-align: top;"> <label for="node-input-fallingEdge" style="width: auto" data-i18n="@metz-connect/node-red-ewio2/ewio2:label.fallingEdge"></label> </div> <hr> <div class="form-row"> <h4><span data-i18n="@metz-connect/node-red-ewio2/ewio2:label.nodeOutput"></h4> </div> <div class="form-row"> <label for="node-input-outputTopic"><i class="fa fa-map-signs"></i> Topic</label> <input type="text" id="node-input-outputTopic"> </div> <hr> <div class="form-row"> <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="@metz-connect/node-red-ewio2/ewio2:label.name"></label> <input type="text" id="node-input-name"/> </div> </script>