feat: Advanced Web UI Dashboard with Live Map, Route Resolution, and Dynamic Settings - #33
Conversation
|
Hardware & testing methodology: ESP32-C3 Super Mini ( Results: several real bugs, fixed locally in my integration build (not yet upstreamed): 1. Wrong board targeted — ; This PR's platformio.ini
[env:xiao_esp32c6]
platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip
board = seeed_xiao_esp32c6// This PR's config.h — different pins entirely
constexpr gpio_num_t kDisplayPinRst = GPIO_NUM_16;
constexpr gpio_num_t kDisplayPinCs = GPIO_NUM_17;
// ...Silently retargets the whole build to a Seeed XIAO ESP32C6 with different GPIO pins — incompatible with the repo's actual default board. I reverted both files to the existing 2. Build breaks on this repo's pinned Arduino core ( // route_fetcher.cpp
- #include <NetworkClientSecure.h>
+ #include <WiFiClientSecure.h>
...
- NetworkClientSecure client;
+ WiFiClientSecure client;
// web_server.cpp
- s_server = std::make_unique<WebServer>(80);
+ s_server.reset(new WebServer(80));
3. Port conflict, - s_server.reset(new WebServer(80));
+ constexpr uint16_t kDashboardPort = 8080;
+ s_server.reset(new WebServer(kDashboardPort));The new dashboard and the existing WiFiManager LAN portal (from #45) both bound port 80, racing for the socket — whichever started first won, the other became silently unreachable. 4. Crash serving the dashboard page, // Before (crashes): copies the ~18KB PROGMEM page into a fresh heap String
s_server->send(200, "text/html", kWebUiHtml);
// After: stream in 2KB chunks, bail out if the client drops or after 5s
constexpr size_t kChunkSize = 2048;
constexpr unsigned long kMaxServeMs = 5000;
const unsigned long deadline = millis() + kMaxServeMs;
const size_t total = strlen_P(kWebUiHtml);
s_server->setContentLength(total);
s_server->send(200, "text/html", "");
for (size_t sent = 0; sent < total; sent += kChunkSize) {
if (!s_server->client().connected() || millis() >= deadline) break;
const size_t n = std::min(kChunkSize, total - sent);
s_server->sendContent_P(kWebUiHtml + sent, n);
}
5. Route-lookup feature (Airport Data Mode) is not viable on this board. After several rounds of fixes — not caching transient failures as permanent, removing an over-aggressive heap gate that silently blocked every fetch attempt, adding a mutex to fully serialize TLS use against the main ADS-B fetch, and reusing the TLS client instead of rebuilding it per request — route lookups to The core dashboard (live map, aircraft table, settings save) works well once #1–#4 are fixed. Happy to share my local diffs if useful. |
Summary
This PR introduces a comprehensive, dark-themed Web UI dashboard to monitor local ADS-B airspace from a browser, fully synchronized with the physical GC9A01 radar display. It includes live interactive mapping, airline route resolution, and real-time NVS configuration updates without requiring device reboots.
Key Features
Leaflet.jsto render a responsive, dark-themed map in the browser. Planes are plotted dynamically as SVG icons rotated to match their actual heading. The heavy Haversine trigonometric distance/bearing math is offloaded directly to the browser client.RouteFetcherservice that automatically resolves cryptic ADS-B IATA codes (e.g.DEN-LGA) into full city names (e.g.Denver - New York). The data is securely cached using RTOS Semaphores to ensure thread-safety on the ESP32 without crashing the LwIP network stack.Technical Improvements
PROGMEMto drastically reduce SRAM fragmentation during early boot, preventingLovyanGFXDMA buffer allocation failures.WebServerinitialization to explicitly wait untilwifiSetupConnect()has successfully resolved an IP, completely eliminatingxQueueSemaphoreTakeboot loop crashes insideapi_msg.c./api/planesand/api/configGET/POST endpoints that serve lightweightArduinoJsonpayloads to drive the frontend.