From eafc1e4f5de9e428a202a27ffeb6da55760fe897 Mon Sep 17 00:00:00 2001 From: Nicholas O'Leary Date: Wed, 2 Oct 2013 19:42:52 +0100 Subject: [PATCH 01/33] Failed to set http request headers - fixes #32 --- nodes/io/21-httpin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nodes/io/21-httpin.js b/nodes/io/21-httpin.js index c3e3a027b..cc6a6ebb0 100644 --- a/nodes/io/21-httpin.js +++ b/nodes/io/21-httpin.js @@ -82,7 +82,7 @@ function HTTPRequest(n) { var opts = urllib.parse(msg.url||url); opts.method = msg.method||method; if (msg.headers) { - opts.header = headers; + opts.header = msg.headers; } var req = httplib.request(opts,function(res) { res.setEncoding('utf8'); From 362bc9a805b1402f16c1b937bfe409856d794da4 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Wed, 2 Oct 2013 20:37:28 +0100 Subject: [PATCH 02/33] Add screenshot --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 10f384d3a..94f1f6fd6 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ A visual tool for wiring the Internet of Things. +![Screenshot](http://nodered.org/images/node-red-screenshot.png "Node-RED: A visual tool for wiring the Internet of Things") + ## Quick Start Check out [INSTALL](INSTALL.md) for full instructions on getting started. From f6da96e7e160fca580062f2ae0e5a1d0cac2eb40 Mon Sep 17 00:00:00 2001 From: Dave C-J Date: Wed, 2 Oct 2013 21:14:02 +0100 Subject: [PATCH 03/33] Tweak Twitter Properties UI to improve flow --- nodes/social/27-twitter.html | 35 +++++++++++++++++++---------------- nodes/social/27-twitter.js | 9 ++++----- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/nodes/social/27-twitter.html b/nodes/social/27-twitter.html index 08e80786b..98dcd23f8 100644 --- a/nodes/social/27-twitter.html +++ b/nodes/social/27-twitter.html @@ -29,8 +29,8 @@ pathname += "/"; } var callback = encodeURIComponent(location.protocol+"//"+location.hostname+":"+location.port+pathname+"twitter/"+twitterConfigNodeId+"/auth/callback"); - - $("#node-config-twitter-row").html('Click here to authenticate with Twitter.'); + + $("#node-config-twitter-row").html('Click here to authenticate with Twitter.'); $("#node-config-twitter-start").click(function() { twitterConfigNodeIntervalId = window.setTimeout(pollTwitterCredentials,2000); }); @@ -103,33 +103,36 @@ @@ -140,7 +143,7 @@ defaults: { twitter: {type:"twitter-credentials",required:true}, tags: {value:"",required:true}, - user: {value:false}, + operation: {value:"words",required:true}, name: {value:""}, topic: {value:"tweets"} }, diff --git a/nodes/social/27-twitter.js b/nodes/social/27-twitter.js index 923fec859..ef9b05787 100644 --- a/nodes/social/27-twitter.js +++ b/nodes/social/27-twitter.js @@ -24,11 +24,10 @@ function TwitterNode(n) { } RED.nodes.registerType("twitter-credentials",TwitterNode); - function TwitterInNode(n) { RED.nodes.createNode(this,n); this.active = true; - this.user = n.user; + this.oper = n.operation; this.tags = n.tags.replace(/ /g,''); this.twitter = n.twitter; this.topic = n.topic; @@ -47,11 +46,13 @@ function TwitterInNode(n) { if (this.tags !== "") { try { var thing = 'statuses/filter'; - if (this.user) { thing = 'user'; } + if (this.oper === "user") { thing = 'user'; } + if (this.oper === "site") { thing = 'site'; } function setupStream() { if (node.active) { twit.stream(thing, { track: [node.tags] }, function(stream) { //twit.stream('user', { track: [node.tags] }, function(stream) { + //twit.stream('site', { track: [node.tags] }, function(stream) { //twit.stream('statuses/filter', { track: [node.tags] }, function(stream) { node.stream = stream; stream.on('data', function(tweet) { @@ -101,8 +102,6 @@ TwitterInNode.prototype.close = function() { } } - - function TwitterOutNode(n) { RED.nodes.createNode(this,n); this.topic = n.topic; From 148f6f418e54bc4a1930de2a7959bd021f6b583c Mon Sep 17 00:00:00 2001 From: Dave C-J Date: Wed, 2 Oct 2013 21:15:12 +0100 Subject: [PATCH 04/33] slightly better IRC error catching --- nodes/social/91-irc.html | 8 ++++---- nodes/social/91-irc.js | 12 +++++------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/nodes/social/91-irc.html b/nodes/social/91-irc.html index 10f062ec9..7e0fa3cbc 100644 --- a/nodes/social/91-irc.html +++ b/nodes/social/91-irc.html @@ -65,12 +65,12 @@ -
Sending complete object will stringify the whole msg object before sending.
+
Sending the complete object will stringify the whole msg object before sending.
@@ -103,7 +103,7 @@
- +
diff --git a/nodes/social/91-irc.js b/nodes/social/91-irc.js index 4041147dc..acc7fc974 100644 --- a/nodes/social/91-irc.js +++ b/nodes/social/91-irc.js @@ -16,6 +16,7 @@ var RED = require("../../red/red"); var irc = require("irc"); +var util = require("util"); // The Server Definition - this opens (and closes) the connection function IRCServerNode(n) { @@ -26,13 +27,15 @@ function IRCServerNode(n) { this.ircclient = new irc.Client(this.server, this.nickname, { channels: [this.channel] }); + this.ircclient.addListener('error', function(message) { + util.log('[irc] '+ JSON.stringify(message)); + }); this._close = function() { this.ircclient.disconnect(); } } RED.nodes.registerType("irc-server",IRCServerNode); - IRCServerNode.prototype.close = function() { this._close(); } @@ -46,17 +49,12 @@ function IrcInNode(n) { this.ircclient = this.serverConfig.ircclient; var node = this; - this.ircclient.addListener('message', function (from, to, message) { console.log(from + ' => ' + to + ': ' + message); var msg = { "topic":from, "to":to, "payload":message }; node.send(msg); }); - this.ircclient.addListener('error', function(message) { - node.error(JSON.stringify(message)); - }); - } RED.nodes.registerType("irc in",IrcInNode); @@ -71,7 +69,7 @@ function IrcOutNode(n) { var node = this; this.on("input", function(msg) { - console.log(msg); + //console.log(msg,node.channel); if (node.sendAll) { node.ircclient.say(node.channel, JSON.stringify(msg)); } From e316c4734f450fc1521df312b62cca63c3326a61 Mon Sep 17 00:00:00 2001 From: Dave C-J Date: Wed, 2 Oct 2013 21:16:26 +0100 Subject: [PATCH 05/33] Make "alert" nodes more consistent. --- nodes/social/57-notify.html | 2 +- nodes/social/57-prowl.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nodes/social/57-notify.html b/nodes/social/57-notify.html index ed711bed0..67c04cbf3 100644 --- a/nodes/social/57-notify.html +++ b/nodes/social/57-notify.html @@ -16,7 +16,7 @@ @@ -143,7 +142,7 @@ defaults: { twitter: {type:"twitter-credentials",required:true}, tags: {value:"",required:true}, - operation: {value:"words",required:true}, + operation: {value:"false",required:true}, name: {value:""}, topic: {value:"tweets"} }, diff --git a/nodes/social/27-twitter.js b/nodes/social/27-twitter.js index ef9b05787..576ea21e1 100644 --- a/nodes/social/27-twitter.js +++ b/nodes/social/27-twitter.js @@ -27,7 +27,7 @@ RED.nodes.registerType("twitter-credentials",TwitterNode); function TwitterInNode(n) { RED.nodes.createNode(this,n); this.active = true; - this.oper = n.operation; + this.user = n.user; this.tags = n.tags.replace(/ /g,''); this.twitter = n.twitter; this.topic = n.topic; @@ -46,8 +46,7 @@ function TwitterInNode(n) { if (this.tags !== "") { try { var thing = 'statuses/filter'; - if (this.oper === "user") { thing = 'user'; } - if (this.oper === "site") { thing = 'site'; } + if (this.user == "true") { thing = 'user'; } function setupStream() { if (node.active) { twit.stream(thing, { track: [node.tags] }, function(stream) { From d36cc4fb4c30765b68c5a6e8746608d48733395d Mon Sep 17 00:00:00 2001 From: Dave C-J Date: Wed, 2 Oct 2013 23:40:08 +0100 Subject: [PATCH 07/33] Twitter tweak --- nodes/social/27-twitter.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nodes/social/27-twitter.html b/nodes/social/27-twitter.html index aebcbd856..fbde2bd3e 100644 --- a/nodes/social/27-twitter.html +++ b/nodes/social/27-twitter.html @@ -103,8 +103,8 @@ diff --git a/nodes/99-sample.js.demo b/nodes/99-sample.js.demo index a212df469..5db5b141d 100644 --- a/nodes/99-sample.js.demo +++ b/nodes/99-sample.js.demo @@ -14,38 +14,39 @@ * limitations under the License. **/ +// If you use this as a template, replace IBM Corp. with your own name. + // Sample Node-RED node file // Require main module var RED = require("../../red/red"); // The main node definition - most things happen in here -function SampleNode(n) { +function SampleNode(n) { // Create a RED node RED.nodes.createNode(this,n); - + // Store local copies of the node configuration (as defined in the .html) this.topic = n.topic; - + // Do whatever you need to do in here - declare callbacks etc // Note: this sample doesn't do anything much - it will only send // this message once at startup... // Look at other real nodes for some better ideas of what to do.... var msg = {}; - msg.topic = node.topic; + msg.topic = this.topic; msg.payload = "Hello world !" - + // send out the message to the rest of the workspace. this.send(msg); + + this.on("close", function() { + // Called when the node is shutdown - eg on redeploy. + // Allows ports to be closed, connections dropped etc. + // eg: this.client.disconnect(); + }); } // Register the node by name. This must be called before overriding any of the // Node functions. RED.nodes.registerType("sample",SampleNode); - - -SampleNode.prototype.close = function() { - // Called when the node is shutdown - eg on redeploy. - // Allows ports to be closed, connections dropped etc. - // eg: this.client.disconnect(); -} From ee92967efaa001419f4e9d91fd181df5bb0dc299 Mon Sep 17 00:00:00 2001 From: Dave C-J Date: Thu, 10 Oct 2013 15:35:26 +0100 Subject: [PATCH 28/33] Fixes for Arduino (firmata) node - to try to make it work on a Pi... very slow to initialise... was never coming ready in time... hopefully fixes Issue #35 --- nodes/hardware/35-arduino.html | 2 +- nodes/hardware/35-arduino.js | 32 ++++++++++++++++++-------------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/nodes/hardware/35-arduino.html b/nodes/hardware/35-arduino.html index e4d1a9d43..6640b77a0 100644 --- a/nodes/hardware/35-arduino.html +++ b/nodes/hardware/35-arduino.html @@ -138,7 +138,7 @@ category: 'config', defaults: { //baud: {baud:"57600",required:true}, - repeat: {value:"25",required:true,validate:RED.validators.number()}, + repeat: {value:"50",required:true,validate:RED.validators.number()}, device: {value:"",required:true} }, label: function() { diff --git a/nodes/hardware/35-arduino.js b/nodes/hardware/35-arduino.js index 1bf87178a..b81ea7cfc 100644 --- a/nodes/hardware/35-arduino.js +++ b/nodes/hardware/35-arduino.js @@ -25,12 +25,11 @@ function ArduinoNode(n) { RED.nodes.createNode(this,n); this.device = n.device; this.repeat = n.repeat||25; - util.log("[firmata] Opening"+this.device); + util.log("[firmata] Opening "+this.device); var node = this; node.toun = setInterval(function() { if (!arduinoReady) { - arduinoReady = false; if (thisboard == null) { node.board = new firmata.Board(node.device, function(err) { if (err) { @@ -44,21 +43,22 @@ function ArduinoNode(n) { }); } else { - util.log("[firmata] Arduino already connected"); node.board = thisboard; - console.log(node.board.sp); node.board.removeAllListeners(); arduinoReady = true; clearInterval(node.toun); + node.toun = false; + util.log("[firmata] Arduino already connected"); } } else { util.log("[firmata] Waiting for Firmata"); } }, 10000); // wait for firmata to connect to arduino this.on('close', function() { //this.board.sp.close(function() { console.log("[firmata] Serial port closed"); arduinoReady = false; }); + arduinoReady = false; if (node.toun) { clearInterval(node.toun); - util.log("[arduino] arduino wait loop stopped"); + util.log("[firmata] arduino wait loop stopped"); } util.log("[firmata] Stopped"); }); @@ -80,9 +80,11 @@ function DuinoNodeIn(n) { var node = this; node.toui = setInterval(function() { - if (arduinoReady) { + if (thisboard != null) { + node.board = thisboard; clearInterval(node.toui); - console.log(node.state,node.pin,node.board.MODES[node.state]); + node.toui = false; + //console.log(node.state,node.pin,node.board.MODES[node.state]); node.board.pinMode(node.pin, node.board.MODES[node.state]); node.board.setSamplingInterval(node.repeat); var oldrdg = ""; @@ -108,12 +110,12 @@ function DuinoNodeIn(n) { this.on('close', function() { if (node.toui) { clearInterval(node.toui); - util.log("[arduino] input wait loop stopped"); + util.log("[firmata] input wait loop stopped"); } }); } else { - util.log("[arduino] Serial Port not Configured"); + util.log("[firmata] Serial Port not Configured"); } } RED.nodes.registerType("arduino in",DuinoNodeIn); @@ -133,7 +135,7 @@ function DuinoNodeOut(n) { this.on("input", function(msg) { //console.log(msg); - if (arduinoReady) { + if (thisboard != null) { if (node.state == "OUTPUT") { if ((msg.payload == true)||(msg.payload == 1)||(msg.payload.toString().toLowerCase() == "on")) { node.board.digitalWrite(node.pin, node.board.HIGH); @@ -161,22 +163,24 @@ function DuinoNodeOut(n) { }); node.touo = setInterval(function() { - if (arduinoReady) { + if (thisboard != null) { clearInterval(node.touo); - //console.log(node.state,node.pin,node.board.MODES[node.state]); + node.touo = false; + node.board = thisboard; node.board.pinMode(node.pin, node.board.MODES[node.state]); } + else { util.log("[firmata] waiting for arduino to connect"); } }, 5000); // loop to wait for firmata to connect to arduino this.on('close', function() { if (node.touo) { clearInterval(node.touo); - util.log("[arduino] output wait loop stopped"); + util.log("[firmata] output wait loop stopped"); } }); } else { - util.log("[arduino] Serial Port not Configured"); + util.log("[firmata] Serial Port not Configured"); } } RED.nodes.registerType("arduino out",DuinoNodeOut); From 9741c36fdbd0d4e27bdd0edb42ee1416273dd56a Mon Sep 17 00:00:00 2001 From: Dave C-J Date: Fri, 11 Oct 2013 21:42:34 +0100 Subject: [PATCH 29/33] New UDP node to go with updated TCP node - includes multicast support --- nodes/io/32-udp.html | 176 +++++++++++++++++++++++++++++++++++++++++++ nodes/io/32-udp.js | 115 ++++++++++++++++++++++++++++ 2 files changed, 291 insertions(+) create mode 100644 nodes/io/32-udp.html create mode 100644 nodes/io/32-udp.js diff --git a/nodes/io/32-udp.html b/nodes/io/32-udp.html new file mode 100644 index 000000000..25dbdc2ac --- /dev/null +++ b/nodes/io/32-udp.html @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + diff --git a/nodes/io/32-udp.js b/nodes/io/32-udp.js new file mode 100644 index 000000000..39b7b1222 --- /dev/null +++ b/nodes/io/32-udp.js @@ -0,0 +1,115 @@ +/** + * Copyright 2013 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var RED = require("../../red/red"); +var dgram = require('dgram'); + +// The Input Node +function UDPin(n) { + RED.nodes.createNode(this,n); + this.group = n.group; + this.port = n.port; + this.host = n.host || null; + this.datatype = n.datatype; + this.iface = n.iface || null; + this.multicast = n.multicast; + var node = this; + + var server = dgram.createSocket('udp4'); + + server.on("error", function (err) { + console.log("udp listener error:\n" + err.stack); + server.close(); + }); + + server.on('message', function (message, remote) { + var msg; + if (node.datatype =="base64") { msg = { payload:message.toString('base64'), fromip:remote.address+':'+remote.port }; } + else if (node.datatype =="utf8") { msg = { payload:message.toString('utf8'), fromip:remote.address+':'+remote.port }; } + else { msg = { payload:message, fromip:remote.address+':'+remote.port }; } + node.send(msg); + }); + + server.on('listening', function () { + var address = server.address(); + node.log('udp listener at ' + address.address + ":" + address.port); + if (node.multicast == "true") { + server.setBroadcast(true) + server.setMulticastTTL(128); + server.addMembership(node.group,node.iface); + node.log("udp multicast group "+node.group); + } + }); + + node.on("close", function() { + try { + server.close(); + node.log('udp listener stopped'); + } + catch (err) { console.log(err); } + }); + + server.bind(node.port,node.host); +} +RED.nodes.registerType("udp in",UDPin); + + +// The Output Node +function UDPout(n) { + RED.nodes.createNode(this,n); + //this.group = n.group; + this.port = n.port; + this.base64 = n.base64; + this.addr = n.addr; + this.iface = n.iface || null; + this.multicast = n.multicast; + var node = this; + + var sock = dgram.createSocket('udp4'); // only use ipv4 for now + sock.bind(node.port); // have to bind before you can enable broadcast... + if (this.multicast != "false") { + sock.setBroadcast(true); // turn on broadcast + if (this.multicast == "multi") { + sock.setMulticastTTL(128); + sock.addMembership(node.addr,node.iface); // Add to the multicast group + node.log('udp multicast ready : '+node.addr+":"+node.port); + } + else node.log('udp broadcast ready : '+node.addr+":"+node.port); + } + else node.log('udp ready : '+node.addr+":"+node.port); + + node.on("input", function(msg) { + if (msg.payload != null) { + //console.log("UDP:",msg.payload); + var message; + if (node.base64) { message = new Buffer(b64string, 'base64'); } + else { message = new Buffer(""+msg.payload); } + console.log("UDP send :",node.addr,node.port); + sock.send(message, 0, message.length, node.port, node.addr, function(err, bytes) { + if (err) node.error("udp : "+err); + }); + } + }); + + node.on("close", function() { + try { + sock.close(); + node.log('udp output stopped'); + } + catch (err) { console.log(err); } + }); +} +RED.nodes.registerType("udp out",UDPout); From 4c9f3bcdb6c38c58fd82117a0293290922207da3 Mon Sep 17 00:00:00 2001 From: Nicholas O'Leary Date: Sat, 12 Oct 2013 21:43:26 +0100 Subject: [PATCH 30/33] Keep node icon centered when resizing --- public/red/ui/view.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/public/red/ui/view.js b/public/red/ui/view.js index d8fe0bdeb..42d815666 100644 --- a/public/red/ui/view.js +++ b/public/red/ui/view.js @@ -649,7 +649,13 @@ RED.view = function() { //mainRect.on("touchend",nodeMouseUp); if (d._def.icon) { - var icon = node.append("image").attr("xlink:href","icons/"+d._def.icon).attr("class","node_icon").attr("x",0).attr("y",0).attr("width","15").attr("height",function(d){return Math.min(50,d.h);}); + var icon = node.append("image") + .attr("xlink:href","icons/"+d._def.icon) + .attr("class","node_icon") + .attr("x",0).attr("y",function(d){return (d.h-Math.min(50,d.h))/2;}) + .attr("width","15") + .attr("height", function(d){return Math.min(50,d.h);}); + if (d._def.align) { icon.attr('class','node_icon node_icon_'+d._def.align); } @@ -747,7 +753,7 @@ RED.view = function() { var port = d3.select(this); port.attr("y",function(d){return (d.h/2)-5;}) }); - thisNode.selectAll(".node_icon").attr("height",function(d){return Math.min(50,d.h);}); + thisNode.selectAll(".node_icon").attr("height",function(d){return Math.min(50,d.h);}).attr("y",function(d){return (d.h-Math.min(50,d.h))/2;}); thisNode.selectAll('.node_right_button_group').attr("transform",function(d){return "translate("+(d.w-100)+","+0+")";}); thisNode.selectAll('.node_right_button').attr("transform",function(d){return "translate("+(d.w-100)+","+0+")";}).attr("fill",function(d) { From 8c6aa07d91d9988fd5c9dedae5af91f26c5aee93 Mon Sep 17 00:00:00 2001 From: Nicholas O'Leary Date: Sat, 12 Oct 2013 21:54:07 +0100 Subject: [PATCH 31/33] Allow node properties to be objects/arrays --- public/red/ui/editor.js | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/public/red/ui/editor.js b/public/red/ui/editor.js index fc85f58cc..98605baf6 100644 --- a/public/red/ui/editor.js +++ b/public/red/ui/editor.js @@ -143,8 +143,34 @@ RED.editor = function() { var changes = {}; var changed = false; var wasDirty = RED.view.dirty(); + + if (editing_node._def.oneditsave) { + var oldValues = {}; + for (var d in editing_node._def.defaults) { + if (typeof editing_node[d] === "string" || typeof editing_node[d] === "number") { + oldValues[d] = editing_node[d]; + } else { + oldValues[d] = $.extend(true,{},{v:editing_node[d]}).v; + } + } editing_node._def.oneditsave.call(editing_node); + + for (var d in editing_node._def.defaults) { + if (oldValues[d] === null || typeof oldValues[d] === "string" || typeof oldValues[d] === "number") { + if (oldValues[d] !== editing_node[d]) { + changes[d] = oldValues[d]; + changed = true; + } + } else { + if (JSON.stringify(oldValues[d]) !== JSON.stringify(editing_node[d])) { + changes[d] = oldValues[d]; + changed = true; + } + } + } + + } if (editing_node._def.defaults) { @@ -177,7 +203,6 @@ RED.editor = function() { changes[d] = editing_node[d]; editing_node[d] = newValue; changed = true; - RED.view.dirty(true); } } } @@ -185,6 +210,7 @@ RED.editor = function() { var removedLinks = updateNodeProperties(editing_node); if (changed) { + RED.view.dirty(true); RED.history.push({t:'edit',node:editing_node,changes:changes,links:removedLinks,dirty:wasDirty}); } From 1fb185d081e1ca7b990d04a0eadb2423c1383cba Mon Sep 17 00:00:00 2001 From: Dave C-J Date: Sat, 12 Oct 2013 22:00:34 +0100 Subject: [PATCH 32/33] Catch SIGINT (ctrl-C/break) and try to close nodes prior to exit. --- red.js | 8 ++++++-- red/nodes.js | 35 ++++++++++++----------------------- 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/red.js b/red.js index c46ce7a9d..55a4c6022 100644 --- a/red.js +++ b/red.js @@ -56,7 +56,7 @@ app.use(settings.httpRoot,red); RED.start(); server.listen(settings.uiPort,function() { - util.log('[red] Server now running at http'+(settings.https?'s':'')+'://127.0.0.1:'+settings.uiPort+settings.httpRoot); + util.log('[red] Server now running at http'+(settings.https?'s':'')+'://127.0.0.1:'+settings.uiPort+settings.httpRoot); }); process.on('uncaughtException',function(err) { @@ -70,4 +70,8 @@ process.on('uncaughtException',function(err) { process.exit(1); }); - +process.on('SIGINT', function () { + RED.nodes.closedown(); + console.log("Exiting Node-RED. Thank you."); + process.exit(); +}); diff --git a/red/nodes.js b/red/nodes.js index 0cfebe9a0..c3d901223 100644 --- a/red/nodes.js +++ b/red/nodes.js @@ -42,7 +42,6 @@ function getCallerFilename(type) { return stack[0].getFileName(); } - var registry = (function() { var nodes = {}; var logHandlers = []; @@ -91,7 +90,6 @@ 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"); @@ -117,7 +115,6 @@ var node_type_registry = (function() { result += node_configs[nt]; } return result; - } } return obj; @@ -176,7 +173,6 @@ Node.prototype.send = function(msg) { } module.exports.Node = Node; - Node.prototype.receive = function(msg) { this.emit("input",msg); } @@ -197,9 +193,6 @@ Node.prototype.error = function(msg) { this.emit("log",o); } - - - var credentials = {}; var credentialsFile = "credentials.json"; if (fs.existsSync(credentialsFile)) { @@ -225,8 +218,6 @@ module.exports.deleteCredentials = function(id) { delete credentials[id]; saveCredentialsFile(); } - - module.exports.createNode = function(node,def) { Node.call(node,def); } @@ -257,12 +248,9 @@ module.exports.load = function() { }); } loadNodes(__dirname+"/../nodes"); - //events.emit("nodes-loaded"); } - - var activeConfig = null; var missingTypes = []; @@ -279,10 +267,15 @@ events.on('type-registered',function(type) { } }); - module.exports.getNode = function(nid) { return registry.get(nid); } + +module.exports.closedown = function() { + util.log("[red] Closing Down Nodes"); + registry.clear(); +} + module.exports.setConfig = function(conf) { if (activeConfig&&activeConfig.length > 0) { util.log("[red] Stopping flows"); @@ -293,7 +286,6 @@ module.exports.setConfig = function(conf) { } var parseConfig = function() { - missingTypes = []; for (var i in activeConfig) { var type = activeConfig[i].type; @@ -307,7 +299,6 @@ var parseConfig = function() { for (var i in missingTypes) { util.log("[red] - "+missingTypes[i]); } - return; } @@ -317,19 +308,18 @@ var parseConfig = function() { var nn = null; var nt = node_type_registry.get(activeConfig[i].type); if (nt) { - try { - nn = new nt(activeConfig[i]); - } - catch (err) { - util.log("[red] "+activeConfig[i].type+" : "+err); - } + try { + nn = new nt(activeConfig[i]); + } + catch (err) { + util.log("[red] "+activeConfig[i].type+" : "+err); + } } // console.log(nn); if (nn == null) { util.log("[red] unknown type: "+activeConfig[i].type); } } - // Clean up any orphaned credentials var deletedCredentials = false; for (var c in credentials) { @@ -343,5 +333,4 @@ var parseConfig = function() { saveCredentialsFile(); } events.emit("nodes-started"); - } From e60120f7c9426edc0de1c0d43d116c56e38be1f7 Mon Sep 17 00:00:00 2001 From: Dave C-J Date: Sun, 13 Oct 2013 10:25:01 +0100 Subject: [PATCH 33/33] Make RED.stop as per @knollery suggestion. --- red.js | 4 ++-- red/red.js | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/red.js b/red.js index 55a4c6022..4001cba12 100644 --- a/red.js +++ b/red.js @@ -71,7 +71,7 @@ process.on('uncaughtException',function(err) { }); process.on('SIGINT', function () { - RED.nodes.closedown(); - console.log("Exiting Node-RED. Thank you."); + RED.stop(); + util.log('[red] Exiting Node-RED. Thank you.'); process.exit(); }); diff --git a/red/red.js b/red/red.js index 23134df57..b2d18b2c5 100644 --- a/red/red.js +++ b/red/red.js @@ -14,7 +14,7 @@ * limitations under the License. **/ -var events = require("./events"); +var events = require("./events"); var server = require("./server"); var nodes = require("./nodes"); var library = require("./library"); @@ -24,23 +24,23 @@ var settings = null; var events = require("events"); var RED = { - + init: function(httpServer,userSettings) { settings = userSettings; server.init(httpServer,settings); library.init(); return server.app; }, - + start: server.start, - nodes: nodes, library: library, - events: events + events: events, + stop: nodes.closedown, }; RED.__defineGetter__("app", function() { return server.app }); RED.__defineGetter__("server", function() { return server.server }); RED.__defineGetter__("settings", function() { return settings }); -module.exports = RED; +module.exports = RED;