Skip to content

icom-lan

Python library for controlling Icom, Yaesu, and other transceivers over LAN (UDP) or USB serial.

Direct connection to your radio — no wfview, hamlib, or RS-BA1 required.



Features

  • ✅ Multi-vendor support — Icom CI-V, Yaesu CAT, Kenwood CAT (future); data-driven rig profiles
  • ✅ Direct UDP connection — no intermediate software (LAN backend)
  • ✅ USB serial backend — CI-V over USB for IC-7610, IC-7300; USB audio devices
  • ✅ Full CI-V command set — frequency, mode/filter, power, meters, PTT, CW keying, VFO, split, ATT/PREAMP
  • ✅ Yaesu CAT backend — full working backend for Yaesu FTX-1 (USB serial)
  • ✅ Audio streaming — RX/TX with jitter buffer and full-duplex support
  • ✅ Audio FFT Scope — real-time FFT on USB/LAN audio for radios without hardware spectrum
  • ✅ Network discovery — find radios on your LAN automatically
  • ✅ CLI toolicom-lan status, icom-lan freq 14.074m
  • ✅ Built-in Web UI — spectrum, waterfall, controls, meters, audio in browser; LCD layout for non-scope radios
  • ✅ Async + Sync API — async by default, blocking wrapper available
  • ✅ Auto-reconnect — watchdog + exponential backoff (opt-in)
  • ✅ Minimal dependencies — core requires only pyserial; no web frameworks or heavy libraries
  • ✅ Type-annotated — full py.typed support for IDE autocompletion
  • ✅ 4492 tests — high coverage with golden protocol fixtures, UDP wire tests, and real-radio integration suite

Supported Radios

Radio Protocol Status
IC-7610 CI-V 0x98 ✅ Tested (LAN + USB)
IC-7300 CI-V 0x94 ✅ Tested (USB)
Yaesu FTX-1 Yaesu CAT ✅ Tested (USB)
IC-705 CI-V 0xA4 ✅ Validated (LAN/WiFi community-tested)
IC-9700 CI-V 0xA2 Profile — not yet tested
Xiegu X6100 CI-V 0x70 Profile only
Lab599 TX-500 Kenwood CAT Profile only
IC-7851 CI-V 0x8E Should work
IC-R8600 CI-V 0x96 Should work

See Supported Radios for full details. Any Icom radio with LAN/WiFi control should work — the CI-V address is configurable.

Minimal Example

import asyncio
from icom_lan import create_radio, LanBackendConfig

async def main():
    config = LanBackendConfig(host="192.168.1.100", username="user", password="pass")
    async with create_radio(config) as radio:
        freq = await radio.get_frequency()
        print(f"{freq / 1e6:.3f} MHz")

asyncio.run(main())

License

MIT — see LICENSE.

Protocol knowledge derived from the wfview project's reverse engineering work. This is an independent clean-room implementation.

Trademark Notice

Icom™ and the Icom logo are registered trademarks of Icom Incorporated. This project is not affiliated with, endorsed by, or sponsored by Icom. Product names are used solely for identification and compatibility purposes (nominative fair use).