Skip to content

Plane radar pr#329

Open
havedill wants to merge 3 commits into
brettdottech:devfrom
havedill:plane-radar-pr
Open

Plane radar pr#329
havedill wants to merge 3 commits into
brettdottech:devfrom
havedill:plane-radar-pr

Conversation

@havedill

Copy link
Copy Markdown

Summary

Adds a Plane Radar widget that shows live nearby aircraft on the center orb and detail views on the other four orbs. Inspired by ESP32-Plane-Radar.

  • Orb 0: Radar view with range rings, aircraft positions, heading triangles, speed vectors, and beyond-range edge dots
  • Orbs 1–4: Closest aircraft detail (callsign, type, route, speed, altitude, arriving/departing hint, military/PIA/LADD flags)
  • OK button: Cycles radar range (5 / 10 / 15 / 25 mi ring presets); selection is saved in NVS
  • Incremental redraws: Refreshes without full-screen flash; detail orbs stay pinned to the same aircraft between polls
    Data sources (no API keys required):
  • ADS-B: adsb.fi opendata API
  • Routes: adsbdb.com
    Disabled by default (WIDGET_OFF) so existing builds are unchanged.

Configuration (config.h)

Add to your config.h (see config.h.template):
#define INCLUDE_PLANE_RADAR WIDGET_ON // WIDGET_ON | WIDGET_OFF | WIDGET_DISABLED
Optional overrides (defaults in config.system.h):

Define Default Description
PLANE_RADAR_LAT 48.4284 Radar center latitude
PLANE_RADAR_LON -123.3656 Radar center longitude
PLANE_RADAR_RANGE_INDEX 1 Initial range preset: 0=5 mi, 1=10 mi, 2=15 mi, 3=25 mi (inner ring label)
PLANE_RADAR_FETCH_INTERVAL_SEC 3 ADS-B poll interval (seconds)
PLANE_RADAR_CYCLE_DELAY 180 Seconds to stay on Plane Radar before widget carousel advances
PLANE_RADAR_UNITS_METRIC (undefined) Define to show range label in km; omit for miles
Example:
#define INCLUDE_PLANE_RADAR WIDGET_ON
#define PLANE_RADAR_LAT 45.4215
#define PLANE_RADAR_LON -75.6972
#define PLANE_RADAR_RANGE_INDEX 1
#define PLANE_RADAR_FETCH_INTERVAL_SEC 5
#define PLANE_RADAR_CYCLE_DELAY 180
// #define PLANE_RADAR_UNITS_METRIC

Most settings can also be changed in the web UI when web-based config is enabled (planeLat, planeLon, planeFetchSec, planeCycleSec, planeUnitsMetric, enable/disable).

havedill and others added 3 commits June 23, 2026 03:59
Port live ADS-B radar widget (orb 0 sonar display, orbs 1-4 aircraft
detail) inspired by ESP32-Plane-Radar. Fetches positions from adsb.fi;
optional route labels via adsbdb.com with rate-limited caching.

Integrates with dev branch ConfigManager (web portal toggles, lat/lon,
poll interval, carousel dwell) and INCLUDE_PLANE_RADAR widget gating.
Adds per-widget carousel delay override for longer Plane Radar dwell.

Co-authored-by: Cursor <cursoragent@cursor.com>
Erase and repaint only changed radar aircraft and detail fields, pin detail slots to callsigns, and use consistent background clears so text stays readable.

Co-authored-by: Cursor <cursoragent@cursor.com>
Track per-screen paint state so unused detail slots are initialized when fewer than four aircraft are in range.

Co-authored-by: Cursor <cursoragent@cursor.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Plane Radar widget to the firmware widget carousel, fetching live nearby aircraft via ADS-B and enriching details with route lookups, with optional per-widget carousel cycle timing.

Changes:

  • Introduces PlaneRadarWidget (radar center orb + detail orbs), including range cycling persisted to NVS.
  • Adds ADS-B (AdsbClient) and route (RouteClient) HTTP clients with lightweight caching/prefetch.
  • Extends the widget framework to support a per-widget cycle delay override, and wires the new widget into main.cpp plus configuration defaults/templates.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
firmware/src/widgets/planeradarwidget/RouteClient.h Declares route lookup + cache interface.
firmware/src/widgets/planeradarwidget/RouteClient.cpp Implements callsign normalization, caching, and adsbdb route fetch/prefetch.
firmware/src/widgets/planeradarwidget/PlaneRadarWidget.h Declares the Plane Radar widget, state, and drawing/update helpers.
firmware/src/widgets/planeradarwidget/PlaneRadarWidget.cpp Implements radar rendering, detail screens, range cycling, NVS persistence, and route refresh integration.
firmware/src/widgets/planeradarwidget/AdsbClient.h Declares ADS-B fetch API and aircraft model.
firmware/src/widgets/planeradarwidget/AdsbClient.cpp Implements ADS-B fetch + JSON parsing into a fixed-size aircraft list.
firmware/src/main.cpp Registers Plane Radar widget behind INCLUDE_PLANE_RADAR != WIDGET_DISABLED.
firmware/src/core/widget/Widget.h Adds getWidgetCyclePageDelayMs() optional override hook.
firmware/src/core/utils/MainHelper.cpp Uses per-widget cycle delay override when advancing the widget carousel.
firmware/config/config.system.h Adds default macros for enabling/configuring Plane Radar.
firmware/config/config.h.template Documents Plane Radar config knobs and enables include toggle.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +754 to +757
strncpy(out->callsign, plane.callsign, sizeof(out->callsign) - 1);
strncpy(out->desc, plane.desc[0] != '\0' ? plane.desc : plane.type, sizeof(out->desc) - 1);
RouteClient::formatRoute(plane.callsign, out->route, sizeof(out->route));
strncpy(out->alt, plane.alt, sizeof(out->alt) - 1);
Comment on lines +807 to +812
if (rank >= 0) {
buildDetailSnapshot(rank, &next);
strncpy(m_slotCallsign[slot], next.callsign, sizeof(m_slotCallsign[slot]) - 1);
} else {
m_slotCallsign[slot][0] = '\0';
}
Comment on lines +214 to +223
if (!plane["lat"].is<float>() || !plane["lon"].is<float>()) {
continue;
}
if (isOnGround(plane)) {
continue;
}

s_aircraft[n].lat = plane["lat"].as<float>();
s_aircraft[n].lon = plane["lon"].as<float>();
s_aircraft[n].noseDeg = pickNoseHeading(plane);
Comment on lines +34 to +38
void normalizeCallsign(const char *in, char *out, size_t outLen) {
out[0] = '\0';
if (outLen == 0 || in == nullptr) {
return;
}
Comment on lines +188 to +193
void offsetKmFromCenter(double centerLat, double centerLon, float lat, float lon, float *dxKm, float *dyKm,
float *distKm) {
*dxKm = static_cast<float>(lon - centerLon) * kKmPerDeg;
*dyKm = static_cast<float>(lat - centerLat) * kKmPerDeg;
*distKm = sqrtf((*dxKm) * (*dxKm) + (*dyKm) * (*dyKm));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants