-
Notifications
You must be signed in to change notification settings - Fork 0
/
atmo_webrequests.h
170 lines (154 loc) · 7.24 KB
/
atmo_webrequests.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
#pragma once
void GetGeolocationFromNet();
void ParseWeatherAndTime();
void ParseGeoLocation();
HTTPClient weathercurrenthttp, geolocatehttp;
// original strings:
// OLD// http://api.openweathermap.org/data/2.5/weather?&appid=ba42e4a918f7e742d3143c5e8fff9210&lat=59.3307&lon=18.0718&units=metric
// CURRENT //https://weather.api.here.com/weather/1.0/report.json?app_id=JoN1SBsEzJ5pWD5OkXwN&app_code=J9XdgHlHuUKzV2j5GqxlVg&product=forecast_7days_simple&latitude=59.3307&longitude=18.0718
//const String weatherCurrent = "http://api.openweathermap.org/data/2.5/weather?&appid=ba42e4a918f7e742d3143c5e8fff9210&lat=";
const String weatherCurrent = "https://weather.api.here.com/weather/1.0/report.json?app_id=JoN1SBsEzJ5pWD5OkXwN&app_code=J9XdgHlHuUKzV2j5GqxlVg&product=forecast_7days_simple&product=observation&oneobservation=true&latitude=";
const String weatherAndLon = "&longitude=";
const String weatherNoMetric = "&metric=false";
const String weatherMetric = "&metric=true";
const String weatherLanguage = "&language="; // https://developer.here.com/documentation/weather/topics/supported-languages.html
const String geolocatestring = "http://api.ipstack.com/check?access_key=d0dfe9b52fa3f5bb2a5ff47ce435c7d8&fields=city,latitude,longitude";
//key=ab925796fd105310f825bbdceece059e
void GetGeolocationFromNet()
{
pp("getting geolocation from internet");
geolocatehttp.setTimeout(SITE_TIMEOUT_MS);
EnsureWiFiIsStarted();
geolocatehttp.begin(geolocatestring);
pp(geolocatestring);
int geoHttpCode = geolocatehttp.GET();
if (geoHttpCode == 200)
{
ParseGeoLocation();
pp("got location:" + Prefs.getString(PREF_CITY_STRING));
}
else if (geoHttpCode != 200) { // FAILED TO CONNECT TO GEOLOCATE SITE
DrawFailedToConnectToSite(); // draws to epaper
AtmoDeepSleep();
}
}
int RequestWeatherData()
{
String weatherCall = weatherCurrent + Prefs.getFloat(PREF_LAT_FLOAT) + weatherAndLon + Prefs.getFloat(PREF_LON_FLOAT);
pp(weatherCall);
if (Prefs.getBool(PREF_METRIC_BOOL))
{
weatherCall = weatherCall + weatherMetric;
}
else
{
weatherCall = weatherCall + weatherNoMetric;
}
weathercurrenthttp.setTimeout(SITE_TIMEOUT_MS);
EnsureWiFiIsStarted();
weathercurrenthttp.addHeader("Content-Encoding", "gzip");
weathercurrenthttp.begin(weatherCall); //Specify the URL
pp("making actl internet call");
return weathercurrenthttp.GET();
}
void ParseCurrentTimeForDisplay(int timezone)
{
int startI = CurrentTime.indexOf('T');
int hourI = CurrentTime.indexOf(':');
int minuteI = hourI + 3;
int hour = CurrentTime.substring(startI + 1, hourI).toInt() + timezone; // TODO add timezone 4real -- use lib tho haha
String minutes = CurrentTime.substring(hourI + 1, minuteI);
CurrentTime = String(hour) + ":" + minutes;
if (CurrentTime.length() < 5)
CurrentTime = " " + CurrentTime; // prepend whitespace to keep time in the corner
}
void SetClockAndDriftCompensate() // TODO put on second core?
{ // CurrentTime should be freshly parsed from JSON at this point
// 0YYY-5M-8DThh:mm:ssfZ
int YYYY = CurrentTime.substring(0, 4).toInt();
int MM = CurrentTime.substring(5, 2).toInt();
int DD = CurrentTime.substring(8, 2).toInt();
int hh = CurrentTime.substring(11, 2).toInt();
int mm = CurrentTime.substring(14, 2).toInt();
int ss = CurrentTime.substring(17, 2).toInt();
tmElements_t tm;
tm.Year = CalendarYrToTm(YYYY);
tm.Month = MM;
tm.Day = DD;
tm.Hour = hh;
tm.Minute = mm;
tm.Second = ss;
time_t oldTime = now();
time_t newTime = makeTime(tm);
setTime(newTime);
int64_t timeDriftSeconds = newTime - oldTime; // negative if i woke up early, bc oldtime was too fast
SleepDriftWasTooFast = (timeDriftSeconds < 0);
if (SleepDriftWasTooFast)
timeDriftSeconds *= -1;
if (oldTime < 1579461559)
timeDriftSeconds = 0; // TODO make this whole thing not terrible, set time in hard wake eg
SleepDriftCompensation = (uint64_t)timeDriftSeconds * OneSecond;
}
void ParseWeatherAndTime()
{
ArduinoJson6141_0000010::DynamicJsonDocument weatherCurrentDoc(12000);
/*InputStream instream = response.getEntity().getContent();
Header contentEncoding = response.getFirstHeader("Content-Encoding");
if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip")) {
instream = new GZIPInputStream(instream);
}*/
ArduinoJson6141_0000010::DeserializationError error = deserializeJson(weatherCurrentDoc, weathercurrenthttp.getString()); //optimize doc size
if (error) {
Serial.print(F("deserializeJson() failed22: "));
Serial.println(error.c_str());
AtmoDeepSleep();
}
String ObservationTime = weatherCurrentDoc["observations"]["location"][0]["observation"][0]["utcTime"].as<String>();
int timezonestartI = ObservationTime.lastIndexOf('+');
int timezoneendI = ObservationTime.lastIndexOf(':');
int timezone = ObservationTime.substring(timezonestartI + 1, timezoneendI).toInt();
CurrentTime = weatherCurrentDoc["feedCreation"].as<String>();
SetClockAndDriftCompensate();
ParseCurrentTimeForDisplay(timezone);
for (int i = 0; i <= 7; i++)
{
//WeatherDays[i].UTCTime = weatherCurrentDoc["dailyForecasts"]["forecastLocation"]["forecast"][i]["utcTime"];
WeatherDays[i].DayOfWeek = weatherCurrentDoc["dailyForecasts"]["forecastLocation"]["forecast"][i]["weekday"].as<char*>();
WeatherDays[i].High = weatherCurrentDoc["dailyForecasts"]["forecastLocation"]["forecast"][i]["highTemperature"];
WeatherDays[i].Low = weatherCurrentDoc["dailyForecasts"]["forecastLocation"]["forecast"][i]["lowTemperature"];
WeatherDays[i].PrecipChance = weatherCurrentDoc["dailyForecasts"]["forecastLocation"]["forecast"][i]["precipitationProbability"];
WeatherDays[i].SkyText = weatherCurrentDoc["dailyForecasts"]["forecastLocation"]["forecast"][i]["skyDescription"];
WeatherDays[i].PrecipText = weatherCurrentDoc["dailyForecasts"]["forecastLocation"]["forecast"][i]["precipitationDesc"];
}
TodayHigh = weatherCurrentDoc["observations"]["location"][0]["observation"][0]["highTemperature"];
TodayLow = weatherCurrentDoc["observations"]["location"][0]["observation"][0]["lowTemperature"];
TodaySky = weatherCurrentDoc["observations"]["location"][0]["observation"][0]["skyDescription"].as<String>();
TodayTempDesc = weatherCurrentDoc["observations"]["location"][0]["observation"][0]["temperatureDesc"].as<String>();
//TodayTempDesc.toLowerCase();
//TodaySky.toLowerCase();
CurrentTemp = weatherCurrentDoc["observations"]["location"][0]["observation"][0]["temperature"];
}
void ParseGeoLocation()
{
// Enough space for:
// + 1 object with 3 members
// + 2 objects with 1 member
//const int capacity = JSON_OBJECT_SIZE(3) + 2 * JSON_OBJECT_SIZE(1);
//StaticJsonDocument<capacity> doc;
// TODO look into this for making exactly sized JSON docs
//"Of course, if the JsonDocument were bigger, it would make sense to move it the heap" (<- from PDF)
ArduinoJson6141_0000010::StaticJsonDocument<200> geoDoc;
ArduinoJson6141_0000010::DeserializationError error = deserializeJson(geoDoc, geolocatehttp.getString()); //optimize doc size
if (error) {
Serial.print(F("deserializeJson() failed 1 : "));
Serial.println(error.c_str());
AtmoDeepSleep();
}
String city = geoDoc["city"].as<String>();
city.replace(" ", "%20");
pp(city);
Prefs.putBool(PREF_VALID_BOOL, true);
Prefs.putFloat(PREF_LAT_FLOAT, geoDoc["latitude"]);
Prefs.putFloat(PREF_LON_FLOAT, geoDoc["longitude"]);
Prefs.putString(PREF_CITY_STRING, city);
}