Знакомство с нодами Node-RED для работы с входами
Введение: от физического уровня к логическому в Node-RED
В предыдущих уроках мы подробно изучили физическую природу сигналов, рассмотрели типы универсальных входов контроллера HI и освоили базовые схемы подключения датчиков. Теперь наша задача — перейти от аппаратного уровня к программному и научиться работать с этими сигналами в среде Node-RED. Этот урок является мостом, соединяющим мир электрических импульсов и мир логических сценариев автоматизации.
> 🔗 Связанный материал: В этом уроке мы будем работать с логикой в Node-RED. Концепции физических сигналов и схемы подключения подробно рассмотрены в уроках `COURSE-04-M01-L01` "Физический сигнал, логическое событие, состояние системы" и `COURSE-04-M01-L04` "Базовые схемы подключения".
Контроллер HI предоставляет специальную палитру нод `home-intelligence`, которая служит интерфейсом между операционной системой Linux, управляющей портами ввода-вывода, и вашими потоками в Node-RED. Эти ноды инкапсулируют сложную низкоуровневую работу, предоставляя инженеру простой и понятный инструмент для получения данных.
Ключевая задача, которую мы будем решать на программном уровне, — это преобразование физических сигналов в значимые для системы события или состояния.
- Событие: Дискретный, одномоментный факт. Например, "кнопку нажали", "дверь открылась".
- Состояние: Длительная, измеряемая характеристика. Например, "температура в комнате составляет 22.5 °C", "освещенность равна 500 люкс".
Node-RED выступает в роли центрального процессора для этих данных. Он позволяет не просто считывать их, но и выполнять критически важные операции:
В этом уроке мы сосредоточимся на первых двух пунктах, используя базовые ноды из палитры `home-intelligence` и стандартную ноду `rbe` для фильтрации.
---
Нода 'hi-di': Чтение состояний дискретных входов
Нода `hi-di` (Home Intelligence - Digital Input) — это ваш основной инструмент для работы с сигналами типа "сухой контакт", кнопками, выключателями, герконами и любыми другими устройствами, генерирующими два состояния: замкнуто или разомкнуто. Эта нода работает по Push-модели, то есть она не опрашивает вход постоянно, а реагирует на прерывание (interrupt), генерируемое при изменении электрического состояния на клемме. Такой подход чрезвычайно эффективен и не создает нагрузки на процессор.
Настройка и конфигурация
При добавлении ноды `hi-di` на холст, ее панель настроек предлагает несколько ключевых параметров:
- Pin: Выпадающий список для выбора конкретного физического входа контроллера, к которому подключен датчик (например, `DI-01`, `DI-02`, ... `DI-22`).
- Initial state on start: Определяет, должно ли состояние входа быть считано при запуске потока. Рекомендуется всегда устанавливать `true`, чтобы система сразу знала актуальное состояние датчика.
- Debounce: Числовое поле для установки задержки в миллисекундах. Это важнейший параметр для подавления дребезга контактов.
> 💡 Подсказка: Дребезг (bounce) — это физическое явление, при котором механические контакты кнопки или реле при замыкании несколько раз соударяются друг с другом, прежде чем установить стабильный контакт. Без фильтрации это приводит к генерации целой "лавины" ложных событий `true`/`false` за доли секунды. Значение Debounce в 50-100 мс является стандартной практикой для большинства кнопок и герконов.
- Name: Поле для присвоения ноде осмысленного имени, например, "Датчик двери (вход)".
Формат исходящего сообщения
После каждого отфильтрованного изменения состояния на входе, нода `hi-di` генерирует сообщение `msg` со следующей структурой:
- `msg.payload` (boolean): Содержит `true` (если контакты замкнуты, т.е. на вход подано напряжение) или `false` (если контакты разомкнуты).
- `msg.topic` (string): По умолчанию содержит имя ноды, что можно использовать для идентификации источника события.
Пример: Мониторинг датчика открытия двери
Представим, что к входу `UI-05` (универсальный вход, настроенный как дискретный) подключен магнитный датчик открытия двери (геркон).
[hi-di]─────────[debug]
* Pin: `UI-05`
* Initial state on start: `true`
* Debounce: `75` ms
* Name: `Геркон входной двери`
* Output: `complete msg object`
Теперь, при открытии и закрытии двери, вы будете видеть в панели отладки сообщения. При открытии двери (контакты размыкаются) придет сообщение:
{
"payload": false,
"topic": "Геркон входной двери",
"_msgid": "a1b2c3d4.e5f6g7"
}
При закрытии двери (контакты замыкаются):
{
"payload": true,
"topic": "Геркон входной двери",
"_msgid": "h8i9j0k1.l2m3n4"
}
Благодаря параметру `Debounce`, даже если контакты геркона слегка "завибрируют" в момент срабатывания, нода проигнорирует кратковременные колебания и выдаст только одно, стабильное событие.
---
Нода 'hi-ai': Получение данных с аналоговых входов
В отличие от дискретных входов, аналоговые входы измеряют непрерывную величину — напряжение. Нода `hi-ai` (Home Intelligence - Analog Input) предназначена для считывания этих значений. Она работает по Pull-модели, то есть периодически опрашивает аналого-цифровой преобразователь (АЦП) контроллера с заданным интервалом.
> ⚠️ Внимание: Нода `hi-ai` работает по модели Pull (опрос). Слишком частый опрос (например, каждые 100 мс) может необоснованно нагружать системную шину и процессор контроллера, не принося при этом полезной информации, если измеряемый процесс инертен (как изменение температуры). Всегда выбирайте интервал, соответствующий характеру процесса. Для температуры это может быть 30-60 секунд, для освещенности — 5-10 секунд.
Настройка и конфигурация
- Pin: Выбор аналогового канала для чтения (например, `AI-01`, `AI-02`, ...).
- Polling Interval: Интервал опроса в секундах. Определяет, как часто нода будет считывать значение и отправлять его дальше по потоку.
- Name: Имя ноды, например, "Датчик освещенности (0-10V)".
"Сырые" значения и нормализация
АЦП контроллера преобразует аналоговое напряжение (например, от 0 до 10 Вольт) в цифровое представление — "сырое" значение (raw value). Для 12-битного АЦП это будет целое число в диапазоне от 0 до 4095.
| Напряжение на входе | "Сырое" значение (12-bit АЦП) |
| ------------------- | ------------------------------ |
| 0V | 0 |
| 2.5V | ~1024 |
| 5V | ~2048 |
| 10V | 4095 |
Сама по себе нода `hi-ai` не знает, что означают эти цифры. Она лишь передает их в `msg.payload`. Наша задача как инженеров — в последующих нодах потока нормализовать это значение, то есть превратить его в понятную физическую величину (например, люксы, вольты, проценты). Этому будет посвящен следующий урок.
Формат исходящего сообщения
С заданным интервалом `hi-ai` генерирует сообщение:
- `msg.payload` (number): "Сырое" числовое значение, полученное от АЦП.
- `msg.topic` (string): Имя ноды.
Пример: Чтение данных с датчика освещенности (0-10V)
Подключим аналоговый датчик освещенности с выходом 0-10V к входу `UI-01` (настроен как аналоговый).
[hi-ai]─────────[debug]
* Pin: `UI-01`
* Polling Interval: `5` seconds
* Name: `Датчик освещенности (гостиная)`
Каждые 5 секунд в панели отладки вы будете видеть новое сообщение, даже если освещенность не меняется.
В полной темноте:
{
"payload": 0,
"topic": "Датчик освещенности (гостиная)",
"_msgid": "..."
}
При ярком свете (напряжение близко к 10V):
{
"payload": 4091,
"topic": "Датчик освещенности (гостиная)",
"_msgid": "..."
}
На данном этапе мы просто получаем "сырые" данные. Мы видим, что система реагирует на изменение освещенности, но пока не можем использовать эти цифры напрямую в логике. Главная проблема — поток сообщений идет непрерывно, даже если значение не меняется. Эту проблему решает следующая нода.
---
Фильтрация потока: нода 'rbe' (Report by Exception)
Нода `rbe` (Report by Exception, "сообщать по исключению") — это одна из самых фундаментальных и полезных нод в Node-RED. Ее задача очень проста, но крайне важна: блокировать прохождение сообщения, если его содержимое не изменилось по сравнению с предыдущим прошедшим сообщением.
> ℹ️ Информация: Нода `rbe` — одна из самых важных для оптимизации. Она превращает непрерывный поток состояний (например, "температура 22°C", "температура 22°C", "температура 22°C"...) в дискретные события изменения ("температура стала 22°C"). Это кардинально снижает нагрузку на систему и делает логику сценариев более чистой и предсказуемой.
Проблема избыточных данных
Представим наш датчик освещенности из предыдущего примера. Он отправляет значение каждые 5 секунд. Если освещенность в комнате стабильна, система будет каждые 5 секунд получать сообщение с `payload: 1530`. Это бессмысленная работа. Сценарии, которые должны запускаться по изменению освещенности, будут срабатывать постоянно, или нам придется писать сложную логику для проверки "а изменилось ли значение?".
Нода `rbe` решает эту проблему элегантно.
Принцип работы
`rbe` работает как фильтр с памятью.
Этот принцип одинаково хорошо работает как для аналоговых сигналов (где `payload` — число), так и для дискретных (где `payload` — `true`/`false`).
Режимы работы
В настройках `rbe` можно выбрать режим (`Mode`):
- block if value hasn't changed: Стандартный режим. Сравнивается только `msg.payload`.
- block if value and topic haven't changed: Более строгий режим. Сообщение блокируется, только если и `msg.payload`, и `msg.topic` остались прежними. Это полезно, когда через одну ноду `rbe` проходят данные от разных датчиков с разными топиками.
В большинстве случаев для фильтрации данных от одного датчика достаточно стандартного режима.
---
Практический пример: Кнопка + 'hi-di' + 'rbe'
Давайте на практическом примере убедимся в пользе комбинации этих нод. Мы будем обрабатывать нажатие настенной кнопки звонкового типа (без фиксации), подключенной к входу `UI-08`.
Шаг 1: Только 'hi-di'
Сначала соберем поток только с нодой `hi-di`, чтобы увидеть проблему.
Поток:[hi-di: Кнопка]─────────[debug: Выход с hi-di]
Настройки `hi-di`:
- Pin: `UI-08`
- Debounce: `50` ms
- Name: `Кнопка вызова`
Казалось бы, все в порядке. Но что если мы хотим считать не только событие нажатия, но и состояние "кнопка удерживается"? Если бы `hi-di` отправляла состояние постоянно (как `hi-ai`), мы бы получили лавину `true`. Хоть `hi-di` и работает по прерываниям, для демонстрации пользы `rbe` представим следующую логическую задачу: мы хотим получать только момент изменения состояния.
Шаг 2: Добавляем 'rbe'
Теперь усложним задачу. Предположим, другая часть системы (по какой-то причине) генерирует дублирующиеся состояния. Вставим `rbe` в нашу цепочку, чтобы гарантировать чистоту событий.
Полный поток:[hi-di: Кнопка]────[rbe]────[debug: Выход с rbe]
Настройки `rbe`:
- Mode: `block if value hasn't changed` (по умолчанию).
Результат на выходе из `rbe` — это чистая последовательность событий изменения:
- `true` — кнопка была нажата.
- `false` — кнопка была отпущена.
Никаких дубликатов, никаких промежуточных состояний. Мы получили идеальный "триггер" для наших сценариев: одно сообщение на каждое действие пользователя. Этот паттерн (`[вход] -> [rbe] -> [логика]`) является одним из самых фундаментальных в проектировании надежных систем на Node-RED.
---
Итоги и следующие шаги
В этом уроке мы сделали важнейший шаг от аппаратной части к программной, научившись получать и первично обрабатывать данные с физических входов контроллера HI.
📋 Ключевые понятия:
- Нода `hi-di` используется для обработки дискретных сигналов (`true`/`false`) по Push-модели (прерывания). Её ключевой параметр — Debounce для фильтрации дребезга.
- Нода `hi-ai` используется для периодического опроса аналоговых входов по Pull-модели. Она выдает "сырые" цифровые значения (`raw values`), требующие дальнейшей обработки.
- Нода `rbe` (Report by Exception) является универсальным фильтром, который пропускает сообщения только при изменении их `payload`, превращая поток состояний в поток событий.
Мы установили фундаментальный принцип проектирования: любой ввод данных в систему должен проходить через фильтры для генерации только значимых, уникальных событий. Это делает систему эффективной, предсказуемой и легкой для отладки.
> 🔗 Что дальше: Мы научились получать "сырые" данные с аналоговых датчиков, но пока не можем их использовать. В следующем уроке, `COURSE-04-M02-L01: Нормализация аналоговых сигналов с помощью ноды 'range'`, мы подробно разберем, как превратить абстрактные цифры типа `4095` в понятные физические величины: градусы Цельсия, проценты влажности или люксы освещенности.