Xteink-X4-crosspoint-reader/src/activities/calendar/CalendarActivity.h
Chris Korhonen 50b2a37fb7 feat: Add Calendar Mode for automated e-ink calendar display
- Add CALENDAR sleep mode that bypasses /sleep/ directory to ensure calendar image displays
- Implement CalendarActivity state machine: WiFi→NTP→HTTP fetch→save to /sleep.bmp→deep sleep
- Add NTP time sync and fetch timestamp persistence in CrossPointState
- Show visual status feedback during calendar fetch ("Connecting...", "Fetching...")
- Add calendar settings UI: toggle, refresh hours (1-24h), "Test Calendar Now" action
- Fix hardware button sleep to display calendar when calendar mode enabled
- Graceful fallback: if fetch fails but cached image exists, use cached; otherwise use default screen

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-01-17 19:14:58 -05:00

48 lines
1.4 KiB
C++

#pragma once
#include "../Activity.h"
/**
* CalendarActivity - Automated calendar image fetch and display
*
* This activity is triggered on timer wake (not power button wake).
* It connects to WiFi, fetches a BMP image from a configured URL,
* saves it as the sleep screen, and returns to deep sleep.
*
* Flow:
* 1. Load saved WiFi credentials
* 2. Connect to WiFi (timeout: 30s)
* 3. HTTP GET image from configured URL (timeout: 60s)
* 4. Save image to /sleep.bmp on SD card
* 5. Render sleep screen
* 6. Schedule timer wake for next refresh
* 7. Enter deep sleep
*/
enum class CalendarState { INIT, CONNECTING_WIFI, FETCHING_IMAGE, RENDERING, ERROR };
class CalendarActivity final : public Activity {
public:
explicit CalendarActivity(GfxRenderer& renderer, MappedInputManager& mappedInput)
: Activity("Calendar", renderer, mappedInput) {}
void onEnter() override;
void loop() override;
bool preventAutoSleep() override { return true; }
bool skipLoopDelay() override { return true; }
private:
CalendarState state = CalendarState::INIT;
unsigned long stateStartTime = 0;
String errorMessage;
void startWifiConnection();
bool checkWifiConnection();
bool fetchAndSaveImage();
void handleError(const char* message);
void renderStatus(const char* status);
static constexpr unsigned long WIFI_TIMEOUT_MS = 30000;
static constexpr unsigned long HTTP_TIMEOUT_MS = 60000;
};