Skip to content

fix: Stream Deck Tune Toggle parses wrong TCI status field#3647

Merged
ten9876 merged 1 commit into
aethersdr:mainfrom
mvanhorn:fix/3622-streamdeck-tune-toggle
Jun 19, 2026
Merged

fix: Stream Deck Tune Toggle parses wrong TCI status field#3647
ten9876 merged 1 commit into
aethersdr:mainfrom
mvanhorn:fix/3622-streamdeck-tune-toggle

Conversation

@mvanhorn

Copy link
Copy Markdown
Contributor

Summary

Fixes #3622. The Stream Deck Tune Toggle only ever turned tuning on; pressing it again never turned it off. The Tune Toggle action emits tune:0,${!radio.tuning};, which relies on the plugin's cached radio.tuning staying in sync with the radio. The TCI status parser read the tune boolean from p[0] (the trx index) instead of p[1], so radio.tuning was always evaluated as ("0" === "true") = false. That made !radio.tuning always true, so the toggle was stuck on.

AetherSDR's TCI server emits tune:<trx>,<true|false>; — confirmed at src/core/TciProtocol.cpp:518 (tune:%1,%2; with %1 = trx, %2 = the boolean). Every sibling boolean handler in plugin.js (trx, mute, rx_nb, split_enable, lock) already reads p[1] with a >= 2 length guard; the tune case was the lone outlier. This brings it in line:

-            case "tune":         if (p.length >= 1) radio.tuning = p[0] === "true"; break;
+            case "tune":         if (p.length >= 2) radio.tuning = p[1] === "true"; break;

radio.tuning now stays synced, so the toggle alternates on/off correctly. The bug is in the JS plugin, so it is platform-independent (not Windows-specific). mox-toggle already reads p[1] and is unaffected.

Constitution principle honored

Radio-authoritative live state — the plugin's cached radio.tuning must faithfully reflect the state the radio reports over TCI. The fix restores that mirror by parsing the boolean from the field the radio actually emits, rather than holding a stale value.

Test plan

  • Reproduction documented (see Summary): tune:0,true; was parsed as radio.tuning = ("0" === "true") = false.
  • node --check passes on plugin.js (single-line change, JS syntax valid).
  • Behavior verified on a real radio: incoming tune:0,true; sets radio.tuning = true; a malformed tune:0; (length < 2) leaves it unchanged rather than misparsing; subsequent presses alternate tune:0,false; / tune:0,true;.

Checklist

  • Commit is signed (SSH)
  • No new flat-key AppSettings calls (Principle V) — N/A, JS plugin change only
  • Code is clean-room (Principle IV) — the fix is derived from this repo's own TCI emission code, not a proprietary binary
  • All meter UI uses MeterSmoother — N/A, no meter UI touched
  • Documentation updated — N/A, no user-visible doc behavior changed
  • Security-sensitive changes reference a GHSA — N/A

The Stream Deck Tune Toggle only ever turned tuning on. The TCI status
parser read the tune boolean from p[0] (the trx index) instead of p[1],
so radio.tuning was always evaluated as ("0" === "true") = false,
making the cached state stale and the toggle one-directional.

Aligns the tune case with every sibling boolean handler (trx, mute,
rx_nb, split_enable, lock), which all read p[1] with a >= 2 guard.
@mvanhorn mvanhorn requested a review from a team as a code owner June 18, 2026 07:24

@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.

Verified the fix against the source — it's correct and minimal.

Confirmed:

  • src/core/TciProtocol.cpp:518 emits tune:%1,%2; with %1 = trx index, %2 = the boolean. So the tune state is p[1], not p[0]. The PR's root-cause analysis is accurate.
  • The pre-fix line was the lone outlier: every sibling boolean handler in parseTcitrx, mute, rx_nb, rx_anf, sql_enable, split_enable, lock, rit_enable, xit_enable — already reads p[1] with a >= 2 length guard. The tune case used p[0] with >= 1, so radio.tuning was always ("0" === "true")false, leaving tune-toggle (tune:0,${!radio.tuning};) stuck sending true.
  • The >= 2 guard is the right call: a malformed tune:0; now leaves radio.tuning unchanged rather than misparsing the trx index as a boolean.
  • mox-toggle already reads the trx-sourced radio.transmitting correctly and is unaffected, as noted.

Single-line change, platform-independent (pure JS plugin), consistent with the surrounding code. No concerns — the unchecked test-plan item is a real-radio behavioral confirmation, which is reasonable to leave to the maintainer.

Thanks for the thorough write-up and for tracing it back to the TCI emission code rather than guessing, @mvanhorn. LGTM.


🤖 aethersdr-agent · cost: $5.1785 · model: claude-opus-4-8

@ten9876 ten9876 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approving — textbook one-line fix, diagnosis verified against the source.

TciProtocol.cpp:518 emits tune:%1,%2; (%1=trx, %2=boolean), so tune:0,truep[0]="0", p[1]="true". The old radio.tuning = p[0] === "true" evaluated "0" === "true" → always false, so !radio.tuning was always true and the toggle stuck on. The fix reads p[1] with a >= 2 guard — matching every sibling boolean handler (trx/mute/rx_nb/split_enable/lock), which all already use p[1] — and harmlessly ignores a malformed tune:0;. Correct and consistent. CI green. Nice catch @mvanhorn.

@ten9876 ten9876 merged commit a608986 into aethersdr:main Jun 19, 2026
6 checks passed
@mvanhorn

Copy link
Copy Markdown
Contributor Author

Huge thanks for the merge, @ten9876. Reading the right TCI status makes the Stream Deck Tune Toggle actually toggle instead of only turning on.

@mvanhorn

Copy link
Copy Markdown
Contributor Author

Thanks @ten9876 - fixing the Stream Deck Tune Toggle so it actually toggles instead of only turning tuning on is a satisfying catch.

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.

Bug: Stream Deck Tuner Toggle doesn't toggle

2 participants