| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- # -*- coding: utf-8 -*-
- """
- Client/Satellite-Konfiguration.
- """
- from dataclasses import dataclass, field
- @dataclass
- class InputMicrophone:
- """Ein einzelnes Mikrofon im Multi-Mic-Mix.
- `device` ist der PulseAudio/PipeWire-Source-Name, z.B.
- "alsa_input.usb-Generic-00.mono-fallback".
- """
- device: str = ""
- enabled: bool = True
- label: str = ""
- @dataclass
- class OutputSpeaker:
- """Ein einzelner Lautsprecher im Multi-Speaker-Verbund.
- `device` ist der PulseAudio/PipeWire-Sink-Name, z.B.
- "alsa_output.usb-Generic-00.analog-stereo".
- """
- device: str = ""
- enabled: bool = True
- volume: int = 80
- @dataclass
- class ServerConnectionConfig:
- """Server-Verbindungs-Konfiguration."""
- host: str = "localhost"
- port: int = 2101
- reconnect_interval_seconds: float = 5.0
- connection_timeout_seconds: float = 10.0
- @dataclass
- class ClientAudioConfig:
- """Audio-Konfiguration für den Client."""
- # Sprach-Audio (Wakeword-Erkennung)
- sample_rate: int = 16000
- channels: int = 1
- bit_depth: int = 16
- # Musik-Wiedergabe (sollte mit Server übereinstimmen)
- music_sample_rate: int = 44100 # 44.1kHz - Standard für die meisten Geräte
- music_channels: int = 2
- music_bit_depth: int = 16
- # Geräte
- input_device: str | None = None
- output_device: str | None = None
- buffer_size: int = 1024
- # System-Lautstärke (ALSA/PulseAudio, 0-100)
- output_volume: int = 80
- output_muted: bool = False
- input_volume: int = 80
- input_muted: bool = False
- # ALSA Mixer Controls (leer = Auto-Detect)
- output_mixer_control: str = ""
- input_mixer_control: str = ""
- # Multi-Speaker (PulseAudio Combined Sink)
- # Wenn ≥2 Eintraege enabled sind, wird ein Combined-Sink erstellt
- # und der Audio-Player auf diesen umgelenkt. Bei 0 oder 1 Eintrag
- # bleibt der klassische Single-Output-Pfad aktiv.
- output_speakers: list[OutputSpeaker] = field(default_factory=list)
- output_combine_sink_name: str = "trixy_combined"
- # Multi-Mic (PulseAudio null-sink + loopback-Mix)
- # Wenn ≥2 Eintraege enabled sind, wird ein virtueller gemischter
- # Input erstellt und der Default-Source darauf gesetzt. Bei 0 oder
- # 1 Eintrag bleibt der klassische Single-Input-Pfad aktiv.
- input_microphones: list[InputMicrophone] = field(default_factory=list)
- input_mix_sink_name: str = "trixy_mics_combined"
- @dataclass
- class ClientWakewordConfig:
- """Wakeword-Konfiguration für den Client."""
- models: list[str] = field(default_factory=lambda: ["custom", "system_command"])
- threshold: float = 0.5
- model_directory: str = "models/wakeword"
- use_onnx: bool = True
- enabled: bool = True
- silence_timeout_seconds: float = 3.0
- max_recording_seconds: float = 60.0
- no_speech_timeout_seconds: float = 5.0
- pre_buffer_seconds: float = 0.5
- wakeword_cooldown_seconds: float = 3.0
- @dataclass
- class SatelliteIdentityConfig:
- """Satelliten-Identität."""
- room: str = ""
- alias: str = ""
- mac_address: str = "" # Wird automatisch ermittelt wenn leer
- @dataclass
- class ClientLoggingConfig:
- """Logging-Konfiguration für den Client."""
- level: str = "INFO"
- log_directory: str = "logs"
- @dataclass
- class LEDConfig:
- """WS2812/NeoPixel LED-Konfiguration fuer Satellites."""
- enabled: bool = False
- gpio_pin: int = 18 # BCM Pin (18 = PWM0, empfohlen)
- led_count: int = 1 # 1, 7, 12
- type: str = "single" # "single" | "jewel_7" | "ring_12"
- brightness: int = 80 # 0-255 globale Helligkeit
- states: dict = field(default_factory=dict) # Pro Zustand: {color, animation, speed}
- @dataclass
- class ClientConfig:
- """Haupt-Client-Konfiguration."""
- server: ServerConnectionConfig = field(default_factory=ServerConnectionConfig)
- audio: ClientAudioConfig = field(default_factory=ClientAudioConfig)
- wakeword: ClientWakewordConfig = field(default_factory=ClientWakewordConfig)
- identity: SatelliteIdentityConfig = field(default_factory=SatelliteIdentityConfig)
- logging: ClientLoggingConfig = field(default_factory=ClientLoggingConfig)
- led: LEDConfig = field(default_factory=LEDConfig)
- config_port: int = 2105
- config_listener_enabled: bool = True
- assets_directory: str = "assets"
- profile: str = "default"
|