#include "weather.h" //#define DEBUG #define HTTP_TIMEOUT 5000 // ms #define DOWNLOADSIZE 1100 // http buffer size, *should* be enough for a cnt=2 request #define JSONSIZE 1500 // json buffer size, for a cnt=2 request // ^ be careful with counter over/underflows! #error "Specify an OpenWeatherMap API key and delete this line." #define CITYID "YOURCITYID" #define APIKEY "YOURAPIKEY" #define APIHOST "api.openweathermap.org" #define APIPATH "/data/2.5/forecast?id=" CITYID "&appid=" APIKEY "&cnt=2" // "cnt=2" for 3 hour forecast // queries OWM for the 3-hour-forecast, returns icon code // see http://openweathermap.org/weather-conditions for codes String getWeatherStatus() { #ifdef DEBUG Serial.println("Requesting weather data."); #endif WiFiClient cli; cli.connect(APIHOST, 80); cli.println("GET " APIPATH " HTTP/1.1"); cli.println("Host: " APIHOST); cli.println("Connection: close\r\n"); #ifdef DEBUG Serial.println("Sent request: " APIHOST APIPATH); #endif unsigned int timeoutTimer = HTTP_TIMEOUT; boolean gotHeaders = false; // skip headers while (cli.connected() && timeoutTimer-- && !gotHeaders) { while (cli.available()) { String line = cli.readStringUntil('\n'); if (line == "\r") { gotHeaders = true; break; } } delay(1); } if (!gotHeaders) { #ifdef DEBUG Serial.println("Did not receive headers."); #endif cli.stop(); if (!cli.connected()) { #ifdef DEBUG Serial.println("Connection was reset."); #endif } return "-1"; } // read response into char array char response[DOWNLOADSIZE]; unsigned int buffPointer = 0; boolean jsonStarted = false; int charsSinceJsonEnd = 0; while (cli.connected() && timeoutTimer-- && buffPointer < DOWNLOADSIZE) { while (cli.available() && buffPointer < DOWNLOADSIZE) { char ch = (char) cli.read(); if (!jsonStarted) { if (ch == '{') { jsonStarted = true; } } if (jsonStarted) { if (ch == '}') { charsSinceJsonEnd = 0; } else { charsSinceJsonEnd++; } response[buffPointer++] = ch; } } delay(1); } cli.stop(); response[buffPointer - charsSinceJsonEnd] = '\0'; // OWM seems to send some weird extra characters we do not want if (!timeoutTimer) { #ifdef DEBUG Serial.println("Timed out."); #endif return "-1"; } if (buffPointer == DOWNLOADSIZE) { #ifdef DEBUG Serial.println("Maximum buffer size exceeded."); #endif return "-1"; } #ifdef DEBUG Serial.println("'" + String(response) + "'"); #endif StaticJsonBuffer json; JsonObject& root = json.parseObject(response); if (!root.success()) { #ifdef DEBUG Serial.println("JSON invalid."); #endif return "-1"; } String strConditionId = root["list"][1]["weather"][0]["icon"].asString(); if (!strConditionId.length()) { return "-1"; } #ifdef DEBUG Serial.println("Parsed JSON. Weather code: " + strConditionId); #endif return strConditionId; // 3 hour future weather by icon code }