mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
b2f4bc915e | ||
|
13deef189d | ||
|
b5a8a7288b | ||
|
b6fd103b37 | ||
|
6a17a7d4c2 | ||
|
c39f4f9738 | ||
|
c20128b80f | ||
|
0b7fa1ab5c | ||
|
775297d625 | ||
|
d00624f9e3 | ||
|
d702caa5be | ||
|
729036ec0b | ||
|
eee8f89146 | ||
|
4ae5f34d2e | ||
|
18ae7108f5 |
@@ -134,6 +134,9 @@
|
||||
}
|
||||
ws.onmessage = function(event) {
|
||||
var o = JSON.parse(event.data);
|
||||
if (o.heartbeat) {
|
||||
return;
|
||||
}
|
||||
//console.log(msg);
|
||||
var msg = document.createElement("div");
|
||||
msg.onmouseover = function() {
|
||||
|
@@ -57,6 +57,26 @@ function DebugNode(n) {
|
||||
});
|
||||
}
|
||||
|
||||
var lastSentTime = (new Date()).getTime();
|
||||
|
||||
setInterval(function() {
|
||||
var now = (new Date()).getTime();
|
||||
if (now-lastSentTime > 15000) {
|
||||
lastSentTime = now;
|
||||
for (var i in DebugNode.activeConnections) {
|
||||
var ws = DebugNode.activeConnections[i];
|
||||
try {
|
||||
var p = JSON.stringify({heartbeat:lastSentTime});
|
||||
ws.send(p);
|
||||
} catch(err) {
|
||||
util.log("[debug] ws heartbeat error : "+err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 15000);
|
||||
|
||||
|
||||
|
||||
RED.nodes.registerType("debug",DebugNode);
|
||||
|
||||
DebugNode.send = function(msg) {
|
||||
@@ -85,7 +105,7 @@ DebugNode.send = function(msg) {
|
||||
if (msg.msg.length > debuglength) {
|
||||
msg.msg = msg.msg.substr(0,debuglength) +" ....";
|
||||
}
|
||||
|
||||
|
||||
for (var i in DebugNode.activeConnections) {
|
||||
var ws = DebugNode.activeConnections[i];
|
||||
try {
|
||||
@@ -95,6 +115,7 @@ DebugNode.send = function(msg) {
|
||||
util.log("[debug] ws error : "+err);
|
||||
}
|
||||
}
|
||||
lastSentTime = (new Date()).getTime();
|
||||
}
|
||||
|
||||
DebugNode.activeConnections = [];
|
||||
|
@@ -29,9 +29,18 @@
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="template">
|
||||
<p>Creates new messages based on a template.</p>
|
||||
<p>Very useful for creating boilerplate web pages, emails, tweets and so on.</p>
|
||||
<p>Uses the <i><a href="http://mustache.github.io/mustache.5.html" target="_new">Mustache</a></i> format.</p>
|
||||
<p>Creates a new payload based on the provided template.</p>
|
||||
<p>This uses the <i><a href="http://mustache.github.io/mustache.5.html" target="_new">mustache</a></i> format.</p>
|
||||
<p>For example, when a template of:
|
||||
<pre>Hello {{name}}. Today is {{date}}</pre>
|
||||
<p>receives a message containing:
|
||||
<pre>{
|
||||
name: "Fred",
|
||||
date: "Monday"
|
||||
payload: ...
|
||||
}</pre>
|
||||
<p>The resulting payload will be:
|
||||
<pre>Hello Fred. Today is Monday</pre>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
@@ -138,6 +138,7 @@ function HTTPRequest(n) {
|
||||
var node = this;
|
||||
var credentials = RED.nodes.getCredentials(n.id);
|
||||
this.on("input",function(msg) {
|
||||
var url;
|
||||
if (msg.url) {
|
||||
url = msg.url;
|
||||
} else if (isTemplatedUrl) {
|
||||
@@ -145,7 +146,6 @@ function HTTPRequest(n) {
|
||||
} else {
|
||||
url = nodeUrl;
|
||||
}
|
||||
var url = msg.url||nodeUrl;
|
||||
var method = (msg.method||nodeMethod).toUpperCase();
|
||||
var opts = urllib.parse(url);
|
||||
opts.method = method;
|
||||
|
@@ -16,6 +16,7 @@
|
||||
var util = require("util");
|
||||
var mqtt = require("mqtt");
|
||||
var events = require("events");
|
||||
//var inspect = require("sys").inspect;
|
||||
|
||||
//var Client = module.exports.Client = function(
|
||||
|
||||
@@ -44,131 +45,143 @@ function MQTTClient(port,host) {
|
||||
util.inherits(MQTTClient, events.EventEmitter);
|
||||
|
||||
MQTTClient.prototype.connect = function(options) {
|
||||
var self = this;
|
||||
options = options||{};
|
||||
self.options = options;
|
||||
self.options.keepalive = options.keepalive||15;
|
||||
self.options.clean = self.options.clean||true;
|
||||
self.options.protocolId = 'MQIsdp';
|
||||
self.options.protocolVersion = 3;
|
||||
|
||||
self.client = mqtt.createConnection(this.port,this.host,function(err,client) {
|
||||
if (err) {
|
||||
self.connected = false;
|
||||
self.connectionError = true;
|
||||
self.emit('connectionlost',err);
|
||||
return;
|
||||
}
|
||||
client.on('close',function(e) {
|
||||
clearInterval(self.watchdog);
|
||||
if (!self.connectionError) {
|
||||
if (!this.connected) {
|
||||
var self = this;
|
||||
options = options||{};
|
||||
self.options = options;
|
||||
self.options.keepalive = options.keepalive||15;
|
||||
self.options.clean = self.options.clean||true;
|
||||
self.options.protocolId = 'MQIsdp';
|
||||
self.options.protocolVersion = 3;
|
||||
|
||||
self.client = mqtt.createConnection(this.port,this.host,function(err,client) {
|
||||
if (err) {
|
||||
self.connected = false;
|
||||
clearInterval(self.watchdog);
|
||||
self.connectionError = true;
|
||||
//util.log('[mqtt] ['+self.uid+'] connection error 1 : '+inspect(err));
|
||||
self.emit('connectionlost',err);
|
||||
return;
|
||||
}
|
||||
client.on('close',function(e) {
|
||||
//util.log('[mqtt] ['+self.uid+'] on close');
|
||||
clearInterval(self.watchdog);
|
||||
if (!self.connectionError) {
|
||||
if (self.connected) {
|
||||
self.connected = false;
|
||||
self.emit('connectionlost',e);
|
||||
} else {
|
||||
self.emit('disconnect');
|
||||
}
|
||||
}
|
||||
});
|
||||
client.on('error',function(e) {
|
||||
//util.log('[mqtt] ['+self.uid+'] on error : '+inspect(e));
|
||||
clearInterval(self.watchdog);
|
||||
if (self.connected) {
|
||||
self.connected = false;
|
||||
self.emit('connectionlost',e);
|
||||
} else {
|
||||
self.emit('disconnect');
|
||||
}
|
||||
}
|
||||
});
|
||||
client.on('error',function(e) {
|
||||
clearInterval(self.watchdog);
|
||||
if (self.connected) {
|
||||
self.connected = false;
|
||||
self.emit('connectionlost',e);
|
||||
}
|
||||
});
|
||||
client.on('connack',function(packet) {
|
||||
if (packet.returnCode == 0) {
|
||||
self.watchdog = setInterval(function(self) {
|
||||
var now = (new Date()).getTime();
|
||||
if (now - self.lastOutbound > self.options.keepalive*500 || now - self.lastInbound > self.options.keepalive*500) {
|
||||
if (self.pingOutstanding) {
|
||||
try {
|
||||
self.client.disconnect();
|
||||
} catch (err) {
|
||||
}
|
||||
} else {
|
||||
self.lastOutbound = (new Date()).getTime();
|
||||
self.lastInbound = (new Date()).getTime();
|
||||
self.pingOutstanding = true;
|
||||
self.client.pingreq();
|
||||
}
|
||||
}
|
||||
|
||||
},self.options.keepalive*500,self);
|
||||
self.pingOutstanding = false;
|
||||
self.lastInbound = (new Date()).getTime()
|
||||
self.lastOutbound = (new Date()).getTime()
|
||||
self.connected = true;
|
||||
self.connectionError = false;
|
||||
self.emit('connect');
|
||||
} else {
|
||||
self.connected = false;
|
||||
self.emit('connectionlost');
|
||||
}
|
||||
});
|
||||
client.on('suback',function(packet) {
|
||||
self.lastInbound = (new Date()).getTime()
|
||||
var topic = self.pendingSubscriptions[packet.messageId];
|
||||
self.emit('subscribe',topic,packet.granted[0]);
|
||||
delete self.pendingSubscriptions[packet.messageId];
|
||||
});
|
||||
client.on('unsuback',function(packet) {
|
||||
self.lastInbound = (new Date()).getTime()
|
||||
var topic = self.pendingSubscriptions[packet.messageId];
|
||||
self.emit('unsubscribe',topic,packet.granted[0]);
|
||||
delete self.pendingSubscriptions[packet.messageId];
|
||||
});
|
||||
client.on('publish',function(packet) {
|
||||
self.lastInbound = (new Date()).getTime()
|
||||
if (packet.qos < 2) {
|
||||
var p = packet;
|
||||
self.emit('message',p.topic,p.payload,p.qos,p.retain);
|
||||
} else {
|
||||
self.inboundMessages[packet.messageId] = packet;
|
||||
this.lastOutbound = (new Date()).getTime()
|
||||
self.client.pubrec(packet);
|
||||
}
|
||||
if (packet.qos == 1) {
|
||||
this.lastOutbound = (new Date()).getTime()
|
||||
self.client.puback(packet);
|
||||
}
|
||||
});
|
||||
|
||||
client.on('pubrel',function(packet) {
|
||||
self.lastInbound = (new Date()).getTime()
|
||||
var p = self.inboundMessages[packet.messageId];
|
||||
if (p) {
|
||||
self.emit('message',p.topic,p.payload,p.qos,p.retain);
|
||||
delete self.inboundMessages[packet.messageId];
|
||||
}
|
||||
self.lastOutbound = (new Date()).getTime()
|
||||
self.client.pubcomp(packet);
|
||||
});
|
||||
|
||||
client.on('puback',function(packet) {
|
||||
self.lastInbound = (new Date()).getTime()
|
||||
// outbound qos-1 complete
|
||||
});
|
||||
|
||||
client.on('pubrec',function(packet) {
|
||||
self.lastInbound = (new Date()).getTime()
|
||||
self.lastOutbound = (new Date()).getTime()
|
||||
self.client.pubrel(packet);
|
||||
});
|
||||
client.on('pubcomp',function(packet) {
|
||||
self.lastInbound = (new Date()).getTime()
|
||||
// outbound qos-2 complete
|
||||
});
|
||||
client.on('pingresp',function(packet) {
|
||||
self.lastInbound = (new Date()).getTime()
|
||||
self.pingOutstanding = false;
|
||||
});
|
||||
|
||||
this.lastOutbound = (new Date()).getTime()
|
||||
this.connectionError = false;
|
||||
client.connect(self.options);
|
||||
});
|
||||
});
|
||||
client.on('connack',function(packet) {
|
||||
if (packet.returnCode == 0) {
|
||||
self.watchdog = setInterval(function(self) {
|
||||
var now = (new Date()).getTime();
|
||||
|
||||
//util.log('[mqtt] ['+self.uid+'] watchdog '+inspect({connected:self.connected,connectionError:self.connectionError,pingOutstanding:self.pingOutstanding,now:now,lastOutbound:self.lastOutbound,lastInbound:self.lastInbound}));
|
||||
|
||||
if (now - self.lastOutbound > self.options.keepalive*500 || now - self.lastInbound > self.options.keepalive*500) {
|
||||
if (self.pingOutstanding) {
|
||||
//util.log('[mqtt] ['+self.uid+'] watchdog pingOustanding - disconnect');
|
||||
try {
|
||||
self.client.disconnect();
|
||||
} catch (err) {
|
||||
}
|
||||
} else {
|
||||
//util.log('[mqtt] ['+self.uid+'] watchdog pinging');
|
||||
self.lastOutbound = (new Date()).getTime();
|
||||
self.lastInbound = (new Date()).getTime();
|
||||
self.pingOutstanding = true;
|
||||
self.client.pingreq();
|
||||
}
|
||||
}
|
||||
|
||||
},self.options.keepalive*500,self);
|
||||
self.pingOutstanding = false;
|
||||
self.lastInbound = (new Date()).getTime()
|
||||
self.lastOutbound = (new Date()).getTime()
|
||||
self.connected = true;
|
||||
self.connectionError = false;
|
||||
self.emit('connect');
|
||||
} else {
|
||||
self.connected = false;
|
||||
self.emit('connectionlost');
|
||||
}
|
||||
});
|
||||
client.on('suback',function(packet) {
|
||||
self.lastInbound = (new Date()).getTime()
|
||||
var topic = self.pendingSubscriptions[packet.messageId];
|
||||
self.emit('subscribe',topic,packet.granted[0]);
|
||||
delete self.pendingSubscriptions[packet.messageId];
|
||||
});
|
||||
client.on('unsuback',function(packet) {
|
||||
self.lastInbound = (new Date()).getTime()
|
||||
var topic = self.pendingSubscriptions[packet.messageId];
|
||||
self.emit('unsubscribe',topic,packet.granted[0]);
|
||||
delete self.pendingSubscriptions[packet.messageId];
|
||||
});
|
||||
client.on('publish',function(packet) {
|
||||
self.lastInbound = (new Date()).getTime()
|
||||
if (packet.qos < 2) {
|
||||
var p = packet;
|
||||
self.emit('message',p.topic,p.payload,p.qos,p.retain);
|
||||
} else {
|
||||
self.inboundMessages[packet.messageId] = packet;
|
||||
this.lastOutbound = (new Date()).getTime()
|
||||
self.client.pubrec(packet);
|
||||
}
|
||||
if (packet.qos == 1) {
|
||||
this.lastOutbound = (new Date()).getTime()
|
||||
self.client.puback(packet);
|
||||
}
|
||||
});
|
||||
|
||||
client.on('pubrel',function(packet) {
|
||||
self.lastInbound = (new Date()).getTime()
|
||||
var p = self.inboundMessages[packet.messageId];
|
||||
if (p) {
|
||||
self.emit('message',p.topic,p.payload,p.qos,p.retain);
|
||||
delete self.inboundMessages[packet.messageId];
|
||||
}
|
||||
self.lastOutbound = (new Date()).getTime()
|
||||
self.client.pubcomp(packet);
|
||||
});
|
||||
|
||||
client.on('puback',function(packet) {
|
||||
self.lastInbound = (new Date()).getTime()
|
||||
// outbound qos-1 complete
|
||||
});
|
||||
|
||||
client.on('pubrec',function(packet) {
|
||||
self.lastInbound = (new Date()).getTime()
|
||||
self.lastOutbound = (new Date()).getTime()
|
||||
self.client.pubrel(packet);
|
||||
});
|
||||
client.on('pubcomp',function(packet) {
|
||||
self.lastInbound = (new Date()).getTime()
|
||||
// outbound qos-2 complete
|
||||
});
|
||||
client.on('pingresp',function(packet) {
|
||||
//util.log('[mqtt] ['+self.uid+'] received pingresp');
|
||||
self.lastInbound = (new Date()).getTime()
|
||||
self.pingOutstanding = false;
|
||||
});
|
||||
|
||||
this.lastOutbound = (new Date()).getTime()
|
||||
this.connectionError = false;
|
||||
client.connect(self.options);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
MQTTClient.prototype.subscribe = function(topic,qos) {
|
||||
|
@@ -34,6 +34,7 @@ module.exports = {
|
||||
connections[id] = function() {
|
||||
var uid = (1+Math.random()*4294967295).toString(16);
|
||||
var client = mqtt.createClient(port,broker);
|
||||
client.uid = uid;
|
||||
client.setMaxListeners(0);
|
||||
var options = {keepalive:15};
|
||||
options.clientId = clientid || 'mqtt_' + (1+Math.random()*4294967295).toString(16);
|
||||
@@ -73,7 +74,7 @@ module.exports = {
|
||||
client.once(a,b);
|
||||
},
|
||||
connect: function() {
|
||||
if (!client.isConnected() && !connecting) {
|
||||
if (client && !client.isConnected() && !connecting) {
|
||||
connecting = true;
|
||||
client.connect(options);
|
||||
}
|
||||
@@ -90,7 +91,6 @@ module.exports = {
|
||||
client.on('connect',function() {
|
||||
if (client) {
|
||||
util.log('[mqtt] ['+uid+'] connected to broker tcp://'+broker+':'+port);
|
||||
|
||||
connecting = false;
|
||||
for (var s in subscriptions) {
|
||||
var topic = subscriptions[s].topic;
|
||||
@@ -108,13 +108,13 @@ module.exports = {
|
||||
});
|
||||
client.on('connectionlost', function(err) {
|
||||
util.log('[mqtt] ['+uid+'] connection lost to broker tcp://'+broker+':'+port);
|
||||
connecting = false;
|
||||
setTimeout(function() {
|
||||
if (client) {
|
||||
client.connect(options);
|
||||
}
|
||||
obj.connect();
|
||||
}, settings.mqttReconnectTime||5000);
|
||||
});
|
||||
client.on('disconnect', function() {
|
||||
connecting = false;
|
||||
util.log('[mqtt] ['+uid+'] disconnected from broker tcp://'+broker+':'+port);
|
||||
});
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name" : "node-red",
|
||||
"version" : "0.7.0",
|
||||
"version" : "0.7.2",
|
||||
"description" : "A visual tool for wiring the Internet of Things",
|
||||
"homepage" : "http://nodered.org",
|
||||
"license" : "Apache",
|
||||
@@ -11,7 +11,7 @@
|
||||
"main" : "red/red.js",
|
||||
"scripts" : {
|
||||
"start": "node red.js",
|
||||
"test": "grunt"
|
||||
"test": "./node_modules/.bin/grunt"
|
||||
},
|
||||
"contributors": [
|
||||
{"name": "Nick O'Leary"},
|
||||
@@ -42,6 +42,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"grunt": "0.4.4",
|
||||
"grunt-cli": "0.1.13",
|
||||
"grunt-simple-mocha": "0.4.0",
|
||||
"mocha": "1.18.2",
|
||||
"should": "3.3.1"
|
||||
|
@@ -246,7 +246,7 @@
|
||||
<form class="form-horizontal">
|
||||
<div class="form-row">
|
||||
<ul id="node-dialog-library-breadcrumbs" class="breadcrumb">
|
||||
<li class="active"><a href="#">Library</a> <span class="divider">/</span></li>
|
||||
<li class="active"><a href="#">Library</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
|
@@ -80,30 +80,32 @@ var RED = function() {
|
||||
$("#btn-icn-deploy").addClass('spinner');
|
||||
RED.view.dirty(false);
|
||||
|
||||
d3.xhr("flows").header("Content-type", "application/json")
|
||||
.post(JSON.stringify(nns),function(err,resp) {
|
||||
$("#btn-icn-deploy").removeClass('spinner');
|
||||
$("#btn-icn-deploy").addClass('icon-upload');
|
||||
if (resp && resp.status == 204) {
|
||||
RED.notify("Successfully deployed","success");
|
||||
RED.nodes.eachNode(function(node) {
|
||||
if (node.changed) {
|
||||
node.dirty = true;
|
||||
node.changed = false;
|
||||
}
|
||||
});
|
||||
// Once deployed, cannot undo back to a clean state
|
||||
RED.history.markAllDirty();
|
||||
RED.view.redraw();
|
||||
} else {
|
||||
RED.view.dirty(true);
|
||||
if (resp) {
|
||||
RED.notify("<strong>Error</strong>: "+resp,"error");
|
||||
} else {
|
||||
RED.notify("<strong>Error</strong>: no response from server","error");
|
||||
}
|
||||
console.log(err,resp);
|
||||
$.ajax({
|
||||
url:"flows",
|
||||
type: "POST",
|
||||
data: JSON.stringify(nns),
|
||||
contentType: "application/json; charset=utf-8"
|
||||
}).done(function(data,textStatus,xhr) {
|
||||
RED.notify("Successfully deployed","success");
|
||||
RED.nodes.eachNode(function(node) {
|
||||
if (node.changed) {
|
||||
node.dirty = true;
|
||||
node.changed = false;
|
||||
}
|
||||
});
|
||||
// Once deployed, cannot undo back to a clean state
|
||||
RED.history.markAllDirty();
|
||||
RED.view.redraw();
|
||||
}).fail(function(xhr,textStatus,err) {
|
||||
RED.view.dirty(true);
|
||||
if (xhr.responseText) {
|
||||
RED.notify("<strong>Error</strong>: "+xhr.responseText,"error");
|
||||
} else {
|
||||
RED.notify("<strong>Error</strong>: no response from server","error");
|
||||
}
|
||||
}).always(function() {
|
||||
$("#btn-icn-deploy").removeClass('spinner');
|
||||
$("#btn-icn-deploy").addClass('icon-upload');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -150,7 +152,7 @@ var RED = function() {
|
||||
}
|
||||
|
||||
function loadFlows() {
|
||||
d3.json("flows",function(nodes) {
|
||||
$.getJSON("flows",function(nodes) {
|
||||
RED.nodes.import(nodes);
|
||||
RED.view.dirty(false);
|
||||
RED.view.redraw();
|
||||
|
@@ -17,7 +17,7 @@ RED.library = function() {
|
||||
|
||||
|
||||
function loadFlowLibrary() {
|
||||
d3.json("library/flows",function(data) {
|
||||
$.getJSON("library/flows",function(data) {
|
||||
//console.log(data);
|
||||
|
||||
var buildMenu = function(data,root) {
|
||||
@@ -84,7 +84,7 @@ RED.library = function() {
|
||||
li.onclick = function () {
|
||||
var dirName = v;
|
||||
return function(e) {
|
||||
var bcli = $('<li class="active"><a href="#">'+dirName+'</a> <span class="divider">/</span></li>');
|
||||
var bcli = $('<li class="active"><span class="divider">/</span> <a href="#">'+dirName+'</a></li>');
|
||||
$("a",bcli).click(function(e) {
|
||||
$(this).parent().nextAll().remove();
|
||||
$.getJSON("library/"+options.url+root+dirName,function(data) {
|
||||
@@ -112,6 +112,7 @@ RED.library = function() {
|
||||
$(".list-selected",ul).removeClass("list-selected");
|
||||
$(this).addClass("list-selected");
|
||||
$.get("library/"+options.url+root+item.fn, function(data) {
|
||||
console.log(data);
|
||||
selectedLibraryItem = item;
|
||||
libraryEditor.setText(data);
|
||||
});
|
||||
@@ -239,12 +240,13 @@ RED.library = function() {
|
||||
open: function(e) {
|
||||
var form = $("form",this);
|
||||
form.height(form.parent().height()-30);
|
||||
$(".form-row:last-child",form).height(form.height()-60);
|
||||
$("#node-select-library-text").height("100%");
|
||||
$(".form-row:last-child",form).children().height(form.height()-60);
|
||||
},
|
||||
resize: function(e) {
|
||||
var form = $("form",this);
|
||||
form.height(form.parent().height()-30);
|
||||
$(".form-row:last-child",form).height(form.height()-60);
|
||||
$(".form-row:last-child",form).children().height(form.height()-60);
|
||||
}
|
||||
});
|
||||
|
||||
|
22
red.js
22
red.js
@@ -44,6 +44,7 @@ nopt.invalidHandler = function(k,v,t) {
|
||||
var parsedArgs = nopt(knownOpts,shortHands,process.argv,2)
|
||||
|
||||
if (parsedArgs.help) {
|
||||
console.log("Node-RED v"+RED.version());
|
||||
console.log("Usage: node red.js [-v] [-?] [--settings settings.js] [flows.json]");
|
||||
console.log("");
|
||||
console.log("Options:");
|
||||
@@ -163,6 +164,16 @@ function getListenPath() {
|
||||
|
||||
RED.start().then(function() {
|
||||
if (settings.httpAdminRoot !== false || settings.httpNodeRoot !== false || settings.httpStatic) {
|
||||
server.on('error', function(err) {
|
||||
if (err.errno === "EADDRINUSE") {
|
||||
util.log('[red] Unable to listen on '+getListenPath());
|
||||
util.log('[red] Error: port in use');
|
||||
} else {
|
||||
util.log('[red] Uncaught Exception:');
|
||||
util.log(err.stack);
|
||||
}
|
||||
process.exit(1);
|
||||
});
|
||||
server.listen(settings.uiPort,settings.uiHost,function() {
|
||||
if (settings.httpAdminRoot === false) {
|
||||
util.log('[red] Admin UI disabled');
|
||||
@@ -176,14 +187,9 @@ RED.start().then(function() {
|
||||
|
||||
|
||||
process.on('uncaughtException',function(err) {
|
||||
if (err.errno === "EADDRINUSE") {
|
||||
util.log('[red] Unable to listen on '+getListenPath());
|
||||
util.log('[red] Error: port in use');
|
||||
} else {
|
||||
util.log('[red] Uncaught Exception:');
|
||||
util.log(err.stack);
|
||||
}
|
||||
process.exit(1);
|
||||
util.log('[red] Uncaught Exception:');
|
||||
util.log(err.stack);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
process.on('SIGINT', function () {
|
||||
|
@@ -29,8 +29,7 @@ function init() {
|
||||
});
|
||||
req.on('end', function() {
|
||||
storage.saveFlow(req.params[0],fullBody).then(function() {
|
||||
res.writeHead(204, {'Content-Type': 'text/plain'});
|
||||
res.end();
|
||||
res.send(204);
|
||||
}).otherwise(function(err) {
|
||||
util.log("[red] Error loading flow '"+req.params[0]+"' : "+err);
|
||||
res.send(500);
|
||||
@@ -40,17 +39,14 @@ function init() {
|
||||
|
||||
redApp.get("/library/flows",function(req,res) {
|
||||
storage.getAllFlows().then(function(flows) {
|
||||
res.writeHead(200, {'Content-Type': 'text/plain'});
|
||||
res.write(JSON.stringify(flows));
|
||||
res.end();
|
||||
res.json(flows);
|
||||
});
|
||||
});
|
||||
|
||||
redApp.get(new RegExp("/library/flows\/(.*)"), function(req,res) {
|
||||
storage.getFlow(req.params[0]).then(function(data) {
|
||||
res.writeHead(200, {'Content-Type': 'text/plain'});
|
||||
res.write(data);
|
||||
res.end();
|
||||
res.set('Content-Type', 'application/json');
|
||||
res.send(data);
|
||||
}).otherwise(function(err) {
|
||||
if (err) {
|
||||
util.log("[red] Error loading flow '"+req.params[0]+"' : "+err);
|
||||
@@ -67,13 +63,13 @@ function createLibrary(type) {
|
||||
redApp.get(new RegExp("/library/"+type+"($|\/(.*))"),function(req,res) {
|
||||
var path = req.params[1]||"";
|
||||
storage.getLibraryEntry(type,path).then(function(result) {
|
||||
res.writeHead(200, {'Content-Type': 'text/plain'});
|
||||
if (typeof result === "string") {
|
||||
res.writeHead(200, {'Content-Type': 'text/plain'});
|
||||
res.write(result);
|
||||
res.end();
|
||||
} else {
|
||||
res.write(JSON.stringify(result));
|
||||
res.json(result);
|
||||
}
|
||||
res.end();
|
||||
}).otherwise(function(err) {
|
||||
if (err) {
|
||||
util.log("[red] Error loading library entry '"+path+"' : "+err);
|
||||
|
10
red/red.js
10
red/red.js
@@ -18,6 +18,7 @@ var events = require("./events");
|
||||
var server = require("./server");
|
||||
var nodes = require("./nodes");
|
||||
var library = require("./library");
|
||||
var fs = require("fs");
|
||||
var settings = null;
|
||||
|
||||
var path = require('path');
|
||||
@@ -34,6 +35,15 @@ var RED = {
|
||||
library.init();
|
||||
return server.app;
|
||||
},
|
||||
|
||||
version: function() {
|
||||
var p = require(path.join(process.env.NODE_RED_HOME,"package.json"));
|
||||
if (fs.existsSync(path.join(process.env.NODE_RED_HOME,".git"))) {
|
||||
return p.version+".git";
|
||||
} else {
|
||||
return p.version;
|
||||
}
|
||||
},
|
||||
|
||||
start: server.start,
|
||||
stop: server.stop,
|
||||
|
@@ -37,46 +37,38 @@ function createServer(_server,_settings) {
|
||||
flowfile = settings.flowFile || 'flows_'+require('os').hostname()+'.json';
|
||||
|
||||
app.get("/nodes",function(req,res) {
|
||||
res.writeHead(200, {'Content-Type': 'text/plain'});
|
||||
res.write(redNodes.getNodeConfigs());
|
||||
res.end();
|
||||
res.send(redNodes.getNodeConfigs());
|
||||
});
|
||||
|
||||
app.get("/flows",function(req,res) {
|
||||
res.writeHead(200, {'Content-Type': 'text/plain'});
|
||||
res.write(JSON.stringify(redNodes.getConfig()));
|
||||
res.end();
|
||||
res.json(redNodes.getConfig());
|
||||
});
|
||||
|
||||
app.post("/flows",function(req,res) {
|
||||
var fullBody = '';
|
||||
req.on('data', function(chunk) {
|
||||
fullBody += chunk.toString();
|
||||
app.post("/flows",
|
||||
express.json(),
|
||||
function(req,res) {
|
||||
var flows = req.body;
|
||||
storage.saveFlows(flows).then(function() {
|
||||
res.json(204);
|
||||
redNodes.setConfig(flows);
|
||||
}).otherwise(function(err) {
|
||||
util.log("[red] Error saving flows : "+err);
|
||||
res.send(500,err.message);
|
||||
});
|
||||
req.on('end', function() {
|
||||
try {
|
||||
var flows = JSON.parse(fullBody);
|
||||
storage.saveFlows(flows).then(function() {
|
||||
res.writeHead(204, {'Content-Type': 'text/plain'});
|
||||
res.end();
|
||||
redNodes.setConfig(flows);
|
||||
}).otherwise(function(err) {
|
||||
util.log("[red] Error saving flows : "+err);
|
||||
res.send(500, err.message);
|
||||
});
|
||||
} catch(err) {
|
||||
util.log("[red] Error saving flows : "+err);
|
||||
res.send(400, "Invalid flow");
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
function(error,req,res,next) {
|
||||
res.send(400,"Invalid Flow");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function start() {
|
||||
var RED = require("./red");
|
||||
var defer = when.defer();
|
||||
|
||||
storage.init(settings).then(function() {
|
||||
console.log("\nWelcome to Node-RED\n===================\n");
|
||||
util.log("[red] Version: "+RED.version());
|
||||
util.log("[red] Loading palette nodes");
|
||||
var nodeErrors = redNodes.load(settings);
|
||||
if (nodeErrors.length > 0) {
|
||||
|
Reference in New Issue
Block a user