Події, їх обробка та карти подій
Враховуючи спектр задач, для яких може використовуватися OpenSCADA, треба передбачити механізм управління інтерактивними користувацькими подіями. Це пов'язано з тим, що при вирішені окремих задач вбудованих систем, пристрої вводу та управління можуть значно відрізнятися. Власне, достатньо поглянути на звичайну офісну клавіатуру та клавіатуру ноутбука, щоб зняти будь-які сумніви у необхідності менеджеру подій.
Менеджер подій має працювати використовуючи карти подій. Карта подій — це перелік іменованих подій з указанням його походження. Походженням події може бути клавіатура, маніпулятор миші, джойстик та інше. При виникненні події, менеджер подій шукає його у активній карті та співставляє з ім'ям події. Співставлене ім'я події поміщається у чергу на обробку. Віджети, у цьому випадку, повинні обробляти отриману чергу подій.
Активна карта повідомлень вказується у профілі кожного користувача або встановлюється по замовченню, у планах.
Загалом, передбачено чотири типи подій:
- події образів-примітивів СВУ (префікс: ws_), наприклад, подія натискання екранної кнопки — "ws_BtPress";
- клавішні події (префікс: key_) — всі події від клавіатури та миші у вигляді "key_presAlt1";
- користувацькі події (префікс: usr_), генеруються користувачем у процедурах обрахунку віджетів;
- маповані події (префікс: map_) — події, отримані з карти події, у планах.
Сама подія надає недостатньо інформації, особливо якщо її обробка відбувається на рівнях вище. Для однозначної ідентифікації події та її джерела, події, загалом, записуються наступним чином: "ws_BtPress:/curtime". Де:
- ws_BtPress — подія;
- /curtime — шлях до дочірнього елементу, який згенерував подію.
У таблиці 3.5 наведено перелік стандартних подій, підтримку яких має бути забезпечено у візуалізаторах СВУ.
Таблиця 3.5. Стандартні події
Ідентифікатор | Опис |
---|---|
Клавіатурні події: key_[pres|rels][Ctrl|Alt|Shift]{Key} | |
*SC#3b | Скан-код клавіші. |
*#2cd5 | Код неіменованої клавіші. |
*Esc | "Esc". |
*BackSpace | Видалення попереднього символу — "<-". |
*Return, *Enter | Ввід — "Enter". |
*Insert | Вставка — "Insert". |
*Delete | Видалення — "Delete". |
*Pause | Пауза — "Pause". |
Друк екрану — "Print Screen". | |
*Home | Дім — "Home". |
*End | Кінець — "End". |
*Left | Ліворуч — "<-". |
*Up | Вверх — '^'. |
*Right | Праворуч — "->". |
*Down | Додолу — '\/'. |
*PageUp | Сторінки нагору — "PageUp". |
*PageDown | Сторінки додолу — "PageDown". |
*F1 ... *F35 | Функціональна клавіша від "F1" до "F35". |
*Space | Пробіл — ' '. |
*Apostrophe | Апостроф — '`'. |
*Asterisk | Зірочка на додатковому полі клавіатури — '*'. |
*Plus | Плюс на додатковому полі клавіатури — '+'. |
*Comma | Кома — ','. |
*Minus | Мінус — '-'. |
*Period | Крапка — '.'. |
*Slash | Похила риска — '\'. |
*0 ... *9 | Цифра від '0' до '9'. |
*Semicolon | Крапка з комою — ';'. |
*Equal | Дорівнює — '='. |
*A ... *Z | Клавіші літер латинського алфавіту від 'A' до 'Z'. |
*BracketLeft | Ліва квадратна дужка — '['. |
*BackSlash | Зворотня похила риска — '/'. |
*BracketRight | Права квадратна дужка — ']'. |
*QuoteLeft | Ліва лапка — . |
Події клавіатурного фокусу. | |
ws_FocusIn | Фокус отримано віджетом. |
ws_FocusOut | Фокус втрачено віджетом. |
Події маніпулятору миші: | |
key_mouse[Pres|Rels][Left|Right|Midle] | Натиснута/відпущена кнопка миші. |
key_mouseDblClick | Подвійний натиск лівої кнопки миші. |
Події квітація на боці візуалізатору. | |
ws_alarmChange | Сповіщає щодо зміни статусу порушення, атрибут "alarmSt". |
ws_alarmLev | Квітація всіх порушень всіма способами та типами сповіщення. |
ws_alarmNtf{N} | Квітація всіх порушень сповіщення типу {N} (0...7). |
Події примітиву елементарної фігури ElFigure: | |
ws_Fig[Left|Right|Midle|DblClick] | Активація фігур (заливок) клавішею миші. |
ws_Fig{N}[Left|Right|Midle|DblClick] | Активація фігури (заливки) N клавішею миші. |
Події примітиву елементу форми FormEl: | |
ws_LnAccept | Встановлено нове значення у рядку вводу. |
ws_TxtAccept | Змінено значення редактору тексту. |
ws_ChkChange | Стан ознаки змінено. |
ws_BtPress | Кнопку натиснуто. |
ws_BtRelease | Кнопку відпущено. |
ws_BtToggleChange | Змінено втисненість кнопки. |
ws_BtMenu={Item} | Вибір елементу меню Item за кнопкою. |
ws_BtLoad | Обраний файл завантажено. |
ws_CombChange | Змінено значення поля обрання. |
ws_ListChange | Змінено поточний елемент переліку. |
ws_TreeChange | Змінено поточний елемент дерева. |
ws_TableChangeSel | Змінено вибір елементу таблиці. |
ws_TableEdit_{colN}_{rowN} | Відредаговано клітинку таблиці ({colN}:{rowN}). |
ws_SliderChange | Зміна положення слайдеру. |
Події примітиву медіа-контенту Media: | |
ws_MapAct{N}[Left|Right|Midle] | Активовано медіа-область з номером N, клавішею миші. |
ws_MediaFinished | Закінчено програвання Медіа-потоку. |
Події є основним механізмом сповіщення та активно використовуються для здійснення взаємодії з користувачем. Для обробки події передбачено два механізми:
- Первинний — сценарій управління відкриттям сторінок.
- Вторинний — обчислювальна процедура віджета.
Механізм "Сценарій управління відкриттям сторінок" засновано на базовому атрибуті віджету "evProc", у якому може описуватися відкриття сторінок. Сценарій цього атрибуту записується у вигляді переліку команд з синтаксисом: "{event}:{evSrc}:{com}:{prm}". Де:
- event — очікувана подія;
- evSrc — шлях вкладеного віджета-джерела події;
- com — команда сеансу;
- prm — параметр команди.
Реалізовано наступні команди:
- open — відкриття сторінки; сторінка, що відкривається, вказується у параметрі prm як прямо, так і у вигляді шаблону, наприклад — /pg_so/1/*/*;
- next — відкриття наступної сторінки; сторінка, що відкривається, вказується у параметрі prm, у вигляді шаблону, наприклад: /pg_so/*/*/$;
- prev — відкриття попередньої сторінки; сторінка, що відкривається, вказується у параметрі prm, у вигляді шаблону, наприклад: /pg_so/*/*/$.
Спеціальні символи шаблону розшифровуються наступним чином:
- pg_so — пряме ім'я потрібної-статичної сторінки (з префіксом), потребує обов'язкової відповідності та використовується для ідентифікації попередньої відкритої сторінки;
- 1 — ім'я та місце нової сторінки у загальному шляху (без префіксу);
- * — сторінка береться з ім'я попередньої відкритої сторінки або підставляється перша доступна сторінка, якщо попередня відкрита відсутня;
- $ — вказує на місце відкритої сторінки, відносно якої треба шукати наступну або попередню.
Для правильного розуміння роботи механізму шаблонів, при виборі сторінки, приведемо декілька реальних прикладів:
- Перемикання об'єкту сигналізації:
- Початково: /pg_so/pg_1/pg_mn/pg_1
- Команда: open:/pg_so/2/*/*
- Результат: /pg_so/pg_2/pg_mn/pg_1
- Перемикання виду відображення:
- Початково: /pg_so/pg_1/pg_mn/pg_1
- Команда: open:/pg_so/*/gkadr/*
- Результат: /pg_so/pg_1/pg_gkadr/pg_1
- Наступна/попередня сторінка виду відображення:
- Початково: /pg_so/pg_1/pg_mn/pg_1
- Команда: next:/pg_so/*/*/$
- Результат: /pg_so/pg_1/pg_mn/pg_2
У якості прикладу, наведемо сценарій забезпечення роботи головної сторінки інтерфейсу користувача:
ws_BtPress:/prev:prev:/pg_so/*/*/$ ws_BtPress:/next:next:/pg_so/*/*/$ ws_BtPress:/go_mn:open:/pg_so/*/mn/* ws_BtPress:/go_graph:open:/pg_so/*/ggraph/* ws_BtPress:/go_cadr:open:/pg_so/*/gcadr/* ws_BtPress:/go_view:open:/pg_so/*/gview/* ws_BtPress:/go_doc:open:/pg_so/*/doc/* ws_BtPress:/go_resg:open:/pg_so/rg/rg/* ws_BtPress:/so1:open:/pg_so/1/*/* ws_BtPress:/so2:open:/pg_so/2/*/* ws_BtPress:/so3:open:/pg_so/3/*/* ws_BtPress:/so4:open:/pg_so/4/*/* ws_BtPress:/so5:open:/pg_so/5/*/* ws_BtPress:/so6:open:/pg_so/6/*/* ws_BtPress:/so7:open:/pg_so/7/*/* ws_BtPress:/so8:open:/pg_so/8/*/* ws_BtPress:/so9:open:/pg_so/9/*/* ws_BtPress:*:open:/pg_control/pg_terminator
Механізм "Обробка подій за допомогою обчислювальної процедури віджета" заснований на атрибуті "event" та користувацькій процедурі обчислення, на мові програмування OpenSCADA. Події, по мірі надходження, акумулюються у атрибуті "event" до моменту виклику обчислювальної процедури. Обчислювальна процедура викликається з вказаним періодом обчислення віджета та отримує значення атрибуту "event" у вигляді переліку подій. У процедурі обчислення, користувач може: проаналізувати, обробити та виключити оброблені події з переліку, а також додати до переліку нові події. Решта подій, після виконання процедури, та нові аналізуються на предмет відповідності умовам виклику сценарієм первинного механізму, після чого, події, що залишилися, передаються на верхній за ієрархією віджет, для обробки ним, при цьому здійснюється доповнення шляху події згідно до ієрархії проникнення.
Вмістом атрибуту "event" є перелік подій формату "{event}:{evSrc}", з подією у окремому рядку. Наведемо приклад процедури обробки події на Java-подібній мові користувацького програмування OpenSCADA:
for(ev_rez = "", off = 0; (sval=event.parse(0,"\n",off)).length; ) {
if(sval == "ws_BtPress:/cvt_light") alarmSt = 0x1000001;
else if(sval == "ws_BtPress:/cvt_alarm") alarmSt = 0x1000002;
else if(sval == "ws_BtPress:/cvt_sound") alarmSt = 0x1000004;
else ev_rez += sval+"\n";
}
event = ev_rez;