feat(notifier): route TTS to tablet when TABLET_TTS_ENABLED

When TABLET_URL and VOICE_API_KEY are set, the tablet handles TTS
via its ElevenLabs proxy — local speak() is skipped. Controlled
by TABLET_TTS_ENABLED (default true when tablet is configured).

- notifier.speak_locally() — gate used by all local speech paths
- llm._maybe_speak — no-op when tablet plays the voice
- modes._handle_reset — emits response event and skips local speak
  when tablet TTS is on; keeps spoken fallback otherwise

Tablet side in smart-home-tablet repo: /api/voice/tts endpoint +
VoiceOverlay audio playback (commit ba2e… pending).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Cosmo
2026-04-23 12:52:34 +00:00
parent e4e7529063
commit 584e21923c
4 changed files with 26 additions and 3 deletions

View File

@@ -16,16 +16,30 @@ from .config import log
TABLET_URL = os.getenv("TABLET_URL", "").rstrip("/")
VOICE_API_KEY = os.getenv("VOICE_API_KEY", "")
# Когда True — локальный speak() пропускается, голос идёт через планшет.
# По умолчанию включено если TABLET_URL и VOICE_API_KEY заполнены;
# явно отключить: TABLET_TTS_ENABLED=false
TABLET_TTS_ENABLED = (
bool(TABLET_URL and VOICE_API_KEY)
and os.getenv("TABLET_TTS_ENABLED", "true").lower() in ("true", "1", "yes", "on")
)
# Переиспользуем HTTP сессию (keep-alive) для минимума latency
_session = requests.Session()
_ENABLED = bool(TABLET_URL and VOICE_API_KEY)
if _ENABLED:
print(f"🔔 Notifier: планшет {TABLET_URL}")
tts_where = "планшет" if TABLET_TTS_ENABLED else "локально"
print(f"🔔 Notifier: события → {TABLET_URL}, TTS: {tts_where}")
else:
print("🔕 Notifier: отключён (нет TABLET_URL или VOICE_API_KEY в .env)")
def speak_locally() -> bool:
"""True если локальный speak() должен работать (TTS на этой машине)."""
return not TABLET_TTS_ENABLED
def _send(event: str, **payload):
if not _ENABLED:
return