ESPN DeportesInglaterra marca el empate en un partidazo ante EspañaESPNBears QB Williams out for MNF; Bagent back at practiceThe Jerusalem PostTrump predicts Cuba, US will make a dealRTP DesportoMundiais Triatlo. Maria Tomé 20.ª nas Elites, Cassandre Beaugrand campeãStraits Times SportGeorgia replace manager Sagnol with Svanadze after Northern Ireland lossThe South AfricanSouth Africa’s URC franchises complete round one clean sweepNU AchterklapSylvester Stallone kampte vroeger met eetstoornis: 'Kon niets binnenhouden'n-tvKrach: "Sehr hohe Hürden": Auch Berliner SPD will mit der Linkspartei sondierenMyJoyOnlineStakeholders demand action against foreign-led illegal mining in Ahafo RegionGlobal NewsLawyer wins case against multinational firm behind day school settlementPunch2027: Osun APC rallies electorate for candidates, says current hardship temporaryABC News (Australia)What young people want to know about the law
The Daily Newsstand · Free, Always
Saturday, September 26, 2026

Умная теплица на Raspberry Pi 4. Или сказ про то как проект вырос в полноценный контроллер умного дома. Часть 2

Translate

В первой части я рассказывал о системе автоматизации теплицы на Raspberry Pi 4. Она собирала показания датчиков и управляла оборудованием. Постепенно захотелось применить её и за пределами теплицы: дома, в мастерской или серверной. Задачи там знакомые — следить за температурой, включать устройства по условию и получать уведомления.

Для этого понадобились новые способы подключения устройств, удалённый доступ и обновления с сохранением настроек. В проекте появились Zigbee-датчики, поддержка Rock Pi, облачный кабинет и уведомления в MAX. Теперь это Geek Automation System — контроллер умного дома, для которого теплица остаётся одним из вариантов применения.

В этой статье покажу, что изменилось, как устроена связь с облаком и зачем на самой плате работает отдельная служба - provision agent

Кто за что отвечает

В системе три основных участника: подключённые устройства, контроллер и облачный сервис.

Устройства — это датчики, розетки и реле. Одни передают показания, другие выполняют команды.

Контроллер — Raspberry Pi или Rock Pi — получает показания и выполняет правила. Например, включает вентиляцию, когда температура поднимается выше заданного порога. На нём хранятся настройки и история измерений, а управлять им можно через страницу в браузере.

Облачный сервис работает на отдельном сервере, доступном через интернет. Через него пользователь видит свои контроллеры вне дома, открывает их интерфейсы и получает уведомления.

В облачном кабинете к аккаунту привязывается контроллер целиком. Его датчиками и остальным оборудованием управляет программа на плате.

Правила автоматизации выполняются на контроллере. При обрыве интернета продолжают работать локальный интерфейс, сбор показаний и управление доступным оборудованием. Разумеется, самой плате и устройствам нужны питание и связь между собой. Удалённый доступ и отправка через облако возобновятся после восстановления соединения.

Что теперь видно в интерфейсе

Раньше проект был ориентирован на оборудование теплицы. Теперь на одной странице собраны устройства, подключённые разными способами:

- проводами к контактам платы — такие контакты называются GPIO;

- через локальную сеть — например, модули ESP8266 и ESP32 с собственной прошивкой;

- по беспроводной связи Zigbee — датчики и розетки.

Устройства собраны в общий список. Из него можно открыть карточку, посмотреть состояние и показания.

Рис. 2. Главная панель Rock Pi: устройства, их доступность и последние показания

Рис. 2. Главная панель Rock Pi: устройства, их доступность и последние показания

У показаний на странице есть важная особенность: последнее сохранённое значение может уже устареть. Если датчик вчера передал 22 °C, а потом у него села батарейка, число останется в базе, хотя температура за это время могла измениться.

Интерфейс учитывает время получения и состояние связи. Когда свежих данных нет, он показывает последнее известное значение с предупреждением.

То же относится к дымовому датчику: вчерашнее сообщение «дыма нет» ничего не говорит о ситуации сейчас.

Как подключаются беспроводные датчики Zigbee

Zigbee — способ беспроводной связи, который используют многие домашние датчики, кнопки и розетки. Чтобы контроллер мог с ними общаться, к нему подключается USB-адаптер — координатор Zigbee. Он служит точкой связи с этой сетью.

В проекте я использовал Zigbee2MQTT Dongle — USB-координатор с внешней антенной. На фото он подключён к Rock Pi.

Рис. 3. Zigbee2MQTT Dongle с внешней антенной в USB-разъёме Rock Pi

Рис. 3. Zigbee2MQTT Dongle с внешней антенной в USB-разъёме Rock Pi

На плате работают Zigbee2MQTT и Mosquitto. Zigbee2MQTT переводит сообщения датчиков в форму, понятную остальному ПО. Mosquitto доставляет их программе контроллера по протоколу MQTT — это своего рода внутренняя почта системы.

Путь показания получается таким:

Датчик → USB-координатор → Zigbee2MQTT → Mosquitto → программа контроллера

Эта цепочка работает локально: показания поступают на контроллер и сохраняются у него.

Рис. 4. В общем списке появились Zigbee-датчики температуры и дыма, а также розетки

Рис. 4. В общем списке появились Zigbee-датчики температуры и дыма, а также розетки

Состояния и события

У дымового датчика есть состояние «обнаружен дым» и кнопка Test для проверки. Оба признака могут передаваться числами 0 и 1, но обрабатывать их нужно по-разному.

Дым — состояние. Датчик сообщает, что тревога началась, а затем должен сообщить о возврате в норму. Одного ожидания или потери связи недостаточно, чтобы считать тревогу завершённой.

Нажатие Test — событие. Оно произошло в конкретный момент. Если нажать кнопку дважды, это два отдельных события, даже если последнее сохранённое число в обоих случаях равно 1.

Расширение Zigbee2MQTT передаёт отдельные отчёты о событиях. Контроллер сохраняет их время и уникальный идентификатор — метку, позволяющую распознать повторную доставку. Так повтор одного сообщения не становится новым нажатием, а запоздалый отчёт не заменяет более свежее состояние.

Рис. 5. В карточке дымового датчика различаются показания, состояние связи и событие Test

Рис. 5. В карточке дымового датчика различаются показания, состояние связи и событие Test

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

Подтверждение команд

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

Если устройство прислало ожидаемое состояние, команда считается подтверждённой. Если за отведённое время ответа нет, интерфейс сообщает об этом. При этом ответ розетки подтверждает именно её состояние: исправность подключённого вентилятора и вращение его лопастей так проверить нельзя.

Правила автоматизации и уведомления

Правило автоматизации связывает условие с действием: например, при высокой температуре включает вентиляцию.

У такого правила два режима. В первом действие выполняется при наступлении условия: температура пересекла порог — отправлена команда. Во втором действие повторяется с заданной паузой, пока условие выполняется. Режим выбирается под задачу и подключённое оборудование.

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

Уведомления настроены иначе. Для дымового датчика сообщение отправляется в начале тревоги и после подтверждённого возврата в норму. Повтор того же активного состояния не должен каждый раз создавать новую тревогу.

А нажатие Test — самостоятельное событие. Следующее нажатие нужно обработать как следующую проверку.

Рис. 6. Правило уведомления для кнопки Test дымового датчика

Рис. 6. Правило уведомления для кнопки Test дымового датчика

Что будет с сообщением при обрыве связи

Сведения о тревоге и задание на отправку уведомления сохраняются вместе в базе на самом контроллере. Так после перезапуска остаётся понятно, что произошло и какое сообщение ещё нужно доставить.

Фоновая программа на той же плате берёт задания из очереди и передаёт их службе доставки. При временной ошибке предусмотрены повторные попытки. Это повышает надёжность, но не делает интернет и мессенджер безотказными. В редкой ситуации возможен и повтор сообщения: например, внешняя служба уже приняла его, а подтверждение этого потерялось.

Рис. 7. Уведомление в MAX с названием устройства и временем в часовом поясе контроллера

Рис. 7. Уведомление в MAX с названием устройства и временем в часовом поясе контроллера

История показаний

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

Рис. 8. На момент съёмки в выбранные 7 дней попадала вся история после переноса сети на Rock Pi — 58 измерений

Рис. 8. На момент съёмки в выбранные 7 дней попадала вся история после переноса сети на Rock Pi — 58 измерений

Как перенесли систему на Rock Pi

Следующей платформой стал Radxa ROCK Pi 4A с Armbian — операционной системой на базе Linux для одноплатных компьютеров. На нём нужно было сохранить тот же набор функций и привычный интерфейс.

Рис. 9. ROCK Pi 4A, на котором проверялась установка под Armbian

Рис. 9. ROCK Pi 4A, на котором проверялась установка под Armbian

Основную программу удалось перенести, но с контактами платы потребовалась отдельная работа. Похожий 40-контактный разъём ещё не означает одинаковое назначение всех контактов. У плат различаются обозначения, функции и линии, уже занятые операционной системой.

Поэтому контроллер определяет модель платы и показывает подходящую схему GPIO. В ней физическое место контакта отделено от номера, под которым с ним работает Linux.

Рис. 10. Справочная схема помогает найти контакт и проверить его назначение

Рис. 10. Справочная схема помогает найти контакт и проверить его назначение

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

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

Пакеты установки подготовлены отдельно для Raspberry Pi и ROCK 4. При этом для каждой ревизии ROCK 4 не нужен собственный интерфейс: поддерживаемая модель определяется во время работы. Пользователь видит название платы и логотип производителя как локально, так и в облаке.

Зачем понадобился Cloud Service

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

Поэтому в проекте появился Cloud Service — облачный сервис GeekLab. Он связывает аккаунт с контроллерами и позволяет обращаться к ним через личный кабинет из внешней сети.

Рис. 11. В одном кабинете собраны Raspberry Pi и Rock Pi, принадлежащие пользователю

Рис. 11. В одном кабинете собраны Raspberry Pi и Rock Pi, принадлежащие пользователю

Через кабинет можно выбрать контроллер, увидеть состояние его подключения и открыть интерфейс. Облачная часть также участвует в регистрации новых плат и доставке уведомлений в MAX.

Например, при срабатывании датчика локальная программа проверяет правило и формирует предупреждение. Дальше событие передаётся по облачному каналу, а служба уведомлений отправляет сообщение связанному получателю. Решение о срабатывании правила принимается на плате.

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

Как открыть контроллер из другой сети

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

Когда пользователь выбирает «Открыть интерфейс устройства», облако проверяет его доступ к контроллеру и создаёт временный сеанс. Страница загружается из облака, а запросы за данными и командами передаются контроллеру через его защищённое соединение. Для удалённого интерфейса используется отдельный домен, чтобы его авторизация была отделена от облачного кабинета.

Облачный сервер проверяет доступ пользователя к выбранной плате. Права на действия в её интерфейсе проверяются отдельно.

Почему ушли от WireGuard

Изначально связь работала через WireGuard — защищённый сетевой туннель. Позже понадобилось ограничить взаимодействие конкретными операциями: передать событие, сообщить о доступности, получить команду.

Поэтому вместо общей виртуальной сети появился прикладной канал на основе gRPC. Это технология обмена заранее описанными сообщениями между программами.

За шифрование и взаимную проверку сторон отвечает mTLS. Контроллер проверяет облачный сервер, а сервер проверяет контроллер по его сертификату.

Вместе с этим облако проверяет права на запросы и позволяет отключить доступ отдельной платы. Шифрование соединения и разрешение конкретных действий здесь решают разные задачи.

Как новая плата получает доступ к облаку

Новому контроллеру нужно получить сертификат и привязаться к аккаунту владельца. Этот процесс называется provisioning, или первоначальная привязка.

Пользователь запускает её в мастере настройки. Программы на плате и в облаке регистрируют контроллер и подготавливают данные для дальнейшего подключения.

Свой сертификат для каждого контроллера

Человек входит в облачный кабинет со своей учётной записью. Плате же нужны собственные данные для автоматического подключения.

Для этого каждый контроллер получает сертификат — цифровое удостоверение. Сертификат не секретен, но пользоваться им позволяет закрытый ключ, который хранится на плате. Ключ создаётся локально и при регистрации в облако не отправляется.

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

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

Что делает provision-agent

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

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

Эту работу выполняет provision-agent — служба первоначальной привязки, установленная на Raspberry Pi или Rock Pi. Она получает задание от основной программы контроллера, проверяет его и сохраняет данные подключения.

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

Распределение работы получается таким:

Участник

Его задача

Облачная служба регистрации

проверить запрос на привязку и выдать сертификат

Основная программа контроллера

подготовить запрос, получить ответ и передать задание агенту

provision-agent на плате

проверить и установить данные подключения

Основная программа после настройки

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

Одного успешного ответа облака недостаточно: полученный сертификат ещё нужно установить на плате. Агент выполняет этот этап и возвращает результат. Проверки файлов и восстановление после ошибок собраны в одном компоненте, отдельно от веб-интерфейса.

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

От мастера настройки до подключения

1. Пользователь входит в облачный аккаунт через мастер настройки и при необходимости дополнительно вводит код активации.

2. Контроллер создаёт ключ и запрос на сертификат — CSR. В облако отправляется запрос с открытой частью ключа; закрытая остаётся на плате.

3. Облако проверяет регистрацию и выпускает сертификат с учётом привязки контроллера к владельцу.

4. Основная программа передаёт комплект агенту. Он проверяет данные, записывает файлы с ограниченными правами и сохраняет результат.

5. Контроллер подключается к облачному шлюзу — службе, принимающей соединения плат. Она проверяет сертификат и подтверждение владения ключом, затем разрешает обмен.

Рис. 12. В карточке контроллера видны состояние облачного соединения и сведения о сертификате

Рис. 12. В карточке контроллера видны состояние облачного соединения и сведения о сертификате

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

Что будет, если настройка прервётся

Настройка может прерваться, например из-за перезагрузки платы. Агент хранит состояние задания и результат обработки, чтобы после запуска было понятно, что успело выполниться. Новый ключ и сертификаты сначала записываются в отдельный каталог. Только после успешной записи конфигурация переключается на этот комплект, а предыдущий остаётся на диске. При повторном запуске служба может обработать оставшееся задание, а при ошибке — сообщить о ней.

Программа и обновления

Основная программа контроллера теперь написана на Go. Для проекта так удобнее собирать исполняемый файл под одноплатные компьютеры и выпускать согласованные версии компонентов. Параллельно дорабатывались обработка событий, подтверждение команд и очередь уведомлений.

Веб-интерфейс написан на React. База PostgreSQL хранит настройки, историю и задания. Чтобы показания обновлялись без перезагрузки страницы, используется WebSocket — постоянное соединение между браузером и сервером контроллера. Обычные запросы, например сохранение настройки, проходят через API — набор операций, которые предоставляет сервер.

Для установки подготовлены Debian-пакеты, то есть файлы .deb, которые умеет устанавливать пакетный менеджер системы. GitLab CI автоматически запускает проверки и собирает эти пакеты. Номер версии позволяет определить, какие исходники использовались для конкретной сборки.

Обновление должно сохранять историю, правила, сеть Zigbee, сертификаты и локальные учётные записи. Заново подключать датчики и проходить облачную регистрацию после каждой версии не требуется.

На случай потери локального пароля в пакет входит утилита восстановления:

sudo geek-automation-system-admin

Её запускает администратор с доступом к системе, например по SSH — защищённому удалённому подключению к командной строке. Она позволяет изменить локальный логин и пароль. Пароль облачного аккаунта эта команда не меняет.

Что в итоге

Теплица остаётся одним из сценариев использования. Теперь тот же контроллер может собирать показания домашних датчиков, управлять оборудованием по правилам, хранить историю и передавать уведомления.

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

Мне важно, чтобы пользоваться системой было проще, чем разбираться в её внутреннем устройстве: подключить плату, добавить датчик, задать правило. При ошибке должно быть понятно, что именно не получилось.

Следующую часть можно посвятить установке с нуля: чистая Raspberry Pi или Rock Pi, пакет с программой, первый датчик и первое уведомление в MAX.

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.