ГлавнаяАкадемияДатчики и входы: нормализация сигналов → Реализация SMA с помощью ноды Smooth

Реализация SMA с помощью ноды Smooth

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

Введение в 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

  • Надежность: Нода написана и протестирована сообществом. Внутренний код уже обрабатывает множество пограничных случаев (например, что делать до полного заполнения буфера значений), о которых можно забыть при написании собственной `Function`.
  • Простота поддержки: Поток, использующий ноду `Smooth`, гораздо более читаем. Другой инженер, взглянув на схему, сразу поймет, что в этом месте происходит сглаживание сигнала. Ему не придется разбираться в коде JavaScript внутри ноды `Function`.
  • Сокращение кода: Вся сложная логика по хранению буфера значений, вычислению среднего и обработке ошибок инкапсулирована внутри одной ноды. Это делает ваши потоки (flows) более компактными и сфокусированными на основной задаче.
  • Обзор возможностей

    Нода `Smooth` поддерживает несколько алгоритмов усреднения, что делает ее универсальным инструментом:

    Для большинства задач автоматизации на объектах, таких как усреднение температуры, влажности или освещенности, возможностей SMA более чем достаточно.

    Установка ноды

    Установка библиотеки `node-red-contrib-smooth` на контроллер HI производится стандартным способом через веб-интерфейс Node-RED:

  • Откройте меню (три горизонтальные линии в правом верхнем углу).
  • Выберите пункт `Manage palette` (Управление палитрой).
  • Перейдите на вкладку `Install` (Установка).
  • В строке поиска введите `node-red-contrib-smooth`.
  • Нажмите кнопку `install` напротив найденного пакета.
  • После короткого процесса установки в вашей палитре узлов (слева) появится новая нода оранжевого цвета с именем `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 messages`: Рекомендуемый вариант. Нода не будет отправлять выходное сообщение, пока не накопит достаточно данных для корректного расчета. |

    | Name | Имя ноды, которое будет отображаться в потоке. | Всегда задавайте осмысленное имя, например "SMA Температура Гостиная" или "Усреднение CO2". |

    > ⚠️ Внимание: Большое значение `Period` приведет к очень плавному графику, но создаст существенную инерционность (задержку реакции) на реальные изменения. Маленькое значение `Period` быстрее реагирует на изменения, но хуже справляется с фильтрацией шума. Всегда ищите баланс между плавностью и скоростью реакции, необходимой для конкретной задачи (например, медленная температура и быстрая освещенность).

    Стратегии обработки начальных значений (`Initial Value`)

    Этот параметр критически важен для предсказуемого поведения системы при старте контроллера или развертывании потока.

  • `Ignore first messages` (Игнорировать первые N-1 сообщений):
  • * Как работает: Если `Period` равен 10, нода получит первые 9 сообщений, сохранит их в буфер, но ничего не отправит на выход. Только после получения 10-го сообщения она вычислит первое среднее значение и отправит его.

    * Преимущества: Гарантирует, что первое же выходное значение является корректно посчитанным средним. Исключает отправку "сырых" или неполных данных в остальную часть системы.

    * Недостатки: Создает первоначальную задержку в работе логики.

  • `Send every message from the start` (Отправлять каждое сообщение с самого начала):
  • * Как работает: Нода будет отправлять среднее значение по мере заполнения буфера. После первого сообщения выйдет оно же. После второго — среднее из двух. И так далее, пока буфер не заполнится до размера `Period`.

    * Преимущества: Логика начинает работать сразу, без задержки.

    * Недостатки: Первые `N-1` выходных значений не являются полноценно усредненными и могут вызвать ложные срабатывания в последующей логике.

    Для большинства систем автоматизации, где стабильность важнее мгновенной реакции при старте, рекомендуется использовать опцию `Ignore first messages`.

    Обработка нечисловых данных

    Нода `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] -> | |

    +----------------+

  • Шаг 1: Эмуляция зашумленного датчика.
  • Создадим несколько нод `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`, которая превратит массив в последовательность отдельных сообщений. Этот метод более компактен для тестирования.

  • Шаг 2: Конфигурация ноды `Smooth`
  • * Перетащите ноду `smooth` на поле и соедините ее выход с выходом нашей `Function`.

    * Откройте настройки ноды `Smooth` и установите следующие параметры:

    * Method: `Simple Moving Average`

    * Period: `10`

    * Initial Value: `Ignore first messages`

    * Name: `SMA Temp (P=10)`

  • Шаг 3: Анализ результата
  • * Добавьте ноду `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`

        msg.payload: 20.19
    

    Это среднее арифметическое всех 10 введенных значений.

    Теперь отправим 11-е значение, например, `19.5`.

        msg.payload: 20.11
    

    Нода `Smooth` "забыла" самое первое значение (`20.1`) и усреднила 9 последних + новое (`19.5`).

    Как видно из примера, выходное значение гораздо более стабильно. Оно плавно меняется, игнорируя резкие, но короткие колебания, такие как единичный "выброс" до `21.0`. Именно это стабильное значение и следует использовать для управления, например, нагревателем или системой кондиционирования.

    ---

    Комбинированный подход: Smooth + Гистерезис для надежного управления

    Мы уже знаем две мощные техники для повышения надежности систем автоматизации:

    Наилучшего результата можно добиться, применяя эти две техники последовательно.

    > 🔗 Связанный материал: Подробная реализация алгоритма гистерезиса с примерами кода в ноде `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`
  • На этом этапе сигнал колеблется вокруг порога `20.0`, что могло бы вызвать "дребезг" реле.

  • Выход ноды `Smooth`: После получения 5-го значения нода выдаст среднее: `(19.8 + 20.1 + 19.9 + 19.7 + 20.2) / 5 = 19.94`.
  • Следующие значения на выходе `Smooth` также будут плавно меняться вокруг реальной средней температуры.

  • Вход ноды Гистерезис: На вход поступает стабильное значение `19.94`.
  • Логика гистерезиса:
  • * Текущее состояние: `ВЫКЛЮЧЕНО`.

    * Входящее значение `19.94` меньше нижнего порога `20.0`.

    * Логика принимает решение: `ВКЛЮЧИТЬ` нагреватель и изменить состояние на `ВКЛЮЧЕНО`.

    Теперь, даже если следующее "сырое" значение будет `20.1`, усредненное значение изменится незначительно (например, до `19.96`), и оно все еще будет ниже порога выключения `21.0`. Это предотвратит немедленное выключение нагревателя и обеспечит стабильную работу системы.

    ---

    Итоги и лучшие практики

    Нода `node-red-contrib-smooth` является неотъемлемым инструментом в арсенале инженера по автоматизации, работающего с платформой HI. Ее правильное применение значительно повышает надежность и предсказуемость работы всей системы.

    Что дальше

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