Дано:
- Мохнатая собачья морда, любящая шариться по столам и тумбочкам на кухне
- Наличие Xiaomi Aqara Gateway 2
- Два датчика движения Xiaomi
- Home Assistant в виде Hass.io установленного на Raspberry Pi 3
- Настроенный и проверенный telegram_bot из предыдущей статьи
- Настроенный и проверенный Music Player Daemon (MPD)
- Колонки подключенные к Raspberry PI 3
- две кнопки Xiaomi размещенные в разных комнатах
- подключенный Amazon Polly TTS (но можно и штатным Google TTS)
Что необходимо сделать:
При двойном нажатии на одну из кнопок Xiaomi (или при включении автоматизации под названием Сигнализация в веб интерфейсе НА) происходит активация или дезактивация сигнализации
Что происходит:
При наличии движения на одном из датчиков движения должно происходить следующее:
Возникавшие сложности
- Добиться аналогичности действий при двойном нажатии на кнопку и при активации через веб интерфейс (если все звуки снятия и постановки на охрану прописать в автоматизации для кнопки, то при активации или деактивации сигнализации через веб интерфейс - все происходит в гробовой тишине)
- При сработке сигнализации, отрабатывалась часть автоматизации отвечающая за воспроизведение звуков при постановке/снятии на охрану так как использовался алгоритм is_state
Итоговая реализация
Используются следующие элементы системы Home Assistant:
- Автоматизации
- Скрипты
- Кастомизация
Разберем конфигурацию
Для начала нам нужно понимать откуда нам брать названия сенсоров, кнопок, датчиков и автоматизаций чтобы их использовать в коде. Для этого мы идем в раздел "Элементы" из инструментов разработчика
а дальше уже из списка который у нас появился, мы выбираем названия элементов, которые нам нужны для работы:
Ну а дальше пошло самое веселье. Начинаем вставлять код в файл automations.yaml
# Основной модуль сигнализации, который отвечает за обнаружение движения и включение тревоги - alias: 'Motion Detection' # используется последовательное перечисление с указанием # платформ, так как простой список через запятую не заработал trigger: # Здесь перечисляются датчики, которые определяют момент # сработки сигнализации. Параметр "state" означает сработку # по состоянию (вкл/выкл) или (сработал/не сработал) - platform: state # Наименование кнопок или сенсоров если что берется из раздела # "состояние" или "state" в левом меню НА в инструментах разработчика со значком '< >' entity_id: binary_sensor.motion_sensor_номер_сенсора1 to: 'on' - platform: state entity_id: binary_sensor.motion_sensor_номер_сенсора2 to: 'on' # Дальше начинается модуль действий action: # Уведомление через бот телеграма - service: notify.telegram data: # символ | указывает на возможность отправлять сообщения # из нескольких строк просто через перевод строки message: | !!! Эта мохнатая сволочь полезла на столы !!! # Запуск скрипта, который и выполняет роль сирены (описан ниже) # используется для скриптов. Означает просто состояние включенности # Home Assistant и потому что нужно указать какой то сервис в данном месте - service: homeassistant.turn_on #запуск скрипта alarm_sequence прописанного в scripts.yaml entity_id: script.alarm_sequence # Следующая автоматизация прекращает ор сирены если вдруг # сие случится когда я дома по нажатию одной из кнопок один раз - alias: 'Disable Sound Of Alarm' trigger: # триггером является момент начала или прерывания какого либо процесса - platform: event # это означает что мы совершаем действие (или что то совершает) event_type: click # описывается формат действия, в данном случае нажатие на кнопку event_data: #указывается какая именно кнопка имеется в виду entity_id: binary_sensor.switch_номер_кнопки_1 # указывается какое именно нажатие на кнопку используется # (в данном случае однократное, но у этой кнопки есть двукратное (описано ниже) и длительное) click_type: single - platform: event # по аналогии с предыдущей кнопкой event_type: click event_data: entity_id: binary_sensor.switch_номер_кнопки_2 click_type: single # А дальше по аналогии указывается действие которое должно произойти после нажатия кнопки action: # Мы выбираем что нам нужно действие с Xiaomi Gateway и даем команду остановить проигрывание рингтона - service: xiaomi_aqara.stop_ringtone data: gw_mac: МАК_АДРЕС_ШЛЮЗА # Автоматизация включения или отключения сигнализации - alias: 'Arm/Disarm alarm' trigger: # Все по аналогии с кнопками описанной выше - platform: event event_type: click event_data: entity_id: binary_sensor.switch_номер_кнопки_1 click_type: double # только клик двойной - platform: event event_type: click event_data: entity_id: binary_sensor.switch_номер_кнопки_2 click_type: double # Данной командой мы переключаем состояние автоматизации. # У нее есть состояние On и Off. Toggle переключает состояние между On и Off action: - service: automation.toggle # и указываем какую именно автоматизацию мы переключаем entity_id: automation.motion_detection # Маленький комментарий. Автоматизация срабатывает только во включенном состоянии. # Если она отключена, то все что в ней описано работать не будет пока мы ее не включим. # Самая "веселая автоматизация" которая отвечает за обозначение звуками и # уведомлениями процесса включения или отключения сигнализации # (кнопкой мы это делаем или через веб интерфейс - неважно) - alias: 'Alarm Status Sound' # Данным триггером мы отслеживаем состояние сигнализации # которая у нас описана в самой первой автоматизации trigger: platform: state entity_id: automation.motion_detection #данная настройка нужна для того, чтобы данная автоматизация # срабатывала только при изменении состоянии сигнализации # и не использовалась при срабатывании сигнализации condition: - condition: template # мы отслеживаем этой командой только изменение состояние сигнализации каким бы оно ни было value_template: "{{ trigger.to_state.state != trigger.from_state.state }}" action: # тут мы указываем что система голосом "кожаные мешки" должна через подключенные # напрямую в малину колонки нам сказать текст который мы хотим - service: tts.amazon_polly_say entity_id: media_player.mpd data_template: message: # тут мы выясняем в каком же состоянии находится сигнализация {% if trigger.to_state.state == 'on' %} # так как выше мы выяснили что она включена - то говорим что она работает Замри мешок с костями, а то ушибу # а тут рассматривается вариант что сигнализация отключена {% elif trigger.to_state.state == 'off' %} # и система сообщает что можно двигаться так как сработки не будет Можешь шевелиться кожаный мешок # а так как других условий у нас нет, то тут мы ничего и не указываем {% else %} {% endif %} # выше описано, что этот блок отправляет уведомление нам через нашего бота - service: notify.telegram data_template: message: # ну и дальше по аналогии с вышеописанным мы выбираем варианты # действий в соответствии с состоянием сигнализации {% if trigger.to_state.state == 'on' %} Замри мешок с костями, а то ушибу {% elif trigger.to_state.state == 'off' %} Можешь шевелиться кожаный мешок {% else %} {% endif %} # а тут у нас шлюз Xiaomi проигрывает кастомный рингтон постановки # на охрану записанный в него через MiHome - service: xiaomi_aqara.play_ringtone data_template: ringtone_id: > {% if trigger.to_state.state == 'on' %} 10003 # Нумерация загруженных рингтонов через MiHome начинается с 10001 {% elif trigger.to_state.state == 'off' %} 10004 {% else %} {% endif %} gw_mac: МАК_АДРЕС_ШЛЮЗА ringtone_vol: 40 # громкость с которой будет воспроизводиться рингтон
Итак, зачем все так сложно ?
Создавая это я столкнулся со следующими проблемами. Автоматизация Alarm Status Sound конфликтовала с автоматизацией Motion Detection когда использовалось штатное решение отработки по состоянию приведенное ниже:
script: msg_who_is_home: sequence: - service: notify.notify data_template: message: > # и вот эта вот гадина is_state отрабатывала при любом событии которое # происходило при любой автоматизации в системе # и брякало звуками и действиями {% if is_state('device_tracker.paulus', 'home') %} Ha, Paulus is home! {% else %} Paulus is at {{ states('device_tracker.paulus') }}. {% endif %}
и так как файл автоматизаций отрабатывает последовательно все что в нем написано, то в моем случае сначала начиналась сработка сирены по датчику движения, а потом система видела что статус сигнализации находится в режиме 'On' и начинала последовательность прописанную в автоматизации 'Alarm Status Sound' назначенную для сигнализации в режиме 'On' и сигнализация прекращала орать и проигрывала звук включения сигнализации.... ну вы понимаете....
Именно поэтому в данной конфигурации 'Alarm Status Sound' срабатывает только при изменении состояния автоматизации 'Motion Detection'.
Ну а то, что происходит при срабатывании самой сигнализации прописано в файле scripts.yaml и довольно скучно на фоне написанного ранее:
alarm_sequence: alias: "Действия при сработке сигнализации" sequence: - service: tts.amazon_polly_say entity_id: media_player.mpd data: message: 'Куда ты полез мохнатая наглая сука?!' - delay: 00:00:03 - service: xiaomi_aqara.play_ringtone data: gw_mac: МАК_АДРЕС_ШЛЮЗА ringtone_id: 6 ringtone_vol: 8 - delay: 00:00:05 - service: xiaomi_aqara.play_ringtone data: gw_mac: МАК_АДРЕС_ШЛЮЗА ringtone_id: 5 ringtone_vol: 8
Зачем нужны задержки ? Потому что автоматизация не получает от перечисленных исполнительных устройств обратной связи о завершении проигрывания текста или звука. И запускает все одновременно.
Без задержек получается что Текст проигрывается одновременно с последним указанным рингтоном шлюза, так как на шлюз пришли сразу две одинаковых команды и он выполняет последнюю. И получается каша.
Упомянутые кастомизации
Когда мы настраиваем автоматизации, они появляются на основном экране Home Assistant и вводят в заблуждение. По факту нам кроме основной кнопки включения/отключения сигнализации, на главном экране больше ничего и не нужно.
Поэтому мы берем файл customize.yaml и вставляем туда параметры
# название автоматизации или элемента на основной странице системы automation.disable_sound_of_alarm: # то как мы хотим чтобы она называлась "по человечески" friendly_name: 'Отключить сирену' # а тут мы говорим хотим ли мы видеть этот элемент на основной странице # это на самом деле означает спрятать. # типа ответа на вопрос "хотим ли мы спрятать элемент ?" # ответ "true" означает "да, хотим спрятать" hidden: true automation.motion_detection: friendly_name: 'Сигнализация на кухне' automation.arm_disarm_alarm: friendly_name: 'Отключить сигнализацию кнопкой' hidden: true automation.alarm_status_sound: friendly_name: 'Подзвучка включения/отключения сигнализации' hidden: true script.alarm_sequence friendly_name: 'Действия при сработке сигнализации' hidden: true
где hidden: true скрывает ненужные нам автоматизации и скрипты с главного экрана и все становится значительно удобней.
Выводы:
Все это делалось не только для того, чтобы одна мохнатая морда получила предынфарктное состояние при попытке залезть на подоконник или стол.
Данный пример показывает вариации автоматизаций с использованием различных совмещенных параметров отслеживания состояний различных автоматизаций и датчиков, и аккумулирует найденные мной примеры конфигурации в некий набор шаблонов, которые можно будет в дальнейшем использовать для автоматизации процессов в доме.
Основательный подход ))) отличная работа ))) страшно представить что будет в след статье ))))))
подробно и с юмором 👍🏽