fix(sat,decodes): the left column holds position too, and drift stops lying
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.
This commit is contained in:
+58
-12
@@ -50,18 +50,28 @@ type interruptible interface {
|
||||
// and RxFreqHz is the active VFO (where they listen). When not split,
|
||||
// RxFreqHz is 0 — the UI shouldn't show a redundant RX field.
|
||||
type RigState struct {
|
||||
Enabled bool `json:"enabled"` // user toggled CAT on
|
||||
Connected bool `json:"connected"` // backend says rig is online
|
||||
Backend string `json:"backend,omitempty"` // active backend name
|
||||
RigNum int `json:"rig_num,omitempty"` // OmniRig slot 1 or 2 (when applicable)
|
||||
Rig string `json:"rig,omitempty"` // rig model (best-effort)
|
||||
FreqHz int64 `json:"freq_hz,omitempty"` // TX freq (= active VFO when not split)
|
||||
RxFreqHz int64 `json:"freq_rx_hz,omitempty"` // RX freq, only set when Split
|
||||
Split bool `json:"split,omitempty"` // rig is in split mode
|
||||
Mode string `json:"mode,omitempty"` // ADIF mode (SSB/CW/DATA/AM/FM/RTTY)
|
||||
Band string `json:"band,omitempty"` // computed from FreqHz
|
||||
Vfo string `json:"vfo,omitempty"` // "A" | "B" | "AA" | "AB" | "BA" | "BB"
|
||||
Error string `json:"error,omitempty"` // last connect/poll error if any
|
||||
Enabled bool `json:"enabled"` // user toggled CAT on
|
||||
Connected bool `json:"connected"` // backend says rig is online
|
||||
Backend string `json:"backend,omitempty"` // active backend name
|
||||
RigNum int `json:"rig_num,omitempty"` // OmniRig slot 1 or 2 (when applicable)
|
||||
Rig string `json:"rig,omitempty"` // rig model (best-effort)
|
||||
FreqHz int64 `json:"freq_hz,omitempty"` // TX freq (= active VFO when not split)
|
||||
RxFreqHz int64 `json:"freq_rx_hz,omitempty"` // RX freq, only set when Split
|
||||
Split bool `json:"split,omitempty"` // rig is in split mode
|
||||
Mode string `json:"mode,omitempty"` // ADIF mode (SSB/CW/DATA/AM/FM/RTTY)
|
||||
Band string `json:"band,omitempty"` // computed from FreqHz
|
||||
// RxBands is every band the radio currently has a receiver on, Band
|
||||
// included. One entry on a rig with one VFO; one per slice on a Flex.
|
||||
//
|
||||
// It exists because Band alone is the TRANSMIT band, and a station running
|
||||
// two slices on two bands with a decoder on each is not drifting when one
|
||||
// of them announces the band it is legitimately on. Reported for W4TE:
|
||||
// slice A on 20 m with its own WSJT-X, slice B on 40 m holding transmit
|
||||
// focus, and OpsLog telling him his 20 m decoder disagreed with a radio
|
||||
// that was on 20 m — on that slice.
|
||||
RxBands []string `json:"rx_bands,omitempty"`
|
||||
Vfo string `json:"vfo,omitempty"` // "A" | "B" | "AA" | "AB" | "BA" | "BB"
|
||||
Error string `json:"error,omitempty"` // last connect/poll error if any
|
||||
UpdatedAt time.Time `json:"updated_at,omitempty"`
|
||||
}
|
||||
|
||||
@@ -1002,11 +1012,47 @@ func (m *Manager) run(b Backend, stop, done chan struct{}, cmds chan func(), pol
|
||||
if ns.FreqHz != 0 && ns.Band == "" {
|
||||
ns.Band = BandFromHz(ns.FreqHz)
|
||||
}
|
||||
ns.RxBands = m.rxBands(ns)
|
||||
m.update(ns)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rxBands lists the bands the radio has a receiver on.
|
||||
//
|
||||
// Asked of the backend rather than derived from the state, because only the
|
||||
// backend knows: a Flex reports its slices, and everything else has exactly
|
||||
// one receiver whose band is already in the state. The transmit band is
|
||||
// always included, even on a Flex, so this can never come back empty while
|
||||
// the rig is on a frequency.
|
||||
func (m *Manager) rxBands(st RigState) []string {
|
||||
seen := map[string]bool{}
|
||||
var out []string
|
||||
add := func(b string) {
|
||||
if b = strings.ToLower(strings.TrimSpace(b)); b != "" && !seen[b] {
|
||||
seen[b] = true
|
||||
out = append(out, b)
|
||||
}
|
||||
}
|
||||
add(st.Band)
|
||||
if st.RxFreqHz != 0 {
|
||||
add(BandFromHz(st.RxFreqHz))
|
||||
}
|
||||
if fx, ok := m.FlexState(); ok {
|
||||
for _, sl := range fx.Slices {
|
||||
if sl.Band != "" {
|
||||
add(sl.Band)
|
||||
continue
|
||||
}
|
||||
// A slice the radio has reported a frequency but no band for.
|
||||
if sl.FreqHz != 0 {
|
||||
add(BandFromHz(sl.FreqHz))
|
||||
}
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (m *Manager) applyCommandDelay() {
|
||||
m.mu.RLock()
|
||||
d := m.cmdDelay
|
||||
|
||||
Reference in New Issue
Block a user