Build a home automation auto-away assist for Nest Thermostat with Azure Functions, Particle.io, and Azure IoT Hub
Tags: azureapril, iot, serverless, diy
Published: 2019-04-25 04:49:22

---
title: Build a home automation auto-away assist for Nest Thermostat with Azure Functions, Particle.io, and Azure IoT Hub
published: true
description: Let Nest know when you are in another room to assist Auto-Away using motion sensors, Particle.io, and Azure!
tags: azureapril, IoT, serverless, DIY
series: "Azure April"
cover_image: https://thepracticaldev.s3.amazonaws.com/i/pblyvmtj4y8bdqisyzey.jpeg
---

*We've selected our favorite tips and tricks created by [Michael Crump](https://twitter.com/mbcrump) and are delivering fresh technical content on Azure all April! Miss a day (or more)? [Catch up with the series](https://dev.to/t/azureapril/latest).*

**Don't have Azure?** [Grab a free subscription](https://azure.microsoft.com/en-us/free?&WT.mc_id=azureapril_devto-blog-cxa). 

{% youtube WaNvKtDCHA4 %}


| Materials List                 |
|--------------------------------|
| 1x [Particle Core / Photon / Argon](https://store.particle.io/collections/wifi) |
| 1x [PIR Motion Sensor](https://www.amazon.com/DIYmall-HC-SR501-Motion-Infrared-Arduino/dp/B012ZZ4LPM)              |
| 1x [Free Azure Subscription](https://azure.microsoft.com/en-us/free?&WT.mc_id=azureapril_devto-blog-cxa)        |

#Introduction

The Nest Thermostat is a Wi-Fi enabled device that can optimize usage of heating and cooling systems using weather information and local sensor data. This device can also be controlled remotely so you can do cool things like set the house to heat / cool while on a drive home from work. The device is a bit of a black box though, and uses some underlying machine learning mechanisms (from what I hear anyway) to create a model of your particular usage habits and tries to determeine whether you are home or not. 

The problem is that the Nest does not always determine home / away properly. For example, I have two Nest units controlling two HVAC units at home (one upstairs which controls the left-side of my house and another downstairs which controls the right-side). Oftentimes, I find myself working in my upstairs office (located on the right-side of the house) and the AC shuts off due to thinking I am away from the house. This is a problem and often involves manually firing off the Nest controller via the mobile / web application or running out of the office and tripping the motion sensor on one of my other Nest Devices. 

The Nest is a Wi-Fi enabled device, so why not just tell it when you are home using motion sensing or something similar? Nest is aware of [this issue](https://nest.com/support/article/Troubleshooting-Home-Away-Assist) and sells a [motion sensor](https://store.google.com/product/nest_detect) and an additive [monitoring thermostat](https://nest.com/thermostats/nest-temperature-sensor/overview/) for controlling temperatures in rooms outside of the Nest controller location. These sensors are really expensive and they are only compatible with the Nest v3 thermostats (many of us have v2 models). The Nest v2 has enabled Wi-Fi, so you would think a Wi-Fi based device would exist to solve this issue, but it doesn't. 

#Solution

All we really need is a method of informing the Nest that we are home using some form of hardware based trigger (PIR motion / reed switch / something more sophisticated). One would think that If This Then That would support this feature with their Nest integration, but there is nothing specific to setting the Home / Away status of the Nest at this time. That's not a deal-breaker, we can just roll our own.

To create our own mechanism for updating the Nest Home / Away status we need only a few ingredients:

* A valid Oauth Token to allow us to make API requests to update Home / Away status through Nest's developer API
* A device which can detect presence and send an event to trigger this API call. We will use a Particle Core / Photon and a PIR motion sensor along with an integration to forward messages to an Azure IoT Hub.
* A Service to make the actual call to the Nest API. We will use a serverless Azure function to make the call to the Nest API which will be triggered when events arrive through the aforementioned Azure IoT Hub.
A diagram outlining the overall architecture is provided below:
![Diagram](https://thepracticaldev.s3.amazonaws.com/i/3t2muover2x21xpswl5r.png)
*Hardware => Particle.io => Azure IoT HuB => Azure Function => Nest API*

##Obtaining an Oauth Token to access the Nest API

1. You will need to create an active Nest Developer account at - https://developer.nest.com
2. Create a new OAuth Client at - https://console.developers.nest.com/products/new

Make sure to enable the "Away read / write" setting!

![Settings](https://thepracticaldev.s3.amazonaws.com/i/6zz24v7vtkhduu6k0wio.jpg)

3.Obtain the Authorization URL value for your OAuth client from the screen below and select "Allow". After allowing your application, you will receive a pin code, make sure to copy this down. The Authorization URL can be obtained from the Overview screen for your OAuth Client as shown below.

![Settings2](https://thepracticaldev.s3.amazonaws.com/i/j1qi0pgoeylem764x0h2.jpg)

4.In the Overview screen where you obtained the Authorization URL, take note of the 'Client ID' and 'Client Secret' values. Next, from a suitable command prompt with "curl" installed, execute the following command to obtain your AUTH_TOKEN:

`curl -X POST "https://api.home.nest.com/oauth2/access_token?client_id=<YOUR_CLIENT_ID>&code=<YOUR_PIN_CODE>&client_secret=<YOUR_CLIENT_SECRET>&grant_type=authorization_code"`

5. Finally, we need to obtain your desired STRUCTURE_ID which is a representation of your Home which associates to specific Nest devices. The following will return a json payload. You will want to take note of the value for the structure_id property.

`curl --location-trusted \ -H "Content-Type: application/json" \ -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \ -X GET "https://developer-api.nest.com/`

##Constructing the Hardware

We will use Particle Photon or Particle Core device available from [http://particle.io](http://particle.io) along with a digital PIR sensor to create a device which monitors for motion and is capable of publishing events to Particle.io.
1. Begin by obtaining a Digital PIR sensor and connecting to an available Particle device according to the following schematic:

![Schematic](https://thepracticaldev.s3.amazonaws.com/i/u156vidutumdtlmisz48.jpg)
![Prototype](https://thepracticaldev.s3.amazonaws.com/i/gpq97unuz03gozopm65e.jpg)

2. Create a new program in the particle Web IDE at [https://build.particle.io/build](https://build.particle.io/build)
You will need to flash the attached [nest-motion.ino](http://nest-motion.ino/) and be sure to include the associated CircularBuffer.h
The program uses a CircularBuffer to allow for monitoring of Sensor readings over a Sample Window. This allows us to very precisely control the sensitivity of motion trigger events from the hardware. Typically, PIR sensors are very prone to producing false-positive events without a mechanism to evaluate sample readings according to a governor. For higher sensitivity, reduce the 'PostiveSamplesToTriggerMotion' variable. To require a longer window of motion for trigger , you can adjust 'SampleWindowSize'. 
[nest-motion.ino](https://github.com/toolboc/Auto-Away-Assist-for-NEST-Thermostat/blob/master/Particle/nest-motion/src/nest-motion.ino) can be found in `nest-motion/src` in the repo below:


{% github https://github.com/toolboc/Auto-Away-Assist-for-NEST-Thermostat %}

##Setup Particle Integration to forward events to an Azure IoT Hub

This step will require an active Azure account. The services that we will create will be free for or cost next to nothing to operate. 
1. Create an Azure IoT Hub at [http://azure.com](https://azure.microsoft.com/en-us/free?&WT.mc_id=azureapril_devto-blog-cxa)

![Create IoT Hub](https://thepracticaldev.s3.amazonaws.com/i/rjnt1i07wvtp9eiy4wtp.jpg)

2.Create the Particle Integration
Create a new particle integration at https://console.particle.io/integrations/azure-iot-hub/create. Be sure to follow all of the instructions and pay particular attention to the part about creating a "Shared Access Policy". Use the value "motion" for the Event Name on the resulting setup page.

When you have filled in the appropriate information, enable the integration.

![Enable Integration](https://thepracticaldev.s3.amazonaws.com/i/5p6o9oqio0tnddg4f4z1.png)

Now when `Particle.publish("motion", "true", PRIVATE);` is called in nestmotion.ino, the event will be sent to Particle.io and then forwarded to your Azure Iot Hub.

##Set Nest 'Away' status with Azure Function

We are almost done, we simply need to trigger a call to Nest's API to set the Nest 'Away' status to home when motion is detected.

I've done my best to make this as easy as possible with a premade Azure function which performs this task.

1. Create a new Azure Function app at https://ms.portal.azure.com/#create/Microsoft.FunctionApp

2. Within Visual Studio Code, open the Nest-Controller folder included in the source repo at https://github.com/toolboc/Auto-Away-Assist-for-NEST-Thermostat

You will need to edit the local.settings.json config file:

ACCESS_TOKEN and STRUCTURE_ID should be set to the values obtained in steps 4 & 5 of 'Obtaining an Oauth Token to access the Nest API'

In the azure Portal, navigate to your IoT Hub and select the "Built-in endpoints' section under 'Settings'. 

<EventHub-Compatible-Endpoint> should be changed to the value of 'Event Hub-compatible endpoint'.

![Eventhub-Compatible-Endpoint](https://thepracticaldev.s3.amazonaws.com/i/hobp7leqrms5v7nbcvgk.png)

You are now able to debug and test the Azure Function. You should see the Function trigger when a motion event is sent from the Particle device.

![Azure Function Debugging](https://thepracticaldev.s3.amazonaws.com/i/p156pi8sk7m78i37wyq5.png)

When you are able to verify that the function is working as intended, you can publish the Function to Azure within Visual Studio by right-clicking the project and selecting 'Deploy to Function App'.

**Optional:** If you know what you are doing, you could create the Function entirely in the Azure portal using the code provided below. Be aware that you will have to install the 'request' dependency in the kudu cli by visiting `http://<YOUR_FUNCTION_SITENAME>.scm.azurewebsites.net`, navigating to 'wwwroot', and issuing the command 'npm install azure-cli -g' to satisfy the dependency for 'request.js'.

`module.exports = function (context, eventInput) {
   context.log('Triggered!');
   if(eventInput.event === "motion" && eventInput.data === "true");
   {
       var url = 'https://developer-api.nest.com/structures/' + process.env.STRUCTURE_ID + '/away?auth=' + process.env.ACCESS_TOKEN;
       var request = require('request');
       request({ method: 'PUT', url: url, followAllRedirects : true, 'content-type': 'application/json', body: '"home"' }, function (err, res, body) {        
               context.log('Away status set to: ' + JSON.parse(body));
               context.done();
       });
   }             
}`

3.Update the function AppSettings to use your values for 
ACCESS_TOKEN, STRUCTURE_ID, and particle-iot-hub_events_IOTHUB should be set to the values of your local.settings.json config file which were configured in Step 2 of '**Set Nest 'Away' status with Azure Function**'.

![AppSettings](https://thepracticaldev.s3.amazonaws.com/i/8nm6r061c9aanzuyv37z.png)

You can test the Function using the contents of [sample.dat](https://github.com/toolboc/Auto-Away-Assist-for-NEST-Thermostat/blob/master/Azure/Nest-Controller/SetNestToHOME/sample.dat) within the Azure Portal:

![Azure Portal Test](https://thepracticaldev.s3.amazonaws.com/i/78hs7cpt15g8ue3zr3k3.png)

And there you have it! You should now have a full pipeline in Azure for processing messages from Hardware => Particle.io => Azure IoT HuB => Azure Function => Nest API.

You can monitor motion events to the particle integration point at https://console.particle.io/integrations/ then select your integration and scroll down to history. Be sure to check this area to ensure you are not sending false-positive motion events:

![Particle Monitor](https://thepracticaldev.s3.amazonaws.com/i/7biw3k2tc8qilnttohf7.png)


#Conclusion

Nest has a pretty awesome line of products as-is, however, we have shown that using access to their developer API, we can make them even better! I no longer have to worry that my AC will shut off when working upstairs. I can simply flash the nest-motion.ino code to multiple particle devices and alert Nest of home occupancy in multiple rooms in the house. Currently, I have one device attached to the usb port of my office printer (always-on), another in my brother's room that is plugged into the wall, and one attached to the usb port of my downstairs TV which only turns on when the TV is on. This setup allows the Nest to REALLY know when we are home or not. 

The services we have employed are all free, and for around $22/piece you can build as many devices as you need. The hardware is energy conscientious as it goes into a deep sleep mode for 10 minutes by default after a motion detect event occurs, consuming only a [mere 200uA](https://community.particle.io/t/power-usage-in-deep-sleep-mode-solved/8909). In addition, we can expand on the features by employing a variety of additional sensors. We could even create our own Nest Thermostat by employing a temperature sensor, and display.

Let us know in the comments what you think and feel free to share your ideas to improve on the design!

---
We'll be posting articles every day in April, so stay tuned or jump ahead and check out more tips and tricks [now](http://azuredev.tips).