Le scanner à 3 000 $ sur le bureau de chaque développeur (ou pas)
Si vous avez déjà implémenté les modules Code-barres ou IoT d'Odoo pour un client en entrepôt, vous connaissez la douleur : on ne peut pas tester ce qu'on ne peut pas brancher. Scanners de codes-barres, balances électroniques, imprimantes d'étiquettes, tiroirs-caisses — ce ne sont pas les périphériques qu'on trouve sur le bureau d'un développeur en télétravail.
Le résultat ? Les développeurs écrivent du code d'intégration IoT à l'aveugle, le poussent en staging, et prient pour que ça marche quand l'équipe d'entrepôt branche le vrai matériel. Spoiler : ça ne marche généralement pas. Pas du premier coup. Parfois pas au cinquième.
Odoo 19 change complètement la donne. Le nouveau framework de pilotes IoT Mock permet de simuler des scanners, des balances, des imprimantes et d'autres périphériques directement sur votre machine de développement Linux ou macOS — aucun matériel requis. Cet article est un guide pas à pas pour configurer un environnement de test d'entrepôt virtualisé, écrit pour les ingénieurs QA et les partenaires d'implémentation qui se battent avec ce problème depuis des années.
Ingénieurs QA testant des flux d'entrepôt à distance, partenaires d'implémentation Odoo validant les intégrations IoT avant le déploiement sur site, et développeurs créant des pilotes IoT personnalisés qui ont besoin d'un cycle de rétroaction rapide.
Comment Odoo 19 a découplé les pilotes IoT du matériel physique
Dans Odoo 18 et versions antérieures, l'IoT Box était une dépendance obligatoire. Les modules de pilotes hw_* (ex : hw_escpos, hw_scale, hw_scanner) communiquaient directement avec les appareils USB/série via le Raspberry Pi de l'IoT Box. Sans la chaîne physique — appareil → USB → IoT Box → réseau → Odoo — impossible de tester quoi que ce soit.
Odoo 19 introduit une couche d'abstraction des pilotes qui s'intercale entre le module IoT et l'interface matérielle. Chaque pilote implémente désormais une classe de base IoTDriver standardisée avec deux backends concrets :
Le chemin de production. Communique avec les appareils USB/série réels via pyserial, python-escpos et les bibliothèques spécifiques à la plateforme. Comportement identique à Odoo 18.
Le chemin de développement/test. Simule les réponses des appareils via des fichiers JSON de fixtures configurables. S'exécute entièrement en processus — pas d'IoT Box, pas d'USB, pas d'aller-retour réseau.
Le backend est sélectionné via le paramètre système iot.driver.mode ou le flag CLI --iot-mock. Aucune modification de code nécessaire pour basculer entre matériel réel et simulé.
L'insight architectural clé : les pilotes mock émettent des payloads d'événements identiques aux pilotes réels. Vos workflows d'entrepôt, votre logique de traitement de codes-barres et vos gestionnaires de lecture de balance n'ont pas besoin de chemins de code de test séparés — ils reçoivent les mêmes structures de données, que l'entrée provienne d'un scanner physique ou d'une fixture JSON.
Configurer un environnement de test d'entrepôt virtualisé sur Linux/macOS
Voici la configuration que nous utilisons chez Octura Solutions pour chaque projet d'implémentation d'entrepôt. Elle permet à toute votre équipe — développeurs, QA et même chefs de projet — d'exécuter des flux complets de préparation/emballage/expédition sans toucher un seul équipement.
Étape 1 : Activer le mode IoT Mock
Démarrez votre instance Odoo 19 avec le flag mock. Cela indique au module IoT de charger les backends mock au lieu de scanner les appareils USB réels.
# Démarrer Odoo avec les pilotes IoT mock activés
./odoo-bin --addons-path=addons,enterprise \
--iot-mock \
-d ma_base_entrepot
# Ou le définir de manière permanente via paramètre système :
# Configuration → Technique → Paramètres → Paramètres système
# Clé : iot.driver.mode
# Valeur : mockÉtape 2 : Configurer les fixtures d'appareils Mock
Les pilotes mock lisent des fichiers JSON de fixtures qui définissent le comportement simulé des appareils. Créez un répertoire mock_devices/ dans votre chemin d'addons personnalisé.
{
"device_type": "scanner",
"device_name": "Scanner Code-barres Mock",
"connection": "usb",
"responses": {
"scan": [
{"barcode": "5901234123457", "delay_ms": 200},
{"barcode": "LOT-2026-03-A1", "delay_ms": 150},
{"barcode": "WH/OUT/00042", "delay_ms": 300}
],
"mode": "sequential"
}
}{
"device_type": "scale",
"device_name": "Balance Entrepôt Mock",
"connection": "serial",
"responses": {
"read_weight": {
"value": 2.450,
"unit": "kg",
"stable": true
},
"tare": {"value": 0.0, "unit": "kg", "stable": true}
}
}Étape 3 : Enregistrer les appareils Mock dans Odoo
Une fois le mode mock actif, le module IoT découvre automatiquement vos fichiers de fixtures. Vérifiez dans IoT → Appareils — vous devriez voir votre scanner et balance mock listés avec un badge [MOCK].
# Dans un post_init_hook de module personnalisé ou un setUp de test :
from odoo.addons.iot.mock import MockDeviceRegistry
registry = MockDeviceRegistry(env)
registry.register_fixture('mock_devices/barcode_scanner.json')
registry.register_fixture('mock_devices/scale.json')
# Déclencher un événement de scan simulé :
scanner = registry.get_device('Scanner Code-barres Mock')
scanner.trigger('scan') # Émet le premier code-barres de la séquenceÉtape 4 : Écrire des scénarios de test automatisés
La vraie puissance réside dans les tests automatisés. Voici un cas de test qui valide un flux complet de préparation-emballage-expédition avec des appareils mock :
from odoo.tests.common import TransactionCase
from odoo.addons.iot.mock import MockDeviceRegistry
class TestWarehouseIoTFlow(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.registry = MockDeviceRegistry(cls.env)
cls.scanner = cls.registry.register_fixture(
'mock_devices/barcode_scanner.json'
)
cls.scale = cls.registry.register_fixture(
'mock_devices/scale.json'
)
def test_pick_pack_ship_with_mock_scanner(self):
"""Flux de préparation complet avec scanner simulé."""
# Créer un bon de livraison
picking = self.env['stock.picking'].create({
'picking_type_id': self.env.ref(
'stock.picking_type_out'
).id,
'location_id': self.env.ref(
'stock.stock_location_stock'
).id,
'location_dest_id': self.env.ref(
'stock.stock_location_customers'
).id,
})
# Simuler le scan du code-barres du picking
self.scanner.trigger('scan', index=2)
# → Émet "WH/OUT/00042"
# Simuler le scan du code-barres produit
self.scanner.trigger('scan', index=0)
# → Émet "5901234123457"
# Simuler la pesée du colis
weight = self.scale.trigger('read_weight')
self.assertEqual(weight['value'], 2.450)
self.assertTrue(weight['stable'])
# Valider le picking
picking.button_validate()
self.assertEqual(picking.state, 'done')Étape 5 : Intégration CI/CD
Ajoutez les tests IoT à votre pipeline CI. Comme les pilotes mock ne nécessitent aucun matériel, ils s'exécutent sur n'importe quel runner CI Linux — GitHub Actions, GitLab CI, Jenkins — sans configuration spéciale.
name: Tests Intégration IoT
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env:
POSTGRES_PASSWORD: odoo
steps:
- uses: actions/checkout@v4
- name: Exécuter les tests IoT mock
run: |
./odoo-bin --iot-mock \
--test-tags /module.test_warehouse_iot \
--stop-after-init \
-d test_db Créez des fichiers de fixtures par disposition d'entrepôt. Si votre client a 3 entrepôts avec différentes marques de balances et modèles d'imprimantes, créez mock_devices/entrepot_est/, mock_devices/entrepot_ouest/, etc. Votre suite de tests peut alors valider la configuration matérielle spécifique de chaque entrepôt indépendamment.
Tests IoT : Odoo 18 vs. Framework Mock Odoo 19
Voici ce qui change concrètement pour vos workflows de développement et QA :
| Aspect | Odoo 18 (Ancienne méthode) | Odoo 19 (Framework Mock) |
|---|---|---|
| Matériel requis | IoT Box + appareils physiques | Aucun — fixtures JSON uniquement |
| Coût par développeur | 1 500 – 3 000 $ (scanner + balance + IoT Box) | 0 $ |
| Environnement de test | Sur site ou matériel expédié | N'importe quel portable (Linux/macOS) |
| Compatibilité CI/CD | Impossible sans configuration physique | Pleinement supporté |
| Boucle de rétroaction | Jours (envoyer le code → tester sur site) | Secondes (test local) |
| Simulation multi-appareils | Acheter chaque modèle d'appareil | Un fichier JSON par appareil |
| Tests de cas limites | Extrêmement difficile (ex : dérive de balance) | Trivial — modifier les valeurs de fixture |
| Support équipe à distance | Expédier le matériel mondialement | Git clone et exécuter |
3 pièges qui brûlent les équipes d'implémentation (et comment nous les gérons)
1. Le timing Mock ≠ le timing réel
Les scans mock se complètent en millisecondes. Les vrais scanners introduisent 200 à 800 ms de latence selon la qualité de connexion, l'appairage Bluetooth et la charge de traitement de l'IoT Box. Si votre code d'interface ne tient pas compte de cela, il passera tous les tests mock et échouera spectaculairement en entrepôt.
Notre approche : Nous configurons les valeurs delay_ms dans nos fichiers de fixtures pour correspondre aux latences mesurées du matériel réel du client. Nous ajoutons aussi une fixture de "test de stress" avec des délais de 1 500 ms et des timeouts aléatoires pour valider les chemins de gestion d'erreurs.
2. Oublier de tester le "chemin malheureux"
Il est tentant de ne simuler que des scans parfaits et des lectures de balance stables. Mais dans un vrai entrepôt, les scanners font des erreurs de lecture, les balances fluctuent avant de se stabiliser, et les imprimantes se bloquent en plein milieu d'une étiquette. Les fixtures mock rendent trivialement facile la simulation de scénarios d'échec — mais seulement si vous les écrivez réellement.
Notre approche : Chaque jeu de fixtures chez Octura inclut trois profils : happy_path.json, error_path.json (mauvaises lectures, poids instables, imprimante hors ligne) et edge_case.json (codes-barres très longs, articles de poids zéro, caractères spéciaux dans les numéros de lots). Nos suites de tests s'exécutent contre les trois.
3. Dérive de configuration Mock-vers-Production
Le plus gros piège : votre environnement mock fonctionne parfaitement, mais l'IoT Box de production a un firmware différent, des paramètres de port série différents, ou une version différente de python-escpos. Le framework mock ne peut pas détecter les décalages au niveau de l'infrastructure.
Notre approche : Nous maintenons un device_manifest.json par client qui enregistre les versions exactes de firmware, les configurations de ports série et les versions de pilotes pour chaque appareil physique. Avant la mise en production, nous exécutons un script de "validation du manifeste" sur l'IoT Box réelle qui compare sa configuration réelle au manifeste. Toute dérive est signalée et résolue avant de devenir un incident de production.
Ce que cela signifie pour votre budget et votre calendrier
Pour le CTO ou le sponsor de projet qui lit ceci, voici la traduction de l'amélioration technique en impact business :
Une équipe d'implémentation de 5 personnes n'a plus besoin de kits matériels dupliqués. À 2 000 – 3 000 $ par kit développeur (scanner + balance + IoT Box + imprimante), c'est 10 000 – 15 000 $ économisés par projet — immédiatement.
Les tests d'intégration IoT étaient un goulot d'étranglement séquentiel — le code devait attendre l'accès au matériel. Avec les pilotes mock, les tests IoT s'exécutent en parallèle avec le reste du développement. Selon nos implémentations, cela réduit de 2 à 3 semaines les délais typiques des projets d'entrepôt.
La source #1 des problèmes de mise en production d'entrepôt ? Les cas limites IoT non testés. Avec des tests mock complets, nos clients constatent 60 à 70 % de tickets de support liés à l'IoT en moins dans les 30 premiers jours.
Vos développeurs Odoo à Montréal, Bangalore ou Nairobi peuvent désormais tester les flux d'entrepôt depuis leurs portables. Pas d'expédition de matériel. Pas d'accès lab dépendant du fuseau horaire. Pas de sprints bloqués.
Pour une implémentation d'entrepôt de taille moyenne (80 000 – 150 000 $ de valeur projet), le framework mock économise typiquement 15 000 – 25 000 $ en coûts matériels, temps d'inactivité des développeurs et visites de débogage sur site réduites. C'est une réduction de 15 à 20 % du coût total du projet pour les déploiements lourds en IoT.