Skip to content

Cross-session persistence of NRS level (and other firmware-default-on-recall settings) #2985

Description

@ten9876

Context

PR #2917 (merged 2026-05-23) added within-session cache + re-push of `speex_nr_level` (NRS) so a profile-global recall doesn't snap the user's choice back to the firmware default of 50. That fixes the reported behavior in #2849.

It does NOT survive an app restart: `m_nrsLevelUser` and `m_nrsLevelUserOverride` are in-memory only. After AetherSDR is restarted:

  1. User reconnects to the radio
  2. Radio sends `speex_nr_level=50` (firmware default, since `profile global` doesn't persist it)
  3. `m_nrsLevelUserOverride == false` (initial state) → no re-push → NRS sits at 50
  4. User has to manually reset NRS to their preferred value each session

Proposal

Persist the user's NRS level (and the override flag) per-radio in AppSettings so the in-session cache also survives across restarts.

Suggested storage shape

Per the AppSettings refactor memo, prefer one nested-JSON value under one key rather than flat per-slice keys:

```
SliceUserOverrides = {
"": {
"slice-0": { "nrsLevel": 30 },
"slice-1": { "nrsLevel": 22 }
}
}
```

Keyed by radio serial so two different physical radios on the same operator workstation don't share overrides.

Loading flow

On `SliceModel` construction or first `applyStatus` with serial available:

  1. Look up the radio+slice tuple in `SliceUserOverrides`
  2. If a cached value exists, set `m_nrsLevelUser` and `m_nrsLevelUserOverride = true`
  3. The existing applyStatus re-push logic handles the rest — radio echoes 50 on first status, we re-push the cached value

Saving flow

In `setNrsLevel`, write the new value to the JSON map and `AppSettings::save()`.

Why this is worth doing

NRS isn't the only setting Flex firmware fails to persist across `profile global` recall. The same pattern (in-memory override + applyStatus re-push) is already used for `rtty_mark`. If we keep adding these per-setting workarounds, building one shared persistence layer for them all is cleaner than N copies of the cache-and-re-push code.

The current PR #2917 fix is good for one-shot bug closure (#2849), but the next user report along the lines of "X also resets on profile recall" would benefit from infrastructure already being in place.

Why this can wait

  • The reported bug (NRS setting value not persistent goes to 50 each time. #2849) is fixed within a session — that's the primary complaint
  • No multi-setting demand yet — adding the persistence layer for one knob alone is overengineering
  • The AppSettings refactor is on the roadmap independently; this work would benefit from landing on top of the nested-JSON-under-one-key infrastructure rather than ahead of it

Effort

If the AppSettings nested-JSON infrastructure is already done: ~2 hours (storage + load + save + manual test of restart-survival).
If not: ~half day, including the small per-setting persistence layer that can be reused for `rtty_mark` and future similar workarounds.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementImprovement to existing featuremaintainer-reviewRequires maintainer review before any action is takenpriority: lowLow priorityprotocolSmartSDR protocol

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions