# Prompt #7 — D7 Orchestrator

**Rôle :**
Tu es _Développeur Orchestrator_ du projet **Skull Pi**. Tu livres le service central (`svc-orchestrator`) qui coordonne tous les autres via MQTT, expose une API REST (FastAPI), applique la **machine d’états** définie dans le cahier des charges, et pilote les services via `systemctl`. Langue : FR. Cible : Raspberry Pi Zero 2 W.

**Contexte & contraintes :**

- Dossier : `/opt/Skull/apps/orchestrator`.
- Exécution : `python -m orchestrator.main`.
- Supervision systemd : services `skull-*.service` (motion, vision, voice, audioin, asr, ai).
- Communication :

  - MQTT (topics `vision/*`, `motion/*`, `audio/*`, `asr/*`, `ai/*`, `skull/config/*`, `orchestrator/state`).
  - REST API (FastAPI) pour UI & intégrations.

- Orchestrator = cœur logique, doit être **robuste et tolérant aux pannes**.

---

## Objectif fonctionnel

1. **Machine d’états complète** (Idle, Track, Talk, Sing, Listen, Think, Speak, etc. voir cahier).

   - Transitions pilotées par événements MQTT (vision.motion, audio.vad, asr.text, ai.response, voice.state…).
   - Inclure modes : Accueil, Chanson, IA, Full Auto.

2. **Gestion modes**

   - Souscrit/publie `skull/mode`.
   - Paramètres Full Auto (`interval_song_ms`, `accueil_after_song`, `ia_after_accueil`).

3. **Contrôle services**

   - Lancer/stopper services via `systemctl` (sudoers déjà configuré).
   - Healthchecks périodiques : si service silencieux → restart.

4. **API REST (FastAPI)**

   - `/status`, `/mode` (GET/POST), `/config/*`, `/servo/*`, `/song/*`, `/ia/*`, `/fullauto/*`.
   - Swagger/OpenAPI activé.

5. **Persistence config**

   - Config via MQTT retained + fichiers JSON (`/opt/Skull/config/*`).
   - Synchronisation bidirectionnelle REST ↔ MQTT.

6. **Logs**

   - JSON lignes → `/opt/Skull/logs/orchestrator.log`.
   - Inclure transitions d’états, erreurs services, commandes REST.

---

## Spécification MQTT

### Sorties clés

- `orchestrator/state`
  `"Idle" | "Track" | "Talk" | "Sing" | "Listen" | "Think" | "Speak" | "Sleep"`

- `skull/mode` (retained)
  `"Accueil" | "Chanson" | "IA" | "FullAuto"`

### Entrées clés

- `vision/motion`, `vision/pose`
- `audio/vad`, `asr/text`
- `ai/response`
- `voice/state`

---

## Implémentation attendue

1. **Structure package** (`/opt/Skull/apps/orchestrator`)

```
orchestrator/
  __init__.py
  main.py           # démarrage FastAPI + boucle état
  state_machine.py  # transitions & logique
  services.py       # wrappers systemctl start/stop/status
  mqtt.py
  config.py         # sync fichiers JSON + retained
  rest.py           # endpoints FastAPI
  scheduler.py      # timers Full Auto
  health.py
  tests/
```

2. **Machine d’états**

- Implémenter transitions décrites dans cahier (Idle→Track→Talk→Idle, etc.).
- Full Auto = boucle orchestrée : chanson périodique → accueil → IA.
- E-stop = transition immédiate vers Idle + centre moteurs.

3. **REST API**

- FastAPI, port configurable (par `.env`, défaut 8080).
- Endpoints :

  - `/status` → état global (mode, état machine, uptime, services).
  - `/mode` (GET/POST).
  - `/config/*` pour vision/gaze/motion/song/ia/fullauto.
  - `/servo/{name}/move`, `/servo/{name}/limits`, `/estop`.
  - `/song/upload`, `/song/play|pause|stop`.
  - `/ia/config`, `/ia/prompt-system`, `/ia/reply`.
  - `/fullauto/config`, `/fullauto/test-once`.

- Docs OpenAPI activés.

4. **Services management**

- Wrapper `systemctl` (`start/stop/restart/status`).
- Sur crash (service silencieux > timeout) → restart auto.

5. **Scheduler Full Auto**

- Timer interne, intervalle chanson (par défaut 300000 ms).
- Flags `accueil_after_song`, `ia_after_accueil`.

6. **Config sync**

- Abonne topics `skull/config/*`.
- Persiste changements dans fichiers `/opt/Skull/config/*.json`.
- Sur démarrage, republie configs retained.

---

## Déploiement / systemd

- Service `skull-orchestrator.service`.
- Wrapper `/opt/Skull/bin/skull-orchestrator.sh` :

  ```bash
  #!/usr/bin/env bash
  set -euo pipefail
  source /opt/Skull/venv/bin/activate
  exec python -m orchestrator.main
  ```

---

## Livrables

- Code Python (type hints), `ruff` + `mypy` clean.
- Tests unitaires couvrant transitions machine d’états, API REST, sync configs.
- `README.md` (diagrammes états, usage API, check-list debug).

---

## Critères d’acceptation

- Boot : publie `skull/mode="Idle"`, `orchestrator/state="Idle"`.
- Passage mode Accueil : détection vision.motion.score>threshold → Track puis Talk (TTS).
- Mode Chanson : lecture MP3 + jaw sync, retour Idle.
- Mode IA : flux complet VAD→ASR→AI→TTS OK.
- Mode Full Auto : enchaînement chanson → accueil → IA, boucle timer OK.
- E-stop : arrêt immédiat, moteurs centrés, état Idle.
- API REST : tous endpoints répondent 200, cohérents avec MQTT.
- Services crash simulé → orchestrator détecte et restart.

---

## Plan de tests unitaires

1. **Transitions simples**

   - Event motion → Idle→Track→Talk→Idle.

2. **Mode Chanson**

   - Commande REST `/song/play` → état `Sing`, puis retour Idle après stop.

3. **IA cycle**

   - `audio/vad.active=true` + `asr/text="bonjour"` + `ai/response` → enchaînement Listen→Think→Speak→Idle.

4. **Full Auto**

   - Timer chanson 2 s, flags ON → cycle complet déclenché automatiquement.

5. **E-stop**

   - Publier `motion/estop=on` → état Idle immédiat.

6. **Config sync**

   - Publier `skull/config/motion` → fichier JSON mis à jour.
   - Restart orchestrator → republie même config.

7. **REST API**

   - `/status` renvoie état global.
   - `/mode` POST change mode et publie MQTT.

8. **Health services**

   - Simuler crash service (pas de heartbeat) → orchestrator restart.

---

## Test manuel rapide

1. Lancer orchestrator :

   ```
   curl http://localhost:8080/status
   ```

2. Passer en mode Accueil :

   ```
   curl -X POST http://localhost:8080/mode -d '{"state":"Accueil"}' -H "Content-Type: application/json"
   ```

   → Sur mouvement caméra, Skull parle.

3. Passer en Chanson puis IA via API ou MQTT.
4. Activer Full Auto, vérifier séquence.
5. Stopper un service manuellement → orchestrator le relance.

---

**À livrer** : MR “D7 Orchestrator — Machine d’états + REST + supervision” avec code, tests, service, README.
