blob: e76e462e26192bdd1f1fc5f2976bf48cf55b65bd (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
#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<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
}
|