ГлавнаяАкадемияОсновы умного дома → Функция ПЛК и Safe-State

Функция ПЛК и Safe-State

Урок 3 · Основы умного дома · 30 мин · theory

Функция ПЛК и отказоустойчивость в Node-RED

В мире промышленной автоматизации ПЛК (Программируемый Логический Контроллер) является краеугольным камнем надежности. Это специализированное вычислительное устройство, спроектированное для работы в жестких условиях и гарантирующее детерминированное, предсказуемое выполнение управляющих программ в режиме реального времени. Ключевые отличия классического ПЛК от обычного компьютера или одноплатника (как наш контроллер) заключаются в аппаратной и программной архитектуре, нацеленной на максимальную отказоустойчивость.

Такие контроллеры имеют:

Адаптация концепции ПЛК для систем умного дома

Контроллер нашей платформы, работающий под управлением Debian Linux и Node-RED, по своей сути является "мягким" ПЛК (Soft PLC). Он предоставляет огромную гибкость, широкие возможности интеграции и удобную среду для визуального программирования. Однако стандартная операционная система общего назначения, такая как Debian, не является системой реального времени. Процесс Node-RED может быть остановлен операционной системой, завершиться с ошибкой из-за нехватки памяти или "зависнуть" из-за некорректно написанного потока.

> ⚠️ Внимание: Доверять всю логику, особенно связанную с безопасностью и жизнеобеспечением, исключительно программной среде уровня Node-RED — критическая архитектурная ошибка. Необходимо разделять уровни ответственности.

Именно поэтому наш контроллер имеет гибридную архитектуру. Он сочетает в себе:

  • Верхний уровень (гибкий): Мощный процессор с Debian, Node-RED, MQTT-брокером для реализации сложной логики, сценариев, интеграций и пользовательских интерфейсов.
  • Нижний уровень (исполнительный): Аппаратные компоненты и специализированное ПО, выполняющие роль базового, надежного слоя. Сюда входят защищенные входы/выходы, микроконтроллер для детерминированных задач и, что самое важное для этого урока, механизм Safe-State.
  • Этот нижний, исполнительный уровень выступает в роли страховки. Если верхний уровень (Node-RED) по какой-либо причине выходит из строя, именно исполнительный уровень должен перевести систему в заранее определенное безопасное состояние.

    ---

    Концепция 'Safe-State': проектирование безопасного отказа

    Безопасное Состояние (Safe-State) — это предопределенное состояние выходов и исполнительных механизмов, в которое система автоматически переходит в случае отказа управляющей логики верхнего уровня. Это не просто технический термин, а фундаментальная концепция проектирования отказоустойчивых систем. Задача инженера — на этапе проектирования системы ответить на вопрос: "Что должно произойти с каждым устройством, если контроллер зависнет или перезагрузится?".

    Сценарии отказа могут быть разнообразными:

    > ⚠️ Внимание: Отсутствие продуманного 'Safe-State' может привести не только к дискомфорту (например, неработающий свет), но и к аварийным ситуациям: работе котла отопления без циркуляции, неперекрытые клапаны при протечке, включенные без присмотра мощные электроприборы.

    Типовые стратегии Safe-State

    Выбор стратегии зависит от функции, которую выполняет конкретный выход контроллера.

    | Стратегия | Описание | Примеры применения | Реализация на платформе HI |

    | ----------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ | ---------------------------------------------------------------------- |

    | Fail-Safe (Выключено) | Самая распространенная и безопасная стратегия. При отказе все выходы переходят в положение "Выключено". | Освещение, розетки, полив, мультимедиа-оборудование, нагревательные элементы. | Установка состояния "Off" для реле при загрузке в настройках контроллера. |

    | Сохранить последнее состояние | Система пытается восстановить то состояние, которое было у выхода до сбоя. | Дежурное/аварийное освещение, некоторые режимы вентиляции, питание сетевого оборудования. | Использование энергонезависимой памяти EEPROM (как рассмотрено в уроке COURSE-01-M07-L03) для хранения состояния. |

    | Перейти в аварийный режим | Система активирует специальный, заранее запрограммированный режим работы. | Включить циркуляционный насос котла на минимальную скорость, перевести вентиляцию в приточный режим. | Реализуется через встроенный движок правил (`wb-rules`), не зависящий от Node-RED. |

    Проектирование Safe-State — это обязательный этап, который должен быть задокументирован в проектной документации для каждого управляемого контура.

    ---

    Практика: Настройка Safe-State на контроллерах Wirenboard

    Наш контроллер, будучи идеологическим наследником Wirenboard, предоставляет схожие мощные механизмы для настройки Safe-State на аппаратном уровне, вне зависимости от работы Node-RED.

    > 🔗 Связанный материал: Этот механизм дополняет возможности, рассмотренные в уроке `COURSE-01-M07-L03: Роль EEPROM для надёжного хранения`. Состояние при загрузке может быть записано в энергонезависимую память, что позволяет реализовать стратегию "Сохранить последнее состояние".

    Настройка через Web-интерфейс

    Это самый простой и быстрый способ для реализации стратегии "Fail-Safe".

  • Откройте Web-интерфейс контроллера в браузере.
  • Перейдите в раздел `Настройки оборудования` (`Hardware Modules Configuration`).
  • Найдите в списке модуль реле, например, `Relay module (MOSFET)`.
  • Напротив каждого канала реле (`Relay 1`, `Relay 2`, ...) вы увидите поле `Boot-up state` (Состояние при загрузке).
  • Для большинства выходов (свет, розетки) выберите значение `Off` (Выключено).
  • Нажмите кнопку `Сохранить` (`Save`).
  • Теперь, после каждой перезагрузки контроллера, независимо от того, запустился Node-RED или нет, эти реле гарантированно будут выключены.

    Продвинутый способ: использование движка правил `wb-rules`

    Для реализации более сложных стратегий, таких как "Аварийный режим" или "Сторожевой таймер для MQTT", используется встроенный движок правил `wb-rules`. Он работает как отдельный легковесный сервис и не зависит от Node-RED. Правила пишутся на простом JavaScript-подобном языке.

    Пример: Сторожевой таймер для системы защиты от протечек Задача: Система защиты от протечек управляется через Node-RED. Реле `RL-10` открывает клапан подачи воды. Мы хотим быть уверены, что если Node-RED "зависнет" и перестанет посылать управляющие команды, клапан автоматически закроется через 5 минут. Логика:
  • Node-RED, пока работает штатно, раз в минуту отправляет MQTT-сообщение в топик `hi_platform/system/watchdog/nodered` со значением `1`.
  • Правило в `wb-rules` следит за этим топиком. Оно запускает виртуальный таймер на 5 минут. Каждый раз, когда приходит сообщение, таймер сбрасывается.
  • Если в течение 5 минут сообщение не пришло, таймер срабатывает, и правило принудительно выключает реле `RL-10`.
  • Код для файла `/etc/wb-rules/leak-protection.js`:
    // Определяем устройство и его элементы управления
    

    defineVirtualDevice("nodered_watchdog", {

    title: "Node-RED Watchdog",

    cells: {

    // Виртуальный таймер на 300 секунд (5 минут)

    timer: {

    type: "timer",

    value: 300 // seconds

    }

    }

    });

    // Правило, которое реагирует на сообщение от Node-RED

    defineRule("rule_nodered_heartbeat", {

    // Выполняется, когда меняется значение в топике .../nodered/control

    when: function (value, devName, cellName) {

    return devName === "hi_platform/system/watchdog/nodered";

    },

    // Действие: сбросить таймер

    then: function (value, devName, cellName) {

    log("Node-RED heartbeat received. Resetting watchdog timer.");

    dev["nodered_watchdog"]["timer"] = 300; // Сбрасываем таймер на 5 минут

    }

    });

    // Правило, которое срабатывает, когда таймер истекает

    defineRule("rule_leak_protection_failsafe", {

    // Выполняется, когда таймер nodered_watchdog досчитал до нуля

    when: function (value, devName, cellName) {

    return devName === "nodered_watchdog" && cellName === "timer" && value === 0;

    },

    // Действие: закрыть клапан воды

    then: function (value, devName, cellName) {

    log.error("Node-RED watchdog timed out! Closing water valve as a precaution.");

    // dev["wb-mr6c_35"] - это ID релейного модуля в системе

    // "K10" - это ID элемента управления (контрола) реле

    dev["wb-mr6c_35"]["K10"] = false; // Отправляем команду на выключение

    // Опционально: отправить уведомление администратору через другой канал

    }

    });

    Этот пример демонстрирует мощь двухуровневой архитектуры: Node-RED управляет штатной логикой, а независимый сервис `wb-rules` страхует систему от его отказа.

    ---

    Программная инициализация: Восстановление логики в Node-RED

    После того как аппаратный уровень обеспечил базовую безопасность (Safe-State), задача программного уровня (Node-RED) — корректно восстановить свою работу и привести систему в актуальное рабочее состояние. Этот процесс называется программной инициализацией.

    > 💡 Подсказка: Разделяйте 'Safe-State' (аппаратный уровень) и 'Initial State' (программный). Safe-State — это про безопасность при отказе. Initial State — про восстановление сложной логики после штатной перезагрузки.

    Запуск потока инициализации

    Стандартный и самый надежный способ запустить логику инициализации — использовать узел `Inject`.

  • Добавьте узел `Inject` на холст.
  • Откройте его настройки.
  • Поставьте галочку `Inject once after ... seconds, then`.
  • Установите задержку, например, `15` секунд.
  • Эта задержка критически важна. Она дает время операционной системе полностью загрузиться, а всем необходимым драйверам и сервисам (например, MQTT-брокеру, Modbus-клиенту) — установиться и подключиться к устройствам. Попытка опросить устройства сразу после старта Node-RED, скорее всего, приведет к ошибкам.

    Построение потока инициализации

    Поток инициализации должен выполнить следующие действия:

  • Опросить фактическое состояние устройств: Запросить текущее состояние всех ключевых реле, диммеров, датчиков. Это можно сделать через Modbus, MQTT, KNX и другие протоколы.
  • Обновить переменные контекста: На основе полученных данных установить правильные значения в переменных `flow` и `global` контекста Node-RED. Это особенно важно для логики с состоянием (Stateful Logic), например, для конечных автоматов (FSM).
  • Синхронизировать пользовательский интерфейс: Обновить все элементы на дашборде (Node-RED Dashboard, Grafana), чтобы они отражали реальное, а не "предполагаемое" состояние системы.
  • Пример потока инициализации:
    // Flow: COURSE-01-M07-FLOW01 - System Initialization
    

    // Triggered on Node-RED start

    [Inject: 15s delay]--+-->[Function: Prepare MQTT request]-->[MQTT Out: hi/office/light/get]

    |

    +-->[Function: Prepare Modbus request]-->[Modbus-Read: Thermostat]

    |

    +-->[Function: Set default variables]

    Пример `msg` для запроса состояния по MQTT:

    Узел `Function: Prepare MQTT request` может формировать вот такое сообщение:

    // Этот поток запускается один раз при старте Node-RED
    

    // Он нужен, чтобы запросить актуальное состояние у всех устройств

    // и привести внутренние переменные и UI в соответствие.

    msg.topic = 'hi/system/request_state';

    // Контракт сообщения для запроса состояний

    msg.payload = {

    "requester": "nodered-init-flow",

    "timestamp": Date.now(),

    "targets": ["all"] // Запросить состояние у всех, кто слушает этот топик

    };

    // Устанавливаем флаг retain=false, т.к. этот запрос актуален только в момент запуска

    msg.retain = false;

    node.status({fill:"blue",shape:"dot",text:"Requesting all states"});

    return msg;

    Устройства, получив такое сообщение, должны опубликовать свое текущее состояние в свои `state` топики (например, `hi/office/light/state`). Другой поток в Node-RED, подписанный на эти топики, обновит переменные и интерфейс.

    ---

    Резюме: Двухуровневая модель надёжности

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

    Уровень 1: Аппаратный 'Safe-State' (Контроллер) Уровень 2: Программная инициализация (Node-RED)

    Только совместное применение этих двух подходов позволяет создавать системы автоматизации, которые являются не просто "умными", но и по-настояшему надежными и безопасными, соответствуя высоким стандартам профессионального внедрения.

    Что дальше

    Теперь, когда вы понимаете теоретические основы и практические методы обеспечения отказоустойчивости, вы готовы применить эти знания на практике. В следующих лабораторных работах вы самостоятельно настроите 'Safe-State' для релейного модуля и создадите поток инициализации в Node-RED для комплексного сценария управления освещением и климатом.