Skip to content

Instantly share code, notes, and snippets.

@emily-pesce
Last active June 26, 2023 07:12
Show Gist options
  • Save emily-pesce/a4ba55d4fc4f4df7d3a6 to your computer and use it in GitHub Desktop.
Save emily-pesce/a4ba55d4fc4f4df7d3a6 to your computer and use it in GitHub Desktop.
Nest Thermostat Data Collection in Google Sheets for Upstairs/Downstairs Setups
// CREDIT TO BEEZLY for a lot of this, I just adapted it a bit and added more documentation :)
// --> BEEZLY's work: https://gist.github.com/beezly/9b2de3749d687fdbff3f
// To make this work:
// 1) create a new Google Sheet (name it whatever you'd like, e.g., "Nest Data")
// 2) on the menu bar click Tools -> Script Editor... to open Script Editor (new window)
// 3) in Script Editor delete all the default scripts/files, and create a new one (I called it "NestScript.gs")
// 4) cut and paste this entire file into NestScript.gs, then SAVE THE SCRIPT
// 5) on the menu bar click Publish -> Deploy as Web App
// select "Execute the App as Me"
// select Who has access to the app: "Anyone, even anonymous"
// 6) Copy/take note of the link to your new web app
// 7) on the menu bar click Current Project's Triggers
// click add new trigger
// for Run select the function runDataCollection, Events: time-driven, and select the rest per your preference (I do hourly)
//
// Every hour you should get updated data.
// Note: I have noticed that if the thermostat is not running the heat or the AC it doesn't seem to update the temperature reading...
function runDataCollection() {
//this function is called by a trigger (create one in: Resources -> Current Project's Triggers)
Logger.log("Starting Data Collection")
// fetch calls your webapp, which via Google magic calls the doGet() function which is defined below
//make sure you relpace the placeholder with your web app id (or the entire link you copied in step 6 )
var response = UrlFetchApp.fetch("http://script.google.com/macros/s/YOUR_WEBAPP_ID_HERE/exec");
}
function performLogin(email, password) {
var payload = {
// do not change these:
"username" : email,
"password" : password
};
var options = {
"method" : "post",
"payload" : payload
};
var response = JSON.parse(UrlFetchApp.fetch('https://home.nest.com/user/login', options).getContentText());
if ('error' in response) {
throw "Invalid login credentials";
}
return response
}
function doGet() {
Logger.log("Running web function...")
//change these two variables:
var login_auth = performLogin('YOUR_NEST_USERNAME','YOUR_NEST_PASSWORD');
var headers = {
"Authorization" : 'Basic '+login_auth['access_token'],
"X-nl-user-id" : login_auth['userid'],
"X-nl-protocol-version" : '1',
'Accept-Language': 'en-us',
'Connection' : 'keep-alive',
'Accept' : '*/*',
};
var options = {
'headers' : headers
};
var request=UrlFetchApp.fetch(login_auth['urls']['transport_url']+'/v2/mobile/user.'+login_auth['userid'], options);
var result=JSON.parse(request.getContentText());
var structure_id = result['user'][login_auth['userid']]['structures'][0].split('.')[1]
//I added upstairs and downstairs since I have two thermostats. You can get the id for each thermostat
//by going to the Nest dashboard, clicking on the Thermostat, clicking the gear icon on the top right
//then copying the "Serial no."" field. It will look something like: 02XX01XX471XXX3S
var device_id = result['structure'][structure_id]['devices'][0].split('.')[1]
var upstairs = 'YOUR_UPSTAIRS_DEVICE_ID' //upstairs
var downstairs = 'YOUR_DOWNSTAIRS_DEVICE_ID' // downstairs
//upstairs
var u_current_temp = result["shared"][upstairs]["current_temperature"] * 1.8000 + 32.00;
var u_target_temp_low = result["shared"][upstairs]["target_temperature_low"]* 1.8000 + 32.00;
var u_target_temp_high = result["shared"][upstairs]["target_temperature_high"]* 1.8000 + 32.00;
var u_target_range = u_target_temp_low.toFixed(1) + "-" + u_target_temp_high.toFixed(1);
var u_humidity = result["device"][upstairs]["current_humidity"];
var u_auto_away = result["shared"][upstairs]["auto_away"];
var u_heater_state = result["shared"][upstairs]["hvac_heater_state"];
var u_ac_state = result["shared"][upstairs]["hvac_ac_state"];
//downstairs
var d_current_temp = result["shared"][downstairs]["current_temperature"] * 1.8000 + 32.00;
var d_target_temp_low = result["shared"][downstairs]["target_temperature_low"]* 1.8000 + 32.00;
var d_target_temp_high = result["shared"][downstairs]["target_temperature_high"]* 1.8000 + 32.00;
var d_target_range = d_target_temp_low.toFixed(1) + "-" + d_target_temp_high.toFixed(1);
var d_humidity = result["device"][downstairs]["current_humidity"];
var d_auto_away = result["shared"][downstairs]["auto_away"];
var d_heater_state = result["shared"][downstairs]["hvac_heater_state"];
var d_ac_state = result["shared"][downstairs]["hvac_ac_state"];
//get outside data
//MAKE SURE TO CHANGE ZIP CODE IN THE NEXT LINE where it says "YOUR_ZIPCODE_HERE"
var wxrequest=UrlFetchApp.fetch('http://api.openweathermap.org/data/2.5/weather?q=YOUR_ZIPCODE_HERE,us');
var wxresult=JSON.parse(wxrequest.getContentText());
var outside_temp = (wxresult["main"]["temp"] - 273) * 1.8000 + 32.00;
var outside_humidity = (wxresult["main"]["humidity"]);
var time = new Date();
//var ss = SpreadsheetApp.getActiveSpreadsheet();
//If you haven't already, create a Google Sheet where this data will be logged, and grab the Sheet id
// The Sheet id can be grabbed from the shee URL
// See this pattern for where the Sheet id is in the URL:
// https://docs.google.com/spreadsheets/d/THIS_IS_WHERE_THE_SHEET_ID_IS/edit#gid=123456789
var ss = SpreadsheetApp.openById("ENTER_YOUR_SHEET_ID_HERE");
//I have multiple tabs, this puts the data in the first tab. Change the [0] to [1] for the second tab, [2] for the third, etc
var sheet = ss.getSheets()[0];
// Write data to the Google Sheet
// For readability, make sure the sheet has the following column headers:
// Date/Time | Downstairs Temp | Downstairs Target Range | Downstairs Humidity | Upstairs Temp | Upstairs Target Range | Upstairs Humidity | Outside Temp | Outside Humidity | Downstairs AutoAway | Upstairs AutoAway | Downstairs Heater State | Downstairs AC State | Upstairs Heater State | Upstairs AC State
sheet.appendRow([time, d_current_temp, d_target_range, d_humidity, u_current_temp, u_target_range, u_humidity, outside_temp,outside_humidity, d_auto_away, u_auto_away, d_heater_state, d_ac_state, u_heater_state, u_ac_state ]);
return 'success'
}
@MaxBurgundy
Copy link

Hi - the script is running fine but no data appears in my spreadsheet - I've double checked everything - anybody got any ideas ? Many thanks for any help you can give me , Max

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment