ГлавнаяАкадемияОсновы умного дома → Практика: Симуляция 'Датчик-Реле'

Практика: Симуляция 'Датчик-Реле'

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

Введение: Логическая связка "Датчик-Реле" и цели урока

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

Этот принцип окружает нас повсюду:

Понимание этой базовой модели «Вход → Обработка → Выход» является ключом к проектированию как простых, так и сложных сценариев автоматизации на платформе HI.

Цель этого урока — собрать в среде Node-RED простую, но полнофункциональную виртуальную схему, которая имитирует логику "Датчик-Реле". Мы не будем использовать физические входы и выходы контроллера. Вместо этого мы создадим их симуляцию с помощью стандартных узлов Node-RED. Это позволит нам полностью сосредоточиться на логике потока данных и обработке сообщений, не отвлекаясь на аппаратную часть.

Для достижения этой цели мы будем использовать следующие "виртуальные" компоненты:

> 💡 Подсказка: На этом уроке мы работаем с виртуальными узлами, чтобы сфокусироваться на логике. В последующих модулях, например, в курсе `COURSE-03` по работе с протоколом MQTT, мы научимся заменять эти симуляторы на узлы, которые получают данные от реальных беспроводных датчиков и отправляют команды на настоящие исполнительные устройства.

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

---

Шаг 1: Создание симулятора датчика

Начнем с создания нашего "виртуального датчика". Как мы уже знаем из предыдущих уроков, узел `Inject` идеально подходит для этой задачи, так как он позволяет вручную или автоматически генерировать сообщения `msg` с заданным содержимым. Мы создадим два таких узла: один будет имитировать сигнал датчика "обнаружено движение" (состояние `true`), а другой — "движение отсутствует" (состояние `false`).

Настройка узла "Датчик: Включено"

  • Добавьте узел `Inject`. Перетащите узел `inject` из палитры слева на рабочее пространство.
  • Откройте настройки. Дважды щелкните по узлу, чтобы открыть его панель конфигурации.
  • Настройте `msg.payload`. В поле `Payload` выберите из выпадающего списка тип `boolean` (логический). Установите значение в `true`. Это означает, что при нажатии на этот узел будет сгенерировано сообщение, в `msg.payload` которого будет `true`.
  • Задайте `msg.topic`. Перейдите к полю `Topic` и введите в него идентификатор нашего виртуального датчика. Это критически важный шаг для создания структурированных и масштабируемых систем. Используем формат `тип/расположение/имя`. Например: `sensor/motion/livingroom`. Это позволит в будущем легко фильтровать и маршрутизировать сообщения от десятков и сотен датчиков.
  • Задайте имя узла. В поле `Name` внизу введите понятное имя, например, `Датчик: Движение ЕСТЬ`. Это имя будет отображаться в редакторе и сделает ваш поток читаемым.
  • Сохраните изменения. Нажмите кнопку Done.
  • После настройки узел будет выглядеть так на панели конфигурации:

    | Параметр | Тип значения | Значение | Пояснение |

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

    | Payload | boolean | `true` | Состояние датчика "обнаружено" |

    | Topic | string | `sensor/motion/livingroom` | Уникальный идентификатор источника |

    | Name | - | `Датчик: Движение ЕСТЬ` | Человекочитаемое имя на схеме |

    Настройка узла "Датчик: Выключено"

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

  • Скопируйте первый узел. Выделите уже настроенный узел `Датчик: Движение ЕСТЬ`, нажмите `Ctrl+C`, а затем `Ctrl+V` (или `Cmd+C`/`Cmd+V` на macOS). Это быстрее, чем настраивать новый узел с нуля.
  • Откройте настройки копии. Дважды щелкните по скопированному узлу.
  • Измените `msg.payload`. В поле `Payload` измените значение с `true` на `false`.
  • Измените имя. В поле `Name` измените имя на `Датчик: Движения НЕТ`. Поле `Topic` оставьте без изменений, так как это сигнал от того же самого датчика.
  • Сохраните изменения. Нажмите кнопку Done.
  • Теперь у вас на рабочем пространстве находятся два узла, которые полностью имитируют поведение одного датчика, способного отправлять два состояния. При нажатии на первый будет сгенерировано сообщение:

    {
    

    "payload": true,

    "topic": "sensor/motion/livingroom",

    "_msgid": "..."

    }

    А при нажатии на второй:

    {
    

    "payload": false,

    "topic": "sensor/motion/livingroom",

    "_msgid": "..."

    }

    Мы успешно создали симулятор входа данных в нашу систему. Следующий шаг — научить систему реагировать на эти данные.

    ---

    Шаг 2: Реализация логического ветвления с узлом Switch

    Получив сигнал от датчика, система должна принять решение: что делать дальше? Для этого в Node-RED существует узел `Switch`. Он работает как железнодорожная стрелка для сообщений: проверяет `msg` по одному или нескольким правилам и отправляет его на тот выход, который соответствует первому сработавшему условию.

    > ⚠️ Внимание: Узел `Switch` проверяет условия последовательно, сверху вниз, и по умолчанию отправляет сообщение на первый же совпавший выход. Для оптимизации производительности на сложных потоках размещайте наиболее частые или критичные условия выше в списке правил, чтобы уменьшить задержку обработки.

    Наша задача — настроить узел `Switch` так, чтобы он направлял сообщения со значением `true` на один выход, а со значением `false` — на другой.

    Настройка узла `Switch`

  • Добавьте узел `Switch`. Найдите его в палитре (в разделе `function`) и перетащите на рабочее пространство.
  • Соедините входы. Соедините выходы обоих наших узлов `Inject` (`Датчик: Движение ЕСТЬ` и `Датчик: Движения НЕТ`) с единственным входом узла `Switch`. Теперь любой сигнал от нашего "датчика" будет поступать на проверку.
  • Откройте настройки узла `Switch`. Дважды щелкните по нему.
  • Задайте проверяемое свойство. В поле `Property` по умолчанию уже стоит `msg.payload`. Оставим это значение, так как именно в `payload` наши узлы `Inject` передают состояние `true`/`false`.
  • Создайте первое правило.
  • * В первой строке правил оставьте условие `==` (is equal to).

    * Рядом в поле выберите тип `boolean`.

    * Установите значение `true`.

    * Таким образом, первое правило звучит как: "Если `msg.payload` равен `true`".

  • Создайте второе правило.
  • * Нажмите на кнопку `+add` внизу, чтобы добавить второе правило.

    * Аналогично первому, установите условие `==` `boolean` `false`.

    * Второе правило теперь звучит как: "Если `msg.payload` равен `false`".

  • Задайте имя узла. В поле `Name` введите `Проверка состояния датчика`.
  • Сохраните изменения. Нажмите Done.
  • Теперь узел `Switch` на рабочем пространстве имеет два выхода. Верхний (выход 1) будет активироваться, когда `msg.payload` равно `true`. Нижний (выход 2) — когда `msg.payload` равно `false`.

    Если бы мы сейчас подключили к этим выходам узлы `Debug`, то увидели бы, что при нажатии на `Датчик: Движение ЕСТЬ` сообщение появляется на выходе 1, а при нажатии на `Датчик: Движения НЕТ` — на выходе 2. Мы создали логическое ветвление.

    Схема потока на данном этапе:
    [Датчик: Движение ЕСТЬ] ---+
    

    |---> [Проверка состояния датчика] ---(выход 1, if true)

    [Датчик: Движения НЕТ] ----+ |

    +--(выход 2, if false)

    Мы разделили поток на две логические ветки. Теперь на каждой из них нам нужно сформировать конкретную команду для нашего гипотетического исполнителя.

    ---

    Шаг 3: Формирование команд для исполнителя

    Наш "датчик" отправляет логические `true` и `false`. Это удобно для внутренней логики, но реальные исполнительные устройства часто ожидают команды в ином формате.

    Для преобразования наших внутренних логических сигналов в команды нужного формата используется узел `Change`. Этот узел позволяет гибко изменять различные части объекта `msg`. Мы будем использовать его, чтобы заменить `msg.payload`.

    Создадим два узла `Change`: один для формирования команды "ВКЛЮЧИТЬ", другой для команды "ВЫКЛЮЧИТЬ".

    Настройка узла "Команда: ON"

  • Добавьте узел `Change`. Перетащите его из палитры на рабочее пространство.
  • Подключите его к первому выходу `Switch`. Соедините выход 1 (который срабатывает на `true`) узла `Switch` со входом узла `Change`.
  • Откройте настройки. Дважды щелкните по узлу `Change`.
  • Настройте правило изменения. Нам нужно задать одно правило:
  • * В поле `Set` выберите `msg.payload`.

    * В поле `to` (в) выберите тип `string` (строка).

    * Впишите в текстовое поле значение `ON`.

  • Задайте имя. Назовите узел `Сформировать команду ON`.
  • Сохраните. Нажмите Done.
  • Теперь, когда сообщение с `payload: true` пройдет через этот узел, его `payload` изменится на `"ON"`.

    Трансформация сообщения:
        {
    

    "payload": true,

    "topic": "sensor/motion/livingroom",

    "_msgid": "..."

    }

        {
    

    "payload": "ON",

    "topic": "sensor/motion/livingroom",

    "_msgid": "..."

    }

    Настройка узла "Команда: OFF"

  • Добавьте второй узел `Change` (или скопируйте первый).
  • Подключите его ко второму выходу `Switch`. Соедините выход 2 (который срабатывает на `false`) узла `Switch` со входом этого нового узла `Change`.
  • Откройте настройки.
  • Настройте правило. Аналогично предыдущему шагу, установите правило `Set` `msg.payload` `to` (string) `"OFF"`.
  • Задайте имя. Назовите узел `Сформировать команду OFF`.
  • Сохраните. Нажмите Done.
  • Теперь наш поток полностью реализует логику: получить сигнал, принять решение в зависимости от его значения и сформировать соответствующую команду. Остался последний шаг: увидеть результат нашей работы.

    ---

    Шаг 4: Визуализация и отладка

    Мы подошли к финальному этапу сборки нашей схемы — визуализации результата. Для этого мы будем использовать узел `Debug`, который, как мы знаем из урока `COURSE-01-M01-L05`, является незаменимым инструментом для отладки и просмотра содержимого сообщений `msg` в любой точке потока. Мы используем его как индикатор состояния нашего "виртуального реле".

    Настройка узлов `Debug`

  • Добавьте узел `Debug`. Перетащите его из палитры.
  • Подключите его к выходу узла "Сформировать команду ON".
  • Откройте настройки `Debug`.
  • * В поле `Output` по умолчанию стоит `msg.payload`. Это то, что нам нужно.

    * Для удобства вывода можно изменить значение `to` на `debug tab and console` (вкладка отладки и консоль), чтобы видеть результат и там, и там.

    * В поле `Name` можно написать `ИНДИКАТОР РЕЛЕ: ON`.

    * Нажмите Done.

  • Добавьте второй узел `Debug`. Подключите его к выходу узла "Сформировать команду OFF".
  • Настройте его аналогично, но с именем `ИНДИКАТОР РЕЛЕ: OFF`.
  • Теперь наш поток полностью собран и готов к тестированию.

    Полная схема потока (ASCII-диаграмма):
    [Датчик: Движение ЕСТЬ] ---+                           +---> [Сформировать команду ON] ---> [ИНДИКАТОР РЕЛЕ: ON]
    

    |---> [Проверка состояния] --|

    [Датчик: Движения НЕТ] ----+ +---> [Сформировать команду OFF] --> [ИНДИКАТОР РЕЛЕ: OFF]

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

  • Разверните поток. Нажмите на красную кнопку Deploy в правом верхнем углу редактора, чтобы применить все наши изменения.
  • Откройте панель отладки. Если она не открыта, нажмите на иконку жука (🐞) на боковой панели справа.
  • Сымитируйте сигнал "Движение ЕСТЬ". Нажмите на кнопку слева от узла `Датчик: Движение ЕСТЬ`. В панели отладки вы должны мгновенно увидеть сообщение `"ON"`.
  • Сымитируйте сигнал "Движения НЕТ". Нажмите на кнопку на узле `Датчик: Движения НЕТ`. В панели отладки появится сообщение `"OFF"`.
  • Поздравляем! Вы только что создали и протестировали свой первый полноценный сценарий автоматизации, реализующий логику "Датчик-Реле".

    Экспорт потока

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

  • Выделите все узлы вашего потока.
  • В меню "гамбургер" (☰) в правом верхнем углу выберите `Export`.
  • Во всплывающем окне вы увидите JSON-представление вашего потока. Вы можете скопировать его в буфер обмена.
  • Вот как выглядит JSON-код для нашего потока. Вы можете импортировать его на своем контроллере через меню `Import`, чтобы сразу получить готовую схему.

    [
    

    {

    "id": "a1b2c3d4.123456",

    "type": "inject",

    "z": "...",

    "name": "Датчик: Движение ЕСТЬ",

    "props": [

    {

    "p": "payload"

    },

    {

    "p": "topic",

    "vt": "str"

    }

    ],

    "repeat": "",

    "crontab": "",

    "once": false,

    "onceDelay": 0.1,

    "topic": "sensor/motion/livingroom",

    "payload": "true",

    "payloadType": "bool",

    "x": 150,

    "y": 100,

    "wires": [

    [

    "e5f6g7h8.789012"

    ]

    ]

    },

    {

    "id": "e5f6g7h8.789012",

    "type": "switch",

    "z": "...",

    "name": "Проверка состояния датчика",

    "property": "payload",

    "propertyType": "msg",

    "rules": [

    {

    "t": "true"

    },

    {

    "t": "false"

    }

    ],

    "checkall": "true",

    "repair": false,

    "outputs": 2,

    "x": 400,

    "y": 120,

    "wires": [

    [

    "i9j0k1l2.345678"

    ],

    [

    "m3n4o5p6.901234"

    ]

    ]

    },

    {

    "id": "b1c2d3e4.567890",

    "type": "inject",

    "z": "...",

    "name": "Датчик: Движения НЕТ",

    "props": [

    {

    "p": "payload"

    },

    {

    "p": "topic",

    "vt": "str"

    }

    ],

    "repeat": "",

    "crontab": "",

    "once": false,

    "onceDelay": 0.1,

    "topic": "sensor/motion/livingroom",

    "payload": "false",

    "payloadType": "bool",

    "x": 140,

    "y": 160,

    "wires": [

    [

    "e5f6g7h8.789012"

    ]

    ]

    },

    {

    "id": "i9j0k1l2.345678",

    "type": "change",

    "z": "...",

    "name": "Сформировать команду ON",

    "rules": [

    {

    "t": "set",

    "p": "payload",

    "pt": "msg",

    "to": "ON",

    "tot": "str"

    }

    ],

    "action": "",

    "property": "",

    "from": "",

    "to": "",

    "reg": false,

    "x": 650,

    "y": 100,

    "wires": [

    [

    "q7r8s9t0.123456"

    ]

    ]

    },

    {

    "id": "m3n4o5p6.901234",

    "type": "change",

    "z": "...",

    "name": "Сформировать команду OFF",

    "rules": [

    {

    "t": "set",

    "p": "payload",

    "pt": "msg",

    "to": "OFF",

    "tot": "str"

    }

    ],

    "action": "",

    "property": "",

    "from": "",

    "to": "",

    "reg": false,

    "x": 650,

    "y": 160,

    "wires": [

    [

    "u1v2w3x4.789012"

    ]

    ]

    },

    {

    "id": "q7r8s9t0.123456",

    "type": "debug",

    "z": "...",

    "name": "ИНДИКАТОР РЕЛЕ: ON",

    "active": true,

    "tosidebar": true,

    "console": false,

    "tostatus": false,

    "complete": "payload",

    "targetType": "msg",

    "statusVal": "",

    "statusType": "auto",

    "x": 900,

    "y": 100,

    "wires": []

    },

    {

    "id": "u1v2w3x4.789012",

    "type": "debug",

    "z": "...",

    "name": "ИНДИКАТОР РЕЛЕ: OFF",

    "active": true,

    "tosidebar": true,

    "console": false,

    "tostatus": false,

    "complete": "payload",

    "targetType": "msg",

    "statusVal": "",

    "statusType": "auto",

    "x": 900,

    "y": 160,

    "wires": []

    }

    ]

    ---

    Итоги урока и дальнейшие шаги

    На этом практическом занятии мы сделали важный шаг от теории к практике. Мы разобрали и реализовали краеугольный камень любой автоматизации — логическую связку "Датчик-Реле".

    Давайте кратко повторим, что мы сделали:
  • Создали симулятор датчика с помощью двух узлов `Inject`, которые генерируют сообщения со значениями `true` и `false` и, что важно, с осмысленным `topic`.
  • Добавили узел `Switch` для логического ветвления, который направляет сообщения по разным путям в зависимости от их содержимого.
  • Использовали узлы `Change` для формирования команд, преобразовав абстрактные `true`/`false` в конкретные строковые команды `ON`/`OFF`, готовые для отправки на исполнительное устройство.
  • Визуализировали результат с помощью узлов `Debug` и протестировали весь поток от начала до конца.
  • Главная концепция, которую вы должны были усвоить, — это универсальная модель потока данных: Вход → Обработка → Выход. Эта простая трехэтапная модель лежит в основе 90% всех задач, которые вы будете решать с помощью контроллера HI и Node-RED. Сегодняшний поток — это ее идеальная иллюстрация.

    > 🔗 Связанный материал: В следующем уроке, `COURSE-01-M01-L08: Работа с MQTT-протоколом`, мы сделаем эту схему гораздо более реалистичной. Мы заменим наш виртуальный датчик (`Inject`) на узел `MQTT In`, который будет получать данные от настоящего (или симулированного) устройства по сети. Это станет вашим первым шагом в мир распределенных систем и Интернета вещей (IoT).