Logging Nest Thermostat Data

I recently had a Nest Thermostat installed at my house for free by my gas company as part of a pilot program that they’re running. It’s a pretty cool device, though I wouldn’t spend $250 to buy one. I like the fact that it’s a lot easier to use than my previous smart thermostat, especially being able to program it from a computer or my smartphone.  One very interesting feature to me is that it tracks the relative humidity of my house. Unfortunately, the Nest app doesn’t let you keep a running log of your data, so I decided to hack together a solution today.

I used node.js to implement a data logger which queries some parameters from my Nest thermostat, and upload it to ThingSpeak at regular intervals. Specifically, my node.js script uploads my Nest’s current temperature, humidity, and the current set temperature to thingspeak every 15 minutes. Below is the node.js script:

[code language=”java”]
"option strict";
var util = require(‘util’),
ThingSpeakClient = require(‘thingspeakclient’);
nest = require(‘unofficial-nest-api’); // get from npm

// nest parameters
var username = ‘YOUR-NEST-USERNAME’;
var password = ‘YOUR-NEST-PASSWORD’;

// thingspeak parameters
var channelId = YOUR-THINGSPEAK-CHANNELID;
var apiKey = ‘YOUR-THINGSPEAK-WRITE-API-KEY’;

// update interval in ms
var updateInterval = 1000*60*15;

var tsclient = new ThingSpeakClient();
tsclient.attachChannel(channelId, { writeKey:apiKey});

function trimQuotes(s) {
if (!s || s.length === 0) {
return ”;
}
var c = s.charAt(0);
var start = (c === ‘\” || c === ‘"’) ? 1 : 0;
var end = s.length;
c = s.charAt(end – 1);
end -= (c === ‘\” || c === ‘"’) ? 1 : 0;
return s.substring(start, end);
}

function merge(o1, o2) {
o1 = o1 || {};
if (!o2) {
return o1;
}
for (var p in o2) {
o1[p] = o2[p];
}
return o1;
}

function fetchData(data) {
nest.login(username, password, function (err, data) {
if (err) {
console.log(err.message);
process.exit(1);
return;
}

nest.fetchStatus(function (data) {
for (var deviceId in data.device) {
if (data.device.hasOwnProperty(deviceId)) {
var shared = data.shared[deviceId];
var date = new Date();
var time = date.getFullYear()+’/’+date.getMonth()+’/’+date.getDate()+’-‘+date.getHours()+’:’+date.getMinutes();

console.log(util.format("%s %s [%s], Current temp: %d F Current Humidity: %d %% Target temp: %d",
time,
shared.name, deviceId,

nest.ctof(shared.current_temperature),
data.device[deviceId].current_humidity,

nest.ctof(shared.target_temperature)));

var fields = { field1: nest.ctof(shared.current_temperature),field2: data.device[deviceId].current_humidity, field3: nest.ctof(shared.target_temperature)};
tsclient.updateChannel(channelId,fields);
}
}
});
});
}

fetchData();
setInterval(fetchData,updateInterval);
[/code]

In order to run my node.js script, you need to first use npm to install unofficial-nest-api and thingspeakclient. My script is actually just a hacked up version of the example that comes with unofficial-nest-api.

Note that you must first update the initialization of username and password with your Nest.com login credentials.

Also, you need to enter your channel id and write api key from thingspeak.com. Below are my thingspeak channel settings:

channel

You can view my channel live on thingspeak here: Nest Logging Demo

channelview

19 thoughts on “Logging Nest Thermostat Data”

  1. I’ve been hoping to ride the coat tails of someone much more knowledgeable than I on this for a while now! Thanks for the help!

    Any chance you could provide some guidance on how you pulled the external temp, heater state, etc. (all the other data points)? I can’t find any documentation that lays out what data is available.

  2. I made a site for myself but you the non programmers out there are welcome to use it. Google reports it as a forgery but its apparently because I don’t follow the rules of the “NEST-API” which prohibit more than 10 days of data logging and they won’t remove the forgery warning until I remove the 10 day logging. which defets the whole point of my site I don’t have the humidity or time breakdowns yet but slowly I am working on it…I want to implement custom functions as well. Mostly automation stuff like if humidity outside is lower than humidity inside and temperatire is less than 0 turn on HRV…stuff like that.
    check it out http://www.mynestreports.com

  3. Hi,

    Great script, thanks! I’m quite new to this. It works for me, but only seems to run once. Once I log out of SSH on my RPi, no further updates are submitted.any idea how to make it run continuously and run at start up?

    I’ve stored the script in /home/pi/nestlog.js

    Thanks,

    Glyn

  4. I implemented customs function on the website and also automatic humidity levels based on outside temperature.
    I have email alerts setup if a problem is detected and other email alerts. I also setup notifications if you have above average usage or. I have added support for multiple thermostats….my plan is to annoy nest with awesome features until they put them in the app.

    1. Where can I find these features? I thought your website was just for logging. BTW, that phishing warning that google put on you must really suck.

  5. If you click on your thermostat name..the option on the bottom is called custom functions…there will be a desperate one for each thermostat. I have just moved to a dedicated server so depending of your ISP has updated their DNS servers today you may have to wait a few hours to get access.

    The stupid fraud warning it because nest has a clause in the API that forbids logging more than 10 days of data.

    1. Sheesh, it’s bad enough that they don’t give us more than 10 days data… why the heck do they care if we want to save more than 10 days. Anyway, thanks for offering the service. I’ll check it out when I have time.

    1. nest.ctof() converts from celcius to fahrenheit. So just get rid of all calls to that function, and it will report in the native celcius units.

      1. Yeah, I have to see if I should spend the $100 for the protect or the $250 for the thermostat, and get it here to El Salvador (shipping, + about 30% in taxes). I think it would be sturdier and more practical (alarm or thermostat as well) than the Pi with DHT22’s I’ve been using fore a few years. Thanks for sharing- you’ve given many of us a great head start!

        1. Looks like the protect doesn’t give you temperature or humidity. see https://developers.nest.com/documentation/api-reference
          This part shows what the protect outputs:

          “smoke_co_alarms”: {
          “RTMTKxsQTCxzVcsySOHPxKoF4OyCifrs”: {
          “device_id”: “RTMTKxsQTCxzVcsySOHPxKoF4OyCifrs”,
          “locale”: “en-US”,
          “software_version”: “1.01”,
          “structure_id”: “VqFabWH21nwVyd4RWgJgNb292wa7hG_dUwo2i2SG7j3-BOLY0BA4sw”,
          “name”: “Hallway (upstairs)”,
          “name_long”: “Hallway Protect (upstairs)”,
          “last_connection”: “2016-10-31T23:59:59.000Z”,
          “is_online”: true,
          “battery_health”: “ok”,
          “co_alarm_state”: “ok”,
          “smoke_alarm_state”: “ok”,
          “is_manual_test_active”: true,
          “last_manual_test_time”: “2016-10-31T23:59:59.000Z”,
          “ui_color_state”: “gray”,
          “where_id”: “UNCBGUnN24…”
          }
          },

          Pretty primitive stuff! I would rather stick with the Pi. The binary sensor outputs don’t impress me.

  6. This works great! However, my Thermostat E returns my night-time heating target temp. I would like to specify the current cooling target temp, if possible. Detailed documentation for the unofficial-nest-api is hard to find. Does anyone have the modifications I need to get what I want?

    1. it looks like they changed the API since I wrote this blog post. Below are all of the current thermostat fields from the Nest API:
      https://developers.nest.com/documentation/api-reference
      I think maybe you’re looking for target_temperature_low_x.

      “thermostats”: {
      “peyiJNo0IldT2YlIVtYaGQ”: {
      “device_id”: “peyiJNo0IldT2YlIVtYaGQ”,
      “locale”: “en-US”,
      “software_version”: “4.0”,
      “structure_id”: “VqFabWH21nwVyd4RWgJgNb292wa7hG_dUwo2i2SG7j3-BOLY0BA4sw”,
      “name”: “Hallway (upstairs)”,
      “name_long”: “Hallway Thermostat (upstairs)”,
      “last_connection”: “2016-10-31T23:59:59.000Z”,
      “is_online”: true,
      “can_cool”: true,
      “can_heat”: true,
      “is_using_emergency_heat”: true,
      “has_fan”: true,
      “fan_timer_active”: true,
      “fan_timer_timeout”: “2016-10-31T23:59:59.000Z”,
      “has_leaf”: true,
      “temperature_scale”: “C”,
      “target_temperature_f”: 72,
      “target_temperature_c”: 21.5,
      “target_temperature_high_f”: 80,
      “target_temperature_high_c”: 24.5,
      “target_temperature_low_f”: 65,
      “target_temperature_low_c”: 19.5,
      “eco_temperature_high_f”: 80,
      “eco_temperature_high_c”: 24.5,
      “eco_temperature_low_f”: 65,
      “eco_temperature_low_c”: 19.5,
      “away_temperature_high_f”: 80,
      “away_temperature_high_c”: 24.5,
      “away_temperature_low_f”: 65,
      “away_temperature_low_c”: 19.5,
      “hvac_mode”: heat,
      “previous_hvac_mode”: heat,
      “ambient_temperature_f”: 72,
      “ambient_temperature_c”: 21.5,
      “humidity”: 40,
      “hvac_state”: “heating”,
      “where_id”: “UNCBGUnN24…”,
      “is_locked”: true,
      “locked_temp_min_f”: “65”,
      “locked_temp_max_f”: “80”,
      “locked_temp_min_c”: “19.5”,
      “locked_temp_max_c”: “24.5”,
      “label”: “Pat’s room”,
      “where_name”: “Hallway”,
      “sunlight_correction_enabled”: true,
      “sunlight_correction_active”: true,
      “fan_timer_duration”: 15,
      “time_to_target”: “~15”,
      “time_to_target_training”: “training”
      }

Leave a Reply