ГлавнаяАкадемияCOURSE-16: Основы Интернета Вещей и практическое применение → Итоговый тест по модулю "Данные в системах IoT"

Итоговый тест по модулю "Данные в системах IoT"

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

COURSE-16-M03-QUIZ — Итоговый тест по модулю "Данные в системах IoT"

Введение

Данный тест предназначен для проверки знаний и практических навыков, полученных в Модуде 3 «Данные в системах IoT». Цель теста — оценить вашу способность работать с данными на платформе HI: от сбора с физических устройств до обработки, форматирования, хранения и подготовки к отправке в облачные сервисы.

Инструкции:

---

Задание 1: Форматирование данных по контракту (3 балла)

На универсальный вход `UI-01` контроллера HI подключен датчик температуры DS18B20. Его уникальный идентификатор (ID) в системе 1-Wire — `28-01234567abcd`. Узел Node-RED `ds18b20 in` вернул сырое значение температуры в виде строки: `"23.7"`.

Задача: Сформируйте корректное сообщение `msg.payload` в формате JSON согласно «Контракту сообщения» Академии HI. Временную метку (timestamp) можно оставить в виде заполнителя (например, `1678886400000`).

Критерии оценки:

Пример эталонного ответа:

{

"value": 23.7,

"source": "28-01234567abcd",

"ts": 1678886400000,

"unit": "°C"

}

---

Задание 2: Валидация данных (4 балла)

Инженер спроектировал поток Node-RED для чтения показаний мощности (в Ваттах) с однофазного счетчика электроэнергии, подключенного по Modbus RTU.

ASCII-схема потока:
[Inject: 10s] -> [Modbus-Getter: Read Power] -> [MQTT Out: telemetry/power/meter1]

Иногда из-за помех на линии RS-485 узел `Modbus-Getter` возвращает некорректное значение (например, `0` или `-1`), которое немедленно отправляется в MQTT.

Задача:
  • Опишите, в чем заключается потенциальная проблема данного потока для системы верхнего уровня (например, для аналитики или биллинга).
  • Предложите, какой узел (или узлы) необходимо добавить между `Modbus-Getter` и `MQTT Out` для решения этой проблемы. Кратко опишите логику работы этого узла.
  • Критерии оценки:

    Пример эталонного ответа:

  • Проблема: Поток отправляет в систему аналитики "сырые", невалидированные данные. Значения `0` или `-1` могут быть неверно интерпретированы системой верхнего уровня. Например, биллинговая система может посчитать, что потребление упало до нуля, а система аналитики зафиксирует ложные аномалии, что приведет к искажению отчетов и неверным бизнес-решениям.
  • Решение: Между `Modbus-Getter` и `MQTT Out` необходимо добавить узел `Function` для валидации данных.
  • Логика узла:

    * Узел получает на вход сообщение от `Modbus-Getter`.

    * Он проверяет, что полученное значение мощности (`msg.payload`) является числом и находится в допустимом диапазоне (например, `msg.payload >= 0`).

    * Если значение корректно, узел пропускает сообщение дальше в поток.

    * Если значение некорректно (не число, отрицательное), узел должен остановить дальнейшее распространение сообщения, вернув `return null;`. Дополнительно, он может сгенерировать ошибку с помощью `node.error()` для ее перехвата узлом `Catch`.

    ---

    Задание 3: Проектирование MQTT-топиков (4 балла)

    Вы проектируете систему "умный дом" для коттеджа. Необходимо разработать структуру MQTT-топиков для управления освещением в гостиной и получения данных с датчика движения в коридоре.

    Устройства: Задача: Предложите иерархическую структуру топиков для следующих сценариев:
  • Отправка команды на включение/выключение света.
  • Получение обратной связи о текущем состоянии света.
  • Получение данных о срабатывании датчика движения.
  • Критерии оценки:

    Пример эталонного ответа:

    Предлагается следующая структура: `project/location/device/type`

  • Команда на управление светом: `smart-cottage/livingroom/light-main/set` (сообщения: "ON", "OFF")
  • Состояние света: `smart-cottage/livingroom/light-main/state` (сообщения: "ON", "OFF")
  • Данные с датчика движения: `smart-cottage/corridor/motion-sensor-1/state` (сообщения: `{"value": true, ...}`)
  • 💡 Обоснование: Такая структура позволяет гибко подписываться на данные. Например, подписка на `smart-cottage/livingroom/#` позволит получить все события в гостиной, а на `smart-cottage/+/+/state` — все сообщения о состояниях устройств в доме.

    ---

    Задание 4: Обработка ошибок (5 баллов)

    Инженер создал поток для опроса Modbus-устройства. Он хочет, чтобы при любой ошибке связи (например, таймаут) в базу данных MySQL на контроллере записывалась информация об инциденте.

    Задача:
  • Назовите основной узел Node-RED, который используется для централизованного перехвата ошибок на вкладке.
  • Нарисуйте простую ASCII-схему, показывающую, как этот узел подключается к узлу `mysql` для записи лога.
  • Какая информация об ошибке, доступная в объекте `msg`, является наиболее важной для записи в лог? Назовите как минимум два ключевых свойства.
  • Критерии оценки:

    Пример эталонного ответа:

  • Узел: `Catch`.
  • ASCII-схема:
  •     // Поток обработки ошибок

    [Catch: All nodes] -> [Function: "Prepare SQL"] -> [mysql: "Log Error DB"]

  • Важные свойства для логирования:
  • * `msg.error.message`: Текстовое описание ошибки (например, "Timeout").

    * `msg.error.source.id`: Уникальный ID узла, который сгенерировал ошибку. Позволяет точно определить источник проблемы.

    * `msg.topic` или `msg.payload` из оригинального сообщения (если они сохранились), чтобы понять, какая операция вызвала сбой.

    ---

    Задание 5: Работа с Modbus (5 баллов)

    Счетчик электроэнергии отдает 32-битное значение активной энергии (типа `float`) в двух последовательных 16-битных Holding-регистрах, начиная с адреса `100`.

    Задача:
  • Как должен быть настроен узел `Modbus-Getter` для чтения этих данных одним запросом? (Укажите `FC`, `Address`, `Quantity`).
  • После чтения узел `Modbus-Getter` вернет `msg.payload` в виде массива из двух 16-битных чисел. Какая дополнительная операция требуется в узле `Function` для получения итогового `float` значения?
  • Назовите две частые ошибки при работе с многорегистровыми значениями в Modbus.
  • Критерии оценки:

    Пример эталонного ответа:

  • Настройки `Modbus-Getter`:
  • * `FC`: `FC 3: Read Holding Registers`

    * `Address`: `100`

    * `Quantity`: `2`

  • Дополнительная операция: Необходимо работать с буфером данных. Узел `Modbus-Getter` предоставляет `msg.payload.buffer`. В узле `Function` нужно использовать встроенные методы Node.js для чтения числа из буфера, например: `let value = msg.payload.buffer.readFloatBE(0);` (Big-Endian) или `readFloatLE(0);` (Little-Endian), в зависимости от спецификации устройства.
  • Частые ошибки:
  • * Неправильный порядок байт/слов (Endianness): Устройство может возвращать старший и младший байты/слова в разном порядке. Если не учесть это, значение будет неверным.

    * Ошибка "на единицу" (Off-by-one error): В документации может быть указан регистр `40101`, что соответствует адресу `100` в запросе. Инженеры часто ошибочно указывают `101`.

    ---

    Задание 6: Управление состоянием (FSM) (5 баллов)

    Необходимо реализовать логику работы простого кондиционера с тремя состояниями: `Off`, `Cooling`, `FanOnly`. Переходы между состояниями инициируются MQTT-командами.

    Задача:
  • Где в Node-RED следует хранить текущее состояние (`Off`, `Cooling` или `FanOnly`), чтобы оно было доступно в рамках одной вкладки (flow) и не терялось при пропадании питания?
  • Какой узел Node-RED является ключевым для маршрутизации логики в зависимости от текущего состояния?
  • Нарисуйте ASCII-схему простого конечного автомата (FSM) для этой задачи.
  • Критерии оценки:

    Пример эталонного ответа:

  • Хранение состояния: Текущее состояние следует хранить в переменной контекста уровня потока (`flow context`). Чтобы состояние не терялось при перезагрузке контроллера, в файле `settings.js` необходимо настроить `contextStorage` на использование файловой системы, что является стандартной возможностью платформы HI.
  • Ключевой узел: Узел `Switch`. Он будет проверять значение переменной `flow.ac_state` и направлять сообщение по разным выходам в зависимости от текущего состояния.
  • ASCII-схема:
  •     [MQTT In: cmd] -> [Switch: by flow.ac_state] --+-- (state: Off) ----> [Logic for Off] ----+-> [Change: set flow.ac_state]

    |

    +-- (state: Cooling) --> [Logic for Cooling]--+

    |

    +-- (state: FanOnly) --> [Logic for FanOnly]--+

    ---

    Задание 7: Визуальный статус (3 балла)

    Вы создали поток, который считывает температуру. Вы хотите, чтобы под узлом, который обрабатывает данные, отображался его текущий статус (например, "OK: 25.1°C" зеленым цветом или "Error" красным).

    Задача:
  • Какой узел Node-RED позволяет отслеживать и реагировать на статусы других узлов?
  • Какую команду нужно написать внутри узла `Function`, чтобы установить его собственный статус? Приведите пример для успешного считывания температуры `25.1°C`.
  • Критерии оценки:

    Пример эталонного ответа:

  • Узел: `Status`.
  • Команда: `node.status()`.
  • Пример кода:

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

    ---

    Задание 8: Переиспользуемые компоненты (4 балла)

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

    Задача:
  • Какой механизм в Node-RED следует использовать, чтобы избежать 15-кратного копирования одной и той же группы узлов?
  • Как параметризовать этот механизм, чтобы каждый его экземпляр управлял своим уникальным реле (например, указать ему номер реле или MQTT-топик)?
  • Критерии оценки:

    Пример эталонного ответа:

  • Механизм: Необходимо использовать субпотоки (Subflows). Логика управления реле выносится в отдельный субпоток.
  • Параметризация: В настройках субпотока (во вкладке `Properties`) создаются переменные окружения (Environment Variables). Например, можно создать переменные `RELAY_ID` и `MQTT_TOPIC`. При размещении экземпляра субпотока в основном потоке, для него можно будет задать уникальные значения этих переменных, что позволит одному и тому же коду работать с разным оборудованием.
  • ---

    Задание 9: Диагностика физического уровня (4 балла)

    После монтажа системы на объекте вы обнаружили, что ни одно из 10 устройств на шине RS-485 не отвечает на запросы контроллера HI.

    Задача: Перечислите 3 наиболее вероятные причины проблемы, начиная с самых базовых (физических).

    Критерии оценки:

    Пример эталонного ответа:

  • Неправильная полярность шины: Провода `A` и `B` перепутаны на клеммах контроллера или одного из устройств. Это самая частая причина.
  • Отсутствие терминирующих резисторов: На длинной шине (> 20-30 м) отсутствие резисторов 120 Ом на ее концах приводит к отражению сигнала и невозможности коммуникации.
  • Проблема с питанием: На Modbus-устройства не подано питание 12/24V, либо оно подано некорректно.
  • ---

    Задание 10: Хранение данных (4 балла)

    Ваш поток Node-RED успешно сформировал сообщение о событии согласно «Контракту сообщения». Теперь его нужно записать в таблицу `events_log` в локальной базе данных MySQL.

    Таблица `events_log`:

    `id (INT, PK, AI), ts (BIGINT), source (VARCHAR), value (DOUBLE), unit (VARCHAR)`

    Сообщение `msg.payload`:
    {
    

    "value": 23.7,

    "source": "28-01234567abcd",

    "ts": 1678886400000,

    "unit": "°C"

    }

    Задача: Напишите шаблон SQL-запроса `INSERT`, который будет сформирован в узле `Function` или `Template` для записи этих данных. Используйте плейсхолдеры для значений.

    Критерии оценки:

    Пример эталонного ответа:

    Для узла `Template`:

    INSERT INTO events_log (ts, source, value, unit)
    

    VALUES ({{{payload.ts}}}, '{{{payload.source}}}', {{{payload.value}}}, '{{{payload.unit}}}');

    💡 Примечание: Для строковых значений (`source`, `unit`) используются кавычки, а для числовых (`ts`, `value`) — нет. Узел `mysql` также поддерживает параметризованные запросы для защиты от SQL-инъекций, что является предпочтительным методом.

    ---

    Задание 11: Анализ потока (5 баллов)

    Инженер написал поток для включения света по датчику движения. Свет должен выключаться через 60 секунд, если новых движений не было.

    ASCII-схема потока:
    [MQTT In: motion] -> [Change: set msg.payload="ON"] -> [Relay Out] -> [Delay: 60s] -> [Change: set msg.payload="OFF"] -> [Relay Out]
    
    Задача:
  • Опишите, какая проблема возникнет в работе этой логики, если во время 60-секундной задержки произойдет новое движение.
  • Какой узел Node-RED лучше подходит для реализации такой логики "с перезапуском таймера"?
  • Критерии оценки:

    Пример эталонного ответа:

  • Проблема: Узел `Delay` просто задерживает сообщение. Если во время отсчета 60 секунд придет новое сообщение о движении, оно запустит параллельную ветку, и в итоге свет может выключиться, даже если в помещении кто-то есть. Логика не "перезапускает" таймер.
  • Решение: Для этой задачи идеально подходит узел `Trigger`. Его можно настроить так: при получении сообщения он отправляет команду "ON", затем ждет 60 секунд. Если за это время приходит новое сообщение, он сбрасывает свой таймер и начинает отсчет заново. Если же за 60 секунд новых сообщений не было, он автоматически отправит второе сообщение (команду "OFF").
  • ---

    Задание 12: Облачная интеграция (3 балла)

    Контроллер HI собирает данные с сотен датчиков на объекте. Необходимо передавать эти данные в облачную платформу (например, AWS IoT, Azure IoT Hub) для долгосрочного хранения и анализа.

    Задача: Какую роль в этой архитектуре выполняет MQTT-брокер, развернутый на контроллере HI или в локальной сети? Опишите его как посредника.

    Критерии оценки:

    Пример эталонного ответа:

    Локальный MQTT-брокер выполняет роль шлюза (Gateway) и агрегатора.

  • Агрегатор: Все потоки Node-RED на контроллере публикуют свои обработанные данные в топики на этом локальном брокере. Это позволяет отвязать логику сбора данных от логики их отправки.
  • Шлюз: Брокер настраивается в режиме "моста" (MQTT bridge) с облачным MQTT-брокером (например, AWS IoT Core). Он устанавливает одно защищенное соединение с облаком и пересылает в него все (или только необходимые) сообщения из локальной сети. Это эффективно, безопасно и позволяет всей локальной системе оставаться работоспособной даже при временной потере связи с интернетом.