OpenSCADAWiki: Doc/API/part14
 

14. Интерфейс управления системой и динамическое дерево объектов системы (TCntrNode)

Для полного покрытия ключевых компонентов системы сетью объектов единой структуры предназначен объект узла динамического дерева TCntrNode. На этот объект возлагаются следующие функции:

Любой объект, имеющий потребность в предоставлении динамического доступа к себе или своим компонентам должен наследоваться от объекта узла динамического дерева TCntrNode. Данное родство автоматически включает узел в динамическое дерево объектов, охваченное как прямой, так и обратной связью, а также предоставляет возможность создания контейнеров под собственные дочерние узлы. В дополнении к этому узел получает возможность упреждения про включение и исключение/удаление узла из дерева с возможностью отказа от исключения/удаления.

Интерфейс управления системы включён в состав объекта TCntrNode и, соответственно, охватывает все узлы динамического дерева системы, позволяя единообразно управлять системой вне зависимости от используемого клиентского инструмента. Интерфейс управления системой выполнен на основе языка разметки XML. Можно придумать множество способов использования интерфейса управления системой, в качестве примера отметим следующие наиболее яркие решения:

Интерфейс управления системой реализован посредством составляющих:

Информационная иерархическая структура содержит информацию о публичных элементах управления и может быть использована для построения пользовательских диалогов управления узлами системы.

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

Контейнер позволяет собрать в один запрос несколько информационных структур и динамических частей, оптимизируя тем самым время запроса особенно на сетевых высоколатентных интерфейсах.

Общий интерфейс управления строится из отдельных узлов динамического дерева. Иерархическое наследование от объекта TCntrNode позволяет реализовывать многоуровневое дополнение конфигурации интерфейса управления. Общий вид динамического дерева узлов представлен на рис. 8.

Пример динамического дерева узлов системы OpenSCADA. (120 Kb)
Рис. 8. Пример динамического дерева узлов системы OpenSCADA.


Узлы системы, содержащие данные для интерфейса управления системой также должны подключаться в динамическое дерево объектов.

Подключение узла в динамическое дерево производится следующим образом:

14.1. Синтаксис запроса и ответа интерфейса управления

Весь обмен с интерфейсом управления производится посредством языка XML. При этом внутренний обмен выполняется разобранной структурой языка XML (DOM), а внешний — посредством преобразования в поток символов сплошного XML-файла и обратно.

Запрос выполняется посредством отправки одного контейнера с некоторыми параметрами в атрибутах. Результат помещается в полученный контейнер с изменением некоторых атрибутов корневого контейнера. В общем виде контейнер запроса можно записать следующим образом:
<cmd path="/TreePath" user="user" force="1"/>
Где:
cmd — команда запроса;
path — путь к узлу или ветви узла;
user — пользователь системы от имени которого направлен запрос;
force — признак выполнить запрос без предупреждения.

В подтверждение результата запроса устанавливается атрибут результата rez в значения: 0-запрос прошел, 1-предупреждение (с возможностью выполнения), 2-ошибка. В случае ошибки и предупреждения сообщения записываются в текст контейнера и атрибут mcat (категория сообщения): <cmd path="/TreePath" user="user" force="1" rez="2" mcat="sub_DAQ/mod_BlockCalc>Невозможно удалить узел</cmd>.

Группирующий запрос "CntrReqs" обрабатываются на уровне API узла и не требуют отдельной обработки в пользовательском коде. Фактически в тег "CntrReqs" могут помещаться любые другие запросы с возможностью иерархической группировки путём включения внутренних тегов "CntrReqs". Единственным атрибутом этого тега является атрибут path, который указывает путь к узлу и является основой для внутренних запросов.

<CntrReqs path="/sub_DAQ/cntr_gate">
  <get path="/%2fprm%2fcfg%2fNAME"/>
  <get path="/%2fprm%2fcfg%2fDESCR"/>
  <list path="/%2fserv%2fattr"/>
</CntrReqs>

14.2. Тег информационной структуры для описания групп дочерних веток страницы

Каждая страница может содержать группы дочерних ветвей. Для описания групп ветвей предусмотрен тег branches. Тег содержит описание групп ветвей посредством вложенных тегов grp. К тегу группы возможен доступ как на "чтение" (видимость) так и на модификацию (выполнение команд добавления и удаления элементов группы), следовательно элемент триады доступа может принимать значения:
00 — доступ вообще отсутствует;
04 — присутствует доступ только на чтение;
02 — присутствует доступ только на запись, обычно такое значение не имеет смысла поскольку доступ на запись подразумевает и доступ на чтение;
06 — присутствует доступ и на чтение, и на запись.


Действия над группой элементов полностью совпадают с действиями над списком визуальных элементов "list", о котором написано ниже.

14.3. Теги описания информационной структуры интерфейса управления

Информационные теги для языка XML составляют алфавит формирования описания конфигурационных диалогов. Команда запроса информационной части имеет вид: <info path="/TreePath" user="user"/>

В результате запроса будет получена информационная структура страницы в соответствии с привилегиями указанного пользователя.

14.3.1. Тег области "area"

Области описываются тегом area и предназначены для группировки элементов по различным признакам. Область может включать другие элементы и области. Корневые области формируют закладки в представлении пользовательского интерфейса. К тегу возможен доступ только на "чтение" или "видимость", следовательно элемент триады доступа может принимать значение 00, если доступ отсутствует, или 04, если присутствует.
<area id='base' dscr='Base information'>
  <fld id='host' dscr='Host name' tp='str'/>
  <fld id='user' dscr='Operated user' tp='str'/>
  <fld id='sys' dscr='Station system' tp='str'/>
  <area id='other' dscr='Other options'>
     <fld id='val' dscr='Value' tp='real'/>
  </area>
</area>

14.3.2. Теги данных

Теги, описывающие данные, сведены в таблице 1.

Таблица 1. Теги, описывающие данные
ТегОписание
<fld>Простейшие данные строкового, целого, вещественного и логического типов.
<list>Списки с данными строкового, целого, вещественного и логического типов.
<table>Таблицы с данными в ячейках строкового, целого, вещественного и логического типов.
<img>Изображения.

a) Тег "fld"
<fld id='host' dscr='Host name' tp='str'/>
<fld id='user' dscr='Operated user' tp='str'/>
<fld id='sys' dscr='Station system' tp='str'/>


К тегу возможен доступ как на "чтение", так и на "запись", следовательно элемент триады доступа может принимать значения:
00 — доступ вообще отсутствует;
04 — присутствует доступ только на чтение;
02 — присутствует доступ только на запись, обычно такое значение не имеет смысла поскольку доступ на запись подразумевает и доступ на чтение;
06 — присутствует доступ и на чтение и на запись.

Тип элемента, описываемого тегом "fld", указывается атрибутом tp (таблица 2).

Таблица 2. Значения атрибута tp тега "fld".
Тег tpОписание
strСтроковый тип.
<fld id='host' dscr='Host name' tp='str'/>
decЦелое число в десятичном представлении.
<fld id='debug' dscr='Debug level' tp='dec'/>
octЦелое число в восьмеричном представлении.
<fld id='cr_file_perm' dscr='Make files permissions(default 0644)' tp='oct' len='3'/>
hexЦелое число в шестнадцатеричном представлении.
realВещественное число.
boolЛогический признак ("false"|"true").
<fld id='log_sysl' dscr='Direct messages to syslog' tp='bool'/>
timeВремя в секундах (от 01/01/1970).
<fld id='v_beg' dscr='Start time' tp='time'/>

Таблица 3. Действия над элементом, описанным тегом "fld".
ОперацияДействие
ОпросЗапрос: команда "get": <get path="/fld_teg" user="user"/>.
Результат: подтверждение со значением в тексте тега или сообщение об ошибке.
МодификацияЗапрос: команда "set": <set path="/fld_teg" user="user">value</set>
Результат: подтверждение или сообщение об ошибке.
Запрос правил подсветки синтаксиса, для текстовых полей (определён атрибут "rows").Запрос: команда "SnthHgl": <SnthHgl path="/fld_teg" user="user"/>
Результат: подтверждение со списком правил подсветки синтаксиса:
<rule expr="\b(if|else|for|while|in|using|new|var|break|continue|return|Array|Object)\b" color="darkblue" font_weight="1"/>
<rule expr="(\?|\:)" color="darkblue" font_weight="1"/>
<rule expr="(\b0[xX][0-9a-fA-F]*\b|\b[+-]?[0-9]*\.?[0-9]+[eE]?[-+]?[0-9]*\b|\btrue\b|\bfalse\b)" color="blue"/>
<rule expr="&quot;[^&quot;]*&quot;" color="darkgreen"/>
<rule expr="//[^\n]*" color="gray" font_italic="1"/>
<blk beg="/\\*" end="\\*/" color="gray" font_italic="1"/>

b) Тег "list"
<list id='mod_auto' dscr='List of shared libs(modules)' tp='str' dest='file'/>


К тегу возможен доступ как на "чтение", так и на "запись"(модификацию), следовательно элемент триады доступа может принимать значения:
00 — доступ вообще отсутствует;
04 — присутствует доступ только на чтение;
02 — присутствует доступ только на запись, обычно такое значение не имеет смысла поскольку доступ на запись подразумевает и доступ на чтение;
06 — присутствует доступ и на чтение и на запись.

Тип элементов в списке указывается атрибутом tp. Значения атрибута tp приведены в таблице 1.

Таблица 4. Действия над списком.
ОперацияДействие
ОпросЗапрос: команда "get": <get path="/fld_teg" user="user"/>
Результат: подтверждение с результатом в тексте тега или сообщение об ошибке. Результат формируется в виде:
<get path="/fld_teg" user="user" rez="0">
<el id='0'>./MODULES/arh_base.o</el>
<el id='1'>./MODULES/cntr_sys.o</el>
</get>
Добавление строкиЗапрос: команда "add": <add path="/fld_teg" user="user" id="tst">Test</add>
Читается, как добавить строку с идентификатором "tst" и значением "Test". Если список не индексированный, то атрибут id отсутствует.
Результат: подтверждение или сообщение об ошибке.
Вставка строкиЗапрос: команда "ins": <ins path="/fld_teg" user="user" pos="3" p_id="tst1" id="tst">Test</ins>
Читается, как вставить строку с идентификатором "tst" и значением "Test" в позицию 3 со строкой "tst1". В случае индексного списка атрибут p_id содержит идентификатор, иначе — текст строки. Если список не индексирован, то атрибут id отсутствует.
Результат: подтверждение или сообщение об ошибке.
Удаление строкиЗапрос: команда "del": <del path="/fld_teg" user="user" pos='3' id='tst'>Test</del>
Читается, как удалить строку с идентификатором "tst" и значением "Test" в позиции 3. Если список не индексирован, то атрибут id отсутствует.
Результат: подтверждение или сообщение об ошибке.
Изменение строкиЗапрос: команда "edit": <edit path="/fld_teg" user="user" pos='3' p_id='tst1' id='tst' >Test</edit>
Читается, как заменить строку в позиции 3 с идентификатором "tst1" на строку с идентификатором "tst" и значением "Test". В случае индексированного списка атрибут p_id содержит идентификатор, иначе — текст строки. Если список не индексирован, то атрибут id отсутствует.
Результат: подтверждение или сообщение об ошибке.
Перемещение строкиЗапрос: команда "move": <move path="/fld_teg" user="user" pos='3' to='5'/>
Читается, как переместить строку с позиции 3 в позицию 5.
Результат: подтверждение или сообщение об ошибке.
c) Тег "table"
<table id='a_mess' key='0' col_lst="0;1;2">
  <list id='0' dscr='Id' acs='4' tp='str'/>
  <list id='1' dscr='Name' acs='4' tp='str'/>
  <list id='2' dscr='Type' acs='4' tp='str'/>
  <list id='3' dscr='Hide' acs='4' tp='bool'/>
</table>


К тегу таблицы и колонкам отдельно возможен доступ как на "чтение", так и на "запись"(модификацию), следовательно элемент триады доступа может принимать значения:
00 — доступ вообще отсутствует;
04 — присутствует доступ только на чтение;
02 — присутствует доступ только на запись, обычно такое значение не имеет смысла поскольку доступ на запись подразумевает и доступ на чтение;
06 — присутствует доступ и на чтение и на запись.

Если указан атрибут key и в нём перечислены ключевые колонки, то работа с таблицей переходит в режим адресации по идентификаторам колонок и ключам.

Таблица 5. Действия над таблицей.
ОперацияДействие
ОпросЗапрос: команда "get": <get path="/fld_teg" user="user" cols="0;2" rows="100;1000"/>
Читается, как получить колонки 0-2 и строки в них с 100 по 1000 таблицы.
Результат: Подтверждение с данными таблицы или сообщение об ошибке. Результат формируется в виде:
<get path="/fld_teg" user="user" cols="0;2" rows="100;1000" rez="0">
<list id='0' tp='str'>
<el id='100'>Sat Feb 21 18:04:16 2004</el>
</list>
<list id='1' tp='str'>
<el id='100'>SYS</el>
</list>
<list id='2' tp='str'>
<el id='100'>*:(TSYS)Broken PIPE signal allow!</el>
</list>
</get>
Добавление строкиЗапрос: команда "add": <add path="/fld_teg" user="user"/>
Результат: подтверждение или сообщение об ошибке.
Вставка строкиЗапрос: команда "ins": <ins path="/fld_teg" user="user" row='3'/>
Читается, как вставить строку в позицию 3. Команда не работает при установленном атрибуте key!
Результат: подтверждение или сообщение об ошибке.
Удаление строки
Запрос: команда "del": <del path="/fld_teg" user="user" row='3'/> или <del path="/fld_teg" user="user" key_id='Test'/> для ключевого режима
Читается, как удалить строку в позиции 3 или строку в позиции, где значение колонки id равно 'Test'.
Результат: подтверждение или сообщение об ошибке.
Перемещение строкиЗапрос: команда "move": <move path="/fld_teg" user="user" row='3' to='5'/>
Читается, как переместить строку с позиции 3 в позицию 5. Данная команда не работает при установленном атрибуте key!
Результат: подтверждение или сообщение об ошибке.
Изменить ячейкуЗапрос: команда "set": <set path="/fld_teg" user="user" row='3' col='id'>Test</set> или <set path="/fld_teg" user="user" key_id='Test' col='id'>Test1</set> для ключевого режима
Читается как — установить значение ячейки в строке 3 и колонке 'id' в "Test" или установка колонки с именем 'id' строки в позиции где значение колонки id равно 'Test' в значение 'Test1'. Практически данная команда переименовывает ключевой элемент указанной строки.
Результат: подтверждение или сообщение об ошибке.
d) Тег "img"
<img id='ico' descr='Иконка страницы'/>


К тегу возможен доступ как на "чтение", так и на "запись", следовательно элемент триады доступа может принимать значения:
00 — доступ вообще отсутствует;
04 — присутствует доступ только на чтение;
02 — присутствует доступ только на запись, обычно такое значение не имеет смысла поскольку доступ на запись подразумевает и доступ на чтение;
06 — присутствует доступ и на чтение и на запись.

Тег предназначен для передачи изображений клиентам интерфейса управления. Под изображением могут выступать: иконки страниц, графики массивов значений и другие данные, которые можно представить в графическом виде.

Поддерживаются команды запросов:
Результатом является подтверждение с данными изображения или сообщение об ошибке.
Результатом является подтверждение или сообщение об ошибке.
e) Команды с параметрами. Тег "comm"
<comm id='add'>
  <fld id='tm' tp='time'/>
  <fld id='cat' tp='str'/>
  <fld id='lvl' tp='dec' min='0' max='7'/>
  <fld id='mess' tp='str'/>
</comm>


К тегу возможен доступ как на "чтение" или видимость+обслуживание запросов, так и на модификацию или выполнение команды, следовательно элемент триады доступа может принимать значение 00, если доступ отсутствует вообще; 04, если команду можно увидеть; и 06, если команду можно инициировать.

Предназначен для передачи команд и действий узлу, а также может использоваться для создания ссылок на другие страницы. Команды могут включать параметры. Параметры описываются тегом "fld".

Поддерживаются команды запросов:
<set path="/fld_teg" user="user"/>
  <fld id='tm'>1023456244</fld>
  <fld id='cat'>*</fld>
  <fld id='lvl'>2</fld>
  <fld id='mess'>Test mess</fld>
</set>

<get path="/fld_teg" user="user" tp="lnk"/>"


Результатом является подтверждение или сообщение об ошибке.
f) Ветки (дочерние узлы)
<list id='k_br' dscr='Kernel branches' tp='br'/>


Ветки описываются обычным списком "list" со специальными атрибутами tp='br'. Методика запроса и модификации веток полностью совпадает с методикой работы со списком "list".

14.4 Иерархические зависимости информационных элементов языка управления

Пример страницы узла языка управления:
<oscada_cntr>
  <area id='a_gen' dscr='Generic control'>
    <fld id='config' dscr='Config file' tp='str' dest='file'/>
    <fld id='cr_file_perm' dscr='Files' tp='oct' len='3'/>
    <fld id='cr_dir_perm' dscr='Directories' tp='oct' len='3'/>
    <comm id='upd_opt' dscr='Update options(from config)'/>
    <comm id='quit' dscr='Quit'/>
  </area>
  <area id='a_kern' dscr='Kernels'>
    <list id='k_br' dscr='Kernels' tp='br'/>
  </area>
</oscada_cntr>


Таблица 6. Иерархические зависимости информационных элементов языка:
ТегОписаниеАтрибутыСодержимое
oscada_cntrКорневой элемент страницы. Является единственным и служит для идентификации принадлежности к языку интерфейса управления.id — идентификатор;
dscr — описание.
area, img, branches
branchesКонтейнер групп дочерних веток узла.id — идентификатор контейнера. Равен: br.grp
grpГруппа дочерних узлов.id — префикс группы дочерних узлов в системе;
dscr — описание группы веток;
acs — опции доступа.
areaГруппировка стандартных тегов.id — идентификатор;
dscr — описание;
acs — опции доступа.
area, fld, list, table, comm, img
commКоманды узлу.id — идентификатор;
dscr — описание;
help — помощь по команде;
tp — тип команды (lnk — ссылка);
acs — опции доступа.
fld
fldОписание данных стандартных типов.id — идентификатор;
dscr — описание;
help — помощь;
acs — опции доступа.
tp — тип элемента:
str(len, dest, cols, rows(SnthHgl)) — строковый элемент;
dec(len, max, min, dest) — целое число в десятичном представлении;
oct(len, max, min, dest) — целое число в восьмеричном представлении;
hex(len, max, min, dest) — целое число в шестнадцатеричном;
real(len, max, min, dest) — вещественное число;
bool — логический признак;
time — время/дата в секундах (от 01/01/1970).
Связные:
len — длина значения (симв.);
min — минимум значения;
max — максимум значения;
cols — количество колонок;
rows — количество строк;
dest — способ ввода:
data — источник бинарных данных (base64).
select(select) — выборный тип;
sel_ed(select) — выборный тип с возможностью редактирования.
select — путь к скрытому списку;
sel_list — статический список (разделитель ';');
sel_id — статический список идентификаторов (разделитель ';').
listСписок данных стандартных типов.id — идентификатор;
dscr — описание;
help — помощь по списку;
acs — опции доступа.
tp — как в fld кроме:
br(br_pref) — дочерние узлы.
idm — индексированный список (0|1);
s_com — способы модификации списка [add][,ins][,edit][,del]:
add — добавлять строки;
ins — вставлять строки;
edit — модифицировать строки;
del — удалять строки.
Связные:
br_pref — префикс дочерних узлов;
dest — как в fld.
tableТаблица данных стандартных типов.id — идентификатор;
dscr — описание;
help — помощь по таблице;
acs — опции доступа;
key — ключевые колонки (key="id,name,per");
cols — перечень колонок в атрибуте запроса;
rows — диапазон строк в атрибуте запроса;
s_com — способы модификации таблицы [add][,del][,ins][,move]:
add — добавлять строки;
ins — вставлять строки;
del — удалять строки;
move — перемещать строки.
list
imgИзображение.id — идентификатор;
dscr — описание;
help — помощь по изображению;
acs — опции доступа;
h_sz — горизонтальное ограничение;
v_sz — вертикальное ограничение.

14.5. Объект узла динамического дерева (TCntrNode)

Наследуется:Всеми динамическими и управляемыми объектами прямо или через потомков.

Данные:
Именованные права доступа к элементам управления (define):

Флаги динамического узла (enum TCntrNode::Flag):

Флаги режимов включения/отключения узла (enum TCntrNode::Flag):

Флаги модификации узла (enum TCntrNode::ModifFlag):

Публичные методы:
static XMLNode *ctrMkNode( const char *n_nd, XMLNode *nd, int pos, const char *req, const string &dscr int perm = 0777, const char *user = "root", const char *grp = "root", int n_attr = 0, ... );
static XMLNode *ctrMkNode2( const char *n_nd, XMLNode *nd, int pos, const char *req, const string &dscr, int perm = 0777, const char *user = "root", const char *grp = "root", ... );
— Добавление элемента управления на страницу. Возможно указание множества дополнительных атрибутов в количестве n_attr в виде: "{атрибут1},{значений1},{атрибут2},{значений2},..." или по нулевому указателю в конце последовательности пар.

Защищённые методы: