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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *