IoT в промышленности (IIoT): от теории к практике на платформе HI
COURSE-16-M05-L03 — IoT в промышленности (IIoT): от теории к практике на платформе HI
Введение в промышленный IoT (IIoT)
Промышленный интернет вещей (Industrial Internet of Things, IIoT) — это применение технологий IoT для кардинального улучшения производственных и технологических процессов. В отличие от потребительского IoT (умные часы, бытовая техника), IIoT фокусируется на повышении эффективности, надежности и безопасности промышленных систем: от отдельных станков до целых производственных линий и инфраструктурных объектов.
На платформе HI контроллер выступает в роли шлюза и локального центра обработки данных, позволяя реализовать полноценные IIoT-решения для малых и средних промышленных объектов, таких как насосные станции, котельные, системы вентиляции и небольшие производственные участки.
Компоненты IIoT в экосистеме HI
Абстрактные компоненты IIoT находят прямое воплощение в аппаратных и программных возможностях контроллера HI.
- Датчики и исполнительные устройства (The Edge): Это "органы чувств" и "руки" вашей системы.
* Универсальные входы (UI): Для датчиков с выходом "сухой контакт" (аварии, концевые выключатели), аналоговых датчиков 0-10В (давление, уровень), а также цифровых датчиков температуры/влажности (1-Wire).
* Шина RS-485: Для подключения промышленных устройств по протоколу Modbus RTU (счетчики электроэнергии, частотные преобразователи, модули ввода-вывода).
* Шина CAN: Для связи с автомобильным или промышленным оборудованием, требующим высокой скорости и надежности.
* Управление: Встроенные реле контроллера используются для коммутации силовых цепей (включение/выключение двигателей, насосов, освещения) через контакторы и пускатели.
- Системы сбора и управления (The Fog/Local Control): Это "мозг" системы, расположенный непосредственно на объекте.
* Функция ПЛК (PLC): Для критически важных, детерминированных задач контроллер HI использует выделенное ядро ARM32, обеспечивающее предсказуемое время реакции и переход в безопасное состояние (safe-state) при сбоях основной системы.
* Локальное хранилище: Встроенная база данных MySQL и EEPROM используются для надежного хранения сценариев, уставок и журнала событий (audit log), обеспечивая автономность объекта даже при потере связи с "облаком".
- Облачные технологии и связь (The Cloud): Обеспечивают удаленный мониторинг, управление и аналитику.
* Резервные каналы: Опциональные модули GSM/LTE обеспечивают передачу данных при отказе основного интернет-канала.
- Системы безопасности:
* Контроль доступа: Защита интерфейса Node-RED паролем, разграничение прав доступа.
* Физическая безопасность: Установка контроллера в запираемый электротехнический шкаф.
Практический пример: Мониторинг и управление небольшим насосным агрегатом
Рассмотрим типовую задачу для небольшого промышленного объекта — мониторинг состояния и базовое управление насосом, который откачивает воду из резервуара.
Задача:- Контроллер HI.
- Однофазный контактор для управления двигателем насоса.
- Modbus-счетчик электроэнергии (например, WB-MAP12E), установленный на линии питания насоса, для измерения тока.
- Цифровой датчик температуры DS18B20 в гильзе, закрепленный на корпусе двигателя.
Схема подключения (WIRING-PUMP-001)
📋 Чеклист подключения:
//=============== WIRING-PUMP-001: Pump Monitoring & Control ===============
// LEGEND:
// CTRL:HI-Core - Контроллер HI
// CONTACTOR-01 - Силовой контактор насоса
// PUMP-MOTOR-01 - Двигатель насоса
// METER-MODBUS-01- Modbus-счетчик (Slave ID: 15)
// T-SENS-01 - Датчик температуры DS18B20
// Relay Control (Contactor)
[CTRL:HI-Core] (CONTACTOR-01)
RL-10 (C) ---- ~L~ (от автомата)
RL-10 (NO) --- A1 (катушка контактора)
A2 ---- ~N~
// Power Line
~L~ (от автомата) --- (METER-MODBUS-01) --- 1/L1 (CONTACTOR-01) --- (PUMP-MOTOR-01)
~N~ --------------------------------------- 3/L2 (CONTACTOR-01) --- (PUMP-MOTOR-01)
// Modbus RTU (RS-485) Connection
[CTRL:HI-Core] (METER-MODBUS-01)
RS485-1 (A) ----A---- (зеленый) ---- A
RS485-1 (B) ----B---- (белый) ------ B
RS485-1 (GND) --GND-- (черный) ----- GND
// 1-Wire Sensor Connection
[CTRL:HI-Core] (T-SENS-01: DS18B20)
UI-05 (Data) --- (желтый) --------- Data
GND ---------- (черный) --------- GND
+5V ------------ (красный) -------- VDD (если не паразитное питание)
Логика в Node-RED (FLOW-PUMP-MONITOR-001)
ASCII-схема потока:// Flow: Опрос датчиков
[Inject: 10s] -> [Modbus-Getter: Ток] -> [Function: Формат] -> |
|-> [Join] -> [Function: Проверка] -> [MQTT Out]
[Inject: 30s] -> [ds18b20 in: Темп.] -> [Function: Формат] -> |
// Flow: Управление
[MQTT In: cmd] -> [Switch: ON/OFF] -> [Function: Команда] -> [GPIO Out: Реле] -> [MQTT Out: Статус]
// Flow: Обработка ошибок
[Catch: All] -> [Function: Лог ошибки] -> [MQTT Out: /errors]
Реализация ключевых узлов:
* Настраивается на опрос регистра тока с устройства с `Unit-ID: 15`.
* 💡 Изучите карту регистров вашего счетчика, чтобы найти правильный адрес. Например, для WB-MAP12E ток фазы 1 — это регистр `128`.
* Критически важно: Все данные в системе должны соответствовать единому контракту сообщения.
* Этот узел преобразует "сырые" данные от датчиков в стандартный JSON-формат.
// Пример для узла после Modbus-Getter
// msg.payload от узла = { data: [156], buffer: <...> }
// 156 -> 1.56 A (согласно документации на счетчик)
let currentValue = msg.payload.data[0] / 100;
// Формируем сообщение по контракту
msg.payload = {
value: currentValue,
unit: "A",
source: "METER-MODBUS-01",
ts: Date.now()
};
msg.topic = "telemetry/pump-01/current";
// Паттерн "Визуальный статус"
node.status({fill:"green", shape:"dot", text: `Ток: ${currentValue} A`});
return msg;
* Этот узел реализует логику конечного автомата (FSM). Он получает объединенные данные о токе и температуре и принимает решение.
* Состояние насоса (`ON`/`OFF`) хранится в переменной контекста (`flow.pump_state`).
// Получаем данные из контекста
let current = msg.payload.current; // Предполагаем, что узел Join собрал данные
let temperature = msg.payload.temperature;
let pumpState = flow.get("pump_state") || "OFF";
const MAX_CURRENT = 5.0; // Аварийный ток, А
const MAX_TEMP = 85.0; // Аварийная температура, °C
if (pumpState === "ON" && (current > MAX_CURRENT || temperature > MAX_TEMP)) {
// АВАРИЯ! Отключаем насос
node.warn(`Аварийное отключение насоса! Ток: ${current}A, Темп: ${temperature}°C`);
// Отправляем команду на отключение реле
// Это сообщение пойдет на узел управления реле
return { payload: "OFF", topic: "commands/pump-01/set" };
}
// Если все в норме, просто пропускаем сообщение дальше (на MQTT)
// В реальной системе здесь будет более сложная логика
return null;
* На вкладке должен быть узел `Catch`, настроенный на перехват ошибок со всех узлов.
* Он ловит ошибки связи (например, таймаут Modbus), ошибки в коде и т.д.
* Пойманная ошибка форматируется и отправляется в специальный MQTT-топик `telemetry/system/errors` и/или пишется в локальную MySQL базу для аудита.
План тестирования и сдачи объекта
После монтажа и настройки необходимо провести комплексное тестирование.
---
Лабораторные работы
COURSE-16-M05-LAB01: Настройка мониторинга промышленного датчика
- Цель: Настроить чтение данных с Modbus-устройства (счетчика) и отправку телеметрии в MQTT в стандартизированном формате.
- Скелет: Предоставляется поток с узлами `Inject` и `Modbus-Getter`. Инженеру необходимо добавить узел `Function` для валидации и форматирования данных согласно контракту, узел `Status` для визуализации и узел `MQTT Out` для отправки.
- Рубрика оценивания:
* (40%) Узел `Function` корректно преобразует данные в JSON-формат по контракту сообщения.
* (20%) Узел `Status` отображает актуальное значение и единицу измерения.
* (10%) Данные успешно публикуются в заданный MQTT-топик.
COURSE-16-M05-LAB02: Реализация логики аварийной защиты
- Цель: Добавить к потоку из LAB01 логику автоматического отключения оборудования при выходе параметра за допустимые пределы.
- Скелет: Предоставляется поток из LAB01. Инженеру необходимо добавить узел `Function` или `Switch` для проверки порогового значения, узел `GPIO Out` для управления реле и реализовать обратную связь о состоянии в MQTT.
- Рубрика оценивания:
* (30%) При превышении порога команда на отключение корректно отправляется на узел `GPIO Out`.
* (20%) После отключения в MQTT-топик статуса отправляется сообщение `OFF`.
* (10%) В поток добавлен узел `Catch` для перехвата возможных ошибок.
Квиз по модулю
COURSE-16-M05-QUIZ
* a) MQTT
* b) CAN
* c) Modbus RTU
* d) DALI
* a) Для измерения тока насоса.
* b) Для коммутации силовой цепи двигателя насоса с помощью слаботочного сигнала от реле контроллера.
* c) Для защиты от короткого замыкания.
* d) Для преобразования протоколов.
* a) Лицензионное соглашение на использование узлов.
* b) Стандартизированный JSON-формат объекта `msg.payload` для обеспечения предсказуемости данных.
* c) Документ, описывающий физические подключения.
* d) Настройки MQTT-брокера.
* a) `Inject`
* b) `Switch`
* c) `Catch`
* d) `Link Out`
* a) С обеих сторон (у контроллера и у датчика).
* b) Только со стороны датчика.
* c) Только со стороны контроллера.
* d) Не подключается совсем.
* a) В глобальной переменной (`global.context`).
* b) В `msg.payload`.
* c) В переменной потока (`flow.context`) с настроенным персистентным хранилищем (filesystem или MySQL).
* d) В имени узла.
* a) Перепутаны провода A и B.
* b) Адрес регистра в документации (например, 40001) не совпадает с адресом в запросе (который должен быть 0).
* c) Не установлен терминирующий резистор.
* d) Неверно указан Slave ID.
* a) Для прямого управления реле.
* b) Для опроса Modbus-устройств.
* c) Для легковесной и надежной передачи телеметрии от контроллера в облако или на пульт диспетчера.
* d) Для программирования логики контроллера.
* a) Паттерн "Конечный автомат".
* b) Паттерн "Визуальный статус" с использованием `node.status()`.
* c) Паттерн "Обработка ошибок".
* d) Паттерн "Субпоток".
* a) Неправильный формат данных в узле `Function`.
* b) Физическая проблема на линии RS-485 (обрыв, неверный Slave ID, отсутствие питания у устройства).
* c) Ошибка в MQTT-брокере.
* d) Недостаточно оперативной памяти у контроллера.
Мини-runbook: "Что делать, если не работает?"
- Проблема: Данные с Modbus-устройства не приходят (ошибка `Timeout`).
1. Проверьте физическое подключение: не перепутаны ли клеммы A/B? Есть ли питание на устройстве?
2. Проверьте настройки в узле `Modbus-Getter`: правильный ли `Unit-ID` (Slave ID)? Правильные ли параметры порта (скорость, четность)?
3. Проверьте шину: есть ли на концах терминаторы 120 Ом? Нет ли на шине устройств с одинаковыми адресами?
- Проблема: Данные приходят, но они некорректны (огромные числа, неверный знак).
1. Перечитайте документацию на устройство. Скорее всего, вы неверно интерпретируете формат данных (например, значение нужно делить на 100, или это 32-битное число с другим порядком байт).
2. Проверьте на ошибку "Off-by-one": для регистра `40001` в запросе должен быть адрес `0`.
- Проблема: Реле щелкает, но насос не включается.
1. Проверьте силовую цепь: есть ли напряжение на входе контактора?
2. "Прозвоните" катушку контактора. Возможно, она неисправна.
3. Убедитесь, что автомат, питающий насос, включен.
- Проблема: Поток Node-RED остановился с ошибкой `TypeError` в узле `Function`.
1. Подключите узел `Debug` к выходу предыдущего узла. Посмотрите, в каком формате приходят данные.
2. Скорее всего, вы пытаетесь обработать свойство, которого нет в `msg.payload` (например, `msg.payload.data[0]`, когда `msg.payload.data` не является массивом). Добавьте в код проверки: `if (msg.payload && msg.payload.data) {...}`.