Skip to content

feat(tgxl): SSDR-parity PWR/SWR display in TunerApplet#3276

Closed
chibondking wants to merge 2 commits into
aethersdr:mainfrom
chibondking:feat/tgxl-parity-telemetry
Closed

feat(tgxl): SSDR-parity PWR/SWR display in TunerApplet#3276
chibondking wants to merge 2 commits into
aethersdr:mainfrom
chibondking:feat/tgxl-parity-telemetry

Conversation

@chibondking

@chibondking chibondking commented May 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

Brings the TGXL (Tuner Genius XL) applet's PWR/SWR display to parity with SmartSDR.

What changed

  • External row labels — PWR and SWR labels now live to the left of their bargauges (72 px fixed width) and carry live numeric values: PWR 987, SWR 1.2:1. Internal gauge label is empty, matching the PGXL applet layout.
  • Slow-release fwd-power ballistics — fwd gauge uses {30 ms attack / 800 ms release} so the bar rises quickly on RF bursts and decays slowly, matching SmartSDR behaviour.
  • Threshold gating — values are only shown when forward power ≥ 5 W; at idle the labels read PWR / SWR with no noisy floor reading.
  • 800 ms hold on label clear — instead of a polling timer (which caused blinking against the TGXL's slower/irregular update cadence), labels update synchronously on each meter event and are held visible for 800 ms after power drops below threshold, eliminating flicker.
  • HGauge::setBallistics() — added as a public API so individual gauges can opt into custom attack/release curves without subclassing.

What's remaining / deferred

  • Secondary temperature display for TGXL (no temp field in TGXL protocol; N/A for this device)
  • PGXL secondary temp (tempb / compound temp field) — requires pcap analysis to confirm exact key name

Test plan

  • Transmit with barefoot radio — PWR and SWR appear and hold during TX, blank ~800 ms after TX ends
  • Confirm no blink/flicker at threshold
  • Verify fwd gauge decays slowly after TX (800 ms tail visible)
  • Relay bars (C1 / L / C2) still update normally
  • TUNE / OPERATE / BYPASS / STANDBY buttons unaffected

🤖 Generated with Claude Code

Mirrors the PGXL applet improvements for the TGXL tuner:
- External "PWR" / "SWR" row labels with live numeric values
  ("PWR 987", "SWR 1.2:1") replacing the centred internal gauge labels
- Values suppressed at idle (< 5 W) to avoid noise-floor clutter
- Label text throttled to 10 Hz via QTimer (kMeterReadoutUpdateMs);
  bargraph fill continues to animate at full frame rate
- Fwd-power gauge uses 30 ms attack / 800 ms release ballistics so
  brief RF bursts remain visible for ~0.8 s after key-up
- HGauge::setBallistics() added (public setter for MeterSmoother
  ballistics, same change present in feat/pgxl-parity-telemetry)

Principle I (display parity with SmartSDR reference).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@chibondking chibondking requested a review from a team as a code owner May 29, 2026 18:48
…hold

The per-tick timer was causing PWR/SWR text to blink visibly because
TGXL meter updates arrive at a slower, irregular cadence — values
oscillated around the 5 W gate on nearly every timer firing.

Replace the polling timer with a synchronous call to updateValueLabels()
directly from updateMeters().  Add an 800 ms single-shot hold timer so
the label stays visible after power drops below threshold; inter-packet
noise below 5 W no longer causes flicker.  Principle XI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@chibondking chibondking self-assigned this May 29, 2026
@chibondking chibondking added the aetherclaude-eligible Issue approved for AetherClaude automated agent label May 29, 2026
@chibondking

Copy link
Copy Markdown
Collaborator Author

@AetherClaude your thoughts?

@aethersdr-agent

Copy link
Copy Markdown
Contributor

Reviewed the diff against HGauge.h, TunerApplet.{h,cpp}, and the existing PGXL/Aurora scale switching. Overall this is a clean, well-targeted change — happy to see the SmartSDR-parity layout land.

A few notes:

Strong choices

  • Synchronous updateValueLabels() from updateMeters() instead of a polling timer is exactly right for the TGXL's irregular cadence. Anchoring the hold to the last "above-threshold" event eliminates the polling race entirely.
  • HGauge::setBallistics() is a nice minimal addition. The existing setReversed() at HGauge.h:90-102 already round-trips through m_smooth.{ballistics,setBallistics}, so exposing it publicly is consistent — no subclassing tax, no surprises.
  • 5 W threshold + 800 ms release on the fwd gauge (30 ms attack) gives the bar a believable PEP-style decay without painting noise into the label.

Worth verifying

  1. 72 px label width at PGXL full-scale. With setPowerScale(maxWatts, true) the gauge goes to 0–2000 W, so the label can read PWR 2000 — 9 chars at 10 px bold. Should fit, but worth eyeballing once on the PGXL path so a four-digit reading doesn't get elided to PWR 200…. If it's tight, bumping to 80 px (or using setMinimumWidth instead of setFixedWidth) costs nothing.
  2. m_labelClearTimer re-entrancy on TUNE. During the 400 ms m_postTuneTimer capture window, fwd power is typically very low — make sure the label hold doesn't cause stale PWR <last> to overlap with the TUNE button's SWR x.xx confirmation in a confusing way. Probably a non-issue since the readouts live in different widgets, but worth a quick visual check during the test plan's BYPASS→TUNE→OPERATE cycle.
  3. Threshold below 5 W on the 200 W gauge: at idle key-up some radios can leak a watt or two of carrier hangover. Threshold of 5 W is conservative enough that this shouldn't matter, but if you ever see the label briefly flash during PTT release on a barefoot rig, the cause is here.

Nit

  • TunerApplet.cpp:12-14 lost the blank line between #include "core/ThemeManager.h" and namespace AetherSDR {. Easy to fold back in.

Re: the deferred items — agreed on punting TGXL temp (the protocol genuinely doesn't carry it) and on holding PGXL tempb/compound temp until pcap confirms the key name. Better to land this parity work first than to guess at field names.

LGTM pending the 72 px sanity check on PGXL.

73, Jeremy KK7GWY & Claude (AI dev partner)


🤖 aethersdr-agent · cost: $1.5885 · model: claude-opus-4-7

@chibondking

Copy link
Copy Markdown
Collaborator Author

@AetherClaude
Screenshot 2026-05-29 141059

@aethersdr-agent

Copy link
Copy Markdown
Contributor

Screenshot looks right — the left-anchored PWR <int> / SWR <x.x>:1 row labels with the bars to their right is exactly the SmartSDR layout, and the proportions match the PGXL applet. A few specific things I can read off the visual against the diff:

What checks out

  • m_pwrLabel/m_swrLabel at setFixedWidth(72) lines up cleanly with the bar left edges in the shot — no visible truncation on the displayed value, and the bar widths look consistent between the PWR and SWR rows. Good.
  • Internal gauge labels are empty (HGauge(..., "", "", ...) at both call sites) and the bar interior is unobstructed in the screenshot — matches the PGXL applet convention.
  • The setBallistics({0.030f, 0.800f}) slow-release behavior isn't visible in a still frame, but the 30 ms attack / 800 ms release ratio is consistent with SmartSDR's PEP-style fwd decay. That'll be visible in motion during the test plan's TX cycle.

Still worth eyeballing in motion (no change requested, just things the screenshot can't show):

  1. PGXL 0–2000 W path. The barefoot screenshot doesn't exercise the four-digit case. PWR 2000 is 10 chars × 10 px bold ≈ 60–62 px including the double-space — fits 72 px, but only just. If you ever see clipping during PGXL TX, this is the spot.
  2. m_labelClearTimer vs. TUNE capture. During the 400 ms m_postTuneTimer window the m_tuneBtn text gets set to SWR x.xx (TunerApplet.cpp:35 and the post-tune capture branch). That readout lives in a different widget than m_swrLabel, so the 800 ms hold on the row label and the TUNE-button confirmation should coexist fine — but the BYPASS→TUNE→OPERATE cycle in the test plan is the right place to confirm no visually-confusing overlap.

One small nit still present in the diff (TunerApplet.cpp:12-13):

 #include "core/ThemeManager.h"
-
 namespace AetherSDR {

The blank line between the last include and the namespace got eaten. Trivial to restore — purely a style consistency thing with the rest of the file. Not blocking.

Overall LGTM. The HGauge::setBallistics() API is clean (parallel to how setReversed() round-trips through m_smooth.ballistics()), the synchronous-update + hold-window design avoids the polling/blink trap, and the layout matches SmartSDR. Ready to land once the test plan checkboxes are exercised on a real radio.

A maintainer can authorize the orchestrator to land the blank-line nit by adding the aetherclaude-eligible label, but honestly it's small enough to fold into the next change in this file rather than spinning a separate PR.

73, Jeremy KK7GWY & Claude (AI dev partner)


🤖 aethersdr-agent · cost: $2.8814 · model: claude-opus-4-7

@chibondking

Copy link
Copy Markdown
Collaborator Author

Superseded by #3277 which consolidates PGXL and TGXL applet metering into one PR.

jensenpat pushed a commit that referenced this pull request May 31, 2026
…3277)

## Summary

Consolidates PGXL and TGXL applet metering improvements into one PR.
Closes #3276 and the PGXL applet PR.

### PGXL (Amplifier applet)

- **External row labels** — PWR, SWR, and Id labels left-aligned at 72
px carry live numeric values (`PWR 933`, `SWR 1.2:1`, `Id 25`); internal
gauge labels cleared
- **Id bargraph** — new drain-current gauge (0–70 A, red > 60 A) with
label row matching SSDR layout
- **Bottom info row** — temperature, Vdd, and Vac values displayed in
the empty space left of the OPERATE button
- **Slow-release fwd-power ballistics** — `{30 ms attack / 800 ms
release}` on fwd gauge so brief TX bursts stay visible
- **100 ms label throttle** — value labels update at 10 Hz via QTimer;
gauge fill animates at full rate
- **S-push parser fix** — `PgxlConnection` was silently dropping S-push
messages whose KV string began directly with `key=value` (no prefix
word); fixed with a conditional instead of an early return
- **Telemetry field fixes** — `tempb`, `vdd`, and compound `temp`
(`"34.5/28.1"`) now handled in both direct-TCP and radio-proxy data
paths

### TGXL (Tuner applet)

- **External row labels** — same 72 px PWR/SWR label pattern as PGXL
- **Slow-release fwd-power ballistics** — same `{30 ms / 800 ms}`
profile
- **Label update strategy** — synchronous update on each meter event (no
polling timer) with an 800 ms single-shot hold so inter-packet noise
below 5 W doesn't cause flicker

### Shared

- **`HGauge::setBallistics()`** — added as public API so individual
gauges can opt into custom attack/release curves

### Deferred

- Id drain-current field name requires pcap analysis to confirm (PGXL
protocol not fully documented); field name placeholder in place

## Test plan

- [x] PGXL connected: PWR, SWR, Id bars and labels update during TX;
temp/Vdd/Vac show in bottom row
- [x] PGXL: fwd gauge decays slowly (~800 ms) after TX ends
- [x] TGXL connected: PWR and SWR labels appear during TX, hold 800 ms
after, no flicker at threshold
- [x] No regression on relay bars, TUNE button, OPERATE/BYPASS/STANDBY
cycle, antenna switch

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
G6PWY-Chris pushed a commit to G6PWY-Chris/AetherSDR that referenced this pull request Jun 22, 2026
…ethersdr#3277)

## Summary

Consolidates PGXL and TGXL applet metering improvements into one PR.
Closes aethersdr#3276 and the PGXL applet PR.

### PGXL (Amplifier applet)

- **External row labels** — PWR, SWR, and Id labels left-aligned at 72
px carry live numeric values (`PWR 933`, `SWR 1.2:1`, `Id 25`); internal
gauge labels cleared
- **Id bargraph** — new drain-current gauge (0–70 A, red > 60 A) with
label row matching SSDR layout
- **Bottom info row** — temperature, Vdd, and Vac values displayed in
the empty space left of the OPERATE button
- **Slow-release fwd-power ballistics** — `{30 ms attack / 800 ms
release}` on fwd gauge so brief TX bursts stay visible
- **100 ms label throttle** — value labels update at 10 Hz via QTimer;
gauge fill animates at full rate
- **S-push parser fix** — `PgxlConnection` was silently dropping S-push
messages whose KV string began directly with `key=value` (no prefix
word); fixed with a conditional instead of an early return
- **Telemetry field fixes** — `tempb`, `vdd`, and compound `temp`
(`"34.5/28.1"`) now handled in both direct-TCP and radio-proxy data
paths

### TGXL (Tuner applet)

- **External row labels** — same 72 px PWR/SWR label pattern as PGXL
- **Slow-release fwd-power ballistics** — same `{30 ms / 800 ms}`
profile
- **Label update strategy** — synchronous update on each meter event (no
polling timer) with an 800 ms single-shot hold so inter-packet noise
below 5 W doesn't cause flicker

### Shared

- **`HGauge::setBallistics()`** — added as public API so individual
gauges can opt into custom attack/release curves

### Deferred

- Id drain-current field name requires pcap analysis to confirm (PGXL
protocol not fully documented); field name placeholder in place

## Test plan

- [x] PGXL connected: PWR, SWR, Id bars and labels update during TX;
temp/Vdd/Vac show in bottom row
- [x] PGXL: fwd gauge decays slowly (~800 ms) after TX ends
- [x] TGXL connected: PWR and SWR labels appear during TX, hold 800 ms
after, no flicker at threshold
- [x] No regression on relay bars, TUNE button, OPERATE/BYPASS/STANDBY
cycle, antenna switch

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

aetherclaude-eligible Issue approved for AetherClaude automated agent

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant