Mini menu client + luminosite impression + endpoints systeme

- Menu client coin haut-gauche : WiFi, luminosite, relancer, redemarrer, eteindre
- Popup WiFi : scan, statut, connexion (reutilise les endpoints existants)
- Popup luminosite : slider -50% a +50%, ajuste la luminosite avant impression
  (ImageEnhance.Brightness dans _preparer_image)
- Endpoints systeme : /api/systeme/eteindre, redemarrer, redemarrer-app
- Endpoint exposition Canon : /api/camera/exposition (GET choix + POST valeur)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-09-20 10:22:00 +02:00
parent bb49c2c82d
commit 5e8cff7951
5 changed files with 297 additions and 3 deletions

View File

@@ -495,10 +495,30 @@ async def _reconnecter_dslr_avec_reset(echecs: int):
def _appliquer_config_camera():
"""Applique les paramètres caméra persistants (flash, etc.) après connexion."""
"""Applique les paramètres caméra persistants (flash, exposition) après connexion."""
cfg = charger_config()
flash_integre = cfg.get("camera", {}).get("flash_integre", True)
camera.configurer_flash(flash_integre)
ev = cfg.get("camera", {}).get("exposure_compensation")
if ev is not None:
_set_canon_config("exposurecompensation", str(ev))
def _set_canon_config(nom: str, valeur):
"""Applique un réglage gphoto2 sur le Canon."""
if camera.mode != "gphoto2" or not camera.connectee:
return False
try:
with camera._gp_lock:
cfg = camera.camera.get_config()
w = cfg.get_child_by_name(nom)
w.set_value(valeur)
camera.camera.set_config(cfg)
log.info(f"Canon config: {nom} = {valeur}")
return True
except Exception as e:
log.warning(f"Canon config {nom} échoué: {e}")
return False
async def _watchdog_systemd():
@@ -1260,6 +1280,55 @@ async def api_camera_reconnecter(body: dict = {}):
return {"connectee": ok, "mode": camera.mode}
@app.post("/api/camera/exposition")
async def api_camera_exposition(body: dict):
"""Ajuste la compensation d'exposition Canon (-3 à +3 EV)."""
valeur = body.get("valeur", "0")
ok = _set_canon_config("exposurecompensation", str(valeur))
if ok:
mettre_a_jour_config({"camera": {"exposure_compensation": str(valeur)}})
return {"succes": ok, "valeur": valeur}
@app.get("/api/camera/exposition")
async def api_camera_exposition_get():
"""Retourne les valeurs possibles et la valeur actuelle d'exposition."""
result = {"valeur": "0", "choix": []}
if camera.mode == "gphoto2" and camera.connectee:
try:
with camera._gp_lock:
cfg = camera.camera.get_config()
w = cfg.get_child_by_name("exposurecompensation")
result["valeur"] = w.get_value()
result["choix"] = [w.get_choice(i) for i in range(w.count_choices())]
except Exception as e:
result["erreur"] = str(e)
return result
# --- API Système (menu client) ---
@app.post("/api/systeme/eteindre")
async def api_eteindre():
import subprocess
subprocess.Popen(["sudo", "shutdown", "-h", "now"])
return {"succes": True, "message": "Extinction en cours..."}
@app.post("/api/systeme/redemarrer")
async def api_redemarrer():
import subprocess
subprocess.Popen(["sudo", "reboot"])
return {"succes": True, "message": "Redémarrage en cours..."}
@app.post("/api/systeme/redemarrer-app")
async def api_redemarrer_app():
import subprocess, signal
os.kill(os.getpid(), signal.SIGTERM)
return {"succes": True}
# --- API Effets ---
@app.get("/api/filtres")

View File

@@ -111,6 +111,13 @@ def _preparer_image(chemin: Path, largeur: int, hauteur: int,
if config_imp.get("rotation_180", False) and not skip_rotate:
img = img.rotate(180)
luminosite = config_imp.get("luminosite_impression", 0)
if luminosite != 0:
from PIL import ImageEnhance
facteur = 1.0 + luminosite / 100.0
img = ImageEnhance.Brightness(img).enhance(facteur)
log.debug(f"Luminosité impression ajustée : {luminosite}% (facteur {facteur:.2f})")
tmp = tempfile.NamedTemporaryFile(suffix=".jpg", delete=False)
img.save(tmp.name, "JPEG", quality=95, dpi=(300, 300))
log.debug(f"Image préparée : {orientation} {largeur}x{hauteur}px → {tmp.name}")