Умный дом на минималках
Или история о том, как из планшета на Andoid я делал хаб для умного дома с управлением через Telegram.
В последнее время я всё чаще задумывался на тему реализации простых сценариев умного дома. Хотелось сделать просто, без голосового управления, минимальными вложениями для начала. Мои мечты почти разбились о суровую реальность протоколов, на которых работают умные устройства. И, о чудо, я сумел сформулировать запрос для себя правильно, и гугл помог мне найти «умную розетку с открытым HTTP API».
Что получилось из связки: умная розетка, китайский планшет на Android 11, Wi-Fi роутер — можно прочитать под катом.
Вступление
Меня зовут Алексей, я Golang разработчик.
Планировал этот проект я давно, а получилось воплотить только в Новогодние праздники 2023. Получился рабочий проект, про который я решил рассказать на Хабре. Это мой дебют: я постарался вчитаться в правила, разложить по полочкам и написать интересную статью. При этом, конечно, старался сделать материал понятным для любого читателя. Как у меня это получилось, решать, конечно, вам. Сам я от этого процесса получил (и получаю) максимальное удовольствие, пусть и путь, для начала, был долог и тернист.
В результате получился достаточно объемный лонгрид для продвинутых пользователей. Так что я рекомендую и вам запастись чайком-кофейком, а я постараюсь рассказать вам о том как получилось сделать «чуть поумневший дом» из, практически, подручных средств. Go (или вперёд)!
Зачем
Я видел множество хороших постов на тему интеграции Telegram Bot API с системами умного дома, в том числе и с созданием своего хаба. В том числе и на Хабре. С удовольствием ознакомился со многими, прочитал большую часть. Мне же захотелось сделать относительно простую систему, из того что было «под рукой». По этому критерию, протоколом взаимодействия был выбран TCP/IP. И для старта докупать пришлось только реле — умную розетку.
Функционал
Для себя я определил, что большинство сценариев умного дома, интересующих меня в текущий момент — это включение/выключение реле. Поэтому, функционал я определил следующим образом:
Управление устройством: включение / выключение, запрос статуса;
Админка: CRUD для пользователей, CRUD для устройств.
Схема взаимодействия
Этот материал может быть полезен:
тому кто хочет попробовать управлять устройствами в доме удаленно, с минимальными вложениями;
тому кто ищет устройства умного дома с открытым API;
тому кто задумывался сделать сервер из no-root Android на ARM.
Формат рассказа и план
Я постараюсь рассказывать в формате легкой прозы, с минимумом технических подробностей. В то же время, добавлю подробные технические вставки для заинтересованных и гайд по сборке своей системы.
План — оглавление
Выбор устройства реле
У меня уже давно появлялись мысли что-то автоматизировать дома. По сценариям я представлял какие-то основные: управление светом, теплом. Меня останавливало, что я часто переезжаю: путешествую, живу в разных городах, странах. Зачем в таком случае устанавливать (часто)дорогостоящие системы, если я не буду их использовать? Умные устройства, в основном, работают на специализированных стандартах и протоколах. Чтобы управлять такими устройствами нужны специальные хабы или адаптеры-трансмиттеры. Казалось, на этом можно было бы завершить размышления и поиски. Но, в какой-то момент, я случайно сформулировал запрос в виде «умная розетка с открытым HTTP API». И, по первой ссылке на Хабр Q&A, я нашел ответ на свой вопрос. Устройство найдено, можно исследовать тему дальше.
Выбор устройства сервера
После того как я сформулировал запрос на тему розетки с открытым HTTP API, я задался вопросом, на основе чего лучше будет собрать хаб.
Идея использовать собственный ноут отлетела сразу — я почти всегда с ним, сервер нужен локальный. Стационарного ПК нет.
Популярную малинку я решил не брать, так как затраты на новую 4-ку больше 16к₽, в среднем. С подержанной сталкиваться не захотелось.
Собирать сервер из старых запчастей тем более выглядело избыточным по трудозатратам и занимаемому пространству.
Перешить роутер под Linux и запустить на нём сервер, как выяснилось, возможно. Но я выбрал другой путь.
Да, залежавшийся планшет на Android 11 — показался мне идеальным вариантом для запуска на нем серверного приложения. Android, ведь, почти Linux?)
Путём недлительного рисерча я понял что на Android можно поставить Termux (эмулятор *nix CLI), на Termux можно поставить разные дистрибутивы и туда уже можно будет поставить серверное приложение.
Та самая разумная розетка с HTTP API заказана, буду делать умный дом.
Серверное приложение
В качестве языка программирования сервера я выбрал Golang. Почему? Для меня сейчас Go является основным профессиональным языком программирования, он легко компилируется почти в любую среду, да и нравится мне писать на нем всякие штуки.
Технические подробности организации хранения
Итоговое приложение использует хранение конфигурации в файловой системе. То есть, не требует никаких дополнительных баз данных и/или облачных систем.
Конечно, в таком случае, необходимо было снизить количество циклов чтения/записи в память устройства, рассчитывая на лимиты чтения/записи носителей. Поэтому в приложении используется кеширование, конфигурация подгружается в RAM после запуска приложения и дальше подлежит дополнительному чтению с твердой памяти только при добавлении новых пользователей/устройств.
В качестве интерфейса для пользователя я выбрал интеграцию с Telegram Bot API. Причин несколько:
мне интересно с этим разбираться;
это достаточно быстро (не нужно отрисовывать GUI);
авторизация уже есть — нужно только привязаться к определённому пользователю;
да и, вообще, я постоянно использую Telegram в организации своего информационного пространства.
Задуманная архитектура достаточно быстро воплотилась в коде, MVP был создан менее чем за день с перерывами. MVP включал в себя:
доступ только для определенных пользователей Telegram;
включение/выключение/получение инфо по одному устройству.
Что ж, с ноутбуком в качестве сервера протестировал. Пришло время разбираться с Android«ом.
Про адресацию устройств IoT
Ах, да, примерно на этом этапе я понял что придется вручную закреплять IP за устройством умного дома в интерфейсе роутера. Были мысли сканировать с помощью ARP сеть, но от этой идеи я пока отказался.
Так что, для стабильного управления устройством, пришлось выдавать ему статический IP на роутере. Что, в прочем, не сильно усложняет схему. Интерфейсы у роутеров разные, инструкций много, так что красочное описание набрасывания статики на устройство пропускаем.
Настройка сервера
Я заранее сохранил несколько статеек о том, как можно на Android поставить практически полноценный дистрибутив *nix системы. Схема была следующей:
сделать root доступ к ОС планшета;
установить Termux;
под Termux поставить proot;
под proot установить дистрибутив по типу серверной Ubuntu;
под Ubuntu запускать необходимые сервисы.
Но вся моя схема сломалась в тот момент, когда мне не удалось рутануть китайский планшет без подключения к ПК на Windows, по причине отсутствия последнего. Тогда я подумал: почему бы мне не обойтись без root прав?
Ок, пробую запустить свое приложение прямо из Termux, получаю ошибку резолва DNS. Чуть поискав, ответ был найден — проблема в окружении. Сразу я видел несколько вариантов:
билдить проект прямо из под Android;
установить на Termux proot, под него Alpine и запускать приложение из под Alpine.
Я выбрал второй вариант. Проверил, написал под него скрипт, установил Termux Boot для автозагрузки и — voila — сервер готов.
Про превращение планшета в сервер
Честно говоря, это был практически самый долгий и муторный этап, перемежающийся молитвами и восклицаниями про то, что я готов купить малинку или, на крайний случай, апельсинку. Лишь бы только не лепить больше эти костыли.
Самым долгим процессом были тщетные попытки заставить работать автозагрузку в Android, хотя оказалось что ларчик просто открывался, и нужно было просто подождать. Подробнее расскажу, чего именно пришлось ждать, в гайде по установке.
Все закончилось успехом, после того как я пошел на перерыв после одной из попыток. И я решил оставить систему как есть :)
Кстати, «voila» — решил оставить это слово почти в оригинале. Мало ли, кому-то будет интересно что это за «войла» такая.
Итоговый функционал, поддерживаемые устройства и скриншоты
Что умеет текущая версия приложения
включить/выключить устройство;
запросить статус устройства;
добавить/редактировать/удалить устройство;
добавить/редактировать/удалить пользователя;
показать метрики приложения.
Поддерживаемые устройства:
! Справедливо отметить здесь, что устройства Magic Home не имеют поддержки открытого API. Запись настроек происходит побайтово, с помощью определенной библиотеки на Go.
Скриншоты интерфейса приложения в Telegram
В основном меню можно выбрать устройство для настройки. Также на кнопке сразу отображается статус устройства.
Меню управления устройствомВ меню устройства всего четыре кнопки. «Инфо» дает сервисную информацию, доступную по устройству. Просто и лаконично.
Админ менюАдмин меню дает возможность управления пользователями и устройствами. Также доступен вывод основных технических метрик приложения.
Админ меню — управление устройствамиУправление устройствами позволяет добавлять/редактировать/удалять устройства. С пользователями меню выглядит примерно так же.
Плюсы и минусы решения
Начну с плюсов:
оно работает;
привычный интерфейс Telegram;
все устройства работают по TCP/IP;
не нужен оверпрайснутый хаб для управления;
нет голосового управления;
Минусы:
нет голосового управления;
стабильность, отказоустойчивость (планшет на Android);
мало устройств;
мало сценариев;
Про стабильность можно говорить отдельно, для проекта «на коленке», получилась достаточно стабильная штука. Но управление водоснабжением и/или чем-то более серьезным чем лампочки и безопасные электроприборы, я бы точно не стал вешать на эту систему.
Последние пару минусов, вероятно, уйдут. Если мне, конечно, не надоест делать свои велосипеды.
Инструкция по установке
Всю инструкцию убираю под спойлер, для технически готовых читателей.
Установка сервера умного дома на Android с ARM архитектурой
! Все операции с устройствами вы делаете на свой страх и риск. И, хотя в инструкции не описано никаких пунктов, которые могут повредить вашему имуществу, выполнение инструкции рекомендуется только для продвинутых пользователей. Также здесь встречаются инструкции на английском языке, начальные знания английского настоятельно рекомендуются.
Для начала, определимся с системными требованиями.
Нам понадобятся
Устройство Shelly или MagicHome в вашей сети;
Telegram Bot;
Настроенный дистрибутив
Планшет на Android с ARM в вашей сети;
Устройство Shelly или MagicHome
Инструкция по настройке Shelly Plug S тут.
Инструкция по добавлению MagicHome LED Controller тут.
После настройки, в интерфейсе роутера нужно присвоить статический IP для устройства и планшета. На примере Zyxel Keenetic описано тут.
Telegram Bot
Инструкций на эту тему великое множество, рекомендую посмотреть в сети. Дополню только тем, что нам нужен только бот созданный в официальном BotFather от Telegram.
После создания бота запоминаем API-Key (Token).
Настройка приложения
Подготовка:
Скачать на компьютер и распаковать архив*;
Открыть в текстовом редакторе файл smarthouse.sh
Изменить строчку SMARTHOUSE_TELEGRAM_BOT_API_KEY — после знака = необходимо поставить сохраненный API-Key Telegram бота, должно получиться примерно так:
export SMARTHOUSE_TELEGRAM_BOT_API_KEY=5942551826391:SHBDYSmALqU0we2rbG9pwX2-01X99HBndsjQg
Сохранить файл;
Открыть файл config/users/admin.json
Заменить значение поля «tg_nick» на ваш username в Telegram (без @)
{
"tg_nick": "aleksei_pershinov",
"grant": "master"
}
Сохранить файл;
Рекомендую также сразу изменить стартовое устройство config/devices/device.json
{
"name": "device",
"vendor": "magic",
"description": "умная розетка",
"host": "192.168.1.55"
}
название устройства может быть только a-z, A-Z, 0–9, _ и -
Поддерживается всего два типа vendor: shelly, magic
После того как мы изменили конфигурацию, запаковываем измененные файлы в архив smarthouse-edited.tar.bz2, запоминаем где он лежит.
* Для того, чтобы работать с архивом в формате tar под Windows, вам может понадобиться архиватор 7z.
Подготовка планшета
Планшет на Android с процессором ARM, около 512 МБ свободного места на планшете и 512 оперативной памяти.
Установить Termux*;
Установить Termux: Boot**;
Для продвинутых пользователей, можно сразу настроить SSH;
Запускаем Termux и выполняем настройку:
termux-setup-storage
# proot / alpine install
pkg update
pkg install proot-distro
proot-distro install alpine
# autorun settings
pkg install nano # можно также установить vim, если умеете
mkdir -p ~/.termux/boot/
nano ~/.termux/boot/smarthouse
# добавляем в файл следующие строки
#!/data/data/com.termux/files/usr/bin/sh
termux-wake-lock
proot-distro login alpine --termux-home -- /bin/sh /root/services/smarthouse/smarthouse.sh
# сохраняем файл
mkdir -p ~/services/smarthouse
После этого нам нужно передать сохраненный ранее архив smarthouse-edited.tar.bz2 в директорию стартовую директорию. Это можно сделать с помощью Telegram — открыть архив на планшете с помощью Termux. Или, как вариант, перекинуть с помощью SSH/SCP;
После того как мы передали архив, распаковываем
tar xvf ~/tmp/smarthouse-edited.tar.bz2 -C ~/services/smarthouse
* оба приложения должны быть установлены из одного источника, например F-Droid.
** автозагрузка Termux может срабатывать через несколько минут после запуска планшета. Рекомендую набраться терпением при тестировании.
Результат
После перезагрузки планшета, через некоторое время (у меня занимает до 15 минут) должен автоматически стартануть Telegram Bot, и мы можем продолжить с ним работать уже в Telegram.
После первого открытия бота и команды /start, должна сработать капча. Капча сделана для того, чтобы память приложения не хранила информацию о ненужных нам пользователях, и хранила только авторизованных.
КапчаПосле правильного ответа на вопрос, появится доступ к функционалу бота по команде /start
Для доступа в Админ меню, есть команда /admin
Админ меню доступно только пользователям с правами admin или master.
Пользователи с правами user имеют доступ только к управлению устройствами.
Через Админ меню можно добавить/редактировать пользователей только с правами admin и user. Учетную запись с правом master можно редактировать только из файловой системы.
Если что-то пошло не так
После всех инструкций по установке, если приложение не запускается, можно попробовать запустить его вручную в Termux командой
proot-distro login alpine --termux-home -- /bin/sh /root/services/smarthouse/smarthouse.sh
И посмотреть результат вывода в консоль. Большинство ошибок должны быть интуитивно понятны. Если же и это не поможет понять, можно попробовать связаться со мной.
Если будет спрос, со временем, сделаю сборки под другие архитектуры и ОС. А также раскрою исходники.
Планируемый функционал
Из того, что мне бы хотелось добавить в приложение в ближайшее время:
Настройка диммируемых устройств;
Настройка расписания включения/выключения устройств;
Автоматический сбор и отправка статусов устройств;
И еще что-то, на что найдутся силы.
Выводы
Я доволен полученным результатом разработки: устройства работают, шлюз отвечает удалённо, появляются новые идеи автоматизации. Все это без дополнительных приложений, в интерфейсе уже хорошо знакомого Telegram.
Получилось, конечно, не самым простым путем. И, в следующий раз, вероятно, я уже обзаведусь каким-то микрокомпьютером для более продуктивных и быстрых экспериментов.
Писать пост на Хабр — было и есть незабываемое удовольствие. С удовольствием продолжу рассказывать вам о новых и старых идеях и разработках.
Я благодарен всем, кто обратил внимание на этот пост и буду рад обратной связи.
До новых экспериментов, au revoir!