UNPKG

node-red-contrib-esplogin

Version:

This node is specifically designed to work with ESP-GO home control software - link and info at https://tech.scargill.net

119 lines (97 loc) 5.42 kB
/** * Mostly - apart from the Sunrise module on which this depends * this is copyright (c) Peter Scargill - but as I've had so * many ideas from others - consider it free to use for whatever * purpose you like. If you redesign it please remember to drop * my name and link in there somewhere. http://tech.scargill.net * This software puts out a message suitable for MQTT use depending * on whether a specific MQTT unit inputs a message or a daily update * occurs - daily updates send message which will go to ALL units. * specific inputs result in a message being returned to a specific * unit. The information includes the time. **/ module.exports = function(RED) { "use strict"; var SunCalc = require('suncalc'); function esploginNode(n) { RED.nodes.createNode(this,n); var node = this; node.lat = n.lat; node.lon = n.lon; node.start = n.start; node.end = n.end; node.duskOff=n.duskoff; node.dawnOff=n.dawnoff; node.on("input", function (inmsg) { var now = new Date(); var nowOff=-now.getTimezoneOffset()*60000; var times = SunCalc.getTimes(now, node.lat, node.lon); var nowMillis = Date.UTC(now.getUTCFullYear(),now.getUTCMonth(),now.getUTCDate(),now.getUTCHours(),now.getUTCMinutes(), 1); var accurateMillis = Date.UTC(now.getUTCFullYear(),now.getUTCMonth(),now.getUTCDate(),now.getUTCHours(),now.getUTCMinutes(), now.getUTCSeconds()); var midnightMillis = Date.UTC(now.getUTCFullYear(),now.getUTCMonth(),now.getUTCDate(),0,1); var startMillis = Date.UTC(times[node.start].getUTCFullYear(),times[node.start].getUTCMonth(),times[node.start].getUTCDate(),times[node.start].getUTCHours(),times[node.start].getUTCMinutes()); var endMillis = Date.UTC(times[node.end].getUTCFullYear(),times[node.end].getUTCMonth(),times[node.end].getUTCDate(),times[node.end].getUTCHours(),times[node.end].getUTCMinutes()); var outmsg = { payload:"", topic:""}; nowMillis+=nowOff; accurateMillis+=nowOff; startMillis+=nowOff; endMillis+=nowOff; var dawn = (((startMillis - midnightMillis)/60000)+Number(node.dawnOff))%1440; var dusk = (((endMillis - midnightMillis)/60000)+Number(node.duskOff))%1440; var today = (Math.round((nowMillis - midnightMillis)/60000))%1440; var m=inmsg.payload; var newMsg = { topic:"", payload:""}; var newMsg2 = { topic:"", payload:""}; var newMsg3 = { topic:"", payload:""}; var newMsg4 = { topic:"", payload:""}; var newMsg5 = { topic:"", payload:""}; if ((inmsg.topic!="Xstartup") && (inmsg.topic!="X12hours")) { try { var fred; fred=JSON.parse(m); } catch (e) { node.error("Bad JSON:"+m) ; return ([null,null,null,null]); } outmsg.topic = fred.id +"/toesp"; newMsg5.topic = fred.id + "/toesp"; } outmsg.payload = '{time:' + accurateMillis/1000 + ';dusk:' + dusk+ ';dawn:' + dawn + '}'; newMsg5.payload = '{"time":' + accurateMillis/1000 + ',"dusk":' + dusk+ ',"dawn":' + dawn + '}'; if (inmsg.topic=="X12hours") { outmsg.topic='toesp'; newMsg5.topic='toesp'; node.send([outmsg,null,null,null,newMsg5]); node.status({fill:"blue",shape:"dot",text:"12hr updated"}); } else if (inmsg.topic=="Xstartup") { outmsg.topic='toesp'; newMsg5.topic='toesp'; node.send([outmsg,null,null,null,newMsg5]); node.status({fill:"yellow",shape:"dot",text:"Started"}); } else { node.status({fill:"green",shape:"dot",text:"last unit: "+ fred.id}); newMsg.topic = "insert into device_list(device_name, device_description, device_attribute,logins,last_update,creation_date) values('" + fred.id +"','" + fred.desc + "','" + fred.attribute + "',1,NOW(),NOW()) on duplicate key update logins = logins+1, device_description='" + fred.desc + "', device_attribute='" + fred.attribute + "', last_update=NOW()"; newMsg2.payload="Logging in device " + fred.id + " at " +("0" + now.getHours()).slice(-2) + ':' +("0" + now.getMinutes()).slice(-2) + ':' + ("0" + now.getSeconds()).slice(-2) + ' ' + ("0" + (now.getDate())).slice(-2) + '-' + ("0" + (now.getMonth() + 1)).slice(-2) + '-' + now.getFullYear(); // in the case of mysql - send out the one message... for SQLite - different syntax so send it out in 2 halves... the conditional insert then the increment newMsg3.topic = "insert or ignore into device_list(device_name, device_description, device_attribute,logins,last_update,creation_date) values('" + fred.id +"','" + fred.desc + "','" + fred.attribute + "',1,(datetime('now','localtime')),(datetime('now','localtime')))"; newMsg4.topic = "update device_list set logins = logins+1, last_update=(datetime('now','localtime')) where device_name='" + fred.id +"'"; node.send([outmsg,newMsg,newMsg2,[newMsg3,newMsg4],newMsg5]); } }); var tock = setTimeout(function() { var msg = { payload:'{}', topic:"Xstartup"}; node.emit("input",msg); },5000); // wait 5 secs before starting to let things settle down - e.g. UI connect var tick = setInterval(function() { var msg = { payload:'{}', topic:"X12hours"}; node.emit("input",msg); },60000*60*12); // trigger every every 12 hours... node.on("close", function() { if (tock) { clearTimeout(tock); } if (tick) { clearInterval(tick); } }); } RED.nodes.registerType("esplogin",esploginNode); }