mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Merge remote-tracking branch 'upstream/master'
This commit is contained in:
		| @@ -23,22 +23,154 @@ | ||||
|         <label for="node-input-payload"><i class="icon-envelope"></i> Payload</label> | ||||
|         <input type="text" id="node-input-payload" placeholder="Payload"> | ||||
|     </div> | ||||
|     <div class="form-row node-input-repeat"> | ||||
|         <label for="node-input-repeat"><i class="icon-repeat"></i> Repeat (S)</label> | ||||
|         <input type="text" id="node-input-repeat" placeholder="0"> | ||||
|     </div> | ||||
|  | ||||
|     <div class="form-row"> | ||||
|         <label> </label> | ||||
|         <input type="checkbox" id="node-input-once" placeholder="once" style="display: inline-block; width: auto; vertical-align: top;"> | ||||
|         <label for="node-input-once" style="width: 70%;">Fire once at start ?</label> | ||||
|     </div> | ||||
|      | ||||
|     <div class="form-row"> | ||||
|         <label for=""><i class="icon-repeat"></i> Repeat</label> | ||||
|         <select id="inject-time-type-select"><option value="none">None</option><option value="interval">interval</option><option value="interval-time">interval between times</option><option value="time">at a specific time</option></select> | ||||
|         <input type="hidden" id="node-input-repeat" placeholder="Payload"> | ||||
|         <input type="hidden" id="node-input-crontab" placeholder="Payload"> | ||||
|     </div> | ||||
|      | ||||
|     <div class="form-row inject-time-row hidden" id="inject-time-row-interval"> | ||||
|         every <input id="inject-time-interval-count" class="inject-time-count" value="1"></input> | ||||
|               <select style="width: 100px" id="inject-time-interval-units"><option value="s">seconds</option><option value="m">minutes</option><option value="h">hours</option></select><br/> | ||||
|         on <select disabled id="inject-time-interval-days" class="inject-time-days"></select> | ||||
|     </div> | ||||
|      | ||||
|     <div class="form-row inject-time-row hidden" id="inject-time-row-interval-time"> | ||||
|         every <input id="inject-time-interval-time-units" class="inject-time-count" value="1"></input> minutes<br/>  | ||||
|         between <select id="inject-time-interval-time-start" class="inject-time-times"></select> | ||||
|         and <select id="inject-time-interval-time-end" class="inject-time-times"></select><br/> | ||||
|         on <select id="inject-time-interval-time-days" class="inject-time-days"></select> | ||||
|     </div> | ||||
|      | ||||
|     <div class="form-row inject-time-row hidden" id="inject-time-row-time"> | ||||
|         at <input id="inject-time-time" value="12:00"></input><br/> | ||||
|         on <select id="inject-time-time-days" class="inject-time-days"></select> | ||||
|     </div> | ||||
|      | ||||
|     <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-tips">Tip: Injects Date.now() if no payload set.<br/>Repeat interval blank or 0 means no repeat.</div> | ||||
| </script> | ||||
|      | ||||
|     <div class="form-tips">Tip: Injects Date.now() if no payload set</div> | ||||
|     <script> | ||||
|     { | ||||
|      | ||||
|         $("#inject-time-type-select").change(function() { | ||||
|             var id = $("#inject-time-type-select option:selected").val(); | ||||
|             $(".inject-time-row").hide(); | ||||
|             $("#inject-time-row-"+id).show(); | ||||
|         }); | ||||
|      | ||||
|         var days = [ | ||||
|             {v:"*",t:"every day"}, | ||||
|             {v:"1-5",t:"Mondays to Fridays"}, | ||||
|             {v:"6-7",t:"Saturdays and Sundays"}, | ||||
|             {v:"1",t:"Mondays"}, | ||||
|             {v:"2",t:"Tuesdays"}, | ||||
|             {v:"3",t:"Wednesdays"}, | ||||
|             {v:"4",t:"Thursdays"}, | ||||
|             {v:"5",t:"Fridays"}, | ||||
|             {v:"6",t:"Saturdays"}, | ||||
|             {v:"7",t:"Sundays"} | ||||
|         ]; | ||||
|         $(".inject-time-days").each(function() { | ||||
|             for (var d in days) { | ||||
|                 $(this).append($("<option></option>").val(days[d].v).text(days[d].t)); | ||||
|             } | ||||
|         }); | ||||
|          | ||||
|         $(".inject-time-times").each(function() { | ||||
|             for (var i=0;i<24;i++) { | ||||
|                 var l = (i<10?"0":"")+i+":00"; | ||||
|                 $(this).append($("<option></option>").val(i).text(l)); | ||||
|             } | ||||
|         }); | ||||
|         $(".inject-time-count").spinner({ | ||||
|             min:1, | ||||
|             max:60 | ||||
|         }); | ||||
|          | ||||
|         $("#inject-time-interval-units").change(function() { | ||||
|             var units = $("#inject-time-interval-units option:selected").val(); | ||||
|             $("#inject-time-interval-days").prop("disabled",(units == "s")?"disabled":false); | ||||
|             $(".inject-time-count").spinner("option","max",(units == "h")?24:60); | ||||
|              | ||||
|         }); | ||||
|          | ||||
|  | ||||
|         $.widget( "ui.injecttimespinner", $.ui.spinner, { | ||||
|             options: { | ||||
|                 // seconds | ||||
|                 step: 60 * 1000, | ||||
|                 // hours | ||||
|                 page: 60, | ||||
|                 min:0, | ||||
|                 max:(23*60+59)*60*1000 | ||||
|             }, | ||||
|             _parse: function( value ) { | ||||
|                 if ( typeof value === "string" ) { | ||||
|                     // already a timestamp | ||||
|                     if ( Number( value ) == value ) { | ||||
|                         return Number( value ); | ||||
|                     } | ||||
|                     var p = value.split(":"); | ||||
|                     return ((p[0]*60)+Number(p[1]))*60*1000; | ||||
|                 } | ||||
|                 return value; | ||||
|             }, | ||||
|             _format: function( value ) { | ||||
|                 var d = new Date(value); | ||||
|                 var h = d.getHours(); | ||||
|                 var m = d.getMinutes(); | ||||
|                  | ||||
|                 return ((h<10)?"0":"")+h+":"+((m<10)?"0":"")+m; | ||||
|             } | ||||
|         }); | ||||
|          | ||||
|          | ||||
|         $("#inject-time-time").injecttimespinner(); | ||||
|     }; | ||||
|  | ||||
|          | ||||
|     </script> | ||||
| </script> | ||||
| <style> | ||||
|     .inject-time-row { | ||||
|         padding-left: 110px; | ||||
|     } | ||||
|     .inject-time-row select { | ||||
|         margin: 3px 0; | ||||
|     } | ||||
|     .inject-time-days { | ||||
|         width: 225px; | ||||
|     } | ||||
|     .inject-time-times { | ||||
|         width: 90px; | ||||
|     } | ||||
|     .inject-time-row > .ui-spinner { | ||||
|         height: 28px; | ||||
|         margin: 3px 0; | ||||
|         border-color: rgb(204, 204, 204); | ||||
|     } | ||||
|     #inject-time-time { | ||||
|         margin-top: 3px; | ||||
|         width: 75px; | ||||
|     } | ||||
|     .inject-time-count { | ||||
|         width: 30px !important; | ||||
|     } | ||||
|     . | ||||
|      | ||||
| </style> | ||||
| <script type="text/x-red" data-help-name="inject"> | ||||
| 	<p>Pressing the button on the left side of the node allows a message on a topic to be injected into the flow. This is mainly for test purposes.</p> | ||||
| 	<p>If no payload is specified the payload is set to the current time in millisecs since 1970. This allows subsequent functions to perform time based actions.</p> | ||||
| @@ -55,6 +187,7 @@ | ||||
|             topic: {value:""}, | ||||
|             payload: {value:""}, | ||||
|             repeat: {value:""}, | ||||
|             crontab: {value:""}, | ||||
|             once: {value:false} | ||||
|         }, | ||||
|         inputs:0, | ||||
| @@ -66,6 +199,150 @@ | ||||
|         labelStyle: function() { | ||||
|             return this.name?"node_label_italic":""; | ||||
|         }, | ||||
|         oneditprepare: function() { | ||||
|             var repeattype = "none"; | ||||
|             if (Number(this.repeat) != 0) { | ||||
|                 repeattype = "interval"; | ||||
|                 $("#inject-time-interval-units option").filter(function() {return $(this).val() == "s";}).attr('selected',true); | ||||
|                 $("#inject-time-interval-count").val(this.repeat); | ||||
|                 $("#inject-time-interval-days").prop("disabled","disabled"); | ||||
|             } else if (this.crontab) { | ||||
|                 var cronparts = this.crontab.split(" "); | ||||
|                 var days = cronparts[4]; | ||||
|                 if (Number(cronparts[0]) && Number(cronparts[1])) { | ||||
|                     repeattype = "time"; | ||||
|                     // Fixed time | ||||
|                     var time = cronparts[1]+":"+cronparts[0]; | ||||
|                     $("#inject-time-time").val(time); | ||||
|                     $("#inject-time-type-select option").filter(function() {return $(this).val() == "s";}).attr('selected',true); | ||||
|                     $("#inject-time-time-days option").filter(function() {return $(this).val() == days;}).attr('selected',true); | ||||
|                      | ||||
|                 } else if (cronparts[0] == "0") { | ||||
|                     // interval - hours | ||||
|                     var hours = cronparts[1].slice(2); | ||||
|                     repeattype = "interval"; | ||||
|                     $("#inject-time-interval-days").prop("disabled",false); | ||||
|                     $("#inject-time-interval-days option").filter(function() {return $(this).val() == days;}).attr('selected',true); | ||||
|                     $("#inject-time-interval-count").val(hours) | ||||
|                     $("#inject-time-interval-units option").filter(function() {return $(this).val() == "h";}).attr('selected',true); | ||||
|                 } else if (cronparts[1] == "*") { | ||||
|                     // interval - minutes | ||||
|                     var minutes = cronparts[0].slice(2); | ||||
|                     repeattype = "interval"; | ||||
|                     $("#inject-time-interval-days").prop("disabled",false); | ||||
|                     $("#inject-time-interval-days option").filter(function() {return $(this).val() == days;}).attr('selected',true); | ||||
|                     $("#inject-time-interval-count").val(minutes) | ||||
|                     $("#inject-time-interval-units option").filter(function() {return $(this).val() == "m";}).attr('selected',true); | ||||
|                 } else { | ||||
|                     repeattype = "interval-time"; | ||||
|                     // interval - time period | ||||
|                     var minutes = cronparts[0].slice(2); | ||||
|                     $("#inject-time-interval-time-units").val(minutes); | ||||
|                     $("#inject-time-interval-time-days option").filter(function() {return $(this).val() == days;}).attr('selected',true); | ||||
|                     var time = cronparts[1]; | ||||
|                     var timeparts = time.split(","); | ||||
|                     var start; | ||||
|                     var end; | ||||
|                     if (timeparts.length == 1) { | ||||
|                         // 0 or 0-10 | ||||
|                         var hours = timeparts[0].split("-"); | ||||
|                         if (hours.length == 1) { | ||||
|                             start = hours[0]; | ||||
|                             end = Number(hours[0])+1; | ||||
|                         } else { | ||||
|                             start = hours[0]; | ||||
|                             end = (Number(hours[1])+1)%24; | ||||
|                         } | ||||
|                     } else { | ||||
|                         // 23,0 or 17-23,0-10 or 23,0-2 or 17-23,0 | ||||
|                         var startparts = timeparts[0].split("-"); | ||||
|                         start = startparts[0]; | ||||
|                          | ||||
|                         var endparts = timeparts[1].split("-"); | ||||
|                         if (endparts.length == 1) { | ||||
|                             end = Number(endparts[0])+1; | ||||
|                         } else { | ||||
|                             end = Number(endparts[1])+1; | ||||
|                         } | ||||
|                     } | ||||
|                     $("#inject-time-interval-time-start option").filter(function() {return $(this).val() == start;}).attr('selected',true); | ||||
|                     $("#inject-time-interval-time-end option").filter(function() {return $(this).val() == end;}).attr('selected',true); | ||||
|  | ||||
|                 } | ||||
|             } else { | ||||
|                 $("#inject-time-type-select option").filter(function() {return $(this).val() == "none";}).attr('selected',true); | ||||
|             } | ||||
|              | ||||
|             $(".inject-time-row").hide(); | ||||
|             $("#inject-time-type-select option").filter(function() {return $(this).val() == repeattype;}).attr('selected',true); | ||||
|             $("#inject-time-row-"+repeattype).show(); | ||||
|  | ||||
|          | ||||
|         }, | ||||
|         oneditsave: function() { | ||||
|             var repeat = ""; | ||||
|             var crontab = ""; | ||||
|             var type = $("#inject-time-type-select option:selected").val(); | ||||
|             if (type == "none") { | ||||
|                 // nothing | ||||
|             } else if (type == "interval") { | ||||
|                 var count = $("#inject-time-interval-count").val(); | ||||
|                 var units = $("#inject-time-interval-units option:selected").val(); | ||||
|                 var days = $("#inject-time-interval-days option:selected").val(); | ||||
|                 if (units == "s") { | ||||
|                     repeat = count; | ||||
|                 } else { | ||||
|                     if (units == "m") { | ||||
|                         crontab = "*/"+count+" * * * "+days; | ||||
|                     } else if (units == "h") { | ||||
|                         crontab = "0 */"+count+" * * "+days; | ||||
|                     } | ||||
|                 }  | ||||
|             } else if (type == "interval-time") { | ||||
|                 var count = $("#inject-time-interval-time-units").val(); | ||||
|                 var startTime = Number($("#inject-time-interval-time-start option:selected").val()); | ||||
|                 var endTime = Number($("#inject-time-interval-time-end option:selected").val()); | ||||
|                 var days = $("#inject-time-interval-time-days option:selected").val(); | ||||
|                 var timerange = ""; | ||||
|                 if (startTime == endTime) { | ||||
|                     //TODO: invalid | ||||
|                     repeat = 0; | ||||
|                     crontab = ""; | ||||
|                 } else if (endTime == 0) { | ||||
|                     timerange = startTime+"-23"; | ||||
|                 } else if (startTime+1 < endTime) { | ||||
|                     timerange = startTime+"-"+(endTime-1); | ||||
|                 } else if (startTime+1 == endTime) { | ||||
|                     timerange = startTime; | ||||
|                 } else { | ||||
|                     var startpart = ""; | ||||
|                     var endpart = ""; | ||||
|                     if (startTime == 23) { | ||||
|                         startpart = "23"; | ||||
|                     } else { | ||||
|                         startpart = startTime+"-23"; | ||||
|                     } | ||||
|                     if (endTime == 1) { | ||||
|                         endpart = "0"; | ||||
|                     } else { | ||||
|                         endpart = "0-"+(endTime-1); | ||||
|                     } | ||||
|                     timerange = startpart+","+endpart; | ||||
|                 } | ||||
|                 repeat = 0; | ||||
|                 crontab = "*/"+count+" "+timerange+" * * "+days; | ||||
|             } else if (type == "time") { | ||||
|                 var time = $("#inject-time-time").val(); | ||||
|                 var days = $("#inject-time-time-days option:selected").val(); | ||||
|                 var parts = time.split(":"); | ||||
|                 repeat = 0; | ||||
|                 crontab = parts[1]+" "+parts[0]+" * * "+days; | ||||
|             } | ||||
|              | ||||
|             $("#node-input-repeat").val(repeat); | ||||
|             $("#node-input-crontab").val(crontab); | ||||
|              | ||||
|         }, | ||||
|         button: { | ||||
|             onclick: function() { | ||||
|                 var label = this.name||this.payload; | ||||
|   | ||||
| @@ -15,15 +15,22 @@ | ||||
|  **/ | ||||
|  | ||||
| var RED = require("../../red/red"); | ||||
| try { | ||||
|     var cron = require("cron"); | ||||
| } catch(err) { | ||||
|     require("util").log("[inject] Warning: cannot find module 'cron'"); | ||||
| } | ||||
|  | ||||
| function InjectNode(n) { | ||||
| 	RED.nodes.createNode(this,n); | ||||
| 	this.topic = n.topic; | ||||
| 	this.payload = n.payload; | ||||
| 	this.repeat = n.repeat; | ||||
| 	this.crontab = n.crontab; | ||||
| 	this.once = n.once; | ||||
| 	var node = this; | ||||
| 	this.interval_id = null; | ||||
| 	this.cronjob = null; | ||||
|  | ||||
| 	if (this.repeat && !isNaN(this.repeat) && this.repeat > 0) { | ||||
| 		this.repeat = this.repeat * 1000; | ||||
| @@ -31,6 +38,17 @@ function InjectNode(n) { | ||||
| 		this.interval_id = setInterval( function() { | ||||
| 			node.emit("input",{}); | ||||
| 		}, this.repeat ); | ||||
| 	} else if (this.crontab) { | ||||
| 	    if (cron) { | ||||
| 	        this.log("crontab = "+this.crontab); | ||||
| 	        this.cronjob = new cron.CronJob(this.crontab, | ||||
| 	            function() { | ||||
| 	                node.emit("input",{}); | ||||
| 	            }, | ||||
| 	            null,true); | ||||
| 	    } else { | ||||
| 	        this.error("'cron' module not found"); | ||||
| 	    } | ||||
| 	} | ||||
|  | ||||
| 	if (this.once) { | ||||
| @@ -51,6 +69,10 @@ InjectNode.prototype.close = function() { | ||||
|     if (this.interval_id != null) { | ||||
|         clearInterval(this.interval_id); | ||||
|         this.log("inject: repeat stopped"); | ||||
|     } else if (this.cronjob != null) { | ||||
|         this.cronjob.stop(); | ||||
|         this.log("inject: cronjob stopped"); | ||||
|         delete this.cronjob; | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -27,7 +27,8 @@ | ||||
| </script> | ||||
|  | ||||
| <script type="text/x-red" data-help-name="debug"> | ||||
| 	<p>The Debug node can be connected to the output of any node. It will display the timestamp, <b>msg.topic</b> and <b>msg.payload</b> fields of any messages it receives under the Debug tab at the top of the sidebar.</p> | ||||
| 	<p>The Debug node can be connected to the output of any node. It will display the timestamp, <b>msg.topic</b> and <b>msg.payload</b> fields of any messages it receives in the debug tab of the sidebar.  | ||||
| 	<br/>The sidebar can be accessed under the options drop-down in the top right corner.</p> | ||||
| 	<p>The button to the right of the node will toggle it's output on and off so you can de-clutter the debug window.</p> | ||||
| 	<p>If the payload is an object it will be stringified first for display and indicate that by saying "(Object) ".</p> | ||||
| 	<p>If the payload is a buffer it will be stringified first for display and indicate that by saying "(Buffer) ".</p> | ||||
|   | ||||
| @@ -13,9 +13,9 @@ | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
|   | ||||
|  | ||||
| var RED = require("../../red/red"); | ||||
|   | ||||
|  | ||||
| var util = require("util"); | ||||
| var ws = require('ws'); | ||||
| var events = require("events"); | ||||
| @@ -28,12 +28,12 @@ function DebugNode(n) { | ||||
| 	this.on("input",function(msg) { | ||||
| 		if (this.active) { | ||||
| 			if (msg.payload instanceof Buffer) { | ||||
| 			    msg.payload = "(Buffer) "+msg.payload.toString(); | ||||
| 				msg.payload = "(Buffer) "+msg.payload.toString(); | ||||
| 			} | ||||
| 			if (this.complete) { | ||||
| 			    DebugNode.send({id:this.id,name:this.name,topic:msg.topic,msg:msg,_path:msg._path}); | ||||
| 				DebugNode.send({id:this.id,name:this.name,topic:msg.topic,msg:msg,_path:msg._path}); | ||||
| 			} else { | ||||
| 			    DebugNode.send({id:this.id,name:this.name,topic:msg.topic,msg:msg.payload,_path:msg._path}); | ||||
| 				DebugNode.send({id:this.id,name:this.name,topic:msg.topic,msg:msg.payload,_path:msg._path}); | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
| @@ -44,9 +44,19 @@ RED.nodes.registerType("debug",DebugNode); | ||||
| DebugNode.send = function(msg) { | ||||
| 	if (msg.msg instanceof Error) { | ||||
| 		msg.msg = msg.msg.toString(); | ||||
| 	} else if (typeof msg.msg === 'object') { | ||||
| 		msg.msg = "(Object) "+JSON.stringify(msg.msg,null,1); | ||||
| 	} else if (msg.msg == 0) msg.msg = "0"; | ||||
| 	} | ||||
| 	else if (typeof msg.msg === 'object') { | ||||
| 		try { | ||||
| 			msg.msg = "(Object) "+JSON.stringify(msg.msg,null,1); | ||||
| 		} | ||||
| 		catch (err) { | ||||
| 			console.log(msg.msg); | ||||
| 			console.log(err); | ||||
| 			msg.msg = "[Error] Can't stringify object with circular reference - see console log."; | ||||
| 		} | ||||
| 	} | ||||
| 	else if (typeof msg.msg === "boolean") msg.msg = "(boolean) "+msg.msg.toString(); | ||||
| 	else if (msg.msg === 0) msg.msg = "0"; | ||||
|  | ||||
| 	for (var i in DebugNode.activeConnections) { | ||||
| 		var ws = DebugNode.activeConnections[i]; | ||||
| @@ -85,11 +95,11 @@ RED.app.post("/debug/:id", function(req,res) { | ||||
| 	var node = RED.nodes.getNode(req.params.id); | ||||
| 	if (node != null) { | ||||
| 		if (node.active) { | ||||
| 		    node.active = false; | ||||
| 		    res.send(201); | ||||
| 			node.active = false; | ||||
| 			res.send(201); | ||||
| 		} else { | ||||
| 		    node.active = true; | ||||
| 		    res.send(200); | ||||
| 			node.active = true; | ||||
| 			res.send(200); | ||||
| 		} | ||||
| 	} else { | ||||
| 		res.send(404); | ||||
|   | ||||
| @@ -31,13 +31,13 @@ | ||||
| <script type="text/javascript"> | ||||
| 	RED.nodes.registerType('blinkstick',{ | ||||
| 		category: 'advanced-output', | ||||
| 		color:"cornsilk", | ||||
| 		color:"GoldenRod", | ||||
| 		defaults: { | ||||
| 			name: {value:""} | ||||
| 		}, | ||||
| 		inputs:1, | ||||
| 		outputs:0, | ||||
| 		icon: "arrow-in.png", | ||||
| 		icon: "light.png", | ||||
| 		align: "right", | ||||
| 		label: function() { | ||||
| 			return this.name||"blinkstick"; | ||||
|   | ||||
| @@ -17,23 +17,44 @@ | ||||
| var RED = require("../../red/red"); | ||||
| var blinkstick = require("blinkstick"); | ||||
|  | ||||
| Object.size = function(obj) { | ||||
| 	var size = 0, key; | ||||
| 	for (key in obj) { | ||||
| 		if (obj.hasOwnProperty(key)) size++; | ||||
| 	} | ||||
| 	return size; | ||||
| }; | ||||
|  | ||||
| function BlinkStick(n) { | ||||
| 	RED.nodes.createNode(this,n); | ||||
| 	var p1 = /^#.*/ | ||||
| 	var p1 = /^\#[A-Za-z0-9]{6}$/ | ||||
| 	var p2 = /[0-9]+,[0-9]+,[0-9]+/ | ||||
|  | ||||
| 	this.led = new blinkstick.findFirst(); | ||||
| 	this.led = blinkstick.findFirst(); // maybe try findAll() (one day) | ||||
| 	var node = this; | ||||
|  | ||||
| 	node.log("started"); | ||||
| 	this.on("input", function(msg) { | ||||
| 		if (msg != null) { | ||||
| 				if ((p1.test(msg.payload))|(p2.test(msg.payload))) { | ||||
| 			if (Object.size(blinkstick.findFirst()) !== 0) { | ||||
| 				if (p2.test(msg.payload)) { | ||||
| 					var rgb = msg.payload.split(","); | ||||
| 					node.led.setColor(parseInt(rgb[0]), parseInt(rgb[1]), parseInt(rgb[2])); | ||||
| 				} | ||||
| 				else if ((p1.test(msg.payload))|(p2.test(msg.payload))) { | ||||
| 					node.led.setColor(msg.payload); | ||||
| 				} | ||||
| 				else { | ||||
| 					node.error("Incorrect format: "+msg.payload); | ||||
| 					try { | ||||
| 						node.led.setColor(msg.payload); | ||||
| 					} | ||||
| 					catch (err) { | ||||
| 						node.error("Incorrect format: "+msg.payload); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			else { | ||||
| 				node.error("No BlinkStick found"); | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
|   | ||||
| @@ -29,13 +29,13 @@ | ||||
| <script type="text/javascript"> | ||||
|     RED.nodes.registerType('blink',{ | ||||
|         category: 'output', | ||||
|         color:"cornsilk", | ||||
|         color:"GoldenRod", | ||||
|         defaults: { | ||||
|             name: {value:""} | ||||
|         }, | ||||
|         inputs:1, | ||||
|         outputs:0, | ||||
|         icon: "arrow-in.png", | ||||
|         icon: "light.png", | ||||
|         align: "right", | ||||
|         label: function() { | ||||
|             return this.name||"blink1"; | ||||
|   | ||||
| @@ -14,7 +14,8 @@ | ||||
|     "express": "3.x", | ||||
|     "mqtt": "*", | ||||
|     "ws": "*", | ||||
|     "mustache": "*" | ||||
|     "mustache": "*", | ||||
|     "cron":"*" | ||||
|   }, | ||||
|   "engines": { "node": ">=0.8" } | ||||
| } | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								public/icons/light.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								public/icons/light.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 288 B | 
							
								
								
									
										30
									
								
								red.js
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								red.js
									
									
									
									
									
								
							| @@ -17,34 +17,32 @@ var http = require('http'); | ||||
| var https = require('https'); | ||||
| var util = require("util"); | ||||
| var express = require("express"); | ||||
| var crypto = require("crypto"); | ||||
| var settings = require("./settings"); | ||||
|  | ||||
| var redApp = null; | ||||
|  | ||||
| if (settings.https) { | ||||
|     server = https.createServer(settings.https,function(req,res){redApp(req,res);}); | ||||
| } else { | ||||
|     server = http.createServer(function(req,res){redApp(req,res);}); | ||||
| } | ||||
|  | ||||
| redApp = require('./red/server.js').init(server,settings); | ||||
|  | ||||
| var server; | ||||
| var app = express(); | ||||
|  | ||||
| settings.httpRoot = settings.httpRoot||""; | ||||
| if (settings.httpRoot.slice(-1) == "/") { | ||||
|     settings.httpRoot = settings.httpRoot.slice(0,-1); | ||||
| var redApp = null; | ||||
|  | ||||
| if (settings.https) { | ||||
|     server = https.createServer(settings.https,function(req,res){app(req,res);}); | ||||
| } else { | ||||
|     server = http.createServer(function(req,res){app(req,res);}); | ||||
| } | ||||
|  | ||||
| redApp = require('./red/server.js').init(server,settings); | ||||
|  | ||||
| settings.httpRoot = settings.httpRoot||"/"; | ||||
|  | ||||
| if (settings.httpRoot[0] != "/") { | ||||
|     settings.httpRoot = "/"+settings.httpRoot; | ||||
| } | ||||
| if (settings.httpRoot == "/") { | ||||
|     settings.httpRoot = ""; | ||||
| if (settings.httpRoot.slice(-1) != "/") { | ||||
|     settings.httpRoot = settings.httpRoot + "/"; | ||||
| } | ||||
| settings.uiPort = settings.uiPort||1880; | ||||
|  | ||||
|  | ||||
| if (settings.httpAuth) { | ||||
|     app.use(settings.httpRoot, | ||||
|         express.basicAuth(function(user, pass) { | ||||
|   | ||||
							
								
								
									
										24
									
								
								red/nodes.js
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								red/nodes.js
									
									
									
									
									
								
							| @@ -66,7 +66,7 @@ var registry = (function() { | ||||
|                 events.emit("nodes-stopped"); | ||||
|                 nodes = {}; | ||||
|             }, | ||||
|              | ||||
|  | ||||
|             addLogHandler: function(handler) { | ||||
|                 logHandlers.push(handler); | ||||
|             } | ||||
| @@ -87,7 +87,7 @@ var node_type_registry = (function() { | ||||
|         var obj = { | ||||
|             register: function(type,node) { | ||||
|                 util.inherits(node, Node); | ||||
|                  | ||||
|  | ||||
|                 var callerFilename = getCallerFilename(type); | ||||
|                 if (callerFilename == null) { | ||||
|                     util.log("["+type+"] unable to determine filename"); | ||||
| @@ -115,7 +115,7 @@ var node_type_registry = (function() { | ||||
|                     result += node_configs[nt]; | ||||
|                 } | ||||
|                 return result; | ||||
|                  | ||||
|  | ||||
|             } | ||||
|         } | ||||
|         return obj; | ||||
| @@ -253,9 +253,9 @@ module.exports.load = function() { | ||||
|                 } | ||||
|         }); | ||||
|     } | ||||
|      | ||||
|  | ||||
|     loadNodes("nodes"); | ||||
|      | ||||
|  | ||||
|     events.emit("nodes-loaded"); | ||||
| } | ||||
|  | ||||
| @@ -265,22 +265,27 @@ module.exports.getNode = function(nid) { | ||||
|     return registry.get(nid); | ||||
| } | ||||
| module.exports.parseConfig = function(conf) { | ||||
|      | ||||
|  | ||||
|     registry.clear(); | ||||
|      | ||||
|  | ||||
|     events.emit("nodes-starting"); | ||||
|     for (var i in conf) { | ||||
|         var nn = null; | ||||
|         var nt = node_type_registry.get(conf[i].type); | ||||
|         if (nt) { | ||||
|             nn = new nt(conf[i]); | ||||
| 			try { | ||||
| 				nn = new nt(conf[i]); | ||||
| 			} | ||||
| 			catch (err) { | ||||
| 				util.log("[red] "+conf[i].type+" : "+err); | ||||
| 			} | ||||
|         } | ||||
|         // console.log(nn); | ||||
|         if (nn == null) { | ||||
|             util.log("[red] unknown type: "+conf[i].type); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|  | ||||
|     // Clean up any orphaned credentials | ||||
|     var deletedCredentials = false; | ||||
|     for (var c in credentials) { | ||||
| @@ -296,4 +301,3 @@ module.exports.parseConfig = function(conf) { | ||||
|     events.emit("nodes-started"); | ||||
|  | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										10
									
								
								red/ui.js
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								red/ui.js
									
									
									
									
									
								
							| @@ -21,8 +21,14 @@ var app = express(); | ||||
|  | ||||
| function setupUI(settings) { | ||||
|      | ||||
|     app.get(/^$/,function(req,res) { | ||||
|         res.redirect("/"); | ||||
|     // Need to ensure the url ends with a '/' so the static serving works | ||||
|     // with relative paths | ||||
|     app.get("/",function(req,res) { | ||||
|             if (req.originalUrl.slice(-1) != "/") { | ||||
|                 res.redirect(req.originalUrl+"/"); | ||||
|             } else { | ||||
|                 req.next(); | ||||
|             } | ||||
|     }); | ||||
|      | ||||
|     app.use("/",express.static(__dirname + '/../public')); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user