Home

Awesome

Яндекс.Диалоги для Home Assistant

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

С помощью Яндекс.Диалогов вы можете настроить реакцию Алисы на абсолютно любые фразы. А не только те, что заложили разработчики. Яндекс Алиса работает на колонках, мобильных приложениях Яндекса и на компьютере в браузере Яндекса.

Особенностью управления через Диалоги является необходимость называть имя навыка:

Для начала диалога без использования имени навыка есть два метода:

Для работы компонента нужен рабочий внешний доступ к вашему 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

И укажите:

Компонент автоматически создаст новый приватный диалог, опубликует его и сохранит идентификатор вашего пользователя в настройки интеграции. Навык публикуется в течение нескольких минут!

По умолчанию приватный навык доступен только вашему пользователю. Но для дополнительной безопасности можно ограничить доступ только списку пользователей. Идентификаторы пользователей уникальны для связки пользователь+навык и выглядят примерно так: ABCDEF01234567890ABCDEF01234567890ABCDEF01234567890ABCDEF0123456. Если список пользователей пуст - дополнительная проверка выключена.

При необходимости вы можете создать несколько диалогов с разными именами.

PS: При желании можете самостоятельно создать приватный навык с Webhook на ваш Home Assistant: https://myhome.duckdns.org/api/yandex_dialogs

Управление

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

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

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

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

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

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

Для ответа вы можете заполнить или 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 опциональный. Он выполняется ДО генерации ответа и при желании может на него повлиять.

Внимание: у вашего скрипта пара секунд, чтоб вернуть ответ. Алиса дольше не ждёт. Если ваш скрипт выполняется дольше - запускайте его ассинхронно (читайте документацию).

Вам доступны переменные:

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-скрипт

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.

Полная документация.

Интенты можно настраивать только после публикации навыка. Любые изменения в интентах требуют новой публикации (занимает пару минут).

Пример калькулятора

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:
    в зале | в ванной | на балконе