fix(agent): advertise USRP auto-select (identifier=None), not name=

The CLI get_sdr_device path can only open a USB USRP via auto-select: its
_create_device_dict matches the identifier against raw device-dict values,
but common.py prepends "addr="/"name=" before handing it over, so no prefixed
identifier ever matches (this is also why addr=192.168.3.1 failed to match the
B210). Advertising name=<name> was therefore unusable.

detect_devices() now advertises a single USRP entry with identifier=None
(auto-select the sole device), labelled with the serial(s) found. The hub
forwards None, so the agent opens USRP() and picks the attached B210.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
J jrhughes003 2026-06-05 10:30:33 -04:00
parent bf64604bcf
commit 6bead217a3

View File

@ -84,24 +84,26 @@ def _enumerate_usrp() -> list[dict] | None:
logger.debug("USRP enumeration failed: %s", exc)
return None
entries: list[dict] = []
for dev in found:
serial = dev.get("serial") or ""
name = dev.get("name") or ""
product = dev.get("product") or dev.get("type") or "USRP"
# parse_ident only round-trips IP (bare) or ``name=`` — UHD has no
# serial= addressing here, so prefer name; otherwise auto-select (None).
identifier = f"name={name}" if name else None
suffix = serial or name or product
entries.append(
{
"device": "usrp",
"identifier": identifier,
"label": _label_for("usrp", suffix),
"connected": True,
}
)
return entries
if not found:
return []
# Addressing reality for the CLI get_sdr_device path: its USRP
# _create_device_dict matches the identifier against *raw* device values,
# but common.py prepends "addr="/"name=" before handing it over — so no
# prefixed identifier ever matches. The only reliable open for a USB USRP
# (B2x0) is auto-select (identifier=None → first device found). Networked
# USRPs addressed by IP would need a separate fix and aren't enumerated
# distinctly here. So advertise one auto-select entry, labelled with the
# serial(s) we saw so the operator still knows what's attached.
labels = [dev.get("serial") or dev.get("name") or dev.get("product") or "USRP" for dev in found]
return [
{
"device": "usrp",
"identifier": None,
"label": _label_for("usrp", ", ".join(labels)),
"connected": True,
}
]
# Device types we can cheaply enumerate into concrete instances. Anything not