feat: HAMLOG.online upload and confirmations, Yaesu antenna, a named port holder
HAMLOG.online is a seventh external service: one API key, one ADIF record per QSO, immediate / delayed / on-close like the rest. They publish no API documentation, so the protocol is read from THEIR OWN client — the HAMLOG Agent (github.com/hamlogonline/Agent), which is the authoritative source short of asking them: POST https://hamlog.online/api/agent/ {"ADIFADD": {"APIKEY": k, "ADIFDATA": record}} → {"STATUS":"OK"} {"KEYSTATUS": {"APIKEY": k}} → {"STATUS":"OK","CALLSIGN":…} Success is STATUS == OK, not "no ERROR field": their failure carries ERROR and no STATUS, and reading an unknown reply — a proxy page, a maintenance notice — as an acceptance is how a contact goes missing without anyone noticing. KEYSTATUS buys something no other service here offers: the key can be checked BEFORE the first QSO, and the answer names the account. A key pasted from another callsign is caught in the settings panel rather than through a week of silent refusals. Their confirmations are also an award source now, ticked like LoTW rather than expressed through "custom". It reads the ADIF extras, not a column: the standard names a field for hamlog.EU and none for hamlog.ONLINE, and borrowing the other site's field would write a falsehood into every exported log. Three plausible key names from their own export are accepted too, so nobody has to rename a column by hand after an export. Yaesu gains antenna selection (AN), remembered per band — the antenna picked on a band comes back with it, with no table to fill in anywhere. Rigs with one socket never answer AN and never show the row; the log says which case it is. And a serial port that is refused now names its likely holder. OmniRig stays resident once activated and keeps the port of the rig configured in it, so a native backend never gets it — "Serial port busy" alone accused nobody, and an FTDX10 spent a morning being blamed for it.
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
package cat
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParseYaesuFreq(t *testing.T) {
|
||||
cases := []struct {
|
||||
@@ -380,3 +383,26 @@ func TestYaesuModeVFOSuffix(t *testing.T) {
|
||||
t.Errorf("setting CW on main sends %q, want MD03;", cmd)
|
||||
}
|
||||
}
|
||||
|
||||
// The antenna command, as the FTDX10 reference gives it: AN + receiver + jack.
|
||||
// The jack is clamped rather than trusted — a panel bug that sent AN09 would be
|
||||
// answered by the rig with silence, and the operator would be left wondering
|
||||
// which antenna they were on.
|
||||
func TestYaesuAntennaCommand(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
in int
|
||||
want string
|
||||
}{
|
||||
{1, "AN01;"},
|
||||
{2, "AN02;"},
|
||||
{3, "AN03;"},
|
||||
{0, "AN01;"}, // below range → the first jack
|
||||
{9, "AN03;"}, // above range → the last
|
||||
{-1, "AN01;"},
|
||||
} {
|
||||
got := fmt.Sprintf("AN0%d;", clampInt(tc.in, 1, 3))
|
||||
if got != tc.want {
|
||||
t.Errorf("antenna %d → %q, want %q", tc.in, got, tc.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user