Code for managing, monitoring and testing Umber Fi-Wi networks
Go to file
Robert McMahon ed8020ecc3 docs(html): static Fi-Wi L4S spec for local browser viewing
- Replace Fi-Wi-L4S.php (session_start preamble) with Fi-Wi-L4S.html
- README: .html path and note to open file locally

Made-with: Cursor
2026-04-10 20:24:59 -07:00
configs refactor: move lab discovery to fiwicontrol.lab; remote setup to commands 2026-04-10 18:39:43 -07:00
docs refactor(flows): rename async iperf entrypoints for clarity 2026-04-10 19:47:51 -07:00
html docs(html): static Fi-Wi L4S spec for local browser viewing 2026-04-10 20:24:59 -07:00
scripts refactor: move lab discovery to fiwicontrol.lab; remote setup to commands 2026-04-10 18:39:43 -07:00
src/fiwicontrol refactor(flows): rename async iperf entrypoints for clarity 2026-04-10 19:47:51 -07:00
tests feat(spc): ShewhartControlChart and HotellingT2 under fiwicontrol.spc 2026-04-10 19:39:00 -07:00
.gitignore Initial import: fiwicontrol package (commands + power scaffold) 2026-04-10 11:36:23 -07:00
LICENSE license: Umber copyright header and complete Apache-2.0 appendix 2026-04-10 19:16:02 -07:00
README.md docs(html): static Fi-Wi L4S spec for local browser viewing 2026-04-10 20:24:59 -07:00
pyproject.toml feat(spc): ShewhartControlChart and HotellingT2 under fiwicontrol.spc 2026-04-10 19:39:00 -07:00

README.md

FiWiControl

Tools, libraries and statistical software for automating, managing, monitoring and testing Umber FiWi networks.

Where it runs: FiWiControl is built to run on the Umber concentrator — the FiWi control plane described in the architecture spec (html/Fi-Wi-L4S.html in this repo; open that file in a browser for local viewing) — for lab and customer automation. Day-to-day development still uses workstation installs and lab rigs (e.g. Raspberry Pi) as in docs/install.md.

Naming: The Git repository and checkout directory are FiWiControl (mixed case). The Python distribution and import package are fiwicontrol (all lowercase, PEP 8) — same project, different casing rules for Git vs Python. Use fiwicontrol for pip install / import, not FiWiControl.

This repository ships that distribution (fiwicontrol on PyPI / pip) with import root fiwicontrol:

  1. fiwicontrol.commands — run commands on remote rigs via OpenSSH or ush (Command, CommandManager, ssh_node). Remote Pi bootstrap: python3 -m fiwicontrol.commands <ip> --remote-repo … (see docs/install.md). Must not import fiwicontrol.power.
  2. fiwicontrol.lab — USB discovery (Acroname / Monsoon) and configs/*.ini inventory load + verify. Imports fiwicontrol.commands for SSH discovery only.
  3. fiwicontrol.powerPower (.on() / .off() / .voltage() / …) via AcronamePower and MonsoonPower, plus a small CLI (--discovery-json, --list-power-devices, --verify-inventory with -c). Re-exports fiwicontrol.lab discovery/inventory for compatibility. May import fiwicontrol.commands and fiwicontrol.lab; the reverse is forbidden.
  4. fiwicontrol.flows — async iperf-driven traffic flows over ssh (remote server/client processes, sampling, histogram / KS tooling). Lives in flows/flows.py, structured for Python 3.11 (asyncio.timeout, asyncio.gather, await iperf_flow.run_traffic and related coroutines; sync run / commence / … call asyncio.run only when no loop is already running). Depends on SciPy, NumPy, Matplotlib, and a compatible iperf binary on endpoints—use pip install -e ".[flows]" when you need it; import fiwicontrol.flows alone stays lightweight (lazy load). Not yet integrated with ssh_node or iperf 2 on Pi 5 roadmap text above—that wiring is follow-on work.
  5. fiwicontrol.spcSPC primitives: ShewhartControlChart (individuals / MR limits) and HotellingT2 (Phase I meancovariance, T² and UCL). Under spc/ (not flows/). Optional pip install -e ".[spc]" (NumPy, SciPy); import fiwicontrol.spc is lazy until you reference a class.

Relationship to the FiWi architecture spec

The spec (html/Fi-Wi-L4S.html) describes the FiWi system: the Umber concentrator as the centralized control, queueing, and time plane, RRHs on the PCIe / fronthaul fabric, and the L4S-oriented latency model that depends on that split. FiWiControl does not implement the datapath or MAC; it is the concentrator-resident (and dev-workstation) Python layer that manages and validates the deployed system around that architecture.

Concretely, it is how we keep what we think is connected aligned with what is actually cabled and powered: INI inventory and verification (fiwicontrol.lab, fiwicontrol.power), scripted remote work over the same SSH / ush paths we use in production (fiwicontrol.commands), programmable power and USB so bring-up and PCIe hot-plug sequences are repeatable, async iperf flows for load and measurement against RRHs or lab stand-ins (fiwicontrol.flows), and SPC when we need statistical discipline across long campaigns (fiwicontrol.spc). Read the spec for why the topology and timing model look the way they do; read this repo and docs/ for how we install, verify, and operate it day to day.

Near-term focus: PCIe hot-swap testing

A first concrete goal for this stack is to support PCIe hot-swap (hot-plug) testing in the lab: controlled remove / restore of the link, predictable enumeration and driver behavior, and repeatable runs across builds and rigs.

That work fails if the bench is informal—wrong port, wrong power path, or no shared picture of what was connected when. FiWiControl targets that gap by combining documented inventory (INI + --verify-inventory), remote automation (ssh_node, python3 -m fiwicontrol.commands to bring up rigs), and programmable power / USB paths (fiwicontrol.power) so sequences are scripted and checkable before the PCIe harness runs. fiwicontrol.spc is aimed at many hot-plug cycles—spotting drift in failure rates or side metrics—not only general FiWi bring-up (see docs/spc.md).

Lab fleet: Raspberry Pi 5 and iperf 2 (planned)

We expect a fleet of Raspberry Pi 5 boards to act as controllers and actuators in the lab: remote fiwicontrol install, discovery over SSH, PCIe / FiWi harness hosts (docs already assume Pi-class rigs). Those Pi 5s will run iperf 2 as synthetic traffic endpoints—controlled load and measurement during FiWi and bring-up experiments, not one-off manual runs. None of this is automated in-repo yet beyond what you can already drive by hand over ssh_node; first-class orchestration and reporting are roadmap.

ESP32, IEEE 802.11, and advanced telemetry (planned)

Separately from the Pi 5 iperf plane, we plan ESP32-based nodes for advanced telemetry, including rich use of IEEE 802.11 (WiFi): airlink statistics, channel / PHY-adjacent metrics, retries, timing, and correlation with harness and inventory state. The goal is lab- and field-grade 802.11 telemetry, not only GPIO or serial counters. This stack is not implemented yet in fiwicontrol; todays code is still the commands / lab / power packages above.

ush expansion (planned)

Expanded ush orchestration alongside OpenSSH—not only the ush transport already wired through ssh_node, but first-class tooling for benches that standardize on ush. Roadmap only beyond todays transport path.

Product differentiation

We expect advanced telemetry (including 802.11-centric, e.g. ESP32, data) and advanced use of iperf 2 on Raspberry Pi 5 hosts—patterns tied to rig state, inventory, and SPC (fiwicontrol.spc), not ad hoc throughput screenshots—to help differentiate Umber FiWi products in the market.

Statistical process control

In tree: fiwicontrol.spcShewhartControlChart and HotellingT2 (Phase I fit, T², Phase II UCL). Optional pip install -e ".[spc]"; overview docs/spc.md.

Planned: tighter coupling with inventory / harness automation, campaign-scale reporting, and richer charting beyond these primitives.

Layout

FiWiControl/
├── LICENSE
├── README.md
├── pyproject.toml
├── html/
│   └── Fi-Wi-L4S.html
├── docs/
│   ├── install.md
│   ├── node-control-asyncio-design.md
│   ├── power-control-and-inventory.md
│   ├── flows.md
│   └── spc.md
├── src/
│   └── fiwicontrol/
│       ├── commands/
│       │   ├── __init__.py
│       │   ├── __main__.py
│       │   ├── node_control.py
│       │   └── remote_setup.py
│       ├── lab/
│       │   ├── __init__.py
│       │   ├── discovery.py
│       │   ├── inventory_config.py
│       │   └── inventory_verify.py
│       ├── power/
│       │   ├── __init__.py
│       │   ├── __main__.py
│       │   ├── acroname.py
│       │   ├── control.py
│       │   └── monsoon.py
│       ├── flows/
│       │   ├── __init__.py
│       │   └── flows.py
│       └── spc/
│           ├── __init__.py
│           ├── shewhart.py
│           └── hotelling.py
└── tests/

Requirements

  • Python 3.11+
  • For sshtype="ssh": passwordless SSH to root@<host> (non-interactive ssh; see docs/node-control-asyncio-design.md).

Install

First-time / new machine: follow docs/install.md“Bring up systems (new workstation + lab rig)”, then the Workstation and Remote host setup sections.

Full guide (workstation, remote host setup for the Pi, pip install -e, PYTHONPATH=src, scripts/setup_pi_power.sh): docs/install.md.

Minimal editable install from the repo root:

cd ~/Code/FiWiControl
python3 -m pip install -e ".[dev]"
# optional: power / USB discovery (Acroname, Monsoon)
python3 -m pip install -e ".[power]"
# optional: async iperf flows / SPC (see docs/flows.md, docs/spc.md)
python3 -m pip install -e ".[flows]"
python3 -m pip install -e ".[spc]"

Imports:

from fiwicontrol.commands import ssh_node, Command, CommandManager

Tests

After install, use the ordered verification checklist and INI reference in docs/power-control-and-inventory.md (sections “Verification checklist (after install)” and “Lab INI file reference”).

Commands, example pytest output, and unittest entry points for node_control: docs/node-control-asyncio-design.md → section “Running tests” (top-level ## heading near the top of the file).

Whole suite (from repo root; pyproject.toml adds src to PYTHONPATH for pytest):

cd ~/Code/FiWiControl
python3 -m pytest tests/ -q

Example summary when the opt-in live INI test is not enabled ( FIWI_VERIFY_POWER_INI unset — one test skipped):

.....s......................                                                                                          [100%]
27 passed, 1 skipped in 18.20s

Run a single test by id (replace with a name from python3 -m pytest tests/<file>.py --collect-only -q):

python3 -m pytest tests/test_package_layout.py::test_import_subpackages -v

Layout / import smoke (no network):

cd ~/Code/FiWiControl
python3 -m pytest tests/test_package_layout.py -q

Remote integration (needs FIWI_REMOTE_IP and key auth):

cd ~/Code/FiWiControl
FIWI_REMOTE_IP=192.168.1.39 python3 -m pytest tests/test_node_control.py -q

Power / USB inventory (needs brainstem and pyserial, e.g. pip install -e ".[power]"): see docs/power-control-and-inventory.md. Lab layout is configs/default.ini by default (override with -c). configs/clubhouse.ini is an alternate example file.

cd ~/Code/FiWiControl
python3 -m pip install -e ".[power]"
python3 -m fiwicontrol.power --verify-inventory
# or: python3 -m fiwicontrol.power -c configs/clubhouse.ini --verify-inventory

The same check from pytest (set FIWI_VERIFY_POWER_INI=1 or pytest skips the live INI test):

FIWI_VERIFY_POWER_INI=1 python3 -m pytest -q tests/test_inventory_verify_live.py

Remote package sanity (imports + python3 -m fiwicontrol.power --discovery-json) for the host in FIWI_REMOTE_IP (default 192.168.1.39):

python3 -m pytest -q tests/test_remote_power_dependencies.py

Example when SSH and the rig are configured (-v; line spacing may vary):

tests/test_remote_power_dependencies.py::TestRemotePowerDependencies::test_remote_imports_fiwicontrol_power_brainstem_serial PASSED [ 50%]
tests/test_remote_power_dependencies.py::TestRemotePowerDependencies::test_remote_power_module_discovery_json PASSED [100%]

============================== 2 passed in 0.65s ==============================

Remote (Gitea)

git remote add origin "https://git.umbernetworks.com/rjmcmahon/FiWiControl.git"
git push -u origin main

Use a Gitea personal access token as the HTTPS password if prompted.