Добрый день, уважаемый читатель. На днях довелось мне поиграться с многим уже известной игрушкой от Google – Google Home. Штука хорошая — обзор ее я делать конечно не буду. В чулане совершенно случайно завалялись Raspberry PI 3 (RPi), Arduino Mega и еще им подобная мелочь, которую захотелось подключить к Google Home (GH) с целью голосового управления. Простого API у GH нет, но есть возможность с помощью стороннего сервиса организовать голосовое управление системой на RPi + Arduino с задержкой команд в несколько секунд.
Читая буржуйские форумы (справедливости ради, нужно отметить, человек я повернутый на автоматизации и IoT), обратил внимание на доселе мне неизвестное нечто, что называют Home Assistant (HASS), эту систему умельцы-то и прикручивают к GH.
В двух словах о самой платформе:
Система написана на Phyton, последний релиз был 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 и многое, многое другое.
Для запуска, подключения и настройки компонентов, выключателей, сценариев, групп, триггеров совершенно не обязательно знать Phyton, но нужно хоть немного знать 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 есть, а также, возможно, поможет вам в настройке собственного окружения.
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
И приступаем к заполнению.
Так как у меня используется инкрементирование громкости каждую секунду — файл большой. Я приведу самые необходимые строки, остальное можно настроить по аналогии.
- 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 будет живой интерес, опишу и другие возможности с примерами. До новых встреч!
Автор: conspiratus