Практические методы анализа данных на контроллере HI
COURSE-16-M03-L05 — Практические методы анализа данных на контроллере HI
Введение в аналитику на Edge-устройствах
В экосистеме Интернета вещей (IoT) данные являются главным активом. Контроллер HI непрерывно собирает информацию с десятков датчиков и устройств. Однако сырые данные сами по себе бесполезны. Их ценность раскрывается только через анализ.
Вопреки распространенному мнению, сложный анализ данных — это не только прерогатива мощных облачных серверов. Значительную часть аналитической работы можно и нужно выполнять непосредственно на «краю» сети (Edge Computing), то есть на самом контроллере. Это обеспечивает высокую скорость реакции, автономность системы при потере связи с интернетом и снижение затрат на трафик.
В этом уроке мы разберем четыре уровня анализа данных и, что самое важное, научимся реализовывать их на практике с помощью Node-RED на контроллере HI. Мы превратим абстрактные концепции в работающие сценарии автоматизации для реальных объектов.
Четыре уровня аналитики данных в IoT
Анализ данных можно условно разделить на четыре ступени, каждая из которых отвечает на свой вопрос и повышает ценность системы.
* Цель: Агрегировать и суммировать исторические данные для получения общей картины.
* Пример: Расчет среднего расхода электроэнергии за последний час, определение максимальной температуры в помещении за сутки.
* Цель: Найти взаимосвязи и причины событий путем сопоставления различных данных.
* Пример: Установить, что скачок энергопотребления совпал по времени с включением системы кондиционирования.
* Цель: Использовать исторические данные для прогнозирования будущих состояний и событий.
* Пример: Спрогнозировать, через сколько часов заполнится бак для сбора конденсата, на основе текущей скорости его наполнения.
* Цель: На основе анализа и прогнозов автоматически принимать оптимальные решения и выполнять действия.
* Пример: Автоматически перевести систему отопления в экономичный режим, если прогноз погоды обещает потепление и в здании нет людей.
Далее мы рассмотрим, как реализовать каждый из этих уровней на платформе HI.
Описательная аналитика: «Что произошло?»
Это базовый уровень, с которого начинается любой анализ. Наша задача — преобразовать поток сырых данных в осмысленную сводку.
Практический сценарий: Анализ температуры в серверной. Необходимо каждые 10 минут получать минимальное, максимальное и среднее значение температуры за этот интервал и отправлять их в MQTT для отображения на дашборде. Реализация в Node-RED (FLOW-ANALYSIS-DESC-001):[1-Wire In] -> [Function: Validate] -> [Aggregator: 10 min] -> [Function: Calculate Stats] -> [MQTT Out]
| |
+--------------------(on error)-----------------------------------+-> [Catch] -> [Log Error]
Код для узла `Function: Calculate Stats`:
// Входящее сообщение msg.payload - это массив значений, например:
// [25.1, 25.2, 25.1, 25.3, 25.4, 25.3, 25.2, 25.3, 25.4, 25.5]
const values = msg.payload;
if (!Array.isArray(values) || values.length === 0) {
node.status({fill:"yellow", shape:"ring", text:"No data in interval"});
return null;
}
const sum = values.reduce((a, b) => a + b, 0);
const avg = (sum / values.length) || 0;
const min = Math.min(...values);
const max = Math.max(...values);
// Формируем исходящее сообщение по контракту
msg.payload = {
"avg_temp": parseFloat(avg.toFixed(2)),
"min_temp": min,
"max_temp": max,
"period_sec": 600,
"source": "temp-sensor-server-room",
"ts": Date.now()
};
msg.topic = "telemetry/server-room/temperature/summary";
// 💡 Паттерн "Визуальный статус": отображаем результат прямо на узле
node.status({fill:"green", shape:"dot", text:`Avg: ${avg.toFixed(1)}°C`});
return msg;
Диагностическая аналитика: «Почему это произошло?»
Этот уровень помогает находить скрытые зависимости. Мы не просто фиксируем событие, а пытаемся понять его причину, сопоставляя данные из разных источников.
Практический сценарий: В офисном помещении резко ухудшилось качество воздуха (вырос уровень CO2). Необходимо выяснить причину: это произошло из-за большого скопления людей или из-за отключения вентиляции? Реализация в Node-RED (FLOW-ANALYSIS-DIAG-003):* Поток 1: Узел `Modbus-Read` опрашивает датчик CO2 (например, WB-MSW3) и отправляет значение.
* Поток 2: Узел `Modbus-Read` опрашивает релейный модуль, чтобы узнать состояние вентилятора (включен/выключен).
* Поток 3: Узел `Presence Detector` (например, на базе дискретного входа от датчика движения) считает количество людей.
[Modbus: CO2] --+
+--> [Join: 3 parts] -> [Function: Diagnose] -> [MQTT Alert]
[Modbus: Fan] --+
|
[Presence In] --+
Код для узла `Function: Diagnose`:
// Входящий msg.payload после узла Join:
// { "co2": 1250, "fan_state": "OFF", "presence_count": 5 }
const co2_level = msg.payload.co2;
const fan_state = msg.payload.fan_state;
const people_count = msg.payload.presence_count;
let diagnosis = "Причина не установлена";
let alert_level = "info";
// 💡 Простая логика корреляции
if (co2_level > 1000) { // Порог превышен
if (fan_state === "OFF") {
diagnosis = "Высокий CO2: Вентиляция отключена!";
alert_level = "critical";
} else if (people_count > 4) {
diagnosis = "Высокий CO2: Много людей в помещении.";
alert_level = "warning";
}
} else {
// Уровень CO2 в норме, ничего не делаем
node.status({fill:"green", shape:"dot", text:`CO2 OK: ${co2_level} ppm`});
return null;
}
msg.payload = {
"alert_level": alert_level,
"message": diagnosis,
"details": {
"co2_ppm": co2_level,
"fan_state": fan_state,
"people_count": people_count
},
"ts": Date.now()
};
msg.topic = "alerts/office/air_quality/diagnosis";
node.status({fill:"red", shape:"dot", text: diagnosis});
return msg;
Предсказательная аналитика: «Что произойдет?»
Здесь мы делаем шаг от анализа прошлого к прогнозированию будущего. На уровне контроллера это редко бывают сложные модели машинного обучения, но даже простые прогнозы на основе трендов чрезвычайно полезны.
Практический сценарий: Мониторинг заполнения дренажного бака системы кондиционирования. Необходимо спрогнозировать, когда бак заполнится, чтобы вовремя отправить уведомление службе эксплуатации и избежать протечки. Реализация в Node-RED (FLOW-ANALYSIS-PRED-002):[Analog In: Level] -> [RBE] -> [Smooth] -> [Function: Predict Time] -> [Switch: Check Threshold] -> [MQTT Alert]
Код для узла `Function: Predict Time`:
// Входящий msg.payload от узла smooth может выглядеть так:
// { "value": 75, "rate_min": 0.5 } // Уровень 75%, скорость +0.5% в минуту
const TANK_CAPACITY_PERCENT = 100;
const current_level = msg.payload.value;
const rate_per_minute = msg.payload.rate_min;
if (rate_per_minute <= 0) {
// Уровень не растет или падает
node.status({fill:"green", shape:"dot", text:`Level: ${current_level.toFixed(1)}%`});
return null;
}
const remaining_capacity = TANK_CAPACITY_PERCENT - current_level;
const minutes_to_full = remaining_capacity / rate_per_minute;
// Формируем сообщение с прогнозом
msg.payload = {
"current_level_percent": current_level,
"rate_percent_per_min": rate_per_minute,
"predicted_minutes_to_full": parseFloat(minutes_to_full.toFixed(1))
};
// 💡 Обновляем статус для наглядности
node.status({fill:"yellow", shape:"ring", text:`Full in ~${Math.round(minutes_to_full)} min`});
return msg;
Далее узел `Switch` проверяет, если `predicted_minutes_to_full < 60`, и отправляет предупреждение.
Предписывающая аналитика: «Что следует сделать?»
Высший уровень автоматизации. Система не просто информирует, а самостоятельно принимает и исполняет решения. Это — ядро умных сценариев.
Практический сценарий: Интеллектуальное управление бойлером в умном доме для экономии электроэнергии. Логика (предписание):- Если сейчас утро буднего дня и в доме есть люди, нагреть воду до 65°C (режим «Комфорт»).
- Если в доме никого нет или сейчас ночь, поддерживать температуру на уровне 45°C (режим «Эко»).
- Если активирован режим «Отпуск», полностью отключить нагрев.
Здесь идеально подходит паттерн "Конечный автомат" (FSM).
// Inputs
[Scheduler] --+
+--> [Join] -> [Switch: Check State] --+-- (State: OFF) ----> [Logic for OFF] --+
[Presence] ---+ | |
+-- (State: ECO) ----> [Logic for ECO] --+--> [Change: Set State] -> [Modbus Write]
[Manual UI] --+ | |
+-- (State: COMFORT) -> [Logic for COMFORT]--+
Эта реализация является классическим примером предписывающей аналитики: система анализирует контекст (`почему?`), прогнозирует потребность в горячей воде (`что будет?`) и отдает команду (`что делать?`).
---
📋 Лабораторные работы
COURSE-16-M03-LAB01: Описательный анализ температуры
- Цель: Создать поток, который эмулирует данные с датчика температуры, рассчитывает минимальное, максимальное и среднее значение за 1 минуту и выводит результат в узел `Debug`.
- Скелет потока: `[Inject]` -> `[Function: Эмулятор датчика]` -> `[Delay: 5 сек]` -> `[Aggregator]` -> `[Function: Расчет статистики]` -> `[Debug]`.
- Чек-лист выполнения:
2. [ ] `Function: Эмулятор датчика` генерирует случайное число в диапазоне 20-25.
3. [ ] `Aggregator` настроен на сбор данных в течение 1 минуты.
4. [ ] `Function: Расчет статистики` корректно вычисляет min, max, avg.
5. [ ] Узел `Debug` выводит JSON-объект с тремя рассчитанными значениями.
6. [ ] На узле расчета статистики настроен `node.status` для вывода среднего значения.
- Рубрика оценивания: Задание считается выполненным, если в панели `Debug` раз в минуту появляется корректно сформированный объект со статистикой.
COURSE-16-M03-LAB02: Диагностика и предписание для освещения
- Цель: Создать поток, который включает реле (эмулируется узлом `Debug`) только при выполнении двух условий: в помещении темно И обнаружено движение.
- Скелет потока:
* Поток 2: `[Inject: "motion"]` -> `[Function: Проверка условий]` -> `[Debug: "Включить свет!"]`
- Чек-лист выполнения:
2. [ ] Состояние освещенности сохраняется в `flow` контексте.
3. [ ] `Function: Проверка условий` срабатывает от датчика движения.
4. [ ] Внутри функции происходит чтение `flow.light_level`.
5. [ ] Сообщение в `Debug` отправляется, только если `flow.light_level == "dark"`.
- Рубрика оценивания: Задание выполнено, если сообщение "Включить свет!" появляется только после нажатия `Inject: "motion"`, при условии, что до этого был нажат `Inject: "dark"`.
---
📝 Квиз по модулю (COURSE-16-M03-QUIZ)
* a) Диагностическая
* b) Описательная
* c) Предсказательная
* a) Описательной аналитики
* b) Диагностической аналитики
* c) Предписывающей аналитики
* a) `Switch`
* b) `Function`
* c) `Join`
* a) Контракт сообщения
* b) Конечный автомат (FSM)
* c) Визуальный статус
* a) Диагностическая аналитика
* b) Предсказательная аналитика
* c) Описательная аналитика
* a) Для снижения нагрузки на процессор контроллера
* b) Для обеспечения автономности и быстрой реакции системы
* c) Потому что в облаке нет нужных инструментов
* a) `Delay`
* b) `RBE`
* c) `Smooth`
* a) Диагностической аналитики
* b) Предсказательной аналитики
* c) Описательной аналитики
* a) Лицензионное соглашение на использование узла
* b) Стандартный формат JSON-объекта `msg.payload` для обмена данными между узлами
* c) Зашифрованное сообщение
* a) Описательной аналитики
* b) Диагностической аналитики
* c) Предписывающей аналитики
---
🆘 Мини-runbook «Если не работает»
- Проблема: Статистика (min/max/avg) не рассчитывается или равна 0/null.
- Проблема: Прогноз (например, время до заполнения) постоянно "скачет" или некорректен.
- Проблема: Диагностический сценарий (например, CO2 + вентилятор) не срабатывает.
- Проблема: Сценарий на базе конечного автомата (FSM) "забывает" свое состояние после перезагрузки контроллера.
⚠️ Типовые ошибки и план тестирования при сдаче объекта
- Типовые ошибки:
* Жестко заданные пороги: Пороги для тревог (например, 1000 ppm для CO2) зашиты прямо в коде. Решение: Выносите такие параметры в переменные `flow` контекста или используйте UI-элементы дашборда для их настройки.
* Игнорирование единиц измерения: Смешивание в расчетах разных единиц (ватты и киловатты, градусы Цельсия и Фаренгейта). Решение: Используйте "контракт сообщения", где `unit` является обязательным полем.
- План тестирования аналитических сценариев на объекте:
2. [ ] Тест диагностической аналитики: Имитировать событие. Например, закрыть вентиляционную решетку у датчика CO2. Убедиться, что система сгенерировала корректное тревожное сообщение («Высокий CO2: возможно, проблема с вентиляцией»).
3. [ ] Тест предсказательной аналитики: Имитировать тренд. Например, медленно подливать воду в емкость с датчиком уровня. Убедиться, что система показывает адекватное прогнозное время до заполнения и вовремя выдает предупреждение.
4. [ ] Тест предписывающей аналитики: Проверить работу автоматических сценариев в разных режимах. Переключить дом в режим «Никого нет». Убедиться, что климатические системы перешли в экономичный режим, а бойлер снизил температуру нагрева. Вернуть режим «Дома» и проверить возврат к комфортным настройкам.