mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Add node status updates
This commit is contained in:
parent
8e7fc011f0
commit
7ecb80bf40
@ -303,6 +303,7 @@
|
|||||||
<script src="orion/built-editor.min.js"></script>
|
<script src="orion/built-editor.min.js"></script>
|
||||||
<script src="d3.v3.min.js"></script>
|
<script src="d3.v3.min.js"></script>
|
||||||
<script src="red/main.js"></script>
|
<script src="red/main.js"></script>
|
||||||
|
<script src="red/comms.js"></script>
|
||||||
<script src="red/ui/state.js"></script>
|
<script src="red/ui/state.js"></script>
|
||||||
<script src="red/nodes.js"></script>
|
<script src="red/nodes.js"></script>
|
||||||
<script src="red/history.js"></script>
|
<script src="red/history.js"></script>
|
||||||
@ -317,6 +318,5 @@
|
|||||||
<script src="red/ui/editor.js"></script>
|
<script src="red/ui/editor.js"></script>
|
||||||
<script src="red/ui/library.js"></script>
|
<script src="red/ui/library.js"></script>
|
||||||
<script src="red/ui/notifications.js"></script>
|
<script src="red/ui/notifications.js"></script>
|
||||||
<script src="red/comms.js"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -18,26 +18,36 @@ RED.comms = function() {
|
|||||||
|
|
||||||
var errornotification = null;
|
var errornotification = null;
|
||||||
var subscriptions = {};
|
var subscriptions = {};
|
||||||
|
var ws;
|
||||||
function connectWS() {
|
function connectWS() {
|
||||||
var path = location.hostname+":"+location.port+document.location.pathname;
|
var path = location.hostname+":"+location.port+document.location.pathname;
|
||||||
path = path+(path.slice(-1) == "/"?"":"/")+"comms";
|
path = path+(path.slice(-1) == "/"?"":"/")+"comms";
|
||||||
path = "ws"+(document.location.protocol=="https:"?"s":"")+"://"+path;
|
path = "ws"+(document.location.protocol=="https:"?"s":"")+"://"+path;
|
||||||
var ws = new WebSocket(path);
|
ws = new WebSocket(path);
|
||||||
ws.onopen = function() {
|
ws.onopen = function() {
|
||||||
if (errornotification) {
|
if (errornotification) {
|
||||||
errornotification.close();
|
errornotification.close();
|
||||||
errornotification = null;
|
errornotification = null;
|
||||||
}
|
}
|
||||||
|
for (var t in subscriptions) {
|
||||||
|
ws.send(JSON.stringify({subscribe:t}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ws.onmessage = function(event) {
|
ws.onmessage = function(event) {
|
||||||
var msg = JSON.parse(event.data);
|
var msg = JSON.parse(event.data);
|
||||||
var subscribers = subscriptions[msg.topic];
|
if (msg.topic) {
|
||||||
|
for (var t in subscriptions) {
|
||||||
|
var re = new RegExp("^"+t.replace(/([\[\]\?\(\)\\\\$\^\*\.|])/g,"\\$1").replace(/\+/g,"[^/]+").replace(/\/#$/,"(\/.*)?")+"$");
|
||||||
|
if (re.test(msg.topic)) {
|
||||||
|
var subscribers = subscriptions[t];
|
||||||
if (subscribers) {
|
if (subscribers) {
|
||||||
for (var i=0;i<subscribers.length;i++) {
|
for (var i=0;i<subscribers.length;i++) {
|
||||||
subscribers[i](msg.topic,msg.data);
|
subscribers[i](msg.topic,msg.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
ws.onclose = function() {
|
ws.onclose = function() {
|
||||||
if (errornotification == null) {
|
if (errornotification == null) {
|
||||||
@ -46,16 +56,20 @@ RED.comms = function() {
|
|||||||
setTimeout(connectWS,1000);
|
setTimeout(connectWS,1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
connectWS();
|
|
||||||
|
|
||||||
function subscribe(topic,callback) {
|
function subscribe(topic,callback) {
|
||||||
if (subscriptions[topic] == null) {
|
if (subscriptions[topic] == null) {
|
||||||
subscriptions[topic] = [];
|
subscriptions[topic] = [];
|
||||||
}
|
}
|
||||||
subscriptions[topic].push(callback);
|
subscriptions[topic].push(callback);
|
||||||
|
if (ws && ws.readyState == 1) {
|
||||||
|
ws.send(JSON.stringify({subscribe:topic}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
connect: connectWS,
|
||||||
subscribe: subscribe
|
subscribe: subscribe
|
||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
|
@ -156,6 +156,15 @@ var RED = function() {
|
|||||||
RED.nodes.import(nodes);
|
RED.nodes.import(nodes);
|
||||||
RED.view.dirty(false);
|
RED.view.dirty(false);
|
||||||
RED.view.redraw();
|
RED.view.redraw();
|
||||||
|
RED.comms.subscribe("status/#",function(topic,msg) {
|
||||||
|
var parts = topic.split("/");
|
||||||
|
var node = RED.nodes.node(parts[1]);
|
||||||
|
if (node) {
|
||||||
|
node.status = msg;
|
||||||
|
node.dirty = true;
|
||||||
|
RED.view.redraw();
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,6 +189,7 @@ var RED = function() {
|
|||||||
$(function() {
|
$(function() {
|
||||||
RED.keyboard.add(/* ? */ 191,{shift:true},function(){showHelp();d3.event.preventDefault();});
|
RED.keyboard.add(/* ? */ 191,{shift:true},function(){showHelp();d3.event.preventDefault();});
|
||||||
loadSettings();
|
loadSettings();
|
||||||
|
RED.comms.connect();
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -44,6 +44,12 @@ RED.view = function() {
|
|||||||
|
|
||||||
var clipboard = "";
|
var clipboard = "";
|
||||||
|
|
||||||
|
|
||||||
|
var status_colours = {
|
||||||
|
"red" : "#00c",
|
||||||
|
"green": "#5a8"
|
||||||
|
}
|
||||||
|
|
||||||
var outer = d3.select("#chart")
|
var outer = d3.select("#chart")
|
||||||
.append("svg:svg")
|
.append("svg:svg")
|
||||||
.attr("width", space_width)
|
.attr("width", space_width)
|
||||||
@ -893,6 +899,21 @@ RED.view = function() {
|
|||||||
text.attr('text-anchor','end');
|
text.attr('text-anchor','end');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var status = node.append("svg:g").attr("class","node_status_group").style("display","none");
|
||||||
|
|
||||||
|
var statusRect = status.append("circle").attr("class","node_status")
|
||||||
|
.attr("cx",9).attr("cy",6).attr("r",5).attr("stroke-width","3");
|
||||||
|
var statusLabel = status.append("svg:text")
|
||||||
|
.attr("class","node_status_label")
|
||||||
|
.attr('x',20).attr('y',10)
|
||||||
|
.style({
|
||||||
|
'stroke-width': 0,
|
||||||
|
'fill': '#999',
|
||||||
|
'font-size':'9pt',
|
||||||
|
'stroke':'#000',
|
||||||
|
'text-anchor':'start'
|
||||||
|
});
|
||||||
|
|
||||||
//node.append("circle").attr({"class":"centerDot","cx":0,"cy":0,"r":5});
|
//node.append("circle").attr({"class":"centerDot","cx":0,"cy":0,"r":5});
|
||||||
|
|
||||||
if (d._def.inputs > 0) {
|
if (d._def.inputs > 0) {
|
||||||
@ -1017,6 +1038,36 @@ RED.view = function() {
|
|||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
});
|
});
|
||||||
|
if (!d.status) {
|
||||||
|
thisNode.selectAll('.node_status_group').style("display","none");
|
||||||
|
} else {
|
||||||
|
thisNode.selectAll('.node_status_group').style("display","inline").attr("transform","translate(3,"+(d.h+3)+")");
|
||||||
|
var fill = status_colours[d.status.fill]; // Only allow our colours for now
|
||||||
|
if (d.status.shape == null && fill == null) {
|
||||||
|
thisNode.selectAll('.node_status').style("display","none");
|
||||||
|
} else {
|
||||||
|
var style;
|
||||||
|
if (d.status.shape == null || d.status.shape == "dot") {
|
||||||
|
style = {
|
||||||
|
display: "inline",
|
||||||
|
fill: fill,
|
||||||
|
stroke: fill
|
||||||
|
};
|
||||||
|
} else if (d.status.shape == "ring" ){
|
||||||
|
style = {
|
||||||
|
display: "inline",
|
||||||
|
fill: '#fff',
|
||||||
|
stroke: fill
|
||||||
|
}
|
||||||
|
}
|
||||||
|
thisNode.selectAll('.node_status').style(style);
|
||||||
|
}
|
||||||
|
if (d.status.text) {
|
||||||
|
thisNode.selectAll('.node_status_label').text(d.status.text);
|
||||||
|
} else {
|
||||||
|
thisNode.selectAll('.node_status_label').text("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
d.dirty = false;
|
d.dirty = false;
|
||||||
}
|
}
|
||||||
|
33
red/comms.js
33
red/comms.js
@ -23,6 +23,8 @@ var settings;
|
|||||||
var wsServer;
|
var wsServer;
|
||||||
var activeConnections = [];
|
var activeConnections = [];
|
||||||
|
|
||||||
|
var retained = {};
|
||||||
|
|
||||||
var heartbeatTimer;
|
var heartbeatTimer;
|
||||||
var lastSentTime;
|
var lastSentTime;
|
||||||
|
|
||||||
@ -47,6 +49,12 @@ function start() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
ws.on('message', function(data,flags) {
|
||||||
|
var msg = JSON.parse(data);
|
||||||
|
if (msg.subscribe) {
|
||||||
|
handleRemoteSubscription(ws,msg.subscribe);
|
||||||
|
}
|
||||||
|
});
|
||||||
ws.on('error', function(err) {
|
ws.on('error', function(err) {
|
||||||
util.log("[red:comms] error : "+err.toString());
|
util.log("[red:comms] error : "+err.toString());
|
||||||
});
|
});
|
||||||
@ -67,15 +75,32 @@ function start() {
|
|||||||
}, 15000);
|
}, 15000);
|
||||||
}
|
}
|
||||||
|
|
||||||
function publish(topic,data) {
|
function publish(topic,data,retain) {
|
||||||
var msg = JSON.stringify({topic:topic,data:data});
|
if (retain) {
|
||||||
|
retained[topic] = data;
|
||||||
|
}
|
||||||
|
lastSentTime = Date.now();
|
||||||
activeConnections.forEach(function(conn) {
|
activeConnections.forEach(function(conn) {
|
||||||
|
publishTo(conn,topic,data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function publishTo(ws,topic,data) {
|
||||||
|
var msg = JSON.stringify({topic:topic,data:data});
|
||||||
try {
|
try {
|
||||||
conn.send(msg);
|
ws.send(msg);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
util.log("[red:comms] send error : "+err.toString());
|
util.log("[red:comms] send error : "+err.toString());
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
|
function handleRemoteSubscription(ws,topic) {
|
||||||
|
var re = new RegExp("^"+topic.replace(/([\[\]\?\(\)\\\\$\^\*\.|])/g,"\\$1").replace(/\+/g,"[^/]+").replace(/\/#$/,"(\/.*)?")+"$");
|
||||||
|
for (var t in retained) {
|
||||||
|
if (re.test(t)) {
|
||||||
|
publishTo(ws,t,retained[t]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ var clone = require("clone");
|
|||||||
|
|
||||||
var flows = require("./flows");
|
var flows = require("./flows");
|
||||||
|
|
||||||
|
var comms = require("../comms");
|
||||||
|
|
||||||
function Node(n) {
|
function Node(n) {
|
||||||
this.id = n.id;
|
this.id = n.id;
|
||||||
@ -114,6 +114,11 @@ Node.prototype.error = function(msg) {
|
|||||||
if (this.name) o.name = this.name;
|
if (this.name) o.name = this.name;
|
||||||
this.emit("log",o);
|
this.emit("log",o);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* status: { fill:"red|green", shape:"dot|ring", text:"blah" }
|
||||||
|
*/
|
||||||
|
Node.prototype.status = function(status,retain) {
|
||||||
|
comms.publish("status/"+this.id,status,retain);
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = Node;
|
module.exports = Node;
|
||||||
|
@ -18,7 +18,6 @@ var events = require("./events");
|
|||||||
var server = require("./server");
|
var server = require("./server");
|
||||||
var nodes = require("./nodes");
|
var nodes = require("./nodes");
|
||||||
var library = require("./library");
|
var library = require("./library");
|
||||||
var comms = require("./comms");
|
|
||||||
var log = require("./log");
|
var log = require("./log");
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var settings = null;
|
var settings = null;
|
||||||
@ -51,7 +50,6 @@ var RED = {
|
|||||||
stop: server.stop,
|
stop: server.stop,
|
||||||
nodes: nodes,
|
nodes: nodes,
|
||||||
library: library,
|
library: library,
|
||||||
comms: comms,
|
|
||||||
events: events,
|
events: events,
|
||||||
log: log
|
log: log
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user