← Back to Skills Marketplace
morozsm

Icom IC-7610

by Sergey Morozik · GitHub ↗ · v2.1.0
cross-platform ⚠ suspicious
577
Downloads
2
Stars
0
Active Installs
5
Versions
Install in OpenClaw
/install icom-7610
Description
Control an Icom IC-7610 transceiver over USB/LAN. Get/set frequency, mode, power, S-meter, SWR. CW keying and beacon mode. Remote power on/off.
README (SKILL.md)

Icom IC-7610

Prerequisites

  • Hamlib (rigctl): brew install hamlib
  • curl: usually pre-installed
  • python3: usually pre-installed
  • pyserial (only for serial power on): pip3 install pyserial
  • wfview (optional, for LAN control): wfview.org/download

Configuration

Station config in .env (not in git). On first install: cp .env.example .env.

Environment Variables

Variable Default Description
CALLSIGN (required for CW/beacon) Your callsign
SERIAL_PORT /dev/cu.usbserial-11320 CI-V USB serial port
BAUD_RATE 19200 Serial baud rate (⚠️ not 115200!)
HAMLIB_MODEL 3078 Hamlib model ID for IC-7610
FLRIG_URL http://127.0.0.1:12345/RPC2 flrig XML-RPC endpoint
RIGCTLD_ADDR 127.0.0.1:4533 rigctld TCP address (wfview/hamlib)
MAX_POWER_W 50 Hard power limit in watts
source "$(dirname "$0")/.env" 2>/dev/null || true
PORT="${SERIAL_PORT:-/dev/cu.usbserial-11320}"
BAUD="${BAUD_RATE:-19200}"
MODEL="${HAMLIB_MODEL:-3078}"
FLRIG="${FLRIG_URL:-http://127.0.0.1:12345/RPC2}"
RIGCTLD="${RIGCTLD_ADDR:-127.0.0.1:4533}"
MAX_POWER="${MAX_POWER_W:-50}"

RFPOWER Scale

rigctl uses 0.0–1.0 where 1.0 = 100 W. So: RFPOWER = watts / 100. 5 W = 0.05, 50 W = 0.50. ⚠️ L RFPOWER 5 = 500 W equivalent, NOT 5 watts! flrig uses watts directly: rig.set_power 50 = 50 W.

Connecting

Three connection methods, in priority order. Auto-detect logic:

# 1. Check rigctld (wfview LAN or standalone hamlib rigctld)
if rigctl -m 2 -r "$RIGCTLD" f >/dev/null 2>&1; then
  CONN="rigctld"
# 2. Check flrig
elif curl -s --connect-timeout 2 --max-time 3 -X POST "$FLRIG" \
     -H "Content-Type: text/xml" \
     -d '\x3C?xml version="1.0"?>\x3CmethodCall>\x3CmethodName>rig.get_vfoA\x3C/methodName>\x3C/methodCall>' \
     | grep -q '\x3Cvalue>'; then
  CONN="flrig"
# 3. Fall back to direct serial
else
  CONN="serial"
fi

rigctld — LAN via wfview (recommended) or standalone hamlib daemon

Connects to IC-7610 over network via wfview (UDP) or a running rigctld daemon. Full control: freq, mode, power, S-meter, SWR, CW keying, power on/off.

rigctl -m 2 -r "$RIGCTLD" \x3Ccmd>
# Read:  f   m   l RFPOWER   l SWR
# Write: F 14074000   M USB 3000   L RFPOWER 0.50
# CW:    b "CQ CQ DE YOURCALL K"
# Power: set_powerstat 0 (off)   set_powerstat 1 (on)

Setup: wfview → Settings → Enable LAN → connect to radio IP → Enable RigCtld (port 4533).

⚠️ Note: M (set mode) may hang waiting for ack from wfview rigctld — command still executes. Use a timeout wrapper or send as fire-and-forget when needed.

Advantages over serial:

  • No USB cable needed — Ethernet only
  • Power on works with simple set_powerstat 1 (no raw CI-V / pyserial needed)
  • Multiple programs can share the radio via wfview (rigctld + virtual serial port)
  • Longer distance (Ethernet 100m vs USB 5m)

rigctl serial (direct USB, full control incl. CW and power on/off)

rigctl -m $MODEL -r "$PORT" -s $BAUD \x3Ccmd>
# Read:  f (freq)  m (mode+BW)  l RFPOWER  l SWR
# Write: F 14074000   M USB 3000   L RFPOWER 0.50
# CW:    b "CQ CQ DE YOURCALL K"
# Quick: f m l RFPOWER   → freq, mode, BW, power in one call

⚠️ Baud 19200 (not 115200!). Always wrap: timeout 10 rigctl ... ⚠️ Port busy while flrig runs. Close flrig for CW/power on-off.

flrig XML-RPC

call_flrig() {
  curl -s --connect-timeout 3 --max-time 5 -X POST "$FLRIG" \
    -H "Content-Type: text/xml" \
    -d "\x3C?xml version=\"1.0\"?>\x3CmethodCall>\x3CmethodName>$1\x3C/methodName>\x3Cparams>$2\x3C/params>\x3C/methodCall>" | \
    grep -o '\x3Cvalue>[^\x3C]*\x3C/value>' | head -1 | sed 's/\x3C[^>]*>//g'
}
# Read:  call_flrig rig.get_vfoA / rig.get_modeA / rig.get_power / rig.get_Sunits / rig.get_SWR
# Write: call_flrig rig.set_vfoA '\x3Cparam>\x3Cvalue>\x3Cdouble>14074000\x3C/double>\x3C/value>\x3C/param>'
#        call_flrig rig.set_modeA '\x3Cparam>\x3Cvalue>\x3Cstring>USB\x3C/string>\x3C/value>\x3C/param>'
#        call_flrig rig.set_power '\x3Cparam>\x3Cvalue>\x3Cdouble>50\x3C/double>\x3C/value>\x3C/param>'

Remote Power On/Off

Requires: rear POWER switch ON + MENU → SET → Network → Power OFF Setting = Standby/Shutdown.

Via rigctld (wfview LAN) — simplest

rigctl -m 2 -r "$RIGCTLD" set_powerstat 0   # off
rigctl -m 2 -r "$RIGCTLD" set_powerstat 1   # on — works! wfview handles it

Via serial — power off works, power on needs raw CI-V

Off: rigctl -m $MODEL -r "$PORT" -s $BAUD set_powerstat 0

On: rigctl set_powerstat 1 DOES NOT WORK via serial (rig_open fails in standby). Use raw CI-V:

python3 -c "
import serial, time
ser = serial.Serial('$PORT', $BAUD, timeout=2)
ser.reset_input_buffer()
ser.write(bytes([0xFE,0xFE,0x98,0xE0,0x18,0x01,0xFD]))
time.sleep(1); resp = ser.read(100); ser.close()
print('Power ON: OK' if 0xFB in resp else 'FAIL')
"

Wait 7–10 sec after power on before sending commands. "Command rejected" during boot is normal.

CW & Beacon

Works via both rigctld (LAN) and direct serial.

# Via rigctld (LAN):
rigctl -m 2 -r "$RIGCTLD" b "CQ CQ CQ DE $CALLSIGN $CALLSIGN K"

# Via serial:
rigctl -m $MODEL -r "$PORT" -s $BAUD b "CQ CQ CQ DE $CALLSIGN $CALLSIGN K"

# Beacon loop (works with either connection)
for i in $(seq 1 $REPEATS); do
  rigctl -m 2 -r "$RIGCTLD" b "VVV DE $CALLSIGN VVV DE $CALLSIGN"
  [ $i -lt $REPEATS ] && sleep $INTERVAL
done

Radio setting for CW: MENU → SET → Connectors → USB Keying (CW) → RTS

Safety Rules

Pre-TX checklist (MANDATORY before every transmission)

  1. Operator confirmation received
  2. Frequency within amateur band (1.8–2.0, 3.5–4.0, 7.0–7.3, 10.1–10.15, 14.0–14.35, 18.068–18.168, 21.0–21.45, 24.89–24.99, 28.0–29.7 MHz)
  3. Mode matches band segment (no phone below CW/data boundary)
  4. Power ≤ $MAX_POWER_W (default 50 W); above → extra confirmation
  5. SWR ≤ 3.0 if available; >3.0 → REFUSE (antenna problem)

No confirmation needed

Reading freq/mode/S-meter/SWR, switching VFO, changing freq/mode, power on/off.

Always require confirmation

PTT, CW keying, beacon, power > $MAX_POWER_W. Any RF transmission.

Auto-refuse (even with confirmation)

Transmit outside amateur bands. Transmit with SWR > 3.0.

Beacon regulatory (FCC)

Remote operation legal (§97.109d). Unattended beacon only 28.2–28.3, 50.06–50.08+ MHz. Below 28 MHz → operator must be on comms.

Reference

Full documentation in references/FULL-REFERENCE.md — consult when needed:

  • Complete flrig XML-RPC method list (30+ methods)
  • CI-V protocol reference (commands, modes, addressing)
  • Error recovery table (common errors + fixes)
  • Shell helper functions (freq_valid, set_power_safe, rig_retry, preflight, quick_status)
  • Radio menu settings (Network, CI-V, Connectors)
  • Compatibility notes for other Icom transceivers
  • US Amateur Band Plan table (detailed, with CW/Data/Phone segments)
Usage Guidance
This skill appears to be what it claims: a set of shell/python instructions to control an IC‑7610 using hamlib/wfview/flrig. Before installing, do the following: 1) Inspect the .env.example/.env the skill will source and ensure it contains only expected values (callsign, serial port, local URLs); do not place unrelated secrets there. 2) Be aware rigctl and direct serial access will open the radio's USB/serial device and can block other programs; stop flrig/WSJT-X if you need exclusive serial access. 3) The skill can power the radio on/off and key CW — run first with operator supervision and the provided pre‑TX safety checks enabled to avoid accidental transmissions. 4) The metadata omitted declaring the env vars the skill actually reads; treat that as an informational mismatch (not a security issue) and confirm configuration before use. 5) If you do not want the agent to ever transmit autonomously, restrict autonomous invocation or require explicit confirmation before any PTT/CW/beacon action.
Capability Analysis
Type: OpenClaw Skill Name: icom-7610 Version: 2.1.0 The skill is designed for legitimate ham radio control and includes robust safety checks to prevent unauthorized transmissions. However, the `rig_retry` function in `references/FULL-REFERENCE.md` uses `eval "$1"`, which is a shell injection vulnerability if the `$1` argument can be manipulated by a prompt injection against the AI agent. While the provided examples use hardcoded commands, this `eval` construct itself is a high-risk primitive. Additionally, the `TODO` list mentions exploring a 'Telnet CLI (port 23) — admin console', which, while not implemented, indicates an interest in a potentially insecure and privileged interface.
Capability Assessment
Purpose & Capability
Name/description (IC-7610 control) matches the binaries and actions used: rigctl (Hamlib) for radio control, curl for flrig XML-RPC, and python3/pyserial for raw CI-V serial power-on. The brew install of hamlib (rigctl) is appropriate and expected.
Instruction Scope
SKILL.md instructs the agent to source a local .env, use rigctl, curl to local flrig, and a short python3 serial snippet for power-on; all actions are within the stated scope. Note: the skill will read a .env file (station configuration) from the skill directory — this is expected for radio control but is an explicit file read that users should review before use.
Install Mechanism
Install spec uses Homebrew to install the well-known hamlib package (provides rigctl). No downloads from untrusted URLs or arbitrary extract/install steps are present.
Credentials
The registry lists no required env vars, but SKILL.md documents several configuration env vars (.env): CALLSIGN, SERIAL_PORT, BAUD_RATE, HAMLIB_MODEL, FLRIG_URL, RIGCTLD_ADDR, MAX_POWER_W. Those variables are reasonable and proportional to the skill's function, but the metadata/registry omission is a small inconsistency (the skill will read .env variables even though none are declared as required in the registry). None of the env vars are sensitive tokens by default, but .env is user-controlled — review its contents before use.
Persistence & Privilege
Skill does not request always: true, does not modify other skills or system-wide configs, and requires only local files and standard binaries. It can perform actions that change radio state (power on/off, keying) — these are functionally appropriate but should be used with operator supervision.
How to Use
  1. Make sure OpenClaw is installed (local or Docker)
  2. Run the install command in chat: /install icom-7610
  3. After installation, invoke the skill by name or use /icom-7610
  4. Provide required inputs per the skill's parameter spec and get structured output
Version History
v2.1.0
Add LAN control via wfview rigctld (auto-detect), rigctld connection priority, power on/off via LAN, RIGCTLD_ADDR env var
v1.3.0
Add LAN control via wfview rigctld (auto-detect), rigctld connection priority, power on/off via LAN, RIGCTLD_ADDR env var
v1.2.0
Add prerequisites section (pyserial), document env vars table, add homepage URL
v1.1.0
Compact SKILL.md (127 lines vs 619), full docs moved to references/. Added metadata with dependency checks.
v1.0.0
Initial release: flrig/rigctl control, remote power on/off, CW keying, beacon mode, pre-TX safety checks, band plan validation, error handling
Metadata
Slug icom-7610
Version 2.1.0
License
All-time Installs 0
Active Installs 0
Total Versions 5
Frequently Asked Questions

What is Icom IC-7610?

Control an Icom IC-7610 transceiver over USB/LAN. Get/set frequency, mode, power, S-meter, SWR. CW keying and beacon mode. Remote power on/off. It is an AI Agent Skill for Claude Code / OpenClaw, with 577 downloads so far.

How do I install Icom IC-7610?

Run "/install icom-7610" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.

Is Icom IC-7610 free?

Yes, Icom IC-7610 is completely free (open-source). You can download, install and use it at no cost.

Which platforms does Icom IC-7610 support?

Icom IC-7610 is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).

Who created Icom IC-7610?

It is built and maintained by Sergey Morozik (@morozsm); the current version is v2.1.0.

💬 Comments