Compare commits

...
3 Commits
Author SHA1 Message Date
rouggy 8b66030c89 fix(udp): WSJT-X QSOs were missing the solar data and the distance
The UDP path applies the station profile, the DXCC number, the Club Log
exceptions, the zone refinement and the QSL defaults — and its comment says
"same as the manual AddQSO path", which it was not. applySolar and fillDistance
were never called there.

For an operator running digital, and that is most of the traffic on most
stations, it meant SFI, A, K and distance were empty across the whole log while
a hand-logged contact carried all four. It also quietly undermines the
history-based propagation work, which needs those numbers to be there.

applySolar now refuses a QSO more than a day old, whichever path it arrives by.
The UDP feed and the ADIF monitor normally carry contacts seconds old but
neither promises it — a logger re-broadcasting its backlog, or an operator
typing last month's contact by hand, would be handed this morning's SFI as
though it had been measured at the time. A wrong reading is worse than a missing
one: afterwards nothing tells it apart from a real one.
2026-08-11 22:11:29 +02:00
rouggy d4f23a52af fix(details): QSL via gets the width, QSL message gives it up
Width should follow use, and these two are nowhere near equal: a manager's
callsign is typed constantly, a QSL message almost never. The message held 7
columns of 12 for text most operators never write, while the field beside it —
often a long "via" instruction — was the one running out of room.

Swapped, so QSL via takes 7 and the message 5. Also puts them in the order they
are reached for.
2026-08-11 21:35:41 +02:00
rouggy b4b9674d8c chore: open 0.24.7
Empty block at the top so the next change has somewhere to go. 0.24.6 keeps its
six entries; the release script stamps the version constants.
2026-08-11 21:15:52 +02:00
3 changed files with 37 additions and 4 deletions
+19
View File
@@ -2721,6 +2721,15 @@ func (a *App) applySolar(q *qso.QSO) {
if a.solar == nil {
return
}
// Today's space weather belongs on today's QSO. The ADIF monitor and the UDP
// path both feed contacts that are normally seconds old, but neither promises
// it: a logger re-broadcasting its backlog, or an operator typing in last
// month's contact by hand, would otherwise be given this morning's SFI as if
// it had been measured at the time. A wrong number is worse than none — it
// cannot be told from a real reading afterwards.
if !q.QSODate.IsZero() && time.Since(q.QSODate) > 24*time.Hour {
return
}
d := a.solar.Get()
if !d.OK {
return
@@ -11823,6 +11832,16 @@ func (a *App) LogUDPLoggedADIF(adifText string) (int64, error) {
a.refineDistrictZones(&q) // W6 → CQ3/ITU6 for zone-split countries
a.applyQSLDefaults(&q)
// ── Space weather and path length ──
// Also "same as the manual path", and they were missed when that comment was
// written. A QSO auto-logged from WSJT-X went in with no SFI, no A, no K and
// no distance, so an operator running digital — which is most of the traffic
// on most stations — had those fields empty across the whole log while a
// hand-logged contact carried them. Both are stamped only where the record
// left them empty, so an ADIF that supplied its own still wins.
a.applySolar(&q)
fillDistance(&q)
// ── Dedup (serialised) ──
// Match by call + band + mode within a ±2-minute window: a QSO logged
// manually in OpsLog and re-broadcast by Log4OM over UDP often differs by
+10
View File
@@ -1,4 +1,14 @@
[
{
"version": "0.24.7",
"date": "",
"en": [
"QSOs logged from WSJT-X now carry the space weather and the distance, like hand-logged ones. The UDP path stamped the station profile, the DXCC and the QSL defaults but not SFI, A, K or distance — so an operator running digital had those fields empty across the whole log. Space weather is only stamped on a contact less than a day old: a logger re-broadcasting its backlog would otherwise be handed this morning readings for last month contacts."
],
"fr": [
"Les QSO enregistrés depuis WSJT-X portent désormais la météo spatiale et la distance, comme ceux saisis à la main. Le chemin UDP posait le profil station, le DXCC et les défauts QSL mais ni SFI, ni A, ni K, ni distance — un opérateur en numérique avait donc ces champs vides sur tout son log. La météo spatiale n est posée que sur un contact de moins d un jour : sinon un logiciel qui rediffuse son historique se verrait attribuer les relevés de ce matin sur des contacts du mois dernier."
]
},
{
"version": "0.24.6",
"date": "",
+8 -4
View File
@@ -373,12 +373,16 @@ export function DetailsPanel({ callsign, prefix, operatorGrid, remoteGrid, qth,
<Input value={details.address} onChange={(e) => onChange({ address: e.target.value })} />
</Field>
</div>
<Field label={t('detp.qslMessage')} span={7}>
<Input value={details.qsl_msg} onChange={(e) => onChange({ qsl_msg: e.target.value })} />
</Field>
<Field label={t('detp.qslVia')} span={5}>
{/* QSL via gets the room, not the message. Width should follow use, and
these two are nowhere near equal: a manager's callsign is filled in
constantly and a QSL message almost never. The message had 7 columns
of 12 for text most operators never type. */}
<Field label={t('detp.qslVia')} span={7}>
<Input value={details.qsl_via} onChange={(e) => onChange({ qsl_via: e.target.value })} />
</Field>
<Field label={t('detp.qslMessage')} span={5}>
<Input value={details.qsl_msg} onChange={(e) => onChange({ qsl_msg: e.target.value })} />
</Field>
</div>
)}