Skip to content
Test Station Setup

Manage Operator Certification

Learn how to track operator training, certification status, and test authorization using TofuPilot properties and station access controls.

JJulien Buteau
intermediate9 min readMarch 14, 2026

How to Manage Operator Certification with TofuPilot

A new operator runs a test wrong and scraps three boards before anyone notices. It happens more than it should. Most teams track operator certification in spreadsheets that go stale the day they're created.

TofuPilot lets you tie operator identity to every test run and enforce certification requirements at the station level.

Why Operator Tracking Matters

Regulated industries require it. ISO 13485 (medical devices), AS9100 (aerospace), and IATF 16949 (automotive) all mandate that operators are trained and qualified for the tasks they perform. But even without regulatory pressure, knowing who ran what test matters when you're debugging a yield drop.

Prerequisites

  • A TofuPilot account
  • Python 3.8+ with tofupilot installed
  • An operator authentication method (badge scan, login, or barcode)

Step 1: Capture Operator Identity on Every Run

The simplest approach is to record the operator as a run property:

operator_tracking.py
from tofupilot import TofuPilotClient

client = TofuPilotClient()

operator_id = input("Scan operator badge: ")

result = client.create_run(
    procedure_id="pcba-fct-v2",
    unit_under_test={
        "serial_number": dut_serial,
        "part_number": "PCB-100-R4",
    },
    run_passed=True,
    properties={
        "operator_id": operator_id,
        "operator_name": get_operator_name(operator_id),
        "station_id": "ST-04",
    },
)

Every run now has an operator attached. You can filter and analyze by operator in the TofuPilot dashboard.

Step 2: Build an Operator Certification Check

Before allowing a test to run, verify the operator is certified for that procedure:

certification_check.py
import json
from pathlib import Path

# Certification data (could also come from an API or database)
CERT_FILE = Path("operator_certs.json")

def load_certifications():
    """Load operator certification records."""
    if CERT_FILE.exists():
        return json.loads(CERT_FILE.read_text())
    return {}

def is_certified(operator_id: str, procedure_id: str) -> bool:
    """Check if operator is certified for a specific test procedure."""
    certs = load_certifications()
    operator = certs.get(operator_id, {})
    procedures = operator.get("certified_procedures", [])
    return procedure_id in procedures

def require_certification(operator_id: str, procedure_id: str):
    """Block test execution if operator isn't certified."""
    if not is_certified(operator_id, procedure_id):
        raise PermissionError(
            f"Operator {operator_id} is not certified for {procedure_id}. "
            f"Contact your line supervisor."
        )

Example certification file:

operator_certs.json
{
  "OP-001": {
    "name": "Jane Chen",
    "certified_procedures": ["pcba-fct-v2", "motor-fct", "burn-in-48h"],
    "certification_date": "2026-01-15",
    "expiry_date": "2027-01-15"
  },
  "OP-002": {
    "name": "Mike Torres",
    "certified_procedures": ["pcba-fct-v2"],
    "certification_date": "2026-02-01",
    "expiry_date": "2027-02-01"
  }
}

Step 3: Integrate with Your Test Sequence

Wire the certification check into your test startup:

certified_test.py
import openhtf as htf
from tofupilot import TofuPilotClient
from certification_check import require_certification

PROCEDURE_ID = "pcba-fct-v2"

def test_start(test):
    """Scan operator badge and verify certification before testing."""
    operator_id = input("Scan operator badge: ")

    # Block uncertified operators
    require_certification(operator_id, PROCEDURE_ID)

    test.state["operator_id"] = operator_id
    test.dut_id = input("Scan DUT serial: ")

def main():
    test = htf.Test(
        functional_tests,
        power_tests,
    )

    test.add_output_callbacks(
        TofuPilotClient().as_openhtf_callback(
            procedure_id=PROCEDURE_ID,
        )
    )

    test.execute(test_start=htf.PhaseDescriptor.wrap(test_start))

Step 4: Track Certification Expiry

Certifications expire. Build a simple check that warns before expiry and blocks after:

cert_expiry.py
from datetime import date, timedelta

def check_certification_status(operator_id: str, procedure_id: str):
    """Check certification validity with advance warning."""
    certs = load_certifications()
    operator = certs.get(operator_id)

    if not operator:
        raise PermissionError(f"Unknown operator: {operator_id}")

    if procedure_id not in operator.get("certified_procedures", []):
        raise PermissionError(
            f"{operator['name']} is not certified for {procedure_id}"
        )

    expiry = date.fromisoformat(operator["expiry_date"])
    today = date.today()

    if today > expiry:
        raise PermissionError(
            f"Certification expired on {expiry}. Recertification required."
        )

    days_remaining = (expiry - today).days
    if days_remaining < 30:
        print(f"WARNING: Certification expires in {days_remaining} days")

    return True

Step 5: Analyze Operator Performance

With operator data on every run, you can answer questions that matter:

  • Yield by operator: Is one operator consistently lower? They might need retraining.
  • Test duration by operator: Slower operators may be following procedures more carefully, or struggling with the equipment.
  • Failure modes by operator: If one operator sees more of a specific failure, check their technique.
operator_analysis.py
from tofupilot import TofuPilotClient
from collections import defaultdict

client = TofuPilotClient()

runs = client.get_runs(
    procedure_id="pcba-fct-v2",
    limit=1000,
)

# Group by operator
operator_stats = defaultdict(lambda: {"pass": 0, "fail": 0})

for run in runs:
    op = run.properties.get("operator_id", "unknown")
    if run.passed:
        operator_stats[op]["pass"] += 1
    else:
        operator_stats[op]["fail"] += 1

for op_id, stats in operator_stats.items():
    total = stats["pass"] + stats["fail"]
    fpy = stats["pass"] / total * 100
    print(f"Operator {op_id}: {fpy:.1f}% FPY ({total} runs)")

Regulatory Compliance Notes

StandardRequirementTofuPilot Solution
ISO 13485Documented training records, competency assessmentOperator ID on every run, certification check
AS9100Personnel qualified for assigned tasksPre-test certification gate
IATF 16949Training effectiveness evaluatedYield-by-operator analysis
FDA 21 CFR 820Personnel training documentedFull audit trail with operator identity

The key is that every test run links back to a certified operator, and that link is immutable in your test history.

More Guides

Put this guide into practice