Files
ESPTimeCast/ESPTimeCast_ESP8266/months_lookup.h
M-Factory 7153e11829 ESPTimeCast v1.5.0 - Action API, Physical Button & WiFi Improvements
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`
2026-03-23 13:56:58 +09:00

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