Adding a New Radio (Rig Profiles)¶
Overview¶
icom-lan uses TOML rig files to define radio capabilities, protocol type, CI-V commands,
and hardware parameters. Adding a new radio means adding a new .toml file — no Python
changes required for most radios.
Rig files live in rigs/. Reference files:
rigs/ic7610.toml— IC-7610 (dual receiver, LAN, CI-V, full feature set)rigs/ic7300.toml— IC-7300 (single receiver, USB serial, CI-V)rigs/ftx1.toml— Yaesu FTX-1 (Yaesu CAT protocol, dual RX)rigs/x6100.toml— Xiegu X6100 (CI-V, IC-705 compatible subset, QRP)rigs/tx500.toml— Lab599 TX-500 (Kenwood CAT protocol, QRP)
Quick Start¶
# 1. Copy the closest reference rig file
cp rigs/ic7610.toml rigs/ic9700.toml # for Icom CI-V
cp rigs/tx500.toml rigs/ts890s.toml # for Kenwood CAT
cp rigs/ftx1.toml rigs/ft710.toml # for Yaesu CAT
# 2. Edit [radio] and [protocol] sections
# 3. Update [capabilities] to match your radio
# 4. Update [commands] (CI-V radios) or leave empty (Kenwood/Yaesu CAT)
# 5. Add [controls], [meters], [[rules]] as needed
# 6. Run the loader tests
uv run pytest tests/test_rig_loader.py tests/test_rig_multi_vendor.py -v
Supported Protocols¶
| Protocol | Type string | Examples | Description |
|---|---|---|---|
| Icom CI-V | "civ" |
IC-7610, IC-7300, Xiegu X6100/X6200 | Binary CI-V frames |
| Kenwood CAT | "kenwood_cat" |
Lab599 TX-500, Kenwood TS-890S | Text "CMD params;" |
| Yaesu CAT | "yaesu_cat" |
Yaesu FTX-1, FT-710 | Yaesu text protocol |
For CI-V radios, [radio].civ_addr is required. For Kenwood/Yaesu, omit it.
TOML Schema Reference¶
The sections below provide complete field documentation.
Section-by-Section Walkthrough¶
[radio] — Model Identity¶
[radio]
id = "icom_ic9700" # unique snake_case ID
model = "IC-9700" # human-readable, used in UI and logs
civ_addr = 0xA2 # CI-V address (required for civ, omit for others)
receiver_count = 2 # 1 or 2 independent receivers
has_lan = true # Ethernet port built-in?
has_wifi = false # WiFi built-in?
default_baud = 115200 # optional: default serial baud rate
id must be globally unique. Convention: <vendor>_<model_lower> (e.g. icom_ic7300,
yaesu_ftx1, lab599_tx500).
[protocol] — Communication Protocol¶
[protocol]
type = "civ" # "civ" | "kenwood_cat" | "yaesu_cat"
address = 0xA2 # optional: override civ_addr for protocol
baud = 115200 # optional: protocol-specific baud rate
Omit this section entirely for CI-V radios — defaults to type = "civ".
[capabilities] — Feature Flags¶
[capabilities]
features = [
"audio", # RX/TX audio streaming
"scope", # spectrum scope
"dual_rx", # dual independent receivers
"meters", # S-meter, SWR, ALC, etc.
"tx", # transmit capability
"attenuator", # ATT control
"preamp", # preamplifier
# ... see _schema.md for full list
]
The capability list controls Web UI guards — features not listed are hidden.
[controls] — UI Control Styles (new)¶
Defines how controls render in the UI. Each sub-table corresponds to a capability:
[controls.attenuator]
style = "stepped" # IC-7610: 16 discrete steps with stepper UI
[controls.nb]
style = "toggle_and_level" # IC-7610: separate ON/OFF + level slider
Styles:
- toggle — ON/OFF (IC-7300 ATT, X6100 ATT)
- stepped — Discrete steps with [−][dropdown][+] (IC-7610 ATT)
- selector — Dropdown/selector (FTX-1 ATT: 4 named levels)
- toggle_and_level — Separate toggle + slider (IC-7610 NB/NR)
- level_is_toggle — 0=OFF, >0=level (FTX-1 NB/NR)
[meters] — Calibration Tables (new)¶
Non-linear raw→actual calibration for meters. The frontend interpolates between points:
[meters.s_meter]
redline_raw = 130 # where the red zone starts
[[meters.s_meter.calibration]]
raw = 0
actual = -54.0
label = "S0"
[[meters.s_meter.calibration]]
raw = 130
actual = 0.0
label = "S9"
[[rules]] — Constraint Rules (new)¶
Defines how capabilities interact (mutual exclusion, dependencies):
[[rules]]
kind = "mutex"
fields = ["attenuator", "preamp"]
[[rules]]
kind = "disables"
when_active = "digisel"
disables = ["preamp"]
reason = "DIGI-SEL overrides preamp"
Rule kinds: mutex, disables, requires, value_limit.
[vfo] — VFO Scheme¶
Four schemes supported:
| Scheme | Receivers | VFOs | Example |
|---|---|---|---|
main_sub |
2 | 2 | IC-7610 |
ab |
1 | 2 | IC-7300, X6100, TX-500 |
ab_shared |
2 | 1 | FTX-1 |
single |
1 | 1 | Simple QRP rigs |
[commands] — Wire Bytes¶
Required for CI-V radios. Optional (may be empty) for Kenwood/Yaesu CAT:
[commands]
get_freq = [0x03]
set_freq = [0x05]
get_af_level = [0x14, 0x01]
# ... full list in ic7610.toml
[commands.overrides]
# Model-specific differences
For Kenwood/Yaesu radios, commands are handled by the protocol adapter, not CI-V bytes.
Other Sections¶
See the full schema for: [attenuator], [preamp], [agc], [spectrum],
[[freq_ranges.ranges]], [cmd29], [antenna], [apf], [notch],
[ssb_tx_bw], [break_in], [rit], [cw], [nb], [power].
Testing Your Rig File¶
# Basic load + validation
uv run python -c "
from pathlib import Path
from icom_lan.rig_loader import load_rig
cfg = load_rig(Path('rigs/ic9700.toml'))
print(cfg.model, cfg.protocol_type, cfg.receiver_count)
print('capabilities:', cfg.capabilities)
print('controls:', cfg.controls)
print('rules:', cfg.rules)
"
# Full test suite
uv run pytest tests/ -x -q
# Multi-vendor specific tests
uv run pytest tests/test_rig_multi_vendor.py -v
Common Mistakes¶
| Mistake | Error message |
|---|---|
Missing [capabilities].features |
features must not be empty |
| Unknown capability | unknown capability 'xyz'. Known: [...] |
| Invalid VFO scheme | scheme must be one of {'ab', 'main_sub', 'ab_shared', 'single'} |
| Invalid protocol type | type must be one of {'civ', 'kenwood_cat', 'yaesu_cat'} |
| Invalid control style | style must be one of {'toggle', 'stepped', ...} |
| Invalid rule kind | kind must be one of {'mutex', 'disables', ...} |
| CI-V addr missing for CI-V radio | Parser defaults to 0 — may cause runtime errors |
See Also¶
docs/api/rig-loader.md—load_rig()/discover_rigs()APIdocs/guide/radios.md— supported radios and backend comparisondocs/api/commands.md— usingCommandMapwith command functions