Модуль SmiuiSrv


Название SmiuiSrv можно расшифровать как SMI User Interface Server.
Библиотечный модуль SmiuiSrv содержит константы (_con_SmiuiSrv.inc), переменные (_var_SmiuiSrv.inc) и функции (_fun_SmiuiSrv.inc) для работы с распределенными Конечными Автоматами (FSM - Finite State Machine) с использованием технологии SMI.

Модуль SmiuiSrv запускает программу SMIUISRV.EXE, которая общается с сервером домена Конечных Автоматов smiSM.exe через динамическую библиотеку smiuirtl.dll с интерфейсом smiuirtl.pas.

В состав библиотеки входят модули:
FsmManager - библиотека для работы с конечными автоматами FSM.
Специально подключать эти модули не надо, они подключаются автоматически.


Конфигурирование:

Использование библиотеки SmiuiSrv предполагает (помимо обычного описания программы) наличие следующих параметров в секции описания программы:
[DeviceList]
&SMITEST.MAIN.CTRL = device software program
[&SMITEST.MAIN.CTRL]
Comment       = Программа, использующая SMIUISRV.
InquiryPeriod = 0
DevicePolling = 10, tpNormal
ProgramSource = ..\DaqPas\smitest_main_ctrl.pas
... и другие параметры ...

;--------------- Memory buffers -----
StdInFifo      = 128                ; StdIn  Console size, kB
StdOutFifo     = 128                ; StdOut Console size, kB
StdInPipeSize  = 128                ; StdIn  process pipe size, kB
StdOutPipeSize = 128                ; StdOut process pipe size, kB
;------------- SMIUISRV server parameters -----------------------
SMIUISRV_EXE = ~~\Resource\DaqSite\SmiServer\SmiuiSrv.exe       ; Location of executable file SMIUISRV.EXE
SMIUISRV_DNS = [&DimSrv] DIM_DNS_NODE %DIM_DNS_NODE% localhost  ; DIM_DNS_NODE uses to launch SMIUISRV.EXE
SMIUISRV_ARG = -auto -dom DEMO -sleep 1000                      ; Command line arguments for  SMIUISRV.EXE
SMIUISRV_FSM = -dom DEMO -sml run_con.sml                       ; Command line to initialize FSM Manager
SMIUISRV_WDT = 10                                               ; WatchDog Timer, seconds for SMIUISRV.EXE
SMIUISRV_SWM = 0                                                ; Show Window Mode to display SMIUISRV.EXE
SmiTagPrefix = SMI.                                             ; Common Prefix for all SMI related tags
SmiMenuFont  = Name:PT_Mono\Size:16\Style:[Bold]                ; Font uses for State/Action Menu's
;----------------------------------------------------------------

[]
  
Здесь используются следующие параметры SmiuiSrv:
SMIUISRV_EXE = ~~\Resource\DaqSite\SmiServer\SmiuiSrv.exe       ; Расположение исполняемого файла SMIUISRV.EXE
SMIUISRV_DNS = [&DimSrv] DIM_DNS_NODE %DIM_DNS_NODE% localhost  ; Задание DIM_DNS_NODE при запуске SMIUISRV.EXE
               [&DimSrv] DIM_DNS_NODE                           ; --- взять DNS из переменной [&DimSrv] DIM_DNS_NODE
               %DIM_DNS_NODE%                                   ; или взять из переменной окружения %DIM_DNS_NODE%
               localhost                                        ; или взять значение localhost
SMIUISRV_ARG = -auto -dom DEMO -sleep 1000                      ; Строка аргументов вызова программы SMIUISRV.EXE
               -auto                                            ; --- автоматическое подключение всех найденных объектов
               -dom DOM                                         ; --- подключение к SMI домену с именем DEMO
               -sleep 1000                                      ; --- пауза 1000 миллисекунд после подключения
SMIUISRV_FSM = -dom DEMO -sml run_con.sml                       ; Команда инициализации Менеджера Конечных Автоматов FSM Manager
               -dom DEMO                                        ; --- загрузить домен DEMO
               -sml run_con.sml                                 ; --- из SML файла run_con.sml (путь относительно Config)
SMIUISRV_WDT = 10                                               ; Сторожевой таймер (секунд), для SMIUISRV.EXE
SMIUISRV_SWM = 0                                                ; Режим рисования ShowWindow, для SMIUISRV.EXE
SmiTagPrefix = SMI.                                             ; Общий префикс для всех тегов SMI, по умолчанию SMI.
SmiMenuFont  = Name:PT_Mono\Size:16\Style:[Bold]                ; Фонт для меню Состояние/Действие, по умолчанию Name:PT_Mono\Size:14\Style:[Bold]
                
  Обратите внимание - параметры SMIUISRV_ARG, SMIUISRV_FSM должны быть согласованы,
  т.е. в них должно указываться то же самое имя домена (в данном случае DEMO), иначе будут ошибки.
  
При задании командной строки SMIUISRV_ARG, SMIUISRV_FSM можно использовать несколько доменов, перечисляемых один за другим (но при этом используется один и тот же DNS), например:
SMIUISRV_EXE = ~~\Resource\DaqSite\SmiServer\SmiuiSrv.exe
SMIUISRV_DNS = [&DimSrv] DIM_DNS_NODE %DIM_DNS_NODE% localhost
SMIUISRV_ARG = -auto -dom DEMO -sleep 1000 -dom TEST -sleep 1000
SMIUISRV_FSM = -dom DEMO -sml run_con.sml -dom TEST run_test.sml
SMIUISRV_WDT = 10
SMIUISRV_SWM = 0
  
Это позволяет обслуживать сразу несколько доменов Конечных Автоматов.


Подключение:

Использование библиотеки SmiuiSrv предполагает использование следующего шаблона программы (код подключения выделен жирным шрифтом):
program Demo;                    { How to use SmiuiSrv              }
const
 {------------------------------}{ Declare uses program constants:  }
 {$I _con_StdLibrary}            { Include all Standard constants,  }
 {------------------------------}{ And add User defined constants:  }
 {$I _con_SmiuiSrv}              { SmiuiSrv   constants             }
 
 // User code - constants...
 
var
 {------------------------------}{ Declare uses program variables:  }
 {$I _var_StdLibrary}            { Include all Standard variables,  }
 {------------------------------}{ And add User defined variables:  }
 {$I _var_SmiuiSrv}              { SmiuiSrv   variables             }
 
 // User code - variables...

 {------------------------------}{ Declare procedures & functions:  }
 {$I _fun_StdLibrary}            { Include all Standard functions,  }
 {------------------------------}{ And add User defined functions:  }
 {$I _fun_SmiuiSrv}              { SmiuiSrv   functions             }
 
 // User code - functions...
 
 {
 Clear user application strings...
 }
 procedure ClearApplication;
 begin
  ClearSmiuiSrv;
  // User code - clear...
 end;
 {
 User application Initialization...
 }
 procedure InitApplication;
 begin
  InitSmiuiSrv;
  // User code - init...
 end;
 {
 User application Finalization...
 }
 procedure FreeApplication;
 begin
  FreeSmiuiSrv;
  // User code - free...
 end;
 {
 User application Polling...
 }
 procedure PollApplication;
 begin
  if ShouldPollSmiuiSrv then PollSmiuiSrv;
  //
  // User code - poll...
  //
  
  //
  // Sensor Click Handler...
  //
  if ClickWhat<>0 then
  repeat
   if (ClickWhat=cw_MouseDown) or (ClickWhat=cw_KeyDown) then begin
    if (ClickButton=VK_LBUTTON) then begin
     
     //
     // SMI FSM click handler...
     //
     if (smiuisrv_click_fsm<>0) then begin
      smiuisrv_click_fsm_default_handler(ClickParams(''));
     end;
     
    end;
   end;
  until (ClickRead=0);
 end;
 {
 Process data coming from standard input...
 }
 procedure StdIn_Processor(var Data:String);
 var cmd,arg:String; n:Integer;
 begin
  ViewImp('CON: '+Data);
  {
  Handle "@cmd=arg" or "@cmd arg" commands:
  }
  cmd:='';
  arg:='';
  if GotCommand(Data,cmd,arg) then begin
   
   // User code - handle stdin...
   
   {
   !!! Handle SMIUISRV by default handler !!!
   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   }
   if smiuisrv_default_handler(Data,cmd,arg,cmdid) then begin
    if (Data<>'') then Success(smiuisrv_prompt+Data);
    Data:='';
   end else
   
   {
   Handle other commands by default handler...
   }
   StdIn_DefaultHandler(Data,cmd,arg);
  end;
  Data:='';
  cmd:='';
  arg:='';
 end;

{***************************************************}
{***************************************************}
{***                                             ***}
{***  MMM    MMM        AAA   IIII   NNN    NN   ***}
{***  MMMM  MMMM       AAAA    II    NNNN   NN   ***}
{***  MM MMMM MM      AA AA    II    NN NN  NN   ***}
{***  MM  MM  MM     AA  AA    II    NN  NN NN   ***}
{***  MM      MM    AAAAAAA    II    NN   NNNN   ***}
{***  MM      MM   AA    AA   IIII   NN    NNN   ***}
{***                                             ***}
{***************************************************}
{$I _std_main}{*** Please never change this code ***}
{***************************************************}
 



Константы:

см. файл _con_SmiuiSrv.inc


Переменные:

см. файл _var_SmiuiSrv.inc


Функции:

см. файл _fun_SmiuiSrv.inc

Функции API условно делятся на прикладные (которые бывают нужны для создания прикладных программ) и служебные (которые предназначены в основном для внутреннего использования и обычно не вызываются явно). Некоторые служебные функции вызывать напрямую запрещено, иначе это нарушит логику работы программы. Напротив, некоторые прикладные функции являются основными, то есть обычно должны присутствовать в прикладной программе.


function smiuisrv_fsm:Integer;
Функция возвращает ссылку Менеджера Состояний FSM для сервера SMIUISRV.
Менеджер состояний хранит все данные о текущем состоянии Конечных Автоматов. см. FSM API.
Инициализируется с помощью параметров конфигурации SMIUISRV_DNS и SMIUISRV_FSM.


function smiuisrv_prompt:String;
Функция возвращает промпт SMIUISRV => используемый для вывода на печать в консоль.


function smiuisrv_smitagprefix:String;
Функция возвращает общий префикс тегов SMI, используемый для формирования имен тегов, связанных с SMI.
Задается параметром конфигурации SmiTagPrefix = SMI. (по умолчанию SMI.).


function smiuisrv_create_command(obj,act:String):String;
function smiuisrv_add_param_to_command(cmd,name,value:String; typ:Integer):String;
Функция smiuisrv_create_command(obj,act) формирует команду для посылки в консоль устройства, которая вызвает действие (act) объекта (obj).
Функция smiuisrv_add_param_to_command(cmd,name,value,typ) добавляет к команде (cmd) параметр с именем (name) и значением (value) заданного типа (typ=SMI_STRING,SMI_INTEGER,SMI_FLOAT).
Например:
   cmd:=smiuisrv_create_command('DEMO::RUN','START');
   cmd:=smiuisrv_add_param_to_command(cmd,'TYPE','TEST',SMI_STRING);
   cmd:=smiuisrv_add_param_to_command(cmd,'NR',Str(123),SMI_INTEGER);
   DevPostCmdLocal(cmd);
   
   Формирует и посылает команду
   @smiuisrv_send @smiui_send_command=DEMO::RUN,START/TYPE(S)=TEST/NR(I)=123
  



function smiuisrv_color_default:Integer;
function smiuisrv_color_btnface:Integer;
function smiuisrv_color_neutral:Integer;
function smiuisrv_color_dormant:Integer;
function smiuisrv_color_working:Integer;
function smiuisrv_color_success:Integer;
function smiuisrv_color_refused:Integer;
function smiuisrv_color_offline:Integer;
function smiuisrv_color_warning:Integer;
function smiuisrv_color_trouble:Integer;
function smiuisrv_color_online:Integer;
function smiuisrv_color_error:Integer;
function smiuisrv_color_fatal:Integer;
function smiuisrv_color_dead:Integer;
function smiuisrv_color_edit:Integer;
function smiuisrv_color_text:Integer;
function smiuisrv_color_info:Integer;
function smiuisrv_color_alert(severity:Integer):Integer;
Функции возвращают функциональные цвета используемые для отображения состояний элементов.
smiuisrv_color_default
Фон элемента по умолчанию.
smiuisrv_color_btnface
Фон кнопки, метки, текста.
smiuisrv_color_neutral
Фон нейтрального элемента (метки, текста).
smiuisrv_color_dormant
Фон элемента FSM в ждущем (пассивном) состоянии.
smiuisrv_color_working
Фон элемента FSM в рабочем (активном) состоянии.
smiuisrv_color_success
Фон элемента для индикации успешого выполнения операции.
smiuisrv_color_refused
Фон элемента при ошибке связи.
smiuisrv_color_offline
Фон элемента при разрыве связи.
smiuisrv_color_warning
Фон элемента при возникновении потенциально опасного состояния (предупреждение).
smiuisrv_color_trouble
Фон элемента при обнаружении проблем средней тяжести (неприятность).
smiuisrv_color_online
Фон элемента при наличии нормальной связи.
smiuisrv_color_error
Фон элемента при средней (восстановимой) ошибке.
smiuisrv_color_fatal
Фон элемента при серьезной (фатальной) ошибке.
smiuisrv_color_dead
Фон "мертвого" (отключенного) элемента.
smiuisrv_color_edit
Фон редактируемого элемента (поле вода).
smiuisrv_color_text
Цвет текста.
smiuisrv_color_info
Фон информационного элемента (нередактируемые данные).
smiuisrv_color_alert(0)
Фон элемента при уровне тревоги 0=smi_severity_norm - нормальное функционирование.
smiuisrv_color_alert(1)
Фон элемента при уровне тревоги 1=smi_severity_info - нормальная работа, есть информация к сведению пользователя.
smiuisrv_color_alert(2)
Фон элемента при уровне тревоги 2=smi_severity_warning - потенциально опасное состояние, низкий уровень тревоги.
smiuisrv_color_alert(3)
Фон элемента при уровне тревоги 3=smi_severity_error - обнаружена восстановимая ошибка, высокий уровень тревоги.
smiuisrv_color_alert(4)
Фон элемента при уровне тревоги 4=smi_severity_fatal - обнаружена серьезная (фатальная) ошибка, высший уровень тревоги.



function smiuisrv_substitute_keywords(ref:Integer; s:String):String;
Функция выполняет в строке (s) подстановку зарезирвированных слов _DOMAIN_, _OBJECT_, _STATE_, _ACTION_ на соответствующее значение, взятое из элемента (ref). Подстановки позволяют ссылаться на домены/объекты/состояния/действия без указания их явного значения. Например:
   obj:=fsm_find(smiuisrv_fsm,'DEMO::LOGGER');                               // Object DEMO::LOGGER reference
   writeln(smiuisrv_substitute_keywords(obj,'SMI._domain_::_object_.FSM'));  // Print: SMI.DEMO::LOGGER.FSM
  



function smiuisrv_smimenufont:String;
Функция возвращает описание шрифта (вида Name:PT_Mono\Size:14\Color:Black\Style:[Bold]) используемый для меню выбора Действий в FSM.
Инициализируется с помощью параметра конфигурации SmiMenuFont.


function smiuisrv_task_dnsnode:String;
Функция возвращает DNS используемый для подключения к сети DIM.
Инициализируется с помощью параметра конфигурации SMIUISRV_DNS.


function smiuisrv_task_fsmargs:String;
function smiuisrv_task_fsmline:String;
Функции возвращают параметры Менеджера Состояний FSM: аргументы (fsmargs) и строка инициализации (fsmline).
Инициализируется с помощью параметров конфигурации SMIUISRV_DNS и SMIUISRV_FSM.


function smiuisrv_task_exefile:String;
function smiuisrv_task_cmdargs:String;
function smiuisrv_task_cmdline:String;
Функции возвращают параметры запуска задачи (task) SMIUISRV.EXE: полное имя файла (exefile), аргументы вызова (cmdargs), командную строку (cmdline).


function smiuisrv_task_tid:Integer;
function smiuisrv_task_pid:Integer;
Функции возвращают параметры работы задачи (task) SMIUISRV.EXE: идентификатор задачи (tid), идентификатор процесса (pid).


function smiuisrv_task_running:Boolean;
Функция возвращает состояние работы процесса SMIUISRV.EXE - работает ли он в данный момент или нет.


procedure smiuisrv_task_send(msg:String);
Процедура посылает (send) сообщение (msg) процессу SMIUISRV.EXE в консоль StdIn. Сообщение обычно содержит команду для обработки. Команды процессу SMIUISRV.EXE можно также посылать с помощью сообщений в локальную консоль DAQ устройства вида @smiuisrv_send command, например:
  DevPostCmdLocal('@smiuisrv_send @exit'); // Послать процессу SMIUISRV команду @exit
  
см. также smiuisrv_task_processing, smiuisrv_default_handler.


procedure smiuisrv_task_processing(var Data:String);
Процедура выполняет обработку строки данных (Data), поступающих от процесса SMIUISRV.EXE через консоль StdOut.
Часть команд обрабатывается непосредственно в процедуре smiuisrv_task_processing, а часть пересылается в локальную консоль для последующей обработки в процедуре smiuisrv_default_handler:
  Обрабатываются внутри процедуры smiuisrv_task_processing:
  
    @Exit                   - команда завешения процесса, процесс будет перезапущен через некоторое время
    @Errors                 - команда чтения счетчика ошибок
    @Memory                 - команда чтения счетчика памяти
    @ProcessPriority        - команда чтения/записи приоритета процесса
    @ThreadPriority         - команда чтения/записи приоритета потока
    @OnException            - сообщение о возникшем исключении (ошибке выполнения)
    @Sleep                  - команда "засыпания" на заданное время
    @dim_dns_node           - команда чтения/записи процессу значения DNS
    
  Пересылаются в локальную консоль и обрабатываются в процедуре smiuisrv_default_handler:
  
    см. smiuisrv_default_handler
  
Пересылка команд в локальную консоль DAQ-устройства имеет то преимущество, что позволяет "перехватывать" сообщения, если их надо обрабатывать каким-то особым способом, отличным от стандартной функции обработки smiuisrv_default_handler.


procedure smiuisrv_task_clear;
Служебная процедура очищает переменные задачи SMIUISRV.EXE, вызывается из других процедур библиотеки. Вызывать её напрямую не стоит, это может нарушить работу программы.


procedure smiuisrv_task_stop(exitcode:Integer);
Процедура останавливает работу процесса SMIUISRV.EXE с кодом возврата (exitcode). Обычно вызывается автоматически.


procedure smiuisrv_task_start;
Процедура запускает процесс SMIUISRV.EXE, если он еще не запущен, с аргументами, указанными в параметре конфигурации SMIUISRV_ARG. Обычно вызывается автоматически.


procedure smiuisrv_task_poll;
procedure smiuisrv_watchdog_poll;
Процедуры опроса заачи (task) обслуживания процесса SMIUISRV.EXE и сторожевого таймера (watchdog). Процедура опроса задачи выполняет периодическую проверку статуса задачи, а также обработку ввода-вывода. Сторожевой таймер периодически проверяет состояние процесса SMIUISRV.EXE и при необходимости перезапускает его в случае "падения". Обычно вызывается автоматически.


procedure smiuisrv_clear_all;
procedure smiuisrv_initialize;
procedure smiuisrv_finalize;
Служебные процедуры очистки/инициализации/завершения. Обычно вызываются автоматически. Вызывать их напрямую не стоит, это может нарушить работу программы.


procedure smiuisrv_update_object_state(objname,state,busy:String);
Процедура обработки принятия (изменения) состояния (state) объекта (objname). В результате процедуры объект (objname) переводится в состояние (state) и маркируется как "измененный" (fsm_modified). Кроме того, в поле fsm_link(obj,'busy_action') заносится ссылка на выполняемую акцию (busy) или 0, если busy не задано. Наличие непустого (не равного знаку '-') параметра busy означает, что объект "занят", т.е. выполняет акцию (действие ACTION). Параметр (busy) содержит имя текущей выполняемой в данный момент акции или '-', если акция в данный момент не выполняется.


function smiuisrv_find_fsm_by_linked_tag(tag:Integer):Integer;
Функция находит элемент FSM по ссылке тега (tag), который был присоединен (fsm_link) во время инициализации сервера InitSmiuiSrv. Список присоединенных тегов:
Теги FSM Менеджера                    Тип      Комментарий
    SMI.HOSTNAME                            string   - Имя этого  компьютера  например: W10X32-DEMO-VM
    SMI.DATETIME                            string   - Дата-Время компьютера  например: 2022.04.21-09:51:21
    SMI.DNS_NODE                            string   - Имя DIM DNS сервера    например: localhost или w10x32-demo-vm
    SMI.DNS_TASK                            string   - Имя задачи DIM DNS     например: DIS_DNS@w10x32-demo-vm
    SMI.DNS_PID                             integer  - PID DIM DNS сервера    например: 4032
    SMI.DNS_VERSION                         integer  - Версия DNS или 0       например: 2033 или 0 если нет связи с DNS
Теги SMI FSM Домена с именем domain              
    SMI.domain.SMI_MESSAGE                  string   - Системные сообщения от SMI сервера smiSM.exe (запуск, ошибки)
    SMI.domain.USER_MESSAGE                 string   - Сообщения от пользователя домена через SML инструкцию REPORT(...)
    SMI.domain.DOMAIN_NAME                  string   - Имя домена SMI         например: DEMO
    SMI.domain.NUMBER_OF_OBJECTS            integer  - Число объектов в домене или 0 если нет подключения к домену SMI
Теги SMI FSM Объекта domain::object              
    SMI.domain::object.OBJECT_NAME          string   - имя объекта            например: DEMO::LOGGER
    SMI.domain::object.OBJECT_TITLE         string   - заголовок объекта      например: ДЕМО::ЖУРНАЛ
    SMI.domain::object.OBJECT_PARAM         string   - параметры объекта      например: NUMBER_T(I)=1/NUMBER_P(I)=1
    SMI.domain::object.STATE_NAME           string   - имя текущего состояния например: NOT_LOGGING
    SMI.domain::object.STATE_TITLE          string   - заголовок состояния    например: ОТКЛЮЧЕН
    SMI.domain::object.BUSY_ACTION          string   - имя текущего действия  например: ВКЛЮЧИТЬ
                                                       если действие завершено - пустая строка
Теги SMI FSM Объекта domain::objectset              
    SMI.domain::objectset.OBJECTSET_LIST    string   - список объектов в наборе например: DEMO::LOGGER,DEMO::EVT_BUILDER
    SMI.domain::objectset.OBJECTSET_NAME    string   - имя набора объектов    например: DEMO::PROXY_SET
    SMI.domain::objectset.OBJECTSET_TITLE   string   - заголовок набора --    например: ДЕМО::ПРОКСИ
Примечание:
    1) Префикс SMI. задается в параметре конфигурации SmiTagPrefix = SMI.
    2) Теги меняют цвет (Get/SetTagColor) в зависимости от состояния, см. функцию LinkedTagColor() в Painter.
    3) В стабильном состоянии BUSY_ACTION содержит пустую строку, имя действия действительно только в момент перехода.
    4) Теги OBJECT_NAME/STATE_NAME содержат имена объектов/состояний, а OBJECT_TITLE/STATE_TITLE - заголовки для их отображения.
  
Функция smiuisrv_find_fsm_by_linked_tag обычно используется при обработке "кликов" (событий нажатия элементов мнемосхем) для определения элемента FSM, с которым связан этот "клик".


function smiuisrv_click_fsm:Integer;
Функции для обработки графического ввода пользователя, т.е. нажатий элементов мнемосхем ("кликов" - click). Возвращает элемент FSM, с которым связан этот "клик", либо 0, если клик не связан с FSM. Функция работает аналогично вызову smiuisrv_find_fsm_by_linked_tag(ClickTag). Применяется для обработки пользовательского ввода Конечных Автоматов.


procedure smiuisrv_start_menu_state_click(state:Integer; click:String);
procedure smiuisrv_menu_state_default_handler;
Служебные процедуры для вызова меню при нажатии на сенсор состояния и его обработки. Обычно вызывается автоматически при выполнении smiuisrv_click_fsm_default_handler.


procedure smiuisrv_click_fsm_default_handler(click:String);
Процедура стандартной (default) обработки (handler) нажатий кнопок (click), связанных с Конечным Автоматами (fsm), обслуживающимися сервером (SMIUISRV). В качестве аргумента передается текст (click) параметров нажатия, обычно это ClickParams(''). Например:
 procedure Polling; // ... в цикле обработки ...
 begin
 
  ... прикладной код ...
  
  //
  // Обработка нажатий кнопок...
  //
  if ClickWhat<>0 then
  repeat
   if (ClickWhat=cw_MouseDown) or (ClickWhat=cw_KeyDown) then begin
    if (ClickButton=VK_LBUTTON) then begin
     
     //
     // SMI FSM click handler
     //
     if (smiuisrv_click_fsm<>0) then begin
      smiuisrv_click_fsm_default_handler(ClickParams(''));
     end;
     
    end;
   end;
  until (ClickRead=0);
  
  ... прикладной код ...
  
 end;
  
При необходимости обработки, отличной от стандартной, надо "перехватывать" клики до вызова стандартной процедуры обработки.


function smiuisrv_parse_csv(var arg,w1,w2,w3,w4,w5,w6:String; nlast:Integer):Integer;
Служебная функция выполяет разбор (parse) списка аргументов (arg) разделенного запятой, т.е. в формате CSV (comma separated list) и возвращает число строковых полей, разделенных запятой (с учетом параметра nlast). Поля (после удаления лишних пробелов) записываются в переменные (w1..w6), которые изначально (перед анализом) инициализируются пустыми строками. Значение поля '-' (это маркер пустой строки) при записи заменяется на пустую строку. Если указан ненулевой параметр nlast, то число полей ограничивается значением nlast, причем в последнее поле с номером nlast в этом случае включается остаток строки, независимо от наличия в нем запятых ("хвостовое поле").
Например:
  arg:='1,DEMO,SML INFO DEMO, State Manager started';
  // Исходная строка для анализа
  
  n:=smiuisrv_parse_csv(arg,w1,w2,w3,w4,w5,w6,0);
  // Результат вызова: n=4, w1='1', w2='DEMO', w3='SML INFO DEMO', w4='State Manager started', w5='', w6=''
  
  n:=smiuisrv_parse_csv(arg,w1,w2,w3,w4,w5,w6,3);
  // Результат вызова: n=3, w1='1', w2='DEMO', w3='SML INFO DEMO, State Manager started', w4='', w5='', w6=''
  
Функция smiuisrv_parse_csv применяется для анализа потока данных от SMIUISRV.EXE в процедурах smiuisrv_task_processing, smiuisrv_default_handler. Обычно эта функция вызывается автоматически, но может использоваться в прикладном коде, если используется "перехват" командных сообщений SMIUISRV.EXE, при котором надо выполнять разбор списка аргументов.


procedure smiuisrv_default_fsm_poll;
Стандартная процедура обработки Конечного Автомата SMIUISRV.EXE в цикле опроса.

Алгоритм работы процедуры smiuisrv_default_fsm_poll следующий.
Для каждого элемента FSM начиная с Менеджера smiuisrv_fsm рекурсивно вызывается процедура обработки, которая проверяет (и сбрасывает) счетчик модификаций fsm_modified(ref,0), установленный ранее (обычно при получении сообщения процедурами smiuisrv_task_processing, smiuisrv_default_handler). Процедура обработки, в зависимости от типа элемента FSM, вызывает обновление соответствующих тегов и внутренних переменных.

Такой алгоритм обработки принят потому, что он позволяет разделить процедуры получения данных (от процесса SMIUISRV.EXE) и их последующей обработки. Это позволяет выполнять обработку состояний FSM централизованно, в одном месте.

При необходимости "перекрыть" стандартную обработку другой процедурой достаточно в цикле опроса вызывать её ДО вызова smiuisrv_default_fsm_poll, используя для проверки состояний fsm_modified(ref,0) (для полной замены обработкика), либо fsm_modified(ref,-1) (для добавления своих новых действий). Это связано с тем, что при вызове fsm_modified(ref,0) счетчик модификаций сбрасывается и элемент помечается как "не модифицированный", т.е. не требующий обработки. Поэтому последующий вызов smiuisrv_default_fsm_poll не будет обновлять уже обработанные элементы. Если же использовать fsm_modified(ref,-1), то счетчик модификаций не сбрасывается, то есть при последующем вызове smiuisrv_default_fsm_poll будет выполнена стандартная обработка элементов.


function smiuisrv_default_handler(var Data,cmd,arg:String; cmdid:Integer):Boolean;
Стандартная процедура обработки консольного ввода для сообщений от процесса SMIUISRV.EXE. Эта процедура должна вызываться так, как показано в шаблоне. При необходимости специальной обработки можно перехватывать сообщения до вызова этой процедуры.
  Обрабатываются внутри процедуры smiuisrv_task_processing:
  
    см. smiuisrv_task_processing
    
  Пересылаются в локальную консоль и обрабатываются в процедуре smiuisrv_default_handler:
  
    ---
    @smiuisrv_send                  - посылка команды в консоль SMIUISRV.EXE
        например:
        > @smiuisrv_send @exit
        < Server request to stop with exit code 0
        
    ---
    @smiuisrv_restart               - (пере)запуск задачи SMIUISRV.EXE с заданным кодом возврата
        например:
        > @smiuisrv_restart 0
        
    ---
    @smiuisrv_fsm_dump              - отладочный вывод ключей FSM (вызов функции fsm_dump).
        например:
        > @smiuisrv_fsm_dump                    - вывод списка всех ключей
        > @smiuisrv_fsm_dump 1 demo::run        - вывод (подробный) ключей, содержащих DEMO::RUN
        > @smiuisrv_fsm_dump 1 demo::run ^class - вывод (подробный) ключей, содержащих DEMO::RUN и не содержащих CLASS
        
    ---
    @smiui_current_state            - обработка команды чтения текущего состояния объекта
        например:
        > @smiuisrv_send @smiui_current_state=DEMO::LOGGER
        < @smiui_current_state=1,DEMO::LOGGER,NOT_LOGGING,-
                1               - статус (0/1)
                DEMO::LOGGER    - имя объекта
                NOT_LOGGING     - состояние объекта
                -               - состояние BUSY: (- если не занят), или (ACTION = имя действия если занят)
        
    ---
    @smiui_send_command             - посылка команды (изменения состояния) объекту           (асинхронно)
    @smiui_ep_send_command          - посылка команды (изменения состояния) прокси-объекту    (асинхронно)
    @smiui_send_command_wait        - посылка команды (изменения состояния) объекту           (синхронно)
    @smiui_ep_send_command_wait     - посылка команды (изменения состояния) прокси-объекту    (синхронно)
        например:
        > @smiuisrv_send @smiui_send_command=DEMO::LOGGER,LOG
        < @smiui_send_command=1,DEMO::LOGGER,LOG
                1               - статус (0/1)
                DEMO::LOGGER    - имя объекта
                LOG             - новое (желаемое) состояние объекта после выполнения команды
        
    ---
    @smiui_change_option            - команда изменения опции сервера Конечных Автоматов smiSM.exe (асинхронно)
    @smiui_change_option_wait       - команда изменения опции сервера Конечных Автоматов smiSM.exe (синхронно)
        например:
        > @smiuisrv_send @smiui_change_option=DEMO,d,8
        < @smiui_change_option=1,DEMO,d,8
                1               - статус (0/1)
                DEMO            - имя домена
                d               - имя опции
                8               - значение опции
    
    ---
    @smiui_get_options              - команда чтения опций сервера Конечных Автоматов smiSM.exe
        например:
        > @smiuisrv_send @smiui_get_options=DEMO
        < @smiui_get_options=1,DEMO,d/INT/9/Diagnostic Level|...
                1               - статус (0/1)
                DEMO            - имя домена
                d/INT/9...      - список значений опций в формате
                                  Имя/Тип/Значение/Комментарий|...
                                  список опций разделяется знаком |
                                  список полей разделяется знаком /
    
    ---
    @smiui_number_of_objects        - получение числа объектов в домене
    @smiui_connect_domain           - получение числа объектов в домене
        например:
        > @smiuisrv_send @smiui_number_of_objects=DEMO
        < @smiui_number_of_objects=6,DEMO
                6                   - число объектов в домене
                DEMO                - имя домена
        
    
    ---
    @smiui_book_connect_domain      - подписка на события подключения домена (@smiui_connect_domain_handler)
    @smiui_cancel_connect_domain    - отписка  от событий подключения домена (@smiui_connect_domain_handler)
        например:
        > @smiuisrv_send @smiui_book_connect_domain=DEMO
        < @smiui_book_connect_domain=0,DEMO
        > @smiuisrv_send @smiui_cancel_connect_domain=DEMO
        < @smiui_cancel_connect_domain=1,DEMO
        
    ---
    @smiui_shutdown_domain          - завершение работы домена
    @smiui_kill                     - завершение работы домена
        например:
        > @smiuisrv_send @smiui_shutdown_domain=DEMO
        < @smiui_shutdown_domain=1,DEMO
    
    ---
    @smiui_check_proxy              - проверка статуса прокси-объекта SMI
        например:
        > @smiuisrv_send @smiui_check_proxy=DEMO::LOGGER
        < @smiui_check_proxy=1,DEMO::LOGGER
                1                   - статус прокси объекта (0/1=не/работает)
                DEMO::LOGGER        - имя проверяемого прокси-объекта
    
    ---
    @smiui_book_statechange         - подписка на события изменения состояния объектов (@smiui_statechange_handler)
    @smiui_cancel_statechange       - отписка  от событий изменения состояния объектов (@smiui_statechange_handler)
        например:
        > @smiuisrv_send @smiui_book_statechange=DEMO::LOGGER,auto
        < @smiui_book_statechange=18,DEMO::LOGGER
        > @smiui_cancel_statechange=DEMO::LOGGER
        < @smiui_cancel_statechange=1,DEMO::LOGGER
                DEMO::LOGGER        - имя объекта
                auto                - флаг автоматической подписки на все найденные объекты в домене
                18                  - идентификатор (номер) подписки
                1                   - статус отписки
    
    ---
    @smiui_book_smi_message         - подписка на события получения системных сообщений SMI (@smiui_smi_message_handler)
    @smiui_cancel_smi_message       - отписка  от событий получения системных сообщений SMI (@smiui_smi_message_handler)
        например:
        > @smiuisrv_send @smiui_book_smi_message=DEMO
        < @smiui_book_smi_message=10,DEMO
        > @smiuisrv_send @smiui_cancel_smi_message=DEMO
        < @smiui_cancel_smi_message=1,DEMO
                DEMO::LOGGER        - имя домена
                10                  - идентификатор (номер) подписки
                1                   - статус отписки
    
    ---
    @smiui_book_user_message        - подписка на события получения пользовательских сообщений SMI (@smiui_user_message_handler)
    @smiui_cancel_user_message      - отписка  от событий получения пользовательских сообщений SMI (@smiui_user_message_handler)
        например:
        > @smiuisrv_send @smiui_book_user_message=DEMO
        < @smiui_book_user_message=10,DEMO
        > @smiuisrv_send @smiui_cancel_user_message=DEMO
        < @smiui_cancel_user_message=1,DEMO
                DEMO::LOGGER        - имя домена
                10                  - идентификатор (номер) подписки
                1                   - статус отписки
    
    ---
    @smiui_list_domain_objects      - получение списка объектов в домене (работает пока не сделана подписка)
    
    ---
    @smiui_list_domain_objectsets   - получение списка наборов объектов (objectset) в домене
        например:
        > @smiuisrv_send @smiui_list_domain_objectsets=DEMO,auto
        < @smiui_list_domain_objectsets=2,DEMO,DEMO::LOW_SET|DEMO::TOP_SET
                2                   - число наборов объектов в домене
                DEMO                - имя домена
                auto                - флаг автоматической подписки на все найденные наборы объектов
                DEMO::LOW_SET|...   - список наборов объектов в домене, разделенный знаком |
    
    ---
    @smiui_list_domain_objectsets=2,DEMO,DEMO::LOW_SET|DEMO::TOP_SET
    
    ---
    @smiui_book_objectsetchange     - команда подписки на изменение набора объектов
        например:
        > @smiuisrv_send @smiui_book_objectsetchange=DEMO::LOW_SET
        < @smiui_book_objectsetchange=1,DEMO::LOW_SET

    ---
    @smiui_cancel_objectsetchange   - команда отмены подписки на изменение набора объектов
        например:
        > @smiuisrv_send @smiui_cancel_objectsetchange=DEMO::LOW_SET
        < @smiui_cancel_objectsetchange=1,DEMO::LOW_SET
    
    ---
    @smiui_connect_domain_handler   - извещение о подключении/отключении домена SMI
        например:
        < @smiui_connect_domain_handler=1,DEMO,3,DEMO::RUN|DEMO::LOGGER/ASSOCIATED|DEMO::EVT_BUILDER/ASSOCIATED
                1                   - счетчик событий
                DEMO                - имя домена
                3                   - число объектов в домене
                DEMO::RUN|...       - список объектов домена, разделенный знаком |
                                      прокси-объекты имеют атрибут /ASSOCIATED
                
    ---
    @smiui_statechange_handler      - извещение о изменении состояния объекта SMI
        например:
        < @smiui_statechange_handler=2,DEMO::EVT_BUILDER,ERROR,-,RECOVER,NUMBER_T(I)=145/NUMBER_P(I)=28
                2                   - счетчик событий
                DEMO::EVT_BUILDER   - имя объекта
                ERROR               - состояние объекта
                -                   - имя текущей выполняемой акции (если BUSY) или - (если не BUSY)
                RECOVER...          - список доступных в данном состоянии акций (действий), разделенный знаком |
                NUMBER_T(I)=145/... - список параметров объекта, разделенных символом /
                                      int:    NUMBER(I)=123
                                      float:  VOLTAGE(F)=220.1
                                      string: TITLE(S)="Demo"

    ---
    @smiui_smi_message_handler      - извещение о поступлении системного сообщения от сервера SMI
        например:
        < @smiui_smi_message_handler=1,DEMO,SMI INFO DEMO, State Manager started
                1                   - счетчик событий
                DEMO                - имя домена
                SMI INFO ...        - текст сообщения от сервера SMI домена DEMO

    ---
    @smiui_user_message_handler     - извещение о поступлении пользовательского сообщения, SML инструкция REPORT(..)
        например:
        < @smiui_user_message_handler=2,DEMO,SMI INFO DEMO::AUTO_PILOT, doing ACTIVATE
                2                   - счетчик событий
                DEMO                - имя домена
                SMI INFO ...        - текст сообщения REPORT(INFO,"doing ACTIVATE") от объекта DEMO::AUTO_PILOT
    
    ---
    @smiui_objectsetchange_handler  - извещение о событии изменения набора объектов (objectset)
        например:
        < @smiui_objectsetchange_handler=1,DEMO::LOW_SET,DEMO::LOGGER|DEMO::EVT_BUILDER
                1                   - счетчик событий
                DEMO::LOW_SET       - имя набора объектов
                DEMO::LOGGER|..     - список объектов в наборе, разделенный знаком |
    
    ---
    @smiui_errors                   - чтение счетчика ошибок SMIUISRV
        например:
        > @smiuisrv_send @smiui_errors
        < @smiui_errors=0
    
    ---
    @smiui_report                   - извещение от SMIUISRV об обнаруженных ошибках выполнения
        например:
        < @smiui_report=ERROR: Could not init domain DEMO
  



procedure ClearSmiuiSrv;
procedure InitSmiuiSrv;
procedure FreeSmiuiSrv;
procedure PollSmiuiSrv;
Стандартные процедуры очистки/инициализации/завершения/опроса модуля SmiuiSrv. Они должны вызываться так, как показано в шаблоне.


Желаю успешного использования SmiuiSrv!