UNPKG

prisme-flow

Version:

prisme platform flow engine

493 lines (444 loc) 15.5 kB
<!-- Created by prisme.io on 09/06/2017. @author <a href="mailto:hello@prisme.io">savane vamara</a> (prisme.io) --> <script type="text/x-red" data-template-name="s7 endpoint"> <div class="form-row"> <ul style="background: #fff; min-width: 600px; margin-bottom: 20px;" id="node-config-s7-endpoint-tabs"></ul> </div> <div id="node-config-s7-endpoint-tabs-content" style="min-height: 170px;"> <div id="s7-endpoint-tab-connection" style="display:none"> <div class="form-row"> <label for="node-config-input-address"><i class="fa fa-globe"></i> <span>IP Address</span></label> <input class="input-append-left" type="text" id="node-config-input-address" style="width: 40%;"> <label for="node-config-input-port" style="margin-left: 10px; width: 35px; "> <span>Port</span></label> <input type="text" id="node-config-input-port" style="width:45px"> </div> <div class="form-row"> <label for="node-config-input-rack"><i class="fa fa-globe"></i> <span>Rack</span></label> <input class="input-append-left" type="text" id="node-config-input-rack" style="width: 40%;"> <label for="node-config-input-slot" style="margin-left: 10px; width: 35px; "> <span>Slot</span></label> <input type="text" id="node-config-input-slot" style="width:45px"> </div> <div class="form-row"> <label for="node-config-input-cycletime"><i class="fa fa-refresh"></i> <span>Cycle time</span></label> <input type="text" id="node-config-input-cycletime" style="width: 60px;"> <span>ms</span> </div> <div class="form-row"> <label for="node-config-input-timeout"><i class="fa fa-clock-o"></i> <span data-i18n="s7.endpoint.label.timeout">Timeout</span></label> <input type="text" id="node-config-input-timeout"style="width: 60px;"> <span>ms</span> </div> <div class="form-row"> <label for="node-config-input-name"><i class="fa fa-tag"></i> <span data-i18n="s7.label.name">s7 in</span></label> <input type="text" id="node-config-input-name"> </div> </div> <div id="s7-endpoint-tab-variables" style="display:none"> <div class="form-row" style="margin-bottom:0;"> <label><i class="fa fa-list"></i> <span>Variable list</span></label> </div> <div class="form-row node-input-variables-container-row" style="margin-bottom: 0px;"> <div id="node-config-input-variables-container-div" style="box-sizing: border-box; border-radius: 5px; height: 300px; padding: 5px; border: 1px solid #ccc; overflow-y:scroll;"> <ol id="node-config-input-variables-container" style=" list-style-type:none; margin: 0;"></ol> </div> </div> <div class="form-row"> <a href="#" class="editor-button editor-button-small" id="node-config-input-add-variable" style="margin-top: 4px;"><i class="fa fa-plus"></i> <span>Add</span></a> </div> <!--<input type="hidden" id="node-config-input-vartable">--> </div> </div> </script> <script type="text/x-red" data-help-name="s7 endpoint"> <p>Represents a PLC connection</p> </script> <script type="text/javascript"> RED.nodes.registerType('s7 endpoint', { category: 'config', defaults: { address: { value: "", validate: RED.validators.regex(/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/) }, port: { value: "102", validate: RED.validators.number() }, rack: { value: "0", validate: RED.validators.number() }, slot: { value: "2", validate: RED.validators.number() }, cycletime: { value: 500 }, timeout: { value: 1500 }, name: { value: "" }, vartable: { value: [{ name: "", addr: "" }] } }, label: function() { return this.name || this.address + ":" + this.port + ":" + this.rack + ":" + this.slot; }, oneditprepare: function() { var self = this; var labelName = this._("Name"); var labelAddr = this._("Address"); var labelDel = this._("Remove"); // Prepare tabs var tabs = RED.tabs.create({ id: "node-config-s7-endpoint-tabs", onchange: function(tab) { $("#node-config-s7-endpoint-tabs-content").children().hide(); $("#" + tab.id).show(); } }); tabs.addTab({ id: "s7-endpoint-tab-connection", label: this._("Connection") }); tabs.addTab({ id: "s7-endpoint-tab-variables", label: this._("Variables") }); setTimeout(function() { tabs.resize() }, 0); function generateVariable(variable) { var container = $('<li/>', { style: "background: #fff; margin:0; padding:8px 0px; border-bottom: 1px solid #ccc;" }); var row1 = $('<div/>').appendTo(container); var variableAddr = $('<input/>', { style: "width: 110px; margin-right: 10px;", class: "node-config-input-variable-addr", type: "text", placeholder: labelAddr }).appendTo(row1); var variableName = $('<input/>', { style: "width: 250px", class: "node-config-input-variable-name", type: "text", placeholder: labelName }).appendTo(row1); var finalspan = $('<span/>', { style: "float: right; margin-right: 10px;" }).appendTo(row1); var deleteButton = $('<a/>', { href: "#", class: "editor-button editor-button-small", style: "margin-top: 7px; margin-left: 5px;", title: labelDel }).appendTo(finalspan); $('<i/>', { class: "fa fa-remove" }).appendTo(deleteButton); deleteButton.click(function() { container.css({ "background": "#fee" }); container.fadeOut(150, function() { $(this).remove(); }); }); //populate data variableAddr.val(variable.addr); variableName.val(variable.name); $("#node-config-input-variables-container").append(container); } $("#node-config-input-add-variable").click(function() { generateVariable({ name: "", addr: "" }); }); $("#node-config-input-cycletime").spinner({ min: 50 }); $("#node-config-input-timeout").spinner({ min: 500 }); if(self.vartable) { if(typeof self.vartable == 'string') { self.vartable = JSON.parse(self.vartable); } for (var i = 0; i < self.vartable.length; i++) { generateVariable(self.vartable[i]); } } }, oneditsave: function() { var node = this; var vars = $("#node-config-input-variables-container").children(); node.vartable = []; vars.each(function(i) { var elm = $(this); var v = { addr: elm.find(".node-config-input-variable-addr").val(), name: elm.find(".node-config-input-variable-name").val() } node.vartable.push(v); }); //$('#node-config-input-vartable').val(JSON.stringify(node.vartable)); }/*, oneditresize: function(size) { var rows = $("#s7-endpoint-tab-variables>div:not(.form-row node-input-variables-container-row)"); var height = size.height; for (var i = 0; i < rows.size(); i++) { height -= $(rows[i]).outerHeight(true); } var editorRow = $("#s7-endpoint-tab-variables>div.form-row node-input-variables-container-row"); height -= (parseInt(editorRow.css("marginTop")) + parseInt(editorRow.css("marginBottom"))); $("#node-config-input-variables-container-div").css("height", height + "px"); var rules = $("#node-config-input-variables-container").children(); var newWidth = $("#node-config-input-variables-container").width(); rules.each(function(i) { $(this).find('.node-config-input-variable-name').typedInput("width", newWidth - 180); }); }*/ }); //# sourceURL=s7EndpointScript.js </script> <!-- ######################################################################################## --> <script type="text/x-red" data-template-name="s7 in"> <div class="form-row"> <label for="node-input-endpoint"><i class="fa fa-bolt"></i> <span>PLC</span></label> <input type="text" id="node-input-endpoint"> </div> <div class="form-row"> <label for="node-input-mode"><i class="fa fa-sliders"></i> <span>Mode</span></label> <select type="text" id="node-input-mode"> <option value="single">Single variable</option> <option value="all-split">All variables, one per message</option> <option value="all">All variables</option> </select> </div> <div class="form-row s7-input-var-row"> <label for="node-input-variable"><i class="fa fa-random"></i> <span>Variable</span></label> <select type="text" id="node-input-variable"> </select> <span id="s7-custom-var-addr"></span> </div> <div class="form-row"> <label>&nbsp;</label> <input type="checkbox" id="node-input-diff" style="display: inline-block; width: auto; vertical-align: top;"> <label for="node-input-diff" style="width:70%;"><span>Emit only when value changes (diff)</span></label> </div> <div class="form-row"> <label for="node-input-name"><i class="fa fa-tag"></i> <span>s7 in</span></label> <input type="text" id="node-input-name"> </div> </script> <script type="text/x-red" data-help-name="s7 in"> <p>Reads data from a S7 PLC</p> <p>All data is read cyclically from the PLC as configured in the <i>s7 endpoint</i>, but there are three modes of making it available in a flow:</p> <ul> <li><b>Single variable:</b> A single variable can be selected from the configured variables, and a message is sent every cycle, or only when it changes if <i>diff</i> is checked. <code>msg.payload</code> contains the variable's value and <code>msg.topic</code> has the variable's name.</li> <li><b>All variables, one per message:</b> Like the <i>Single variable</i> mode, but for all variables configured. If <i>diff</i> is checked, a message is sent everytime any variable changes. If <i>diff</i> is unchecked, one message is sent for every variable, in every cycle. Care must be taken about the number of messages per second in this mode.</li> <li><b>All variables:</b> In this mode, <code>msg.payload</code> contains an object with all configured variables and their values. If <i>diff</i> is checked, a message is sent if at least one of the variables changes its value.</li> </ul> </script> <script type="text/javascript"> RED.nodes.registerType('s7 in', { category: 'plc-input', defaults: { endpoint: { value: "", type: "s7 endpoint", required: true }, mode: { value: "single" }, variable: { value: "" }, diff: { value: true }, name: { value: "" } }, color: "#3FADB5", inputs: 0, outputs: 1, icon: "s7.png", label: function() { var self = this; if (this.name) return this.name; var endpointNode = RED.nodes.node(this.endpoint); if (endpointNode) { return (this.mode == 'single' ? this.variable : null) || endpointNode.label(); } return this._("s7"); }, labelStyle: function() { return this.name ? "node_label_italic" : ""; }, oneditprepare: function() { var self = this; var varList = $('#node-input-variable'); var varAddr = $('#s7-custom-var-addr'); var modeList = $('#node-input-mode'); var endpointList = $("#node-input-endpoint"); var vars = []; function updateVarList(endpointId) { $('#node-input-variable option').remove(); var endpointNode = RED.nodes.node(endpointId); if (!endpointNode) return; vars = endpointNode.vartable || []; if (typeof vars === 'string') vars = JSON.parse(vars); varList.append($('<option/>', { disabled: "disabled", selected: "selected", style: "display:none;", text: vars.length ? self._("Select a variable") : self._("No variables") })); $.each(vars, function(i, val) { varList.append($('<option/>', { value: val.name || val.addr, text: val.name || val.addr })); if(val.name == self.variable) { varList.val(self.variable); } }); } varList.change(function() { $.each(vars, function(i, val) { if(varList.val() == val.name) { varAddr[0].innerText = val.addr; return true; } }); }); endpointList.change(function() { updateVarList(endpointList.val()); }); updateVarList(self.endpoint); modeList.change(function() { if (modeList.val() == "single") { varList.parent().show(); } else { varList.parent().hide(); } }); modeList.change(); } }); </script> <!-- ######################################################################################## --> <script type="text/x-red" data-template-name="s7 out"> <div class="form-row"> <label for="node-input-endpoint"><i class="fa fa-bolt"></i> <span>PLC</span></label> <input type="text" id="node-input-endpoint"> </div> <div class="form-row s7-input-var-row"> <label for="node-input-variable"><i class="fa fa-random"></i> <span>Variable</span></label> <select type="text" id="node-input-variable"> </select> <span id="s7-custom-var-addr"></span> </div> <div class="form-row"> <label for="node-input-name"><i class="fa fa-tag"></i> <span>s7 out</span></label> <input type="text" id="node-input-name"> </div> <div class="form-tips"><span data-i18n="[html]s7.out.disclaimer">Caution when writing data to production PLCs!</span></div> </script> <script type="text/x-red" data-help-name="s7 out"> <p>Writes <code>msg.payload</code> to a memory area in a S7 PLC</p> <p>The variable name can be configured in the node and takes precedence. If left blank it should be set by <code>msg.variable</code> on the incoming message.</p> <p><b>Warning:</b> Caution when writing data to production PLCs!</p> </script> <script type="text/javascript"> RED.nodes.registerType('s7 out', { category: 'plc-output', defaults: { endpoint: { value: "", type: "s7 endpoint", required: true }, variable: { value: "" }, name: { value: "" } }, color: "#3FADB5", inputs: 1, outputs: 0, icon: "s7.png", align: 'right', label: function() { var self = this; if (this.name) return this.name; var endpointNode = RED.nodes.node(this.endpoint); if (endpointNode) { return this.variable || endpointNode.label(); } return this._("s7 out"); }, labelStyle: function() { return this.name ? "node_label_italic" : ""; }, oneditprepare: function() { var self = this; var varList = $('#node-input-variable'); var varAddr = $('#s7-custom-var-addr')[0]; var endpointList = $("#node-input-endpoint"); var vars = []; function updateVarList(endpointId) { $('#node-input-variable option').remove(); varList.append($('<option/>', { //disabled: "disabled", selected: "selected", //style: "display:none;", text: self._("Select a variable"), value: "" })); var endpointNode = RED.nodes.node(endpointId); if (!endpointNode) return; vars = endpointNode.vartable || []; if (typeof vars === 'string') vars = JSON.parse(vars); $.each(vars, function(i, val) { varList.append($('<option/>', { value: val.name || val.addr, text: val.name || val.addr })); if(val.name == self.variable) { varList.val(self.variable); } }); } varList.change(function() { varAddr.innerText = "" $.each(vars, function(i, val) { if(varList.val() == val.name) { varAddr.innerText = val.addr; return true; } }); }); endpointList.change(function() { updateVarList(endpointList.val()); }); updateVarList(self.endpoint); } }); </script>