TofuPilot associe chaque exécution de test à une station nommée. En encodant la ligne, l'usine et l'équipe dans le nom de la station et les métadonnées de l'exécution, vous obtenez une surface de requête unique qui couvre chaque ligne de production et chaque usine sans outillage personnalisé.
Pourquoi la traçabilité multi-lignes est importante
Quand un défaut PCBA apparaît sur le terrain, vous devez répondre rapidement à trois questions :
- Quelle ligne de production a fabriqué les unités concernées ?
- Quelle équipe était en service à ce moment-là ?
- La défaillance est-elle isolée à une station ou systémique sur une ligne ?
Sans métadonnées structurées sur chaque exécution, répondre à ces questions nécessite de recouper manuellement les journaux d'opérateurs, les plannings d'équipes et les exports CSV de tests. TofuPilot résout ce problème en faisant de l'identité de la station et des métadonnées de l'exécution des champs de premier ordre sur chaque enregistrement de test.
| Sans métadonnées structurées | Avec les métadonnées de station et d'exécution TofuPilot |
|---|---|
| Recoupement manuel des journaux | Filtre unique dans le tableau de bord |
| Données d'équipe dans des tableurs | Encodées dans l'exécution au moment du test |
| Fichiers d'export par ligne | Requête API unifiée |
| Comparaison de rendement dans Excel | Graphique de rendement par station intégré |
Prérequis
- Python 3.9+
- OpenHTF installé (
pip install openhtf) - Client TofuPilot installé (
pip install tofupilot) - Un compte TofuPilot avec au moins une procédure créée
Configurer l'identité de la station dans TofuPilot
Chaque station de test physique correspond à une station nommée dans TofuPilot. La convention de nommage porte tout le contexte de traçabilité nécessaire.
Convention de nommage des stations
Utilisez un nom structuré qui encode l'usine, la ligne et le numéro de station :
{USINE}-{LIGNE}-FCT{NUMÉRO_STATION}
Exemples :
| Nom de station | Usine | Ligne | Station |
|---|---|---|---|
SZX-L1-FCT01 | Shenzhen | Ligne 1 | Station FCT 1 |
SZX-L2-FCT01 | Shenzhen | Ligne 2 | Station FCT 1 |
TXL-L1-FCT01 | Toulouse | Ligne 1 | Station FCT 1 |
TXL-L1-FCT02 | Toulouse | Ligne 1 | Station FCT 2 |
Configuration de la station par variables d'environnement
Stockez l'identité de la station dans les variables d'environnement de chaque machine, pas dans le script de test :
TOFUPILOT_API_KEY=tp_station_xxxxxxxxxxxxx
STATION_ID=SZX-L1-FCT01
FACTORY=SZX
LINE=L1Chargez-les dans votre script de test au moment de l'exécution :
import os
STATION_ID = os.environ["STATION_ID"]
FACTORY = os.environ["FACTORY"]
LINE = os.environ["LINE"]Cette approche signifie que le même binaire de script de test se déploie sur chaque station. Seul l'environnement diffère.
Étiqueter les exécutions avec les métadonnées de ligne, usine et équipe
Déterminer l'équipe en cours
from datetime import datetime
def get_current_shift() -> str:
"""Retourne le libellé de l'équipe selon l'heure locale."""
hour = datetime.now().hour
if 6 <= hour < 14:
return "morning"
elif 14 <= hour < 22:
return "afternoon"
else:
return "night"Test OpenHTF complet avec métadonnées de station
Cet exemple teste une carte d'alimentation PCBA. L'identité de la station, la ligne, l'usine et l'équipe sont injectées au moment de l'initialisation du test et jointes à chaque exécution.
import os
import openhtf as htf
from openhtf.util import units
from tofupilot.openhtf import TofuPilot
import config
from shift import get_current_shift
class PowerSupplyPlug(htf.plugs.BasePlug):
"""Contrôle l'alimentation de banc via USB-série."""
def setUp(self):
import serial
self._port = serial.Serial("/dev/ttyUSB0", 9600, timeout=1)
def set_voltage(self, volts: float, channel: int = 1):
self._port.write(f":APPL CH{channel},{volts},1.0
".encode())
def measure_voltage(self, channel: int = 1) -> float:
self._port.write(f":MEAS:VOLT? CH{channel}
".encode())
return float(self._port.readline().strip())
def tearDown(self):
self._port.close()
@htf.plug(psu=PowerSupplyPlug)
@htf.measures(
htf.Measurement("rail_3v3")
.in_range(minimum=3.235, maximum=3.365)
.with_units(units.VOLT)
.doc("Rail 3,3V sous charge de 100 mA"),
htf.Measurement("rail_5v0")
.in_range(minimum=4.900, maximum=5.100)
.with_units(units.VOLT)
.doc("Rail 5,0V sous charge de 200 mA"),
)
def test_power_rails(test, psu):
psu.set_voltage(3.3, channel=1)
test.measurements.rail_3v3 = psu.measure_voltage(channel=1)
psu.set_voltage(5.0, channel=2)
test.measurements.rail_5v0 = psu.measure_voltage(channel=2)
@htf.plug(psu=PowerSupplyPlug)
@htf.measures(
htf.Measurement("idle_current")
.in_range(minimum=0, maximum=0.350)
.with_units(units.AMPERE)
.doc("Consommation totale de la carte au repos"),
)
def test_idle_current(test, psu):
psu.set_voltage(5.0, channel=2)
current_a = float(psu._port.readline().strip())
test.measurements.idle_current = current_a
def main():
serial_number = input("Scanner le numéro de série du DUT : ").strip()
test = htf.Test(
test_power_rails,
test_idle_current,
procedure_id="PCBA-FCT-001",
)
with TofuPilot(test):
test.execute(test_start=lambda: serial_number)
if __name__ == "__main__":
main()Chaque exécution dans TofuPilot porte l'identité de la station comme métadonnée interrogeable aux côtés du résultat pass/fail standard et des mesures.
Comparer les résultats entre les lignes dans TofuPilot
Avec les exécutions envoyées depuis toutes les lignes, le filtrage et l'analytique de TofuPilot vous donnent une comparaison directe :
- FPY par station affiche le rendement pour chaque station regroupée par préfixe de ligne. Si la Ligne B est systématiquement en retard par rapport à la Ligne A, le problème est systémique à cette ligne.
- Les histogrammes de mesures révèlent si les valeurs d'une ligne sont décalées ou ont une dispersion plus large. Une moyenne décalée suggère un décalage de calibration.
- Le Pareto des défaillances par station montre quels tests spécifiques échouent le plus souvent sur chaque station. Si une station concentre la majorité des défaillances, commencez l'investigation sur ce montage.
- Les graphiques de tendance montrent si les écarts de rendement sont constants, croissants, ou sont apparus soudainement après un changement.
Investiguer les écarts de rendement
Quand vous trouvez un écart de rendement entre les lignes, cernez la cause de manière systématique :
- Vérifiez les distributions de mesures. Si les valeurs d'une ligne sont décalées, c'est probablement la calibration ou l'équipement. Si elles sont plus dispersées, c'est de la variation de processus.
- Vérifiez par tranche horaire. Des baisses de rendement en équipe de nuit pointent vers la formation des opérateurs ou des changements environnementaux.
- Vérifiez par station individuelle. Parfois le problème de « ligne » est en fait une mauvaise station qui tire la moyenne vers le bas.
- Vérifiez par lot de composants. Si vous suivez les numéros de lot comme métadonnées, filtrez par lot pour voir si des lots spécifiques provoquent la différence.
Une station avec un FPY inférieur à 95% alors que les stations voisines sont à 97-98% indique typiquement un problème de contact du montage, une dégradation de câble ou une dérive de calibration.
Liste de contrôle de déploiement
| Étape | Action |
|---|---|
| Nommage des stations | Suivre la convention {USINE}-{LIGNE}-FCT{N} |
| Clés API | Une clé par station, stockée dans l'environnement |
| Identifiant de procédure | Même identifiant sur toutes les lignes pour une vue de rendement unifiée |
| Tableau de bord | Vérifier que les noms de station apparaissent dès la première exécution avant le déploiement complet |