Click here to Skip to main content
15,881,027 members
Articles / Programming Languages / C#

.NET Works with Nest - Guide to calling Nest API from C#

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
14 Sep 2014CPOL3 min read 38.8K   477   10   5
How to call Nest API from .NET using FirebaseSharp

Introduction

This article demonstrates how to call Nest API from .NET using FirebaseSharp, an unofficial open source Firebase .NET client.

To follow along and test drive Nest API you do not need to own a Nest device, a simulator is available.

Background

Nest API enables developers to integrate with their Nest Learning Thermostat™ and Nest Protect: Smoke + Carbon Monoxide™.

But although the API comes in different flavours (Firebase, REST and REST Streaming), currently you're a bit left in the cold when trying to consume the API's real time features from .NET:

  • the official Firebase client libraries currently target Web (JavaScript client), iOS and Android
  • the alternative REST Streaming is based on EventSource, another option that doesn't come out of the .NET box
  • and finally the REST option is not intended for real-time updates, with Nest placing limits on the number of calls you can make in a specific time period (so forget about polling for updates)

Looking for a solution I stumbled upon FirebaseSharp, which enables you to call Nest API using the Firebase protocol and get all the real time goodness.

Read below to discover what happened next.

Using the code

You can download the completed project.

Get access to Nest API

To get access to Nest API, you have to register your client.

Complete this easy no-hassle step at https://developer.nest.com/

  1. Sign in
    • Sign up
  2. Clients (available when signed in)
    • Register new client
      • OAuth Redirect URI
      • Permissions
        • Choose Thermostat > read permission at the minimum, to successfully run this demo

Well done, you now have a client ID and secret which are required for OAuth in the next step.

Get access to Nest device data

To get access to Nest device data, Nest explains why and how they use OAuth.

So let's translate this to .NET

First update the App.config with your client OAuth settings, copy them from your Nest client settings:

XML
<add key="client-id" value="<client-id>" />
<add key="client-secret" value ="<client-secret>" />

To request access, we simply browse to the authorization URL, which uses your client ID to identify the application requesting access:

C#
var authorizationUrl = string.Format("https://home.nest.com/login/oauth2?client_id={0}&state={1}",
    ConfigurationManager.AppSettings["client-id"], "dummy-random-value-for-anti-csfr");

using (var process = Process.Start(authorizationUrl))
{
    Console.WriteLine("Awaiting response, please accept on the Works with Nest page to continue");
}

If the user accepts, Nest redirects to the OAuth redirect URI you configured.

To keep this demo simple and self contained in the console application, we self-host ASP .NET Web API, to handle the repsonse:

C#
using (WebApp.Start<Startup>(url: "http://localhost:9000/"))
{
    // snip
}

So, first the state argument is validated, this should match the anti-cross-site forgery request token we sent to ensure the integrity of the communication.
Then the received authorization code is used to request an access token.
Again to keep it simple, the resulting access code response is cast to dynamic, so we can access the token property without having to properly deserialize to a strongly typed object.

C#
/// <summary>
/// Called by Nest when user grants access
/// </summary>
/// <param name="state">Anti-cross-site forgery request token</param>
/// <param name="code">Code to request access token</param>
/// <returns>Access code</returns>
public HttpResponseMessage Get(string state, string code)
{
     if (!string.Equals("dummy-random-value-for-anti-csfr", state))
         throw new HttpResponseException(HttpStatusCode.BadRequest);

     var accessToken = GetAccessToken(code);
     Program.SubscribeToNestDeviceDataUpdates(accessToken);

     var response = new HttpResponseMessage(HttpStatusCode.OK) 
     {
         Content = new StringContent("Well done, you now have an access token which allows you to call Nest API on behalf of the user.") 
     };
     response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");

     return response;
}

private async Task<string> GetAccessToken(string authorizationCode)
{
    var url = string.Format("https://api.home.nest.com/oauth2/access_token?code={0}&client_id={1}&client_secret={2}&grant_type=authorization_code",
                authorizationCode, ConfigurationManager.AppSettings["client-id"], ConfigurationManager.AppSettings["client-secret"]);

    using (var httpClient = new HttpClient())
    {
        using (var response = httpClient.PostAsync(url, content: null).Result)
        {
            var accessToken = JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().Result);

            return (accessToken as dynamic).access_token;
        }
    }
}

Well done, you now have an access token which allows you to call Nest API on behalf of the user.

Simulate Nest device

To simulate a Nest device, you have to use the Nest Developer Chrome Extension.

If you have any trouble with this, follow the easy steps at https://developer.nest.com/documentation/chrome-extension, in a nutshell:

  1. Launch Google Chrome
  2. Install the Nest Developer Chrome Extension
  3. Browse to https://home.nest.com
  4. Open the Developer tools
  5. Open the Nest tab
  6. Add a thermostat

Well done, you now have a virtual device which can simulate real time events which we'll consume in the next step.

Consume real-time updates

Get FirebaseSharp through nuget, to install through the Nuget Package Manager Console:

Install-Package FirebaseSharp

Once the access token is in, we initialize a Firebase client, that points to Nest API using the access token we retrieved. In this case we listen to the devices, but go ahead and consult the Nest API reference to find out your options on how granular you want to be.

Change the current temperature in the Nest Developer Chrome Extension and witness the real-time updates :)

C#
var firebaseClient = new Firebase("https://developer-api.nest.com", _accessToken);
var response = firebaseClient.GetStreaming("devices",
        changed: (s, e) => {
            if (e.Path.Contains("ambient_temperature_f"))
                Console.WriteLine("Current temperature has been updated to: {0}.", e.Data);
        });

Well done, you have a working solution!

Points of Interest

Official support for C# by Firebase might come, mentioned in a blog post by the author of FirebaseSharp, read it here http://www.roberthorvick.com/2014/03/26/firebase-net-client-library/.

History

  1. Added link to download the completed project.
  2. Removed duplicate attachment

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Belgium Belgium
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionGet access Token from Redirect URL Pin
Member 1097569320-Feb-17 20:24
Member 1097569320-Feb-17 20:24 
QuestionSet the target temperature Pin
eyasso25-Feb-15 21:41
eyasso25-Feb-15 21:41 
QuestionPut Example Pin
ahankahank25-Dec-14 11:03
ahankahank25-Dec-14 11:03 
QuestionNice project but needs updating since Nest requires https OAuth Pin
ahankahank25-Dec-14 5:06
ahankahank25-Dec-14 5:06 
QuestionTres bien! Pin
Volynsky Alex15-Sep-14 10:21
professionalVolynsky Alex15-Sep-14 10:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.