summaryrefslogtreecommitdiff
path: root/weather.cpp
diff options
context:
space:
mode:
authorschneefux <schneefux+commit@schneefux.xyz>2015-12-25 13:38:31 +0100
committerschneefux <schneefux+commit@schneefux.xyz>2015-12-25 13:38:31 +0100
commit76edd6c448c55c4f9bcf37509ec372149c966993 (patch)
treec4eed3c1ecb40987cbe2b77df47b2e6e23c71494 /weather.cpp
downloadweather-snowman-76edd6c448c55c4f9bcf37509ec372149c966993.tar.gz
weather-snowman-76edd6c448c55c4f9bcf37509ec372149c966993.zip
first commit
Diffstat (limited to 'weather.cpp')
-rw-r--r--weather.cpp122
1 files changed, 122 insertions, 0 deletions
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<JSONSIZE> 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
+}
+