diff --git a/README.md b/README.md index 4607f86..6d4131b 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ This repository ships that distribution (**`fiwicontrol`** on PyPI / `pip`) with 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. Longer term, **SPC** (below) is meant for **many hot-plug cycles**—spotting drift in failure rates or side metrics—not only general Fi‑Wi bring-up. +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 Fi‑Wi bring-up (see **`docs/spc.md`**). ## Lab fleet: Raspberry Pi 5 and iperf 2 (planned) @@ -32,11 +32,13 @@ Expanded **ush** orchestration alongside OpenSSH—not only the **`ush`** transp ## 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 (eventually) SPC**, not ad hoc throughput screenshots—to help **differentiate** Umber Fi‑Wi products in the market. +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 Fi‑Wi products in the market. -## Statistical process control (planned) +## Statistical process control -The project is intended to grow **statistical process control (SPC)** support—for example **Hotelling**-style multivariate monitoring and **Shewhart** control charts—for lab and field metrics tied to Fi‑Wi rigs (including **high-volume PCIe hot-swap** campaigns where you need to know if the **process** is still in control). That code is **not** in the tree yet; today’s packages focus on automation, inventory, and power/USB control as described above. +**In tree:** **`fiwicontrol.spc`** — **`ShewhartControlChart`** 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** @@ -49,7 +51,8 @@ FiWiControl/ │ ├── install.md │ ├── node-control-asyncio-design.md │ ├── power-control-and-inventory.md -│ └── flows.md +│ ├── flows.md +│ └── spc.md ├── src/ │ └── fiwicontrol/ │ ├── commands/ @@ -96,6 +99,9 @@ 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: diff --git a/docs/install.md b/docs/install.md index e9547c1..a393b6b 100644 --- a/docs/install.md +++ b/docs/install.md @@ -14,7 +14,7 @@ Use this order the first time you (or someone else) joins the project or replace | Step | Where | What to do | |------|--------|------------| | 1 | Workstation | **Clone** this repo and **`cd`** into it. | -| 2 | Workstation | **Python 3.11+** and an **editable install**: **`python3 -m pip install -e ".[dev]"`**, then **`python3 -m pip install -e ".[power]"`** if you use Acroname/Monsoon or remote power tests (see **Workstation** below). | +| 2 | Workstation | **Python 3.11+** and an **editable install**: **`python3 -m pip install -e ".[dev]"`**, then **`python3 -m pip install -e ".[power]"`** if you use Acroname/Monsoon or remote power tests. Add **`".[flows]"`** / **`".[spc]"`** when you use **`fiwicontrol.flows`** or **`fiwicontrol.spc`** (see **Workstation** below and **`docs/flows.md`** / **`docs/spc.md`**). | | 3 | Workstation → rig | **Passwordless SSH as root:** **`ssh -o BatchMode=yes root@192.168.1.39 true`** must exit **0** with no password prompt. On the rig, install your workstation’s **public key** in **`/root/.ssh/authorized_keys`** and ensure **`sshd`** allows **`root`** with pubkey auth. | | 4 | Rig (e.g. Pi) | **`git clone`** the same repo where you will run power/discovery (often **`/root/Code/FiWiControl`**). Your **`--remote-repo`** path must match. | | 5 | Workstation | From your clone, run **`python3 -m fiwicontrol.commands`** with the Pi IP and **`--remote-repo`** (PEP 668 / Raspberry Pi OS needs **`--break-system-packages`** or **`FIWI_REMOTE_PIP_FLAGS`**). See **Remote host setup** below (numbered subsections **3** and **4**: install **`fiwicontrol[power]`** on the rig, then align **`python3`** with **`pip`**). | @@ -48,6 +48,19 @@ Or in one line: python3 -m pip install -e ".[dev,power]" ``` +**Flows** (async **iperf** over SSH, SciPy / Matplotlib stack) and **SPC** (**Shewhart** / **Hotelling** *T*² helpers) are separate optional extras: + +```bash +python3 -m pip install -e ".[flows]" # NumPy, SciPy, Matplotlib — see docs/flows.md +python3 -m pip install -e ".[spc]" # NumPy, SciPy — see docs/spc.md +``` + +Or combined with dev and power: + +```bash +python3 -m pip install -e ".[dev,power,flows,spc]" +``` + **Why this is the default:** you avoid remembering **`PYTHONPATH=src`**, IDEs and **`python -m`** behave predictably, and it matches how **`pyproject.toml`** / **`pytest`** are meant to be used. ### Without a local install (one-off) diff --git a/docs/spc.md b/docs/spc.md new file mode 100644 index 0000000..7d9d1ce --- /dev/null +++ b/docs/spc.md @@ -0,0 +1,55 @@ +# FiWiControl SPC — Shewhart and Hotelling *T*² + +**Package:** **`fiwicontrol.spc`** +**Implementation:** **`src/fiwicontrol/spc/`** (`shewhart.py`, `hotelling.py`; lazy exports from **`fiwicontrol/spc/__init__.py`**) + +Small **statistical process control (SPC)** building blocks for lab metrics: a univariate **Shewhart**-style individuals chart (moving-range dispersion) and a multivariate **Hotelling *T*²** object with a Phase II upper control limit. + +--- + +## Install + +SPC uses **NumPy** and **SciPy** (not bundled in the base **`fiwicontrol`** install): + +```bash +cd ~/Code/FiWiControl +python3 -m pip install -e ".[spc]" +``` + +**`import fiwicontrol.spc`** does not load **NumPy** / **SciPy** until you access **`ShewhartControlChart`** (NumPy only) or **`HotellingT2`** (both). + +--- + +## Classes + +### `ShewhartControlChart` + +- **`ShewhartControlChart(k=3.0)`** — chart width in multiples of estimated sigma. +- **`fit_individuals(x, moving_range_span=2)`** — Phase I fit from a 1-D **`numpy`** array; only **`moving_range_span=2`** is supported (average moving range of consecutive pairs, **`d₂ = 1.128`**). +- **`limits()`** → **`(LCL, center, UCL)`** with width **`k`** sigma (default **`k=3.0`**). +- **`is_out_of_control(value)`** — boolean vs those limits. + +### `HotellingT2` + +- **`fit(X)`** — **`X`** shape **`(m, p)`** with **`m > p + 1`**; unbiased sample covariance, inverse for *T*². +- **`mean_`**, **`covariance_`** — fitted Phase I mean vector and covariance (after **`fit`**). +- **`t2(x)`** — Hotelling statistic for one observation **`x`** of length **`p`** vs the fitted mean. +- **`ucl(alpha=0.05)`** — Phase II UCL using the **`F_{p, m-p}`** distribution (**SciPy**). +- **`is_out_of_control(x, *, alpha=0.05)`** — **`True`** if **`t2(x) > ucl(alpha=alpha)`** (**`alpha`** is keyword-only). + +--- + +## Tests + +With **`[spc]`** installed: + +```bash +python3 -m pytest tests/test_spc.py -q +``` + +--- + +## See also + +- **`README.md`** (package list) +- **`docs/install.md`** (optional **`[spc]`** alongside **`[flows]`**, **`[power]`**, …) diff --git a/src/fiwicontrol/spc/__init__.py b/src/fiwicontrol/spc/__init__.py index 8c19eae..c0adcce 100644 --- a/src/fiwicontrol/spc/__init__.py +++ b/src/fiwicontrol/spc/__init__.py @@ -8,8 +8,9 @@ Install optional dependencies before importing the classes:: pip install -e ".[spc]" -Symbols load lazily so ``import fiwicontrol.spc`` does not import **NumPy** until -you access a class. +Symbols load lazily so ``import fiwicontrol.spc`` does not import **NumPy** or +**SciPy** until you access a class (``ShewhartControlChart`` uses NumPy; +``HotellingT2`` uses both). """ from __future__ import annotations