# Extra ioBroker State-Prefixes (zusätzlich zu den enum-basierten Geräten des Adapters) # extra_state_prefixes: # - "0_userdata.0" # Gruppen (Satelliten-Sets für Announcements/Steuerung) liegen in der "groups"/ # "group_satellites"-Tabelle, nicht mehr hier — siehe Admin-UI / GetGroups/CreateGroup/ # SetGroupSatellites gRPC (#56, war vorher raumbasiert über diesen Config-Block). udp: host: "0.0.0.0" # Bind-Adresse des Servers port: 7775 # UDP-Port für Audio-Streaming und Registrierung advertise_host: "" # Leer = eigene IP automatisch ermitteln discovery_topic: "hannah/server" # Retained MQTT-Topic für Satellit-Discovery mqtt: host: "192.168.1.1" # IP-Adresse des MQTT-Brokers port: 1883 username: "mqtt" password: "IHR_MQTT_PASSWORT" # Eingehende Audio-Streams: {device} wird automatisch aus dem Topic extrahiert topic_audio_in: "hannah/+/audio" # Ausgehende Topics: {device} wird durch den Gerätenamen ersetzt topic_intent_out: "hannah/{device}/intent" topic_text_out: "hannah/{device}/text" # STT-Ergebnis (optional) topic_answer_out: "hannah/{device}/answer" # Textantwort auf Fragen topic_error_out: "hannah/{device}/error" # Fehler topic_text_command_in: "0_userdata/0/hannah/set/textCommand" # Satellit-Status (retained, von Hannah publiziert) # hannah/satellite/{device}/status → idle | listening | processing | speaking # hannah/satellite/{device}/online → true | false (LWT vom Satellit) # Fahrzeug-Integration: wird über die "cars"-Tabelle verwaltet (eigenes Modell + # user_to_car-Pivot für Owner, #115), nicht mehr hier — siehe Admin-UI / GetCars/ # CreateCar/UpdateCar/DeleteCar gRPC. # BLE Indoor-Lokalisierung (optional) # Satelliten scannen passiv BLE-Advertisements und melden RSSI per MQTT. # Hannah bestimmt per „stärkster RSSI gewinnt" den Aufenthaltsort jedes Tags. # Ergebnis: hannah/ble/{label}/location (MQTT, retained) + hannah.0.ble.{label}.* (ioBroker Adapter) # ble: # stale_timeout: 30 # Sekunden ohne Report → Tag gilt als "nicht sichtbar" # Tag-Liste (mac_address/label/user_id) liegt in der "ble_tags"-Tabelle (eigenes Modell, #115), nicht hier. grpc: host: "0.0.0.0" # Bind-Adresse des gRPC-Servers port: 50051 # Standard gRPC-Port enforce_protocol_version: false # #60: Mismatch/fehlende x-proto-version-Metadata ablehnen statt nur loggen — erst aktivieren, wenn ALLE Clients umgestellt sind enforce_compat_version: false # #217: wie oben, aber pro Message (x-compat-version) statt global — erst aktivieren, wenn ALLE Clients umgestellt sind asset_server: url: "https://hannah-asset.example.com" token: "IHR_ASSET_TOKEN" user_registry: sync_interval: 60 # Sekunden zwischen ioBroker-Abfragen satellite_manager: seed_ttl_days: 7 # Provisionierte, aber nie gepairte Satelliten-Seeds nach X Tagen löschen restart_interval_days: 7 # Präventiver Rejuvenation-Restart (#162) — grobe Schätzung, anpassen sobald Heap-Trend-Daten aus #150 vorliegen residents: topic_prefix_read: "residents/0/roomie" # ioBroker → Hannah (subscribe) state_key: "presence/state" # Datenpunkt-Suffix unterhalb von /{name}/ hannah_roomie: "hannah" state_home: 1 # 🏠 zu Hause state_away: 0 # ⏸️ Abwesend iobroker: # Pfad-Prefix der virtualDevice-Geräte in ioBroker virtual_device_prefix: "javascript.0.virtualDevice" feedback_timeout: 3.0 # Sekunden bis "Gerät antwortet nicht" # State-Namen der Geräte liegen in den DB-Settings (Kategorie "iobroker", Setting # "state_names"), nicht mehr hier. Wird bei leerer DB automatisch mit generischen # Defaults befüllt (SettingsManager.seed_defaults(), #114) — siehe Admin-UI / # GetSettings/UpdateConfig gRPC zum Anpassen. tts: # Backend: piper (lokal/offline) | azure | polly # Piper ist immer der Fallback wenn ein Cloud-Backend nicht erreichbar ist. backend: piper # Piper — lokal, kein Internet nötig (auch als Fallback für Cloud-Backends) model: "/home/pi/de_DE-kerstin-low.onnx" # leer = TTS deaktiviert length_scale: 1.0 # Sprechgeschwindigkeit (>1 = langsamer) noise_scale: 0.667 noise_w: 0.8 # Azure Cognitive Services TTS (backend: azure) # Freies Tier: 500.000 Zeichen/Monat # azure_key: "..." # azure_region: westeurope # azure_voice: de-DE-KatjaNeural # Alternativen: de-DE-ConradNeural # Amazon Polly (backend: polly) # polly_key_id: "..." # polly_secret_key: "..." # polly_region: eu-central-1 # polly_voice: Vicki # Alternativen: Daniel # polly_engine: neural # Disk-Cache für Cloud-Synthesen (Phrasen werden nach erster Synthese gespeichert) cache_dir: .tts_cache # Standard-Phrasen beim Start vorsynthetisieren — danach ohne Cloud-Aufruf verfügbar warm_phrases: - "Ich habe dich nicht verstanden." - "Tut mir leid, ich weiß nicht was du meinst." - "Es wurden keine Geräte gefunden." confirmation_sound: "/home/pi/confirmation.wav" # leer = synthetisiert voice_id: enabled: false # true = Speaker-ID aktiv (Core löst Sprecher selbst auf, #210) base_url: "http://localhost:8765" # HTTP-Base-URL des Voice-ID-Diensts (voiceid/) timeout_sec: 3.0 stt: model: "base" # tiny | base | small | medium | large-v3 (lokales Fallback) language: "de" device: "cpu" # cpu | cuda compute_type: "int8" # int8 (schnell, Pi) | float16 (GPU) | float32 # Mindest-Confidence: unterhalb wird kein Intent gesendet no_speech_threshold: 0.6 # Remote-STT: faster-whisper-server auf einem stärkeren Rechner (empfohlen) # Wenn gesetzt, wird Remote bevorzugt — bei Fehler automatischer Fallback auf lokales Modell. # Setup: https://github.com/fedirz/faster-whisper-server # remote_url: "http://192.168.1.2:8000" # remote_model: "Systran/faster-whisper-large-v3" # remote_timeout: 15.0 # Sekunden (beim ersten Request wird das Modell geladen) # Azure Speech-to-Text (alternativ zu faster-whisper) # azure_key: "..." # azure_region: germanywestcentral audio: sample_rate: 16000 sample_width: 2 # Bytes pro Sample (2 = 16-bit) channels: 1 # Format des base64-Payloads: "raw_pcm" | "wav" # "auto" versucht WAV-Header zu erkennen, fällt auf raw_pcm zurück format: "auto" # NLU-Wortlisten (turn_on_words, turn_off_words, category_words, query_words, # temperature_units, percentage_units) liegen komplett in den DB-Settings (Kategorie # "nlu"), nicht mehr hier. Wird bei leerer DB automatisch mit generischen Defaults # befüllt (SettingsManager.seed_defaults(), #114) — siehe Admin-UI / GetSettings/ # UpdateConfig gRPC zum Anpassen. llm: enabled: false # true = LLM aktiv (Smalltalk, Notification-Reformulierung) provider: ollama # ollama | openai_compat | openai | groq | mistral base_url: "http://localhost:11434" # Ollama lokal; openai_compat: http://host:port/v1 # api_key: "" # Nur für Cloud-Anbieter (OpenAI, Groq, Mistral) model: "llama3.2" # Ollama-Modell, Cloud-Modell-ID, oder custom Modelfile-Name timeout: 60 # Sekunden bis LLM-Timeout max_tokens: 2048 # Persönlichkeit (optional) — weglassen wenn die Persönlichkeit im Modell eingebaut ist. # # Ollama Modelfile-Alternative: ollama create hannah -f Hannah.mf # → System-Prompt ist dann fest im Modell, kein Eintrag hier nötig. # → Funktioniert nur mit selbst gehostetem Ollama. # # Für Cloud-Anbieter (OpenAI, Groq, Mistral) oder Standard-Modelle: # system_prompt liegt in den DB-Settings (Kategorie "llm", Key "system_prompt"), # nicht mehr hier — siehe Admin-UI / GetSettings/UpdateConfig gRPC. # Antworten werden per TTS vorgelesen — kurze Sätze, kein Markdown, keine Emojis. memory: db: "memory.db" # SQLite-Datei für Langzeitgedächtnis (relativ zum Arbeitsverzeichnis, # im Docker-Image z.B. auf "/app/data/memory.db" zeigen für Persistenz) recent_limit: 10 # Wie viele Erinnerungen in den System-Prompt injiziert werden # hannah.db (Settings/Trigger/Routines/Rooms/User-Registry) hat keinen Config-Key — # Pfad kommt ausschließlich aus der Env-Var DB_PATH (Default: "hannah.db", relativ # zum Arbeitsverzeichnis; siehe hannah/utils/db.py). Im Docker-Image auf # "/app/data/hannah.db" vorbelegt. # Activity-Log (#220): welcher Kanal hat wann was erkannt/getan. Separate MySQL-DB, # bewusst getrennt von hannah.db (SD-Karten-Last auf dem Pi + erwartete Schreiblast). # Kein "host" gesetzt = Feature deaktiviert, kein Logging (nicht Core-kritisch). # activity_log: # host: "192.168.1.X" # port: 3306 # user: "hannah_activity" # password: "IHR_MYSQL_PASSWORT" # database: "hannah_activity" # audio_dir: "activity_audio" # WAV-Ordner (relativ zum Arbeitsverzeichnis), wird selbst angelegt