Documentation
Rigctl Protocol
Source:
protocols/rigctl/README.md
A small, dependency-free Python client for controlling a Hamlib-style rigctl
TCP server, including the SDR++ \start and \stop extensions used by
applications.
This directory belongs in the protocol layer. It knows how to format and send rigctl commands, but it does not decide what a higher-level application action means.
Contents
rigctl_protocol/
├── __init__.py
├── rigctl_client.py
├── README.md
└── component_test/
├── __init__.py
├── rigctl_cli.py
└── test_rigctl_component.py
└── emulator/
├── __init__.py
└── example_rigctl_server.py
└── emulator/
rigctl_client.py: reusable TCP client.rigctl_cli.py: one-shot and interactive command-line test client.component_test/test_rigctl_component: end-to-end tests using a real localhost TCP connection.emulator/example_rigctl_server.py: stateful local server for development.
Requirements
Python 3.10 or newer is recommended. No third-party libraries are required. Everything uses the Python standard library.
Supported Client Operations
| Client method | Wire command | Purpose |
|---|---|---|
set_frequency(hz) |
F <hz> |
Set frequency in hertz |
get_frequency() |
f |
Read frequency |
set_mode(mode, bandwidth) |
M <mode> <bandwidth> |
Set mode and bandwidth |
start() |
\start |
Start SDR++ playback |
stop() |
\stop |
Stop SDR++ playback |
get_signal_strength() |
l STRENGTH |
Read signal strength |
get_snr() |
l SNR |
Read SNR |
get_rds() |
l RDS |
Read RDS text |
send(command) |
raw | Send any command |
NFM is normalized to FM for SDR++ compatibility. Unknown mode names are
uppercased and passed through unchanged.
Basic Library Use
from rigctl_protocol import RigctlClient
client = RigctlClient(host="127.0.0.1", port=4532)
client.start()
client.set_frequency(101_100_000)
client.set_mode("WFM", 200_000)
print(client.get_frequency())
print(client.get_signal_strength())
print(client.get_rds())
The client opens a new TCP connection for each command. This keeps it stateless and matches the simple request/response behavior expected by this package.
Run the Example Server
From the package directory:
python3 example_rigctl_server.py --verbose
The default endpoint is 127.0.0.1:4532. Use a different port when SDR++ is
already using 4532:
python3 example_rigctl_server.py --port 14532 --verbose
The example server supports the commands used by RigctlClient, plus m to
read the current mode and bandwidth. It is a development fixture, not a full
Hamlib implementation and, tragically, does not actually demodulate radio.
Use the CLI
Run one command:
python3 rigctl_cli.py --port 14532 set-frequency 101100000
python3 rigctl_cli.py --port 14532 get-frequency
python3 rigctl_cli.py --port 14532 set-mode NFM 12500
python3 rigctl_cli.py --port 14532 strength
python3 rigctl_cli.py --port 14532 raw m
Open an interactive raw-command prompt:
python3 rigctl_cli.py --port 14532 interactive
Example session:
rigctl> F 101100000
RPRT 0
rigctl> f
101100000
rigctl> M FM 12500
RPRT 0
rigctl> quit
Run the Component Tests
From the package directory:
python3 -m unittest discover -s component_test -v
Or run the component-test file directly:
python3 component_test/test_rigctl_component.py
The tests start the example server on an automatically assigned localhost port, exercise the real client over TCP, and shut the server down afterward. They do not require SDR++ and do not occupy port 4532.
Testing Against SDR++
- Enable SDR++’s rigctl server.
- Confirm its host and TCP port, commonly
127.0.0.1:4532. - Run CLI checks such as:
python3 rigctl_cli.py get-frequency
python3 rigctl_cli.py set-frequency 162550000
python3 rigctl_cli.py set-mode NFM 12500
python3 rigctl_cli.py start
Be aware that commands and returned level formats can vary between rigctl server
implementations. The \start, \stop, and l RDS commands are SDR++-specific
extensions rather than portable Hamlib operations.
Error Behavior
- Socket and connection failures are allowed to propagate as
OSErrorfrom the library so callers can distinguish timeout, refused connection, and network failures. - A read timeout after a successful send returns an empty string because some servers do not reply to every command.
- Invalid local arguments raise
ValueErrorbefore opening a socket. - The example server returns
RPRT 0for success,RPRT -1for invalid values, andRPRT -4for unsupported commands.