I. ARCHITECTURE GLOBALE ET FLUX DE CONTRÔLE 🏗️
Le système est conçu selon une architecture modulaire Orchestrateur-Contrôleurs-Matériel. L’Orchestrateur (chrono1.py) est le point d’entrée qui lit un fichier de chronologie et maintient l’état du système (Veille/Événement).
1. Structure des Répertoires
Le bon fonctionnement dépend d’une structure de fichiers précise :
mp3/: Fichiers audio d’ambiance pour le mode Veille.json_screen0/: Fichiers de définition des vidéos/effets de Veille pour l’écran 0.json_screen1/: Fichiers de définition des vidéos/effets de Veille pour l’écran 1.json_evenements/: Fichiers de définition des événements programmés.chronologie.txt: Fichier maître définissant l’heure de déclenchement des événements.
2. Flux de Données Principal
- Orchestrator (
chrono1.py) : Démarre le Mode Veille par défaut. - Mode Veille : Lance
AudioPlayerpour l’ambiance et des threads pour chaque écran viaMultiPlayerManager. - Surveillance : L’Orchestrateur vérifie
chronologie.txtà chaque minute pour un événement. - Événement : Si l’heure correspond, l’Orchestrateur arrête la Veille et demande à
MultiPlayerManagerde lancer l’événement JSON. VideoPlayer: Charge le JSON, démarre la vidéo MPV sur l’écran cible et lance le thread de synchronisation.- Synchronisation : Le thread de synchronisation envoie les commandes à
EffectControllerau milliseconde près. EffectController: Traduit les instructions JSON en commandes série et les envoie viaArduinoController.ArduinoController: Gère la communication série avec le Firmware Arduino (noel2025_83.ino).- Firmware : Reçoit, interprète les commandes, et contrôle physiquement les LEDs et les moteurs.
II. GESTION DES EFFETS PHYSIQUES ET PROTOCOLE SÉRIE
1. arduinocontroller.py (Couche de Communication Basse)
Classe ArduinoController
Cette classe gère l’aspect le plus critique : la stabilité et l’intégrité de la communication série.
- Synchronisation : Utilise un
threading.Lockpour s’assurer qu’une seule commande est envoyée et qu’une seule réponse est attendue à la fois, évitant la corruption des messages. - Identification :
self.msg_idest incrémenté pour chaque requête. Ce numéro est inclus dans l’envoi et sert à vérifier que l’Arduino répond bien à la dernière commande envoyée. - Méthodes :
send_and_wait(cmd): Bloquant. Utilisé pour les commandes nécessitant un retour immédiat de l’ID d’effet (ex:START_EFFECT). Gère un timeout pour éviter le blocage perpétuel.send_no_wait(cmd): Non bloquant. Utilisé pour des commandes moins critiques (ex: réglage de la luminosité).
Protocole de Messages Détaillé
| Direction | Format | Composants | Description |
| Python → Arduino | ID_MSG,CMD_CODE,PARAM1,...<LF> | ID_MSG (int), CMD_CODE (int), PARAMx (int/str) | Commande à exécuter. |
| Arduino → Python | ID_MSG,CODE_RETOUR,VALEUR<LF> | ID_MSG (int), CODE_RETOUR (str: OK ou ER), VALEUR (int/str) | Réponse de l’Arduino. |
2. effectcontroller.py (Couche d’Abstraction des Effets)
Classe EffectController
Elle fait le pont entre le JSON de l’utilisateur (logique) et le protocole série (technique).
- Conversion de Couleurs : La méthode
cv_color(value)convertit les noms de couleurs prédéfinis (rouge,bleu,blanc, etc.) ou les chaînes hexadécimales (#FF0000) en un triplet de valeurs RGB (0-255) nécessaire à l’Arduino. - Parsing de Description : La méthode
_parse_description(effect)analyse le champ multilignedescriptiondu JSON, qui contient les paramètres de l’effet sous la formeclé=valeur, et le structure en dictionnaire. - Logique de Commande :
start_effectconstruit la chaîne de commande en remplaçant les clés de couleur par leurs triplets RGB (ex:couleur=rougedevient255,0,0,). Elle gère aussi la logiquecode_endqui définit quelle commande sera envoyée pour arrêter l’effet. - Gestion des IDs : Maintient un mapping interne (
self.active_effects) entre son propre ID incrémentiel (self.id_effect) et la commande d’arrêt (code_end) pour pouvoir arrêter l’effet correctement.
3. noel2025_83.ino (Firmware Arduino) 💡
Gestion des Commandes (Fonction processCmd)
- La fonction
processCmdreçoit la chaîne série, la découpe en jetons (tokens) viastrtok, et vérifie la validité du format (nombre de jetons, numéro de ruban, etc.). - Le CMD_CODE reçu oriente vers la fonction d’exécution appropriée (
processStripCmdpour les LEDs,processMotorCmdpour les moteurs).
Commandes Clés Implémentées :
| Code | Commande | Description |
| 0 | STOP_EFFECT | Arrête l’effet identifié par son ID. |
| 1 | START_EFFECT | Démarre l’un des nombreux effets (STROBE, RAINBOW, COLOR, FIRE, SNOW, SMOKE) sur un ruban LED spécifique. |
| 10 | START_MOTOR | Démarre le mouvement d’un moteur pas à pas sur un nombre de pas ou un angle donné. |
| 11 | STOP_MOTOR | Arrête immédiatement un moteur en mouvement. |
| 12 | SET_BRIGHTNESS | Ajuste la luminosité globale d’un ruban LED. |
| 13 | RESET_MOTORS | Remet les moteurs à leur position initiale/zéro. |
III. CONTRÔLEURS MULTIMÉDIA
1. videocontroller.py (Synchronisation Vidéo/Effets)
Classe VideoPlayer
Elle est responsable de la lecture d’une seule vidéo et de la synchronisation de ses effets associés.
- Géométrie d’Affichage : Utilise la librairie
screeninfopour déterminer les coordonnées (WxH+X+Y) de l’écran cible (self.screen_id) et force MPV à s’y afficher via l’argument--geometry. - Mécanisme de Lecture : Utilise MPV comme lecteur vidéo, lancé en sous-processus via
subprocess.Popen. - Synchronisation par Horloge Monotonique :
- Contrairement aux méthodes classiques de lecture du temps vidéo (souvent instables), la synchronisation utilise le temps système écoulé (
time.monotonic()) depuis le lancement du processus MPV (self.start_time_monotonic). - La méthode
_playback_loop(exécutée dans un thread) vérifie à chaque itération (toutes les 20 ms) si lecurrent_time_msatteint lestart_timeou leend_timede tout effet planifié. - Ordonnancement des Effets : Les effets sont triés par
start_timedans le JSON, et un index (self.next_effect_index) permet de traiter uniquement les effets à venir, optimisant la boucle.
- Contrairement aux méthodes classiques de lecture du temps vidéo (souvent instables), la synchronisation utilise le temps système écoulé (
2. audiocontroller.py (Gestion des Ambiances)
Classe AudioPlayer
Gère spécifiquement les ambiances sonores pour le Mode Veille, distinctes de l’audio des vidéos.
- MPV en Mode IPC : MPV est lancé avec l’option
--input-ipc-server=<socket_path>pour permettre le contrôle externe via un socket. - Lecture Aléatoire : La logique de
play_randomgarantit qu’un fichier audio ne soit pas rejoué immédiatement après sa lecture (self.played_files). - Fondu Audio (
fade_out_and_stop) :- Utilise un thread séparé (
_run_fade_out). - Envoie des commandes JSON de réglage de volume progressif au socket IPC de MPV, créant un fondu audio en douceur.
- Une fois le volume à zéro, le processus MPV est terminé.
- Utilise un thread séparé (
3. multiplayermanager.py (Gestionnaire d’Écrans)
Classe MultiPlayerManager
C’est le point central pour adresser les commandes aux bons lecteurs.
- Elle instancie et stocke deux objets
VideoPlayer(pourscreen_id=0etscreen_id=1). - Les méthodes
play_videoetstop_videone font que déléguer les actions auVideoPlayercorrespondant dans le dictionnaireself.players.
IV. ORCHESTRATEUR ET CHRONOLOGIE (chrono1.py)
Classe Orchestrator
Le chef d’orchestre du système, il gère les états (Veille / Événement) et le temps.
1. Gestion de la Chronologie
- Structure
Event: Simple classe contenant l’heure (datetime.time), le fichier JSON, le mode de gestion du son (sound_mode: « stop » ou « sound »), et l’écran cible. Le drapeauhas_played_todayest essentiel pour ne pas redéclencher un événement une fois qu’il est passé pour la journée. _load_timeline(): Charge et trie les événements à partir du fichierchronologie.txt.
2. Logique du Mode Veille
start_idle_loop(): Démarre les ambiances sonores et lance deux threads de veille vidéo (_play_idle_video), un pour chaque écran. Ces threads tournent en boucle._play_idle_video:- Sélectionne une vidéo JSON aléatoire dans le répertoire de veille (
json_screenX/). - Lance la vidéo via
MultiPlayerManager. - Bloque le thread tant que la vidéo est en cours de lecture (
player.playback_done.wait()), puis boucle sur une nouvelle vidéo.
- Sélectionne une vidéo JSON aléatoire dans le répertoire de veille (
3. Logique d’Événement Programmé
main_loop(): La boucle principale, exécutée en permanence :- Vérifie l’heure et recherche l’événement non joué le plus proche.
- Déclenchement : Si un événement doit se produire (
event.time <= now), il exécuteprocess_event.
process_event(event):- Arrêt de la Veille : Arrête les vidéos de veille en cours sur tous les écrans.
- Gestion Audio : Si
sound_modeest « stop », il lance un fondu audio viaAudioPlayer.fade_out_and_stop(). - Exécution : Lance la vidéo/effets de l’événement (
MultiPlayerManager.play_video). - Attente : Bloque jusqu’à la fin de l’événement (
player.playback_done.wait()). - Relance : Après la fin, remet le drapeau
has_played_todayà Vrai et relance le mode veille (start_idle_loop()).
4. Fichier Chronologie (chronologie.txt)
- Chaque ligne est essentielle pour l’automatisation.
- Exemple
| Champ | Description | Exemple |
| Heure | Format HH:MM | 14:30 |
| JSON | Nom du fichier JSON dans json_evenements/ | grande_scene.json |
| Mode Son | sound ou nosound | sound |
| Écran ID | Écran cible de la vidéo principale (0 ou 1) | 0 |
CONCLUSION : AMÉLIORATIONS ET EXTENSIONS POTENTIELLES 🚀
Ce système d’orchestration démontre une architecture solide, basée sur une séparation claire des responsabilités (Orchestrateur, Contrôleurs, Matériel) et l’utilisation de méthodes de synchronisation fiables (horloge monotone pour la vidéo, communication série verrouillée).
Afin de garantir une robustesse accrue, une meilleure maintenabilité et d’ouvrir la porte à des fonctionnalités étendues, plusieurs axes d’amélioration et d’extension peuvent être envisagés.
I. AXES D’AMÉLIORATION DU SYSTÈME EXISTANT
1. Amélioration de la Communication Série (Robustesse)
Le modèle actuel send_and_wait dans arduinocontroller.py est synchrone et peut potentiellement bloquer le thread de l’Orchestrateur si l’Arduino tarde à répondre ou si le message est perdu.
- Implémentation Asynchrone : Mettre en place un thread de surveillance série (Serial Watcher) dédié qui lit les réponses de l’Arduino en permanence, les stocke dans une file d’attente (queue), et les associe au
msg_idcorrespondant. Lesend_and_waitpourrait alors devenir non bloquant, lisant la file au lieu d’attendre la ligne sur le port série, augmentant la résilience du système aux latences. - Gestion des Erreurs : Dans le firmware Arduino, développer des codes de retour d’erreur plus granulaires pour diagnostiquer rapidement les problèmes matériels (ex: court-circuit LED, moteur bloqué).
2. Optimisation de la Synchronisation Vidéo
La boucle de lecture dans videocontroller.py effectue un polling intensif (toutes les 20 ms) basé sur le temps système (time.monotonic()).
- Fréquence de Polling Dynamique : Ajuster la fréquence de
time.sleep()de manière dynamique. Si le prochain événement est dans plus d’une seconde, le thread pourrait ralentir sa vérification (ex: 100 ms) et n’accélérer (20 ms) que lorsque l’événement est imminent. - API de Lecteur Avancée : Si le lecteur MPV est remplacé par une librairie vidéo Python intégrée (ex: OpenCV, Pyglet), il serait possible d’attacher des callbacks directement aux événements de l’horloge vidéo, éliminant la nécessité du polling manuel.
3. Centralisation et Facilité de Configuration
Les chemins des répertoires et les configurations de base (port série, écrans) sont actuellement codés en dur au début de chrono1.py.
- Fichier de Configuration Externe : Migrer toutes les constantes du système (chemins,
baudrate,screen_ids,timeout) vers un unique fichier de configuration (par exemple, YAML ou JSON) lu au démarrage. Cela rend le déploiement et la maintenance beaucoup plus simples sans modification du code Python. - Noms d’Écran Logiques : Dans le fichier de configuration, associer l’ID d’écran physique (0, 1) à un nom logique (ex:
Ecran_Principal,Ecran_Ambiance) pour une meilleure lisibilité du code et de la chronologie.
II. EXTENSIONS FONCTIONNELLES POSSIBLES
1. Interface de Contrôle Utilisateur (HMI)
Le système est actuellement en mode « boîte noire » (entièrement automatisé).
- Interface Web (API REST/Flask) : Développer une interface Web légère pour :
- Monitoring : Afficher l’état du système (Mode Veille/Événement, événement en cours, statut de l’Arduino).
- Déclenchement Manuel : Permettre le lancement d’un événement (fichier JSON) manuellement, à la demande, ou le basculement forcé en mode Veille.
- Contrôle en Temps Réel : Ajouter une fonction pour envoyer directement des commandes à l’Arduino (ex:
SET_BRIGHTNESS 50sur le ruban 1) pour des ajustements en direct.
2. Gestion de Chronologie Avancée
La chronologie actuelle est statique et basée uniquement sur l’heure du jour.
- Règles de Récurrence (CRON-like) : Ajouter la possibilité de définir des événements basés sur le jour de la semaine (ex: événement spécial uniquement le week-end) ou des dates spécifiques (ex: du 1er au 24 décembre).
- Événements Conditionnels : Permettre le déclenchement d’un événement non pas à une heure fixe, mais après une condition externe (ex: « Déclencher l’événement ‘bienvenue.json’ après 10 itérations de vidéos de Veille »).
3. Extension du Matériel et des Contrôleurs
Le système est limité à une seule carte Arduino et des rubans LED/moteurs pas à pas locaux.
- Réseau d’Effets Distribués (OSC/MQTT) : Utiliser des protocoles réseau légers comme OSC (Open Sound Control) ou MQTT (Message Queuing Telemetry Transport) pour remplacer la communication série. Cela permettrait de déporter le contrôle vers plusieurs microcontrôleurs (ESP32, Raspberry Pi Pico) distants, augmentant le nombre d’effets et la portée de l’installation.
- Intégration d’Entrées : Ajouter la gestion de capteurs externes (boutons, capteurs de mouvement, capteurs de distance) pour que le système puisse réagir à l’environnement et passer du mode Veille à un événement interactif.
En adoptant ces améliorations, le système passerait d’un simple orchestrateur basé sur le temps à une plateforme d’automatisation interactive, distribuée et hautement résiliente.
Voici la liste des fichiers qui ont été chargés et l’inventaire des dépendances logicielles et des bibliothèques Python nécessaires au bon fonctionnement de l’ensemble du système.
I. LISTE DES FICHIERS disponibles dans orchestrator.zip 📂
Les scripts suivants ont été analysés pour la rédaction de la documentation :
noel2025_83.ino: Le firmware (code) pour la carte Arduino, gérant le contrôle direct des rubans LED et des moteurs pas à pas.arduinocontroller.py: La classe Python de bas niveau pour la gestion de la connexion et du protocole de communication série avec l’Arduino.effectcontroller.py: La classe Python qui sert d’interface de haut niveau, traduisant les descriptions d’effets (issues du JSON) en commandes série structurées pour l’Arduino.audiocontroller.py: La classe Python qui gère la lecture des ambiances sonores MP3 via un lecteur externe (MPV).videocontroller.py: La classe Python qui gère la lecture d’une vidéo sur un écran spécifique et la synchronisation temporelle des effets (lancement/arrêt).multiplayermanager.py: La classe Python qui orchestre et gère les instances deVideoPlayerpour les différents écrans.chrono1.py: Le script Python principal (Orchestrateur) qui lit la chronologie, bascule entre le mode Veille et le mode Événement.
II. REQUIREMENTS ET DÉPENDANCES NÉCESSAIRES (Écosystème Python et Exécutables) ⚙️
Le projet repose sur un mélange de bibliothèques Python et de logiciels exécutables externes qui doivent être installés sur le système d’exploitation hôte.
1. Dépendances Python (Bibliothèques)
Ces modules doivent être installés dans l’environnement Python (généralement via pip).
pyserial: Nécessaire à la classeArduinoControllerpour l’ouverture et la gestion du port série (communication Arduino).screeninfo: Nécessaire à la classeVideoPlayer(utilisé dansmultiplayermanager.pyetvideocontroller.py) pour détecter la résolution et les coordonnées des différents moniteurs connectés.
2. Dépendances Logicielles Externes (Exécutables)
Ces programmes doivent être installés et accessibles dans le PATH du système d’exploitation.
- MPV (Media Player) : Le lecteur multimédia en ligne de commande. Il est essentiel pour les classes
VideoPlayeretAudioPlayercar il est utilisé comme sous-processus pour la lecture de vidéos et d’audio, notamment via son support du contrôle IPC (Inter-Process Communication) par socket.
3. Dépendances pour le Firmware Arduino
Ces éléments sont nécessaires pour la compilation et le fonctionnement du code noel2025_83.ino.
- Arduino IDE/CLI : L’environnement de développement ou l’outil en ligne de commande pour compiler et téléverser le code sur la carte.
- Librairies Arduino :
Adafruit_NeoPixel: Indispensable pour contrôler les rubans LED.- Librairie pour Moteurs Pas à Pas : Une librairie de gestion des moteurs (implicite dans le code pour la gestion de
plateau1etplateau2via une classemanager).
0 commentaire