diff --git a/docs/Planned-Features.md b/docs/Planned-Features.md index 7419c443..a2250b72 100644 --- a/docs/Planned-Features.md +++ b/docs/Planned-Features.md @@ -328,8 +328,8 @@ trx-configurator ## Logbook and Ham Radio Layout Two halves of one feature ([#54](https://git.haxx.space/sjg/trx-rs/issues/54)): a station -logbook that speaks ADIF, and an operator layout that puts a transceiver's controls and that -logbook on one screen. +logbook in a panel of its own, and an operator layout that puts a transceiver's controls +around it. Nothing in the application records a QSO today. The map's "QSO summary" cards describe contacts *between other stations*, reconstructed from decoded traffic; bookmarks are @@ -340,25 +340,49 @@ frequencies, not contacts. Neither is the operator's own log. | ID | Description | |----|-------------| | REQ-LOG-001 | The system shall record QSOs the operator makes, each holding at minimum callsign, date, time, band, frequency, mode and both signal reports. | -| REQ-LOG-002 | When logging a QSO, the system shall pre-fill frequency, band, mode and time from the selected rig, and the station's own callsign and locator from configuration. | -| REQ-LOG-003 | The system shall allow a logged QSO to be edited and deleted. | -| REQ-LOG-004 | The system shall survive a crash without losing a QSO that was recorded before it. | -| REQ-LOG-005 | The system shall list, search and filter the log by callsign, band, mode and date range. | -| REQ-ADIF-001 | The system shall export the log as an ADIF 3.1.x `.adi` file. | -| REQ-ADIF-002 | The system shall import ADIF `.adi` files produced by other logging software, preserving fields it does not itself use. | -| REQ-ADIF-003 | When importing, the system shall identify QSOs already held and shall not duplicate them. | -| REQ-LOG-006 | Where a decoded station is on screen, the system shall offer to start a log entry from it, pre-filled, without logging it unattended. | -| REQ-LOG-007 | The system shall show whether a callsign has been worked before, and on which bands. | -| REQ-LAY-001 | The system shall offer a "Ham radio" operator layout presenting the transceiver controls and the logbook together. | -| REQ-LAY-002 | Where the selected rig cannot transmit, the system shall not offer the ham layout. | +| REQ-LOG-002 | When starting a log entry, the system shall pre-fill exactly six fields: frequency, mode, rig name, time, callsign and locator. | +| REQ-LOG-003 | The system shall leave every other field of a log entry empty for the operator to fill. | +| REQ-LOG-004 | The system shall allow a logged QSO to be edited and deleted. | +| REQ-LOG-005 | The system shall survive a crash without losing a QSO that was recorded before it. | +| REQ-LOG-006 | The system shall list, search and filter the log by callsign, band, mode and date range. | +| REQ-LOG-007 | Where a decoded station is on screen, the system shall offer to start a log entry from it, pre-filled, without logging it unattended. | +| REQ-LOG-008 | The system shall show whether a callsign has been worked before, and on which bands. | +| REQ-FMT-001 | The system shall export the log as an ADIF 3.1.x `.adi` file. | +| REQ-FMT-002 | The system shall import ADIF `.adi` files produced by other logging software, preserving fields it does not itself use. | +| REQ-FMT-003 | When importing, the system shall identify QSOs already held and shall not duplicate them. | +| REQ-FMT-004 | The system shall export a filtered selection of the log as a Cabrillo 3.0 file for contest submission. | +| REQ-LAY-001 | The system shall present the logbook in a panel of its own, reachable whatever layout is selected. | +| REQ-LAY-002 | The system shall offer a "Ham radio" operator layout presenting the transceiver controls and that panel together. | +| REQ-LAY-003 | Where the selected rig cannot transmit, the system shall not offer the ham layout. | ### A decode is not a QSO The decoders are receive-only: FT8, CW, APRS and the rest report what was *heard*. A heard callsign is the beginning of a log entry, not a contact, and the logbook must never write one -by itself — REQ-LOG-006 says offer and pre-fill, never auto-log. Digital QSOs made in +by itself — REQ-LOG-007 says offer and pre-fill, never auto-log. Digital QSOs made in WSJT-X or similar arrive the way every other logger takes them: through ADIF import. +### What is pre-filled, and what is not + +Six fields, and no more (REQ-LOG-002, REQ-LOG-003): + +| Field | From | ADIF | +|-------|------|------| +| Frequency | the selected rig's dial | `FREQ`, with `BAND` derived from it | +| Mode | the selected rig | `MODE`, and `SUBMODE` where the mode implies one | +| Rig name | the rig's display name | `MY_RIG` | +| Time | the clock, at the moment the entry opens | `QSO_DATE`, `TIME_ON` | +| Callsign | the decode row or map station the entry was started from, else empty | `CALL` | +| Locator | that station's grid, where the decode carried one, else empty | `GRIDSQUARE` | + +Signal reports, power, name, QTH and the rest stay empty. A report in particular is the +operator's to give: an FT8 SNR is not what was sent, and pre-filling one would put a number in +the log that nobody exchanged. + +The station's own callsign and locator are not pre-filled per entry either — they are station +identity, taken from configuration when the QSO is written (`STATION_CALLSIGN`, `OPERATOR`, +`MY_GRIDSQUARE`), and shown once at the top of the panel rather than typed into every row. + ### Architecture #### New crate: `trx-logbook` @@ -392,15 +416,35 @@ keeps the last one, and a compaction pass rewrites the file when superseded reco threshold. Appending is O(1) and atomic per line, so a crash costs at most the line being written. -#### ADIF in-repo +#### Two formats, for the two things a log is asked for -ADI is a tagged text format: `value`, records ended by ``, a header ended -by ``, everything outside a tag ignored. It is small enough to implement exactly, which -this project already prefers for its decoders, and doing so keeps the dependency list where it -is. The reader must be lenient in the ways real files are irregular — lowercase tags, CRLF, -missing header, unknown fields, type indicators — and the writer strict. Unknown fields are -carried through import to export unchanged, so a round trip through trx-rs does not quietly -strip what another logger wrote. ADX (the XML form) is out of scope. +The file formats were left open ("pick a well-known ham format"), so: **ADIF for interchange, +Cabrillo for contest submission.** Both are implemented in-repo, in the way this project +already implements its decoders, and neither adds a dependency. + +**ADIF has to stay.** It is not one option among several — it is the only thing the ecosystem +reads. LoTW, eQSL, Club Log, QRZ.com and every other logger take ADIF and nothing else, so a +log that cannot write `.adi` cannot be uploaded, confirmed, or moved to another program. That +is a one-way door, and the interoperability is most of the point of keeping a log at all. +Nothing on disk is ADI regardless: the store is JSON Lines, and ADIF is what comes out of an +export. + +ADI is a tagged text format — `value`, records ended by ``, a header ended +by ``, everything outside a tag ignored — small enough to implement exactly. The reader +must be lenient in the ways real files are irregular (lowercase tags, CRLF, missing header, +unknown fields, type indicators) and the writer strict. Unknown fields are carried through +import to export unchanged, so a round trip through trx-rs does not quietly strip what another +logger wrote. ADX, the XML serialisation of the same data model, is out of scope: it is part +of the standard but almost nothing reads it. + +**Cabrillo is the second format, because ADIF cannot do its job.** Contest logs are submitted +to sponsors in Cabrillo 3.0 and are rejected in anything else — a header of `CALLSIGN:`, +`CONTEST:`, `CATEGORY-*` and `CLAIMED-SCORE:` lines, then one fixed-column `QSO:` line per +contact carrying frequency in kHz, a mode code (`CW`, `PH`, `FM`, `RY`, `DG`), the UTC date and +time, and both stations' calls, reports and exchanges. It is export-only and drops everything +outside the contest's exchange, which is why it complements ADIF rather than replacing it. +It arrives with the contest exchange fields in phase 5, since without a serial or a zone to +put in the exchange there is nothing for it to write. #### Integration points @@ -420,7 +464,8 @@ strip what another logger wrote. ADX (the XML form) is out of scope. | `POST` | `/logbook` | Add a QSO | | `PUT` | `/logbook/{id}` | Edit | | `DELETE` | `/logbook/{id}` | Delete | -| `GET` | `/logbook/export.adi` | Export, honouring the current filter | +| `GET` | `/logbook/export.adi` | ADIF export, honouring the current filter | +| `GET` | `/logbook/export.cbr` | Cabrillo export of a contest selection | | `POST` | `/logbook/import` | Import, answering with counts: added, duplicate, rejected | | `GET` | `/logbook/worked/{call}` | Worked-before: bands and modes | @@ -428,9 +473,15 @@ Writes require the control role, as the rig endpoints do. ### Frontend -A **Logbook tab** joins the tab order: an entry form that opens pre-filled, a table with the -filters of REQ-LOG-005, and import/export. Worked-before shows against the callsign as it is -typed. +The logbook is **its own panel**, not a strip bolted to the radio page: a `logbook` entry in +the tab order beside Bookmarks, holding the entry form, the table with the filters of +REQ-LOG-006, and import and export. It stands on its own in every layout, so a log can be kept +without adopting the ham layout, and read while another layout is selected (REQ-LAY-001). + +The panel is three parts: the station line at the top (own callsign, locator, the rig a QSO +would be logged against), the entry form beneath it opening with the six pre-filled fields, +and the log itself under that, filtered as REQ-LOG-006 asks. Worked-before shows against +the callsign as it is typed. The **ham layout** is a fifth entry in the operator layouts (`compact`, `broadcast`, `digital`, `full`), which already gate on capability, seed the disclosure sections and persist per rig: @@ -445,8 +496,10 @@ ham: { ``` with the `ham` capability set from `RigCapabilities.tx`. It keeps frequency, VFO, mode, filter, -PTT, power and the meters; it hides the broadcast furniture; and it puts the log beside the -spectrum rather than a tab away. +PTT, power and the meters, and hides the broadcast furniture. What it adds over `full` is where +it starts: the logbook panel, with the radio controls a keystroke away rather than the other +way round — the layout an operator working the bands wants, where logging the contact is the +task and the rig is the instrument. ### Phases @@ -456,7 +509,7 @@ spectrum rather than a tab away. | 2 | Store, dedupe, and the HTTP API behind the control role | | 3 | Logbook tab: entry, table, filters, import, export | | 4 | Ham layout, pre-filled entry from a decode row or the map, worked-before | -| 5 | Optional: QSL and LoTW/eQSL fields, contest exchange fields, per-band worked/confirmed statistics | +| 5 | Contest exchange fields and Cabrillo export; QSL and LoTW/eQSL fields; per-band worked/confirmed statistics | ### Open questions