From 7e7ad50f60fc93685b4c912c4e381a6bfdf36fa8 Mon Sep 17 00:00:00 2001 From: rouggy Date: Fri, 28 Aug 2026 23:35:25 +0200 Subject: [PATCH] =?UTF-8?q?feat(k3):=20a=20mode=20row=20on=20the=20Elecraf?= =?UTF-8?q?t=20console=20=E2=80=94=20CW/USB/LSB/DATA/DATA-RTTY?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The report: switching the K3 to a data mode 'does not work for FT8 — the K3 does not go into DATA'. The mode digit is only half the answer on that radio: MD6 keeps whatever DT submode the previous session left, and with FSK D still armed the rig keys FT8 with no rear-audio modulation. The panel buttons say the whole thing: DATA is MD6+DT0 (DATA A, the soundcard path), DATA RTTY is MD6+DT2 (FSK D). The DT submode is also read on the settings beat — Elecraft only, a plain Kenwood would '?;' it — so the active DATA button follows what the rig is actually in, front-panel changes included. A dedicated SetKenwoodPanelMode rather than the logger's SetMode: a panel button is the operator saying exactly what the rig should do, not an ADIF mode to be mapped through preferences. --- app_k3.go | 6 ++ changelog.json | 6 +- frontend/src/components/ElecraftPanel.tsx | 36 +++++++++++- frontend/src/lib/i18n.tsx | 6 ++ frontend/wailsjs/go/main/App.d.ts | 2 + frontend/wailsjs/go/main/App.js | 4 ++ frontend/wailsjs/go/models.ts | 2 + internal/cat/kenwood_panel.go | 69 +++++++++++++++++++++++ 8 files changed, 127 insertions(+), 4 deletions(-) diff --git a/app_k3.go b/app_k3.go index 796e569..5cb5a65 100644 --- a/app_k3.go +++ b/app_k3.go @@ -24,6 +24,12 @@ func (a *App) GetKenwoodState() cat.KenwoodTXState { return st } +// SetKenwoodPanelMode sets the operating mode from the panel's mode row — +// CW / USB / LSB / DATA (soundcard, DT0) / RTTY (FSK D, DT2). +func (a *App) SetKenwoodPanelMode(mode string) error { + return a.kenwoodPanelDo(func(k cat.KenwoodPanelController) error { return k.SetKenwoodPanelMode(mode) }) +} + func (a *App) SetKenwoodPower(w int) error { return a.kenwoodPanelDo(func(k cat.KenwoodPanelController) error { return k.SetKenwoodPower(w) }) } diff --git a/changelog.json b/changelog.json index 8384332..7761dd8 100644 --- a/changelog.json +++ b/changelog.json @@ -5,12 +5,14 @@ "en": [ "TCI (SunSDR): the meter subscription is renewed when the radio announces it is ready — sent only at connect, it could fall inside the initial state dump and be ignored, which left the transmit power and SWR empty. The log now also records the subscription and the first sensor frames, so a report can tell “the radio never sends them” from “they arrived and were dropped”.", "Sending a spot while in split now pre-fills the RX frequency — where the station actually is — instead of the TX frequency, which spotted the pile-up five up from the DX.", - "Cluster: NEW SLOT gets its own colour — the sky cyan the panadapter palette already uses for it, clearly apart from POTA green and the yellows. The NEW SLOT and NEW COUNTY filter chips now wear the same colours as the badges they select, and the NEW CALL filter works even when the slot-highlight display option is off." + "Cluster: NEW SLOT gets its own colour — the sky cyan the panadapter palette already uses for it, clearly apart from POTA green and the yellows. The NEW SLOT and NEW COUNTY filter chips now wear the same colours as the badges they select, and the NEW CALL filter works even when the slot-highlight display option is off.", + "Elecraft console: a mode row — CW, USB, LSB, DATA and DATA RTTY. The two DATA buttons set the K3’s submode as well (DATA A for FT8/FT4, FSK D for RTTY): switching to DATA by mode alone kept whatever submode the last session left, which is how a K3 “in DATA” keys FT8 with no audio." ], "fr": [ "TCI (SunSDR) : l'abonnement aux mesures est renouvelé quand la radio annonce qu'elle est prête — envoyé seulement à la connexion, il pouvait tomber pendant l'envoi initial de l'état et être ignoré, laissant la puissance et le ROS vides en émission. Le journal enregistre aussi l'abonnement et les premières trames de mesure, pour distinguer « la radio ne les envoie jamais » de « elles arrivaient et étaient perdues ».", "Envoyer un spot en split préremplit désormais la fréquence RX — là où la station se trouve réellement — au lieu de la fréquence TX, qui spottait le pile-up cinq au-dessus du DX.", - "Cluster : NOUVEAU SLOT reçoit sa propre couleur — le cyan ciel que la palette du panadapter lui donne déjà, bien distinct du vert POTA et des jaunes. Les puces de filtre NOUVEAU SLOT et NOUVEAU COMTÉ portent désormais les couleurs des badges qu'elles sélectionnent, et le filtre NOUVEAU CALL fonctionne même quand l'option de surlignage par slot est désactivée." + "Cluster : NOUVEAU SLOT reçoit sa propre couleur — le cyan ciel que la palette du panadapter lui donne déjà, bien distinct du vert POTA et des jaunes. Les puces de filtre NOUVEAU SLOT et NOUVEAU COMTÉ portent désormais les couleurs des badges qu'elles sélectionnent, et le filtre NOUVEAU CALL fonctionne même quand l'option de surlignage par slot est désactivée.", + "Console Elecraft : une rangée de modes — CW, USB, LSB, DATA et DATA RTTY. Les deux boutons DATA règlent aussi le sous-mode du K3 (DATA A pour FT8/FT4, FSK D pour le RTTY) : passer en DATA par le seul mode gardait le sous-mode de la session précédente, et un K3 « en DATA » manipulait le FT8 sans audio." ] }, { diff --git a/frontend/src/components/ElecraftPanel.tsx b/frontend/src/components/ElecraftPanel.tsx index 9d83b79..a474016 100644 --- a/frontend/src/components/ElecraftPanel.tsx +++ b/frontend/src/components/ElecraftPanel.tsx @@ -4,7 +4,7 @@ import { GetKenwoodState, RefreshKenwood, SetKenwoodPower, SetKenwoodAFGain, SetKenwoodTX, TuneKenwoodATU, SetKenwoodRFGain, SetKenwoodMicGain, SetKenwoodSquelch, SetKenwoodPreamp, SetKenwoodAtt, SetKenwoodNB, SetKenwoodNR, SetKenwoodAGC, SetKenwoodFilter, SetKenwoodAntenna, - SetKenwoodRIT, SetKenwoodXIT, ClearKenwoodRIT, SetKenwoodKeySpeed, ToggleKenwoodATU, NudgeKenwoodRIT, + SetKenwoodRIT, SetKenwoodXIT, ClearKenwoodRIT, SetKenwoodKeySpeed, ToggleKenwoodATU, NudgeKenwoodRIT, SetKenwoodPanelMode, GetCATState, } from '../../wailsjs/go/main/App'; import { cn } from '@/lib/utils'; @@ -14,7 +14,7 @@ import { MeterBar } from '@/components/MeterBar'; import { WheelRange } from '@/components/WheelRange'; type KenwoodState = { - available: boolean; model?: string; elecraft: boolean; mode?: string; + available: boolean; model?: string; elecraft: boolean; mode?: string; data_sub?: string; transmitting: boolean; split: boolean; split_tx_hz?: number; s_meter: number; s_meter_raw: number; power_meter: number; swr: number; swr_raw: number; @@ -89,6 +89,16 @@ function Toggle({ label, on, off, onClick }: { label: string; on: boolean; off: ); } +// isDataMode: what the rig reports for MD6 varies — "DATA", or the configured +// digital default (FT8…) — so the DATA family is "not one of the native modes". +function isDataMode(m?: string): boolean { + switch ((m ?? '').toUpperCase()) { + case '': case 'CW': case 'USB': case 'LSB': case 'SSB': case 'FM': case 'AM': case 'RTTY': + return false; + } + return true; +} + export function ElecraftPanel({ onReportRST }: { onReportRST?: (rst: string) => void }) { const { t } = useI18n(); const [st, setSt] = useState(ZERO); @@ -149,6 +159,28 @@ export function ElecraftPanel({ onReportRST }: { onReportRST?: (rst: string) => {freqHz > 0 ? (freqHz / 1e6).toFixed(6) : '—'} + {/* Mode row. The two DATA buttons are why it exists: MD6 alone keeps + whatever submode the last session left, and a K3 "in DATA" with FSK D + still armed keys FT8 with no audio. DATA sends MD6+DT0 (DATA A, the + soundcard path), RTTY sends MD6+DT2 (FSK D). The active DATA button + follows the rig's own DT answer. */} +
+ {([ + ['CW', 'CW', view.mode === 'CW'], + ['USB', 'USB', view.mode === 'USB'], + ['LSB', 'LSB', view.mode === 'LSB'], + ['DATA', t('k3.modeData'), isDataMode(view.mode) && view.data_sub !== 'FSK D' && view.data_sub !== 'PSK D'], + ['RTTY', t('k3.modeRtty'), (isDataMode(view.mode) && (view.data_sub === 'FSK D' || view.data_sub === 'PSK D')) || view.mode === 'RTTY'], + ] as [string, string, boolean][]).map(([cmd, label, on]) => ( + + ))} +