-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathproviders.cpp
174 lines (158 loc) · 3.78 KB
/
providers.cpp
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
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include <Timezone.h>
#include "Configuration.h"
#include "providers.h"
#include "state.h"
#include "dbg.h"
#include "jsonclient.h"
void Provider::begin() {
if (!cfg.nearest)
return;
WiFiClient wifi;
JsonClient client(wifi, F("ip-api.com"));
if (client.get("/json")) {
extern struct Conditions conditions;
JsonDocument geo;
DeserializationError error = deserializeJson(geo, wifi);
if (error) {
ERR(print(F("Deserializing ip-api.com response: ")));
ERR(println(error.f_str()));
} else {
cfg.lat = geo["lat"];
cfg.lon = geo["lon"];
strncpy(conditions.city, geo["city"], sizeof(conditions.city));
cfg.nearest = true;
}
}
wifi.stop();
}
bool Provider::fetch_conditions(struct Conditions &conditions) {
WiFiClient wifi;
JsonClient client(wifi, _host);
bool ret = false;
if (client.get([&](Stream &s) { on_connect(s, true); })) {
JsonDocument doc;
DeserializationError error = deserializeJson(doc, wifi);
if (error) {
ERR(print(F("Deserialization of Conditions failed: ")));
ERR(println(error.f_str()));
stats.parse_failures++;
} else {
ret = update_conditions(doc, conditions);
if (ret)
stats.num_updates++;
DBG(print(F("Done ")));
}
}
wifi.stop();
return ret;
}
bool Provider::fetch_forecasts(struct Forecast forecasts[], int days) {
WiFiClient wifi;
JsonClient client(wifi, _host);
bool ret = false;
if (client.get([&](Stream &s) { on_connect(s, false); })) {
JsonDocument doc;
DeserializationError error = deserializeJson(doc, wifi);
if (error) {
ERR(print(F("Deserialization of Forecasts failed: ")));
ERR(println(error.f_str()));
stats.parse_failures++;
} else {
ret = update_forecasts(doc, forecasts, days);
DBG(print(F("Done ")));
}
}
wifi.stop();
return ret;
}
// https://en.wikipedia.org/wiki/Lunar_phase#Calculating_phase
int Provider::moon_age(time_t &epoch) {
const long last_full = 937008000; // Aug 11, 1999
const double secs_per_day = 86400;
const double lunation_period = 29.530588853;
return round(fmod(((long)epoch - last_full) / secs_per_day, lunation_period));
}
const char *Provider::moon_phase(int age) {
if (age == 0)
return PSTR("New Moon");
if (age < 7)
return PSTR("Waxing Crescent");
if (age == 7)
return PSTR("First Quarter");
if (age < 15)
return PSTR("Waxing Gibbous");
if (age == 15)
return PSTR("Full Moon");
if (age < 22)
return PSTR("Waning Gibbous");
if (age == 22)
return PSTR("Last Quarter");
if (age < 29)
return PSTR("Waning Crescent");
return PSTR("New Moon");
}
const char *Provider::weather_description(int wmo_code) {
switch(wmo_code) {
case 0:
return PSTR("clear sky");
case 1:
return PSTR("mostly clear");
case 2:
return PSTR("partly cloudy");
case 3:
return PSTR("overcast");
case 45:
return PSTR("fog");
case 48:
return PSTR("icy fog");
case 51:
return PSTR("light drizzle");
case 53:
return PSTR("drizzle");
case 55:
return PSTR("heavy drizzle");
case 56:
return PSTR("light icy drizzle");
case 57:
return PSTR("icy drizzle");
case 61:
return PSTR("light rain");
case 63:
return PSTR("rain");
case 65:
return PSTR("heavy rain");
case 66:
return PSTR("light icy rain");
case 67:
return PSTR("icy rain");
case 71:
return PSTR("light snow");
case 73:
return PSTR("snow");
case 75:
return PSTR("heavy snow");
case 77:
return PSTR("snow grains");
case 80:
return PSTR("light showers");
case 81:
return PSTR("showers");
case 82:
return PSTR("heavy showers");
case 85:
return PSTR("light snow showers");
case 86:
return PSTR("snow showers");
case 95:
return PSTR("thunderstorm");
case 96:
return PSTR("thunderstorm with light hail");
case 99:
return PSTR("thunderstorm with hail");
default:
return PSTR("unknown");
}
}