add nerdy weather messages and display brightness

This commit is contained in:
Tomislav Kopić 2024-11-11 19:50:50 +01:00
parent 86d5bcc729
commit 215d412778
2 changed files with 117 additions and 13 deletions

View File

@ -11,6 +11,7 @@
[env:d1_mini_lite] [env:d1_mini_lite]
platform = espressif8266 platform = espressif8266
board = d1_mini_lite board = d1_mini_lite
; board_build.f_cpu = 160000000L
framework = arduino framework = arduino
lib_deps = lib_deps =
bblanchon/ArduinoJson@^7.2.0 bblanchon/ArduinoJson@^7.2.0

View File

@ -23,12 +23,6 @@ NTPClient timeClient(ntpUDP, "pool.ntp.org", 3600, 43200000);
const String Location = LOCATION; const String Location = LOCATION;
const String API_Key = API_KEY; const String API_Key = API_KEY;
void capitalizeFirstLetter(char* str) {
if (str != nullptr && *str != '\0') {
str[0] = toupper(str[0]);
}
}
void beep(int buzz) { void beep(int buzz) {
tone(PIN_BUZZER, buzz, 100); tone(PIN_BUZZER, buzz, 100);
delay(100); delay(100);
@ -43,7 +37,7 @@ void initSystems() {
pinMode(LED_BUILTIN, OUTPUT); pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH); digitalWrite(LED_BUILTIN, HIGH);
Wire.begin(); // Initialize I2C Wire.begin(); // Initialize I2C
Wire.setClock(400000); // Set I2C to Fast Mode (400 kHz) Wire.setClock(400000L); // Set I2C to Fast Mode (400 kHz)
// Initialize the SSD1306 display // Initialize the SSD1306 display
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Adjust I2C address if needed if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Adjust I2C address if needed
@ -64,8 +58,8 @@ void initSystems() {
// Timers for dynamic updates // Timers for dynamic updates
unsigned long lastWeatherUpdate = 0; unsigned long lastWeatherUpdate = 0;
unsigned long lastDisplayOverride = 0; unsigned long lastDisplayOverride = 0;
const unsigned long weatherUpdateInterval = 1800000; // 30 minutes in milliseconds const unsigned long weatherUpdateInterval = 2700000; // 45 minutes in milliseconds
const unsigned long displayOverrideTimeout = 60000; // 1 minute in milliseconds const unsigned long displayOverrideTimeout = 1200000; // 2 minutes in milliseconds
bool is_display_off = false; bool is_display_off = false;
bool display_override = false; bool display_override = false;
@ -141,6 +135,7 @@ void commonButtonHandler() {
if (!middleBeeped) { if (!middleBeeped) {
beep(1000); // Play beep sound beep(1000); // Play beep sound
middleBeeped = true; // Set beeped state middleBeeped = true; // Set beeped state
lastWeatherUpdate += weatherUpdateInterval;
// Handle middle long press action here // Handle middle long press action here
} }
} }
@ -179,6 +174,11 @@ float wind_speed;
int forecastIcons[3]; int forecastIcons[3];
int currentYear, currentMonth, currentDay; int currentYear, currentMonth, currentDay;
// Function to get a random message from an array
String getRandomMessage(const String messages[], int size) {
return messages[random(size)];
}
bool fetchWeatherData() { bool fetchWeatherData() {
// Get current time // Get current time
time_t epochTime = timeClient.getEpochTime(); time_t epochTime = timeClient.getEpochTime();
@ -199,8 +199,110 @@ bool fetchWeatherData() {
if (!deserializeJson(doc, payload)) { if (!deserializeJson(doc, payload)) {
String mainWeather = doc["weather"][0]["main"].as<String>(); String mainWeather = doc["weather"][0]["main"].as<String>();
String description = doc["weather"][0]["description"].as<String>(); String description = doc["weather"][0]["description"].as<String>();
capitalizeFirstLetter(const_cast<char*>(description.c_str()));
weatherState = mainWeather + " " + description; // Define 10 messages for each weather condition
if (mainWeather == "Clear") {
String clearMessages[] = {
"Solar intensity optimal. Prepare for a day of high visibility.",
"Sky is clear, perfect for horizon scanning protocols.",
"Bright skies detected. Enjoy the solar boost!",
"All systems go. Solar power at full capacity.",
"Clear skies engaged. Optimal light detected for maximum efficiency.",
"Visibility: crystal-clear. Time to explore the open landscape.",
"Atmospheric clarity confirmed. Solar shields inactive.",
"The sky is pristine. Energy absorption at max.",
"Clear skies overhead. Pathfinding ideal for visual systems.",
"No obstructions above. Horizon detection is in prime mode."
};
weatherState = getRandomMessage(clearMessages, 10);
} else if (mainWeather == "Clouds") {
String cloudMessages[] = {
"Cloud cover detected. Sky shield engaged for mild solar filtering.",
"Overcast overhead. Perfect ambiance for low-light operations.",
"Clouds in the atmosphere. System monitoring for breaks in cover.",
"Skies are shaded - ideal for thermal conservation.",
"Cloud barrier active. Solar input reduced for optimal temperature.",
"Cloud density increasing. Adjusting light sensitivity.",
"Partial shade above. Charging might be slower.",
"A mild cover blankets the sky. Solar intake downscaled.",
"Gray layers up high. Vision systems compensating.",
"Cloudscape in progress. Ideal time for internal diagnostics."
};
weatherState = getRandomMessage(cloudMessages, 10);
} else if (mainWeather == "Rain") {
String rainMessages[] = {
"Precipitation incoming. Deploy waterproof systems if venturing outside.",
"Raindrops detected. External surfaces advised to stay dry.",
"Rain detected. Surface moisture levels increasing rapidly.",
"Incoming rainstorm - caution advised for all outdoor units.",
"Prepare for water influx. Systems on standby for slippery terrain.",
"Moisture levels spiking. External sensors on alert.",
"Rainfall in progress. Hydration of external units possible.",
"Drips from the sky. Activate surface protection measures.",
"Rain warning: path may be slippery. Engage traction mode.",
"Rain detected. Outdoor activity may face hydration challenges."
};
weatherState = getRandomMessage(rainMessages, 10);
} else if (mainWeather == "Drizzle") {
String drizzleMessages[] = {
"Micro-droplets detected. Light atmospheric moisture active.",
"Atmosphere in drizzle mode. Surface wetting minimal.",
"Drizzle detected: gentle hydration for the surroundings.",
"Light rain mode activated - atmospheric refresh in progress.",
"Tiny droplets detected. Surroundings entering gentle wet mode.",
"Drizzle overhead. Water levels rising at a slow pace.",
"Mist-level rain. Surface dampness increasing slightly.",
"Fine mist in the air. Slight hydration for surfaces detected.",
"Low-intensity rain. Cooling effect minimal.",
"Drizzle detected. Perfect time for a smooth power cycle."
};
weatherState = getRandomMessage(drizzleMessages, 10);
} else if (mainWeather == "Thunderstorm") {
String thunderstormMessages[] = {
"Warning: Electrical storm approaching. Secure sensitive devices.",
"Severe storm alert. Brace for lightning and thunder activity.",
"System warning: Thunderstorm detected. High voltage hazard active.",
"Thunderstorm detected. Power up shields and secure electronics.",
"Electrical interference detected - storm protocol activated.",
"Heavy storm active. Electrical currents elevated.",
"Thunder and lightning detected. External energy sensors triggered.",
"Storm intensity rising. Secure pathways advised.",
"High-energy weather detected. Storm protection measures on.",
"Electrical storm in progress. Surge protection engaged."
};
weatherState = getRandomMessage(thunderstormMessages, 10);
} else if (mainWeather == "Snow") {
String snowMessages[] = {
"Cryo-precipitation alert: Snowfall active. Surface stability may be reduced.",
"Snowfall detected. Thermal insulation advised for all systems.",
"Cryogenic conditions active. Snow accumulation possible.",
"System temperature cooling due to snowfall. Low-traction alert.",
"External temperature dropping rapidly. Snow detected - proceed cautiously.",
"Icy precipitation confirmed. Outdoor conditions less stable.",
"Snow alert: Prepare for reduced surface traction.",
"Snow detected. Temperature protocols active.",
"Heavy snow warning: Surface coating likely.",
"Snowfall registered. External mobility may be impacted."
};
weatherState = getRandomMessage(snowMessages, 10);
} else if (mainWeather == "Mist" || mainWeather == "Fog") {
String mistMessages[] = {
"Low-visibility alert: Mist/fog detected. Navigation systems advised.",
"Foggy conditions active - visibility restricted, adjust pathfinding.",
"Atmospheric opacity high mist encountered. Slow travel recommended.",
"Dense mist detected. Sensor accuracy may be affected.",
"Atmosphere shrouded in mist. Low-visibility protocols recommended.",
"Fog cover detected. Vision range significantly reduced.",
"High density fog. Calibrate sensors for low-light conditions.",
"Environmental opacity increased. Proceed with caution.",
"Fog barrier detected. Slow-moving navigation optimal.",
"Mist detected - navigating carefully for minimal interference."
};
weatherState = getRandomMessage(mistMessages, 10);
} else {
weatherState = "Atmospheric anomaly detected: " + description + ". Monitoring closely.";
}
temperature = doc["main"]["temp"].as<float>() - 273.15; temperature = doc["main"]["temp"].as<float>() - 273.15;
humidity = doc["main"]["humidity"]; humidity = doc["main"]["humidity"];
pressure = doc["main"]["pressure"].as<float>() / 1000; pressure = doc["main"]["pressure"].as<float>() / 1000;
@ -245,7 +347,7 @@ bool fetchWeatherData() {
int scrollPos = SCREEN_WIDTH; // Global variable to keep track of the scroll position int scrollPos = SCREEN_WIDTH; // Global variable to keep track of the scroll position
unsigned long lastScrollTime = 0; // To control the scroll speed unsigned long lastScrollTime = 0; // To control the scroll speed
const int scrollDelay = 30; // Delay in milliseconds between scroll updates const int scrollDelay = 100; // Delay in milliseconds between scroll updates
void displayWeatherData() { void displayWeatherData() {
display.clearDisplay(); display.clearDisplay();
@ -264,13 +366,14 @@ void displayWeatherData() {
if (!is_display_off) { if (!is_display_off) {
if (millis() - lastScrollTime > scrollDelay) { if (millis() - lastScrollTime > scrollDelay) {
// Update scroll position // Update scroll position
scrollPos -= 1; // Move left by 1 pixel each time scrollPos -= 6; // Move left by 1 pixel each time
lastScrollTime = millis(); lastScrollTime = millis();
// If the text has completely scrolled off, reset scroll position to start from the right // If the text has completely scrolled off, reset scroll position to start from the right
if (scrollPos < -stateWidth) { if (scrollPos < -stateWidth) {
scrollPos = SCREEN_WIDTH; scrollPos = SCREEN_WIDTH;
delay(3000);
} }
} }
} }