ГлавнаяАкадемияСценарии умного дома: режимы, состояния, приоритеты → SCN-SAFETY-014: Имитация присутствия в режиме 'Отпуск'

SCN-SAFETY-014: Имитация присутствия в режиме 'Отпуск'

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

Введение в сценарий 'Имитация присутствия'

Сценарий «Имитация присутствия» (SCN-SAFETY-014) — это один из ключевых элементов проактивной системы безопасности умного дома. Его основная цель — не реагировать на вторжение, а предотвратить его, создавая у наблюдателя со стороны устойчивое впечатление, что в доме или квартире находятся люди. В криминальной психологии известно, что большинство злоумышленников ищут легкие и безопасные цели — пустующие объекты, где риск быть замеченным минимален. Данный сценарий напрямую работает против этого фактора, делая объект менее привлекательным для вторжения.

Основной принцип работы заключается в автоматическом управлении различными системами дома по расписанию, которое выглядит реалистичным, но при этом является непредсказуемым. В отличие от простых таймеров, которые включают свет ровно в 19:00 и выключают в 23:00, профессиональный сценарий имитации присутствия использует элементы случайности, чтобы избежать легко вычисляемых паттернов.

> 💡 Подсказка: Начните с малого. Даже простое включение/выключение света в двух-трех комнатах по вечерам значительно повышает эффективность сценария по сравнению с полным бездействием. Главное — нарушить статичную картину пустого дома.

Ключевым фактором эффективности является рандомизация и вариативность. Сценарий должен создавать видимость естественной, немного хаотичной человеческой деятельности:

В экосистеме автоматизации контроллера HI этот сценарий не работает постоянно. Он является частью логики верхнего уровня и активируется только при выполнении двух условий:

  • Система переведена в глобальный режим «Отпуск» (Vacation).
  • Наступило темное время суток (например, после заката) или утренние часы.
  • Таким образом, сценарий является составной частью более крупного конечного автомата безопасности, который мы рассматривали в предыдущих модулях. Он не заменяет датчики движения, открытия окон или камеры, а дополняет их, работая на первом, превентивном рубеже обороны.

    ---

    Проектирование логики: состояния, таймеры и триггеры

    Перед тем как приступить к реализации в Node-RED, необходимо тщательно спроектировать логику сценария. Качественное проектирование — залог создания эффективной и реалистичной симуляции, а не простого "мигания лампочками".

    Логические периоды суток

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

    | Период | Временной интервал | Характер активности в симуляции |

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

    | Утро | 06:30 – 09:00 | Имитация пробуждения и утренних сборов. Умеренная активность. |

    | День | 09:00 – 18:00 | Минимальная активность или ее полное отсутствие. Имитация того, что жильцы на работе или ушли по делам. |

    | Вечер | 18:00 – 23:30 | Наиболее активная фаза симуляции. Имитация возвращения домой, ужина, отдыха, подготовки ко сну. |

    | Ночь | 23:30 – 06:30 | Активность отсутствует. Все системы находятся в состоянии покоя, за исключением дежурного освещения, если оно предусмотрено. |

    Сценарий «Имитация присутствия» будет активен преимущественно в периоды «Утро» и «Вечер».

    > ⚠️ Внимание: Избегайте жестко заданных временных интервалов (например, 'включать свет ровно в 19:00'). Это делает симуляцию предсказуемой. Используйте узлы, генерирующие случайное время в заданном диапазоне, например, 'включить свет между 19:00 и 20:15'.

    Триггеры и события

    Основным триггером для запуска действий будет таймер со случайным интервалом. Например, «каждые 15-45 минут выполнять одно случайное действие». В качестве дополнительных, более продвинутых триггеров можно использовать астрономические события, доступные во многих библиотеках Node-RED (например, `node-red-contrib-sun-position`):

    Устройства-участники

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

    Разработка «подсценариев»

    Для каждого активного периода («Утро», «Вечер») создается свой набор возможных действий.

    Подсценарий «Утро» (06:30 - 09:00):
  • Начало: Плавное открытие штор в спальне на 30-50%.
  • Действие 1: Через 5-15 минут включение света в спальне на неполную яркость (40%).
  • Действие 2: Через 10-25 минут выключение света в спальне и включение на кухне.
  • Действие 3: Через 20-40 минут выключение света на кухне.
  • Конец: Полное открытие штор в гостиной.
  • Подсценарий «Вечер» (18:00 - 23:30):
  • Начало (после заката): Закрытие штор в гостиной и спальне.
  • Действие 1: Включение основного света в гостиной.
  • Действие 2: Через 20-60 минут включение телевизора (командой по MQTT).
  • Действие 3: Выключение основного света и включение торшера (другая группа света).
  • Действие 4: Через 30-70 минут выключение телевизора.
  • Действие 5: Свет в гостиной гаснет, включается в коридоре, затем в спальне.
  • Конец: Все огни гаснут.
  • Каждое действие и каждая задержка между ними должны быть случайными в заданных пределах.

    > 💡 Подготовка: Для выполнения практической части этого урока убедитесь, что у вас установлены следующие узлы через `Manage palette`: `node-red-contrib-cron-plus` и `node-red-contrib-random-timer`.

    ---

    Реализация в Node-RED: ядро сценария

    Теперь переведем спроектированную логику в поток Node-RED. Для этого нам понадобятся дополнительные узлы (палитры), которые можно установить через `Manage palette`: `node-red-contrib-cron-plus` и `node-red-contrib-random-timer`.

    Запуск по расписанию с `cron-plus`

    Узел `cron-plus` является мощным планировщиком, который позволит нам запускать сценарий только в нужные периоды. Мы создадим два таких узла: один для "Вечера" и один для "Утра".

    Настройка узла `cron-plus` для "Вечернего" сценария: - `Expression`: `/20 18-23 ` (Каждые 20 минут с 18:00 до 23:59, каждый день).

    Создание непредсказуемых задержек с `random-timer`

    Чтобы действия не происходили с фиксированным интервалом в 20 минут (как в cron-выражении), мы добавляем элемент случайности.

  • Сразу после узла `cron-plus` ставим узел `random-timer`.
  • Настройка `random-timer`:
  • - Timeout: `random`

    - From: `1` To: `15`

    - Units: `Minutes`

  • Теперь поток будет запускаться не сразу, а со случайной задержкой от 1 до 15 минут после каждого срабатывания `cron-plus`. Это полностью ломает предсказуемый 20-минутный паттерн.
  • "Бассейн" устройств и действий в узле `function`

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

    // Узел Function: "Выбор случайного действия"
    
    

    // 1. Определяем "бассейн" устройств-участников.

    // Каждый объект описывает устройство и возможные команды.

    const devices = [

    {

    id: "light-livingroom-main",

    type: "knx-light",

    actions: [

    { command: "ON", payload: { value: true } },

    { command: "OFF", payload: { value: false } },

    { command: "DIM_70", payload: { value: 70, dpt: "5.001" } }

    ]

    },

    {

    id: "light-kitchen-spot",

    type: "dali-light",

    actions: [

    { command: "ON", payload: { brightness: 254 } },

    { command: "OFF", payload: { brightness: 0 } }

    ]

    },

    {

    id: "blinds-bedroom",

    type: "modbus-blinds",

    actions: [

    // Для штор обычно нет простого "ON/OFF", а есть позиция.

    { command: "CLOSE", payload: { value: 0 } }, // 0% - закрыто

    { command: "OPEN_HALF", payload: { value: 50 } } // 50% - приоткрыто

    ]

    },

    {

    id: "tv-livingroom",

    type: "mqtt-media",

    topic: "hi/living_room/tv/cmnd/POWER",

    actions: [

    { command: "ON", payload: "ON" },

    { command: "OFF", payload: "OFF" }

    ]

    }

    ];

    // 2. Выбираем случайное устройство из бассейна

    const randomDeviceIndex = Math.floor(Math.random() * devices.length);

    const selectedDevice = devices[randomDeviceIndex];

    // 3. Выбираем случайное действие для этого устройства

    const randomActionIndex = Math.floor(Math.random() * selectedDevice.actions.length);

    const selectedAction = selectedDevice.actions[randomActionIndex];

    // 4. Формируем сообщение в соответствии с "Контрактом сообщения"

    // Это позволит нам легко маршрутизировать его дальше.

    msg.topic = selectedDevice.topic || null; // Если топик задан прямо в объекте (для MQTT)

    msg.payload = selectedAction.payload;

    // Добавляем метаданные для маршрутизации и логирования

    msg.deviceInfo = {

    id: selectedDevice.id,

    type: selectedDevice.type,

    action: selectedAction.command

    };

    // 5. Визуализируем, что происходит, прямо на узле

    const statusText = `Do: ${selectedDevice.id} -> ${selectedAction.command}`;

    node.status({ fill: "blue", shape: "dot", text: statusText });

    // Логируем действие для отладки

    node.log(`Имитация: ${statusText}`);

    return msg;

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

    ---

    Управление конечными устройствами

    После того как ядро сценария в узле `function` сформировало управляющее сообщение, его необходимо направить на правильный исполнительный узел. Для этого используется узел `switch`, который анализирует метаданные `msg.deviceInfo.type`.

    ASCII-схема маршрутизации:
    [Function: Выбор действия] --+--> [Switch: по msg.deviceInfo.type] --+--> [Flow: Управление KNX] --> [knxUltimate]
    

    |

    +--> [Flow: Управление DALI] --> [dali-out]

    |

    +--> [Flow: Управление MQTT] --> [mqtt out]

    |

    +--> [Flow: Управление Modbus] -> [modbus-write]

    Управление освещением (KNX/DALI)

    Если узел `switch` определил, что `msg.deviceInfo.type` равно `knx-light`, он направляет сообщение в соответствующий поток.

    Управление медиа (MQTT)

    Если тип устройства `mqtt-media`, сообщение направляется в поток для MQTT.

    Пример полного сообщения для включения умной розетки с прошивкой Tasmota, управляющей торшером:

    // msg объект перед отправкой в узел mqtt out
    

    {

    "topic": "tele/tasmota_lamp/cmnd/POWER",

    "payload": "ON",

    "qos": 1,

    "retain": false

    }

    Управление шторами (Modbus RTU)

    🔗 Связанный материал: Детальная работа с протоколом подробно описана в гайде `Скилл: Протоколы Modbus`.

    Если тип устройства `modbus-blinds`, сообщение обрабатывается для отправки по шине RS-485.

  • Сообщение из `switch` попадает в узел `function` "Формирование Modbus-команды".
  • Этот узел преобразует `msg.payload` в формат, понятный узлу `modbus-write`.
  • Например, если `msg.payload` был `{ "value": 50 }` (открыть на 50%), код может выглядеть так:

        // Адрес устройства и регистра берем из настроек или контекста

    const unitId = 5; // Slave ID привода штор

    const registerAddress = 100; // Адрес Holding Register для позиции

    msg.payload = {

    'value': msg.payload.value,

    'unitid': unitId,

    'fc': 6, // FC 6: Preset Single Register

    'address': registerAddress

    };

    return msg;

  • Сформированное сообщение подается на узел `modbus-write` для отправки команды на шину RS-485.
  • Таким образом, мы создали гибкую систему, где добавление нового устройства в симуляцию сводится к добавлению объекта в массив `devices` в центральном `function` узле.

    ---

    Интеграция с глобальными режимами

    Сценарий имитации присутствия не должен работать сам по себе. Он должен быть жестко привязан к общему состоянию дома.

    > 🔗 Связанный материал: Логика глобальных состояний и режимов ('Дома', 'Отпуск', 'Гости') подробно рассматривается в `COURSE-07-M02 'Глобальные режимы и состояния'`. Убедитесь, что у вас настроен персистентный глобальный контекст для хранения текущего режима.

    Проверка глобального режима

    Самое первое действие в нашем потоке, еще до таймеров и планировщиков, — это проверка текущего режима.

  • Поток запускается узлом `cron-plus`.
  • Сразу после него ставится узел `switch`.
  • Настройка узла `switch` "Проверка режима 'Отпуск'":
  • - `Property`: `global.houseMode` (выбираем тип `global`).

    - `Rule`: `==` (string) `vacation`.

    - Если правило выполняется, сообщение проходит дальше, на узел `random-timer` и к основной логике.

    - Если `global.houseMode` не равно `vacation`, сообщение никуда не идет, и весь поток прерывается, не создавая нагрузки.

    ASCII-схема потока:
    [cron-plus] --> [Switch: global.houseMode == 'vacation'?] -- (да) --> [random-timer] --> [Function: Выбор действия] ...
    

    |

    +-- (нет) --> (останов потока)

    Мгновенная деактивация сценария

    Что произойдет, если вы вернетесь из отпуска раньше, а сценарий продолжает работать? Необходимо предусмотреть механизм его немедленной остановки.

  • Создаем отдельный поток, который начинается с узла `mqtt in`.
  • Настройка `mqtt in`:
  • - `Topic`: `hi/system/mode/set` (или топик, где публикуется смена режимов).

  • После него ставим узел `switch`, который проверяет, что новый режим не является `'vacation'`.
  • Если режим сменился (например, на `'home'`), нам нужно остановить все запущенные таймеры в сценарии имитации. Для этого можно использовать управляющие сообщения. Например, если `random-timer` находится в процессе ожидания, ему можно отправить сообщение с `msg.payload = "stop"`, чтобы сбросить таймер.
  • Также, если ваш сценарий включает длительные действия (например, "включить ТВ на 2 часа"), необходимо предусмотреть механизм их прерывания.
  • Обратная связь и уведомления

    Для повышения уверенности пользователя в работе системы, настройте отправку уведомлений.

  • В потоке, где происходит смена глобального режима, после успешной установки `global.houseMode = 'vacation'`, добавьте узел, отправляющий сообщение в мастер-чат (Telegram, Matrix и т.д.).
  • Текст сообщения: "Система переведена в режим 'Отпуск'. Активирована защита от протечек, контроль периметра и имитация присутствия."
  • Это простое действие значительно улучшает пользовательский опыт (UX), давая владельцу четкое подтверждение, что дом находится под охраной.
  • ---

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

    Мы разработали и реализовали один из самых интеллектуально сложных, но эффективных сценариев безопасности — SCN-SAFETY-014: Имитация присутствия. Это многослойная автоматизация, которая гармонично сочетает в себе:

    Лучшие практики для максимальной эффективности:

    Возможности для расширения

    Тестирование

    Перед тем как доверить этому сценарию безопасность своего дома во время длительного отсутствия, проведите его "боевое" тестирование:

  • Активируйте режим "Отпуск" на 1-2 вечера, находясь дома.
  • Наблюдайте за работой сценария. Свет включается/выключается корректно? Шторы двигаются? Нет ли аномалий, когда свет остается включенным на всю ночь?
  • Проверьте логи в Node-RED или в вашей системе журналирования (например, в таблице MySQL), чтобы убедиться, что все шаги выполняются без ошибок.
  • Тщательно протестированный и грамотно настроенный сценарий имитации присутствия станет надежным и незаметным стражем вашего дома.

    Что дальше?

    В следующем уроке мы рассмотрим еще один критически важный аспект безопасности: SCN-SAFETY-020: "Периметр безопасности: интеграция датчиков открытия и движения в ночном режиме". Мы научимся создавать логику, которая ставит дом на охрану, когда все ложатся спать, и корректно реагирует на события на датчиках.