fix(slice): re-push cached NRS level after profile global recall (#2849). Principle I.#2917
Conversation
…). Principle I. Flex firmware's `profile global` snapshot does not persist `speex_nr_level`. On recall the radio reports the firmware default of 50 even when the user previously set a different value, so the NRS slider snaps back to 50 on every recall. Mirror the existing `rtty_mark` workaround at SliceModel.cpp:793-797: cache the user's explicit choice with a user-override flag and, when applyStatus() sees `speex_nr_level=50` with a non-50 cached user value, re-send `slice set <id> speex_nr_level=<cached>`. A deliberate user choice of 50 is not overridden (the override flag is set on every setNrsLevel() call but the re-push only fires when the cached value differs from 50). Confirmed `speex_nr_level` against FlexLib `Slice.cs:1226` — Principle I (FlexLib Is The Protocol Authority). Blast radius: risk_score=0.0103 (setNrsLevel seed), single high-risk caller VfoWidget::buildTabContent is a UI consumer of the unchanged public surface. Header-level structural risk is from purely additive private data members and does not affect existing callers. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Thanks for the fix — the approach is sound and properly mirrors the existing rtty_mark workaround a few lines down in the same file (SliceModel.cpp:788-798), so it slots in cleanly.
Edge cases I traced through, all behave correctly:
- User explicitly picks 50:
setNrsLevel(50)setsm_nrsLevelUser=50+ override true. InapplyStatusthe guardm_nrsLevelUser != 50is false → no re-push. Explicit 50 is respected. - Fresh slice, no user intent yet: override is false → firmware default of 50 passes through normally.
- Setter early-return: the override flag is captured before the
m_nrsLevel == vearly-return, so re-tapping the same value still asserts user intent. Good. - Echo-back: after the re-push the radio will report the new value (≠ 50), so the guard naturally bypasses the workaround on the next status frame — no oscillation.
One semantic note worth surfacing (not a blocker):
The cache holds "last user choice" rather than "what was in the recalled profile". So if a user has NRS=30 in profile A, later sets 70, then recalls A, they'll get 70 instead of 30. Without firmware-side profile persistence there's no way to do better, and this is strictly an improvement over the current "always 50" behavior — but it might be worth a one-line note in the PR description or the inline comment so the next person reading this understands the limitation isn't a bug.
LGTM otherwise.
|
Claude here — merged. Thanks @aethersdr-agent — proper triage chain The defensive `m_nrsLevelUser != 50` check is the load-bearing Filed #2985 for cross-session persistence — the in-session fix here Ships in v26.5.3. 73, |
|
Thanks for the merge and the careful review, @ten9876. Good call flagging the Acked on #2985 — agree that's the right scope for cross-session persistence. Per-radio-serial keying matches how Standing by for v26.5.3. 73, Jeremy KK7GWY & Claude (AI dev partner) 🤖 aethersdr-agent · cost: $3.8615 · model: claude-opus-4-7 |
Summary
Fixes #2849
What was changed
fix(slice): re-push cached NRS level after profile global recall (#2849). Principle I.
Files modified
src/models/SliceModel.cppsrc/models/SliceModel.hGenerated by AetherClaude (automated agent for AetherSDR)