Одним из самых вдохновляющих моментов в разработке микроконтроллерных устройств является их первая установка и запуск в локальной сети. И этот же момент может превратиться в настоящий ад, когда процедуру приходится повторять десятки или сотни раз. Множество однотипных контроллеров, развертываемых одновременно, требуют часов монотонного конфигурирования — времени, которое любому инженеру хотелось бы провести с большей творческой пользой.

Для решения этой проблемы был разработан легкий open-source сервис с открытым исходным кодом и условным названием «esp-monitor».

Проблема конфигурации и выбор протокола

Одним из самых популярных (и что немаловажно, дешевых — стоимостью около $2) микроконтроллеров является Wemos D1 Mini на базе чипа ESP8266. Он быстрый, в меру надежный и обладает широчайшей экосистемой дополнительных модулей. Именно такие контроллеры массово используются в бытовой технике и DIY-проектах благодаря колоссальным возможностям внедрения в датчики и системы домашней автоматизации.

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

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

  • требуется административный доступ к Wi-Fi роутеру;

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

  • отсутствует единый центр управления семейством устройств — к каждому девайсу придется обращаться индивидуально по его собственному адресу;

  • возникают постоянные вопросы к безопасности системы.

Гораздо более изящное и практичное решение — использование внешнего MQTT-брокера за пределами локальной сети. Устройство само подключается к брокеру, передает ему текущее состояние и ожидает от него исполняемые команды.

MQTT (Message Queuing Telemetry Transport) — это очень легкий двунаправленный протокол для передачи телеметрии. В отличие от WebSockets, он не требует удержания постоянного тяжелого соединения, что делает его идеальным стандартом для IoT. Запустить MQTT-брокер можно на любом микрокомпьютере (включая Raspberry Pi 3), арендовать в облаке или развернуть на базе публичных бесплатных сервисов.

Архитектура Esp-Server

Инструмент управления esp-server — это легковесный сервис, написанный на Go со встроенной базой данных SQLite. Его можно развернуть в облаке на любой системе с поддержкой Docker либо собрать из исходного кода везде, где есть среда выполнения Go (Windows, Linux, macOS).

Сервер централизованно управляет устройствами, автоматизируя сложные конфигурации, которые включают в себя настройки Wi-Fi, MDNS, стандартный стек SSDP (с HTTP-портом для чтения данных), а также параметры подключения к MQTT-брокеру. Всю остальную логику инженер может легко реализовать стандартными средствами MQTT.

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

Общая схема взаимодействия компонентов через облачный сервис  MQTT.
Общая схема взаимодействия компонентов через облачный сервис MQTT.

Первичная посадка в сеть и API

Пользователь взаимодействует с esp-server либо через публичное REST API, либо через веб-интерфейс в браузере. Мобильные приложения удобнее, но веб-интерфейс выигрывает в универсальности.

Для сопряжения микроконтроллеров с локальной сетью можно использовать нативное iOS-приложение(исходный код которого также есть в репозитории). В нем достаточно один раз прописать конфигурационные параметры, а затем отправлять их на устройство, находящееся в режиме точки доступа (AP), по нажатию одной кнопки. Однако политика Apple усложняет жизнь инженерам: для сборки приложения потребуется среда разработки Xcode и аккаунт разработчика.

Для тех, кто использует Android или предпочитает универсальные методы, предложен альтернативный и максимально простой способ — отправка параметров через обычный cURL-запрос (POST REST):

Bash

curl -X POST 192.168.4.1:80/config \
  -H "Content-Type: application/json" \
  -d '{
  "WIFI_SSID": "<wi-fi SSID>",
  "WIFI_PASS": "wi-fi pass",
  "MDNS": "<mdns identifier, e.g. local.esp>",
  "SSDP": "SSDP name",
  "HTTP_PORT": "80",
  "MQTT_HOST": "<HOST>",
  "MQTT_PORT": "1883",
  "MQTT_USER": "",
  "MQTT_PASS": "",
  "MQTT_ROOT": "<root topic>"
  }'

Пример этого запроса находится в каталоге ./clients/curl проекта.

Важные нюансы работы с устройствами:

  1. Первый запуск: При первом включении ESP-устройство поднимает собственную точку доступа (Access Point) по стандартному адресу 192.168.4.1 (в сетях esp8266-setup или esp32-setup в зависимости от чипа). Задача инженера — отправить REST-запрос на этот адрес. После успешного получения параметров устройство перезагружается, подключается к домашней Wi-Fi сети и связывается с MQTT-брокером.

  2. Аварийный сброс: Если что-то пошло не так, сбросить некорректную конфигурацию можно физически — удерживая кнопку на пине D4 более 3 секунд.

  3. Идентификация (SSDP name): Это ключевое поле, по которому устройство идентифицируется на стороне esp-server. Если его оставить пустым, имя сгенерируется автоматически на основе типа чипа и его MAC-адреса. При необходимости использовать Unix-время вместо MAC-адреса можно переопределить метод createMacAddress() прямо в прошивке.

  4. MQTT_ROOT: Если вы контролируете собственный MQTT-брокер, здесь достаточно указать короткое имя (например, root). Если же используется публичный брокер вроде test.mosquitto.org, в качестве корня лучше прописать уникальный идентификатор (например, UUID, сгенерированный на специальном сайте), чтобы ваши топики не пересекались с чужими.

Эволюция проекта: от статического импорта к интерактивности

Изначально предполагалось, что базовый сценарий будет выглядеть так: инженер заносит конфигурации контроллеров в таблицу Excel, экспортирует её в .csv, загружает на сервер, а при подключении устройства видит статус успешного сетапа.

Однако практика показала, что простого мониторинга списка недостаточно — конфигурацию устройств хочется менять оперативно и «на лету».

Важно понимать: сами ESP-устройства ничего не знают про существование esp-server — они работают только с MQTT-брокером. В свою очередь, esp-server тоже не знает внутренней схемотехники ESP — он лишь читает и пишет в топики, определенные в конфигурационном файле сервера .env.

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

  • <root>/<ssdp_name>/state — отправка текущего состояния пинов от ESP к серверу.

  • <root>/<ssdp_name>/action — передача управляющих команд от сервера к ESP.

В прошивке установлено ограничение на отправку данных в топик state — не чаще одного раза в секунду, чтобы не перегружать сеть (при необходимости лимит можно снять). Сервер считает устройство активным (online), если от него поступали сообщения в течение последней минуты. Поскольку ESP32 аппаратно стабильнее и реже страдает от «дребезга контактов» без нагрузки, важно предусмотреть, чтобы прошивка ESP32 отправляла хотя бы минимальный пинг-пакет раз в минуту для поддержания статуса сети.

Интерфейс и безопасность

Добавление новых устройств происходит автоматически: как только сервер видит новое сообщение в топике <root>, он извлекает имя <ssdp_name> и регистрирует новое устройство в базе данных SQLite.

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

Web интерфейс неавторизированного пользователя.
Web интерфейс неавторизированного пользователя.

Поскольку сервер должен смотреть в интернет, но права на управление им должны быть монопольными, была реализована простая и надежная авторизация в стиле Linux:

  • В конфигурационном файле сервера задается секретный параметр xtoken.

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

Возможности авторизованного пользователя:

  • Просмотр расширенного реестра (дата активации, время старта, дата последнего обновления).

  • Фильтрация устройств по имени SSDP или MDNS (удобно для администрирования разных семейств устройств на одном сервере).

  • Импорт устройств через .csv на стартовой странице.

  • Переход в детальную карту устройства: просмотр состояния пинов, истории последних событий (action), удаление неактивных девайсов (находящихся в таймауте).

  • Конфигурирование («Configure device»): Возможность переопределить любые параметры устройства прямо с экрана мобильного телефона.

Web интерфейс авторизированного пользователя.
Web интерфейс авторизированного пользователя.
Страница расширенной информации об устройстве
Страница расширенной информации об устройстве
Конфигурирование устройства
Конфигурирование устройства

Конфигурации развертывания (Deploy Tiers)

И на этом мы только подходим к «кроличьей норе» архитектуры проекта. Esp-Monitor поддерживает 5 основных конфигураций развертывания в зависимости от масштаба и задач вашей сети:

Ярус (Tier)

Описание и состав инфраструктуры

Tiny

Минимальный уровень. Устанавливается только esp-server. MQTT-брокер используется внешний/облачный (по умолчанию публичный test.mosquitto.org).

Small

К серверу добавляется собственный локальный приватный MQTT-брокер. Данные передаются внутри вашего контура безопасности.

Medium

Появляется распределенная шина событий Apache Kafka, веб-интерфейс для работы с ней Kafdrop, а также специализированные обработчики: kworkerai-worker и hworker.

Large

Комплексный мониторинг. Добавляются сборщик метрик Vector, база данных временных рядов VictoriaMetrics (совместимая с Prometheus) и дашборды Grafana.

Huge

То же, что и Large, но вся инфраструктура разворачивается в оркестраторе Kubernetes (k8s).

Что выбрать: Docker или Kubernetes?

В репозитории папка deploy разделена на два направления:

  1. docker — содержит конфигурационные файлы для развертывания ярусов от Tiny до Large.

  2. k8s — содержит скрипты для настройки локального окружения Minikube и манифесты запуска кластера Kubernetes.

Плюсы и минусы Kubernetes:

  • Достоинства: Самовосстанавливающаяся и легко масштабируемая платформа. Если один из сервисов падает — K8s перезапускает его автоматически. Компоненты можно разносить на разные физические серверы или запускать десятки реплик воркеров под разные сегменты данных. При этом все упаковано в единые манифесты.

  • Недостатки: Высокий порог входа. Потребуется потратить «пару килограмм нервных клеток» на базовую настройку.

Примечание: Для упрощения в проект включены готовые автоматизированные скрипты установки. Вам не придется глубоко погружаться в дебри Docker CLI или Kubernetes API — развертывание и перезапуск происходят буквально парой команд. Кроме того, Minikube из коробки предоставляет удобный веб-дашборд.

Если вы выберете классический Docker, вы получите другие преимущества: готовые легковесные образы на Docker Hub собраны сразу под три архитектуры (amd64arm64 и arm). Это позволяет запускать систему на ПК, Mac с чипами Apple Silicon и энергоэффективных платах уровня Raspberry Pi.

Minikube dashboard
Minikube dashboard

Как это устроено внутри: Kafka и воркеры (Medium+)

Вы могли заметить, что сам по себе esp-server хранит лишь последнее состояние пинов и последнюю команду. Но если вы выбираете ярус Medium и выше, раскрывается вся мощь архитектуры: esp-server транслирует абсолютно все события в Kafka. Там они могут храниться и накапливаться неделями.

На данный момент в Kafka предопределены 5 топиков:

  1. root — системные события (например, запуск самого esp-server).

  2. logs — диагностические сообщения, ошибки, логи подключений к брокеру и шине.

  3. pins — детальная хронология изменения состояний пинов микроконтроллеров.

  4. actions — отправленные команды и обновления конфигураций.

  5. anomalies — аномалии в работе устройств, выявляемые внешними обработчиками.

В топик anomalies пишет специализированный сервис — ai-worker.

Хронология состояний пинов в Kafdrop
Хронология состояний пинов в Kafdrop
Хронология изменения конфигурации в Kafdrop (esp32-001   меняет ssdp.name на esp32-002).
Хронология изменения конфигурации в Kafdrop (esp32-001 меняет ssdp.name на esp32-002).

Всего в проекте из коробки поставляется три типа воркеров:

  • kworker — строит агрегированные таблицы, отображая изменения состояний пинов ESP в реальном времени.

  • ai-worker — отправляет потоковые агрегированные данные на анализ искусственному интеллекту для поиска аномалий и пишет результаты обратно в Kafka.

  • hworker — забирает зафиксированные аномалии из Kafka и передает их на следующий уровень бизнес-логики (например, в сценарии автоматизации платформы n8n).

Благодаря такой распределенной схеме воркеры можно масштабировать горизонтально: запустить ровно столько экземпляров, сколько партиций создано в топиках Kafka, распределив нагрузку. Исходный код всех воркеров находится в каталоге services и полностью открыт для кастомизации.

Таблицы kworker доступные в терминале.
Таблицы kworker доступные в терминале.
Работа ai-worker. Информация доступная в терминале.
Работа ai-worker. Информация доступная в терминале.
Чтение аномальной активности при помощи Kafdrop
Чтение аномальной активности при помощи Kafdrop

Осциллограмма пинов в реальном времени (Large+)

Для детального анализа физических показателей датчиков используется связка Vector + VictoriaMetrics + Grafana.

Агент Vector читает «сырые» данные об изменении пинов из Kafka, преобразует их во временные ряды (Time Series) и пишет в высокопроизводительную СУБД VictoriaMetrics. Подключив к ней Grafana, вы можете строить красивые графики, отслеживать дребезг контактов и создавать полноценные инженерные дашборды мониторинга вашей квартиры или производства.

Пример дашборда, построенного в Garafana  для осцилляций аналогового пина устройств esp8266.
Пример дашборда, построенного в Garafana для осцилляций аналогового пина устройств esp8266.

Быстрый запуск

Требования:

  1. Установленный Docker (актуально и для запуска Kubernetes через Minikube).

  2. Настройка окружения: В каталогах deploy/docker и deploy/k8s находится файл my.env.example. Скопируйте его с именем .env и заполните параметры (токены, адреса брокеров) по аналогии с примерами внутри файла.

Команды запуска:

  • Tiny: docker compose -f deploy/docker/tiny.yaml up -d

  • Small: docker compose -f deploy/docker/small.yaml up -d

  • Medium: docker compose -f deploy/docker/medium.yaml up -d

  • Large: docker compose -f deploy/docker/large.yaml up -d

  • Huge (Kubernetes):

    1. Выполните скрипт инициализации: sh ./setup-k8s-cluster.sh

    2. Запустите кластер скриптом en-start-cluster или ru-start-cluster (это простые bash-скрипты, структуру которых вы можете изучить в текстовом редакторе).

    3. Обратите внимание: При запуске Minikube-туннеля система попросит ввести пароль sudo. Это необходимо для проброса (маппинга) внутренних портов кластера на ваш хост-компьютер, чтобы вы могли открыть веб-интерфейсы esp-server, Grafana, Kafdrop и Minikube Dashboard в обычном браузере.

Процесс установки кластера k8s.
Процесс установки кластера k8s.
Рабочий режим полёта сервисов кластера k8s.
Рабочий режим полёта сервисов кластера k8s.

Документация и исходный код

Проект детально документирован: практически в каждой папке находится свой файл README.md. В каталоге docs/arch представлена подробнейшая архитектурная документация, состоящая из 11 глав на русском и английском языках.

Проект активно развивается, и его исходный код полностью открыт.