Углубленное использование нод Debug, Status и Catch для отладки
Введение в расширенную отладку: За пределами msg.payload
В повседневной работе инженер-инсталлятор часто использует ноду Debug для быстрой проверки содержимого сообщений, курсирующих между узлами. В 90% случаев это сводится к выводу `msg.payload`, что позволяет увидеть значение с датчика или результат выполнения функции. Однако такой подход является лишь вершиной айсберга и имеет серьезные ограничения при отладке комплексных, многокомпонентных систем.
Стандартное использование ноды Debug не дает ответов на ключевые диагностические вопросы:
- Маршрут сообщения: Как именно сообщение попало в данный узел? Какой у него был `topic`?
- Контекст сбоя: Если узел `Function` вызвал ошибку, какое именно сообщение послужило причиной?
- Состояние системы: Работает ли в данный момент подключение к MQTT-брокеру или Modbus-шлюзу?
Для перехода от простого "просмотра данных" к полноценной системной диагностике необходимо овладеть тремя фундаментальными инструментами Node-RED, которые выходят за рамки `msg.payload`:
Эти инструменты являются прямым практическим воплощением системного подхода к диагностике, который мы начали рассматривать в предыдущем уроке. Если методология "сверху-вниз" позволяет нам логически сужать область поиска неисправности, то ноды Debug, Status и Catch — это наши "диагностические приборы" на прикладном уровне, позволяющие подтвердить или опровергнуть гипотезы о причинах сбоя. Внедрение этих нод в каждый проект является обязательным требованием для создания по-настоящему надежных и отказоустойчивых систем автоматизации, готовых к сдаче в промышленную эксплуатацию.
---
Глубокое погружение в ноду Debug
Нода Debug — это первый и самый доступный инструмент в арсенале инженера. Однако для эффективной диагностики необходимо научиться использовать ее на 100% ее возможностей.
Настройка для вывода полного объекта сообщения
По умолчанию нода Debug настроена на вывод только свойства `msg.payload`. Чтобы получить полную картину происходящего, необходимо изменить эту настройку.
Теперь при прохождении через эту ноду любого сообщения, на панели отладки справа вы увидите полный, разворачиваемый JSON-объект.
Анализ структуры полного объекта `msg`
Полный объект `msg` содержит гораздо больше полезной информации, чем просто `payload`.
> 📋 Ключевые понятия:
> * _msgid: Уникальный идентификатор сообщения, генерируемый Node-RED. Позволяет отследить путь одного и того же сообщения через несколько нод. Крайне важен для диагностики сложных потоков.
> * topic: Строка, часто используемая для маршрутизации и фильтрации сообщений. Анализ `topic` помогает понять, почему сообщение пошло по той или иной ветке в ноде `Switch`.
> * payload: Полезная нагрузка. То, с чем мы работаем чаще всего.
> * Другие свойства: Ноды могут добавлять в объект `msg` свои собственные свойства. Например, нода `http request` добавляет `msg.statusCode` и `msg.headers`. Нода `Modbus-Read` добавляет `msg.responseBuffer`.
Рассмотрим пример `msg` от ноды `mqtt in` после получения данных с датчика температуры:
{
"_msgid": "a1b2c3d4.5e4f32",
"topic": "telemetry/living_room/temperature",
"payload": "{\"value\": 22.5, \"source\": \"ds18b20-01\", \"ts\": 1678886400000}",
"qos": 1,
"retain": false
}
Анализируя этот объект, мы видим не только полезную нагрузку (`payload`), но и топик, по которому он пришел, и уровень качества обслуживания (QoS). Это позволяет точно понять источник данных.
Вывод отладочной информации в системные логгеры
Помимо вывода на боковую панель, нода Debug может перенаправлять информацию в другие места:
- System Console: Вывод будет направлен в стандартный поток вывода процесса Node-RED. На контроллере HI это можно просмотреть с помощью команды `journalctl -u nodered -f`. Это полезно для долговременного мониторинга, когда веб-интерфейс закрыт.
- Node-RED Log: Специализированный логгер Node-RED (если настроен).
- File: Запись отладочных сообщений напрямую в файл на контроллере. Удобно для сбора данных для последующего "офлайн" анализа.
Практика: Отслеживание пути сообщения
Представим поток, где данные с Modbus-датчика проходят валидацию и отправляются в MQTT.
ASCII-схема:[Modbus Read] --1--> [Debug A] --> [Function: Validate] --2--> [Debug B] --> [MQTT Out]
{
"_msgid": "f9e8d7c6.b5a432",
"payload": {
"data": [ 234 ],
"buffer": ""
},
"topic": "poll-temp-sensor"
}
com {
"_msgid": "f9e8d7c6.b5a432",
"payload": {
"value": 23.4,
"unit": "°C",
"source": "modbus-temp-01"
},
"topic": "telemetry/technical_room/temperature"
}
Обратите внимание, что `_msgid` остался прежним. Это доказывает, что мы наблюдаем за трансформацией одного и того же сообщения. Если бы `_msgid` изменился, это означало бы, что нода `Function` создает новое сообщение, а не модифицирует старое, что тоже является важной диагностической информацией.
---
Нода Status — Пульс вашего потока
Если нода Debug позволяет заглянуть "внутрь" сообщения, то нода Status позволяет наблюдать за состоянием самих узлов. Она является ключевым инструментом для мониторинга здоровья коммуникационных интерфейсов.
Принцип работы
Нода Status не обрабатывает поток сообщений. Вместо этого она подписывается на события изменения статуса от других нод. Каждый раз, когда целевая нода меняет свой визуальный статус (например, с "connected" на "disconnected"), нода Status генерирует новое сообщение, содержащее информацию об этом событии.
Конфигурация ноды
Главный параметр ноды Status — это ее область видимости (scope). Вы можете настроить ее на отслеживание:
- Всех нод (All Nodes): Генерирует слишком много шума, используется редко.
- Выбранных нод (Selected Nodes): Идеальный вариант. Нажмите кнопку `Select` и укажите в появившемся списке те узлы, за которыми нужен присмотр. Как правило, это узлы-коннекторы: `mqtt in/out`, `Modbus-Client`, `http request`.
> ⚠️ Внимание: Избегайте отслеживания состояния (Status) для каждой ноды в потоке. Это создает избыточную нагрузку на контроллер. Используйте ноду Status точечно, для мониторинга ключевых, "нестабильных" компонентов: шлюзов, серверов, внешних API.
Разбор объекта `msg` от ноды Status
Сообщение, сгенерированное нодой Status, имеет специфическую структуру:
{
"_msgid": "c1d2e3f4.a9b8c7",
"status": {
"text": "disconnected",
"fill": "red",
"shape": "ring",
"source": {
"id": "12345abc.de6f54",
"type": "mqtt-broker",
"name": "Main Broker"
}
}
}
- msg.status.text: Текстовое описание статуса (например, "connected", "timeout", "Error: CRC mismatch").
- msg.status.fill: Цвет иконки статуса (`green`, `yellow`, `red`).
- msg.status.shape: Форма иконки (`dot`, `ring`).
- msg.status.source: Объект, идентифицирующий ноду-источник события. Содержит ее ID, тип и имя. Это позволяет одной ноде Status мониторить несколько узлов и понимать, от какого из них пришло событие.
Практический пример: Оповещение о потере связи с Modbus RTU
Задача: Немедленно отправлять уведомление в системный MQTT-топик `system/alerts`, если шина RS-485 перестала отвечать. ASCII-схема: +---------------------+
| Status (Modbus-IO) |
+---------------------+
|
v
+----------------+
| Switch: is_err |
+----------------+
| |
(no error) (error)
| |
null v
+---------------------+
| Function: FormatMsg |
+---------------------+
|
v
+--------------------+
| MQTT Out: Alerts |
+--------------------+
* Добавляем на поток ноду `Status`.
* В конфигурации выбираем `Selected Nodes` и указываем из списка наш узел `Modbus-Client` (узел конфигурации сервера Modbus).
* Добавляем ноду `Switch` после `Status`.
* Настраиваем правило: проверять свойство `msg.status.fill`. Если оно `==` (строка) `red`, то сообщение идет на второй выход. В противном случае — на первый (и далее никуда).
* Эта нода формирует сообщение для администратора.
* Код:
// Входящее сообщение от ноды Status уже содержит информацию об ошибке
let sourceNode = msg.status.source;
let statusText = msg.status.text;
// Формируем payload по контракту для системы оповещений
msg.payload = {
level: "CRITICAL",
service: "Modbus-RTU",
message: `Потеря связи с устройством на шине RS-485.`,
details: `Узел '${sourceNode.name}' (ID: ${sourceNode.id}) сообщил об ошибке: ${statusText}`,
ts: Date.now()
};
// Устанавливаем топик для отправки
msg.topic = "system/alerts";
return msg;
* Настраиваем на отправку в топик `system/alerts`.
Теперь, как только Modbus-устройство на шине перестанет отвечать и `Modbus-Client` перейдет в состояние ошибки, система автоматически сгенерирует и отправит структурированное оповещение. Это позволяет перейти от реактивной модели ("клиент позвонил, что ничего не работает") к проактивной ("система сообщила о проблеме до того, как ее заметили пользователи").
---
Нода Catch — Глобальный обработчик ошибок
Нода Catch — это ваша последняя линия обороны, "сетка безопасности" для всего потока. Ее задача — перехватывать ошибки, которые не были обработаны локально (например, через второй выход ноды `Modbus Read`), и предотвращать остановку или непредсказуемое поведение потоков.
> 💡 Подсказка: В каждом проекте рекомендуется создавать отдельную вкладку (flow) под названием "System" или "Diagnostics", где будут централизованно размещены ноды Catch, обработчики статусов и другая системная логика. Это упрощает поддержку и стандартизирует подход к отладке.
Назначение и область действия
В отличие от ноды Status, которая реагирует на состояние, нода Catch реагирует на событие ошибки (exception), выброшенное другой нодой. Типичные примеры:
- Ошибка парсинга в ноде`JSON`.
- Синтаксическая ошибка в коде ноды `Function`.
- Таймаут ответа от устройства в ноде `Modbus Read`.
- Ошибка подключения в ноде `TCP Request`.
Нода Catch также имеет настройку области действия:
- All nodes on current flow: Перехватывает ошибки только на той вкладке, где она размещена. Рекомендуемый вариант для разделения логики.
- All nodes: Глобальный перехватчик для всего проекта.
- Selected nodes: Перехват ошибок только от выбранных нод.
Структура объекта `msg.error`
При срабатывании нода Catch генерирует сообщение, главным свойством которого является `msg.error`. Этот объект содержит бесценную информацию для диагностики.
{
"_msgid": "d4e5f6a1.b2c3d4",
"error": {
"message": "Timed out",
"source": {
"id": "abcdef12.345678",
"type": "modbus-read",
"name": "Read Energy Meter",
"count": 1
}
}
// Также в msg может быть сохранено оригинальное сообщение,
// которое вызвало ошибку, что помогает в отладке.
}
- msg.error.message: Текст ошибки, например, "Timed out", "ReferenceError: variable is not defined", "Invalid JSON".
- msg.error.source.id: ID ноды, которая сгенерировала ошибку.
- msg.error.source.type: Тип ноды (`function`, `modbus-read`).
- msg.error.source.name: Имя, которое вы дали ноде.
Имея эти данные, вы можете точно и мгновенно локализовать проблему.
Кейс: Создание универсального логгера ошибок
Задача: Создать систему, которая логгирует все необработанные ошибки в файл `errors.log` на контроллере и отправляет критические уведомления администратору. ASCII-схема:(On "Diagnostics" Tab)
+---------------------+
| Catch (All nodes) |
+---------------------+
|
v
+-----------------------+
| Function: Format Log |
+-----------------------+
|
+-----> [File Out: errors.log]
|
v
+-----------------------+
| Switch: is_critical? |
+-----------------------+
|
v
[MQTT Out: alerts]
* Размещаем на отдельной вкладке "Diagnostics".
* Устанавливаем `Scope` в `All nodes`.
* Код для форматирования сообщения, которое будет записано в файл.
let err = msg.error;
let source = err.source;
let timestamp = new Date().toISOString();
// Формируем читаемую строку лога
let logMessage = `${timestamp} | LEVEL: ERROR | SOURCE_ID: ${source.id} | SOURCE_TYPE: ${source.type} | SOURCE_NAME: ${source.name} | MESSAGE: ${err.message}\n`;
// Помещаем эту строку в payload для ноды File
msg.payload = logMessage;
// Также можно обогатить сообщение для дальнейшей обработки
msg.logData = {
ts: timestamp,
source_id: source.id,
source_name: source.name,
error_message: err.message
};
return msg;
* `Filename`: `/home/hi/logs/errors.log` (или другой путь на контроллере).
* `Action`: `append to file`.
* Убедитесь, что у процесса Node-RED есть права на запись в эту директорию.
* Нода `Switch` может анализировать `msg.logData.error_message` на наличие ключевых слов (например, "timeout", "critical") и, если они есть, направлять сообщение дальше, в ноду `MQTT Out`, для отправки PUSH-уведомления.
---
Резюме и лучшие практики
Мы рассмотрели три мощных инструмента, которые выводят процесс отладки в Node-RED на принципиально новый уровень. Их правильное и совместное использование — признак профессионального подхода к разработке систем автоматизации.
Роли нод в диагностике:- Debug (в режиме "complete msg object"): Отвечает на вопрос "Что происходит?". Показывает полное содержимое и маршрут сообщения в любой точке потока.
- Status: Отвечает на вопрос "В каком состоянии компонент?". Позволяет проактивно мониторить "здоровье" внешних подключений (MQTT, Modbus, TCP).
- Catch: Отвечает на вопрос "Что пошло не так?". Служит глобальной системой безопасности, которая ловит и протоколирует все непредвиденные сбои.
Синергия трех нод для комплексной диагностики
Представим "плавающую" неисправность: иногда команды на включение света не проходят.
Рекомендации по внедрению
- Обязательное использование: Ноды `Catch` и `Status` не являются опциональными. Наличие на каждой вкладке проекта как минимум одной ноды `Catch` и централизованного потока обработки ошибок является обязательным условием для сдачи системы в эксплуатацию.
- Документирование логики отладки: Потоки на вкладке "Diagnostics" должны быть так же хорошо прокомментированы, как и основная бизнес-логика. Другой инженер должен понимать, куда и в каком формате отправляются алерты и где искать логи ошибок.
- Стандартизация: Разработайте для своих проектов стандартный шаблон вкладки "Diagnostics", который можно будет импортировать в новые проекты. Это ускоряет разработку и обеспечивает единообразие.
Что дальше
В следующем уроке мы объединим все полученные знания и на практике проведем комплексную диагностику системы по структурированному чек-листу, имитируя процесс приемо-сдаточных испытаний (ПСИ) на реальном объекте. Мы научимся систематически проверять все уровни системы — от затяжки клемм до корректности выполнения сложных сценариев автоматизации.