LabVIEW est puissant, mais il s'accompagne de licences à 3 000-5 000 $/poste, d'un déploiement Windows uniquement et de fichiers binaires mal adaptés au contrôle de version. Python vous offre les mêmes capacités de contrôle d'instruments sans coût de licence, avec un support multiplateforme et une intégration Git native. Ce guide fait correspondre les concepts LabVIEW à leurs équivalents Python et vous montre comment reconstruire votre système de test avec OpenHTF et TofuPilot.
Pourquoi les équipes migrent
| Point de friction | LabVIEW | Python |
|---|---|---|
| Coût de licence | 3 160-4 840 $/poste/an (selon l'édition) | Gratuit |
| Déploiement | Windows uniquement | Linux, macOS, Windows |
| Contrôle de version | Fichiers binaires .vi, conflits de fusion | Fichiers texte, natif Git |
| Recrutement | Les développeurs LabVIEW sont rares et coûteux | Les développeurs Python sont partout |
| CI/CD | Difficile à intégrer | Natif (pytest, GitHub Actions, etc.) |
| Écosystème de packages | Packages NI + communauté limitée | pip, PyPI, 400 000+ packages |
| Revue de code | Nécessite LabVIEW pour visualiser | N'importe quel éditeur de texte |
| Collaboration | Une personne par VI à la fois | Workflow Git standard |
Correspondance des concepts LabVIEW vers Python
| Concept LabVIEW | Équivalent Python | Notes |
|---|---|---|
| VI (Virtual Instrument) | Fonction Python | Même idée : unité réutilisable et appelable |
| SubVI | Fonction ou méthode de classe | Import depuis un module |
| Face-avant | Pas d'équivalent (ou : tableau de bord TofuPilot) | Python n'a pas besoin d'interface graphique par fonction |
| Diagramme | Code Python | Du texte au lieu de fils |
| Panneau de connecteurs | Signature de fonction | def measure_voltage(channel: int) -> float |
| Cluster d'erreur | Gestion d'exceptions | try/except au lieu de fils d'erreur |
| Typedef | Classe ou dataclass | @dataclass pour les données structurées |
| Variable globale | Variable au niveau module ou attribut de classe | À éviter dans la mesure du possible |
| Nœud de propriété | Décorateur property | @property sur une classe |
| Machine d'états | Classe avec méthodes ou match/case | Voir l'exemple ci-dessous |
| Fichier TDMS | JSON, CSV ou TofuPilot | TofuPilot remplace la journalisation fichier |
| Pilote DAQmx | PyVISA + pyvisa-py | Ou package Python nidaqmx |
| Pilote d'instrument | Plug OpenHTF | BasePlug avec setUp/tearDown |
| Séquence de test | Test OpenHTF | htf.Test(phase1, phase2, ...) |
Étape 1 : Configurer votre environnement Python
python -m venv venv
source venv/bin/activate # Linux/macOS
# venv\Scripts\activate # Windows
pip install openhtf tofupilot pyvisa pyvisa-pyCela vous donne :
- openhtf : Framework de test (remplace le séquenceur de test LabVIEW)
- tofupilot : Analyses cloud (remplace la journalisation fichier TDMS)
- pyvisa : Contrôle d'instruments (remplace les pilotes d'instruments LabVIEW)
Étape 2 : Convertir les SubVI en fonctions Python
Un SubVI LabVIEW qui lit la tension d'un DMM devient une fonction Python :
def measure_voltage(channel: int) -> float:
"""Équivalent d'un SubVI LabVIEW qui lit la tension d'un DMM.
En LabVIEW : SubVI avec entrée canal (I32) et sortie tension (DBL).
En Python : fonction avec annotations de type.
"""
readings = {1: 3.31, 2: 5.02, 3: 1.81} # Remplacer par de vraies lectures
return readings.get(channel, 0.0)
# L'appeler comme on câblerait un SubVI
rail_3v3 = measure_voltage(1)
rail_5v0 = measure_voltage(2)La signature de la fonction remplace le panneau de connecteurs. Les annotations de type (int, float) remplacent les types de données LabVIEW.
Étape 3 : Remplacer le cluster d'erreur
LabVIEW utilise un cluster d'erreur (status, code, source) câblé à travers chaque VI. Python utilise les exceptions.
class InstrumentError(Exception):
"""Remplace le cluster d'erreur LabVIEW pour les erreurs d'instrument."""
def __init__(self, code: int, source: str, message: str):
self.code = code
self.source = source
super().__init__(f"[{code}] {source}: {message}")
# LabVIEW : vérifier le cluster d'erreur à chaque nœud
# Python : try/except attrape les erreurs de n'importe où dans le bloc
try:
voltage = measure_voltage(1)
if voltage < 0:
raise InstrumentError(1001, "DMM", "Lecture de tension négative")
except InstrumentError as e:
print(f"Erreur d'instrument : {e}")
# Gérer ou relancerC'est plus propre que de câbler des clusters d'erreur à travers chaque nœud. Les exceptions se propagent automatiquement jusqu'à ce qu'elles soient attrapées.
Étape 4 : Remplacer la machine d'états
Les machines d'états LabVIEW utilisent une boucle while + structure case. Python offre plusieurs options.
class TestSequencer:
"""Remplace une machine d'états LabVIEW pour le séquencement de tests."""
def __init__(self):
self.results = {}
self.state = "init"
def run_step(self, name: str, func, limits: tuple) -> bool:
"""Exécuter une étape de test et enregistrer le résultat."""
value = func()
passed = limits[0] <= value <= limits[1]
self.results[name] = {
"value": value,
"limits": limits,
"passed": passed,
}
return passed
def run(self):
"""Exécuter la séquence de test complète."""
self.run_step("rail_3v3", lambda: 3.31, (3.2, 3.4))
self.run_step("rail_5v0", lambda: 5.02, (4.8, 5.2))
all_passed = all(r["passed"] for r in self.results.values())
return all_passed
seq = TestSequencer()
passed = seq.run()
print(f"Test {'RÉUSSI' if passed else 'ÉCHOUÉ'}")Mais vous n'avez pas besoin de construire cela vous-même. OpenHTF gère le séquencement, les mesures et les limites nativement.
Étape 5 : Utiliser OpenHTF au lieu de construire un séquenceur
OpenHTF remplace à la fois le séquenceur de test LabVIEW et la journalisation des données (TDMS). Les pilotes d'instruments deviennent des Plugs.
import openhtf as htf
from openhtf.plugs import BasePlug
from openhtf.util import units
from tofupilot.openhtf import TofuPilot
class InstrumentPlug(BasePlug):
"""Remplace les VI de pilote d'instrument LabVIEW.
setUp = équivalent de l'ouverture d'une session VISA dans LabVIEW
méthodes = équivalent des SubVI pour chaque mesure
tearDown = équivalent de la fermeture de session
"""
def setUp(self):
self._voltages = iter([3.31, 5.02])
# Remplacer par : rm = pyvisa.ResourceManager("@py")
# self.instr = rm.open_resource("TCPIP::192.168.1.100::INSTR")
def read_voltage(self) -> float:
return next(self._voltages)
# Remplacer par : return float(self.instr.query(":MEAS:VOLT:DC?"))
def tearDown(self):
pass
# Remplacer par : self.instr.close()
@htf.measures(
htf.Measurement("rail_3v3")
.in_range(3.2, 3.4)
.with_units(units.VOLT)
.doc("Rail 3,3 V"),
htf.Measurement("rail_5v0")
.in_range(4.8, 5.2)
.with_units(units.VOLT)
.doc("Rail 5,0 V"),
)
@htf.plug(instr=InstrumentPlug)
def test_power_rails(test, instr):
"""Remplace une séquence de test LabVIEW avec des Numeric Limit Tests."""
test.measurements.rail_3v3 = instr.read_voltage()
test.measurements.rail_5v0 = instr.read_voltage()
def main():
test = htf.Test(
test_power_rails,
procedure_id="FCT-001",
part_number="PCBA-100",
)
with TofuPilot(test):
test.execute(test_start=lambda: input("Scanner le numéro de série : "))
if __name__ == "__main__":
main()Étape 6 : Remplacer TDMS par TofuPilot
LabVIEW écrit les données de test dans des fichiers TDMS. Vous devez ensuite construire vos propres outils d'analyse pour les lire. TofuPilot remplace l'ensemble de cette chaîne.
| LabVIEW (TDMS) | TofuPilot |
|---|---|
| Écrire un fichier TDMS après chaque test | Upload automatique (une ligne de code) |
| Construire des outils d'analyse personnalisés | Tableau de bord avec FPY, Cpk, cartes de contrôle |
| Agrégation manuelle des données entre postes | Agrégation multi-postes automatique |
| Serveur de fichiers pour le stockage TDMS | Stockage cloud avec accès API |
| Génération de rapports personnalisés | Rapports et exports intégrés |
Checklist de migration
| Étape | Action | Équivalent LabVIEW |
|---|---|---|
| 1 | Installer Python + venv | Installer LabVIEW |
| 2 | pip install openhtf tofupilot pyvisa | Installer les packages NI |
| 3 | Créer des classes Plug pour chaque instrument | Créer les VI de pilote d'instrument |
| 4 | Écrire les fonctions de phase avec @htf.measures | Créer la séquence de test avec vérification des limites |
| 5 | Assembler htf.Test() avec toutes les phases | Construire la séquence de test dans LabVIEW |
| 6 | Ajouter with TofuPilot(test) | Configurer la journalisation TDMS |
| 7 | Exécuter et valider que les résultats concordent avec LabVIEW | Comparer les valeurs de mesure |
Pièges courants
| Piège | Solution |
|---|---|
| « La face-avant me manque » | Utilisez le tableau de bord TofuPilot pour le suivi en temps réel. Pour l'interface opérateur, OpenHTF a une interface web intégrée. |
| « Mon matériel NI nécessite des pilotes NI » | Utilisez le package Python nidaqmx pour le matériel DAQmx. Pour GPIB, installez le runtime NI-VISA. |
| « LabVIEW gère le threading automatiquement » | Python a le threading et asyncio. OpenHTF gère le threading d'exécution des phases. |
| « Mon équipe ne connaît pas Python » | Python a une courbe d'apprentissage plus douce que LabVIEW. La plupart des ingénieurs l'apprennent en jours, pas en semaines. |
| « Nous avons des années de code LabVIEW » | Migrez de manière incrémentale. Commencez par les nouveaux tests en Python. Convertissez les tests existants un par un. |