diff --git a/admin/ia/stt.md b/admin/ia/stt.md index 3056e0a..0d73f3b 100644 --- a/admin/ia/stt.md +++ b/admin/ia/stt.md @@ -181,12 +181,19 @@ Lancer le HUD + voix automatiquement à l'ouverture de session (écran « Jarvis ```bash stt --install-service # écrit ~/.config/systemd/user/stt.service, enable + start stt --uninstall-service # retire le service +stt --start # démarre le service +stt --restart # redémarre — recharge la config (modèle ASR, wake word…) stt --stop # éteint l'instance en cours (service systemd OU process lancé à la main) ``` Le unit est lié à `graphical-session.target` (démarre avec la session graphique, s'arrête avec). Suivi : `systemctl --user status|restart stt`, `journalctl --user -u stt -f`. +Ces actions sont aussi dispo **depuis le HUD** (Réglages → section « Service ») : **Redémarrer**, +**Mettre à jour** (`stt --update` puis `--restart`), **Arrêter**. Le HUD tournant *dans* le service, +ces actions sont lancées en **process détaché** (`start_new_session`) → le redémarrage va à son terme +même quand le process courant est tué (systemd possède le job). + `stt --stop` arrête proprement : si le service `stt.service` (systemd --user) est actif il fait `systemctl --user stop`, sinon il envoie un `SIGTERM` aux process `stt` vocaux trouvés via `/proc` (en s'excluant lui-même et les sous-commandes utilitaires `--update`/`--version`/…). diff --git a/stt/client/pyproject.toml b/stt/client/pyproject.toml index 5f7c218..50dc0c1 100644 --- a/stt/client/pyproject.toml +++ b/stt/client/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "stt" -version = "0.8.0" +version = "0.9.0" description = "STT — client vocal Jarvis du homelab Funk (voix + HUD, parle au STT-server)" requires-python = ">=3.11" readme = "README.md" diff --git a/stt/client/stt/cli.py b/stt/client/stt/cli.py index c0b130a..77124de 100644 --- a/stt/client/stt/cli.py +++ b/stt/client/stt/cli.py @@ -109,6 +109,47 @@ def _cmd_uninstall_service() -> int: return 0 +def _service_installed() -> bool: + """Le unit systemd --user stt.service est-il installé ?""" + import subprocess + + return subprocess.run( + ["systemctl", "--user", "cat", SERVICE_NAME], + capture_output=True, text=True, + ).returncode == 0 + + +def _cmd_start() -> int: + """Démarre le service STT (systemd --user).""" + import subprocess + + if not _service_installed(): + print("Service non installé — lance d'abord : stt --install-service") + print("(ou simplement `stt` pour un lancement direct, sans service)") + return 1 + subprocess.run(["systemctl", "--user", "start", SERVICE_NAME], check=False) + state = subprocess.run( + ["systemctl", "--user", "is-active", SERVICE_NAME], + capture_output=True, text=True, + ).stdout.strip() + print(f"✓ Service STT démarré (état : {state}).") + return 0 + + +def _cmd_restart() -> int: + """Redémarre le service STT — recharge la config (modèle ASR, wake word…).""" + import subprocess + + if not _service_installed(): + print("Service non installé — lance d'abord : stt --install-service") + return 1 + # systemd possède le job : même si ce process est tué (cas restart depuis le + # HUD, qui tourne DANS le service), le redémarrage va à son terme. + subprocess.run(["systemctl", "--user", "restart", SERVICE_NAME], check=False) + print("✓ Service STT redémarré.") + return 0 + + def _running_stt_pids() -> list[int]: """PID des instances `stt` (service voix/HUD) en cours, hors la commande courante. @@ -117,7 +158,7 @@ def _running_stt_pids() -> list[int]: """ me = os.getpid() utilitaires = { - "--stop", "--update", "--version", "--setup", "--text", + "--stop", "--start", "--restart", "--update", "--version", "--setup", "--text", "--install-service", "--uninstall-service", "--install-desktop", "--uninstall-desktop", } @@ -397,6 +438,10 @@ def main(argv: list[str] | None = None) -> int: p.add_argument("--no-tts", action="store_true", help="Réponses texte seulement (voix)") p.add_argument("--window", choices=["app", "kiosk", "none"], help="Ouverture du HUD : app (fenêtre, type Discord) | kiosk (plein écran) | none") + p.add_argument("--start", action="store_true", + help="Démarre le service STT (systemd --user)") + p.add_argument("--restart", action="store_true", + help="Redémarre le service STT (recharge la config : ASR, wake word…)") p.add_argument("--stop", action="store_true", help="Éteint le service STT en cours (systemd --user ou process vocal)") p.add_argument("--install-service", action="store_true", @@ -418,6 +463,10 @@ def main(argv: list[str] | None = None) -> int: return _cmd_setup() if args.update: return _cmd_update() + if args.start: + return _cmd_start() + if args.restart: + return _cmd_restart() if args.stop: return _cmd_stop() if args.install_service: diff --git a/stt/client/stt/hud/index.html b/stt/client/stt/hud/index.html index 9c827a4..f9eec5c 100644 --- a/stt/client/stt/hud/index.html +++ b/stt/client/stt/hud/index.html @@ -683,6 +683,11 @@ white-space: nowrap; } + /* Actions de service (redémarrer / mettre à jour / arrêter) */ + .svc-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; } + .svc-actions .btn { width: auto; font-size: 14px; padding: 11px 10px; } + .svc-actions .btn#svcStop { grid-column: 1 / -1; } /* Arrêter sur toute la largeur */ + /* Toast — confirmation éphémère (clic / voix) */ .toast { position: fixed; @@ -911,6 +916,17 @@
Gérer le service STT sur cette machine (systemd --user).
+