feat(ftmap): a layer for who hears me
The map drew one direction of every path on it: what this receiver decoded. The reverse — which stations are reporting our own transmissions — is the half an operator cannot see from their own radio, and on FT8 it is the half that decides whether calling is worth the cycle. It is the narrowest slice of the PSK Reporter feed there is. The v2 topic is pskr/filter/v2/<band>/<mode>/<tx call>/<rx call>/… so putting the operator's callsign in the TRANSMIT level makes the broker send nothing else. For scale, from internal/pskr's own measured numbers: four bands unfiltered is 83 messages a second, filtered on the receiver's square 0.2 to 1.2 a second — one callsign in the transmit level is a handful per FT8 cycle however open the band is. Both grids are in the payload, so the arc is arithmetic and there is no lookup. internal/pskrme, with its own connection, for the same reason internal/pskrtgt has its own: the three want slices of the feed that cannot be filtered out of one another. It also means this keeps working with the band-opening watch off — hanging it off that feed's lifecycle would have made it fail silently for anyone not chasing openings. Nothing is persisted. One entry per STATION inside a fifteen-minute window, carrying its freshest report: PSK Reporter's uploaders batch, many every five minutes, so a tighter window would show a fraction of who actually heard the last few calls. Stop clears the window, or switching the layer back on would redraw who heard us before it was on. On the map the layer is dashed and single-coloured. Solid is what we decoded, dashed is somebody decoding us; colour alone could not carry that distinction next to fourteen band colours. The receivers are rings rather than filled dots for the same reason. Per profile, since the callsign IS the subscription — a switch resubscribes rather than going on reporting who hears the previous station.
This commit is contained in:
@@ -56,6 +56,7 @@ import (
|
||||
"hamlog/internal/powergenius"
|
||||
"hamlog/internal/profile"
|
||||
"hamlog/internal/pskr"
|
||||
"hamlog/internal/pskrme"
|
||||
"hamlog/internal/pskrtgt"
|
||||
"hamlog/internal/psu"
|
||||
"hamlog/internal/qslcard"
|
||||
@@ -773,6 +774,11 @@ type App struct {
|
||||
// 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
|
||||
// hearMe is the THIRD PSK Reporter connection: who is reporting our own
|
||||
// transmissions, for the reverse layer on the FT map. Its own connection
|
||||
// for the same reason as pskTgt — a different slice of the feed, and one
|
||||
// that must keep working with the opening watch switched off.
|
||||
hearMe *pskrme.Watcher
|
||||
// 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.
|
||||
@@ -1732,6 +1738,9 @@ func (a *App) startup(ctx context.Context) {
|
||||
// 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()
|
||||
// The reverse layer. Needs the CALLSIGN rather than the grid, so it goes
|
||||
// after the profile is scoped, which it already is by here.
|
||||
a.startHearMe()
|
||||
// Auto-call. After the watch list and the logbook: the ladder is meaningless
|
||||
// without either, and it must never call anybody on a log it cannot read.
|
||||
a.startAutoCall()
|
||||
@@ -17076,6 +17085,10 @@ func (a *App) reloadAfterProfileSwitch() {
|
||||
// Same reasoning for the satellite tracker: it transmits, and the new profile
|
||||
// may be a different station on a different antenna.
|
||||
a.StopSatelliteTracking()
|
||||
// A new profile is usually a new callsign, and the callsign IS this
|
||||
// subscription — left alone it would go on reporting who hears the previous
|
||||
// station.
|
||||
a.startHearMe()
|
||||
}
|
||||
|
||||
// DuplicateProfile clones an existing profile under newName. Useful when
|
||||
|
||||
Reference in New Issue
Block a user