Как стать автором
Обновить
76.65
Ростелеком
Крупнейший провайдер цифровых услуг и решений

Умный дом своими руками на ESP8266 + Kotlin + React

Время на прочтение13 мин
Количество просмотров27K

Всем привет!

Решил написать про свой опыт построения «умного дома». Тема конечно достаточно избита и статей последнее время про нее много. Но это же и хорошо – значит люди занимаются, делают. Недавно, например, вышел совершенно могучий материал (очень большой труд): Умный Дом. Большое пособие по организации умного дома и автоматизаций в Homekit.

Сразу оговорюсь, что мой кейс достаточно специфический, цели и задачи всей затеи тоже не вполне классические (спойлер: изучить Kotlin и React для работы), поэтому эта статья – для разработчиков, гиков и просто увлеченных людей. Всё что вы увидите под катом я позиционирую как дополнение к материалу «Мой умный дом на ESP8266» (автор: khusamov).

Вместо эпиграфа

Совсем недавно я прочитал заметку писателя Леонида Каганова про проблематику умного дома – очень понравилось (не настолько круто, конечно, как его же рассказ «За что я ненавижу Линукс»), но все равно очень хорошо, рекомендую. Позволю себе процитировать:

Проблема УД — никчемность. Объем задач, которые электроника может решить, — это около 1% всех домашних дел, связанных с ведением хозяйства, пищей, уборкой и повседневными операциями. Электроника не сварит борщ, не сбегает в магазин, не протрет пыль с книжных корешков, не сметет крошки со стола, не почистит за вас зубы и не помоет голову, не вынесет мусор, не выгрузит и не развесит белье, не погладит рубашку, не уберет г#%$о за котом.

Электроника сможет включить свет на кухне. Но как раз это не проблема сделать самостоятельно. Среди этого 1% задач нет качественных — тех, которые дают принципиально новое качество жизни. В основном УД предлагает решения количественные: снизить количество секунд, затраченных для включения света — с пяти секунд (при традиционном путешествии к выключателю) до 11 секунд (поиск смартфона и запуск специального приложения в нем).

Для кого этот материал

Как я уже сказал выше, эта статья – для разработчиков. Отмечу, что я ни разу не «электронщик», а скорее программист и менеджер, максимум что умею: спаять контакты по схеме, измерить напряжение мультиметром.

Иными словами, если у вас есть страх перед железяками, но вы нормально общаетесь с компьютером, софтом и программированием – вам сюда. Ну и как предупреждение – делайте скидку там, где «электронные» рассуждения будут наивными.

Что такое «умный дом» (imho)

Само название себя достаточно дискредитировало, поэтому я сам склоняюсь к термину «автоматизированный дом». В моем случае я сделал пока только включалку лампочек и розеток.

Цели и задачи

Настало время сформулировать цели и задачи:

  1. Развиваться всегда хочется разносторонне, для этого вполне подойдет реализация какого-нибудь очередного pet-проекта;

  2. Давно присматриваюсь к «умным домам», потому что это интересно, это «железяки + программы»;

  3. Также хочется провести время с пользой и поэтому ключевое – изучить некоторые новые языки программирования и фреймворки. Забегая вперед скажу, что в части софта речь пойдет про Kotlin/Spring и React.

Остановимся на третьем пункте, ключевом для меня. Большое количество статей и поделок основано на том, чтобы взять какое-нибудь ПО и «сконфигурировать его должным образом». Чаще всего, как мне кажется, берут Domoticz, Home Assistant (не ставил ни то ни другое), но перечень постоянно растет.

Почему этой дорогой идти не хотелось: вероятно, получилось бы «стройнее» и «грамотнее», но приобретенные знания заключались бы в том, что я научился хорошо конфигурировать специализированное ПО. А цель ставилась другая. В моем случае изучение языков программирования помогает в текущих и будущих проектах, позволяет лучше понимать коллег из фронтэнда и бэкэнда. В общем, одни сплошные плюсы.

Начало

Итак, приступим. Решено было делать все на знаменитой микросхеме 8266. Плюсы:

  1. Очень популярна;

  2. Куча документации, информации;

  3. Работает по Wi-Fi, а провода (слаботочка) у меня не проложены;

  4. Может быть точкой доступа и веб-сервером;

  5. Некий опыт работы с «ардуиной» уже имеется, поэтому как минимум – не с нуля.

Принципы умного дома

Сформулируем основные принципы, это важно:

  1. Все должно функционировать в локальной сети дома;

  2. Должен быть доступ из интернета. А когда нет интернета, см. п.1;

  3. Должно работать с мобильных устройств и из браузеров;

  4. Никакие сторонние серверы для управления устройствами быть не должны (только те, что из п.1);

  5. Также прикрутить это все к Алисе, раз уж она есть;

  6. Пульт управления должен находиться внутри самой квартиры.

Выбор оборудования

Можно было строить все на голых платах и реле – их доступно масса (Алиэкспресс, родной), но, посмотрев, выбор пал на устройства Sonoff. Что мы тут имеем:

Плюсы

Минусы

• Корпус;
• Заводская сборка, заводская пайка;
• Некий опыт использования «в народе»;
• Постоянно расширяющаяся линейка продукции. Уже и лампочки есть;
• Легко перевешивается туда, куда захочешь (ESP Easy, Tasmota)

• Своя прошивка, которая общается со своими же китайскими серверами;

Заказываем на Али устройства: Sonoff 4Ch Pro, Sonoff Basic, Sonoff S26. Первая – штуковина на четыре устройства. Не знаю, нужно ли было брать Pro, но что взял то взял. Есть смысл брать подобные, так как подключить можно четыре канала, а соединение по Wi-Fi одно – бережем сеть. Вот он, красавец, смонтирован даже в корпус и на дин-рейку.

Sonoff 4CH Pro.
Sonoff 4CH Pro.
Basic и S26. 
Бейсики - просто минимальные устройства, их можно вкрутить в "разрыв провода". S26 - умная розетка. Как по мне, с ней чересчур громоздко, более мелкая пайка, но, тоже опыт.
Basic и S26. Бейсики - просто минимальные устройства, их можно вкрутить в "разрыв провода". S26 - умная розетка. Как по мне, с ней чересчур громоздко, более мелкая пайка, но, тоже опыт.

Для пульта управления купил на Авито планшет Amazon Fire по совсем уж скромным деньгам (оно и понятно – пользоваться им в 2021 году вряд ли кто уже будет, но для пульта управления подойдет). Видимо даже чуть ли не одной из первых версий, с андроидом аж второй версии, причем сильно кастомизированной.

После танцев с бубном удалось поднять версию до обычной 5-ки, этого хватит для запуска браузера. Планшет хоть и дубовый, но качество сборки у Амазона все-таки выше, чем у китайского ноунейма. Он был прикручен к стене в коридоре

UPD: к сожалению, после года висения в постоянно включенном виде планшет перестал работать, поэтому фото не прикладываю до момента его замены.

Как прошивать

Не буду подробно останавливаться, в статьях выше есть. Ключевое – покупается платка (конвертор интерфейса USB в TTL UART). Я покупал на Авито, можно на Али (но не хотелось ждать), можно скорее всего в «чип и дипе».

Магии почти никакой нет, куча информации есть на 4pda (важно во всей этой мелкой электронике никогда не путать 3.3V и 5V – иногда на платах даже есть переключатели). Одной стороной плата смотрит в USB компьютера, другой припаивается к Sonoff (важно не перепутать контакты Rx и Tx, но если и перепутаете, то греха не будет – просто прошивка не пойдет, ничего не сломается).

Прошивка инициируется определенными действиями – либо надо кнопку нажать, либо определенный контакт замкнуть (зависит от устройства – смотреть в профильной теме на 4pda). Все сработает, хоть и не с первого раза.

После прошивки устройство поднимает собственную Wi-Fi сеть. Нужно подключиться к ней и прописать устройство в сеть роутера, тогда оно станет полноценным членом этой сети.

О прошивках

Интереснее выглядит ESP-Easy, она такая, более техническая что ли. Но у меня была проблема – пробовал прошить бэйсики одной из версий, в итоге все время отключалась сеть (видимо была проблема в конкретной версии). Тогда я поставил на эти устройства «Тасмоту», с ней проблем не было (хотя, 4ch очень успешно работает на ESP-Easy).

Минимально все сделано, можно монтировать. Все устройства доступны по HTTP, включать/выключать можно простым GET запросом из браузера. Но это ведь не то, что мы хотели?

Нужно написать софт, который всем этим будет управлять. Софт должен где-то располагаться, т.е. ему нужен сервер. В качестве сервера подойдет любой более-менее приличный одноплатник (jvm все-таки ресурсоемкая штука).

Под это дело я купил Orange Pi 4B (попутно на нем еще несколько других штук крутится), плата достаточно хорошая, сравнительно недешевая – производительность на хорошем уровне. Из минусов – греется как утюг, но вроде это ее не портит, иначе не работала бы. На всякий случай просверлил две дырки и поставил ей вентилятор (стало шумновато).

Orange Pi 4B. Однако, как самое популярное решение, наверное проще всего - взять Raspberry PI.
Orange Pi 4B. Однако, как самое популярное решение, наверное проще всего - взять Raspberry PI.

Пишем софт

Концепция приложения

Сформулируем концепцию. Она же потом ляжет в основу базы данных приложения.

Основные понятия:

  1. Конфигурация. Идея следующая – чтобы можно было вести в одной программе несколько конфигураций. Допустим дома одна картина мира, а на приусадебном участке – другая. Пока не пригодилось, но оставим задел на будущее;

  2. Пользователи. Да, все пользователи у нас авторизованные, по паролю. И один служебный – для работы Алисы.

  3. Локация. Группирующий элемент, ближайший аналог – комната;

  4. Устройство. Собственно, само устройство. Здесь, как раз, записываются конкретные команды на включение / выключение / получения статуса.

  5. По мелочи и не совсем по теме. Решил также вести перечень полезных ссылок – всего, что дом умеет отдавать себя через браузер.

Самое время придумать приложению название – пусть у нас будет «Умное гнездо», т.е. Clever nest.

Рассказ про Kotlin

Настало время чуть более подробно остановиться на приложениях. Серверную часть писать будем на Kotlin. Почему он? Java я уже более менее знаю, а Kotlin у нас на работе набирает популярность, т.е. есть смысл к нему присмотреться. Тем более в Андроиде он сейчас уже язык по умолчанию, а еще он сейчас шагает и в сторону Native, JS и iOS. Как оказалось – не зря. Изначально его воспринимаешь как некий синтаксический сахар «над явой» (прощай lombok!), но потом начинаешь уже думать на нем.

Синтаксис интересный, в чем-то даже напоминает старый добрый паскаль – ощутимо проще и лаконичнее явы. Главная киллер-фича, вокруг которой носятся котлинисты – это, так называемая, null safety. Хотя я считаю, что программист все-таки должен уметь обрабатывать нуллы и не бояться их, в целом – это действительно очень удобно.

Есть много статей, в которых преимущества Kotlin описаны более подробно, например недавно попалась на глаза из свежих – в целом там все более-менее нормально описано.

Также мы будем использовать Spring (Spring Boot 2), так как этот фреймворк тоже максимально популярен, мы его также используем.

Что будет делать приложение?

Оно будет принимать входящие запросы (GET, POST) и отдавать в ответ данные в формате JSON. Визуальной части у приложения не будет, хотя одна страничка все-таки есть:

Страница серверного приложения
Страница серверного приложения

Целью статьи не ставится детальное описание процесса написания софта (больше хочется показать всю картину в целом), поэтому остановлюсь тезисно:

  1. Разработка велась в IntellijIDEA. Лучшая IDE на мой взгляд, вполне хватило бесплатной версии;

  2. Из базового шаблона был выбран Kotlin + Spring Boot + Gradle. Шаблон приложения можно построить инициализатором: https://start.spring.io/;

  3. В качестве БД была взята легковесная Java БД: H2 database (https://www.h2database.com/html/main.html). Не знаю почему, просто было интересно попробовать. В целом – никаких нареканий, все нормально. Хотя, как-то развивается она вяло и в следующий раз я взял бы HSQLDB или SQLite;

Какие удалось применить и опробовать фишки, которые ранее не пробовал:

  • Самодокументирование методов и отдача REST-эндпоинтов в качестве Swagger интерфейса. Отлично и для описаний, и для тестирования, не требует почти ничего дополнительного. Всегда сейчас буду пользоваться (на скриншоте ссылка /swagger-ui/ как раз об этом). Выглядит вот так:

Самодокументирование эндпоинтов приложения через swagger
Самодокументирование эндпоинтов приложения через swagger

Вляпался в одну неприятность – самая последняя версия Spring Boot не захотела работать со сваггером (вернее он с ней), но “предпоследняя» вполне работает – если будете брать проект и обновлять версии библиотек – вы предупреждены (сейчас уже могло все измениться).

  • Мониторинг java-melody. Тоже в целом приятная штука со всякими графиками и т.д., которая много чего показывает. Особо не нужно в таком мелком проекте, но для интереса – прикрутил. Умеет даже SQL запросы выводить и время их выполнения;

  • Аутентификация в сервисе с помощью Spring security, JWT-токенов с хранением пользователей в таблице БД. Использовалась библиотека «Java JWT: JSON Web Token for Java and Android». Так как интерфейса для ввода пользователей нет (вводятся напрямую в БД), а пароли в БД хранятся в виде закодированных хэшей – сделана сервисная ссылка: password encryption;

  • Опробованы также действия по расписанию через Spring аннотацию @Scheduled (пригодилось для периодического опроса устройств)

  • Приложение установлено в систему в виде systemd сервиса, при перезагрузке устройства (плановой и аварийной) автозапускается;

  • Исходники доступны на github.

Минусы и планы. Весь ввод данных сейчас идет напрямую в базу данных (я использую DBeaver). По хорошему, надо под это дело сделать интерфейс. Но, конечно, в целом не критично.

Рассказ про React

Настало время написать клиентское приложение.  С этим всем у меня куда как хуже. То есть на базовом уровне о Javascript я представление имею. Когда-то использовал jQuery и это очень классная библиотека.

Почему React? Тут тоже все просто – у нас много пишут на нем (хотя пишут и на ангуляре и на vue, но на реакте больше). Это знание также показалось полезным, хотя можно было тут поэкспериментировать с тем же котлином (он сейчас умеет в Javascript). Ну ладно, пойдем путем мэйнстрима – итак все вокруг незнакомое – будем разбираться.

Для начала нужно установить node.js. В качестве среды разработки я взял VSCode, и потом немного пожалел. Он конечно классный, на нем много чего можно, но почему-то он у меня под убунтой (периодически) достаточно крепко зависал – и я так и не разобрался почему (может плагины были тому виной). IDEA же заявляет поддержку JS только в Ultimate версии. Но в нее можно поставить бесплатное расширение, которое подсветит синтаксис JS. И этого, в целом, тоже хватило.

Честно говоря, впечатление от современной фронтовой разработки у меня остались неоднозначные. React – это некий «псевдо-js» (jsx), который компилируется уже в js и запускается в браузере (но этот js уже принимает технический вид, т.е. становится нечитаемым).

Приложение на реакте далось уже сложнее, видимо фронтэнд – не моя сильная сторона. Много гуглил, пробовал, двигался на ощупь. Тем не менее – приложение получилось (простенькое конечно), успехи следующие:

  • Удалось разобраться в базовых вещах;

  • Также получилось разобраться в жизненном цикле компонента, передаче параметров между компонентами;

  • Авторизация, куки, токены;

  • Удалось прикрутить всё это к первому приложению;

  • Исходники доступны на github.

Правда мне не удалось досконально разобраться с CSS, но видимо оставлю на следующий заход. Но в целом – все работает, причем прекрасно ведет себя как на большом мониторе, так и на смартфонах. В качестве компонента взял material-ui, выглядит достаточно лаконично:

Интерфейс приложения
Интерфейс приложения

Как всё работает технически

React-приложение ставится тоже на тот же сервер (Orange PI4B), но на другой порт - под управлением Nginx. Когда вы на него заходите в браузере, оно запускается у вас на устройстве и переговаривается с приложением на бэкэнде. Таким образом между сервером и устройством на котором приложение отображается должна быть связь. Эта связь есть по умолчанию, если все устройства находятся в домашней сети.

Но мы же хотим через интернет? Поэтому пару слов о роутере и настройке портов.

Про роутер Mikrotik

Для того, чтобы попасть «домой» из интернета нам нужно знать домашний ip-адрес и настроить перенаправление портов. Так как провайдер в общем случае не гарантирует постоянство этого адреса, это может быть проблемой. Чаще всего она решается двумя способами:

  1. Фиксацией IP-адреса у провайдера. Обычно это стоит дополнительной ежемесячной оплаты;

  2. Регистрация на каком либо Dynamic DNS сервисе, который может выдать (и обновлять) вам символьное имя, гарантируя его постоянство.

К счастью, у меня есть роутер Mikrotik (про эти роутеры очень много материалов – это могучие устройства, поэтому в статье я буквально вскользь упомяну), второй вариант у нас есть «из коробки». В разделе «IP \ Cloud» мы можем включить «DDNS Enabled» и получить адрес вида: цифрыибуквы.sn.mynetname.net.

Запускаем все вместе, проверяем

Все запустилось, работает, устройства щелкают, мигают.

Но выяснилась одна особенность: если устройства долго не трогать, то потом к ним сложновато достучаться – засыпают. Дорабатываем бэкэнд и делаем периодический запрос статусов устройств. Помогло – стало сильно стабильнее. 

Алиса, Домовенок Кузя и другие сказочные персонажи

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

Для Алисы есть так называемые навыки, это что-то вроде расширений. Навык регистрируется, настраивается. Запускается он просто голосом – «Алиса, запусти навык Х». 

Изучив каталог навыков стало понятно, что нам нужен Домовенок Кузя. Для настройки он имеет свой веб-интерфейс (https://alexstar.ru/).

Интерфейс работы с Домовенком Кузей
Интерфейс работы с Домовенком Кузей

У него тоже есть своя парадигма, начинается настройка с правил. Приведу пример описания правила:

Правило HTTP

Большая комната, включить свет

Активационная фраза

Большая комната, включить свет

Ответ Кузи

Включено!

Тип запроса

GET

Поиск значений в фразе

Не искать

URL управления устройством, доступный из интернета

http://1234asdf5678.sn.mynetname.net:8086/espdevice/control?Command=ON&dId=4&aLinkConf=1&domovenokFormat=true&password=XXX

Ждать ответ от сервера

да

Правило включено

да

Разберем URL, который мы ему даем:

1234asdf5678.sn.mynetname.net:8086

Адрес, по которому мы можем достучаться до нашего бэкэнд приложения (фронтэнд тут не нужен, по сути Алиса - это альтернативный голосовой фронтэнд)

/espdevice/control

Эндпоинт который отвечает за коммуникацию с устройствами

Command=ON

Команда включить

aLinkConf=1

Ссылка на конфигурацию (у нас она одна)

dId=4

Идентификатор устройства = 4

domovenokFormat=true

Выдавать ответ в формате, понятном Домовенку

password=XXX

Постоянный пароль, соответствующий служебному пользователю с идентификатором -1

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

Всё? Не всё.

Теперь чтобы включить, например, принтер...

О принтере

Cтаренький принтер даже не знал о том, какая яркая судьба ждет его в финале карьеры – при помощи платы Orange Pi Lite из обычного лазерного МФУ он превратился в сетевой принтер (с помощью CUPS), а еще в сетевой сканер (с помощью SANE).

...мы должны сказать:

  1. «Алиса, включи навык Домовенок Кузя»;

  2. Включить принтер;

  3. «Алиса, хватит».

Интерфейс приложения Яндекс
Интерфейс приложения Яндекс

Неудобно. К счастью, созданные в Кузе устройства можно добавить как устройства в приложении «Яндекс», т.е. повторно их там зарегистрировать.

При этом мы получаем возможность не заходить в навык, а просто говорить «Алиса, включи свет в большой комнате». При это у Алисы менее жесткие требования к активационным фразам (в Кузе надо проговаривать в точности как сконфигурировали).

Вот теперь неплохо!

Заключение

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

  • Прошло больше года со старта этой затеи. Приятно, что все работает;

  • Сдох планшет, висящий на стене, но это мелочь – скоро появится новый;

  • Настала и не закончилась пандемия, мы практически все время работаем из дома и необходимости в удаленном управлении практически нет;

  • Но есть приятные фишки, такие как удаленная (из другой комнаты) перезагрузка принтера, если он завис;

  • Sonoff 4CH Pro иногда немного глючит – выключает один из своих четырех каналов, при этом его нужно включить фразой «Алиса, включи свет в большой комнате» и все работает дальше;

  • Мы в департаменте продолжаем работать на Котлине, теперь это у нас основной язык для разрботки бэкэнда и небольших утилит;

  • Планы по развитию проекта? Если честно, особо нет. Хочется еще освоить лампочку (тоже на 8266, даже куплена одна), хочется в люстры закинуть basic-устройства (подвесной потолок позволяет), чтобы можно было регулировать не целиком вкл/выкл, а «по половине люстры». Были мысли посмотреть в сторону ZigBee устройств, но они (мысли) пока не вызрели. Наверное в подобных затеях есть смысл на даче, в своем доме и т.д. В рамках квартиры же – это скорее интересные эксперименты, чем реальная необходимость;

  • Здесь могла бы быть реклама нашего РТ-шного умного дома (знаю, что эта тема активно развивается в компании), с посылом «Ну, если не хотите идти такой сложной и запутанной дорогой, то вот вам, смотрите как клево». Но этот пользовательский опыт у меня еще впереди :)

Вернемся к эпиграфу – прав ли был писатель lleo? Предлагаю вам решить это самим ;)

В качестве дополнения напишу, что еще можно поднять на одноплатнике.

Чтобы было весело и интересно
  1. RPi Monitor – небольшое приложение, отдающее веб-страницу по мониторингу самого себя (температура, память, загрузка). Подходит не только для Raspberry, пусть название вас не смущает;

  2. Pi-hole – решение, позволяющее убирать рекламу (основано на подмене DNS) при серфинге интернета;

  3. Подключить USB SSD диск и настроить его автомонтирование. Это понадобиться в следующем пункте;

  4. Transmission – торрент клиент, с легким веб-интерфейсом;

  5. FTP сервер – для доступа к файлам на одноплатнике / жестком диске (можно со смартфона). На armbian-debian обнаружилась проблема с русскими буквами;

  6. Samba сервер – примерно то же, но более нативный доступ с Windows-машин, тоже можно со смартфона. И с русскими буквами все окей (обязательно нужно установить пароль, иначе машины будут упорно отказываться соединяться);

  7. MiniDLNA – отличная вещь, которая позволяет одноплатнику выступать в роли DLNA-сервера. Контент видят все смартфоны и практически все телевизоры в локальной сети (как новые, так и десятилетней давности). Появляется возможность включать фильмы сразу после того как они были скачаны в п.4;

  8. CUPS – решение по превращению локального принтера в сетевой;

  9. SANE – решение по превращению локального сканера в сетевой. На МФУ в сочетании с п.8. реализуются обе составляющее;

  10. TorBOX Next Generation – решение, которое позволяет поднять на одноплатнике отдельную WiFi-сеть, которая будет TOR-сетью со всеми вытекающими. Если пункты выше можно установить на одном одноплатнике, то здесь лучше отдельную плату использовать.

Ссылки на проекты в GitHub:

  • Серверное приложение: github;

  • Клиентское приложение: github.

Теги:
Хабы:
+8
Комментарии19

Публикации

Информация

Сайт
www.company.rt.ru
Дата регистрации
Дата основания
Численность
свыше 10 000 человек
Местоположение
Россия
Представитель
Alexeev Ilya