From a702f2f9aa46adfdea409532a3a211b6ae3a55da Mon Sep 17 00:00:00 2001 From: Fred Boniface Date: Wed, 27 Nov 2024 13:30:54 +0000 Subject: [PATCH] Random work --- NewDisplayDriver/esphub/bitmap.cpp | 35 -- NewDisplayDriver/esphub/config_loader.h | 8 + NewDisplayDriver/esphub/esphub.ino | 260 +++++++++- NewDisplayDriver/esphub/helper_fn.cpp | 69 +++ NewDisplayDriver/esphub/helper_fn.h | 14 + NewDisplayDriver/esphub/tls_certificates.h | 38 ++ NewDisplayDriver/esphub/weather.cpp | 536 +++++++++++++++++++++ NewDisplayDriver/esphub/weather.h | 64 +++ 8 files changed, 975 insertions(+), 49 deletions(-) create mode 100644 NewDisplayDriver/esphub/helper_fn.cpp create mode 100644 NewDisplayDriver/esphub/helper_fn.h create mode 100644 NewDisplayDriver/esphub/tls_certificates.h create mode 100644 NewDisplayDriver/esphub/weather.cpp create mode 100644 NewDisplayDriver/esphub/weather.h diff --git a/NewDisplayDriver/esphub/bitmap.cpp b/NewDisplayDriver/esphub/bitmap.cpp index bbee0f2..7396896 100644 --- a/NewDisplayDriver/esphub/bitmap.cpp +++ b/NewDisplayDriver/esphub/bitmap.cpp @@ -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 -}; \ No newline at end of file diff --git a/NewDisplayDriver/esphub/config_loader.h b/NewDisplayDriver/esphub/config_loader.h index 4e1836c..f77f389 100644 --- a/NewDisplayDriver/esphub/config_loader.h +++ b/NewDisplayDriver/esphub/config_loader.h @@ -19,6 +19,14 @@ struct Config { String ncUrl; }; +// Active Features +struct ActiveFeatures { + bool network; + bool homeassistant; + bool calendar; + bool weather; +}; + Config loadConfig(); #endif \ No newline at end of file diff --git a/NewDisplayDriver/esphub/esphub.ino b/NewDisplayDriver/esphub/esphub.ino index 8a6f8e9..cbb5948 100644 --- a/NewDisplayDriver/esphub/esphub.ino +++ b/NewDisplayDriver/esphub/esphub.ino @@ -35,17 +35,28 @@ SPIClass hspi(HSPI); // #include "bitmap.h" #include "config_loader.h" +#include "weather.h" +#include "helper_fn.h" // #include +#include +#include +#include +#include // #include +#include #include #include +#include "tls_certificates.h" +#include // 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(); + 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() {} diff --git a/NewDisplayDriver/esphub/helper_fn.cpp b/NewDisplayDriver/esphub/helper_fn.cpp new file mode 100644 index 0000000..6156d70 --- /dev/null +++ b/NewDisplayDriver/esphub/helper_fn.cpp @@ -0,0 +1,69 @@ +#include "helper_fn.h" +#include +#include + +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 +} \ No newline at end of file diff --git a/NewDisplayDriver/esphub/helper_fn.h b/NewDisplayDriver/esphub/helper_fn.h new file mode 100644 index 0000000..edf30c5 --- /dev/null +++ b/NewDisplayDriver/esphub/helper_fn.h @@ -0,0 +1,14 @@ +#ifndef HELPER_FN_H +#define HELPER_FN_H + +#include + +struct NotableDay { + int month; + int day; + String notableDays[5]; +}; + +String getNotableDay(int month, int day); + +#endif \ No newline at end of file diff --git a/NewDisplayDriver/esphub/tls_certificates.h b/NewDisplayDriver/esphub/tls_certificates.h new file mode 100644 index 0000000..81e29d7 --- /dev/null +++ b/NewDisplayDriver/esphub/tls_certificates.h @@ -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 \ No newline at end of file diff --git a/NewDisplayDriver/esphub/weather.cpp b/NewDisplayDriver/esphub/weather.cpp new file mode 100644 index 0000000..0a25ec3 --- /dev/null +++ b/NewDisplayDriver/esphub/weather.cpp @@ -0,0 +1,536 @@ +#include "weather.h" +#include "tls_certificates.h" +#include +#include +#include + +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 += "¤t=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(); + weatherData.longitude = doc["longitude"].as(); + weatherData.elevation = doc["elevation"].as(); + weatherData.timezone = doc["timezone"].as(); + weatherData.timezone_abbreviation = doc["timezone_abbreviation"].as(); + + // Parse current weather data + JsonObject current = doc["current"]; + weatherData.current.time = current["time"].as(); + weatherData.current.interval = current["interval"].as(); + weatherData.current.temperature_2m = current["temperature_2m"].as(); + + // Parse daily weather data + JsonObject daily = doc["daily"]; + weatherData.daily.time = daily["time"][0].as(); + weatherData.daily.weather_code = daily["weather_code"][0].as(); + weatherData.daily.temperature_2m_max = daily["temperature_2m_max"][0].as(); + weatherData.daily.temperature_2m_min = daily["temperature_2m_min"][0].as(); + weatherData.daily.sunrise = daily["sunrise"][0].as(); + weatherData.daily.sunset = daily["sunset"][0].as(); + weatherData.daily.precipitation_sum = daily["precipitation_sum"][0].as(); + weatherData.daily.wind_speed_10m_max = daily["wind_speed_10m_max"][0].as(); + weatherData.daily.wind_gusts_10m_max = daily["wind_gusts_10m_max"][0].as(); + + 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 +}; \ No newline at end of file diff --git a/NewDisplayDriver/esphub/weather.h b/NewDisplayDriver/esphub/weather.h new file mode 100644 index 0000000..8681893 --- /dev/null +++ b/NewDisplayDriver/esphub/weather.h @@ -0,0 +1,64 @@ +// weather.h +#ifndef WEATHER_H +#define WEATHER_H + +#include "tls_certificates.h" +#include +#include +#include +#include + +// 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 \ No newline at end of file