Перейти к содержанию

Архитектура

Участники

Компонент Где Роль
Станция Мини колонка, root слово активации «Алиса» (встроенный спотер, заменить нельзя), микрофоны, динамик
Мост alice-ha LXC-контейнер эмулирует облако Яндекса (quasard) и переводит запросы в REST HA
Home Assistant отдельный хост stt.vosk → Assist (без LLM) → tts.piper
Интеграция noema_alice HA media_player для колонки: TTS, файлы, радио, громкость

Голосовой запрос

  1. Колонка слышит «Алиса» и по WSS :443 отправляет звук на uniproxy.alice.yandex.net. Домен в /etc/hosts колонки указывает на мост.
  2. Мост отправляет PCM в POST /api/stt/stt.vosk и получает текст.
  3. Текст уходит в POST /api/conversation/process, ответ — текст.
  4. Мост синтезирует его через POST /api/tts_get_url (tts.piper), забирает звук и отдаёт колонке.

Код этого тракта: bridge/ha.py и патч bridge/apply_ha.py.

Почему /etc/hosts, а не DNS роутера

  • Адрес uniProxyUrl в quasar.cfg задаёт только фоновое соединение. Голос идёт на адрес из облачных настроек (/data/quasar/data/user_config.dat), которые облако перезаписывает.
  • Если подменить один uniproxy, колонка зацикливается на обновлении: каждые ~15 секунд «Updater is ready to apply update», кольцо мигает, голос не обрабатывается.
  • Когда все домены Яндекса, включая quasar.yandex.net, ведут на мост, он отвечает на check_updates «обновлений нет», и цикл прекращается.
  • Колонка читает /etc/hosts раньше своего DNS-резолвера unbound. nslookup файл игнорирует и показывает настоящие адреса, это нормально. Правки в /etc переживают перезагрузку.

Управление колонкой из HA (glagol)

Колонка игнорирует звук, который мост присылает без её запроса. Поэтому:

  1. Мост выписывает токен glagol сам (/quasar.yandex.net/glagol/token), так как quasar.yandex.net ведёт на него.
  2. Мост подключается к локальному API колонки wss://<станция>:1961 и отправляет sendText.
  3. Колонка пересылает текст мосту как обычный запрос. Мост узнаёт служебную фразу и отвечает нужным звуком или директивой плееру.

Служебные фразы: «повтори за мной …» (информер) и «включи поток <ключ>» (плеер). Плееру команды stop, play, next, prev, setVolume отправляются в glagol напрямую.

Радио

В GStreamer колонки нет декодера ICY (Missing decoder: ICY internet radio в mediad.log). Мост забирает поток сам с Icy-MetaData: 0, следует редиректам и отдаёт чистый mp3 через /_stream. Колонке интернет не нужен. Внешние адреса, кроме частных сетей и homeassistant, мост оборачивает автоматически.

Ограничения

  • Слово активации менять нельзя.
  • media_player не знает реального состояния колонки: состояние и громкость оптимистичные, обратной связи от glagol нет.
  • STATION_IP в мосту один на всех, так что одна колонка на мост.
  • Сброс колонки кнопками стирает /data (dropbear, блокировку OTA, бэкапы).
  • Интеграция AlexxIT/YandexStation с этой колонкой больше не работает: облачные токены glagol колонка проверяет у моста.