UNPKG

node-red-contrib-services-mentor

Version:

Mentor Services

228 lines (199 loc) 6.93 kB
module.exports = function(RED) { var request = require('request'); var utils = require('./utils.js'); var log = RED.log; function Node(config) { RED.nodes.createNode(this, config); var node = this; this.mydb = config.mysql; this.mydbConfig = RED.nodes.getNode(this.mydb); node.status({}); this.url = config.url; this.reqTimeout = 120000; this.mentor = RED.nodes.getNode(config.mentor); this.broker = config.mqtt; this.brokerConn = RED.nodes.getNode(this.broker); this.priority = parseInt(config.priority, 10) || 0; this.mentor_id = 0; if (this.mentor) this.mentor_id = this.mentor.mentor_id; var channel = "mentor_answer_" + this.mentor_id; if (node.url != "") { this.opts = { method: 'POST', url: node.url, timeout: node.reqTimeout, //followRedirect: nodeFollowRedirects, //forever: nodePersistentHTTP, headers: {}, encoding: null, strictSSL: false }; //if (this.credentials && (this.credentials.user==null)) { node.opts.auth = { user: "", pass: "", //this.credentials.password, sendImmediately: false }; //} } if (this.brokerConn) { this.status({fill:"red",shape:"ring",text:"node-red:common.status.disconnected"}); node.brokerConn.register(this); node.brokerConn.subscribe(channel,2,function(topic,msg,packet) { var msg = JSON.parse(msg.toString()); switch (msg.topic) { case "mentor_pong": //log.error(msg); sendRecords(node, msg); break; case "mentor_rec": saveMysql(node, msg); break; default: log.error(msg.topic); break; } }, this.id); if (this.brokerConn.connected) { node.status({fill:"green",shape:"dot",text:"node-red:common.status.connected"}); } this.on('close', function(done) { node.brokerConn.deregister(node,done); }); } if (this.mydbConfig) { this.mydbConfig.connect(); node.busy = false; node.mydbConfig.on("state", function(info) { if (info === "connecting") { node.status({fill:"grey",shape:"ring",text:info}); } else if (info === "connected") { node.status({fill:"green",shape:"dot",text:info}); } else { if (info === "ECONNREFUSED") { info = "connection refused"; } if (info === "PROTOCOL_CONNECTION_LOST") { info = "connection lost"; } node.status({fill:"red",shape:"ring",text:info}); } }); node.on("input", function(msg) { this.msg_status = {}; sendPing(node,msg); }); node.on('close', function () { if (node.tout) { clearTimeout(node.tout); } node.mydbConfig.removeAllListeners(); node.status({}); }); } else { this.error("MySQL database not configured"); } } function sendPing(node,msg) { if (node.brokerConn) { msg = {}; //msg.mentor_id = node.mentor_id; msg.qos = 2; msg.retain = false; msg.payload = JSON.stringify({topic:"mentor_ping", mentor_id: node.mentor_id}); msg.topic = "mentor_data"; node.brokerConn.publish(msg); } } function sendRecords(node,msg) { if (node.mydbConfig.connected) { node.status({}); var where = (node.priority === 0 || node.priority === 2) ? " status=0 ": " restful=0 "; var sql = "SELECT t1.device, t1.time, t1.content FROM mqtt_lecturas t1 JOIN ( SELECT MIN(TIME) AS min_value, device FROM mqtt_lecturas WHERE "+where+" GROUP BY device ) AS t2 ON t1.device = t2.device AND t1.time = t2.min_value WHERE t1."+where; node.mydbConfig.connection.query(sql, [], function(err, rows) { if (err) { log.error(err); return;} else for (var item in rows) { rows[item].mentor_id = node.mentor_id; rows[item].topic = "mentor_rec"; node.send({"payload" : rows[item].content}); msg.data = rows[item].content; if (node.priority === 0 || node.priority === 2 ) { if (node.brokerConn.connected) { msg.qos = 0; msg.retain = false; msg.payload = JSON.stringify(rows[item]); msg.topic = "mentor_data"; node.brokerConn.publish(msg); } } else { msg.payload = utils.encode(rows[item].content); node.opts.body = msg.payload; sendRestFul(node, msg); } } }) } else { node.error("Database not connected",msg); node.msg_status = {fill:"red",shape:"ring",text:"not yet connected"}; } if (!node.busy) { node.busy = true; node.status(node.msg_status); node.tout = setTimeout(function() { node.busy = false; node.status(node.msg_status); },500); } } function sendRestFul(node, msg) { request(node.opts, function (error, response, body) { node.status({}); if (error) { if (error.code === 'ETIMEDOUT') { node.error(RED._("common.notification.errors.no-response"), msg); setTimeout(function () { node.status({ fill: "red", shape: "ring", text: "common.notification.errors.no-response" }); }, 10); } else { node.error(error, msg); msg.payload = error.toString() + " : " + node.url; msg.statusCode = error.code; node.send(msg); node.status({ fill: "red", shape: "ring", text: error.code }); } } else { msg.payload = body; msg.headers = response.headers; msg.statusCode = response.statusCode; var obj = JSON.parse(msg.payload); msg.payload = obj; node.send(msg); if (obj.status == 1) { obj.device = obj.code; saveMysql(node, obj); node.status({fill:"green",shape:"ring",text:"OK"}); } } }) } function saveMysql(node, msg) { var update = (node.priority === 0 || node.priority === 2) ? " restful=1, status=" : " status=1, restful="; node.mydbConfig.connection.query("UPDATE mqtt_lecturas SET " + update + msg.status + " WHERE time*1="+ msg.time + " And device='"+msg.device + "'", [], function(err, rows) { if (err) { log.error(err);} else node.send({payload: {msg: rows.affectedRows + " record(s) updated", data:msg}}); }); } RED.nodes.registerType("Sender", Node); }