События, их обработка и карты событий
Учитывая спектр задач, для которых может использоваться OpenSCADA, нужно предусмотреть механизм управления интерактивными пользовательскими событиями. Это связано с тем, что при решении отдельных задач встраиваемых систем, устройства ввода и управления могут значительно отличатся. Впрочем, достаточно взглянуть на обычную офисную клавиатуру и клавиатуру ноутбука, чтобы снять любые сомнения о необходимости менеджера событий.
Менеджер событий должен работать используя карты событий. Карта событий — это список именованных событий с указанием его происхождения. Происхождением события может быть клавиатура, манипулятор мыши, джойстик и т.д. При возникновении события менеджер событий ищет его в активной карте и сопоставляет с именем события. Сопоставленное имя события помещается в очередь на обработку. Виджеты, в этом случае, должны обрабатывать полученную очередь событий.
Активная карта событий указывается в профиле каждого пользователя или устанавливается по умолчанию, в планах.
В целом, предусмотрены четыре типа событий:
- события образов-примитивов СВУ (префикс: ws_), например, событие нажатия экранной кнопки — "ws_BtPress";
- клавишные события (префикс: key_) — все события от клавиатуры и мыши в виде "key_presAlt1";
- пользовательские события (префикс: usr_), генерируются пользователем в процедурах обсчёта виджетов;
- мапированные события (префикс: map_) — события, полученные из карты событий, в планах.
Само событие представляет недостаточно информации, особенно если его обработка происходит на уровнях выше. Для однозначной идентификации события и его источника, событие, в целом, записывается следующим образом: "ws_BtPress:/curtime". Где:
- ws_BtPress — событие;
- /curtime — путь к дочернему элементу, сгенерировавшее событие.
В таблице 3.5 приведён перечень стандартных событий, поддержка которых должна быть обеспечена в визуализаторах СВУ.
Table 3.5. Standard events
Identifier | Description |
---|---|
Keyboard events: key_[pres|rels][Ctrl|Alt|Shift]{Key} | |
*SC#3b | Scan-code of the key. |
*#2cd5 | Code of the unnamed key. |
*Esc | "Esc". |
*BackSpace | Removing of the previous character — "<--". |
*Return, *Enter | Enter — "Enter". |
*Insert | Insertion — "Insert". |
*Delete | Deleting — "Delete". |
*Pause | Pause — "Pause". |
Print of the screen — "Print Screen". | |
*Home | Home — "Home". |
*End | End — "End". |
*Left | To the left — "<-". |
*Up | To the up — '^'. |
*Right | To the right — "->". |
*Down | To the down — '\/'. |
*PageUp | Page up — "PageUp". |
*PageDown | Page down — "PageDown". |
*F1 ... *F35 | Function key from "F1" to "F35". |
*Space | Space — ' '. |
*Apostrophe | Apostrophe — '`'. |
*Asterisk | Asterisk on the additional field of the keyboard — '*'. |
*Plus | Plus on the additional field of the keyboard — '+'. |
*Comma | Comma — ','. |
*Minus | Minus — '-'. |
*Period | Period — '.'. |
*Slash | Slash — '\'. |
*0 ... *9 | Number from '0' to '9'. |
*Semicolon | Semicolon — ';'. |
*Equal | Equal — '='. |
*A ... *Z | Keys of Latin alphabet from 'A' to 'Z'. |
*BracketLeft | Left square bracket - '['. |
*BackSlash | Backslash — '/'. |
*BracketRight | Right square bracket — ']'. |
*QuoteLeft | Left quote — . |
Keyboard focus events. | |
ws_FocusIn | Focus is obtained by the widget. |
ws_FocusOut | Focus is lost by the widget. |
Mouse events: | |
key_mouse[Pres|Rels][Left|Right|Midle] | Pressed/released the mouse button. |
key_mouseDblClick | Double-click the left mouse button. |
Events of quietance on the side of the visualizer. | |
ws_alarmChange | Notifies about the alarm status change, the attribute "alarmSt". |
ws_alarmLev | Quietance of all violations by all notices methods and types. |
ws_alarmNtf{N} | Quietance of all violations by the type {N} (0...7). |
Events of the elementary figure primitive ElFigure: | |
ws_Fig[Left|Right|Midle|DblClick] | Activating of the figures (fills) by the mouse button. |
ws_Fig{N}[Left|Right|Midle|DblClick] | Activating of the figure (fill) N by the mouse button. |
Events of the form element primitive FormEl: | |
ws_LnAccept | A new value in the input line is set. |
ws_TxtAccept | The value of the text editor is changed. |
ws_ChkChange | The state of the flag is changed. |
ws_BtPress | The button is pressed. |
ws_BtRelease | The button is released. |
ws_BtToggleChange | The button toggle is changed. |
ws_BtMenu={Item} | Selection of the menu Item on the button. |
ws_BtLoad | The selected file loaded. |
ws_CombChange | The value of the combo box is changed. |
ws_ListChange | The current list item is changed. |
ws_TreeChange | The current tree item is changed. |
ws_TableChangeSel | The table item selection is changed. |
ws_TableEdit_{colN}_{rowN} | The table cell ({colN}:{rowN}) is edited. |
ws_SliderChange | The slider position is changed. |
Events of the media content primitive Media: | |
ws_MapAct{N}[Left|Right|Midle] | Media area with the number N is activated by the mouse button. |
ws_MediaFinished | Media-stream play is finished. |
События являются основным механизмом уведомления и активно используются для осуществления взаимодействия с пользователем. Для обработки событий предусмотрены два механизма:
- Первичный — сценарий управления открытием страниц.
- Вторичный — вычислительная процедура виджета.
Механизм "Сценарий управления открытием страниц" основан на базовом атрибуте виджета "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
The mechanism "Processing the events with the help of computational procedure of the widget" is based on the attribute "event" and the user procedure of calculating written with the help of the programming language of OpenSCADA. The events in process of receipt are accumulated in the attribute "event" till the moment of call of the computational procedure. The computational procedure is called with the specified frequency of calculating the widget and receives the attribute "event" value as the list of events. In the calculation procedure the user can: analyse, process and delete the processed events from the list, and add to the list new events. The remaining, after the procedure execution, and new events are analysed for compliance with the conditions of the call by means of script of the primary mechanism after which the remaining events are transmitted to the upper by the hierarchy widget to be processed by it, with the appending of the events path in accordance with the hierarchy of the penetration. When the widget is the top already, that is a page, then the remaining events are sent to a page who opened the source page and to the upper page, with the source page whole address.
Содержимым атрибута "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;