Commit Graph
39 Commits
Author SHA1 Message Date
rouggy 2dd68da284 feat(flex): chase a split pile-up on the skimmer's report marker
Working a DXpedition split means guessing where it listens. The useful
information is not the callsign the DX answered but the FREQUENCY that
station was calling on, and a CW skimmer already marks it: SDC posts each
decoded report to the panadapter as a spot.

Those spots reach OpsLog through the radio's spot feed. On a marker, the
TRANSMIT slice moves there plus a signed offset; the receive slice never
moves, because losing the DX is worse than missing a call. The marker
text is a setting -- it is chosen in SDC by the operator, so any constant
here would be wrong for whoever chose otherwise -- and the switch is a
button beside SPLIT, since it is turned on when a DXpedition appears and
off when it is worked.

Moves are throttled and ignore a marker landing where the slice already
is: a busy pile-up produces several reports a second and the slice would
otherwise never be anywhere long enough to call.

The spot feed is now subscribed to unconditionally. It was tied to
OpsLog's own spot overlay, so an operator running SDC with the overlay
off received nothing -- the reason no foreign spot was ever logged. The
connect-time 'spot clear' stays behind the overlay flag: it wipes every
spot on the radio, a skimmer's included.
2026-08-23 18:49:40 +02:00
rouggy 65991be09d chore(flex): log the spots other programs post to the radio
Chasing a split pileup with a CW skimmer means acting on the report the
DX just sent: SDC posts what it decodes as panadapter spots, so the 5NN
is already on the radio and OpsLog already subscribes to 'spot all'.

What is not known is the shape of those spots -- which field carries the
report, whether it is the callsign or the comment, what source the
skimmer names itself. Guessing produces a feature that never fires, so
this logs the first 60 foreign spots of a session verbatim and does
nothing else. Bounded because a skimmer posts hundreds an hour.
2026-08-23 18:36:55 +02:00
rouggy f50806fbd9 feat: panadapter spots that read, a CI-V link that survives, no auto-call
Panadapter spots are now worth reading. The comment carries the spotter, the
entity and the status in DXHunter's own shape — "CQ up 2 [F4BPO] [Franz Josef
Land] [New Slot]" — which needed two things nothing documents: SmartSDR splits
its command line on SPACES, so the words ran together until every space became
non-breaking; and it truncates past ~60 characters, so the cluster's own words
are trimmed first and the three brackets always survive. RBN column padding is
collapsed on the way in, or a preserved run of spaces opened a gap wide enough
to push the rest off screen.

"Already worked" means the CALLSIGN is in the log, not the entity: saying it of
a station never contacted was simply wrong. Each status can also be kept off the
panadapter entirely, and the WSJT-X decode spots obey the same switches — the
palette governs the panadapter, not one of the two things that feed it.

And the radio is no longer hammered: a spot whose frequency, colour and comment
are unchanged is not removed and redrawn. A busy skimmer feed re-spots the same
station every few seconds; one two-minute session sent 2128 adds, 88 of them for
a single callsign, and the display did not move a pixel for any of them.

CI-V, from an IC-7850 that kept killing JTDX: a reply the rig sent to another
controller on the same bus is no longer taken for ours, and a set_ptt, set_freq
or set_mode whose acknowledgement goes missing is verified by reading the rig
back instead of being reported as a failure. WSJT-X and JTDX answer a failed
command with a Rig Control Error and drop the link mid-over — 98 keyings, 6 lost
acknowledgements, 2 dropped connections in one session. The check waits 700 ms,
not the poll's 150: the rig has just failed to answer twice because it was
retuning, and a short probe would fail for the same reason.

Auto-call is withdrawn — it duplicated DXHunter, which already answers decodes,
and two programs deciding that from one shack key over each other. The library
is kept whole and dormant; a guard in App.tsx makes sure a stored preference
cannot key a transmitter whose switch no longer exists.

Also:
  - the log rotates while running, not only at startup: the CI-V trace left on
    wrote 416 MB and nothing would have stopped it before the disk did. Closing
    it now releases the crash file too — the runtime keeps its own duplicate.
  - the interface zoom announces itself, with a badge, a click back to 100% and
    a View menu; Ctrl+wheel and Ctrl+0 always worked and nothing said so.
  - no more elastic bounce, and no swipe-to-navigate out of the app.
  - Edit QSO: your own TX power and the contacted station's extended locator
    were saved and written back with no box to set them.
  - FT decodes: continents are a multiple choice; a compound MSHV message that
    answers two stations in one line is recognised as addressed to you.
2026-08-23 01:16:26 +02:00
rouggy d48420485f chore: release v0.26.3 2026-08-21 23:28:55 +02:00
rouggy 0cd243fe00 chore: release v0.26.2 2026-08-21 18:21:33 +02:00
rouggy 43095a1d89 feat(rigctld): split that actually reaches the radio, or an honest refusal
set_split_vfo and set_split_freq both answered RPRT 0 and did nothing. WSJT-X
and JTDX in "Split Operating: Rig" send exactly that pair, believed both, and
transmitted on the RECEIVE frequency — on a pileup, straight onto the DX, while
showing the operator precisely what they had asked for. A lie that leaves no
trace in any log is the worst kind of bug this program can have.

The two commands are honoured as a PAIR. Arming alone does nothing on the radio,
because WSJT-X sends the frequency second and split armed on whatever the
transmit VFO happened to hold is worse than no split at all: it transmits
somewhere the operator never chose. The request is remembered and set_split_freq
does the work.

Kenwood gains SetSplit — FB to place the dial, then FR0/FT1 to arm, in that
order for the same reason. It writes what State() already knows how to read.

Everything else REFUSES, and that is the feature, not a shortfall. Only Flex and
Icom could even toggle split before, neither could set the transmit frequency,
and Yaesu, TCI and OmniRig have nothing at all. A refusal WSJT-X can report —
and act on, by falling back to Fake It — is worth far more than a success it has
no way to check.

Both paths are pinned: split reaching the rig as one armed call with the right
frequency, and a backend that cannot do it producing an error rather than RPRT 0.
2026-08-11 17:53:46 +02:00
rouggy 18f9b915c5 fix: PGXL meters/auth/fan, TCI spots+click, PTT-over-CAT, CW <LOGQSO>
- PGXL: remote AUTH password; direct-link meter fallback (VITA-first) with
  250 ms poll + peak-hold; fan mode uses bare "fanmode=" (was ignored).
- TCI: spot colour sent as decimal ARGB (ExpertSDR dropped the hex string);
  spot click handled via CLICKED_ON_SPOT / RX_CLICKED_ON_SPOT to fill the entry.
- FlexRadio: clicking an OpsLog spot on the panadapter now applies the mode too.
- Filter presets: the trash icon deletes again (Radix pointer-down intercept).
- PTT hotkey: keys over CAT when a backend is active (was hijacked by a stale
  Audio-tab RTS/DTR serial setting); AltGr keys allowed; presses logged.
- CW macro <LOGQSO>: logs after the preceding CW is sent, not on the first letter.
2026-08-04 15:55:10 +02:00
rouggy f6cd6e999a chore: release v0.22.9 2026-08-02 06:40:10 +02:00
rouggy 961357474d feat: Flex stays on the RX slice in split
SmartSDR moves its active flag onto the TX slice as soon as the transmit
frequency is touched, and OpsLog followed it. But the operator is listening to
the DX on the other slice: the S-meter, audio level, filter and DSP they are
adjusting all belong there, so following the transmitter handed them the
controls of a receiver they were not using.

In split the receive slice now wins. Simplex is unchanged, and two same-band
slices in different classes (SSB alongside FT8) are still not a split.

A slice clicked IN OPSLOG is remembered and overrides both the split rule and
the radio's focus — that is the operator speaking. Activating a slice on the
radio or in SmartSDR deliberately does not move OpsLog. The pin is dropped when
that slice stops being in use, so a closed receiver cannot strand the display.

The panel now highlights the slice OpsLog is working with rather than the radio's
focused one; reporting the radio's flag would light up one slice while every
control acted on another.
2026-07-30 23:03:29 +02:00
rouggy d49126d45c chore: stop logging FlexRadio meter values
They arrive many times a second and were dumped every 5 s, drowning the rest of
the log. They only ever existed to confirm the meter NAMES during development,
which the subscription line already does — and that one is now a single summary
instead of one line per meter, a Flex announcing dozens of them at each connect.
2026-07-27 22:20:47 +02:00
rouggy 51e279887d feat: Super Check Partial + N+1 helper; fix Flex binding to SmartSDR CAT; telemetry callsign wait
- SCP/N+1: new internal/scp downloads the community MASTER.SCP master list and a
  docked two-column widget shows, as you type a call, the known calls containing it
  (Partial) and the calls one edit away (N+1) — click to fix a busted call. Opt-in
  in Settings → General; top-bar toggle; queried debounced on callsign input.
- Flex: OpsLog's GUI-client detection was too loose and could bind to "SmartSDR CAT"
  (or DAX) — both carry "smartsdr" in the program name — instead of the real GUI
  client, making SmartSDR CAT drop and reconnect in a loop while OpsLog was open.
  Now it binds only to a real SmartSDR/Maestro GUI client (e.g. a FLEX-8600M's
  integrated screen) and excludes cat/dax; dropped the risky empty-program fallback.
- Telemetry: on a fresh install the callsign isn't set at launch, so the once-a-day
  heartbeat recorded the machine UUID. Now it waits (~10 min) for the operator to
  enter their callsign before sending, falling back to the UUID only if none appears.
2026-07-25 20:05:33 +02:00
rouggy b83d55cc32 fix: SteppIR flaky status pinned FlexRadio TX interlock — operator couldn't transmit
The motorized-antenna follow loop keyed its deadband off the antenna's reported
frequency. A SteppIR reports an intermittent/stale status frequency (flips
between the commanded freq and its home/6 m value), so the deadband tripped on
almost every 1.5 s poll and re-issued a tune command. Each command refreshed
noteMotorMoveCommanded(), keeping motorTXInhibitLoop's recentCmd window alive, so
the Flex transmit-inhibit ("Interlock is preventing transmission") never
released — confirmed in a real log (moving=0 throughout, recentCmd was the
driver).

Follow loop now keys the deadband off the LAST COMMANDED rig frequency, only
re-tuning when the radio actually QSYs beyond the step — immune to a flaky
antenna status. Falls back to the antenna's freq only until the first command.

Also dropped SetTXInhibit's `interlock set reason=` sends: `reason` is a
read-only field on the Flex interlock object, so writing it is rejected
(cmd error 5000002D on V1.4.0.0) and did nothing; `transmit set inhibit=` is the
real mechanism and is unchanged.
2026-07-24 15:53:40 +02:00
rouggy 1070637c40 feat+fix batch: Station Control dashboard (fixed-width panels, grip-handle drag reorder, amp meters from the Flex stream, compact relays), Ultrabeam element list capped to 3 (READ_BANDS over-read), spot-click on Flex panadapter now sets mode, DAX TX toggle, DVK panel state persists across relaunch, duplicate amp meters cleared on power-cycle, QSO audio recording snapshot taken synchronously at log time (was racing the form-clear cancel), Flex COMP meter max -20->-25 and MIC scale to 0; changelog 0.20.10 2026-07-23 01:08:47 +02:00
rouggy 6b04072e52 fix: clicking an OpsLog spot on the Flex panadapter now sets the mode too — cluster spots get a mode inferred (comment/band plan) and SendSpot converts it to a real Flex mode (SSB->USB/LSB, FT8->DIGU), so SmartSDR actually switches mode on the click; changelog 0.20.10 2026-07-22 20:36:29 +02:00
rouggy a9ca50b2dd fix: the Flex panel DAX button now toggles the TRANSMIT-bar DAX (transmit set dax=), not the slice RX DAX channel — this is the button that routes TX audio through DAX (WSJT-X); state follows changes made in SmartSDR too 2026-07-22 20:24:25 +02:00
rouggy 512b5fd35b feat: DAX selector on the Flex panel — routes the active slice's RX audio to a DAX channel (slice dax=0-8, Off..8 dropdown next to the antenna selection, highlighted when active); changelog updated 2026-07-22 17:33:45 +02:00
rouggy b7dd8d4852 feat: multiple amplifiers + SmartSDR v4 DSP filters
Multi-amp: Settings->Amplifier becomes a list (amps.json, legacy single-amp keys auto-migrate to entry #1); one client per enabled amp with per-id bindings (GetAmplifiers/SaveAmplifiers/GetAmpStatuses/AmpOperate/AmpPower/AmpPowerLevel/AmpFanMode); legacy a.pgxl/a.spe/a.acom point at the first enabled amp of each family. Amp cards in FlexPanel and Station Control gain a dropdown to pick the amp; the status bar shows one clickable chip per amp. Use case: two SPEs run in parallel.

Flex v4 DSP (8000/Aurora): NRL/ANFL (lms_nr/lms_anf), NRS (speex_nr), NRF (nrf) with level sliders, RNN (rnnoise) and ANFT on/off — keys per the FlexLib slice docs; the section only shows when the radio reports these keys (dsp_v4 flag), so 6000-series panels are unchanged.
2026-07-22 17:25:10 +02:00
rouggy 3cef885934 feat: Flex CWX type-ahead backspace (cwx erase) — phase 2
Completes the CWX type-ahead loop: with send-on-type the keyer-panel CW text
already streams each typed char to the radio's CWX buffer (which keys in order,
so you can keep typing while it sends); this adds the matching un-send. Route
wkBackspace to FlexBackspaceCW -> cwx erase N, so backspacing a mistyped char in
send-on-type removes it from the buffer before the radio keys it.
2026-07-20 16:12:24 +02:00
rouggy 9729ef62ba feat: FlexRadio CWX CW keyer (send/stop/speed) — no WinKeyer/SmartCAT needed
Adds a third CW engine alongside WinKeyer and Icom CI-V: FlexRadio's CWX keyer
over the existing SmartSDR CAT connection.

- cat.FlexController: SendCW (cwx send), StopCW (cwx clear); flex.go implements
  them, escaping the quoted text form. Speed reuses SetCWSpeed (cw wpm).
- App bindings FlexSendCW/FlexStopCW/FlexSetKeySpeed via FlexDo.
- Frontend: cwSource gains 'flex'; macros/auto-call/<LOGQSO>/send-on-type route to
  Flex when the CAT backend is a Flex (estimate-based timing like Icom, no busy
  echo). Keyer panel shows 'Flex CWX' + ready/offline; Settings adds the engine
  option with a CAT-backend guard.

Core send/stop/speed first; type-ahead buffer + mid-send backspace (cwx delete)
to follow.
2026-07-20 15:13:24 +02:00
rouggy 829c236d6c feat: New Station Control, allow to control Webswitch 1216H or KMTronic 2026-07-16 22:01:07 +02:00
rouggy c9fd1379e1 feat: While using Flex & Steppir or Ultrabeam can prevent transmit when antenna is moving 2026-07-16 19:51:25 +02:00
rouggy 3cd80ead81 fix: wrong scale on the PGXL meter 2026-07-15 12:01:12 +02:00
rouggy 9e2ffdb758 feat: Adding XIT RIT in the Flex panel 2026-07-14 23:54:06 +02:00
rouggy 73f3ec51f7 fix: Flex with multiple slices opened was always showing slice A s-meter. 2026-07-10 23:13:06 +02:00
rouggy 6c39204301 chore: release v0.19.4 2026-07-10 17:16:32 +02:00
rouggy 6ab606fa54 fix: Bug showing split for flex while in different mode on same band 2026-07-10 15:59:32 +02:00
rouggy 19c2de5f61 chore: release v0.19.2 2026-07-09 16:51:57 +02:00
rouggy 521f8266cf feat: added full support in USB (local) & ethernet (local or remote) of audio for Icom 2026-07-09 11:30:06 +02:00
rouggy 6db90abcad feat: Management of multiple slices on Flexradio 2026-07-07 19:35:25 +02:00
rouggy 5b37397a64 fix: Save and close taking time when Flex or Icom is not connected 2026-07-07 11:07:16 +02:00
rouggy edede0bc1e fix: zoom taking too long after clicking a spot 2026-06-30 09:14:50 +02:00
rouggy a05dd6b3a9 feat: Added Antenna selection to Flex FlexPanel
feat: New settings flexradio to select antennas per band
2026-06-29 23:07:52 +02:00
rouggy 464a1c702c feat: added mute and AGC-T to Flex control 2026-06-27 21:03:13 +02:00
rouggy 6ac9783f7c feat: qrz clickable in cw decoder 2026-06-21 21:57:11 +02:00
rouggy 0e2ef317c3 feat: Added chat when MySQL is in use 2026-06-21 02:30:01 +02:00
rouggy 4b5e2e0b72 fix: Binding to Gui Client to get proper values for cw delay and pitch 2026-06-20 19:34:10 +02:00
rouggy 95d37da3bb feat: While importing ADIF, update MY fields 2026-06-20 15:48:21 +02:00
rouggy bde1195b34 feat: added FlexRadio support (meters & basic functions) 2026-06-17 18:29:35 +02:00
rouggy 69d0780bac feat: added versionning & About window 2026-06-16 19:36:56 +02:00