Introduction: Google Home + Raspberry Pi Power Strip

Picture of Google Home + Raspberry Pi Power Strip

UPDATE #2: IFTTT changes:

My existing IFTTT commands through the maker channel are still working, but they've changed the naming structure since I made this guide. New commands still use the Google Assistant trigger, but the web requests are now handled by the "Webhooks" action.

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

Picture of 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

Picture of 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

Picture of 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 "Webhooks"
  11. 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 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

The Binraker (author)2017-12-02

Take a run up to Washington DC. Install an IFTTT controlled relay.....and then wait for the lighting of the national Christmas tree and then say

"Ok Google" "Turn off the national Christmas tree".


Make sure to be standing naked in your front yard with your hands in the air when the feds show up.

The Binraker (author)2017-12-02

Last year I took three remote controlled power outlets and re-coded them (internal jumpers) to all work from one remote control.

The remote was two momentary on buttons.

One for on. One for off.

Using this project it would be possible to connect one relay to the ON button and a second relay to the OFF button.

rysliv (author)2017-09-10

Is there a way to set the switch to on even if it's already on instead of the HTTP POST always triggering the switch on/off. I would like a light to turn on at a certain time through IFTTT but if it's already on, I don't want to turn it off.

It sounds like it's possible after looking at the commit on git "defaults to a toggle, but you can designate on or off via a command query" But I have no idea how you're suppose to specify on or off. I've tried &state=on but it still just triggers on/off.

The Binraker (author)rysliv2017-12-02

Use a current sensor to monitor the condition of the light.

You will have to modify the code to ignore the on command if the light is already on based upon the output of the current sensor.

herantd. (author)2017-10-23

Hi there! Great project you've got there. I followed you're steps and managed to get to the point where i'm getting:

{"id":"sw1","state":"off","name":"Lamp"}

from

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

I also getting the right answer from google home when i'm asking to turn the lamp on, but no relay is clicking. So what am i doing wrong here?

I also tried to edit sw1_on.py and added GPIO.output(17, 1), when i run it from my terminal the light is turning on but still cant activate it through Google Home.

Maybe i did put the wrong address in IFTTT Configuration, i used

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

as URL with my ip and password ofc.

I don't get it, where did i go wrong?

herantd. (author)herantd.2017-10-24

Btw i managed to toggle "on" / "off" through postman by pasting :

{

"id": "sw1",

"state": "on",

"name": "Maksim's Lamp"

}

into Body -> raw.

Still when i tell Google Home to turn my gpio on it answers as it should but gpio wont turn on. Can it be that the port 80 is blocked or something? I added port forwarding with rpi's ip and both port 80 and 8000 still nothing..

GraemeS6 (author)2017-09-17

Hi there Kyle! I've got everything working so far (using Rasbperry Pi Zero W). Because I am not a dev, and have not much experience with java, I have no idea what the correct format for adding switches - your instructions say "add a new object to the switches array.

In saveState.json, I have:

{"switches":[{"id":"sw1","state":"off","name":"Lamp"}]}

How do I add sw2,sw3 and sw4 to this?

In /home/pi/google_home_starter/public/python, I have replicated sw1_off.py/sw1_on.py with sw2, sw3 and sw4, editing the BCM numbers to match the same coming out of the GPIO of the pie. Thanks!

Thomas Groell (author)2017-09-07

Hi Kyle,
As you mentioned on step 3, this is a bit tricky for non-developers!
I have successfully installed the Starter, when running 'npm start' i get the "listening on port 8000" and when opening http://<myIP>:8000/API/switches/sw1?password=<PWD> on my browser i get this displaying:

{"id":"sw1","state":"off","name":"Kyle's Lamp"}

If I understand correctly, I'm on the right path.

I didn't catch however the meaning of the other part of step 3, after you mention installing a Node+Express server.

This is a bit obscure for me, so I went on my Node Red to create a flow where a HTTP in node on POST method with the URL mentioned above would trigger a command that turns on my switch. However, accessing this URL doesn't trigger the switch, whether on my laptop or via the Google Assistant applet.

I can feel I'm only few steps from finalizing the project, this is so frustrating!
I hope my explanation is clear enough and you can maybe enlighten me a little on how to proceed for the next step. Thanks in advance for your help and thanks for sharing this very cool project!

If you are getting the "listening on port 8000" message, it means that you are already running my sample Node+Express server locally!

All you need now is to hook up a method to make POST requests. I recommend using Postman, which you can read about and download from here: https://www.getpostman.com/docs/postman/sending_api_requests/requests. Once you point that at the same address you used in your browser and make a POST request (the browser URL is making a GET request), you should see the switch toggling.

call_me_kyle (author)2017-07-04

That's probably because you haven't configured your router to pass http requests to your IP address on to the raspberry pi. I recommend using port 80 with sudo privileges when you're ready to interface with it. You'll need to look up a guide for the type of router you own for this part.

You definitely should also remove your IP address from your comment.

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

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!

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

Fabritren (author)2017-05-21

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

ManishU3 (author)2017-05-20

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

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.

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]

marciokoko (author)jf892017-04-11

Hi

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

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....

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.

jf89 (author)marciokoko2017-04-17

Finally got it, thanks man.

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?

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?

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

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!

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 ?

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/.

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

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.

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!

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.

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

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.

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!

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!

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

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?

JacobZ12 (author)call_me_kyle2017-01-26

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

call_me_kyle (author)JacobZ122017-01-26

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

Swansong (author)2017-01-24

That's a neat setup :)

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

13,237views

34favorites

License:

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