# -*- coding: utf-8 -*- """ Wakeword-bezogene Netzwerk-Befehle. """ from dataclasses import dataclass, field from datetime import datetime from trixy_core.network.cmd.base import CommandMessage @dataclass class WakewordDetected(CommandMessage): """ Wakeword-Erkennung durch einen Satellite. Wird vom Satellite zum Server gesendet, wenn ein Wakeword erkannt wurde. Der Server führt dann die Arbitrierung durch (höchstes Audio-Level gewinnt). Enthält auch die Audio-Chunks mit dem Wakeword für Stimmenerkennung. """ satellite_id: str = "" wakeword_type: str = "" # "custom" oder "system_command" wakeword_model: str = "" # Modell-Name (z.B. "hey_jarvis") confidence: float = 0.0 # Erkennungs-Confidence audio_level: float = 0.0 # RMS-Level für Arbitration audio_chunks: list[str] = field(default_factory=list) # Hex-encodierte Chunks timestamp: str = "" # ISO-Format Timestamp client_session_id: str = "" # Vom Client generierte Session-ID @dataclass class WakewordSelected(CommandMessage): """ Satellite wurde für die Konversation ausgewählt. Wird vom Server zum ausgewählten Satellite gesendet. Enthält die Server-generierte Session-ID. """ session_id: str = "" # Server-generierte Session-ID conversation_id: str = "" # Konversations-ID (= session_id) start_streaming: bool = True # Audio-Streaming starten max_duration_seconds: float = 60.0 # Max. Aufnahmedauer silence_timeout_seconds: float = 3.0 # Stille-Timeout @dataclass class WakewordAbort(CommandMessage): """ Wakeword-Erkennung abbrechen. Wird gesendet, wenn ein anderer Satellite ausgewählt wurde oder die Erkennung abgebrochen werden soll. """ reason: str = "" resume_detection: bool = True selected_satellite_id: str = "" # Welcher Satellite wurde stattdessen ausgewählt @dataclass class RecordingComplete(CommandMessage): """ Audio-Aufnahme abgeschlossen. Wird vom Satellite zum Server gesendet, wenn die Aufnahme beendet wurde (durch Stille oder Timeout). """ session_id: str = "" audio_data: str = "" # Hex-encodierte Audio-Daten duration_seconds: float = 0.0 ended_by: str = "" # "silence", "timeout", "user", "error" speech_detected: bool = True # Wurde Sprache erkannt? peak_level: float = 0.0 # Peak Audio-Level vad_stats: dict = field(default_factory=dict) # VAD-Statistiken @dataclass class RecordingAck(CommandMessage): """ Bestätigung für empfangene Aufnahme. Wird vom Server zum Satellite gesendet nach Empfang der Aufnahme. """ session_id: str = "" received_bytes: int = 0 processing: bool = True # Wird verarbeitet @dataclass class FollowUpRequest(CommandMessage): """ Rückfrage vom Server an den Satellite. Der Assistent stellt eine Rückfrage und erwartet eine Antwort. """ session_id: str = "" question: str = "" # Rückfrage-Text audio_data: str = "" # Hex-encodiertes TTS-Audio (optional) follow_up_number: int = 0 # Nummer der Rückfrage timeout_seconds: float = 60.0 # Timeout für Antwort audio_duration: float = 0.0 # TTS-Audio-Dauer in Sekunden (fuer Wait) @dataclass class FollowUpResponse(CommandMessage): """ Antwort auf eine Rückfrage. Wird vom Satellite zum Server gesendet. """ session_id: str = "" audio_data: str = "" # Hex-encodierte Audio-Antwort duration_seconds: float = 0.0 follow_up_number: int = 0 # Welche Rückfrage wird beantwortet speech_detected: bool = True @dataclass class ConversationEnd(CommandMessage): """ Konversation beenden. Kann vom Server oder Satellite gesendet werden. """ session_id: str = "" reason: str = "" # "completed", "timeout", "cancelled", "error" final_response: str = "" # Letzte Antwort des Assistenten audio_data: str = "" # Hex-encodiertes TTS-Audio (optional) @dataclass class AssistantResponse(CommandMessage): """ Assistenten-Antwort. Wird vom Server zum Satellite gesendet mit der Antwort. """ session_id: str = "" text: str = "" # Antwort-Text audio_data: str = "" # Hex-encodiertes TTS-Audio is_final: bool = True # Ist dies die finale Antwort? has_follow_up: bool = False # Folgt eine Rückfrage? @dataclass class TranscriptionResult(CommandMessage): """ Transkriptions-Ergebnis. Wird vom Server zum Satellite gesendet mit dem transkribierten Text. """ session_id: str = "" text: str = "" # Transkribierter Text confidence: float = 0.0 # Transkriptions-Confidence language: str = "de" # Erkannte Sprache is_final: bool = True # Finale Transkription? @dataclass class IntentResult(CommandMessage): """ Intent-Erkennungs-Ergebnis. Wird vom Server gesendet mit dem erkannten Intent. """ session_id: str = "" intent: str = "" # Erkannter Intent confidence: float = 0.0 entities: dict = field(default_factory=dict) # Extrahierte Entities handled_by: str = "" # Welches Plugin/Service handhabt den Intent @dataclass class TextInput(CommandMessage): """ Text-Eingabe vom Client (Keyboard-Input). Wird als Alternative zu Spracheingabe verwendet. Startet eine neue Conversation oder setzt eine bestehende fort. Flow: 1. Client sendet TextInput an Server 2. Server erstellt/fortsetzt Conversation 3. Server emittiert speech_recognized Event 4. NLP verarbeitet Text 5. Bei Follow-Up: Server sendet FollowUpRequest zurück """ satellite_id: str = "" text: str = "" # Eingegebener Text session_id: str = "" # Leer = neue Session, sonst Fortsetzung room_id: str = "" # Raum-ID language: str = "de" # Sprache is_follow_up: bool = False # Ist dies eine Antwort auf Follow-Up? follow_up_number: int = 0 # Welche Rückfrage wird beantwortet @dataclass class TextInputAck(CommandMessage): """ Bestätigung für Text-Eingabe. Wird vom Server zum Client gesendet nach Empfang der Text-Eingabe. """ session_id: str = "" # Zugewiesene Session-ID received: bool = True # Erfolgreich empfangen error: str = "" # Fehlermeldung falls nicht erfolgreich @dataclass class WakewordPause(CommandMessage): """Wakeword-Erkennung extern pausieren (Server → Satellite).""" reason: str = "" @dataclass class WakewordResume(CommandMessage): """Extern pausierte Wakeword-Erkennung fortsetzen (Server → Satellite).""" pass @dataclass class WakewordControlStop(CommandMessage): """Wakeword-Erkennung komplett stoppen (Server → Satellite).""" reason: str = "" @dataclass class WakewordControlStart(CommandMessage): """Wakeword-Erkennung starten (Server → Satellite).""" pass