Settings ▸ Lists ▸ Satellites is gone. It was a text box an operator
typed their birds into by hand, and it had nothing to do with the
satellites the tracker knew: the same station kept two lists of the same
satellites and they drifted apart. The SAT_NAME box on the entry form now
offers the followed set — or every satellite with a frequency plan when
none is followed — merged with whatever that old list still holds, read
and never written, because what it holds is somebody's past work.
And the satellite section moved out of Hardware, which it never was.
Which birds you chase, where your antenna stands and how old your
elements are is operating; the rotator inside it is the only hardware
there, and one block does not make a section a device.
Two things belong in different places, and they were in one.
Settings → Satellites now holds the setup: which satellites to follow —
the same two-column shape as the awards, for the same reason, since a
feed carries two hundred birds and an operator works six — and the
orbital elements, their age, the fetch, and pasting your own. Following
none still means every satellite with both elements and a frequency plan,
so somebody who has not chosen yet is not handed an empty tab.
The panel keeps only what a pass needs. A countdown to AOS, or to LOS
once it is up, because that is the number that decides whether you sit
down; a bar for where in the pass you are, since mid-pass the useful
question is not the clock but whether you are past the peak; rise, peak
and set with compass directions, because "rises SW" is a direction to
look in and 213° is arithmetic. Distance, altitude and footprint. And
approaching or receding, which is the sign of the whole Doppler
correction and the only thing that explains why the frequencies are
moving the way they are.
The countdowns run in the browser from two timestamps. Predicting a pass
steps the orbit across a day thirty seconds at a time, which is not
something to do once a second for a clock the page can keep itself.
Two things reported together on the new tab.
The locator: the station's is on the ACTIVE PROFILE, not in a settings
key. keyStationMyGrid is a legacy key that EnsureDefault migrated into
the profile long ago and nothing writes any more, so reading it told an
operator with a perfectly good locator on screen that he had not set one
— and refused every pass prediction on the strength of it.
The map: Leaflet stacks its panes and controls up to z-index 1000, which
without a stacking context of their own float over the whole application
— Preferences opened behind the map, its Save and Close buttons under it.
The other three maps in OpsLog each carry `isolate` for exactly this
reason; this one was missing it.
EasyComm is what satellite rotator controllers agreed on, so a box that
works with SatPC32, Gpredict or Hamlib works here. Serial or TCP, and its
own settings rather than the HF rotator's: an az/el pair is a different
machine on a different port, and an operator who has both must not have
to choose.
A great many EasyComm controllers — the Arduino trackers above all —
accept commands and never say a word back. That is legal and common, so a
silent controller is not treated as a broken one: it is still driven, and
the last commanded position is reported in its place, marked as commanded
rather than read. A stuck rotator must not be able to hide behind an
order it never carried out, which is why the panel shows the antenna's
position beside the satellite's.
The 450° overlap is the reason a satellite rotator is worth having, so it
is used: a pass crossing north continues past 360 instead of unwinding
three quarters of a turn with the antenna sweeping the ground. Below the
configured elevation the mast is left alone — the numbers are right all
the way round the orbit, but a rotator that chases a satellite through
the far side of the earth spends the night turning, and a mast has a
finite number of turns in it.
The hard part of satellite tuning is not the arithmetic, it is deciding
who owns the dial. A tracker that forces both frequencies fights the
operator every time they turn the knob to follow a station across a
linear transponder; one that never touches the receiver leaves them
chasing a signal that slides nine kilohertz across a 70 cm pass.
So the operator owns the receiver and the tracker follows them. Every
second it asks the radio where the receiver actually is. Where it put it,
nothing has changed. Further than a dial-turn's tolerance, and the
operator has chosen a station: what they landed on is converted back into
a nominal frequency, and the transmitter is derived from that. Which is
the division of labour on a linear bird — the operator listens, the radio
does the sums.
Three ways to reach the radio, because a satellite pair is a shape of
operating rather than a manufacturer's feature. An IC-9700 or IC-9100 is
asked for its OWN satellite mode: it pairs main and sub, gives full
duplex, and keeps the dials linked the way its designers meant, which is
always better than an imitation built out of split. A Flex gets two
slices, A the downlink and B the uplink, created when missing, because
"slice B does not exist" is not something to make an operator fix at the
start of a ten-minute pass. Everything else gets the downlink, and is
told so — half the job announced beats half the job hidden.
What goes in the log is the NOMINAL pair. Two stations working each other
through a transponder read different numbers off their dials at the same
instant; the only figure they can both agree on is the transponder's own.
FREQ is the uplink and FREQ_RX the downlink — the one place a satellite
QSO differs from every other kind, and the reason FREQ alone cannot
describe one.
Three questions answered at once, because on a pass there is no time to
go looking for any of them: where the bird is, when the next one comes,
and what to tune. The map draws each satellite's footprint — the honest
answer to "can I hear it", since everything inside the circle has the
satellite above its horizon — and the selected one's path over the
ground. The pass list is every favourite in time order, the one in
progress in green.
The readout shows the corrected frequency large and the nominal one
beneath it. Only one of them, and an operator cannot tell a Doppler
correction from a mistuned transponder.
The map opens on the station rather than the Atlantic, and remembers
where it was left like the others. The panel is mounted only while its
tab is visible: it asks for the tuning once a second, and there is no
reason to compute an orbit nobody is looking at.
What internal/sat could not know: where the antenna is, which birds the
operator cares about, and where the files live.
Startup reads the cached elements and the frequency plan from disk and
nothing else — one file and a few hundred parses, so the tab is full the
moment it is opened, on a shack PC with no internet as much as on one
with. Fetching is the slow, optional half and never blocks a launch; it
happens on its own only when the set is stale and the operator asked for
it.
Elements pasted in by hand go in their own file. The feed cache is
replaced wholesale on every refresh, so a freshly launched satellite —
whose elements circulate on a mailing list days before any feed carries
it, which is exactly the week everybody wants to hear it — would
otherwise be wiped by the first automatic update.
The list joins both halves and shows what is missing on either side. A
bird with elements and no plan is one the operator can still track; a
bird with a plan and no elements is the visible symptom of an element set
that is too old. Dropping either turns a fixable configuration problem
into a satellite that "does not exist".
GetSatelliteTuning is the working answer, and everything that will later
drive a radio is built on top of it rather than beside it, so the display
and the rig can never disagree. It keeps the operator's frequency
nominal and applies Doppler only on the way out: on a linear pass the
station being answered stays put on the dial while both radios chase the
shift. A geostationary bird is corrected by nothing at all.
Two things the tracker cannot work without, both kept apart from the
orbital maths on purpose.
The elements come from Celestrak's amateur group, with PE0SAT as the
fallback for the hour when Celestrak is rate-limiting a hundred trackers
at once. A malformed satellite is skipped rather than fatal — a feed of
two hundred birds with one bad checksum must still give the operator the
other hundred and ninety-nine — and the count is returned so the app can
say so. The cache is plain TLE text in the data directory, written
beside and renamed, and only replaced once a feed has produced usable
elements: a captive portal must not take away the set the station
already had. Loading it first is what makes the satellite tab full on a
shack PC with no internet.
The frequency plan is separate because it changes for different reasons:
elements every few days from a feed, a transponder when the satellite is
commanded into another mode. The shipped list is a starting point, copied
to the data directory on first use and read from there afterwards, so an
operator can correct a frequency without waiting for a release and keep
the correction across updates — and a file they have broken is reported,
not overwritten.
UplinkFor is the part that matters on the air. On an inverting linear
transponder, tuning up the downlink means going down the uplink; get it
backwards and you transmit at the far end of the passband from the
station you can hear, which is the classic first evening on a linear
bird.
Names are matched on letters and digits alone. Celestrak says
"RADFXSAT (FOX-1B)" where every operator says AO-91, and nobody spells
Es'hail the same way twice.
The foundation of the satellite branch, and nothing above it yet: where a
satellite is (SGP4 from akhenakh/sgp4, Apache-2.0 and pure Go, so the
no-cgo rule holds), where it will be (passes with an elevation floor,
because a three-degree scrape is a line in a table that will never be a
QSO), and what its motion does to a frequency.
The Doppler pair is the part worth being careful about: the two
corrections go in OPPOSITE directions. The downlink arrives shifted and
we tune to meet it; the uplink must LEAVE shifted the other way to land
on the transponder's nominal input. A test pins the signs and the size —
7 km/s on 2 m is about 3.4 kHz.
Elements keep their raw lines beside the parsed form: that is what the
cache stores and what an operator pastes by hand for a bird no feed
carries yet, which is exactly when everyone wants to hear it.
Ticking "RTTY on USB" changed nothing: the flag is deliberately absent
from catLinkSig — none of these preferences is worth dropping the CAT
link, and with it WSJT-X's rigctl session, to apply — so saving the
settings left the link alone and the running client kept its old answer
until the next launch.
Preferences that the link does not depend on are now pushed to the
connected rig when the settings are saved, through the Yaesu escape on
the manager. SetRTTYUpper joins the controller interface for that: it is
a preference rather than a command, but it has to be reachable on a rig
that is already talking.
The selector row appears above the dial when there is more than one
rotor, and the widget's height is not its own to take — it sits in a
strip sized by the entry form beside it. The row was simply added, so the
SP/LP pair and half the Stop button went off the end.
The dial (24 px), the three button rows (8 px each) and the padding
(4 px) now give that height back between them, which is a selector row
almost exactly. The dial and the controls column stay the same height as
each other, so the two columns still line up.
Windows Defender removed 0.27.14 from a station as
Trojan:Script/Wacatac.H!ml. That detection is machine-learning, not a
signature, and the behaviour it scored is ours: an unsigned binary
replaces itself on disk, clears the mark-of-the-web, and spawns a
windowless PowerShell that waits for its own process to die before
starting another executable. Byte for byte, that is a dropper; the model
reads the shape, not the intention, and "Script/" names the PowerShell.
The wait it was written for is not needed. --post-update already makes
the new instance patient with the single-instance mutex — twenty seconds
of it — so the new exe can be started directly while this one is still
shutting down and simply wait its turn.
The deferred-swap fallback keeps its helper: nothing else on a stock
Windows can wait for a pid and then move a file over an image that is
still running. It is reached only when the rename failed, never on the
ordinary path.
The eight-digit rigs, the typed watering hole and the RTTY sideband all
landed after the 0.27.15 release commit, so they were sitting in a block
that had already shipped. 0.27.15 says what was released again.
His log settles the 28.074 case: "SetCATFrequency 28.074 MHz" and the
state still reads mode=USB — nothing sent a mode, so the rig simply
stayed where it was. A spot click has always carried one; a frequency
typed by hand carried none. It now uses the same table and the same
tolerance as a spot (±3 kHz of a known FT8/FT4/JS8 frequency), and only
towards the digital modes: tuning AWAY from one leaves the mode alone,
because there the frequency says nothing about what the operator means.
RTTY on Yaesu is a choice the log cannot make: ADIF records "RTTY" and
the rig has MD06 (RTTY-L) and MD09 (RTTY-U). The older lower sideband
stays the default and a station whose FSK controller wants the upper one
says so once in Settings → CAT.
An FTDX3000 rejects every FA command: the FTDX10 family writes a
frequency in nine digits and everything before it — FTDX3000, FTDX5000,
FTDX1200, FT-2000, FT-950, FT-450 — writes eight, answering the longer
form with "?;". The rig would not follow and nothing said why.
The width is LEARNED from the rig's own replies rather than tabulated: it
announces the format in every answer to FA;, so it comes from the radio
in front of the operator instead of from a model list that is always one
release behind — and a Yaesu this backend has never heard of is right on
the first read. Nine until the first reply lands, which is what the
modern rigs use and what this backend was written against.
The five older ID codes are named too, so the console says FTDX3000
rather than a bare number.
The main hint named three fixed colours, which stopped being true the
moment the operator could choose them. And the paragraph under "Mark
stations already worked" explained a trade-off nobody reads standing at
the radio; the switch says what it does.
Same order as the last block: what is new leads, each fix follows the
thing it belongs to — the antenna pair, then the Icom network run, then
the rest.
The shortened transmit gag was written for an Ultrabeam that is now polled
four times a second while it moves. The SteppIR was still on two seconds
and reported nothing at all until its own poll came round, so the gap
between the 900 ms grace and the first poll that would have seen the
movement was a hole in "block TX while the elements travel" — the
transmitter released in the middle of a move.
It now reports a commanded move at once (bounded, so an antenna that
never answers cannot latch the inhibit on), on a COPY of the cached
status so the flag cannot leak into what the poll goroutine owns, and
follows the motors with its poll rate exactly as the Ultrabeam does.
The transmit gag starts when the move is commanded; the indicator waited
for a status poll to say the elements were travelling, so the two
disagreed by a second or more — and on an automatic follow (band change
with tracking on) there was no sign at all until a poll landed. The
backend now announces the order as it goes out, the interface shows it at
once and re-reads the antenna immediately, and the real status takes over
the moment it arrives.
The WSJT-X "grey out stations already worked" switch is renamed "Mark
stations already worked": with the colour now chosen by the operator the
old name described the wrong thing, but the switch still answers a
question the palette cannot — WHETHER dupes should be marked at all. On a
well-filled log they are most of a period, and a window where nearly
every line is coloured has stopped saying anything.
The motorised antenna gagged the transmitter for a second or two after it
had finished moving. Three delays were stacked: the antenna polled every
two seconds, the gag held for three after the command whatever the
antenna said, and the widget refreshed every three. The antenna is now
asked four times a second WHILE IT MOVES — an idle one has nothing to say
and stays at two seconds — the gag only bridges the command itself
(900 ms), and the widget follows at half a second while moving.
WSJT-X highlighting:
- A watch-list station already worked on this band and mode is no longer
painted as one to call. The list is a statement of intent, not of what
is left to do, and its pink outranked every other verdict including the
log's, so a worked station stayed pink for the session with nothing to
tell it from one still needed.
- The four colours are the operator's to choose (Settings → UDP). Only
the background: the text colour is derived by luma, so a dark blue
cannot come back as black-on-black in somebody else's window. Changing
one clears the installed highlights, or the de-duplication would keep
showing yesterday's colour until a callsign changed verdict.
The square ring put the ticks in the corners where the room is, and made
every distance from the centre depend on direction — a marker at 45 sat
further out than one at north. A dial is read by angle, so the ring it is
read against is the same distance away all the way round now, and the
markers need one radius instead of a per-direction one.
The antenna is a sector that fades outwards rather than an arrow: an
antenna does not look along a line, it looks through a lobe, and the
arrow claimed a precision the beamwidth does not have. Where the mouse
would send it is drawn the same way, and its azimuth cross-fades into the
big readout while aiming — the figure is read at the moment the beam is,
so it belongs in the same place rather than somewhere to look away to.
Three colours, three meanings, kept apart: green where the antenna IS
(as everywhere else in OpsLog), orange where a click would send it,
yellow what was ORDERED. His revision drew all of them orange and yellow,
which loses the distinction the dial exists for — and drew the second
lobe of a bidirectional Ultrabeam at full strength, indistinguishable
from the main one. It is dimmed again; the dashed boom, the REV/BI badge
and the compact form are untouched.
The conninfo that authorises the RX stream goes out during the login,
before the audio socket exists — it has to, since it is what authorises
it. So the rig is told to send audio to :50003 while nothing is bound
there, gets an ICMP port-unreachable back, backs off, and the audio turns
up only when its own retry timer comes round: twenty to thirty seconds by
the operator's watch, ninety in one log.
It is sent once more the moment the port is listening, which is the same
message the session already carries — RS-BA1 repeats it too. The audio
dial moved above the pumps, because after ctrlPump is running the
control-stream auth state belongs to it.
"I turned the sound back on and nothing comes out of the speakers", with
a log that reports success at every step: the network audio stream up,
664-byte packets arriving, the monitor started. The render goroutine's
error was thrown away — a device unplugged, renamed by Windows or unable
to open at 16 kHz fails exactly there, silently.
It is logged now, with the device id. Two once-only lines either side of
it say whether the decoded audio is reaching a running monitor or
arriving with nobody listening, which separates a device fault from the
speakers simply being switched off.
The guard I added for services with no credentials demanded one, and
nobody has ever set it: OpsLog carries its own Club Log APPLICATION key
(clublogAppAPIKey), so the account is an email, a password and the
logbook callsign. An operator whose live upload had been working for
months was told the service was not configured the moment he sent QSOs by
hand after an import.
Written in app.go, the rules drifted from the uploaders on the first try.
They now live in internal/extsvc beside the Upload* functions that
enforce them, each case mirroring that function's own guard — which also
caught Cloudlog, where the station profile is required and the check did
not ask for it. The message names the fields actually missing rather than
listing everything the service takes.
Audio off, and the IC-7760 still answers at connect and then never again:
twenty-eight commands sent, not one reply, packets still arriving on the
stream. A count says how much went unanswered and never which command
went out last — which is the one thing that can identify a frame this rig
does not tolerate, on a radio nobody here has.
The transport now keeps the command headers of the last eight frames and
prints them with the silence report.
The RX audio stream is experimental and shares the rig's session with
CI-V. The shape in an operator's log is unmistakable: audio packets
arriving by the hundred while not one CI-V reply comes back, the watchdog
tearing the session down, twenty seconds' pause, and the whole thing
again — read from outside as "the Icom keeps disconnecting", with
nothing pointing at the switch that would end it.
The log now says it, and names the setting. icomAudio counts what it has
delivered so the line distinguishes "audio is enabled" from "audio is
arriving", which is the half that makes it a suspect.
From an operator's log: an IC-7760 in standby, and OpsLog dialling and
dropping every forty seconds for as long as it was left there — control
link up, login OK, token renewed, and not one CI-V answer.
lastGoodAt bounds "the link answers but no CI-V comes back". It belongs
to a session and was never cleared when a new one opened, so a rig that
went to standby half an hour ago handed every fresh session a
half-hour-old last good read: past the grace before the first command was
even sent. Torn down at once, redialled twenty seconds later, torn down
again. Cleared on connect, the rule reads as it was written — silent
since connect is a rig in standby, and the session is kept so it can be
woken.
The console it is woken from was missing too. It appeared only once the
live CAT state said "icom", which a sleeping rig never says, so the ON
button was absent at the one moment it exists for. It now follows the
CONFIGURED radio — which also had to start following a radio switched
from the status bar, instead of waiting for a trip through Settings and a
Save that changed nothing.
An exported file was full of blank gaps: a record ran down a dozen lines
and the next appeared to start in the middle of the page. ADDRESS is a
multi-line field by the standard and callbooks and other loggers fill it
that way — "Kabul", four blank lines, "Afghanistan" — and the writer
copied the value out as it stood. The files were always valid, since ADIF
counts bytes; they were unreadable, and so was anything that quoted them.
Line breaks inside a value are now joined with a comma and tabs become
spaces, which is how an address reads on one line anyway. The length
prefix is computed after the flattening, so the record stays exact, and
every path through the writer gets it: the file exports, the uploads and
the record forwarded over UDP.
The changelog's 0.27.15 block also takes back the FT-map hover fix, which
landed after the 0.27.14 release commit and was sitting in that block.
The invisible circle that catches the clicks sits ON TOP of the dot, so
it takes the hover as well — and the tooltip was bound only to the dot
underneath. From the moment the stations became clickable, pointing at
one said nothing: the callsign, square and report an operator reads off
the map had simply gone.
The map draws a dot per decoded station and they did nothing. They now
answer the same two gestures as the decodes list, because the two are
views of the same list and a click has to mean the same thing on both:
one takes the callsign into the entry (and points the PSK Reporter panel
at it), two answer it.
The handlers were written inline on the list, so the map could not offer
them without a second copy — they are named once now and given to both.
Leaflet leaves the telling apart of click and dblclick to the handler, an
invisible marker three times the dot's radius takes the clicks (a
three-pixel dot is a fine mark and a poor target), and the double click
is stopped rather than merely unpropagated: the map zooms on one, and
answering a station is not a request to zoom in on it.
The rest between two series was two minutes — four overs on FT8, by
which time the DX has worked four other callers and half the time has
gone. It is now counted in the station's OWN overs and is one by default:
seven calls, one over listened through, and it goes again if the station
is still there. The deadline lands mid-cycle on purpose, so "sit out one
over" means one over rather than depending on a millisecond of clock
skew.
A period the target was DECODED in is never counted as a miss. A period
is judged more than once — decodes arrive in a burst and stragglers
follow — and a later judgement holds a partial view of it, not evidence
of absence: D2ACE answered in the very period the counter then read as a
miss.
The readout moved out of the Auto button and beside it. "Auto D2ACE 1/7
·1/3" read as one number, and the control changed width every period.
The callsign is now the biggest thing on the row, the calls and the
missed periods each carry a label, the miss count appears only once there
is one, and a station being waited for gets its own amber chip.
The world map was the only one that remembered anything. Panning and
zooming a map is the operator saying which part of the world they work,
and on the FT decodes map and the grid-square map that was thrown away on
every tab switch. Both now keep centre and zoom, through one shared
helper (lib/mapView) that the world map uses too, and the keys are
portable so a copied data folder brings the views with it.
The world map also waits for the station's square before it paints. It
drew the world at 0 degrees and then moved to the operator's longitude —
a screenful of Esri tiles fetched and discarded on every first run. It is
now built once, knowing where it is looking; a profile with no locator
gets the default view after two seconds rather than a blank panel.
Centred on 0 degrees it left an Australian looking at their own country
in the bottom-right corner, with the paths to everywhere they work
running off both edges. Centred on their own longitude the same map reads
the way their antenna does: the Americas to the east, Europe and Africa
to the west. Leaflet repeats the world horizontally, so this is a choice
of viewpoint and costs nothing — the tiles either side are the same
world, and unwrapLon already draws the arcs across the seam.
The latitude is damped rather than followed (a station at 69 north
centred on itself would spend half the map on the Arctic), the station's
square arrives after the map is built so it re-centres once when it
lands, and a view the operator has panned to themselves still wins.
An operator with a callsign in the field, switching FT8 to SSB, kept
"+00" as the report. The edited flag protects a report the operator
chose — 57 rather than 59 — and it was holding across a change of mode as
well, where it protects nothing: a decibel figure is not a weak SSB
report, it is not a report at all. Worse, anything that fills the field
from the rig sets that flag too (the S-meter readouts in the rig
consoles), so the field could be stuck in the wrong notation for the rest
of the QSO.
The flag now holds only while the report still belongs to the mode's
family. When it does not, the operator's own judgement is carried across
where it can be — 57 becomes 579, 599 becomes 59 — and the mode's preset
answers where it cannot.
Below 59+20 comes 59+15, then +10, +5, then a plain 59 and down through
58, 57. Stepping the S digit and leaving the suffix where it was turned
59+20 into 58+20, which nobody has ever said on the air. Five decibels at
a time above S9 — the same increment sMeterRST rounds an S-meter reading
to — and one S-unit below it.
The mouse wheel steps the RST fields — one S-unit on an RST or RS, one
decibel on a digital report, up for a better one — in the entry strip and
in the QSO editor. The dropdown beside them lists the reports worth
having to hand, not all 41 decibels, so the wheel works on the value
rather than walking the list. The listener is native and non-passive:
React attaches onWheel passively, where preventDefault does nothing and
the panel scrolls away under the field being adjusted.
PSK Reporter, whole-band scope: clicking a decode reset the report count
to zero. The window there is the BAND's — every FTx report on it,
filtered by target only when the analysis is drawn — and it was emptied
on every target change, throwing away an hour of evidence at the moment
the operator asked the question it answers. The narrow scope still clears
it: there the window is one station's, and keeping it would answer the
new question with the old station's evidence.
ZD8GB — watch-listed, six streams a period, two of them RR73 — was
refused as "parked" for the rest of the session. Parking answers "it
will not answer, stop wasting the evening on it", which is a fair verdict
about a station the LOG picked out and the wrong one about a station the
OPERATOR named: a DXpedition running a pileup takes more than two series
of calls to get through to, which is exactly why it is on the list. The
rest between series still applies, so it cannot monopolise the
transmitter — it simply never becomes ineligible.
Send to (right-click) now refuses a service with no credentials and says
which are missing. The upload runs on its own goroutine and reports into
the QSL Manager's console, which is not open when the command came from
the QSO list, so an upload to an unconfigured service looked exactly like
one that worked. The toast is also raised only once the backend has
accepted the request, and Cloudlog / Wavelog and HamQTH name themselves
in it.
Three field reports.
Icom CI-V address 00 could not be kept: zero was read as "not
configured" in all three places that validate it, so every save put the
rig back to the IC-7610's 0x98 — and the model dropdown followed, since
it is derived from the address rather than stored. Picking "Other
(custom address)" also had no effect of its own: the list re-derived
itself and snapped back to whatever rig matched. It now stays chosen.
Cloudlog/Wavelog showed "17m/17m" on ordinary FT8 contacts (OE6CLD).
Every QSO is stamped with a receive side equal to the transmit side, and
the uploaded record carried it; Wavelog draws band/band_rx whenever both
are there. In ADIF an absent BAND_RX means "same as transmit", so the
uploaded record now writes the receive side only when it differs. The
copy forwarded to another logger over UDP keeps writing it in full —
that is why it was stamped in the first place (Log4OM reads BAND_RX) —
through its own ForwardRecordADIF.
"S/F" in a spot comment joins superfox / sfox / F-H as FT8.
It went in after the 0.27.13 release commit, so the shipped build does not
contain it — and the entry had been folded into that block's fixes line,
where it claimed a fix nobody had. The 0.27.13 block is back to what was
released.
A decoder sends a period's decodes in a burst, and stragglers follow — a
deep decode a second behind the rest. The sweeper judged the burst and
CLEARED the buffer, so the straggler opened a fresh one under the same
period key and was judged on its own: the ladder applied to a handful of
late arrivals with the other thirty stations of that period nowhere in
sight, and often after the reply to the burst had already put us on the
air, where nothing can act on it at all.
The buffer now outlives the judgement. A period stays open until a decode
stamped with the NEXT slot arrives; a straggler appends to it and the
period is judged again, whole. Judged once per period otherwise — acDirty
says whether anything new has come in — and the same flag now answers the
dead-band case that the cleared buffer used to stand for.
Callsign, band, mode, badge, age in reading order, and the widget widened
to 290 px so the badge and the age never squeeze the callsign. Two lines
made the panel twice as tall for the same three facts; the entry that
matched — which only differs when it is a prefix — moved into the row's
tooltip.
The watch list was a tab, and an operator working FT8 lives on the decodes
one: a station they had asked to be told about turned up on a screen they
were not looking at. The same answer is now docked in the widget strip,
above the tabs, reduced to what is worth acting on — on the air and still
needed, one row per band and mode, with the cluster's own NEW DXCC /
NEW BAND / NEW SLOT badge and a click that tunes. Off by default. The
"active and needed" answer costs a debounced query per visible slot, so it
is written once (lib/watchlistSpots) and the tab uses it too.
Auto-call:
- It answers a new prefix, county, state, square or park. Those markers
are orthogonal to the entity, they ranked as nothing-needed, and the
engine sat through a never-worked WPX prefix calling CQ. New rung at
the foot of the ladder, gated by the chase switches the badges use —
which meant making those switches portable, since the backend cannot
read localStorage.
- It calls THROUGH a pileup. Giving up the moment the DX answered
somebody else is precisely how a queue is not worked; the call and miss
counters already bound the effort, and a station in mid-exchange is
still never chosen as a new target.
The PSK Reporter panel now follows the station auto-call is waiting for:
the analysis takes a history query and a period or two to fill, so
starting it when the DX comes free is starting it too late.
Callbook lookup: a compound callsign with a page of its OWN keeps that
page's location. QRZ files HP/WE9G under exactly that form, with the
Panama square the station is operating from, and the rule that drops a
home address from a portable call was throwing it away. The record's own
country tells an operation's page from a home page.
Changelog: entries may open with [NEW], drawn as a pill in the What's new
dialog — a release is mostly fixes and the two or three genuinely new
things should not have to be found by reading all of it.
Six faults from an evening on 60 m, all in the same family: the engine
judging a station by what the log wants from it and forgetting what is
already under way.
- An exchange was abandoned mid-QSO. The reply lands in the same period
the ladder is re-read, and that period was judged before the reply was
taken into account, so a better-ranked caller took the slot from a
station that had just come back to us. The answer is settled first now,
and our own report counts as being inside the exchange too — which also
protects a QSO the operator started by hand.
- A station just picked started with misses against it. Its transmit slot
was unknown until a second decode, and with the parity unknown every
period counted, including the one spent transmitting to it.
- The freed slot after "it is working somebody else" was thrown away: the
period's decodes are in hand, so the next station is picked from them
rather than fifteen seconds later. Never mid-over.
- Auto-call is never armed from a stored setting — not at launch, not on
a profile switch. It is the one feature that puts the station on the
air by itself and OpsLog starts with Windows.
- It says what it is waiting for: a wanted station in a QSO with somebody
else now shows beside the Auto button instead of looking idle.
- Switching profile left the previous logbook's verdicts on screen. The
worked-index, chase-new and the frontend's cached verdicts are dropped
when the logbook changes.
FT decodes: distance column, a message addressed to you set whole in
green (the station you are calling keeps a tint — most of what it sends
goes to other people), badge order L / Wkd / WL, list cleared when the
RIG changes band.
Rotor: new world-map compass from EC1KD's design, with the Ultrabeam boom
and second lobe restored and the compact form preserved; the classic dial
is kept and Settings → Rotator chooses between them. Stop no longer
flickers on a rotor standing still — movement was inferred from a degree,
less than the jitter a controller reports at rest.
Decodes:
- one click SELECTS, two transmit. A single click handed the decode
straight to WSJT-X as a reply, so brushing a row while reading the
band started calling a station.
- the list empties for a receiver that changes band, and a receiver
column appears when more than one is feeding one merged list.
- the period clock turns red while transmitting: it is the one thing on
the screen that moves, so it is where the eye already is.
- a WL badge, after the LoTW "L" — one letter, always in the same
place, so the column does not shift from row to row.
- the auto-call switch, its target and its count, and the chase list:
naming the station you are waiting for is done while watching the
band, not in a settings tree.
Themes: DXHunter's slate with its own blue, and the same slate with
OpsLog's orange. Counted across its sources rather than guessed from
one panel — blue is 132 uses to violet's 25, and the violet is the PSK
Reporter panel alone.
Watchlist: drawn as DXHunter draws it — the callsign in the interface
font rather than monospaced, which is the difference that shows with
the two windows side by side.
FT Map: arcs no longer run off the side of the map. The map shows one
world, and a path crossing the antimeridian was drawn past 180° into
the blank space beside it — from VK that is most of them.
Cluster: "superfox", "fox/hound" and "F/H" in a comment are read as
FT8. They are WSJT-X's DXpedition transmit modes, and the comment fell
through to the band plan and came out DATA — which then decided the
band+mode verdict.
A decoder is named by what it IS: Nexus sends its packets as "Tempo",
the engine inside it, and OpsLog showed a program nobody has heard of.
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.