A 7760 switched fully off takes its LAN server down, and no session means no
console and no ON button — the one thing remote operation cannot tolerate.
The rig's MAC is learned from every login and persisted; when a dial finds
nobody home, the magic packet goes out to it before the next attempt. The
rig wakes into standby, the session opens, and the ON button does the rest.
The generic Freq write lands on the TX VFO when split is engaged: an FT-2000
moved B and left A — the receiver — behind, so a spot click QSYed the
transmitter and nothing audible changed; without split the same write moved A.
With split on (and the operator on MAIN), FreqA and FreqB are both written,
so the radio arrives on the spot whole, split left as the operator had it.
The inference tables knew FT8 on some bands and nothing on others: a 10.136
spot with a bare comment read as generic DATA — which is what every
skimmerless spot of a DXpedition's 30 m FT8 slot did. The standard FT8/FT4
windows are added on 30 m, 60 m, 80 m (FT4), 17 m (FT4) and 12 m, in BOTH
tables (backend band plan and frontend spot.ts), ahead of the wide segments
they sit inside — order is the mechanism there.
The console's thin home-made bars were the one holdout — every other panel
(Flex, Elecraft, the amps, the tuner) draws the same MeterBar. And the mode
badge said SSB, which on any band leaves the operator guessing which
sideband the rig is on: the panel now shows USB or LSB (the log keeps ADIF's
SSB).
The CI-V meters are point samples: between two SSB syllables a poll lands on
0 W and a perfect SWR, so a 150 W transmission read 0-10 W most of the time
and the SWR sat at 1.0. Power now decays like a needle and SWR holds its peak
then snaps to the live value — the same meterPeak the Yaesu and Kenwood
consoles already use. The readout column also widens so '180 W' stays on one
line.
TUNE (1C 01 02) started a cycle; nothing sent the 0 that puts the tuner back
through. An ATU chip beside SPLIT now toggles it, and the tuner state is read
on the slow front-panel beat so the radio's own TUNER button stays in sync.
Added on a report that they were missing; they were below the fold, not
absent. The useful parts stay: the MOX button routes the PC microphone on a
network station, split aligns the TX VFO's mode, and SetIcomSplitOffset
remains available for a future use.
The 0x27 output flag lives in the RADIO and survives our sessions: a scope
enabled by an older build (or another program) kept flooding every new
session with 700-byte frames — and on the IC-7760 that flood is what kills
the CI-V link. One 'waveform output off' as soon as the rig answers, once per
session; the front-panel display is deliberately untouched.
Every Icom streams its waveform differently: the IC-7851 controls a scope it
never streams, and a real IC-7760 stops answering CI-V altogether a few
frames in — taking CAT and the audio down with it, which is this week's whole
dropout saga. Chasing a per-model frame layout for a decoration is not worth
a console that drops the link; the radio's own scope is better anyway. The
backend scope plumbing stays (harmless while nothing enables it); the UI and
its enable path go.
Keying alone is right on USB, where the operator talks into the radio's own
mic; over the LAN it transmitted silence. The console button now goes through
one binding that picks the road: network To-radio → the same key-and-stream
path as the Talk button, USB → key and nothing more.
The MOX and SPLIT controls lived at the bottom of the Transmit card, below
the fold on most layouts — a console whose PTT needs scrolling is not a
console. A strip under the mode row now carries the PTT and Split as
OFF/+1k/+5k/+10k, DXpedition style, on a new SetIcomSplitOffset that takes
the chosen TX offset (0 keeps the old CW/SSB convention). The mode-alignment
from the previous fix rides along on every engage.
A radio in standby is silent on CI-V by design; only the transport chats.
The quiet-recovery added for the mid-session deafness treated that silence
as the fault it usually is and tore the session down every 15 s — taking the
console and its ON button with it, so a radio that was off when OpsLog
started could never be turned on. The recovery now arms only once the
session has heard at least one CI-V payload.
The sink — decode + recorder feed — was built only on the success path of
starting the monitor, so speakers-off (the remembered preference) or an
output device that failed to open silently disabled the WHOLE stream: the
session connected audio=false, and a ticked RX-audio checkbox did nothing.
The sink now exists whenever the stream is on; only the monitor obeys the
speaker choice.
The unselected VFO was read only when split was on, so a dual-receiver rig's
second dial sat blank on the console. It is now read on the same slow beat
regardless. And engaging split copies the main's mode (and data flag) onto
the TX VFO with 0x26 01 — a split whose TX VFO still speaks yesterday's mode
transmits FM into a CW pileup; rigs that predate 0x26 NAK it harmlessly.
The talk button learns the network road the voice keyer already took: when
To-radio is the radio itself, the microphone is captured and re-framed into
the rig's 320-sample packets, the capture callback serving as the clock — the
mic delivers in real time, so no ring and no pacer. Counters and the frame
remainder live on the audio stream, so a talk session spans calls. PTT keys
before and releases after, through the same code as the USB path.
With this, a network Icom is a complete remote station over three UDP ports:
RX audio to the headset, live voice and recorded messages back, CW through
the rig's keyer, CAT for everything else.
Same remembered preference as the console's speaker button, surfaced where
the stream itself is enabled — tick RX audio and decide in the same breath
whether it reaches the speakers. Applied immediately, no save needed.
Muting the network RX audio took a trip through Settings → Audio → Stop
listening — two panels away from the console the operator is actually using.
A speaker button now sits beside ON/OFF (network only, like them): one click
to listen or mute, the recorder and the voice keyer unaffected, the choice
remembered across reconnects and launches.
The RX stream and the speakers were welded together: every reconnect and
every launch restarted the monitor, so an operator sitting in the room with
the radio could not have the stream (which the recorder and the voice keyer
need) without also hearing it twice. Stop listening now persists, the Listen
button turns it back on, and reconnects respect the choice.
The audio session opens its TX side alongside RX (txenable in the conninfo,
16 kHz both ways), the stream gains a paced sender — 320 samples every 20 ms,
the frame mirroring what the rig itself sends on this socket, IDs swapped —
and the network Icom takes the same NetworkPlayer slot a TCI radio does: pick
'Radio (network audio)' as the To-radio device and the voice keyer needs no
cable and no virtual sound card. PTT brackets the message through the same
code as every other audio path.
The capture shows the spiral: a session goes deaf on CI-V (28 unanswered
commands, transport alive), the fast-fail rebuilds it, the new session answers
for one second — one state read got through — and is then strangled when the
rig purges the half-open old one. Twenty seconds a lap, no audio throughout,
and only the third or fourth session survives. When the previous session died
less than 90 s after connecting, the redial now pauses 20 s so the purge
happens BEFORE the new session, not on top of it. A long-lived session still
reconnects immediately.
The IC-7760 recurrently stops answering CI-V a few minutes into a network
session while the transport keeps chatting — pings answered, session alive,
commands unanswered — and the only recovery was the 30 s watchdog's full
teardown. At 10 s of CI-V silence the pump now says 'open' again on the
existing stream, which is all it should take if the rig quietly closed the
data flow; the watchdog remains as the backstop. The send counters gain a
mutex since the pump now transmits too.
reloadCAT builds the network audio sink gated on audioMgr, and startup created
the manager AFTER the first reloadCAT: every fresh launch connected with audio
silently off however the option was set, and the operator had to
untick/save/retick it to hear anything. The manager is idle-until-used, so
creating it earlier costs nothing.
Every audio packet was delivered as if it were the next 20 ms, duplicates and
late retransmits included. The monitor's capped ring quietly threw the surplus
away, so the speakers sounded fine — but the recorder keeps every sample it is
given, and the file came out longer than the QSO, slowed and stuttering, each
lost-then-resent packet heard twice. trackRxSeq now says whether a packet
advances the stream, and only those are handed on.
Two halves of the same station confusion. The entry form pre-filled MY_RIG
from the per-band default on every band change, so the log-time priority (the
radio that is keying beats the radio that was planned) never ran — the field
was no longer empty by the time the backend looked. The form now asks the
active radio first, through a new ActiveRadioMyRig binding.
And the manual record button started its capture from the From-radio sound
card unconditionally, where the automatic recorder already knew a network
Icom's audio is pushed from the 50003 stream: a manual take on the IC-7760
was a faithful recording of the Flex's DAX. Same source rule for both, and
the button is offered with no sound card at all when the network stream is
the source.
Two effects, wrong order: the ticking effect ran before the reset effect on a
new take, so its closure captured the PREVIOUS take's elapsed as its starting
point — the counter showed 0 for one second and then jumped back to thirty
minutes. Effects run in declaration order; the reset now comes first.
The power meter applies Icom's own meter calibration (raw 143 = half
deflection, 213 = full scale) anchored against the real radio: a measured
100 W sits at half deflection of the 7760's 250 W face — the linear guess
showed it as 140. The RF power slider says watts on a 200 W rig instead of a
percentage the operator has to convert.
And the Listening button, pressed while a network Icom is connected, restarts
the monitor render-only: it used to open a USB capture from the From-radio
device as well, and that second producer interleaved with the network pushes
chopped the audio to pieces.
The loader looked for an 'active' flag the radio list has never carried, so
reopening the panel always landed on the first entry — Radio 1's name over
whichever radio's settings were live, and every field edit (MY_RIG included)
silently rewriting the wrong entry. The backend is the only one who knows
which radio is on the air; ask it.
The console gains a DATA mode button (USB-D, what FT8 and friends ride on);
the PSK button now maps to the rigs' native PSK mode (0x12) instead of erroring
as an unknown mode — rigs without one NAK it, exactly as RS-BA1's button does
there. The power meter shows real watts on the IC-7760, whose meter face runs
to 250 W where a 100 W rig's percentage was the watts. The clickable S-meter
gets a pointer cursor so it looks like what it is.
Network audio: rxcodec 0x04 — the experiments on the real 7760 settle the
codec table (0x10 = 16-bit stereo, 0x02 = 8-bit mono, both heard as garble),
and 0x04 is the 16-bit mono the playback path actually plays.
The IC-7760 acknowledges the 1A 06 data-mode command and stays in USB-D
anyway, which left the operator unable to get back to plain USB from the
console at all. After every mode set the flag is read back; on a mismatch it
is said again with 0x26 — mode, data flag and filter in one frame, the form
the newer rigs actually honour. Only on a mismatch, so rigs that predate 0x26
never see the command.
The first real radio on the 50003 stream (an IC-7760) settles the two guesses
the experimental audio path shipped with. The payload starts at 0x18 — the
packet carries a big-endian payload length at 0x14 (0x500 on every packet) —
not at 0x16, which swallowed two header bytes into the PCM and laid a 50 Hz
click track under everything. And rxcodec 0x10 asks for TWO-channel LPCM,
which the mono playback path rendered as double-speed garble; 0x02 asks for
the one channel the monitor plays.
The S-unit mapping was provisional, waiting for a real radio. One arrived:
side by side with a K3's own display, raw 5 reads S7 and raw 9 reads S9+20,
so S9 sits near raw 6.5 — not 9 — and each raw step above it is worth ~8 dB.
The old scale showed everything two S-units low.
The SWR meter borrowed the power meter's needle inertia — hold the peak, then
close a quarter of the gap per poll. The K3 throws a brief SWR spike as an FT8
frame ends, and that decay turned one bad sample into twelve seconds of red on
the next transmission. SWR now holds the peak for the same 1.5 s and then
snaps back to the live reading: it is a warning light, not a needle.
The block's one genuinely new feature opens it — with the ClubLog enrichment,
which had not made it into the entry yet — instead of sitting seventh between
an Elecraft button row and a bulk-edit field.
Double-clicking a cluster spot tuned the slice and zoomed the panadapter in
the same breath. On a cross-band jump SmartSDR moves the panadapter itself to
follow the slice, and that follow lands after — and overrides — a zoom sent in
the same instant, so the width the operator configured never appeared. A spot
clicked ON the panadapter never hit this, because the radio had already tuned
before our zoom arrived; the two paths now behave the same. The Chase new
panel's pick is sequenced identically.
Every other spot click — cluster grid, band map, watchlist, alert list — goes
through handleSpotClick, which applies the operator's per-mode panadapter
width after the tune. The Chase new panel had its own pick handler that tuned
and stopped there; it now makes the same view change, after the tune for the
same reason.
The prefix matching ported from DXHunter swallowed too much: a three-letter
special-event entry N8W lit up NEEDED for N8WCR, a different station entirely.
The implicit becomes explicit — a bare entry matches exactly that call, a
trailing star makes it a family: VK9* catches every VK9…, RI0SP* the
expedition's portable forms. A star anywhere else (or alone) is refused at Add
rather than silently matching nothing. Same rule in the backend Match and the
tab's own matcher, pinned by test.
The concept, transplanted: a list of callsigns or prefixes being hunted,
matched against the live spot stream, one card per entry with the spots
underneath and the two questions that matter answered on every line — is this
slot still needed, and what is it worth (the cluster's own NEW badges, read
from the same status index).
The file is DXHunter's own watchlist.json, field for field, ClubLog block
included though phase 2 will fill it — a file that round-trips unchanged is the
whole of 'same format', and a test pins it with a real DXHunter entry. Global
(dataDir), not per profile.
CONTEST is per entry, not the global mode DXHunter has: a contest entry is
judged against the current UTC day — the boundary lives in the query's date
bound, so midnight needs no timer and resets nothing. Normal entries read the
same in-memory worked index the alerts use. Prefix matching is why RI0SP
catches RI0SP/MM, pinned by test.
Notify goes through the existing alert:fired event — the frontend already
toasts and sounds it — throttled to one alert per entry per two minutes,
because a DXpedition lights every skimmer on the planet.
Tab wired like NET Control: opt-in from Tools, persisted, closable. Single
click fills the callsign, double click works the spot — the cluster's own
gesture, kept.
The My-station group covered nineteen fields and not the three numeric ones.
They take their own integer path rather than the generic text setter: the
columns are nullable integers, and while SQLite would coerce '14' quietly, a
shared MySQL logbook would not — and empty must become NULL, never ''. Bounds
checked (DXCC <1000, CQ 1-40, ITU 1-90) so a slip cannot stamp zone 400 across
a thousand rows.
'None of the consoles look alike' is the complaint ShiftRow exists to answer,
and the Elecraft panel was still driving its offset with a row of nudge buttons.
It now uses the shared control — ±, wheel, typed value — plus the same
Ctrl+←/→ 10 Hz clarifier the Icom and TCI panels have. The K3 keeps ONE offset
for RIT and XIT, so both rows show it, exactly like the Icom's.
The backend gains the absolute setter the shared control speaks
(SetKenwoodRITOffset, funnelled through the same RO write as the nudge), and
the power slider moves in 1 W steps — nobody asks a K3 for 'between 10 and 15
watts' in fives.
Also per review: the chase switches are labelled 'Chase POTA' / 'Chase SOTA',
matching 'Chase new grids' beside them.
An operator who does not chase parks does not want NEW POTA shouting from every
activator spot. Two switches (Settings → DX Cluster, on by default): off, the
marker is withdrawn at the display layer — applySpotDisplay, the same chokepoint
the grid, the band map and the filter read through — so the badge, the colour,
the filter chip and the reference column all go quiet together, and a new-band +
new-POTA spot reads NEW BAND alone. The facts keep being computed; only the
telling stops, so ticking the box back on needs no rescan.
The report: switching the K3 to a data mode 'does not work for FT8 — the K3
does not go into DATA'. The mode digit is only half the answer on that radio:
MD6 keeps whatever DT submode the previous session left, and with FSK D still
armed the rig keys FT8 with no rear-audio modulation.
The panel buttons say the whole thing: DATA is MD6+DT0 (DATA A, the soundcard
path), DATA RTTY is MD6+DT2 (FSK D). The DT submode is also read on the
settings beat — Elecraft only, a plain Kenwood would '?;' it — so the active
DATA button follows what the rig is actually in, front-panel changes included.
A dedicated SetKenwoodPanelMode rather than the logger's SetMode: a panel
button is the operator saying exactly what the rig should do, not an ADIF mode
to be mapped through preferences.
Three from review. Aqua for NEW SLOT sat right next to the POTA green — it is
now the sky cyan the panadapter palette has shipped for new-slot all along.
The NEW COUNTY chip was green while its badge is violet, and NEW SLOT's chip
was still caution yellow: chips now carry the badge's own colour (color-mix for
the muted border/背景), because a filter that does not look like what it selects
has to be learned twice.
And the NEW CALL chip matched only the DISPLAYED status, which is manufactured
by the slot-highlight option — with that option off the chip matched nothing
and read as broken. It now filters on the fact itself (worked_slot false), so
it works either way.
The whole new-* family shared the warning amber while the NEW PFX marker sits in
caution yellow — two different facts, two near-identical colours in one cell.
NEW SLOT now takes aqua (chart-2), the same story the panadapter palette already
tells: its default for new-slot has been cyan all along.
The Send-spot dialog took catState.freq_hz, which is the TX frequency. Working
a DXpedition split, that is where WE transmit: the spot went out five up from
the DX, pointing the whole cluster at the pile-up instead of the station. The
RX frequency is where we listen — where the DX is — and is what a spot names.
The report from a real SunSDR: transmit power and SWR still empty after the
sensors fix. The subscription went out once, at connect — while ExpertSDR3 is
still streaming its initial state dump, exactly where a unidirectional control
command can be ignored. It is now renewed every time the server says 'ready'.
The sensor messages also join the logged-on-arrival set, capped like the rest:
the next log will say whether TX_SENSORS ever arrives, which is the question —
a radio that never sends it (AetherSDR may not) and a frame that arrived and
was dropped leave the same blank meters and need opposite fixes.
The band maps carried one hard-coded table — Region 1's — so a US operator's
40 m stopped at 7200 with stations spotted at 7250 hanging past the top of the
map, and the SSB wash started 25 kHz early. The region is a station-level fact
stated once (Settings → General, portable pref); lib/bandplan owns the three
tables and publishes changes to the open maps the way the distance unit reaches
the grids.
The tables stay deliberately coarse: a band map's wash is context, not a
regulatory chart, so only the differences an operator notices are split out —
Region 2's 80 m to 4000 and 40 m to 7300 (phone from 7125), Region 3's 80 m to
3900, the wider VHF/UHF allocations. National fine print does not belong in a
background tint.
The feature needs more rounds than the next release can wait for, so main goes
back to before it: the packages, bindings, migration, UI and i18n all move to
the feature/labels branch, which holds every commit. The 0.26.23 block keeps
only the Station column.
The 0031 migration may already have run on a machine that launched a dev build;
the two label tables it created are inert and the recorded migration row is
harmless — the runner only applies filenames it has, so re-adding the migration
when the branch merges will skip cleanly there and apply everywhere else.