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
JavaScript
/**
* 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);
}