Awesome
Яндекс.Диалоги для Home Assistant
Компонент позволяет управлять Home Assistant из Яндекс Алисы через собственный навык в Яндекс.Диалогах.
С помощью Яндекс.Диалогов вы можете настроить реакцию Алисы на абсолютно любые фразы. А не только те, что заложили разработчики. Яндекс Алиса работает на колонках, мобильных приложениях Яндекса и на компьютере в браузере Яндекса.
Особенностью управления через Диалоги является необходимость называть имя навыка:
- Алиса, узнай у Умного дома температуру в спальне
- Алиса, попроси Мой дом включить Ютуб на телевизоре в зале
- Алиса, узнай у Домашнего ассистента когда было последнее движение у входной двери
Для начала диалога без использования имени навыка есть два метода:
- Создать сценарий Яндекса, например: если я скажу "включи мультики на телевизоре", умная колонка выполнит команду "скажи навыку умный дом включи мультики на ТВ"
- Начинать диалог из Home Assistant с помощью компонента Yandex.Station
Для работы компонента нужен рабочий внешний доступ к вашему Home Assistant по протоколу HTTPS. Его можно получить через другой мой компонент - Dataplicity.
Не стоит путать Яндекс.Диалоги с Умным домом Яндекса. Это разные технологии, не связанные между собой.
Установка
Способ 1. HACS > Интеграции > 3 точки (правый верхний угол) > Пользовательские репозитории > URL: AlexxIT/YandexDialogs
, Категория: Интеграция > Добавить > подождать > YandexDialogs > Установить
Способ 2. Вручную скопируйте папку yandex_dialogs
из latest release в директорию /config/custom_components
.
Настройка
Способ 1. GUI
Настройки > Интеграции > Добавить интеграцию > Yandex Dialogs
Если интеграции нет в списке - очистите кэш браузера.
Способ 2. YAML
yandex_dialogs:
Использование
Если у вас уже работает компонент YandexStation и есть внешний доступ по HTTPS - этот компонент может автоматически создать и настроить навык в Яндекс.Диалогах.
Для этого ещё раз добавьте интеграцию:
Настройки > Интеграции > Добавить интеграцию > Yandex Dialogs
И укажите:
- аккаунт Яндекса, от имени которого создавать Диалог
- публичную HTTPS-ссылку на ваш сервер Home Assistant
- имя навыка (Яндекс требует имя из двух слов)
Компонент автоматически создаст новый приватный диалог, опубликует его и сохранит идентификатор вашего пользователя в настройки интеграции. Навык публикуется в течение нескольких минут!
По умолчанию приватный навык доступен только вашему пользователю. Но для дополнительной безопасности можно ограничить доступ только списку пользователей. Идентификаторы пользователей уникальны для связки пользователь+навык и выглядят примерно так: ABCDEF01234567890ABCDEF01234567890ABCDEF01234567890ABCDEF0123456
. Если список пользователей пуст - дополнительная проверка выключена.
При необходимости вы можете создать несколько диалогов с разными именами.
PS: При желании можете самостоятельно создать приватный навык с Webhook на ваш Home Assistant: https://myhome.duckdns.org/api/yandex_dialogs
Управление
Поддерживается обработка команд диалога разными способами:
- Управление через автоматизации на событиях
- Управление через Intent Script
- Управление через python-скрипт
Управление через автоматизации на событиях
Внимание: у вас несколько секунд, чтоб вызвать событие с текстовым результатом ответа.
Этот подход можно использовать в Node-RED.
При обращении к навыку создаётся событие yandex_intent
с параметрами:
text
- произнесённая фразаcommand
- фраза, почищенная от знаков препинания и числетельные преобразованы в числаintent
- интент это обозначение "типовой" фразы. Например, для ответов "да" или "хорошо" здесь будет значениеYANDEX.CONFIRM
. При желании вы можете настраивать свои интенты (описано ниже)session
,user
,application
- "хранилище" состояний диалога...
- другие переменные, которые вы прописали в Интенте в Яндекс.Диалогах
Для ответа вы должны сами вызвать событие yandex_intent_response
с параметрами:
text
- опциональный, текст ответаtts
- опциональный, ответ в формате TTSend_session
, опциональный, по умолчаниюTrue
, "выйти" из диалога после ответаsession
,user
,application
- опциональные, новое значение "хранилища" состояний. Состоянияsession
иapplication
не переносятся между разными шагами диалога автоматически!
Для ответа вы можете заполнить или text
или tts
в зависимости от того, нужно ли вам произнести ответ со спецэффектами TTS.
automation:
- trigger:
platform: event
event_type: yandex_intent # это событие ОТ вашего навыка
event_data:
text: привет # проверяем точное совпадение с фразой "привет"
action:
event: yandex_intent_response # это наш ответ навыку, нужно уложиться в пару секунд
event_data:
text: "{{ ['слушаю', 'здесь я', 'на связи']|random }}"
- trigger:
platform: event
event_type: yandex_intent
event_data:
intent: calc # проверяем на совпадение с Интентом калькулятора
action:
- service: persistent_notification.create
data:
title: Яндекс Калькулятор
message: "{{ trigger.event.data.text }}"
- event: yandex_intent_response
event_data: # есть все переменные, как и в примере выше
text: >-
{% if trigger.event.data.action == 'плюс' %}
{{ trigger.event.data.x + trigger.event.data.y }}
{% elif trigger.event.data.action == 'минус' %}
{{ trigger.event.data.x - trigger.event.data.y }}
{% elif trigger.event.data.action == 'умножить на' %}
{{ trigger.event.data.x * trigger.event.data.y }}
{% elif trigger.event.data.action == 'разделить на' %}
{{ trigger.event.data.x / trigger.event.data.y }}
{% endif %}
Управление продолжением диалога
Фраза "Алиса, включи навык Умный дома" включит навык и навык будет ждать вашей команды.
Фраза "Алиса, спроси у Умного дома сколько градусов в зале" - вызовет ваш навык, получит ответ и тут же выйдет из него назад к Алисе.
Чтоб изменить это поведение, используйте параметр end_session
. С ним вы можете либо продолжить разговор при фразе "Алиса спроси у Умного дома...". Либо прервать диалог в любом месте.
Управление через Intent Script
Альтернативный способ управления диалогом. Более сложный и не рекомендуется к использованию.
Существует скрипт по умолчанию yandex_default
. Он выполняется когда для фразы не совпал ни один Интент.
action
опциональный. Он выполняется ДО генерации ответа и при желании может на него повлиять.
Внимание: у вашего скрипта пара секунд, чтоб вернуть ответ. Алиса дольше не ждёт. Если ваш скрипт выполняется дольше - запускайте его ассинхронно (читайте документацию).
Вам доступны переменные:
text
- произнесённая фразаcommand
- фраза, почищенная от знаков препинания и числетельные преобразованы в числаintent
- если фраза совпала, тут будет ID Интента из Яндекс.Диалогов...
- другие переменные, которые вы прописали в Интенте в Яндекс.Диалогах
intent_script:
yandex_default: # это скрипт по умолчанию
action: # действие опционально и должно уложиться в пару секунд
- service: persistent_notification.create
data:
title: Команда из Яндекса
message: "{{ text }}"
speech: # фраза для ответа, поддерживает шаблоны
text: >-
{% if text == 'привет' %}
{{ ['слушаю', 'здесь я', 'на связи']|random }}
{% elif text == 'какая температура в спальне' %}
Температура {{ states("sensor.temperature_bedroom")|round }} °C
{% else %}
Не могу выполнить: {{ text }}
{% endif %}
calc: # это Интент калькулятора (пример как настроить ниже)
action:
- service: persistent_notification.create
data:
title: Яндекс Калькулятор
message: "{{ text }}"
speech: # в нём распознались переменные action, x и y
text: >-
{% if action == 'плюс' %}
{{ x+y }}
{% elif action == 'минус' %}
{{ x-y }}
{% elif action == 'умножить на' %}
{{ x*y }}
{% elif action == 'разделить на' %}
{{ x/y }}
{% endif %}
temperature: # это Интент температуры в помещении (пример как настроить ниже)
speech:
text: >-
{% if room == 'в зале' %}
Температура в зале {{ states("sensor.temperature_hall")|round }} °C
{% elif room == 'в ванной' %}
Температура в ванной {{ states("sensor.temperature_bathroom")|round }} °C
{% elif room == 'на балконе' %}
Температура на балконе {{ states("sensor.temperature_balcony")|round }} °C
{% endif %}
Управление через python-скрипт
- Python-код можно писать во внешнем файле или сразу в YAML
- Код из внешнего файла загружается при каждом вызове диалога (его можно закешировать при старте Hass)
- Можно установить внешние зависимости python через pip
- Синтаксис скрипта совместим с функциями Yandex Cloud
yandex_dialogs:
requirements: # можно установить внешние библиотеки python
- requests
file: dialogs.py # можно писать код в внемнем файле
cache: True # закешировать код внешнего файла (по умолчанию выключено)
source: |
def handler(event, context):
return {"response": {"text": "OK"}, "version": "1.0"}
Пример скрипта (подробнее в документации):
def make_response(event: dict, text: str, end_session=False) -> dict:
return {
"version": event["version"],
"session": event["session"],
"response": {"text": text, "end_session": end_session},
}
def handler(event: dict, context: dict) -> dict:
return make_response(event, "Ну привет!")
Настройка Интентов в Яндекс.Диалогах
Платформа Яндекс.Диалогов позволяет гибко обрабатывать сказанные фразы через Natural Language Processing (NLU) от Яндекса.
Фраза, которую нужно распознать, называется Интентом. ID интента и все составляющие разобранной фразы прилетят в Home Assistant. И их можно использовать в автоматизациях.
При желании вы можете не пользоваться Интентами, а анализовать фразы в автоматизациях Home Assistant или Node-RED.
$room
- слово с долларом это переменная[...]
- квадрытные скобки означают, что слова могут идти в любом порядке(какая)?
- вопрос означает, что слова может не быть%lemma
- означает режим сравнение без учёта формы слова (например "включай свет" приравнивается к "включи свет")
Полная документация.
Интенты можно настраивать только после публикации навыка. Любые изменения в интентах требуют новой публикации (занимает пару минут).
Пример калькулятора
root:
сколько будет $x $action $y
slots:
x:
source: $x
type: YANDEX.NUMBER
y:
source: $y
type: YANDEX.NUMBER
action:
source: $action
$x:
$YANDEX.NUMBER
$y:
$YANDEX.NUMBER
$action:
плюс | минус | умножить на | разделить на
Пример тепературы в разных помещениях
root:
[(какая)? температура $room]
[сколько градусов $room]
slots:
room:
source: $room
$room:
в зале | в ванной | на балконе