- Node-RED v0.18.6
- Node.js v8.11.2
- node-red-contrib-os
- bootstrap v3.3.7
- jquery v2.2.4
- Odometer
[{"id":"7f6aafad.dbf63","type":"http in","z":"b038fb61.944c48","name":"","url":"/benchmark","method":"get","upload":false,"swaggerDoc":"","x":110,"y":363.2222309112549,"wires":[["ec4a9465.b44c28"]]},{"id":"24d04112.87940e","type":"function","z":"b038fb61.944c48","name":"OS version","func":"//msg.payload = \n//{ hostname: '4ZRBQ72',\n// type: 'Windows_NT',\n// platform: 'win32',\n// arch: 'x64',\n// release: '10.0.10586',\n// endianness: 'LE'\n//}\n\nvar sysinfo = msg.payload;\n\nmsg.payload = {};\nmsg.payload.os = { \n hostType : sysinfo.type,\n platform : sysinfo.platform,\n arch : sysinfo.arch\n};\n\n//console.log(msg);\nreturn msg;","outputs":1,"noerr":0,"x":298.0001106262207,"y":426.2222595214844,"wires":[["fced9b3c.226228","7cf1913b.82146"]]},{"id":"413ce72f.1610c8","type":"template","z":"b038fb61.944c48","name":"CSS","field":"payload.style","fieldType":"msg","format":"html","syntax":"mustache","template":"body{\n font-family: 'Droid Sans', 'Helvetica', Arial, sans-serif;\n margin:3px;\n\n}\n.carousel{\n background: #2f4357;\n margin-top: 20px;\n}\n.carousel .item{\n min-height: 300px; /* Prevent carousel from being distorted if for some reason image doesn't load */\n}\n.carousel .item img{\n margin: 0 auto; /* Align slide image horizontally center */\n}\n\n.odometer {\n font-size: 30px;\n}","x":491.00000381469727,"y":364.2222318649292,"wires":[["f2998092.6df02"]]},{"id":"7cf1913b.82146","type":"template","z":"b038fb61.944c48","name":"JavaScript","field":"payload.script","fieldType":"msg","format":"javascript","syntax":"plain","template":"(function ($) {\n\n/////////////////////////////////\nvar loc = window.location;\nvar ws;\nvar wsUri = \"ws:\";\n\nif (loc.protocol === \"https:\") { wsUri = \"wss:\"; }\n// This needs to point to the web socket in the Node-RED flow\n// ... in this case it's ws/simple\nwsUri += \"//\" + loc.host + loc.pathname.replace(\"benchmark\",\"ws/alert\");\n\n///////////////////////////////////////////////\n// WebSocket \nfunction init() {\n console.log(\"connect\",wsUri);\n ws = new WebSocket(wsUri);\n\n ws.onopen = function() {\n console.log(\"connected\");\n }\n \n ws.onclose = function() {\n setTimeout(wsConnect,5000);\n }\n \n ws.onmessage = function(msg) {\n var payload = JSON.parse(msg.data);\n response ( payload );\n }\n}\n\nfunction request(m) {\n // Browser -> Server\n // Nothing has been defined yet\n if (ws) { ws.send(m); }\n}\n \nfunction response(payload) {\n // console.log(payload);\n // Browser <- Server\n if (payload.hasOwnProperty('uptime')) {\n //console.log(payload.uptime);\n uptime_meter.innerHTML = payload.uptime.uptime;\n }\n if (payload.hasOwnProperty('cpu')) {\n // console.log(payload.cpu.cpus[0]);\n var cpu = payload.cpu.cpus[0];\n // model, speed, times { user:, nice:, sys:, idle: }\n $('#cpuModel').html(cpu.model.substr(0, cpu.model.indexOf('@')));\n \n var cpuSpeed = cpu.speed / 1000; \n $('#cpuSpeed').html(cpuSpeed);\n \n // Performance\n $('#cpuUser').html(cpu.times.user);\n $('#cpuSys').html(cpu.times.sys);\n $('#cpuIdle').html(cpu.times.idle);\n }\n if (payload.hasOwnProperty('load')) {\n \n }\n if (payload.hasOwnProperty('memory')) {\n // console.log(payload.memory);\n // totalmem, freemem, memusage (%)\n var total_m = parseFloat(payload.memory.totalmem / 1073741824).toFixed( 2 );\n var free_m = parseFloat(payload.memory.freemem / 1073741824).toFixed( 2 );\n var used_m = parseFloat(total_m - free_m).toFixed( 2 ) ;\n \n $('#totalMem').html(total_m);\n $('#freeMem').html(free_m);\n $('#memUsage').html(payload.memory.memusage);\n $('#memUsageGB').html(used_m);\n \n }\n if (payload.hasOwnProperty('network')) {\n console.log(payload.network);\n var wireless = payload.network.networkInterfaces[\"Wi-Fi\"];\n var address = wireless[1].address;\n var family = wireless[1].family;\n var mac = wireless[1].mac;\n var netmask = wireless[1].netmask;\n \n $('#nAddress').html(address);\n $('#nFamily').html(family);\n $('#nMac').html(mac);\n $('#nNetmask').html(netmask);\n }\n}\n \n$(window).load(init);\n \n}(jQuery));\n","x":337.0000534057617,"y":363.2222309112549,"wires":[["413ce72f.1610c8"]]},{"id":"f2998092.6df02","type":"template","z":"b038fb61.944c48","name":"HTML","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<!doctype html>\n<html>\n<head>\n <!-- Required meta tags -->\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n\n <!-- Bootstrap CSS -->\n <!-- Latest compiled and minified CSS -->\n <link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css\" integrity=\"sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u\" crossorigin=\"anonymous\">\n <link href=\"https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css\" rel=\"stylesheet\" integrity=\"sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN\" crossorigin=\"anonymous\">\n <style>{{{payload.style}}}</style>\n \n <!-- jQuery first, then Bootstrap JS -->\n <script src=\"https://code.jquery.com/jquery-2.2.4.js\" integrity=\"sha256-iT6Q9iMJYuQiMWNd9lDyBUStIq/8PuOW33aOqmvFpqI=\" crossorigin=\"anonymous\"></script> <!-- Latest compiled and minified JavaScript -->\n <script src=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js\" integrity=\"sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa\" crossorigin=\"anonymous\"></script>\n\n <!-- Odometr includes -->\n <link rel=\"stylesheet\" href=\"http://github.hubspot.com/odometer/themes/odometer-theme-train-station.css\" />\n <script src=\"http://github.hubspot.com/odometer/odometer.js\"></script>\n\n <script>{{{payload.script}}}</script>\n</head>\n<body> <!-- Fixed navbar -->\n <nav class=\"navbar navbar-default navbar-fixed-top\">\n <div class=\"container\">\n <div id=\"navbar\" class=\"navbar-collapse collapse\">\n <ul class=\"nav navbar-nav\">\n <!-- <li><a href=\"#\">Host Type <button class=\"btn btn-default navbar-btn\" >{{{payload.os.hostType}}}</button></button></a></li> -->\n <li><a href=\"#\">Platform <button class=\"btn btn-default navbar-btn\" >{{{payload.os.platform}}}</button></a></li>\n <li><a href=\"#\">Arch <button class=\"btn btn-default navbar-btn\" >{{{payload.os.arch}}}</button></a></li>\n </ul>\n </div><!--/.nav-collapse -->\n </div>\n </nav>\n<div>\n <div id=\"myCarousel\" class=\"carousel slide\" data-interval=\"3000\" data-ride=\"carousel\">\n \t<!-- Carousel indicators -->\n <ol class=\"carousel-indicators\">\n <li data-target=\"#myCarousel\" data-slide-to=\"0\" class=\"active\"></li>\n <li data-target=\"#myCarousel\" data-slide-to=\"1\"></li>\n <li data-target=\"#myCarousel\" data-slide-to=\"2\"></li>\n </ol> \n <!-- Wrapper for carousel items -->\n <div class=\"carousel-inner\">\n <div class=\"active item\">\n <div class=\"carousel-caption\">\n <h3>CPU</h3>\n <div>Model <span id=\"cpuModel\" class=\"label label-default\">Intel</span></div>\n <div>Speed <span id=\"cpuSpeed\" class=\"label label-default\">0</span> GHz</div>\n\n <h3>Performance</h3>\n <div>User <span id=\"cpuUser\" class=\"label label-warning\" >0</span>\n Sys <span id=\"cpuSys\" class=\"label label-warning\">0</span>\n Idle <span id=\"cpuIdle\" class=\"label label-primary\">0</span>\n </div>\n </div>\n </div>\n <div class=\"item\">\n <div class=\"carousel-caption\">\n <h3>Memory</h3>\n <div>Total <span id=\"totalMem\" class=\"label label-primary\">0</span> GB </div>\n <div>Free <span id=\"freeMem\" class=\"label label-primary\">0</span> GB</div>\n <br>\n <div>Usage <span id=\"memUsageGB\" class=\"label label-warning\">0</span>GB <span id=\"memUsage\" class=\"label label-warning\">0</span> %</div>\n \n </div>\n </div>\n <div class=\"item\">\n <div class=\"carousel-caption\">\n <h3>Wi-Fi Network</h3>\n <div>Family <span id=\"nFamily\" class=\"label label-primary\">IPv4</span></div>\n <div>Address <span id=\"nAddress\" class=\"label label-primary\">0:0:0:0</span></div>\n <div>Netmask <span id=\"nNetmask\" class=\"label label-primary\">0:0:0:0</span></div>\n <br>\n <div>Mac <span id=\"nMac\" class=\"label label-primary\">0:0:0:0:0:0</span></div>\n </div>\n </div>\n </div>\n <!-- Carousel controls -->\n <a class=\"carousel-control left\" href=\"#myCarousel\" data-slide=\"prev\">\n <span class=\"glyphicon glyphicon-chevron-left\"></span>\n </a>\n <a class=\"carousel-control right\" href=\"#myCarousel\" data-slide=\"next\">\n <span class=\"glyphicon glyphicon-chevron-right\"></span>\n </a>\n </div>\n </div>\n</div> \n<br>\n<div class=\"container\">\n <div class=\"row\">\n <div class=\"col-lg-6 col-lg-offset-3 text-center\">\n <span ><font size=\"4\">Uptime</font></span> <div id=\"uptime_meter\" class=\"odometer\">8888.88</div> \n </div>\n </div>\n</div>\n</body>\n</html>","output":"str","x":625.0000591278076,"y":365.2222309112549,"wires":[["c3d4f2ba.80bce"]]},{"id":"97927252.ccf6a","type":"comment","z":"b038fb61.944c48","name":"Extract OS Info (Static Info )","info":"","x":207.00003051757812,"y":466.2222328186035,"wires":[]},{"id":"2b7eb011.5a38c","type":"comment","z":"b038fb61.944c48","name":"http://localhost:1880/benchmark","info":"","x":163,"y":319.222204208374,"wires":[]},{"id":"5551eb83.09fcf4","type":"comment","z":"b038fb61.944c48","name":"Message to Browser","info":"","x":736.0000076293945,"y":533.2222328186035,"wires":[]},{"id":"4b32c04b.afc31","type":"comment","z":"b038fb61.944c48","name":"System Monitoring Site","info":"","x":383,"y":268.222204208374,"wires":[]},{"id":"1a19686b.0696a8","type":"comment","z":"b038fb61.944c48","name":"System Monitor","info":"","x":96.16665649414062,"y":596.3333978652954,"wires":[]},{"id":"863c0c88.261fe","type":"inject","z":"b038fb61.944c48","name":"","topic":"","payload":"","payloadType":"date","repeat":"3","crontab":"","once":false,"onceDelay":0.1,"x":107,"y":656.1112308502197,"wires":[["62cf35d7.25743c","65032b5f.0dcc54","ca86d276.86751","636732a9.866fec","8c497129.df344"]]},{"id":"eb69f34b.b6f84","type":"debug","z":"b038fb61.944c48","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":727.1666717529297,"y":741.0000114440918,"wires":[]},{"id":"c02c8662.1b2448","type":"websocket out","z":"b038fb61.944c48","name":"","server":"d53abbe8.b7e5e8","client":"","x":739.1666717529297,"y":572.8888988494873,"wires":[]},{"id":"ec4a9465.b44c28","type":"OS","z":"b038fb61.944c48","name":"","x":148.16665267944336,"y":426.00003719329834,"wires":[["24d04112.87940e"]]},{"id":"62cf35d7.25743c","type":"Uptime","z":"b038fb61.944c48","name":"","x":319.1666717529297,"y":554.0000114440918,"wires":[["6c51054a.57b07c"]]},{"id":"65032b5f.0dcc54","type":"CPUs","z":"b038fb61.944c48","name":"","x":328.1666679382324,"y":605.0000114440918,"wires":[["2be22056.a552"]]},{"id":"c3d4f2ba.80bce","type":"http response","z":"b038fb61.944c48","name":"","statusCode":"","headers":{},"x":765.1666717529297,"y":364.555645942688,"wires":[]},{"id":"ca86d276.86751","type":"Loadavg","z":"b038fb61.944c48","name":"","x":319.1666717529297,"y":652.8889007568359,"wires":[["b1450aa1.41a2e8"]]},{"id":"636732a9.866fec","type":"Memory","z":"b038fb61.944c48","name":"","x":315.1666717529297,"y":708.8889007568359,"wires":[["7ff09234.40e4cc"]]},{"id":"8c497129.df344","type":"NetworkIntf","z":"b038fb61.944c48","name":"Network - Wifi","x":307.1666679382324,"y":759.8889017105103,"wires":[["d65a17f.d1a96e8"]]},{"id":"fced9b3c.226228","type":"debug","z":"b038fb61.944c48","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":504.1666717529297,"y":427.00000953674316,"wires":[]},{"id":"6c51054a.57b07c","type":"function","z":"b038fb61.944c48","name":"UpTime","func":"//msg.payload = \n//{ uptime: 4121.0176141 }\n\nmsg.topic = \"uptime\";\nreturn msg;","outputs":1,"noerr":0,"x":456.16669845581055,"y":553.3333988189697,"wires":[["9a03c38.50bc24"]]},{"id":"9a03c38.50bc24","type":"function","z":"b038fb61.944c48","name":"Collector","func":"context.data = context.data || new Object();\n\nvar ws_connected = false;\n\n// ws out node\nvar WebSocketOutNode = RED.nodes.getNode(\"c02c8662.1b2448\");\n//console.log( WebSocketOutNode );\n// status check\nws_connected = WebSocketOutNode.connected;\n\nif (ws_connected )\n node.status({fill:\"green\",shape:\"ring\",text: 'connected' });\nelse\n node.status({fill:\"red\",shape:\"ring\",text: 'disconnected' });\n \nswitch (msg.topic) {\n case \"uptime\":\n context.data.uptime = msg.payload;\n msg = null;\n break;\n case \"cpu\":\n context.data.cpu = msg.payload;\n msg = null;\n break;\n case \"load\":\n context.data.load = msg.payload;\n msg = null;\n break;\n case \"memory\":\n context.data.memory = msg.payload;\n msg = null;\n break;\n case \"network\":\n context.data.network = msg.payload;\n msg = null;\n break;\n default:\n msg = null;\n \tbreak;\n}\n\nif ( ws_connected ) {\n if( context.data.uptime !== null \n && context.data.cpu !== null \n && context.data.load !== null\n && context.data.memory !== null \n && context.data.network !== null \n ) {\n\t new_msg = new Object();\n new_msg.payload = context.data;\n context.data=null;\n //console.log( new_msg );\n\t return new_msg;\n } else return msg;\n} else return null;","outputs":1,"noerr":0,"x":658.1666717529297,"y":654.3333721160889,"wires":[["eb69f34b.b6f84","c02c8662.1b2448"]]},{"id":"2be22056.a552","type":"function","z":"b038fb61.944c48","name":"CPU","func":"//msg.payload = \n//{ cpu : cpus[x] }\n// cpus[]\n// model : \"Intel(R) ....\",\n// spped : 2712\n// times : { user : xxxx, nice : 0, sys : xxxx, idle: xxxx }\n\nmsg.topic = \"cpu\";\nreturn msg;\n","outputs":1,"noerr":0,"x":452.16669845581055,"y":602.3333988189697,"wires":[["9a03c38.50bc24"]]},{"id":"b1450aa1.41a2e8","type":"function","z":"b038fb61.944c48","name":"Performance","func":"//msg.payload = \n//{ load : loadavg[x] }\n\nmsg.topic = \"load\";\nreturn msg;\n","outputs":1,"noerr":0,"x":469.1666946411133,"y":654.3333988189697,"wires":[["9a03c38.50bc24"]]},{"id":"7ff09234.40e4cc","type":"function","z":"b038fb61.944c48","name":"Memory","func":"//msg.payload = \n//{ memory : { totalmem : xxx, freemen: xxx, memusage: xxx }}\n\nmsg.topic = \"memory\";\nreturn msg;\n","outputs":1,"noerr":0,"x":460.16669845581055,"y":709.3333992958069,"wires":[["9a03c38.50bc24"]]},{"id":"d65a17f.d1a96e8","type":"function","z":"b038fb61.944c48","name":"Network","func":"//msg.payload = \n//{ network : networkInterfaces }\n// networkInterfaces\n// Wi-Fi[0] IPv6\n// Wi-Fi[1] IPv4\n// Wi-Fi[1] { address: xxx, netmask:xxx, family, xxx, mac: xxx, ...} \nmsg.topic = \"network\";\nreturn msg;\n","outputs":1,"noerr":0,"x":468.16669845581055,"y":761.333399772644,"wires":[["9a03c38.50bc24"]]},{"id":"d53abbe8.b7e5e8","type":"websocket-listener","z":"","path":"/ws/alert","wholemsg":"false"}]
RED.nodes.getNode(
flow ID)
in Function Node "Collector".
// ws out node
var WebSocketOutNode = RED.nodes.getNode("c02c8662.1b2448");
//console.log( WebSocketOutNode );
// status check
ws_connected = WebSocketOutNode.connected;
C:\Users\<your-name>\AppData\Roaming\npm\node_modules\node-red\nodes\core\core\io\22-websocket.js
function WebSocketOutNode(n) {
RED.nodes.createNode(this,n);
var node = this;
this.server = (n.client)?n.client:n.server;
this.serverConfig = RED.nodes.getNode(this.server);
+ this.connected = false;
if (!this.serverConfig) {
return this.error(RED._("websocket.errors.missing-conf"));
}
else {
// TODO: nls
this.serverConfig.on('opened', function(n) {
+ node.connected = true;
node.status({fill:"green",shape:"dot",text:"connected "+n}); });
this.serverConfig.on('erro', function() {
+ node.connected = false;
node.status({fill:"red",shape:"ring",text:"error"}); });
this.serverConfig.on('closed', function(n) {
if (n > 0) {
+ node.connected = true;
node.status({fill:"green",shape:"dot",text:"connected "+n});
} else {
+ node.connected = false;
node.status({fill:"red",shape:"ring",text:"disconnected"});
}
});
}
C:\Users\<your-name>\AppData\Roaming\npm\node_modules\node-red\nodes\core\core\80-function.js
RED: {
util: RED.util,
+ nodes : RED.nodes
},