ГлавнаяАкадемияОсновы умного дома → Шаблон 1: Standalone (Автономный контроллер)

Шаблон 1: Standalone (Автономный контроллер)

Урок · Основы умного дома · 30 мин · theory
id: COURSE-01-M06-L01

title: "Шаблон 1: Standalone (Автономный контроллер)"

level: foundation

tags: ["архитектура", "standalone", "автономность", "отказоустойчивость", "spof"]

prerequisites: ["COURSE-01-M02", "COURSE-01-M04", "COURSE-01-M05"]

version: 1.0

status: review

learning_outcomes:

- "Студент сможет объяснить преимущества и недостатки Standalone-архитектуры."

- "Студент сможет подобрать базовый аппаратно-программный стек для реализации Standalone-решения."

- "Студент сможет создать и настроить простой поток в Node-RED для управления периферийным устройством на базе MQTT-сообщений."

- "Студент сможет определить, когда применение данного шаблона целесообразно, а когда — нет."

key_concepts:

- "Standalone-архитектура"

- "Единая точка отказа (SPOF)"

- "Локальное управление"

- "MQTT-брокер"

- "Node-RED"

- "Автономность системы"

- "Нода 'trigger'"

- "Контракт сообщения"

---

COURSE-01-M06-L01-S01: Введение в архитектуру Standalone (Автономный контроллер)

Добро пожаловать в шестой модуль курса, посвященный базовым шаблонам архитектуры. В этом уроке мы детально разберем первый и самый фундаментальный шаблон — Standalone, или автономный контроллер.

> 💡 Подсказка: Архитектура Standalone — идеальный выбор для систем, где отказоустойчивость и скорость реакции критически важны, например для систем защиты от протечек или управления котельным оборудованием.

📋 Ключевые понятия:

Ключевые преимущества

  • Высокая надежность и отказоустойчивость. Поскольку вся логика выполняется локально на контроллере, система не зависит от стабильности интернет-соединения или доступности облачных платформ. Пропал интернет — свет по движению продолжает включаться, климат-контроль работает, защита от протечки активна. Наличие специализированного ARM32-ядра для критичных функций и EEPROM для хранения сценариев на нашей платформе дополнительно повышает этот параметр.
  • Низкая задержка (Low Latency). Команды обрабатываются мгновенно. Сигнал от датчика движения до включения реле проходит путь в несколько миллисекунд внутри одного устройства. В облачных системах этот путь может занимать сотни миллисекунд или даже секунды, что недопустимо для многих задач (например, мгновенное перекрытие воды при сигнале от датчика протечки).
  • Приватность и безопасность данных. Вся информация о состоянии вашего объекта (кто дома, какие устройства включены, графики температур) не покидает пределы контроллера. Это исключает риски утечки данных через внешние серверы и несанкционированного доступа извне, если система правильно настроена.
  • Простота развертывания. Для базовых задач внедрение такой системы сводится к монтажу одного контроллера, подключению периферии и настройке логики на нем.
  • Основные недостатки

  • Единая точка отказа (Single Point of Failure - SPOF). Главный минус — если контроллер выходит из строя (например, из-за сбоя питания или аппаратной поломки), вся система автоматизации полностью перестает функционировать. Это требует использования надежных промышленных контроллеров и качественного электропитания с резервированием (ИБП).
  • Ограниченная масштабируемость. Масштаб системы ограничен физическими возможностями одного контроллера: количеством портов, производительностью процессора. Наша платформа с 22 универсальными входами и 22 релейными выходами покрывает потребности квартиры или небольшого коттеджа, но для крупного офисного здания или гостиницы одного контроллера будет недостаточно.
  • Сложность централизованного управления и мониторинга. Если на одном объекте установлено несколько независимых Standalone-систем (например, одна для климата, другая для освещения), собрать с них общую статистику или управлять ими из единого интерфейса становится нетривиальной задачей. Каждая система — это "остров автоматизации".
  • Типичные сценарии применения

    Шаблон Standalone идеально подходит для изолированных и критически важных подсистем:

    ---

    COURSE-01-M06-L01-S02: Аппаратно-программный стек для Standalone-решения

    Для построения надежной Standalone-системы необходимо правильно выбрать компоненты — как аппаратные, так и программные.

    > ⚠️ Внимание: Использование не-промышленных решений, таких как Raspberry Pi без соответствующей обвязки (промышленные блоки питания, watchdog-таймеры, гальваническая развязка портов), значительно снижает надежность Standalone-системы. Для коммерческих объектов это является недопустимым риском.

    1. Выбор контроллера

    Основа всей системы — контроллер. Наша платформа представляет собой промышленный контроллер, спроектированный для работы в режиме 24/7. Его ключевые аппаратные интерфейсы, необходимые для Standalone-архитектуры:

    2. Операционная система

    Наш контроллер работает под управлением Debian Linux. Это зрелая, стабильная и хорошо документированная операционная система, являющаяся промышленным стандартом. Для базовой настройки Standalone-системы необходимо убедиться, что:

    3. Программная среда для логики

    Для визуального программирования логики мы используем Node-RED. Как мы уже рассматривали в COURSE-01-M05, Node-RED позволяет инженерам без глубоких знаний программирования создавать сложные сценарии, соединяя функциональные блоки (ноды). В Standalone-архитектуре Node-RED выполняется непосредственно на контроллере, обеспечивая мгновенную обработку событий.

    4. Протокол взаимодействия: локальный MQTT

    Даже внутри одного контроллера компоненты должны общаться друг с другом. Чтобы отделить драйверы оборудования от логики, используется протокол MQTT. В Standalone-архитектуре MQTT-брокер (например, `mosquitto`) устанавливается прямо на контроллер.

    # Пример установки MQTT-брокера Mosquitto на Debian
    

    sudo apt-get update

    sudo apt-get install -y mosquitto mosquitto-clients

    Такая организация превращает MQTT в "кровеносную систему" проекта:

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

    ---

    COURSE-01-M06-L01-S03: Практический пример: автономное управление освещением по датчику движения

    Рассмотрим реализацию классической задачи в рамках Standalone-архитектуры.

    > 🔗 Связанный материал: Подробно о настройке драйвера `wb-mqtt-serial` для работы с Modbus-устройствами и об общей структуре MQTT-топиков нашей платформы мы говорили в уроке COURSE-01-M04-L02.

    Постановка задачи

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

    Аппаратная конфигурация

  • Контроллер: Наш платформенный контроллер.
  • Датчик: Пассивный инфракрасный (PIR) датчик движения с выходом типа "сухой контакт". Подключается к одному из 22 универсальных входов контроллера, настроенному как дискретный вход (DI). Например, вход `DI 1`.
  • Нагрузка: Светодиодная лента или лампа. Управляется через одно из 22 реле контроллера. Например, реле `Relay 1`.
  • Настройка системного ПО

    На контроллере предустановлен драйвер `wb-gpio`, который автоматически опрашивает состояние встроенных входов/выходов и публикует их в MQTT. Нам не требуется дополнительная конфигурация. Драйвер сам создает необходимые топики.

    Структура MQTT-топиков и контракт сообщений

  • Топик состояния датчика движения:
  • Драйвер `wb-gpio` будет публиковать состояние входа `DI 1` в следующий топик:

        /devices/wb-gpio/controls/DI1_IN

    Контракт сообщения (msg.payload):

    * `"1"` — движение обнаружено (контакт замкнут).

    * `"0"` — движение отсутствует (контакт разомкнут).

  • Топик управления реле:
  • Для управления реле `Relay 1` мы должны публиковать сообщения в топик:

        /devices/wb-gpio/controls/Relay_1/on

    Контракт сообщения (msg.payload):

    * `"1"` — включить реле.

    * `"0"` — выключить реле.

    > 💡 Подсказка: Используйте утилиту `mosquitto_sub` прямо в консоли контроллера, чтобы в реальном времени видеть сообщения от датчика и отлаживать систему.

    >

    > # Подписаться на все топики устройства wb-gpio

    > mosquitto_sub -v -t '/devices/wb-gpio/controls/#'

    >

    Теперь, когда аппаратная часть подключена, а каналы обмена данными (MQTT-топики) определены, мы можем приступить к созданию логики в Node-RED.

    ---

    COURSE-01-M06-L01-S04: Реализация логики в Node-RED

    Создадим поток (flow), который реализует нашу задачу по управлению освещением.

    Визуальная схема потока

    ┌──────────┐   ┌─────────┐   ┌─────────────────┐   ┌───────────┐
    

    │ MQTT in ├─► │ rbe ├─► │ trigger ├─► │ MQTT out │

    │ (датчик) │ │ (фильтр)│ │ (таймер задержки) │ │ (реле) │

    └──────────┘ └─────────┘ └─────────────────┘ └───────────┘

    Пошаговая настройка нод

  • Нода `MQTT in` (Получение данных от датчика)
  • * Перетащите ноду `mqtt in` на поле.

    * Server: Выберите `localhost:1883` (локальный MQTT-брокер). Если он не настроен, добавьте новый, указав `localhost` в поле Server и `1883` в поле Port.

    * Topic: Укажите `/devices/wb-gpio/controls/DI1_IN`.

    * Output: `a string`.

    * Name: `Датчик движения в коридоре`.

  • Нода `rbe` (Фильтр дубликатов)
  • Датчики движения могут отправлять сообщения несколько раз в секунду, пока обнаруживают движение. Чтобы наш таймер не перезапускался постоянно, нужно пропускать только изменение состояния (с 0 на 1 или с 1 на 0).

    * Перетащите ноду `rbe` (в разделе `function`). Ее полное название "report by exception".

    * Mode: `block unless value changes`.

    * Соедините выход ноды `MQTT in` со входом ноды `rbe`.

  • Нода `trigger` (Таймер задержки выключения)
  • Это ядро нашей логики. Она будет включать свет немедленно и отправлять команду на выключение через заданное время.

    * Перетащите ноду `trigger`.

    * Send: `1` (строка или число). Это сообщение будет отправлено на выход немедленно при получении любого сообщения на входе.

    * then wait for: `1` `minute`.

    * then send: `0` (строка или число). Это сообщение будет отправлено после истечения таймера.

    * Extend delay if new message arrives: Обязательно поставьте галочку! Это обеспечит сброс таймера, если придет новое сообщение о движении.

    * Name: `Таймер на 1 минуту`.

    * Соедините выход ноды `rbe` со входом ноды `trigger`.

  • Нода `MQTT out` (Отправка команды на реле)
  • * Перетащите ноду `mqtt out`.

    * Server: `localhost:1883`.

    * Topic: `/devices/wb-gpio/controls/Relay_1/on`. Убедитесь, что топик указан полностью и корректно.

    * Name: `Управление светом в коридоре`.

    * Соедините выход ноды `trigger` со входом ноды `MQTT out`.

    После выполнения этих шагов нажмите красную кнопку Deploy в правом верхнем углу интерфейса Node-RED. Система готова к работе.

    Экспорт потока (Flow)

    Для быстрого развертывания этого сценария вы можете импортировать следующий JSON-код в ваш Node-RED (Menu -> Import):

    [
    

    {

    "id": "c1a2b3c4.d5e6f7",

    "type": "tab",

    "label": "Управление освещением (Standalone)",

    "disabled": false,

    "info": ""

    },

    {

    "id": "a1b2c3d4.e5f6a7",

    "type": "mqtt in",

    "z": "c1a2b3c4.d5e6f7",

    "name": "Датчик движения в коридоре",

    "topic": "/devices/wb-gpio/controls/DI1_IN",

    "qos": "2",

    "datatype": "utf8",

    "broker": "b1c2d3e4.f5a6b7",

    "x": 150,

    "y": 100,

    "wires": [

    [

    "f1e2d3c4.b5a698"

    ]

    ]

    },

    {

    "id": "f1e2d3c4.b5a698",

    "type": "rbe",

    "z": "c1a2b3c4.d5e6f7",

    "name": "Фильтр дубликатов",

    "func": "rbe",

    "gap": "",

    "start": "",

    "inout": "out",

    "property": "payload",

    "x": 360,

    "y": 100,

    "wires": [

    [

    "d1c2b3a4.e5f6a7"

    ]

    ]

    },

    {

    "id": "d1c2b3a4.e5f6a7",

    "type": "trigger",

    "z": "c1a2b3c4.d5e6f7",

    "op1": "1",

    "op2": "0",

    "op1type": "str",

    "op2type": "str",

    "duration": "1",

    "extend": true,

    "units": "min",

    "reset": "",

    "bytopic": "all",

    "name": "Таймер на 1 минуту",

    "x": 570,

    "y": 100,

    "wires": [

    [

    "e1f2a3b4.c5d6e7"

    ]

    ]

    },

    {

    "id": "e1f2a3b4.c5d6e7",

    "type": "mqtt out",

    "z": "c1a2b3c4.d5e6f7",

    "name": "Управление светом в коридоре",

    "topic": "/devices/wb-gpio/controls/Relay_1/on",

    "qos": "0",

    "retain": "false",

    "broker": "b1c2d3e4.f5a6b7",

    "x": 810,

    "y": 100,

    "wires": []

    },

    {

    "id": "b1c2d3e4.f5a6b7",

    "type": "mqtt-broker",

    "name": "Локальный брокер",

    "broker": "localhost",

    "port": "1883",

    "clientid": "",

    "usetls": false,

    "compatmode": true,

    "keepalive": "60",

    "cleansession": true,

    "birthTopic": "",

    "birthQos": "0",

    "birthPayload": "",

    "closeTopic": "",

    "closeQos": "0",

    "closePayload": "",

    "willTopic": "",

    "willQos": "0",

    "willPayload": ""

    }

    ]

    ---

    COURSE-01-M06-L01-S05: Резюме и ограничения шаблона

    В этом уроке мы подробно изучили архитектурный шаблон Standalone. Он является краеугольным камнем для построения надежных и быстрых систем автоматизации на локальных объектах.

    Давайте закрепим ключевые моменты.

    Чек-лист для выбора шаблона Standalone

    Используйте этот шаблон, если ответы на следующие вопросы - "Да":

    Проблема "острова автоматизации"

    Применение нескольких Standalone-контроллеров на одном большом объекте (например, в коттедже, где один контроллер отвечает за дом, а второй за баню) порождает проблему "островов автоматизации". Эти системы не знают друг о друге, не могут обмениваться данными и управляться из единого интерфейса. Вы не сможете, например, одной кнопкой "Я ушел" выключить весь свет и в доме, и в бане.

    Решение этой проблемы лежит в переходе к более сложным архитектурным шаблонам.

    Что дальше?

    Проблема "островов автоматизации" и ограниченной масштабируемости подводят нас к необходимости централизации. В следующем уроке мы рассмотрим шаблон "Центральный хаб" (Hub & Spoke), который позволяет объединить несколько контроллеров в единую систему с центральным сервером для управления, сбора данных и интеграции.

    🔗 Следующий урок: COURSE-01-M06-L02: Шаблон 2: Центральный хаб (Hub & Spoke)