UNPKG

node-red-contrib-scenario

Version:

Node-Red Node that can be configured to send a list of output messages with delays between them

152 lines (134 loc) 7.48 kB
<script type="text/javascript"> RED.nodes.registerType('scenario',{ category: 'function', color: '#FFCC66', defaults: { name: {value:""}, scenes: {value:[{value: '', time : ''}]}, repeatType: {value: 'once'}, repeatTimes: {value: 1, validate: function(val) { return val > 0; } } }, inputs:1, outputs:1, icon: "light.png", label: function() { return this.name||"scenario"; }, oneditprepare: function() { this.resizeRule = function(scene,newWidth) { scene.find(".node-input-scene-value").width(newWidth); scene.find(".node-input-scene-time").width(newWidth); } function generateScene(i, scene) { var container = $('<li/>',{style:"background: #fff; margin:0; padding:8px 0px 0px; border-bottom: 1px solid #ccc;"}); var row = $('<div/>').appendTo(container); var row2 = $('<div/>',{style:"padding-top: 5px; padding-left: 175px;"}).appendTo(container); var row3 = $('<div/>',{style:"padding-top: 5px; padding-left: 120px;"}).appendTo(container); $('<i style="color: #eee; cursor: move; margin-left: 3px;" class="node-input-scene-handle fa fa-bars"></i>').appendTo(row); var valueField = $('<input/>',{class:"node-input-scene-value",type:"text",style:"margin-left: 7px; width: 135px;", placeholder: 'Value',value:scene.value}).appendTo(row).typedInput({default: 'str',types:['str','num','bool', 'json']}); var labelField = $('<input/>',{class:"node-input-scene-time",type:"text",style:"margin-left: 7px; width: 135px;", placeholder: 'Time', value:scene.time}).appendTo(row).typedInput({default:'num',types:['num']}); var finalspan = $('<span/>',{style:"float: right;margin-right: 10px;"}).appendTo(row); var deleteButton = $('<a/>',{href:"#",class:"editor-button editor-button-small", style:"margin-top: 7px; margin-left: 5px;"}).appendTo(finalspan); $('<i/>',{class:"fa fa-remove"}).appendTo(deleteButton); deleteButton.click(function() { container.css({"background":"#fee"}); container.fadeOut(300, function() { $(this).remove(); }); }); $("#node-input-scene-container").append(container); } $("#node-input-add-scene").click(function() { generateScene($("#node-input-scene-container").children().length+1, {}); $("#node-input-scene-container-div").scrollTop($("#node-input-scene-container-div").get(0).scrollHeight); }); for (var i=0; i<this.scenes.length; i++) { var scene = this.scenes[i]; generateScene(i+1,scene); } $( "#node-input-scene-container" ).sortable({ axis: "y", handle:".node-input-scene-handle", cursor: "move" }); $('#node-input-repeatType').on("change", function(){ if($(this).val() === 'custom') $('#node-input-repeatTimes').show().prev().show(); else $('#node-input-repeatTimes').hide().prev().hide(); }); $('#node-input-repeatType').trigger('change'); }, oneditsave: function() { var scenes = $("#node-input-scene-container").children(); var node = this; node.scenes = []; scenes.each(function(i) { var scene = $(this); var o = { value: scene.find(".node-input-scene-value").val(), time: scene.find(".node-input-scene-time").val() }; if (scene.find(".node-input-scene-value").typedInput('type') === "num") { o.value = Number(o.value); } if (scene.find(".node-input-scene-value").typedInput('type') === "bool") { o.value = (o.value == "true"); } if (scene.find(".node-input-scene-value").typedInput('type') === "json") { o.value = JSON.parse(o.value); } node.scenes.push(o); }); }, oneditresize: function() { var scenes = $("#node-input-scene-container").children(); var newWidth = ($("#node-input-scene-container").width() - 175)/2; var node = this; scenes.each(function(i) { node.resizeRule($(this),newWidth); }); } }); </script> <script type="text/x-red" data-template-name="scenario"> <div class="form-row"> <label for="node-input-name"><i class="icon-tag"></i> Name</label> <input type="text" id="node-input-name" placeholder="Name"> </div> <div class="form-row node-input-scene-container-row" style="margin-bottom: 0px;width: 100%"> <label for="node-input-width" style="vertical-align:top"><i class="fa fa-list-alt"></i> Scenes</label> <div id="node-input-scene-container-div" style="box-sizing: border-box; border-radius: 5px; height: 257px; padding: 5px; border: 1px solid #ccc; overflow-y:scroll;display: inline-block; width: calc(70% + 15px);"> <ol id="node-input-scene-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-input-add-scene" style="margin-top: 4px; margin-left: 103px;"><i class="fa fa-plus"></i> <span>scene</span></a> </div> <div class="form-row"> <label for="node-input-repeatType"><i class="fa fa-repeat"></i> Repeat</label> <select id="node-input-repeatType"> <option value="once">once</option> <option value="custom">custom times</option> <option value="infinite" selected="selected">infinite loop</option> </select> </div> <div class="form-row"> <label for="node-input-repeatTimes"><i class="icon-tag"></i> Repeat count</label> <input type="number" id="node-input-repeatTimes" style="width: 30%;"> </div> </script> <script type="text/x-red" data-help-name="scenario"> <p>Send a list of output messages with differents delays between them</p> <h3>Details</h3> <p>Send <code>msg.payload = "start"</code> in input to start the scenario.</p> <p>Send <code>msg.payload = "stop"</code> in input to stop the scenario.</p> <p>Send <code>msg.payload = "init" msg.scenes = [value: (Object, Number, Bool), time: (Number)]</code> in input to override node configuration scenes.</p> <p>The node will start to output scenes <code>value</code> added in node configuration, scenes <code>value</code> can be <code>String</code>, <code>Number</code>, <code>JSON</code> or <code>Bool</code> each scene has a <code>time</code> of duration in millisecond</p> <p>You can choose how many times the node will repeat the scene sequence. Possible values are once, custom times and infinite loop.</p> <h3>References</h3> <ul> <li><a href="https://github.com/robertsLando/node-red-contrib-scenario">GitHub</a> - the node github repository</li> </ul> </script>