Ruchir Sharma
Published © GPL3+

Home automation using Raspberry Pi Matrix voice and Snips

Controlling lights, door and light intensity using Raspberry Pi, Matrix Voice and Snips.

ExpertFull instructions provided10 hours1,029
Home automation using Raspberry Pi Matrix voice and Snips

Things used in this project

Hardware components

MATRIX Voice
MATRIX Labs MATRIX Voice
Use for microphone
×1
5V 2.5A power supply adapter
×1
SG90 Micro-servo motor
SG90 Micro-servo motor
×1
MATRIX Creator
MATRIX Labs MATRIX Creator
Use either Matrix Creator or Voice
×1
Raspberry Pi 3 Model B+
Raspberry Pi 3 Model B+
×1
Relay (generic)
×8

Software apps and online services

Raspbian
Raspberry Pi Raspbian
Snips
MATRIX Labs Matrix-lite-js

Story

Read more

Schematics

Schematic

Code

assistant.js

JavaScript
Dummy code
/////////////
//VARIABLES//
/////////////
var fs=require('fs');
var mqtt = require('mqtt');
var client  = mqtt.connect('mqtt://localhost', { port: 1883 });
var func =require('./func.js'); 
var everloop = require('./everloop.js');
var pwmlight = require('./pwm.js');
var snipsUserName = 'ruchir';
var wakeword = 'hermes/hotword/default/detected';
var sessionEnd = 'hermes/dialogueManager/sessionEnded';
var lightState = 'hermes/intent/'+snipsUserName+':lights';
var nodemailer=require('nodemailer');
//////////////
//ON CONNECT//
//////////////
client.on('connect', function() {
   console.log('Connected to Snips MQTT server\n');
   client.subscribe('hermes/hotword/default/detected');
   client.subscribe('hermes/dialogueManager/sessionEnded');
   client.subscribe(lightState);
});


//////////////
//ON MESSAGE//
//////////////
client.on('message', function(topic,message) {
   var message = JSON.parse(message);
   switch(topic) {
       // * On Wakeword
       case wakeword:
           everloop.startWaiting();
           console.log('Wakeword Detected');
       break;
       // * On Light State Change
       case lightState:
           // Turn lights On/Off
           try{

// controlling light using PWM
		if(message.slots[0].rawValue==='on' || message.slots[0].rawValue==='off'|| message.slots[0].rawValue==='open' || message.slots[0].rawValue==='close'){ 

		var room=message.slots[1].rawValue; // room types slot
		console.log(room);
		var state=message.slots[0].rawValue; // state type slot
		console.log(state);
		var device=message.slots[2].rawValue;// device type slot
                console.log(device);



		switch(room){
			// Bathroom light on/off
			case 'bathroom':
               if(device ==='light'){
                    func.roomtype(0,state);
                    console.log("Bathroom light");
                }
                else if(device ==='fan'){
                    func.roomtype(5,state);
                    console.log("Bathroom fan");
                                }
			break;


			// Bedroom light on/off

			case 'bedroom':
				      if(device === 'light'){
					         func.roomtype(1,state);
  		             console.log("Bedroom light");
				      }
				      else if(device === 'fan'){
					         func.roomtype(6,state);
					         console.log("Bedroom fan");
				}

			break;

			// Kitchen light on/off

			case 'Kitchen':
              if(device === 'light'){
                  func.roomtype(2,state);
                  console.log("Kitchen light");
              }
              else if(device ==='fan'){
                  func.roomtype(7,state);
                  console.log("Kitchen chimney");
                  }

			break;


			// Living room light on/off
			case 'living room':
				      if(device ==='light'){
                  func.roomtype(3,state);
                  console.log("Living room light");
              }
              else if(device ==='fan'){
                  func.roomtype(8,state);
                  console.log("Living room fan");
                                }
			break;

			// Drawing room light on/off
			case 'drawing room':
				      if(device ==='light'){
                  func.roomtype(4,state);
                  console.log("Drawing room light");
              }
              else if(device ==='fan'){
                   func.roomtype(9,state);
                   console.log("Drawing room fan");
                                }

			break;
			
			// mail hall
			case 'main hall':
				if(device ==='door'){
                  func.roomtype(10,state);
                  console.log(" Main hall door ");
        }
        else if(device ==='light'){
                  func.roomtype(11,state);
                  console.log("main hall light");
                                }
			break;
			// for turning all lights on/off
			case 'all':func.roomtype(0,state);
        console.log("Bathroom light");
        func.roomtype(1,state);
        console.log("Bedroom light");
        func.roomtype(2,state);
				console.log("Kitchen light");
				func.roomtype(3,state);
				console.log("Living room light");
				func.roomtype(4,state);
				console.log("Drawing room light");
				func.roomtype(11,state);
				console.log("Hall room light");

                }
		var date=new Date();
                read json file info.json
                if(info==""){
                      write a fresh json file (array of objects in this case)
                }
                else{
                        append the data into the json file   
                }
		            read the new json file contents
		            if(greater than certain length){
                        mail it to you and delete the json records
                }
	}

	else{

        // for controlling light brightness using PWM

			var room=message.slots[0].rawValue; // room type slot
			console.log(room);
			var device=message.slots[1].rawValue; // device type slot
                	console.log(device);
			var brightness= message.slots[2].rawValue; // brightness value slot
                	console.log(brightness);


		switch(room){
			// set bathroom light brightness 
			case 'bathroom':

				if (device ==='light' && brightness === 'seventy five'){
                  pwmlight.pwmthreequater(0);
                  console.log('Brightness is set to 75 ')
				}
        else if (device === 'light' && brightness === 'fifty'){
                  pwmlight.pwmhalf(0);
					        console.log('Brightness is set to 50 ')
        }
        else if (device ==='light' &&  brightness === 'twenty five'){
                  pwmlight.pwmonequat(0);
					        console.log('Brightness is set to 25 ')
        }
				else if (device ==='light' &&  brightness === 'zero'){
                  pwmlight.pwmzero(0);
					         console.log('Brightness is set to 0 ')
				}						
				else if (device ==='light' &&  brightness === 'hundred'){
                  pwmlight.pwmfull(0);
                  console.log('Brightness is set to 100 ')
				}
			break;

			// set bedroom light brightness

			case 'bedroom' :

				if (device === 'light' &&  brightness === 'hundred'){
                  pwmlight.pwmfull(1);
					        console.log("Brightness is set to 100")
				}
				else if (device === 'light' && brightness === 'seventy five'){
                  pwmlight.pwmthreequater(1);
	                console.log("Brightness is set to 75")
 				}
        else if (device === 'light' && brightness === 'fifty'){
                  pwmlight.pwmhalf(1);
					        console.log("Brightness is set to 50")
        }
        else if (device === 'light' && brightness === 'twenty five'){
                  pwmlight.pwmonequat(1);
					        console.log("Brightness is set to 25")
        }
				else if (device === 'light' && brightness === 'zero'){
                  pwmlight.pwmzero(1);
                  console.log("Brightness is set to 0")
                                }

			break;
			
			// Set Kitchen light brightness

			case 'Kitchen' :

				if (device === 'light' &&  brightness === 'hundred'){
                  pwmlight.pwmfull(2);
                  console.log("Brightness is set to 100")
        }
				else if (device === 'light' && brightness === 'seventy five'){
                  pwmlight.pwmthreequater(2);
					        console.log("Brightness is set to 75")
        }
        else if (device === 'light' && brightness === 'fifty'){
                  pwmlight.pwmhalf(2);
					        console.log("Brightness is set to 50")
        }
        else if (device === 'light' && brightness === 'twenty five'){
                  pwmlight.pwmonequat(2);
					        console.log("Brightness is set to 25")
        }
				else if (device === 'light' && brightness === 'zero'){
                  pwmlight.pwmonequat(2);
                  console.log("Brightness is set to 0")
				}
			break;


			// Set Living room brightness 

			case 'living room':
				if (device === 'light' &&  brightness === 'hundred'){
                  pwmlight.pwmfull(3);
                  console.log("Brightness is set to 100")
        }
        else if (device === 'light' && brightness === 'seventy five'){
                  pwmlight.pwmthreequater(3);
                  console.log("Brightness is set to 75")
        }
        else if (device === 'light' && brightness === 'fifty'){
                  pwmlight.pwmhalf(3);
                  console.log("Brightness is set to 50")
        }
        else if (device === 'light' && brightness === 'twenty five'){
                  pwmlight.pwmonequat(3);
                  console.log("Brightness is set to 25")
        }
        else if (device === 'light' && brightness === 'zero'){
                  pwmlight.pwmonequat(3);
                  console.log("Brightness is set to 0")
				}

			break;

			//Set drawing room brightness 

			case 'drawing room':
				if (device === 'light' &&  brightness === 'hundred'){
                  pwmlight.pwmfull(4);
                  console.log("Brightness is set to 100")
        }
        else if (device === 'light' && brightness === 'seventy five'){
                  pwmlight.pwmthreequater(4);
                  console.log("Brightness is set to 75")
        }
        else if (device === 'light' && brightness === 'fifty'){
                  pwmlight.pwmhalf(4);
                  console.log("Brightness is set to 50")
        }
        else if (device === 'light' && brightness === 'twenty five'){
                  pwmlight.pwmonequat(4);
                  console.log("Brightness is set to 25")
        }
        else if (device === 'light' && brightness === 'zero'){
                  pwmlight.pwmzero(4);
                  console.log("Brightness is set to 0")
				}
				break;



                }
		var date=new Date();
                read json file info.json
                if(info==""){
                      write a fresh json file (array of objects in this case)
                }
                else{
                      append the data into the json file   
                }
		            read the new json file contents
		            if(greater than certain length){
                        mail it to you and delete the json records
                }

        }
} 
  // Expect error if `on` or `off` is not heard
           catch(e){
               console.log(e)
           }
       break;
       // * On Conversation End
       case sessionEnd:
           everloop.stopWaiting();
           console.log('Session Ended\n');
       break;
  }
});

HA.html

HTML
Dummy code
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>GUI View</title>

</head>
<style>
	body{
		background-size: 100% 100%;
		align:center;
	}
	table{
		color: white;
		border: ridge 3px yellow;
	}
</style>
<script src = "./js/angular.min.js"> </script> //uses angular js
<script src = './js/gauge.min.js'></script> //uses gauge js
<script src = 'index.js'></script>
<body onload = "checkcookie()" background ='./image/i1.jpeg' ng-app="APP" onmouseover="cellcolor()">
    <table border =3 id ='table_id'align="center">
        <tr>
            <td>
                room & devices
            </td>
            <td>
                device state
            </td>
            <td>
                device intensity
            </td>
	    <td>
		Time
	    </td>
        </tr>
        <tbody ng-controller="ctrl">
        <tr ng-repeat="x in datafile">
            <td>
                {{x.device}}
            </td>
            <td>
                {{x.state}}
            </td>
            <td>
                {{x.intensity}}
            </td>
	    <td>
		{{x.time}}
	    </td>
        </tr>
        </tbody>
    </table><br><br>
	<div style="background-color:yellow">
	<center>
	<canvas id='foo'></canvas><br>
	<div id='demo123'></div>
	</center>
	</div>
</body>
<script>

    var app= angular.module("APP",[]); 
    app.controller("ctrl",
        function($scope,$http){
            $http.get("./jsonpage/info.json").then(function(response){
                $scope.datafile=response.data;//fetches response from info.json
            });
    });

function cellcolor(){
        sets different colors of cells based on there text
    }
	read(); //calling read function
	setTimeout(function(){draw('demo123');},3000);//calling draw function at an interval of 3 sec
	function cookies(){
            var name = "User=";
            var decodedCookie = decodeURIComponent(document.cookie);
            var ca = decodedCookie.split(';');
            for(var i = 0; i < ca.length; i++) {
            var c = ca[i];
            while (c.charAt(0) == ' ') {
            c = c.substring(1);
            }
            if (c.indexOf(name) == 0) {
                    return c.substring(name.length, c.length);
                }
            }
        }
	function checkcookie(){
		var user=cookies();
		if(user==undefined){
			window.location.href = 'index.html'
		}
	}
</script>
</html>

pwm.js

JavaScript
var matrix = require("@matrix-io/matrix-lite");
var methods = {};// Declaration of method controls at the end

methods.pwmfull = function(pin){

                   matrix.gpio.setFunction(pin, 'PWM');
                   matrix.gpio.setMode(pin, 'output');
                   matrix.gpio.setPWM({
                        pin: pin,
                        percentage: 100,
                        frequency: 60 
});

};

methods.pwmthreequater = function(pin){

	   matrix.gpio.setFunction(pin, 'PWM');
	   matrix.gpio.setMode(pin, 'output');
	   matrix.gpio.setPWM({
	  	pin: pin,
		percentage: 75,
		frequency: 60 

});

};

methods.pwmhalf = function(pin){

	   matrix.gpio.setFunction(pin, 'PWM');
	   matrix.gpio.setMode(pin, 'output');
	   matrix.gpio.setPWM({
	  	pin: pin,
		percentage: 50,
		frequency: 60  

});
};

methods.pwmonequat = function(pin){

                   matrix.gpio.setFunction(pin, 'PWM');
                   matrix.gpio.setMode(pin, 'output');
                   matrix.gpio.setPWM({
                        pin: pin,
                        percentage: 25,
                        frequency: 60 // min 36
});
};

methods.pwmzero = function(pin){

                   matrix.gpio.setFunction(pin, 'PWM');
                   matrix.gpio.setMode(pin, 'output');
                   matrix.gpio.setPWM({
                        pin: pin,
                        percentage: 0,
                        frequency: 60 

});
};

methods.lightOn = function(pin){

                   matrix.gpio.setFunction(pin, 'PWM');
                   matrix.gpio.setMode(pin, 'output');
                   matrix.gpio.setPWM({
                        pin: pin,
                        percentage: 100,
                        frequency: 60 
});

};

methods.lightOff = function(pin){

                   matrix.gpio.setFunction(pin, 'PWM');
                   matrix.gpio.setMode(pin, 'output');
                   matrix.gpio.setPWM({
                        pin: pin,
                        percentage: 0,
                        frequency: 60 

});

};

//For controlling doors

methods.dooropen = function(pin){

		matrix.gpio.setFunction(pin, 'PWM');
		matrix.gpio.setMode(pin, 'output');
		matrix.gpio.setServoAngle({
  			pin: pin,
  			angle: 160,
  // minimum pulse width for a PWM wave (in milliseconds)
  			min_pulse_ms:0.8 
});

};

methods.doorclose = function(pin){

		matrix.gpio.setFunction(pin, 'PWM');
		matrix.gpio.setMode(pin, 'output');
		matrix.gpio.setServoAngle({
  			pin: pin,
  			angle: 10,
  // minimum pulse width for a PWM wave (in milliseconds)
  			min_pulse_ms:0.8 
});

};

module.exports = methods;

func.js

JavaScript
var everloop = require('./everloop.js');
var pwmlight = require('./pwm.js');
var methods={};
methods.roomtype = function(pin,state){
        if (state === 'on'){
                   pwmlight.lightOn(pin);
                   everloop.stopWaiting();
                   console.log('light is turned On');
               }
        else if(state === 'off'){
                   pwmlight.lightOff(pin);
                   everloop.stopWaiting();
                   console.log('light is turned Off');
               }
	else if(state === 'open'){
		   pwmlight.dooropen(pin);
		   everloop.stopWaiting();
		   console.log('door is open');
		}
	else if(state === 'close'){
                   pwmlight.doorclose(pin);
                   everloop.stopWaiting();
                   console.log('door is close');
                }

};

module.exports = methods;

everloop.js

JavaScript
/////////////
//VARIABLES//
/////////////
var zmq = require('zeromq');// Asynchronous Messaging Framework
var matrix_io = require('matrix-protos').matrix_io;// Protocol Buffers for MATRIX function
var matrix_ip = '127.0.0.1';// Local IP
var matrix_everloop_base_port = 20021;// Port for Everloop driver
var matrix_device_leds = 0;// Holds amount of LEDs on MATRIX device
var methods = {};// Declaration of method controls at the end
var waitingToggle = false;
var counter = 0;
///////////////////
//KEEP ALIVE PORT//
///////////////////
// Create a Pusher socket
var pingSocket = zmq.socket('push')
// Connect Pusher to Keep-alive port
pingSocket.connect('tcp://' + matrix_ip + ':' + (matrix_everloop_base_port + 1));
// Send a single ping
pingSocket.send('');
//////////////
//ERROR PORT//
//////////////
// Create a Subscriber socket
var errorSocket = zmq.socket('sub');
// Connect Subscriber to Error port
errorSocket.connect('tcp://' + matrix_ip + ':' + (matrix_everloop_base_port + 2));
// Connect Subscriber to Error port
errorSocket.subscribe('');
// On Message
errorSocket.on('message', function(error_message){
 console.log('Error received: ' + error_message.toString('utf8'));// Log error
});
////////////////////
//DATA UPDATE PORT//
////////////////////
// Create a Subscriber socket
var updateSocket = zmq.socket('sub');
// Connect Subscriber to Data Update port
updateSocket.connect('tcp://' + matrix_ip + ':' + (matrix_everloop_base_port + 3));
// Subscribe to messages
updateSocket.subscribe('');
// On Message
updateSocket.on('message', function(buffer){
 var data = matrix_io.malos.v1.io.EverloopImage.decode(buffer);// Extract message
 matrix_device_leds = data.everloopLength;// Save MATRIX device LED count
});
/////////////
//BASE PORT//
/////////////
// Create a Pusher socket
var configSocket = zmq.socket('push');
// Connect Pusher to Base Port
configSocket.connect('tcp://' + matrix_ip + ':' + matrix_everloop_base_port);
// Create an empty Everloop image
var image = matrix_io.malos.v1.io.EverloopImage.create();
setInterval(function(){
   // Turns off all LEDs
   if (waitingToggle == false) {
       for (var i = 0; i < matrix_device_leds; ++i) {
           // Set individual LED value
           image.led[i] = {
               red: 0,
               green: 0,
               blue: 0,
               white: 0
           };
       }
   };
   // Creates pulsing LED effect
   if (waitingToggle == true) {
       for (var i = 0; i < matrix_device_leds; ++i) {
           // Set individual LED value
           image.led[i] = {
               red: 0,
               green: 0,
               blue: (Math.round((Math.sin(counter) + 1) * 100) + 10),// Math used to make pulsing effect
               white: 0
           };
       }
   };
   counter = counter + 0.2;
   // Store the Everloop image in MATRIX configuration
   var config = matrix_io.malos.v1.driver.DriverConfig.create({
       'image': image
   });
   // Send MATRIX configuration to MATRIX device
   if(matrix_device_leds > 0) {
       configSocket.send(matrix_io.malos.v1.driver.DriverConfig.encode(config).finish());
   };
},50);
///////////////////
//WAITING METHODS//
///////////////////
methods.startWaiting = function() {
   waitingToggle = true;
};
methods.stopWaiting = function() {
   waitingToggle = false;
};
module.exports = methods;

index.js

JavaScript
function read(){
console.log('js started');
var intensity;

var rawfile = new XMLHttpRequest();
rawfile.overrideMimeType("application/json");
rawfile.open("GET", "./jsonpage/info.json", true); 
rawfile.onreadystatechange = function()
{
        if (rawfile.readyState === 4 && rawfile.status == "200" )
        {   
           
              console.log("ready to read");
            
              var data = JSON.parse(rawfile.responseText);
              console.log('json parsed');
              intensity = data[data.length-1].intensity;
              console.log('intensity set to ',intensity);
              console.log('intensity is',intensity);
              document.getElementById('demo123').innerHTML = intensity;
          }
}
rawfile.send();

}
function draw(x){
  var opts = {
  angle: -0.1,
  lineWidth: 0.1, //0.15
  limitMax: 'true', //false
  title:{
    text: 'Intensity'
  } ,
  
  strokeColor: 'red',
  generateGradient: true,
    pointer: {
    length: 0.5, // 1 The radius of the inner circle
    strokeWidth: 0.03, //  The rotation offset
    color: 'orange' // Fill color
  },
  staticLabels: {
    font: "90% sans-serif",  // Specifies font
    labels: [0, 25, 50, 75, 100],  // Print labels at these values
    color: "red",  // Optional: Label text color
    fractionDigits: 2  // Optional: Numerical precision. 0=round off.
  },
    strokeColor: 'red', 
    staticZones: [
     {strokeStyle: "powderblue", min: 0, max: 25}, 
     {strokeStyle: "lightskyblue", min: 25, max: 50}, 
     {strokeStyle: "royalblue", min: 50, max: 75}, 
     {strokeStyle: "blue", min: 75, max: 100},
  ],
 
  generateGradient: true
};
console.log(document.getElementById(x)); //
if(document.getElementById(x).firstChild.data == 'zero'){
	var inten=0;
}
if(document.getElementById(x).firstChild.data == 'twenty five'){
        var inten=25;
}
if(document.getElementById(x).firstChild.data == 'fifty'){
        var inten=50;
}
if(document.getElementById(x).firstChild.data == 'seventy five'){
        var inten=75;
}
 
var gauge_value = inten;
console.log(gauge_value);
var target = document.getElementById('foo'); 
var gauge = new Gauge(target).setOptions(opts); 
gauge.maxValue = 100; // set max gauge value
gauge.animationSpeed = 32; // set animation speed (32 is default value)
gauge.set(gauge_value); // set actual value  
}

server.js

JavaScript
var http = require('http');
var url = require('url');
var fs = require('fs');
var express=require('express');
var bodyParser=require('body-parser');
var nodemailer=require('nodemailer');

var app = express();
app.post('/formaction',function(req,res){
res.writeHead(301,{'location':'http://127.0.0.1:8080/HA.html'});
res.write('<html><script>function newpage(){window.location.href="localhost:8008/HA.html";}</script><body onload="newpage()"></body></html>');
res.end();
var transporter = nodemailer.createTransport({
  service: 'gmail',
  auth: {
    user: '', // your email address
    pass: '' // password
  }
});
console.log('transporter ready');
var mailOptions = {
  from: '', // sender email address 
  to: '', // receiver email address
  subject: 'Sending Email using Node.js',
  text: Any
};
console.log('mail options set');
transporter.sendMail(mailOptions, function(error, info){
  if (error) {
    console.log(error);
  } else {
    console.log('Email sent: ' + info.response);
  }
console.log('mail on sending');
});
}).listen(8008);



http.createServer(function (req, res) {
  var q = url.parse(req.url, true);
  var filename = "." + q.pathname;
  fs.readFile(filename, function(err, data) {
    if (err) {
      res.writeHead(404, {'Content-Type': 'text/html'});
      return res.end("404 Not Found");
    } 
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.write(data);
    return res.end();
  });
}).listen(8080); 

index.html

HTML
<html>
<head>

<title>Login Page</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>


<body bgcolor = #E6E6FA >

<div align='right'>
<canvas id="canvas" width="150" height="150"
style="background-color:red">
</canvas>
</div>


<div align="center">
<p><font color="red"size=5>PLEASE LOGIN TO SEE THE LOGS</font></p> 
</div>


<form name="loginForm" method="post" action="HA.html">
<table width="20%" bgcolor="0099CC" align="center" >

<tr>
<td colspan=2><center><font size=4><b>Login Page</b></font></center></td>
</tr>

<tr>
<td>Username:</td>
<td><input type="text" size=25 name="userid"></td>
</tr>

<tr>
<td>Password:</td>
<td><input type="Password" size=25 name="pwd"></td>
</tr>


<tr>
<td ><input type="Reset"></td>
<td><input type="submit" onclick="return check(this.form)" value="Login"></td>
</tr>

</table>
</form>
<script language="javascript">
function check(form)
{

if(form.userid.value == "default" && form.pwd.value == "default")
{	
	var date=new Date();
	date.setTime(date.getTime()+(15*60*1000));
	document.cookie= 'User=default;expires='+date.toGMTString()+';';
	return true;
	
}
else
{
	alert("Error, Enter valid Username or Password")
	return false;
}
}
</script>


</body>
</html>

Credits

Ruchir Sharma

Ruchir Sharma

12 projects • 182 followers

Comments