Introduction: Google Home + Raspberry Pi Power Strip

UPDATE #1: Starter Application Now Available!

Hello World!

Now that the Google Home is out, there are lots of people wondering how to use it to control their existing Arduino or Raspberry Pi smart devices. Now that I've got my setup working, I thought I would share my fairly simple setup with you.

While I am currently using a Raspberry Pi Zero to control a five outlet power strip, This guide is more general. It will walk you through how to use any Raspberry Pi device to control an electronic relay, using Node.js and the IFTTT web services.

Check out a video of the device in action, or scroll to the final step, where I have it embedded!

https://www.youtube.com/watch?v=mCTjZTCaTzM

Step 1: What You'll Need

At the very least, you will need:

And the rest is software. If you are totally new to Raspberry Pi, be aware that you may need some additional hardware like usb cables or wifi chips in order to get up and running.

Step 2: On-Board Software Setup

So, to make this guide as user-friendly as possible, I'm going to include some links that you power-users might find excessive.

TLDR in advance: set up your raspberry pi on WiFi or Ethernet (preferably WiFi) and configure your router so that you have a server available externally. You'll use raspberry-gpio-python to control the relay.

For newer hobbyists, you will start out by setting up your raspberry pi.

You will want to get your raspberry pi set up on your local WiFi.

I'll be working in Node.js, so you will want to upgrade to the latest version of Node.

Configure the router so that port 80 redirects to your raspberry Pi's MAC address. (Sorry, this will depend on what router you're using, and there isn't really a universal guide)

I prefer using SSH to connect to my raspberry pi.

Plenty of things can go wrong in this process while you're starting out. Stay patient, and google things. The community is very supportive, and the odds are someone else has had your problem before!

Step 3: Make a Circuit

So, there are lots of guides on getting started with relays on the Rasberry Pi. I mostly used Youtube tutorials like this one to get started.

Basically, you will need to provide power from your Raspberry Pi's 5v out pin, and choose which control pins you want to use to send the on/off signal to trigger the relay.

Using the above image, I recommend using the yellow pins for whichever model you use.

Step 4: Create Your Server

Starter application now available!

Vist https://github.com/krpeacock/google_home_starter to download a starter application for this project, and follow the README to get it configured and running on your own device.

You can also check out my more-fleshed-out React project at https://github.com/krpeacock/power_strip/tree/strip if you are interested in seeing a slightly more complex version of the project

The main step is to build an Node + Express server that is able to handle POST requests.

In my code, it looks like this:

app.post('/api/switches/:id', function(req, res){  

  var foundSwitch = getSwitch(req.params.id);  

  foundSwitch.toggle();  

  saveState();  

  console.log("postSwitch "+JSON.stringify(foundSwitch));  

  res.json(foundSwitch);

})

I make a post request to /api/switches/:id, where id is written as sw1, sw2, and so on. After identifying the switch, I call a toggle() method to run my Python script and change the state of my relay.

I wrote individual python scripts for off and on functions, specifying which GPIO pin was tied to each switch. for example, sw1_on.py looks like:

import RPi.GPIO as GPIO<br>GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(23, GPIO.OUT)

Then, by requiring the Python-shell node module, I can execute the script, using:

<p>const PythonShell = require('python-shell');</p><p>PythonShell.run('./public/python/scripts/sw1_on.py')</p>

Looking back, this is a little bit tricky for a non-developer. I probably will need to throw in some starter code down the road.

Step 5: Connecting to the Google Home

If you've managed to get this far, this information is probably the only reason that you're here. That's fine! this is the cool bit.

You have your server running, and it can control a relay. It is structured so that a POST request can change the state of the relay. Now all you need is to get your Google Home to deliver a POST request to your device. Eventually, you will want to add some authorization so that strangers can't control your devices, but now we just want the request to work.

  1. Go to https://ifttt.com and connect it to your Google account.
  2. Go to https://ifttt.com/create, and click on the +this link.
  3. Search for Google Assistant
  4. Select Google Assistant
  5. Choose "Say a simple phrase" as your trigger
  6. Tell Google what should trigger the action.
    • I prefer to name use the device I want to control, so I said "turn my lamp on"
  7. Designate a response
    • "Turning your lamp on"
  8. Click "Create Trigger" and proceed
  9. Click the +that link
  10. Search for "Maker"
  11. Choose the Gray icon (not WeMo Maker)
  12. Select "Make a web request"

Now, here is the important bit. Identify your IP address (or domain, if you set up that level of abstraction), and enter it into the URL portion. If you followed my the structure in my starter project, it will look like

http://ipaddressgoeshere/API/switches/sw1?password=yourpasswordhere

Set Method to POST

Content Type should be text/plain

Body can be left blank

Create your action and choose Finish.

Step 6: Congrats!

You've done it! Your Google Home now knows how to communicate over HTTP with your smart device.

Since this does a toggle, you can technically keep saying "Turn the lamp on" to turn it on and off. I preferred to add duplicate on and off commands for each of my switches to make everything feel more comfortable.

If you enjoyed this project, please share! There's a LinkedIn post here that can really help me out.

I am a web developer struggling to find work in the SF Bay Area, so I could use some visibility. If you are looking to hire a JavaScript developer, or know someone who is, you can can get in touch with me at kylpeacock@gmail.com.

If you would like to contribute to this guide, or to work with me on building out a starter application, you can also feel free to get in touch! I want to make this process as easy as possible for new hackers.

Comments

author
ChinmayJ9 (author)2017-07-02

Hi Kyle

thanks for putting this up. I'm able to get the starter app running and when I type npm start i get the following (which I assume means its running normally)

pi@raspberry:~/google_home_starter $ npm start

> google_home_controller@1.0.0 start /home/pi/google_home_starter

> node app.js

Listening on port 8000

However ,when I try your actual code which is in power strip i get the following error :

pi@raspberry:~/power_strip $ npm start

> strip@1.0.0 start /home/pi/power_strip

> node app.js

Listening on port 8000

events.js:182

throw er; // Unhandled 'error' event

^

Error: ENOENT: no such file or directory, open 'saveState.json'

npm ERR! code ELIFECYCLE

npm ERR! errno 1

npm ERR! strip@1.0.0 start: `node app.js`

npm ERR! Exit status 1

npm ERR!

npm ERR! Failed at the strip@1.0.0 start script.

npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:

npm ERR! /home/pi/.npm/_logs/2017-07-02T20_41_00_338Z-debug.log

Any idea what could be going on here. Im very new to node and have very limited experience so pardon my ignorance !

thanks

author
call_me_kyle (author)ChinmayJ92017-07-03

That will be an easy fix. The raspberry pi doesn't have a copy of the saveState.json file, because I disabled git tracking for it. It gets annoying when normal app functioning creates changes to the app.

In retrospect, I should have used a default state to start the app, but it's easy enough to copy the file over.

Copy the text from your computer's saveState. Run `touch saveState.json` in the root directory of your raspberry pi app and paste the contents in. That should do it for you!

author
ChinmayJ9 (author)call_me_kyle2017-07-03

Thanks for the quick reply! I realized after I wrote the comment that I was missing the file so I downloaded the zip file and it does run successfully now. Only problem is I can't get it to run on port 80 my router complains of a conflict with another virtual sever. Port 8080 works. Can I just edit the URL on the ifft applet to do the following?
http://ipaddressgoeshere/API/switches/sw1?password=yourpasswordhere:8080
Thanks

author
Fabritren (author)2017-05-21

Thank you very much for the information! I did not know about IFTTT, it simply works great!

author
ManishU3 (author)2017-05-20

I cannot find Maker Trigger in IFTTT. Am I missing something here?

author
call_me_kyle (author)ManishU32017-05-21

Ah, that's because Google Assistant will be the trigger. The Maker web request is the IFTTT action.

author
jf89 (author)2017-04-05

Hey dude, awesome tutorial. I'm having a little trouble with starting the npm. I've added the port and psw to the hidden .env file but when I "npm start" I get this...

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

pi@raspberrypi:~/google_home_starter $ npm cache clear

pi@raspberrypi:~/google_home_starter $ npm start

> google_home_controller@1.0.0 start /home/pi/google_home_starter

> node app.js

module.js:340

throw err;

^

Error: Cannot find module 'dotenv'

at Function.Module._resolveFilename (module.js:338:15)

at Function.Module._load (module.js:280:25)

at Module.require (module.js:364:17)

at require (module.js:380:17)

at Object.<anonymous> (/home/pi/google_home_starter/app.js:1:63)

at Module._compile (module.js:456:26)

at Object.Module._extensions..js (module.js:474:10)

at Module.load (module.js:356:32)

at Function.Module._load (module.js:312:12)

at Function.Module.runMain (module.js:497:10)

npm ERR! google_home_controller@1.0.0 start: `node app.js`

npm ERR! Exit status 8

npm ERR!

npm ERR! Failed at the google_home_controller@1.0.0 start script.

npm ERR! This is most likely a problem with the google_home_controller package,

npm ERR! not with npm itself.

npm ERR! Tell the author that this fails on your system:

npm ERR! node app.js

npm ERR! You can get their info via:

npm ERR! npm owner ls google_home_controller

npm ERR! There is likely additional logging output above.

npm ERR! System Linux 4.4.50+

npm ERR! command "/usr/bin/nodejs" "/usr/bin/npm" "start"

npm ERR! cwd /home/pi/google_home_starter

npm ERR! node -v v0.10.29

npm ERR! npm -v 1.4.21

npm ERR! code ELIFECYCLE

npm WARN This failure might be due to the use of legacy binary "node"

npm WARN For further explanations, please read

/usr/share/doc/nodejs/README.Debian

npm ERR!

npm ERR! Additional logging details can be found in:

npm ERR! /home/pi/google_home_starter/npm-debug.log

npm ERR! not ok code 0

pi@raspberrypi:~/google_home_starter $

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

two things in my mind...

-do I need to change the code you provided before running npm

-everytime I assign port 80 to the rpi the port closes.... I check with "canyouseeme.org" The port works with my cctv system but when I assign it to the rpi ip it closes... Let me know if you have any thoughts on that pls.

-----------------------

Also I have no idea what to do with the code after starting npm, if you could point to some resources or walk us through it I would be willing to make a video to put here.

Thanks so much in advance and good luck in your job hunt.

JF

[delete]

author
marciokoko (author)jf892017-04-11

Hi

jf89, did you fix this? Im getting the same error

author
jf89 (author)marciokoko2017-04-11

no mate... but let me know if you do!

I think its going to have something to do with the script, like us hosting/altering the files but I have not experience in js or node....

author
marciokoko (author)jf892017-04-17

i got it working on my laptop.

1. So you install node.js on your computer where you will test this starter project in node.js. Then inside the starter directory which has the package.json file, you run "npm install" which installs all the modules required by that package.json.

2. Then you create a file (in the same directory) called ".env" using touch or nano. Touch is nice because you just type touch .env and itll create the empty file for you.

3. Then you edit the file to look like this:

DEV=TRUE

PORT=8000

PASS=yourpass

4. Finally you run "npm start" and you get a prompt telling you the server is running and you can run the ipaddress:8000/api...etc... url in your browser with the password in the .env file you created.

author
jf89 (author)marciokoko2017-04-17

Finally got it, thanks man.

author
marciokoko (author)2017-04-11

I updated node and npm on my mac (im away from my pi), downloaded and unzipped the google_home_master file and Im reading thru the readme. How do I run touch .env?

author
marciokoko (author)2017-04-10

Hi. I wrote you a message via instruct able but I'm not sure it worked. I have a raspberry with a Bluetooth module in it's GPio pins. A script sends commands to that Bluetooth module which relays the command to a Bluetooth relay board which controls components. What I want to do now is to have a Google home send commands to that raspberry pie in order to execute a different script. Is that possible?

author
AntonioN43 (author)2017-03-23

hello Kyle,

i am a developer , and i worked with arduino , but not raspberry pi and node.i did everything step by step.
extracted the zip in Home/pi
not sure what to do next
when i call the http://192.168.0.2/API/switches/sw1?password=Passw...
this is what i get
___________________________________________

Not Found

The requested URL /API/switches/sw1 was not found on this server.


Apache/2.4.10 (Raspbian) Server at 192.168.0.2 Port 80

________________________________________________

i tried to run the app.js and i got this error:

File "app.js", line3const Pythonshell = reque.......
sytax error

author
call_me_kyle (author)AntonioN432017-03-23

It sounds like Apache is hijacking port 80. You'll need to disable the Apache server with something like 'sudo service stop Apache' and then you'll be able to to run the Node.js server with 'sudo node app.js'.

Also, if you haven't yet, make sure to run 'npm install' in the console so that the package manager can pull in the additional resources that I aren't part of the bundle. You'll need those before Node will be able to execute my starter code.

Let me know if that helps!

author
AntonioN43 (author)call_me_kyle2017-03-24

hello again ,
after playing around for a while i sorted out the problem.
now when i call the link with the password from any device on my network it diplay this page " {"id":"sw1","state":"off","name":"Kyle's Lamp"}"
but still the relay is no switching on or of, i modified the python on and off script and changed the pin number to the one i am using.
should i do anything else ?

author
call_me_kyle (author)AntonioN432017-03-24

So, the problem there is that you are making a GET request to the API, which is telling you the state of the sample switch. You'll need to make a POST request to the server in order to affect the state.

A great tool for this is https://www.getpostman.com/.

author
AntonioN43 (author)call_me_kyle2017-03-25

hello again.
and sorry , but i couldnt get my head around that.
i installed it on my pc, and when i request the link , i get the same result i get on a normal browser.
i got my google home to australia ( its not relased her yet) and want it to work so bad :P

author
AntonioN43 (author)call_me_kyle2017-03-24

1- i did stop apache .
2- when i do 'sudo node app.js' i get "Listening on port undefined'
what dose this means ?
3- when i go to "http://192.168.0.2:8000/API/switches/sw1?password=...
i am asked again to enter username and a password.

author
call_me_kyle (author)AntonioN432017-03-24

It is trying to read your password and port from a hidden .env file that you will need to create.

Run `touch .env` in the root of the project. In that file, you'll need a port and password with syntax like this:

PORT=80

PASSWORD=password_here

I didn't want to share my info up on GitHub, and I figured you wouldn't either!

author
DmitriyB7 (author)2017-01-25

This is very interesting, I was looking for something similar!

No authentication? So anyone knowing your ip address can easily control your lamp even without Google Home.
My preference would be a local service, but I don't know when (or if) Google is going to allow that.

author
call_me_kyle (author)DmitriyB72017-01-27

I've just released a starter application that requires you to use a password query string in the URL. It's not the most secure method, but it should keep your friends from messing with you.

https://github.com/krpeacock/google_home_starter

author
call_me_kyle (author)DmitriyB72017-01-25

This is an intermediary step. Since you have the ability to edit the body of the post request on IFTTT, you can readily attach some private key or JWT to your request. Hopefully, I'll get that next step running as part of my starter code, and then I'll share my authentication solution with everyone!

As for a local solution, you can check out this https://timleland.com/wireless-power-outlets/ implementation. There is a project that imitates a Phillips Hue Bridge, which can be accessed on local wifi. Unfortunately, those protocols limit you to On/Off and "dimming" features.

My approach has the benefit of being accessible through browser, phone widgets, and voice control, as long as you set up those features. Since the server's API can handle whatever requests you can dream up, it leaves room for scheduling events, affecting multiple devices, and so on.

author
DmitriyB7 (author)call_me_kyle2017-01-26

Kyle,

I understand the the phase you did was just a start. Hopefully ifttt.com has a way to send url requests with authentication.

And thank you for the links! The habridge hack looks very promising for what I'm trying to do!

author
JacobZ12 (author)2017-01-26

This is a great project, I'm going to set it up for myself. You mentioned examples and a starter project, which I would find very useful. I am a programmer, but with no experience with Node.JS, it would help!

author
call_me_kyle (author)JacobZ122017-01-27

I've just set up a starter application for you to use. Let me know if you have any issues setting it up! https://github.com/krpeacock/google_home_starter

author
call_me_kyle (author)JacobZ122017-01-26

I'm going to build the new project over the weekend. I'll reply here with it once it's ready, and I'll update the Instructable to point to it.

Also, for my benefit, do you think you'll need more details on the electronics portion, or are you mainly concerned about the Node.js environment?

author
JacobZ12 (author)call_me_kyle2017-01-26

The Node.js. I'll be adjusting the python scripts to work with my own IoT project.

author
call_me_kyle (author)JacobZ122017-01-26

Great! I'll let you know when I've got something for you to use.

author
Swansong (author)2017-01-24

That's a neat setup :)

author
call_me_kyle (author)Swansong2017-01-24

Thanks! I use the strip at my nightstand along with a couple Phillips Hue bulbs around the apartment for the full "smart home" experience

About This Instructable

9,389views

28favorites

License:

Bio: I'm a maker, programmer, and designer. I love music, games, and simple design. I'm looking for work!
More by call_me_kyle:Google Home + Raspberry Pi Power Strip
Add instructable to: