SmiProxy для CRW-DAQ


В начале ознакомьтесь с обзором технологии SMI, без которой назначение SmiProxy будет непонятным.

SmiProxy - это интегрированные в пакет CRW-DAQ средства для создания прокси объектов SMI средствами пакета CRW-DAQ на языке DaqPascal. Это очень важный компонент, потому что именно он отвечает за связь SMI/FSM с реальной аппаратурой. Интеграция в пакет CRW-DAQ позволяет создавать логические прокси объекты управления привычными средствами.

Каждый прокси объект SmiProxy выполняется в отдельной прикладной программе DaqPascal и запускает свой экземпляр сервера SmiProxy.exe, через который общается по сети с сервером SMI с помощью библиотеки smirtl.dll. Для создания прикладного кода используется включаемая библиотека SmiProxy, которая берет на себя всю рутину по запуску сервера, приемо-передаче данных и т.д. Прикладному программисту нужно только создать конфигурацию и описать логику работы конечного автомата FSM на DaqPascal.

SmiProxy - включает в себя и использует для работы модуль поддержки Конечных Автоматов FsmManager. При использовании модуля SmiProxy модуль FsmManager включается автоматически, поэтому включать специально его не надо.

Ссылки: Обзор Состав Конфигурация Структура API Сообщения FsmManager


Состав библиотеки SmiProxy


SmiProxy включает в себя (помимо самой библиотеки SMI):


Конфигурация устройств SmiProxy


Здесь приведен пример конфигурации устройства &SmiProxyEvtBuilder:
        [DeviceList]
        &SmiProxyEvtBuilder = device software program
        [&SmiProxyEvtBuilder]
        Comment         = SMI proxy for FiniteStateMachine`s
        InquiryPeriod   = 1
        DevicePolling   = 50, tpNormal
        ProgramSource   = ..\DaqPas\SmiProxyEvtBuilder.pas                  ; Имя прикладной программы
        StartupScript   = [&SmiProxyEvtBuilder.StartupScript]
        FinallyScript   = [&SmiProxyEvtBuilder.FinallyScript]
        OpenConsole     = 2
        DebugFlags      = 3
        ;---------------- SMIPROXY Memory buffers
        StdInFifo       = 32   ; StdIn FIFO buffer size, kB
        StdOutFifo      = 32   ; StdOut FIFO buffer size, kB
        StdInPipeSize   = 32   ; Task StdIn pipe buffer size, kB
        StdOutPipeSize  = 32   ; Tack StdOut pipe buffer size, kB
        ;---------------- SMIPROXY_OBJ = DOMAIN::OBJECT/STATE/PARAMETERS ----
        SMIPROXY_OBJ    = DEMO::EVT_BUILDER/READY/NUMBER_T(I)=1/NUMBER_P(I)=1
        SMIPROXY_DNS    = [&DimSrv] DIM_DNS_NODE %DIM_DNS_NODE% localhost   ; Задание SmiProxy DIM DNS NODE
        SMIPROXY_EXE    = ~~\Resource\DaqSite\SmiServer\SmiProxy.exe        ; Универсальный прокси сервер
        SMIPROXY_SML    = run_con.sml                                       ; Ссылка на файл *.SML с описанием FSM
        SmiTermRepeater = 10, 100                                           ; Repeater & period for smi_terminate_action calls
        RecoveryPeriod  = 10                                                ; Период восстановления для сервера, сек
        SmiDisplayMode  = 0                                                 ; Режим отображения SmiProxy.exe (обычно 0)
        SmiVolatile     = 0                                                 ; Режим времени жизни сервера (обычно 0)
        tagPrefix       = SmiProxyEvtBuilder                                ; Префикс имен тегов (необязательно)
        ;-------------------------------------------------------------------- 
        []
        [&SmiProxyEvtBuilder.StartupScript]                                 ; Здесь можно задать начальные команды
        []

        [TagList]                                                           ; Все теги необязательны!
        SmiProxyEvtBuilder.ObjectName     = string                          ; Имя объекта SMI
        SmiProxyEvtBuilder.ObjectState    = string                          ; Состояние объекта SMI
        SmiProxyEvtBuilder.ObjectDns      = string                          ; Имя DIM DNS
        SmiProxyEvtBuilder.HandlerStage   = integer 0                       ; Стадия обработки: DEAD/IDLE/READ/BUSY/TERM
        SmiProxyEvtBuilder.HandlerCount   = integer 0                       ; Счетчик принятых команд
        SmiProxyEvtBuilder.HandlerAction  = string                          ; Принятая акция   (на стадии BUSY)
        SmiProxyEvtBuilder.HandlerCommand = string                          ; Принятая команда (на стадии BUSY)
        SmiProxyEvtBuilder.HandlerUptime  = real    0                       ; Время с начала текущей стадии обработки
        []
  
При задании SMIPROXY_DNS используется "альтернативное чтение параметров" (ReadIniAlter), которая позволяет считывать переменную из другой секции, переменной окружения или в крайнем случае задавать значение по умолчанию. Здесь сначала делается попытка прочитать переменную [&DimSrv] DIM_DNS_NODE, т.к. обычно в состав распределенных систем входит сервер &DimSrv. Затем делается попытка прочитать переменную окружения %DIM_DNS_NODE%. Если это не удалось, принимается значение по умолчанию localhost.

SMIPROXY_OBJ задает ДОМЕН::ОБЪЕКТ/СОСТОЯНИЕ/ПАРАМЕТРЫ, например:
  формат    SMIPROXY_OBJ = DOMAIN::OBJECT/STATE/PARAMETERS
  например  SMIPROXY_OBJ = DEMO::EVT_BUILDER/READY/PARAM1(S)=ABC/PARAM2(I)=123/PARAM3(F)=1.23
  
Описание содержит имя домена (DEMO), имя объекта (EVT_BUILDER), имя состояния (READY), а далее идут параметры, разделенные символом слеша (/).
Здесь PARAM1,PARAM2,PARAM3 - имена параметров; а строки (S),(I),(F) - описатели типа (string, integer, float).
Задание параметров (если они есть) очень важно, т.к. неописанные параметры приниматься не будут.


Создание прикладных программ с помощью библиотеки SmiProxy


Для создания прикладных программ реализации прокси объектов SMI предпринимаются следующие действия:
  1. На языке SML описывается логика конечного автомата FSM.
    Созданный SML файл нужен также для запуска SMI сервера, так что создавать его все равно придется.
    Например (здесь и далее рассматривается "сборщик событий" EvtBuilder):
    object: EVT_BUILDER /associated
        parameters: int NUMBER_T, int NUMBER_P
        state: DEAD /dead_state                 !color: DarkGray
        state: READY                            !color: Aqua
            action: START(TYPE, int NR)
        state: RUNNING                          !color: Lime
            action: STOP
        state: ERROR                            !color: Red
            action: RECOVER
              
    Цикл разработки FSM в CRW-DAQ.
    Обратите внимание: цвета состояний объектов можно задавать в SML файле (через !color:).

  2. Создается DAQ конфигурация, где описываются параметры устройства.

  3. Включается библиотека SmiProxy:
            program SmiProxyEvtBuilder;
            const
             {------------------------------}{ Declare uses program constants:  }
             {$I _con_StdLibrary}            { Include all Standard constants,  }
             {------------------------------}{ And add User defined constants:  }
            
             {$I _con_SmiProxy}              { Include SMI Proxy    constants   }
            
            var
             {------------------------------}{ Declare uses program variables:  }
             {$I _var_StdLibrary}            { Include all Standard variables,  }
             {------------------------------}{ And add User defined variables:  }
            
             {$I _var_SmiProxy}              { Include SMI Proxy    variables   }
            
            .................                { User defined         variables   }
    
             {------------------------------}{ Declare procedures & functions:  }
             {$I _fun_StdLibrary}            { Include all Standard functions,  }
             {------------------------------}{ And add User defined functions:  }
            
             {$I _fun_SmiProxy}              { Include SMI Proxy    functions   }
            
            ...
           


  4. Создается прикладная процедура SmiProxyLogic с описанием логики конечного автомата:
             //
             // SMI Proxy Logic.
             //
             procedure SmiProxyLogic;
             var complete:Boolean; typ:String; nr:Integer;
             begin
              typ:='';
              //
              // SMI Proxy BUSY operations.
              // SMI actions handler there.
              //
              if smi_proxy_handler_busy then begin
               complete:=false;
               if smi_test_action('START') then begin
                complete:=true;
                if complete then begin
                 KickTime:=mSecNow; // Set marker of START to generate ERROR later for demo
                 typ:=smi_proxy_handler_params_value_byname('TYPE');
                 nr:=Val(smi_proxy_handler_params_value_byname('NR'));
                 if IsSameText(typ,'PHYSICS') then smi_set_par('NUMBER_P',Str(nr+1),SMI_INTEGER);
                 if IsSameText(typ,'TEST') then smi_set_par('NUMBER_T',Str(nr+1),SMI_INTEGER);
                 smi_terminate_action('RUNNING');
                end;
               end else
               if smi_test_action('STOP') then begin
                complete:=(smi_proxy_handler_uptime>1500);
                if complete then begin
                 KickTime:=0; // Reset marker
                 smi_terminate_action('READY');
                end;
               end else
               if smi_test_action('RECOVER') then begin
                complete:=(smi_proxy_handler_uptime>1500);
                if complete then begin
                 KickTime:=0; // Reset marker
                 smi_terminate_action('READY');
                end;
               end else
               begin // Unknown action came
                KickTime:=0; // Reset marker
                smi_terminate_action('ERROR');
                Problem('Unknown action came: '+smi_proxy_handler_action);
               end;
              end else
              //
              // SMI Proxy IDLE operations.
              // Do when actions completed.
              //
              if smi_proxy_handler_idle then begin
               if msElapsedSinceMarker(KickTime)>7000 then begin
                smi_set_state('ERROR');
                KickTime:=0;
               end;
              end;
              typ:='';
             end;
           
    При создании процедуры рекомендуется использовать ранее созданный файл *.SML, который транслируется в код на языке C с помощью программы smiTrans.exe. Этот код довольно легко переводится в код DaqPascal (имена основных процедур одинаковы).

    Обработка команд SMI осуществляется в блоке smi_proxy_handler_busy, что означает наличие принятой и необработанной команды.
    С помощью функции smi_test_action выясняется, какая команда поступила и какое действие надо предпринять.
    Далее выполняется содержательная работа по выполнению принятой команды.
    Когда работа завершена, вызывается функция smi_terminate_action, которая завершает обработку команды и устанавливает новое состояние объекта.

    Обработка фоновых событий, не связанных напрямую с SMI, осуществляется в блоке smi_proxy_handler_idle, что означает отсутствие необработанных команд.

  5. В стандартных местах добавляется вызов процедур очистки ClearSmiProxy, инициализации InitSmiProxy, завершения FreeSmiProxy, опроса PollSmiProxy и созданной на предыдущем шаге процедуры прикладной логики PollSmiLogic:
             {
             Clear user application strings...
             }
             procedure ClearApplication;
             begin
            
              ClearSmiProxy;
            
             end;
             {
             User application Initialization...
             }
             procedure InitApplication;
             begin
              StdIn_SetScripts('@StartupScript','@FinallyScript');
              StdIn_SetTimeouts(0,60000,0,3000);
              iNul(ClickFilter(ClickFilter(1)));
              iNul(ClickAwaker(ClickAwaker(1)));
            
              InitSmiProxy;
            
              KickTime:=0;
             end;
             {
             User application Finalization...
             }
             procedure FreeApplication;
             begin
            
              FreeSmiProxy;
            
             end;
             {
             User application Polling...
             }
             procedure PollApplication;
             begin
            
              PollSmiProxy;
              SmiProxyLogic;
            
             end;
           


  6. В обработчик консольных команд добавляется вызов smi_proxy_default_handler:
             {
             Process data coming from standard input...
             }
             procedure StdIn_Processor(var Data:String);
             var cmd,arg:String; cmdid:Integer;
             begin
              if DebugFlagEnabled(dfViewImp) then ViewImp('CON: '+Data);
              {
              Handle "@cmd=arg" or "@cmd arg" commands:
              }
              cmd:='';
              arg:='';
              if GotCommandId(Data,cmd,arg,cmdid) then begin
            
               {
               !!! Handle SMI Proxy by default handler !!!
               !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
               }
               if smi_proxy_default_handler(Data,cmd,arg,cmdid) then begin
                Success(smi_proxy_prompt+Data);
                Data:='';
               end else
            
               {
               Handle other commands by default handler...
               }
               StdIn_DefaultHandler(Data,cmd,arg);
              end;
              Data:='';
              cmd:='';
              arg:='';
             end;
            





Программный интерфейс SmiProxy API


Для использования библиотеки её надо включить в программу.

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

В целом библиотека работает так. При старте она считывает параметры прокси объекта из файла конфигурации и запускает задачу (task) - сервер SmiProxy.exe. В цикле обработки событий библиотека следит за тем, чтобы задача работала и перезапускает её при необходимости. Библиотека также организует обмен данными с сервером (внутренний протокол) и с консолью (внешний протокол). Также надо заметить, что библиотека имеет сторожевой таймер, который автоматически перезапускает сервер SmiProxy.exe, если он долгое время не отвечает.

Обработчик событий (handler) циклически опрашивается и обычно находится в стадии (smi_proxy_handler_stage) ожидания команд от сервера для обработки IDLE (smi_proxy_handler_idle). При поступлении команд от SMI обработчик переходит в стадию чтения параметров READ, а затем обработки принятой команды - BUSY. На этой стадии (smi_proxy_handler_busy) прикладной код должен определить (smi_test_action) и обработать поступившую команду, а затем вызвать функцию завершения обработки (smi_terminate_action), которая переводит обработчик в стадию TERM. После получения подтверждения завершения обработки от сервера обработчик возвращается в стадию IDLE.
Это можно изобразить в виде такой диаграммы состояний:
Алгоритм (конечный автомат) работы SmiProxy.

smi_proxy_stage_dead
smi_proxy_stage_idle
smi_proxy_stage_read
smi_proxy_stage_busy
smi_proxy_stage_term
Прикладные константы, обозначающие состояния цикла обработки - DEAD, IDLE, READ, BUSY, TERM.

smi_string, smi_integer, smi_float
Прикладные константы, обозначающие типы данных в параметрах команд SMI.

smi_proxy_tab
Служебная запись, содержащая все необходимые данные библиотеки SmiProxy. Настоятельно рекомендуется не трогать её в прикладном коде.

function smi_proxy_fsm:Integer;
function smi_proxy_dom:Integer;
function smi_proxy_obj:Integer;
function smi_proxy_state:Integer;
function smi_proxy_state_name:String;
function smi_proxy_state_color:Integer;
Прикладная функция, возвращает экземпляр менеджера состояний (fsm), домен (dom), прокси объкт (obj), его текущее состояние (state), имя состояния (state_name) и цвет (state_color). Эти параметры (домен и объект) задаются в файле конфигурации (параметр SMIPROXY_OBJ).

function smi_proxy_prompt:String;
Прикладная функция, возвращает приглашение (промпт) вида "SMI => ", которое маркирует сообщения от сервера SmiProxy.exe. Используется для вывода консольных сообщений.

function smi_extract_state(line:String):String;
function smi_extract_action(line:String):String;
Прикладная функция, извлекает состояние (state) или действие (action) из строки (line) вида STATE/PARAMS или ACTION/PARAMS. Данные о состоянии/действии могут приходить в виде ACTION/PARAM1(S)=ABC/PARAM2(I)=123/PARAM3(F)=1.23. Первое слово - имя состояния или действия, далее идут параметры, разделенные символом слеша (/).

function smi_to_fsm_type(typ:Integer):Integer;
function smi_to_tag_type(typ:Integer):Integer;
Служебная функция, преобразует идентификатор типа SMI (0/1/2=STRING/INTEGER/FLOAT) в тип FSM (1/2/3=INTEGER/FLOAT/STRING) или в тип тегов CRW (1/2/3=INTEGER/REAL/STRING).

function smi_proxy_task_exefile:String;
function smi_proxy_task_smlfile:String;
function smi_proxy_task_cmdline:String;
function smi_proxy_task_pid:Integer;
function smi_proxy_task_running:Boolean;
Прикладная функция, возвращает для текущего серверного процесса (task) имя исполняемого EXE файла (exefile), имя SML файла с описанием конечного автомата (smlfile), командную строку для запуска сервера SmiProxy.exe (cmdline), идентификатор процесса (pid), а также статус работы (running).

function smi_proxy_object_name:String;
function smi_proxy_domain_name:String;
function smi_proxy_dns_node:String;
function smi_proxy_volatile:Integer;
Прикладные функции чтения актуального значения состояния (state), имени объекта (object) и домена (domain), имени DNS NODE, режима volatile. Актуальным считается значение, прочитанное из потока вывода SmiProxy.exe.

procedure smi_proxy_state_name_put(state:String);
procedure smi_proxy_object_name_put(name:String);
procedure smi_proxy_dns_node_put(dns:String);
procedure smi_proxy_volatile_put(volatile:Integer);
procedure smi_proxy_handler_stage_put(stage:Integer);
procedure smi_proxy_handler_params_clear(n:Integer);
procedure smi_proxy_handler_count_put(count:Integer);
procedure smi_proxy_handler_action_put(action:String);
procedure smi_proxy_handler_command_put(command:String);
function smi_translate_state_command(WantedCommand,s:String):String;
Служебные процедуры и функции для задания параметров, которые не надо вызывать в прикладном коде, чтобы не нарушать логику программы.

function smi_proxy_handler_stage:Integer;
function smi_proxy_handler_dead:Boolean;
function smi_proxy_handler_idle:Boolean;
function smi_proxy_handler_read:Boolean;
function smi_proxy_handler_busy:Boolean;
function smi_proxy_handler_term:Boolean;
Чтение значения стадии цикла обработки команд SmiProxy, которая может принимать значения:
  1. DEAD - сервер умер (процесс SmiProxy.exe остановлен).
  2. IDLE - ничего не происходит, нет команд для обработки.
  3. READ - идет чтение параметров поступившей команды.
  4. BUSY - команда принята, прикладной код должен её обработать.
  5. TERM - послана команда завершения обработки, ожидается подтверждение.


function smi_proxy_handler_count:Integer;
Прикладная функция - счетчик поступивших для обработки команд SMI.

function smi_proxy_handler_uptime:Real;
Прикладная функция - время (мс), прошедшее с последней смены стадии цикла обработки команд. То есть время, в течение которого цикл обработки (все ещё) находится в текущей стадии.

function smi_proxy_handler_action:String;
function smi_proxy_handler_command:String;
Прикладная функция - поступившая для обработки акция или действие (action) и команда (command). Акция - это слово (например, RESET), а команда - это акция со списком параметров (например, RESET/LOAD(I)=1/VOLT(F)=1.0). Если параметров нет, акция и команда совпадают.

function smi_proxy_handler_params_count:Integer;
function smi_proxy_handler_params_name(index:Integer):String;
function smi_proxy_handler_params_type(index:Integer):Integer;
function smi_proxy_handler_params_value(index:Integer):String;
function smi_proxy_handler_params_index(name:String):Integer;
function smi_proxy_handler_params_type_byname(name:String):Integer;
function smi_proxy_handler_params_value_byname(name:String):String;
Прикладные функции для чтения принятых параметров текущей обрабатываемой команды SMI. Вызывается в цикле BUSY для чтения аргументов команды. Число параметров команды равно count. По индексу (0..count-1) можно узнать имя (name), тип (type) и значение (value) параметра. Если имена параметров заранее известны, их тип и значение можно извлечь по имени (byname). Возвращаемое значение типа (type) приводится к значениям, принятым в CRW-DAQ, т.е. 1/2/3=INTEGER/REAL/STRING. Это сделано для того, чтобы было легче работать с тегами.

function smi_proxy_find_state_color(objectname,state:String; def:Integer):Integer;
Прикладная функция, возвращает прочитанный из SML файла цвет для указанного объекта (objectname) и состояния (state). Если цвет не найден, возвращает def.

procedure smi_set_state(state:String);
Прикладная функция для задания нового состояния логического объекта SMI. Вызывается в цикле IDLE при изменении состояния управляемого объекта. Состояние передается в формате 'STATE/PARAMETERS', например, 'RUN/TYPE(S)=TEST/NUMBER(I)=123'. Имя (state) извлекается автоматически вызовом smi_extract_state(...). При задании пустого состояния (state='') заменяет его текущим состоянием (smi_proxy_state_name), поэтому вызовы smi_set_state('') и smi_set_state(smi_proxy_state_name) эквивалентны. При задании других состояний проверяет существование (state) в списке состояний объекта. Если такого состояния нет, фиксирует ошибку и заменяет (state) текущим состоянием (smi_proxy_state_name). Это связано с тем, что при задании несуществующего состояния FSM переходит в состояние &UNDEFINED_STATE и поле этого машина не реагирует на команды (застревает в этом состоянии). Проверка состояния позволяет избежать этого.

procedure smi_set_par(par,value:String; typ:Integer);
Прикладная функция для задания параметру логического объекта с именем par нового значения value типа typ. Тип может иметь значения (SMI_STRING, SMI_INTEGER, SMI_FLOAT). Вызывается в цикле BUSY для задания параметров объекта.

procedure smi_terminate_action(state:String);
procedure smi_move_to(state:String);
Прикладная функция для завершения обработки поступившей акции (команды) и задания нового состояния логического объекта SMI. Обычно вызывается в цикле BUSY для завершения обработки текущей команды. Состояние передается в формате 'STATE/PARAMETERS', например, 'RUN/TYPE(S)=TEST/NUMBER(I)=123'. Имя (state) извлекается автоматически вызовом smi_extract_state(...). При задании пустого состояния (state='') заменяет его текущим состоянием (smi_proxy_state_name), поэтому вызовы smi_terminate_action('') и smi_terminate_action(smi_proxy_state_name) эквивалентны. При задании других состояний проверяет существование (state) в списке состояний объекта. Если такого состояния нет, фиксирует ошибку и заменяет (state) текущим состоянием (smi_proxy_state_name). Это связано с тем, что при задании несуществующего состояния FSM переходит в состояние &UNDEFINED_STATE и поле этого машина не реагирует на команды (застревает в этом состоянии). Проверка состояния позволяет избежать этого.
Функция smi_move_to является синонимом smi_terminate_action.

function smi_test_action(action:String):Boolean;
Прикладная функция для проверки того что была принята указанная в аргументе акция. Вызывается в цикле BUSY для организации обработки команд.

function smi_test_state(state:String):Boolean;
Прикладная функция для проверки того что текущее состояние объекта имеет указанное в аргументе имя. Вызывается в цикле опроса для организации обработки состояний.

procedure smi_proxy_task_send(msg:String);
Служебная функция для посылки сообщения серверу SmiProxy.exe. Обычно её нет нужды вызывать, но при необходимости её можно использовать. Например, вызов smi_proxy_task_send('@Exit'); остановит (и через некоторое время перезапустит) сервер.

procedure smi_proxy_task_processing(var Data:String);
procedure smi_proxy_become_dead;
procedure smi_proxy_task_stop(exitcode:Integer);
procedure smi_proxy_task_start;
procedure smi_proxy_task_poll;
procedure smi_proxy_watchdog_poll;
procedure smi_proxy_clear_all;
procedure smi_proxy_initialize;
procedure smi_proxy_finalize;
Служебные процедуры. Не вызывайте их в прикладном коде.

function smi_proxy_default_handler(var Data,cmd,arg:String; cmdid:Integer):Boolean;
Прикладная функция для обработки событий консоли.
Она обязательно должна быть включена в консольный обработчик, иначе программа работать не будет.

procedure ClearSmiProxy;
procedure InitSmiProxy;
procedure FreeSmiProxy;
procedure PollSmiProxy;
Прикладные процедуры. Обязательно включите их в стандартных местах.


Сообщения SmiProxy


Для своей работы SmiProxy использует сообщения, большинство из которых используются для служебных целей. Только некоторые сообщения предназначены для прикладного программирования. Кроме того, ряд сообщений служит для внутренних целей. Эти внутренние сообщения передаются между клиентской программой и сервером SmiProxy.exe и не видны на прикладном уровне. Имена некоторых сообщений совпадают с именами функций, и это не случайно - эти сообщения, собственно, и инициируют работу одноименных функций на стороне сервера.

@Exit=n - внутреннее сообщение серверу для выхода с кодом n.

@Memory=n - внутреннее сообщение серверу для проверки использования памяти.

@Errors=n - внутреннее сообщение серверу для проверки счетчика ошибок канала связи.

@ProcessPriority=p - внутреннее сообщение серверу для задания приоритета процесса (4,6,8,10,13,24).

@ThreadPriority=p - внутреннее сообщение серверу для задания приоритета потока (tpIdle,tpLowest,tpLower,tpNormal,tpHigher,tpHighest,tpRealtime).

@OnException=msg - внутреннее сообщение сервера при возбуждении исключения.

@smi_attach=obj - служебное сообщение серверу для подключения к объекту (obj).

@smi_volatile=n - служебное сообщение серверу для режима времени жизни (завершаться при отключении SMI сервера).

@smi_get_state - служебное сообщение серверу для чтения состояния объекта.

@smi_set_state=s - служебное сообщение серверу для задания состояния объекта (s).

@smi_set_par=p,t,v - служебное сообщение серверу для задания параметра (p) тира (t) значения (v).

@smi_proxy_handler=s - внутреннее сообщение сервера для начала/завершения чтения (s=BEGIN/END).

@smi_get_action=a - внутреннее сообщение сервера для передачи текущей акции (a).

@smi_get_command=c - внутреннее сообщение сервера для передачи текущей команды (c).

@smi_get_next_par=p,t,s - внутреннее сообщение сервера для передачи имени (p) типа (t) и размера (s) параметра.

@smi_get_par_value=p,t,v - внутреннее сообщение сервера для передачи имени (p) типа (t) и значения (v) параметра.

@dim_dns_node=n - служебное сообщение серверу для задания DNS.

@smi_terminate_action=state - служебное сообщение серверу для завершения обработки текущей команды и задания состояния (state).

@smi_errors=n - служебное сообщение серверу для чтения счетчика ошибок SMI.

@smi_report=msg - внутренне сообщение сервера с отчетом (обычно об ошибке).

@smi_restart n - прикладное сообщения для перезапуска сервера SmiProxy.exe с кодом выхода n.

@smi_repost s - прикладное сообщения для посылки сообщения @smi_terminate_action=s с состоянием s. Если состояние не указано, берется текущее состояние объекта (отсюда и название repost).

@smi_proxy cmd - прикладное сообщение, которое посылает серверу служебную команду (cmd).
Например: @smi_proxy @smi_set_state READY

Команда @smi_proxy дает доступ к внутреннему протоколу сервера SmiProxy.exe. Это дает большие возможности (в основном для отладки), которыми не стоит злоупотреблять.
В прикладном коде настоятельно рекомендуется использовать только функции SmiProxy API.


© 2020 Курякин Алексей Валерьевич, kouriakine@mail.ru.