# duplo-controller Librairie Python minimale pour contrôler un train LEGO DUPLO Bluetooth (Hub n°5) via le protocole LEGO Wireless. ## Fonctionnalités - connexion BLE avec adresse explicite **ou découverte automatique** du hub - avancer / reculer / stop (vitesse `-100..100`) - jouer les sons DUPLO (`brake`, `station_departure`, `water_refill`, `horn`, `steam`) - jouer un tone direct (`0..10`) via `play_tone(...)` - allumer/changer la couleur de la lumière (11 couleurs) - éteindre la lumière (`turn_off_light()`) - script CLI interactif (`duplo-test`) pour tests manuels ## Installation ```bash python -m venv .venv source .venv/bin/activate pip install -e . ``` ## Utilisation rapide ```python import asyncio from duplo_controller import DuploTrainHub, DuploColor, DuploSound async def main(): async with DuploTrainHub() as hub: await hub.forward(50) await asyncio.sleep(2) await hub.stop() await hub.play_sound(DuploSound.HORN) await hub.change_light_color(DuploColor.WHITE) await hub.play_tone(4) await asyncio.sleep(1) await hub.turn_off_light() asyncio.run(main()) ``` ## Script de test manuel ```bash python -m tests.manual_test # ou après installation: duplo-test ``` Options: - `--address XX:XX:XX:XX:XX:XX` pour forcer une adresse BLE - `--speed 50` vitesse par défaut du menu Dans le menu, l'option de couleur supporte : `black`, `pink`, `purple`, `blue`, `lightblue`, `cyan`, `green`, `yellow`, `orange`, `red`, `white`. Dans le menu, l'option son supporte : `brake`, `station_departure`, `water_refill`, `horn`, `steam`. ## API principale - `await hub.connect()` / `await hub.disconnect()` - `await hub.forward(speed=50)` - `await hub.backward(speed=50)` - `await hub.stop()` - `await hub.set_motor_speed(speed)` - `await hub.change_light_color(DuploColor.RED)` - `await hub.turn_off_light()` - `await hub.play_sound(DuploSound.HORN)` - `await hub.play_tone(4)` - `await hub.demo()` ## Intégration pygame (résumé) `DuploTrainHub` est asynchrone (`asyncio`). - Option simple : démarrer une boucle `asyncio` dans un thread dédié et y soumettre les commandes BLE depuis la boucle pygame. - Option avancée : piloter la boucle pygame depuis une coroutine principale `asyncio`. Exemple minimal de pattern (thread + loop asyncio) : ```python import asyncio import threading ble_loop = asyncio.new_event_loop() threading.Thread(target=ble_loop.run_forever, daemon=True).start() hub = DuploTrainHub() asyncio.run_coroutine_threadsafe(hub.connect(), ble_loop).result() # Depuis un event pygame: # asyncio.run_coroutine_threadsafe(hub.forward(60), ble_loop) # À la fin: asyncio.run_coroutine_threadsafe(hub.disconnect(), ble_loop).result() ble_loop.call_soon_threadsafe(ble_loop.stop) ``` ## Notes techniques - Service LEGO Hub: `00001623-1212-efde-1623-785feabcd123` - Characteristic LEGO Hub: `00001624-1212-efde-1623-785feabcd123` - Hub DUPLO détecté via manufacturer data LEGO (`0x0397`) + type `0x20` ## Références - Protocole officiel: https://lego.github.io/lego-ble-wireless-protocol-docs/ - Référence commandes (inspiration): https://github.com/corneliusmunz/legoino