2026-04-06 00:23:33 -04:00
2026-04-06 00:23:33 -04:00
2026-04-06 00:23:33 -04:00
2026-04-06 00:23:33 -04:00

DRB Client (Edge Node)

The client-side stack for the Discord Radio Bot system. Runs on the SDR hardware machine. Decodes radio with OP25, streams audio via Icecast, and connects to the C2 server over MQTT.

Services

Service Description
op25 OP25 SDR decoder — tunes to radio systems and streams decoded audio
icecast Audio streaming server — receives audio from OP25 and serves it over HTTP
edge-node FastAPI node agent — bridges OP25 metadata, MQTT C2 commands, and Discord voice

All services run with network_mode: host so they share the host network and can reach each other on localhost.

Prerequisites

  • Docker + Docker Compose
  • An RTL-SDR or compatible SDR dongle connected to the host
  • Network access to the DRB server (C2 server)

Setup

# 1. Copy env file
cp .env.example .env

# 2. Fill in .env
#    At minimum: NODE_ID, MQTT_BROKER (IP of the C2 server)

# 3. Build and start
docker compose build
docker compose up -d

Environment Variables (.env)

Variable Description Default
NODE_ID Unique identifier for this node required
NODE_NAME Human-readable name shown in the UI My Radio Node
NODE_LAT / NODE_LON GPS coordinates for the map view 0.0
MQTT_BROKER IP or hostname of the C2 server localhost
MQTT_PORT MQTT broker port 1883
C2_URL C2 server HTTP API URL (for audio uploads)
ICECAST_HOST Icecast hostname (leave as localhost) localhost
ICECAST_PORT Icecast port 8000
ICECAST_MOUNT Icecast mount point /radio

Node Provisioning Flow

  1. Start the client stack — the edge node connects to MQTT and sends a checkin
  2. The C2 server registers the node as pending approval
  3. An admin approves the node in the web UI
  4. The admin assigns a radio system to the node via the UI
  5. The C2 server pushes the system config over MQTT
  6. The edge node writes the config and starts OP25
  7. OP25 begins decoding and streaming audio to Icecast

After a restart, OP25 resumes automatically if the node was already configured.

Discord Voice

When a user runs /join in Discord (or clicks "Join Discord" in the UI), the C2 server sends a discord_join command to this node over MQTT. The edge node spins up a Discord bot using a token from the server's token pool and connects it to the requested voice channel, streaming live audio from Icecast.

Logs

docker compose logs -f edge-node
docker compose logs -f op25
docker compose logs -f icecast
S
Description
No description provided
Readme 220 KiB
Languages
Python 81.8%
Shell 7.6%
HTML 7.1%
Dockerfile 2.8%
Makefile 0.7%