ГлавнаяАкадемияСценарии умного дома: режимы, состояния, приоритеты → Техника 'Задержка на включение/выключение' (Delay On/Off)

Техника 'Задержка на включение/выключение' (Delay On/Off)

Урок 1 · Сценарии умного дома: режимы, состояния, приоритеты · 30 мин · theory

Введение в стабилизацию состояний: Задержка On/Off

ведение в стабилизацию состояний: Задержка On/Off

В процессе создания систем автоматизации мы неизбежно сталкиваемся с проблемой нестабильных или "шумных" сигналов. Как мы подробно рассмотрели в предыдущих уроках, это явление, известное как дребезг (flapping), может быть вызвано самыми разными причинами: от физических вибраций на датчике до кратковременных помех в сети. Последствия такого дребезга могут быть крайне неприятными — от мерцающего света до постоянно включающегося и выключающегося насоса, что приводит к износу оборудования и высокому энергопотреблению.

Для борьбы с этим фундаментальным недостаком цифровых систем существуют программные методы стабилизации. Ключевыми из них являются техники 'Задержка на включение' (Delay On) и 'Задержка на выключение' (Delay Off). Это базовые, но чрезвычайно мощные инструменты в арсенале инженера по автоматизации, позволяющие отфильтровать ложные срабатывания и сделать поведение системы предсказуемым и надежным.

🔗 Связанный материал: Мы подробно разбирали природу и источники 'дребезга' в уроке Модуля 4 (Очистка данных). Рекомендуется ознакомиться с ним перед изучением данного материала.

По своей сути, эти техники являются программной реализацией аппаратного механизма подавления дребезга (`debouncing`), который используется в электронике для обработки сигналов от физических кнопок. Когда вы нажимаете кнопку, внутри нее происходит серия микроскопических замыканий и размыканий контакта, прежде чем он установится в стабильное положение. Аппаратный `debounce` игнорирует эти быстрые колебания, регистрируя только первое устойчивое состояние.

Мы переносим этот же принцип на уровень логики контроллера. Вместо того чтобы немедленно реагировать на каждое изменение входного сигнала (от датчика движения, геркона, статуса сетевого устройства), система берет паузу и проверяет: "Действительно ли это изменение является стабильным и преднамеренным?".

Практические рекомендации по настройке задержек

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

| Тип датчика / Событие | Рекомендуемая задержка On | Рекомендуемая задержка Off | Цель настройки |

| :--- | :--- | :--- | :--- |

| Движение (PIR) | 0.5 – 1 сек. | 2 – 10 мин. | Исключение ложных бликов (On) и сохранение света, пока человек малоподвижен (Off). |

| Протечка воды | 2 – 5 сек. | 0 – 10 сек. | Фильтрация брызг или случайного касания мокрой тряпкой при уборке. |

| Датчик CO2 / Влажности | 30 – 60 сек. | 5 – 15 мин. | Предотвращение «тактования» вытяжки при колебаниях около порогового значения. |

| Геркон (Дверь/Окно) | 0.2 – 0.5 сек. | 1 – 2 сек. | Защита от вибраций рамы и кратковременных открытий (сквозняк). |

| Статус On-line (Ping) | 5 – 10 сек. | 30 – 120 сек. | Игнорирование микро-сбоев в Wi-Fi сети или перезагрузки роутера. |

Применение этих задержек позволяет отсечь весь "шум": кратковременные сигналы, случайные пики, мимолетные триггеры. В результате система реагирует только на значимые события, что кардинально повышает ее стабильность и надежность.

Практика: 'Задержка на включение' (Delay On) в Node-RED

рактика: 'Задержка на включение' (Delay On) в Node-RED

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

Основным инструментом для реализации этой логики в Node-RED является стандартный узел `trigger`.

Пошаговая настройка узла 'trigger' для Delay On

Конфигурация узла `trigger` для реализации задержки на включение интуитивно понятна. Мы настраиваем его так, чтобы он "подумал" перед тем, как отдать команду.

  • Первое действие (`Send`): В поле "Отправить" устанавливаем значение `ничего` (`nothing`). Это означает, что при получении первого сообщения узел не будет ничего передавать дальше, а просто запустит свой внутренний таймер.
  • Ожидание (`Then wait for`): Устанавливаем необходимую временную задержку. Например, `2 секунды`. Это время, в течение которого узел будет ожидать, проверяя стабильность сигнала.
  • Итоговое действие (`Then send`): В этом поле выбираем `последнее сообщение` (`the latest message`). Если за время ожидания не пришло никаких новых сообщений, сбрасывающих таймер, узел отправит дальше то самое последнее сообщение, которое он получил.
  • Сброс таймера: Убедитесь, что активирована опция "Продлить задержку, если придет новое сообщение" (`Extend delay if new message arrives`). Это позволит таймеру перезапускаться при каждом новом сигнале, и команда на включение будет отправлена только после того, как поток сигналов прекратится на установленное время (что нетипично для Delay On) или, что более правильно, когда таймер наконец отсчитает свое время после первого сигнала.
  • 💡 Подсказка: Выбор времени задержки — это компромисс. Слишком короткая задержка не решит проблему 'дребезга', а слишком длинная может негативно сказаться на пользовательском опыте.

    Рекомендованные значения задержек

    Для разных типов датчиков и систем автоматизации время "проверки намерения" (Delay On) и время "удержания" (Delay Off) существенно различается:

    | Тип датчика / Сценарий | Задержка (Delay On) | Цель фильтрации | Примечание |

    | :--- | :--- | :--- | :--- |

    | Датчик движения | 0.5 – 2 сек | Кратковременные проходы, домашние животные | Выше 3с вызывает дискомфорт ("тупит") |

    | Протечка воды | 1 – 3 сек | Случайные брызги при уборке, конденсат | Не ставить большие значения (критично) |

    | Датчик CO2 / Влажность | 30 – 120 сек | Реакция на выдох рядом, открытие двери | Газы перемешиваются медленно |

    | Датчик освещенности | 10 – 30 сек | Облачность, тени от птиц/деревьев | Предотвращает "дискотеку" штор |

    | Геркон (дверь/окно) | 0.5 – 1 сек | Дребезг контактов, неплотное закрытие | Убирает ложные срабатывания охраны |

    Практический кейс: Фильтрация кратковременного движения

    Рассмотрим сценарий для гостиной, где установлен датчик движения. Мы хотим, чтобы свет включался, только если в зоне детекции есть активность дольше 2 секунд. Это позволит игнорировать быстрые перемещения, например, пробежавшего кота.

    Схема потока:
    [MQTT In]──────────>[trigger]──────────>[rbe]──────────>[MQTT Out]
    

    `hi/sensors/motion/living-room` (Wait 2s) (Block duplicates) `hi/lights/switch/living-room`

    Анализ работы потока:
  • Датчик движения (например, `lumi.sensor_motion.aq2`) отправляет в топик `hi/sensors/motion/living-room` сообщение, соответствующее нашему контракту данных:
  •     {

    "value": true,

    "source": "motion-livingroom-01",

    "ts": 1678886400000

    }

  • Узел `MQTT In` принимает это сообщение.
  • Узел `trigger` (настроенный для 'Delay On' на 2 секунды) получает сообщение. Он ничего не отправляет и запускает таймер на 2 секунды.
  • * Сценарий A (ложный триггер): Через 1 секунду датчик перестает видеть движение и присылает `{"value": false, ...}`. Узел `trigger` получает это новое сообщение и сбрасывает свой таймер. В итоге ни одно сообщение не проходит дальше. Задача фильтрации выполнена.

    * Сценарий B (устойчивый триггер): В течение 2 секунд никаких новых сообщений не приходит (или приходят такие же `{"value": true, ...}`, которые продлевают таймер, но для Delay On это менее актуально). По истечении 2 секунд узел `trigger` берет последнее полученное сообщение (`{"value": true, ...}`) и отправляет его дальше по потоку.

  • Узел `rbe` (`report-by-exception`) получает сообщение. Он проверяет, не отправлял ли он такое же значение (`true`) ранее. Если свет уже включен, `rbe` заблокирует дублирующую команду, предотвращая лишнюю нагрузку на исполнительное устройство и сеть.
  • Узел `MQTT Out` публикует команду на включение в топик `hi/lights/switch/living-room`, и свет включается.
  • Таким образом, мы построили надежный сценарий, который не реагирует на мимолетные события, а срабатывает только на намеренное и продолжительное присутствие.

    Практика: 'Задержка на выключение' (Delay Off) для удержания состояния

    `Задержка на выключение` решает другую, но не менее важную задачу — удержание состояния. Классический пример — свет в проходных зонах или санузлах. Он должен включаться мгновенно, но выключаться не сразу после того, как человек покинул помещение, а спустя некоторое время. Это обеспечивает комфорт и предотвращает ситуацию, когда свет гаснет, если человек на несколько секунд замер на месте.

    Для этой логики мы также используем узел `trigger`, но конфигурируем его иначе.

    Конфигурация узла 'trigger' для сброса таймера

    Ключевой элемент этой логики — способность таймера перезапускаться.

  • Прием сообщения "ВКЛЮЧИТЬ": Узел `trigger` настроен так, чтобы при получении определенного сообщения (например, `{"payload": true}`) он немедленно отправлял команду на включение, но при этом также сбрасывал любой активный таймер на выключение.
  • Прием сообщения "ВЫКЛЮЧИТЬ": При получении "выключающего" сообщения (например, `{"payload": false}`), узел `trigger` не отправляет команду сразу. Вместо этого он запускает таймер на заданное время (например, 3 минуты).
  • Сброс таймера: Если во время этого трехминутного ожидания снова приходит сообщение "ВКЛЮЧИТЬ", узел `trigger` должен сбросить таймер на выключение и снова продлить состояние "Включено". Это делается либо активацией опции `Extend delay if new message arrives`, либо отправкой специального сбрасывающего сообщения (например, `msg.reset = true`).
  • ⚠️ Внимание: Неправильная конфигурация сброса таймера — частая ошибка. Если узел `trigger` не настроен на продление или сброс задержки (`Extend delay` или обработка `msg.reset`), он отправит команду на выключение по истечении таймера, даже если за это время человек снова появился в зоне видимости датчика.

    Практический кейс: Освещение в санузле

    Задача: свет в санузле включается мгновенно при детекции движения. После того, как датчик перестал детектировать движение, свет должен гореть еще 3 минуты и только потом выключиться. Если за эти 3 минуты движение будет обнаружено снова, таймер должен сброситься.

    Схема потока:
    // Датчик присылает true при движении и false, когда движение прекратилось.
    

    [MQTT In: `.../presence/bathroom`] ---> [trigger: Send ON, wait 3 mins, Send OFF] ---> [rbe] ---> [MQTT Out: `.../light/bathroom`]

    Анализ работы потока:
  • Узел `trigger` сконфигурирован следующим образом:
  • * Отправить (`Send`): сообщение `{"payload": true}`.

    * Затем (`Then`): `подождать` (`wait for`) `3 минуты`.

    * Отправить (`Then send`): сообщение `{"payload": false}`.

    * Опция `Extend delay if new message arrives` активирована.

    * Входящее сообщение: ожидается `{"value": true}` от датчика.

  • Шаг 1: Человек входит в санузел.
  • Датчик отправляет `{"value": true}`.

    Узел `trigger` немедленно отправляет дальше по потоку `{"payload": true}` (так как это его первое действие). Свет включается. Одновременно запускается таймер на 3 минуты, по истечении которого будет отправлено `{"payload": false}`.

  • Шаг 2: Человек двигается в санузле.
  • Датчик периодически присылает новые сообщения `{"value": true}`. Каждое такое сообщение, поступая в узел `trigger`, перезапускает трехминутный таймер благодаря опции `Extend delay...`. Свет продолжает гореть.

  • Шаг 3: Человек выходит из санузла.
  • Датчик перестает присылать сообщения `{"value": true}`. Таймер, запущенный последним таким сообщением, продолжает тикать.

  • Шаг 4: Выключение света.
  • Проходит 3 минуты с момента последнего детектированного движения. Таймер в узле `trigger` завершается. Узел выполняет свое второе действие — отправляет сообщение `{"payload": false}`. Узел `rbe` пропускает его (так как предыдущее состояние было `true`), и команда на выключение уходит в `MQTT Out`. Свет гаснет.

    Этот паттерн чрезвычайно эффективен и является основой для 90% сценариев управления освещением по датчикам движения или присутствия.

    ---

    Продвинутый пример: Управление климатом (HVAC) с комбинированной задержкой

    Объединение техник 'Delay On' и 'Delay Off' позволяет создавать сложные и надежные сценарии для управления дорогостоящим оборудованием, таким как климатические установки (HVAC). Это защищает оборудование от износа и повышает комфорт в помещении.

    Кейс: Управляем кондиционером в офисном помещении через Modbus RTU с помощью контроллера HI. Данные о температуре поступают с высокоточного MQTT-датчика. Уставка — 24.0°C.

    ℹ️ Информация: В данном примере критически важно использовать узел `RBE` ('Report by Exception') после логики задержек, чтобы отправлять на шину Modbus команды только при реальном изменении требуемого состояния (ВКЛ/ВЫКЛ). Это многократно снижает нагрузку на шину и ведомое устройство.

    Логика 'Delay On': Защита от ложных включений

    Проблема: Температура в комнате — 24.1°C. Формально, нужно включать кондиционер. Но это может быть кратковременный скачок из-за того, что рядом поставили горячий чайник. Частое включение/выключение компрессора (тактование) — главный враг любого кондиционера. Решение: Включаем кондиционер, только если температура держится выше уставки (например, > 24.2°C) в течение 5 минут.

    Логика 'Delay Off': Предотвращение коротких циклов (Short-Cycling)

    Проблема: Кондиционер охладил воздух до 23.9°C и сразу выключился. Через 2 минуты температура из-за притока тепла снова стала 24.1°C, и он снова включился. Такие короткие циклы неэффективны и вредны для оборудования. Решение: После достижения целевой температуры (например, < 23.8°C), кондиционер не выключается мгновенно, а продолжает работать еще 3 минуты. Это позволяет более равномерно охладить помещение и его массивные элементы (стены, мебель), создавая "буфер холода".

    Сборка комплексного потока

    Поток будет состоять из нескольких ключевых узлов, реализующих эту логику.

                                                ┌─("start_cooling")─>[trigger: Delay ON 5m]─┐
    

    │ │

    [MQTT In: temp] -> [function: HVAC Logic] ──┤ ├─>[function: Format Modbus]─>[rbe]─>[Modbus Write]

    │ │

    └─("stop_cooling")──>[trigger: Delay OFF 3m]─┘

  • Узел `function: HVAC Logic`:
  • * Получает температуру с MQTT-датчика.

    * Сравнивает ее с уставкой (например, `flow.setpoint = 24.0`).

    * Имеет два выхода.

    * Логика:

            const currentTemp = msg.payload.value;

    const setpoint = flow.get("hvac_setpoint") || 24.0;

    // Гистерезис для предотвращения дребезга вокруг уставки

    const upperThreshold = setpoint + 0.2; // 24.2°C

    const lowerThreshold = setpoint - 0.2; // 23.8°C

    if (currentTemp > upperThreshold) {

    // Условие для ЗАПУСКА охлаждения

    return [{payload: "start_cooling"}, null];

    } else if (currentTemp < lowerThreshold) {

    // Условие для ОСТАНОВКИ охлаждения

    return [null, {payload: "stop_cooling"}];

    }

    // В "мертвой зоне" ничего не делаем

    return null;

  • Верхняя ветка (`trigger: Delay ON 5m`):
  • * Настроена как в первом примере: `send nothing`, `wait 5 minutes`, `send latest message`.

    * Фильтрует кратковременные команды `start_cooling`.

  • Нижняя ветка (`trigger: Delay OFF 3m`):
  • * Настроена аналогично, но для команды `stop_cooling`: `send nothing`, `wait 3 minutes`, `send latest message`.

    * Удерживает выключение кондиционера на 3 минуты.

  • `function: Format Modbus`:
  • * Принимает сообщения `"start_cooling"` или `"stop_cooling"`.

    * Формирует `msg.payload` для узла `Modbus-Write` для записи в нужный регистр (например, Holding Register) значения `1` (ВКЛ) или `0` (ВЫКЛ).

  • `rbe` и `Modbus Write`:
  • * `rbe` гарантирует, что на шину Modbus будет отправлена только одна команда `ВКЛ` и одна команда `ВЫКЛ`, а не поток однотипных команд каждую секунду.

    * `Modbus Write` исполняет команду.

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

    ---

    Итоги и лучшие практики применения задержек

    Техники 'Задержка на включение' и 'Задержка на выключение' являются краеугольным камнем при построении стабильных и предсказуемых систем автоматизации. Они позволяют отделить реальные, намеренные события от случайного "шума" датчиков и триггеров.

    Ключевые различия: Delay On (Задержка на включение): Используется для фильтрации ложных срабатываний на входе. Действие выполняется только после того, как условие сохраняется в течение N секунд. Пример: не включать свет от пробежавшего кота.* Delay Off (Задержка на выключение): Используется для удержания состояния на выходе. Действие отменяется не сразу, а по истечении N секунд после пропадания поддерживающего сигнала. Пример: свет в коридоре гаснет через 2 минуты после ухода человека.*

    Основные рекомендации:

  • Начинайте с малого: При настройке задержек начинайте с небольших значений (0.5-2 секунды) и наблюдайте за поведением системы и реакцией пользователей. Постепенно увеличивайте время, если это необходимо.
  • Документируйте логику: Всегда добавляйте комментарии или подробные описания к узлам `trigger` в Node-RED. Указывайте, какую задержку (On/Off) вы реализуете и почему выбрано именно такое время (`// Delay OFF 3 min для комфортного выхода из санузла`).
  • Оценивайте влияние на UX: Помните, что любая задержка влияет на пользовательский опыт. Задержка на включение света более 1-2 секунд может вызывать раздражение. Задержка на выключение, наоборот, чаще всего повышает комфорт. Находите баланс.
  • Фильтруйте избыточные команды: Всегда используйте узел `rbe` после логики задержек, особенно перед отправкой команд на физические шины (Modbus, CAN, DALI, KNX) или на исполнительные реле. Это снижает износ оборудования и предотвращает перегрузку сетей ненужными данными.
  • Освоив эти две простые, но мощные техники, вы сможете значительно повысить качество и надежность создаваемых вами сценариев автоматизации.

    Что дальше

    Мы научились бороться с дребезгом и удерживать простые состояния с помощью задержек. В следующем уроке мы перейдем к еще более мощному инструменту управления сложными сценариями — конечным автоматам (Finite State Machines). Это позволит нам создавать системы с множеством состояний и строгими правилами перехода между ними, такие как комплексное управление режимами "День/Ночь/Нет дома" или работа системы безопасности.