[feature] Add HLTH antenna health sidebar applet#3133
Conversation
Add a compact antenna health applet that tracks live SWR, return loss, and output power from the freshest active meter source. The applet includes adaptive graph scaling, variance highlighting, incident markers, click-to-pause behavior for screenshots, and explanatory label tooltips. Co-authored-by: Codex <noreply@openai.com>
There was a problem hiding this comment.
Thanks for the thoughtful applet, @jensenpat — the moving-average-centered lanes, incident markers, and source-priority cascade (AMP → TUN → RAD) all read as deliberate choices for spotting broad-variance counterpoise/ground problems, which is a real gap. Scope of the six touched files matches the stated feature. A few items worth addressing before merge:
1. Theme bypass — all colours are hardcoded. Every visible colour in HealthApplet.cpp is a literal hex (#56d8a3, #ffd066, #0x08,0x0d,0x14, severity bands, pill backgrounds, trace glows). The file #includes core/ThemeManager.h but never uses it. With Default Light theme just shipped (#3129) and the live Theme Editor in flight (#3130), this applet will look wrong under Light and won't respond to themeChanged. Sibling applets call ThemeManager::instance().resolve("... {{color.text.primary}} ...") — see TxApplet.cpp:128-166 for the pattern. For the painter-side colours (traces, severity bands, lane backgrounds), please pull from existing tokens (color.meter.bar.fill, color.accent.danger, color.background.0/1/2, etc.) and re-resolve on ThemeManager::themeChanged. If you need new tokens for the three-lane series colours and the WATCH/GROUND severity tints, that's a reasonable follow-up — but the current hardcoded path will land already-broken under Light.
2. 20 Hz timer runs unconditionally — even when the applet is hidden. The constructor calls hide() then m_tickTimer->start() at 50 ms, and appendFrame() keeps doing EWMA/stddev/severity math + a QWidget::update() on the graph every tick regardless of isVisible(). Two cheap options: gate appendFrame() on isVisible() (early-return when hidden, keep the timer cheap), or start/stop the timer in showEvent/hideEvent. The work-per-tick is small, but it runs 20×/sec forever in every session whether HLTH is active or not.
3. Duplicate amplifier path. MainWindow.cpp now calls m_appletPanel->healthApplet()->updateAmplifierMeters(watts, swr) from the PGXL connection lambda and the applet subscribes to MeterModel::ampMetersChanged in setMeterModel(). If PGXL telemetry feeds into MeterModel::ampMetersChanged (which it appears to, since MeterApplet uses the model signal), every amp update is being cached twice. Functionally last-write-wins so it isn't a bug, but pick one path. The model signal alone is cleaner and consistent with how MeterApplet consumes amp data.
4. Minor — unused <limits> include is fine, but the unused ThemeManager.h include should go (or, better, actually use it per item 1).
Nothing structurally wrong with the meter cascade, stats, or pause UX — those look solid. The theme item is the one that genuinely needs to land before merge so this doesn't become a regression on Light themes.
73
🤖 aethersdr-agent · cost: $7.2036 · model: claude-opus-4-7
Resolve the PR review concerns by moving HLTH paint and label colors to ThemeManager tokens with live theme refresh, stopping the 20 Hz applet timer while hidden or paused, and relying on MeterModel amp telemetry instead of the duplicate direct PGXL path. Co-authored-by: Codex <noreply@openai.com>
|
Claude here. The HLTH applet itself is well-built — the meter-source-priority (amp → tuner → radio TX), the EWMA-against-recent-window variance detection, the centered moving-average graphs instead of fixed scales, and the visibility-gated 20 Hz timer all read as production-ready. Particularly appreciate the theme-token migration in the latest iteration and the timer-on-show / off-hide pattern; that's exactly the right shape for a sidebar applet. There's a mechanical conflict, though, that I want to give you a head start on rather than blocking review: PR #3150 (currently open) restructures the button bar into a 5-button favorites row + push-down drawer model, and both PRs touch To avoid making you re-do work that's already correct, I've rebased your PR onto PR #3150's branch (
A couple of paths forward, your call:
Either way the HLTH applet ships — this is purely about which side absorbs the merge. Thanks for the careful work on this, especially the EWMA/recent-window variance detection. That's the kind of diagnostics that actually catches grounding issues operators would otherwise blame on the radio. 73, Jeremy KK7GWY & Claude (AI dev partner) |
|
Claude here. Quick follow-up — Jeremy asked me to go ahead with option A from my earlier comment. Pushed #3153 as the rebased version targeting PR #3150's branch. Your This is purely so the HLTH work doesn't have to wait on you doing a manual rebase after #3150 lands. Your PR (#3133) stays open as the canonical reference — happy to close ours and you do the rebase yourself if you'd prefer, or close #3133 once #3153 lands. Whichever shape you'd like the merge to take. Either path, credit stays with you on the HealthApplet commit. 73, Jeremy KK7GWY & Claude (AI dev partner) |
…n-bar refactor) Rebases @jensenpat's PR #3133 onto the customisable button-bar architecture introduced in PR #3150. HealthApplet.{h,cpp} are preserved verbatim from PR #3133; the integration changes are the delta that lets the new BarButton registry + favorites/drawer model own placement. Changes vs PR #3133 originally targeted at main: * Default placement moved from position 4 (between TX and PHNE, inside the new favorites zone) to after MTR in the drawer. Reasoning: HLTH is a diagnostic, not an every-tune control — putting it in favorites by default would push PHNE out of the 5-button favorites row and surprise shipping users. Operators who want HLTH in favorites can right-click any bar button → Favorites picker → drag HLTH up. * makeEntry() call uses m_drawer / m_drawerLayout (the new drawer layout from PR #3150), matching the convention every other drawer-resident applet now uses. * Bar-button registration is automatic via PR #3150's registerBarButton() inside makeEntry() — no manual btnRow1/2 routing needed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Claude here. Closing this in favour of #3153 — same If you'd rather take #3153 over yourself (push commits to its branch, or open a fresh PR from your fork that supersedes #3153), entirely welcome — happy to close #3153 in that case so you stay in control of your own work. Otherwise we'll merge #3153 once review wraps up and your commit attribution carries through. Either way, thanks again for the HLTH applet — the EWMA variance detection is a really nice touch. 73, Jeremy KK7GWY & Claude (AI dev partner) |
…on-bar refactor (#3153) ## Summary Rebased version of @jensenpat's #3133 onto PR #3150's customisable button-bar architecture. Same `HealthApplet.{h,cpp}` source verbatim from #3133 (zero changes to applet code) — this PR is purely the AppletPanel integration delta that adapts to PR #3150's new `BarButton` registry + favorites/drawer model. **Depends on #3150** — currently targets `fix/button-bar`. Once #3150 merges to main, this PR's base will be retargeted to main and the diff will collapse to just the HLTH integration touchpoints. ## What changed vs #3133 Three integration touchpoints adjusted; HealthApplet itself untouched: 1. **`makeEntry()` callsite** routes through `m_drawer` / `m_drawerLayout` (the new drawer layout from #3150), matching every other drawer-resident applet's pattern. PR #3150's `registerBarButton()` inside `makeEntry()` handles bar-button registration automatically — no manual `btnRow2` plumbing required. 2. **Default position** moved from index 4 (between TX and PHNE) to after MTR in the drawer: ```cpp "RX", "TUN", "AMP", "TX", "PHNE", "P/CW", "EQ", "WAVE", "TXDSP", "CAT", "DAX", "TCI", "IQ", "MTR", "HLTH", "AG", "SS" ``` With the new 5-button favorites row, putting HLTH at index 4 would push PHNE out of favorites and surprise shipping users. Operators who want HLTH up top can drag it via the right-click Favorites picker. 3. **CMakeLists.txt** — `src/gui/HealthApplet.cpp` added to `GUI_SOURCES`. ## Credit Commit attribution stays with @jensenpat as the HealthApplet author. This PR exists only so the HLTH work doesn't have to wait on the contributor doing a manual rebase after #3150 lands — they're welcome to keep #3133 open if they'd prefer to do the rebase themselves. ## Review of HLTH itself The applet code is well-built — appreciated zero hardcoded colours (every paint and stylesheet call reads from `ThemeManager`), clean paint-method separation, visibility-gated 20 Hz timer, three-tier meter source priority (amp → TGXL tuner → radio TX), and EWMA + recent-window variance detection. One small consistency note for a follow-up: HLTH uses `widget->setStyleSheet(theme.resolve(...))` (~8 sites) instead of `theme.applyStyleSheet(widget, ...)`. That's the pattern PR #3144 swept across the rest of the codebase to make widgets inspector-discoverable. A two-line conversion would let the Phase 5 inspector find HLTH labels. Tiny follow-up — not blocking this PR. ## Test plan - [x] Linux (x86_64) — builds clean against `fix/button-bar` (`cmake --build --target all`) - [ ] Live smoke: HLTH appears in the drawer after MTR; right-click bar → Favorites picker shows HLTH in Active column - [ ] Once #3150 merges, retarget base to main, confirm no further diff change 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Pat Jensen <jensenpat@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Adds a new
HLTHsidebar applet focused on antenna health while transmitting. The applet gives operators a compact, always-available view of SWR, return loss, and output power, with adaptive graphing and incident markers designed for spotting broad variance patterns that can indicate counterpoise, grounding, feedline, or matching issues.Features
HLTHapplet to the default sidebar applet order near the transmit-related controls.SWR,RL,VAR, andWATCHtransitions.IDLE,OK,WATCH,GROUND?, andPAUSED.Use Cases
Implementation Notes
HealthApplet, a compact Qt widget with its own custom graph renderer.MeterModel::txMetersChanged,MeterModel::tgxlMetersChanged, andMeterModel::ampMetersChanged.MeterModelamp telemetry as the single amplifier data path, matching the existing meter applet flow and avoiding duplicate PGXL writes.ThemeManagertokens so the applet follows Default Dark, Default Light, and live theme changes.Review Feedback Addressed
ThemeManager::themeChanged.showEvent/hideEvent, with an additional visibility guard inappendFrame().MeterModel::ampMetersChanged.Validation
env -u CPLUS_INCLUDE_PATH cmake --build build -j22./Users/patj/Desktop/AetherSDR.appdue Desktop/app bundle permissions, so the uploaded review-fix build was preserved as/Users/patj/Desktop/AetherSDR-HLTH-REVIEW-20260525-083550.appwith quarantine cleared.👨🏼💻 Generated with OpenAI Codex (GPT-5.5 Pro 4/23) and tested by @jensenpat