Skip to content

Компонент для управления Home Assistant через Яндекс.Диалоги

Notifications You must be signed in to change notification settings

AlexxIT/YandexDialogs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Яндекс.Диалоги для 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

Управление

Поддерживается обработка команд диалога разными способами:

Управление через автоматизации на событиях

Внимание: у вас несколько секунд, чтоб вызвать событие с текстовым результатом ответа.

Этот подход можно использовать в Node-RED.

При обращении к навыку создаётся событие yandex_intent с параметрами:

  • text - произнесённая фраза
  • command - фраза, почищенная от знаков препинания и числетельные преобразованы в числа
  • intent - интент это обозначение "типовой" фразы. Например, для ответов "да" или "хорошо" здесь будет значение YANDEX.CONFIRM. При желании вы можете настраивать свои интенты (описано ниже)
  • session, user, application - "хранилище" состояний диалога
  • ... - другие переменные, которые вы прописали в Интенте в Яндекс.Диалогах

Для ответа вы должны сами вызвать событие yandex_intent_response с параметрами:

  • text - опциональный, текст ответа
  • tts - опциональный, ответ в формате TTS
  • end_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:
    в зале | в ванной | на балконе

About

Компонент для управления Home Assistant через Яндекс.Диалоги

Topics

Resources

Stars

Watchers

Forks

Languages