I'm trying to connect to the nest_API (thermostat) using ESP8266 and the Arduino EDK. But so far with no result.
I've seen somebody asking the same question here before. But the answer to his problem didn't help me.
So here's my code:
Code
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
const char* ssid = "xxxxx";
const char* password = "xxxxx";
const char* host = "developer-api.nest.com";
const int httpsPort = 443;
const char* BearerKey = "xxxxxxxuB0QSbgw2nsT85dJEHRpwvR7rSyrLHm2E54QpC9vnSzB5PV8OtGDPm0mAh96wgM0MwApmS";
//declaring GPIO's
int gpio13Led = 13;
int gpio12Relay = 12;
// Use web browser to view and copy
// SHA1 fingerprint of the certificate
const char* fingerprint = "87:CB:F2:E6:44:C0:AA:F2:4C:28:B2:97:85:70:18:92:45:1B:A4:57";
void setup() {
// preparing GPIOs
pinMode(gpio13Led, OUTPUT);
digitalWrite(gpio13Led, HIGH);
pinMode(gpio12Relay, OUTPUT);
digitalWrite(gpio12Relay, HIGH);
Serial.begin(115200);
Serial.println();
Serial.print("connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
// Use WiFiClientSecure class to create TLS connection
WiFiClientSecure client;
Serial.print("connecting to ");
Serial.println(host);
if (!client.connect(host, httpsPort)) {
Serial.println("connection failed");
return;
}
if (client.verify(fingerprint, host)) {
Serial.println("certificate matches");
digitalWrite(gpio13Led, LOW);
} else {
Serial.println("certificate doesn't match");
}
String url = "/";
Serial.print("requesting URL: ");
Serial.println(url);
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Content-Type: application/json\r\n" +
"Authorization: Bearer " + BearerKey + "\r\n\r\n"
);
Serial.println("request sent");
while (client.connected()) {
String line = client.readStringUntil('\n');
Serial.println(line);
if (line == "\r") {
Serial.println("headers received");
break;
}
}
while (client.available()) {
String line = client.readStringUntil('\n');
Serial.println("reply was:");
Serial.println("==========");
Serial.println(line);
Serial.println("==========");
Serial.println("closing connection");
}
}
void loop() {
}
I never get any result from the server. But when I'm using postman, it works. So I wonder. Do I need to use the "host: " + host + ... line?
And is there a way to catch some errors with the WiFiClientSecure.h library.
I also once changed the url for host in the get string.
Then I received one error from the server. I was already happy there was a response after all.
Serial output
connecting to xxxxx
........
WiFi connected
IP address:
xxxxx
connecting to developer-api.nest.com
certificate matches
requesting URL: /
request sent
HTTP/1.1 307 Temporary Redirect
Content-Type: application/json; charset=UTF-8
Access-Control-Allow-Origin: *
Cache-Control: private, no-cache, no-store, max-age=0
Pragma: no-cache
Location: https://firebase-apiserver10-tah01-iad01.dapi.production.nest.com:9553/
Connection: close
Authorization: Bearer xxxxx
content-length: 0
headers received
reply was:
==========
==========
closing connection
Now I'm completely stuck. It would be nice if somebody could help me further out. thx
Wow. Holy smoke! I've got a response! You're tip made it work @gre_gor.
I've changed the host name and the port because my reply said something like this.
Here's my final code:
CODE:
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
const char* ssid = "xxxxx";
const char* password = "xxxxx";
const char* host = "firebase-apiserver10-tah01-iad01.dapi.production.nest.com";
const int httpsPort = 9553; //443;
const char* BearerKey = "xxxxx";
//declaring GPIO's
int gpio13Led = 13;
int gpio12Relay = 12;
// Use web browser to view and copy
// SHA1 fingerprint of the certificate
const char* fingerprint = "87:CB:F2:E6:44:C0:AA:F2:4C:28:B2:97:85:70:18:92:45:1B:A4:57";
void setup() {
// preparing GPIOs
pinMode(gpio13Led, OUTPUT);
digitalWrite(gpio13Led, HIGH);
pinMode(gpio12Relay, OUTPUT);
digitalWrite(gpio12Relay, HIGH);
Serial.begin(115200);
Serial.println();
Serial.print("connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
// Use WiFiClientSecure class to create TLS connection
WiFiClientSecure client;
Serial.print("connecting to ");
Serial.println(host);
if (!client.connect(host, httpsPort)) {
Serial.println("connection failed");
return;
}
if (client.verify(fingerprint, host)) {
Serial.println("certificate matches");
digitalWrite(gpio13Led, LOW);
} else {
Serial.println("certificate doesn't match");
}
String url = "/";
Serial.print("requesting URL: ");
Serial.println(url);
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Content-Type: application/json\r\n" +
"Authorization: Bearer " + BearerKey + "\r\n\r\n"
);
Serial.println("request sent");
while (client.connected()) {
String line = client.readStringUntil('\n');
Serial.println(line);
if (line == "\r") {
Serial.println("headers received");
break;
}
}
while (client.available()) {
String line = client.readStringUntil('\n');
Serial.println("reply was:");
Serial.println("==========");
Serial.println(line);
Serial.println("==========");
Serial.println("closing connection");
}
}
void loop() {
}
Serial monitor:
connecting to xxxxx
...........
WiFi connected
IP address:
xxxxx
connecting to firebase-apiserver10-tah01-iad01.dapi.production.nest.com
certificate doesn't match
requesting URL: /
request sent
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Access-Control-Allow-Origin: *
Cache-Control: private, no-cache, no-store, max-age=0
Pragma: no-cache
Connection: close
content-length: 8060
headers received
reply was:
==========
{"devices":{"thermostats":{"exxx":{"humidity":40,"locale":"nl-NL","temperature_scale":"C","is_using_emergency_heat":false,"has_fan":false,"software_version":"5.6.6-4","has_leaf":true,"where_id":"YygkopgUUc_cIFnCNG7GRDIIQnENO0ScVx9Pa78qfG7XyH-9WDdVgA","device_id":"e97ayjdpIOkPa4vZFxHggZMXiHKfhsyU","name":"Downstairs","can_heat":true,"can_cool":false,"target_temperature_c":15.0,"target_temperature_f":59,"target_temperature_high_c":24.0,"target_temperature_high_f":75,"target_temperature_low_c":20.0,"target_temperature_low_f":68,"ambient_temperature_c":15.5,"ambient_temperature_f":61,"away_temperature_high_c":24.0,"away_temperature_high_f":76,"away_temperature_low_c":8.5,"away_temperature_low_f":48,"eco_temperature_high_c":24.0,"eco_temperature_high_f":76,"eco_temperature_low_c":8.5,"eco_temperature_low_f":48,"is_locked":false,"locked_temp_min_c":20.0,"locked_temp_min_f":68,"locked_temp_max_c":22.0,"locked_temp_max_f":72,"sunlight_correction_active":false,"sunlight_correction_enabled":true,"structure_id":"vEJb634MNif-xxx{"access_token":"xxxx","client_version":2,"user_id":"xxxx"}}
==========
closing connection
The weird thing is that my fingerprint doesn't match but that it still proceeds to give me information.
Next step is to read this response and use the data I want. :-)