8x32 PI : vitesse de lecture, QR code et affiche, sens de l'image sur la vitrine

- Vitesse de lecture : réglage VITESSE du lecteur et menu « Vitesse » sur la
  page web (×0,25 à ×2, gardé dans .vitesse.txt du dossier des animations).
- QR code d'accès à la page web et affiche A5 (outils/generer_qrcode.py →
  qrcode/) : une coulée inspirée de « cascade » en haut, une partie de
  « tetris » en bas, couleurs tirées des animations de l'équipe
  (qrcode/sources/), titre en pixels de couleur.
- Matrice de la vitrine : image retournée d'un demi-tour (INVERSER_X et
  INVERSER_Y) et nouveau réglage DECALAGE_X / DECALAGE_Y (ici 1 pixel vers
  la droite).
- Doc : README, INTERFACE_WEB.md et CLAUDE.md à jour.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
bach
2026-10-09 16:04:13 +02:00
co-authored by Claude Opus 5.5
parent 156f9ce438
commit 5b0e858abe
135 changed files with 434 additions and 11 deletions
+21 -3
View File
@@ -91,6 +91,13 @@ IMAGES_PAR_SECONDE = 12
# Une image fixe reste affichée pendant cette durée.
DUREE_MINIMUM = 10
# VITESSE de lecture de toutes les animations :
# 1 = la vitesse prévue dans Krita ;
# 0.5 = deux fois plus lent ; 2 = deux fois plus vite.
# La page web peut la changer : elle l'écrit alors dans le fichier caché
# « .vitesse.txt » du dossier des animations, qui a la priorité sur ce réglage.
VITESSE = 1.0
# Noir entre deux animations, en secondes (0 = enchaîner directement).
PAUSE_ENTRE_ANIMATIONS = 0.3
@@ -256,8 +263,19 @@ def charger(chemin):
# 4. JOUER UNE ANIMATION
# =============================================================================
def jouer(etapes, duree_minimum=DUREE_MINIMUM):
def lire_vitesse_de_lecture(dossier):
"""La vitesse choisie sur la page web (fichier .vitesse.txt), sinon VITESSE."""
try:
with open(os.path.join(dossier, ".vitesse.txt")) as f:
vitesse = float(f.read().strip().replace(",", "."))
return min(4.0, max(0.1, vitesse)) # entre ×0,1 et ×4, par prudence
except (OSError, ValueError):
return VITESSE
def jouer(etapes, duree_minimum=DUREE_MINIMUM, vitesse=1.0):
"""Joue la liste d'étapes, et la rejoue jusqu'à atteindre la durée minimum.
vitesse = 0.5 : chaque image reste affichée deux fois plus longtemps.
S'arrête plus tôt si le serveur web demande autre chose (partie 5)."""
debut = time.monotonic()
while True:
@@ -265,7 +283,7 @@ def jouer(etapes, duree_minimum=DUREE_MINIMUM):
moment = time.monotonic()
matrice.montrer(image)
# On retire le temps déjà passé à afficher, pour garder le rythme.
if not attendre_ou_interrompre(duree - (time.monotonic() - moment)):
if not attendre_ou_interrompre(duree / vitesse - (time.monotonic() - moment)):
return
if time.monotonic() - debut >= duree_minimum:
break
@@ -296,7 +314,7 @@ def jouer_animation(chemin, dossier):
print(f" ✗ impossible de lire ce fichier ({erreur}) : on passe au suivant")
return
if etapes:
jouer(etapes)
jouer(etapes, vitesse=lire_vitesse_de_lecture(dossier))
if PAUSE_ENTRE_ANIMATIONS > 0:
matrice.effacer()
matrice.montrer()