From 76edd6c448c55c4f9bcf37509ec372149c966993 Mon Sep 17 00:00:00 2001 From: schneefux Date: Fri, 25 Dec 2015 13:38:31 +0100 Subject: first commit --- weather.cpp | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 weather.cpp (limited to 'weather.cpp') diff --git a/weather.cpp b/weather.cpp new file mode 100644 index 0000000..4fabb1e --- /dev/null +++ b/weather.cpp @@ -0,0 +1,122 @@ +#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! + +#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 +} + -- cgit v1.3.1