Two things. The sky plot and the position share the left column now, and the button that opens it says so the way the right one does — it was a radar icon, left over from when it toggled a plot inside the readout column, and the gesture is the same one on both sides. The plot and the numbers are the same answer at two precisions: azimuth and elevation drawn, then written out to the digit. Having them at opposite ends of the window meant reading a bearing off one side and finding it on the other. And the band-drift warning, reported by W4TE. It compared the decoder's announced band against RigState.Band, which is the TRANSMIT band — so with slice A on 20 m running its own WSJT-X, slice B on 40 m, and transmit focus on B, the 20 m decoder was told the rig was on 40 m while the slice it listens to had been on 20 m throughout. The panel's own comment had accepted this as a line that setup could read past; it is worse than that, because the warning names a band and asserts something false about the radio. RigState now carries RxBands: every band the rig has a receiver on. One entry on a single-VFO rig, one per slice on a Flex, the transmit band always included so it cannot come back empty while the rig is on a frequency. The warning fires only when the decoder announces a band NOTHING on the radio is on, which is what it was always for and what a lost CAT link actually looks like.
67 lines
2.0 KiB
Go
67 lines
2.0 KiB
Go
package cat
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// RxBands is what stops the decode panel's band-drift warning from lying to a
|
|
// station running two slices.
|
|
//
|
|
// Reported for W4TE: slice A on 20 m with its own WSJT-X, slice B on 40 m
|
|
// holding transmit focus. RigState.Band is the TRANSMIT band, so the 20 m
|
|
// decoder was told "the rig is on 40M" while the slice it listens to had been
|
|
// on 20 m the whole time.
|
|
func TestRxBandsAlwaysCarriesTheTransmitBand(t *testing.T) {
|
|
m := &Manager{}
|
|
got := m.rxBands(RigState{FreqHz: 14074000, Band: "20m"})
|
|
if len(got) != 1 || got[0] != "20m" {
|
|
t.Fatalf("got %v, want [20m]", got)
|
|
}
|
|
}
|
|
|
|
// A split rig receives on one band and transmits on another — cross-band split
|
|
// is unusual but legal, and the receive side is where a decoder listens.
|
|
func TestRxBandsIncludesTheSplitReceiveBand(t *testing.T) {
|
|
m := &Manager{}
|
|
got := m.rxBands(RigState{FreqHz: 14074000, Band: "20m", RxFreqHz: 7074000, Split: true})
|
|
if !has(got, "20m") || !has(got, "40m") {
|
|
t.Fatalf("got %v, want both 20m and 40m", got)
|
|
}
|
|
}
|
|
|
|
// Nothing to report when the rig is on no frequency: an empty list means "there
|
|
// is nothing to compare with", and the panel treats it as such rather than as
|
|
// "the radio is on no band", which would warn about every decode.
|
|
func TestRxBandsIsEmptyWithNoFrequency(t *testing.T) {
|
|
m := &Manager{}
|
|
if got := m.rxBands(RigState{}); len(got) != 0 {
|
|
t.Fatalf("got %v, want nothing", got)
|
|
}
|
|
}
|
|
|
|
// Deduplicated and lower-cased, because the panel compares strings: two slices
|
|
// on the same band are one band, and "20M" from a backend must match "20m" from
|
|
// BandFromHz.
|
|
func TestRxBandsIsNormalised(t *testing.T) {
|
|
m := &Manager{}
|
|
got := m.rxBands(RigState{FreqHz: 14074000, Band: "20M", RxFreqHz: 14080000})
|
|
if len(got) != 1 || got[0] != "20m" {
|
|
t.Fatalf("got %v, want [20m]", got)
|
|
}
|
|
for _, b := range got {
|
|
if b != strings.ToLower(b) {
|
|
t.Errorf("%q is not lower-cased", b)
|
|
}
|
|
}
|
|
}
|
|
|
|
func has(list []string, want string) bool {
|
|
for _, s := range list {
|
|
if s == want {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|