Хабрахабр

Яндекс: умный дом по-взрослому

Нам предлагают купить недорогие работающие по Wi-Fi устройства: адаптер в розетку, лампочку и ИК пульт. Недавно компания Яндекс запустила свою систему «умного дома». В списках навыков появляется всё больше новых брендов. Интересно, что у разработчиков «умных» устройств появилась возможность создать свои навыки «умного дома», это позволит подключить девайсы к системе Яндекса и управлять ими голосом через Алису. Их надежность порой вызывает сомнения, так как их работоспособность на прямую зависит от качества соединения с серверами производителя. Алиса прекрасно понимает русскую речь, что делает ее безусловным лидером среди голосовых ассистентов на российском рынке.
Однако, не всё так гладко…
Первый минус: в основном, все предложенные системы — «облачные». Немаловажная часть умного дома — сценарии. А при отключении интернета устройства вовсе превращаются в “тыкву”.
Второй минус: система сценариев. Для моего умного дома этого оказалось слишком мало.
Минусы на этом не заканчиваются, но остальное связанно скорее с незрелостью системы. И тут они очень примитивные: Если “фраза такая-то”, то включить “устройство такое то”. Это позволит не зависеть от облачных серверов, реализовывать любые сценарии локально на контроллере и при этом управлять системой голосом через Алису. Команда разработчиков Яндекса продолжает активно добавлять различные фичи, а баги — править, за что им большое спасибо!
Изучив документацию, я решил создать навык Яндекс УД и подключить к нему контроллер умного дома. Для этого я написал плагин “yandex2mqtt” на Node.js.

Немного теории

— Алиса, включи свет.
После этой фразы происходит магия и включается свет. Но что же за кулисами? Давайте разбираться, как всё это работает.
Яндекс-станция, услышав знакомую команду, отправляет данные на сервер Яндекса, которому мы заранее указали адрес нашего контроллера. Сервер обрабатывает информацию и перенаправляет ее на контроллер в виде Post-запроса. На контроллере промежуточный API (в нашем случае это плагин yandex2mqtt) обрабатывает запрос и перенаправляет его в MQTT топик. Дальше происходит обработка сценария в программе Node-Red.
Node-Red решает, что делать дальше. Если это предусмотрено сценарием, он посылает команду на включение света в соответствующий топик MQTT. Драйвер wb-mqtt-serial реагирует, посылая команду по Modbus на релейный модуль, тот переключает реле. И наконец-то включается свет! Да, путь не близкий, однако для пользователя проходят считанные доли секунд.

Первое, что требует Яндекс для работы навыка, — oAuth сервис для связки аккаунтов в приложении Яндекс. Давайте посмотрим на плагин yandex2mqtt поближе. Плагин yandex2mqtt отдает в ответ список устройств со всеми свойствами в json формате. После того как Яндекс получит токен авторизации от oAuth сервиса, он запрашивает список устройств. Теперь, если скомандовать Алисе включить какое-то устройство из списка, Яндекс пошлёт Post запрос с данными устройства, которое он хочет включить, на контроллер. Затем они появляются в списке доступных для управления устройств (в так называемом квазаре). Если же устройство изменило свой статус без участия Яндекса, то плагин, увидев новые данные в mqtt топике, отправит их Яндексу при запросе статуса, который сейчас происходит, только если зайти в само устройство в квазаре. В ответ плагин подтверждает включение и записывает новое состояние в mqtt топик, указанный в настройках все того же плагина. В иных случаях Яндекс не опрашивает статусы.
Теперь расскажу о некоторых свойствах устройств Яндекс УД.

Тип устройств:

Для правильного отображения в “квазаре” и более точного определения команд Алисой Яндекс предлагает присваивать устройствам разные типы. Всего типов 10:

  • devices.types.light — Любой светильник, люстра, лампочка итд.
  • devices.types.socket — Розетка
  • devices.types.switch — Переключатель
  • devices.types.thermostat — Термостат
  • devices.types.thermostat.ac — Кондиционер
  • devices.types.media_device — Медиа устройство
  • devices.types.media_device.tv — Телевизор
  • devices.types.cooking — Кухонная техника
  • devices.types.cooking.kettle — Чайник
  • devices.types.other — Всё остальное, что не подошло под предыдущие пункты.

Умение (capability)

Также у каждого устройства должно быть минимум одно умение (capability).
Всего у Яндекс УД есть 5 типов умений. Каждое умение имеет разную функцию (instance), а некоторые умения имеют несколько таких функций, что добавляет гибкости при настройке устройств.

Сapabilities:

devices.capabilities.on_off — Включение и выключение.
instance:
1.

devices.capabilities.color_setting — Управление цветом.
instance:
2.

  • rgb
  • hsv
  • temperature_k

3. devices.capabilities.mode — Переключение режимов.
instance:

  • thermostat
  • fan_speed

4. devices.capabilities.range — Управление диапазоном.
instance:

  • brightness
  • temperature
  • volume
  • channel

5. devices.capabilities.toggle — Выключение звука.

instance:

Тут, конечно, есть некие трудности с комбинированием умений. При правильной комбинации всех свойств устройства Алиса без проблем понимает все отданные ей команды по управлению Умным домом. Но с этим нам поможет “метод научного тыка”.
Так, к примеру, я выяснил, что кондиционер содержит четыре умения: В документации явно не указано, какие умения можно комбинировать, а какие нельзя.

Тип устройства:
devices.types.thermostat.ac

Тип умения:
devices.capabilities.on_off
instance:

devices.capabilities.range
instance:

  • temperature

devices.capabilities.mode
instance:

  • thermostat

devices.capabilities.mode
instance:

Остальные свойства описывать не буду, там всё довольно просто.

Чтобы всё заработало, требуется:

  • Контроллер
  • Любой домен
  • SSL сертификат
  • Node.js
  • Плагин yandex2mqtt
  • MQTT брокер
  • Node-red

Контроллер

Моя “умная” квартира управляется контроллером Wiren Board 6. Но можно использовать любой другой контроллер на линуксе, который потянет Node.js и Node-Red. Например, Raspberry pi или ПК.

Домен

Желательно, конечно, иметь белый IP адрес и купить домен, но это необязательно. Можно использовать DDNS — например, www.noip.com.
Тут всё просто: регистрируемся, создаем бесплатный хостнейм, вписываем свой IP адрес. У некоторых роутеров есть специальная настройка DDNS, куда можно вписать данные noip.com. Роутер будет автоматически отправлять IP адрес при его смене. Если такой настройки в роутере нет, можно установить программу noip на контроллер и добавить её в автозапуск. Программа будет делать ровно то же самое, что и роутер со специальной настройкой DDNS — обновлять Ваш ip адрес в базе noip.com
Таким образом, мы имеем статический адрес, который перенаправляет все запросы на наш контроллер.

Порты 443 и 80

Сейчас почти у каждого человека дома есть роутер. Помимо очевидных его функций, он также является барьером для локальной сети от нежелательных гостей извне. Но в определённых случаях нам требуется доступ к внутренней сети снаружи. Производители роутеров это предусмотрели и добавили функцию NAT (Network Address Translation).
Момент настройки роутера я расписывать не стану, так как он разный для каждого производителя. Как это сделать, читайте в инструкции к Вашему роутеру. Ключевые слова для гугления: Port Forwarding, Port Mapping, NAT.
Необходимо пробросить порт для доступа к yandex2mqtt (может быть любой, я выбрал 443) и 80 порт (нужен только для получения SSL сертификата. После получения сертификата 80 порт можно закрыть).

SSL-сертификат

Сразу расставим все точки над «и»: самоподписанные сертификаты работать не будут.
Большинство регистраторов доменов (например, reg.ru) дарят своим клиентам бесплатные SSL-сертификаты для основного домена (www.yourdomain.ru). Если вы купили домен специально для Алисы, то Вы можете воспользоваться предоставленным SSL-сертификатом.
Если же собственного домена Вы не имеете, либо для Алисы у Вас выделен другой поддомен (например, alice.yourdomain.ru), то нужно получить сертификат на этот поддомен, либо на адрес, предоставленный DDNS-службой.
Для этого предлагаю воспользоваться бесплатной услугой получения SSL-сертификата от letsencrypt.org.
Для получения сертификата необходимо установить программу certbot, запустить и указать все данные, которые она запросит. При этом должен быть свободен и доступен снаружи порт 80. Я советую внимательно изучить инструкцию от letsencrypt.

Установка и настройка certbot

apt-get update
apt-get install certbot

Останавливаем сервисы watchdog и nginx.

service watchdog stop
service nginx stop

Пробрасываем 80 порт в роутере.

Запускаем программу certbot:

certbot certonly --standalone

После запуска программа задаст несколько простых вопросов

Ваш e-mail. 1. Просто введите адрес и нажмите enter

Вам предлагают прочесть пользовательские соглашения. 2. Если вы со всем согласны, просто введите “A”, что означает Agree, то есть согласен.

Программа просит разрешения на отправку Вашего адреса электронной почты разработчикам. 3. Введите N.

Введите свой домен, на который хотите получить сертификат (можно ввести тот, что мы получили в noip ранее). 4. Префикс http:// вводить не нужно.

Если Вы всё сделали правильно, то увидите следующее:

Значит, сертификат успешно получен. Тут я привожу пример ошибочного ввода. Для безопасности закройте 80 порт в настройках роутера, он больше не пригодится. Запомните путь к сертификату и ключу, он потребуется при настройке плагина yandex2mqtt.

Включаем сервисы watchdog и nginx.

service nginx start
service watchdog start

Не забывайте обновлять. Сертификат от letsencrypt выдаётся на 3 месяца.

Node.js и плагин yandex2mqtt

Установка

Настраиваем репозиторий node.js

curl -sL https://deb.nodesource.com/setup_10.x | bash -

Далее устанавливаем или обновляем все необходимые компоненты

apt-get install -y nodejs git make g++ gcc build-essential

После успешной установки копируем репозиторий yandex2mqtt на контроллер.

git clone https://github.com/munrexio/yandex2mqtt.git /mnt/data/root/yandex2mqtt

Задаём права.

chown -R root:root /mnt/data/root/yandex2mqtt

Заходим в папку.

cd /mnt/data/root/yandex2mqtt

Запускаем установку.

npm install

Установка завершена.

Автозапуск

Cоздайте юнит systemd:
Перейдите в папку /etc/systemd/system/ на контроллере и создайте файл с названием yandex2mqtt.service. Скопируйте в него следующее:

[Unit]
Description=yandex2mqtt
After=network.target [Service]
ExecStart=/usr/bin/npm start
WorkingDirectory=/mnt/data/root/yandex2mqtt
StandardOutput=inherit
StandardError=inherit
Restart=always
User=root [Install]
WantedBy=multi-user.target

После этого сохраните изменения и закройте файл.
Для включения юнита введите в консоль команду:

systemctl enable yandex2mqtt.service

Теперь можно запускать и останавливать плагин командами

service yandex2mqtt start
service yandex2mqtt stop
service yandex2mqtt restart

Настройка:

Все необходимые настройки плагина находятся в файле /mnt/data/root/yandex2mqtt/config.js
Отредактируйте этот файл в соответствии с Вашими параметрами.
SSL-сертификат обязательно должен быть fullchain.
После настройки запустите yandex2mqtt командой:

service yandex2mqtt start

После настройки и запуска моста советую проверить сертификат на сайте www.sslshopper.com/ssl-checker.html

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

Навык Яндекс УД

Создание навыка

Добавление устройств в Яндекс УД.

Теперь Алисе можно отдавать команды для управления добавленными устройствами. В указанные mqtt топики будут приходить соответствующие команды.

Осталось привязать к этим топикам какие-то действия.

Node-Red

Это отличный инструмент визуального программирования. Для системы автоматизации был выбран Node-Red. Процедуру установки и настройки можно подсмотреть тут.

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

Для удобства на контроллере Wiren Board 6 в веб интерфейсе создаем виртуальное устройство.
В движок правил wb-rules нужно вписать

defineVirtualDevice("yandex", , }
});



MQTT топики этого виртуального устройства впишем в config.js на тип умения “on” устройства “Свет”:

devices: [ //_______________ Начало устройства ______________//
{ name: 'Свет', room: 'Комната', type: 'devices.types.light', mqtt: [ { type: 'on', set: '/devices/yandex/controls/light1/on', // топик управления stat: '/devices/yandex/controls/light1' // топик статуса }, ], capabilities: [ { type: 'devices.capabilities.on_off', retrievable: true, state: { instance: 'on', value: true } }, ] }, //_______________ Конец устройства _______________// ]

Теперь при фразе “Алиса, включи/выключи Свет” переключается виртуальное устройство.

Перейдем в Node-Red, который установили по инструкции.
Для удобной работы с Wiren Board 6 также можно использовать дополнительную “ноду” node-red-contrib-wirenboard.
В контроллер поставлен модуль расширения WBE2R-R-ZIGBEE, что позволило подключиться к “Икеевской” умной лампочке серии ТРОДФРИ по ZigBee-протоколу.

Закинуть несколько блоков в рабочее поле Node-Red, соединить “ниточками” и нажать Deploy.

Икеевская лампочка подключена через плагин zigbee2mqtt, поэтому в mqtt топик лампочки для управления нужно отправлять json. Теперь дело за малым. Проверяем. Для этого между виртуальным девайсом WB и mqtt топиком лампочки вставим простую функцию.

Нажимаем Deploy.

Алиса, включи Свет!

Возможно в некоторых случаях это слишком сложно, проще купить обычную wi-fi лампочку, и этого хватит. Итак, сегодня мы научились подключать Алису к системе автоматизации. А стоит оно того или нет, каждый решит сам. Но если Вы задумали собрать себе по-настоящему умный дом, то простыми способами тут не обойтись. Спасибо за внимание!

Показать больше

Похожие публикации

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

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

Кнопка «Наверх»