Random work

This commit is contained in:
Fred Boniface 2024-11-27 13:30:54 +00:00
parent ac11576550
commit a702f2f9aa
8 changed files with 975 additions and 49 deletions

View File

@ -613,38 +613,3 @@ const unsigned char esphub_lrg [] PROGMEM = {
0x00, 0x7f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00
};
const unsigned char sun [] PROGMEM = {
// 'sun, 64x64px
0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff,
0xff, 0xef, 0xff, 0xf8, 0x1f, 0xff, 0xf7, 0xff, 0xff, 0x87, 0xff, 0xfc, 0x3f, 0xff, 0xe1, 0xff,
0xff, 0x83, 0xff, 0xfe, 0x7f, 0xff, 0xc1, 0xff, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0x80, 0xff,
0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xc0, 0x7f, 0xff, 0xff, 0xfe, 0x03, 0xff,
0xff, 0xe0, 0x3f, 0xff, 0xff, 0xfc, 0x07, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xfc, 0x0f, 0xff,
0xff, 0xf8, 0x7f, 0xf0, 0x0f, 0xfe, 0x1f, 0xff, 0xff, 0xfc, 0xff, 0x80, 0x01, 0xff, 0x3f, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xf8, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x03, 0xc0, 0x0f, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x1f, 0xf8, 0x07, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x3f, 0xfc, 0x03, 0xff, 0xff,
0xff, 0xff, 0xc0, 0x7f, 0xfe, 0x03, 0xff, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0x01, 0xff, 0xff,
0xff, 0xff, 0x81, 0xff, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0x83, 0xff, 0xff, 0xc1, 0xff, 0xff,
0xff, 0xff, 0x03, 0xff, 0xff, 0xc0, 0xff, 0xff, 0xc0, 0x7f, 0x03, 0xff, 0xff, 0xc0, 0xfe, 0x03,
0x00, 0x3f, 0x07, 0xff, 0xff, 0xe0, 0xfc, 0x00, 0x00, 0x1f, 0x07, 0xff, 0xff, 0xe0, 0xf8, 0x00,
0x00, 0x1f, 0x07, 0xff, 0xff, 0xe0, 0xf8, 0x00, 0x00, 0x3f, 0x07, 0xff, 0xff, 0xe0, 0xfc, 0x00,
0xc0, 0x7f, 0x03, 0xff, 0xff, 0xc0, 0xfe, 0x03, 0xff, 0xff, 0x03, 0xff, 0xff, 0xc0, 0xff, 0xff,
0xff, 0xff, 0x83, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xff, 0x81, 0xff, 0xff, 0x81, 0xff, 0xff,
0xff, 0xff, 0x80, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x7f, 0xfe, 0x03, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x3f, 0xfc, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x1f, 0xf8, 0x07, 0xff, 0xff,
0xff, 0xff, 0xf0, 0x03, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x1f, 0xff, 0xff,
0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff,
0xff, 0xfc, 0xff, 0x80, 0x01, 0xff, 0x3f, 0xff, 0xff, 0xf8, 0x7f, 0xf0, 0x0f, 0xfe, 0x1f, 0xff,
0xff, 0xf0, 0x3f, 0xff, 0xff, 0xfc, 0x0f, 0xff, 0xff, 0xe0, 0x3f, 0xff, 0xff, 0xfc, 0x07, 0xff,
0xff, 0xc0, 0x7f, 0xff, 0xff, 0xfe, 0x03, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff,
0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0x81, 0xff, 0xff, 0x83, 0xff, 0xfe, 0x7f, 0xff, 0xc1, 0xff,
0xff, 0x87, 0xff, 0xfc, 0x3f, 0xff, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff
};

View File

@ -19,6 +19,14 @@ struct Config {
String ncUrl;
};
// Active Features
struct ActiveFeatures {
bool network;
bool homeassistant;
bool calendar;
bool weather;
};
Config loadConfig();
#endif

View File

@ -35,17 +35,28 @@ SPIClass hspi(HSPI);
// <Local Includes>
#include "bitmap.h"
#include "config_loader.h"
#include "weather.h"
#include "helper_fn.h"
// <Fonts>
#include <Fonts/FreeMono9pt7b.h>
#include <Fonts/FreeMonoBold9pt7b.h>
#include <Fonts/FreeMonoBold12pt7b.h>
#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeSansBold24pt7b.h>
// <Connectivity>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <time.h>
#include <HTTPClient.h>
#include "tls_certificates.h"
#include <ArduinoJson.h>
// Globals
Config conf;
ActiveFeatures activeFeatures;
int loopIteration = 0;
void setup()
{
@ -75,8 +86,10 @@ void setup()
conf = loadConfig();
if (connect_WiFi(conf.ssid.c_str(), conf.wifiPass.c_str())) {
bootMsg("WiFi Connection: OK", text_y);
activeFeatures.network = true;
} else {
bootMsg("WiFi Connection: FAIL", text_y);
activeFeatures.network = false;
}
text_y += line_height;
if (update_time()) {
@ -87,18 +100,54 @@ void setup()
text_y += line_height;
if (checkUrlPing(conf.haUrl)) { // FAILS FOR SOME REASON -- DEBUG ME
bootMsg("Home Assistant URL Reachable: OK", text_y);
// Check home entity is reachable here.
text_y += line_height;
if (haAnybodyHome() < 0) {
bootMsg("Home Assistant Home Entity Check: FAIL", text_y);
activeFeatures.homeassistant = false;
} else {
activeFeatures.homeassistant = true;
bootMsg("Home Assistant Home Entity Check: OK", text_y);
}
text_y += line_height;
} else {
bootMsg("Home Assistant URL Reachable: FAIL", text_y);
text_y += line_height;
activeFeatures.homeassistant = false;
}
if (getWeather(conf.latitude, conf.longitude).latitude) {
bootMsg("Fetch Weather Data: OK", text_y);
activeFeatures.weather = true;
} else {
bootMsg("Fetch Weather Data: FAIL", text_y);
activeFeatures.weather = false;
}
text_y += line_height;
// Check Nextcloud reachable here
display.hibernate();
displayActiveFeatures(activeFeatures);
bootMsg("Weather Icons sourced from flaticon.com", text_y);
text_y += 2 * line_height;
bootMsg("Starting main loop...", text_y);
}
void loop()
{
// Run loop here
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("Unable to get time, some features will be buggy");
}
WeatherData weather = getWeather(conf.latitude, conf.longitude);
Serial.printf("Loop iteration %d\n", loopIteration);
display.setFullWindow();
do {
display.fillScreen(GxEPD_WHITE);
display.fillRect(0, 0, 800, 80, GxEPD_BLACK);
displayHeaderText(timeinfo);
displayWeather(weather);
} while (display.nextPage());
display.hibernate();
delay(3600000);
loopIteration ++;
}
// Places the boot logo in position at the top of the screen
@ -112,7 +161,6 @@ void bootLogo() {
display.drawBitmap(img_x, 15, esphub_lrg, 648, 120, GxEPD_BLACK);
}
while (display.nextPage());
delay(2000);
}
// Prints a one-line message to the screen, aligned with the boot logo at `y_pos`
@ -127,7 +175,46 @@ void bootMsg(const char* msg, const uint16_t y_pos) {
display.nextPage(); // Only needed for e-ink paginated updates
}
void displayActiveFeatures(const ActiveFeatures activeFeatures) {
constexpr uint16_t x_pos = 650; // X Position
uint16_t y_pos = 180; // Y Position
uint16_t line_height = 17;
display.setPartialWindow(0, 0, display.width(), display.height());
display.setFont(&FreeSans9pt7b); // Set font
display.setTextColor(GxEPD_WHITE); // Set color
//display.firstPage();
do {
// Convert booleans to "Y"/"N"
auto boolToYN = [](bool value) -> const char* { return value ? "Y" : "N"; };
display.fillRect(x_pos - line_height, y_pos - line_height, 170, 7 * line_height, GxEPD_BLACK);
display.setCursor(x_pos, y_pos);
display.print("Enabled Features\n");
display.setCursor(x_pos, y_pos + 2 * line_height);
display.print("Network: ");
display.print(boolToYN(activeFeatures.network));
display.setCursor(x_pos, y_pos + 3 * line_height);
display.print("HASS: ");
display.print(boolToYN(activeFeatures.homeassistant));
display.setCursor(x_pos, y_pos + 4 * line_height);
display.print("Calendar: ");
display.print(boolToYN(activeFeatures.calendar));
display.setCursor(x_pos, y_pos + 5 * line_height);
display.print("Weather: ");
display.print(boolToYN(activeFeatures.weather));
}
while (display.nextPage());
}
bool connect_WiFi(String ssid, String pass) {
Serial.print("Connecting to SSID ");
Serial.println(ssid);
WiFi.begin(ssid, pass);
int retries = 10;
while (WiFi.status() != WL_CONNECTED && retries > 0) {
@ -152,17 +239,162 @@ bool update_time() {
}
bool checkUrlPing(const String& url) {
HTTPClient http;
WiFiClient client;
WiFiClientSecure *client = new WiFiClientSecure;
if (client) {
client -> setCACert(letsencrypt_root_ca);
{
HTTPClient https;
Serial.println("Starting HTTPS Request");
if (https.begin(*client, url)) {
int httpCode = https.GET();
Serial.printf("HTTPS GET code: %d\n", httpCode);
http.begin(client, url);
int httpCode = http.GET();
if (httpCode > 0) {
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
https.end();
delete client;
return true;
}
}
}
https.end();
delete client;
}
}
return false;
}
if (httpCode == HTTP_CODE_OK) {
http.end();
return true;
} else {
http.end();
return false;
float haAnybodyHome() {
WiFiClientSecure *client = new WiFiClientSecure;
if (client) {
client -> setCACert(letsencrypt_root_ca);
String url = conf.haUrl + "/api/states/" + conf.homeEntity;
Serial.println("URL: " + url);
HTTPClient https;
Serial.println("Starting HTTPS Request to Home Assistant");
if (https.begin(*client, url)) {
https.addHeader("Authorization", "Bearer " + conf.haKey);
int httpCode = https.GET();
Serial.printf("Home Assistant GET Code: %d\n", httpCode);
if (httpCode == HTTP_CODE_OK) {
String payload = https.getString();
DynamicJsonDocument doc(1024);
DeserializationError error = deserializeJson(doc, payload);
if (error) {
Serial.println("Failed to Parse JSON Response");
https.end();
delete client;
return -0.1;
}
float state = doc["state"].as<float>();
Serial.printf("Entity %s state: %f\n", conf.homeEntity.c_str(), state);
https.end();
delete client;
return state;
}
return -0.2;
}
}
}
String getGreeting(struct tm timeinfo) {
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time from RTC");
return "Hello";
}
int currentHour = timeinfo.tm_hour; // Get the current hour
if (currentHour >= 5 && currentHour < 12) {
return "Good morning";
} else if (currentHour >= 12 && currentHour < 18) {
return "Good afternoon";
} else if (currentHour >= 18 && currentHour < 22) {
return "Good evening";
} else {
return "Good night";
}
}
String getDate(struct tm timeinfo) {
char dateStr[11];
strftime(dateStr, sizeof(dateStr), "%d/%m/%Y", &timeinfo);
return String(dateStr); // Convert the C string to a String object and return it
}
String getDayOfWeek(struct tm timeinfo) {
char dayStr[10];
strftime(dayStr, sizeof(dayStr), "%A", &timeinfo);
return String(dayStr);
}
void displayHeaderText(struct tm timeinfo) {
display.setTextColor(GxEPD_WHITE);
// Define vars for bound calculations
int16_t tbx, tby;
uint16_t tbw, tbh;
// Get Greeting and notable day
String greeting = getGreeting(timeinfo);
String notableDay = getNotableDay(timeinfo.tm_mon + 1, timeinfo.tm_mday);
String date = getDate(timeinfo);
String dayOfWeek = getDayOfWeek(timeinfo);
display.setFont(&FreeSansBold24pt7b); // Set Greeting Font
// Calculate Bounds for Greeting
display.getTextBounds(greeting, 0, 0, &tbx, &tby, &tbw, &tbh);
uint16_t gx = (display.width() - tbw) / 2;
uint16_t gy = 42;
// Print Greeting
display.setCursor(gx, gy);
display.print(greeting);
display.setFont(&FreeMonoBold9pt7b); // Set Notable Day Font
// Calculate Bounds for Notable Day
display.getTextBounds(notableDay, 0, 0, &tbx, &tby, &tbw, &tbh);
uint16_t nx = (display.width() - tbw) / 2;
uint16_t ny = 70;
// Print Notable Day
display.setCursor(nx, ny);
display.print(notableDay);
// Print date
display.setCursor(680, 25);
display.print(date);
display.setCursor(680, 60);
display.print(dayOfWeek);
}
void displayWeather(WeatherData weather) {
display.setFont(&FreeMonoBold12pt7b);
display.setTextColor(GxEPD_WHITE);
display.setCursor(5, 23);
display.print(String((int)round(weather.current.temperature_2m)) + "°C");
display.drawBitmap(5, 27, hi, 22, 22, GxEPD_WHITE); // Draw 'max temp' bitmap
display.setFont(&FreeMonoBold9pt7b);
display.setCursor(18, 44);
display.print(String((int)round(weather.daily.temperature_2m_max)) + "°C");
display.drawBitmap(5, 50, lo, 22, 22, GxEPD_WHITE); // Draw 'min temp' bitmap
display.setCursor(18, 64);
display.print(String((int)round(weather.daily.temperature_2m_min)) + "°C");
display.drawBitmap(65, 10, getWeatherBitmap(weather.daily.weather_code), 64, 64, GxEPD_WHITE); // Draw Weather Bitmap
display.drawBitmap(129, 8, wind, 22, 22, GxEPD_WHITE); // Draw 'wind speed' bitmap
display.setCursor(153, 23);
display.print("km/h");
display.setCursor(133, 45);
display.print(String(weather.daily.wind_speed_10m_max));
display.setCursor(133, 64);
display.print(String(weather.daily.wind_gusts_10m_max));
}
void displayFullScreenArt() {}

View File

@ -0,0 +1,69 @@
#include "helper_fn.h"
#include <cstdlib>
#include <ctime>
NotableDay notableDays[] = { // Max characters in a notable day is 39 characters
{1, 1, {"New Years Day!"}},
{1, 4, {"National Trivia Day", "World Braille Day"}},
{1, 5, {"The Twelfth Night of Christmas"}},
{1, 16, {"Blue Monday"}},
{1, 18, {"Whinnie the Pooh Day"}},
{1, 24, {"International Day of Education"}},
{1, 25, {"Burns Night"}},
{1, 26, {"International Day of Clean Energy"}},
{1, 27, {"Holocaust Memorial Day"}},
{2, 2, {"Candlemas", "World Wetlands Day"}},
{2, 4, {"World Cancer Day", "International Day of Human Fraternity"}},
{2, 6, {"Anti-FGM Day"}},
{2, 10, {"Intl. Day of the Arabian Leopard", "World Pulses Day"}},
{2, 11, {"Internation Day of Women and Girls in Science"}},
{2, 13, {"World Radio Day"}},
{2, 14, {"St. Valentine's Day"}},
{2, 15, {"International Choldhood Cancer Day"}},
{2, 17, {"Global Tourism Resilience Day"}},
{2, 20, {"World Day of Social Justice"}},
{2, 21, {"International Mother Language Day"}},
{2, 22, {"World Thinking Day"}},
{2, 29, {"Leap Year Day"}},
{3, 1, {"St. David's Day", "Zero Discrimination Day", "World Seagrass Day"}},
{3, 3, {"World Wildlife Day"}},
{3, 8, {"International Women's Day"}},
{3, 10, {"International Day of Women Judges"}},
{3, 15, {"Combat Islamophobia Day"}},
{3, 20, {"International Happiness Day", "French Language Day"}},
{3, 21, {"World Poetry Day", "Intl. Day of Nowruz", "World Down Syndrome Day"}},
{3, 22, {"World Water Day"}},
{3, 23, {"World Meteorological Day"}},
{3, 24, {"World Tuberculosis Day"}},
{3, 25, {"Transatlantic Slavery Remembrance Day"}},
{3, 30, {"International Zero Waste Day"}},
{5, 5, {"St. Piran's Day"}},
{11, 30, {"St. Andrew's Day", "Computer Security Day"}},
{12, 21, {"Abolishion of Slavery Day"}},
{12, 24, {"Christmas Eve"}},
{12, 25, {"Christmas Day"}},
{12, 26, {"Boxing Day"}},
{12, 27, {"Epidemic Preparedness Day"}},
{12, 31, {"New Year's Eve"}}
};
String getNotableDay(int month, int day) {
for (NotableDay notable : notableDays) {
if (notable.month == month && notable.day == day) {
// Count the number of non-empty notable days
int count = 0;
for (String notableDay : notable.notableDays) {
if (notableDay != "") {
count++;
}
}
if (count > 0) {
// Pick a random notable day
int randomIndex = rand() % count;
return notable.notableDays[randomIndex];
}
}
}
return "Today is not a special day"; // Return an empty string if no notable day is found
}

View File

@ -0,0 +1,14 @@
#ifndef HELPER_FN_H
#define HELPER_FN_H
#include <Arduino.h>
struct NotableDay {
int month;
int day;
String notableDays[5];
};
String getNotableDay(int month, int day);
#endif

View File

@ -0,0 +1,38 @@
#ifndef TLS_CERTIFICATES_H
#define TLS_CERTIFICATES_H
const char letsencrypt_root_ca[] = R"(
"-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----
)";
#endif

View File

@ -0,0 +1,536 @@
#include "weather.h"
#include "tls_certificates.h"
#include <WiFiClientSecure.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
WeatherData getWeather(float latitude, float longitude) {
// Correct the URL construction
String url = "https://api.open-meteo.com/v1/forecast?latitude=" + String(latitude, 6) + "&longitude=" + String(longitude, 6);
url += "&current=temperature_2m&daily=weather_code,temperature_2m_max,temperature_2m_min,sunrise,sunset,precipitation_sum,wind_speed_10m_max,wind_gusts_10m_max";
url += "&timezone=Europe%2FLondon&forecast_days=1";
Serial.println("Weather URL: " + url);
// Create a WiFiClientSecure object
WiFiClientSecure *client = new WiFiClientSecure;
if (client) {
client->setCACert(letsencrypt_root_ca); // Set the root certificate
// Create an HTTPClient object for making the GET request
HTTPClient https;
// Start the HTTPS request
Serial.println("Starting HTTPS Request to Weather API");
if (https.begin(*client, url)) { // Use the pre-defined URL
// Send GET request
int httpCode = https.GET();
Serial.printf("Weather API GET Code: %d\n", httpCode);
// Check if the request was successful
if (httpCode == HTTP_CODE_OK) {
String payload = https.getString(); // Get the JSON payload from the response
Serial.println("Weather data received, parsing...");
// Create a WeatherData object to store the parsed data
WeatherData weatherData;
// Parse the JSON response into the WeatherData structure
DynamicJsonDocument doc(4096); // Adjust size as needed
DeserializationError error = deserializeJson(doc, payload);
if (error) {
Serial.println("Failed to parse JSON");
https.end();
delete client;
return weatherData; // Return empty struct in case of error
}
// Populate the WeatherData structure
weatherData.latitude = doc["latitude"].as<float>();
weatherData.longitude = doc["longitude"].as<float>();
weatherData.elevation = doc["elevation"].as<float>();
weatherData.timezone = doc["timezone"].as<String>();
weatherData.timezone_abbreviation = doc["timezone_abbreviation"].as<String>();
// Parse current weather data
JsonObject current = doc["current"];
weatherData.current.time = current["time"].as<String>();
weatherData.current.interval = current["interval"].as<int>();
weatherData.current.temperature_2m = current["temperature_2m"].as<float>();
// Parse daily weather data
JsonObject daily = doc["daily"];
weatherData.daily.time = daily["time"][0].as<String>();
weatherData.daily.weather_code = daily["weather_code"][0].as<int>();
weatherData.daily.temperature_2m_max = daily["temperature_2m_max"][0].as<float>();
weatherData.daily.temperature_2m_min = daily["temperature_2m_min"][0].as<float>();
weatherData.daily.sunrise = daily["sunrise"][0].as<String>();
weatherData.daily.sunset = daily["sunset"][0].as<String>();
weatherData.daily.precipitation_sum = daily["precipitation_sum"][0].as<float>();
weatherData.daily.wind_speed_10m_max = daily["wind_speed_10m_max"][0].as<float>();
weatherData.daily.wind_gusts_10m_max = daily["wind_gusts_10m_max"][0].as<float>();
https.end();
delete client; // Clean up
return weatherData; // Return the populated weather data
} else {
Serial.printf("Failed to get weather data, HTTP Code: %d\n", httpCode);
}
https.end(); // Close the connection
}
delete client; // Clean up the client if the request fails
}
return WeatherData(); // Return empty struct in case of failure
}
const unsigned char* getWeatherBitmap(int weatherCode) {
switch (weatherCode) {
case 0: // Clear Sky
return sun;
case 1: // Mainly Clear
return partialCloud;
case 2: // Partly Cloudy
return partialCloud;
case 3: // Overcast
return cloud;
case 45: // Fog
return fog;
case 48: // Depositing Rime Fog
return fog;
case 51: // Light Drizzle
return showers;
case 53: // Moderate Drizzle
return showers;
case 55: // Dense Drizzle
return rain;
case 56: // Freezing Drizzle
return hail;
case 57: // Heavy Freezing Drizzle
return hail;
case 61: // Slight Rain
return rain;
case 63: // Moderate Rain
return heavyRain;
case 65: // Heavy Rain
return heavyRain;
case 66: // Freezing Rain
return freezingRain;
case 67: // Heavy Freezing Rain
return freezingRain;
case 71: // Light Snow
return snow;
case 73: // Moderate Snow
return snow;
case 75: // Heavy Snow
return snow;
case 77: // Snow Grains
return snow;
case 80: // Rain Showers
return showers;
case 81: // Moderate Rain Showers
return showers;
case 82: // Heavy Rain Showers
return showers;
case 85: // Slight Snow Showers
return snow;
case 86: // Heavy Snow Showers
return snow;
case 95: // Thunderstorm
return hail;
case 96: // Thunderstorm with Slight Hail
return hail;
case 99: // Thunderstorm with Heavy Hail
return hail;
default:
return hail; // I need to source a default icon
}
}
const unsigned char sun [] PROGMEM = {
// 'sun, 64x64px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x01, 0x80, 0x06, 0x00, 0x00,
0x00, 0x00, 0x70, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x1c, 0x00, 0x00,
0x00, 0x00, 0x1c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x70, 0x00, 0x00,
0x00, 0x00, 0x04, 0x0f, 0xf0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0x80, 0x00, 0x00,
0x00, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x3f, 0xc3, 0xff, 0xff, 0xc3, 0xfc, 0x00,
0x00, 0x3f, 0xc3, 0xff, 0xff, 0xc3, 0xfc, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x01, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0f, 0xf0, 0x20, 0x00, 0x00,
0x00, 0x00, 0x0e, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x38, 0x00, 0x00,
0x00, 0x00, 0x38, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x0e, 0x00, 0x00,
0x00, 0x00, 0x60, 0x01, 0x80, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char freezingRain [] PROGMEM = {
// 'weather, 64x64px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xf8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x80, 0x00, 0x00,
0x00, 0x00, 0x3f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x7f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x1f, 0xfe, 0x00, 0x00,
0x00, 0x00, 0x7f, 0xe0, 0x1f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x7f, 0xc3, 0x07, 0xff, 0xc0, 0x00,
0x00, 0x00, 0x7f, 0x83, 0x83, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x7d, 0x83, 0x80, 0xff, 0xf0, 0x00,
0x00, 0x01, 0xe8, 0x1f, 0xe0, 0x0f, 0xf8, 0x00, 0x00, 0x03, 0xc0, 0x1f, 0xe0, 0x07, 0xf8, 0x00,
0x00, 0x0f, 0x80, 0x0f, 0xe2, 0x07, 0xf8, 0x00, 0x00, 0x0f, 0x81, 0x83, 0x87, 0x63, 0xfc, 0x00,
0x00, 0x1f, 0x1f, 0x83, 0x87, 0xf1, 0xfc, 0x00, 0x00, 0x1f, 0x1f, 0x83, 0x83, 0xe1, 0xfc, 0x00,
0x00, 0x3e, 0x0f, 0x83, 0x8f, 0xc3, 0xfc, 0x00, 0x00, 0x3f, 0x07, 0xe3, 0x9f, 0xc3, 0xfc, 0x00,
0x00, 0x3f, 0x8f, 0xfb, 0xfc, 0xe3, 0xf8, 0x00, 0x00, 0x3f, 0x8e, 0x7f, 0xf8, 0xc3, 0xf8, 0x00,
0x00, 0x1f, 0x80, 0x1f, 0xe0, 0x07, 0xf0, 0x00, 0x00, 0x1f, 0xc0, 0x0f, 0xe0, 0x03, 0xf0, 0x00,
0x00, 0x0f, 0x80, 0x1f, 0xf0, 0xc3, 0xe0, 0x00, 0x00, 0x0f, 0x8e, 0x7f, 0xfc, 0xe3, 0xc0, 0x00,
0x00, 0x03, 0x8f, 0xfb, 0x9f, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x87, 0xe3, 0x8f, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x0f, 0x83, 0x83, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x83, 0x83, 0xf0, 0x00, 0x00,
0x00, 0x00, 0x1f, 0xc3, 0x87, 0x20, 0x00, 0x00, 0x00, 0x00, 0x09, 0xc3, 0x83, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 0x00,
0x00, 0x01, 0x80, 0x03, 0x80, 0x00, 0x60, 0x00, 0x00, 0x03, 0x80, 0x03, 0x80, 0x00, 0x60, 0x00,
0x00, 0x07, 0x00, 0x03, 0x80, 0x00, 0xe0, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0x00,
0x00, 0x0e, 0x00, 0x00, 0x01, 0xc1, 0xc0, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x01, 0xc3, 0x80, 0x00,
0x00, 0x1c, 0x0c, 0x00, 0x03, 0x83, 0x00, 0x00, 0x00, 0x18, 0x1c, 0x0c, 0x03, 0x07, 0x00, 0x00,
0x00, 0x00, 0x18, 0x0e, 0x07, 0x06, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1c, 0x0e, 0x02, 0x00, 0x00,
0x00, 0x00, 0x70, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x38, 0x1c, 0x00, 0x00, 0x00,
0x00, 0x00, 0xe0, 0x70, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x30, 0x38, 0x00, 0x00, 0x00,
0x00, 0x01, 0xc0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x70, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char partialCloud [] PROGMEM = {
// 'upload, 64x64px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x60, 0x08, 0x00, 0x00, 0x00,
0x00, 0x03, 0x80, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x38, 0x00, 0x00, 0x00,
0x00, 0x00, 0xe0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x20, 0x00, 0x00, 0x00,
0x00, 0x00, 0x03, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf8, 0x7f, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1f, 0xf1, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xe3, 0xff, 0xe0, 0x00, 0x00,
0x00, 0x3e, 0x1f, 0xc7, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x3e, 0x1f, 0xcf, 0xff, 0xf8, 0x00, 0x00,
0x00, 0x00, 0x1f, 0xcf, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x8f, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x0f, 0x9f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x0f, 0x1f, 0xff, 0xff, 0xf0, 0x00,
0x00, 0x00, 0x06, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xf8, 0x00,
0x00, 0x00, 0x61, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0xe1, 0xff, 0xff, 0xff, 0xfc, 0x00,
0x00, 0x01, 0xc3, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x03, 0x83, 0xff, 0xff, 0xff, 0xfc, 0x00,
0x00, 0x01, 0x03, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xf8, 0x00,
0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xf0, 0x00,
0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, 0x00,
0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char showers [] PROGMEM = {
// 'cloud, 64x64px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x70, 0x04, 0x00, 0x00, 0x00,
0x00, 0x03, 0x80, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x1c, 0x00, 0x00, 0x00,
0x00, 0x00, 0xe0, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x30, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x07, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf8, 0x7e, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1f, 0xf1, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xe3, 0xff, 0xe0, 0x00, 0x00,
0x00, 0x3f, 0x1f, 0xc7, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x3f, 0x1f, 0x8f, 0xff, 0xf0, 0x00, 0x00,
0x00, 0x00, 0x1f, 0x9f, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x9f, 0xff, 0xfc, 0x00, 0x00,
0x00, 0x00, 0x0f, 0x9f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x0f, 0x1f, 0xff, 0xff, 0xe0, 0x00,
0x00, 0x00, 0x04, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xf8, 0x00,
0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x63, 0xff, 0xff, 0xff, 0xfc, 0x00,
0x00, 0x00, 0xe3, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x01, 0xc7, 0xff, 0xff, 0xff, 0xfc, 0x00,
0x00, 0x01, 0x87, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xfc, 0x00,
0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf8, 0x00,
0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xe0, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x01, 0x80, 0x00,
0x00, 0x00, 0x01, 0xc0, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x01, 0x80, 0x01, 0x83, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char cloud [] PROGMEM = {
// 'cloud(1), 64x64px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x00,
0x00, 0x00, 0x07, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x80, 0x00, 0x00,
0x00, 0x00, 0x3f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x7f, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0x80, 0x00,
0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xe0, 0x00,
0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00,
0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00,
0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00,
0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00,
0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00,
0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00,
0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00,
0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
0x00, 0x01, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char snow [] PROGMEM = {
// 'night, 64x64px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x80, 0x00, 0x00,
0x00, 0x00, 0x1f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x1f, 0xf8, 0x00, 0x00,
0x00, 0x00, 0x7f, 0xf0, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x0f, 0xff, 0xc0, 0x00,
0x00, 0x00, 0x7f, 0xc1, 0x83, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x7f, 0xc1, 0x80, 0xff, 0xf0, 0x00,
0x00, 0x00, 0xfe, 0x07, 0xe0, 0x4f, 0xf0, 0x00, 0x00, 0x03, 0xe0, 0x0f, 0xf0, 0x07, 0xf8, 0x00,
0x00, 0x07, 0xe0, 0x0f, 0xf0, 0x07, 0xf8, 0x00, 0x00, 0x0f, 0xc0, 0xc1, 0x87, 0x23, 0xf8, 0x00,
0x00, 0x1f, 0xcd, 0xc1, 0x83, 0xf1, 0xfc, 0x00, 0x00, 0x1f, 0x8f, 0xc1, 0x83, 0xf1, 0xfc, 0x00,
0x00, 0x3f, 0x8f, 0xc1, 0x87, 0xc1, 0xfc, 0x00, 0x00, 0x3f, 0x83, 0xf1, 0x8f, 0xc3, 0xf8, 0x00,
0x00, 0x3f, 0xc7, 0xfd, 0xbe, 0xe3, 0xf8, 0x00, 0x00, 0x3f, 0xc7, 0x3f, 0xf8, 0x43, 0xf8, 0x00,
0x00, 0x1f, 0xc2, 0x0f, 0xf0, 0x07, 0xf0, 0x00, 0x00, 0x1f, 0xe0, 0x07, 0xe0, 0x03, 0xf0, 0x00,
0x00, 0x0f, 0xc0, 0x0f, 0xf8, 0x43, 0xe0, 0x00, 0x00, 0x07, 0xc7, 0x3f, 0xfe, 0xe3, 0xc0, 0x00,
0x00, 0x03, 0xc7, 0xf9, 0x9f, 0xe3, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xf1, 0x87, 0xe0, 0x00, 0x00,
0x00, 0x00, 0x07, 0xc1, 0x83, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc1, 0x83, 0xf0, 0x00, 0x00,
0x00, 0x00, 0x06, 0xe1, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc1, 0x01, 0x38, 0x00,
0x00, 0x00, 0xc0, 0x0f, 0xf0, 0x03, 0xf0, 0x00, 0x00, 0x0f, 0xc0, 0x0f, 0xf0, 0x03, 0xf0, 0x00,
0x00, 0x0f, 0x80, 0x01, 0x80, 0x00, 0xf8, 0x00, 0x00, 0x07, 0xc0, 0x01, 0x80, 0x00, 0xfc, 0x00,
0x00, 0x07, 0xe0, 0x01, 0x80, 0x01, 0xd8, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x80, 0x00,
0x00, 0x06, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3e, 0x00, 0x60, 0x00,
0x00, 0x03, 0x03, 0xf0, 0x1f, 0x87, 0xe0, 0x00, 0x00, 0x1b, 0x83, 0xf0, 0x1f, 0x87, 0xe0, 0x00,
0x00, 0x3f, 0x01, 0xf0, 0x39, 0x03, 0xe0, 0x00, 0x00, 0x1f, 0x01, 0xf8, 0x00, 0x03, 0xf0, 0x00,
0x00, 0x0f, 0xc1, 0xd8, 0x00, 0x03, 0xb0, 0x00, 0x00, 0x0f, 0x81, 0x80, 0x00, 0x03, 0x00, 0x00,
0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char rain [] PROGMEM = {
// 'cloud(2), 64x64px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xfc, 0x00, 0x00, 0x00,
0x00, 0x00, 0x07, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x80, 0x00, 0x00,
0x00, 0x00, 0x3f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x7f, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0x80, 0x00,
0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xe0, 0x00,
0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00,
0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00,
0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00,
0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00,
0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00,
0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00,
0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00,
0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
0x00, 0x01, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0xe0, 0x00, 0x0c, 0x00, 0x00,
0x00, 0x03, 0x00, 0xc0, 0x0c, 0x1c, 0x00, 0x00, 0x00, 0x07, 0x00, 0x40, 0x1c, 0x38, 0x00, 0x00,
0x00, 0x02, 0x00, 0x00, 0x18, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x06, 0x00, 0x00,
0x00, 0x00, 0x38, 0x18, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10, 0x18, 0x00, 0x0c, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char hail [] PROGMEM = {
// 'weather(1), 64x64px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x07, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x80, 0x00, 0x00,
0x00, 0x00, 0x3f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x7f, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xe0, 0x00,
0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xf0, 0x00,
0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00,
0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00,
0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00,
0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00,
0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00,
0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00,
0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
0x00, 0x01, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x40, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60, 0x07, 0x00, 0x00, 0x00,
0x00, 0x00, 0xc0, 0x60, 0x0e, 0x01, 0x00, 0x00, 0x00, 0x01, 0xc0, 0xe0, 0x0c, 0x03, 0x80, 0x00,
0x00, 0x03, 0x80, 0xc0, 0x1c, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x38, 0x07, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x38, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x70, 0x0e, 0x00, 0x00,
0x00, 0x1c, 0x07, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x07, 0x00, 0x00, 0x30, 0x00, 0x00,
0x00, 0x3e, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0xc0, 0x7c, 0x00, 0x00,
0x00, 0x1c, 0x00, 0x07, 0xe0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x78, 0x00, 0x00,
0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char fog [] PROGMEM = {
// 'cloud(3), 64x64px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xf0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x80, 0x00, 0x00,
0x00, 0x00, 0x3f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x7f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00,
0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xc0, 0x00,
0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xf0, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00,
0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00,
0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00,
0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00,
0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00,
0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00,
0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00,
0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00,
0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char heavyRain [] PROGMEM = {
// 'night(1), 64x64px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x80, 0x00, 0x00,
0x00, 0x00, 0x3f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x7f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xe0, 0x00,
0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xf0, 0x00,
0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00,
0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00,
0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00,
0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00,
0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00,
0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00,
0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xf0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x40, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x60, 0xe1, 0xc3, 0x86, 0x00, 0x00,
0x00, 0x00, 0xe1, 0xc1, 0xc3, 0x0e, 0x00, 0x00, 0x00, 0x01, 0xc1, 0x83, 0x87, 0x1c, 0x00, 0x00,
0x00, 0x01, 0xc3, 0x87, 0x0e, 0x38, 0x00, 0x00, 0x00, 0x03, 0x87, 0x0e, 0x1c, 0x38, 0x00, 0x00,
0x00, 0x07, 0x0e, 0x0e, 0x1c, 0x70, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x1c, 0x38, 0x60, 0x00, 0x00,
0x00, 0x02, 0x1c, 0x38, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x30, 0xe0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x70, 0x30, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x01, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char hi [] PROGMEM = {
// 'menu-up-fill-custom, 22x22px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x78, 0x00, 0x00, 0xfc,
0x00, 0x01, 0xfe, 0x00, 0x03, 0xff, 0x00, 0x07, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00
};
const unsigned char lo [] PROGMEM = {
// 'menu-up-fill-custom, 22x22px
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x80, 0x03, 0xff, 0x00, 0x01, 0xfe,
0x00, 0x00, 0xfc, 0x00, 0x00, 0x78, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00
};
const unsigned char wind [] PROGMEM = {
// 'wind, 22x22px
0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x67, 0x00, 0x00, 0x67, 0x00, 0x00,
0x0e, 0x00, 0x0f, 0xfc, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x3f, 0xff,
0x80, 0x00, 0x07, 0xc0, 0x3f, 0x80, 0xe0, 0x3f, 0xc4, 0x60, 0x00, 0xec, 0xe0, 0x02, 0x6f, 0xc0,
0x06, 0xe7, 0x80, 0x07, 0xc0, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00
};

View File

@ -0,0 +1,64 @@
// weather.h
#ifndef WEATHER_H
#define WEATHER_H
#include "tls_certificates.h"
#include <Arduino.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
// Struct for current weather data
struct CurrentWeather {
String time; // e.g., "2024-11-26T20:30"
int interval; // e.g., 900
float temperature_2m; // e.g., 7.1°C
};
// Struct for daily weather data
struct DailyWeather {
String time; // Date as string e.g., "2024-11-26"
int weather_code; // e.g., 61 (WMO code)
float temperature_2m_max; // e.g., 10.9°C
float temperature_2m_min; // e.g., 6.5°C
String sunrise; // e.g., "2024-11-26T06:47"
String sunset; // e.g., "2024-11-26T14:59"
float precipitation_sum; // e.g., 2.3 mm
float wind_speed_10m_max; // e.g., 11.5 km/h
float wind_gusts_10m_max; // e.g., 25.6 km/h
};
// Main weather data structure
struct WeatherData {
float latitude; // e.g., 52.52
float longitude; // e.g., 13.419998
float elevation; // e.g., 38 meters
String timezone; // e.g., "Europe/London"
String timezone_abbreviation; // e.g., "GMT"
// Current weather data
CurrentWeather current;
// Daily weather data
DailyWeather daily;
};
// Bitmap Images
extern const unsigned char sun[] PROGMEM;
extern const unsigned char freezingRain[] PROGMEM;
extern const unsigned char partialCloud[] PROGMEM;
extern const unsigned char showers[] PROGMEM;
extern const unsigned char cloud[] PROGMEM;
extern const unsigned char snow[] PROGMEM;
extern const unsigned char rain[] PROGMEM;
extern const unsigned char hail[] PROGMEM;
extern const unsigned char fog[] PROGMEM;
extern const unsigned char heavyRain[] PROGMEM;
extern const unsigned char hi[] PROGMEM;
extern const unsigned char lo[] PROGMEM;
extern const unsigned char wind[] PROGMEM;
WeatherData getWeather(float latitude, float longitude);
const unsigned char* getWeatherBitmap(int weatherCode);
#endif