↓ Перейти к основному содержимому

Hermes и Яндекс Станция: сообщения и команды Алисе прямо из чата

·546 слов·3 минут·
logo

Хотелось отправлять короткие объявления на Яндекс Станцию прямо из чата с Hermes. Не генерировать аудиофайл, не поднимать отдельный медиасервер, а просто написать агенту:

Скажи в станции: через десять минут пора выходить

Hermes вызывает локальный скрипт, Станция ставит музыку на паузу и произносит фразу голосом Алисы. После этого возвращает прежнюю громкость и продолжает воспроизведение.

Пока тестировал протокол, выяснилось, что тем же способом можно передавать Алисе обычные команды:

Команда Алисе: включи свет

Свет действительно включился. Значит, через Hermes можно управлять устройствами, запускать музыку, ставить таймеры и выполнять сценарии умного дома без фразы “Алиса” рядом с колонкой.

Как это работает
#

Скрипт подключается к колонке по локальному протоколу Glagol через WSS на порту :1961. Короткоживущий conversationToken он получает через Quasar API, хранит в .env около 25 минут и затем обновляет.

Полный цикл выглядит так:

  1. Прочитать текущую громкость и состояние плеера.
  2. Поставить музыку на паузу.
  3. Временно установить громкость 80%.
  4. Передать фразу в сценарий Алисы repeat_phrase.
  5. Дождаться стабильного состояния IDLE.
  6. Вернуть исходную громкость.
  7. Продолжить музыку, если она играла до сообщения.

Если колонка до команды молчала, скрипт не отправляет “продолжить”. Иначе Алиса может внезапно включить радио из простоя. При ошибке соединения скрипт всё равно пытается вернуть громкость и воспроизведение.

Glagol — недокументированный протокол Яндекса. После обновления прошивки его поведение может измениться.

Установка
#

Я сделал форк проекта Realmagnum/yandex-station-speak и адаптировал его под Hermes. Готовый вариант лежит на GitHub.

git clone https://github.com/tatarinovms/yandex-station-speak-from-hermes.git
cd yandex-station-speak-from-hermes
./install.sh

Установщик копирует скилл в активный каталог ${HERMES_HOME:-$HOME/.hermes}, создаёт .env с правами 0600 и отдельное Python-окружение для авторизации. Для основной озвучки достаточно Python 3.10+, а helper получения MUSIC_TOKEN требует Python 3.12+.

Получаем MUSIC_TOKEN
#

Для Glagol нужен токен Яндекс Музыки. В репозитории есть helper с OAuth Device Flow, поэтому пароль и код двухфакторной авторизации не приходится вводить в терминале:

"${HERMES_HOME:-$HOME/.hermes}/skills/smart-home/yandex-station-speak/.token-venv/bin/python" \
  "${HERMES_HOME:-$HOME/.hermes}/skills/smart-home/yandex-station-speak/get_music_token.py"

Скрипт покажет страницу Яндекса и короткий код. После подтверждения MUSIC_TOKEN сразу попадёт в .env и не появится в выводе терминала.

Дальше получаем параметры колонки:

cd "${HERMES_HOME:-$HOME/.hermes}/skills/smart-home/yandex-station-speak"
python3 scripts/tts_dialog.py --list-devices

Из вывода переносим в .env значения DEVICE_ID и DEVICE_PLATFORM. Там же указываем статический IP Станции из DHCP leases роутера:

DEVICE_ID=0123456789ABCDEF
DEVICE_PLATFORM=yandexmini
STATION_IP=192.168.0.50

Проверка и использование
#

Проверяем напрямую:

"${HERMES_HOME:-$HOME/.hermes}/skills/smart-home/yandex-station-speak/speak.sh" \
  'Проверка. Озвучка Яндекс Станции подключена.'

В SKILL.md прописан триггер “скажи в станции”. После установки достаточно отправить Hermes обычное сообщение:

Скажи в станции: ужин готов

Для фразы поверх музыки у speak.sh есть флаг --nopause, но в обычном режиме мне больше нравится полный цикл с паузой и возвратом громкости.

Выполняем команды Алисы
#

Для команд из агента безопасно передавать текст через --file. Сначала запишите команду в отдельный файл (пример для агента), а потом выполните:

"${HERMES_HOME:-$HOME/.hermes}/skills/smart-home/yandex-station-speak/command.sh" \
  --file /root/.hermes/cache/scratch/alice-command.txt

Для ручного запуска можно использовать прямой текст, но в агенте пользовательский текст не должен попадать в shell-строку:

# Агент: записать команду в файл, затем вызвать фиксированный скрипт
cat > /root/.hermes/cache/scratch/alice-command.txt <<'EOF'
Команда Алисе: выключи свет
EOF
"${HERMES_HOME:-$HOME/.hermes}/skills/smart-home/yandex-station-speak/command.sh" \
  --file /root/.hermes/cache/scratch/alice-command.txt
rm -f /root/.hermes/cache/scratch/alice-command.txt

Скрипт передаёт фразу через Glagol-команду sendText. Для Станции это похоже на обычное голосовое обращение. Набор работающих команд зависит от модели колонки, аккаунта Яндекса и поддержки конкретной команды через sendText.

Команды света, музыки и таймеров агент выполняет сразу. Для замков, ворот, сигнализации, нагревателей, духовки и сценариев с неизвестным составом действий в SKILL.md прописано обязательное подтверждение. Это ограничение агента, а не самого command.sh.

Теперь домашний ИИ-агент умеет не только докричаться до всей квартиры, но и попросить Алису что-нибудь сделать.

Вы восхитительны!

Related