Name the band beside every frequency, and map who was heard

Two additions, both about turning a number into something meaningful.

A band column.  Next to every frequency -- on the live display, in the
line-per-hit output, in saunterbrowse's list and details -- is the name of
the band it falls in.  421 MHz is the 70 cm amateur band, and being told
so is quicker than remembering where the edges are.

The names come from the existing preset table, so there is one band plan
to keep right rather than two, but naming is not the job that table was
shaped for: several presets cover any frequency, some of them whole-tuner
sweeps that say nothing.  So the candidates are ranked.  Sweeps and the
"-complete" duplicates are dropped outright.  The narrowest of what is
left wins, because it says the most -- 146.52 MHz comes back as the 2 m
simplex calling channel rather than as the whole 2 m band.  Two exceptions
where the narrowest would be the wrong answer: ISM yields to the
allocation it shares (433.92 is 70 cm first, 915 is 33 cm first), and
shortwave broadcast yields to amateur where the two overlap, because
3.9-4.0 and 7.2-7.3 MHz are Region 1 and 3 broadcast but Region 2 amateur,
and this plan is documented as Region 2.  6 MHz really is 49 m shortwave
and is left alone.

The name is written into each capture's sidecar, so it travels with the
recording and an edit to the plan later cannot rewrite history, and
saunterbrowse searches on it: /70 cm finds the band without anyone having
to remember 420-450 MHz.

A map.  A licence says where its holder is, so a list of callsigns is also
a map.  Callsigns heard during a scan are now looked up as the transcripts
come in, announced on the display, and written to callsigns.kml in the
output directory; saunterbrowse --kml builds the same file from recordings
already on disk, and the two continue one map rather than starting two.

One placemark per station, not one per transmission: the same repeater
heard twenty times in an evening is one operator, and twenty pins on one
rooftop would say less than one.  Each pin carries the callsign, the
licensee, the town, the grid square, and every frequency and time it was
heard on.  The file is read back on open and added to, so later scans
build it up rather than replacing it.

Where a licence has no coordinates the grid square's centre is used and
the placemark says so -- a square is kilometres across where an address is
a street.  A callsign with no licence at all is still recorded, in a
folder that starts switched off, because that a station was heard is worth
keeping even when nothing says where.  A file already there that is not
readable as KML is never overwritten.

Also fixed along the way:

- The hit list's "no signals recorded yet" placeholder was one cell short
  of its row, so it landed in the SNR column and wrapped, making the panel
  taller than the layout had budgeted for and scrolling the display off a
  short terminal.  The identification column can no longer wrap either,
  which is what _hit_capacity has always assumed.

- Licence lookups now record coordinates.  The cache is versioned so that
  entries written before this are asked about again, rather than pinning
  every station to its grid square for good.

- CallsignBook.wait dropped joined threads; an all-night scan calls it
  after every transcript and the list only ever grew.

- Tests redirect XDG_CACHE_HOME, so a run no longer reads or writes the
  real lookup cache.

676 -> 761 tests.
This commit is contained in:
The Dust Council 2026-08-28 11:02:16 -07:00
parent 739a2faaf4
commit fb2bb3344b
23 changed files with 2155 additions and 42 deletions

View file

@ -1,5 +1,5 @@
.\" Generated by packaging/make-man.py -- do not edit by hand.
.TH BANDSAUNTER 1 "2026-08-22" "bandsaunter 2026-08-22_04" "User Commands"
.TH BANDSAUNTER 1 "2026-08-28" "bandsaunter 2026-08-28_01" "User Commands"
.SH NAME
bandsaunter \- scan, record and identify radio signals with an RTL-SDR
.SH SYNOPSIS
@ -659,6 +659,26 @@ Accepts: at least 0.
Do not bother transcribing captures shorter than this. Very short clips rarely contain a whole word and mostly produce noise or nothing, while still costing the processing.
.RE
.PP
.SS Callsigns
.TP
.B --callsign-lookup / --no-callsign-lookup --offline-callsigns
Look callsigns up \[em] ask the licence database who a callsign belongs to.
.br
Setting name \fBcallsign_lookup\fR, default \fByes\fR.
.RS
.PP
When someone gives their callsign, look it up and say who they are. The data is the FCC's own published licence register, which carries the licensee's name, the town they are licensed in and the coordinates that put them on the map. Only the callsign is sent, and each one is asked about once and then remembered, so this costs almost nothing. Turn it off if you would rather the scan reached the network for nothing at all -- callsigns are still picked out of the transcripts, and the prefix still says which country and which US district they belong to.
.RE
.TP
.B --kml
Map file \[em] KML map of where the stations heard are licensed (blank = none).
.br
Setting name \fBkml_file\fR, default \fBcallsigns.kml\fR.
.RS
.PP
The name of a map file, kept in the output directory, of everyone who identified themselves. Each station is one pin: the callsign, who holds the licence, where they are licensed, and every frequency and time you heard them. It is added to as the scan runs and again by later scans, so it builds up into a picture of what you can hear from where you are. KML is the format Google Earth uses; QGIS, Marble and OsmAnd read it too. Leave it blank if you do not want the map.
.RE
.PP
.SS Run control
.TP
.B --cycles
@ -761,6 +781,19 @@ sweeps every Morse segment of every amateur band, and
.IR 2m\-complete ", " 70cm\-complete
and their like sweep a whole amateur band end to end rather than one segment
of it.
.PP
The same plan names what is heard. Beside every frequency on the display,
and in the line\-per\-hit output, is the band it falls in: a signal at
421 MHz is labelled
.IR "70 cm Amateur" ,
one at 462.5625 MHz is
.IR "GMRS / FRS" ,
and 162.55 MHz is
.IR "NOAA Weather Radio" .
Where several allocations overlap, the narrowest wins, because it says the
most \[em] 146.52 MHz is named as the 2 m simplex calling channel rather than
as the whole 2 m band. The name is written into each recording's sidecar as
well, so it stays with the capture.
.SH LOCK-OUTS
Every receiving setup has a few frequencies not worth stopping on: a pager
transmitter down the road, a nearby data link, or a spurious signal the
@ -901,6 +934,39 @@ than a directory of placeholders.
.BR saunterbrowse (1)
reads these back, and lists any callsigns it finds in them with the licence
they belong to.
.SH THE MAP
A callsign heard in a transcript is looked up in the FCC's published licence
data, which gives the licensee, the town, and coordinates. Those go into a
KML file in the output directory \[em]
.I callsigns.kml
unless
.B \-\-kml
names another \[em] which opens in Google Earth,
.BR qgis (1),
.BR marble (1)
and OsmAnd.
.PP
One placemark per station, not one per transmission: the same repeater heard
twenty times in an evening is one operator, and twenty pins on the same
rooftop would say less than one. Each pin carries the callsign, the licensee,
where they are licensed, and every frequency and time you heard them.
.PP
The file is added to, by this scan and by later ones, so it builds up into a
picture of what the aerial can actually reach rather than a snapshot of one
evening.
.PP
Only the callsign is sent, and each is asked about once and then remembered
under
.IR ~/.cache/bandsaunter/ ,
so a net recorded night after night is looked up once.
.B \-\-no\-callsign\-lookup
stops it contacting anything at all; callsigns are still found, and the
prefix still says which country and which US district they belong to. Setting
.B \-\-kml
to nothing turns the map off.
.PP
US amateur licence records are public by law and include the licensee's
address. That is what is written.
.SH HF RECEPTION
These receivers cannot normally tune below about 24 MHz. Below that they can
sample the antenna directly instead, which opens up shortwave: broadcast,
@ -929,6 +995,12 @@ Where recordings, transcripts and logs are written, unless
.B \-\-output
says otherwise. Chosen on first run.
.TP
.I ~/bandsaunter/callsigns.kml
The map of stations heard, added to as scans run.
.TP
.I ~/.cache/bandsaunter/callsigns.json
Licence lookups already made, so they are not repeated.
.TP
.I /etc/modprobe.d/blacklist-rtlsdr.conf
Written by the package to keep the DVB-T television driver from claiming the
receiver.