Технології індустрії 4.0. Лекції. Автор і лектор: Олександр Пупена
<- до лекцій | на основну сторінку курсу |
---|---|
Node-RED - це інструмент для візуального програмування потоків даних, розроблений працівниками компанії IBM для поєднання різноманітних пристроїв, API та онлайн-сервісів як складових частин Інтернету речей. Node-RED дає можливість програмувати об’єднані апаратні пристрої, API та сервіси онлайн новими способами, інколи навіть не використовуючи текстові мови програмування.
Редактор Node-RED базується на браузері, який дозволяє легко об’єднувати в потоки вузли з широкого набору палітри, які можуть бути розгорнуті для виконання лише одним клацанням миші.
Node-RED дає змогу працювати з браузерним редактором потоків даних як окремими вузлами з різним функціоналом, що уможливлюють створення JavaScript-функцій. Причому можна використовувати як базові вузли, якими одразу забезпечений Node-RED, так і встановлювати вузли з додатковим функціоналом з репозиторію NPM або ж навіть створити свій власний вузол з унікальним функціоналом.
Програми або ж їхні частини, розроблені за допомогою Node-RED, можуть бути збережені та поширені для вільного використання. Саме середовище побудовано на основі Node.js, яке буде вивчатися в одній з наступних лекцій. За ініціативою IBM у 2016 році Node-RED став відкритим програмним забезпеченням (open-source) як частина проекту JS Foundation.
Легке середовище виконання (runtime) побудоване на Node.js, в повній мірі використовуючи перевагу його подіє-орієнтованої не блокуючої моделі. Це робить його ідеальним для роботи на краю (Edge) мережі на недорогих апаратних засобах, таких як Raspberry Pi, а також у хмарі.
Діапазон вузлів палітри легко розширити додаванням великої кількості модулів (сотні тисяч) зі сховища Node щоб отримати нові можливості.
Потоки, створені в Node-RED, зберігаються за допомогою JSON, що дозволяє легко імпортувати та експортувати їх для спільного використання з іншими.
Детальний опис редактору доступний за посиланням
Редактор складається з таких 4 компонентів:
рис.2.1. Вигляд редактору Node-RED.
Уся програма складається з об’єднання вузлів – потоків (flow). Потоки розробляються в межах вкладок браузера з певною назвою. Вкладки також називаються потоками, хоч на них може бути кілька наборів об’єднаних вузлів.
Термін “потік” також використовується для неофіційного опису одного набору підключених вузлів. Таким чином, потік (вкладка) може містити кілька потоків (набори з’єднаних вузлів).
Потоки можна добавляти, видаляти, деактивувати (вони не розгортаються). До потоків можна добавляти опис у форматі MarkDown.
Вузли (Nodes) можуть бути додані до робочої області з палітри або безпосередньо по імені.
Вузли з’єднуються один з одним за допомогою з’єднань через їхні входи та виходи, які називаються портами. Вузол може мати:
Порт може мати мітку (label), що буде показуватися при наведенні курсору. Деякі вузли відображають статусне повідомлення або піктограми поряд з ними. Це використовується для позначення стану вузла в режимі виконання. Якщо вузол має які-небудь зміни, що не були розгорнуті в режимі виконання, це буде відображено синім кружком над ним. Якщо є помилки у конфігурації, то буде відображатися червоний трикутник. Вузли Inject
і Debug
є єдиними вузлами, які мають кнопки керування: вприскування (Inject
) та відображення повідомлення (Debug
).
Діалогове вікно редагування вузла має три окремих розділи: властивості (properties), опис (Description) та зовнішній вигляд (Appearance) .
Конфігураційні вузли (config Node) - це спеціальний тип вузла, що містить конфігурацію багаторазової доступності, що може бути розподілена між звичайними вузлами потоку. Доступ до них відбувається через бічну панель.
Вузли можуть бути об’єднані разом, щоб утворити групу (Group). Потім вони можуть бути переміщені або скопійовані як єдиний об’єкт у редакторі.
Під-потоки (subflow) - це сукупність вузлів, які згортаються в єдиний вузол у робочій області. Вони можуть бути використані для зменшення певної візуальної складності потоку або для об’єднання групи вузлів, що використовується в різних місцях. Після створення, під-потік додається до палітри доступних вузлів. Потім окремі екземпляри під-потоку можна додати до робочої області, як і будь-який інший вузол. Під-потік не може існувати сам собою без жодних вузлів, він повинен містити їх прямо або опосередковано. Як і в звичайних потоках у вузлах підпотоків, може бути не більше одного вводу та багато виходів, за необхідності. Кожен запис у таблиці властивостей можна розширити, щоб налаштувати його відображення під час редагування екземпляру підпотоку.
Потоки можна імпортувати та експортувати з редактора, використовуючи формат JSON, що дозволяє дуже легко обмінюватися потоками з іншими редакторами.
Діалогове вікно Імпорту можна використовувати для імпорту потоку за допомогою таких методів:
Палітра містить всі вузли, які встановлені та доступні для використання. Вони організовані в декілька категорій починаючи зверху з inputs, outputs та functions. Якщо є під-потоки, вони з’являються у категорії у верхній частині палітри.
Для встановлення нових вузлів до палітри може використовуватися менеджер палітри (Palette Manager). Доступ до нього можна отримати за вкладкою Palette tab в User Settings dialog.
Бічна панель надає наступні можливості:
Деякі вузли додають власні панелі бічної панелі, наприклад node-red-dashboard
Потік Node-RED працює, передаючи повідомлення між вузлами. Повідомлення є простими об’єктами JavaScript, які можуть мати будь-який набір властивостей. Повідомлення, як правило, мають властивість payload
, це властивість за умовчанням, з якою працюватиме більшість вузлів. Node-RED також додає властивість, що називається _msgid
- це ідентифікатор для повідомлення, яке може використовуватися для відстеження його проходження потоком
{
"_msgid": "12345",
"payload": "..."
}
Значенням властивості може бути будь-який дійсний тип JavaScript, наприклад
Boolean
– true, falseNumber
– наприклад 0, 123.4String
– “hello”Array
- [1,2,3,4]Object
- { “a”: 1, “b”: 2}Null
Докладніше про типи JavaScript буде в наступних лекціях.
Найпростіший спосіб зрозуміти структуру повідомлення - передати його в вузол Debug
і переглянути його на бічній панелі Debug. За замовчуванням на вузлі Debug відображатиметься властивість msg.payload
, але може бути налаштована для відображення будь-яка інша властивість або все повідомлення цілком. При відображенні масиву, або об’єкта, бічна панель забезпечує структурований вигляд, який може використовуватися для вивчення повідомлення.
рис.2.2. Перегляд структури повідомлення на бічній панелі Debug
msg.payload
До вузлів, що входять до стандартної комплектації Node-RED v.1.1 відносяться:
Мережні вузли, парсери та storage будуть розглянуті в інших лекціях.
Довідник по всім основним вузлам доступний за посиланням.
рис.2.3. Основні вузли Node-RED
Таблиця 2.1. Перелік загальних вузлів
Вузол | Призначення |
---|---|
Inject для ініціювання потоку (відправки повідомлення) користувачем, автоматично при запуску, періодично або за розкладом. | |
Debug використовується для відображення повідомлень на бічній панелі Debug у редакторі. | |
Complete запускає потік, коли інший вузол завершує оброблення повідомлення. | |
Catch ловить помилки виконання інших вузлів у тому самому потоці (вкладці) і формує повідомлення з інформацією про них. | |
Status показує стан (status message) вказаних або усіх вузлів в потоці. | |
Link in вхідне з’єднання з іншого потоку | |
Link out вихідне з’єднання до іншого потоку | |
Comment для добавлення коментарів в потік. | |
Unknown вузол невідомого типу для встановленого Node-RED |
Вузол Inject потрібен для ініціювання потоку (відправки повідомлення) користувачем, автоматично при запуску, періодично або за розкладом. У налаштуваннях вузла можна вказати тему повідомлення (Topic
) та значення Payload
. У новіших версіях можливості вузла Inject
значно розширилися. Тепер в ньому можна задавати будь яку властивість повідомлення а також вказувати налаштування запуску в певні дні тижня по календарю. Для payload можна встановити різні типи: відмітку часу (Timestamp), константу, значення контекстів потоку (flow context
) або глобального контексту (global context
), $env variable
– змінну середовища Node.js, J:expression
– JSONata перетворення.
Вузол Debug використовуватися для відображення повідомлень на бічній панелі Debug у редакторі, середовища виконання або зображення статусу вузла. Бічна панель забезпечує структурований перегляд повідомлень, що надсилаються, що полегшує вивчення цього повідомлення. Поряд з кожним повідомленням бічна панель налагодження включає в себе інформацію про час надходження повідомлення та місце з якого вузлу воно надіслане. Натискання на ідентифікатор вихідного вузла покаже цей вузол у робочій області. Кнопку на вузлі можна використовувати для ввімкнення або вимкнення його виходів.
Потоки різних вкладок можна з’єднувати між собою інформаційними дротами. Це робиться за допомогою вузлів Link in (вхідне з’єднання з іншого потоку) та Link out (вихідне з’єднання до іншого потоку). Таким чином потік на одній вкладці передає повідомлення до потоку іншої вкладки.
Вузол Catch буде розглянуто в іншій темі.
JSON (JavaScript Object Notation) - це стандартний спосіб подання об’єкта JavaScript у вигляді рядку (string). Він часто використовується у веб-API для відправки та повернення даних.
Усі об’єкти беруться у фігурні дужки. Це приклад порожнього об’єкту.
{}
Властивості об’єкту типу ключ-значення записуються наступним чином:
{"key1" : 23 , "key2" : "24", "key5" : {"key5_1": 37, "key5_2": [123, 124]} }
Ключі обовязково беруться в подвійні лапки.
Масиви записуються з використанням квадратних дужок, в яких перераховуються елементи масиву:
[10, "20", 30]
У якості елементів можна використовувати різні типи даних: Number, String (“”), Object, Array, true/false, null. Таким чином масиви та об’єкти можуть включати у свою чергу масиви та об’єкти.
Структура msg та змінні контексту в Node-RED є об’єктами. Усі їх поля можна представити у вигляді JSON. Якщо властивість повідомлення містить рядок JSON, то перед тим, як отримувати доступ до його властивостей, його слід перетворити до еквівалентного об’єкта JavaScript. Щоб визначити, чи властивість вміщує String чи Object, може бути використаний вузол Debug. Для здійснення цього перетворення Node-RED забезпечує вузол JSON з розділу “парсери”.
Node-RED забезпечує спосіб зберігання інформації, яка може бути розподілена між різними вузлами, без використання повідомлень, що проходять через потоки. Це називається контекстом (context). Контекст можна сприймати як внутрішні змінні, для зберігання проміжних значень, які мають різні області видимості. Існує три рівні контексту:
Вибір області видимості для будь-якого конкретного значення залежить від того, як воно використовується. Наприклад кожен екземпляр вузлу типу Function, може зберігати всередині значення змінних між викликами. Потоки можуть зберігати значення змінних для доступу з усіх вузлів цього потоку. Глобальний контекст зручний у тому випадку, коли треба розподіляти змінні для всіх вузлів проекту.
За замовчуванням контекст зберігається лише в пам'яті. Це означає, що його вміст очищується, коли Node-RED перезавантажується. З випуском версії 0.19 можна налаштувати Node-RED для збереження контекстних даних, щоб він став доступним і після перезавантаження.
Найпростішим способом встановити значення контексту є використання вузла Change. Наприклад, наступне правило вузлу Change зберігатиме значення msg.payload
в контексті потоку (flow) під ключем (назвою) myData
рис.2.4. Використання Change для збереження в контекст.
Різні вузли можуть безпосередньо отримати доступ до контексту. Наприклад, вузол Inject може бути налаштований для введення значення в контекст, а вузол Switch може маршрутизувати повідомлення на основі значення, збереженого в контексті. Використання контексту у вузлі Function буде розглянуто в одній з наступних лекцій.
Контекст можна остаточно видалити, використовуючи вузол Change
та правило delete
.
рис.2.5. Приклад видалення властивості потоку з використанням вузла Change
Для перегляду та видалення контексту вручну можна скористатися бічною панеллю редактора. Детальніше читайте за посиланням. Детально про роботу з контекстом можна прочитати з довідника.
Вузли цієї групи призначені для перетворення повідомлень та керування потоком.
Таблиця 2.2. Функціональні вузли
Вузол | Призначення |
---|---|
Function дозволяє виконувати код JavaScript для обробки повідомлень, що передаються через нього. | |
Switch дозволяє передавати повідомлення до різних гілок потоку, оцінюючи набір правил для кожного повідомлення | |
Change для зміни властивостей повідомлення та контекстів (потоку і глобального) без необхідності вдаватися до вузла Function | |
Range масштабує числові значення відповідно до вказаних вхідних та вихідних діапазонів | |
Template використовується для створення тексту з властивостей повідомлення з використанням означеного шаблону Mustache | |
Delay робить затримку для кожного повідомлення, що проходить через вузол, або обмежує швидкість, з якою вони можуть пройти. | |
Trigger відправляє повідомлення з вказаним інтервалом | |
Exec запускає системну команду. | |
Rbe пропускає повідомлення лише у випадку зміни корисного навантаження |
Вузол Change використовується для зміни властивостей повідомлення та контекстів (потоку і глобального) без необхідності вдаватися до вузла Function. Кожен вузол може бути налаштований з декількома операціями, які застосовуються у вказаному порядку. Доступні операції:
Для кожного правила вказується що саме треба змінити: властивість змінної msg.
, контекст потоку (flow.
) або глобальний контекст (global.
). Для set
вказується яке саме значення необхідно присвоїти властивості. Це може бути константа, відмітка часу, значення властивості змінної msg
, контексту чи змінної середовища, значення також може бути результатом виразу JSONata (буде розглянуто в одній із наступних лекцій).
Вузол Switch дозволяє передавати повідомлення до різних гілок потоку, оцінюючи набір правил для кожного повідомлення і направивши його на конкретний порт. Цей вузол налаштовано за допомогою властивості для перевірки - це може бути або властивість повідомлення (message property), або властивість контексту (context property). Також в якості першого аргументу для порівняння може використовуватися вираз JSONata або змінна середовища. Існує чотири типи правил:
Split
Вузол Delay робить затримку для кожного повідомлення, що проходить через вузол, або обмежує швидкість, з якою вони можуть пройти. Якщо налаштовано на затримку повідомлень (delay messages), інтервал затримки може бути фіксованим значенням, випадковим значенням у межах діапазону або динамічно заданим для кожного повідомлення. Кожне повідомлення затримується незалежно від будь-якого іншого повідомлення, але залежно від часу його надходження.
Вузол Range масштабує числові значення відповідно до вказаних вхідних та вихідних діапазонів. Масштабування відбувається відповідно до налаштованого вхідного діапазону (input range) та цільового діапазону (target range). Вхідне та вихідне значення мусять бути числового формату, інакше вузол намагатиметься перетворити їх в такий.
Вузли Function та Template будуть розглянуті в одній з наступних лекцій. З іншими вузлами ознайомтеся самостійно.
JSONata - це мова запитів і перетворень даних JSON. Іншими словами це мова яка вказує як з вхідного JSON зробити вихідний JSON. JSONata використовується в багатьох вузлах Node-RED. У якості вхідних даних для JSONata є змінна повідомлення msg
, яка розглядається як вхідний документ JSON. Тому до властивостей об’єкта msg
доступаються безпосередньо через імена, наприклад msg.payload
доступний просто як payload
.
JSONata проводить послідовні розрахунки відповідно до вказаного виразу. Після кожного розрахунку результат знаходиться в певній контекстній змінній (називатимемо розрахунковий контекст), який можна використовувати в наступних розрахунках. Звернутися до контексту можна через знак $
. Перед початком розрахунків в контексті знаходиться вхідний документ, тобто msg
, тому звертатись до нього можна через $
. Тобто, якщо потрібно отримати доступ до всього об’єкту msg
на верхньому рівні виразу, можна використовувати змінну $
. Наприклад $._msgid
поверне унікальний ідентифікатор повідомлення. Якщо звертання йде всередині розрахунку, то розрахунковий контекст буде містити проміжні результати, тому при необхідності оцінювання вхідного документу до нього звертаються через подвійний “долар” $$
З символу $
починаються також усі функції JSONata та змінні користувача. Останні використовуються тоді, коли є необхідність писати не просто вирази а підпрограми на мові JSONata.
У розрахунках можна також використовувати літеральні константи у форматі JavaScript, значення глобального контексту та контексту потоку, значення змінної середовища та комбінацію всього перерахованого.
Аналогічно як Java Script через крапку можна доступатися до полів властивостей будь якого рівня вкладеності, а через []
до індексу масиву. Однак в JSONata квадратні дужки використовуються також для позначення умови пошуку (предикату). Якщо результат треба перетворити в інший вигляд, використовуються конструктори масивів ([]
) та об’єктів ({}
). Так наступне повідомлення сформує обєкт з двома полями, в одне запише payload
вхідного повідомлення, а в інше - topic
.
Доступ до контекстів потоку та глобального контексту можна робити через відповідні функції. Доступ до глобального контексту відбувається через вбудовану у Node-RED JSONata функцію $globalContext()
в якій вказується назва змінної та за необхідності сховище (другим аргументом). Аналогічно попередній, функція $flowContext()
доступається до контексту потоку.
Для рядків у JSONata можна використовувати оператор конкатенації &
. Числові літетерали та вирази можуть бути використані в розрахунках результатів з використанням звичайних математичних операторів. Можна використовувати оператори порівняння двох значень, які повертають логічні значення true
або false
(типу >
, <
і т.д).
Детальніше про JSONata в довіднику.
Регулярні вирази це шаблони, що використовуються для пошуку збігу, співпадіння в тексті чи рядках. Ці шаблони використовуються для пошуку збігу у тексті. Тобто текст у регулярному виразі вказує на правила пошуку.
Якщо в регулярному виразі просто вказати текст, наприклад ABC
, то буде пошук співпадіння саме цієї комбінації, причому з урахуванням регістру. Для завдання спеціальних правил, необхідно використовувати спеціальні (службові) символи, типу:
. ^ $ * + ? { } [ ] | ( )
Використання регулярних виразів відрізняться в різних реалізаціях. Тут розглянуті тільки пояснення щодо принципів їх використання, застосовно до вузлів, наприклад Change
. Нижче наведений приклад для пошуку та заміни усіх комбінацій ABC
. Кожна комбінація змінюється на символ заміни.
рис.2.6. Приклад використання регулярного виразу.
Квадратні дужки []
використовуються для вказівки будь якого символу з наведених. Якщо в наведеному вище прикладі регулярний вираз замінити на [ABC]
то в результаті буде --- abc 123 --- abc 123
.
Якщо в послідовності треба шукати спеціальні символи, то їх необхідно екранувати \
, щоб вони не сприймалися як службові. Наприклад, якщо в тексті [ABC][abc]
треба замінити усі квадратні дужки пробілами, то пошуковий текст треба написати так [\[\]]
, де перша і остання квадратна дужка вказує на те, що шукаються будь які з наведених символів, а зворотня коса вказує на те, що символи [
та]
не є службовими.
Зірочка *
показує що символ, після якого він іде може зустрічатися один або нуль разів. Наприклад у тексті baobaboooo
пошуковий запит bo*
з зміною на -
поверне результат -ao-a-
, бо змінюються комбінація bo
з будь якою кількістю o
, навіть з 0-ю.
Плюс +
, на відміну від зірочки шукає результати як мінімум з одним символом. Наприклад у тексті baobaboooo
пошуковий запит bo+
з зміною на -
поверне результат baoba-
, бо змінюються комбінація bo
з будь якою кількістю o
більшою або рівною 1.
Використання регулярних виразів у вузлах дещо обмежене. Так, наприклад, наразі не підтримуються у вузлах типу change
прапорці. Детальніше про регулярні вирази можна прочитати за посиланням
Змінні середовища (environment variables) – це конфігураційні змінні, які задаються у файлі settings.js
безпосередньо, або через “Project Settings” (планується у майбутніх версіях Node-RED) чи налаштування підпотоку. Ці змінні можна використовувати (зчитувати) в середовищі виконання для різноманітних функцій.
Змінні середовища можуть бути доступні через добавлення в розділ functionGlobalContext:
файлу settings.js
наступної властивості (перераховуються через кому):
env: process.env
Після введення ви можете отримати доступ до них у будь-якому вузлі, який має текстове поле (a/z), або у функціональному вузлі. Щоб оголосити власну змінну навколишнього середовища (наприклад ENV_VAR
), потрібно її назву внести у файл settings.js
. Додайте такі рядки безпосередньо перед рядком module.exports = {
:
process.env.ENV_VAR = ‘just another bar’;
Після внесення змін у файл settings.js
зупиніть/перезапустіть node-red, щоб зробити їх доступними для використання.
рис.2.7. Добавлення змінних середовища.
Будь-яку властивість вузла можна встановити змінною середовища, встановивши його значення на рядок форми ${ENV_VAR}
. Коли Node-RED виконує завантаження потоків, він замінить значення цієї змінної середовища перед передачею її у вузол.
До змінних середовища можна також отримати доступ у виразах JSONata, таких як у вузлі Change, використовуючи функцію $env
:
$env('ENV_VAR')
У вузлі Function доступ до змінних середовища можна отримати за допомогою функції env.get
:
let foo = env.get("FOO");
Починаючи з 0,20, підпотоки можна налаштувати з властивостями екземпляра. Вони відображаються як змінні середовища в підпотоці і можуть бути налаштовані для окремих екземплярів підпотоку.
Послідовність повідомлень - це впорядкована серія повідомлень, які певним чином пов’язані між собою. Деякі вузли призначені для обробки таких послідовностей. Наприклад, вузол Split
може перетворювати одне повідомлення, яке є масивом payload
, у послідовність повідомлень, де кожне повідомлення містить payload що відповідає одному з елементів масиву. До групи sequnece
входять вузли, які можуть працювати з послідовностями повідомлень.
Таблиця 2.3. Вузли для роботи з послідовностями повідомлень
Вузол | Призначення |
---|---|
Split розділює одне повідомлення в послідовність повідомлень. | |
Join об’єднує послідовність повідомлень у єдине повідомлення | |
Sort сортує масив або послідовність повідомлень на основі значення властивості або результату виразу JSONata | |
Batch створює нові послідовності згрупованих повідомлень з отриманих. |
Кожне повідомлення в послідовності має властивість msg.parts
. Це об’єкт, який містить інформацію про те, як повідомлення входить у послідовність. Він має такі властивості:
id
- ідентифікатор послідовності (групи повідомлень)index
- позиція в середині послідовності (групи)count
- якщо відома загальна кількість повідомлень в групі. Див streaming mode
нижчеtype
- тип повідомлення - string/array/object/bufferch
- для string або buffer, дані (наприклад рядок), що використовуються для розділення повідомлення як рядка або масиву байтівkey
- для розділення об’єкту, ключ або властивість, з якого було створено це повідомлення. Вузол може бути налаштований також для копіювання цього значення в інші властивості повідомлення, такі як msg.topic
.len
– довжина кожного повідомлення при розділенні з використанням фіксованого значення довжиниВузол Split розділює одне повідомлення в послідовність повідомлень. Конкретна поведінка вузла залежить від типу msg.payload
: String/Buffer
, Array
або Object
. Вихідне повідомлення містить властивості, які вказують скільки повідомлень було створено, індекс повідомлення, тип, який символ використовувався для розділення та параметри розділення для об’єкта. Вузол Split
дозволяє легко створити потік, який виконує загальні дії по всій послідовності повідомлень перед тим, як використати вузол join , рекомбінуючи послідовність знову в одне повідомлення. Він використовує властивість msg.parts
для відстеження окремих частин послідовності.
Вузол Join об’єднує послідовність повідомлень у єдине повідомлення. Вузол забезпечує три режими роботи: автоматичний (по властивостям, що сформував Split), ручний - кофігурується, за правилами JSONata.
Sort сортує масив або послідовність повідомлень на основі значення властивості або результату вираження JSONata. Якщо вузол налаштований для сортування властивості повідомлення (Sort = msg
), вузол сортує дані масиву, на які вказує задана властивість повідомлення. Якщо налаштовано для сортування послідовності повідомлень (Sort = messge seqence
), вузол буде змінювати їх порядок. Під час сортування послідовності повідомлень вузол сортування покладається на отримані повідомлення, щоб встановити msg.parts
. м імен в невідсортованому порядку.
Inject
.Debug
.Change
.Switch
Range
Fucntion
Split
Join
. Які вимоги до повідомлень ставляться в автоматичному режимі роботи?<- до лекцій | на основну сторінку курсу |
---|---|