feat(app): auto-call, PSK Reporter analysis and the decode band change
The Wails boundary for the two features above, plus the pieces that belong to neither: - decodes are cut into periods PER RECEIVER, and judged 0.8 s after the last one arrives rather than a slot and four seconds after the period they belong to. That stamp is the START of the slot, thirteen seconds before its decodes exist, so every answer left four seconds into the next slot and the decoder began its call late. - WSJT-X colouring can grey out a station already worked on this band AND in this mode. Its own switch, off by default: the other three verdicts pick out a handful of decodes, this one can match most of a period on a full log. - the watch list's contest auto-add takes a list of callsigns as well as a pattern. A pattern collects a fleet that shares a string; it cannot collect the station taking part under a callsign that says nothing about the event.
This commit is contained in:
@@ -753,6 +753,9 @@ type App struct {
|
||||
// is consulted once per message.
|
||||
chaseBandsMu sync.RWMutex
|
||||
chaseBands map[string]bool
|
||||
// The Chase new panel's OWN band filter, as the set switched off. Read per
|
||||
// message like the list above, so an atomic rather than a settings lookup.
|
||||
chaseNewBandsOff atomic.Value // map[string]bool
|
||||
// pskr is the PSK Reporter MQTT feed, up only while the opening watch is on.
|
||||
// It is the source that makes VHF detection work at all: the cluster and RBN
|
||||
// carry a handful of 6 m spots where PSK Reporter carries hundreds.
|
||||
@@ -773,8 +776,12 @@ type App struct {
|
||||
// FT8 window and an FT4 one do not even share a period length — and one
|
||||
// buffer for both cut every slot into fragments, each judged as a period of
|
||||
// its own. The engine then counted a missed period several times a slot.
|
||||
acPeriod map[string]string
|
||||
acAt map[string]time.Time
|
||||
acPeriod map[string]string
|
||||
acAt map[string]time.Time
|
||||
// acFed is when the last decode of the open period ARRIVED, wall clock. The
|
||||
// period's own timestamp cannot answer "has it gone quiet" — it is the start
|
||||
// of the slot, thirteen seconds before its decodes exist.
|
||||
acFed map[string]time.Time
|
||||
acTR map[string]int
|
||||
acBuf map[string][]acDecode
|
||||
acTX autocall.TXState
|
||||
@@ -782,6 +789,10 @@ type App struct {
|
||||
acLastJudge time.Time
|
||||
// acTXPeriod is the last transmit period already counted — see autoCallNoteTX.
|
||||
acTXPeriod string
|
||||
// What the decodes panel is SHOWING, and whether it is publishing at all.
|
||||
// The panel owns the filters; this is its answer, not a second copy of them.
|
||||
acVisible map[string]bool
|
||||
acVisibleOn bool
|
||||
// Self-spot throttle: when and on what frequency we last announced ourselves.
|
||||
// Held in memory only — a restart legitimately re-announces the station.
|
||||
selfSpotMu sync.Mutex
|
||||
@@ -1653,6 +1664,7 @@ func (a *App) startup(ctx context.Context) {
|
||||
a.startGridCache()
|
||||
a.chaseNew = newChaseNewStore()
|
||||
a.refreshChaseNew()
|
||||
a.refreshChaseNewBands()
|
||||
// PSK Reporter. After the operator's grid is known: without it there is no
|
||||
// distance to measure and no receiver squares to filter on, so it stays down.
|
||||
a.startBandOpenFeed()
|
||||
@@ -20578,6 +20590,15 @@ func (a *App) SaveChaseSettings(cs ChaseSettings) error {
|
||||
a.clusterStatusMu.Lock()
|
||||
a.clusterStatusIdx = nil
|
||||
a.clusterStatusMu.Unlock()
|
||||
// Chase new judges each decode AS IT ARRIVES and keeps only what was new at
|
||||
// that moment, so its list is a set of verdicts reached under the old rule —
|
||||
// and nothing in it would ever be re-judged. Switching to "new only" left
|
||||
// rows listed that are merely unconfirmed; switching the other way could not
|
||||
// bring back what had already been refused. Emptied, it refills from the
|
||||
// live feed within a period or two, under the rule now in force.
|
||||
if a.chaseNew != nil {
|
||||
a.chaseNew.clear()
|
||||
}
|
||||
// The frontend caches resolved verdicts and only asks about unknown keys —
|
||||
// without this it kept judging half the screen under the OLD rules until a
|
||||
// restart, which read as the new mode simply not working.
|
||||
|
||||
Reference in New Issue
Block a user