To get connected into the Google Nest API is rather complicated and costs $5 ($10 in my case since I did it against the wrong email the first time!). It utilises the Device Access Program from Google, and the Smart Device Management (SDM) API.
Register for Device Access program
- Register with Google for device access. This includes a one-off payment of US$5
- Device Access Console
- NOTE: If you have more than one Google email address, make sure you select the right one or you will have to pay again for the correct email address (bitter experience!)
- Once registered there will be a projects screen with the option to create a project
Create GCP project, Enable SDM API and Get OAuth 2.0 Client ID
- Access to the SDM API is provided through the Google Cloud Platform (GCP). To enable the API and authorise a Google account with a supported Nest device, you need a GCP project
- On the Device Access home page, select Go To Console button top right, and this brings up the projects page [or might allow direct access to Projects page, sometimes wanted paying again… avoid!]
- Select Documentation top right -> Guides top left -> 1. Get Started and scroll down to Set up Google Cloud Platform section [link]
- Click the Enable the API and get an OAuth 2.0 Client ID button, Create Project
- Project name: Nest API Project
- Product name: NestDeviceAccess
- Where are you calling from: Web Server
- Authorized redirect URIs: https://www.google.com
- Click Create, brings up a page with client configuration
- Download JSON
- Client ID: 803912481486-gcdoopdmarudrmacgvh65pl689mlj15j.apps.googleusercontent.com
- Client Secret: GOCSPX–c-l3e5DYxEDGJ9LXPyB9-wYddj0
Create Device Access Project, get Project ID
- Return to the Device Access Console projects page
- Create project: Nest Thermostat Project
- OAuth Client ID: from above
- Enable Events allows faster thermostat state updates
- Click Create Project button and a Project ID is created. Take note of it
- f93794af-4ffb-49fb-8a27-ad8b929c27a0
Authorise an Account
- Link the Account using the Partner Connections Manager (PCM). This uses a web browser to generate an authorisation code for Nest devices. Either use the Device Access page (preferred) or, replace the projectId and clientId in the following URL and paste into a browser (ensure no space or carriage returns)
1 2 3 4 5 6 7
https://nestservices.google.com/partnerconnections/><projectId>/auth? redirect_uri=https://www.google.com& access_type=offline& prompt=consent& client_id=<strong><clientId></strong>& response_type=code& scope=https://www.googleapis.com/auth/sdm.service
- Enable all permissions, and click Next
- Select relevant Google account when prompted
- At the warning “Google hasn’t verified this app”, select Advanced, click on link “Go to NestDeviceAccess (unsafe)”
- At the “NestDeviceAccess wants access to your Google Account”, select Continue
- This will redirect to Google.com with the authorisation code between the “…code=” and the “&scope…” part of the URL:
- 4/0AX4XfWgkBHmydbmXSUYcn2m8BBGVvEo9TIq2vCEHXQiZ_czoidtC_eVY3xWBuBCPeJV_mA
Get Access and Refresh Tokens
Using the Device Access page again, enter the ClientID, clientSecret and authorisationCode to create a curl command to paste into Terminal:
1
curl -L -X POST 'https://www.googleapis.com/oauth2/v4/token?client_id=<strong>clientId</strong>&client_secret=<strong>clientSecret</strong>&code=<strong>authorizationCode</strong>&grant_type=authorization_code&redirect_uri=https://www.google.com'
returns:
1
2
3
4
5
{ "access_token": "accessToken",
"expires_in": 3599,
"refresh_token": "refreshToken",
"scope": "https://www.googleapis.com/auth/sdm.service",
"token_type": "Bearer" }
Node-RED Flow
Could not get OpenHAB plugin for Nest to work so setup a flow in Node-RED instead. which are then used to get the Nest state every 5 minutes.
This first function uses the credentials and refreshToken above to get new accessToken every hour (refer to return message above expires_in: 3599 seconds) which is saved in a flow variable:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let clientId = '803912481486-gcdoopdmarudrmacgvh65pl689mlj15j.apps.googleusercontent.com';
let clientSecret = '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';
let refreshToken = '1//03wEYMPOJQzPmCgYIARAAGAMSNwF-L9IrhU4P98YREGQfmpfTm2jb57ud-FOh6ESLJNpmWuWuIjSmYbgKMl5LFqlN7o1sjgjiVSk';
msg.url = "https://www.googleapis.com/oauth2/v4/token";
msg.method = "POST";
msg.payload = {
"client_id": clientId,
"client_secret": clientSecret,
"refresh_token": refreshToken,
"grant_type": 'refresh_token'
};
var d = new Date();
node.status({fill:'blue',shape:'dot',text:'Last update ' + ('0'+d.getHours()).slice(-2) + ':' + ('0'+d.getMinutes()).slice(-2)});
return msg;
The second function, called every 5 minutes, requests the device data which is then used to populate the OpenHAB items:
1
2
3
4
5
6
7
8
let projectId = 'f93794af-4ffb-49fb-8a27-ad8b929c27a0';
msg.url = "https://smartdevicemanagement.googleapis.com/v1/enterprises/" + projectId + "/devices"
msg.method = "GET";
msg.headers = {
'Authorization': 'Bearer ' + flow.get("access_token"),
'Content-Type': 'application/json'
};
return msg;
NOTE: Had to enable the Smart Device Management API for the testing via Terminal to work. Received messages then okay: https://console.developers.google.com/apis/api/smartdevicemanagement.googleapis.com/overview?project=803912481486 [these digits are first part of OAuth ID]
HabPanel Widget
The widget is similar in function to the other temperature widgets.
Uses the Nest_Connection item state to show either the orange (online) or grey (offline) thermometer. When online it also shows the current temperature associated with Nest_AmbientTemp.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div class="rounded-box">
<table style="width: 100%; text-align: center">
<tr><td style="padding-top: 0.1vw">
<div ng-if="itemValue('Nest_Connection') == 'Online'">
<img ng-src="/static/images/thermometer-online.svg" style="height: 3vw" />
</div>
<div ng-if="itemValue('Nest_Connection') != 'Online'">
<img ng-src="/static/images/thermometer-offline.svg" style="height: 3vw" />
</div>
</td></tr>
<tr><td style="font-size: 0.9vw;">Hall (Nest)</td></tr>
<tr><td class="hilite" style="font-size: 1.2vw;">
<div ng-if="itemValue('Nest_Connection') == 'Online'">
{{'%.1f' | sprintf:itemValue('Nest_AmbientTemp')}} °C
</div>
</td></tr>
</table>
</div>
Resources
- Google Device Access Program
- Google Cloud Platform (GCP)
- Step by Step Guide to Nest on OpenHAB (GitHub)
- openHAB page for Nest Binding