feat: a typed watering hole carries its mode; Yaesu RTTY sideband
His log settles the 28.074 case: "SetCATFrequency 28.074 MHz" and the state still reads mode=USB — nothing sent a mode, so the rig simply stayed where it was. A spot click has always carried one; a frequency typed by hand carried none. It now uses the same table and the same tolerance as a spot (±3 kHz of a known FT8/FT4/JS8 frequency), and only towards the digital modes: tuning AWAY from one leaves the mode alone, because there the frequency says nothing about what the operator means. RTTY on Yaesu is a choice the log cannot make: ADIF records "RTTY" and the rig has MD06 (RTTY-L) and MD09 (RTTY-U). The older lower sideband stays the default and a station whose FSK controller wants the upper one says so once in Settings → CAT.
This commit is contained in:
@@ -157,6 +157,7 @@ const (
|
||||
// the rule since is that nothing a backend does may be steered by another
|
||||
// backend's setting.
|
||||
keyCATYaesuLowLines = "cat.yaesu.low_dtr_rts" // deassert DTR/RTS on connect
|
||||
keyCATYaesuRTTYUSB = "cat.yaesu.rtty_usb" // set RTTY on USB rather than the older LSB
|
||||
keyCATKenwoodLowLines = "cat.kenwood.low_dtr_rts" // deassert DTR/RTS on connect
|
||||
keyCATKenwoodDataMode = "cat.kenwood.data_mode" // data modes → "usb" | "data" (MD6) | "keep"
|
||||
keyCATIcomPort = "cat.icom.port" // Icom USB CI-V serial port (e.g. COM5)
|
||||
@@ -510,7 +511,11 @@ type CATSettings struct {
|
||||
// Per-backend: deassert DTR and RTS after opening the CAT port, for
|
||||
// interfaces that read either line as PTT. Off by default: lowering them
|
||||
// stops some USB-serial interfaces transmitting at all.
|
||||
YaesuLowLines bool `json:"yaesu_low_lines"`
|
||||
YaesuLowLines bool `json:"yaesu_low_lines"`
|
||||
// YaesuRTTYUSB: ADIF says "RTTY" and Yaesu has both sidebands, so the rig
|
||||
// cannot be driven from the logged mode alone. Off = RTTY-L, the older
|
||||
// convention.
|
||||
YaesuRTTYUSB bool `json:"yaesu_rtty_usb"`
|
||||
KenwoodLowLines bool `json:"kenwood_low_lines"`
|
||||
IcomPort string `json:"icom_port"` // Icom USB CI-V serial port (e.g. COM5)
|
||||
IcomBaud int `json:"icom_baud"` // Icom CI-V baud (default 115200)
|
||||
@@ -8317,7 +8322,7 @@ func (a *App) GetCATSettings() (CATSettings, error) {
|
||||
if a.settings == nil {
|
||||
return CATSettings{Backend: "omnirig", OmniRigNum: 1, PollMs: 250}, fmt.Errorf("db not initialized")
|
||||
}
|
||||
m, err := a.settings.GetMany(a.ctx, keyCATEnabled, keyCATBackend, keyCATOmniRigNum, keyCATOmniRigVFO, keyCATFlexHost, keyCATFlexPort, keyCATFlexSpots, keyCATFlexDVKDax, keyCATFlexDecodeSpots, keyCATFlexDecodeSecs, keyCATXieguPort, keyCATXieguBaud, keyCATXieguAddr, keyCATXieguPTTLine, keyCATYaesuPort, keyCATYaesuBaud, keyCATKenwoodPort, keyCATKenwoodBaud, keyCATKenwoodHost, keyCATKenwoodLink, keyCATYaesuLowLines, keyCATKenwoodLowLines, keyCATKenwoodDataMode, keyCATIcomPort, keyCATIcomBaud, keyCATIcomAddr, keyCATIcomNetHost, keyCATIcomNetUser, keyCATIcomNetPass, keyCATIcomNetAudio, keyCATTCIHost, keyCATTCIPort, keyCATTCISpots, keyCATPttHotkeyEnabled, keyCATPttHotkey, keyCATPttHotkeyToggle, keyCATPollMs, keyCATDelayMs, keyCATOffsetOn, keyCATOffsetHz, keyCATDigitalDefault, keyCATShareEnabled, keyCATSharePort, keyCATShareProto, keyCATShareTCIPort, keyCATDigiUSB)
|
||||
m, err := a.settings.GetMany(a.ctx, keyCATEnabled, keyCATBackend, keyCATOmniRigNum, keyCATOmniRigVFO, keyCATFlexHost, keyCATFlexPort, keyCATFlexSpots, keyCATFlexDVKDax, keyCATFlexDecodeSpots, keyCATFlexDecodeSecs, keyCATXieguPort, keyCATXieguBaud, keyCATXieguAddr, keyCATXieguPTTLine, keyCATYaesuPort, keyCATYaesuBaud, keyCATYaesuRTTYUSB, keyCATKenwoodPort, keyCATKenwoodBaud, keyCATKenwoodHost, keyCATKenwoodLink, keyCATYaesuLowLines, keyCATKenwoodLowLines, keyCATKenwoodDataMode, keyCATIcomPort, keyCATIcomBaud, keyCATIcomAddr, keyCATIcomNetHost, keyCATIcomNetUser, keyCATIcomNetPass, keyCATIcomNetAudio, keyCATTCIHost, keyCATTCIPort, keyCATTCISpots, keyCATPttHotkeyEnabled, keyCATPttHotkey, keyCATPttHotkeyToggle, keyCATPollMs, keyCATDelayMs, keyCATOffsetOn, keyCATOffsetHz, keyCATDigitalDefault, keyCATShareEnabled, keyCATSharePort, keyCATShareProto, keyCATShareTCIPort, keyCATDigiUSB)
|
||||
if err != nil {
|
||||
return CATSettings{}, err
|
||||
}
|
||||
@@ -8343,6 +8348,7 @@ func (a *App) GetCATSettings() (CATSettings, error) {
|
||||
KenwoodLink: kenwoodLinkOr(m[keyCATKenwoodLink], m[keyCATKenwoodHost]),
|
||||
KenwoodBaud: 9600,
|
||||
YaesuLowLines: m[keyCATYaesuLowLines] == "1",
|
||||
YaesuRTTYUSB: m[keyCATYaesuRTTYUSB] == "1",
|
||||
KenwoodLowLines: m[keyCATKenwoodLowLines] == "1",
|
||||
KenwoodDataMode: m[keyCATKenwoodDataMode],
|
||||
IcomPort: m[keyCATIcomPort],
|
||||
@@ -8556,6 +8562,7 @@ func (a *App) SaveCATSettings(s CATSettings) error {
|
||||
keyCATKenwoodLink: kenwoodLinkOr(s.KenwoodLink, s.KenwoodHost),
|
||||
keyCATKenwoodBaud: strconv.Itoa(s.KenwoodBaud),
|
||||
keyCATYaesuLowLines: b01(s.YaesuLowLines),
|
||||
keyCATYaesuRTTYUSB: b01(s.YaesuRTTYUSB),
|
||||
keyCATKenwoodLowLines: b01(s.KenwoodLowLines),
|
||||
keyCATKenwoodDataMode: strings.ToLower(strings.TrimSpace(s.KenwoodDataMode)),
|
||||
keyCATIcomPort: strings.TrimSpace(s.IcomPort),
|
||||
@@ -16283,6 +16290,7 @@ func (a *App) reloadCAT() {
|
||||
// (a rig file that hides the VFO, a Freq property meaning A on one model
|
||||
// and B on another); talking to the radio directly removes it.
|
||||
yz := cat.NewYaesu(s.YaesuPort, s.YaesuBaud, s.DigitalDefault)
|
||||
yz.SetRTTYUpper(s.YaesuRTTYUSB)
|
||||
yz.SetLowerLines(s.YaesuLowLines)
|
||||
a.cat.Start(yz)
|
||||
case "kenwood", "elecraft":
|
||||
|
||||
+6
-2
@@ -16,7 +16,9 @@
|
||||
"ADIF export: a record is written on one line again. ADDRESS is a multi-line field by the standard and callbooks and other loggers fill it that way — “Kabul”, four blank lines, “Afghanistan” — and OpsLog wrote it out as it was, so a record ran down a dozen lines with the next apparently starting in the middle of the page. Line breaks inside a value are now joined with a comma, which is how an address reads on one line anyway. The files were always valid (ADIF counts bytes); they were unreadable.",
|
||||
"Club Log uploads are no longer refused as “not configured”. The check added for services with no credentials demanded a Club Log API key, which nobody has ever set — OpsLog carries its own application key — so an operator whose live upload had worked for months was turned away when sending QSOs by hand. Each service’s requirements now live beside the uploader that enforces them, and the message names the fields that are actually missing.",
|
||||
"FT map: the callsign, square and report show on hover again. The invisible circle that catches the clicks sits on top of the dot, so it takes the hover too — and the label was bound only to the dot underneath, which left the map silent from the moment the stations became clickable.",
|
||||
"Yaesu CAT now drives the older radios. The FTDX10, FT-991A, FT-891 and FT-710 write a frequency in nine digits; everything before them — FTDX3000, FTDX5000, FTDX1200, FT-2000, FT-950, FT-450 — writes eight and answers a nine-digit command with a rejection, which is what an FTDX3000 owner saw: every FA refused and a radio that would not follow. The width is taken from the rig’s own reply rather than from a table of models, so a set is in the format that radio speaks — including models this backend has never heard of."
|
||||
"Yaesu CAT now drives the older radios. The FTDX10, FT-991A, FT-891 and FT-710 write a frequency in nine digits; everything before them — FTDX3000, FTDX5000, FTDX1200, FT-2000, FT-950, FT-450 — writes eight and answers a nine-digit command with a rejection, which is what an FTDX3000 owner saw: every FA refused and a radio that would not follow. The width is taken from the rig’s own reply rather than from a table of models, so a set is in the format that radio speaks — including models this backend has never heard of.",
|
||||
"Typing a digital watering hole sets the mode with it. A spot click has always carried one; a frequency typed by hand carried none, so the rig stayed in SSB on 28.074 while the operator waited for decodes. Same table and same tolerance as a spot (±3 kHz of a known FT8/FT4/JS8 frequency), only towards the digital modes: tuning away from one leaves the mode alone, because there the frequency says nothing about what you mean to do.",
|
||||
"Yaesu: RTTY can be set on USB (Settings → CAT). ADIF records only “RTTY” and the rig has both sidebands, so the log cannot answer for it — the older RTTY-L stays the default, and a station whose FSK controller wants the upper one says so once."
|
||||
],
|
||||
"fr": [
|
||||
"[NEW] Les couleurs de mise en évidence WSJT-X / JTDX sont au choix (Réglages → UDP), une par verdict — watchlist, nouveau DXCC, nouvelle bande, contactée. Seul le fond se règle : la couleur du texte en est déduite, pour qu’une couleur choisie ne revienne jamais illisible dans la fenêtre du décodeur. L’option « griser les stations déjà contactées » garde sa raison d’être — elle décide SI les doublons sont marqués, pas de quelle couleur — et s’appelle désormais « Marquer les stations déjà contactées ».",
|
||||
@@ -32,7 +34,9 @@
|
||||
"Export ADIF : un enregistrement tient de nouveau sur une ligne. ADDRESS est un champ multiligne selon la norme, et les callbooks comme les autres logiciels le remplissent ainsi — « Kabul », quatre lignes vides, « Afghanistan » — qu’OpsLog recopiait tel quel : un enregistrement s’étalait sur une douzaine de lignes, le suivant semblant commencer au milieu de la page. Les retours à la ligne dans une valeur sont désormais réunis par une virgule, ce qui est de toute façon la façon de lire une adresse sur une ligne. Les fichiers étaient valides (l’ADIF compte les octets) ; ils étaient illisibles.",
|
||||
"Les envois vers Club Log ne sont plus refusés comme « non configuré ». Le contrôle ajouté pour les services sans identifiants réclamait une clé API Club Log que personne n’a jamais saisie — OpsLog embarque la sienne — et un opérateur dont l’envoi automatique fonctionnait depuis des mois se voyait éconduit au moment d’envoyer des QSO à la main. Les exigences de chaque service vivent désormais à côté du code qui les applique, et le message nomme les champs réellement manquants.",
|
||||
"Carte FTx : l’indicatif, le locator et le report réapparaissent au survol. Le cercle invisible qui capte les clics est au-dessus du point, donc il capte aussi le survol — et l’étiquette n’était liée qu’au point du dessous, ce qui rendait la carte muette dès que les stations sont devenues cliquables.",
|
||||
"Le CAT Yaesu pilote désormais les postes plus anciens. FTDX10, FT-991A, FT-891 et FT-710 écrivent une fréquence sur neuf chiffres ; tout ce qui précède — FTDX3000, FTDX5000, FTDX1200, FT-2000, FT-950, FT-450 — l’écrit sur huit et rejette une commande à neuf chiffres. C’est ce que voyait un possesseur de FTDX3000 : chaque FA refusée et une radio qui ne suivait pas. Le format est pris dans la réponse du poste plutôt que dans une table de modèles : l’envoi part donc dans la langue de cette radio-là, y compris pour des modèles que ce backend ne connaît pas."
|
||||
"Le CAT Yaesu pilote désormais les postes plus anciens. FTDX10, FT-991A, FT-891 et FT-710 écrivent une fréquence sur neuf chiffres ; tout ce qui précède — FTDX3000, FTDX5000, FTDX1200, FT-2000, FT-950, FT-450 — l’écrit sur huit et rejette une commande à neuf chiffres. C’est ce que voyait un possesseur de FTDX3000 : chaque FA refusée et une radio qui ne suivait pas. Le format est pris dans la réponse du poste plutôt que dans une table de modèles : l’envoi part donc dans la langue de cette radio-là, y compris pour des modèles que ce backend ne connaît pas.",
|
||||
"Taper une fréquence d’appel numérique règle le mode avec elle. Un clic sur un spot en portait un depuis toujours ; une fréquence tapée à la main n’en portait aucun, si bien que le poste restait en SSB sur 28.074 pendant qu’on attendait les décodages. Même table et même tolérance qu’un spot (±3 kHz d’une fréquence FT8/FT4/JS8 connue), et seulement vers les modes numériques : en s’en éloignant le mode n’est pas touché, car là la fréquence ne dit rien de ce qu’on veut faire.",
|
||||
"Yaesu : le RTTY peut être placé en USB (Réglages → CAT). L’ADIF n’enregistre que « RTTY » et le poste a les deux bandes latérales : le log ne peut pas répondre à sa place. Le RTTY-L ancien reste par défaut, et une station dont l’interface FSK veut la supérieure le dit une fois."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
+24
-1
@@ -5926,7 +5926,29 @@ export default function App() {
|
||||
const mhz = parseFloat(mhzStr);
|
||||
if (!Number.isFinite(mhz) || mhz < 0.1 || mhz > 3000) return;
|
||||
noteManualEdit();
|
||||
SetCATFrequency(Math.round(mhz * 1_000_000)).catch(() => {});
|
||||
const hz = Math.round(mhz * 1_000_000);
|
||||
SetCATFrequency(hz).catch(() => {});
|
||||
tuneModeForWateringHole(hz);
|
||||
};
|
||||
|
||||
// 28.074 IS FT8, and typing it says so.
|
||||
//
|
||||
// A spot click has always carried a mode; a frequency typed by hand carried
|
||||
// none, so the rig stayed in whatever it was — an FTDX3000 landing on 28.074
|
||||
// in USB while the operator waited for decodes. Nobody tunes a watering hole
|
||||
// to listen to it in SSB, and this is the same table and the same tolerance a
|
||||
// spot click is judged with (±3 kHz of a known digital frequency).
|
||||
//
|
||||
// Only when it actually changes something, and only towards the digital
|
||||
// modes: tuning away from 28.074 leaves the mode alone, because there the
|
||||
// frequency says nothing about what the operator means to do.
|
||||
const tuneModeForWateringHole = (hz: number) => {
|
||||
const m = inferDigitalMode(hz);
|
||||
if (!m || m === mode) return;
|
||||
setMode(m);
|
||||
applyModePreset(m);
|
||||
if (catState.enabled && catState.connected && !locks.mode) SetCATMode(m).catch(() => {});
|
||||
ConfigureDecoderMode(m).catch(() => {});
|
||||
};
|
||||
// Carry out what was typed in the call field. Bands go through the ordinary
|
||||
// band change, so the antennas, the power table and the outbound integrations
|
||||
@@ -5944,6 +5966,7 @@ export default function App() {
|
||||
const b = bandForMHz(hz / 1_000_000);
|
||||
if (b) setBand(b);
|
||||
if (catState.enabled && catState.connected) SetCATFrequency(hz).catch(() => {});
|
||||
tuneModeForWateringHole(hz);
|
||||
showToast((hz / 1_000_000).toFixed(3) + ' MHz');
|
||||
};
|
||||
|
||||
|
||||
@@ -1628,7 +1628,7 @@ function SettingsModalImpl({ onClose, onSaved, initialSection, onMainPaneChanged
|
||||
const [icomCustom, setIcomCustom] = useState(false);
|
||||
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_link: 'usb', kenwood_data_mode: 'usb', xiegu_port: '', xiegu_baud: 19200, xiegu_addr: 0x70, xiegu_ptt_line: '',
|
||||
yaesu_port: '', yaesu_baud: 38400, yaesu_low_lines: false, yaesu_rtty_usb: 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,
|
||||
@@ -3532,6 +3532,17 @@ function SettingsModalImpl({ onClose, onSaved, initialSection, onMainPaneChanged
|
||||
</label>
|
||||
<span className="text-xs text-muted-foreground">{t('cat.lowerLinesHint')}</span>
|
||||
</div>
|
||||
{/* ADIF records "RTTY" and nothing more, and the rig has two
|
||||
sidebands to put it on — so this is the operator's answer, not
|
||||
something the log can supply. */}
|
||||
<div className="col-span-2 space-y-1">
|
||||
<label className="flex items-center gap-2 text-xs cursor-pointer">
|
||||
<Checkbox checked={!!(catCfg as any).yaesu_rtty_usb}
|
||||
onCheckedChange={(c) => setCatCfg((s) => ({ ...s, yaesu_rtty_usb: !!c } as any))} />
|
||||
{t('cat.yaesuRttyUsb')}
|
||||
</label>
|
||||
<span className="text-xs text-muted-foreground">{t('cat.yaesuRttyUsbHint')}</span>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{['icom', 'xiegu', 'kenwood', 'elecraft'].includes(catCfg.backend) && (
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -2379,6 +2379,7 @@ export namespace main {
|
||||
kenwood_baud: number;
|
||||
kenwood_data_mode: string;
|
||||
yaesu_low_lines: boolean;
|
||||
yaesu_rtty_usb: boolean;
|
||||
kenwood_low_lines: boolean;
|
||||
icom_port: string;
|
||||
icom_baud: number;
|
||||
@@ -2432,6 +2433,7 @@ export namespace main {
|
||||
this.kenwood_baud = source["kenwood_baud"];
|
||||
this.kenwood_data_mode = source["kenwood_data_mode"];
|
||||
this.yaesu_low_lines = source["yaesu_low_lines"];
|
||||
this.yaesu_rtty_usb = source["yaesu_rtty_usb"];
|
||||
this.kenwood_low_lines = source["kenwood_low_lines"];
|
||||
this.icom_port = source["icom_port"];
|
||||
this.icom_baud = source["icom_baud"];
|
||||
|
||||
+21
-4
@@ -108,8 +108,10 @@ type Yaesu struct {
|
||||
// and VS is used — see ReadState.
|
||||
rxVFOCmd string
|
||||
// freqDigits is how many digits this rig writes a frequency in, LEARNED from
|
||||
// its own replies. See setFreqWidth.
|
||||
// its own replies. See learnFreqWidth.
|
||||
freqDigits int
|
||||
// rttyUpper picks RTTY-U over RTTY-L — see SetRTTYUpper.
|
||||
rttyUpper bool
|
||||
|
||||
curFreq int64
|
||||
curRXFreq int64
|
||||
@@ -140,6 +142,18 @@ func NewYaesu(portName string, baud int, digital string) *Yaesu {
|
||||
return &Yaesu{portName: strings.TrimSpace(portName), baud: baud, digital: digital, curVFO: "A"}
|
||||
}
|
||||
|
||||
// SetRTTYUpper chooses which sideband RTTY is set on.
|
||||
//
|
||||
// Yaesu has both — MD06 is RTTY-L, MD09 is RTTY-U — and ADIF has neither: it
|
||||
// says "RTTY" and stops there, so the rig cannot be driven from the logged mode
|
||||
// alone. LSB is the older convention and stays the default; an operator whose
|
||||
// FSK controller or decoder wants the other one says so once here.
|
||||
func (y *Yaesu) SetRTTYUpper(v bool) {
|
||||
y.mu.Lock()
|
||||
defer y.mu.Unlock()
|
||||
y.rttyUpper = v
|
||||
}
|
||||
|
||||
// SetLowerLines chooses whether DTR and RTS are deasserted on connect. Set
|
||||
// before Connect.
|
||||
func (y *Yaesu) SetLowerLines(v bool) {
|
||||
@@ -375,7 +389,7 @@ func (y *Yaesu) SetMode(mode string) error {
|
||||
if y.port == nil {
|
||||
return fmt.Errorf("yaesu: not connected")
|
||||
}
|
||||
d := yaesuModeDigit(mode, y.curFreq)
|
||||
d := yaesuModeDigit(mode, y.curFreq, y.rttyUpper)
|
||||
if d == 0 {
|
||||
return fmt.Errorf("yaesu: no CAT mode for %q", mode)
|
||||
}
|
||||
@@ -608,7 +622,7 @@ func resolveYaesuVFOs(freqA, freqB int64, vfo string, split bool) (tx, rx int64,
|
||||
// yaesuModeDigit maps an ADIF mode to the MD digit. SSB has no single digit —
|
||||
// the sideband follows the worldwide convention (LSB below 10 MHz, USB above),
|
||||
// which is why the current frequency is part of the decision.
|
||||
func yaesuModeDigit(mode string, freqHz int64) byte {
|
||||
func yaesuModeDigit(mode string, freqHz int64, rttyUpper bool) byte {
|
||||
switch strings.ToUpper(strings.TrimSpace(mode)) {
|
||||
case "SSB":
|
||||
if freqHz > 0 && freqHz < 10_000_000 {
|
||||
@@ -626,7 +640,10 @@ func yaesuModeDigit(mode string, freqHz int64) byte {
|
||||
case "AM":
|
||||
return '5'
|
||||
case "RTTY":
|
||||
return '6'
|
||||
if rttyUpper {
|
||||
return '9' // RTTY-U
|
||||
}
|
||||
return '6' // RTTY-L, the older convention
|
||||
case "":
|
||||
return 0
|
||||
default:
|
||||
|
||||
@@ -123,7 +123,7 @@ func TestYaesuModeDigit(t *testing.T) {
|
||||
{"", 14074000, 0}, // nothing to set
|
||||
}
|
||||
for _, c := range cases {
|
||||
if got := yaesuModeDigit(c.mode, c.hz); got != c.want {
|
||||
if got := yaesuModeDigit(c.mode, c.hz, false); got != c.want {
|
||||
t.Errorf("yaesuModeDigit(%q, %d) = %q, want %q", c.mode, c.hz, got, c.want)
|
||||
}
|
||||
}
|
||||
@@ -406,3 +406,22 @@ func TestYaesuAntennaCommand(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ADIF says "RTTY" and stops there, but Yaesu has both sidebands and the rig
|
||||
// has to be told one. LSB is the older convention and the default; the other is
|
||||
// a station's own choice, made once.
|
||||
func TestYaesuRTTYSideband(t *testing.T) {
|
||||
if got := yaesuModeDigit("RTTY", 14_080_000, false); got != '6' {
|
||||
t.Errorf("RTTY = %q, want RTTY-L", got)
|
||||
}
|
||||
if got := yaesuModeDigit("RTTY", 14_080_000, true); got != '9' {
|
||||
t.Errorf("RTTY (upper) = %q, want RTTY-U", got)
|
||||
}
|
||||
// The switch is about RTTY and nothing else.
|
||||
if got := yaesuModeDigit("FT8", 28_074_000, true); got != 'C' {
|
||||
t.Errorf("FT8 = %q, want DATA-U", got)
|
||||
}
|
||||
if got := yaesuModeDigit("CW", 14_030_000, true); got != '3' {
|
||||
t.Errorf("CW = %q, want CW-U", got)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user