Skip to content

Developer Guide

Brian Keating edited this page May 2, 2026 · 3 revisions

Developer Guide

This page covers building and running OpenHPSDR Zeus from source, the dev loop with hot-reload, the project layout, and the conventions to know before contributing.

End users don't need any of this — head to Installation for the binary installers and PWA path.

Prerequisites

  • .NET 10 SDK
  • Node.js 20+ (npm ships with it)
  • git
  • A Hermes Lite 2 (or any supported HPSDR board) on the same LAN — optional. The synthetic DSP engine drives most of the UI without a radio.

WDSP native libraries for macOS (arm64, x64), Linux (x64, arm64), and Windows (x64, arm64) are pulled in as runtime assets. See native/README.md for build details if you need to rebuild them yourself.

First-time setup

git clone https://github.com/brianbruff/openhpsdr-zeus.git
cd openhpsdr-zeus

# Restore .NET dependencies and sanity-check the build
dotnet restore
dotnet build Zeus.slnx

# Install frontend dependencies
npm --prefix zeus-web install

Dev loop (two terminals)

The backend and frontend run as two independent processes during development. The Vite dev server proxies /api and the WebSocket hub through to the .NET host, so you get hot-reload on the React side without rebuilding the server.

# Terminal 1 — backend on :6060
dotnet run --project Zeus.Server

# Terminal 2 — Vite dev server on :5173 (proxies /api and /hub to :6060)
npm --prefix zeus-web run dev

Then open http://localhost:5173. Edits under zeus-web/src/ hot-reload; changes under Zeus.Server/, Zeus.Protocol1/, Zeus.Protocol2/, Zeus.Dsp/, or Zeus.Contracts/ require restarting the backend.

On the very first backend start, wait for wdsp.wisdom ready before clicking Discover — see Installation → First run.

Production-style single-port build

To run the same shape the installer ships, build the frontend into Zeus.Server/wwwroot/ and let ASP.NET Core serve everything — UI, API, WebSocket — on port 6060:

# Build the web UI (one-time, or whenever zeus-web changes)
cd zeus-web && npm install && npm run build && cd ..

# Run the server on :6060
dotnet run --project Zeus.Server

Open http://localhost:6060, hit Discover, and connect to your radio.

Ports and HTTPS modes

OpenHPSDR Zeus listens on a different set of ports depending on how you started it. If you are looking for a port and don't see it, the most common explanation is that you are in a mode that doesn't open it.

Port Protocol Opened when…
5173 HTTP Vite dev server is running (npm run dev)
6060 HTTP Standalone Zeus.Server is running
6443 HTTPS Standalone Zeus.Server is running (with the self-signed LAN cert)
40001* TCI/WS TCI is enabled in config — independent of host mode

* TCI port and bind address are configurable in appsettings.json and via the in-app TCI settings panel.

The two runtime shapes:

Standalone Zeus.Server (service / dev-loop mode)

dotnet run --project Zeus.Server opens :6060 HTTP and :6443 HTTPS, both bound to all interfaces. The HTTPS port exists so phones and other LAN browsers can reach the server by IP and still get getUserMedia (browsers require a secure context for mic access on non-localhost origins). The self-signed LAN cert is generated on first run and cached on disk.

Override the HTTPS port with ZEUS_HTTPS_PORT=<n> if :6443 collides with something else.

Native installer / desktop app (Photino shell)

The desktop installers and the dev launcher (dotnet run --project Zeus.Desktop) run loopback-only on an OS-assigned ephemeral port — no LAN binding, no HTTPS, no :6443. The Photino window loads the UI from that loopback origin, which is already a secure context, so the LAN cert and HTTPS listener are unnecessary.

If you lsof -i :6443 while the desktop app is running and see nothing, that is expected behaviour, not a bug.

Picking a mode

  • Building the UI / debugging the backend → dev loop (standalone Zeus.Server + Vite).
  • Running on a headless box / Pi for LAN clients (phones, other desktops) → standalone Zeus.Server. You need :6443 for mobile mic access — see Mobile.
  • Single-machine "open and operate" → the desktop installer or the PWA.

Tests

dotnet test Zeus.slnx

Please ensure tests pass before opening a PR.

Project layout

Path What it is
Zeus.Server/ ASP.NET Core host, SignalR hub, radio service
Zeus.Protocol1/ OpenHPSDR Protocol-1 client, framing, discovery
Zeus.Protocol2/ OpenHPSDR Protocol-2 client (ANAN G2)
Zeus.Dsp/ DSP engine — WDSP via P/Invoke + synthetic fallback
Zeus.Contracts/ Wire-format DTOs shared backend ↔ web
zeus-web/ Vite + React + TypeScript + WebGL frontend
native/wdsp/ WDSP build scaffolding for the native DSP library
tests/Zeus.*.Tests/ xUnit tests
tools/zeus-dump/ Protocol-1 packet dump utility
tools/discovery-probe/ LAN discovery probe

Useful tools

  • tools/zeus-dump/ — Protocol-1 packet dumper, handy for protocol debugging
  • tools/discovery-probe/ — LAN discovery probe for Protocol-1 radios

Project conventions

  • Backend port :6060, Vite dev port :5173 — don't change these casually
  • Panadapter amber is #FFA028 (single-hue, alpha-varied, no rainbow gradients)
  • Reference implementation is Thetis
  • Deeper context for agents and contributors lives in CLAUDE.md, docs/lessons/, and docs/rca/ — worth a skim before touching DSP, protocol, or layout code

Distribution roadmap

Shipping surfaces are being added one at a time:

  • PWA (installable web app) — available now. Precached shell, works offline for the static assets, installs from any browser that supports PWAs.
  • Native installers (Windows .exe, macOS .dmg, Linux .tar.gz) — available now. Self-contained .NET 10 publish, WDSP native library, and a per-platform launcher. See Installation.
  • Photino native-window shell — Phase 2, ETA TBD. Replaces the launcher-plus-browser pattern with a single double-click app (WebView2 / WKWebView / WebKitGTK from .NET, no console window). Deferred until radio / protocol functionality lands.
  • Mobile apps (iOS / Android) via Capacitor — planned. Cadence: TBD.

Clone this wiki locally