GrabDuck

Home Assistant или еще один «мозг» для проекта типа «Умный Дом»

:

Добрый день, уважаемый читатель. На днях довелось мне поиграться с многим уже известной игрушкой от Google – Google Home. Штука хорошая — обзор ее я делать конечно не буду. В чулане совершенно случайно завалялись Raspberry PI 3 (RPi), Arduino Mega и еще им подобная мелочь, которую захотелось подключить к Google Home (GH) с целью голосового управления. Простого API у GH нет, но есть возможность с помощью стороннего сервиса организовать голосовое управление системой на RPi + Arduino с задержкой команд в несколько секунд.

Читая буржуйские форумы (справедливости ради, нужно отметить, человек я повернутый на автоматизации и IoT), обратил внимание на доселе мне неизвестное нечто, что называют Home Assistant (HASS), эту систему умельцы-то и прикручивают к GH.

В двух словах о самой платформе:

Система написана на Python, последний релиз был 29 января, текущая версия: 0.37.0

Поддерживаемые ОС:

  • Windows 10
  • Mac OS X
  • Ubuntu 14.04
  • Raspbian (Raspberry PI)
  • iOS App – beta

Поддерживаемые компоненты: 545 шт., включая почти все TV/AV receivers, Broadlink, ZigBee, iCloud, Yandex TTS и многое, многое другое.

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

«Чёйта вдруг?» — подумаете вы.

Отвечаю: настройка всего вышеперечисленного (существующих компонентов) осуществляется исключительно через YAML файл (“configuration.yaml”).

Установка простая – останавливаться на ней и расписывать все шаги смысла не имеет, к тому же у проекта имеется шикарное сообщество, готовое помочь в трудную минуту (Eng). (все ссылки дополнительно помещу в подвале, как предписывает устав)

Будьте готовы, что установка занимает немало времени, на моей RPi 3 общее время (без Raspbian) заняло около часа.

После завершения заветного wget, я приступил к изучению платформы. Установка HASS производится в директорию: /home/homeassistant. Нас же интересует /home/homeassistant/.homeassistant/configuration.yaml.

По умолчанию в конфиге присутствует такой компонент:

# Автоопределение устройств
discovery:

Если у вас в сети имеются такие устройства:
  • Google Chromecast
  • Belkin WeMo switches
  • Philips Hue
  • Netgear routers
  • Plex media server
  • Panasonic Viera
  • Roku media player
  • Sonos Speakers
  • Yamaha media player
  • Logitech media server (Squeezebox)
  • DirecTV

Они будут обнаружены автоматически и отображены в основной (и пока единственной) группе « Home».

Компонент « http»:

# Включение доступа к frontend
http:
  # Убрать тэг комментария и выставить пароль (recommended!)
  #api_password: YOUR_PASSWORD

Как абсолютно справедливо отмечено на портале — HIGHLY recommended – из соображений безопасности.

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

1) Использовать shell команды:

~ $ sudo systemctl stop home-assistant.service
~ $ sudo systemctl start home-assistant.service 

или сразу
~ $ sudo systemctl restart home-assistant.service

2) Выполнить перезапуск из GUI: Развернуть гамбургер, в подвале “ Developer Tool” открыть “ Services”, в выпадающем списке “ Domain” выбрать « homeassistant», в выпадающем списке “ Service” – « Restart» и нажать кнопку «CALL SERVICE».
Обращу ваше внимание, что frontend использует кэширование, во время перезапуска или остановки сервиса, страница полностью доступна для просмотра, однако никаких действий осуществить не представляется возможным.

Как только запущен рестарт сервиса, либо через shell либо через GUI, в нижней части экрана отобразится поле показывающее текущий статус сервиса.

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

Что необходимо сделать в таком случае:

1) Открыть лог файл: ~/.homeassistant/ home-assistant.log
Записи в логе довольно структурированы, с зачастую, указанием номером строки в configuration.yaml в которой возникла ошибка.
2) Решить проблему указанную в логе
3) Запустить сервис командой выше из консоли

Мы задали пароль, мы выставили (если по какой-то причине не было по умолчанию) автоопределение оборудования, пришло время зайти на портал:

http://IP-Address:8123

8123 — порт по умолчанию.
Что позволяет сделать HASS с ресивером:

Нам доступны: Источник, Громкость, Без Звука (при прослушивании аудио записей, доступны кнопки управления треками).

Теперь же, более подробно рассмотрим yaml-ку. Я привожу несколько расширенную версию, на базе которой будет проще понять какие возможности у HASS есть, а также, возможно, поможет вам в настройке собственного окружения.

configuration.yaml
homeassistant:

# Название окружения запущенного HASS
  name: Дом

  # Координаты для Зоны Дом*, а также для расчета рассвета и заката
  latitude: _REDACTED_
  longitude: _REDACTED_

  # Высота над уровнем моря – для расчета рассвета и заката
  elevation: 0

  # 'metric' измерения в метрической, 'imperial' - имперской
  unit_system: metric

  # Часовой пояс: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones
  time_zone: Europe/Moscow

  # К описанию элемента customize вернемся позже. Здесь - подключение файла в котором описан компонент
  #customize: !include customize.yaml

# Включение frontend GUI. Чтобы скрыть, необходимо закомментировать
frontend:

# Проверка доступных обновлений
updater:
  reporting: no

# Отслеживание изменений показателей подключенных устройств и компонентов
logbook:

# Отслеживание закатов и рассветов по гео-координатам и высотой над уровнем моря
sun:

# надиктовывание команд из фронтенд GUI
conversation:

# отслеживание истории показателей
history:

# Автоопределение совместимых устройств
discovery:

# Настройка доступа к ФронтЕнду:
http:
  api_password: _REDACTED_
#  ssl_certificate: _REDACTED_  # SSL опционально
#  ssl_key: _REDACTED_
#  base_url: _REDACTED_
#  trusted_networks:
#	- 127.0.0.1
#	- _REDACTED_/24
#  ip_ban_enabled: True
#  login_attempts_threshold: 5

Зона Дом* — HASS позволяет создавать зоны (локации) по миру, стране, городу (где угодно) на основе гео-координат, для использования их в последующем при создании «автоматизаций» (automation) и оповещений (notify).


Забегая вперед, HASS поддерживает интеграцию с сервисом Telegram, на базе которого я реализовал оповещение, но об этом чуть позже.

Далее нужно отредактировать конфиг файл, перезапустить сервис HASS, перейти на Web страницу и посмотреть, что получилось.

Теперь приступим к первой автоматизации (далее automation). В качестве первой automation, предлагаю рассмотреть «Будильник». Для реализации этой задачи нам не обязательно иметь аудио или видео устройства в сети. Однако, в примере, я покажу использование ресивера в качестве самого будильника.

Задача

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

Ресурсы

  • Raspberry Pi
  • Home Assistant
  • Сеть (wired/wireless) с выходом в Internet
  • VLC
  • AV Ресивер (опционально)
  • Telegram
  • Telegram Bot
  • Yandex SpeechKit Cloud
  • OpenWeatherMap

Реализация

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

Итак, у нас есть свой Бот. Для его подключения к HASS необходимо в configuration.yaml прописать следующее:

# Telegram Notifier
notify:
  - name: NOTIFIER_NAME (имя которое впоследствии будет использоваться для идентификации компонента ‘notify’ - eng)
    platform: telegram
    api_key: ABCDEFGHJKLMNOPQRSTUVXYZ
    chat_id: YOUR_CHAT_ID

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

О том как это сделать будет написано ниже.

Как видно из комментариев, нам необходимо API выданное нам для Бота, а также, Chat ID. Для того, что бы его получить Chat ID, нужно написать вашему Боту хотя бы одно сообщение, после чего открыть страницу с адресом:

 https://api.telegram.org/bot*API*/getUpdates.

Где *API* — API выданное вам.

В результате вы получите некий JSON, в котором нас интересует следующее:

{"<b>id</b>":<b>123456789 </b>…}

Значение ID нам и нужно.

Далее, подключим компонент отвечающий за синтезирование текста — SpeechKit Cloud Yandex.

Для этого нам необходимо зарегистрироваться и пройти несколько несложных шагов настройки.

Выбрать из подключаемых сервисов API SpeechKit Cloud и получить ключ.

В configuration.yaml внести следующую запись:

tts:
  - platform: yandextts # Определение платформы по работе с компонентом TTS
    name: yandextts # Имя компонента, для использования в последующем
    api_key: 'API к SpeechKit'
    language: 'ru-RU' # Язык произносимой фразы – по умолчанию ru
    codec: 'mp3' # Формат генерируемого аудио файла
    voice: 'jane' # Голос диктора
    emotion: 'good'  # Настроение диктора
    speed: '1'  # Скорость речи

Пояснения и варианты параметров доступны на сайте Яндекс.

Теперь у нас есть аж два сервиса по оповещению, но нам «маловато будет», придется добавить еще один: VLC.

Так как я изначально использовал Raspberry PI, VLC я устанавливал простой командой:

sudo apt-get install vlc

Далее, нужно настроить параметры звука на Raspberry — устройство воспроизведения по умолчанию и проделать нехитрую манипуляцию с правами доступа пользователя, который был создан при установке HASS AIO (All-In-One).
sudo usermod -a -G audio homeassistant

Команда добавляет пользователя в группу audio.

В configuration.yaml вносим строку:

media_player: !include media_player.yaml

В родительской папке создаем файл: media_player.yaml где будут храниться все настройки для медиа устройств которые мы будем подключать.

Вносим следующие настройки:

- platform: yamaha
  name: Yamaha_671
  zone: 2
 # Определяем кастомные элементы управления - опционально
  commands:
    turn_on:
      service: media_player.turn_on
    turn_off:
      service: media_player.turn_off
    volume_up:
      service: media_player.volume_up
    volume_down:
      service: media_player.volume_down
  customize: # изменяем отображение на frontend данного устройства
    media_player.yamaha_671:
    hidden: true # скрываем устройство yamaha_671 - зона основная (Main)
 
- platform: vlc
  name: vlcmp # название нашего плеера VLC

У моего ресивера имеется две зоны воспроизведения ( Main, Zone 2). В примере я использую второю.

Все дополнительные компоненты подключены. Можем переходить к настройке самого элемента будильника.

Добавим в конфигурационный файл строку:

## Input Boolean
input_boolean: !include input_boolean.yaml

Создаем файл в родительской папке: input_boolean.yaml

Вносим следующие строки:

alarmweekday: #создаем переключатель - Будить только в рабочие дни
  name: Рабочая неделя
  initial: on # Значение по умолчанию
  icon: mdi:calendar

Как видно из названия yaml, мы подключаем компонент типа «Выключатель». Единственное что мне кажется дополнительно стоит описать это icon. Мы можем использовать любые иконки из библиотеки MDI.

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

input_slider 
input_select 

Один представляет собой выбор из списка. Другой слайдер. Я воспользовался удобным в настройке слайдером.

В configuration.yaml прописываем:

## Input Slider
input_slider: !include input_slider.yaml

Как уже завелось в родительской папке создаем файл: input_slider.yaml
Далее заполняем его:
alarmhour:
  name: Часы
  icon: mdi:timer
  initial: 8 # значение по умолчанию
  min: 0  #Минимальное значение
  max: 23 #Максимальное значение
  step: 1 #Шаг изменения
alarmminutes:
  name: Минуты
  icon: mdi:timer
  initial: 40
  min: 0
  max: 59
  step: 1

И еще одну нехитрую штуку нам предстоит сделать: сенсор.
В конфиге прописываем:
sensor: !include_dir_merge_list sensors

Эта команда означает, что брать следует все файлы из папки sensors. В свою очередь, в папке sensors создаем yaml файл с названием: alarmclock.yaml. Настройка alarmclock.yaml:
- platform: template
  sensors:
    alarm_time:
    friendly_name: 'Будильник '
    value_template: '{{ states.input_slider.alarmhour.state | int }}:{% if states.input_slider.alarmminutes.state|length == 1 %}0{% endif %}{{ states.input_slider.alarmminutes.state | int }}'

Тут интереснее. Появляется некий template. Этот компонент позволяет всячески управлять данными других компонентов HASS. В данном примере, мы создаем сенсор и заполняем его данными из слайдеров будильника, принудительно приводя значение к int и добавляя «0» если «длина» минут == 1. Более подробно о возможностях можно узнать на портале HASS.

Нам потребуется еще один сенсор — погодные условия.

Среди всех доступных компонентов типа weather мой выбор пал на OpenWeatherMap Sensor. В папке sensors необходимо создать файл weather.yaml и наполнить его следующим:

- platform: openweathermap
  api_key: *API*
  latitude: *latitude*
  longitude: *longitude*
  monitored_conditions:
    - weather
    - temperature
    - wind_speed
    - humidity
    - clouds
    - rain
    - snow

Как не трудно заметить, нам потребуется для интеграции API от OWM. API бесплатное, и получить его можно зарегистрировавшись на портале. Сохраняем, закрываем, идем дальше.

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

Приступим к созданию automation.

В configuration.yaml прописываем:

## Automation for: alarmclock...
automation: !include_dir_merge_list automation

Это значит, что будут подгружены все файлы из папки automation. Теперь создаем в родительской директории папку «automation».

Создаем файл: alarmclock.yaml

И приступаем к заполнению.

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

Automation для Будильника
- alias: 'Будильник '
  trigger:
    platform: template
    value_template: '{{ states.sensor.time.state == states.sensor.alarm_time.state }}' # Определение тригера.
  condition: # Условия
    condition: or
    conditions:
      - condition: and
        conditions:
        - condition: state
          entity_id: input_boolean.alarmweekday
          state: 'on'
        - condition: time
      	   weekday:
      	    - mon
      	    - tue
      	    - wed
      	    - thu
      	    - fri
      - condition: state
        entity_id: input_boolean.alarmweekday
        state: 'off'
  action: # Действия 
    - service: notify.NOTIFIER_NAME
      data_template:
        title: Доброе утро, Дружище! =)
        message: "Просыпайся, на работу пора! За окном сейчас {{ states('sensor.owm_temperature')|int }} °C."
    - service: media_player.turn_on # Включаем медиа плеер
      entity_id: media_player.yamaha_671_zone_2 # Указываем, какой именно медиа плеер нас интересует
  	
    - service: media_player.volume_set # Устанавливаем громкость
      data:
        entity_id: media_player.yamaha_671_zone_2# Указываем, какой именно медиа плеер нас интересует
        volume_level: '0.20' # Значение параметра Громкость
    	
    - service: media_player.select_source # Выбираем источник 
      data:
        entity_id: media_player.yamaha_671_zone_2
        source: NET RADIO
	    
    - delay: 00:00:10 # Пауза
    - service: media_player.volume_set # Устанавливаем громкость
      data:
        entity_id: media_player.yamaha_671_zone_2
        volume_level: '0.25'
    	
    - delay: 00:00:01 # Пауза
    - service: media_player.volume_set # Устанавливаем громкость
      data:
        entity_id: media_player.yamaha_671_zone_2
        volume_level: '0.30'
    	 
# Тут было много повторяющихся блоков с растущим значением громкости каждую секунду

    - delay: 00:00:01
    - service: media_player.turn_on # Включаем опять, вдруг выключен. (В идеале лучше выносить в отдельный automation)
      entity_id: media_player.yamaha_671_zone_2
  	
    - service: media_player.select_source
      data:
        entity_id: media_player.yamaha_671_zone_2 # Выбираем источник - теперь это вход Audio 2 - именно к нему подключен RPi
        source: AUDIO2
    	
    - service: media_player.volume_set
      data:
        entity_id: media_player.yamaha_671_zone_2
        volume_level: '0.70'
    	
    - delay: 00:00:01 	
    - service: tts.yandextts_say # Вызываем Яндекс
      data_template:
        message: "Любезный сударь! Извольте выслушать краткую сводку новостей о погоде. За окном сейчас {{ states('sensor.owm_temperature')|int }} градусов." # Указываем какой текст нам необходимо синтезировать
        entity_id: media_player.vlcmp # Указываем, какой медиа плеер должен воспроизвести поток
        language: 'ru-RU'


«Ура! Заработало!». Но чтобы все сделать красиво, предлагаю совершить еще одно несложное действие. Создать группы (вкладка на фронтенде).

Создаем файл group.yaml в родительской папке. В конфиге ссылаемся на него:

group: !include group.yaml

И приступаем к заполнению group.yaml.
Настройка отображения созданных элементов
# Определяем какие вкладки и элементы будут отображаться во frontend, а также, что будет отображаться на основной вкладке.
default_view:
  view: yes
  entities:
    - group.AlarmClock
    - sensor.alarm_time
    - sensor.owm_cloud_coverage
    - sensor.owm_condition
    - sensor.owm_humidity
    - sensor.owm_rain
    - sensor.owm_snow
    - sensor.owm_temperature
    - sensor.owm_wind_speed
 
#Определяем какие элементы входят в состав группы
alarmclock:
  name: Будильник.
  entities:
    - sensor.alarm_time
    - input_slider.alarmhour
    - input_slider.alarmminutes
    - input_boolean.alarmweekday
 
#Вкладка (tab) описываем состав вкладки.
AlarmClock:
  name: Будильник
  view: yes
  entities:
    - group.alarmclock
 


Настала пора сохранить все наши настройки, перезапустить сервис и посмотреть, что получилось!

На данный момент у меня подключены следующие компоненты:

TV, AV Ресивер, роутер TP-Link, ведется отслеживание устройств, оповещение меня и жены, когда кто-то из нас пришел\вышел из дома, автовключение ресивера, когда кто-то появляется дома первый, выключение устройств при выходе всех из дома, временно: Broadlink + Livolo Switch.

Развитие

  • Подключиться к DIY выключателям света
  • Попытаться подключиться к кофемашине и чайнику
  • Сделать кнопки у кровати для более простого выключения будильника!
  • Создать более оптимальные «автоматизации»

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