Why a newcomer started writing code before his first field day
I joined the WLD club recently. September will be my first field day with them, and like most new members I spent the first few meetings mostly listening. But one thing came up again and again in those conversations, always with the same half-amused sigh: the list.
Every field day, someone sits at a table with a printed or half-digital Excel sheet. Down the left: the participating stations. Across the top: 160 m, 80 m, 40 m. Every time an operator works one of the other participating clubs, someone has to be told, and someone has to put a mark in the right box. It works, it has worked for years, but it is slow, it is error prone, and at three in the morning when you actually need it most, it is exactly the thing nobody wants to maintain.
Meanwhile, right next to that sheet, a computer is already logging every single QSO perfectly.
That gap bothered me. So instead of showing up in September with nothing but enthusiasm and a thermos flask, I decided to contribute something a newcomer can actually contribute: software. This post describes what came out of it, version 1 of the N1MM Field Day Tracker.
The core idea
The tracker is not a logger. That distinction matters, and it was the first design decision.
N1MM Logger+ remains the official log. It is mature, it is trusted, it handles the contest rules, and nobody in their right mind should try to replace it during a live event. The tracker sits beside it and answers one very specific question that N1MM does not answer.
That is it. One question, answered live, on a big readable screen, without anybody having to update a spreadsheet by hand.
Here is roughly what that looks like on the display in the corner of the tent:
Automatic coupling with N1MM Logger+
This is the part that makes the whole thing worthwhile.
N1MM Logger+ can broadcast every logged contact over the network as a UDP message. You enable it under:
From that moment every QSO you log lands in the tracker within milliseconds. The matrix cell turns green. Nobody had to say anything, write anything, or remember anything.
Four things that bit me along the way
Real field days are messier than the documentation suggests, and the interesting engineering was almost entirely in the edge cases.
LookupInfo packets have a field structure identical to real contacts, arrive on the same recommended port, and are broadcast the moment an operator merely looks up a callsign, before anything is logged. A naive parser happily counts QSOs that never happened. The tracker filters strictly on the XML root tag and counts everything else as an ignored packet type in the sync log.<band> text field is locale dependent: it may say 3.5 or 3,5 depending on the Windows regional settings of the logging PC. So the tracker never reads it. Band is always derived from rxfreq (which, delightfully, is expressed in units of 10 Hz) against an IARU Region 1 band plan./P, while N1MM may log them with or without. Normalisation is applied on both sides, so ON4BAF, ON4BAF/P, on4baf/p and F/ON4BAF/P all resolve to the same station. Strict matching is available for those who want it, but it is off by default.N1MM also broadcasts contactreplace and contactdelete, and the tracker follows both. Fix a busted callsign in the log and it un-marks the old cell and marks the new one. Delete a QSO and the cell opens back up.
ADIF import: the safety net
Realtime is wonderful right up until it isn’t. A laptop is off. The tracker was started an hour late. A station joins in the evening. Someone’s network cable was, in the finest field day tradition, doubling as a tent guy-line.
So the tracker imports ADIF files as a catch-up mechanism. Feed it a log at any point and it will merge everything in, deduplicate against what it already has, and produce an honest import report: records read, new, duplicate, outside the field day window, unknown station, unparseable. No silent magic. You always see exactly what happened.
Manual overrides: because paper still exists
Software that assumes the digital record is complete is software written by someone who has never been on a field. A QSO gets written on a scrap of paper. A station is worked on a rig that isn’t hooked to a computer at all. Something is logged that shouldn’t count.
Any cell in the matrix can therefore be set by hand:
| Status | Meaning |
|---|---|
| Not worked | Still open |
| Worked (N1MM) | Automatic, from the live feed |
| Manually worked | Set by an operator, with a reason |
| Manually not worked | Correcting a false positive |
| Excluded | This combination doesn’t apply |
Manual always wins over automatic. That is a hard rule in the codebase, tested on every build. And manual cells are never distinguished by colour alone, there is a marker too, because colour blindness exists and so does bright sunlight on a tablet screen in an open field.
Everyone follows along, live
Here is the part that got the club genuinely excited.
The view is built exactly once, as static HTML that reads a snapshot.json file. Locally, the app serves that view on 127.0.0.1. And with one button, or automatically every few minutes, the identical snapshot is pushed to GitHub Pages.
Same code, same colours, same filters. The published page refreshes itself every 30 seconds. So members at home, family, other clubs, anyone with the link can watch the grid fill up in real time. No login, no app, just a URL.
Because that page is genuinely public, the tracker warns you about it in the interface and lets you strip remarks and operator notes out of the published snapshot before it goes live.
Beyond the main matrix there are views for still to work (the one you actually want at 03:00), per band, per station, and per source PC, which doubles as your feed diagnostics, plus a statistics view. Everything is filterable by callsign, status, band, category and section, with CSV and PDF export for the archive.
Windows and Linux, yes really
N1MM Logger+ is Windows software. The tracker is not.
Because the coupling happens over UDP across the network, the logging PCs can sit in the operating tent running Windows while the tracker runs on whatever machine you happen to have, including a Linux laptop, or a small box in the corner serving the display. All data lives in plain JSON files with atomic writes and corruption recovery. No database to install, no server, no cloud service, no account. It runs entirely offline. Only the optional GitHub publishing needs internet.
The interface starts in English and switches to Dutch, French or Spanish.
Windows users get an installer, Linux users get an x86_64 tarball. Source, documentation and issue tracker all live in the repository. Contributions, bug reports and band plan corrections for other IARU regions are very welcome.
What version 1 is, and what it isn’t
V1 deliberately does not do cloud sync, multi-user editing of the tracker itself, authentication, online score reporting, or automatic creation of unknown stations. The participant list decides who counts. A callsign that isn’t on it is ignored, never silently added.
That restraint is the point. A field day tool has exactly one chance to work, in a tent, possibly in the rain, with tired operators and a generator. Fewer moving parts means fewer things that can fail at 02:00.
See you in September
I still have a great deal to learn from the people in this club, about antennas, about propagation, about how a field day actually runs when the mast goes up. But a spreadsheet that nobody enjoys maintaining seemed like a solvable problem, and solving it was something I could do before my first event rather than after it.
If it works as intended, the most visible result will be that nobody thinks about the list at all. That would be the best possible outcome.
73 and see you on the bands.