ГлавнаяАкадемияCOURSE-16: Основы Интернета Вещей и практическое применение → Интерфейсы и протоколы взаимодействия в экосистеме HI

Интерфейсы и протоколы взаимодействия в экосистеме HI

Урок · COURSE-16: Основы Интернета Вещей и практическое применение · theory

COURSE-16-M03-L01 — Интерфейсы и протоколы взаимодействия в экосистеме HI

Введение

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

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

Уровень 1: Физические интерфейсы контроллера

Физический интерфейс — это точка, где цифровой мир контроллера встречается с реальным оборудованием: датчиками, кнопками, реле и исполнительными механизмами. Ошибки на этом уровне являются причиной до 80% всех проблем на объекте.

Наш контроллер оснащен следующими основными физическими интерфейсами:

* "Сухой контакт" (Dry Contact): Кнопки, выключатели, герконы (датчики открытия), выходы реле других систем.

* Датчики 1-Wire: Цифровые датчики температуры (DS18B20), влажности и др.

* Аналоговые датчики: Датчики с выходом 0-10В или 4-20мА (давление, уровень CO2).

* RS-485: Промышленный стандарт для подключения устройств по протоколу Modbus RTU. Используется для счетчиков электроэнергии, модулей ввода-вывода, климатического оборудования.

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

* DALI: Стандарт для управления профессиональным осветительным оборудованием.

💡 Совет: Всегда используйте стандарт `WIRING-XXX-YYY` для документирования подключений. Это критически важно для последующей диагностики и обслуживания.

Практический пример: Подключение настенного выключателя

Задача: Подключить стандартный кнопочный выключатель для управления светом. Схема подключения: `WIRING-INPUT-001`
//========= WIRING-INPUT-001: Wall Switch to Universal Input =========

(SW-01: Wall Switch) [CTRL:HI-Core]

Клемма 1 --------- UI-05 (GND)

Клемма 2 --------- UI-06

Уровень 2: Протоколы канального уровня

После физического подключения необходимо установить "правила общения" по шине данных. Для промышленных и полупромышленных объектов основным протоколом является Modbus RTU.

* Master (Ведущий): Наш контроллер HI. Он инициирует все обмены данными.

* Slave (Ведомый): Оконечные устройства (счетчики, датчики) с уникальными адресами (1-247) на шине. Они только отвечают на запросы Master'а.

⚠️ Предупреждение: Ключ к успешной работе Modbus — точное совпадение настроек порта (скорость, четность, стоп-биты) на контроллере и всех устройствах на шине, а также уникальность адресов.

Практический пример: Чтение данных со счетчика электроэнергии

Задача: Считывать текущее потребление мощности со счетчика с Modbus-адресом `5`. Мощность хранится в Holding Register `40101` (адрес `100`). Логика в Node-RED:
  • Устанавливается палитра `node-red-contrib-modbus`.
  • Настраивается узел `Modbus-Getter` для периодического (раз в 15 секунд) чтения регистра `100` с устройства `5`.
  • Данные поступают в узел `Function` для валидации и преобразования.
  • Результат отправляется дальше для логирования или отображения.
  • ASCII-схема потока: `FLOW-INTEG-MODBUS-001`
    [Inject: 15s] -> [Modbus-Getter: Read Power] -> [Function: Validate & Format] -> [Debug]
    

    | (on error)

    v

    [Catch] -> [Function: Log Error] -> [MySQL: audit_log]

    Уровень 3: Протоколы прикладного уровня

    Эти протоколы определяют, как данные передаются по сетям TCP/IP и как приложения взаимодействуют друг с другом. Для экосистемы HI ключевыми являются MQTT и HTTP API.

    MQTT (Message Queuing Telemetry Transport)

    MQTT — это легковесный протокол для IoT, работающий по модели "Издатель-Подписчик" (Publisher-Subscriber) через центральный сервер — брокер.

    Критически важный элемент — Контракт сообщения. Все данные внутри экосистемы HI должны передаваться в стандартизированном JSON-формате. Стандартный контракт сообщения `msg.payload`:
    {
    

    "value": 23.5,

    "source": "temp-sensor-office-101",

    "ts": 1678886400000,

    "unit": "°C",

    "meta": {

    "room": "Office 101",

    "floor": 1

    }

    }

    Практический пример: Публикация данных с датчика в MQTT

    Задача: Данные с датчика 1-Wire (DS18B20) после чтения необходимо отформатировать и опубликовать в MQTT. ASCII-схема потока: `FLOW-SENS-TEMP-001`
    [Inject: 30s] -> [1-Wire In] -> [Function: Format to Contract] -> [MQTT Out: telemetry/temp]
    
    Код для узла `Function: Format to Contract`:
    // Входящее msg.payload от узла 1-Wire: "24.125" (строка)
    

    let temp = parseFloat(msg.payload);

    // 1. Валидация

    if (isNaN(temp) || temp < -55 || temp > 125) {

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

    node.error("Некорректное значение температуры: " + msg.payload, msg);

    return null; // Останавливаем поток

    }

    // 2. Формирование сообщения по контракту

    msg.payload = {

    value: temp,

    source: "28-01234567abcd", // Уникальный ID датчика 1-Wire

    ts: Date.now(),

    unit: "°C"

    };

    // 3. Установка топика для MQTT

    msg.topic = "hi/telemetry/office/room101/temperature";

    node.status({fill:"green", shape:"dot", text:"OK: " + temp + " °C"});

    return msg;

    HTTP API (RESTful)

    Контроллер HI может предоставлять внешний HTTP API для интеграции со сторонними системами, которые не поддерживают MQTT. Это реализуется с помощью узлов `http in` и `http out` в Node-RED.

    Пример: Создать API-endpoint для включения света в кабинете 101. ASCII-схема потока: `FLOW-INTEG-HTTP-002`
    [HTTP In: POST /api/light/room101] -> [JSON] -> [Switch: msg.payload.command] -> [Function: Set Relay ON] -> [GPIO Out] -> [HTTP Response: 200 OK]
    

    Уровень 4: Пользовательские интерфейсы (UI)

    Пользовательский интерфейс — это способ, которым конечный пользователь взаимодействует с системой.

    * Мобильные приложения: По сути, это MQTT-клиенты, которые подписываются на темы состояний (`hi/telemetry/...`) и публикуют команды в темы управления (`hi/commands/...`).

    * Веб-интерфейсы: Могут работать как по MQTT (через WebSocket), так и по HTTP API.

    * Node-RED Dashboard: Встроенный в Node-RED инструмент для быстрого создания простых панелей управления. Идеально подходит для пусконаладки, тестирования и создания интерфейсов для технического персонала.

    Сквозной пример: Сценарий `SCN-LIGHT-023` — Автоматическое управление светом

    Объединим все уровни в одном практическом сценарии.

    Задача: Свет в коридоре включается по датчику движения. Его также можно включить/выключить принудительно через мобильное приложение. Состояние света всегда отображается в приложении.
  • Физический уровень:
  • * Датчик движения (выход "сухой контакт") подключен к `UI-07`.

    * Светильник подключен к `RELAY-03`.

    * Схема: `WIRING-LIGHT-023`.

  • Канальный/Сетевой уровень: Не используется (прямое подключение).
  • Прикладной уровень (Node-RED):
  • * Входы:

    * Событие от датчика движения (узел `rpi gpio in`).

    * Команда из мобильного приложения (узел `mqtt in` на теме `hi/commands/corridor/light`).

    * Логика (Паттерн "Конечный автомат" - FSM):

    * Состояние системы (`AUTO`, `MANUAL_ON`, `MANUAL_OFF`) хранится в переменной `flow.context`.

    * Если пришло движение и режим `AUTO`, включается свет и запускается таймер на выключение.

    * Если пришла команда `ON` из MQTT, система переходит в `MANUAL_ON`, свет включается.

    * Состояние реле (`true`/`false`) и режим (`AUTO`/`MANUAL`) публикуются в `mqtt out` в тему `hi/status/corridor/light`.

    * Выходы:

    * Управление реле `RELAY-03` (узел `rpi gpio out`).

    * Отправка статуса в мобильное приложение (узел `mqtt out`).

  • Пользовательский уровень:
  • * Пользователь видит в приложении актуальный статус света и кнопки для ручного управления.

    * Система автоматически реагирует на движение.

    ---

    Лабораторные работы

    COURSE-16-M03-LAB01: Чтение данных с датчика и публикация в MQTT

    1. Создать поток в Node-RED, который каждые 10 секунд опрашивает датчик DS18B20.

    2. Добавить узел `Function` для валидации данных (температура должна быть в диапазоне от -10 до +40 °C).

    3. В том же узле `Function` преобразовать данные в JSON-формат согласно контракту сообщения Академии.

    4. Опубликовать полученный JSON в MQTT-топик `hi/lab/ваша_фамилия/temperature`.

    5. Использовать узел `Status` для отображения последней успешной температуры или ошибки.

    * Поток успешно публикует данные в MQTT.

    * Формат сообщения в MQTT точно соответствует контракту.

    * Поток корректно обрабатывает невалидные значения (не публикует их, выводит ошибку).

    * Узлы имеют осмысленные имена, поток снабжен комментариями.

    COURSE-16-M03-LAB02: Создание HTTP API для управления реле

    1. Создать поток в Node-RED, который слушает `POST` запросы по URL `/api/relay/5`.

    2. Поток должен принимать JSON-тело вида `{"state": true}` или `{"state": false}`.

    3. В зависимости от полученного значения, поток должен управлять реле №5 на контроллере.

    4. После выполнения команды поток должен возвращать HTTP-ответ с кодом `200 OK` и телом `{"status": "success", "newState": true/false}`.

    5. Добавить обработку некорректных запросов (неверный JSON, отсутствующее поле `state`), возвращая код `400 Bad Request`.

    * Отправка `curl -X POST -H "Content-Type: application/json" -d '{"state": true}' http://:1880/api/relay/5` включает реле.

    * Отправка `curl ... '{"state": false}'` выключает реле.

    * В обоих случаях возвращается корректный JSON-ответ.

    * Отправка некорректного запроса (`'{"command": "ON"}'`) возвращает ошибку 400.

    ---

    Тест для самопроверки (COURSE-16-M03-QUIZ)

  • Какое устройство является "Master" в сети Modbus RTU на платформе HI?
  • * а) Датчик температуры

    * б) Счетчик электроэнергии

    * в) Контроллер HI

    * г) Любое устройство

  • Что определяет "контракт сообщения" в экосистеме HI?
  • * а) Физический способ подключения проводов.

    * б) Стандартизированный JSON-формат для `msg.payload`.

    * в) Договор на техническое обслуживание.

    * г) IP-адрес MQTT-брокера.

  • Какую функцию выполняет MQTT-брокер?
  • * а) Хранит исторические данные за год.

    * б) Напрямую управляет реле.

    * в) Принимает сообщения от издателей и пересылает их подписчикам.

    * г) Шифрует трафик на физическом уровне.

  • Для чего используется узел `Catch` в Node-RED в контексте данного урока?
  • * а) Для запуска потока по расписанию.

    * б) Для перехвата и обработки ошибок от других узлов (например, сбой связи по Modbus).

    * в) Для визуального отображения статуса.

    * г) Для отправки HTTP-запросов.

  • Вы подключили датчик к универсальному входу `UI-10`. Какой узел в Node-RED вы используете для чтения его состояния?
  • * а) `mqtt in`

    * б) `modbus-read`

    * в) `rpi gpio in`

    * г) `http in`

  • В документации на Modbus-устройство указан Holding Register `40016`. Какой адрес нужно указать в узле `Modbus-Getter`?
  • * а) 40016

    * б) 16

    * в) 15

    * г) 40015

  • Какая основная роль у шины RS-485 в типовых проектах на контроллере HI?
  • * а) Подключение к интернету.

    * б) Питание датчиков.

    * в) Объединение промышленных устройств (счетчиков, модулей) по протоколу Modbus RTU.

    * г) Управление освещением по протоколу DALI.

  • Что произойдет, если два устройства на одной шине RS-485 будут иметь одинаковый адрес?
  • * а) Они будут работать по очереди.

    * б) Возникнет конфликт адресов, и связь на шине станет нестабильной или невозможной.

    * в) Контроллер автоматически назначит им новые адреса.

    * г) Ничего, это нормальная ситуация.

  • Вы хотите создать простой веб-интерфейс для отладки сценариев. Какой инструмент, встроенный в платформу HI, лучше всего для этого подойдет?
  • * а) База данных MySQL.

    * б) Написание собственного веб-сервера на Python.

    * в) Палитра Node-RED Dashboard.

    * г) Мобильное приложение от стороннего разработчика.

  • Какую информацию обязательно должен содержать `msg.payload` согласно стандартному контракту сообщения?
  • * а) `value`, `unit`, `color`

    * б) `value`, `source`, `ts`

    * в) `data`, `ip_address`, `port`

    * г) `payload`, `topic`, `qos`

    ---

    Мини-runbook «Если что-то не работает»

    📋 Симптом: Modbus-устройство не отвечает (ошибки Timeout в Node-RED).

  • Проверка физики: Проверьте полярность шины (A/B). Попробуйте поменять провода A и B местами на клеммах контроллера.
  • Проверка питания: Убедитесь, что на устройство подается питание.
  • Проверка адреса: Убедитесь, что `Unit-ID` в узле Node-RED совпадает с адресом, настроенным на самом устройстве.
  • Проверка параметров шины: Проверьте, что скорость (Baud Rate), четность (Parity) и стоп-биты в настройках Modbus-клиента в Node-RED идентичны настройкам на устройстве.
  • Проверка терминирования: Убедитесь, что на двух крайних устройствах шины RS-485 установлены терминирующие резисторы 120 Ом.
  • 📋 Симптом: Команда по MQTT не доходит до контроллера или статус не обновляется в приложении.

  • Проверка подключения к брокеру: Посмотрите на статус узлов `mqtt in`/`out` в Node-RED. Он должен быть "connected" (зеленый кружок).
  • Проверка топиков: Убедитесь, что тема (topic), в которую приложение публикует команду, в точности совпадает с темой, на которую подписан узел `mqtt in` на контроллере (включая все слеши и регистр символов).
  • Проверка контракта: Убедитесь, что JSON, отправляемый приложением, соответствует ожидаемому формату. Используйте узел `Debug`, подключенный сразу после `mqtt in`, чтобы увидеть точное содержимое приходящего `msg`.
  • Проверка брокера: Подключитесь к брокеру сторонним MQTT-клиентом (например, MQTT Explorer) и подпишитесь на нужные темы. Посмотрите, доходят ли сообщения до брокера и в каком виде.
  • 📋 Симптом: Датчик "сухого контакта" (кнопка, геркон) не срабатывает.

  • Проверка подключения: Убедитесь, что один контакт датчика подключен к клемме GND универсального входа, а второй — к сигнальной клемме (например, `UI-06`).
  • Проверка конфигурации GPIO: В узле `rpi gpio in` убедитесь, что вы выбрали правильный номер пина (GPIO), соответствующий клемме.
  • Проверка подтяжки: Убедитесь, что в настройках узла `rpi gpio in` включен внутренний подтягивающий резистор (`pull-up`).
  • "Прозвонка": Отключите провода от контроллера и с помощью мультиметра в режиме "прозвонки" убедитесь, что контакт на датчике физически замыкается/размыкается.