Help & Operating Guide
CHANGELOG
- New accounts (other than the very first/admin account) now get a verify your email link when SMTP is configured β you'll need to click it before an administrator's approval lets you log in. Protects against an admin approving a typo'd email address that would never receive notifications.
- The Admin panel's pending-approval list now shows a Verified / Unverified badge next to each request.
- The account-approved email now includes a direct link back to the login page (requires
APP_BASE_URLto be set in.envβ see.env.example). - If SMTP isn't configured on your instance, nothing changes β accounts are auto-verified exactly like before.
- Upgrading an existing install: adds
email_verified,verification_token, andverification_sent_atcolumns tousersβ./deploy.shrunsmigrate.pyautomatically; run it by hand if upgrading another way. Existing accounts are backfilled as already-verified, so nobody gets locked out.
- Not everyone wants a Star Trek console for their net log β added a per-account theme picker in the header, next to Logout: LCARS (the original look), Dark, Light, High Contrast (for accessibility), or System (follows your OS light/dark setting automatically, including live updates if you change it while the app is open).
- Your choice is saved to your account, so it follows you to any browser or device you log in from β not just the one you picked it on.
- Along the way, fixed a few text/border colors that had been silently falling back to unstyled defaults ever since some earlier styling work.
- Upgrading an existing install: adds a
themecolumn tousersβ./deploy.shrunsmigrate.pyautomatically; run it by hand if upgrading another way.
- The manual check-in form now stays pinned at the top of the screen alongside the session info bar, so it stays reachable while scrolling down a long check-ins table on a busy net β no more scrolling back up to acknowledge each station.
- Added a preferred name that overrides the FCC/GMRS-looked-up name on the Expected Stations list, Checkin History, and net reports (ICS-205, CSV exports) β set it from the βοΈ icon next to a station's name in Expected Stations or Checkin History, or from the "+ Name/Remark" pill next to the Callsign field while checking someone in. Checkin History can be edited any time, including after a net has closed. The live check-in itself still records whatever name was entered at check-in time.
- Fixed: the traffic "called" checkbox in the Traffic banner is now saved to the check-in record as it's ticked, so it correctly stays checked after closing a net and reopening it to review β previously it was tracked only in the browser and reset on reload.
- Upgrading an existing install: adds columns to
checkinsandstation_remarksβ./deploy.shrunsmigrate.pyautomatically; run it by hand if upgrading another way.
- Adding a weekly schedule now auto-fills Timezone to your browser's detected zone, with autocomplete across the full IANA timezone list β no more typing an unfamiliar name from scratch or accidentally leaving it blank (which previously silently defaulted to UTC).
- Every displayed schedule time β Schedule tab, Upcoming list, and the public /directory page β now shows a (H:MM your time) conversion whenever your browser's timezone differs from the schedule's declared one.
- No database changes β this is a display-only change, safe to deploy without a migration.
- New public, unauthenticated page at /directory listing nets whose owners have opted in β name, net type, frequency, description, weekly schedule, and host callsign. Separate from the real-time /live check-in view.
- Enable List in Public Net Directory in a net's Edit form. Off by default β nothing is listed until an owner opts in.
- Sidebar link added: π Net Directory β.
- Fixed a date-matching bug (surfaced while building this): the Schedule tab's upcoming dates were computed from the server's local calendar date, while session/reminder matching used UTC β the two could disagree for a few hours a day in timezones behind UTC, causing Net Control/Broadcaster duty lookups to silently miss a real sign-up and fall back to whoever started the session. Both now consistently use UTC.
- Upgrading an existing install: adds a column to
netsβ./deploy.shrunsmigrate.pyautomatically; run it by hand if upgrading another way.
- Nets can now send Reminder Emails β enable it in the Edit form and set a lead time in minutes. Whoever is signed up as Net Control or Broadcaster on the Schedule tab is emailed shortly before their net starts, at the address they gave when signing up.
- Each role is reminded independently; no reminder is sent for a date nobody has signed up for.
- Requires a new standalone script,
send_reminders.py, run frequently via cron β see Help β Database Migrations (admins) or README.md for setup. Safe to run every few minutes; each signup is only ever reminded once. - Upgrading an existing install: adds columns to
netsandnet_control_signupsβ./deploy.shrunsmigrate.pyautomatically; run it by hand if upgrading another way.
- The Net Script field now supports basic formatting β **bold**, *italic*, headings, bullet lists, and horizontal rules. See Help β Net Control Script for the full syntax.
- {{variable}} placeholders β
{{net_control}},{{broadcaster}}, and related callsign/name variants β are filled in with the live session's Net Control and Broadcaster whenever the script is shown. - Added
{{net_control_next}}and{{broadcaster_next}}(plus callsign/name variants) β show who's signed up for next week on the Schedule tab, useful for closing announcements. These never fall back to anyone β they stay blank until someone actually signs up. - No database changes β this is a display-only change, safe to deploy without a migration.
- The sidebar now auto-collapses when a live session is started or opened, and restores automatically when you view an ended one.
- The Sessions/Schedule tabs and the Sessions toolbar (Start New Session, Export All CSV, History) are hidden while a session is live, and reappear once it ends β still available when reviewing a closed session.
- Session info and the Net Script panel are now pinned to the top of the live session card, so they stay visible while scrolling through check-ins or the Expected Stations panel.
- Additional Broadcast β a net can now carry a second segment alongside Net Control (e.g. Amateur Radio Newsline). Enable it and name it in the net's Edit form.
- The Schedule tab now shows Net Control and Broadcaster as independent sign-up slots per date β different operators can claim each, or one can click + Cover Both Roles.
- The net owner can π€ Assign either role to a registered operator, same as before.
- Whoever is signed up (callsign + name) now shows on the live check-in screen's duty bar and on the public /live page, for both Net Control and Broadcaster.
- Upgrading an existing install: adds columns to
netsandnet_control_signupsand changes a unique constraint β./deploy.shrunsmigrate.pyautomatically; run it by hand if upgrading another way.
- Nets can now have a Net Script attached β a plain-text field in the net's Edit form, below Description.
- When a net has a script, a collapsible π NET SCRIPT panel appears on the live check-in screen (open by default) so you don't need a second window or a printed sheet.
- The field preserves line breaks and spacing exactly as typed, but is not Markdown or HTML β see Help β Net Control Script for an example template.
- Upgrading an existing install: this adds a new column to the
netstable../deploy.shnow runsmigrate.pyautomatically on every deploy (see Help β Database Migrations) β if you're upgrading by hand instead, run it yourself or My Nets will appear empty until you do.
- GMRS net type β when creating or editing a net, choose Ham Radio or GMRS. GMRS nets display a GMRS badge in the net list.
- Shared family callsigns β GMRS licences cover an entire family. Multiple stations may check in using the same callsign; use the Name field to identify each operator.
- GMRS callsign lookup β callsigns in the GMRS format (e.g. WSMC512) are resolved against a local copy of the FCC ULS GMRS database rather than ham radio sources. The database is updated daily from the FCC.
- ARES mode and DMR integration are automatically hidden and disabled for GMRS nets (neither applies to GMRS operations).
- Phone-optimised layout at β€480 px (tested on iPhone 12 Pro): check-in form hides Signal and Comments fields, showing only Callsign, Name, Has Traffic, and a full-width Check In button.
- Check-in table on mobile shows only Callsign, Name, Traffic flag, and the remove button β #, Signal, Comments, and Time columns are hidden.
- Sessions list on mobile hides the Ended and Check-ins columns so the Delete button stays reachable without horizontal scrolling.
- Session Complete summary card scrolls within the viewport rather than being clipped on small screens.
- Header branding truncates gracefully with ellipsis when the org name is long.
- Session action buttons (End Session, ICS-205, CSV) go full-width on mobile for easier tapping.
- Registration tab now shows an info banner explaining that new accounts require admin approval before login.
- After submitting a registration, the form is replaced with a confirmation screen showing the submitted callsign and email address β no more silent redirect to the login tab.
- Any action that triggers an email (operator approval, rejection, Net Control assignment) now shows a ⳠSending⦠state on the button so it is clear the system is working.
- Email send errors are now surfaced inline rather than failing silently.
- Admin, API Tokens, Help, and Report / Request are now standalone pages rather than in-app panels β faster to load and bookmarkable.
- Admin panel reorganised into three tabs: Operators (default), Branding, and Email.
- Sessions list is hidden automatically while a live session is active, reducing visual clutter; it reappears when the session ends.
- End Session button promoted to full size (no longer a small button) to reduce accidental misses.
deploy.shscript added β run./deploy.shon the server for a one-command git-pull deployment.
- DMR Last Heard panel β connect your net to a WPSD, Pi-Star, or BrandMeister talk group; see recently heard stations live during the net.
- Heard stations are filterable (NCS callsign auto-excluded) and update every 30 seconds while a session is active.
- Quick Check-In β click any heard callsign to pre-fill the check-in form with their name and region.
- Supports both direct mode (browser fetches your local-network hotspot) and proxy mode (server fetches a publicly accessible URL or BrandMeister).
- Two new check-in fields: Talk Group and Region/State β shown automatically when a net has DMR configured.
- Configure DMR integration in the net Edit form (net owners only); migration SQL in Help β Database Migrations.
- Fixed ICS-205 export returning "Not authenticated" β now fetches with proper auth credentials.
- ICS-205 / Net Log button now available in the live session toolbar (alongside End Session and CSV export) β no need to wait until the net ends.
- Configurable organization branding: set your org name, tagline, website URL, and upload a custom logo from the Admin panel.
- Public live page (/live) β unauthenticated real-time view of active nets and check-in rosters, auto-refreshes every 30 seconds.
- Net Control confirmations now include a .ics calendar attachment β sign up or get assigned and a calendar event lands in your inbox automatically.
- Net owners can now share nets with all users or individual operators via the Edit form.
- Admins can see and open all nets on the system.
- Shared nets appear with a Shared badge and show the owner's callsign.
- New π Report / Request sidebar item β submit bug reports, enhancement requests, and questions directly to the administrator.
- Traffic Message Log panel (ARES nets) β track message numbers, origin, destination, type, and delivery status.
- Station Remarks β persistent per-net notes on any callsign, accessible during lookup.
- Session Summary card shown automatically when a session ends.
- ICS-205 / Net Log printable export added to ended sessions.
- Session clock showing local time, UTC, and elapsed time.
- / keyboard shortcut to jump to callsign input.
- Traffic banner chips now have "called" checkboxes to track handled traffic.
- Admin and database help sections now hidden from non-admin users.
- SMTP configuration hint hidden once email is configured.
- ARES/ACES net mode with per-station evacuation zone tracking and Zone Roster panel.
- Expected Stations list with Check-In and Traffic pre-flag checkboxes.
- Callsign suffix search against local check-in history (replaces decommissioned FCC search).
- Net Control signup scheduling with weekly recurring time slots.
- Net and session management, check-in logging, signal reports, traffic flagging.
- FCC callsign lookup, session history, CSV export.
- User registration with admin approval, email notifications.
QUICK START
1. Create a Net under My Nets β give it a name and frequency.
2. Open the net and click βΆ Start New Session to begin.
3. Use the Check-In form or Expected Stations list to log stations as they call in.
4. Click β End Session when the net closes β a session summary card will appear automatically.
Keyboard shortcut: Press / anywhere on the session page to instantly focus the callsign input.
SESSION CLOCK & TIMER
While a session is live, a clock bar appears showing local time, UTC time, and the elapsed session time. The timer starts from when the session was opened and updates every second.
The clock disappears automatically when the session ends.
CALLSIGN LOOKUP & SEARCH
Full callsign (e.g. W7KOL) β type it in and the system looks up the licensee name, class, state, and grid from the FCC database, auto-filling the Name field.
Suffix search (e.g. KOL) β type letters without a district number and the system searches your net's check-in history for matching callsigns. A dropdown appears sorted by suffix. Click any result to select it and trigger a full FCC lookup.
Suffix search only finds callsigns already in your net's history. For a brand-new station, type their full callsign.
STATION REMARKS
After looking up a callsign, a small π Remark pill appears in the lookup info bar. Click it to add or edit a persistent note about that station (e.g. "portable op", "relay to W7NET", "hearing impaired β use Winlink").
Remarks are saved per net and appear every time that station is looked up during any future session on that net.
MANUAL CHECK-IN FORM
Fill in callsign, name (auto-filled from FCC), signal report, and optional comments. Check Has Traffic before clicking Check In or pressing Enter.
Duplicate callsigns in the same session are automatically rejected.
NET CONTROL SCRIPT
Net owners can attach a script to a net from its Edit form β the Net Script field below Description. When set, a collapsible π NET SCRIPT panel is pinned to the top of the live check-in screen, open by default, so you can read from it without a second window or a printed sheet β even while scrolling through check-ins.
MARKUP
A small, deliberately limited set of formatting is supported:
**bold**,
*italic*,
# / ## / ### heading,
- item bullet lists, and
--- / === as a horizontal rule (alone on its own line). Everything else β blank lines, indentation, plain text β renders exactly as typed; this is not full Markdown or HTML, so unrecognized syntax (including literal </>) always shows as plain text rather than being interpreted.
VARIABLES
{{variable}} placeholders are filled in with live session info wherever the script is shown:
{{net_name}} | The net's name |
{{net_control}} | Net Control name β callsign |
{{net_control_callsign}} / {{net_control_name}} | Just the callsign / just the name |
{{broadcaster}} | Broadcaster name β callsign (Additional Broadcast nets only) |
{{broadcaster_callsign}} / {{broadcaster_name}} | Just the callsign / just the name |
{{broadcast_label}} | The net's custom broadcast name (e.g. "Amateur Radio Newsline") |
{{net_control_next}} | Next week's Net Control name β callsign |
{{net_control_next_callsign}} / {{net_control_next_name}} | Just the callsign / just the name |
{{broadcaster_next}} | Next week's Broadcaster name β callsign |
{{broadcaster_next_callsign}} / {{broadcaster_next_name}} | Just the callsign / just the name |
Net Control falls back to whoever started the session if no one signed up on the Schedule tab for that date; Broadcaster only fills in from a Schedule sign-up. The _next variables look one week ahead and are never filled by fallback β they stay blank until someone actually signs up on the Schedule tab for that date. An unrecognized {{...}} is left as-is rather than silently dropped, so a typo is easy to spot. For example:
# Monday Night Net Script
Good evening, this is **{{net_control}}**, your net control operator
for the {{net_name}}.
Coming up: tonight's {{broadcast_label}} segment, read by {{broadcaster}}.
- If you would like to check in, please call now with your callsign.
- Traffic? Let us know when you check in.
---
Next week's net control will be {{net_control_next}}.
Thank you all for checking in. This net is now closed.
Leave the field blank to hide the panel entirely. Click the panel header any time to collapse or reopen it during a session.
GMRS NETS
When creating a net, select GMRS as the net type. GMRS nets behave like ham nets with a few differences:
Shared callsigns β a GMRS licence covers an entire family. The same callsign can check in multiple times in a single session. Use the Name field to identify each individual operator (e.g. "Dad", "Mom", "Mobile 1").
Callsign lookup β GMRS callsigns (format: 3β4 letters followed by 3β4 digits, e.g. WSMC512) are looked up in a local copy of the FCC ULS GMRS database. The database is refreshed daily; new licences may take up to 24 hours to appear.
ARES mode and DMR integration are not available for GMRS nets and are hidden automatically.
EXPECTED STATIONS
Click Expected Stations to expand the panel. Set the minimum check-in count and lookback window (weeks), then click Load List.
Each row shows two checkboxes: Check In to log them immediately, and Traffic to pre-flag traffic before they're formally logged. On ARES nets, a π zone badge shows their last known evacuation zone.
Already-checked-in stations are greyed out and the list refreshes automatically.
TRAFFIC MANAGEMENT
When any station has traffic, a red π’ TRAFFIC banner appears listing them as interactive chips. Once you've called a station to pass their traffic, tick the checkbox on their chip β it strikes through and dims to show it's been handled. Unchecked chips remain prominent so nothing gets missed.
Pre-flagged stations from Expected Stations appear with a β³ badge until formally checked in. Their checkbox is disabled until they call in.
In the check-ins table, click the π’ / β button in the Traffic column to toggle the flag on any station.
TRAFFIC MESSAGE LOG
Click π TRAFFIC MESSAGE LOG to expand the panel. Use it to record individual traffic messages handled during the session β message number, origin, destination, type (Formal / Informal / Health & Welfare), and notes.
The Status dropdown on each row lets you track progress: Received β Relayed β Delivered (or Undeliverable). Changes save immediately.
The message log is included in the ICS-205 export.
SESSION SUMMARY & ICS-205
When you end a session, a Session Summary card pops up showing total check-ins, session duration, traffic count, and new stations (first-time visitors to this net).
Click π ICS-205 / Net Log to open a printable net log in a new tab. It includes the ICS-205 header (net name, frequency, NCS callsign, operational period) plus the full check-in roster and traffic message log. Use your browser's Print function to save as PDF.
You can also export the raw check-in data as a CSV for logging or upload to other systems.
ARES/ACES MODE
Enable ARES/ACS Net in the net settings to activate evacuation zone tracking. An Evac Zone field appears in the check-in form β enter the station's zone (e.g. "Zone A") when they check in.
The zone is saved automatically to a per-net zone table. In future sessions, the station's last known zone appears as a π badge in the Expected Stations list and is pre-filled when checking them in.
The Zone Roster panel shows all known zones grouped by zone name with their callsigns, sorted by callsign suffix. The Zone column also appears in the check-in table and the ICS-205 export.
SESSION HISTORY
The History view shows every callsign that has checked into the selected net, with check-in counts for the past 2 weeks, 4 weeks, and all time.
Use the filter dropdown to find: Last Net, Missed Last Net, Active (2 wks), Regular (4 wks, β₯2), Frequent (4 wks, β₯3), or Inactive (4 wks).
Combine the dropdown with the text search box for further filtering. Use β¬ Download CSV to export the current view.
NET SHARING
Net owners can share a net with other registered operators. Open the net's Edit form and expand the π Sharing section at the bottom.
Choose Share with all registered users to give every active account access, or select individual users from the list. Click Save Sharing to apply β this is separate from the main Save button.
Shared nets appear in other operators' net lists with a Shared badge and show the owner's callsign. Shared users can start sessions and add check-ins, but cannot edit the net configuration or manage sharing.
Admins can see and open all nets on the system regardless of sharing settings.
SCHEDULING
In the Schedule tab of a net, add weekly repeating time slots (day, time, timezone). These appear as a calendar of upcoming dates.
The Timezone field auto-fills to your browser's detected timezone when you open the form, and autocompletes from the full IANA timezone list β you're rarely typing it from scratch. It only affects entry, though: change it if the net actually runs somewhere else.
Every schedule time shown anywhere β the Schedule tab, the Upcoming list, and the public /directory page β includes a (H:MM your time) conversion whenever your browser's timezone differs from the one the schedule was declared in, so you don't have to do the math yourself.
Operators can click Sign Up next to any future date to claim the Net Control slot. The net owner can instead click π€ Assign to put a registered operator on the schedule.
If the net has Additional Broadcast enabled in its Edit form (e.g. for a segment like Amateur Radio Newsline), each date also shows a separate Broadcaster sign-up slot β a different operator can claim it, or one operator can click + Cover Both Roles to take both for that date. Whoever is signed up is shown, callsign and name, on the live check-in screen and the public /live page.
SCHEDULED NET REMINDERS
Enable Reminder Emails in a net's Edit form and set a lead time (in minutes) to have whoever's signed up as Net Control or Broadcaster on the Schedule tab emailed shortly before their net starts. Each role is reminded independently, at the email address they gave when signing up.
If nobody has signed up for a date, no reminder goes out β there's no one to email. This depends on the server having SMTP configured and a reminders cron job running; ask your administrator if you enable this and don't receive anything.
PUBLIC NET DIRECTORY
Enable List in Public Net Directory in a net's Edit form to show it at /directory β a public page, no login required, separate from the real-time /live check-in view. Listed nets show their name, net type, frequency, description, weekly schedule, and your callsign as the host.
Nets are unlisted by default β opt in per net. There's currently no integration with external ham radio net directories (no such site offers a public API to publish to); this is a self-contained directory within your instance only.
ADMIN PANEL
The first user to register automatically becomes admin. Additional registrations require approval before login is permitted.
Admins can approve/deactivate accounts, grant admin privileges, delete accounts, and opt in to email notifications for new registrations using the β/π§ toggle in the Notify column.
Newly approved operators receive an automatic confirmation email if SMTP is configured in .env.
DATABASE MIGRATIONS
Schema migrations are managed by migrate.py in the app directory.
It is safe to re-run at any time β every step uses IF NOT EXISTS.
./deploy.sh now runs it automatically as part of every deploy, before the service restarts β no manual step needed if you use it.
To run it by hand:
sudo -u netcontrol python3 /opt/netcontrol/migrate.py
Fresh installs: new tables are created automatically on first startup β no migration needed.
Run migrate.py only when upgrading an existing instance after a code update.
GMRS licence database
Seed the local GMRS callsign database on first install, then let the daily cron keep it current:
# Initial seed (full ~54 MB download) python3 /opt/netcontrol/gmrs_sync.py --mode full # Routine update (runs automatically via cron β daily transaction file) python3 /opt/netcontrol/gmrs_sync.py --mode update
Scheduled net reminders
Net owners enable reminders per-net in the Edit form, but sending them requires send_reminders.py running frequently via cron (it's idempotent, safe to run every few minutes):
*/5 * * * * /opt/netcontrol/venv/bin/python3 /opt/netcontrol/send_reminders.py >> /var/log/nettracker/reminders.log 2>&1