Библиотека StdPyApp (Standard Python Application) служит для поддержки клиент-серверных программ на языке Python со стороны crwdaq. Предполагается, что программа python работает как консольный драйвер (сервер), запускаемый из клиентской программы daqpascal, в которую включается библиотека StdPyApp. Взаимодействие клиента daqpascal и сервера python происходит через анонимный канал, подключенный к потокам stdin, stdout серверной программы. Ввод-вывод происходит асинхронно, без блокировки, поэтому на строне сервера python крутится цикл опроса, который принимает от клиента daqpascal команды и данные, а в ответ передает другие команды и данные. В качестве протокола обычно используется формат команд DaqScript, кратко описанный ниже.
Клиентская библиотека StdPyApp содержит включаемые файлы:
которые надо включить в прикладную программу, как описано далее.
См. также пример demo_pycon.
Python является популярным языком программирования и имеет много преимуществ: наличие большого числа библиотек, сообщество, хорошая документация. Иметь его в своем арсенале полезно.
В пакете crwdaq есть средства поддержки python, рассчитанные на автономную (без подключения Internet) установку, т.к. в закрытых корпоративных сетях другой возможности просто нет.
Пакет daqgroup-pylibs - это набор библиотек python для автономной установки в режиме offline, а также набор средств для их инсталляции и использования. Состав библиотек связан с текущими потребностями и может быть расширен по мере необходимости.
Для установки под Windows есть инсталлятор install-daqgroup-engines.exe, в который входит как сам python, так и библиотеки pylibs. Его надо просто запустить и установить пакеты.
Для установки под Linux есть инсталлятор install-daqgroup-pylibs.run, который устанавливает библиотеки pylibs. Сам python устанавливать не надо, он уже (обычно) есть в системе. Также для работы библиотек python потребуется установить crwkit, т.к. он будет нужен для запуска программ на python.
Установка библиотеки pylibs идет в каталог /opt/daqgroup/share/pylibs.
В библиотеки pylibs входит модуль python под названием pycrwkit. Это библиотека на языке python для поддержки приложений DaqApplication, включая асинхронный ввод-вывод, поддержку команд формата DaqScript и т.д. Она написана А.К. специально для работы в составе пакета crwdaq. Краткое описание модуля см. readme.html. Для примера использования модуля pycrwkit см. демонстрационную программу demoapp.py.
Программы python из соображений безопасности устанавливаются и выполняются в так называемой виртуальной среде окружения (virtual environment), сокращенно venv. Это нужно для того, чтобы избежать конфликта версий и повреждения системы при установке библиотек python. То есть библиотеки устанавливаются не в системный каталог python, а в отдельную папку, а запускаются с помощью специальной утилиты, создающей при запуске свою среду окружения.
Для запуска программ python в виртуальной среде
окружения, нужной для библиотек pylibs, создана утилита
unix pyvenv, входящая в состав пакета
crwkit. Запуск программ выполняется как
unix pyvenv /path/demoapp.py # запуск сценария demoapp.py из папки /path/При ином способе запуска программы работать не будут, т.к. не найдут нужных библиотек.
Библиотеку StdPyApp можно использовать в любой программе DaqPascal, выполенной по шаблону. Надо лишь правильно включить её в программу.
Библиотеку StdPyApp включают примерно так:
program xxxx;
const
{------------------------------}{ Declare uses program constants: }
{$I _con_StdLibrary} { Include all Standard constants, }
{------------------------------}{ And add User defined constants: }
{$I _con_StdPyApp} { <-- Standard Python Application }
...
var
{------------------------------}{ Declare uses program variables: }
{$I _var_StdLibrary} { Include all Standard variables, }
{------------------------------}{ And add User defined variables: }
{$I _var_StdPyApp} { <-- Standard Python Application }
...
{------------------------------}{ Declare procedures & functions: }
{$I _fun_StdLibrary} { Include all Standard functions, }
{------------------------------}{ And add User defined functions: }
{$I _fun_StdPyApp} { <-- Standard Python Application }
...
{
Clear user application strings...
}
procedure ClearApplication;
begin
ClearStdPyApp;
...
end;
...
{
User application Finalization...
}
procedure FreeApplication;
begin
...
FreeStdPyApp;
end;
...
{
User application Polling...
}
procedure PollApplication;
begin
...
PollStdPyApp;
end;
...
{
Process data coming from standard input...
}
procedure StdIn_Processor(var Data:String);
var cmd,arg:String; cmdid:Integer;
procedure Cleanup;
begin
cmd:=''; arg:='';
end;
begin
Cleanup;
ViewImp('CON: '+Data);
{
User PyApp Hook
}
if StdPyApp_UserHookStdIn(Data) then begin
Data:=''; // Data was hooked and handled
end else
{
Handle "@cmd=arg" or "@cmd arg" commands:
}
if GotCommandId(Data,cmd,arg,cmdid) then begin
...
...
{
Default PyApp Hook to handle:
@PyApp Start
@PyAsk @PollCount
@PyAns @PollCount 123
@PyInf Started ...
}
if StdPyApp_DefaultHookStdIn(Data) then begin
Data:=''; // Data was hooked and handled
end else
{
Handle other commands by default handler...
}
StdIn_DefaultHandler(Data,cmd,arg);
end;
Data:='';
Cleanup;
end;Здесь все функции, кроме StdPyApp_UserHookStdIn, являются библиотечными и просто используются в готовом виде. Функция StdPyApp_UserHookStdIn пишется (если надо) для перехвата (Hook) команд PyApp, с целью их особой (специфической для конкретного приложения) обработки перед выполнением стандартной обработки команд.
На библиотеку StdPyApp можно смотреть как на “черный ящик”, взаимодействие с которым происхлодит путем посылки в консоль сообщений и обработки поступающих ответных команд. Команд немного, и они несложные.
Взаимодействия с исполнительной системой StdPyApp происходит с помощью слдующих команд:
############### команды взаимодействия с исполнительной системой StdPyApp
< @PyApp a # команда управления состоянием PyApp с передачей аргумента a
> @PyAsk m # команда пересылки сообщения m в консоль stdin сервера PyApp
> @PyAns m # ответная строка сообщения m из консоли stdout сервера PyApp
> @PyInf m # информационное сообщение от StdPyApp на изменение состояния
############### здесь < - посылка в консоль, > - обработка сообщенийВот, собственно, и все команды StdPyApp. Дальше начинаются детали.
############################################# управление сервером
< @PyApp Start # запуск сервера, т.е. программы python
< @PyApp Stop # останов сервера, т.е. программы python
< @PyApp Status # печатает статус (состояние) сервера
< @PyApp Set Launch unix pyvenv # задает команду запуска сценария
< @PyApp Set Script ..\daqpas\demo_pycon.py # задает имя файла сценария
< @PyApp Set Params # задает параметры сценария
< @PyApp Set PingCall @PollCount # задает команду Ping
< @PyApp Set AutoStart 1 # разрешить АвтоЗапуск
< @PyApp Set PipeSizeKb 64 # размер буфера канала, КБ
< @PyApp Set PreferToSend 0 # 0:devPost, 1:devSend
< @PyApp Set TimeOutToSend 100 # таймаут для посылки данных, ms
< @PyApp Set TimeOutToStop 1000 # таймаут на остановку задач, ms
< @PyApp Set GuardTimerPeriod 1000 # период проверки АвтоЗапуска
< @PyApp Set PingTimerPeriod 1000 # таймер для посылки Ping
< @PyApp Set CalcPing 1 # флаг: нужен расчет Ping
############################################# посылка сообщений
< @PyAsk @PollCount # посылка @PollCount в консоль сервера
> @PyAns @PollCount 123 # ответ сервера с запрошенными данными
############################################# уведомления от сервера
> @PyInf Started PID 234 # уведомление о старте сервера
> @PyInf Stopped PID 234 CODE 1 # уведомление об остановке сервераС помощью этого нехитрого набора команд можно достаточно гибко управлять сервером PyApp. Обратите внимание, что команды самой программы python вложены в команды @PyAsk, PyAns. Это позволяет использовать неограниченное число команд сервера, имея всего 4 команды-обёртки @PyApp, @PyAsk, PyAns, @PyInf.
Обратите также внимание, что ответные команды от сервер (от программы python) можно перехватывать и обрабатывать по-своему. Для этого команды перехватываются в самом начале обработки команд функцией StdPyApp_UserHookStdIn. Для стандарной обработки используется перехват команд библиотечной функцией StdPyApp_DefaultHookStdIn непосредственно перед вызовом стандартного обработчика.
Таким образом, перехват команд позволяет очень гибко управлять реакцией на команды, поступающие от сервера.
Ниже приведен пример пользовательской функции перехвата, которая перехватывает только команды @PyAns, @PyInf и обрабатывает их, пропуская другие команды. Для уведомления о перехвате функция возвращает True, что означает, что команда была обработана и уже не требует дальнешей обработки.
{
StdPyApp - User specific Hook for StdIn commands.
Handle only @PyAns, @PyInf for Application specific stuff.
}
function StdPyApp_UserHookStdIn(var Data:String):Boolean;
var cmd,arg:String; cmdid:Integer; Hook:Boolean; ts,tm,si,co:Real;
begin
cmd:=''; arg:='';
Hook:=False; cmdid:=0;
if GotCommandId(Data,cmd,arg,cmdid) then begin
if (cmdid=cmd_Std_PyAns) then begin
if IsSameText(ExtractWord(1,arg),'@Para') then begin
Success(arg);
Hook:=True;
end;
if IsSameText(ExtractWord(1,arg),'@Wave') then begin
ts:=rVal(ExtractWord(2,arg));
si:=rVal(ExtractWord(3,arg));
co:=rVal(ExtractWord(4,arg));
tm:=1e3*ts/timeunits;
UpdateAo(0,tm,si);
UpdateAo(1,tm,co);
Hook:=True;
end;
end else
if (cmdid=cmd_Std_PyInf) then begin
// On (started,stopped) show tooltip
// After start send parameters to server
if WordIndex(ExtractWord(1,arg),'Started,Stopped')>0 then begin
if IsSameText(ExtractWord(1,arg),'Started') then begin
SendParaToPyApp(True);
end;
ShowTooltip('text "PyApp: '+arg+'" preset stdNotify delay 15000');
Success('PyApp: '+arg);
Hook:=True;
end;
end;
end;
StdPyApp_UserHookStdIn:=Hook;
cmd:=''; arg:='';
end;Использование команд @PyApp, @PyAsk,
@PyAns, PyInf
позволяет довольно просто работать с сервером, не влезая в детали
реализации и API. Однако следует иметь в виду, что
ценой этого упрощения является некоторое снижение производительности,
т.к. данные передаются не сразу в консоль сервера, а проходят цикл
обработки через консоль DAQ-устройства. Если
производительности не хватает, надо использовать функции
API. В случае проблем с производительностью можно,
например, вместо посылки @PyAsk data
непосредственно вызывать процедуру
StdPyApp_Send(data).
Описание API библиотеки StdPyApp здесь не рассматривается, т.к. есть исходники - можно разобраться. Без особых причин (если нет серьезных проблем с производительностью) лучше ограничиться использованием команд @PyApp, @PyAsk, @PyAns, PyInf.
В пакете crwdaq обычно используются команды в формате DaqScript. Этот формат используется и в библиотеке StdPyApp.
@ является признаком команды.
Он должен быть (строго) первым символом строки.@ идет
идентификатор команды, затем (если необходимо)
пробел и строка данных.@Exit # команда без параметров
@Exit 1 # команда с одним параметром
@PyAns Set AutoStart 1 # команда с рядом параметров
@PyAsk @Exit 1 # команда вложенная в команду
@Data 43AFF0DC456 # команда с данными в HEXЗдесь нет возможности изложить курс программирования на python, поэтому очень кратко.
Желаем приятного использования библиотеки StdPyApp.
CRW-DAQ Copyright (c) 2001-2025 Alexey Kuryakin daqgroup@mail.ru