
Недавно компания Яндекс запустила свою систему «умного дома». Нам предлагают купить недорогие работающие по Wi-Fi устройства: адаптер в розетку, лампочку и ИК пульт. Интересно, что у разработчиков «умных» устройств появилась возможность создать свои навыки «умного дома», это позволит подключить девайсы к системе Яндекса и управлять ими голосом через Алису. В списках навыков появляется всё больше новых брендов. Алиса прекрасно понимает русскую речь, что делает ее безусловным лидером среди голосовых ассистентов на российском рынке.
Однако, не всё так гладко…
Первый минус: в основном, все предложенные системы — «облачные». Их надежность порой вызывает сомнения, так как их работоспособность на прямую зависит от качества соединения с серверами производителя. А при отключении интернета устройства вовсе превращаются в “тыкву”.
Второй минус: система сценариев. Немаловажная часть умного дома — сценарии. И тут они очень примитивные: Если “фраза такая-то”, то включить “устройство такое то”. Для моего умного дома этого оказалось слишком мало.
Минусы на этом не заканчиваются, но остальное связанно скорее с незрелостью системы. Команда разработчиков Яндекса продолжает активно добавлять различные фичи, а баги — править, за что им большое спасибо!
Изучив документацию, я решил создать навык Яндекс УД и подключить к нему контроллер умного дома. Это позволит не зависеть от облачных серверов, реализовывать любые сценарии локально на контроллере и при этом управлять системой голосом через Алису. Для этого я написал плагин “yandex2mqtt” на Node.js.
Немного теории
— Алиса, включи свет.
После этой фразы происходит магия и включается свет. Но что же за кулисами? Давайте разбираться, как всё это работает.
Яндекс-станция, услышав знакомую команду, отправляет данные на сервер Яндекса, которому мы заранее указали адрес нашего контроллера. Сервер обрабатывает информацию и перенаправляет ее на контроллер в виде Post-запроса. На контроллере промежуточный API (в нашем случае это плагин yandex2mqtt) обрабатывает запрос и перенаправляет его в MQTT топик. Дальше происходит обработка сценария в программе Node-Red.
Node-Red решает, что делать дальше. Если это предусмотрено сценарием, он посылает команду на включение света в соответствующий топик MQTT. Драйвер wb-mqtt-serial реагирует, посылая команду по Modbus на релейный модуль, тот переключает реле. И наконец-то включается свет! Да, путь не близкий, однако для пользователя проходят считанные доли секунд.
Давайте посмотрим на плагин yandex2mqtt поближе. Первое, что требует Яндекс для работы навыка, — oAuth сервис для связки аккаунтов в приложении Яндекс. После того как Яндекс получит токен авторизации от oAuth сервиса, он запрашивает список устройств. Плагин yandex2mqtt отдает в ответ список устройств со всеми свойствами в json формате. Затем они появляются в списке доступных для управления устройств (в так называемом квазаре). Теперь, если скомандовать Алисе включить какое-то устройство из списка, Яндекс пошлёт 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:
1. devices.capabilities.on_off — Включение и выключение.
instance:
- on
2. devices.capabilities.color_setting — Управление цветом.
instance:
- 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:
- mute
При правильной комбинации всех свойств устройства Алиса без проблем понимает все отданные ей команды по управлению Умным домом. Тут, конечно, есть некие трудности с комбинированием умений. В документации явно не указано, какие умения можно комбинировать, а какие нельзя. Но с этим нам поможет “метод научного тыка”.
Так, к примеру, я выяснил, что кондиционер содержит четыре умения:
Тип устройства:
devices.types.thermostat.ac
Тип умения:
devices.capabilities.on_off
instance:
- on
devices.capabilities.range
instance:
- temperature
devices.capabilities.mode
instance:
- thermostat
devices.capabilities.mode
instance:
- fan_speed
Остальные свойства описывать не буду, там всё довольно просто.
Чтобы всё заработало, требуется:
- Контроллер
- Любой домен
- 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
Останавливаем сервисы watchdog и nginx.
Пробрасываем 80 порт в роутере.
Запускаем программу certbot:
После запуска программа задаст несколько простых вопросов
1. Ваш e-mail. Просто введите адрес и нажмите enter

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

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

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

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

Значит, сертификат успешно получен. Запомните путь к сертификату и ключу, он потребуется при настройке плагина yandex2mqtt. Для безопасности закройте 80 порт в настройках роутера, он больше не пригодится.
Включаем сервисы watchdog и nginx.
Сертификат от letsencrypt выдаётся на 3 месяца. Не забывайте обновлять.
apt-get update apt-get install certbot
Останавливаем сервисы watchdog и nginx.
service watchdog stop service nginx stop
Пробрасываем 80 порт в роутере.
Запускаем программу certbot:
certbot certonly --standalone
После запуска программа задаст несколько простых вопросов
1. Ваш e-mail. Просто введите адрес и нажмите enter

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

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

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

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

Значит, сертификат успешно получен. Запомните путь к сертификату и ключу, он потребуется при настройке плагина yandex2mqtt. Для безопасности закройте 80 порт в настройках роутера, он больше не пригодится.
Включаем сервисы watchdog и nginx.
service nginx start service watchdog start
Сертификат от letsencrypt выдаётся на 3 месяца. Не забывайте обновлять.
Node.js и плагин yandex2mqtt
Установка
Настраиваем репозиторий node.js
Далее устанавливаем или обновляем все необходимые компоненты
После успешной установки копируем репозиторий yandex2mqtt на контроллер.
Задаём права.
Заходим в папку.
Запускаем установку.
Установка завершена.
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. Скопируйте в него следующее:
После этого сохраните изменения и закройте файл.
Для включения юнита введите в консоль команду:
Теперь можно запускать и останавливать плагин командами
Перейдите в папку /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
После настройки и запуска моста советую проверить сертификат на этом сайте.
Просто введите свой домен, который собираетесь использовать для доступа к Алисе. Для корректной работы сертификат должен пройти все проверки. Иначе ничего не заработает.
Навык Яндекс УД
Создание навыка
1. Перейти на страницу dialogs.yandex.ru/developer
2. Залогиньтесь под своим аккаунтом.
3. Нажать “создать диалог”
4. Выбрать пункт “Умный дом”
5. Ввести обязательные параметры:


6. Связка аккаунтов:

Нажать “добавить новую”
1. Идентификатор приложения — clientId
2. Секрет приложения — clientSecret

7. Сохранить навык

8. Нажать “На модерацию”

9. Нажать “Опубликовать”

2. Залогиньтесь под своим аккаунтом.
3. Нажать “создать диалог”
4. Выбрать пункт “Умный дом”
5. Ввести обязательные параметры:
- Название — Любое название.
- Endpoint URL — адрес типа вашдомен/provider , где вместо “вашдомен” адрес из noip или ваш домен, для которого получен ssl-сертификат.

- Приватность — выбрать “Не показывать в каталоге” (Обязательно! Иначе навык не пройдет мгновенную модерацию)
- Имя и Email разработчика — указать Ваши данные.
- Описание — любой текст
- Иконка — любая иконка.

6. Связка аккаунтов:

Нажать “добавить новую”
- Первые два пункта — указываем данные из config.js / clients :
1. Идентификатор приложения — clientId
2. Секрет приложения — clientSecret
- URL авторизации — вашдомен/dialog/authorize
- URL для получения токена — вашдомен/oauth/token
- URL для обновления токена — вашдомен/oauth/token

7. Сохранить навык

8. Нажать “На модерацию”

9. Нажать “Опубликовать”

Добавление устройств в Яндекс УД.
1. Зайти в приложение Яндекс на телефоне

2. В меню выбрать Устройства/Умный дом

3. Нажать “Добавить устройство”

4. Выбрать свой навык

5. Нажать “Объединить аккаунты”

6. Откроется страница авторизации
Ввести логин и пароль (задается в файле config.js в блоке users)

7. Нажать “Разрешить”.

8. Нажать “Обновить список устройств”


2. В меню выбрать Устройства/Умный дом

3. Нажать “Добавить устройство”

4. Выбрать свой навык

5. Нажать “Объединить аккаунты”

6. Откроется страница авторизации
Ввести логин и пароль (задается в файле config.js в блоке users)

7. Нажать “Разрешить”.

8. Нажать “Обновить список устройств”

Теперь Алисе можно отдавать команды для управления добавленными устройствами. В указанные mqtt топики будут приходить соответствующие команды.
Осталось привязать к этим топикам какие-то действия.
Node-Red
Для системы автоматизации был выбран Node-Red. Это отличный инструмент визуального программирования. Процедуру установки и настройки можно подсмотреть тут.
Процесс настройки и автоматизации умного дома потянет на целую статью, а то и две. Да и таких статей уже много. Вместо этого — небольшой пример использования плагина, как включить лампочку голосом.
Для удобства на контроллере Wiren Board 6 в веб интерфейсе создаем виртуальное устройство.
В движок правил wb-rules нужно вписать
defineVirtualDevice("yandex", { title: "yandex controls", cells: { light1: { type: "switch", value: false }, } });

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 лампочку, и этого хватит. Но если Вы задумали собрать себе по-настоящему умный дом, то простыми способами тут не обойтись. А стоит оно того или нет, каждый решит сам. Спасибо за внимание!
