Commit Graph
12 Commits
Author SHA1 Message Date
rouggyandClaude Opus 5 3ac6f7e49c fix(sat): the Flex slices get their antenna, their sideband and their tone
Three things the tracker was leaving to chance on a FlexRadio, all reported from
a real pass.

ANTENNAS. Settings ▸ FlexRadio holds a per-band RX/TX antenna map, and it was
applied in exactly one place: the entry form, on a band change, to the active
slice. A pass never goes through that path — the tracker arms two slices itself.
So both were left on whatever the radio last used, and a station with
transverters (XVTA on 2 m, XVTB on 70 cm) heard nothing at all, having
configured precisely the thing being ignored. The two slices are on two
different bands, so they cannot share one setting: the downlink takes the
receive antenna for ITS band, the uplink the transmit antenna for its. Per
slice, not through sendSlice, which addresses whichever slice is active — during
a pass that is the downlink, so the uplink would never have been set.

SIDEBAND. satMode forced USB above 30 MHz on both sides. An inverting
transponder turns the passband over, so lower sideband up comes back as upper
sideband down: FO-29, RS-44 and AO-73 were being worked with the operator's own
audio going through upside down. The tracker now decides both sidebands from the
transponder's inverting flag and passes them separately; a bare "SSB" still
means USB, so nothing else changes.

CTCSS. Nothing set it, on any bird. The frequency plan has carried the tone all
along — 67.0 on SO-50 and AO-91, 141.3 on PO-101 — and an FM repeater does not
answer without it, which is indistinguishable from a satellite that is not
there. It goes on the uplink slice, value before mode so the radio cannot
transmit the previous tone in the gap between two commands.

Written against the SmartSDR slice API and UNTESTED on hardware.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-09-09 20:20:41 +02:00
rouggyandClaude Opus 5 0add56fb2d fix(sat): the Doppler correction was 250 times too big, and backwards
Reported as "the Doppler moves the frequency enormously", and it did: a 2 m
downlink was being shifted two megahertz across a pass instead of three
kilohertz, in the wrong direction.

The propagator library reports a range rate that is not one. Measured against
the range it is meant to be the derivative of, on this station's own cached
elements:

    PO-101   library -1457.3 km/s    measured +6.227 km/s
    ISS      library +2036.8 km/s    measured -5.522 km/s

Wrong by a factor of some 250 and of the wrong sign, so the correction both
overshot and pushed the operator away from the station they could hear. Nothing
else was affected — the elevation and the passes come from the look angle, which
is right — which is why this survived: the satellite was in the correct place on
the map while the radio was told to go megahertz away from it.

So OpsLog computes it itself, as the difference between two ranges a second
apart. That cannot be wrong in either magnitude or sign: it differentiates the
very number the panel displays. Two extra propagations per call, which is
microseconds.

Two tests pin it, and both fail against the old behaviour: a range rate faster
than orbital velocity is a units mistake, and the Doppler on the two bands
satellites are worked on has a textbook size — about ±3.5 kHz on 2 m, ±10 kHz on
70 cm.

cmd/satdiag is the throwaway that found it, kept because the next report of this
shape ("the frequency moves oddly", "that pass is not real") is answered by the
same three numbers: which elements the satellite resolved to, the range rate
reported against the range rate measured, and the Doppler each transponder gets.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-09-09 20:07:27 +02:00
rouggyandClaude Opus 5 86fd03fd6b feat(sat): generate the frequency plan, and join on the catalog number
25 satellites, typed by hand and never revisited. Eight of them were the
first-generation Tevel constellation, which re-entered in 2024; four more had
come down too; and the nine Tevel-2 satellites that replaced them, the Chinese
space station, AO-27, AO-123 and twenty others were simply absent. So: 44
satellites now, and a generator instead of a memory.

cmd/satgen joins three public sources on the NORAD catalog number — Celestrak's
amateur group and PE0SAT's mirror for which birds OpsLog can actually get
elements for, and SatNOGS DB for the transmitters. It is a one-shot tool, run by
hand, the same arrangement as cmd/cntygen, and it is deliberately conservative:

  - It never destroys a curated entry. The hand-written plans hold things
    SatNOGS does not reliably carry — a CTCSS tone, the QO-100 passband as
    operators describe it — so an existing bird keeps its data and only gains
    its catalog number.
  - It prunes on the re-entry date, which is a fact SatNOGS publishes rather
    than a judgement about which of the missing satellites are missing for good.
  - It refuses a digital uplink that does not say what it is. A GMSK uplink is a
    command channel far more often than a digipeater, and shipping the wrong one
    invites somebody to transmit on a control frequency. An analog uplink with
    both ends is a contact by construction, which is what catches the repeaters
    that describe themselves only as "Mode V/U FM".
  - Its output is deterministic. One satellite can hold two catalog entries —
    GreenCube is 53106 in one feed and 53109 in the other — and iterating a map
    picked a different one each run.

A bird now carries its NORAD number, and that is how its elements are found.
Names were the only join before, and they are written differently by every party
involved: "TIANYAN 01" and "TO-108" are one satellite that had never once met,
so TO-108 tracked nothing at all.

And the plan now reaches a station that has already run OpsLog. The editable
copy was written on the first launch and was the operator's list for ever after,
so a release adding nine satellites reached nobody who had opened the tab. It is
merged on each load instead: a satellite they already have is untouched, edits
and corrections included, and only the ones they have never seen are added.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-09-09 11:20:22 +02:00
rouggy 09f3ddaacb fix(confirmations): count a LoTW "V" everywhere, not only in the awards
An operator's screenshot had it side by side: the Awards panel showed Morocco
validated on five bands, and the band/mode matrix two inches above showed the
entity as merely worked.

ADIF's QSL_Rcvd enumeration has both Y and V — "received" and "verified" — and
V is what a LoTW download writes for a confirmation the ARRL has validated. The
award engine's isYes accepted "Y" or "V". Everything else in the app compared
against 'Y' alone: the worked-before status grid, the slot statistics, the row
colouring by QSL status, the awards QSO list, the call history badges. So the
confirmations an operator cares most about were the ones that did not count.

Now one definition per side, named so the next reader finds the other:
qso.ConfirmedValues on the Go side, used by the queries themselves, and
isQSLConfirmed in lib/qsl on the frontend, which rowColors and the panels call
instead of testing the letter.

The Go test drives the real query shape against a real database with a 'V' row
— the constant being right is not the point, the queries using it is.
2026-08-15 08:31:49 +02:00
rouggy 30143b01bf fix(counties): make the cluster and the entry panel agree on a US county
An operator asked why K1SEI showed "Middlesex" in Info (F2) and "Lower
Connecticut River Valley" in the cluster. Two sources: the entry panel has
a callbook answer, a spot carries only a callsign so the cluster derives one
from the FCC licence ZIP through GeoNames — and GeoNames has followed the
Census in replacing Connecticut's counties with the 2022 planning regions.
No award, callbook or log uses those, so every CT station matched nothing:
new county for ever, and counting toward nothing.

Measured against a full ULS import (1 556 444 US callsigns), 23 223 resolved
to a name the USA-CA reference does not contain. Three causes, three fixes:

  - Spelling. "City and County of San Francisco", "Baltimore (city)",
    "Nome (CA)", plus counties renamed since the award list was drawn
    (Kusilvak, Oglala Lakota, the Valdez-Cordova split) and Alaska's four
    "X City and Borough", whose reference codes read "JUNEAUCITYAND" because
    the county-type suffix strip eats the wrong end. Normalised in
    award.USCountyKey, which both sides already go through. 7 515 callsigns,
    no re-download needed.

  - Doña Ana, NM shipped into the reference as "NM/DO̱AANA" — mangled by a
    non-UTF-8 CSV line, a code nothing could ever produce, so that county was
    unwinnable and silent about it. Row repaired, cntygen now refuses such a
    line, and a test makes every one of the 3 102 references reproduce its own
    code from its own name.

  - Connecticut. A planning region is drawn from towns in several counties, so
    no name maps to a name — only the ZIP can resolve it. cmd/ctzipgen builds
    the table from the Census 2020 crosswalk, filling PO-box-only ZIPs from the
    nearest resolved centroid; all 11 ZIPs GeoNames still labels with a real
    county agree with the result. 15 037 callsigns, applied at import, so the
    store now carries a rules version and Settings says when a re-download is
    needed.

Alignment itself is the last piece: a spot now shows the county the station is
logged with when we have one, and falls back to the ZIP-derived county only for
stations never worked.
2026-08-14 00:42:27 +02:00
rouggy eb2ff8ed59 feat: New badges in cluster view for new Counties and new POTA 2026-07-17 15:28:36 +02:00
rouggy dd3b51a2ae feat: Added support for US Counties in OpsLog / Extra feature with DXHunter 2026-07-17 13:23:35 +02:00
rouggy 701e8a2c25 feat: Implemented Icom Ethernet CAT control 2026-07-06 17:37:25 +02:00
rouggy 06183bd5d4 feat: Themes added, 4 themes available (3 dark, 1 light) 2026-07-06 09:08:47 +02:00
rouggy fafa0c22ab fix: solve issue with Antenna Genius for remote operations 2026-07-05 20:52:37 +02:00
rouggy 4f32012930 feat: Implemented UDP Outbound Adif message, freq to pstrotator 2026-07-05 18:17:30 +02:00
rouggyandClaude Opus 4.7 7ace2cc602 Initial codebase: Go + Wails amateur radio logbook
Backend (Go 1.25 / Wails v2):
- QSO storage on SQLite (modernc) with embedded migrations (0001..0005)
- Streaming ADIF import (batch insert) + WorkedBefore per callsign and DXCC
- Callsign lookup with QRZ.com + HamQTH providers (primary/failsafe routing)
  and SQLite-backed TTL cache
- DXCC resolver from cty.dat (auto-download, longest-prefix-match)
- Multi-profile operator identities (home/portable/SOTA/contest) — every
  QSO stamps MY_* from the active profile
- CAT control via OmniRig COM on a single OS-locked goroutine, with
  bidirectional sync (freq/mode/band/split/VFOs) and Rig1/Rig2 hot-swap
- Settings store (key/value), CAT debug log at %APPDATA%/HamLog/cat.log

Frontend (React 18 + TypeScript + Tailwind v4 + shadcn-style):
- Single-row entry strip with CAT-aware band/mode/freq, RST, Start/End
  UTC, per-field locks (band/mode/freq/start/end) for backdated QSOs
- Topbar: live freq (MHz.kHz.Hz dotted), live UTC, band/mode/SPLIT badges,
  CAT pill with rig selector and clickable Azimuth pill (rotor TODO)
- Settings tree: Profiles (Log4OM-style manager), Station Information
  (edits the active profile), unified Callsign Lookup with Test buttons,
  Bands/Modes lists, CAT
- Worked-before matrix (band × mode × class) with new-DXCC highlighting
- ADIF import from menu + Maintenance > Refresh cty.dat

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
2026-05-26 00:16:45 +02:00