Skip to content

connectivity

Wouter Van de Wiele edited this page Aug 6, 2026 · 2 revisions

Connectivity — WiFi, WebFetcher, Time

WiFi provisioning (WifiDriver, lib/WIFI_DRIVER/)

Thin wrapper around WiFiManager in non-blocking mode:

  • On boot, tries stored credentials; if none/failed, starts the captive-portal AP (ROCAT-xxxx). wifi.process() is pumped from loop().
  • reset() (menu: Forget WiFi) erases credentials and restarts the portal.
  • start_portal() / stop_portal() allow manual control (menu: WiFi Setup).

Guided setup on the LCD (WifiSetupElement)

stateDiagram-v2
    [*] --> AP_QR: not connected
    AP_QR --> PORTAL_QR: a client joined the AP
    PORTAL_QR --> AP_QR: client left
    AP_QR --> CONNECTED: WiFi up
    PORTAL_QR --> CONNECTED: WiFi up
    CONNECTED --> [*]: auto-close after 2.5 s
Loading
  • AP_QR: QR encoding WIFI:S:<ap>;T:nopass;; — scan to join the setup AP.
  • PORTAL_QR: QR for http://192.168.4.1 — the WiFiManager portal where the user picks their home network.
  • CONNECTED: checkmark + SSID, then returns to the previous screen.

IpQrElement (menu: Show IP) shows a QR of the device's LAN IP/URL so the dashboard can be opened by scanning.

WebFetcher (lib/WEB_FETCHER/)

Single background task + FreeRTOS queue (depth 4) that serializes all outbound HTTP, so only one TLS session/buffer set ever exists (RAM). Job types: WEATHER, NTP_SYNC, GEO_ONLY.

News/RSS is currently dead code, not a live feature: NEWS is commented out of the FetchJob enum, _doNews()/requestNewsIfStale() are commented out in web_fetcher.cpp, there is no NewsElement class anywhere in the repo, and lib/RssFeed/ ships only as an unbuilt RssFeed.zip (same pattern as lib/GUI_News/News.zip). NvsStore still stores/seeds a default RSS feed and the dashboard's rss_add/rss_remove handlers exist in source but are #if 0'd out — nothing currently reads or writes that data at runtime.

flowchart LR
    subgraph Requesters
        WEl[WeatherElement fetch]
        TM[TimeManager update]
    end
    Q[[queue, len 4]]
    WEl & TM --> Q
    Q --> T[webfetcher task]
    T --> W[Open-Meteo API]
    T --> G[ip-api.com geolocation]
    T --> NTP[SNTP]
    T --> SLOTS[WeatherSlot / GeoSlot + Blackboard GEO]
Loading
  • Staleness gating: requestWeatherIfStale() (default 1 h) — carousel elements call this instead of unconditional fetches.
  • Weather cache: last weather+location persisted as one NVS blob (wx_cache) so a reboot shows data immediately; the stored age counts toward staleness.
  • Geo: fetched once per boot when WiFi connects (GEO_ONLY from TimeManager::update()); fills Topic::GEO (lat/lon/city/timezone/…) used by weather fetches and timezone auto-config.

Data providers

Service Library Data
Open-Meteo lib/OpenMeteo/ temperature, humidity, wind, weather code, precipitation, pressure, is_day
ip-api.com lib/IPGeo/ lat/lon, city, region, country, zip, IANA timezone, UTC offset
RSS (disabled — see note above) lib/RssFeed/ (unbuilt .zip) NVS still holds up to 10 feed URLs but nothing fetches/parses them

Time (TimeManager, lib/TIME_MANAGER/)

The PCF8523 external RTC is the single source of truthnow() always reads the chip. NTP and manual setting both write into the RTC.

flowchart TD
    NVS[(NVS: ntp_srv, tz)] --> TM[TimeManager.begin]
    TM -->|setenv TZ + tzset| SYS[libc localtime]
    WIFI[WiFi connected] -->|one-shot| GEO[GEO_ONLY job]
    GEO -->|IANA tz| MAP[IANA→POSIX lookup table ~45 zones]
    MAP -->|setTimezone| NVS
    WIFI -->|one-shot, only if ntp_srv set| NTP[NTP_SYNC job]
    NTP -->|localtime result| RTC[(PCF8523)]
    MENU[Menu Set Time / dashboard set_time] --> RTC
    RTC -->|1 Hz read in loop| BB[Blackboard RTC_TIME]
Loading

Key behaviors:

  • Timezone is stored as a POSIX TZ string (default CET-1CEST,M3.5.0,M10.5.0/3). Geo auto-config maps the detected IANA zone through a built-in ~45-entry table; a zone that isn't in the table does not get left alone — it falls back to a computed numeric-offset POSIX string (e.g. <UTC+2>-2) built from the geolocation's UTC offset, and that still overwrites the stored timezone.
  • NTP is one-shot per boot (no periodic re-sync); requestSync() (dashboard ntp_sync command) can re-trigger it manually. Default server pool.ntp.org (NVS ntp_srv).
  • Daily alarm lives in the PCF8523 (day=0 = every day). Enable/disable and time are set from the menu or survive power-off inside the RTC chip — the alarm INT1 line powers the device back on (see Power).
  • All state is guarded by a recursive mutex — the dashboard's httpd task calls setters concurrently with loop().

Clone this wiki locally