Як я проект в OpenSCADA зробив

Мова в статті піде про тієї самої OpenSCADA, яка під Linux і з oscada.org.

Навіщо:
• тому що SCADA насправді варта уваги і популяризації;
• у деяких малобюджетних або маленьких проектах просто безальтернативна;
• судячи за статтями про АСУТП на хабре, багатьом читачам АСУТП представляється чорною магією, недо-IT або чимось схожим (ламають нещасний modbus, мучать WinCC, яка і так ледве торохтить… Люди читають і охають: «Як так можна… діряве ПО в промисловості», але нікого не дивує ламання Win95 і 6го ослика. Поламали б LON шифрований, OPC, OPC_UA… А WinCC сама расшаривает папку з проектом з ім'ям виду WinCC_Project_xxxxxx при першому відкритті + це ви ще не бачили як її плагін до Excel може намертво вінду підвісити при неакуратною додавання клітинок трохи більше, ніж він може подужати!) — додамо лікнепу;


Як вам таке?


А таке?


Індуси взагалі не люблять обробляти помилки… Навіщо, і та-а-ак зійде…

Взагалі, єдині, хто працює Сіменс — це МЕНЕДЖЕРИ. Їм при житті треба пам'ятник ставити. З такими менеджерами програмістам можна не напружуватися.

• хабр приносить користь мені (в плані інформації) — принесу хабру і я;
• позбавиться від read-only для участі в коментарях.

Для кого:
• для тих, хто не чув про openSCADA та й взагалі про OpenSource SCADA під Linux, але цікавиться подібним;
• для тих, хто чув, але все не було часу спробувати, щоб зрозуміти, чи потрібно воно;
• для тих, хто відкрив — подивився — не розібрався — закрив;

Чому openSCADA:
• в даному проекті потрібно заощадити;
• ТЗ не змушувало використовувати що-небудь конкретне;
• в даному випадку можна використовувати зв'язок з ПЛК за Modbus (наприклад, якщо б було потрібно передавати аларм з міткою часу ПЛК, то на жаль...).
<habracut/>
Дано:
• парочка генераторів за півтора мегавати;
• місце оператора для управління всім цим;
• ПЛК B&R, зв'язок зі SCADA за ModbusTCP.

Що треба:
• моніторинг стану вузлів і агрегатів;
• управління вузлами і агрегатами;
• фіксування аварійних та запобіжних подій (аларм);
• ведення архіву подій;
• архівування значень параметрів.

Повинен сказати, що її автор цілком грамотно підійшов до задачі (навіть отримав другу вищу як програміст, перше — електронник). Використовує CPP, Qt, svn і т.п. Тобто найсвіжішу версію ви можете завантажити і зібрати, не чекаючи оформлення релізу. Окремо треба сказати про зворотного зв'язку з багам. Помітили багу? Пишіть на форумі в розділі «Відстеження помилок» і, вуаля, вона виправлена. Конкретні приклади: від 40 хвилин до 4 годин, причому був випадок і після 12 ночі. Можете виправити самі і Рома додасть. А тепер скажіть, хто з гігантів виробництва, хоча б промислового, робить хоча б лише на порядок довше? Наприклад MS MS Project… М?

Вам недостатньо документації wiki? Заходьте на вікі під своїм форумным ніком і доповнюєте.

Схоже, що кожна запис про баг сприймається як мало не особиста образа і, якщо твої аргументи железны і баг все ж у його програмі, а не у твоєму ДНК, то виправляє і кожне речення закінчує оклику.



На перший погляд, у openSCADA високий поріг входження та й сам розробник говорить, що ваш попередній досвід роботи зі SCADA навряд чи згодиться, але це тільки на перший погляд. Все незрозуміло, незрозуміло називається, незрозуміло, як це працює. Документація не особливо-то структурована. Приклад — результат пошуку по сайту рясніє фразами «аргумент атрибута параметра»:



Тому є демо проект — AGLKS. З нього і треба почати. Створити на його основі свій, розколупати складові, підглядати як реалізована та чи інша фіча. Я так і зробив: залишив кореневу сторінку і спосіб навігації по сторінкам.

image
Приклад пояснення концепції взаємодії нутрощів openSCADA

Складові openSCADA:
QTCfg — QT конфігуратор (збір даних, обчислення, архіви);



Vision — графічний інтерфейс користувача («картинки»);



QTCfg — БД


Основа цієї SCADA — бази даних, тобто всі проекти зберігаються в БД. Може це і добре, але от для простого «скопіювати проект з папки Х на флешку» або «копіювати клапан з одного проекту в інший» не тривіально. У випадку з БД SQLite вся база є файлик і скопіювати з папки на флешку не складно. А для PostgeSQL? З копіюванням графічного елемента з одного проекту в інший задачка. Хоча ніхто не заважає вести бібліотеку чого-небудь в окремій БД і в свій проект просто підключати потрібний екземпляр. Всі таблиці всіх баз можна подивитися і є поле вводу запиту SQL, так що можете у табличному редакторі склеїти запити і масово щось впровадити в свій проект замість нескінченного тикання мишкою.

QTCfg — Контролер


У зборі даних настройка зв'язку з нашим ПЛК B&R проста: як часто опитувати, modbus протокол (TCP/IP, RTU, ASCII), адреса транспорти, modbus-адресу нашого ПЛК B&R і тп. Варто особливо відзначити налаштування «Максимальний параметр блоку запиту» — це скільки регістрів за раз запитувати у нашого ПЛК. Деякі пристрої просто не відповідають, якщо запросити більше певної кількості. Наприклад, цим «страждає» коректор газу ЕК-270, панель управління PCC3300 у двигунів Cummins.

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

QTCfg — вихідний транспорт MBTCP


Настройка зв'язку з ПЛК — як? Є транспорти і є транспортні протоколи. Куди? У транспортах є Сокети, в Сокетах Вихідний і Вхідний транспорт. ModbusTCP начебто через сокети, але в Транспортних протоколах є Modbus.
Настройка зв'язку з ПЛК знаходиться в Транспорти — Сокети — Вихідний транспорт — ИмяМоегоТранспорта. Для modbusTCP конфігурація виглядає простенько. Підказка допомагає.

Статус бачимо поточний стан, особливо актуально при налагодженні, діагностиці.

QTCfg — Modbus — діагностика


Для збору даних з нашого ПЛК B&R створили контролер в розділі ModBUS. В Runtime на вкладці «Діагностика» спостерігаємо обмін пакетами. Якщо ПЛК не відповідає — тут же бачимо причину.

QTCfg — Інтерфейс протокол


Користувальницький протокол — це взагалі мега-фіча openSCADA, що відкриває їй двері багато куди. В цьому модулі ви можете описати свій протокол, який відсутній в openSCADA. Наприклад, ті самі modbus-подібні з 32-бітними регістрами і т.п. На малюнку наведено приклад протоколу для теплолічильника ВКТ-7 від Теплоком. Так що можете самі створити в ПЛК свій modbus-подібний протокол з 64-бітними регістрами, мітками часу і шифруванням і в openSCADA реалізувати його прийом.

Більш того, ви можете реалізувати свій протокол на С++ як *.so і підключити модуль Збір даних при складанні openSCADA. За приклад можна взяти модуль SNMP.

Свій механізм алармов якраз і хочемо оформити як модуль Зборі даних, а всередині використовувати не масив (який не зручний для сортування), а SQLite з роботою в оперативці замість файлів.

QTCfg — JavaLikeCalc


Всі користувацькі функції реалізуються в розділі Збір даних — JavaLikeCalc — Бібліотека — ваша_библиотека. Виклик своїх функцій вельми корявий: SYS.DAQ.JavaLikeCalc[«lib_MyLib»][«MyFunc»], префікс «lib_» у імені бібліотеки «MyLib» обов'язковий. Варіантів виклику функцій два: статично прописуємо ім'я функції в коді або динамічно складаємо ім'я коді.

Налагодження власних функцій через аналог printf() — просто пишете в Архів, що вам треба. Ніяких «по кроках або breakpoint». Підсвічування синтаксису є. Автообъявление змінних при першому використанні — будьте обережні з очепятками — створить нову змінну і в шлях. У кожній функції є об'єкт this — посилання на саму функції, наприклад, можна в скрипті звертатися до атрибутів функції в циклі і т.п. Так само є прапор f_start — прапор першого виконання функції, туди зручно засунути ініціалізацію або щось подібне одноразове.

QTCfg — Приклад власної функції prioritets на мові JavaLikeCalc


Приклад створення користувальницької функції. Мова — JavaLikeCalc (він же єдиний). Вхідні/вихідні змінні функції описуєте в таблиці IO. Порядок має значення: рядок 1 = 1 мінлива при виклику функції. Міняти місцями рядки IO можна.

Звертатися до тегам можна кількома способами. У openSCADA взагалі одне і те ж можна зробити як мінімум двома способами. Доступ до тегу (атрибуту в термінах openSCADA) в коді можна здійснити так SYS.DAQ[«JavaLikeCalc»][LocalPLC][Local_Param][«myTag»].get(), де " JavaLikeCalc " — статично заданий модуль Збору даних, "LocalPLC" — ім'я контролера в модулі Збору даних, заданий через змінну, " myTag " — статично задане ім'я тега, get() — функція запиту значення тега.

У JavaLikeCalc синтаксис вживання вбудованих функцій такий: strMyTag.StrToInt()? де StrToInt() — функція конвертації тексту в ціле число, strMyTag — наша текстова переменнаяю. Ця особливість синтаксису вживання вбудованих функцій призвела до того, що в Vision доступ до властивостей об'єкта здійснюється не через точку (MyObject.property1), а через нижнє підкреслення (MyObject_property1), що значно знижує читабельність, оскільки "_" в іменах тегів використовується замість пробілу.
Ще приклад синтаксис: this[«pgCont»].attrSet(«geomY»,soOff).attrSet(«geomH»,this[«pgCont»].attr(«geomH»)+soSize)

QTCfg — виконати функцію


Вкладка «Виконати» дозволяє перевірити свою функцію не відходячи від каси. Плюс покаже витрачений на виконання функції часу.

QTCfg — виклик стороннього додатка на JavaLikeCalc (на прикладі моєї функції play_warn)


Для озвучення алармов нам довелося написати функцію з викликом консольного програвача звукових файлів. Створили контролер, якому призначили функцію моніторингу активнх алармов і програвання відповідного звуку.

QTCfg — SETS


Для «локальних» тегів використовуємо контролер в розділі JavaLikeCalc. Контролер назвали «LocVars», в ньому створили а-ля групи тегів actions, calibrs, sets(«параметри» в термінах openSCADA). Ці параметри корисні і використані невипадково. З ними пов'язаний зручний механізм прив'язки графіки до тегам в графічному редакторі Vision. Ми ще до цього повернемося. В полі «Поля» пишемо імена наших «локальних» тегів. Ці теги зберігають свої значення після перезавантаження комп'ютера.

QTCfg — SETS values


Значення наших «локальних» тегів можна подивитися і поставити на вкладці «Атрибути». В даному випадку «sets» — це просто логічна група тегів, а самі теги в термінах openSCADA — це атрибути. Яка SCADA дозволяє подібне в настільки ж простий формі?

QTCfg — actions


Нам для власних потреб в SCADA потрібні локальні теги. Довелося створити контролер і присвоїти йому функцію. Фішка в тому, що значення атрибутів (які є аналоги класичних тегів) зберігаються при перезавантаженні комп'ютера.

QTCfg — параметр G1


Параметром зветься логічна одиниця з набором тегів. У нас розподіл по вузлам і агрегатам. «Включений» — обробляється він у поточний момент, «Включати» — включати при запуску SCADA.

Конфігурація тегів і адрес в разі Modbus просто пісня — це просто текст, який легко склеюється в табличному редакторі, легко правиться в openSCADA. Наприклад, за проектом у вас є теги read-only, ви їх оформили у регістри 30ххх. У openSCADA це виглядає як RI_b15:101:rw:TagName:TagComment. В такому разі на вкладці Атрибути ви не зможете задавати значення тегів, хоча і прописали rw. Легким рухом руки в будь-якому блокноті замінам RI_ на R_ і у вас вже регістри 40ххх. В такому випадку можете задавати значення тегам на вкладці Атрибути, що є набагато зручніше, ніж обчислювати біт в слові і лізти в modbus симулятор і задавати в десятковому вигляді. Якщо регістр 40ххх, але rw, то задавати значення на вкладці Атрибути не зможете. RI_b15:101 — це 15 біт в 30101 регістрі modbus.

QTCfg — параметр G1 — значення


В Runtime дуже просто спостерігати поточні значення тегів. Відкриваємо вкладку «Атрибути» необхідного параметра контролера і спостерігаємо, якщо регістр 40ххх і «rw», то і управляємо — для налагодження незамінне. Спробуйте повторити подібне у WinCC або Citect… Хоча в WinCC можна подивитися значення тега, навівши на нього мишку.

QTCfg — параметр G1 — архівація значень


Конфігурація архівування тега — поставити галку на вкладці «Архівація». Будь тег можна архівувати одночасно в різні архіви.
Що важливо: інформація в архіві СТИСНУТА (а не просто мільйон рядків виду timestamp|tagName|tagValue).

Структура файлу:

image

Механізм послідовної упаковки значень:
image

Там ще купа тонкощів типу «жорсткої сітки» і «часу високого дозволу»…

QTCfg — архів повідомлень


Конфігуруємо архів повідомлень: будемо зберігати в БД, з категорією «LOG» (категорія в даному випадку просто префікс для фільтрації наших повідомлень від системних), розмір архіву в годинах.

QTCfg — архів повідомлень — повідомлення


Подивитися свої повідомлення в своєму архіві — вкладка «Повідомлення» у відповідного нашого архіву.

Архів повідомлень — папка, файл


Архів повідомлень текстові файли (цілком читабельні). Старі файли закатываеются архіватором gzip згідно налаштувань з архівування повідомлень.

QTCfg — архів трендів


Конфігуруємо тренди: зберігаємо на файловій системі (рекомендація Роми), як часто зчитувати значення, як часто в архів записувати, шлях для файлів-архівів, розмір архіву в годинах і т.д.

QTCfg — архів трендів — значення


Подивитися значення архіву значень можна тут же на вкладці «Архіви». Є можливість експорту в файл *.CSV або *.WAV.

QTCfg — архів трендів — графік


Архів трендів на графіку не відходячи від каси — не питання. Розміри зображення графіка можна змінювати.

QTCfg — конфігурація алармов


Оскільки в openSCADA немає алармов в класичному розумінні SCADA систем (замість них Рома придумав порушення — якась абстракція не зрозумій чого, рівень порушень задається програмістом проекту в момент формування порушення і не говорить ні про що), довелося створити свій механізм. Створили окремий контролер на JavaLikeCalc і задали йому моніторити значення потрібних позначок на предмет алармов і формувати список активних алармов.

QTCfg — порушення


Вбудований механізм «проговорювання» порушень (порушення у openSCADA — це якась абстракції в бік алармов). Звідси взяли команду для програвання файлів для власного механізму озвучування алармов.

QTCfg — синтез мови


Треба зазначити: вбудований механізм «алармов» openSCADA дозволяє промовляти текст повідомлення движком tts. Встановіть tts з російською мовою — вбудовані «аларм» (тобто порушення) заговорять російською.




Vision-розробка


Переходимо до графіку. Для цього використовується «друга половина» openSCADA — Vision.

QTCfg — Vision


Параметри Vision з QTCfg: задаємо з яким користувачем відкриється Vision в розробці і в Runtime графічний інтерфейс користувача, який проект запускати в Runtime.

Vision-розробка — віджети


Віджет — це графічна одиниця (клапан, засувка, генератор, поле введення і навіть ціла сторінка).

Вкладка Віджети — тут знаходяться всі віджети, зібрані в бібліотеки. Це якась загальна база зберігання графічних одиниць.
Є можливість в один віджет-сторінку динамічно в Runtime вставляти інші віджети. Аналог WinCC-шних PictureWindow. Для цього на сторінку треба помістити віджет і задати йому властивість «контейнер» та властивості група дати якесь ім'я. Вставити віджет повинен мати ту ж групу.

Таким чином, формується інтерфейс оператора, де є постійна область меню і алармов і динамічно мінливі мнемосхеми.

Vision-розробка — проекти


А ось на вкладці Проект ми вже збираємо скелет графічної частини нашого проекту з примірників бібліотечних віджетів (набираємо сторінки і визначаємо навігацію по них). В Проект ми можемо ставити персональні властивості бібліотечним віджетів — наприклад, віджет «вікно з даними від цифрового мультиметра» — створюємо 5 вікон для п'яти високовольтних комірок і прив'язуємо до тегам відповідних комірок.

Vision-розробка — групове зміна властивостей


Дуже зручна опція: групове зміна властивостей декількох об'єктів — виділили об'єкти і відразу всім поставили.

Vision-розробка — text — аргументи


У стандартного графічного елемента «Text» є дуже корисна особливість — аргументи.

Таким чином, один елемент Text дозволяє реалізувати закінчений форматований елемент мнемосхеми виду «P = 32, кВт», де «P» — позначення параметра, «32» — його значення (значення тега), «кВт» — одиниці вимірювання. Тобто динамічно прив'язує тільки значення тега, інше вже є. Формат простий: «P = %1, кВт» (замість %1 буде значення тега).

Vision-розробка — малювання фігур


Ось з малювання не дуже. Малювання геометричних фігур можливо тільки в якомусь контейнері типу Box. Як видно на малюнку в поле Список елементів лінії представлені в текстовому вигляді line(15.359|0.505):(15.359|22.915):::::::::::. Спробуйте вгадати хто де… Але не так все сумно. Як видно на малюнку під меню файл є кнопки для малювання прямих, кривих Безьє, кіл. А що сумно? Наприклад, окружність задається по п'яти точках, а не звичним прямокутником/квадратом.



Змінюючи координати будь-якої з п'яти точок інше отримати чорти-що замість того, що треба. Заливка кольором можлива тільки для замкнутого контуру, тобто звичайний стовпчик з заливкою від 0% до 100% реалізується контуром «прямокутник» плюс «палиця-поперечка», яка ділить наш прямокутник на дві половини. Заливку ставимо для однієї половини нашого прямокутника. Паралельно зрушуємо «палицю-поперечку», змінюючи співвідношення площ половинок — змінюється і площа заливки. Тобто зробити заливку кола — важке завдання. Коротше малювати треба пристосуєтеся, а іноді і изголиться. А ось у Citect з такого роду заливками проблем немає.


Приклад заливки у Citect

Намалювати подібне в openSCADA ціла завдання.

Бібліотечний віджет — sets — обробка


Ось ми і підійшли до найцікавішого — зв'язування графіки на сторінці (та й взагалі на будь-якому віджеті) з тегами атрибутами в термінах openSCADA). Для відкриття вищевказаного вікна треба дати фокус нашому віджету і натиснути кнопку з гайковим ключем . У вікні на вкладці Обробка на мові JavaLikeCalc пишемо, власне, всю обробку, створюємо додаткові змінні у віджетів, конфигурим змінні віджетів. Щоб мати можливо працювати з атрибутом (в даному випадку атрибут = змінна), треба у відповідного атрибута поставити галку в стовпці «Обробка».

Другий спосіб звернутися до атрибуту: vcaAttrGet(strParsePath(path,0)+"/pg_control/pg_ElCadr/a_pgOpen").
Третій спосіб: через об'єкт this — this.nodeList(«pg_» ) означає отримати список віджетів у головного віджету.
У другому і третьому випадку ставити галку «Обробка» не треба.

Зверніть увагу на колонку «Конфігураційний шаблон» — це як раз та сама родзинка зв'язування з тегами, про яку я говорив раніше. Там ви задаєте шаблон у вигляді «параметр|атрибут», де параметр і атрибут — суті з модуля Збір даних. І тоді на вкладці Зв'язку нам достатньо прив'язати параметр (наприклад, G1), а атрибути зв'яжуться автоматично за заданим шаблоном. Якщо параметр містить 100 атрибутів, заощадите масу часу. Уміле проектування з таким маневруванням дозволяє робити досить гнучкі системи.
Зв'язати можна не тільки з тегом Збору даних, але і з будь-яким атрибутом віджета, чим я і користуюся.

Бібліотечний віджет — general — зв'язку


Як я вже говорив, зв'язатися з тегом можна прямо з коду в обробці (SYS.DAQ.xxx і так далі аж до тега), а можна на вкладці Зв'язку. Щоб атрибут з'явився на вкладці Зв'язку йому треба задати тип зв'язку в колонці Конфігурація на вкладці Обробка:

Постійна — у вкладці зв'язків віджета з'являється поле вказівки постійної, наприклад, особливого кольору або заголовка для шаблонних кадрів;
Вхідна зв'язок — зв'язок з динамікою тільки для читання;
Вихідна зв'язок — зв'язок з динамікою тільки для запису;
Повна зв'язок — повна зв'язок з динамікою (читання і запис).

Плюсик у кінці рядка-прив'язки говорить коректності шляху.

Бібліотечний віджет — sets — зв'язку з атрибутом віджета


Приклад зв'язку змінних віджетів (наприклад, PU_set_G1) із змінною основного віджета. На вкладці Обробка прописувати шаблон, а тут тільки wdg:… копипастишь.

Бібліотечний віджет — об'єкт this


Приклад роботи з змінними віджета через об'єкт цього віджета this.

Бібліотечний віджет — vcaAttrGet


Той самий третій спосіб звернення до змінних віджета через vcaAttrGet.

Бібліотечний віджет — обробка подій клавіатури/миші


Відкриття сторінок в Runtime конфігурується в спеціальному властивості будь-якого віджета Обробка подій. А от обробка всіх інших клавішних (клавіатура, миша) подій проводиться в Обробці.

Vision — таблиця — редагування


Графічний елемент «таблиця» створюється а-ля HTML. На момент розробки описуваного проекту отримати координати «виділений стовпець: виділена рядок» було неможливо, вставити в комірку об'єкт типу поле вводу/прапорець/кнопка неможливо. Може зараз можливостей додалося.

Тренди


Один полотно може містити до 99 пір'я включно (передаємо привіт Wonderware з її 8 без доплати).
А ось інтерфейс взаємодії з пір'ям доводиться робити самому. Можна взяти приклад з демо-проекту, але там багато ручної роботи при конфігуруванні. Для першого разу піде, але далі хочеться більше автоматизованого (скрипта) інтерфейсу. Зовні підходить як Citect, але там таблиця з прапорцями для управління видимістю пір'я, а у openSCADA поки немає відповідного інструментарію. Треба або іншу реалізацію легенди придумати. Або на З++/Qt свою написати і в openSCADA додати.

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


«Інформаційна панель в нижньому правому куті екрану»

Для зміни користувача необхідно зробити подвійний клік мишею по імені поточного користувача в інформаційній панелі в правому нижньому кутку і у вікні вибрати потрібного користувача і пароль.


Зміна користувача — вибір необхідного


Зміна користувача — пароля

Якщо необхідно надрукувати тільки частину сторінки, необхідно натиснути стрілку поруч із кнопкою друку і вибрати необхідне.



Список доступних для друку сторінок:



Те ж саме і для експорту.



Ім'я файлу в полі повинно містити відповідне розширення (*.png, *.xpm,*.jpg).
У разі вибору неіснуючого на сторінці елемента з'являється попереджувальне повідомлення.

Сторінки експортуються у файли зображень. Документи експортуються файли web-сторінок (*.html, які можна відкривати будь-яким веб-браузером і друкувати з нього) або текстовий файл (*.csv, який можна відкрити в MS Excel або іншому табличному редакторі для подальшої обробки). Документи в openSCADA — це вбудований базовий тип віджетів з яких можна створювати свої будь-які звітні форми. Конфігурація а основі HTML і CSS.



Висновок: openSCADA — дуже навіть ентерпрайз.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.