Обработка данных в реальном времени на контроллере
COURSE-16-M03-L02 — Обработка данных в реальном времени на контроллере
Введение в обработку на лету (Real-Time Processing)
Обработка данных в реальном времени — это способность системы принимать, анализировать и реагировать на события мгновенно, в момент их возникновения. В отличие от пакетной обработки, где данные сначала накапливаются, а затем обрабатываются по расписанию (например, формирование отчета по энергопотреблению за сутки), обработка в реальном времени является основой для всех интерактивных систем автоматизации.
На платформе HI эта задача решается непосредственно на контроллере. Это называется обработкой на краю (Edge Computing). Контроллер не просто собирает данные для отправки в облако, а самостоятельно выполняет логику и принимает решения.
- Пример пакетной обработки: Сбор показаний счетчика электроэнергии и отправка отчета в 1С раз в месяц.
- Пример обработки в реальном времени: Датчик движения обнаружил человека в коридоре, и контроллер немедленно (в течение долей секунды) включает реле освещения.
💡 Ключевая концепция: Вся логика в Node-RED построена на событийно-ориентированной модели. Потоки (flows) не работают постоянно, а "спят", ожидая входящего сообщения (события). Как только сообщение поступает от датчика, таймера или другого источника, поток активируется, выполняет логику и снова переходит в режим ожидания. Это обеспечивает высокую эффективность и низкое потребление ресурсов контроллера.
Архитектура обработки данных на контроллере HI
Забудьте о сложных облачных платформах типа Apache Kafka или AWS IoT для базовых задач. 99% сценариев автоматизации на объекте реализуются в рамках трехуровневой архитектуры непосредственно на контроллере HI.
Это "органы чувств" вашей системы. Данные поступают в Node-RED от физических интерфейсов и протоколов контроллера:
* Универсальные входы: Сигналы от кнопок, выключателей ("сухой контакт"), герконов.
* Шина 1-Wire: Показания с датчиков температуры DS18B20.
* Шина RS-485: Данные с промышленных датчиков, счетчиков, модулей ввода-вывода по протоколу Modbus RTU.
* Сеть TCP/IP: Сообщения по протоколу MQTT, команды по HTTP, данные от устройств по Modbus TCP.
* Внутренние события: Срабатывание таймеров, системные события.
Это "мозг" системы. Здесь входящие сообщения преобразуются, анализируются и на их основе принимаются решения. Для этого используются стандартные узлы Node-RED:
* `Switch`: Маршрутизация сообщений в зависимости от их содержимого (например, если `msg.payload.value > 25`, отправить на ветку "Включить кондиционер").
* `Function`: Написание сложной логики на JavaScript. Здесь реализуются вычисления, валидация и формирование сообщений по контракту.
* `Change`: Простое изменение, установка или удаление свойств сообщения без написания кода.
* `Trigger`: Формирование последовательности действий (например, "после получения команды включить свет, подождать 10 минут и выключить").
Это "руки" вашей системы. После принятия решения контроллер выполняет действие:
* Релейные выходы: Включение/выключение освещения, розеток, управление клапанами и приводами.
* Шина DALI: Управление яркостью и цветом светильников.
* Сеть TCP/IP: Отправка статуса в MQTT, запись данных в локальную базу данных MySQL для истории, отправка уведомлений.
* Визуальный статус: Обновление статуса узла в редакторе Node-RED для быстрой диагностики (`node.status`).
Практический пример: Реализация климат-контроля на Node-RED
Давайте создадим логику простого термостата, который поддерживает температуру в помещении в заданном диапазоне. Это классическая задача обработки данных в реальном времени.
Задача: Поддерживать температуру между 22°C (уставка `setpoint_min`) и 24°C (`setpoint_max`). Если температура падает ниже 22°C, включить обогреватель (реле 1). Если поднимается выше 24°C, выключить обогреватель. Необходимые компоненты:- Датчик температуры DS18B20, подключенный к 1-Wire входу контроллера.
- Обогреватель, подключенный к реле №1 контроллера.
Шаг 1: Схема потока (Flow Diagram)
Это пример использования паттерна "Конечный автомат" (Finite State Machine - FSM), где система может находиться в двух состояниях: `IDLE` (ожидание) и `HEATING` (нагрев).
// FLOW-CLIMATE-001: Simple Thermostat Logic
// Уровень 1: Сбор данных
[1-Wire In: Temp Sensor] --(msg)--> [Function: Thermostat FSM] --+-- (msg to relay ON) --> [Relay Out: Heater]
|
+-- (msg to relay OFF)--> [Relay Out: Heater]
|
+-- (no change) --> [null]
// Уровень 2: Обработка ошибок
[Catch: All Nodes] --> [Function: Format Error] --> [Log to MySQL]
Шаг 2: Контракт сообщения
Чтобы логика была предсказуемой, определим стандартный формат сообщения от датчика.
// Сообщение, которое мы ожидаем от узла 1-Wire
// msg.payload должен содержать числовое значение температуры
// Например: 23.5
Шаг 3: Логика в узле `Function` ("Thermostat FSM")
Это сердце нашей системы. Мы будем использовать контекст потока (`flow context`) для хранения текущего состояния обогревателя.
// Получаем текущую температуру из входящего сообщения
const currentTemp = msg.payload;
// Задаем уставки. В реальном проекте их лучше хранить в контексте
// или получать по MQTT, чтобы можно было менять без перезагрузки потока.
const setpoint_min = 22.0;
const setpoint_max = 24.0;
// Получаем текущее состояние обогревателя из контекста потока.
// Если состояния нет (первый запуск), считаем, что он выключен.
let heaterState = flow.get("heaterState") || "OFF";
// --- Логика Конечного Автомата (FSM) ---
// Если сейчас идет нагрев (состояние HEATING)
if (heaterState === "HEATING") {
// и температура достигла верхней границы,
if (currentTemp >= setpoint_max) {
// то выключаем обогреватель.
heaterState = "OFF";
flow.set("heaterState", heaterState); // Сохраняем новое состояние
node.status({fill:"blue", shape:"dot", text:`Idle at ${currentTemp}°C`});
// Возвращаем сообщение для узла реле
return { payload: false }; // false для выключения
}
}
// Если сейчас обогреватель выключен (состояние IDLE)
else { // heaterState === "OFF"
// и температура упала ниже нижней границы,
if (currentTemp < setpoint_min) {
// то включаем обогреватель.
heaterState = "HEATING";
flow.set("heaterState", heaterState); // Сохраняем новое состояние
node.status({fill:"red", shape:"dot", text:`Heating at ${currentTemp}°C`});
// Возвращаем сообщение для узла реле
return { payload: true }; // true для включения
}
}
// Если никаких действий не требуется, обновляем статус и останавливаем поток.
node.status({fill:"green", shape:"dot", text:`OK: ${currentTemp}°C. State: ${heaterState}`});
return null; // Ничего не отправляем дальше
⚠️ Важно: Использование гистерезиса (разницы между `setpoint_min` и `setpoint_max`) обязательно! Если использовать одну уставку (например, 23°C), реле будет постоянно щелкать (дребезг) при колебаниях температуры около этого значения, что приведет к его быстрому износу.
Лабораторная работа №1 (COURSE-16-M03-LAB03)
Название: "Реакция на событие: автоматическое освещение по кнопке" Цель: Создать поток, который включает и выключает реле освещения при нажатии на настенный выключатель (кнопку без фиксации). Скелет потока:`[Input: Dry Contact]` -> `[Function: Toggle Logic]` -> `[Output: Relay]`
Задание:- [ ] При нажатии на кнопку свет включается.
- [ ] При повторном нажатии свет выключается.
- [ ] В редакторе Node-RED под узлом `Function` отображается актуальный статус.
- [ ] Поток использует `flow.context` для хранения состояния.
- [ ] Присутствует обработка ошибок с помощью узла `Catch`.
- 3 балла (неудовлетворительно): Поток не работает или работает нестабильно.
- 4 балла (удовлетворительно): Поток работает, но не использует контекст (например, считывает состояние реле перед изменением, что создает лишнюю нагрузку) или отсутствует обработка ошибок.
- 5 баллов (отлично): Поток работает корректно, использует `flow.context`, имеет информативный статус и комментарии. Присутствует базовая обработка ошибок.
Лабораторная работа №2 (COURSE-16-M03-LAB04)
Название: "Конечный автомат: базовый климат-контроль" Цель: Реализовать на практике логику термостата, описанную в уроке. Скелет потока:`[Inject: Timer]` -> `[Input: 1-Wire Sensor]` -> `[Function: Thermostat FSM]` -> `[Output: Relay]`
Задание:- [ ] Реле включается, когда температура падает ниже `setpoint_min`.
- [ ] Реле выключается, когда температура поднимается выше `setpoint_max`.
- [ ] Реле не меняет состояние, когда температура находится между уставками.
- [ ] Узел `Function` корректно отображает текущий статус (HEATING/IDLE) и температуру.
- [ ] Ошибки чтения датчика фиксируются узлом `Catch`.
- [ ] (Опционально) Уставки могут быть изменены через MQTT.
- 3 балла (неудовлетворительно): Логика не работает, реле "дребезжит" или не реагирует.
- 4 балла (удовлетворительно): Логика работает, но не используется FSM (например, через два узла `Switch`), что усложняет читаемость, или отсутствует обработка ошибок.
- 5 баллов (отлично): Реализован конечный автомат (FSM) в узле `Function` с использованием `flow.context`. Поток надежен и легко читаем. Присутствует обработка ошибок.
Тест модуля (COURSE-16-M03-QUIZ)
a) Обработка данных в облаке Amazon.
b) Обработка данных непосредственно на IoT-контроллере.
c) Хранение данных в локальной базе MySQL.
d) Шифрование данных перед отправкой.
a) Пакетная.
b) Запрос-ответ.
c) Событийно-ориентированная.
d) Многопоточная.
a) Для написания сложной логики на JavaScript.
b) Для маршрутизации сообщений в зависимости от их содержимого.
c) Для включения и выключения реле.
d) Для хранения переменных.
a) Для повышения точности измерения.
b) Для предотвращения частого переключения реле (дребезга).
c) Для экономии электроэнергии.
d) Это требование протокола Modbus.
a) В глобальном контексте (`global.context`).
b) В контексте потока (`flow.context`).
c) Внутри `msg.payload`.
d) В текстовом файле.
a) Контракт сообщения.
b) Конечный автомат (FSM).
c) Обработка ошибок.
d) Визуальный статус.
a) Вызывает ошибку.
b) Отправляет пустое сообщение.
c) Останавливает дальнейшее движение сообщения по потоку.
d) Перезагружает контроллер.
a) Только числовое значение.
b) JSON-объект со структурой `{ "value": ..., "source": ..., "ts": ... }`.
c) Строку "ON" или "OFF".
d) XML-структуру.
a) Для запуска потока по расписанию.
b) Для перехвата и обработки ошибок, возникающих в других узлах на вкладке.
c) Для проверки JSON-схемы.
d) Для отправки HTTP-запросов.
a) Включает реле.
b) Выключает реле.
c) Ничего не делает.
d) Отправляет сигнал тревоги.
(Правильные ответы: 1-b, 2-c, 3-b, 4-b, 5-b, 6-b, 7-c, 8-b, 9-b, 10-b)Мини-runbook "Если не работает"
📋 Проблема: Реле не реагирует на команды из Node-RED.
📋 Проблема: Узел `1-Wire In` или `Modbus-Read` выдает ошибку или не возвращает данные.
📋 Проблема: Логика термостата работает некорректно (реле щелкает слишком часто).