Skip to content

feat(bands): surface 4m/2m on FLEX-6500/6700 via ModelCapabilities (#695)#2757

Merged
ten9876 merged 1 commit into
mainfrom
auto/fix-695
May 16, 2026
Merged

feat(bands): surface 4m/2m on FLEX-6500/6700 via ModelCapabilities (#695)#2757
ten9876 merged 1 commit into
mainfrom
auto/fix-695

Conversation

@ten9876

@ten9876 ten9876 commented May 16, 2026

Copy link
Copy Markdown
Collaborator

Summary

Implements the plan posted to #695.

FLEX-6500 (Region 1 mod) has a built-in 4m transverter; FLEX-6700 has both 4m and 2m. These are native radio hardware, not user-configurable XVTRs — click the band button and tune, no XVTR-tab setup required.

Changes

  • src/models/ModelCapabilities.{h,cpp} — table mirroring FlexLib ModelInfo.cs (Has4Meters, Has2Meters). Substring-matching lookup with R-variants ordered before base models so FLEX-6700R doesn't accidentally claim 6700 caps. Unknown models default to all-false (forward-compat).
  • RadioModel::capabilities() — thin accessor.
  • SpectrumOverlayMenu — new setRadioCapabilities() slot caches flags and triggers band-panel rebuild; existing setXvtrBands() path inserts a conditional 4m/2m row between HF and user-XVTR rows, styled identically to HF bands.
  • MainWindow::refreshXvtr lambda now pushes both caps and XVTR list on every infoChanged, so capability changes on (re)connect propagate to all open panadapter menus.
  • tests/model_capabilities_test — 36 assertions verifying table against FlexLib row-for-row + substring/case-insensitive/unknown-model behavior. All passing locally.

Scope

Intentionally narrow: only the 2m/4m checks migrate into ModelCapabilities. Existing model.contains(\"6700\") checks for slice count, dual-SCU, has-loop-B stay where they are — can be opportunistically migrated in follow-ups.

Test plan

  • Local build clean (395/395)
  • `./build/model_capabilities_test` — all 36 assertions pass
  • Manual on FLEX-6700: Band menu shows 4m + 2m row between 6m and WWV; click 2m tunes to 144.200 USB; click 4m tunes to 70.200 USB. Verify no XVTR config required.
  • Manual on FLEX-6500: only 4m appears.
  • Manual on FLEX-6400/6600: no change to band menu.

Fixes #695. Thanks @Juanjo-EA1CJ for the original report and @wb8cxo for the correction.

🤖 Generated with Claude Code

)

The FLEX-6500 (Region 1 mod) has a built-in 4m transverter; the
FLEX-6700 has both 4m and 2m.  These are native radio hardware,
not user-configurable XVTRs, and the band selector should treat
them that way — no manual XVTR-tab configuration required, just
click the band button and tune.

Approach mirrors FlexLib's per-model ModelInfo design:

* `src/models/ModelCapabilities.{h,cpp}` — table keyed on the
  model string with Has4Meters / Has2Meters flags.  Substring
  matching with R-variants ordered before base models so a
  "FLEX-6700R" status doesn't accidentally claim 6700 caps.
  Unknown models default to all-false (forward-compat).
* `RadioModel::capabilities()` — thin accessor returning
  capabilitiesFor(m_model).
* `SpectrumOverlayMenu` — new `setRadioCapabilities()` slot
  caches the flags and triggers a band-panel rebuild; the
  existing setXvtrBands() rebuild path inserts a conditional
  4m/2m row between HF bands and the user-XVTR row, styled
  identically to HF (these are native bands, not XVTRs).
* `MainWindow` refreshXvtr lambda pushes both caps and XVTR
  list together on every infoChanged, so capability changes
  on (re)connect propagate to all open panadapter menus.
* `tests/model_capabilities_test` — verifies the table matches
  FlexLib/ModelInfo.cs row-for-row.  Catches drift if Flex
  ever flips a flag in firmware updates; re-sync the C++
  table and update the test together.

Scope is intentionally narrow: only the 2m/4m checks migrate
into ModelCapabilities; the existing model.contains("6700")
checks elsewhere (slice count, dual-SCU, has-loop-B) stay where
they are and can be opportunistically migrated in follow-ups.

Fixes #695.  Thanks @Juanjo-EA1CJ for the original report and
@wb8cxo for the correction that the 6700's 2m is native hardware
and shouldn't require XVTR configuration.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@aethersdr-agent aethersdr-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks @ten9876 — this is a nicely scoped change. The capability-table approach reads cleanly and the substring/case-insensitive lookup with R/M-variants ordered before base models is exactly the right shape. Test coverage is solid (FlexLib row-for-row + suffix + case + unknown + empty).

A few observations, none blocking:

1. Double rebuild on first connect to a 4m/2m radio (minor)

In MainWindow::refreshXvtr the call sequence is:

menu->setRadioCapabilities(caps);   // (a)
menu->setXvtrBands(xvtrBands);      // (b)

When caps differs from the default (i.e. a FLEX-6500/6700), setRadioCapabilities triggers a full setXvtrBands(m_lastXvtrBands) rebuild internally, then call (b) rebuilds the panel again with the real XVTR list. The panel is hidden during rebuild so it's not user-visible — just two deleteLater() + reconstruct cycles where one would do. For 6400/6600/8x00 the early-out skips it, so it's only on 6500/6700. Worth a comment or a small "build once with both inputs" helper if you want to address it, but I wouldn't block on this.

2. setRadioCapabilities early-out when caps equal default-constructed values

On the very first call with all-false caps (FLEX-6400, etc.), the equality check against the default-constructed m_radioCapabilities returns early without ever building the band panel. That's fine because setXvtrBands runs immediately after and does the actual build — but it means setRadioCapabilities is not safe to call in isolation as a "make sure the panel reflects current caps" trigger. The current callsite ordering keeps that invariant intact; just worth noting if a future caller leans on it.

3. 4m frequency choice

70.200 USB matches the IARU Region 1 SSB centre of activity and is the conventional default for AetherSDR's intended audience here — good pick. 144.200 USB is the NA SSB calling frequency; Region 1 users land at 144.300, but as a single default it's defensible and matches what most operators clicking the button will expect.

4. Scope

PR body explicitly defers migrating the other model.contains("6700") checks (slice count, dual-SCU, has-loop-B) to follow-ups. Good call — keeps this reviewable and the table additive.

Nothing AppSettings/RAII/error-handling related to flag. Build config, conventions, and the new test target all look right. Nice work.

@ten9876 ten9876 merged commit 98008a0 into main May 16, 2026
5 checks passed
@ten9876 ten9876 deleted the auto/fix-695 branch May 16, 2026 23:05
@ten9876 ten9876 mentioned this pull request May 16, 2026
6 tasks
@wb8cxo

wb8cxo commented May 17, 2026

Copy link
Copy Markdown

26.5.2 added 2 and 4 m band buttons (TU) but nothing happens when clicked on. 6700 still functions on 2m using profiles. Couldn't get direct freq (2m) entry on slice to work (possibly me). Memories work inconsistantly, more testing needed.

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.

Flexradio 6700 missing 144 and 70Mhz

2 participants