Hi Guys,
I am currently attempting to program a door switch (Reed switch) that will set a Nest Thermostat to "away" when a door is opened and return it to "Home" when the door is closed again.
You can use a REST API which I am currently attempting to interact with, (i can do this manually via Curl)
I have an Arduino Yun on order and have started to write the sketch but am having some problems. I have the basic things down like the set away/home action as that will not change, what I would like to do is automate the program so it can obtain the structure_ID and eventually the auth token.
As obtaining the structure_ID seems to be the smaller problem I am working on that first and will be working backwards to obtain the access token which for the moment is hard coded (Nest use static tokens)
Currently the getStructureID sends a GET request via the bridge using Curl (Command as shown below)
curl -L -X GET -H "Accept: application/json" "https://developer-api.nest.com/?auth=AUTH TOKEN"
This then returns the following JSON Response, from that I would like to filter out the structure_id value and enter it into the String structureID.
Now I have been looking round and have found the aJSON library and have no idea how to use it and it seems like it wants the whole JSON response cached in an array which will send up somewhere around 1200bytes which is most of the memory I have available on the Yun.
Is there a way to parse this on the fly say write to a small buffer say 200 chars and if that does not contain the data that we require clear the buffer and load the next set of data and filter until we find the value that we want?
"devices": {
"thermostats": {
"C2U421cfM3DmjD3VtJxTMYbYYj9JDwkY": {
"humidity": 50,
"locale": "en-GB",
"temperature_scale": "C",
"is_using_emergency_heat": false,
"has_fan": false,
"software_version": "4.3.1",
"has_leaf": true,
"device_id": "C2U421cfM3DmjD3VtJxTMYbYYj9JDwkY",
"name": "Basement",
"can_heat": true,
"can_cool": false,
"hvac_mode": "heat",
"target_temperature_c": 21.0,
"target_temperature_f": 70,
"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": 21.0,
"ambient_temperature_f": 70,
"away_temperature_high_c": 24.0,
"away_temperature_high_f": 76,
"away_temperature_low_c": 12.5,
"away_temperature_low_f": 55,
"structure_id": "rz5wmnglIbLGRSIkONOIPddlthddddIzHESHIVddddlx2xcBqk7y9A",
"fan_timer_active": false,
"name_long": "Basement Thermostat",
"is_online": true
}
}
},
"structures": {
"rz5wmnglIbLGRSIkONOIPddlthddddIzHESHIVddddlx2xcBqk7y9A": {
"name": "Home",
"country_code": "GB",
"time_zone": "Europe/London",
"away": "home",
"thermostats": ["C2U421cfM3DmjD3VtJxTMYbYYj9JDwkY"],
"structure_id": "rz5wmnglIbLGRSIkONOIPddlthddddIzHESHIVddddlx2xcBqk7y9A"
}
},
"metadata": {
"access_token": "Token ID",
"client_version": 1
}
}
#include <Process.h>
const int buttonPin = 2;
const int ledPin = 8;
const String accessToken = "Some Token ID";
// const String structureID = "Some Structure ID";
int buttonState = 0;
String awayState = "home";
String structureID;
void setup() {
Bridge.begin();
Serial.begin(9600);
while (!Serial);
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT);
buttonState = digitalRead(buttonPin);
if (buttonState = HIGH) {
String awayState = "home";
} else; {
String awayState = "away";
}
Serial.println('Away State = ' + awayState);
}
void getStructureID() {
Process getStructureID;
getStructureID.begin("curl");
getStructureID.addParameter("-L");
getStructureID.addParameter("-X");
getStructureID.addParameter("GET");
getStructureID.addParameter("-H");
getStructureID.addParameter("\"Accept: application/json\"");
getStructureID.addParameter("\"https://developer-api.nest.com/?auth=" + accessToken + "\"");
getStructureID.run();
while (getStructureID.available() > 0) {
char c = getStructureID.read();
Serial.print(c);
}
Serial.flush();
}
void setAway() {
Process setAway;
setAway.begin("curl");
setAway.addParameter(" - v");
setAway.addParameter(" - L");
setAway.addParameter(" - X");
setAway.addParameter("PUT");
setAway.addParameter("\"https://developer-api.nest.com/structures/" + structureID + "?auth=" + accessToken + "\"");
setAway.addParameter("-H");
setAway.addParameter("\"Content-Type: application/json\"");
setAway.addParameter("-d");
setAway.addParameter("{\"away:\"" + awayState + "\"}");
setAway.run();
while (setAway.available() > 0) {
char c = setAway.read();
Serial.print(c);
}
Serial.flush();
}
void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
digitalWrite(ledPin, LOW);
String awayState = "home";
}
else {
digitalWrite(ledPin, HIGH);
String awayState = "away";
}
Serial.println('Away State = ' + awayState);
setAway();
}
NOTE: I have not run this code on actual hardware yet as my Arduino is still in the post so this sketch may net even do what I want it to do or expect it to do but am pretty sure that the setAway method should work ok.
Any pointers on how I can improve my code are also appreciated.
I have found this Forum post that suggests parsing this on the Linux side and passing the data string over bridge to the Arduino now I have no idea how I could pass the response from Curl to a Python script without going over the bridge twice. Again any pointers would be great.