Использование в Home Assistant двух движков голосового управления одновременно
Или как прикрутить LLM-ку для неожиданных кеков, не трогая при этом локальный движок.
Статья предполагает, что читатель уже настроил себе голосового помощника вместе с локальной инсталляцией whisper+piper или silero+vosk, управляет всем голосом и у него всё хорошо(например описано тут. И ещё немного тут. И ещё в куче статей по всему интернету). Но иногда читатель хочет немного пошалить)))
Подробности под катом
Для начала про выбор самой LLM-ки. Я остановился на Gigachat от Сбера — для физлиц через API бесплатно даётся 900 000 токенов в год, чего вполне достаточно для того, чтобы изредка позадавать глупых вопросов умной колонке. Возможно в будущем что-то изменится — там посмотрим, а пока сойдёт. В любом случае, метода +- универсальна и должна работать абсолютно с любыми движками.
Для интеграции используем плагин gigachain. Ставится через HACS. Для настройки нужно будет получить API ключ с developers.sber.ru. Регистрируемся, жмём там на GigaChat API, будет предложено создать новый проект — Называем как угодно
В проекте жмём на «Получить ключ» и в открывшейся форме на поле Authorization key — ещё раз «Получить ключ»
После чего в самом Home Assistant ходим в Настройки->Устройства и службы->Добавить интеграцию
Находим в списке Gigachain и жмакаем.
В открывшемся поле вставляем полученный ранее API ключ и жмём «Подтвердить». Если всё хорошо — в списке устройств появится Gigachain с настроенным Gigachat.
Дальше нам нужно его немного поднастроить. Жмём шестерёнку.
По умолчанию в открывшейся форме предзабит промт, направленный на использование гигачата непосредственно для управления умным домом. Нас этот функционал не интересует. Пишем что-то своё.
Модель выбираем Gigachat, температуру на свой вкус(чем выше — тем сильнее железка будет бредить). Остальные галки можно поснимать — они нам не нужны.
Дальше нам нужно создать нового голосового ассистента, который будет использовать в качестве движка гигачат, а не HA. Идём в Настройки->Голосовые Ассистенты->Добавить Ассистента
Вписываем название, в качестве движка диалоговой системы выбираем свежесозданный gigachat.
Галку «Предпочитать локальную обработку команд» снимаем.
Также для своей домашней конфигурации я сделал отдельный инстанс vosk, без ограничений словаря(и назвал его vosk_uncapped), соотв. на скрине выбран он. Вы у себя выбираете ваш движок(обычно это piper).
Синтез речи так же ставим, тот же, что для локального помощника. Сохраняем
Ну и наконец то, ради чего статья писалась. Создаём автоматизацию, которая может временно(на один запрос) сменить голосового помощника для колонки, к которой обратились.
Идём в Настройки->Автоматизации и Сцены->Создать новую автоматизацию.
В открывшейся форме жмём три точки ->Текстовый редактор
И вставляем в редактор эту простыню
Аналогичным образом добавляем вторую автоматизацию.
Чуть больше подробностей о том, что тут происходит.
По сути, вся фишка в том, что выбор голосового помощника — это не только общесистемная настройка(в виде выбора по умолчанию), но ещё и селектор в параметрах каждой умной колонки.
И его значением можно управлять в скриптах и автоматизациях. Ну а всё остальное делает магия jinja шаблонов
Вот так например мы переключаем голосового ассистента на гигачат. С помощью jinja из trigger.device_id (системная переменная, в которую кладётся device_id устройства, от которого запустилась автоматизация) выдирается entity_id интересующего нас поля ввода. Да, с помощью регулярки, способа лучше я не нашёл. Но работает довольно стабильно.
А вот так мы выдёргиваем из него же entity_id assist-pipeline-а для запуска диалога именно на той колонке, к которой обратились изначально.
Ну а вот так мы во второй автоматизации ждём, пока колонка не перестанет говорить
trigger.device_id у нас больше нет(т.к. вторая автоматизация триггерится шаблоном), поэтому мы находим entity_id со значением gigachat, от него получаем device_id, а уже от него по прежней схеме получаем нужный нам entity_id assist_satellite.что-то-там
В идеальном мире всё это должно работать в рамках одной автоматизации, но к сожалению по какой-то причине если действие запуска диалога не последнее в списке — окно для голосового ввода обрубается через несколько секунд. Поэтому приходится одной автоматизацией менять движок на гигачат и запускать диалог, а другой — ловить устройство, которому прописали гигачат и после задержки менять всё обратно. При том я не исключаю что это мой личный баг. У меня core инсталляция версии 2025.10.3 и тестировалось всё на кривой китайской колонке. В любом случае, принцип, думаю, понятен и собрать в одну автоматизацию не составит труда.
В результате получается что-то такое.
Возможно, галочку «цензура» стоит вернуть))) На всякий случай — осуждаю, никому не рекомендую следовать озвученной инструкции.

Вероятно, у многих примерно к этому месту возник вопрос: «Прикольно, но зачем весь этот велосипед городить?» Идея тут в том, именно управление умным домом остаётся завязанным на локальную инсталляцию, при отвале интернета он даже не почувствует что что-то пошло не так. Также в отличии от встроенного в HA механизма фоллбэка через галочку «Предпочитать локальную обработку команд» мы имеем 100% гарантию, что запрос не уйдёт вовне кроме случаев, когда мы сами этого захотим и специально объявим свои намерения через выделенную голосовую команду. Распознавание речи тоже работает строго локально, голосовые семплы никуда не отправляются. Можно наслаждаться остатками приватности))
Ну и раз уж мы собрались на ресурсе, где принято рассказывать про всякие железки — пара слов про колонку, мелькнувшую на видео.
Это вот она и она не фонтан. По железу практически полный клон этого образца, прошивается тоже аналогично, с того же гитхаба, но… То ли расположение микрофона совсем неудачное, то ли ещё какая проблема, но слышит она меня со второго раза на третий. Всё ещё лучше чем M5 Atom Echo(как минимум, динамик тут действительно умеет издавать различимые ухом звуки), но больше плюсов особо нет. Вишенкой на торте — невозможно отключить аккумулятор. Никакого тумблера нет, а чтобы залезть вовнутрь и выдернуть его из разъёма — приходится отклеивать экран. В итоге он постоянно стоит на зарядке, что для липолей прям очень плохо(они от этого любят вспухать и устраивать непредвиденные коллапсы). Я расклеил и отсоединил, но достать его не смог — он намертво приклеен к динамику, настолько хорошо, что стало страшно повредить. Короче — мне не понравилась, если брать, то какой-то другой вариант.
З.Ы. Я понимаю, что статья где руками только пишется код — это немного неформат для DIY блога. Если не надо такое больше писать — прошу отругать меня в комментариях))
В любом случае, всех с наступающим новым годом, желаю счастья и побольше прикольных самоделок!
Статья предполагает, что читатель уже настроил себе голосового помощника вместе с локальной инсталляцией whisper+piper или silero+vosk, управляет всем голосом и у него всё хорошо(например описано тут. И ещё немного тут. И ещё в куче статей по всему интернету). Но иногда читатель хочет немного пошалить)))
Подробности под катом
Для начала про выбор самой LLM-ки. Я остановился на Gigachat от Сбера — для физлиц через API бесплатно даётся 900 000 токенов в год, чего вполне достаточно для того, чтобы изредка позадавать глупых вопросов умной колонке. Возможно в будущем что-то изменится — там посмотрим, а пока сойдёт. В любом случае, метода +- универсальна и должна работать абсолютно с любыми движками.
Для интеграции используем плагин gigachain. Ставится через HACS. Для настройки нужно будет получить API ключ с developers.sber.ru. Регистрируемся, жмём там на GigaChat API, будет предложено создать новый проект — Называем как угодно
В проекте жмём на «Получить ключ» и в открывшейся форме на поле Authorization key — ещё раз «Получить ключ»
После чего в самом Home Assistant ходим в Настройки->Устройства и службы->Добавить интеграциюНаходим в списке Gigachain и жмакаем.
В открывшемся поле вставляем полученный ранее API ключ и жмём «Подтвердить». Если всё хорошо — в списке устройств появится Gigachain с настроенным Gigachat.Дальше нам нужно его немного поднастроить. Жмём шестерёнку.
По умолчанию в открывшейся форме предзабит промт, направленный на использование гигачата непосредственно для управления умным домом. Нас этот функционал не интересует. Пишем что-то своё.
Модель выбираем Gigachat, температуру на свой вкус(чем выше — тем сильнее железка будет бредить). Остальные галки можно поснимать — они нам не нужны.Дальше нам нужно создать нового голосового ассистента, который будет использовать в качестве движка гигачат, а не HA. Идём в Настройки->Голосовые Ассистенты->Добавить Ассистента
Вписываем название, в качестве движка диалоговой системы выбираем свежесозданный gigachat.Галку «Предпочитать локальную обработку команд» снимаем.
Также для своей домашней конфигурации я сделал отдельный инстанс vosk, без ограничений словаря(и назвал его vosk_uncapped), соотв. на скрине выбран он. Вы у себя выбираете ваш движок(обычно это piper).
Синтез речи так же ставим, тот же, что для локального помощника. Сохраняем
Ну и наконец то, ради чего статья писалась. Создаём автоматизацию, которая может временно(на один запрос) сменить голосового помощника для колонки, к которой обратились.
Идём в Настройки->Автоматизации и Сцены->Создать новую автоматизацию.
В открывшейся форме жмём три точки ->Текстовый редактор
И вставляем в редактор эту простынюalias: Voice. давай поговорим
description: ""
triggers:
- trigger: conversation
command:
- давай поговорим
conditions: []
actions:
- action: select.select_option
metadata: {}
data:
option: gigachat
target:
entity_id: >-
{{ device_entities(trigger.device_id) | list | select('match',
'^select.*assistant$') | first }}
alias: Включаем gigachat
- action: assist_satellite.start_conversation
metadata: {}
data:
start_message: Внимательно слушаю.
preannounce: true
target:
entity_id: >-
{{ device_entities(trigger.device_id) | list | select('match',
'^assist_satellite.*') | first }}
alias: Запускаем диалог
mode: single
Дальше снова можно через три точки ->форма ввода вернуться в графический редактор.
Аналогичным образом добавляем вторую автоматизацию.alias: Voice. Gigachat disable
description: ""
triggers:
- trigger: template
value_template: >-
{{ states | selectattr('state', 'eq', 'gigachat') |
map(attribute='entity_id') | list | length > 0}}
conditions: []
actions:
- delay:
hours: 0
minutes: 0
seconds: 10
milliseconds: 0
- alias: Ждём статуса колонки Idle
wait_template: >-
{{ states(device_entities(device_id(states | selectattr('state', 'eq',
'gigachat') | map(attribute='entity_id') | list | first)) | list |
select('match','^assist_satellite.*') | first) == 'idle' }}
continue_on_timeout: true
timeout: "00:00:30"
- action: select.select_option
metadata: {}
data:
option: preferred
target:
entity_id: >-
{{ states | selectattr('state', 'eq', 'gigachat') |
map(attribute='entity_id') | list | first }}
alias: Отключаем gigachat
mode: single
Чуть больше подробностей о том, что тут происходит.По сути, вся фишка в том, что выбор голосового помощника — это не только общесистемная настройка(в виде выбора по умолчанию), но ещё и селектор в параметрах каждой умной колонки.
И его значением можно управлять в скриптах и автоматизациях. Ну а всё остальное делает магия jinja шаблонов
Вот так например мы переключаем голосового ассистента на гигачат. С помощью jinja из trigger.device_id (системная переменная, в которую кладётся device_id устройства, от которого запустилась автоматизация) выдирается entity_id интересующего нас поля ввода. Да, с помощью регулярки, способа лучше я не нашёл. Но работает довольно стабильно.
А вот так мы выдёргиваем из него же entity_id assist-pipeline-а для запуска диалога именно на той колонке, к которой обратились изначально. Ну а вот так мы во второй автоматизации ждём, пока колонка не перестанет говорить
trigger.device_id у нас больше нет(т.к. вторая автоматизация триггерится шаблоном), поэтому мы находим entity_id со значением gigachat, от него получаем device_id, а уже от него по прежней схеме получаем нужный нам entity_id assist_satellite.что-то-тамВ идеальном мире всё это должно работать в рамках одной автоматизации, но к сожалению по какой-то причине если действие запуска диалога не последнее в списке — окно для голосового ввода обрубается через несколько секунд. Поэтому приходится одной автоматизацией менять движок на гигачат и запускать диалог, а другой — ловить устройство, которому прописали гигачат и после задержки менять всё обратно. При том я не исключаю что это мой личный баг. У меня core инсталляция версии 2025.10.3 и тестировалось всё на кривой китайской колонке. В любом случае, принцип, думаю, понятен и собрать в одну автоматизацию не составит труда.
В результате получается что-то такое.
Возможно, галочку «цензура» стоит вернуть))) На всякий случай — осуждаю, никому не рекомендую следовать озвученной инструкции.
Для тех, у кого почему-то плохо работает ютьюб
Запрос-ответ из логов Home Assistant. И да, вот тут отлично видно, почему для vosk приходится включать ограничение словаря — иначе он слова в командах просклоняет только в путь.


Для тех, у кого почему-то плохо работает ютьюб

Вероятно, у многих примерно к этому месту возник вопрос: «Прикольно, но зачем весь этот велосипед городить?» Идея тут в том, именно управление умным домом остаётся завязанным на локальную инсталляцию, при отвале интернета он даже не почувствует что что-то пошло не так. Также в отличии от встроенного в HA механизма фоллбэка через галочку «Предпочитать локальную обработку команд» мы имеем 100% гарантию, что запрос не уйдёт вовне кроме случаев, когда мы сами этого захотим и специально объявим свои намерения через выделенную голосовую команду. Распознавание речи тоже работает строго локально, голосовые семплы никуда не отправляются. Можно наслаждаться остатками приватности))
Ну и раз уж мы собрались на ресурсе, где принято рассказывать про всякие железки — пара слов про колонку, мелькнувшую на видео.
Это вот она и она не фонтан. По железу практически полный клон этого образца, прошивается тоже аналогично, с того же гитхаба, но… То ли расположение микрофона совсем неудачное, то ли ещё какая проблема, но слышит она меня со второго раза на третий. Всё ещё лучше чем M5 Atom Echo(как минимум, динамик тут действительно умеет издавать различимые ухом звуки), но больше плюсов особо нет. Вишенкой на торте — невозможно отключить аккумулятор. Никакого тумблера нет, а чтобы залезть вовнутрь и выдернуть его из разъёма — приходится отклеивать экран. В итоге он постоянно стоит на зарядке, что для липолей прям очень плохо(они от этого любят вспухать и устраивать непредвиденные коллапсы). Я расклеил и отсоединил, но достать его не смог — он намертво приклеен к динамику, настолько хорошо, что стало страшно повредить. Короче — мне не понравилась, если брать, то какой-то другой вариант.
З.Ы. Я понимаю, что статья где руками только пишется код — это немного неформат для DIY блога. Если не надо такое больше писать — прошу отругать меня в комментариях))
В любом случае, всех с наступающим новым годом, желаю счастья и побольше прикольных самоделок!
Самые обсуждаемые обзоры
| +47 |
2483
47
|
| +92 |
3706
96
|
50 лет назад искусственный интеллект впервые обыграл в шахматы чемпиона СССР
Ответ гигачата конечно порадовал
Интересный опыт, пишите ещё конечно же.