Google Home Development Tutorial

Date: 30/07/2017 | Developer, Google Home, Programming, Tutorial, Wemo Switch, Node Js

This tutorial will show you how to write some sweet programs that integrate with your brand spanking new Google Home device. You might have noticed that out of the box the device comes with a few limitations or just don't work. Ahem... Belkin Wemo switch. You've probably discovered some other basic limitations Ie: setting a verbal reminder.. I mean WTF Google!. But… There’s saving grace in the fact that you can cut some custom code and integrate with plenty of third party services such as API AI which should get you some of the results you are looking for. 

Here's an example of what can be done by following this tutorial:

 

For this tutorial I’m going to teach you how to do something fairly trivial like turn on some home lights using a Belkin Wemo compatible switch, so you are going to need the following: Hardware Requirements:

Software Requirements:

Okay, To get the ball rolling. You are going to need to do the following :  

Set Up Your Personal Assistant (or Agent)

1. Navigate to https://console.api.ai/ and create your first agent. See the example in the screenshot below. 2.Click the “Actions on Google” button under the Google Project section as shown above. Once the popup has loaded, click on the “New Project” button and set the project name, then click the “Create Project” button. IMPORTANT: Set the Country / Region to the United States for now. 3. Now complete the form by clicking on the individual edit section(s) and complete the form. This includes completing the images / artwork section for the app and accepting the privacy consent. 4. Let’s add some support for actions by clicking on the “Add actions to your app button” and then clicking on API.AI as shown below.   5. A popup screen similar to the one below should appear. Click on the “Create Actions On API.AI button”. 6. You should have been redirected to the API.AI website. Now navigate to  “Integrations” by clicking in the left menu and then click “SETTINGS” under “Actions On Google”. 7. The screen below should have now appeared. Make sure the slider option is switched to "on" and then click the test button. Cool! Your agent should now be setup and ready to configure.

Configure function(s) in Google Cloud

1. Install the Google Cloud SDK if you haven’t already done so. You can download the tools from https://cloud.google.com/sdk/. MISSION CRITICAL: You will need to also install the beta tools when prompted. 2. Create a new working directory and then create a file called index.js and paste the code below:

  1. /* HTTP Cloud Function. @param {Object} req Cloud Function request context. @param {Object} res Cloud Function response context.*/
  2. exports.homeHttp = function homeHttp(req, res) {
  3.     var key = req.headers["access_key"];
  4.     var extra = JSON.stringify(req.body.result.parameters);
  5.     var lightStatus = req.body.result.parameters["LivingRoomLightStatus"];
  6.     if (key == "mypassword") {
  7.         var request = require('request'); // Generally not recommended; but if you
  8.    // have your own SSL certificate installed on your home router then perfect
  9.         process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
  10.         if (lightStatus == "ON") {
  11.             request.post('https://myhomerouter.mynetgear.com:3000/enableSwitch', {
  12.                 form: {
  13.                     LivingRoomLightStatus: 'ON-1234'
  14.                 }
  15.             });
  16.             response = "attempting to turn the lights on. Please wait";
  17.         }
  18.         if (lightStatus == "OFF") {
  19.             request.post('https://myhomerouter.mynetgear.com:3000/enableSwitch', {
  20.                 form: {
  21.                     LivingRoomLightStatus: 'OFF-1234'
  22.                 }
  23.             });
  24.             response = "attempting to turn the lights off. Please wait";
  25.         }
  26.     }
  27.     res.setHeader('Content-Type''application/json');
  28.     res.send(JSON.stringify({
  29.         "speech": response,
  30.         "displayText": response
  31.     }));
  32. };

IMPORTANT : The incoming cloud request is going to need be able to resolve your home router / internet facing device. You can get your public IP address by visiting https://www.whatismyip.com/ . Now, replace all instances of “myhomerouter.mynetgear.com” with your IP address. 3. In the same directory create a new file named “package.json” and paste the following:

  1. {
  2.     "name""AlphaBot",
  3.     "version""1.0.0",
  4.     "description""Alpha Bot",
  5.     "main""index.js",
  6.     "dependencies": {
  7.         "request""^2.81.0"
  8.     },
  9.     "devDependencies": {},
  10.     "scripts": {
  11.         "test""echo \"Error: no test specified\" && exit 1"
  12.     },
  13.     "author""",
  14.     "license""ISC"
  15. }

3. Deploy your code to a cloud storage bucket on Google Cloud. The easiest way to do this is to click on your “gear icon” and then click the “Google Cloud" link under Google Project on API.AI as shown below: Once you have been redirected to Google cloud, click on the "Storage" button in the left hand menu as shown below :   Now write down the name of your “staging” bucket. In my case my bucket name is “staging.alphabot-d3499.appspot.com”. You will need to include this in your deployment command for the next step. 4. Now run the “Google Cloud SDK Shell” and navigate to the working directory of your index.js file and then copy and paste the following command (press enter):

gcloud beta functions deploy homeHttp --stage-bucket staging.alphabot-d3499.appspot.com --trigger-http

IMPORTANT : Make sure you replace the bucket name above with yours. Wait for a few moments while this process completes. The command will spit out a URL which you will need to use later. So make sure you write it down. It will look a little something like this : https://us-central1-alphabot-820a3.cloudfunctions.net/homeHttp Great your google cloud function should now be deployed and ready to start receiving requests.

Setup Raspberry Pi with Service App

1. Power up your Raspberry Pi and login (if required) 2. Open up a terminal and install nodejs and npm (if you haven’t already done so). The easiest way to do it, is to type :

$sudo apt install nodejs

Then

$sudo apt install npm

3. Create a new folder in your home directory called "WemoService" then run the following command to generate a self signed certificate :

$openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout private.key -out certificate.crt

NOTE: You will need this to help keep the communications between API.AI and your home service secure. 4. In the same “WemoService” directory, you will need to install the following node packages :

5. Now create a file called index.js and paste the following code, then save the file (replace all references to location/to/WemoService, with your actual WemoService folder path on your Raspberry Pi):

  1. var express = require('express');
  2. var https = require('https');
  3. var bodyParser = require('body-parser');
  4. var fs = require('fs');
  5. var options = {
  6.     cert: fs.readFileSync('/location/to/WemoService/certificate.crt'),
  7.     key: fs.readFileSync('/location/to/WemoService/private.key')
  8. };
  9. app = express();
  10. app.use(bodyParser.json());
  11. app.use(bodyParser.urlencoded({
  12.     extended: true
  13. }));
  14. app.get('/'function(req, res) {
  15.     res.send('My Home Wemo Service')
  16. });
  17. app.post('/enableSwitch'function(req, res) {
  18. var execSync = require('exec-sync');
  19. if (req.body.LivingRoomLightStatus == "ON-1234") {
  20. var user = execSync('/location/to/WemoService/node_modules/belkin-wemo-command-line-tools/wemo --host 192.168.1.2 --action ON');
  21.     }
  22. if (req.body.LivingRoomLightStatus == "OFF-1234") {
  23. var user = execSync('/location/to/WemoService/node_modules/belkin-wemo-command-line-tools/wemo --host 192.168.1.2 --action OFF');
  24.     }
  25.     res.send("Operation Complete");
  26. });
  27. var server = https.createServer(options, app);
  28. server.listen(3000, function() {
  29.     console.log("server running at https://LOCALHOST:3000/")
  30. });
IMPORTANT: In order to get this working correctly, you’re going to have to replace the Wemo host IP to the correct IP of your Wemo switch. You can easily retrieve this by logging into your router and look for the network device. I find that the device name is anonymous or is labelled “ - - “. UPDATE: A friend of mine reviewing this article also pointed out that port forwarding needs to be setup on your router. Make sure you set up public HTTP / port 3000 forwarding to port 3000 on your  Raspberry Pi. This excercise will not work without it.
6. In your terminal, type the command $node index.js . This should now kick off your local node web app.  This is what will be used to listen for incoming commands.


You can test the to see the service is working by navigating to https://my_raspberrypi_ip:3000 Perfect!  You got this far. Now it’s time to go connect it all together and get it working.

Now to connect it all up

1. First; let’s change the welcome message of your Google home agent by logging back into API.AI and select Agent > Intents and then click on the “Default Welcome Intent" as shown below:

 

Now delete all of the existing default text responses and change it to something else that’s not so generic and then click save. This can be anything you want it to be. See example below: 2. Now let’s enable / setup a fulfilment webhook. This is what’s used to communicate directly with your Google Cloud function. Remember that time you deployed your Google function and I told you to write down the URL? Well you’re going to need it now. You will need to complete the fields as shown below : Replace the URL with the URL that was generated on deployment, set the "access_key" and "password "(mypassword). These details were in your Google function code, although at some point in the near future, I recommend changing them to something more secure. 3. Create a new "Intent" in API.AI and call it “Power up the office”. This is the agent command that will be used to invoke fulfilment which will chain the other components together and turn the Wemo switch on. Set the parameters to the details in the screenshot below : NOTE: You can change the user commands to anything of your choosing. However, the above screenshots have given you a couple of examples to work with. 4. Time to test and the application out! And if all is working you should be able to invoke your agent by talking to your Google Home unit. Remember to invoke the agent by saying “Okay Google, talk to” and then its name. For example : You : “Okay Google, Talk to Alpha Bot” Google Agent : “Alpha bot ready and awaiting your command” You : “Light this place up” Google Agent : “Attempting to turn the lights on. Please wait” Congrats! You’re done!  Enjoy playing with this neat little toy. I’m interested in hearing your feedback so feel free to comment or reach out if you get stuck.   Common Issues: Regional / Language – If you find that the agent doesn’t work due to your regional / language setting the easiest way to fix it, is to go to your Google Home settings on your smart phone and set the assistant language to English-US and then give it a try.


Posted by: Shaun Case
Position: Technical Consultant
Date: 30/07/2017

Share On: