mirror of
https://github.com/mfactory-osaka/ESPTimeCast.git
synced 2026-04-03 03:00:24 -04:00
v1.5.0 — Action API, Physical Button & WiFi Improvements ⚡ New: Unified `/action` API: - New `/action` endpoint replaces individual `/set_*` endpoints (legacy endpoints still supported) - Device control via HTTP GET or POST: messages, brightness, navigation, timers, toggles, and more - Toggle behavior: sending a parameter without a value toggles it and jumps to the relevant mode - Explicit value behavior: sending `=0` or `=1` sets without disrupting the display - All boolean settings now controllable via API: `twelvehour`, `dayofweek`, `showdate`, `colon_blink`, `humidity`, `weatherdesc`, `units`, `countdown`, `flip`, `clock_only_dimming` - Navigation actions: `next_mode`, `prev_mode`, `go_to_mode` (by number or name) - Brightness actions: `brightness`, `brightness_up`, `brightness_down`, `display_off` - Rotation control: `enable_rotation` — freeze or resume automatic mode rotation - System actions: `save`, `restart`, `clear_message`, `language` - Timer actions: `timer`, `timer_stop`, `timer_cancel`, `timer_pause`, `timer_resume`, `timer_start`, `timer_restart` - Message aliases: `scrolltimes`, `scrolls`, `scroll_times` all accepted - `clear_message` correctly restores the persistent Web UI message 🔘 New: Physical Button Template - Optional physical button support — disabled by default, uncomment to enable - Short press: advance to next mode (customizable) - Long press (800ms): toggle display on/off (customizable) - Uses internal pull-up — no external resistor needed - Any action from the `/action` API can be assigned to either press - Full documentation and wiring guide added to README 📶 Improved: WiFi Reconnection - New exponential backoff reconnection system - Reconnect attempts: 5s → 10s → 20s → 40s → 80s → 160s → 300s (caps at 5 min) - Prevents hammering the router with rapid reconnection attempts - `WiFi.setAutoReconnect(false)` — manual backoff now handles all reconnection - ESP8266 uses `WiFi.begin(ssid, password)` for reconnection (ESP32 uses `WiFi.reconnect()`) - Logs connection loss, reconnection attempts, and successful reconnection - mDNS restarts automatically after reconnection - Weather fetch deferred briefly after reconnection to let network stabilize 🌐 ESPTimeCast Companion Extension - New browser extension available on the Chrome Web Store - Automatically detects and displays media titles from YouTube, Spotify, Prime Video, Twitch, Vimeo, Dailymotion, and SoundCloud - Control brightness, modes, and rotation directly from the popup - Cast to multiple ESPTimeCast devices simultaneously - Requires **v1.5.0 or later** (uses the new `/action` endpoint) 🎨 Font Changes - `mfactoryfont.h` is now bundled directly with the firmware following the license change - No separate font download required — the custom font is included out of the box - Basic Font has been removed — all builds now use the full `mfactoryfont.h` - All icons, weather symbols, and custom glyphs available on all installations 📜 License Change - ESPTimeCast is no longer licensed under GPL-3.0 - New license: Source-available for personal, non-commercial use only - Personal use includes home, hobby, and small non-commercial settings - Forking permitted with license retained - Commercial licensing available — contact mario.felipe.tf@gmail.com - Previous versions (v1.4.2 and earlier) remain under GPL-3.0 ### 📖 Documentation - Full API reference added to README covering all `/action` parameters - Physical button wiring guide and customization examples - WiFi reconnection behavior documented - Timer documentation added (moved from HA section to standalone section) - Chrome Extension section added to README - Legacy endpoint note added for `/set_custom_message` and `/set_brightness`
63 lines
4.0 KiB
C
63 lines
4.0 KiB
C
/*
|
|
ESPTimeCast™
|
|
|
|
Copyright (c) 2026 M-Factory
|
|
|
|
This software is source-available for personal, non-commercial use only.
|
|
It is not open source.
|
|
|
|
See LICENSE.txt for full terms.
|
|
*/
|
|
|
|
#ifndef MONTHS_LOOKUP_H
|
|
#define MONTHS_LOOKUP_H
|
|
|
|
typedef struct {
|
|
const char* lang;
|
|
const char* months[12]; // Jan to Dec
|
|
} MonthsMapping;
|
|
|
|
const MonthsMapping months_mappings[] = {
|
|
{ "af", { "jan", "feb", "mar", "apr", "mei", "jun", "jul", "aug", "sep", "okt", "nov", "des" } }, // Afrikaans
|
|
{ "cs", { "led", "uno", "bre", "dub", "kve", "cer", "cvc", "srp", "zar", "rij", "lis", "pro" } }, // Czech
|
|
{ "da", { "jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec" } }, // Danish
|
|
{ "de", { "jan", "feb", "mar", "apr", "mai", "jun", "jul", "aug", "sep", "okt", "nov", "dez" } }, // German
|
|
{ "en", { "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec" } }, // English
|
|
{ "eo", { "jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec" } }, // Esperanto
|
|
{ "es", { "ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic" } }, // Spanish
|
|
{ "et", { "jan", "veb", "mar", "apr", "mai", "jun", "jul", "aug", "sep", "okt", "nov", "det" } }, // Estonian
|
|
{ "fi", { "tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mar", "jou" } }, // Finnish
|
|
{ "fr", { "jan", "fev", "mar", "avr", "mai", "jun", "jul", "aou", "sep", "oct", "nov", "dec" } }, // French
|
|
{ "hr", { "sij", "vel", "ozu", "tra", "svi", "lip", "srp", "kol", "ruj", "lis", "stu", "pro" } }, // Croatian
|
|
{ "hu", { "jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sze", "okt", "nov", "dec" } }, // Hungarian
|
|
{ "it", { "gen", "feb", "mar", "apr", "mag", "giu", "lug", "ago", "set", "ott", "nov", "dic" } }, // Italian
|
|
{ "ga", { "ean", "fea", "mar", "aib", "bea", "mei", "iui", "lun", "mea", "dei", "sam", "nol" } }, // Irish
|
|
{ "ja", { "1 ²", "2 ²", "3 ²", "4 ²", "5 ²", "6 ²", "7 ²", "8 ²", "9 ²", "10 ²", "11 ²", "12 ²" } }, // Japanese
|
|
{ "lt", { "sau", "vas", "kov", "bal", "geg", "bir", "lie", "rug", "swe", "spa", "lap", "gru" } }, // Lithuanian
|
|
{ "lv", { "jan", "feb", "mar", "apr", "mai", "jun", "jul", "aug", "sep", "okt", "nov", "dec" } }, // Latvian
|
|
{ "nl", { "jan", "feb", "maa", "apr", "mei", "jun", "jul", "aug", "sep", "okt", "nov", "dec" } }, // Dutch
|
|
{ "no", { "jan", "feb", "mar", "apr", "mai", "jun", "jul", "aug", "sep", "okt", "nov", "des" } }, // Norwegian
|
|
{ "pl", { "sty", "lut", "mar", "kwi", "maj", "cze", "lip", "sie", "wrz", "paz", "lis", "gru" } }, // Polish
|
|
{ "pt", { "jan", "fev", "mar", "abr", "mai", "jun", "jul", "ago", "set", "out", "nov", "dez" } }, // Portuguese
|
|
{ "ro", { "ian", "feb", "mar", "apr", "mai", "iun", "iul", "aug", "sep", "oct", "nov", "dec" } }, // Romanian
|
|
{ "ru", { "ian", "feb", "mar", "apr", "mai", "iun", "iul", "aug", "sep", "oct", "noi", "dec" } }, // Russian
|
|
{ "sk", { "jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec" } }, // Slovak
|
|
{ "sl", { "jan", "feb", "mar", "apr", "maj", "jun", "jul", "avg", "sep", "okt", "nov", "dec" } }, // Slovenian
|
|
{ "sr", { "jan", "feb", "mar", "apr", "maj", "jun", "jul", "avg", "sep", "okt", "nov", "dec" } }, // Serbian
|
|
{ "sv", { "jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec" } }, // Swedish
|
|
{ "sw", { "jan", "feb", "mar", "apr", "mei", "jun", "jul", "ago", "sep", "okt", "nov", "des" } }, // Swahili
|
|
{ "tr", { "oca", "sub", "mar", "nis", "may", "haz", "tem", "agu", "eyl", "eki", "kas", "ara" } } // Turkish
|
|
};
|
|
|
|
#define MONTHS_MAPPINGS_COUNT (sizeof(months_mappings)/sizeof(months_mappings[0]))
|
|
|
|
inline const char* const* getMonthsOfYear(const char* lang) {
|
|
for (size_t i = 0; i < MONTHS_MAPPINGS_COUNT; i++) {
|
|
if (strcmp(lang, months_mappings[i].lang) == 0)
|
|
return months_mappings[i].months;
|
|
}
|
|
// fallback to English if not found
|
|
return months_mappings[4].months; // "en" is index 4
|
|
}
|
|
|
|
#endif // MONTHS_LOOKUP_H
|