fix: a cluster spot dragged the rig from SUB back to MAIN

Reported on an FTDX101 (F4NBZ): listening on the SUB VFO, clicking a spot moved
the radio to MAIN.

SetSimplexMode is the first thing SetFrequency tries, and it means "receive and
transmit here, simplex" — OmniRig applies that to the MAIN VFO by definition. It
is there because several Icoms ignore direct FreqA/FreqB writes, so it stays for
the main VFO; on SUB it is now skipped entirely and FreqB carries the change.

The generic "Freq" property is skipped on SUB too: on several rig files it IS the
main VFO, so writing it would move the VFO the operator is not using — or pull
them back to it, which is the bug being fixed.

An operator on SUB put themselves there deliberately. A spot click asks for a
frequency, not for a change of VFO — that distinction is the whole fix, and a
test pins which property each VFO state writes.
This commit is contained in:
2026-07-29 16:07:20 +02:00
parent ee1f9ccf35
commit c297f91ca8
3 changed files with 78 additions and 8 deletions
+26 -8
View File
@@ -493,12 +493,24 @@ func (o *OmniRig) SetFrequency(hz int64) error {
// method (RX=TX=freq, simplex). It works on rigs — notably Icom (IC-9100) —
// where direct FreqA/FreqB writes are accepted but never move the radio.
// Clearing split is the right thing when tuning to a spot anyway.
// …but ONLY when the operator is on the main VFO. SetSimplexMode means
// "receive and transmit here, simplex", and OmniRig implements that on the
// MAIN VFO — so on an FTDX101 listening on SUB, clicking a cluster spot
// dragged the radio back to MAIN (F4NBZ, 2026-07-29). The operator picked SUB
// deliberately; a spot click is a request to change frequency, not to change
// VFO. On SUB the direct FreqB write below does the whole job.
onSubVFO := vfo == "B" || vfo == "BB" || vfo == "BA"
simplexOK := false
if _, err := oleutil.CallMethod(o.rig, "SetSimplexMode", int32(hz32)); err == nil {
simplexOK = true
debugLog.Printf("OmniRig.SetFrequency: SetSimplexMode(%d) OK", hz32)
} else {
debugLog.Printf("OmniRig.SetFrequency: SetSimplexMode unavailable (%v)", err)
switch {
case onSubVFO:
debugLog.Printf("OmniRig.SetFrequency: on VFO %q — skipping SetSimplexMode so the rig stays on SUB", vfo)
default:
if _, err := oleutil.CallMethod(o.rig, "SetSimplexMode", int32(hz32)); err == nil {
simplexOK = true
debugLog.Printf("OmniRig.SetFrequency: SetSimplexMode(%d) OK", hz32)
} else {
debugLog.Printf("OmniRig.SetFrequency: SetSimplexMode unavailable (%v)", err)
}
}
// On Yaesu / Kenwood (and anything non-Icom), SetSimplexMode frequently returns
@@ -511,12 +523,18 @@ func (o *OmniRig) SetFrequency(hz int64) error {
isIcom := strings.HasPrefix(strings.ToUpper(strings.TrimSpace(rigType)), "IC")
if !isIcom || !simplexOK {
prop := "FreqA"
switch vfo {
case "B", "BB", "BA":
if onSubVFO {
prop = "FreqB"
}
okAny := false
for _, p := range []string{prop, "Freq"} {
// The generic "Freq" property is written too — but NOT on SUB, where it is
// the main VFO's frequency on several rig files and would move the VFO the
// operator is not using, or pull them back to it.
props := []string{prop, "Freq"}
if onSubVFO {
props = []string{prop}
}
for _, p := range props {
if _, e := oleutil.PutProperty(o.rig, p, hz32); e != nil {
debugLog.Printf("OmniRig.SetFrequency: PutProperty(%s) error: %v", p, e)
} else {