Когда у меня появилась теплица, первым желанием было автоматизировать всё, что можно: контроль температуры, управление вентиляцией, полив, освещение. Готовые решения либо стоят дорого, либо замкнуты в экосистеме одного производителя, либо не дают нужной гибкости. Поэтому я решил создать собственную систему по автоматизации управления процессами в теплице. Также у меня было много бесхозных контроллеров ESP8266/ESP32, которые нужно было куда-то "пристроить".
В этой статье расскажу о концепции проекта, его архитектуре и обзорно покажу веб-интерфейс. В следующих частях разберу каждый компонент подробнее.
Концепция
Идея простая: Raspberry Pi — это центр управления. К нему подключается всё: датчики, реле, ESP8266/ESP32-устройства, разбросанные по теплице. Пользователь видит единый веб-интерфейс, где можно:
Видеть температуру с каждого датчика в реальном времени
Управлять реле и ШИМ прямо из браузера
Строить автоматизации по принципу «если температура > 29°C — выключить реле нагрева»
Получать алерты при потере связи с устройством
Мониторить историю показаний в виде графиков
Ничего не требует интернета. Всё работает в локальной сети. Плюсом такого подхода является модульность и легкость расширения функционала путем добавления разных по функционалу компонентов.
Архитектура системы
Система состоит из трёх уровней.
1. Raspberry Pi — центральный сервер
FastAPI-бэкенд (порт 8001) — REST API + WebSocket
React-фронтенд через Nginx (порт 8088)
PostgreSQL — история, конфигурация, автоматизации
Весь стек запускается одной командой через Docker Compose
2. ESP8266-устройства — периферия
Прошивка на ESP8266/ESP32 RTOS SDK (без Arduino)
Датчики DS18B20 (1-Wire, до 4 штук) и DHT22 (температура + влажность)
4-канальное реле + 4 PWM-канала
Встроенный HTTP REST API: /status, /control, /config
Raspberry Pi опрашивает каждое устройство по HTTP каждые N секунд
3. GPIO Raspberry Pi 4— прямое управление
Управление пинами через lgpio
Три режима: OUTPUT (цифровой выход), INPUT (цифровой вход), PWM (аппаратный ШИМ)
Аппаратный PWM доступен на GPIO 12, 13, 18, 19
Взаимодействие в реальном времени — через WebSocket. Все изменения состояния (GPIO, датчики) моментально появляются в браузере без перезагрузки страницы.
Технологии бэкенда
FastAPI — фреймворк для REST API. Выбран за нативный async/await, автогенерацию OpenAPI-документации и валидацию через Pydantic. Каждый раздел системы — отдельный роутер: gpio.py, devices.py, sensors.py, automations.py, alerts.py, auth.py.
PostgreSQL + SQLAlchemy + Alembic — реляционная БД, ORM и управление миграциями. Исторические данные с датчиков, конфигурации устройств и правила автоматизации хранятся в PostgreSQL.
WebSocket — FastAPI WebSocket + собственный WebSocket Manager. Клиент подписывается на топики (gpio, sensors, devices), и при любом изменении состояния сервер делает broadcast нужным подписчикам.
JWT-аутентификация — python-jose + passlib/bcrypt. Все защищённые эндпоинты проверяют Bearer-токен. Роли: admin может менять конфигурацию, обычный пользователь — только читать.
gpiozero + lgpio — библиотека для работы с GPIO. Используется lgpio как pin factory: не требует демона pigpiod, работает напрямую через /dev/gpiochip0, является дефолтным бэкендом на Pi OS Bookworm.
psutil — сбор системной информации: температура CPU, загрузка, RAM, диск, uptime.
Технологии фронтенда
React (Create React App) — компонентный SPA. Состояние передаётся через Context API (AuthContext для аутентификации).
i18next — интернационализация. Интерфейс полностью переведён на русский и английский. Переключатель RU / EN виден в правом верхнем углу навбара.
useWebSocket — кастомный хук, который подключается к бэкенду и раздаёт обновления нужным компонентам. Иконка «● Live» в навбаре показывает состояние соединения.
Nginx — раздаёт собранный React-бандл, проксирует /api/* и /ws/* на бэкенд (порт 8001).
Docker multi-stage build — сначала собирается React (node:18-alpine), затем статика копируется в nginx:alpine. Итоговый образ не содержит Node.js.
Прошивка ESP8266
Прошивка написана на C, без Arduino. Используется ESP8266 RTOS SDK v3.4 — IDF-стайл API, аналогичный ESP-IDF для ESP32, но с отличиями в сетевом стеке (tcpip_adapter вместо esp_netif) и PWM-драйвере (driver/pwm.h с общей несущей частотой FRC1 вместо LEDC).
Многозадачность — FreeRTOS
sensor_task опрашивает датчики каждые N мс, HTTP-сервер работает в задаче SDK. Общее состояние (показания датчиков, состояние реле) защищено мьютексом.
Датчики
DS18B20 (1-Wire, bit-bang) — до 4 датчиков на одной шине, каждый идентифицируется по уникальному 64-битному ROM-коду.
DHT22 (AM2302, bit-bang) — температура и влажность.
Управление
4-канальное реле — GPIO, настраиваемая полярность (active LOW / active HIGH).
4 PWM-канала — все каналы делят одну несущую частоту (FRC1). Диапазон 0–1000 (per mille). Режимы: Standard (LED-диммер, вентилятор) и Servo (1000–2000 мкс, управление угловым положением).
HTTP REST API
GET /status — показания датчиков + состояние реле и PWM. Используется поллером Raspberry Pi.
POST /control — управление реле и PWM: {"relay1": 1, "pwm1": 750}.
GET/POST /config — конфигурация устройства, хранится в NVS flash.
WiFi и NVS
При первом запуске поднимается точка доступа SG-Setup-XXXXXX (192.168.4.1). После ввода WiFi-credentials устройство подключается к роутеру в STA-режиме. Конфигурация (SSID, пароль, GPIO-пины, метки датчиков, API-ключ) хранится в NVS flash и переживает перезагрузку.
Сборка и прошивка
Собирается через idf.pybuild в Linux/WSL2, прошивается через esptool (Windows и Linux).
Обзор веб-интерфейса
Веб-интерфейс доступен по адресу RaspberryPi на порту 8088. Навигация — горизонтальный навбар с разделами: Панель, Устройства, Мониторинг, GPIO, GPIO настройки, Автоматизация, Алерты, RaspberryPi.

Панель (Dashboard)
Главный экран показывает сводку: сколько устройств онлайн/офлайн, количество непрочитанных алертов, карточки ESP-устройств с текущими показаниями всех датчиков.

ESP-устройства
Список всех зарегистрированных ESP8266-модулей. Каждое устройство имеет тип (Климат, Полив, Свет, CO₂, Питание, Камера), IP-адрес, интервал опроса и время последнего успешного опроса.


Страница устройства
Детальный вид: текущие показания каждого сенсора с мин/ср/макс, управление реле (кнопки ON/OFF) и PWM-слайдеры (0–1000). Видна мета-информация: MAC-адрес, версия прошивки, интервал опроса.

Мониторинг сенсоров
Исторические графики по любому сенсору за выбранный период (1 час, 24 часа, 3 дня, 7 дней). Отображаются мин/ср/макс и количество измерений за период. Ниже графика — live-таблица текущих показаний всех устройств через WebSocket.

GPIO — настройки и управление
Два раздела для работы с пинами Raspberry Pi. В настройках назначается функция:
· OUTPUT — управляется командами on/off через REST API
· INPUT — состояние отслеживается через WebSocket в реальном времени
· PWM — аппаратный ШИМ (доступен только на GPIO 12, 13, 18, 19 через lgpio)
В панели управления — слайдеры для PWM-пинов и кнопки для OUTPUT. Все изменения мгновенно отражаются у всех подключённых клиентов.



Система правил «ЕСЛИ → ТО». Условие: устройство + сенсор + оператор (>, <, =, ≠) + пороговое значение. Действие: управление ESP-устройством (реле или PWM) либо GPIO Raspberry Pi. Поддерживаются cooldown (минимальный интервал между срабатываниями) и включение/выключение правила без удаления.
Пример: правило «Прогрев ВКЛ» — если temperature_3 < 24 → включить relay1 на устройстве Relay Control 1.


Алерты
Журнал событий. Если ESP-устройство не отвечает на опрос — создаётся алерт с временной меткой и типом error. Можно фильтровать только непрочитанные и отмечать все прочитанными разом.

Информация о Raspberry Pi
Информационная страница платы: модель, процессор, ОЗУ, производитель (из /proc/cpuinfo), температура CPU, загрузка, использование диска и RAM, uptime, IP-адреса, версия ОС и ядра. Внизу перечислены аппаратные PWM-пины с физическими номерами разъёма.

Деплой через Docker Compose
Система запускается одной командой: docker compose up --build.
Три сервиса:
db: postgres:13-alpine — база данных с healthcheck
api: FastAPI + Alembic + Uvicorn — автоматически накатывает миграции при старте
client: React + Nginx — собирается в multi-stage Dockerfile
Для работы с GPIO пробрасываются устройства /dev/gpiomem и /dev/gpiochip0. Pin factory — lgpio (не требует демона pigpiod, дефолтный бэкенд на Pi OS Bookworm).
Что дальше
В следующих статьях планирую разобрать:
Обзор прошивки ESP8266 подробнее
Схему подключения железа к Raspberry Pi и ESP8266
Обзор реализации подключаемых устройств на базе ESP32
Заключение
Получилась полноценная IoT-платформа для теплицы — и не только. Никаких внешних облаков, никаких подписок, всё работает локально. Код переиспользуемый: добавить новый тип ESP-устройства или новый тип автоматизации можно за несколько десятков строк.
Если вам интересен проект или есть вопросы — пишите в комментариях.
Комментарии (10)

shadrap
09.03.2026 11:24да, соглашусь с вышенаписанным, высокая частота опроса никчему, к тому же ds18b20 если по 12 битному режиму , вообще раз в секунду способен что-то разумное вернуть, а днт22 реально раз в 2- 3 секунды опрашивать.
Не вижу влажности почвы , для полива это важно. Если уж учтено снабжение со2 , то уж влажность почвы нужно по крайней мере 1 датчик на 3м.
Критичные вещи лучше замыкать в одном устройстве, что бы продолжало работать даже при потере сети например управление обогревателем и датчик температуры.
я так понимаю это концепция, а не работающий прототип..

nikulin_krd
09.03.2026 11:24Т.е. я правильно понял, что на неоправданно мощное устройство для данной задачи(Raspberry Pi 4) поставили велосипед, который реализует функционал HomeAssistant?

maiorovx
09.03.2026 11:24Тоже хотели теплицы автоматизировать и собирали требования по функционалу от потенциальных заказчиков.
Наши заказчики хотели так управлять заданиями:
Активация задания - по расписанию (день недели, время) или по какому-то условию (температура выше значения и т.д.).
Прекращение выполнения задания - по продолжительности или по какому-то условию (кол-во вылитых литров, температура и т.д.).
В итоге не стали разрабатывать своё решение из-за совсем скромных бюджетов у заказчиков)))

Dr_Faksov
09.03.2026 11:24А что будет, когда в мороз сервер помрёт? Да, да, тут не "если", а "когда". А в отопителе блок автономного аварийного включения не предусмотрен, как я понимаю.
Я у вас вообще не увидел такого понятия как "критическое событие". Это не "ошибка", это другое.

avarte
09.03.2026 11:24Тут главное - "начало положено"
Я вот тоже надеюсь в этом году что-то подобное делать.

BlAnge
09.03.2026 11:24Класс! А нейроночку прицепить ? А лучше - чтобы агент управлял урожайностью.
Например "В теплице 1 помидорки сорт X, в теплице 2 - огурцы сорт Y, вот тебе куча датчиков таких то таких то, поливай и проветривай в соответствии с правилами"
Ещё круче было бы - диагностика состояния по фото.
И агент бы посылал сообщения "внимание, нашествие слизней (или соседей-)", или "листики жёлтые, подкормите растения таким то удобрением"
Измеритель инсоляции тоже прикрутить бы!

Razumdom
09.03.2026 11:24Отлично написано и хорошо сделанная работа.
Но не хватает фото всего комплекса над которым происходят действия, поэтому статья не оживленная. Она выглядит концептом, но не рабочей.
Страницы красивые, красочные, но не хватает фоновой картинки объекта действий - теплицы.
Если - то: это условная логика, но можно добавить другую, циклы, выбор и пр. Можно добавить арифметические операции кроме сложения, например, для вычисления среднего значения.
Контролировать хорошо бы не температуру, а выход её за пределы. И управлять не goio, а пороговым параметром. Для выхода ШИМ идеальным было бы использование ПИД регулирования.
В целом выглядит отлично, но хотелось бы посмотреть как это все работает.
Jury_78
В чем смысл - мс?
semmi
Что бы оправдать использование RPI.