ГлавнаяАкадемияДатчики и входы: нормализация сигналов → Лабораторная работа: Реализация watchdog'a для датчика протечки

Лабораторная работа: Реализация watchdog'a для датчика протечки

Урок 6 · Датчики и входы: нормализация сигналов · 30 мин · theory

Введение и цели лабораторной работы

> 🔗 Связанный материал: Перед началом работы рекомендуется освежить знания о концепции 'Last Seen' (рассмотренной в уроке COURSE-04-M07-L02) и использовании ноды Trigger для создания таймеров (урок COURSE-04-M07-L04).

В современных системах автоматизации надежность является не просто желательным качеством, а абсолютной необходимостью, особенно когда речь идет о критически важных функциях безопасности. Датчики протечки воды, датчики утечки газа или пожарные извещатели — это первая линия обороны вашего объекта. Но что произойдет, если такой датчик выйдет из строя? Если он перестанет передавать данные из-за севшей батарейки, обрыва провода или программного сбоя, система будет считать, что все в порядке, в то время как реальная угроза может остаться незамеченной. Это создает ложное чувство безопасности и сводит на нет саму идею автоматизации.

Для борьбы с этой проблемой инженеры применяют так называемые сторожевые таймеры, или watchdog-механизмы. Принцип их работы прост и гениален: система постоянно ожидает «пульс» от датчика — регулярный сигнал, подтверждающий его работоспособность. Если этот сигнал не поступает в течение заданного промежутка времени, система бьет тревогу. Это позволяет обнаружить не только аварию (протечку), но и отказ самого средства обнаружения аварии.

Цель данной лабораторной работы — спроектировать, собрать и протестировать в среде Node-RED полноценный watchdog-сценарий для виртуального датчика протечки. Мы научимся не просто обнаруживать "мертвые" датчики, но и инициировать аварийный режим (fail-safe), например, отправляя команду на перекрытие магистрального крана.

📋 Ключевые понятия:

Для выполнения работы нам понадобится следующий набор стандартных узлов (нод) Node-RED:

Прежде чем мы начнем, откройте редактор Node-RED на вашем контроллере HI и создайте новую вкладку (поток), назвав ее `LAB-Watchdog`. Именно здесь мы будем собирать нашу схему.

---

Шаг 1: Эмуляция датчика протечки

Первым шагом любой отладки или разработки в Node-RED является создание воспроизводимой среды. Вместо того чтобы сразу подключать физический датчик, мы создадим его эмулятор с помощью ноды `Inject`. Это позволит нам полностью контролировать процесс, имитировать штатную работу и отказы, не завися от внешнего оборудования.

> 💡 Подсказка: Используйте JSON в качестве типа данных в ноде Inject. Это позволяет создавать структурированные сообщения, которые соответствуют паттерну "Контракт сообщения" и которые легко парсить и обрабатывать в последующих нодах.

  • Перетащите на рабочее поле ноду `Inject`.
  • Дважды кликните по ней, чтобы открыть окно настроек.
  • В поле `Payload` выберите тип `JSON`.
  • В редакторе JSON введите следующий код. Это будет наше стандартизированное сообщение от датчика.
  • {
    

    "sensor_id": "leak_kitchen_01",

    "status": "dry",

    "location": "kitchen",

    "type": "leak_detector",

    "timestamp": 0

    }

  • Теперь нам нужно, чтобы это сообщение содержало актуальную временную метку. Для этого мы заменим значение `0` на `timestamp`, выбрав этот вариант из выпадающего списка справа от редактора JSON. В результате поле `Payload` должно выглядеть как `{"sensor_id":"leak_kitchen_01","status":"dry","location":"kitchen","type":"leak_detector","timestamp":}`. Это гарантирует, что каждое сообщение будет иметь уникальное время создания, что критически важно для концепции "Last Seen".
  • В секции `Repeat` установите режим `interval` и задайте периодичность `30` секунд. Это означает, что наш "датчик" будет отправлять отчет о своем состоянии каждые полминуты.
  • Установите галочку `Inject once at start`, чтобы поток начал работать сразу после развертывания.
  • В поле `Name` укажите `Эмулятор датчика протечки (30 сек)`.
  • После выполнения этих шагов мы получили полноценный эмулятор. Он периодически отправляет в поток сообщение, полностью соответствующее контракту сообщения, принятому в нашей системе.

    Структура сообщения `msg.payload` от эмулятора:

    | Поле | Тип | Описание | Пример |

    |---------------|----------|---------------------------------------------------------------------|---------------------|

    | `sensor_id` | `string` | Уникальный идентификатор датчика. | `"leak_kitchen_01"` |

    | `status` | `string` | Текущее состояние. Может быть `"dry"` или `"wet"`. | `"dry"` |

    | `location` | `string` | Местоположение датчика для удобства идентификации. | `"kitchen"` |

    | `type` | `string` | Тип датчика. | `"leak_detector"` |

    | `timestamp` | `number` | Временная метка в формате Unix epoch (ms), добавленная нодой Inject. | `1677611234000` |

    Добавьте ноду `Debug` на поле и соедините выход эмулятора с ее входом. Назовите ноду `Debug` как `Выход эмулятора`. Разверните (`Deploy`) изменения. В панели отладки справа вы должны видеть, как каждые 30 секунд появляется новое сообщение от нашего виртуального датчика. Убедитесь, что структура сообщения соответствует описанной выше.

    ---

    Шаг 2: Реализация сторожевого таймера (Watchdog)

    Теперь, когда у нас есть стабильный поток данных от эмулятора, мы можем построить сам сторожевой таймер. Его сердцем будет нода `Trigger`. Эта нода работает как таймер "обратного отсчета", который сбрасывается каждый раз, когда на его вход приходит сообщение. Если же в течение заданного времени ни одного сообщения не поступило, таймер "срабатывает" и отправляет сигнал тревоги.

    > ⚠️ Внимание: Неправильно подобранный интервал watchdog — частая причина ложных срабатываний. Рекомендуется устанавливать таймаут в 2-3 раза больше периода опроса датчика. Если датчик шлет данные раз в 30 секунд, а таймаут — 31 секунда, то любая минимальная сетевая задержка вызовет ложную тревогу.

  • Добавьте на поле ноду `Trigger` и соедините с ней выход нашего `Эмулятора датчика протечки`.
  • Откройте настройки ноды `Trigger`.
  • Конфигурация ноды Trigger

    | Параметр | Значение | Пояснение |

    |----------------|------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

    | Send | `nothing` | При получении сообщения от датчика (когда все в порядке), нода ничего не должна отправлять дальше. Она просто сбрасывает свой внутренний таймер и ждет следующего сигнала. |

    | Then wait for | `65` `seconds` | Это и есть таймаут нашего watchdog'а. Мы выбрали 65 секунд, что чуть больше чем в два раза превышает интервал опроса датчика (30 секунд). Это дает системе запас на случай небольших задержек. |

    | Then send | `the original message` | Если таймер на 65 секунд истек, нода отправит на свой второй выход то последнее сообщение, которое она получила от датчика. Это очень важно для диагностики, т.к. мы будем знать, каким было последнее известное состояние датчика. |

    | Handling | `extend delay if new message arrives` | Эта опция должна быть включена по умолчанию. Она гарантирует, что каждый новый сигнал от датчика "перезапускает" таймер с самого начала. |

    | Name | `Watchdog (65 сек)` | Присвойте ноде понятное имя. |

    Таким образом, логика работы следующая:

    Именно этот сигнал со второго выхода мы и будем использовать для запуска аварийного сценария. Пока что подключите к обоим выходам ноды `Trigger` по одной ноде `Debug`, назвав их соответственно `Выход 1 (OK)` и `Выход 2 (FAIL)`. Разверните поток. Вы увидите, что в панели отладки появляются сообщения только от `Выхода эмулятора`, но не от двух других нод `Debug`. Это означает, что watchdog работает корректно в штатном режиме.

    ---

    Шаг 3: Обработка отказа и аварийный режим

    Сигнал об отказе датчика — это только полдела. Система должна не просто зафиксировать проблему, но и адекватно на нее отреагировать. Сейчас мы создадим логику, которая при срабатывании watchdog'а сформирует стандартизированное тревожное сообщение и инициирует аварийный режим, отправив команду на перекрытие воды.

  • Отключите ноду `Debug` от второго выхода ноды `Trigger`.
  • Добавьте на поле ноду `Function` и соедините второй выход `Trigger` с ее входом. Назовите ноду `Формирование тревоги`.
  • Откройте настройки ноды `Function` и введите следующий JavaScript-код:
  • // Последнее сообщение от датчика, которое сохранила нода Trigger
    

    const lastSensorMsg = msg.payload;

    // 1. Формируем новое, стандартизированное тревожное сообщение

    // Это сообщение пойдет в систему мониторинга и логирования

    const alert_payload = {

    alert_type: "WATCHDOG_FAIL",

    message: `Датчик ${lastSensorMsg.sensor_id} не выходит на связь более 65 секунд!`,

    source_id: lastSensorMsg.sensor_id,

    last_known_status: lastSensorMsg.status,

    last_seen_ts: lastSensorMsg.timestamp,

    severity: "critical",

    timestamp: Date.now()

    };

    // 2. Формируем команду для аварийного режима (fail-safe)

    // Эта команда будет отправлена на исполнительное устройство (кран)

    const failsafe_command_payload = {

    command: "CLOSE",

    source: "watchdog_leak_system",

    reason: `Отказ датчика ${lastSensorMsg.sensor_id}`

    };

    // 3. Создаем два независимых сообщения для отправки по разным MQTT-топикам

    const alert_msg = {

    topic: "alerts/safety",

    payload: alert_payload

    };

    const failsafe_msg = {

    topic: `commands/valves/kitchen_main/set`,

    payload: failsafe_command_payload

    };

    // Выводим информацию в статус ноды для быстрой диагностики

    node.status({fill:"red", shape:"dot", text:`Отказ: ${lastSensorMsg.sensor_id}`});

    // Отправляем оба сообщения на выход ноды.

    // Мы используем два выхода, чтобы разделить потоки команд и алертов.

    return [alert_msg, failsafe_msg];

  • В настройках ноды `Function` измените количество выходов (`Outputs`) на `2`.
  • Разбор кода:

    Теперь наш сценарий готов к действию. Осталось подключить к выходам обработчики.

    ---

    Шаг 4: Сборка и тестирование сценария

    Сборка и тестирование — финальный и самый важный этап, подтверждающий работоспособность нашей логики. Мы проведем два теста: один для штатного режима и один для имитации отказа.

    Итоговая схема потока

    Соберите все ноды вместе, как показано на ASCII-схеме ниже. Используйте ноды `Debug` для визуализации сообщений на каждом этапе.

    // FLOW-ID: LAB-WATCHDOG-001
    

    // Описание: Сценарий отслеживания доступности датчика протечки.

    // Часть 1: Эмуляция и Watchdog

    [Inject: Эмулятор (30s)] ---> [Trigger: Watchdog (65s)] --+-- (Выход 1, OK) --> [Debug: Штатный режим]

    |

    +-- (Выход 2, FAIL) --> [Function: Формирование тревоги]

    // Часть 2: Обработка отказа

    [Function: Формирование тревоги] --+-- (Выход 1, Alert) --> [MQTT Out: alerts/safety] ----> [Debug: Тревога]

    |

    +-- (Выход 2, Cmd) ---> [MQTT Out: commands/...] ---> [Debug: Команда крану]

    Настройка:
  • Подключите ноды `MQTT Out` к соответствующим выходам ноды `Function`. Настройте их на работу с вашим MQTT-брокером. В качестве топиков используйте те, что мы задали в коде (например, `alerts/safety` и `commands/valves/kitchen_main/set`).
  • Подключите ноды `Debug` к выходам `MQTT Out`, чтобы видеть, что именно отправляется.
  • Тест-план

    Теперь выполним последовательность тестов для проверки нашего сценария.

    Сценарий тестирования №1: Штатный режим

  • Действие: Убедитесь, что нода `Inject: Эмулятор датчика протечки` включена (кнопка на ноде активна).
  • Действие: Нажмите кнопку `Deploy` для развертывания потока.
  • Наблюдение: Откройте панель отладки.
  • Ожидаемый результат:
  • * Каждые 30 секунд в панели отладки появляется сообщение от `Эмулятора датчика протечки`.

    * Ноды `Debug`, подключенные к выходам `Function` (`Тревога` и `Команда крану`), молчат. Никаких сообщений от них не поступает.

    * Статус под нодой `Function: Формирование тревоги` отсутствует.

  • Вывод: В штатном режиме watchdog-таймер успешно сбрасывается, и аварийный сценарий не запускается. Система работает корректно.
  • Сценарий тестирования №2: Режим отказа

  • Действие: Нажмите на кнопку на левой стороне ноды `Inject: Эмулятор датчика протечки`, чтобы отключить ее. Иконка ноды станет серой. Это имитирует внезапный отказ датчика.
  • Действие: Засеките время или просто наблюдайте за панелью отладки.
  • Наблюдение: В течение примерно 65 секунд после последнего сообщения от эмулятора ничего не будет происходить.
  • Ожидаемый результат:
  • * По истечении 65 секунд нода `Trigger` сработает.

    * Нода `Function: Формирование тревоги` выполнит свой код. Под ней появится красный статус `Отказ: leak_kitchen_01`.

    * В панели отладки одновременно появятся два новых сообщения:

    * От ноды `Debug: Тревога` придет JSON с полной информацией об отказе.

    * От ноды `Debug: Команда крану` придет JSON с командой на закрытие крана.

  • Действие (Восстановление): Снова включите ноду `Inject`. Убедитесь, что поток вернулся в штатный режим, и тревоги больше не генерируются.
  • Вывод: Сценарий успешно обнаружил отсутствие "пульса" от датчика, корректно сформировал тревожное сообщение и команду для аварийного режима.
  • Поздравляем! Вы только что реализовали один из важнейших паттернов надежности в системах автоматизации.

    ---

    Заключение: Применение и масштабирование

    В рамках этой лабораторной работы мы на практике освоили создание надежного watchdog-механизма с помощью стандартных средств Node-RED. Мы не просто обнаружили отказ, но и реализовали логику аварийного режима, что является признаком профессионально спроектированной системы.

    Созданный нами паттерн 'Эмулятор -> Watchdog (Trigger) -> Обработчик тревог' является универсальным и может быть легко адаптирован для мониторинга любого критически важного устройства в вашей системе:

    Для масштабирования этого решения на несколько датчиков можно использовать субпотоки (subflows), как было рассмотрено в скилле "Паттерны Node-RED". В субпоток выносится связка `Trigger` + `Function`, а ID датчика и интервал таймаута передаются через переменные окружения субпотока.

    Что дальше?

    Созданный нами сценарий является надежным фундаментом, который можно и нужно развивать:

    В следующем уроке мы рассмотрим, как применять аналогичные подходы для мониторинга состояния устройств, подключенных по шине Modbus, где проблемы со связью являются частым явлением.