Практика: Flow для отключения розеток
Введение: Цели и задачи сценария "Отключение розеток"
ведение: Цели и задачи сценария "Отключение розеток"
В современной системе автоматизации энергоэффективность и безопасность являются не просто желательными, а обязательными характеристиками. Сценарий автоматического отключения розеток — один из наиболее эффективных и быстро окупаемых, позволяющий решать сразу две задачи: снижать фоновое потребление электроэнергии от приборов в режиме ожидания (stand-by) и минимизировать риски возгорания от забытых включенными бытовых приборов, таких как утюги или обогреватели.
> 💡 Связанный материал: Для полного понимания концепции рекомендуется ознакомиться с теоретическим уроком «SCN-ENERGY-001: Отключение розеток в режиме 'Away' или 'Night'», где подробно раскрыты теоретические основы и предпосылки данного сценария.
В рамках текущего практического урока мы перейдем от теории к реализации. Наша основная задача — создать надежный и масштабируемый поток (Flow) в среде Node-RED, который будет централизованно управлять группами розеток на объекте.
Ключевые аспекты, которые мы реализуем:* Режим 'Away' (Никого нет дома): Активируется, когда последний человек покинул объект. В этом режиме отключаются все некритичные потребители.
* Режим 'Night' (Ночь): Активируется, когда все легли спать. Отключаются потребители в жилых зонах (телевизоры, медиацентры, торшеры), но могут оставаться включенными, например, дежурное освещение в коридоре.
В ходе урока мы построим Flow с нуля, уделив особое внимание лучшим практикам: централизованной конфигурации, динамическому управлению устройствами и обработке исключений.
Шаг 1: Идентификация и тегирование розеток
аг 1: Идентификация и тегирование розеток
Перед тем как писать логику базового сценария энергосбережения (SCN-ENERGY-001), необходимо провести инвентаризацию и классификацию управляемых устройств. Не все розетки должны отключаться автоматически. Ошибочное отключение критичного оборудования может привести к гораздо большим проблемам, чем банальная потеря сэкономленной электроэнергии (например, к порче продуктов или остановке серверов умного дома).
Принципы классификации розеток
Все розеточные группы на объекте следует разделить как минимум на три категории:
| Категория | Описание | Примеры | Управляется сценарием? |
| --------------- | ------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | ---------------------- |
| Always-On | Критически важные потребители, отключение которых недопустимо. | Холодильник, морозильная камера, контроллер HI, сетевое оборудование (роутер, коммутатор) | Нет |
| Managed | Некритичные потребители, которые можно и нужно отключать для экономии и безопасности. | Телевизоры, аудиосистемы, зарядные устройства, настольные лампы, торшеры, бытовая техника | Да |
| Conditional | Потребители, отключаемые по особому условию (например, только в режиме 'Away', но не в 'Night'). | Компьютер, сервер (требует корректного завершения работы перед отключением питания) | Да, с доп. логикой |
На этом уроке мы сосредоточимся на категории Managed, которая составляет основную массу устройств в базовых сценариях "Ушел из дома" или "Сон".
Учет пользовательского переопределения (Override / UX)
Даже если розетка успешно отнесена к категории Managed, у пользователя всегда должна быть возможность временно отменить ее выключение (Override). Что делать, если алгоритм отрабатывает штатно, но в розетку временно включен важный медицинский прибор или идет критичная зарядка рабочего ноутбука перед командировкой? Пользователь не должен испытывать дискомфорт или бороться с автоматизацией.
Существует два основных паттерна переопределения:
> 💡 UX Практика: Реализуйте "виртуальные переключатели" (Virtual Switches) или чек-боксы в интерфейсе дашборда умного дома, позволяющие игнорировать команды автоотключения для конкретной розетки программно. В Node-RED это можно реализовать проверкой состояния дополнительного MQTT-топика: `hi/devices/outlets/bedroom_lamp_1/override`, прежде чем посылать команду на выключение в основной топик питания.
Мы спроектируем базовую систему перечисления так, чтобы в будущем этот слой логики (Override) можно было легко добавить перед финальным узлом отправки команды.
Хранение конфигурации в Global Context
Жестко прописывать MQTT-топики каждой розетки внутри узлов Flow — плохая практика. Это усложняет масштабирование и поддержку. Если на объекте добавится новая розетка, придется "хардкодить" изменения в самом Flow, рискуя сломать рабочую логику.
Правильный подход — вынести конфигурацию в глобальный контекст Node-RED (`global context`). Мы создадим JSON-массив, содержащий командные топики всех управляемых розеток категории Managed. Использование массива позволит нам позже легко перебирать элементы (итерироваться) при помощи узла `Split` или внутри `Function`.
> 💡 Подсказка: Используйте единую и понятную систему именования MQTT-топиков. Например: `hi/devices/outlets/
Пример JSON-конфигурации:
[
"hi/devices/outlets/living_room_tv/cmnd/power",
"hi/devices/outlets/living_room_audio/cmnd/power",
"hi/devices/outlets/bedroom_lamp_1/cmnd/power",
"hi/devices/outlets/bedroom_lamp_2/cmnd/power",
"hi/devices/outlets/kitchen_tv/cmnd/power",
"hi/devices/outlets/office_monitor/cmnd/power"
]
* Добавьте узел `Inject` ("On Start").
* Настройте его для однократного автоматического срабатывания при старте платформы: поставьте галочку `Inject once after 0.1 seconds, then disable flow`.
* Добавьте узел `Change` ("Set global.managed_outlets").
* Соедините `Inject` -> `Change`.
* В узле `Change` создайте правило: `Set` `global.managed_outlets` `to` (обязательно выберите тип `JSON` из выпадающего списка) и вставьте скопированный массив. По умолчанию Node-RED корректно распарсит этот массив и положит его в память в виде объектов.
(Примечание: изображение является иллюстрацией)
ASCII-схема потока инициализации:
[Inject: "On Start"] --(timestamp)--> [Change: Set global.managed_outlets]
Тестирование инициализации контекста
После добавления узлов необходимо убедиться, что переменная создана успешно.
⚠️ Чек-лист для проверки инициализации:
- [ ] Нажата кнопка Deploy.
- [ ] Узел `Inject` сработал автоматически (один раз) — на это указывает отсутствие синих точек несохраненных изменений на узлах.
- [ ] Узел `Change` не выдает синтаксических ошибок (JSON валиден). Если есть ошибка парсинга, Node-RED покажет красный треугольник.
- [ ] В боковой правой панели Node-RED во вкладке Context Data нажмите кнопку "Refresh" напротив раздела Global.
- [ ] Убедитесь, что там появилась переменная `managed_outlets` со значением типа `array[6]` (где цифра — количество добавленных вами топиков). При разворачивании массива должны быть видны корректные строковые значения MQTT-топиков.
Теперь достоверный список управляемых розеток хранится в одном месте и легко доступен из любого Flow (как внутри текущей вкладки, так и в других). Для добавления или удаления розетки из логики умного дома достаточно отредактировать JSON-структуру в узле `Change` и снова нажать Deploy. Выносить список в базу данных или внешние конфигурационные файлы можно, но для сценариев до 50–100 розеток решение через узел инициализации `Change` является оптимальным балансом между скоростью настройки и гибкостью поддержки системы.
Шаг 2: Создание Flow для отслеживания смены режимов
аг 2: Создание Flow для отслеживания смены режимов
Основой нашего сценария (согласно спецификации SCN-ENERGY-001) является реакция на смену глобальных режимов объекта. Как мы обсуждали в предыдущих курсах, для этого используется выделенный MQTT-топик, который хранит текущее состояние.
> ⚠️ Внимание: Убедитесь, что ваш MQTT-брокер корректно обрабатывает retained-флаги. Сообщение в топике `hi/state/mode` должно публиковаться с флагом `retained: true`. Это гарантирует, что после перезапуска Node-RED немедленно получит текущий режим и сможет корректно отработать логику, а не будет ждать следующей смены режима, которая может произойти через много часов.
Построение базовой цепочки
* Server: Выберите ваш MQTT-брокер.
* Topic: `hi/state/mode`
* QoS: `1` или `2` для гарантированной доставки.
* Name: `Listen System Mode`
* Property: `msg.payload` (или `msg.payload.mode`, если данные пришли в сложном JSON).
* Настройте два правила:
1. `==` `Away` (string)
2. `==` `Night` (string)
* В настройках узла выберите `checking all rules`. Это создаст два выхода. Соедините оба выхода в одну точку, так как логика отключения для обоих режимов у нас одинаковая.
* Name: `Is Away or Night?`
ASCII-схема потока: +--------------------+ +---------------------+
[MQTT In] ------- | | --- | Switch: |
(hi/state/mode) | JSON: parse string | | Is "Away" or "Night"? |
| (if payload is | +---------------------+
| JSON string) | | |
+--------------------+ | (1) | (2)
| |
v v
(Дальнейшая логика)
Входящее сообщение, например:
{
"topic": "hi/state/mode",
"payload": "Away",
"qos": 1,
"retain": true
...
}
После прохождения через узел `Switch` (по первому или второму выходу), это сообщение без изменений пойдет дальше по цепочке. Теперь у нас есть надежный триггер, который срабатывает только тогда, когда это необходимо.
UX и ручное переопределение (User Overrides)
Важно понимать логику срабатывания: наш Flow реагирует только на факт смены состояния (событийно-ориентированная архитектура с использованием триггера перехода).
Если режим сменился на `Away`, опасные розетки отключатся. Но если после этого пользователь, имея соответствующие права, вручную включит розетку через интерфейс умного дома (например, чтобы удаленно запустить мультиварку или зарядить забытый инструмент), система не будет агрессивно отключать её обратно. Розетка останется включенной до следующей смены режима, подразумевающей отключение (например, если режим сменится обратно на `Home`, а потом снова на `Away`).
Это закладывает базу для предсказуемого и комфортного User Experience: автоматизация надежно страхует пользователя в момент ухода, но не вступает в бесконечный конфликт с его прямыми командами (override). Если бы мы использовали постоянный опрос (polling) состояния (логика "Пока режим Away — жестко держать выключенным"), мы бы лишили пользователя гибкости и спровоцировали раздражение при попытках ручного управления.
Шаг 3: Динамическая отправка команд группе розеток
аг 3: Динамическая отправка команд группе розеток
На этом этапе мы реализуем "сердце" нашей автоматики. Получив сигнал о смене режима на 'Away' или 'Night' (в рамках реализации логики сценария энергосбережения SCN-ENERGY-001), Flow должен взять список управляемых розеток из `global context` и последовательно отправить каждой из них команду на отключение.
Для этого мы используем мощный паттерн Node-RED: итерация по массиву с помощью узла `Split` и динамическая отправка в MQTT.
Построение цепочки узлов
Продолжим наш Flow с выходов узла `Switch`, созданного на предыдущем шаге.
* Name: `Get Outlets List`
* Цель: Скопировать наш массив топиков из глобального контекста в текущее сообщение, чтобы с ним можно было работать дальше.
* Настройте правило: `Set` `msg.topics` `to` `global.managed_outlets`.
Важно:* мы используем новое свойство `msg.topics`, чтобы не затереть `msg.payload` (который содержит "Away" или "Night"), так как он может понадобиться для другой логики.
* Name: `Split by Topic`
* Этот узел — ключевой элемент паттерна. Он принимает на вход сообщение, находит в нем массив (в нашем случае, в `msg.topics`) и создает на выходе серию из нескольких сообщений — по одному на каждый элемент массива.
* Настройте его на работу: в поле Property укажите `msg.topics`.
* Теперь на выходе узла мы получим не одно, а шесть сообщений (согласно нашему примеру), где `msg.topics` будет содержать уже не массив, а одну строку — MQTT-топик.
* Name: `Prepare OFF Command`
* Каждое из шести сообщений, выходящих из `Split`, нужно преобразовать в правильную MQTT-команду.
* Настройте два правила:
1. `Set` `msg.topic` `to` `msg.topics`. Это действие перемещает топик назначения в стандартное свойство `msg.topic`, которое будет использоваться узлом отправки.
2. `Set` `msg.payload` `to` `OFF` (тип: String). Это формирует саму команду.
* Name: `Send OFF Command`
* Server: Выберите ваш MQTT-брокер.
* Topic: ОСТАВЬТЕ ЭТО ПОЛЕ ПУСТЫМ! Это критически важный момент. Когда поле топика в узле `MQTT Out` пусто, он берет топик назначения из свойства `msg.topic` входящего сообщения.
* QoS: `1` (гарантирует доставку команды до брокера как минимум один раз).
> 💡 UX Подсказка: Оставление поля Topic пустым в узле `MQTT Out` позволяет сделать Flow по-настоящему масштабируемым. Один узел отправки у вас может легко обслуживать десятки разных устройств, если перед ним динамически подменять `msg.topic`. Если в будущем вам потребуется учитывать ручное переопределение (Override) — например, временно исключить конкретную розетку из списка из-за работающего 3D-принтера, — вы добавите логику фильтрации перед `MQTT Out`, не дублируя сами узлы отправки.
Трансформация данных в потоке
Полная ASCII-схема Flow: (Выходы "Away"|"Night")
|
v
+-----------------------------+ +-----------------+ +-------------------------+ +------------------+
| Change: Get Outlets List | -> | Split: | -> | Change: Prepare Command | -> | MQTT Out: |
| (set msg.topics from global)| | by msg.topics | | (set topic, set payload)| | (dynamic topic) |
+-----------------------------+ +-----------------+ +-------------------------+ +------------------+
Трансформация `msg` объекта по шагам:
{
"payload": "Away",
"topics": [
"hi/devices/outlets/living_room_tv/cmnd/power",
"hi/devices/outlets/living_room_audio/cmnd/power",
"..."
]
}
{
"payload": "Away",
"topics": "hi/devices/outlets/living_room_tv/cmnd/power",
"parts": { "index": 0, "count": 6, "id": "..." }
}
{
"topic": "hi/devices/outlets/living_room_tv/cmnd/power",
"payload": "OFF",
"topics": "hi/devices/outlets/living_room_tv/cmnd/power",
"parts": { "index": 0, "count": 6, "id": "..." }
}
Это сообщение поступает в узел `MQTT Out`, и брокер отправляет команду по адресу `hi/devices/outlets/living_room_tv/cmnd/power` с телом `OFF`. Затем то же самое автоматически происходит для остальных пяти топиков.
План проверки шага (Тест-план)
Чтобы убедиться в правильности отработки динамической рассылки, выполните следующие проверки до начала интеграции с реальными устройствами:
- [ ] К выходу узла `Prepare OFF Command` подключите проверочный узел `Debug`, настроенный на вывод `complete msg object`.
- [ ] Сымитируйте через `Inject` переключение системы в режим `Away`.
- [ ] Убедитесь, что каждое финальное сообщение перед входом в `MQTT Out` содержит свойство `msg.topic` со строковым адресом конкретной розетки и свойство `msg.payload` со значением `OFF`.
- [ ] Используя MQTT Explorer, удостоверьтесь, что при отправке команды брокер получает столько сообщений OFF, сколько розеток указано в массиве.
Шаг 4: Реализация исключений и ручного управления
аг 4: Реализация исключений и ручного управления
Автоматизация не должна быть абсолютной диктатурой. Всегда могут возникнуть ситуации, когда пользователю нужно временно нарушить правила. Например, в режиме 'Away' один из членов семьи вернулся домой раньше, а система еще не перешла в 'Home'. Он включает телевизор, а через минуту автоматика его снова выключает. Это создает крайне негативный пользовательский опыт (UX), приводит к конфликту между пользователем и алгоритмами (снижая так называемый WAF — Wife/Family Acceptance Factor) и подрывает доверие к умному дому.
> ℹ️ Информация: Существуют разные стратегии обработки ручного управления (User Override). Можно полностью игнорировать ручные действия до следующей смены режима, вводить таймер таймаута (например, автоматика выключит устройство снова только через 30 минут) или применять механизмы принудительной изоляции устройства из пула автоматики. Мы рассмотрим самый простой и надежный UX-паттерн — глобальную блокировку этого сценария до следующей естественной смены режима.
Концепция "флага-блокировки" (Override Flag)
Идея заключается в том, чтобы создать временный "флаг" в контексте Flow, который сигнализирует: "пользователь вмешался, временно приостановить автоматику для управляемых устройств".
Использование контекста `flow` (а не `global`) — отличный подход, так как блокировка затрагивает только конкретный сценарий работы розеток, не нарушая работу климата, безопасности и других систем.
Нам нужен отдельный небольшой Flow, который слушает фактическое состояние* розеток (статус железа), а не команды из дашбордов.
* Создайте узел `MQTT In` и подпишите его на топик с wildcard: `hi/devices/outlets/+/stat/power`. Он будет получать сообщения о смене состояния от всех розеток.
* Если сообщение `ON` пришло в тот момент, когда система находится в режиме 'Away' или 'Night', это означает явное ручное вмешательство, так как автоматика сама такого сделать не могла.
* При обнаружении ручного включения мы устанавливаем флаг в `flow context`. Например `flow.manual_override = true`.
* Этот флаг будет действовать как стоп-сигнал для нашего основного сценария. В основном Flow, перед отправкой команды `OFF`, мы должны добавить узел `Switch`, который проверяет: `if (flow.manual_override === true)`, то поток останавливается и устройства не выключаются.
* Когда блокировка должна сниматься? Самый логичный и предсказуемый для пользователя момент сброса Override — при смене системного режима на дневной.
* В нашем основном Flow (из Шага 2) вернемся к первому узлу `Switch`, который фильтрует режимы. Добавим к нему еще один выход для всех остальных режимов (например, 'Home').
* Соединим этот выход с узлом `Change`, который будет выполнять действие: `Set` `flow.manual_override` `to` `false`.
* Таким образом, как только система переходит в штатный режим 'Home', все блокировки снимаются, и при следующей активации 'Away' сценарий отработает в полную силу.
Практическая реализация флага-блокировки
Давайте посмотрим, как это реализуется в Node-RED с помощью конкретных потоков и кода.
1. Поток для отслеживания ручного включения и установки флагаЭтот вспомогательный поток слушает состояние всех управляемых розеток. Если одна из них включается вручную (payload = "ON"), когда система находится в режиме 'Away' или 'Night', он устанавливает флаг блокировки.
ASCII-схема потока:[MQTT In: Outlet States] --(msg)--> [Switch: Is payload ON?] --(msg)--> [Function: Check Mode & Set Flag]
`hi/.../+/stat/power` `msg.payload == "ON"`
Код для узла `Function` ("Check Mode & Set Flag"):
// Предполагается, что другой поток обновляет global.system_mode при смене режима.
const current_mode = global.get("system_mode") || "Unknown";
// Устанавливаем флаг, только если система в "спящем" режиме ('Away' или 'Night')
if (current_mode === "Away" || current_mode === "Night") {
flow.set("manual_override", true);
node.warn("Обнаружено ручное включение. Автоматика приостановлена до смены режима.");
// Ничего не возвращаем, т.к. этот поток только устанавливает флаг.
}
return null;
2. Модификация основного потока для проверки и сброса флага
Теперь нужно изменить наш главный Flow. Во-первых, он должен проверять флаг перед отключением розеток. Во-вторых, он должен сбрасывать этот флаг при переходе в "активный" режим (например, 'Home').
Измененная ASCII-схема основного потока: +-> (выходы "Away"|"Night") --> [Function: Check Flag] --> (дальнейшая логика)
|
[MQTT In: System Mode] --> [Switch: Is Away or Night?]
(hi/state/mode) |
+-> (выход "otherwise") --> [Change: Reset Flag]
(set flow.manual_override to false)
- В узле `Switch` теперь должна быть опция "otherwise", которая направляет все остальные режимы ('Home', 'Cleaning' и т.д.) на сброс флага.
- Узел `Change` ("Reset Flag") настраивается просто: `Set` `flow.manual_override` `to` (boolean) `false`.
Этот узел ставится сразу после выходов "Away" и "Night" узла `Switch` и перед узлом `Change: Get Outlets List`.
// Проверяем, установлен ли флаг ручного вмешательства
if (flow.get("manual_override") === true) {
node.log("Обнаружен флаг ручного вмешательства. Отключение розеток пропущено.");
return null; // Прерываем выполнение потока, не давая ему дойти до отключения
}
// Если флага нет, пропускаем сообщение дальше без изменений
return msg;
С такой реализацией система становится умнее: она выполняет свою основную задачу, но уважает действия пользователя, временно отступая, если он вручную включил какой-либо прибор через физическую кнопку, приложение или голосового ассистента.
Чек-лист и тест-план проверки флага-блокировки
Чтобы убедиться, что логика обработки ручного вмешательства работает безотказно и не вызывает раздражения пользователей, проведите следующие тесты через интерфейс Node-RED и MQTT-клиент:
- [ ] Тест 1 (Перехват ручного управления): Переведите систему в режим 'Away'. Дождитесь отключения розеток (стандартная логика). Физически (или через прямое MQTT-сообщение) переведите одну розетку в состояние `ON`. Убедитесь, что отработал узел `Check Mode & Set Flag`, и в панели Debug появилось предупреждение об остановке автоматики.
- [ ] Тест 2 (Удержание состояния): Находясь в режиме 'Away' со взведенным флагом, сымитируйте переотправку статуса 'Away' в топик режима (например, это может произойти при перезагрузке контроллера). Убедитесь, что узел `Check Flag` корректно прерывает поток, устройство не получает команду `OFF`, и розетки остаются во включенном состоянии.
- [ ] Тест 3 (Корректный сброс): Переведите систему обратно в режим 'Home'. Проверьте вкладку Context Data (раздел `flow`) в правой панели Node-RED: переменная `manual_override` должна переключиться на `false`.
- [ ] Тест 4 (Повторное срабатывание автоматики): Снова активируйте режим 'Away'. Убедитесь, что на этот раз устройства, ранее активированные вручную, корректно отключаются системой, поскольку блокирующий флаг был предварительно снят.
- [ ] Тест 5 (UX-исключение для ручного выключения): Находясь в 'Away', сымитируйте отправку `OFF` от одной из розеток (ситуация: кто-то вспомнил и выключил за собой свет). Убедитесь, что флаг `manual_override` не взводится (логика реагирует только на `ON`).
Стоит еще раз подчеркнуть, что лучшая "обработка исключений" — это правильное предварительное проектирование системы. Как обсуждалось в уроке по спецификации сценария SCN-ENERGY-001, устройства из категории 'Always-On' (холодильники, сетевые роутеры, сервера, системы NAS) никогда не должны попадать в массив `global.managed_outlets`. Логика ручного управления предназначена исключительно для временных вмешательств пользователя (например, досмотреть фильм или дождаться окончания стирки), а не для постоянной компенсации недочетов в программной архитектуре умного дома.
Итоги и дальнейшие улучшения
тоги и дальнейшие улучшения
В рамках этого практического урока мы создали полнофункциональный, надежный и масштабируемый сценарий управления розетками. Мы не просто решили задачу, но и сделали это, следуя лучшим инженерным практикам Node-RED.
Давайте кратко резюмируем созданный Flow и ключевые паттерны:Чек-лист проверки итогового решения
Перед тем как переносить данный Flow в «боевую» эксплуатацию, проверьте себя по следующим пунктам:
- [ ] Конфигурация: Массив топиков розеток задается в одном месте и имеет правильный синтаксис (без опечаток в путях MQTT).
- [ ] Маршрутизация: Узел `Switch` корректно отсеивает нецелевые режимы (пропускает только 'Away' и 'Night').
- [ ] Масштабирование: Узел `Split` настроен на разбиение массива (длина 1), а `Change` корректно формирует `msg.topic` перед отправкой в MQTT.
- [ ] Блокировки: Логика с `manual_override` (если реализована) сбрасывается по таймауту, чтобы розетка не зависла в заблокированном состоянии навсегда.
Идеи для дальнейшего расширения функционала
Уведомления: После цепочки отправки команд можно добавить узел `telegram sender` (или аналог), который отправит push-уведомление на смартфон: "Активирован режим 'Away'. Отключено 6 некритичных розеток."* Задержка перед отключением: Вместо немедленного отключения используйте узел `Trigger`. При активации 'Away' система может сначала отправлять уведомление "Внимание! Розетки будут обесточены через 1 минуту"*, и только затем отправлять команды `OFF`. Это дает домочадцам окно времени для отмены действия.- Визуальный интерфейс: Вывести в Dashboard кнопку «Отменить отключение розеток», которая программно выставляет `flow.manual_override` в `true` на заданное время (например, на 2 часа).
- Разделение логики для 'Away' и 'Night': Сейчас оба режима приводят к одинаковому действию. Их можно разделить, используя узел `Switch` с двумя выходами: например, для 'Night' применять отдельный массив `global.night_managed_outlets`, который не обесточивает розетки в кабинете или на кухне.
Что дальше?
Освоив управление группами потребителей по событиям, мы готовы перейти к более сложным сценариям энергоменеджмента. В следующем практическом уроке мы будем реализовывать сценарий управления пиковой нагрузкой (SCN-ENERGY-001), который позволяет избежать отключения вводного автомата на объекте путем динамического временного отключения самых мощных, но неприоритетных потребителей.