ГлавнаяАкадемияОсновы умного дома → Сценарии для дома: 'Охранный' режим

Сценарии для дома: 'Охранный' режим

Урок 3 · Основы умного дома · 30 мин · theory

Концепция и компоненты охранного режима

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

Ключевые задачи охранного режима:
  • Обнаружение (Detection): Фиксация факта вторжения с помощью специализированных датчиков. Это первый и самый важный рубеж обороны.
  • Оповещение (Notification): Мгновенная доставка тревожной информации ответственным лицам (владельцу, службе безопасности) по различным каналам связи (push-уведомления, SMS, звонки, Telegram).
  • Реагирование (Response): Активация исполнительных устройств для дезориентации и отпугивания злоумышленника. Это может быть включение сирены, стробоскопа, или включение всего света в доме.
  • Предотвращение (Prevention): Использование превентивных мер, таких как имитация присутствия, для снижения привлекательности объекта для потенциальных грабителей.
  • Для построения надежной охранной системы на базе контроллера HI (аппаратная платформа) требуется тщательно подобранный набор оборудования.

    | Компонент | Тип Оборудования | Назначение | Пример подключения |

    | ----------------------------- | ---------------------------------------------- | --------------------------------------------------------------------------------------------- | ----------------------------- |

    | Датчики открытия | Герконы (магнитоконтактные извещатели) | Устанавливаются на окна и двери для фиксации их открытия. | Дискретные входы (DI) |

    | Датчики движения | Инфракрасные (PIR), микроволновые (MW) | Обнаруживают движение в контролируемых зонах (комнаты, коридоры). | Дискретные входы (DI) |

    | Акустические датчики | Датчики разбития стекла | Реагируют на характерный звук бьющегося стекла. | Дискретные входы (DI) |

    | Исполнительные устройства | Сирены, стробоскопы, релейные модули | Активируются по сигналу тревоги для звукового и светового оповещения. | Выходы реле контроллера |

    | Контроллер | Платформа HI (Linux, Node-RED) | Центральный узел, собирающий данные с датчиков, обрабатывающий логику и управляющий реакцией. | — |

    | Источник питания | Блок питания с источником бесперебойного питания (ИБП) | Обеспечивает непрерывную работу контроллера и датчиков при отключении основного электроснабжения. | — |

    Датчики могут быть двух основных типов:

    > ⚠️ Внимание: Основой любой охранной системы является надежное электропитание. Контроллер, все модули расширения и, по возможности, проводные датчики должны быть запитаны через ИБП. Отключение электричества не должно приводить к деактивации системы охраны.

    ---

    Интеграция датчиков с контроллером и MQTT

    Рассмотрим наиболее надежный вариант — подключение проводных датчиков к модулю дискретных входов, например, `WBIO-DI-DR-14`, который является частью экосистемы контроллера HI.

    Физическое подключение

    Для подключения герконов и датчиков движения (PIR) используются их релейные выходы типа "сухой контакт".

  • Геркон (датчик открытия): Имеет две клеммы. Одна клемма подключается к клемме `GND` (земля) на модуле входов, а вторая — к любой свободной клемме дискретного входа (например, `DI 1-1`).
  • Датчик движения (PIR): Обычно имеет как минимум 4 клеммы: `+V` и `GND` для питания (например, 12V), и `RELAY` (или `ALARM`) для "сухого контакта". Клеммы питания подключаются к соответствующему блоку питания, а клеммы реле — к `GND` и `DI` на контроллере, аналогично геркону.
  • > 💡 Подсказка: Для повышения надежности используйте NC (нормально-замкнутые) герконы и датчики. В спокойном состоянии контакт замкнут, и через него течет небольшой ток. Сработка на разрыв цепи (при открытии двери или тревоге датчика движения) позволяет системе обнаружить не только само событие, но и попытку саботажа (обрез провода). В этом случае система также зафиксирует тревогу.

    Настройка MQTT-топиков

    После физического подключения необходимо сконфигурировать контроллер, чтобы он начал публиковать состояния входов в MQTT. В веб-интерфейсе контроллера (аналогично Wirenboard):

  • Перейдите в раздел `Settings` -> `MQTT Channels`.
  • Найдите ваше устройство, например `wb-gpio` (для входов на самом контроллере) или `wb-mio` (для модулей расширения).
  • Найдите канал, соответствующий подключенному входу, например, `DI1-15`.
  • Активируйте его, установив флажок `Enabled`.
  • В поле `MQTT topic` будет указан уникальный идентификатор, например `DI1-15`.
  • Выберите тип контакта. Если вы использовали NC-датчик, выберите `NC`. Это инвертирует логику: `0` будет означать "норма", а `1` — "тревога".
  • Полный путь к MQTT-топику, на который нужно будет подписаться в Node-RED, будет иметь следующую структуру:

    `/devices/<имя-устройства>/controls/<имя-канала>`

    Например: `/devices/wb-gpio/controls/DI1-15`

    Проверка в Node-RED

    Прежде чем строить сложную логику, убедитесь, что данные от датчиков поступают корректно.

  • Создайте на холсте Node-RED узел `mqtt in`.
  • В его настройках укажите адрес вашего MQTT-брокера (обычно `localhost` или `127.0.0.1`, так как брокер работает на самом контроллере HI).
  • В поле `Topic` укажите топик вашего датчика, например `/devices/wb-gpio/controls/DI1-15`. Для отладки можно использовать wildcard: `/devices/wb-gpio/controls/DI1-#`, чтобы получать данные со всех входов группы.
  • Соедините выход `mqtt in` с узлом `debug`.
  • Разверните поток (Deploy).
  • Откройте панель отладки (`Debug messages`).
  • Сымитируйте сработку датчика (откройте дверь с герконом, помашите рукой перед датчиком движения). В панели отладки вы должны увидеть сообщение. Объект `msg` будет выглядеть примерно так:
  • {
    

    "topic": "/devices/wb-gpio/controls/DI1-15",

    "payload": "1",

    "qos": 0,

    "retain": false,

    "_msgid": "..."

    }

    Если вы видите `1` при сработке и `0` в состоянии покоя, значит, интеграция прошла успешно и можно переходить к построению логики.

    ---

    Практика: Логика постановки и снятия с охраны в Node-RED

    "Охранный режим" — это не свойство датчика, а состояние всей системы. Нам нужно место, где будет храниться информация о том, включена охрана или нет. Для этого идеально подходит глобальный контекст (global context) Node-RED.

    > 📋 Ключевые понятия: Глобальный контекст — это область памяти в Node-RED, доступная из любого потока (flow) на любом листе. Переменные, сохраненные в нем, существуют до перезагрузки Node-RED.

    Создание переменной состояния

    При запуске системы необходимо инициализировать переменную, чтобы избежать неопределенности.

  • Используйте узел `inject`.
  • Настройте его на запуск `Once after 0.1 seconds`, чтобы он сработал один раз при старте Node-RED.
  • Соедините его с узлом `change`.
  • В узле `change` установите `global.security_armed` в значение `false` (булев тип).
  • Теперь при каждом запуске система будет гарантированно находиться в состоянии "Снято с охраны".

    Управление статусом охраны

    Пользователь должен иметь возможность легко ставить и снимать систему с охраны. Рассмотрим реализацию с помощью физической кнопки, подключенной к другому дискретному входу.

    ASCII-схема потока:
    // Постановка/снятие с охраны
    

    [mqtt in: /cmd/security/toggle] --> [function: Toggle Armed State] --> [mqtt out: /state/security]

    |

    +-----> [debug: "Security state changed"]

    Пошаговая реализация:
  • Входной сигнал: Создайте узел `mqtt in` и подпишите его на управляющий топик, например `/cmd/security/set`. Мы будем отправлять в этот топик сообщения `"ARM"` и `"DISARM"`.
  • Логика переключения: Поместите узел `switch` после `mqtt in`. Он будет проверять `msg.payload`:
  • * Если `payload` == `"ARM"`, перенаправить на ветку постановки.

    * Если `payload` == `"DISARM"`, перенаправить на ветку снятия.

  • Запись в глобальную переменную:
  • * После каждой ветки узла `switch` поставьте узел `change`.

    * Для ветки "ARM": `Set global.security_armed to true`.

    * Для ветки "DISARM": `Set global.security_armed to false`.

  • Визуальная и логическая обратная связь: Критически важно обеспечить обратную связь.
  • * Для Node-RED: В узлах `change` можно использовать `node.status()`, но лучше создать отдельный узел `function` для централизованной обработки состояния и его отображения.

    * Для пользователя: После узлов `change` добавьте узел `mqtt out`, который публикует текущий статус (например, `"ARMED"` или `"DISARMED"`) в топик `/state/security/armed`. На этот топик может быть подписан светодиодный индикатор на кнопке или виджет в панели управления.

    Пример кода для узла `function`, который объединяет логику:
    // Этот узел принимает команды "ARM", "DISARM", "TOGGLE"
    

    let currentState = global.get('security_armed') || false;

    let command = msg.payload;

    let newState;

    if (command === "ARM") {

    newState = true;

    } else if (command === "DISARM") {

    newState = false;

    } else if (command === "TOGGLE") {

    newState = !currentState;

    } else {

    // Неизвестная команда, ничего не делаем

    node.warn("Unknown security command: " + command);

    return null;

    }

    // Если состояние изменилось, сохраняем и отправляем обратную связь

    if (newState !== currentState) {

    global.set('security_armed', newState);

    if (newState) {

    node.status({fill:"red", shape:"dot", text:"ARMED"});

    msg.payload = "ARMED";

    } else {

    node.status({fill:"green", shape:"dot", text:"DISARMED"});

    msg.payload = "DISARMED";

    }

    // Возвращаем сообщение для отправки статуса в MQTT

    msg.topic = "/state/security/armed";

    return msg;

    }

    // Состояние не изменилось, останавливаем поток

    return null;

    ---

    Практика: Реакция на вторжение

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

    ASCII-схема потока тревоги:
    [mqtt in: /devices/+/controls/DI+] --+
    

    |

    +--> [switch: Is system armed?] --(yes)--> [function: Format Alarm] --> [trigger: Limit notifications] --> [function: Send to Telegram] --> [mqtt out: Activate Siren]

    |

    +--> (no) (поток останавливается)

    Реализация потока "Тревога":
  • Подписка на датчики: Создайте узел `mqtt in`. В поле `Topic` укажите шаблон, который охватывает все ваши охранные датчики, например `/devices/+/controls/DI+`. Это избавит вас от необходимости создавать отдельный узел для каждого датчика.
  • Проверка статуса охраны: Соедините `mqtt in` с узлом `switch`. Это — главный "фильтр" системы.
  • * Настройте его на проверку `global.security_armed`.

    * Добавьте правило: `is true`.

    * Соедините выход этого правила с дальнейшей логикой тревоги. Все сообщения, пришедшие при `global.security_armed` равном `false`, будут проигнорированы.

  • Логика обработки тревоги:
  • * Формирование сообщения: Создайте узел `function` для подготовки информативного сообщения о тревоге. Он должен извлечь имя датчика из топика.

        // Пример msg, пришедшего на вход:

    // { topic: "/devices/wb-gpio/controls/DI1-15", payload: "1" }

    // Проверяем, что это действительно сработка, а не отбой

    if (msg.payload !== "1") {

    return null; // Игнорируем сообщения "0"

    }

    const topicParts = msg.topic.split('/');

    const deviceName = topicParts[2];

    const controlName = topicParts[4];

    // Можно создать более человекочитаемое имя

    // на основе словаря или простой логики

    let sensorName = `${deviceName}/${controlName}`;

    if (sensorName === "wb-gpio/DI1-15") {

    sensorName = "Датчик открытия входной двери";

    }

    msg.payload = `🚨 ТРЕВОГА! 🚨\nСработал датчик: ${sensorName}`;

    msg.alarm_source = sensorName; // Сохраняем для дальнейшего использования

    node.status({fill:"red", shape:"ring", text:`ALARM: ${sensorName}`});

    return msg;

    * Ограничение шквала уведомлений: Если дверь будет открываться и закрываться несколько раз, система отправит десятки уведомлений. Чтобы этого избежать, используйте узел `trigger`. Настройте его так:

    * `Send`: `the first message`

    * `then`: `block subsequent messages for` `5` `minutes`.

    Это отправит одно уведомление и будет игнорировать следующие сработки в течение 5 минут.

    * Отправка уведомлений: Используйте готовый узел для отправки сообщений в Telegram (например, `node-red-contrib-telegrambot-home`) или универсальный механизм отправки через MQTT, как было рассмотрено в уроке COURSE-01-M05-L03 о защите от протечек.

    * Активация сирены: Добавьте узел `mqtt out`.

    * `Topic`: `/devices/wb-mr6c_25/controls/K1/on` (замените на топик вашего реле).

    * `Payload`: `1`.

    Чтобы выключить сирену через некоторое время, можно использовать узел `trigger` в другом режиме или отдельный поток, который по команде "DISARM" отправит `0` в тот же топик.

    ---

    Дополнительный сценарий: Имитация присутствия

    Имитация присутствия — это эффективный превентивный метод. Задача — создать видимость, что в доме кто-то есть, включая и выключая свет в случайном порядке в вечернее время.

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

    ASCII-схема потока имитации:
    [inject: every 15 min] --> [switch: check time & armed] --(yes)--> [function: random logic] --(ON)--> [mqtt out: light on]
    

    |

    +--(OFF)--> [mqtt out: light off]

    Реализация:
  • Триггер запуска: Используйте узел `inject`, настроенный на периодический запуск, например, каждые 15-30 минут.
  • Проверка условий: Поставьте после `inject` узел `switch`. Он должен проверять два условия одновременно:
  • * `global.security_armed` is `true`.

    * Текущее время находится в заданном интервале (например, с 19:00 до 23:00). Проверку времени можно выполнить с помощью узла `time-range-switch` или в узле `function`.

  • Логика случайности: Если оба условия выполнены, сообщение проходит дальше на узел `function`, который решает, что делать со светом.
  •     // Массив топиков для управления светом в разных комнатах

    const lights = [

    "/devices/wb-mr6c_1/controls/K1/on", // Гостиная

    "/devices/wb-mr6c_1/controls/K2/on", // Кухня

    "/devices/wb-mr6c_2/controls/K3/on" // Коридор

    ];

    // Выбираем случайную группу света

    const randomLightTopic = lights[Math.floor(Math.random() * lights.length)];

    // С вероятностью 50% включаем или выключаем

    const action = (Math.random() > 0.5) ? "1" : "0";

    msg.topic = randomLightTopic;

    msg.payload = action;

    node.status({text: `Sim: ${randomLightTopic} -> ${action}`});

    return msg;

    Этот код будет каждые 15-30 минут случайным образом выбирать одну из групп света и случайным образом либо включать, либо выключать ее.

  • Управление светом: На выходе узла `function` поставьте узел `mqtt out`. Он отправит сформированное сообщение (`msg.topic` и `msg.payload`) в MQTT, управляя светом.
  • Этот простой, но непредсказуемый алгоритм создает гораздо более правдоподобную картину жизни в доме, чем простое включение света по таймеру.

    ---

    Итоги и возможные улучшения

    В рамках этого урока мы спроектировали и реализовали многоуровневую систему охраны, которая является одним из ключевых сценариев для любого умного дома. Мы прошли путь от физического подключения датчиков до создания сложной логики на базе Node-RED.

    Резюме по ключевым элементам логики:

    > 🔗 Связанный материал: Механизм отправки уведомлений, разработанный в этом уроке, является универсальным. Его можно и нужно переиспользовать в других критичных сценариях, таких как тот, что был рассмотрен в уроке COURSE-01-M05-L03 "Сценарии для дома: Защита от протечек". Это отличный кандидат для вынесения в переиспользуемый компонент (Subflow).

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

    Что дальше?

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