Главная → Академия → Основы Интернета вещей и практическое применение → Интеграция с внешними системами по MQTT: управление по погодным данным

Интеграция с внешними системами по 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 поток, который:

  • Подписывается на топик с погодными данными.
  • Извлекает (парсит) из входящего JSON-сообщения значение температуры.
  • Сравнивает температуру с пороговым значением (+10°C).
  • Включает или выключает "виртуальное реле" подогрева и четко отображает его текущее состояние в редакторе Node-RED.
  • 3. Необходимое оборудование и ПО

    • Рабочее место с доступом к контроллеру HI.
    • Стабильное подключение контроллера к сети Интернет для доступа к публичному MQTT-брокеру.
    • Веб-браузер (Chrome, Firefox) для доступа к интерфейсу Node-RED.
    • Учетные данные для входа в редактор Node-RED.

    4. Пошаговое выполнение

    Шаг 1: Создание потока и подписка на MQTT-топик

  • Откройте редактор Node-RED. Создайте новый поток (flow) и переименуйте его в `M02-LAB02-Climate-Control`.
  • Из палитры узлов перетащите на рабочую область узел `mqtt in`.
  • Дважды кликните по узлу `mqtt in` для его настройки:
  • * 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: Анализ и отладка входящих данных

    Прежде чем строить логику, нужно убедиться, что мы получаем данные и понять их структуру.

  • Перетащите узел `debug` на рабочую область.
  • Соедините выход узла `mqtt in` со входом узла `debug`.
  • Нажмите `Deploy`.
  • Перейдите на вкладку отладки (иконка жука справа). В течение 1-2 минут вы должны увидеть входящие сообщения. Они будут иметь следующую структуру (это наш "входящий контракт сообщения"):
  • {
    

    "location": "Moscow",

    "temperature": 12.5,

    "humidity": 78,

    "pressure": 1012,

    "ts": 1678886400000

    }

    ⚠️ Важно: Если сообщения не приходят, проверьте подключение контроллера к интернету и правильность настроек MQTT-брокера.

    Шаг 3: Реализация логики управления (узел Switch)

    Теперь, когда мы получаем данные, нужно реализовать логику принятия решений.

  • Удалите связь между `mqtt in` и `debug`.
  • Перетащите узел `switch` из палитры и разместите его после узла `mqtt in`.
  • Дважды кликните по узлу `switch` для настройки:
  • * Name: `Температура < 10°C?`

    * Property: `msg.payload.temperature` (указываем путь к значению температуры внутри объекта).

    * Правило 1: `is less than` (`<`) -> `number` -> `10`.

    * Правило 2: `otherwise` (`иначе`).

    * Нажмите `Done`.

    Теперь узел `switch` имеет два выхода:

    • Верхний (1): Сообщение пойдет по этому пути, если `temperature < 10`.
    • Нижний (2): Сообщение пойдет по этому пути во всех остальных случаях.

    Шаг 4: Эмуляция исполнительного устройства (виртуальное реле)

    Мы создадим узел, который будет имитировать работу реле и наглядно показывать свое состояние.

  • Перетащите два узла `function` на рабочую область.
  • Подключите верхний выход (1) узла `switch` к первому узлу `function`.
  • Подключите нижний выход (2) узла `switch` ко второму узлу `function`.
  • Настройте первый узел `function` (Включить подогрев):
  • * 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;

  • Настройте второй узел `function` (Выключить подогрев):
  • * 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;

  • Подключите выходы обоих узлов `function` к одному узлу `debug`, чтобы видеть результат работы логики.
  • Нажмите `Deploy`.
  • Теперь под узлами `ВКЛ: Подогрев` и `ВЫКЛ: Подогрев` будет отображаться их последнее состояние, имитируя работу реального реле.

    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`.

  • Добавьте на холст два узла `Inject`.
  • Настройте первый `Inject` (Тест: Холодно):
  • * Payload: `JSON`

    * Значение: `{"temperature": 5.5}`

    * Name: `Тест: t = 5.5°C`

  • Настройте второй `Inject` (Тест: Тепло):
  • * Payload: `JSON`

    * Значение: `{"temperature": 15.2}`

    * Name: `Тест: t = 15.2°C`

  • Подключите выходы обоих узлов `Inject` ко входу узла `switch`.
  • Нажмите `Deploy`.
  • 📋 Тест-план:
  • Нажмите на узел `Тест: t = 5.5°C`.
  • * Ожидаемый результат: Под узлом `ВКЛ: Подогрев` появился статус `ВКЛЮЧЕНО`. В окне отладки появилось сообщение с `state: "ON"`.

  • Нажмите на узел `Тест: t = 15.2°C`.
  • * Ожидаемый результат: Под узлом `ВЫКЛ: Подогрев` появился статус `ВЫКЛЮЧЕНО`. В окне отладки появилось сообщение с `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` не появляются в отладке.
    * Решение 1: Проверьте, что контроллер имеет доступ в Интернет. Попробуйте `ping broker.hivemq.com` из терминала контроллера.

    * Решение 2: Проверьте правильность адреса брокера (`broker.hivemq.com`), порта (`1883`) и имени топика (`hi-academy/weather/station-01`). Убедитесь в отсутствии опечаток.

    * Решение 3: Узел `mqtt in` может показывать статус "connecting" или "disconnected". Наведите на него курсор, чтобы увидеть причину.

    • Проблема: Узел `switch` не работает, все сообщения идут по выходу "otherwise".
    * Решение: Убедитесь, что в узле `switch` вы указали правильный путь к свойству: `msg.payload.temperature`. Проверьте в `debug`, что после `mqtt in` приходит объект, и в нем действительно есть поле `temperature`. Если `mqtt in` выдает строку, добавьте после него узел `json` для принудительного парсинга.
    • Проблема: После нажатия на тестовый `Inject` возникает ошибка `TypeError: Cannot read property 'temperature' of undefined`.
    * Решение: Убедитесь, что в узле `Inject` выбран тип `JSON`, а не `string`. Если вы отправляете строку, узел `switch` не сможет найти в ней свойство `temperature`.