TofuPilot generates manufacturing KPI dashboards from your test data automatically. You don't need to build reports in Python or connect BI tools for standard metrics. Write well-structured tests, and the dashboards populate themselves.
Key Manufacturing KPIs
These are the metrics that matter on the production floor.
First Pass Yield (FPY) is the percentage of units that pass all tests on the first attempt. It's the single best indicator of process health. TofuPilot calculates FPY per procedure, per station, and across your entire line.
Throughput measures units tested per hour or per shift. It tells you whether your line is hitting capacity targets. Bottlenecks show up as throughput drops on specific stations.
Cpk (Process Capability Index) quantifies how centered your measurements are within spec limits. A Cpk above 1.33 means your process has comfortable margin. Below 1.0 means you're producing out-of-spec parts.
Cycle time is how long each test takes. It's the denominator in throughput and the first thing to optimize when you need more capacity.
Failure rate by step breaks down where failures occur. A Pareto chart of failure modes tells you exactly where to invest engineering effort.
Structuring Tests for Complete KPIs
Every KPI above comes from data your tests already produce. The key is structuring tests so TofuPilot can extract all of it cleanly.
import openhtf as htf
from openhtf.util import units
from tofupilot.openhtf import TofuPilot
@htf.measures(
htf.Measurement("boot_time")
.in_range(maximum=3.0),
htf.Measurement("firmware_version")
.with_allowed_values("2.4.1", "2.4.2"),
)
def firmware_validation(test):
"""Validate firmware boots correctly."""
test.measurements.boot_time = 1.8
test.measurements.firmware_version = "2.4.1"
@htf.measures(
htf.Measurement("battery_voltage")
.with_units(units.VOLT)
.in_range(minimum=3.6, maximum=4.2),
htf.Measurement("charge_current")
.in_range(minimum=0.450, maximum=0.550)
.with_units(units.AMPERE),
htf.Measurement("discharge_capacity")
.in_range(minimum=2800),
)
def battery_test(test):
"""Test battery charging and capacity."""
test.measurements.battery_voltage = 3.95
test.measurements.charge_current = 0.502
test.measurements.discharge_capacity = 3050
@htf.measures(
htf.Measurement("touch_sensitivity_pct")
.in_range(minimum=85.0),
htf.Measurement("display_brightness")
.in_range(minimum=400, maximum=600),
htf.Measurement("pixel_defect_count")
.in_range(maximum=0),
)
def display_and_touch_test(test):
"""Verify display and touchscreen performance."""
test.measurements.touch_sensitivity_pct = 94.2
test.measurements.display_brightness = 520
test.measurements.pixel_defect_count = 0
@htf.measures(
htf.Measurement("speaker_thd_pct")
.in_range(maximum=1.0),
htf.Measurement("microphone_snr")
.in_range(minimum=60.0),
)
def audio_test(test):
"""Test speaker and microphone quality."""
test.measurements.speaker_thd_pct = 0.4
test.measurements.microphone_snr = 68.5
def main():
test = htf.Test(
firmware_validation,
battery_test,
display_and_touch_test,
audio_test,
)
with TofuPilot(test):
test.execute(test_start=lambda: "DEVICE-007")
if __name__ == "__main__":
main()This test gives TofuPilot everything it needs. Numeric measurements with limits feed Cpk calculations. Phase structure feeds step-level failure analysis. Timestamps feed throughput and cycle time. Pass/fail outcomes feed FPY.
What Makes Tests KPI-Ready
Three things make the difference between tests that produce useful dashboards and tests that don't.
Numeric measurements with limits. Every measurement that has in_range() limits gets Cpk tracking, histograms, and control charts. Boolean pass/fail checks are fine for go/no-go tests, but they don't feed the analytics.
Consistent phase names. If you rename a phase, TofuPilot treats it as a new step. Keep names stable so historical comparisons work. Use descriptive names that make sense in a dashboard context.
Unique serial numbers. The DUT ID connects a unit's full test history across stations. Use real serial numbers, not placeholder values. This enables traceability and retest tracking.
Viewing Dashboards in TofuPilot
TofuPilot's dashboard shows your KPIs in real time as test results upload. You'll find:
- FPY trends over time, filterable by procedure, station, or time range
- Throughput charts showing units per hour by station
- Measurement histograms and Cpk values for every numeric measurement
- Failure Pareto charts ranking failure modes by frequency
- Yield gauges for at-a-glance status
Custom dashboards let you combine widgets for specific views. Build a line manager dashboard with FPY and throughput, or an engineering dashboard focused on Cpk and failure analysis.
Keeping Dashboards Accurate
Dashboards are only as good as the data behind them. Run every unit through the test, including units you already know will fail. Skipping known-bad units inflates your FPY.
Use separate procedures for retest vs. first test. This keeps FPY calculations clean while still tracking retest outcomes. TofuPilot handles both and shows them independently.