Fix SWR protection on Lab599 Discovery TX-500 (#599)#626
Merged
Conversation
The TX-500 inherited its meter read+parse from KenwoodTS2000Rig, which is incompatible with the TX-500's CAT interface, so SWR always stayed 0 and MeterProtectionController never tripped: - readMeters() only ever sent RM;. The TX-500 needs RM1; to switch the meter to SWR first, then RM; returns the reading. - The RM reply RM1vvvv puts the SWR selector at index 0 (not index 2 like the TS-590) and the value at substring(1,5), so is590MeterSWR() never matched. - The raw 0000-0030 field needed a TX-500-specific curve to normalize into the 0-255 scale MeterProtectionController's halt threshold uses. Give DiscoveryTX500Rig its own meter handling: send RM1; before RM;, parse the RM1vvvv layout, and map the 0-30 field to an SWR ratio (linear per Lab599's published chart: swr = 1 + cat/3) normalized on the same scale the halt threshold is stored on. ALC is reported as -1 (not present on this rig). KenwoodTS2000Rig gains protected sendMeterReadCommand()/handleMeterReply() hooks so the override is a clean seam rather than a copy of the RX path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This pull request fixes SWR protection for the Lab599 Discovery TX-500 by adding TX-500-specific meter selection, parsing, and scaling so SWR readings correctly reach MeterProtectionController and can trigger TX halt/lockout.
Changes:
- Added overridable meter seams to
KenwoodTS2000Rig(sendMeterReadCommand(),handleMeterReply()) and routed RM parsing through them. - Implemented TX-500 meter selection (
RM1;thenRM;), TX-500 RM reply parsing helpers, and TX-500 cat-value → SWR-ratio → normalized mapping. - Added unit tests covering TX-500 RM parsing and the cat-value mapping / protection decisions.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| ft8af/app/src/test/java/com/k1af/ft8af/rigs/Yaesu3CommandTest.java | Adds unit coverage for TX-500 RM reply selector/value parsing. |
| ft8af/app/src/test/java/com/k1af/ft8af/rigs/DiscoveryTX500RigTest.java | Adds pure-logic tests for TX-500 cat-value → SWR mapping and halt decisions. |
| ft8af/app/src/main/java/com/k1af/ft8af/rigs/Yaesu3Command.java | Adds TX-500 RM parsing helpers (isTX500MeterSWR, getTX500MeterValue). |
| ft8af/app/src/main/java/com/k1af/ft8af/rigs/KenwoodTS2000Rig.java | Introduces protected hooks for meter polling/parsing so subclasses can override cleanly. |
| ft8af/app/src/main/java/com/k1af/ft8af/rigs/KenwoodTK90RigConstant.java | Adds TX-500 SWR meter select CAT command constant and accessor. |
| ft8af/app/src/main/java/com/k1af/ft8af/rigs/DiscoveryTX500Rig.java | Overrides meter read/parse to support TX-500 SWR selection, parsing, normalization, and alerting. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jul 22, 2026
patrickrb
added a commit
that referenced
this pull request
Jul 24, 2026
…ramed but split on '\r') (#685) The Kenwood-family rigs (KenwoodTS570Rig, KenwoodTS590Rig, KenwoodTS2000Rig, and DiscoveryTX500Rig which inherits from TS2000) send every CAT command and reply terminated with ';' (FA;, RM;, FR0; -- see KenwoodTK90RigConstant), yet their onReceiveData split incoming bytes on '\r', which these rigs never send. So s.contains("\r") was never true: every reply was appended to the buffer until it passed 1000 chars and got wiped, and no reply was ever parsed. Consequences: - Frequency read-back was dead (FA replies never applied). - SWR/ALC over-power protection was dead -- the safety feature that halts TX on high SWR never received a reading. This is why the TX-500's SWR fix (#599/PR #626) never actually worked: PR #626 corrected the meter *layout* but the reply reached parsing through the inherited '\r' split and was dropped first. The reporter's own evidence in #599 (reply "RM10023;") and #589 ("control works normally except swr protection is not working at all", CAT chip goes red within seconds -- the signature of reads never parsing) confirm the ';' framing. This was a half-migration: the command constants were switched to ';'-terminated but onReceiveData was left splitting on '\r'. The same-repo Kenwood-family rigs TrUSDXRig (TS-480 emulation) and Flex6000Rig already split on ';'. Fix: add a multi-terminator overload CatLineSplitter.split(buffered, incoming, String terminators) -- any character in the set ends a command (the existing char overload delegates to it). The three Kenwood rigs adopt split(buffer, s, ";\r") and extract processCommand(String), draining every complete command in a read. Accepting both ';' and '\r' fixes the confirmed-broken ';' stream while being unable to regress any transport that might interleave a '\r' (Kenwood data never contains ';'; an empty span between ';' and '\r' becomes an empty frame that Yaesu3Command.getCommand treats as a no-op). Draining all frames per read also fixes the coalesced RM SWR+ALC reply drop, matching the CatLineSplitter adoption already done for the Yaesu/Elecraft rigs. DiscoveryTX500Rig is fixed via inheritance. Tests: 6 new CatLineSplitterTest cases covering the ';'-framed Kenwood reply, the coalesced SWR+ALC meter poll, freq+meter coalescing, cross-read reassembly, the stray-'\r' tolerance, and char/String overload agreement (19 total, all green). Full rig unit-test package green; main sources compile. Refs #599, #589. Co-authored-by: Optio Agent <optio-agent@noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
SWR protection never fired on the Lab599 Discovery TX-500 (issue #599). The rig is handled by
DiscoveryTX500Rig, which extendedKenwoodTS2000Rigand inherited its meter read + parse unchanged. Two things there are incompatible with the TX-500's CAT interface, soswrstayed0andMeterProtectionControllerwas never tripped:readMeters()only ever sentRM;. Per the TX-500 CAT protocol the rig first needsRM1;to switch the meter to SWR, thenRM;returns the reading.RM10023;→ after strippingRM,data = "10023": the selector digit is at index 0 ('1'= SWR), not index 2, and the value issubstring(1,5)(a raw0000–0030field).is590MeterSWR()checkscharAt(2), so it never matched and the reading was dropped.0000–0030field is a different curve from the TS-590's, so it needed a TX-500-specific mapping before reaching the halt threshold.Fix
Give
DiscoveryTX500Rigits own meter handling rather than inheriting the TS-2000 path:sendMeterReadCommand()override sendsRM1;(select SWR) beforeRM;.handleMeterReply()override parses theRM1vvvvlayout (selector at index 0, value atsubstring(1,5)) via new pure-logic helpersYaesu3Command.isTX500MeterSWR()/getTX500MeterValue().cat = 3·(swr−1), i.e.swr = 1 + cat/3; cat 6 → 3.0:1, cat 27 → 10:1). The mapped ratio is then normalized through the existingMeterProtectionController.swrRatioToNormalized()— the same scale the user-configured halt threshold is stored on — so the halt decision is meaningful for this rig.KenwoodTS2000Riggains twoprotectedseams (sendMeterReadCommand(),handleMeterReply()) so the override is a clean hook rather than a copy of the RX/parse path; the inherited TS-2000/TS-590 behavior is unchanged.Scope / assumptions
-1("not reported"). This can be a follow-up if the ALC meter id + select command are confirmed.DiscoveryTX500Rigoverride rather than routing through hamlib (which currently has norig_get_level/meter binding), per the reporter's own build-vs-hamlib analysis in the issue.Tests
Per CLAUDE.md, all new logic is covered by pure-logic unit tests:
Yaesu3CommandTest— TX-500RM10023→ SWR selector true + value 23, zero value, non-'1'selector rejected (distinct from the TS-590 index-2 layout), and short-data defaults.DiscoveryTX500RigTest— cat→ratio chart anchor points, monotonicity, unity floor, normalization alignment with the default halt threshold (cat 6 == 120 == 3.0:1), and end-to-endshouldHaltForSwrdecisions (cat 23 halts, cat 3 does not)../gradlew :app:testDebugUnitTestpasses (full suite, no regressions).🤖 Generated with Claude Code