La plupart des systèmes d'enregistrement en production sont conçus pour l'instant où le test s'exécute. Un opérateur a besoin d'un feu vert ou rouge, le test l'affiche, et la réflexion s'arrête là.
Le problème arrive des mois plus tard. Un client retourne une unité. Une enquête de rendement a besoin d'une référence. Un auditeur demande ce qu'a mesuré un numéro de série précis. À ce moment, tout le monde veut exactement les données que personne n'a enregistrées.
Ce guide liste quoi enregistrer, par ordre de priorité, et signale les champs pénibles à rattraper.
Le minimum qui rend les données utiles
La valeur mesurée, pas seulement le pass/fail.
C'est le champ le plus précieux et le plus souvent oublié. Un booléen dit qu'une unité a échoué. La valeur dit qu'elle mesurait 3,19 V pour une limite à 3,20 V, et qu'elle baissait depuis trois semaines.
Tout en dépend. Courbes de tendance, capabilité, détection de dérive et ajustement des limites sont impossibles à partir de booléens. Si vous n'enregistrez qu'une chose au-delà du verdict, enregistrez le nombre.
Les limites appliquées.
Stockez les limites avec la valeur, pas seulement dans le code de test. Les limites changent, et un résultat enregistré sous les anciennes devient ininterprétable si elles ne l'accompagnent pas.
{ "name": "rail_3v3", "value": 3.31, "unit": "V", "lower_limit": 3.2, "upper_limit": 3.4, "passed": true}Les unités. Peu coûteux, et cela évite la classe d'erreurs où quelqu'un suppose ensuite des millivolts.
Un horodatage, en UTC. Stockez en UTC et convertissez à l'affichage. Sinon deux sites dans deux fuseaux ne s'accorderont pas sur le jour d'une défaillance.
Identité : ce qui a été testé
Numéro de série. Sans lui vous avez des statistiques mais aucune traçabilité.
Référence et révision. Une mesure ne signifie pas la même chose en rev C qu'en rev A. Sans la révision, des données de révisions mélangées se fondent silencieusement en une seule distribution.
Liens de sous-ensembles. Quelle carte dans quel boîtier, quel module dans quel assemblage final. C'est le champ le plus souvent omis et le plus pénible à ajouter après coup, car le rattraper implique de reconstruire des relations jamais capturées.
Modélisez-le dès le premier jour même sans l'utiliser. Quand un lot de composants s'avère défectueux, c'est ce qui vous dit quelles unités expédiées le contiennent.
Contexte : où et comment le test a eu lieu
Ces champs ne coûtent rien au moment du test et sont les dimensions de segmentation d'une enquête.
| Champ | Ce qu'il permet de répondre |
|---|---|
| Identifiant de station | Une station échoue-t-elle plus que les autres ? |
| Opérateur | Une technique de mise en place cause-t-elle des échecs ? |
| Version de procédure | Quelle version des limites a produit ce résultat ? |
| Version de firmware du DUT | Une constante de calibration a-t-elle changé ? |
| Identifiant de montage | Un montage précis s'use-t-il ? |
| Instrument utilisé | Si un multimètre était décalibré, quelles unités a-t-il touchées ? |
L'identifiant de station se rentabilise le plus vite. Une seule requête groupant les échecs par station résout une part surprenante des enquêtes, et elle est impossible sans ce champ.
La version de procédure est l'autre à imposer. Les limites évoluent sur la vie d'un produit. Sans savoir quelle version a produit un résultat, vos données historiques cessent d'être comparables à chaque changement.
Détail d'exécution
Verdicts et durées par étape. Un run en échec en dit moins qu'un run échouant à l'étape 7 après avoir passé 1 à 6. Le niveau étape rend possible l'analyse de Pareto, et les durées révèlent une station qui ralentit.
Pièces jointes quand elles comptent. Une capture de forme d'onde, une photo d'unité en échec, une copie d'écran d'instrument. Pas sur chaque run en volume, mais sur les échecs.
Journaux du script de test. Sortie console, réponses d'instruments, traces d'exception. Peu coûteux sur les échecs, et c'est la différence entre diagnostiquer et deviner.
Ce qu'il ne faut pas enregistrer
La retenue compte, car un stockage qui grossit sans limite finit supprimé en bloc, généralement juste avant qu'on en ait besoin.
Formes d'onde brutes sur chaque unité. Stockez les caractéristiques extraites, temps de montée, dépassement, ondulation, et gardez la capture brute pour les échecs ou un échantillon.
Flux à haute cadence. Si vous acquérez à des centaines d'échantillons par seconde, agrégez avant de stocker. Une plateforme d'enregistrement sert aux résultats, pas à l'acquisition temporelle.
Ce qui est dérivable. Ne stockez pas le rendement comme champ. Calculez-le. Un agrégat stocké devient faux dès qu'un retest arrive.
Les quatre pénibles à rattraper
Tout ce qui précède peut s'ajouter plus tard avec un peu d'effort, sauf ceci :
- La valeur mesurée. Des booléens historiques ne redeviennent pas des nombres. Chaque jour sans cela est un jour de données irrécupérables.
- Les relations de sous-ensembles. Les reconstruire après coup implique de lire des dossiers de fabrication à la main, s'ils existent.
- Le versionnage de procédure. Une fois les limites changées sans marqueur de version, impossible de dire quels résultats sont comparables.
- Les numéros de série des premières unités. Prototypes et présérie sautent souvent la sérialisation, et ce sont précisément les unités qui reviennent avec les défaillances les plus intéressantes.
Un schéma minimal
Si vous stockez dans votre propre base, ceci couvre les champs ci-dessus :
CREATE TABLE unit ( id BIGSERIAL PRIMARY KEY, serial_number TEXT NOT NULL UNIQUE, part_number TEXT NOT NULL, revision TEXT, parent_id BIGINT REFERENCES unit(id), created_at TIMESTAMPTZ NOT NULL DEFAULT now());CREATE TABLE run ( id BIGSERIAL PRIMARY KEY, unit_id BIGINT NOT NULL REFERENCES unit(id), procedure_id TEXT NOT NULL, procedure_version TEXT NOT NULL, station_id TEXT NOT NULL, operator TEXT, dut_firmware TEXT, started_at TIMESTAMPTZ NOT NULL, duration_s NUMERIC NOT NULL, passed BOOLEAN NOT NULL);CREATE TABLE step ( id BIGSERIAL PRIMARY KEY, run_id BIGINT NOT NULL REFERENCES run(id) ON DELETE CASCADE, name TEXT NOT NULL, duration_s NUMERIC, passed BOOLEAN NOT NULL);CREATE TABLE measurement ( id BIGSERIAL PRIMARY KEY, step_id BIGINT NOT NULL REFERENCES step(id) ON DELETE CASCADE, name TEXT NOT NULL, value DOUBLE PRECISION, unit TEXT, lower_limit DOUBLE PRECISION, upper_limit DOUBLE PRECISION, passed BOOLEAN NOT NULL);CREATE INDEX ON run (procedure_id, started_at DESC);CREATE INDEX ON run (station_id, started_at DESC);CREATE INDEX ON measurement (name, step_id);Le parent_id sur unit est le lien de sous-ensemble. C'est une colonne, et l'ajouter maintenant coûte bien moins que reconstruire les relations plus tard.
Le faire sans écrire le schéma
Si vos scripts de test sont en Python, cette structure vient gratuitement. La définition de mesure dans votre code porte déjà le nom, la valeur, les unités et les limites, donc un callback de sortie enregistre tous les champs ci-dessus sans schéma de votre part.
Avec OpenHTF, c'est un import et une ligne :
import openhtf as htffrom openhtf.util import unitsfrom tofupilot.openhtf import upload@htf.measures( htf.Measurement("rail_3v3") .in_range(3.2, 3.4) .with_units(units.VOLT),)def power_rail_test(test): test.measurements.rail_3v3 = 3.31def main(): test = htf.Test( power_rail_test, procedure_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", # UUID de procédure du dashboard part_number="PCBA-200", ) test.add_output_callbacks(upload()) test.execute(lambda: "SN-0001")if __name__ == "__main__": main()Installez-le avec pip install "tofupilot[openhtf]". Le callback upload() lit TOFUPILOT_API_KEY dans l'environnement, et add_output_callbacks est le point d'extension d'OpenHTF lui-même, donc il se compose avec vos callbacks existants.
Peu importe l'outil. Ce qui compte, c'est que la décision de ce qu'on enregistre se prend une fois, tôt, et coûte cher à revoir. Enregistrez la valeur, versionnez la procédure, modélisez les sous-ensembles, gardez l'UTC. Le reste peut attendre.