Реализация SMA с помощью ноды Smooth
Введение в node-red-contrib-smooth: Упрощаем сглаживание
В предыдущем уроке мы рассмотрели концептуальные основы алгоритма простого скользящего среднего (SMA) для борьбы с шумом в аналоговых сигналах. Хотя реализация этого алгоритма вручную в ноде `Function` является отличным упражнением для понимания его механики, в реальных производственных условиях предпочтение отдается использованию готовых, проверенных и стандартизированных инструментов. Одним из таких инструментов в экосистеме Node-RED является нода `Smooth` из библиотеки `node-red-contrib-smooth`.
> 💡 Подсказка: Хотя логику SMA можно реализовать вручную в ноде `Function` (как мы концептуально обсуждали в уроке COURSE-04-M05-L05), нода `Smooth` является рекомендуемой практикой для производственных сред, так как снижает сложность потоков, уменьшает вероятность ошибок в коде и упрощает дальнейшее обслуживание системы.
Библиотека `node-red-contrib-smooth` предоставляет простой, но мощный узел для фильтрации и усреднения последовательности числовых значений. Ее основное назначение на контроллерах HI — приведение "сырых", зашумленных данных от аналоговых датчиков к стабильному, предсказуемому виду, пригодному для дальнейшего использования в логике автоматизации.
Преимущества использования ноды Smooth
Обзор возможностей
Нода `Smooth` поддерживает несколько алгоритмов усреднения, что делает ее универсальным инструментом:
- SMA (Simple Moving Average) — Простое скользящее среднее: Вычисляет среднее арифметическое последних `N` значений. Все значения в "окне" имеют одинаковый вес. Это самый простой и распространенный метод, на котором мы сфокусируемся в этом уроке.
- WMA (Weighted Moving Average) — Взвешенное скользящее среднее: Придает больший вес более новым данным в выборке. Позволяет быстрее реагировать на изменения, чем SMA, но все еще учитывает историю.
- EMA (Exponential Moving Average) — Экспоненциальное скользящее среднее: Также придает больший вес последним данным, но делает это экспоненциально. Очень чувствительно к новым данным, но сложнее в настройке.
Для большинства задач автоматизации на объектах, таких как усреднение температуры, влажности или освещенности, возможностей SMA более чем достаточно.
Установка ноды
Установка библиотеки `node-red-contrib-smooth` на контроллер HI производится стандартным способом через веб-интерфейс Node-RED:
После короткого процесса установки в вашей палитре узлов (слева) появится новая нода оранжевого цвета с именем `smooth`.
---
Конфигурация ноды Smooth: Ключевые параметры
После перетаскивания ноды `smooth` на рабочее поле, двойной клик по ней открывает диалоговое окно конфигурации. Правильная настройка этих параметров является ключом к эффективному сглаживанию сигнала.
Основные параметры ноды `Smooth`
| Параметр | Описание | Рекомендации по использованию |
| :------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Method | Выбор алгоритма усреднения. По умолчанию `Simple Moving Average` (SMA). | Для 95% задач автоматизации используйте `Simple Moving Average`. Другие методы требуются для специфических задач, где важна быстрая реакция на тренды. |
| Period | Период или "окно" выборки. Определяет количество последних значений (`msg.payload`), которые будут использоваться для расчета среднего. Это самый важный параметр. | Для инертных процессов (температура в помещении) можно использовать большие значения (10-30). Для быстро меняющихся (освещенность) — малые значения (3-5). |
| Initial Value | Определяет поведение ноды, пока ее внутренний буфер не будет заполнен до размера `Period`. | `Ignore first
| Name | Имя ноды, которое будет отображаться в потоке. | Всегда задавайте осмысленное имя, например "SMA Температура Гостиная" или "Усреднение CO2". |
> ⚠️ Внимание: Большое значение `Period` приведет к очень плавному графику, но создаст существенную инерционность (задержку реакции) на реальные изменения. Маленькое значение `Period` быстрее реагирует на изменения, но хуже справляется с фильтрацией шума. Всегда ищите баланс между плавностью и скоростью реакции, необходимой для конкретной задачи (например, медленная температура и быстрая освещенность).
Стратегии обработки начальных значений (`Initial Value`)
Этот параметр критически важен для предсказуемого поведения системы при старте контроллера или развертывании потока.
* Как работает: Если `Period` равен 10, нода получит первые 9 сообщений, сохранит их в буфер, но ничего не отправит на выход. Только после получения 10-го сообщения она вычислит первое среднее значение и отправит его.
* Преимущества: Гарантирует, что первое же выходное значение является корректно посчитанным средним. Исключает отправку "сырых" или неполных данных в остальную часть системы.
* Недостатки: Создает первоначальную задержку в работе логики.
* Как работает: Нода будет отправлять среднее значение по мере заполнения буфера. После первого сообщения выйдет оно же. После второго — среднее из двух. И так далее, пока буфер не заполнится до размера `Period`.
* Преимущества: Логика начинает работать сразу, без задержки.
* Недостатки: Первые `N-1` выходных значений не являются полноценно усредненными и могут вызвать ложные срабатывания в последующей логике.
Для большинства систем автоматизации, где стабильность важнее мгновенной реакции при старте, рекомендуется использовать опцию `Ignore first
Обработка нечисловых данных
Нода `Smooth` ожидает, что `msg.payload` будет содержать числовое значение (`number`). Если на вход придет сообщение с другим типом данных (например, строка `string`, объект `object` или `boolean`), нода проигнорирует его и выведет предупреждение в `Debug` консоль. Это правильное поведение, так как оно предотвращает "загрязнение" буфера и некорректные расчеты.
Поэтому критически важно следовать паттерну "Контракт сообщения". Перед нодой `Smooth` всегда должна стоять логика, которая извлекает числовое значение и помещает его в `msg.payload`.
Пример правильного входящего сообщения:{
"payload": 21.5,
"topic": "telemetry/office/room101/temperature",
"qos": 1,
"retain": false,
"_msgid": "a1b2c3d4.e5f6g7"
}
Неправильные `msg.payload`, которые будут проигнорированы: `"21.5"`, `{"value": 21.5}`, `true`.
---
Практический пример: Сглаживание показаний датчика температуры Modbus
Рассмотрим типовой сценарий. На объекте установлен датчик температуры, подключенный к контроллеру HI по шине Modbus RTU. Из-за электромагнитных помех (ЭМИ) или особенностей самого сенсора, его показания "шумят" — постоянно колеблются на несколько десятых градуса вокруг реального значения. Это мешает точной работе климатической системы.
Задача: Стабилизировать сигнал, получаемый от датчика, с помощью ноды `Smooth`.Пошаговая инструкция
Мы сымитируем работу зашумленного датчика с помощью серии нод `Inject`, чтобы наглядно увидеть работу сглаживания без реального оборудования.
ASCII-схема потока: +----------------+
[Inject: 20.1] -> | |
| | +-------------------+ +----------------+
[Inject: 19.8] -> | Function: | -> | smooth | -> | Debug |
| Set msg.payload| | (SMA, Period=10) | | (Полный объект)|
[Inject: 20.3] -> | | +-------------------+ +----------------+
| |
[Inject: 19.9] -> | |
+----------------+
Создадим несколько нод `Inject` для имитации потока данных. Чтобы не соединять их все линиями, мы используем одну ноду `Function` как точку сбора.
* Создайте 5-6 нод `Inject`.
* В каждой настройте `msg.payload` на разные, но близкие числовые значения: `20.1`, `19.8`, `20.3`, `19.9`, `20.2`, `21.0` (имитация выброса).
* Соедините выходы всех `Inject` нод с входом одной ноды `Function`.
В ноде `Function` напишем простой код, который просто передает сообщение дальше. Она нужна лишь для аккуратного объединения потоков.
// Просто передаем сообщение дальше.
// Эта нода служит для удобного объединения входов.
return msg;
> 💡 Альтернативный способ: Можно использовать одну ноду `Inject`, настроенную на отправку последовательности сообщений с помощью JSONata. В `Payload` выберите тип `JSONata` и введите выражение: `[20.1, 19.8, 20.3, 19.9, 20.2, 21.0, 20.0, 19.7, 20.4, 20.5]`. Затем соедините эту ноду с нодой `Split`, которая превратит массив в последовательность отдельных сообщений. Этот метод более компактен для тестирования.
* Перетащите ноду `smooth` на поле и соедините ее выход с выходом нашей `Function`.
* Откройте настройки ноды `Smooth` и установите следующие параметры:
* Method: `Simple Moving Average`
* Period: `10`
* Initial Value: `Ignore first
* Name: `SMA Temp (P=10)`
* Добавьте ноду `Debug` после `Smooth`.
* Настройте ноду `Debug` на вывод `complete msg object`.
* Разверните (deploy) поток.
* Начните поочередно нажимать на кнопки нод `Inject`.
Наблюдаемый результат в панели `Debug`:Вы увидите, что первые 9 нажатий на `Inject` не производят никакого вывода от ноды `Debug`. Это работает опция `Ignore first 9 messages`. После 10-го нажатия появится первое сообщение.
Предположим, вы отправили следующие 10 значений: `20.1, 19.8, 20.3, 19.9, 20.2, 21.0, 20.0, 19.7, 20.4, 20.5`
- На 10-м сообщении `Debug` покажет:
msg.payload: 20.19
Это среднее арифметическое всех 10 введенных значений.
Теперь отправим 11-е значение, например, `19.5`.
- На 11-м сообщении `Debug` покажет:
msg.payload: 20.11
Нода `Smooth` "забыла" самое первое значение (`20.1`) и усреднила 9 последних + новое (`19.5`).
Как видно из примера, выходное значение гораздо более стабильно. Оно плавно меняется, игнорируя резкие, но короткие колебания, такие как единичный "выброс" до `21.0`. Именно это стабильное значение и следует использовать для управления, например, нагревателем или системой кондиционирования.
---
Комбинированный подход: Smooth + Гистерезис для надежного управления
Мы уже знаем две мощные техники для повышения надежности систем автоматизации:
- Сглаживание (SMA): Устраняет высокочастотный шум и случайные выбросы в аналоговом сигнале.
- Гистерезис: Борется с "дребезгом" (`flapping`) на пороговых значениях, предотвращая частое переключение исполнительных устройств.
Наилучшего результата можно добиться, применяя эти две техники последовательно.
> 🔗 Связанный материал: Подробная реализация алгоритма гистерезиса с примерами кода в ноде `Function` рассмотрена в уроке COURSE-04-M05-L03 "Реализация гистерезиса в Node-RED". Рекомендуется сначала применить сглаживание к "сырому" сигналу, а затем подавать стабильный результат на вход узла гистерезиса.
Архитектурно верный подход
Правильная архитектура потока обработки аналогового сигнала для управления нагрузкой выглядит следующим образом:
ASCII-схема потока:+------------+ +----------------+ +----------------------+ +-----------------+
| Источник | --> | node | --> | Function / Switch | --> | Исполнительное |
| (Датчик) | | (Smooth) | | (Логика гистерезиса) | | устройство (Реле)|
+------------+ +----------------+ +----------------------+ +-----------------+
Почему именно такой порядок?
Если подать "сырой", зашумленный сигнал сразу на вход логики гистерезиса, существует риск, что сильный шумовой всплеск сможет "пробить" оба порога (верхний и нижний), вызвав ложное срабатывание. Усредняя сигнал перед пороговой логикой, мы гарантируем, что на вход гистерезиса поступает только медленно меняющееся, стабильное значение, отражающее реальный тренд физического процесса, а не кратковременные помехи.
Пример: Управление нагревателем
Задача: Включать нагреватель, когда температура в комнате опускается ниже 20°C, и выключать, когда она поднимается выше 21°C.- Источник: Датчик температуры, показания которого колеблются: `19.8, 20.1, 19.9, 19.7, 20.2 ...`
- Сглаживание: Нода `Smooth` с `Period=5`.
- Гистерезис: Нода `Function` с порогами `(ВКЛ: 20.0, ВЫКЛ: 21.0)`.
На этом этапе сигнал колеблется вокруг порога `20.0`, что могло бы вызвать "дребезг" реле.
Следующие значения на выходе `Smooth` также будут плавно меняться вокруг реальной средней температуры.
* Текущее состояние: `ВЫКЛЮЧЕНО`.
* Входящее значение `19.94` меньше нижнего порога `20.0`.
* Логика принимает решение: `ВКЛЮЧИТЬ` нагреватель и изменить состояние на `ВКЛЮЧЕНО`.
Теперь, даже если следующее "сырое" значение будет `20.1`, усредненное значение изменится незначительно (например, до `19.96`), и оно все еще будет ниже порога выключения `21.0`. Это предотвратит немедленное выключение нагревателя и обеспечит стабильную работу системы.
---
Итоги и лучшие практики
Нода `node-red-contrib-smooth` является неотъемлемым инструментом в арсенале инженера по автоматизации, работающего с платформой HI. Ее правильное применение значительно повышает надежность и предсказуемость работы всей системы.
- Стандартный инструмент: `node-red-contrib-smooth` — это де-факто стандарт для реализации сглаживания аналоговых сигналов. Избегайте написания собственных реализаций в ноде `Function`, если для этого нет веских причин.
- Ключевой параметр `Period`: Выбор значения `Period` — это всегда компромисс между плавностью сигнала и скоростью реакции системы. Этот параметр требует тщательной настройки и тестирования на реальном объекте под конкретную физическую систему (отопление, вентиляция, освещение).
- Правильная архитектура: Всегда применяйте сглаживание перед любой логикой порогового сравнения или гистерезиса. Фильтровать нужно "сырые" данные у их источника.
- Документация: При сдаче проекта всегда документируйте выбранное значение `Period` для каждого усредняемого сигнала и кратко обосновывайте свой выбор (например, "Period=20 для температуры пола, т.к. процесс очень инертный"). Это значительно упростит дальнейшее обслуживание и диагностику системы.
Что дальше
В следующих уроках и лабораторных работах мы применим полученные знания на практике, создавая комплексные потоки для управления климатом, где сглаживание показаний датчиков и логика гистерезиса работают вместе для создания эффективной и надежной системы. Вы научитесь подбирать оптимальные параметры `Period` для различных типов датчиков и интегрировать эти потоки с исполнительными механизмами, такими как реле и приводы клапанов.