Интеграция с внешними системами по MQTT: управление по погодным данным
Вот доработанная версия урока, соответствующая стандартам Академии HI.
COURSE-16-M02-LAB02 — Интеграция с внешними системами по MQTT: управление по погодным данным
1. Цель лабораторной работы
Данная лабораторная работа развивает навыки, полученные в предыдущих модулях, и знакомит инженера с реальной задачей интеграции. Вместо эмуляции данных, мы будем получать, обрабатывать и реагировать на информацию из внешней системы по протоколу MQTT. По завершении этого задания инженер сможет подключаться к MQTT-брокерам, обрабатывать входящие JSON-сообщения, применять условную логику для принятия решений и управлять состоянием системы.
Ключевые навыки:- Настройка и использование узла `mqtt in` для подписки на топики.
- Использование узла `json` для парсинга текстовых данных в структурированный объект.
- Применение узла `switch` для реализации условной логики (маршрутизации потока).
- Создание "виртуального устройства" с помощью узла `function` для отработки логики и визуализации состояния через `node.status`.
- Обработка ошибок парсинга и сбоев связи, применение паттерна "Обработка ошибок".
2. Сценарий
Вы — инженер по автоматизации, которому поручено реализовать базовую климатическую систему для небольшой оранжереи на объекте. Основная задача — автоматически включать систему подогрева грунта, если температура наружного воздуха, получаемая от внешней метеостанции, опускается ниже +10°C.
Данные от метеостанции публикуются на общедоступный MQTT-брокер. Ваша задача — создать в среде Node-RED на контроллере HI поток, который:
3. Необходимое оборудование и ПО
- Рабочее место с доступом к контроллеру HI.
- Стабильное подключение контроллера к сети Интернет для доступа к публичному MQTT-брокеру.
- Веб-браузер (Chrome, Firefox) для доступа к интерфейсу Node-RED.
- Учетные данные для входа в редактор Node-RED.
4. Пошаговое выполнение
Шаг 1: Создание потока и подписка на MQTT-топик
* Server: Нажмите на иконку карандаша для добавления нового брокера.
* Name: `HiveMQ Public Broker`
* Server: `broker.hivemq.com`
* Port: `1883`
* Остальные настройки оставьте по умолчанию. Нажмите `Add`.
* Topic: Укажите топик, на который мы будем подписываться: `hi-academy/weather/station-01`.
💡 Примечание: Это специальный учебный топик, в который периодически отправляются данные в нужном нам формате.
* QoS: `0`
* Output: `a parsed JSON object`. Это позволит Node-RED автоматически попытаться преобразовать входящую строку в JSON.
* Name: `Погода: Внешняя станция`
* Нажмите `Done`.
Шаг 2: Анализ и отладка входящих данных
Прежде чем строить логику, нужно убедиться, что мы получаем данные и понять их структуру.
{
"location": "Moscow",
"temperature": 12.5,
"humidity": 78,
"pressure": 1012,
"ts": 1678886400000
}
⚠️ Важно: Если сообщения не приходят, проверьте подключение контроллера к интернету и правильность настроек MQTT-брокера.
Шаг 3: Реализация логики управления (узел Switch)
Теперь, когда мы получаем данные, нужно реализовать логику принятия решений.
* Name: `Температура < 10°C?`
* Property: `msg.payload.temperature` (указываем путь к значению температуры внутри объекта).
* Правило 1: `is less than` (`<`) -> `number` -> `10`.
* Правило 2: `otherwise` (`иначе`).
* Нажмите `Done`.
Теперь узел `switch` имеет два выхода:
- Верхний (1): Сообщение пойдет по этому пути, если `temperature < 10`.
- Нижний (2): Сообщение пойдет по этому пути во всех остальных случаях.
Шаг 4: Эмуляция исполнительного устройства (виртуальное реле)
Мы создадим узел, который будет имитировать работу реле и наглядно показывать свое состояние.
* Name: `ВКЛ: Подогрев`
* Код на вкладке `On Message`:
// Паттерн "Визуальный статус"
node.status({fill:"green", shape:"dot", text:"ВКЛЮЧЕНО"});
// Формируем сообщение для аудита/логирования
msg.payload = {
action: "SET_HEATING",
state: "ON",
reason: "Temperature below threshold",
triggerValue: msg.payload.temperature, // Сохраняем исходное значение
ts: Date.now()
};
// ID сценария для логирования
msg.topic = "SCN-CLIMATE-001";
return msg;
* Name: `ВЫКЛ: Подогрев`
* Код на вкладке `On Message`:
// Паттерн "Визуальный статус"
node.status({fill:"red", shape:"ring", text:"ВЫКЛЮЧЕНО"});
// Формируем сообщение для аудита/логирования
msg.payload = {
action: "SET_HEATING",
state: "OFF",
reason: "Temperature is normal",
triggerValue: msg.payload.temperature,
ts: Date.now()
};
// ID сценария для логирования
msg.topic = "SCN-CLIMATE-001";
return msg;
Теперь под узлами `ВКЛ: Подогрев` и `ВЫКЛ: Подогрев` будет отображаться их последнее состояние, имитируя работу реального реле.
5. Схема итогового потока (Flow Diagram)
FLOW-INTEG-MQTT-008: Greenhouse Heating Control
+--------------------------+
[mqtt in: hi-academy/...] ---> | switch: temp < 10°C? |
+--------------------------+
| (1) | (2)
| temp < 10 | otherwise
v v
+------------------+ +-------------------+
| function: ВКЛ | | function: ВЫКЛ |
| node.status(ON) | | node.status(OFF) |
+------------------+ +-------------------+
| |
+--------+---------+
|
v
+-------------+
| debug: Log |
+-------------+
6. Проверка и тестирование
Чтобы не ждать реальных данных, можно протестировать логику с помощью узла `Inject`.
* Payload: `JSON`
* Значение: `{"temperature": 5.5}`
* Name: `Тест: t = 5.5°C`
* Payload: `JSON`
* Значение: `{"temperature": 15.2}`
* Name: `Тест: t = 15.2°C`
* Ожидаемый результат: Под узлом `ВКЛ: Подогрев` появился статус `ВКЛЮЧЕНО`. В окне отладки появилось сообщение с `state: "ON"`.
* Ожидаемый результат: Под узлом `ВЫКЛ: Подогрев` появился статус `ВЫКЛЮЧЕНО`. В окне отладки появилось сообщение с `state: "OFF"`.
7. Усложнения и дополнительные задания (для самостоятельной работы)
- Гистерезис: Доработайте логику, чтобы избежать частого переключения реле на границе порога (например, 9.9°C -> 10.1°C -> 9.9°C). Включение должно происходить при < 10°C, а выключение — при > 12°C. 💡 Подсказка: Используйте переменные контекста (`flow.context`) для хранения текущего состояния.
- Контроль связи: Добавьте узел `trigger` после `mqtt in`. Если в течение 5 минут не приходит ни одного сообщения, поток должен генерировать аварийное сообщение (например, "Потеряна связь с метеостанцией") и выключать подогрев для безопасности.
- Централизованная обработка ошибок: Добавьте узел `catch` на вкладку, настройте его на перехват ошибок со всех узлов. Подключите к нему узел `debug` с именем "ОШИБКИ". Спровоцируйте ошибку, отправив в `switch` некорректный JSON (без поля `temperature`). Убедитесь, что ошибка поймана.
8. Рубрика оценивания (10 баллов)
- (2 балла) Узел `mqtt in` корректно настроен на публичный брокер и учебный топик. Данные успешно принимаются.
- (2 балла) Узел `switch` корректно настроен для проверки свойства `msg.payload.temperature` и имеет два выхода для порогового значения и "иначе".
- (3 балла) Созданы два узла `function` для эмуляции "виртуального реле". В коде используется `node.status` для наглядной индикации состояния (ВКЛ/ВЫКЛ) с разными цветами/формами.
- (1 балл) В узлах `function` формируется стандартизированное сообщение для логирования, содержащее как минимум `action`, `state` и `ts`.
- (1 балл) Весь поток собран корректно, логические связи соответствуют схеме. Поток успешно разворачивается (`Deploy`) без ошибок.
- (1 балл) Инженер может продемонстрировать работу логики с помощью тестовых узлов `Inject`.
9. Мини-runbook «Если не работает»
- Проблема: Сообщения от `mqtt in` не появляются в отладке.
* Решение 2: Проверьте правильность адреса брокера (`broker.hivemq.com`), порта (`1883`) и имени топика (`hi-academy/weather/station-01`). Убедитесь в отсутствии опечаток.
* Решение 3: Узел `mqtt in` может показывать статус "connecting" или "disconnected". Наведите на него курсор, чтобы увидеть причину.
- Проблема: Узел `switch` не работает, все сообщения идут по выходу "otherwise".
- Проблема: После нажатия на тестовый `Inject` возникает ошибка `TypeError: Cannot read property 'temperature' of undefined`.