Или история о том, как из планшета на 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!

Комментарии (18)


  1. Lev3250
    23.01.2023 13:29
    +4

    Azis, отвечающий за свет... Идеальная пасхалочка!


    1. gopersh Автор
      23.01.2023 15:05
      +2

      Спасибо, что заметили. :)


  1. boojum
    23.01.2023 14:18

    установить на Termux proot, под него Alpine и запускать приложение из под Alpine.

    Зачем это всё? Почему не запускать приложения просто в термуксе?


    1. gopersh Автор
      23.01.2023 15:22

      Мне близок ход ваших мыслей, но при попытке запуска напрямую я столкнулся с проблемой.
      Post "https://api.telegram.org/bot.../getMe": dial tcp: lookup api.telegram.org on [::1]:53: read udp [::1]:53977->[::1]:53: read: connection refused.
      Путем поиска, я обнаружил что есть проблема резолва DNS при запуске приложений Go, которые собраны в отличной от Termux среде.
      Собирать приложение в Termux среде для меня показалось избыточным, так что я выбрал второй, более простой для меня вариант. Также кратко описывал это в блоке "Настройка сервера".
      Благодарю!


  1. vconst
    23.01.2023 16:03
    +3

    Таки очень рекомендую посмотреть в сторону Tasmota

    С одной стороны — все уже придумано, настроено и работает, esp32 прошивается прямо из браузера. Уже из коробки поддерживается куча периферии. С другой, если хочется странного — то можно даже свою прошивку скомпилировать из готовых частей.

    Никакой возни с поиском библиотек поддержки датчиков и тп для esp — просто воткнуть в плату, указать в интерфейсе номера пинов — и все само подтянется

    А для умного дома не нужна последняя Малинка с 4 гигами и двадцатью портами, хватит маленькой Зеро первого поколения, они новые выпускаются до сих пор, никакого авито не надо.

    Я попробовал несколько подобных решений для esp32 — Tasmota наиболее продуманная и развитая, документации — зачитаться можно.


    1. gopersh Автор
      23.01.2023 17:09

      По поводу Tasmota - добавил себе в закладки. Конечно, получится более объемная система, с поддержкой большего количества устройств. Но и сложность возрастет. В любом случае, интересно. :)

      По поводу Малинки - Zero, да, была на рынке. Но даже так, цена больше чем у завалявшегося дома планшета. Одной из основных целей было: минимальными вложениями запустить тестовый стенд. Как и получилось, докупил только розетку.

      Спасибо!


      1. vconst
        23.01.2023 17:34

        Тасмота тем и хороша — что ничего «более обьемного» там не будет. Все предельно упрощено и уже готово. Надо только подсоединить периферию, дальше она сама


        1. gopersh Автор
          25.01.2023 12:48

          Я, конечно, не спорю. Но, если я правильно понял, в таком случае все же придется что-то докупать в мой первичный набор. Контроллер ESP8266, корпус, какой-то набор для прошивки, бп, и пр. Или просто готовый блок с ESP8266, на который можно будет поставить Tasmota.

          Все зависит от задач и целей, ваша идея наверняка является для кого-то лучшей. Возможно и мне доведется с до этого решения когда-то дойти. :)


          1. vconst
            25.01.2023 13:21

            Да что там покупать то?
            В качестве корпуса любая условная мыльница сойдет, Esp32 wroom 32 на али стоит меньше 300 рублей, если хочется прям завтра — то условном на озоне или авито — рублей 500

            Готовые блоки делает Сонофф, чутка дороже, но уже в корпусе, с удобными выводами и тд тп, ну тысяча где-то, максимум.


          1. Iv38
            25.01.2023 14:35

            Tasmota и ESPHome можно прошивать и всякие готовые устройства. Лишь бы чип внутри был подходящим. Я недавно нашёл дома розетку Viper и перешил. А то чё она работает в какой-то своей экосистеме.


      1. sirota
        26.01.2023 07:17

        Откройте для себя mqtt. Ну и по поводу малинки... Есть апельсина, банана. И прочее. Функционально плюс минус тоже, но раза в 2 дешевле малины. Накатывает армбиан, мкутт сервер туда и погнали через него управлять устройствами. Не надо мучаться с апи и прочим, достаточно знать имя устройства и его конечные точки, которые для каждого типа индивидуальны.


  1. Iv38
    23.01.2023 16:35

    Ну если хотелось просто и без специальных хабов, то можно было просто купить любые WiFi-розетки той или иной экосистемы. MiHome, Tuya, что угодно ещё. Они бы просто подключались через роутер к своему облаку. Да, не работает без интернета. Но и ваш бот тоже. Есть зависимость от чужого облака — это да. Но не факт, что это хуже, чем сервер на планшете дома — зависит от условий.


    1. gopersh Автор
      23.01.2023 17:30
      +1

      Согласен, вы описываете хорошее и простое решение "из коробки".
      Когда я задумывался над управлением, мне, все же, нравилась возможность интеграции устройств разного типа, без жесткой привязки к бренду.
      Как и получилось: при желании, я могу развивать систему и делать интеграции с разными вендорами устройств.
      На текущий момент, кроме Shelly, добавлена поддержка Magic Home LED Controllers.
      К слову, я проверил недавно, пока модерировался пост, реле Shelly 1 - работает с моей системой "из коробки".

      По поводу отвязки от облаков и интернета - такой цели не было. Но, если возникнет, можно достаточно бытро написать REST API, простой фронт (который может крутиться на том же планшете или микропк) - все возможно, при желании.

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

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

      Спасибо!


      1. Iv38
        23.01.2023 21:08
        +2

        Не, я всё понимаю, как хобби-то это всегда пожалуйста. Весело и полезно. Но вообще, если хочется отвязки от облаков, объединения устройств разных экосистем, и при этом есть сервер дома, то на него можно поставить Home Assistant. К нему даже несложно приделать управление через телеграм, если очень хочется.


        1. gopersh Автор
          25.01.2023 12:22

          Здорово, HA в сети находил. И, согласен, для кого-то больше подойдет такой вариант. Возможно, и до него у меня руки дойдут.
          Кстати, нашел очень годный пост по настройке HA в очень схожих условиях. :)

          С другой стороны, свой "самодельный самокат" у меня уже есть. И я на нем даже катаюсь. Так что, погляжу, что будет дальше по интересу и потребностям.


  1. Ut1900
    25.01.2023 12:25
    +1

    Автору респект! Очень грамотно все сделано, еще и работает))
    Homeassistant тоже однозначно +. Особенно для среднестатистических юзеров, у которых фраза "установить на Termux proot, под него Alpine и запускать приложение из под Alpine" вызывает непреодолимое желание пойти покурить (вроде меня).
    Могу порекомендовать связку homeassistant + esphome. Из затрат 2тыр на минипк с авито, 200 р на esp-реле оттуда же. Можно обойтись и без 2 тыр, ha ставится на то что есть под рукой не старше 15 лет, есть кто ставит и на китайские планшеты, роутеры и прочее.
    По времени - вечер ставим ha и разбираемя что к чему, вечер на прикручивание esphome в 2 клика и на пощелкать реле.
    Как итог получаем полноценный сервак умного дома, совместный удаленный доступ, telegram бот, мобильное приложение, gui, управление реле по погоде на марсе, прошивку по воздуху, дальше можно долго продолжать)
    Кстати упомянутая возможность интеграции устройств разного типа, без жесткой привязки к бренду это вот прям можно.


    1. gopersh Автор
      25.01.2023 12:36

      Да, вариантов решений масса. Можно выбирать тот, который больше подходит вам.
      Мой вариант, особенно сейчас, мне напоминает попытки собрать из нескольких разных наборов Lego что-то свое. Может быть даже похожее на новую модель из того же Lego, но не докупая новых деталей. В детстве я так часто делал, получалось.

      Благодарю за позитивный фидбек и развернутый комментарий! :)


      1. Ut1900
        25.01.2023 19:12

        Понимаю, когда заимствуешь готовое решение всегда приходится заимствовать привычки автора, а сам делаешь проект заточенный именно под твои задачи.
        Интересно насколько в предложенной Вами связке важен промежуточный сервер на планшете. Я имею в виду нельзя обойтись без него возложив функции взаимодействия с telegram api на сами исполнительные устройства?
        Конечно придется писать прошивку для той же умной розетки, но взамен получаем очень интересное устройство для несложной автоматизации - избавляемся от ненадежного звена в цепи и получаем что кроме самого устройства нужен будет только роутер и телеграм, а это есть у каждого.
        Интересно будет узнать Ваше мнение.