-
Notifications
You must be signed in to change notification settings - Fork 2
/
AccuWeatherLibrary.h
244 lines (227 loc) · 6.66 KB
/
AccuWeatherLibrary.h
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
#pragma once
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include "JsonStreamingParser.h"
#include "JsonListener.h"
#include <limits.h>
#include <vector>
#include <map>
//Structures for holding the received data
typedef struct {
String LocalObservationDateTime;
String UVIndexText;
String WeatherText;
float CloudCover;
float Pressure;
float RealFeelTemperature;
float RealFeelTemperatureShade;
float RelativeHumidity;
float Temperature;
float Visibility;
float WindGustSpeed;
float WindSpeed;
int EpochTime;
int16_t WindDirection;
uint8_t IsDayTime;
uint8_t UVIndex;
uint8_t WeatherIcon;
}
AccuweatherCurrentData;
typedef struct {
String DateTime;
String IconPhrase;
String UVIndexText;
float Ice;
float Rain;
float RealFeelTemperature;
float RelativeHumidity;
float Snow;
float Temperature;
float TotalLiquid;
float Visibility;
float WindGustSpeed;
float WindSpeed;
int EpochDateTime;
int16_t WindDirection;
uint8_t CloudCover;
uint8_t IceProbability;
uint8_t IsDaylight;
uint8_t PrecipitationProbability;
uint8_t RainProbability;
uint8_t SnowProbability;
uint8_t UVIndex;
uint8_t WeatherIcon;
}
AccuweatherHourlyData;
typedef struct {
String IconPhrase;
String LongPhrase;
float Ice;
float Rain;
float RelativeHumidity;
float Snow;
float TotalLiquid;
float Visibility;
float WindGustSpeed;
float WindSpeed;
int16_t WindDirection;
uint8_t CloudCover;
uint8_t IceProbability;
uint8_t PrecipitationProbability;
uint8_t RainProbability;
uint8_t SnowProbability;
uint8_t ThunderstormProbability;
uint8_t WeatherIcon;
}
AccuweatherForecastData;
typedef struct {
String Date;
float TempMin;
float TempMax;
float RealFeelTempMin;
float RealFeelTempMax;
float HoursOfSun;
int EpochDate;
int SunRise;
int SunSet;
AccuweatherForecastData Day;
AccuweatherForecastData Night;
}
AccuweatherDailyData;
//Tokens for different keys that can be found in the JSON responses
//To extend the functionality, first a new token should be added to the enum below,
//then a mapping from String to that token in the map.
enum AccuParserTokens_ {
ACCUPARSERUnknown,
ACCUPARSERBase,
ACCUPARSERList,
ACCUPARSERObject,
ACCUPARSERUnitPlaceholder,
ACCUPARSERCloudCover,
ACCUPARSERDateTime,
ACCUPARSERDay,
ACCUPARSERDegrees,
ACCUPARSERDirection,
ACCUPARSEREnglish,
ACCUPARSEREpochDateTime,
ACCUPARSEREpochRise,
ACCUPARSEREpochSet,
ACCUPARSEREpochTime,
ACCUPARSERHoursOfSun,
ACCUPARSERIce,
ACCUPARSERIceProbability,
ACCUPARSERIconPhrase,
ACCUPARSERImperial,
ACCUPARSERIsDaylight,
ACCUPARSERIsDayTime,
ACCUPARSERLocalObservationDateTime,
ACCUPARSERLongPhrase,
ACCUPARSERMaximum,
ACCUPARSERMetric,
ACCUPARSERMinimum,
ACCUPARSERMoon,
ACCUPARSERNight,
ACCUPARSERPrecip1hr,
ACCUPARSERPrecipitationProbability,
ACCUPARSERPressure,
ACCUPARSERRain,
ACCUPARSERRainProbability,
ACCUPARSERRealFeelTemperature,
ACCUPARSERRealFeelTemperatureShade,
ACCUPARSERRelativeHumidity,
ACCUPARSERShortPhrase,
ACCUPARSERSnow,
ACCUPARSERSnowProbability,
ACCUPARSERSpeed,
ACCUPARSERSun,
ACCUPARSERTemperature,
ACCUPARSERThunderstormProbability,
ACCUPARSERTotalLiquid,
ACCUPARSERUnit,
ACCUPARSERUVIndex,
ACCUPARSERUVIndexText,
ACCUPARSERValue,
ACCUPARSERVisibility,
ACCUPARSERWeatherIcon,
ACCUPARSERWeatherText,
ACCUPARSERWind,
ACCUPARSERWindGust,
ACCUPARSERDailyForecasts,
ACCUPARSERDate,
ACCUPARSEREpochDate,
ACCUPARSERIcon,
};
//I do this to save memory - by default enums are ints, so to save a bit of memory I use chars instead.
//WARNING: change this if you will need more than 256 tokens
typedef uint8_t AccuParserTokens;
//The parser creates a stack while parsing the JSON response. This allows a lot of flexibility when creating a parser (e.g. we can infer all previous keys and objects before a given value)
//The stack contains tokens instead of strings. This greatly reduces memory usage and allows us to compare stack contents much quicker.
class AccuweatherParser: public JsonListener {
public:
AccuweatherParser(int maxListLength_, bool isMetric_ = true);
virtual void whitespace(char c);
virtual void key(String key);
virtual void value(String value);
virtual void startDocument();
virtual void endDocument();
virtual void startArray();
virtual void endArray();
virtual void startObject();
virtual void endObject();
bool isMetric = true;
protected:
std::vector<AccuParserTokens> tokenStack;
void DEBUG_printStack();
bool stackSuffix(const AccuParserTokens suffix[], int suffix_len);
bool stackContains(const AccuParserTokens token);
void popAllKeys();
int baseListIdx = -1;
int maxListLength = INT_MAX;
bool listFull = false;
};
//Descendant classes for parsing particular types of responses
class AccuweatherCurrentParser: public AccuweatherParser {
public:
AccuweatherCurrentParser(AccuweatherCurrentData* data_ptr_, bool isMetric_);
virtual void value(String value);
protected:
AccuweatherCurrentData* data_ptr;
};
class AccuweatherHourlyParser: public AccuweatherParser {
public:
AccuweatherHourlyParser(AccuweatherHourlyData* data_ptr_, int maxListLength_);
virtual void value(String value);
protected:
AccuweatherHourlyData* data_ptr;
};
class AccuweatherDailyParser: public AccuweatherParser {
public:
AccuweatherDailyParser(AccuweatherDailyData* data_ptr_, int maxListLength_);
virtual void startObject();
virtual void value(String value);
protected:
AccuweatherDailyData* data_ptr;
};
//Main class for sending requests and parsing responses
class Accuweather {
public:
HTTPClient http;
JsonStreamingParser parser;
AccuweatherParser* listener = NULL;
const int locationID;
const char* languageID;
const char* apiKey;
const bool isMetric;
int length;
Accuweather(const char* apiKey_, const int locationID_, const char* languageID_, const bool isMetric_):
locationID(locationID_),
languageID(languageID_),
apiKey(apiKey_),
isMetric(isMetric_){
}
int getCurrent(AccuweatherCurrentData* data_ptr);
int getHourly(AccuweatherHourlyData* data_ptr, int hours);
int getDaily(AccuweatherDailyData* data_ptr, int days);
int continueDownload();
void freeConnection();
};