feat(cat): three transports for Kenwood/Elecraft, chosen not inferred
USB, RS-232-to-Ethernet, and the radio's own network protocol are three different things, so they are three entries in one dropdown — and the transport is now a stored setting rather than something deduced from which field happened to be filled in. The old rule (a host wins whenever it is not empty) is invisible from the settings page: someone who typed a host months ago and later set a COM port had a radio that never answered and nothing on screen to say why. The third entry is named and refused, with the reason. It is a session with its own framing and login, not the CAT byte stream over a socket, so it has to be written per radio and against one — and a K4 owner reading this list should be told that, not left wondering whether the empty address field was the problem. The upgrade reads an older install from what it has: a configured host means the bridge, which is what the previous code used it for. Pinned by a test, including the case that matters after the fact — choosing USB with a stale host still stored gives the COM port.
This commit is contained in:
@@ -1514,7 +1514,7 @@ export function SettingsModal({ onClose, onSaved, initialSection, onMainPaneChan
|
||||
const [modeDraft, setModeDraft] = useState('');
|
||||
const [catCfg, setCatCfg] = useState<CATSettings>({
|
||||
enabled: false, backend: 'omnirig', omnirig_rig: 1, omnirig_vfo: '', flex_host: '', flex_port: 4992, flex_spots: false, flex_decode_spots: false, flex_decode_secs: 120, flex_dvk_dax: false,
|
||||
yaesu_port: '', yaesu_baud: 38400, yaesu_low_lines: false, kenwood_low_lines: false, kenwood_port: '', kenwood_baud: 9600, kenwood_host: '', kenwood_data_mode: 'usb', xiegu_port: '', xiegu_baud: 19200, xiegu_addr: 0x70, xiegu_ptt_line: '',
|
||||
yaesu_port: '', yaesu_baud: 38400, yaesu_low_lines: false, kenwood_low_lines: false, kenwood_port: '', kenwood_baud: 9600, kenwood_host: '', kenwood_link: 'usb', kenwood_data_mode: 'usb', xiegu_port: '', xiegu_baud: 19200, xiegu_addr: 0x70, xiegu_ptt_line: '',
|
||||
icom_port: '', icom_baud: 115200, icom_addr: 0x98, icom_net_host: '', icom_net_user: '', icom_net_pass: '', icom_net_audio: false,
|
||||
tci_host: '', tci_port: 40001, tci_spots: false, poll_ms: 250, delay_ms: 0, offset_on: false, offset_hz: 0,
|
||||
digital_default: 'FT8', share_enabled: false, share_port: 4532, share_proto: 'rigctl', share_tci_port: 40001,
|
||||
@@ -3187,19 +3187,20 @@ export function SettingsModal({ onClose, onSaved, initialSection, onMainPaneChan
|
||||
the field is not empty, which is invisible from here. */}
|
||||
<div className="space-y-1">
|
||||
<Label>{t('cat.kwLink')}</Label>
|
||||
<div className="inline-flex rounded-md border border-border overflow-hidden text-xs">
|
||||
{[['usb', t('cat.kwLinkUsb')], ['net', t('cat.kwLinkNet')]].map(([v, label]) => (
|
||||
<button key={v} type="button"
|
||||
onClick={() => setCatCfg((s) => ({ ...s, kenwood_host: v === 'usb' ? '' : (s.kenwood_host || '') }))}
|
||||
className={cn('px-3 py-1.5 font-medium',
|
||||
((catCfg.kenwood_host || '').trim() !== '') === (v === 'net')
|
||||
? 'bg-primary text-primary-foreground' : 'text-muted-foreground hover:bg-muted')}>
|
||||
{label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<Select value={(catCfg as any).kenwood_link || 'usb'}
|
||||
onValueChange={(v) => setCatCfg((s) => ({ ...s, kenwood_link: v } as any))}>
|
||||
<SelectTrigger><SelectValue /></SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="usb">{t('cat.kwLinkUsb')}</SelectItem>
|
||||
<SelectItem value="bridge">{t('cat.kwLinkBridge')}</SelectItem>
|
||||
<SelectItem value="native">{t('cat.kwLinkNative')}</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{((catCfg as any).kenwood_link || 'usb') === 'native' && (
|
||||
<p className="text-xs text-warning">{t('cat.kwLinkNativeHint')}</p>
|
||||
)}
|
||||
</div>
|
||||
{(catCfg.kenwood_host || '').trim() === '' && (<>
|
||||
{(((catCfg as any).kenwood_link || 'usb') === 'usb') && (<>
|
||||
<div className="space-y-1">
|
||||
<Label>{t('cat.kenwoodPort')}</Label>
|
||||
<div className="flex gap-2">
|
||||
@@ -3222,7 +3223,7 @@ export function SettingsModal({ onClose, onSaved, initialSection, onMainPaneChan
|
||||
</SelectContent>
|
||||
</Select> </div>
|
||||
</>)}
|
||||
{(catCfg.kenwood_host || '').trim() !== '' && (
|
||||
{((catCfg as any).kenwood_link === 'bridge') && (
|
||||
<div className="space-y-1">
|
||||
<Label>{t('cat.kenwoodHost')}</Label>
|
||||
<Input
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user