Zum Hauptinhalt springen

Lifecycle

MyStation uses a multi-phase lifecycle that adapts based on the device's configuration state.

Lifecycle Diagram​

Lifecycle Phases​

There are six lifecycle states. The device usually progresses linearly through them, but can skip phases or branch based on conditions.

ON_INIT: System Initialization​

  • Initialize Serial (debug builds only)
  • Print wake-up diagnostics
  • Check for factory reset (Button 1+2 held), app reset (Button 1 held), application info (Button 2 held), or OTA update (Button 3 held)
  • Initialize e-paper display and font renderer
  • Initialize battery monitoring (ESP32-S3 boards)
  • If battery voltage is critically low (>0.1V and ≀3.0V), show error and jump to ON_SHUTDOWN
  • Load configuration from NVS (or use RTC cache after deep sleep)
  • Configure button GPIO pins and attach interrupts

ON_START: Network & Time Setup​

  • Determine configuration phase (WiFi Setup / App Setup / Complete)
  • If Phase 1 (no WiFi): start WiFi AP, block until configured, then ESP.restart()
  • Connect to WiFi. If connection fails β†’ show error, jump to ON_STOP
  • Synchronize time via NTP (if needed or periodic refresh due)
  • Handle button wakeup: set temporary display mode if woken by button press

ON_RUNNING: Operational Phase​

  • If Phase 2 (app setup needed): start configuration web server, transition to ON_LOOP
  • Check for OTA update (if scheduled time matches)
  • Fetch data from APIs (Phase 3: Complete)
    • If tripMode == true: fetch trip connections via /hapi/trip (origin β†’ destination)
    • If tripMode == false: fetch departures via /hapi/departureBoard (single stop)
  • Disconnect WiFi (saves ~100mA during display rendering)
  • Render display

ON_LOOP: Web Server Mode​

  • Serves the configuration HTTP portal
  • Runs inside setup() as an inline while-loop (not Arduino's loop())
  • Exits when configuration is saved (device enters deep sleep and restarts)

ON_STOP: Prepare for Deep Sleep​

  • Calculate next wake-up time via TimingManager::getNextSleepDurationSeconds()
  • Configure button wakeup pins for deep sleep

ON_SHUTDOWN: Enter Deep Sleep​

  • Final button-press check (restart if pressed during wake cycle)
  • Hibernate display (power off e-paper controller)
  • Enter ESP32 deep sleep with timer + button wakeup sources

Button-Interrupt-Restart Pattern​

Throughout ON_START, ON_RUNNING, and ON_SHUTDOWN, the system calls ButtonManager::checkAndRestartIfButtonPressed() at multiple points. If a button was pressed via ISR during the current wake cycle, the device calls esp_restart() to handle the button press cleanly from the beginning. This avoids complex mid-cycle state changes.

Configuration Phases​

The configuration phase is determined by DeviceModeManager::getCurrentPhase():

PhaseConditionAction
PHASE_WIFI_SETUPNo WiFi SSID storedStart WiFi AP for configuration
PHASE_APP_SETUPWiFi OK, but missing stop/locationStart web config portal
PHASE_COMPLETEAll required settings presentNormal operation

Display Mode Selection​

Display mode is determined by TimingManager::getEffectiveDisplayMode():

Temporary mode is activated by button press and lasts 2 minutes, then reverts to configured mode.

Weather Data Caching​

Weather data is cached in RTC memory. It is only re-fetched when the configured interval (default: 1-3 hours) has elapsed. Transport data is always fetched fresh on each wake cycle.

Deep Sleep Duration Calculation​

The sleep duration calculator uses a rule-based priority queue. Each rule independently proposes a wake-up time. The system picks the earliest.

Terminology​

TermMeaning
Transport windowTime range when departures are shown (e.g. 06:00–09:00)
Sleep windowTime range when the device stays in deep sleep (e.g. 22:30–05:30)
Wake candidateA proposed wake-up time from a rule

Rules​

#RuleWhen it appliesBypasses Sleep Window
1Weather updateAll modes showing weather (weather-only, half&half)No
2Transport updateInside transport window (half&half, transport-only)No
3Transport window startConfigured half&half or transport-only, currently outside windowNo
4OTA checkOTA enabledYes

Algorithm​

1. TEMPORARY MODE (early return)
β†’ If temp mode active and < 2 min elapsed: sleep remaining time
β†’ If in sleep window: sleep until sleep window ends

2. COLLECT CANDIDATES
β†’ Each rule proposes a wake-up timestamp

3. OVERDUE CHECK
β†’ If any candidate is in the past β†’ wake immediately (30s)

4. SLEEP WINDOW FILTER
β†’ Non-OTA candidates inside sleep window are pushed to sleep window end
β†’ OTA candidates bypass this filter

5. PICK EARLIEST
β†’ Minimum of all remaining candidates
β†’ Enforce 30s minimum

Display Mode Logic​

Configured ModeInside Transport WindowOutside Transport Window
Weather OnlyRule 1 (weather)Rule 1 (weather)
Half & HalfRule 1 + Rule 2 (picks earlier)Rule 1 + Rule 3 (picks earlier)
Transport OnlyRule 2 (transport)Rule 3 (next window start)

Sleep Window Handling​

When a wake candidate falls inside the sleep window:

22:00 22:30 05:30 06:00
| | SLEEP | |
| |=============| |
| β”Œβ”€β”€β”€β”€β”Όβ”€β”€β”€β”€ X ─────┼──→ pushed to 05:30
| | | |
candidate sleep start sleep end
(23:00)
  • Non-OTA candidates are pushed to sleep window end
  • OTA candidates are NOT pushed (they bypass the sleep window)
  • If already inside the sleep window, device sleeps until window ends

Examples​

7:00 AM, Half & Half mode, transport window 06:00–09:00:

  • Rule 1: weather at 10:00 (3h interval)
  • Rule 2: transport at 7:05 (5 min interval)
  • Rule 3: not applicable (already inside window)
  • β†’ Picks 7:05 (transport, earliest)

5:00 AM, Half & Half mode, transport window 06:00–09:00:

  • Rule 1: weather at 8:00 (3h interval)
  • Rule 2: not applicable (outside window)
  • Rule 3: transport window starts at 6:00
  • β†’ Picks 6:00 (transport window start, earliest)

22:00, Weather Only, sleep window 22:30–05:30:

  • Rule 1: weather at 23:00 β†’ pushed to 05:30
  • β†’ Picks 05:30

22:00, OTA at 03:00, weather at 23:00, sleep window 22:30–05:30:

  • Rule 1: weather at 23:00 β†’ pushed to 05:30
  • Rule 4: OTA at 03:00 (bypasses sleep window)
  • β†’ Picks 03:00 (OTA, earliest)

Wake-up Sources​

  1. Timer: Scheduled update interval
  2. Button EXT1: User pressed a physical button (ESP32-S3 only)
  3. Reset: Manual reset or power cycle