Add CW keying, function key messages and the documentation
The function keys send through cwdaemon or a WinKeyer, with N1MM's message macros. Escape stops sending. Settings are read with the reflection serializer rather than a generated one: the generated one hands back null for every property the file leaves out instead of the value the property is declared with, which crashed the program the first time a new setting was added. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
54
docs/n1mm-interop.md
Normal file
54
docs/n1mm-interop.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# Opening a Nonemm log in N1MM
|
||||
|
||||
Checked on 2026-08-27 against N1MM Logger+ 1.0.11031 by writing a log here,
|
||||
copying it to a Windows machine and opening it there. N1MM read the contest, its
|
||||
categories and the contacts.
|
||||
|
||||
Three things had to be right, and none of them is obvious from the schema.
|
||||
|
||||
## The `Contest` table needs a row for the contest
|
||||
|
||||
`ContestInstance` says which contest a log is; the `Contest` table says what that
|
||||
contest *is*. N1MM reads it in `Contest.FromRow` when it opens a log and throws
|
||||
`InvalidOperationException: No current row` if the row is missing, which reaches
|
||||
the operator as "A runtime error occurred".
|
||||
|
||||
So the definition row is written whenever a contest is opened, not only when it
|
||||
is created — a log made before this was understood gets its row the next time it
|
||||
is opened. `ContestDefinitions.For` builds the row from the contest's own rules:
|
||||
the display and Cabrillo names, the mode, the dupe type and the multiplier
|
||||
names.
|
||||
|
||||
## The overlay category cannot be empty
|
||||
|
||||
An empty `ContestInstance.OverlayCategory` is answered with "Invalid Overlay
|
||||
Category:" and the log will not open. An entry with no overlay says `N/A`.
|
||||
|
||||
N1MM's list is not the Cabrillo specification's list. N1MM offers:
|
||||
|
||||
N/A, ROOKIE, BAND-LIMITED, TB-WIRES, OVER-50, HQ, NOVICE-TECH, EXPERT
|
||||
|
||||
so that is what the contest dialog offers.
|
||||
|
||||
## The sent exchange omits the report
|
||||
|
||||
N1MM's contest dialog says "Omit RST: CQWW: 05". `SentExchange` for CQ WW is
|
||||
`14`, not `599 14`; for a serial number contest it is `001`. The report is fixed
|
||||
for the whole contest and the entry window fills it in per contact.
|
||||
|
||||
## Getting the schema in the first place
|
||||
|
||||
N1MM ships no template database. `ham.s3db` is built at run time by applying SQL
|
||||
migration files that N1MM writes out from string resources inside
|
||||
`N1MMLogger.net.exe`. To read them: decompile the executable, parse
|
||||
`N1MMLogger.Net.Resources.resx`, and take the untyped `<data>` entries named
|
||||
`DXLogDDL_0001_initial_schema_and_data` through `DXLogDDL_0004_updates`. The QSO
|
||||
table is `DXLOG` and the current `PRAGMA user_version` is 4.
|
||||
|
||||
`src/Nonemm.Storage/Schema.sql` is that schema, flattened to the state version 4
|
||||
leaves behind.
|
||||
|
||||
## One thing to avoid
|
||||
|
||||
Do not replace the database file under a running N1MM. It does not notice and
|
||||
throws on the next read.
|
||||
Reference in New Issue
Block a user