Commit Graph
326 Commits
Author SHA1 Message Date
rouggy 1630c8fdf4 feat: include band in the self-spot toast (Spotted by X on 20m with ...) 2026-07-21 10:08:11 +02:00
rouggy 408791ddf5 fix: <LOGQSO> now logs at its position in the macro (splits the macro there), and ESC/Stop before it completes cancels the pending log 2026-07-21 09:54:54 +02:00
rouggy 3de47a8825 fix: pin bottom status bar — root no longer shows a horizontal scrollbar that overlapped it in a small window 2026-07-21 09:49:49 +02:00
rouggy 880ecdbbb5 fix: cache relay-board drivers so Denkovi/USB-serial boards stay connected
The station-control code rebuilt a fresh driver on every status poll and every
relay set. Stateful boards (Denkovi FTDI D2XX, USB-serial) hold an OS handle only
one opener can own, so the first poll opened the board and leaked the handle, and
every poll after failed with 'device in use' — the relays greyed out a second
after Save and auto-control never switched. Drivers are now cached per device and
reused, closed on config change. Adds a Test-connection button + detect feedback
in the device editor (reported by VK4MA).
2026-07-21 09:31:08 +02:00
rouggy 615df0dc10 docs: update README (EN/FR) — SPE Expert amp, Station Control relays, Flex CWX keyer, statistics dashboard, What's new dialog 2026-07-21 09:24:28 +02:00
rouggy 2194279602 fix: drain SPE status backlog so display is current (was ~15s stale); ON now pulses DTR (0x0B is level-only); power-level cycle waits for real status change 2026-07-21 01:38:39 +02:00
rouggy 51c4bda71a fix: SPE card shows 'SPE offline' instead of 'PowerGenius offline' 2026-07-21 01:31:38 +02:00
rouggy 7d7d175ede feat: SPE amp ON/OFF buttons and Low/Mid/High power-level control (keystroke codes best-guess from APG, pending hw verification) 2026-07-21 01:25:55 +02:00
rouggy be1ae76eb3 fix: correct SPE band-code map (00=160m,01=80m,02=60m...confirmed on hw); add output-power bar to SPE amp card 2026-07-21 01:19:24 +02:00
rouggy 50157a25d3 feat: show band on SPE amp card, spell out power level (Low/Mid/High), larger status text 2026-07-21 01:13:02 +02:00
rouggy fe1a77a54d fix: use official SPE band-code table from the manual (00=60m,01=160m,...) 2026-07-21 01:10:12 +02:00
rouggy b818a2d947 fix: correct SPE status CSV field alignment (leading empty field shifts indices +1); decode band code; OPERATE/STANDBY now reflects real amp state 2026-07-21 01:09:13 +02:00
rouggy 5c4ae0cfd7 fix: put Mode Split By Band and By Mode side by side on the same row 2026-07-21 01:02:34 +02:00
rouggy 69635a15bc refactor: remove redundant By Band chart, keep Mode Split By Band in its place 2026-07-21 00:59:25 +02:00
rouggy 78220e700f fix: hide the entire Flex-reported amp card when PowerGenius is not the selected amp type 2026-07-21 00:57:16 +02:00
rouggy 42a6b9c76a debug: log raw SPE status frame on change (to verify CSV field alignment on real hw) 2026-07-21 00:54:13 +02:00
rouggy 56affa4bed feat: SPE Expert amplifier card in the Flex panel (OPERATE/STANDBY + live status)
When the configured amplifier is an SPE Expert (not the PowerGenius), the Flex
panel now shows an SPE control card — the Flex doesn't report SPE amps, so it's
driven by OpsLog's own SPE link. The PowerGenius fan-mode control is hidden when
the amp type isn't PowerGenius.
2026-07-21 00:49:48 +02:00
rouggy aa5af4fc75 ui: EN/FR toggle in the What's-new dialog (defaults to UI language) 2026-07-21 00:36:39 +02:00
rouggy 46772e54fe chore: check for updates every 5 minutes (was 10) 2026-07-21 00:32:19 +02:00
rouggy a0cea352ff feat: re-check for updates when opening Help - About (no more stale 'up to date')
Opening About now fires a fresh CheckForUpdate with a 'Checking…' state, and
clears the update banner when the latest check finds nothing — so it reflects
reality instead of the last periodic check.
2026-07-21 00:26:54 +02:00
rouggy 190b86eb1c chore: release v0.20.5 v0.20.5 2026-07-21 00:21:55 +02:00
rouggy cfc3d00ea1 feat: Help - What's new button to reopen the changelog anytime
Adds GetChangelog (all entries up to the running version, no seen-marker change)
and a Help menu 'What's new' item that reopens the changelog dialog on demand.
2026-07-21 00:17:11 +02:00
rouggy 9033e8518c feat: What's-new changelog dialog on first launch after an update (EN/FR)
Embeds changelog.json (per-version EN + FR notes, curated from the release's
commits). GetWhatsNew compares the stored last-seen version with the running
build and returns the notes for every newer version, once, then advances the
marker. A dialog shows them in the UI language on the first launch after update.
Seeded with the 0.20.5 notes.
2026-07-20 22:58:05 +02:00
rouggy bfbd9fa61a fix: activity chart uses rolling chronological windows (real dates), not cyclical
Day/Week/Month/Year now show the anchor day hour-by-hour, the last 7 days, the
last 30 days, and the last 12 months — anchored to the period end (else now), in
real date order. Replaces the cyclical hour-of-day/weekday/day-of-month/month
buckets, which left future days empty and ordered the weekend after Monday.
2026-07-20 21:39:24 +02:00
rouggy f0c4f22942 feat: stats activity-over-time granularity selector (timeline / day / week / month / year)
Backend adds cyclical distributions ByHour (hour-of-day), ByDOW (weekday), ByDOM
(day-of-month) and ByMonthYr (calendar month), all UTC. The Activity-over-time
card gains a selector: Timeline keeps the chronological month trend; Day/Week/
Month/Year show the hour/weekday/day/month distribution as bars.
2026-07-20 21:25:33 +02:00
rouggy 19c91f32a0 feat: stats — per-band mode split (CW / phone / data) stacked bar chart
Adds Stats.ByBandCategory (per band: CW/phone/data counts, band-plan order) via a
modeCategory() bucketing in stats.go, and a StackedBandBars chart in the Stats
panel showing the split per band with a legend.
2026-07-20 21:20:29 +02:00
rouggy 3ec23bc613 ui: compact Stations-on-air rows to single line so 5+ fit without scrolling 2026-07-20 19:36:01 +02:00
rouggy 2fbb922bd2 Revert "fix: UDP-logged QSOs adopt the active profile's station callsign (Club Log upload blocked)"
This reverts commit f0afdcc498.
2026-07-20 19:34:33 +02:00
rouggy f0afdcc498 fix: UDP-logged QSOs adopt the active profile's station callsign (Club Log upload blocked)
MSHV/WSJT-X often stamp a personal STATION_CALLSIGN (e.g. F4BPO) that differs
from the special-event/contest profile you're running in OpsLog (e.g. TM74TFR).
The QSO then failed the extsvc station-callsign guard and was never uploaded to
the (matching) Club Log logbook. Live UDP logging now stamps the active profile's
callsign when the base call genuinely differs (portable variants left alone).
2026-07-20 19:32:06 +02:00
rouggy 22352c5748 fix: who's-on-air freq/appearance lag — prompt publish on activity + 5s widget poll
publishLiveStatus only ran on QSO log or the 15s heartbeat, and the widget polled
every 15s, so an operator's band/freq (and their appearance) could trail by up to
a minute. Now ReportLiveActivity debounce-publishes ~1.5s after a freq/band/mode
change, and the widget polls every 5s (and 1.5s after qso:logged).
2026-07-20 19:17:13 +02:00
rouggy 6356d60a66 fix: Stations-on-air widget lagged minutes (timer reset by dbConn object churn)
The 15s poll effect depended on the dbConn OBJECT, which gets a fresh reference
on several events — each reset the interval before it fired, so the widget could
stay stale for over a minute. Depend on the is-mysql boolean instead, and also
refresh ~2s after qso:logged so our own row appears promptly like the ON AIR
badge.
2026-07-20 19:02:57 +02:00
rouggy cafade0dbb remove CW decoder (audio->text) entirely; fix CWX macro not stopping on call typing
- Removes the RX-audio CW decoder: deletes app_cw.go + internal/cwdecode, the
  cwDecoder/cwPitchHz/cwMu/cwStop App fields, and all frontend state/effects, the
  header Ear button, the Tools menu item and the decoded-text strip. The CW
  KEYER (WinKeyer/Icom/Flex) is untouched.
- Fix: typing a callsign while a macro is keying now aborts the CURRENT engine
  (Flex CWX / Icom / WinKeyer) on the first character, not just WinKeyer during
  an auto-call loop — via a shared stopKeyerTx() helper.
2026-07-20 19:00:09 +02:00
rouggy 2e39615554 feat: SPE Expert amplifier control (serial/TCP) — OPERATE toggle + live status
Implements the SPE Application Programmer's Guide protocol: packets
0x55 0x55 0x55|CNT|DATA|CHK (sum%256), OPERATE key 0x0D (toggles STANDBY/OPERATE)
and STATUS request 0x90 whose 0xAA-framed reply is a 19-field CSV (mode, RX/TX,
band, power level, output W, SWR, V/I, temp, warnings, alarms). internal/spe
polls status ~1/s over USB serial (go.bug.st/serial, 8N1) or TCP (RS232-to-
Ethernet bridge) — same codec, different transport.

Wired via startPGXL (starts the SPE client for spe* types), bindings GetSPEStatus
/ SPESetOperate, and a live status card + OPERATE/STANDBY toggle in the Amplifier
settings panel. Only the two example-anchored commands are sent (safe); other
keystroke codes were ambiguous in the guide's table. Untested on hardware.
2026-07-20 17:59:24 +02:00
rouggy 666b933114 feat: generalize Settings 'Power Genius' into 'Amplifier' (type + serial/IP transport) for SPE Expert
Renames the Hardware section to Amplifier and adds an amplifier-type selector
(4O3A PowerGenius XL, SPE Expert 1.3K-FA / 1.5K-FA / 2K-FA) plus a transport
choice for the SPE amps: USB (serial COM + baud) or Network (RS232-to-Ethernet
IP:port). PGXLSettings gains Type/Transport/ComPort/Baud (keys keep the pgxl.*
prefix for back-compat). PowerGenius still drives over TCP; SPE settings are
stored but control is not wired yet (needs the SPE serial protocol).
2026-07-20 17:44:56 +02:00
rouggy def59da748 ui: label both USB relay backends as 'Denkovi USB' (FT245/D2XX vs serial/COM) 2026-07-20 17:33:02 +02:00
rouggy fe69bc308c feat: Denkovi USB 4/8 (selectable) + generic USB-serial relay board (CH340/LCUS)
- Denkovi (FT245 D2XX) now selectable as 4 or 8 relays (a 4-relay board just uses
  the low nibble); NewDenkovi takes a count, driven by the device's Channels.
- New 'usbrelay' backend: cheap CH340/LCUS USB-serial boards over a COM port
  using the common A0 protocol ([0xA0][relay][state][checksum]); write-only, so
  Status is a shadow. Channel count configurable (1/2/4/8/16).
- StationDevice gains Channels; deviceRelayCount() drives label/relay counts for
  the variable-size types. Device editor: channel selector + COM-port picker
  (usbrelay) / FTDI-serial (denkovi).

Both untested on hardware; the A0 command set / Denkovi bit order may need a tweak
after a live test.
2026-07-20 17:23:38 +02:00
rouggy c07a17dc47 feat: Denkovi USB 8-relay board (FT245 D2XX bit-bang)
Third relay device alongside WebSwitch and KMTronic. Despite enumerating as a
COM port, this board is driven via FTDI D2XX synchronous bit-bang (one byte = 8
relays, bit 0 = relay 1), not serial ASCII — so we load ftd2xx.dll at runtime
(no CGO) and call FT_OpenEx/FT_SetBitMode/FT_Write, addressing the board by its
FTDI serial (e.g. DAE0006K), exactly like the vendor tool. Windows-only (stub
elsewhere); ListDenkoviDevices enumerates connected serials for the picker.

Wired into relaydev (Count/Status/Set), app.go (deviceDriver/relayCountFor/type
whitelist + ListDenkoviDevices binding), and the Station device editor (new type
+ FTDI-serial field with Detect). Untested on hardware; bit order / on-polarity
may need a flip after a live test.
2026-07-20 16:50:04 +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 b8db653981 fix: ESC now stops the active CW engine (Icom/Flex), not just WinKeyer
The ESC abort keyed WinkeyerStop unconditionally, so it never aborted the Icom
CI-V or Flex CWX keyer. Route the stop through cwSource like the panel Stop
button does.
2026-07-20 15:51:32 +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 cc6411a618 fix: Antenna Genius buttons ignored clicks while the CW decoder ran
PortBtn was defined inside AntGeniusPanel, so every render produced a new
component type and React unmounted/remounted every port button. Normally
re-renders are rare so it's invisible, but the CW decoder floods the app with
cw:text/cw:status events (re-render many times a second), tearing the buttons
down between mousedown and mouseup — the click never completed and the antenna
never switched. Move PortBtn to module scope (stable identity) and pass
onActivate/t as props.
2026-07-20 14:45:29 +02:00
rouggy 991831bdec chore: DDFM catalog file updated from Publish-to-catalog (address+QTH postal OR-rules, full department reference list) 2026-07-20 14:39:15 +02:00
rouggy 1b2da95ad4 ui: widen the Award management modal (max-w-6xl, 95vw) so the fuller footer fits 2026-07-20 14:35:18 +02:00
rouggy 10d86db50a feat: rename the database from Settings, keeping all config
Adds a Rename button to Settings -> Database: renames the current SQLite database
(e.g. opslog.db -> F4BPO.db) while preserving every setting/profile, unlike New
database which starts empty. Implemented as a VACUUM INTO copy + pointer switch;
the old file (open and locked now) is scheduled via config.json delete_pending
and removed, with its -wal/-shm sidecars, on the next launch.
2026-07-20 14:30:45 +02:00
rouggy 8538f48259 feat: Publish-to-catalog export for awards (edit in UI, version, ship to team)
Adds ExportAwardForCatalog(code, version): writes the selected award as a
catalog-format JSON ({"def":…,"references":…}) stamped with a version and with
user_edited cleared, ready to paste over internal/award/catalog/<code>.json. A
new release then propagates the change to the whole team via mergeCatalog —
unedited copies auto-upgrade, edited ones are offered the update.

UI: a version input + "Publish to catalog…" button in the award editor footer,
defaulting to one past the award's current version.
2026-07-20 14:20:30 +02:00
rouggy 0fa91c3d5f feat: ship DDFM v2 (postal-code OR-rule) via the award catalog so it reaches the team
DDFM now derives the French department from the address postal code, not only
from a note typed by hand — the catalog def gains the address OR-rule (\d{2}\d{3}
-> Dxx), France+Corsica scope, and version 2. On next launch every operator whose
DDFM is unedited auto-upgrades to it (user-edited copies are offered it); the
materialised award_refs then recompute so ~500+ French QSOs gain their department.

Also: a catalog definition update now clears the award_refs backfill flag, so any
future catalog bump self-heals the stored columns without a manual flag bump.
2026-07-20 13:57:50 +02:00
rouggy c86d331bd9 fix: re-materialize award_refs so new matching rules reach existing QSOs
The one-shot award_refs backfill never revisited rows after it ran, so a QSO
materialized before an award gained a rule kept stale values — e.g. DDFM's
postal-code OR-rule matched nothing on the 500+ French QSOs whose department
comes from the address, only the handful with it typed in notes. Two fixes:
bump the backfill flag (awards.materialized.v2) so every operator re-materializes
once on next launch with their current definitions, and make RescanAwards (the
Awards tab Rescan button) also recompute award_refs for an on-demand refresh.
2026-07-20 13:41:14 +02:00
rouggy 77a752efe3 chore: release v0.20.4 v0.20.4 2026-07-20 12:06:32 +02:00
rouggy 781fbfaa30 fix: wire up File - Exit (was disabled and had no handler)
The File menu's Exit item was hard-disabled and its action had no case in the
menu dispatcher, so it did nothing. Enable it and route file.exit to QuitApp,
which runs the same graceful beforeClose shutdown as the window close button.
2026-07-20 12:05:12 +02:00
rouggy 61c11c0fe3 fix: clear entry-form award refs when the callsign is wiped
Live award detection merges pickable refs into award_refs per call, but nothing
dropped them when the call was cleared, so a previous call's ref lingered onto
the next (IT9AOT's ref still showing after typing F4BPO, both listed in the F3
Awards tab). Clear award_refs the moment the callsign field is emptied.
2026-07-20 11:57:04 +02:00