Test Station Setup

Gérer plusieurs SKU sur une station

Apprenez à exécuter plusieurs SKU produit sur une seule station de test en utilisant la sélection de phases par configuration, des limites spécifiques par.

JJulien Buteau
intermediate10 min de lecture14 mars 2026

Une station de test, plusieurs produits : configurez votre test OpenHTF pour détecter le SKU au moment de l'exécution, charger les limites et phases spécifiques au SKU depuis un fichier de configuration, et laisser TofuPilot suivre le rendement par numéro de pièce automatiquement.

Pourquoi les stations multi-SKU sont importantes

Exécuter des stations séparées par SKU gaspille de l'espace au sol et des fixtures. Une seule station qui gère une famille de produits réduit :

  • Le nombre de fixtures (lit de clous ou carte à sondes partagés)
  • La formation des opérateurs (un seul flux de travail, pas cinq)
  • La surface de maintenance (une seule station à calibrer)

Méthodes de détection du SKU

MéthodeQuand l'utiliserFiabilité
Scan code-barresÉtiquette scannée par l'opérateur, pas de contact électrique nécessaireÉlevée
Résistance d'identificationLe PCB possède un diviseur résistif codant le SKUMoyenne
EEPROM I2CLe PCB stocke le numéro de pièce dans une mémoire embarquéeÉlevée

Scan code-barres

station/plugs/barcode_plug.py
import openhtf as htfclass BarcodePlug(htf.plugs.BasePlug):    """Lit le SKU depuis le scan de code-barres de l'opérateur."""    def setUp(self):        pass    def scan(self) -> str:        raw = input("Scanner le code-barres : ").strip()        if not raw:            raise ValueError("Scan de code-barres vide")        return raw    def tearDown(self):        pass

Résistance d'identification

station/plugs/resistor_id_plug.py
import openhtf as htf_VOLTAGE_MAP = {    (0.0, 0.4): "SKU-A",    (0.4, 0.8): "SKU-B",    (0.8, 1.2): "SKU-C",    (1.2, 1.6): "SKU-D",}class ResistorIdPlug(htf.plugs.BasePlug):    """Identifie le SKU depuis la tension du diviseur résistif."""    def setUp(self):        pass    def read_sku(self, adc_voltage: float) -> str:        for (low, high), sku in _VOLTAGE_MAP.items():            if low <= adc_voltage < high:                return sku        raise ValueError(f"Tension non reconnue : {adc_voltage:.3f} V")    def tearDown(self):        pass

Sélection de test pilotée par configuration

Stockez les définitions de SKU dans un fichier YAML. Cela sépare les limites de la logique de test.

station/config/skus.yaml
SKU-A:  part_number: "PCB-001-A"  description: "Variante standard 5 V"  phases:    - power_on    - voltage_check    - current_check  limits:    supply_voltage:      min: 4.85      max: 5.15    supply_current:      min: 0.080      max: 0.120SKU-B:  part_number: "PCB-001-B"  description: "Variante basse consommation 3,3 V"  phases:    - power_on    - voltage_check    - current_check    - sleep_current_check  limits:    supply_voltage:      min: 3.2      max: 3.4    supply_current:      min: 0.030      max: 0.060    sleep_current:      min: 0      max: 0.000050

Chargez la configuration au démarrage de la station :

station/config/loader.py
from pathlib import Pathimport yamldef load_sku_config(path: str = "station/config/skus.yaml") -> dict:    config_path = Path(path)    if not config_path.exists():        raise FileNotFoundError(f"Configuration SKU introuvable : {config_path}")    with config_path.open() as f:        return yaml.safe_load(f)

Limites de mesure spécifiques au SKU avec OpenHTF

Utilisez une phase factory pour intégrer les limites spécifiques au SKU dans les mesures OpenHTF :

station/phases/factory.py
import openhtf as htffrom openhtf.util import unitsdef make_voltage_phase(min_v: float, max_v: float):    """Retourne une phase de tension avec des limites intégrées."""    @htf.measures(        htf.Measurement("supply_voltage")        .in_range(minimum=min_v, maximum=max_v)        .with_units(units.VOLT),    )    def voltage_check(test):        test.measurements.supply_voltage = read_voltage()    return voltage_checkdef make_current_phase(min_a: float, max_a: float):    """Retourne une phase de courant avec des limites intégrées."""    @htf.measures(        htf.Measurement("supply_current")        .in_range(minimum=min_a, maximum=max_a)        .with_units(units.AMPERE),    )    def current_check(test):        test.measurements.supply_current = read_current()    return current_check

Exemple complet fonctionnel

station/main.py
import openhtf as htffrom tofupilot.openhtf import TofuPilotfrom station.config.loader import load_sku_configfrom station.phases.factory import make_voltage_phase, make_current_phaseSKU_CONFIG = load_sku_config()def power_on(test):    """Met le DUT sous tension et attend la stabilisation."""    import time    time.sleep(0.5)def run_station():    # 1. Détecter le SKU    sku_id = input("Scanner le code-barres : ").strip()    if sku_id not in SKU_CONFIG:        raise ValueError(f"SKU inconnu '{sku_id}'. Disponibles : {list(SKU_CONFIG)}")    sku = SKU_CONFIG[sku_id]    limits = sku["limits"]    part_number = sku["part_number"]    # 2. Composer les phases depuis la configuration    phases = [power_on]    if "supply_voltage" in limits:        lim = limits["supply_voltage"]        phases.append(make_voltage_phase(lim["min"], lim["max"]))    if "supply_current" in limits:        lim = limits["supply_current"]        phases.append(make_current_phase(lim["min"], lim["max"]))    # 3. Construire et exécuter le test    test = htf.Test(*phases, test_name=f"Station ({sku_id})")    with TofuPilot(test):        test.execute(test_start=lambda: input("Scanner le numéro de série : "))if __name__ == "__main__":    run_station()

Suivi du rendement par SKU dans TofuPilot

TofuPilot regroupe les statistiques de rendement par numéro de pièce. Chaque SKU obtient son propre graphique de rendement sans configuration supplémentaire.

Numéro de pièceSKUExécutionsTaux de réussite
PCB-001-ASKU-A24097,5 %
PCB-001-BSKU-B18094,4 %

Filtrez par numéro de pièce dans le tableau de bord TofuPilot pour comparer les tendances des SKU côte à côte.

Plus de guides

Mettez ce guide en pratique