Put any radio into AetherSDR.
Aether-gate is a universal bridge that presents any radio — an Icom or Kenwood transceiver, an RTL-SDR/Airspy dongle, anything you can read — to AetherSDR as if it were a FlexRadio. AE speaks exactly one protocol (FlexRadio's); the gate does the translation, so AE keeps a single, clean ingest boundary and the zoo of radio sources lives outside it.
You pick your radio on a web page, hit Start, and it appears in AetherSDR's radio chooser with a live panadapter and waterfall.
An Icom IC-9700 bridged into AetherSDR — offered exactly the bands it can tune.
Status: working, but very young. Proven end-to-end on real hardware — an Icom IC-9700 (LAN, 2m/70cm/23cm) and a Kenwood TS-450S (CAT + SDR dongle for spectrum) both run live in AetherSDR with waterfall and control, and a Raspberry Pi runs both at once as a boot-time appliance. That said, this is early software: expect a few growing pains — rough edges, radios not yet covered, and things that need broader testing than one bench can give. Bug reports, fixes, and new radio adapters are all very welcome. Licensed GPL-3.0-or-later.
- Presents a radio to AetherSDR as a Flex 6000. AE discovers it on the LAN and connects exactly as it would to a real FlexRadio — panadapter, waterfall, slices, frequency/mode control.
- Two ways to get spectrum, chosen per radio:
- radios with their own spectrum scope (e.g. Icom LAN rigs) stream it directly;
- radios without one (most CAT transceivers) get their waterfall from a cheap SDR dongle tapped off-air, steered to follow the rig's dial.
- Declares its real bands. A gateway rig that must impersonate a FLEX-6700 would
otherwise be offered a full HF band menu it can't tune. Aether-gate tells AE the
radio's true band set (via the
bands=discovery key), so an IC-9700 shows only 2m/440/23cm. (Needs an AetherSDR build with radio-declared-band support.) - Runs headless as a service — on a Raspberry Pi it's a flash-and-go appliance; each radio is its own systemd service, always ready in AE's chooser.
⚠️ Receive & control only — no transmit yet. Aether-gate does frequency/mode control and spectrum/waterfall/audio receive. It does not key the radio. If you press TX/MOX/TUNE in AetherSDR, AE's UI will light up as if transmitting, but no RF is produced — the gate acknowledges the transmit command and reports "transmitting" back to AE, but never asserts PTT on the rig. This applies to every radio family below (Icom LAN, hamlib/CAT, dongles). PTT wiring + arm/tx-band safety is the next planned feature; until then treat the gate as a receiver + controller. See How it works for the detail.
All entries below are receive + control. The Status column is about how well the RX/control path works; none of these transmit yet (see the note above).
| Family | How | Spectrum | Status |
|---|---|---|---|
| Icom LAN (IC-9700, RS-BA1-style) | native LAN / CI-V | radio's own scope | ✅ proven (IC-9700) |
| Icom IC-7300 USB | USB CI-V + USB Audio CODEC | radio's own scope | ✅ proven RX/control only |
| Kenwood / Yaesu / Elecraft / Icom-USB (CAT) | hamlib (rigctld) |
SDR dongle, CAT-steered | ✅ proven (Kenwood TS-450S); other hamlib rigs = same path |
| SoapySDR dongles (RTL-SDR, Airspy, SDRplay) | SoapySDR | the dongle itself | ✅ |
| sim | built-in test patterns | synthetic | ✅ (no hardware — for trying it out) |
See RADIO_SUPPORT.md for the two-axis (control + spectrum) model and how to add a radio.
Bridged radios appear in AetherSDR's chooser by name, alongside real FlexRadios.
Download Aether-gate-Setup-<version>.exe from the
latest release, run it, and click
Next → Next → Finish. Then open Aether-gate Setup from the Start menu: the Setup page opens in
your browser. Pick your radio and hit Start.
It installs for you only and asks for no administrator password. (The wizard's first page also offers "all users", which does need one.)
If Windows or your antivirus objects. The installer is not code-signed yet, so it looks "unknown" — a new program from a small project, rather than anything wrong with it:
- "Windows protected your PC" → More info → Run anyway.
- Norton, McAfee and friends may block or quarantine it outright on reputation alone. Either
restore it from quarantine, or use the portable zip on the same release page:
Aether-gate-<version>-windows-portable.zip— unzip it anywhere and runAetherGate.exe. No installer, no admin, and nothing written outside that folder and%USERPROFILE%\.aether-gate. - Every download has a
.sha256beside it if you want to check it arrived intact:certutil -hashfile Aether-gate-Setup-0.5.1.exe SHA256(PowerShell:Get-FileHash).
Then:
- Windows will ask about the firewall the first time the gate runs. Say Allow, or AetherSDR will not see the radio. (The all-users install can add that rule for you instead.)
- AetherSDR on the same PC? Usually nothing to do — the gate binds its own address, so it and AE coexist on 4992 (verified on Windows 11 with AE on the same laptop, 2026-09-22). Only if the gate reports the port in use, or AE never lists it, set Network / advanced → Port to 5992.
- The Windows build covers Icom LAN radios (IC-9700, IC-705…), RTL-SDR dongles and the test sim. Kenwood/Yaesu CAT is still to come.
Windows hands a fresh dongle to its TV-tuner driver, and no SDR program can open it until that is changed. This is not an Aether-gate setting — every Windows SDR needs it, once per dongle.
- Download Zadig and run it (no install needed).
- Options → List All Devices.
- In the drop-down pick "Bulk-In, Interface (Interface 0)" — usually shown as RTL2838UHIDIR.
- Set the driver box on the right to WinUSB, then press Replace Driver.
- Unplug the dongle and plug it back in.
⚠️ Pick the right line in that drop-down. Zadig replaces the driver of whatever is selected, so choosing your mouse or keyboard there will stop it working until you put the driver back.Symptom if you skip it: the Setup page starts, the dongle is listed by Windows, and Aether-gate says no devices found.
Flash the ready-made Pi image from the release: see PI_APPLIANCE.md. On any
Linux machine or NAS with Docker, a prebuilt container is published for every release:
ghcr.io/nigelfenton/aether-gate:full (every adapter) or :lan (Icom LAN only). See
docs/DOCKER.md.
No packaged Mac build yet — you run it from the source. Two commands of setup, then one to start it. Verified on a Mac mini (Apple Silicon, macOS 26.6.2) with Homebrew installed.
brew install python numpy # see both notes below — this is not optional
git clone https://github.com/nigelfenton/Aether-gate.git
cd Aether-gate
python3 -m aether_gate # opens the Setup page in your browserThat runs Icom LAN radios (IC-9700, IC-705…) and the test sim. For the other radio families:
brew install hamlib # Kenwood / Yaesu / any CAT rig (installs rigctld)
brew install soapysdr soapyrtlsdr # RTL-SDR dongles, and the IF-tap spectrum for CAT rigsAn IC-7300, or an IC-9700 over USB? Those talk CI-V over a USB serial port, which needs pyserial — and Homebrew has no formula for it. Run the gate from a virtual environment built to keep Homebrew's packages visible:
python3 -m venv --system-site-packages ~/.aether-gate
~/.aether-gate/bin/pip install pyserial
~/.aether-gate/bin/python -m aether_gate--system-site-packages matters: without it the environment cannot see Homebrew's numpy or SoapySDR either.
Check what it found: the Setup page's Known info / status link lists numpy, SoapySDR, hamlib and any dongles it can see.
Why brew install python numpy, and not the obvious alternatives:
⚠️ The Python that comes with macOS is too old. It is 3.9, the gate needs 3.10 or newer, and the failure is not a helpful message butTypeError: unsupported operand type(s) for |: 'type' and 'NoneType'. Homebrew'spythonis 3.14, and once installed,python3in a new Terminal window is Homebrew's.⚠️ pip install numpyis refused on Homebrew's Python:error: externally-managed-environment. That is Homebrew's policy, not a fault — usebrew install numpy, as above. (If you prefer a virtual environment, create it with--system-site-packages, or it will not see SoapySDR either.)⚠️ Whatever installs SoapySDR decides which Python can use it. Homebrew builds its binding for Homebrew's own Python, so running the gate with/usr/bin/python3givesModuleNotFoundError: No module named 'SoapySDR'even though the dongle support is installed. Use the samepython3throughout.- RTL-SDR Blog V4: Homebrew ships Osmocom's
librtlsdr(2.0.3), not the RTL-SDR Blog fork thatdeploy/install-pi.shbuilds for the Pi. Whether that drives a V4 properly has not been tested here; if a V4 misbehaves on macOS, build the Blog fork and point SoapySDR at it. - Unlike Windows, macOS needs no driver-swapping step (no Zadig equivalent).
python -m aether_gate --adapter sim --ae <your-AE-ip>A synthetic radio appears in AetherSDR's chooser. (Same host as AE? add
--port 5992 so it doesn't clash with AE's own :4992.)
Just run it with no arguments:
python -m aether_gate # opens the Setup UI + your browser
python -m aether_gate --setup # same, explicit
python -m aether_gate --setup --no-browser # headless: just prints the URLThis opens the Radio Setup & launcher at http://localhost:8730/. The first
visit asks you to choose a setup PIN — the page can start radios and keeps their
logins, so it is not left open to everyone on the LAN (forgot it? delete
~/.aether-gate/setup-auth.json and reload). Then pick your
radio family (Icom / Kenwood / dongle / sim), fill in its connection fields, and hit
Start. Save it as a profile with "connect on launch" and it comes up on its own
next time.
The Setup page (:8730) — choose a radio, fill its fields, Start.
The Radio type dropdown picks the adapter family — Icom (LAN), Kenwood (CAT), an SDR dongle, or the built-in sim:
Pick the adapter family from the Radio type dropdown.
The Setup page links to a Known Info / status page (/known) — a turn-it-on
health check: is your advertise IP reachable, are the dependencies present, which
dongles/serial ports are found, and can each saved profile's radio actually be
reached.
Every running gate serves a live diagnostics page on its control port
(--ctl-port, default 8731): open
http://<gate-ip>:<ctl-port>/radio
for a 1-Hz view of the radio as the gate sees it — link/auth state, VFO
frequency + mode, scope frame rate, S-meter, tune counters. There's also raw JSON
at /diagnostics if you want to script against it.
The diagnostics page (/radio on the gate's ctl-port) — the radio as the gate sees it.
Anything the Setup page can launch, you can also run directly from the command line:
# Icom IC-9700 over its LAN interface
python -m aether_gate --adapter icom9700 \
--radio-ip 10.0.0.7 --user <net-user> --pass <net-pass> \
--ae <AE-ip> --ctl-port 8732
# Icom IC-7300 over USB CI-V + USB audio, RX/control only
python -m aether_gate --adapter icom7300 \
--usb-civ-port /dev/serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_IC-7300_03031092-if00-port0 \
--usb-civ-baud 115200 \
--ae <AE-ip> --ctl-port 8731
# Kenwood TS-450S: hamlib CAT + an RTL-SDR-Blog V4 dongle for the waterfall
python -m aether_gate --adapter kenwood --kw-model TS-450S \
--rig-serial-port /dev/ttyUSB0 --rig-baud 4800 \
--soapy-driver rtlsdr --gain 40 \
--ae <AE-ip> --ctl-port 8734python -m aether_gate --help lists every option.
Every flag also has an environment variable: AETHER_GATE_ + the option name in
upper case, underscores for dashes. Precedence is CLI flag > environment >
built-in default, so an explicit flag always wins.
AETHER_GATE_ADAPTER=icom9700 \
AETHER_GATE_RADIO_IP=10.0.0.7 \
AETHER_GATE_USER=<net-user> \
AETHER_GATE_PW=<net-pass> \
AETHER_GATE_RX_ONLY=1 \
python -m aether_gateThis is aimed at unattended hosts — a systemd unit or a container can be configured
without a hand-edited command line, and without a password sitting on one (where
it is visible to every user in ps).
Two things worth knowing:
- The name follows the option's destination, not always its spelling.
--passis stored aspw, so it isAETHER_GATE_PW— notAETHER_GATE_PASS. - On/off flags accept
1/true/yes/on;0,false,no,offand empty all mean off, soAETHER_GATE_RX_ONLY=0leaves transmit alone rather than enabling the lock.
A Pi is the natural home: it runs unattended, survives reboots, and can serve
several radios at once. See PI_APPLIANCE.md for the flash-and-go
install (deploy/install-pi.sh) and deploy/systemd/ for the
service units (each radio a boot-enabled service; systemctl stop shuts it down
cleanly).
Until AetherSDR gains multi-radio connections, AE connects to one gate at a time — so several radios can sit in the chooser and you pick one like changing rigs on the desk. When AE grows multi-radio, the same Pi already serves them all.
Aether-gate reuses flex-sim's proven FlexRadio-emulation core (discovery + FlexLib control + VITA-49 streaming) and adds a per-radio adapter in front of it. Each source normalises to one Flex stream before AE, so AE only ever implements one ingest path.
your radio ──► RadioAdapter ──► Flex-protocol engine ──VITA-49 / FlexLib──► AetherSDR
(Icom LAN, (per family) (from flex-sim)
CAT+dongle,
SoapySDR)
Writing an adapter is small: subclass aether_gate.adapters.base.RadioAdapter, set
provides, implement one source method, and register it. See adapters/sim.py for
the reference and DESIGN.md / RADIO_SUPPORT.md for
the architecture.
Transmit: guarded on the Icom LAN path, still unwired everywhere else. When AE keys
TX it sends xmit 1 (not transmit set mox, which carries state). The engine routes
that to the adapter's key_tx() where one exists — and today only the Icom LAN
adapter defines it. On that path the gate really does assert CI-V 1C 00 and real RF
leaves the rig, behind a stack of guards: an arm latch, a TX-band whitelist (2m/70cm —
23cm is refused outright), a bare-carrier guard, a 10 s stuck-PTT watchdog, and
force-unkey + disarm when AE disconnects.
Note the engine arms automatically on every AE connect, so on a shared LAN any AE
client that connects can reach that path. Pass --rx-only (or
AETHER_GATE_RX_ONLY=1) to refuse PTT at the CI-V layer and advertise
tx_capable=False, so AE greys its TX button instead of offering a control the gate
will refuse. Recommended for any unattended or permanently-online gateway.
For every other family — hamlib/CAT (Kenwood, Yaesu), the dongle adapters, sim, and
the IC-7300 USB path — there is still no TX seam: the hamlib backend has a working
set_ptt (T 1/0), but no adapter exposes key_tx, so the engine never invokes it and
keying stays cosmetic. --enable-tx only makes AE offer TX for a CAT rig; it does not
key anything.
aether_gate/
core/ Flex-protocol engine (from flex-sim) + FFT
adapters/ RadioAdapter contract + per-radio adapters (icom9700, kenwood, soapy, sim)
setup.py the Setup/launcher web UI (:8730)
tests/ offline tests
deploy/ Raspberry Pi installer + systemd service units
python -m aether_gate.tests.test_smoke
python -m aether_gate.tests.test_hamlibAether-gate stands on other people's work:
- The Icom IC-9700 LAN support would not exist without Justin, W5JWP. The gate's entire Icom RS-BA1 / CI-V-over-LAN transport — the discovery, login/token handshake, the ping/keepalive cadence, the CI-V framing, and the band-scope decoding — is derived from his GPL-3.0 project w5jwp/SDR9700. That project reverse-engineered and documented the protocol the hard way; this gate is only possible because he did that work and released it openly. Attribution and license headers are preserved on every derived file. Thank you, Justin. 🙏
- The Icom IC-7300 USB adapter was contributed by s53zo. The receive-safe IC-7300 bridge — USB CI-V control, the radio's native 27h band-scope decode, and USB Audio CODEC RX capture — came in as an external contribution, hardware-verified on the author's own IC-7300. TX/PTT is deliberately left disabled. Thank you! 🙏
- The FlexRadio-emulation core (discovery, FlexLib control, VITA-49 streaming) comes from flex-sim.
- CAT control is Hamlib; dongle spectrum is SoapySDR.
Aether-gate collects nothing and sends nothing about you: no telemetry, no analytics, no account. It talks to your
radio and to AetherSDR, plus one optional GitHub check for a newer release (AETHER_GATE_NO_UPDATE_CHECK=1 turns
that off). Saved radios and the Setup PIN stay on your own machine. See PRIVACY.md.
GPL-3.0-or-later. Because the Icom transport is derived from the GPL-3.0 w5jwp/SDR9700, the whole of Aether-gate is GPL-3.0-or-later; the derived files carry SDR9700's copyright and license headers.