Hi all, So I have a house on spirit lake in Iowa, and I have to admit I have a problem. I needed a decent way to control the dock lights. I needed it to work over the internet and I needed it to have an app…. Since my lake house has media com for internet a NAT wouldn’t be sufficient.
First let me get this out of the way…
Anyways onwards and upwards… I chose nodes for this project, mostly because it’s bad ass. The client uses a raspberry pi, along with it’s GPIO, also 3 relays were used to power 3 different sets of lights…
The code at the server listened for connections front the client. and acted not he messages.
Here is the dock lighthouse master source code!
var io = require('socket.io').listen(3000); var iolocal = require('socket.io').listen(3001); var mysql = require('mysql'); var light; var connection = mysql.createConnection({ host : 'localhost', user : 'docklighthouse', password : 'docklighthouse!', socketPath : '/var/run/mysqld/mysqld.sock', database : 'docklighthouse' }); connection.connect(); function addlight(id,serial,light,sock) { connection.query("DELETE from lights where userid=\""+id+"\" and serial=\""+serial+"\" and lightid=\""+light.id+"\"", function(err, rows) { if(err) { throw err; } else { connection.query("INSERT into lights (userid,serial,lightid,name,socket) values (\""+id+"\",\""+serial+"\",\""+light.id+"\",\""+light.name+"\",\""+sock+"\")",function(err,rows) { if (err) { throw err; } else { setLightStatus(id,serial,light,sock); } }); } }); } function setLightStatus(id,serial,light,sock) { connection.query("UPDATE lights set status=\""+light.status+"\",socket=\""+sock+"\" where userid=\""+id+"\" and serial=\""+serial+"\" and lightid=\""+light.id+"\"",function(err,rows) { if (err) { throw err; } }); } function checkLight(light,serial,id,sock) { connection.query("select count(*) as count from lights where userid=\""+id+"\" and serial=\""+serial+"\" and lightid=\""+light.id+"\" and name=\""+light.name+"\"", function(err, rows) { if (err) { throw err; } else { if (rows[0].count == 0) { //insert it addlight(id,serial,light,sock); } else { setLightStatus(id,serial,light,sock); } } }); } function checkLights(id,serial,lights,sock) { for (var i = 0; i < lights.length; i++) { light = lights[i]; checkLight(light,serial,id,sock); } } function getUsernameForLights(username,password,serial,lights,sock) { var id = 0; connection.query("SELECT id from users where username=\""+username+"\" and password=password(\""+password+"\")", function(err, rows) { if(err) { throw err; }else{ id = rows[0].id; checkLights(id,serial,lights,sock); } }); } function addLights(username,password,serial,lights,sock) { getUsernameForLights(username,password,serial,lights,sock); } function setLightStatusUpdate(sock,lightid,status) { connection.query("UPDATE lights set status=\""+status+"\" where socket=\""+sock+"\" and lightid=\""+lightid+"\"", function(err, rows) { if(err) { throw err; }else{ } }); } io.sockets.on('connection', function (socket) { socket.on('lights', function (data) { var json = JSON.parse(data); var username = json.username; var password = json.password; var serial = json.serial; var lights = json.lights; addLights (username,password,serial,lights,socket.id); }); socket.on('setLightStatus',function(data) { var json = JSON.parse(data); setLightStatusUpdate(json.socket,json.lightid,json.status); }); }); iolocal.sockets.on('connection', function (socketlocal) { socketlocal.on('togglelight', function (data) { var json = JSON.parse(data); io.sockets.socket(json.socket).emit("togglelight",data); }); }); |
The client looks like
var db = dblite('/home/dock/dock.db'); var io = require('socket.io-client'); var socket = io.connect('http://x.x.x.x:3000'); var fs = require('fs'); var serial = ""; var username = ""; var password = ""; start(); function start() { db.query('SELECT username,password from userinfo',function (err, rows) { username = rows[0][0]; password = rows[0][1]; getSerial(); }); } function getSerial() { var fileContent = fs.readFileSync('/proc/cpuinfo').toString(); var lines = fileContent.split("\n"); for( var i = 0; i < lines.length; ++i ) { if (lines[i].indexOf("Serial") > -1) { var sp = lines[i].split(":"); serial = sp[1].trim(); } } getLights(); //sendStatus(); setInterval(function(){getLights()},5000); } function getLightStatusReal(id) { var lightStatus="0"; if (id == 1 ) { lightStatus = fs.readFileSync("/sys/class/gpio/gpio7/value"); } if (id == 2 ) { lightStatus = fs.readFileSync("/sys/class/gpio/gpio8/value"); } if (id == 3 ) { lightStatus = fs.readFileSync("/sys/class/gpio/gpio25/value"); } lightStatus = lightStatus.toString(); lightStatus = lightStatus.trim(); return lightStatus; } function getLights() { db.query('SELECT light,name FROM lights',function (err, rows) { var i = 0; var json = ""; while (i < rows.length) { if (json != "") { json += ","; } var name = rows[i][1]; name = name.escapeSpecialChars(); var id = rows[i][0]; var status = getLightStatusReal(id); json += "{\"name\": \""+name+"\",\"id\": \""+rows[i][0]+"\",\"status\":\""+status+"\"}"; i++; } json = "{\"username\":\""+username+"\",\"password\":\""+password+"\",\"command\":\"setlights\",\"serial\":\""+serial+"\",\"lights\": ["+json+"]}"; console.log(json); socket.emit("lights",json); }); } function getLightStatus() { db.query('SELECT light,name FROM lights',function (err, rows) { var i = 0; var json = ""; while (i < rows.length) { if (json != "") { json += ","; } var name = rows[i][1]; name = name.escapeSpecialChars(); var id = rows[i][0]; var status = getLightStatusReal(id); json += "{\"name\": \""+name+"\",\"id\": \""+rows[i][0]+"\",\"status\":\""+status+"\"}"; i++; } json = "{\"username\":\""+username+"\",\"password\":\""+password+"\",\"command\":\"setlights\",\"serial\":\""+serial+"\",\"lights\": ["+json+"]}"; //console.log(json); socket.emit("lights",json); }); } function sendStatus() { setInterval(function() { getLightStatus(); },5000); } socket.on('togglelight',function (data) { var json = JSON.parse(data); var lightid = parseInt(json.lightid); var lightStatus="0"; if (lightid == 1 ) { lightStatus = fs.readFileSync("/sys/class/gpio/gpio7/value"); if (parseInt(lightStatus) == 1) { fs.writeFileSync("/sys/class/gpio/gpio7/value","0"); socket.emit("setLightStatus",'{"lightid":"'+lightid+'","socket":"'+json.socket+'","status":"0"}'); } else { fs.writeFileSync("/sys/class/gpio/gpio7/value","1"); socket.emit("setLightStatus",'{"lightid":"'+lightid+'","socket":"'+json.socket+'","status":"1"}'); } } if (lightid == 2 ) { lightStatus = fs.readFileSync("/sys/class/gpio/gpio8/value"); if (parseInt(lightStatus) == 1) { fs.writeFileSync("/sys/class/gpio/gpio8/value","0"); socket.emit("setLightStatus",'{"lightid":"'+lightid+'","socket":"'+json.socket+'","status":"0"}'); } else { fs.writeFileSync("/sys/class/gpio/gpio8/value","1"); socket.emit("setLightStatus",'{"lightid":"'+lightid+'","socket":"'+json.socket+'","status":"1"}'); } } if (lightid == 3 ) { lightStatus = fs.readFileSync("/sys/class/gpio/gpio25/value"); if (parseInt(lightStatus) == 1) { fs.writeFileSync("/sys/class/gpio/gpio25/value","0"); socket.emit("setLightStatus",'{"lightid":"'+lightid+'","socket":"'+json.socket+'","status":"0"}'); } else { fs.writeFileSync("/sys/class/gpio/gpio25/value","1"); socket.emit("setLightStatus",'{"lightid":"'+lightid+'","socket":"'+json.socket+'","status":"1"}'); } } }); String.prototype.escapeSpecialChars = function() { return this.replace(/\\n/g, "\\n") .replace(/\\'/g, "\\'") .replace(/\\"/g, '\\"') .replace(/\\&/g, "\\&") .replace(/\\r/g, "\\r") .replace(/\\t/g, "\\t") .replace(/\\b/g, "\\b") .replace(/\\f/g, "\\f"); }; |
And that’s it, short of some database and an iPhone app this is what makes up dock lighthouse!!
–John “Let the light Shine on me!” Hass