Skip to content

Створення та налаштування базових вузлів Node-RED

Мета: Здобути навички налаштування та використання основних вузлів в середовищі Node-RED для створення ефективних потоків обробки даних.

Виконавець:
студент групи КН-41
Кривобоков Микита Олександрович


Завдання

  1. Додати наведений в додатку під-потік для симуляції потоку повідомлень.
  2. Використовуючи відповідний вузол необхідно розпарсити вхідне повідомлення в object.
  3. Визначити тип повідомлення.
  4. Вибрати необхідні для подальшої роботи поля з об'єкту.
  5. Конвертувати дати в локальний формат.
  6. Сформувати шаблони для виведення інформації в залежності від типу повідомлення.
  7. Згрупувати вузли обробки вмісту повідомлення, додати обробник помилок для цієї групи.
  8. Складіть звіт про виконану роботу, в якому необхідно перелічити використані вузли та їх налаштування.

Хід роботи

Додавання під-потоку для симуляції повідомлень

import subflow

Імпортуємо під-потік у проєкт, наданий код використовується для видачі повідомлень у певний проміжок часу.

Імпортований код під-потоку
[
    {
        "id": "5ff25a8154952a9f",
        "type": "subflow",
        "name": "Event Generator",
        "info": "",
        "category": "",
        "in": [],
        "out": [
            {
                "x": 1380,
                "y": 140,
                "wires": [
                    {
                        "id": "3f8ab4b9aaa2bc2c",
                        "port": 0
                    },
                    {
                        "id": "10d1ff149307607d",
                        "port": 0
                    }
                ]
            }
        ],
        "env": [],
        "meta": {},
        "color": "#DDAA99"
    },
    {
        "id": "f60b112f8aa59f69",
        "type": "debug",
        "z": "5ff25a8154952a9f",
        "d": true,
        "name": "Subflow:debugger",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1310,
        "y": 80,
        "wires": []
    },
    {
        "id": "4e6deeec483053f1",
        "type": "delay",
        "z": "5ff25a8154952a9f",
        "name": "Delay: Random (5-15s)",
        "pauseType": "random",
        "timeout": "5",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "5",
        "randomLast": "15",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 470,
        "y": 160,
        "wires": [
            [
                "e49af820b8dfa41c"
            ]
        ]
    },
    {
        "id": "9da3839fc9465d08",
        "type": "inject",
        "z": "5ff25a8154952a9f",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "15",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "alert",
        "payload": "",
        "payloadType": "date",
        "x": 230,
        "y": 160,
        "wires": [
            [
                "4e6deeec483053f1"
            ]
        ]
    },
    {
        "id": "e49af820b8dfa41c",
        "type": "switch",
        "z": "5ff25a8154952a9f",
        "name": "Check: Global event flag",
        "property": "isActive",
        "propertyType": "global",
        "rules": [
            {
                "t": "true"
            },
            {
                "t": "else"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 730,
        "y": 160,
        "wires": [
            [
                "78521d4b1874702b"
            ],
            [
                "f77de4dcf69c0536"
            ]
        ]
    },
    {
        "id": "10d1ff149307607d",
        "type": "function",
        "z": "5ff25a8154952a9f",
        "name": "Func: Generate alert start",
        "func": "\nreturn {\n    ...msg,\n    payload: `{\n    \"id\": 10,\n    \"location_title\": \"Закарпатська область\",\n    \"location_type\": \"oblast\",\n    \"started_at\": \"2022-01-20T12:16:39.000Z\",\n    \"finished_at\": null,\n    \"updated_at\": \"2022-01-20T12:45:26.316Z\",\n    \"alert_type\": \"air_raid\",\n    \"location_uid\": \"11\",\n    \"location_oblast\": \"Закарпатська область\",\n    \"location_oblast_uid\": \"11\",\n    \"location_raion\": \"Ужгородський район\",\n    \"notes\": \"За повідомленям голови ОВА\",\n    \"calculated\": false\n}`\n};",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1080,
        "y": 180,
        "wires": [
            [
                "f60b112f8aa59f69"
            ]
        ]
    },
    {
        "id": "f77de4dcf69c0536",
        "type": "change",
        "z": "5ff25a8154952a9f",
        "name": "Set: Global event flag",
        "rules": [
            {
                "t": "set",
                "p": "isActive",
                "pt": "global",
                "to": "true",
                "tot": "bool"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 720,
        "y": 240,
        "wires": [
            [
                "10d1ff149307607d"
            ]
        ]
    },
    {
        "id": "78521d4b1874702b",
        "type": "change",
        "z": "5ff25a8154952a9f",
        "name": "Set: Global event flag",
        "rules": [
            {
                "t": "set",
                "p": "isActive",
                "pt": "global",
                "to": "false",
                "tot": "bool"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 720,
        "y": 80,
        "wires": [
            [
                "3f8ab4b9aaa2bc2c"
            ]
        ]
    },
    {
        "id": "6f984a17d87093e9",
        "type": "comment",
        "z": "5ff25a8154952a9f",
        "name": "",
        "info": "",
        "x": 200,
        "y": 100,
        "wires": []
    },
    {
        "id": "3f8ab4b9aaa2bc2c",
        "type": "function",
        "z": "5ff25a8154952a9f",
        "name": "Func: Generate alert end",
        "func": "\nmsg.payload = `{\"id\":12,\"location_title\":\"Закарпатська область\",\"location_type\":\"oblast\",\"started_at\":\"2022-01-20T12:16:39.000Z\",\"finished_at\":\"2022-01-20T12:48:26.316Z\",\"updated_at\":\"2022-01-20T12:48:26.316Z\",\"alert_type\":\"air_raid\",\"location_uid\":\"11\",\"location_oblast\":\"Закарпатська область\",\"location_oblast_uid\":\"11\",\"location_raion\":\"Ужгородський район\",\"notes\":\"За повідомленям Командування Повітряних Сил\",\"calculated\":false}`\n\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1070,
        "y": 140,
        "wires": [
            [
                "f60b112f8aa59f69"
            ]
        ]
    }
]

Використання JSON вузла для парсингу

json converter

Компонент JSON з палітри parser забезпечує конвертацію вхідного String у вихідний object і навпаки.

Нормалізація об'єкта для повідомлення

normalize

Крок нормалізації дозволяє привести вхідний об'єкт у валідний стан, наприклад, конветувати дати, або видалити зайві поля.

Видалення полів

deleted fields

Під-потік нормалізації видаляє зайві поля такі як: id, location_type, location_title, updated_at, calculated, location_uid.

Причина видалення updated_at

Вважається що це поле використовується як технічне а не показник того що тривога була завершена. При перейменуванні location, повідомлення буде оновлено що призведе до його виводу як відбій тривоги.

Конвертація дат

Для конвертації використовується toLocaleTimeString() що забезпечує вивід часу відповідно до локалі.

const { started_at, finished_at, isActive } = msg.payload;

const started_time = new Date(started_at).toLocaleTimeString();
const finished_time = isActive ? null : new Date(finished_at).toLocaleTimeString();
const duration_time = !isActive ? Math.ceil((new Date(finished_at).getTime() - new Date(started_at).getTime()) / 1000) : null;

return {
    ...msg, payload: {
        ...msg.payload,
        started_time,
        finished_time,
        duration_time
    }
};

Для додавання поля isActive, використовується перевірка на null для наявного поля дати finished_at що позначає дату закінчення тривоги.

const { finished_at } = msg.payload;

return {
    ...msg, payload: {
        ...msg.payload,
        isActive: !finished_at
    }
};

Приведення типів тривоги

alert type

Перезаписує тип тривоги у форматоване значення.

Фільтр областей

alt text

Використовує switch компонент, керуючись значенням з поля payload.location_oblast_uid в даному випадку Закарпатська область повинна мати значення 11, інакше виняток.

Перевірка чи активна тривога

is active

Якщо true — форматує одразу через шаблон, інакше спочатку переводить час у читабельний формат використовуючи компонент із залежності node-red-contrib-moment, після чого виводить повідомлення за шаблоном.

Результат схеми вузлів

result schema

is true result

is false result


Висновок

Виконуючи практичну роботу було здобуто навички налаштування та використання основних вузлів в середовищі Node-RED, для створення ефективних потоків обробки даних на тематику повітряних тривог, де необхідно було нормалізувати вхідні дані та вивести їх за певним шаблоном.