Ctrl+Y from the entry window, or Enter on a row in the log, opens the whole contact in one dialog. It reaches the fields the log has no column for: QSX frequency, name, QTH, comment, grid, power, radio number, run position, and the country and WPX prefixes. Previous and Next walk the log without closing and offer to save first. The dialog checks values through the same QsoEditor the log columns use, so a zone the contest will not take is refused the same way in both places. QsoEdit now names the field that was refused, so the dialog can put the cursor back in the right box, and QsoEditor.ApplyAll changes several fields at once. Points and the multiplier flags are shown but not editable. They are worked out from the rules every time the log changes, so a typed value would be lost on the next edit. N1MM lets you type them; we do not, rather than offering a box that does nothing. A contact's own country prefix now wins over the country file when scoring. Without this, correcting the country in the dialog would change what the log shows and what Cabrillo says, but not the score. LoggingSession.Update now broadcasts the change like Edit does, so a contact saved from the dialog reaches the other stations. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Nonemm
A contest logger for amateur radio: a from-scratch reimplementation of N1MM Logger+ in C#, running on Linux and Windows.
The contest rules, log formats and database schema are written from their
published definitions. What Nonemm keeps is interoperability: the log
database is N1MM's .s3db in N1MM's schema, user-defined contests are N1MM's
.udc files, and a log either program writes opens in the other.
Running it
The SDK lives at ~/.dotnet on this machine, so a shell that has not been set
up needs:
export DOTNET_ROOT=$HOME/.dotnet PATH="$HOME/.dotnet:$PATH"
Then:
dotnet run --project src/Nonemm.App # start the logger
dotnet test Nonemm.slnx # run every test
./build.sh does the same with the environment already set: ./build.sh test Nonemm.slnx.
To work a contest: Config → Station for your callsign and zones, then File → New Database and File → New Contest. In the entry window, type a callsign and press space to move to the exchange, then Enter to log. Type a frequency into the callsign box and press Enter to change band. View opens the log, check, bandmap, score and packet windows.
Everything that judges a station — the bar under the callsign box, a row in the check window, a spot on the bandmap, a line in the log — is coloured by the same scorer: red for a dupe, green for a new multiplier, blue for points.
What it does
| Contests | CQ WW, CQ WPX, ARRL DX, IARU HF, Sweepstakes, RTTY Roundup, NAQP, general logging, and user-defined .udc contests |
| Log | N1MM .s3db, Cabrillo 3.0 out, ADIF in and out |
| While typing | dupe check, multiplier check, points, country and zone from the country file |
| Windows | entry, log, check, bandmap, score summary, packet |
| Editing | double-click a cell in the log, or open the whole contact with Ctrl+Y; Delete removes it. All of it goes out to the other stations |
| Radio | hamlib rigctld, reconnecting on its own |
| Cluster | DX cluster over telnet, spots feeding the bandmap |
| Network | contacts shared with the other stations of a multi-operator entry, in N1MM's own contact message |
| Keying | CW through cwdaemon or a WinKeyer, with N1MM's message macros |
The country file and the callsign database
Neither is bundled. Config → Download Country File and Download Check
Partial File fetch them from where they are published, which is where N1MM
fetches them from too —
country-files.com/cty/wl_cty.dat
and
supercheckpartial.com/MASTER.SCP.
The country file is wl_cty.dat rather than plain cty.dat: same format, with
the WAE entities listed separately, which is what CQ WW counts.
A download that fails changes nothing. The file is fetched, checked that it parses as what it claims to be, and only then put in place, so a site that answers with an apology page instead of a country file cannot cost an operator their multipliers mid-contest.
Both files can also be dropped into SupportFiles under the configuration
directory (~/.config/nonemm on Linux, Documents\Nonemm on Windows).
User-defined contests go in UserDefinedContests under the same directory.
Without a country file the program still runs; country- and continent-scored contests lose accuracy.
Radio control
The logger reads and tunes the radio through
hamlib's rigctld, started separately for whichever
radio is on the desk:
rigctld -m 2028 -r /dev/ttyUSB0 # -m is the hamlib model number; rigctl -l lists them
Then Config → Radio. With no radio connected nothing changes: frequency and mode stay where they were last typed.
CW
Config → Keyer and messages picks cwdaemon (a UDP port, usually 6789) or a
WinKeyer (a serial port), sets the speed, and edits the twelve function key
messages for CW and for phone. The macros are N1MM's: {MYCALL}, {CALL},
{EXCH}, {SENTRST}, {SENTNR}, # for the serial number, and {SENTRSTCUT}
for cut numbers. Escape stops sending.
Editing the log
Double-click a cell in the log window to change it. The columns follow the contest exchange, so CQ WW shows a Zone column and Sweepstakes shows Nr, Prec, Ck and Sec. A value the contest does not accept — zone 41, an ARRL section that does not exist, a callsign with a space in it — is refused and the reason appears under the log. Changing the callsign looks the country up again.
Delete, or the right-click menu, removes the selected contact after a confirmation. Either way the whole log is scored again, so a multiplier the removed contact was holding passes to the next contact that claims it.
Edit → Edit Last Contact, Ctrl+Y, or Enter on a row in the log opens the whole contact in one dialog. That is where the fields with no log column live: QSX frequency, name, QTH, comment, grid, power, radio number, run position, and the country and WPX prefixes. ◀ and ▶ walk the log without closing, offering to save first. Points and the multiplier flags are shown but cannot be typed in — they are worked out from the rules every time the log changes, so anything typed there would be overwritten on the next edit.
Correcting the country prefix by hand changes the score. The country file is a best guess for calls it has no rule for, so what the contact says now wins over what the file says.
Networked stations
Config → Network names this station and lists the others. Each contact is
sent to them as it is logged, in N1MM's contactinfo message, so an N1MM
station on the same network sees them too. Editing a contact sends
contactreplace and deleting one sends contactdelete, the same as N1MM. With
no addresses listed the messages are broadcast. A contact that arrives is scored
again here from the rules rather than trusted.
An incoming edit or delete is matched by contact id first. N1MM does not know our ids, so the call and the timestamp are the fallback — that is the pair N1MM itself keys a contact on.
Layout
| Project | What it holds |
|---|---|
Nonemm.Core |
Frequencies, bands, modes, callsigns, grid squares, the country file and the callsign database |
Nonemm.Contests |
Contest rules, the scoring engine, .udc files |
Nonemm.Formats |
Cabrillo out, ADIF in and out |
Nonemm.Storage |
The N1MM-compatible .s3db |
Nonemm.Rig |
Radio control over rigctld |
Nonemm.Spotting |
Spots, the bandmap, the DX cluster client |
Nonemm.Network |
Contacts shared between the stations of a multi-operator entry |
Nonemm.Keying |
CW through cwdaemon or a WinKeyer |
Nonemm.Session |
What the operator is typing and what the log says about it — no UI toolkit |
Nonemm.App |
The Avalonia windows |
The split at Nonemm.Session is the important one: it references no UI
framework, so what space does, when a dupe fires and what a contact scores are
covered by plain unit tests.
Where it stands
Working: logging a contest end to end, live dupe and multiplier checking, eight built-in contests plus user-defined ones, Cabrillo and ADIF export, ADIF import, the log, check, bandmap, score and packet windows, editing and deleting logged contacts, radio control, DX cluster spots, contacts shared between networked stations, and CW keying.
Checked against N1MM 1.0.11031: a log this program wrote opens in N1MM, which
reads the contest, its categories and the contacts. See
docs/n1mm-interop.md for what that took.
Not yet: voice keying, QTC handling for WAE, call history files, digital modes beyond logging them, and the check window's Call History and Exchange columns, which are left out rather than shown empty.
The radio, cluster, network and keyer clients are tested against fakes that speak the documented protocols. None has yet been run against a real radio, a live cluster node or a keyer.