add doc
This commit is contained in:
parent
92605d728b
commit
4ac7bd16d2
@ -10,6 +10,36 @@ Le projet intègre de nombreux services externes (STT, TTS, LLM, Google Calendar
|
||||
|
||||
## Vue d'ensemble
|
||||
|
||||
### Architecture globale (robot + cloud)
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────────────────────┐
|
||||
│ ROBOT PHYSIQUE │
|
||||
│ │
|
||||
│ ┌──────────────┐ UART ┌──────────────────────────┐ │
|
||||
│ │ ESP32-S3 │ ◄────────────►│ robot-client (Pi Zero) │ │
|
||||
│ │ • Audio I2S │ │ • WebSocket cloud │ │
|
||||
│ │ • Servos │ │ • Wake word │ │
|
||||
│ │ • LEDs │ │ • Domotique (local) │ │
|
||||
│ │ • Capteurs │ │ • WiFi/BLE setup │ │
|
||||
│ └──────────────┘ └────────────┬─────────────┘ │
|
||||
│ │ │
|
||||
└──────────────────────────────────────────────┼───────────────────────────────┘
|
||||
│ WebSocket (WSS)
|
||||
▼
|
||||
┌──────────────────────────────────────────────────────────────────────────────┐
|
||||
│ BACKEND CLOUD (NestJS) │
|
||||
│ │
|
||||
│ Adaptateurs entrants → Core (services) → Adaptateurs sortants │
|
||||
│ (WebSocket, REST) (Conversation, (STT, TTS, LLM, │
|
||||
│ Calendar, etc.) Storage, etc.) │
|
||||
└──────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
> **Note :** Le robot-client gère la domotique en local (Hue, Home Assistant, MQTT) pour la latence et la résilience. Les commandes domotiques sont décidées par le LLM côté cloud, puis transmises au robot-client qui les exécute sur le réseau local. Voir [home-automation.md](home-automation.md) et [robot-client.md](robot-client.md) pour le détail.
|
||||
|
||||
### Architecture du backend cloud
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ ADAPTATEURS ENTRANTS │
|
||||
@ -297,4 +327,20 @@ Utilisée par l'app web/mobile pour toute la configuration :
|
||||
- **Circuit breaker** sur les appels aux services externes (STT, TTS, LLM) — si un provider tombe, le système peut fallback sur un autre (ex: Deepgram → Whisper local).
|
||||
- **Retry avec backoff exponentiel** sur les appels API.
|
||||
- **Queue de messages** pour les function calls non critiques (ex: envoi d'email) — si ça échoue, on retry sans bloquer la conversation.
|
||||
- **Mode dégradé offline** — le robot peut toujours gérer les timers, alarmes, et commandes basiques en local si le core est injoignable.
|
||||
- **Mode dégradé offline** — le robot peut toujours gérer les timers, alarmes, commandes domotiques basiques, et commandes locales si le core est injoignable.
|
||||
|
||||
## Robot Client
|
||||
|
||||
Le robot-client (`apps/robot-client`) est l'application Node.js/TypeScript qui tourne sur le Raspberry Pi Zero 2 W. Il orchestre toute la logique locale du robot : communication UART avec l'ESP32-S3, connexion WebSocket vers le backend cloud, détection du wake word, provisioning WiFi (BLE + AP mode), et exécution des commandes domotiques sur le réseau local.
|
||||
|
||||
En développement, le robot-client tourne sur le PC du développeur en mode simulateur (`ROBOT_MODE=simulator`), les modules hardware étant remplacés par des mocks. Le simulateur web (`apps/simulator`) sert alors de frontend de debug.
|
||||
|
||||
Voir [robot-client.md](robot-client.md) pour l'architecture détaillée.
|
||||
|
||||
## Couche Domotique
|
||||
|
||||
L'intégration domotique est gérée **localement par le robot-client**, pas par le backend cloud. Chaque écosystème (Philips Hue, Home Assistant, MQTT…) est encapsulé dans un bridge qui implémente une interface `IAutomationBridge`. L'`AutomationManager` orchestre les bridges et expose une API unifiée.
|
||||
|
||||
Le flux : le LLM côté cloud décide d'appeler un tool domotique → le backend transmet la commande au robot-client via WebSocket → le robot-client exécute la commande localement sur le réseau.
|
||||
|
||||
Voir [home-automation.md](home-automation.md) pour le détail complet.
|
||||
|
||||
@ -258,7 +258,63 @@ Une application web (et mobile à terme) pour configurer Ti-Pote et gérer son c
|
||||
|
||||
---
|
||||
|
||||
## 12. Mode offline dégradé
|
||||
## 12. Domotique (contrôle de la maison)
|
||||
|
||||
### Description
|
||||
Ti-Pote peut contrôler les appareils domotiques de la maison par la voix : lumières, thermostats, volets, media players, et tout appareil connecté via les écosystèmes supportés. Le contrôle est exécuté localement depuis le robot (pas via le cloud) pour la latence et la résilience.
|
||||
|
||||
### Cas d'usage
|
||||
- "Allume la lumière du salon"
|
||||
- "Mets le salon en ambiance cinéma"
|
||||
- "Quelle température il fait dans la chambre ?"
|
||||
- "Monte le chauffage à 22 degrés"
|
||||
- "Ferme les volets"
|
||||
- "Active la scène bonne nuit"
|
||||
|
||||
### Écosystèmes supportés
|
||||
- **Philips Hue** — contrôle direct via l'API REST locale du Hue Bridge
|
||||
- **Home Assistant** — accès à tous les appareils gérés par HA via son WebSocket API
|
||||
- **MQTT** — support Zigbee2MQTT, Tasmota, et tout appareil publiant sur MQTT
|
||||
- **Futurs** : Matter/Thread, Apple HomeKit, Tuya, KNX
|
||||
|
||||
### Architecture
|
||||
Chaque écosystème est encapsulé dans un bridge avec une interface commune (`IAutomationBridge`). Un `AutomationManager` orchestre les bridges et expose une API unifiée. La découverte des hubs se fait par mDNS.
|
||||
|
||||
Voir [home-automation.md](home-automation.md) pour le détail complet.
|
||||
|
||||
### Functions exposées au LLM
|
||||
- `list_smart_devices` — Lister les appareils disponibles (par pièce, par type)
|
||||
- `control_device` — Contrôler un appareil (on/off, brightness, color, temperature…)
|
||||
- `get_device_state` — Lire l'état d'un appareil
|
||||
- `execute_scene` — Activer une scène prédéfinie
|
||||
- `get_sensor_value` — Lire un capteur (température, humidité, mouvement…)
|
||||
|
||||
---
|
||||
|
||||
## 13. Provisioning WiFi et setup initial
|
||||
|
||||
### Description
|
||||
Le robot doit pouvoir être configuré sur n'importe quel réseau WiFi par un utilisateur non-technique. Deux mécanismes complémentaires sont prévus.
|
||||
|
||||
### Cas d'usage
|
||||
- Premier démarrage du robot : l'utilisateur le connecte à son WiFi via l'app mobile (BLE) ou via le captive portal (AP mode)
|
||||
- Changement de réseau WiFi (déménagement, nouveau routeur)
|
||||
- Reset réseau (bouton physique sur le robot)
|
||||
|
||||
### Méthode principale : BLE Provisioning
|
||||
L'app Ti-Pote (web/mobile) scanne les robots en BLE, envoie les credentials WiFi. Le robot se connecte et confirme. L'utilisateur n'a pas besoin de changer de réseau sur son téléphone.
|
||||
|
||||
### Méthode fallback : AP Mode + Captive Portal
|
||||
Le robot crée un hotspot WiFi (`Ti-Pote-XXXX`). L'utilisateur s'y connecte, un portail web s'ouvre pour choisir le réseau et entrer le mot de passe. Le robot se connecte et désactive le hotspot.
|
||||
|
||||
### Implémentation
|
||||
- BLE : librairie `noble` (npm) sur le Pi Zero 2 W
|
||||
- AP mode : `hostapd` + `dnsmasq` + serveur HTTP local (Express/Fastify)
|
||||
- Voir [robot-client.md](robot-client.md) pour le détail du flux
|
||||
|
||||
---
|
||||
|
||||
## 14. Mode offline dégradé
|
||||
|
||||
### Description
|
||||
Si le robot perd la connexion internet ou que le core est injoignable, certaines fonctionnalités de base restent disponibles localement.
|
||||
@ -266,6 +322,7 @@ Si le robot perd la connexion internet ou que le core est injoignable, certaines
|
||||
### Fonctionnalités offline
|
||||
- Timers et alarmes (gérés localement)
|
||||
- Heure et date
|
||||
- Commandes domotiques basiques (allumer/éteindre — via les bridges locaux, pas besoin du cloud)
|
||||
- Commandes de base pré-enregistrées
|
||||
- Feedback audio (sons, bips) pour confirmer les actions
|
||||
|
||||
|
||||
313
docs/home-automation.md
Normal file
313
docs/home-automation.md
Normal file
@ -0,0 +1,313 @@
|
||||
# Intégration Domotique
|
||||
|
||||
## Vue d'ensemble
|
||||
|
||||
Ti-Pote peut interagir avec les équipements domotiques de la maison. L'utilisateur contrôle ses lampes, thermostats, volets, et autres appareils connectés par la voix. L'architecture est conçue pour être extensible : chaque écosystème domotique est encapsulé dans un **bridge** (adaptateur) avec une interface commune.
|
||||
|
||||
### Philosophie
|
||||
|
||||
Le contrôle domotique est exécuté **localement depuis le robot-client** (sur le Pi Zero 2 W), pas depuis le backend cloud. C'est un choix délibéré :
|
||||
|
||||
- **Latence** : les commandes domotiques doivent être quasi-instantanées. Passer par le cloud ajouterait 100-300ms inutiles.
|
||||
- **Résilience** : si la connexion internet tombe, le robot peut encore contrôler les lumières et les appareils locaux.
|
||||
- **Privacy** : les commandes domotiques ne transitent pas par des serveurs distants.
|
||||
|
||||
Le flux est le suivant : l'utilisateur parle → le backend cloud traite la requête (STT → LLM) → le LLM décide d'appeler une function domotique → le backend envoie la commande au robot-client via WebSocket → le robot-client exécute la commande sur le réseau local.
|
||||
|
||||
```
|
||||
Utilisateur : "Allume la lumière du salon"
|
||||
|
||||
┌─────────────┐ audio ┌──────────────┐ function call ┌──────────────────┐
|
||||
│ Robot │ ──────────►│ Backend │ ──────────────►│ Robot-client │
|
||||
│ (micro) │ │ Cloud │ "set_light" │ (Pi Zero) │
|
||||
└─────────────┘ │ │ │ │
|
||||
│ STT → LLM │ │ ┌──────────────┐ │
|
||||
│ │ │ │ Hue Bridge │ │
|
||||
│ │ │ │ (REST local) │ │
|
||||
└──────────────┘ │ └──────┬───────┘ │
|
||||
└────────┼─────────┘
|
||||
│
|
||||
┌──────▼───────┐
|
||||
│ Lampe Hue │
|
||||
│ (salon) │
|
||||
└──────────────┘
|
||||
```
|
||||
|
||||
## Architecture des bridges
|
||||
|
||||
Chaque écosystème domotique est implémenté comme un **bridge** qui respecte une interface TypeScript commune. Cela permet d'ajouter de nouveaux écosystèmes sans modifier le reste du code.
|
||||
|
||||
```typescript
|
||||
// bridge.interface.ts
|
||||
interface IAutomationBridge {
|
||||
/** Nom du bridge (ex: "hue", "homeassistant", "mqtt") */
|
||||
readonly name: string;
|
||||
|
||||
/** Initialise la connexion avec le hub/controller */
|
||||
connect(): Promise<void>;
|
||||
|
||||
/** Déconnexion propre */
|
||||
disconnect(): Promise<void>;
|
||||
|
||||
/** Vérifie si le bridge est connecté et fonctionnel */
|
||||
isConnected(): boolean;
|
||||
|
||||
/** Liste tous les appareils découverts */
|
||||
listDevices(): Promise<AutomationDevice[]>;
|
||||
|
||||
/** Récupère l'état d'un appareil */
|
||||
getDeviceState(deviceId: string): Promise<DeviceState>;
|
||||
|
||||
/** Exécute une commande sur un appareil */
|
||||
executeCommand(deviceId: string, command: DeviceCommand): Promise<void>;
|
||||
|
||||
/** S'abonne aux changements d'état (optionnel) */
|
||||
onStateChange?(callback: (deviceId: string, state: DeviceState) => void): void;
|
||||
}
|
||||
|
||||
interface AutomationDevice {
|
||||
id: string;
|
||||
name: string; // Nom lisible ("Lampe salon", "Thermostat chambre")
|
||||
type: DeviceType; // "light" | "switch" | "thermostat" | "cover" | "sensor" | "media" | ...
|
||||
room?: string; // Pièce (si disponible)
|
||||
capabilities: string[]; // ["on_off", "brightness", "color", "temperature", ...]
|
||||
bridge: string; // Nom du bridge source
|
||||
}
|
||||
|
||||
interface DeviceState {
|
||||
on?: boolean;
|
||||
brightness?: number; // 0-100
|
||||
color?: { r: number; g: number; b: number };
|
||||
colorTemp?: number; // en Kelvin
|
||||
temperature?: number; // en °C (thermostat/capteur)
|
||||
targetTemperature?: number; // consigne (thermostat)
|
||||
position?: number; // 0-100 (volets)
|
||||
[key: string]: unknown; // Propriétés spécifiques au bridge
|
||||
}
|
||||
|
||||
type DeviceCommand =
|
||||
| { action: 'turn_on'; brightness?: number; color?: string; colorTemp?: number }
|
||||
| { action: 'turn_off' }
|
||||
| { action: 'set_brightness'; value: number }
|
||||
| { action: 'set_color'; r: number; g: number; b: number }
|
||||
| { action: 'set_color_temp'; kelvin: number }
|
||||
| { action: 'set_temperature'; value: number }
|
||||
| { action: 'set_position'; value: number } // volets
|
||||
| { action: 'toggle' }
|
||||
| { action: 'custom'; payload: Record<string, unknown> };
|
||||
```
|
||||
|
||||
### AutomationManager
|
||||
|
||||
Le `AutomationManager` orchestre tous les bridges actifs. Il maintient un registre unifié des appareils, quelle que soit leur source, et expose une API unique au reste du robot-client.
|
||||
|
||||
```typescript
|
||||
class AutomationManager {
|
||||
private bridges: Map<string, IAutomationBridge>;
|
||||
private devices: Map<string, AutomationDevice>; // Cache unifié
|
||||
|
||||
/** Enregistre un nouveau bridge */
|
||||
registerBridge(bridge: IAutomationBridge): void;
|
||||
|
||||
/** Connecte tous les bridges enregistrés */
|
||||
connectAll(): Promise<void>;
|
||||
|
||||
/** Liste tous les appareils de tous les bridges */
|
||||
listAllDevices(): AutomationDevice[];
|
||||
|
||||
/** Cherche des appareils par nom ou pièce (fuzzy matching) */
|
||||
findDevices(query: string): AutomationDevice[];
|
||||
|
||||
/** Exécute une commande (résout le bridge automatiquement) */
|
||||
executeCommand(deviceId: string, command: DeviceCommand): Promise<void>;
|
||||
|
||||
/** Crée des scènes (groupes de commandes) */
|
||||
executeScene(scene: AutomationScene): Promise<void>;
|
||||
}
|
||||
```
|
||||
|
||||
## Bridges supportés
|
||||
|
||||
### 1. Philips Hue
|
||||
|
||||
Communication directe avec le Hue Bridge via son API REST locale. Pas besoin du cloud Philips — tout se passe sur le réseau local.
|
||||
|
||||
| Paramètre | Détail |
|
||||
|-----------|--------|
|
||||
| Protocole | HTTP REST (API v2 CLIP) |
|
||||
| Découverte | mDNS (`_hue._tcp.local`) ou IP manuelle |
|
||||
| Auth | Appui physique sur le bridge + échange de clé API |
|
||||
| Appareils | Lampes, prises, capteurs de mouvement, boutons |
|
||||
| Capacités | on/off, brightness, color (RGB + CT), groupes, scènes |
|
||||
|
||||
**Découverte et appairage :**
|
||||
|
||||
1. Le robot-client scanne le réseau local pour trouver le Hue Bridge (mDNS ou SSDP).
|
||||
2. L'utilisateur est invité à appuyer sur le bouton du bridge (pour autoriser l'accès).
|
||||
3. Le robot-client enregistre une clé API et la stocke localement (chiffrée).
|
||||
4. Les lampes et groupes sont découverts automatiquement.
|
||||
|
||||
**Exemples de commandes vocales :**
|
||||
- "Allume la lumière du salon"
|
||||
- "Mets le salon en rouge à 50%"
|
||||
- "Éteins toutes les lumières"
|
||||
- "Active la scène cinéma"
|
||||
|
||||
### 2. Home Assistant
|
||||
|
||||
Communication avec une instance Home Assistant via son WebSocket API. Home Assistant est un hub domotique open source qui supporte des centaines de protocoles (Zigbee, Z-Wave, WiFi, Bluetooth, Matter...). C'est le bridge le plus polyvalent : en connectant Ti-Pote à Home Assistant, on accède automatiquement à tous les appareils gérés par HA.
|
||||
|
||||
| Paramètre | Détail |
|
||||
|-----------|--------|
|
||||
| Protocole | WebSocket (+ REST API pour certaines opérations) |
|
||||
| Découverte | mDNS (`_home-assistant._tcp.local`) ou URL manuelle |
|
||||
| Auth | Long-lived access token (généré dans l'interface HA) |
|
||||
| Appareils | Tout ce que Home Assistant gère (lumières, thermostats, volets, media players, capteurs, aspirateurs, caméras...) |
|
||||
| Capacités | Dépend des appareils — HA expose les entités avec leurs services |
|
||||
|
||||
**Intégration :**
|
||||
|
||||
Le bridge Home Assistant est particulièrement puissant car il permet aussi :
|
||||
|
||||
- D'exécuter des **automatisations HA** via la voix ("Lance le scénario bonne nuit").
|
||||
- De lire les **capteurs** ("Quelle est la température dans la chambre ?").
|
||||
- D'interagir avec des **media players** ("Mets la musique dans la cuisine").
|
||||
- D'accéder à l'**historique** des états ("À quelle heure la porte du garage a été ouverte ?").
|
||||
|
||||
### 3. MQTT (Zigbee2MQTT, Tasmota...)
|
||||
|
||||
Pour les utilisateurs qui utilisent un broker MQTT directement (sans Home Assistant). Permet de contrôler des appareils Zigbee (via Zigbee2MQTT), des prises Tasmota, ou tout appareil publiant sur MQTT.
|
||||
|
||||
| Paramètre | Détail |
|
||||
|-----------|--------|
|
||||
| Protocole | MQTT (via broker Mosquitto ou autre) |
|
||||
| Découverte | Topics de discovery (`homeassistant/+/+/config` ou custom) |
|
||||
| Auth | Credentials MQTT (user/password) |
|
||||
| Appareils | Dépend des topics publiés |
|
||||
|
||||
### 4. Bridges futurs (Phase 4+)
|
||||
|
||||
L'interface `IAutomationBridge` permet d'ajouter facilement :
|
||||
|
||||
- **Matter/Thread** — le nouveau standard IoT (quand l'écosystème sera plus mature)
|
||||
- **Apple HomeKit** — via le protocole HAP
|
||||
- **Google Home** — via l'API locale (si disponible)
|
||||
- **Tuya/Smart Life** — protocole local Tuya
|
||||
- **KNX** — domotique filaire haut de gamme
|
||||
|
||||
## Découverte automatique
|
||||
|
||||
Au démarrage (et périodiquement), le robot-client scanne le réseau local pour découvrir les hubs domotiques disponibles :
|
||||
|
||||
```
|
||||
1. Scan mDNS
|
||||
├── _hue._tcp.local → Hue Bridge trouvé à 192.168.1.42
|
||||
├── _home-assistant._tcp.local → HA trouvé à 192.168.1.100
|
||||
└── (autres services...)
|
||||
|
||||
2. Notification à l'utilisateur
|
||||
"J'ai détecté un pont Philips Hue et une instance Home Assistant
|
||||
sur ton réseau. Tu veux que je m'y connecte ?"
|
||||
|
||||
3. Configuration via l'app frontend
|
||||
└── L'utilisateur entre les credentials nécessaires (clé API Hue, token HA...)
|
||||
```
|
||||
|
||||
## Functions LLM (tools pour le backend)
|
||||
|
||||
Le backend cloud expose ces tools au LLM. Quand le LLM les appelle, le backend transmet la commande au robot-client qui l'exécute localement.
|
||||
|
||||
```typescript
|
||||
const automationTools = [
|
||||
{
|
||||
name: 'list_smart_devices',
|
||||
description: 'Liste les appareils domotiques disponibles dans la maison',
|
||||
parameters: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
room: { type: 'string', description: 'Filtrer par pièce (optionnel)' },
|
||||
type: { type: 'string', description: 'Filtrer par type: light, switch, thermostat, cover, sensor, media' },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'control_device',
|
||||
description: 'Contrôle un appareil domotique (allumer, éteindre, régler luminosité, couleur, température...)',
|
||||
parameters: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
device_name: { type: 'string', description: 'Nom de l\'appareil (ex: "lampe salon")' },
|
||||
action: { type: 'string', enum: ['turn_on', 'turn_off', 'toggle', 'set_brightness', 'set_color', 'set_color_temp', 'set_temperature', 'set_position'] },
|
||||
value: { type: 'number', description: 'Valeur numérique selon l\'action (brightness 0-100, temperature en °C, etc.)' },
|
||||
color: { type: 'string', description: 'Couleur (nom ou hex, ex: "rouge", "#FF0000")' },
|
||||
},
|
||||
required: ['device_name', 'action'],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'get_device_state',
|
||||
description: 'Récupère l\'état actuel d\'un appareil (allumé/éteint, température, luminosité...)',
|
||||
parameters: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
device_name: { type: 'string', description: 'Nom de l\'appareil' },
|
||||
},
|
||||
required: ['device_name'],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'execute_scene',
|
||||
description: 'Active une scène ou un scénario domotique prédéfini',
|
||||
parameters: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
scene_name: { type: 'string', description: 'Nom de la scène (ex: "cinéma", "bonne nuit", "matin")' },
|
||||
},
|
||||
required: ['scene_name'],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'get_sensor_value',
|
||||
description: 'Lit la valeur d\'un capteur domotique (température, humidité, mouvement, ouverture...)',
|
||||
parameters: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
sensor_name: { type: 'string', description: 'Nom du capteur (ex: "température chambre", "capteur porte garage")' },
|
||||
},
|
||||
required: ['sensor_name'],
|
||||
},
|
||||
},
|
||||
];
|
||||
```
|
||||
|
||||
## Exemples de conversations
|
||||
|
||||
**Contrôle basique :**
|
||||
> "Hey Ti-Pote, allume la lumière du salon"
|
||||
> → LLM appelle `control_device("lampe salon", "turn_on")` → robot-client → Hue Bridge → lampe s'allume
|
||||
> "C'est fait, la lampe du salon est allumée."
|
||||
|
||||
**Contrôle avancé :**
|
||||
> "Mets le salon en ambiance cinéma"
|
||||
> → LLM appelle `execute_scene("cinéma")` → robot-client → Hue Bridge → scène activée
|
||||
> "Scène cinéma activée. Bon film !"
|
||||
|
||||
**Lecture de capteur :**
|
||||
> "Quelle température il fait dans la chambre ?"
|
||||
> → LLM appelle `get_sensor_value("température chambre")` → robot-client → Home Assistant → 21.5°C
|
||||
> "Il fait 21 degrés et demi dans la chambre."
|
||||
|
||||
**Combinaison avec d'autres services :**
|
||||
> "Il fait froid, monte le chauffage et rappelle-moi de baisser dans 2 heures"
|
||||
> → LLM appelle `control_device("thermostat salon", "set_temperature", 22)` + `set_timer("Baisser le chauffage", 7200)`
|
||||
> "J'ai monté le thermostat à 22 degrés. Je te rappellerai de baisser dans 2 heures."
|
||||
|
||||
## Configuration dans le frontend
|
||||
|
||||
L'interface web (Next.js) propose une section "Domotique" dans les paramètres :
|
||||
|
||||
- **Bridges détectés** : liste des hubs trouvés sur le réseau, avec statut de connexion
|
||||
- **Appairage** : bouton pour initier l'appairage (Hue : appui sur le bridge, HA : saisie du token)
|
||||
- **Appareils** : liste des devices découverts avec possibilité de renommer, assigner à une pièce, masquer
|
||||
- **Scènes** : création de scènes personnalisées (groupes de commandes)
|
||||
- **Test** : bouton pour tester une commande sur un appareil (allumer/éteindre)
|
||||
@ -5,11 +5,11 @@
|
||||
Le développement de Ti-Pote est découpé en phases progressives. Chaque phase produit un livrable fonctionnel et testable. L'objectif est de valider chaque brique avant d'empiler la suivante.
|
||||
|
||||
```
|
||||
Phase 0 Phase 1 Phase 2 Phase 3 Phase 4
|
||||
Setup & Conversation Services Intelligence Expansion
|
||||
Infra vocale métier avancée
|
||||
─────────────────────────────────────────────────────────────────────────────────►
|
||||
[2-3 sem] [3-4 sem] [4-6 sem] [4-6 sem] [Continu]
|
||||
Phase 0 Phase 1 Phase 1.5 Phase 2 Phase 3 Phase 4
|
||||
Setup & Conversation Robot Client Services Intelligence Expansion
|
||||
Infra vocale & Domotique métier avancée
|
||||
──────────────────────────────────────────────────────────────────────────────────────────────────►
|
||||
[2-3 sem] [3-4 sem] [3-4 sem] [4-6 sem] [4-6 sem] [Continu]
|
||||
```
|
||||
|
||||
---
|
||||
@ -82,6 +82,48 @@ L'utilisateur dit "Hey Ti-Pote, raconte-moi une blague" → le robot répond voc
|
||||
|
||||
---
|
||||
|
||||
## Phase 1.5 — Robot Client & Domotique (3-4 semaines)
|
||||
|
||||
### Objectif
|
||||
Remplacer le simulateur comme client direct du backend par un vrai **robot-client** TypeScript (`apps/robot-client`) qui reflète l'architecture cible du robot physique. Ajouter le provisioning WiFi et les premières intégrations domotiques.
|
||||
|
||||
### Livrables
|
||||
|
||||
**Robot Client (`apps/robot-client`)**
|
||||
- Application Node.js TypeScript qui tourne sur le Pi (ou en mode simulateur sur PC de dev)
|
||||
- Communication WebSocket bidirectionnelle avec le backend cloud (même protocole que le simulateur)
|
||||
- Bridge UART avec l'ESP32-S3 via `serialport` (mode physical) ou mock (mode simulator)
|
||||
- Flag `ROBOT_MODE=simulator|physical` pour switcher entre les deux modes
|
||||
- Intégration du wake word (OpenWakeWord via subprocess Python)
|
||||
- Système de health check et heartbeat avec le backend
|
||||
|
||||
**WiFi Provisioning**
|
||||
- Setup WiFi par BLE (méthode principale) : le robot advertise en BLE, l'app envoie les credentials
|
||||
- Setup WiFi par AP mode + captive portal (fallback) : hotspot `Ti-Pote-XXXX`, portail web local
|
||||
- Flux de premier démarrage (onboarding) complet : power on → WiFi → cloud → prêt
|
||||
|
||||
**Domotique — première intégration**
|
||||
- Architecture de bridges domotiques avec interface `IAutomationBridge`
|
||||
- `AutomationManager` pour orchestrer plusieurs bridges
|
||||
- Bridge **Philips Hue** : découverte mDNS, appairage, contrôle des lampes (on/off, brightness, color)
|
||||
- Bridge **Home Assistant** : connexion WebSocket API, listing des entités, exécution de commandes
|
||||
- Bridge **MQTT** : connexion broker, support Zigbee2MQTT / Tasmota
|
||||
- Découverte automatique des hubs sur le réseau local (mDNS)
|
||||
- Tools LLM : `list_smart_devices`, `control_device`, `get_device_state`, `execute_scene`, `get_sensor_value`
|
||||
|
||||
**Simulateur (évolution)**
|
||||
- Le simulateur web (`apps/simulator`) devient un frontend de debug pour le robot-client en mode simulator
|
||||
- Nouvelle topologie : Browser ↔ robot-client (PC) ↔ Backend cloud
|
||||
|
||||
**Frontend**
|
||||
- Page de configuration WiFi (pour le setup initial)
|
||||
- Section domotique : bridges détectés, appairage, liste des appareils, test de commande
|
||||
|
||||
### Critère de validation
|
||||
Le robot-client tourne sur un PC de dev en mode simulator. L'utilisateur peut parler via le simulateur web, la requête transite par le robot-client avant d'atteindre le backend. Depuis la voix, l'utilisateur peut allumer/éteindre une lampe Hue ou un appareil Home Assistant. Le setup WiFi fonctionne en AP mode sur un Pi physique.
|
||||
|
||||
---
|
||||
|
||||
## Phase 2 — Services métier & Function calling (4-6 semaines)
|
||||
|
||||
### Objectif
|
||||
@ -175,7 +217,7 @@ Améliorer, étendre et polish le produit. Cette phase est continue et n'a pas d
|
||||
- WhatsApp Business API
|
||||
- Telegram Bot API
|
||||
- Spotify / services de musique
|
||||
- Domotique (Home Assistant, Philips Hue…)
|
||||
- Nouveaux bridges domotiques (Matter/Thread, Apple HomeKit, Tuya, KNX…)
|
||||
|
||||
**Mobilité**
|
||||
- Firmware pour le module base mobile
|
||||
@ -212,6 +254,9 @@ Améliorer, étendre et polish le produit. Cette phase est continue et n'a pas d
|
||||
| Jalon | Phase | Description |
|
||||
|-------|-------|-------------|
|
||||
| "Hello World" vocal | Phase 1 | Premier aller-retour audio complet |
|
||||
| Robot-client opérationnel | Phase 1.5 | Le robot-client fait le pont simulateur ↔ backend |
|
||||
| "Allume la lumière" | Phase 1.5 | Ti-Pote contrôle une lampe Hue ou un device HA par la voix |
|
||||
| Setup WiFi autonome | Phase 1.5 | Le robot se configure sur un réseau WiFi via AP mode ou BLE |
|
||||
| Premier function call | Phase 2 | Ti-Pote crée un événement dans Google Calendar |
|
||||
| "Tu te souviens ?" | Phase 3 | Ti-Pote retrouve un souvenir d'une conversation passée |
|
||||
| Notification proactive | Phase 3 | Ti-Pote rappelle un RDV sans qu'on lui demande |
|
||||
|
||||
284
docs/robot-client.md
Normal file
284
docs/robot-client.md
Normal file
@ -0,0 +1,284 @@
|
||||
# Robot Client (`apps/robot-client`)
|
||||
|
||||
## Vue d'ensemble
|
||||
|
||||
Le **robot-client** est l'application TypeScript qui tourne directement sur le Raspberry Pi Zero 2 W du robot. C'est le "cerveau logiciel local" de Ti-Pote : il fait le pont entre le hardware (ESP32-S3 via UART) et le backend cloud (via WebSocket). En phase de développement, cette même app est simulée sur un PC de dev, permettant de travailler sans le robot physique.
|
||||
|
||||
### Positionnement dans l'architecture
|
||||
|
||||
```
|
||||
┌──────────────┐ UART ┌──────────────────────┐ WebSocket ┌──────────────┐
|
||||
│ ESP32-S3 │ ◄────────────►│ robot-client │ ◄─────────────►│ Backend │
|
||||
│ (firmware) │ │ (Node.js / Pi) │ │ Cloud │
|
||||
│ │ │ │ │ (NestJS) │
|
||||
│ • Audio I2S │ │ • Orchestration │ │ │
|
||||
│ • Servos │ │ • Wake word │ │ • STT/TTS │
|
||||
│ • LEDs │ │ • WiFi management │ │ • LLM │
|
||||
│ • Capteurs │ │ • Config locale │ │ • Services │
|
||||
└──────────────┘ │ • Domotique bridge │ └──────────────┘
|
||||
│ • OTA updates │
|
||||
└──────────────────────┘
|
||||
```
|
||||
|
||||
## Runtime et contraintes
|
||||
|
||||
| Paramètre | Choix |
|
||||
|-----------|-------|
|
||||
| Runtime | **Node.js** (LTS) |
|
||||
| Langage | TypeScript strict |
|
||||
| OS | Raspberry Pi OS Lite (headless) |
|
||||
| RAM disponible | ~300 Mo (sur 512 Mo, après OS) |
|
||||
| Stockage | microSD 32 Go |
|
||||
| Réseau | WiFi 802.11 b/g/n + BLE 4.2 |
|
||||
|
||||
### Pourquoi Node.js ?
|
||||
|
||||
Node.js est le choix le plus cohérent avec le reste du stack (backend NestJS, simulateur). L'écosystème npm offre des librairies matures pour tout ce dont on a besoin : WebSocket (socket.io-client), serialport (UART), mDNS, BLE, HTTP serveur local. La consommation mémoire est gérable sur le Pi Zero 2 W si on fait attention aux dépendances.
|
||||
|
||||
## Architecture interne
|
||||
|
||||
Le robot-client suit lui aussi une architecture modulaire avec des services découplés. Chaque module peut être activé/désactivé selon la configuration du robot.
|
||||
|
||||
```
|
||||
apps/robot-client/
|
||||
├── src/
|
||||
│ ├── main.ts # Point d'entrée, bootstrap
|
||||
│ ├── config/
|
||||
│ │ ├── robot.config.ts # Config locale (device ID, tokens, WiFi...)
|
||||
│ │ └── hardware.config.ts # Config hardware (UART port, baudrate...)
|
||||
│ │
|
||||
│ ├── transport/
|
||||
│ │ ├── cloud-socket.ts # Client WebSocket vers le backend cloud
|
||||
│ │ ├── uart-bridge.ts # Communication UART avec l'ESP32
|
||||
│ │ └── local-server.ts # Serveur HTTP/WS local pour le setup
|
||||
│ │
|
||||
│ ├── services/
|
||||
│ │ ├── wake-word.service.ts # Détection wake word (OpenWakeWord via subprocess)
|
||||
│ │ ├── wifi.service.ts # Gestion WiFi (scan, connect, AP mode)
|
||||
│ │ ├── bluetooth.service.ts # BLE pour le provisioning
|
||||
│ │ ├── camera.service.ts # Capture image (CSI camera)
|
||||
│ │ ├── ota.service.ts # Mises à jour OTA (self + ESP32)
|
||||
│ │ ├── health.service.ts # Monitoring, heartbeat, diagnostics
|
||||
│ │ └── automation/
|
||||
│ │ ├── automation.manager.ts # Gestionnaire de bridges domotiques
|
||||
│ │ ├── bridges/
|
||||
│ │ │ ├── bridge.interface.ts # Interface commune pour tous les bridges
|
||||
│ │ │ ├── hue.bridge.ts # Philips Hue (API REST locale)
|
||||
│ │ │ ├── homeassistant.bridge.ts # Home Assistant (WebSocket API)
|
||||
│ │ │ └── mqtt.bridge.ts # MQTT générique (Zigbee2MQTT, etc.)
|
||||
│ │ └── discovery.service.ts # Découverte mDNS des hubs domotiques
|
||||
│ │
|
||||
│ ├── setup/
|
||||
│ │ ├── captive-portal.ts # AP mode + portail captif pour config WiFi
|
||||
│ │ ├── ble-provisioning.ts # Provisioning BLE (méthode principale)
|
||||
│ │ └── setup-flow.ts # Orchestration du flux de premier setup
|
||||
│ │
|
||||
│ └── utils/
|
||||
│ ├── logger.ts # Logging local + remote
|
||||
│ ├── network.ts # Utilitaires réseau (IP, connectivity check)
|
||||
│ └── system.ts # Infos système (CPU, RAM, température)
|
||||
│
|
||||
├── scripts/
|
||||
│ ├── install.sh # Installation des dépendances système (Node, OpenWakeWord...)
|
||||
│ └── setup-ap.sh # Configuration du point d'accès WiFi
|
||||
│
|
||||
├── package.json
|
||||
└── tsconfig.json
|
||||
```
|
||||
|
||||
## Fonctionnalités clés
|
||||
|
||||
### 1. Communication cloud (WebSocket)
|
||||
|
||||
Le robot-client maintient une connexion WebSocket persistante avec le backend cloud. C'est le même protocole que le simulateur web — le backend ne fait pas la différence. En cas de déconnexion, le client tente automatiquement de se reconnecter avec un backoff exponentiel.
|
||||
|
||||
Le client gère aussi la bufferisation : si la connexion tombe pendant un échange audio, il peut informer l'utilisateur via les LEDs (passage en orange) et basculer en mode dégradé local.
|
||||
|
||||
### 2. Communication hardware (UART)
|
||||
|
||||
Le robot-client communique avec l'ESP32-S3 via le port série UART à 921600 baud. Il implémente le protocole de frames binaire décrit dans [hardware.md](hardware.md) : réception des chunks audio du micro (AUDIO_UP), envoi des chunks TTS (AUDIO_DOWN), commandes servo/LED, et heartbeat.
|
||||
|
||||
La librairie `serialport` npm est utilisée pour l'accès au port série.
|
||||
|
||||
### 3. Configuration WiFi
|
||||
|
||||
Le robot doit pouvoir être configuré sur n'importe quel réseau WiFi, même par un utilisateur non-technique. Deux mécanismes complémentaires sont prévus.
|
||||
|
||||
#### Méthode principale : BLE Provisioning
|
||||
|
||||
Le mécanisme de setup préféré. L'utilisateur ouvre l'app web/mobile Ti-Pote sur son téléphone et scanne les robots disponibles en BLE. L'app envoie les credentials WiFi (SSID + mot de passe) au robot via BLE. Le robot se connecte au WiFi et confirme la connexion.
|
||||
|
||||
Avantage : l'utilisateur n'a pas besoin de changer de réseau WiFi sur son téléphone pendant le setup.
|
||||
|
||||
```
|
||||
Téléphone (App Ti-Pote) Robot (Pi Zero 2 W)
|
||||
│ │
|
||||
│ ─── BLE scan ──────────────────► │
|
||||
│ ◄── BLE advertise (Ti-Pote-XXXX) │
|
||||
│ │
|
||||
│ ─── Connect BLE ──────────────► │
|
||||
│ ─── Send WiFi credentials ────► │
|
||||
│ │ → connecte au WiFi
|
||||
│ ◄── WiFi connected (IP, status) │ → contacte le backend cloud
|
||||
│ │
|
||||
│ ─── Send device token ─────────► │
|
||||
│ ◄── Setup complete ──────────── │
|
||||
```
|
||||
|
||||
#### Méthode fallback : AP Mode + Captive Portal
|
||||
|
||||
Si le BLE n'est pas disponible (navigateur desktop, BLE désactivé), le robot peut créer son propre point d'accès WiFi.
|
||||
|
||||
1. Au premier démarrage (ou après un reset réseau), le Pi crée un hotspot WiFi : `Ti-Pote-XXXX` (où XXXX est un identifiant unique).
|
||||
2. L'utilisateur se connecte à ce hotspot depuis son téléphone/PC.
|
||||
3. Un captive portal s'ouvre automatiquement (ou manuellement à `http://192.168.4.1`).
|
||||
4. Le portail affiche les réseaux WiFi disponibles. L'utilisateur choisit son réseau et entre le mot de passe.
|
||||
5. Le robot se connecte au réseau, désactive le hotspot, et confirme via une page de succès.
|
||||
|
||||
```
|
||||
┌────────────────────┐
|
||||
│ Captive Portal │
|
||||
│ (page web locale) │
|
||||
│ │
|
||||
│ ┌──────────────┐ │
|
||||
│ │ WiFi: Maison │ │
|
||||
│ │ MDP: ******* │ │
|
||||
│ │ [Connecter] │ │
|
||||
│ └──────────────┘ │
|
||||
│ │
|
||||
│ ► Réseau 1 │
|
||||
│ ► Réseau 2 │
|
||||
│ ► Réseau 3 │
|
||||
└────────────────────┘
|
||||
```
|
||||
|
||||
Technologies utilisées : `hostapd` (AP mode), `dnsmasq` (DHCP + DNS redirect), serveur HTTP local Express/Fastify pour le portail.
|
||||
|
||||
### 4. Mode simulation (développement)
|
||||
|
||||
En phase de développement, le robot-client tourne sur un PC de dev au lieu du Pi physique. Les modules hardware (UART, WiFi, BLE, caméra) sont remplacés par des mocks :
|
||||
|
||||
- **UART** → mockée par le simulateur web (qui joue le rôle de l'ESP32 : capture micro via WebRTC, playback via Web Audio API)
|
||||
- **WiFi** → pas nécessaire en mode dev (le PC est déjà sur le réseau)
|
||||
- **BLE** → désactivé en mode dev
|
||||
- **Caméra** → remplacée par la webcam du PC ou des images statiques
|
||||
|
||||
Un flag d'environnement `ROBOT_MODE=simulator|physical` détermine quels modules sont chargés.
|
||||
|
||||
```bash
|
||||
# Mode développement (sur PC, avec le simulateur web comme frontend)
|
||||
ROBOT_MODE=simulator pnpm dev:robot
|
||||
|
||||
# Mode production (sur le Pi physique)
|
||||
ROBOT_MODE=physical pnpm start:robot
|
||||
```
|
||||
|
||||
### 5. Premier setup (onboarding)
|
||||
|
||||
Le flux de premier démarrage du robot :
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ PREMIER DÉMARRAGE │
|
||||
│ │
|
||||
│ 1. Power on │
|
||||
│ └─► LEDs en respiration violette (mode setup) │
|
||||
│ │
|
||||
│ 2. WiFi pas configuré ? │
|
||||
│ ├─► Active BLE advertising ("Ti-Pote-XXXX") │
|
||||
│ └─► Active AP mode en fallback (30s sans connexion BLE) │
|
||||
│ │
|
||||
│ 3. Credentials WiFi reçus (BLE ou captive portal) │
|
||||
│ └─► Tente la connexion WiFi │
|
||||
│ ├─► Succès → LEDs en vert │
|
||||
│ └─► Échec → LEDs en rouge, retour étape 2 │
|
||||
│ │
|
||||
│ 4. Connexion au backend cloud │
|
||||
│ └─► Envoie device_id + firmware version │
|
||||
│ ├─► Nouveau device → le backend génère un device token │
|
||||
│ └─► Device connu → reprise de session │
|
||||
│ │
|
||||
│ 5. Setup terminé │
|
||||
│ └─► LEDs en bleu, robot prêt │
|
||||
│ └─► "Bonjour, je suis Ti-Pote ! Je suis prêt." │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 6. OTA Updates
|
||||
|
||||
Le robot-client supporte les mises à jour over-the-air :
|
||||
|
||||
- **Self-update** : le backend notifie le client qu'une nouvelle version est disponible. Le client télécharge le nouveau package, le vérifie (checksum), et se redéploie (process manager type PM2 ou systemd).
|
||||
- **ESP32 update** : le Pi peut flasher l'ESP32 via UART (bootloader ESP32). Le firmware est téléchargé depuis le cloud et poussé vers l'ESP32.
|
||||
- **Rollback** : si le nouveau firmware ne démarre pas correctement (pas de heartbeat dans les 60 secondes), le système revient à la version précédente.
|
||||
|
||||
## Transition depuis le simulateur
|
||||
|
||||
Le `apps/simulator` actuel (React + Vite) reste en place comme outil de développement. Il joue désormais le rôle d'interface visuelle pour le robot-client en mode simulateur :
|
||||
|
||||
```
|
||||
Mode développement actuel :
|
||||
Browser (simulator) ──WebSocket──► Backend cloud
|
||||
|
||||
Mode développement futur :
|
||||
Browser (simulator) ──WebSocket──► robot-client (PC) ──WebSocket──► Backend cloud
|
||||
│
|
||||
(simule le Pi)
|
||||
|
||||
Mode production :
|
||||
ESP32 (hardware) ───UART──► robot-client (Pi) ──WebSocket──► Backend cloud
|
||||
```
|
||||
|
||||
Le simulateur web évolue pour devenir un "frontend de debug" du robot-client, plutôt qu'un client direct du backend. Cela permet de tester la logique complète du robot-client (wake word, bufferisation, mode dégradé, domotique) sans hardware.
|
||||
|
||||
## Dépendances système (Pi Zero 2 W)
|
||||
|
||||
```bash
|
||||
# Runtime
|
||||
node >= 20 LTS
|
||||
npm / pnpm
|
||||
|
||||
# Wake word
|
||||
python3
|
||||
pip: openwakeword
|
||||
|
||||
# WiFi AP mode
|
||||
hostapd
|
||||
dnsmasq
|
||||
|
||||
# Bluetooth
|
||||
bluez
|
||||
noble (npm, bindings BLE)
|
||||
|
||||
# Port série
|
||||
librairie native serialport (npm)
|
||||
|
||||
# Caméra
|
||||
libcamera-apps (rpicam-still, rpicam-vid)
|
||||
```
|
||||
|
||||
## Variables d'environnement
|
||||
|
||||
```bash
|
||||
# Mode de fonctionnement
|
||||
ROBOT_MODE=simulator|physical
|
||||
|
||||
# Backend cloud
|
||||
CLOUD_URL=wss://api.tipote.dev/ws/robot
|
||||
DEVICE_TOKEN=eyJ...
|
||||
|
||||
# Hardware (mode physical uniquement)
|
||||
UART_PORT=/dev/ttyS0
|
||||
UART_BAUDRATE=921600
|
||||
|
||||
# WiFi AP (mode physical uniquement)
|
||||
AP_SSID=Ti-Pote-XXXX
|
||||
AP_CHANNEL=6
|
||||
|
||||
# Domotique
|
||||
HUE_BRIDGE_IP=192.168.1.x
|
||||
HUE_API_KEY=xxxxx
|
||||
HOMEASSISTANT_URL=http://homeassistant.local:8123
|
||||
HOMEASSISTANT_TOKEN=xxxxx
|
||||
MQTT_BROKER_URL=mqtt://192.168.1.x:1883
|
||||
```
|
||||
@ -259,11 +259,51 @@ Le simulateur web affiche les timings de chaque étape :
|
||||
|
||||
Ces timings permettent d'identifier les goulots d'étranglement et d'optimiser la latence.
|
||||
|
||||
## Transition vers le robot-client
|
||||
|
||||
> **Important :** À partir de la Phase 1.5, le simulateur web n'est plus un client direct du backend cloud. Il devient un **frontend de debug** pour le robot-client (`apps/robot-client`).
|
||||
|
||||
### Avant (Phase 0-1)
|
||||
|
||||
```
|
||||
Browser (simulator) ──WebSocket──► Backend cloud (NestJS)
|
||||
```
|
||||
|
||||
Le simulateur se connecte directement au backend, exactement comme le ferait un robot. C'est simple et suffisant pour développer les premières features.
|
||||
|
||||
### Après (Phase 1.5+)
|
||||
|
||||
```
|
||||
Browser (simulator) ──WebSocket──► robot-client (PC, mode simulator) ──WebSocket──► Backend cloud
|
||||
```
|
||||
|
||||
Le robot-client tourne sur le PC du développeur en mode `ROBOT_MODE=simulator`. Le simulateur web lui envoie l'audio (comme l'ESP32 enverrait des frames UART). Le robot-client fait transiter vers le backend. Cela permet de tester la logique complète du robot-client (wake word, bufferisation, mode dégradé, domotique) sans hardware.
|
||||
|
||||
### En production
|
||||
|
||||
```
|
||||
ESP32-S3 ──UART──► robot-client (Pi Zero) ──WebSocket──► Backend cloud
|
||||
```
|
||||
|
||||
Le simulateur n'est plus utilisé. Le robot physique parle directement au robot-client via UART.
|
||||
|
||||
### Ce qui change pour le simulateur
|
||||
|
||||
Le simulateur web reste en place et conserve son interface actuelle (statut, bouton wake word, transcript, logs). Ce qui change :
|
||||
|
||||
- Il se connecte au **robot-client local** (ex: `ws://localhost:3001`) au lieu du backend cloud directement.
|
||||
- Il peut afficher des informations supplémentaires : état des bridges domotiques, statut WiFi, devices connectés.
|
||||
- Il sert aussi de frontend pour tester le **captive portal** en mode dev.
|
||||
|
||||
Voir [robot-client.md](robot-client.md) pour l'architecture du robot-client.
|
||||
|
||||
## Évolution progressive
|
||||
|
||||
Le simulateur évolue avec le projet :
|
||||
|
||||
**Phase 1 (MVP)** — Simulateur web avec micro + speaker uniquement. Bouton wake word. Transcript et logs. CLI avec mode texte interactif.
|
||||
**Phase 1 (MVP)** — Simulateur web avec micro + speaker uniquement. Bouton wake word. Transcript et logs. CLI avec mode texte interactif. Connexion directe au backend.
|
||||
|
||||
**Phase 1.5** — Le simulateur se connecte au robot-client (mode simulator) au lieu du backend. Ajout d'un panneau domotique (état des devices). Test du flux complet robot-client ↔ backend.
|
||||
|
||||
**Phase 2** — Ajout de la webcam pour simuler le module caméra. Interface pour afficher ce que le "robot voit". CLI avec mode audio (envoi de fichiers .wav).
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user