Учитывая спектр задач для которых может использоваться система OpenSCADA, нужно предусмотреть механизм управления интерактивными пользовательскими событиями. Это связано с тем, что при решении отдельных задач встраиваемых систем устройства ввода и управления могут значительно отличатся. Впрочем достаточно взглянуть на обычную офисную клавиатуру и клавиатуру ноутбука чтобы снять любые сомнения о необходимости менеджера событий.
Менеджер событий должен работать, используя карты событий. Карта событий — это список именованных событий с указанием его происхождения. Происхождением события может быть клавиатура, манипулятор мыши, джойстик и т.д. При возникновении события менеджер событий ищет его в активной карте и сопоставляет с именем события. Сопоставленное имя события помещается в очередь на обработку. Виджеты, в этом случае, должны обрабатывать полученную очередь событий.
Активная карта событий указывается в профиле каждого пользователя или устанавливается по умолчанию (
в планах).
В целом предусмотрены четыре типа событий:
- события образов-примитивов СВУ (префикс: ws_), например, событие нажатия экранной кнопки — "ws_BtPress";
- клавишные события (префикс: key_) — все события от клавиатуры и мыши в виде "key_presAlt1";
- пользовательские события (префикс: usr_) генерируются пользователем в процедурах обсчёта виджетов;
- мапированные события (префикс: map_) — события, полученные из карты событий, в планах.
Само событие представляет недостаточно информации, особенно если его обработка происходит на уровнях выше. Для однозначной идентификации события и его источника, событие в целом записывается следующим образом: "ws_BtPress:/curtime". Где:
ws_BtPress — событие;
/curtime — путь к дочернему элементу, сгенерировавшего событие.
В таблице 3.5 приведён перечень стандартных событий, поддержка которых должна быть обеспечена в визуализаторах СВУ.
Таблица 3.5. Стандартные события
Id | Описание |
Клавиатурные события: key_[pres|rels][Ctrl|Alt|Shift]{Key} |
*SC#3b | Скан-код клавиши. |
*#2cd5 | Код неименованной клавиши. |
*Esc | "Esc". |
*BackSpace | Удаления предыдущего символа — "<-". |
*Return, *Enter | Ввод — "Enter". |
*Insert | Вставка — "Insert". |
*Delete | Удаление — "Delete". |
*Pause | Пауза — "Pause". |
*Print | Печать экрана — "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_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: