A real-time APRS (Automatic Packet Reporting System) monitoring and control application that interfaces with Direwolf via KISS TCP. Aggregates packets from local RF and APRS-IS, provides interactive mapping, messaging, alerting, and beacon management for ham radio operators.
- Real-time packet capture — Connects to Direwolf via KISS TCP, parses AX.25 frames, and classifies stations by type (Mobile, Fixed, Weather, Digipeater, IGate)
- APRS-IS integration — Dual-source packet aggregation from RF and internet with configurable filters and deduplication
- Interactive map — Leaflet-based map with station plotting, APRS symbols, track history, range rings, heatmap overlay, and Maidenhead grid coverage analysis
- Messaging — Send and receive APRS messages with automatic retry and acknowledgment tracking
- Beacon management — Multi-radio beacon configuration with digipeater confirmation tracking and heard/not-heard status
- Alerting — Watch list alerts, proximity rules, and geofences with real-time notifications
- Weather overlays — NEXRAD radar (IEM), RainViewer Pro, lightning (Tomorrow.io), and wind tiles (OpenWeatherMap)
- Callsign lookup — HamDB and QRZ integration with result caching
- Statistics — Coverage grid analysis, digipeater statistics, packet rates, and per-station metrics
- Real-time updates — SignalR pushes all events (packets, messages, alerts, beacon confirmations) to the browser instantly
| Layer | Technology |
|---|---|
| Backend | ASP.NET Core (.NET 10), Entity Framework Core, SQLite |
| Frontend | Vue 3, Vuetify 4, Vite, TypeScript, Pinia |
| Mapping | Leaflet |
| Realtime | SignalR |
| APRS | AprsSharp (KISS TNC + APRS-IS + parser) |
The easiest way to run DireControl is with Docker Compose. Copy docker-compose.yml and .env.example from the repo, then:
cp .env.example .env
# Edit .env — at minimum set DireControl__OurCallsign to your callsign
docker compose up -dThe app will be available at http://localhost. The SQLite database is persisted in a data/ directory alongside the compose file.
services:
direcontrol:
image: roushtech/direcontrol:${VERSION:-stable}
env_file: .env
ports:
- "${HTTP_PORT:-80}:5010"
volumes:
- ./data:/data
restart: unless-stopped
# Allows the container to reach Direwolf running on the host via host.docker.internal
extra_hosts:
- "host.docker.internal:host-gateway"DireControl is configured through environment variables and the in-app Settings page.
Environment variables (set in .env or passed to the container):
| Variable | Default | Description |
|---|---|---|
HTTP_PORT |
80 |
Host port to expose the web UI on |
DireControl__OurCallsign |
N0CALL-10 |
Your callsign with SSID |
DireControl__HomeLat / DireControl__HomeLon |
(unset) | Home position for beacons and distance calculations |
Direwolf__Host |
localhost |
Direwolf KISS TCP host (host.docker.internal for Docker) |
Direwolf__Port |
8001 |
Direwolf KISS TCP port |
QRZ__Username / QRZ__Password |
(empty) | QRZ callsign lookup credentials (optional — HamDB is used as a free fallback) |
DireControl__StationExpiryTimeoutMinutes |
120 |
Default minutes before inactive stations expire |
See .env.example for the full list including per-type station expiry overrides.
In-app settings (configured through the Settings page in the UI):
- APRS-IS connection (host, port, filter, passcode)
- Weather API keys (OpenWeatherMap, Tomorrow.io, RainViewer)
- Radar provider selection
The stable tag always points to the latest release. Pinned version tags (e.g. 0.2.0.173) are also available — see Docker Hub for all tags.
- .NET 10 SDK
- Node.js 20.19+ or 22.12+
- Direwolf running with KISS TCP enabled
dotnet run --project DireControl.Api
# Listening on http://localhost:5010cd DireControl.Vue
npm install
npm run devThe Vite dev server proxies API and SignalR requests to the backend automatically.
Copy and edit the local settings override (git-ignored):
cp DireControl.Api/appsettings.json DireControl.Api/appsettings.local.jsonThe same settings from the environment variable table above can be set here using the nested JSON format (e.g. Direwolf__Host becomes "Direwolf": { "Host": "..." }).
dotnet test DireControl.Tests/DireControl.Tests.csprojMIT — Copyright (c) 2026 William Roush / RoushTech
