Home Assistant: Яндекс Алиса говорит, какие окна у вас не закрыты

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

О чем тут вообще?

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

Затем я приобрел контактный сенсор Zigbee и повесил его на окно. Мне захотелось, чтобы Алиса сообщала, в каких комнатах открыты окна. Все таки дома есть кот, а погодные условия бывают разными. Когда такой сенсор один, то никаких проблем не возникает: проверяем, что он в статусе “Открыто” и воспроизводим нужную фразу. Когда же таких сенсоров много, то хочется, чтобы Алиса говорила красивое предложение о том, в каких комнатах окна открыты.

Задумка

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

Итак, приступим к реализации.

Реализация

Для начала определим объект (в шаблонитизаторе Jinja2 это называется dictionary), в котором ключ - это кусочек фразы с названием комнаты, а значение - состояние окна в виде boolean.

{% set window_sensors = {
  "в спальне": is_state("binary_sensor.bedroom_window_contact", "on"),
  "на кухне":  is_state("binary_sensor.kitchen_window_contact", "on"),
  "в гостиной":  is_state("binary_sensor.guestroom_window_contact", "on")
} %}

Затем нужно определить массив, в который мы будем добавлять кусочки фраз, для того, чтобы собрать конечное предложение с помощью join. Так гораздо проще, чем напрямую в шаблоне выводить текст и мучиться с его форматированием.

{% set data = namespace(text=[]) %}

Ну а дальше просто пробегаемся по объекту и с помощью условия берем только те сенсоры, у которых состояние "Открыто":

{% for k in window_sensors if window_sensors[k] == true %}
	{% if loop.first %}
	  {% set data.text = data.text + [["Кстати,", "Не забудьте, что", "Напоминаю, что"]|random] + [" у вас"] + [[" открыто", " не закрыто"]|random] + [" окно"] %}
	{% endif %}
	
	{% if not loop.first and not loop.last %}
	  {% set data.text = data.text + [", "] + [k] %}
	{% elif loop.last and not loop.first %}
	  {% set data.text = data.text + [" и "] + [k] %}
	{% else %}
	  {% set data.text = data.text + [" "] + [k] %}
	{% endif %}
{% endfor %}

На первой итерации я добавляю начало фразы. Как можно увидеть, используются разные фразы, чтобы придать “человечности” этому бездушному роботу. Далее идут условия. Если итерация не первая и не последняя, то мы в процессе перечисления - добавляем запятую и имя сенсора (ключ объекта). Если же итерации последняя, но не первая (т. е. открытых окон точно больше одного), то добавляем приставку “И”, а затем имя сенсора. В ином случае просто через пробел добавляем имя сенсора (т. е. это начало перечисления).

В результате получается вот такой массив:

['Напоминаю, что', ' у вас', ' открыто', ' окно', ' ', 'в спальне', ' и ', 'в гостиной']

Собираем с помощью join в строку:

{{ data.text|join("") }}

Результат: "Напоминаю, что у вас открыто окно в спальне и в гостиной".

Готово! Остается только попросить Алису воспроизвести текст с помощью вызова службы media_player.play_media согласно документации AlexxIT/YandexStation.

Финальный код

service: media_player.play_media
target:
  entity_id: media_player.yandex_station_ # ID вашей станции
data:
  media_content_id: >-
    {% set window_sensors = {
      "в спальне": is_state("binary_sensor.bedroom_window_contact", "on"),
      "на кухне":  is_state("binary_sensor.kitchen_window_contact", "on"),
      "в гостиной":  is_state("binary_sensor.guestroom_window_contact", "on")
    } %}
    
    {% set data = namespace(text=[]) %}
    
    {% for k in window_sensors if window_sensors[k] == true %}
      {% if loop.first %}
        {% set data.text = data.text + [["Кстати,", "Не забудьте, что", "Напоминаю, что"]|random] + [" у вас"] + [[" открыто", " не закрыто"]|random] + [" окно"] %}
      {% endif %}
    
      {% if not loop.first and not loop.last %}
        {% set data.text = data.text + [", "] + [k] %}
      {% elif loop.last and not loop.first %}
        {% set data.text = data.text + [" и "] + [k] %}
      {% else %}
        {% set data.text = data.text + [" "] + [k] %}
      {% endif %}
    {% endfor %}
    
    {{ data.text|join("") }}
  media_content_type: text

Источник: https://habr.com/ru/post/714064/


Интересные статьи

Интересные статьи

Согласитесь, в теме криптографической защиты информации больше вопросов, чем ответов. Как учитывать СКЗИ, как их хранить и перевозить? А если защиту надо установить на мобильное приложение, а сколько ...
Прямо сейчас на сайте Правительства Москвы можно подать заявку на субсидирование затрат малого и среднего бизнеса. Одна из программ организована совместно с Яндекс и подр...
Хочу поделиться опытом автоматизации экспорта заказов из Aliexpress в несколько CRM. Приведенные примеры написаны на PHP, но библиотеки для работы с Aliexpress есть и для...
Когда-то поиск Яндекса представлял из себя бутерброд. Каждый его слой могли эффективно разрабатывать единицы людей. Однако верхний добавлял пикантности. Этот слой представлял из себя...
Про Яндекс.Музыку знает или слышал краем уха каждый, кто читает эту статью. C 2018 года Яндекс не хвалился ростом пользовательской базы Я.Музыки, когда она достигла 1 млн. платных пользователей. ...