# PCIe fronthaul hot-swap harness — setup This guide gets you from a **clean workstation + lab INI** to running `**scripts/system/pcie_hotswap_harness.py`** with a valid `**FabricDefinition**` JSON. **Examples use `configs/default.ini`** (repo lab template). Set `**FIWI_LAB_INI**` or pass `**-c**` when your site file lives elsewhere. **Related:** `**docs/fabric-builder.md`** (interactive `**fabric build**`), `**docs/system-test-scripts.md**` (includes `**dump_concentrator.py**` — local CPU / PCIe Wi‑Fi / `**lspci**` / DMI snapshot), `**docs/power-control-and-inventory.md**` (INI reference). --- ## 1. Software From the FiWiControl repo root: ```bash python3 -m pip install -e ".[dev]" python3 -m pip install -e ".[power]" # BrainStem / Acroname on the machine that runs discovery ``` Python **3.11+**. --- ## 2. Lab INI Use `**configs/default.ini`** as the reference layout (or your own copy). Set `**FIWI_LAB_INI**` so tools find it without repeating `**-c**`. You need at least: - `**[site]**` (optional name) - `**[machine.]**` — `**ipaddr**`, `**sshtype**`, `**usb**` (`**local**` vs `**remote**`), expected `**acroname**` / `**monsoon**` (same contract as `**python3 -m fiwicontrol.power --verify-inventory**`) - `**[fabric]**` — harness merge and JSON generation: - `**fabric_id**` - `**concentrator**` — `**[machine.*]**` section id (or unique `**machine.name**`, `**label**`, `**machine.type**`) for **harness SSH** (the host where `**lspci`** / concentrator checks run — usually the concentrator workstation, not an RRH-only Pi). Optional per-RRH rows for the **non-interactive** JSON generator (see §4): ```ini [fabric.rrh.rrh-01] acroname_port = 0 acroname_module_serial = 12345678 # optional if only one hub on USB patch_panel_port = 101 # optional ``` Verify inventory when the bench is wired: ```bash python3 -m fiwicontrol.power --verify-inventory -c configs/default.ini ``` --- ## 3. Produce fabric JSON (pick one path) ### Path A — Interactive (no `[fabric.rrh.*]` required) On a host that **sees the Acroname hub over USB**, run: ```bash python3 -m fiwicontrol.fabric build -o configs/my-fabric.json -c configs/default.ini ``` Answer prompts for hub module, ports, and `**radio_id**` per port. This writes JSON including `**discovery_fingerprint**` and `**lab_ini**`. ### Path B — Non-interactive INI → JSON Add one `**[fabric.rrh.]**` section per RRH with at least `**acroname_port**`, and `**acroname_module_serial**` when multiple BrainStem modules appear on the USB bus for the host that runs `**fabric_realize.py**`. Then: ```bash python3 scripts/system/fabric_realize.py -c configs/default.ini --json > configs/my-fabric.json python3 scripts/system/fabric_realize.py -c configs/default.ini --json -o configs/my-fabric.json ``` (JSON is written to **stdout** unless you pass `**-o PATH`**; status lines go to **stderr**.) Optional `**--strict-ini`** matches `**--verify-inventory**` before writing; `**--force**` continues on mismatch. --- ## 4. Check USB fingerprint vs JSON ```bash python3 -m fiwicontrol.fabric status -f configs/my-fabric.json ``` Exit **0** only when `**READY`** (USB fingerprint matches the JSON). --- ## 5. Run the harness From the repo root (script adds `**src**` to `**PYTHONPATH**`): ```bash # Dry-run structure + INI merge (default lab INI if present) python3 scripts/system/pcie_hotswap_harness.py --fabric-json configs/my-fabric.json --dry-run # Require READY before starting python3 scripts/system/pcie_hotswap_harness.py --fabric-json configs/my-fabric.json --strict-fabric-ready --dry-run # Override concentrator SSH for this run (e.g. point at a different host than [fabric] / JSON) python3 scripts/system/pcie_hotswap_harness.py --fabric-json configs/my-fabric.json --rig-ip 192.168.1.39 --dry-run ``` `**--lab-ini PATH**` — use when your JSON was built against another file and you want this INI merged at harness time. `**--no-lab-ini**` — skip merging `**[fabric]**` from INI (JSON only). `**--dry-run**` — the harness does **not** toggle Acroname power; it exercises SSH and concurrency. Programmable power behavior is described under **DESIGN_GAPS** in the harness module docstring. --- ## 6. SSH Same rules as the rest of FiWiControl: non-interactive `**ssh root@`**. Optional `**FIWI_SSH_CONFIG**`: `**docs/node-control-asyncio-design.md**`. --- ## 7. Where things live | Piece | Location | | ------------------- | ------------------------------------------------------ | | Lab INI | `**configs/*.ini**`, `**FIWI_LAB_INI**` | | Fabric JSON | Your `**-o**` path (e.g. `**configs/my-fabric.json**`) | | Interactive builder | `**python3 -m fiwicontrol.fabric build**` | | INI-only generator | `**scripts/system/fabric_realize.py**` | | Harness | `**scripts/system/pcie_hotswap_harness.py**` |