Особенности автоматизаций в Home Assistant

15 октября 2018, 22:50

Дано:

Что необходимо сделать:

При двойном нажатии на одну из кнопок Xiaomi (или при включении автоматизации под названием Сигнализация в веб интерфейсе НА) происходит активация или дезактивация сигнализации

Что происходит: 

  • на Xiaomi Gateway воспроизводится загруженный через MiHome звук постановки/снятия на охрану
  • в Telegram приходит уведомление о постановке/снятии на охрану
  • Система голосом "кожаного мешка" сообщает нам о том что произведена постановка/снятие на охрану

При наличии движения на одном из датчиков движения должно происходить следующее:

  • Система голосом "кожаного мешка" сообщает мохнатому чудовищу что он неправ
  • Приходит уведомление в телеграм о том что "сволочь шарится по столам"
  • Xiaomi Gateway начинает воспроизводить звуки расстрела из штатного набора звуков шлюза
При одинарном нажатии любой из кнопок - сигнализация прекращает орать без снятия с охраны.

Возникавшие сложности

  • Добиться аналогичности действий при двойном нажатии на кнопку и при активации через веб интерфейс (если все звуки снятия и постановки на охрану прописать в автоматизации для кнопки, то при активации или деактивации сигнализации через веб интерфейс - все происходит в гробовой тишине)
  • При сработке сигнализации, отрабатывалась часть автоматизации отвечающая за воспроизведение звуков при постановке/снятии на охрану так как использовался алгоритм 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 скрывает ненужные нам автоматизации и скрипты с главного экрана и все становится значительно удобней.

Выводы:

Все это делалось не только для того, чтобы одна мохнатая морда получила предынфарктное состояние при попытке залезть на подоконник или стол. 

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


Все новости мира умных домов - t.me/SprutAI_News

Остались вопросы? Мы в Telegram - t.me/soprut

Хочешь умный дом но нет времени разбираться?
Посмотри примеры работ и выбери себе интегратора.
  1. Олег Челбаев (sprut)

    Основательный подход ))) отличная работа ))) страшно представить что будет в след статье ))))))

  2. Евгений Олейник (permadm)

    подробно и с юмором 👍🏽

К списку статей

Похожие статьи

15 ноября 2018, 09:42
Способы автоматизации механических ворот
15 июня 2018, 12:13
Охранная система в гараж на ESP8266 с интеграцией в Apple HomeKit
24 августа 2018, 12:18
Пошаговая установка HomeAssistant
27 августа 2018, 10:14
Интегрируем ХА в HomeKit
20 октября 2018, 22:57
Теоретические основы протокола MQTT и описание того, как он работает и для чего используется
01 ноября 2018, 09:27
Настройка Deconz USB стика ConBee от Dresden Elektronik в Hass.io и некоторые особенности эксплуатации
03 октября 2018, 22:03
Как собрать и настроить Hyperion Ambilight - адаптивную подсветку ТВ.
24 августа 2018, 10:15
Краткий экскурс в настройку Home Assistant
11 мая 2019, 19:57
Как активировать русский язык в Google Assistant для Google Home
14 сентября 2018, 19:34
Изучаем автоматизации в Home Assistant