# UserFuncLibs

ID: techApp
NAME: Technological devices
DB: techApp
uk#NAME: Технологічні апарати
ru#NAME: Технологические аппараты
DESCR:
The models of the technological process devices.

Founded: october 2005
Author: Roman Savochenko
Version: 0.9.0
License: GPL

uk#DESCR:
Моделі апаратів технологічних процесів.

Засновано: жовтень 2005р
Автор: Роман Савоченко
Версія: 0.9.0
Ліцензія: GPL

ru#DESCR:
Модели аппаратов технологических процессов.

Основан: октябрь 2005г
Автор: Роман Савоченко
Версия: 0.9.0
Лицензия: GPL


ID: doc
NAME: Report's documents
DB: flb_doc
uk#NAME: Звітна документація
ru#NAME: Отчётная документация
DESCR:
Library of functions to facilitate the implementation of typical computations the primitive form of reporting documentation VCA "Document".

Founded: January 2008
Author: Roman Savochenko
Version: 0.5.0
License: GPL

uk#DESCR:
Бібліотека функцій для полегшення виконання типових обчислень примітиву формування звітної документації СВК "Документ".

Засновано: січень 2008р
Автор: Роман Савоченко
Версія: 0.5.0
Ліцензія: GPL

ru#DESCR:
Библиотека функций для облегчения выполнения типовых
вычислений примитива формирования отчётной документации
СВУ "Документ".

Основан: январь 2008г
Автор: Роман Савоченко
Версия: 0.5.0
Лицензия: GPL


# UserProtocol_uPrt

ID: SMS
OutPROG:
JavaLikeCalc.JavaScript
// Process SEND SMS message
// <name> - "send"
// pin - SIM card PIN-cod
// tel - recipient telephone number
// <text> - message
if(io.name()=="send")
{
	//> Prepare PDU
	var pdu = "001100";	//SMS center number (default) + SMS-Submit
	//> Telephone number encode
	var tel = io.attr("tel");
	if(!tel.length || tel[0] != "+") { io.setAttr("err","100:Telephone number error."); return; }
	tel = tel.slice(1);
	pdu += tel.length.toString(16,2)+"91";	//Telephone length and type
	while(tel.length < 12) tel += "F";
	for(i=0; i < 6; i++) pdu += tel[i*2+1]+tel[i*2];
	//> Message encode
	var text = SYS.strCodeConv(io.text(),"","UCS2");
	if((text.length/2) > 70) { io.setAttr("err","101:Long length ("+(text.length/2)+") of the message."); return; }
	pdu += "0018C1"+(text.length).toString(16,2);
	for(i=0; i < text.length/2; i++) pdu += text.charCodeAt(i*2+1).toString(16,2)+text.charCodeAt(i*2).toString(16,2);
	//SYS.messDebug("TEST SMS","PDU :"+pdu);
	//> Send request
	if(!io.attr("pin").isEVal())
	{
		var rez = tr.messIO("AT+CPIN="+io.attr("pin")+"\r");
		if(rez.search("OK\r") < 0)	{ io.setAttr("err","10:Error set PIN-code."); return; }
	}
	//>> Switch to PDU SMS mode
	var rez = tr.messIO("AT+CMGF=0\r");
	if(rez.search("OK\r") < 0)	{ io.setAttr("err","10:Error set PDU mode."); return; }
	//>> Send PDU message
	var rez = tr.messIO("AT+CMGS="+(pdu.length/2-1)+"\r");
	if(rez.search(">") < 0)	{ io.setAttr("err","10:Error sent SMS."); return; }
	var rez = tr.messIO(pdu+"\x1A");
	for(var i_tr = 0; i_tr < 5 && rez.search("OK\r") < 0; i_tr++) rez += tr.messIO("");
	if(rez.search("OK\r") < 0)	{ io.setAttr("err","10:Error sent SMS PDU"); return; }
	io.setAttr("err","0");
	//SYS.messDebug("TEST SMS","PDU REZ :"+rez);
}


ID: SCU750
NAME: Cotrol Unit SCU750
DESCR: Transport level protocol realization for EDWARDS TURBOMOLECULAR PUMPS.
InPROG: JavaLikeCalc.JavaScript
OutPROG:
JavaLikeCalc.JavaScript
//Request form:
//<mess addr="1">{req}</mess> - message tag
//  addr - remote station address (<0 - single; >=0 - multy port)

if(io.text().length > 255*255) { io.setAttr("err","1:Message's length more 255*255"); return; }
addr = io.attr("addr").toInt();
k=ceil(io.text().length/255);  //transmission blocks
for(i_k = 1; i_k <= k; i_k++)
{
	request = "\x02"+k.toString(16,3)+io.text().slice((i_k-1)*255,(i_k-1)*255+min(255,io.text().length-(i_k-1)*255))+((k>1&&i_k<k)?"\x17":"\x03");
	//> Calc LRC
	LRC = 0xFF;
	for(i = 0; i < request.length; i++) LRC = LRC^request.charCodeAt(i);
	request += SYS.strFromCharCode(LRC);

	//> Multy port
	if(addr>=0) request = "@"+addr.toString(16,2)+request;
	//SYS.messDebug("PRT","Request: "+Special.FLibSYS.strDec4Bin(request));

	//Send request
	resp = tr.messIO(request);
	while(resp.length)
	{
		tresp = tr.messIO("");
		if(!tresp.length) break;
  		resp += tresp;
	}
	if(!resp.length) { io.setAttr("err","2:No respond"); return; }
	//SYS.messDebug("PRT","Ack: "+Special.FLibSYS.strDec4Bin(resp));
	if(resp.charCodeAt(0) != 6) { io.setAttr("err","3:No acknowledgment"); return; }
	//> Pass included acknowledgement
	resp = resp.slice((addr>=0)?3:1);

	//> Read data blocks
	io.setText("");
	for(i_k = 1; true; i_k++)
	{
		//Send application acknowledgement and wait data
		if(!resp.length)
		{
			request = "\x06";
			if(addr>=0) request += addr.toString(16,2);
			resp = tr.messIO(request);
			while(resp.length)
			{
				tresp = tr.messIO("");
				if(!tresp.length) break;
  				resp += tresp;
			}
			if(!resp.length) { io.setAttr("err","4:No data block get"); return; }
		}
		if(resp.length < ((addr>=0)?10:7) || resp.charCodeAt(0) != 0x40) { io.setAttr("err","5:Data block short or error"); return; }

		//SYS.messDebug("PRT","BLK "+i_k+": "+Special.FLibSYS.strDec4Bin(resp));

		if(addr>=0) resp = resp.slice(3);
		LRC = 0xFF;
		for(i = 0; i < (resp.length-1); i++) LRC = LRC^resp.charCodeAt(i);
		if(LRC != resp.charCodeAt(resp.length-1)) { io.setAttr("err","6:LRC error."); return; }
		if(i_k != resp.slice(1,4).toInt(16)) { io.setAttr("err","7:Block sequence."); return; }
		io.setText(io.text()+resp.slice(4,resp.length-2));
		if(resp.charCodeAt(resp.length-2) == 0x03) break;
		if(resp.charCodeAt(resp.length-2) == 0x17) { resp = ""; continue; }
		io.setAttr("err","8:Unknown block end.");
		return;
	}
}


ID: TMH
NAME: TMP-xx03
DESCR: Power supply for turbomolecular pumps, model EI-R04M.
InPROG: JavaLikeCalc.JavaScript
OutPROG:
JavaLikeCalc.JavaScript
//Request form:
//<mess addr="1">{req}</mess> - message tag
//  addr - remote station address (1...32)

io.setAttr("err","");
addr = io.attr("addr").toInt();
if(addr < 1 || addr > 32) { io.setAttr("err","1:Device address out of range 1...32"); return; }
request = "MJ"+addr.toString(10,2)+io.text();
//> Calc CRC
CRC = 0;
for(i = 0; i < request.length; i++) CRC += request.charCodeAt(i);
request += (CRC&0xFF).toString(16,2)+"\r";
//SYS.messDebug("PRT","Request: "+Special.FLibSYS.strDec4Bin(request));

//Send request
resp = tr.messIO(request);
while(resp.length && resp[resp.length-1] != "\r")
{
	tresp = tr.messIO("");
	if(!tresp.length) break;
  	resp += tresp;
}
if(resp.length < 6 || resp[resp.length-1] != "\r" || resp.slice(0,2) != "MJ" || resp.slice(2,4).toInt() != addr)
{ io.setAttr("err","2:No or error respond"); return; }
//SYS.messDebug("PRT","Respond: "+Special.FLibSYS.strDec4Bin(resp));
CRC = 0;
for(i = 0; i < (resp.length-3); i++) CRC += resp.charCodeAt(i);
if((CRC&0xFF) != resp.slice(resp.length-3,resp.length-1).toInt(16)) { io.setAttr("err","6:CRC error."); return; }
io.setText(resp.slice(4,resp.length-3));


# flb_doc

ID: getVal
NAME: Getting value from archive
uk#NAME: Запит значення архіву
ru#NAME: Запрос знач. архива
DESCR:
Query the value for a specified time from the assigned archive and issuing the result with the specified number of decimal points.

FORMULA:
using Special.FLibSYS;
srcTime = time;
val = vArh(strPath2Sep(addr)).get(time,uTime,0,archtor);
return (val.isEVal() || (strong && srcTime != time)) ? "Empty" : real2str(val,prec);

uk#DESCR:
Запит значення на визначений час з вказаного архіву та видача результату з вказаною кількістю знаків після точки.

uk#FORMULA:
using Special.FLibSYS;
srcTime = time;
val = vArh(strPath2Sep(addr)).get(time,uTime,0,archtor);
return (val.isEVal() || (strong && srcTime != time)) ? "Порожньо" : real2str(val,prec);

ru#DESCR:
Запрос значения на указанное время из установленного архива и выдача результата с указанным количеством знаков после точки.

ru#FORMULA:
using Special.FLibSYS;
srcTime = time;
val = vArh(strPath2Sep(addr)).get(time,uTime,0,archtor);
return (val.isEVal() || (strong && srcTime != time)) ? "Пусто" : real2str(val,prec);


ID: sumVal
NAME: Sum values of archive
uk#NAME: Сума значень архіву
ru#NAME: Сумма знач. архива
DESCR:
Calculating the sum of values ​​for a specified period of time an archive and issuing results with the specified number of decimal points.

FORMULA:
using Special.FLibSYS;

a_src = vArh(strPath2Sep(addr));

vl=0.0; buf_beg_u=buf_end_u=0;
buf_beg=max(a_src.begin(0,archtor),bTime);
buf_end=min(a_src.end(0,archtor),eTime);
while( true )
{
  r_val = a_src.get(buf_beg,buf_beg_u,true,archtor);
  if(r_val != EVAL_REAL) vl+=r_val;
  if( !buf_beg || buf_beg>=buf_end ) break;
  buf_beg_u++;
}

return (vl==EVAL_REAL) ? "Empty" : real2str(vl,prec);

uk#DESCR:
Обчислення суми значень за проміжок часу визначеного архіву та видача результату з вказаною кількістю знаків після точки.

uk#FORMULA:
using Special.FLibSYS;

a_src = vArh(strPath2Sep(addr));

tvar=0.0; buf_beg_u=buf_end_u=0;
buf_beg=max(a_src.begin(0,archtor),bTime);
buf_end=min(a_src.end(0,archtor),eTime);
while( true )
{
  r_val = a_src.get(buf_beg,buf_beg_u,true,archtor);
  if(r_val != EVAL_REAL) tvar+=r_val;
  if( !buf_beg || buf_beg>=buf_end ) break;
  buf_beg_u++;
}

return (tvar==EVAL_REAL) ? "Порожньо" : real2str(tvar,prec);

ru#DESCR:
Вычисление суммы значений за промежуток времени указанного архива и выдача результата с указанным количеством знаков после точки.

ru#FORMULA:
using Special.FLibSYS;

a_src = vArh(strPath2Sep(addr));

vl=0.0; buf_beg_u=buf_end_u=0;
buf_beg=max(a_src.begin(0,archtor),bTime);
buf_end=min(a_src.end(0,archtor),eTime);
while( true )
{
  r_val = a_src.get(buf_beg,buf_beg_u,true,archtor);
  if(r_val != EVAL_REAL) vl+=r_val;
  if( !buf_beg || buf_beg>=buf_end ) break;
  buf_beg_u++;
}

return (vl==EVAL_REAL) ? "Пусто" : real2str(vl,prec);


ID: averVal
NAME: Average value of archive
uk#NAME: Середнє значення архіву
ru#NAME: Среднее знач. архива
DESCR:
Calculate the average value over a specified period of time an archive and issuing results with the specified number of decimal points.

FORMULA:
using Special.FLibSYS;
a_src = vArh(strPath2Sep(addr));

vl=EVAL_REAL;
buf_beg=max(a_src.begin(0,archtor),bTime);
buf_end=min(a_src.end(0,archtor),eTime);
while( true )
{
  buf_beg1=buf_beg;
  r_val = a_src.get(buf_beg,0,true,archtor);
  if(vl ==  EVAL_REAL) vl = r_val; 
  else if(r_val != EVAL_REAL)
    vl=(vl*(buf_beg-bTime)+r_val*(buf_beg-buf_beg1))/(buf_beg-bTime+buf_beg-buf_beg1);
  if( buf_beg == 0 || buf_beg>=buf_end ) break;
  buf_beg++;
}

return (vl==EVAL_REAL) ? "Empty" : real2str(vl,prec);

uk#DESCR:
Обчислення середнього значення за проміжок часу визначеного архіву та видача результату з вказаною кількістю знаків після точки.

uk#FORMULA:
using Special.FLibSYS;
a_src = vArh(strPath2Sep(addr));

tvar=EVAL_REAL;
buf_beg=max(a_src.begin(0,archtor),bTime);
buf_end=min(a_src.end(0,archtor),eTime);
while( true )
{
  buf_beg1=buf_beg;
  r_val = a_src.get(buf_beg,0,true,archtor);
  if(tvar ==  EVAL_REAL) tvar = r_val; 
  else if(r_val != EVAL_REAL)
    tvar=(tvar*(buf_beg-bTime)+r_val*(buf_beg-buf_beg1))/(buf_beg-bTime+buf_beg-buf_beg1);
  if( buf_beg == 0 || buf_beg>=buf_end ) break;
  buf_beg++;
}

return (tvar==EVAL_REAL) ? "Порожньо" : real2str(tvar,prec);

ru#DESCR:
Вычисление среднего значения за промежуток времени указанного архива и выдача результата с указанным количеством знаков после точки.

ru#FORMULA:
using Special.FLibSYS;
a_src = vArh(strPath2Sep(addr));

vl=EVAL_REAL;
buf_beg=max(a_src.begin(0,archtor),bTime);
buf_end=min(a_src.end(0,archtor),eTime);
while( true )
{
  buf_beg1=buf_beg;
  r_val = a_src.get(buf_beg,0,true,archtor);
  if(vl ==  EVAL_REAL) vl = r_val; 
  else if(r_val != EVAL_REAL)
    vl=(vl*(buf_beg-bTime)+r_val*(buf_beg-buf_beg1))/(buf_beg-bTime+buf_beg-buf_beg1);
  if( buf_beg == 0 || buf_beg>=buf_end ) break;
  buf_beg++;
}

return (vl==EVAL_REAL) ? "Пусто" : real2str(vl,prec);


# flb_regEl

ID: pidUnif
NAME: PID (unified)
uk#NAME: ПІД (уніфікований)
ru#NAME: ПИД (унифицированный)
DESCR:
Composite-unified analog and pulse PID. At the heart of the regulator is core a standard analog PID controller from the library "FLibComplex1" (http://wiki.oscada.org/HomePageEn/Doc/FLibComplex1#h902-15) and the implementation of the PWM for the pulse part.

uk#DESCR:
Суміщений-уніфікований аналоговий та імпульсний ПІД-регулятор. У основі регулятора лежить мова стандартного аналогового ПІД-регулятора з бібліотеки "FLibComplex1" та реалізація ШІМ для імпульсної частини.

FORMULA:
//> Call standard analog PID
outA=Special.FLibComplex1.pid(var,sp,max,min,manIn,auto,casc,Kp,Ti,Kd,Td,Tzd,Hup,Hdwn,Zi,followSp,K1,in1,K2,in2,K3,in3,K4,in4,f_frq,int,dif,lag);
if( analog ) return outA;

if( f_start || f_stop ) { impQup = impQdwn = false; return 0; }

//> Call impuls generator
outA = 2*(outA-50);
if( perLag <= 0 && ((outA*KImpRfact) >= (100*TImpMin/TImpPer) || (-outA/KImpRfact) >= (100*TImpMin/TImpPer) || (!auto && abs(outA) > 0.1)) )
{
  impLag = max(abs(outA)*TImpPer/100,TImpMin);
  impLag = (outA>0) ? impLag*KImpRfact : impLag/KImpRfact;
  perLag = TImpPer;
  if( outA > 0 ) impQup = true; else impQdwn = true;  
}
else if( perLag > 0 )
{
  perLag -= 1e3/f_frq;
  if( (TImpPer-perLag) >= impLag ) 
  {
    impQup = impQdwn = false;
    if( !auto ) perLag = 0;
  }
}

if( !auto ) manIn = 50;

if( impQupTm > 1 || (impQupTm && !impQup) ) impQupTm--;
if( impQup && !impQupTm ) impQupTm = 2*f_frq;
if( impQdwnTm > 1 || (impQdwnTm && !impQdwn) ) impQdwnTm--;
if( impQdwn && !impQdwnTm ) impQdwnTm = 2*f_frq;

if( impAnImit )
{
  if( impQup ) out += 100/(impAnOut*f_frq);
  if( impQdwn ) out -= 100/(impAnOut*f_frq);
  return max(0,min(100,out));
}
return impAnOut;

ru#DESCR:
Совмещённый-унифицированный аналоговый и импульсный ПИД-регулятор. В основе регулятора лежит ядро стандартного аналогового ПИД-регулятора из библиотеки "FLibComplex1" (http://wiki.oscada.org/Doc/FLibComplex1#h91-15) и реализация ШИМ для импульсной части.


ID: pidUnifD
NAME: PID dynamic
uk#NAME: PID динамічний
ru#NAME: PID динамический
DESCR:
Completely identical to unified PID regulator is implemented dynamically on ((/HomePageEn/Doc/JavaLikeCalc JavaLikeCalc)). The dynamic implementation allows you to easily adapt the regulator to the desired requirements, simply by editing it.

uk#DESCR:
Повністю ідентичний уніфікованому ПІД регулятор, реалізований динамічно на JavaLikeCalc. Динамічна реалізація дозволяє легко адаптувати регулятор під потрібні вимоги, просто відредагувати його.

FORMULA:
//> Call standard analog PID
Kzd = min(1e3/(f_frq*Tzd),1);
Kint = min(1e3/(f_frq*Ti),1);
Kdif = min(1e3/(f_frq*Td),1);

//> Scale error
if(max <= min) return 0;

//> Prepare values
spv = 100*(sp-min)/(max-min);
val = 100*(var-min)/(max-min);
val += K1*in1 + K2*in2;
val = min(100,max(-100,val));

//> Error
err = spv - val;
err = (abs(err)<Zi) ? 0 : ((err>0) ? err-Zi : err+Zi );
err *= Kp;
err = min(100,max(-100,err));

integ += Kint*err;					//Integral
difer -= Kdif*(difer-val);			//Differecial wait
dlag  += Kzd*((difer-val)-dlag);	//Differecial lag

//> Automatic mode enabled
if(auto) outA = err + integ + Kd*dlag + K3*in3 + K4*in4;
else
{
  casc = false;
  if(followSp) sp = var;
  outA = manIn;
}

//> Check output limits
outA = manIn = min(Hup,max(Hdwn,outA));

//> Fix integral for manual and limits
integ = outA - err - Kd*dlag - K3*in3 - K4*in4;

if(analog) return outA;

if(f_start || f_stop) { impQup = impQdwn = false; return 0; }

//> Call impuls generator
outA = 2*(outA-50);
if(perLag <= 0 && ((outA*KImpRfact) >= (100*TImpMin/TImpPer) || (-outA/KImpRfact) >= (100*TImpMin/TImpPer) || (!auto && abs(outA) > 0.1)))
{
  impLag = max(abs(outA)*TImpPer/100,TImpMin);
  impLag = (outA>0) ? impLag*KImpRfact : impLag/KImpRfact;
  perLag = TImpPer;
  if(outA > 0) impQup = true; else impQdwn = true;  
}
else if(perLag > 0)
{
  perLag -= 1e3/f_frq;
  if((TImpPer-perLag) >= impLag)
  {
    impQup = impQdwn = false;
    if(!auto) perLag = 0;
  }
}

if(!auto) manIn = 50;

if(impQupTm > 1 || (impQupTm && !impQup)) impQupTm--;
if(impQup && !impQupTm) impQupTm = 2*f_frq;
if(impQdwnTm > 1 || (impQdwnTm && !impQdwn)) impQdwnTm--;
if(impQdwn && !impQdwnTm) impQdwnTm = 2*f_frq;

if(impAnImit)
{
  if(impQup)	out += 100/(impAnOut*f_frq);
  if(impQdwn)	out -= 100/(impAnOut*f_frq);
  return max(0,min(100,out));
}
return impAnOut;

ru#DESCR:
Полностью идентичный унифицированному ПИД регулятор, реализованный динамически на JavaLikeCalc. Динамическая реализация позволяет легко адаптировать регулятор под нужные требования, просто отредактировав его.


ID: pidImp
NAME: PID pulse
uk#NAME: ПІД імпульсний
ru#NAME: PID импульсный
DESCR:
Specialized pulse PID regulator is implemented on a special algorithm with compensation of double integration.

uk#DESCR:
Спеціалізований імпульсний ПІД регулятор реалізований за особливим алгоритмом з компенсацією подвійного інтегрування.

FORMULA:
//> Call standard analog PID
Kzd = min(1e3/(f_frq*Tzd),1);
Kint = min(1e3/(f_frq*Ti),1);
Kdif = min(1e3/(f_frq*Td),1);

//> Scale error
if( max <= min ) return 0;

//> Prepare values
spv = 100*(sp-min)/(max-min);
val = 100*(var-min)/(max-min);
val += K1*in1 + K2*in2;
val = min(100,max(-100,val));

//> Error
err = spv - val;
err = (abs(err)<Zi) ? 0 : ((err>0) ? err-Zi : err+Zi );
err *= Kp;
err = min(100,max(-100,err));
errP = err-err1;
errD = err1-err2;
err2 = err1; err1 = err;

integ += Kint*err;          //Integral
difer -= Kdif*(difer-errD);  //Differecial wait
dlag  += Kzd*((errP-difer)-dlag);    //Differecial lag

//> Automatic mode enabled
if( auto ) { outPID = errP + Ki*err + integ + Kd*dlag; outA = 50 + outPID + K3*in3 + K4*in4; }
else
{
  outPID = 0;
  casc = false;
  if( followSp ) sp = var;
  outA = manIn;
}

//> Check output limits
outA = manIn = min(Hup,max(Hdwn,outA));

//> Fix integral for manual and limits
//integ = outA - errP - Kd*dlag - K3*in3 - K4*in4;

if( f_start || f_stop ) { impQup = impQdwn = false; return 0; }

//> Call impuls generator
outA = 2*(outA-50);
if( perLag <= 0 && ((outA*KImpRfact) >= (100*TImpMin/TImpPer) || (-outA/KImpRfact) >= (100*TImpMin/TImpPer) || (!auto && abs(outA) > 0.1)) )
{
  impLag = max(abs(outA)*TImpPer/100,TImpMin);
  impLag = (outA>0) ? impLag*KImpRfact : impLag/KImpRfact;
  perLag = TImpPer;
  if( outA > 0 ) impQup = true; else impQdwn = true;  
}
else if( perLag > 0 )
{
  perLag -= 1e3/f_frq;
  if( (TImpPer-perLag) >= impLag ) 
  {
    impQup = impQdwn = false;
    if( !auto ) perLag = 0;
  }
}

if( !auto ) manIn = 50;

if( impQupTm > 1 || (impQupTm && !impQup) ) impQupTm--;
if( impQup && !impQupTm ) impQupTm = 2*f_frq;
if( impQdwnTm > 1 || (impQdwnTm && !impQdwn) ) impQdwnTm--;
if( impQdwn && !impQdwnTm ) impQdwnTm = 2*f_frq;

if( impQup || impQdwn ) integ = 0;

if( impAnImit )
{
  if( impQup ) out += 100/(impAnOut*f_frq);
  if( impQdwn ) out -= 100/(impAnOut*f_frq);
  return max(0,min(100,out));
}
return impAnOut;

ru#DESCR:
Специализированный импульсный ПИД регулятор реализованный по особому алгоритму с компенсацией двойного интегрирования.


# lib_Controllers

ID: prescr
NAME: prescr
ru#NAME: prescr
uk#NAME: prescr
FORMULA:
clcCnt++;

if(f_start)	work = SYS.XMLNode("prg");

//> Check to commands controller present
comCntrO = false;
if(comsCntr.length)	comCntrO = SYS.DAQ.nodeAt(comsCntr,".");

//> Commands list update
if(f_start || !(clcCnt%(60*f_frq)))
{
	if(!comCntrO)
	{
		rez = SYS.BD.nodeAt(dbDB,".").SQLReq("SELECT * FROM "+dbComs+";");
		comLs = new Object();
		for(i_t = 1; i_t < rez.length; i_t++)
		{
			comNm = rez[i_t]["name"];
			comLs[comNm] = new Object();
			comLs[comNm]["proc"] = rez[i_t]["proc"];
			for(i_a = 1; i_a <= 5; i_a++)
				comLs[comNm]["arg"+i_a] = rez[i_t]["arg"+i_a];
		}
	}
	else
	{
		var nL = comCntrO.nodeList("prm_");
		comLs = new Object();
		for(i_n = 0; i_n < nL.length; i_n++)
		{
			comO = comCntrO[nL[i_n]];
			comNm = comO.cfg("NAME");
			comLs[comNm] = new Object();
			comLs[comNm]["prmID"] = nL[i_n].slice(4);
			for(i_a = 1; i_a <= 5; i_a++)
				if(!(comA=comO["arg"+i_a]).isEVal())
					comLs[comNm]["arg"+i_a] = comA.descr();
		}
	}
}

//> Programm selection change
if(curMode <= 0 && prog.length && (prog != work.attr("name") || mode == 1))
{
	work = SYS.XMLNode("prg");
	rez = SYS.BD.nodeAt(dbDB,".").SQLReq("SELECT prgTxt FROM "+dbProgs+" WHERE name='"+prog+"';");
	if(rez.length > 1)
	{
		//> Parse programm and insert procedure text and argument's labels to here
		work.load(rez[1][0]);
		work.setAttr("name",prog);
		for(i_c = 0; i_c < work.childSize(); i_c++)
		{
			comId = work.childGet(i_c).attr("id");
			if(comLs[comId].isEVal())	continue;
			work.childGet(i_c).setAttr("proc",comLs[comId].proc);
			for(i_a = 1; i_a <= 5; i_a++)
				work.childGet(i_c).setAttr("labArg"+i_a,comLs[comId]["arg"+i_a]);
		}
	}
	else prog = "";
}

//> Start process
if(curMode <= 0 && mode == 1 && prog.length)
{
	startTm = SYS.time();
	curCom = 0;
	curMode = mode;	
}
//> Pause and other process
else if((mode == 0 && curMode < 0) || (curMode == 1 && mode == 2) || (curMode == 2 && mode == 1))
{
	curMode = mode;
	if((curMode == 1 || curMode == 2) && comCntrO)
	{
		var cL = comCntrO.nodeList("prm_");
		for(i_c = 0; i_c < cL.length; i_c++)
			comCntrO[cL[i_c]].pause.set(curMode==2);
	}
}

//> Call program
if(curMode == 1 || curMode == 2)
{
	prog = work.attr("name");

	//> Internal commands call
	if(!comCntrO)
	{
		if(mode == 3 && curCom >= 0 && curCom < work.childSize())
		{
			work.childGet(curCom).setAttr("rez","-10:Step missed");
			curCom++;
		}
		if(curCom >= 0 && curCom < work.childSize())
		{
			comEl = work.childGet(curCom);
			//> Stop process
			if(mode == 0)
			{
				comEl.setAttr("rez","-10:Program terminated");
				//>> Call stop command
				if(!comLs["Stop"].isEVal())
				{
					off = 0;
					prLang = comLs["Stop"].proc.parse(0,"\n",off);
					SYS.DAQ.funcCall(prLang,new Object(),comLs["Stop"].proc.slice(off));
				}
				SYS.messInfo("uprg"+prog,"Terminated by user session of program \""+prog+"\" : "+SYS.strftime(startTm)+" : "+SYS.strftime(SYS.time()));
				curMode = mode = -3;
			}
			//> Pass empty command		
			else if(!comEl.attr("proc").length) curCom++;
			//> Execute command
			else if(curMode == 1)
			{
				args = new Object();
				args.rez = "";
				args.f_start = !comEl.attr("tm").length;
				if(args.f_start) comEl.setAttr("tm",SYS.time());
				args.f_frq = f_frq;
				for(i_a = 1; i_a <= 5; i_a++) args["arg"+i_a] = comEl.attr("arg"+i_a);
				for(i_a = 1; i_a <= 10; i_a++) args["tmp"+i_a] = comEl.attr("tmp"+i_a);
				off = 0;
				prLang = comEl.attr("proc").parse(0,"\n",off);
				rez = SYS.DAQ.funcCall(prLang,args,comEl.attr("proc").slice(off));
				if(rez && args.rez.toInt() > 0) curCom++;
				else if(!rez || args.rez.toInt() < 0)
				{
					//>> Call error command
					if(!comLs["Error"].isEVal())
					{
						off = 0;
						prLang = comLs["Error"].proc.parse(0,"\n",off);
						SYS.DAQ.funcCall(prLang,new Object(),comLs["Error"].proc.slice(off));
					}
					SYS.messInfo("uprg"+prog,"Terminated by error session of program \""+prog+"\" : "+SYS.strftime(startTm)+" : "+SYS.strftime(SYS.time()));
					curMode = mode = -1;
				}
				comEl.setAttr("rez",args.rez);
				for(i_a = 1; i_a <= 5; i_a++) comEl.setAttr("arg"+i_a, args["arg"+i_a]);
				for(i_a = 1; i_a <= 10; i_a++) comEl.setAttr("tmp"+i_a, args["tmp"+i_a]);
				//SYS.messDebug("TEST Calc","TEST Calc rezult: "+args.y);
			}
		}

		//> End call
		if(curCom < 0 || curCom >= work.childSize())
		{
			//>> Call stop command
			if(!comLs["Stop"].isEVal())
			{
				off = 0;
				prLang = comLs["Stop"].proc.parse(0,"\n",off);
				SYS.DAQ.funcCall(prLang,new Object(),comLs["Stop"].proc.slice(off));
			}

			curMode = mode = -2;
			SYS.messInfo("uprg"+prog,"Successful session of program \""+prog+"\" : "+SYS.strftime(startTm)+" : "+SYS.strftime(SYS.time()));

			//> Place to program last execution time
			rez = SYS.BD.nodeAt(dbDB,".").SQLReq("SELECT prgTxt FROM "+dbProgs+" WHERE name='"+prog+"';");
			if(rez.length > 1)
			{
				//> Parse programm and insert procedure text and argument's labels to here
				comTree = SYS.XMLNode("prg");
				comTree.load(rez[1][0]);
				comTree.setAttr("wtm",SYS.time()-startTm);
				SYS.BD.nodeAt(dbDB,".").SQLReq("UPDATE "+dbProgs+" SET prgTxt='"+comTree.save().replace("'","''")+"' WHERE name='"+prog+"';");
			}
		}
	}
	//> External commands call
	else
	{
		//>> Get current command parameter-object		
		curComPrm = EVAL_BOOL;
		if(curCom >= 0 && curCom < work.childSize())
		{
			if(!(comId=comLs[work.childGet(curCom).attr("id")]).isEVal())	curComPrm = comCntrO["prm_"+comId.prmID];
			if(curComPrm.isEVal())
			{
				curMode = mode = -1;
				work.childGet(curCom).setAttr("rez","-11:Comand missed: "+work.childGet(curCom).attr("id"));
				return;
			}
		}

		if(mode == 3 && curCom >= 0 && curCom < work.childSize())
		{
			work.childGet(curCom).setAttr("rez","-10:Step missed");
			curComPrm.run.set(false);
			curCom++;
			mode = curMode;
			return;
		}
		if(curCom >= 0 && curCom < work.childSize())
		{
			comEl = work.childGet(curCom);
			//> Stop process
			if(mode == 0)
			{
				comEl.setAttr("rez","-12:Program terminated");
				//>> Stop all typical and set "abort" flag
				var cL = comCntrO.nodeList("prm_");
				for(i_c = 0; i_c < cL.length; i_c++)
				{
					comCntrO[cL[i_c]].run.set(false);
					comCntrO[cL[i_c]].abort.set(false);
				}

				SYS.messInfo("uprg"+prog,"Terminated by user session of program \""+prog+"\" : "+SYS.strftime(startTm)+" : "+SYS.strftime(SYS.time()));
				curMode = mode = -3;
			}
			//> Commands process
			else
			{
				//>> Start command
				if(!comEl.attr("tm").length)
				{
					curComPrm.run.set(0);	//> Stop for possible background call
					comEl.setAttr("tm",SYS.time());
					for(i_a = 1; i_a <= 5; i_a++)
						if(!(comA=curComPrm["arg"+i_a]).isEVal())
							comA.set(comEl.attr("arg"+i_a));
					curComPrm.rez.set(0);
					curComPrm.run.set(true);
				}

				//> Update steps status, up to current comand
				comTo = min(curCom+1,work.childSize());
				for(i_c = 0; i_c < comTo; i_c++)
				{
					comElI = work.childGet(i_c);
					curComPI = comCntrO["prm_"+comLs[comElI.attr("id")].prmID];
					if(i_c < curCom && !(curComPI.run.get() && 
						comElI.attr("rez").toInt() != 1 && comElI.attr("rez").toInt() > -10))	continue;
					rez = curComPI.rez.get();
					if(i_c == curCom && rez.toInt() > 0) curCom++;
					if(rez.toInt() < 0)
					{
						//>> Stop all typical and call "error" command
						var cL = comCntrO.nodeList("prm_");
						for(i_c = 0; i_c < cL.length; i_c++)
						{
							comCntrO[cL[i_c]].run.set(false);
							comCntrO[cL[i_c]].error.set(false);
						}

						SYS.messInfo("uprg"+prog,"Terminated by error session of program \""+prog+"\" : "+SYS.strftime(startTm)+" : "+SYS.strftime(SYS.time()));
						curMode = mode = -1;
					}
					comElI.setAttr("rez",rez);
					for(i_a = 1; i_a <= 5; i_a++)
						if(!(comA=curComPI["arg"+i_a]).isEVal())
							comElI.setAttr("arg"+i_a, comA.get());
				}
			}
		}
		
		//> End call
		if(curCom < 0 || curCom >= work.childSize())
		{
			//>> Stop all typical and call "stop" command
			var cL = comCntrO.nodeList("prm_");
			for(i_c = 0; i_c < cL.length; i_c++)
				comCntrO[cL[i_c]].run.set(false);

			curMode = mode = -2;
			SYS.messInfo("uprg"+prog,"Successful session of program \""+prog+"\" : "+SYS.strftime(startTm)+" : "+SYS.strftime(SYS.time()));

			//> Place to program last execution time
			rez = SYS.BD.nodeAt(dbDB,".").SQLReq("SELECT prgTxt FROM "+dbProgs+" WHERE name='"+prog+"';");
			if(rez.length > 1)
			{
				//> Parse programm and insert procedure text and argument's labels to here
				comTree = SYS.XMLNode("prg");
				comTree.load(rez[1][0]);
				comTree.setAttr("wtm",SYS.time()-startTm);
				SYS.BD.nodeAt(dbDB,".").SQLReq("UPDATE "+dbProgs+" SET prgTxt='"+comTree.save().replace("'","''")+"' WHERE name='"+prog+"';");
			}
		}
	}
}
mode = curMode;

ru#FORMULA:
clcCnt++;

if(f_start)	work = SYS.XMLNode("prg");

//> Check to commands controller present
comCntrO = false;
if(comsCntr.length)	comCntrO = SYS.DAQ.nodeAt(comsCntr,".");

//> Commands list update
if(f_start || !(clcCnt%(60*f_frq)))
{
	if(!comCntrO)
	{
		rez = SYS.BD.nodeAt(dbDB,".").SQLReq("SELECT * FROM "+dbComs+";");
		comLs = new Object();
		for(i_t = 1; i_t < rez.length; i_t++)
		{
			comNm = rez[i_t]["name"];
			comLs[comNm] = new Object();
			comLs[comNm]["proc"] = rez[i_t]["proc"];
			for(i_a = 1; i_a <= 5; i_a++)
				comLs[comNm]["arg"+i_a] = rez[i_t]["arg"+i_a];
		}
	}
	else
	{
		var nL = comCntrO.nodeList("prm_");
		comLs = new Object();
		for(i_n = 0; i_n < nL.length; i_n++)
		{
			comO = comCntrO[nL[i_n]];
			comNm = comO.cfg("NAME");
			comLs[comNm] = new Object();
			comLs[comNm]["prmID"] = nL[i_n].slice(4);
			for(i_a = 1; i_a <= 5; i_a++)
				if(!(comA=comO["arg"+i_a]).isEVal())
					comLs[comNm]["arg"+i_a] = comA.descr();
		}
	}
}

//> Programm selection change
if(curMode <= 0 && prog.length && (prog != work.attr("name") || mode == 1))
{
	work = SYS.XMLNode("prg");
	rez = SYS.BD.nodeAt(dbDB,".").SQLReq("SELECT prgTxt FROM "+dbProgs+" WHERE name='"+prog+"';");
	if(rez.length > 1)
	{
		//> Parse programm and insert procedure text and argument's labels to here
		work.load(rez[1][0]);
		work.setAttr("name",prog);
		for(i_c = 0; i_c < work.childSize(); i_c++)
		{
			comId = work.childGet(i_c).attr("id");
			if(comLs[comId].isEVal())	continue;
			work.childGet(i_c).setAttr("proc",comLs[comId].proc);
			for(i_a = 1; i_a <= 5; i_a++)
				work.childGet(i_c).setAttr("labArg"+i_a,comLs[comId]["arg"+i_a]);
		}
	}
	else prog = "";
}

//> Start process
if(curMode <= 0 && mode == 1 && prog.length)
{
	startTm = SYS.time();
	curCom = 0;
	curMode = mode;	
}
//> Pause and other process
else if((mode == 0 && curMode < 0) || (curMode == 1 && mode == 2) || (curMode == 2 && mode == 1))
{
	curMode = mode;
	if((curMode == 1 || curMode == 2) && comCntrO)
	{
		var cL = comCntrO.nodeList("prm_");
		for(i_c = 0; i_c < cL.length; i_c++)
			comCntrO[cL[i_c]].pause.set(curMode==2);
	}
}

//> Call program
if(curMode == 1 || curMode == 2)
{
	prog = work.attr("name");

	//> Internal commands call
	if(!comCntrO)
	{
		if(mode == 3 && curCom >= 0 && curCom < work.childSize())
		{
			work.childGet(curCom).setAttr("rez","-10:Шаг пропущен");
			curCom++;
		}
		if(curCom >= 0 && curCom < work.childSize())
		{
			comEl = work.childGet(curCom);
			//> Stop process
			if(mode == 0)
			{
				comEl.setAttr("rez","-10:Программа прервана");
				//>> Call stop command
				if(!comLs["Stop"].isEVal())
				{
					off = 0;
					prLang = comLs["Stop"].proc.parse(0,"\n",off);
					SYS.DAQ.funcCall(prLang,new Object(),comLs["Stop"].proc.slice(off));
				}
				SYS.messInfo("uprg"+prog,"Прерванный пользователем сеанс программы \""+prog+"\" : "+SYS.strftime(startTm)+" : "+SYS.strftime(SYS.time()));
				curMode = mode = -3;
			}
			//> Pass empty command		
			else if(!comEl.attr("proc").length) curCom++;
			//> Execute command
			else if(curMode == 1)
			{
				args = new Object();
				args.rez = "";
				args.f_start = !comEl.attr("tm").length;
				if(args.f_start) comEl.setAttr("tm",SYS.time());
				args.f_frq = f_frq;
				for(i_a = 1; i_a <= 5; i_a++) args["arg"+i_a] = comEl.attr("arg"+i_a);
				for(i_a = 1; i_a <= 10; i_a++) args["tmp"+i_a] = comEl.attr("tmp"+i_a);
				off = 0;
				prLang = comEl.attr("proc").parse(0,"\n",off);
				rez = SYS.DAQ.funcCall(prLang,args,comEl.attr("proc").slice(off));
				if(rez && args.rez.toInt() > 0) curCom++;
				else if(!rez || args.rez.toInt() < 0)
				{
					//>> Call error command
					if(!comLs["Error"].isEVal())
					{
						off = 0;
						prLang = comLs["Error"].proc.parse(0,"\n",off);
						SYS.DAQ.funcCall(prLang,new Object(),comLs["Error"].proc.slice(off));
					}
					SYS.messInfo("uprg"+prog,"Прерванный ошибкой сеанс программы \""+prog+"\" : "+SYS.strftime(startTm)+" : "+SYS.strftime(SYS.time()));
					curMode = mode = -1;
				}
				comEl.setAttr("rez",args.rez);
				for(i_a = 1; i_a <= 5; i_a++) comEl.setAttr("arg"+i_a, args["arg"+i_a]);
				for(i_a = 1; i_a <= 10; i_a++) comEl.setAttr("tmp"+i_a, args["tmp"+i_a]);
				//SYS.messDebug("TEST Calc","TEST Calc rezult: "+args.y);
			}
		}

		//> End call
		if(curCom < 0 || curCom >= work.childSize())
		{
			//>> Call stop command
			if(!comLs["Stop"].isEVal())
			{
				off = 0;
				prLang = comLs["Stop"].proc.parse(0,"\n",off);
				SYS.DAQ.funcCall(prLang,new Object(),comLs["Stop"].proc.slice(off));
			}

			curMode = mode = -2;
			SYS.messInfo("uprg"+prog,"Успешный сеанс программы \""+prog+"\" : "+SYS.strftime(startTm)+" : "+SYS.strftime(SYS.time()));

			//> Place to program last execution time
			rez = SYS.BD.nodeAt(dbDB,".").SQLReq("SELECT prgTxt FROM "+dbProgs+" WHERE name='"+prog+"';");
			if(rez.length > 1)
			{
				//> Parse programm and insert procedure text and argument's labels to here
				comTree = SYS.XMLNode("prg");
				comTree.load(rez[1][0]);
				comTree.setAttr("wtm",SYS.time()-startTm);
				SYS.BD.nodeAt(dbDB,".").SQLReq("UPDATE "+dbProgs+" SET prgTxt='"+comTree.save().replace("'","''")+"' WHERE name='"+prog+"';");
			}
		}
	}
	//> External commands call
	else
	{
		//>> Get current command parameter-object		
		curComPrm = EVAL_BOOL;
		if(curCom >= 0 && curCom < work.childSize())
		{
			if(!(comId=comLs[work.childGet(curCom).attr("id")]).isEVal())	curComPrm = comCntrO["prm_"+comId.prmID];
			if(curComPrm.isEVal())
			{
				curMode = mode = -1;
				work.childGet(curCom).setAttr("rez","-11:Отсутствует команда: "+work.childGet(curCom).attr("id"));
				return;
			}
		}

		if(mode == 3 && curCom >= 0 && curCom < work.childSize())
		{
			work.childGet(curCom).setAttr("rez","-10:Шаг пропущен");
			curComPrm.run.set(false);
			curCom++;
			mode = curMode;
			return;
		}
		if(curCom >= 0 && curCom < work.childSize())
		{
			comEl = work.childGet(curCom);
			//> Stop process
			if(mode == 0)
			{
				comEl.setAttr("rez","-12:Программа прервана");
				//>> Stop all typical and set "abort" flag
				var cL = comCntrO.nodeList("prm_");
				for(i_c = 0; i_c < cL.length; i_c++)
				{
					comCntrO[cL[i_c]].run.set(false);
					comCntrO[cL[i_c]].abort.set(false);
				}

				SYS.messInfo("uprg"+prog,"Прерванный пользователем сеанс программы \""+prog+"\" : "+SYS.strftime(startTm)+" : "+SYS.strftime(SYS.time()));
				curMode = mode = -3;
			}
			//> Commands process
			else
			{
				//>> Start command
				if(!comEl.attr("tm").length)
				{
					curComPrm.run.set(0);	//> Stop for possible background call
					comEl.setAttr("tm",SYS.time());
					for(i_a = 1; i_a <= 5; i_a++)
						if(!(comA=curComPrm["arg"+i_a]).isEVal())
							comA.set(comEl.attr("arg"+i_a));
					curComPrm.rez.set(0);
					curComPrm.run.set(true);
				}

				//> Update steps status, up to current comand
				comTo = min(curCom+1,work.childSize());
				for(i_c = 0; i_c < comTo; i_c++)
				{
					comElI = work.childGet(i_c);
					curComPI = comCntrO["prm_"+comLs[comElI.attr("id")].prmID];
					if(i_c < curCom && !(curComPI.run.get() && 
						comElI.attr("rez").toInt() != 1 && comElI.attr("rez").toInt() > -10))	continue;
					rez = curComPI.rez.get();
					if(i_c == curCom && rez.toInt() > 0) curCom++;
					if(rez.toInt() < 0)
					{
						//>> Stop all typical and call "error" command
						var cL = comCntrO.nodeList("prm_");
						for(i_c = 0; i_c < cL.length; i_c++)
						{
							comCntrO[cL[i_c]].run.set(false);
							comCntrO[cL[i_c]].error.set(false);
						}

						SYS.messInfo("uprg"+prog,"Прерванный ошибкой сеанс программы \""+prog+"\" : "+SYS.strftime(startTm)+" : "+SYS.strftime(SYS.time()));
						curMode = mode = -1;
					}
					comElI.setAttr("rez",rez);
					for(i_a = 1; i_a <= 5; i_a++)
						if(!(comA=curComPI["arg"+i_a]).isEVal())
							comElI.setAttr("arg"+i_a, comA.get());
				}
			}
		}
		
		//> End call
		if(curCom < 0 || curCom >= work.childSize())
		{
			//>> Stop all typical and call "stop" command
			var cL = comCntrO.nodeList("prm_");
			for(i_c = 0; i_c < cL.length; i_c++)
				comCntrO[cL[i_c]].run.set(false);

			curMode = mode = -2;
			SYS.messInfo("uprg"+prog,"Успешный сеанс программы \""+prog+"\" : "+SYS.strftime(startTm)+" : "+SYS.strftime(SYS.time()));

			//> Place to program last execution time
			rez = SYS.BD.nodeAt(dbDB,".").SQLReq("SELECT prgTxt FROM "+dbProgs+" WHERE name='"+prog+"';");
			if(rez.length > 1)
			{
				//> Parse programm and insert procedure text and argument's labels to here
				comTree = SYS.XMLNode("prg");
				comTree.load(rez[1][0]);
				comTree.setAttr("wtm",SYS.time()-startTm);
				SYS.BD.nodeAt(dbDB,".").SQLReq("UPDATE "+dbProgs+" SET prgTxt='"+comTree.save().replace("'","''")+"' WHERE name='"+prog+"';");
			}
		}
	}
}
mode = curMode;

uk#FORMULA:
clcCnt++;

if(f_start)	work = SYS.XMLNode("prg");

//> Check to commands controller present
comCntrO = false;
if(comsCntr.length)	comCntrO = SYS.DAQ.nodeAt(comsCntr,".");

//> Commands list update
if(f_start || !(clcCnt%(60*f_frq)))
{
	if(!comCntrO)
	{
		rez = SYS.BD.nodeAt(dbDB,".").SQLReq("SELECT * FROM "+dbComs+";");
		comLs = new Object();
		for(i_t = 1; i_t < rez.length; i_t++)
		{
			comNm = rez[i_t]["name"];
			comLs[comNm] = new Object();
			comLs[comNm]["proc"] = rez[i_t]["proc"];
			for(i_a = 1; i_a <= 5; i_a++)
				comLs[comNm]["arg"+i_a] = rez[i_t]["arg"+i_a];
		}
	}
	else
	{
		var nL = comCntrO.nodeList("prm_");
		comLs = new Object();
		for(i_n = 0; i_n < nL.length; i_n++)
		{
			comO = comCntrO[nL[i_n]];
			comNm = comO.cfg("NAME");
			comLs[comNm] = new Object();
			comLs[comNm]["prmID"] = nL[i_n].slice(4);
			for(i_a = 1; i_a <= 5; i_a++)
				if(!(comA=comO["arg"+i_a]).isEVal())
					comLs[comNm]["arg"+i_a] = comA.descr();
		}
	}
}

//> Programm selection change
if(curMode <= 0 && prog.length && (prog != work.attr("name") || mode == 1))
{
	work = SYS.XMLNode("prg");
	rez = SYS.BD.nodeAt(dbDB,".").SQLReq("SELECT prgTxt FROM "+dbProgs+" WHERE name='"+prog+"';");
	if(rez.length > 1)
	{
		//> Parse programm and insert procedure text and argument's labels to here
		work.load(rez[1][0]);
		work.setAttr("name",prog);
		for(i_c = 0; i_c < work.childSize(); i_c++)
		{
			comId = work.childGet(i_c).attr("id");
			if(comLs[comId].isEVal())	continue;
			work.childGet(i_c).setAttr("proc",comLs[comId].proc);
			for(i_a = 1; i_a <= 5; i_a++)
				work.childGet(i_c).setAttr("labArg"+i_a,comLs[comId]["arg"+i_a]);
		}
	}
	else prog = "";
}

//> Start process
if(curMode <= 0 && mode == 1 && prog.length)
{
	startTm = SYS.time();
	curCom = 0;
	curMode = mode;	
}
//> Pause and other process
else if((mode == 0 && curMode < 0) || (curMode == 1 && mode == 2) || (curMode == 2 && mode == 1))
{
	curMode = mode;
	if((curMode == 1 || curMode == 2) && comCntrO)
	{
		var cL = comCntrO.nodeList("prm_");
		for(i_c = 0; i_c < cL.length; i_c++)
			comCntrO[cL[i_c]].pause.set(curMode==2);
	}
}

//> Call program
if(curMode == 1 || curMode == 2)
{
	prog = work.attr("name");

	//> Internal commands call
	if(!comCntrO)
	{
		if(mode == 3 && curCom >= 0 && curCom < work.childSize())
		{
			work.childGet(curCom).setAttr("rez","-10:Крок пропущено");
			curCom++;
		}
		if(curCom >= 0 && curCom < work.childSize())
		{
			comEl = work.childGet(curCom);
			//> Stop process
			if(mode == 0)
			{
				comEl.setAttr("rez","-10:Програму перервано");
				//>> Call stop command
				if(!comLs["Stop"].isEVal())
				{
					off = 0;
					prLang = comLs["Stop"].proc.parse(0,"\n",off);
					SYS.DAQ.funcCall(prLang,new Object(),comLs["Stop"].proc.slice(off));
				}
				SYS.messInfo("uprg"+prog,"Перерваний користувачем сеанс програми \""+prog+"\" : "+SYS.strftime(startTm)+" : "+SYS.strftime(SYS.time()));
				curMode = mode = -3;
			}
			//> Pass empty command		
			else if(!comEl.attr("proc").length) curCom++;
			//> Execute command
			else if(curMode == 1)
			{
				args = new Object();
				args.rez = "";
				args.f_start = !comEl.attr("tm").length;
				if(args.f_start) comEl.setAttr("tm",SYS.time());
				args.f_frq = f_frq;
				for(i_a = 1; i_a <= 5; i_a++) args["arg"+i_a] = comEl.attr("arg"+i_a);
				for(i_a = 1; i_a <= 10; i_a++) args["tmp"+i_a] = comEl.attr("tmp"+i_a);
				off = 0;
				prLang = comEl.attr("proc").parse(0,"\n",off);
				rez = SYS.DAQ.funcCall(prLang,args,comEl.attr("proc").slice(off));
				if(rez && args.rez.toInt() > 0) curCom++;
				else if(!rez || args.rez.toInt() < 0)
				{
					//>> Call error command
					if(!comLs["Error"].isEVal())
					{
						off = 0;
						prLang = comLs["Error"].proc.parse(0,"\n",off);
						SYS.DAQ.funcCall(prLang,new Object(),comLs["Error"].proc.slice(off));
					}
					SYS.messInfo("uprg"+prog,"Перерваний помилкою сеанс програми \""+prog+"\" : "+SYS.strftime(startTm)+" : "+SYS.strftime(SYS.time()));
					curMode = mode = -1;
				}
				comEl.setAttr("rez",args.rez);
				for(i_a = 1; i_a <= 5; i_a++) comEl.setAttr("arg"+i_a, args["arg"+i_a]);
				for(i_a = 1; i_a <= 10; i_a++) comEl.setAttr("tmp"+i_a, args["tmp"+i_a]);
				//SYS.messDebug("TEST Calc","TEST Calc rezult: "+args.y);
			}
		}

		//> End call
		if(curCom < 0 || curCom >= work.childSize())
		{
			//>> Call stop command
			if(!comLs["Stop"].isEVal())
			{
				off = 0;
				prLang = comLs["Stop"].proc.parse(0,"\n",off);
				SYS.DAQ.funcCall(prLang,new Object(),comLs["Stop"].proc.slice(off));
			}

			curMode = mode = -2;
			SYS.messInfo("uprg"+prog,"Вдалий сеанс програми \""+prog+"\" : "+SYS.strftime(startTm)+" : "+SYS.strftime(SYS.time()));

			//> Place to program last execution time
			rez = SYS.BD.nodeAt(dbDB,".").SQLReq("SELECT prgTxt FROM "+dbProgs+" WHERE name='"+prog+"';");
			if(rez.length > 1)
			{
				//> Parse programm and insert procedure text and argument's labels to here
				comTree = SYS.XMLNode("prg");
				comTree.load(rez[1][0]);
				comTree.setAttr("wtm",SYS.time()-startTm);
				SYS.BD.nodeAt(dbDB,".").SQLReq("UPDATE "+dbProgs+" SET prgTxt='"+comTree.save().replace("'","''")+"' WHERE name='"+prog+"';");
			}
		}
	}
	//> External commands call
	else
	{
		//>> Get current command parameter-object		
		curComPrm = EVAL_BOOL;
		if(curCom >= 0 && curCom < work.childSize())
		{
			if(!(comId=comLs[work.childGet(curCom).attr("id")]).isEVal())	curComPrm = comCntrO["prm_"+comId.prmID];
			if(curComPrm.isEVal())
			{
				curMode = mode = -1;
				work.childGet(curCom).setAttr("rez","-11:Відсутня команда: "+work.childGet(curCom).attr("id"));
				return;
			}
		}

		if(mode == 3 && curCom >= 0 && curCom < work.childSize())
		{
			work.childGet(curCom).setAttr("rez","-10:Крок пропущено");
			curComPrm.run.set(false);
			curCom++;
			mode = curMode;
			return;
		}
		if(curCom >= 0 && curCom < work.childSize())
		{
			comEl = work.childGet(curCom);
			//> Stop process
			if(mode == 0)
			{
				comEl.setAttr("rez","-12:Програму перервано");
				//>> Stop all typical and set "abort" flag
				var cL = comCntrO.nodeList("prm_");
				for(i_c = 0; i_c < cL.length; i_c++)
				{
					comCntrO[cL[i_c]].run.set(false);
					comCntrO[cL[i_c]].abort.set(false);
				}

				SYS.messInfo("uprg"+prog,"Перерваний користувачем сеанс програми \""+prog+"\" : "+SYS.strftime(startTm)+" : "+SYS.strftime(SYS.time()));
				curMode = mode = -3;
			}
			//> Commands process
			else
			{
				//>> Start command
				if(!comEl.attr("tm").length)
				{
					curComPrm.run.set(0);	//> Stop for possible background call
					comEl.setAttr("tm",SYS.time());
					for(i_a = 1; i_a <= 5; i_a++)
						if(!(comA=curComPrm["arg"+i_a]).isEVal())
							comA.set(comEl.attr("arg"+i_a));
					curComPrm.rez.set(0);
					curComPrm.run.set(true);
				}

				//> Update steps status, up to current comand
				comTo = min(curCom+1,work.childSize());
				for(i_c = 0; i_c < comTo; i_c++)
				{
					comElI = work.childGet(i_c);
					curComPI = comCntrO["prm_"+comLs[comElI.attr("id")].prmID];
					if(i_c < curCom && !(curComPI.run.get() && 
						comElI.attr("rez").toInt() != 1 && comElI.attr("rez").toInt() > -10))	continue;
					rez = curComPI.rez.get();
					if(i_c == curCom && rez.toInt() > 0) curCom++;
					if(rez.toInt() < 0)
					{
						//>> Stop all typical and call "error" command
						var cL = comCntrO.nodeList("prm_");
						for(i_c = 0; i_c < cL.length; i_c++)
						{
							comCntrO[cL[i_c]].run.set(false);
							comCntrO[cL[i_c]].error.set(false);
						}

						SYS.messInfo("uprg"+prog,"Перерваний помилкою сеанс програми \""+prog+"\" : "+SYS.strftime(startTm)+" : "+SYS.strftime(SYS.time()));
						curMode = mode = -1;
					}
					comElI.setAttr("rez",rez);
					for(i_a = 1; i_a <= 5; i_a++)
						if(!(comA=curComPI["arg"+i_a]).isEVal())
							comElI.setAttr("arg"+i_a, comA.get());
				}
			}
		}
		
		//> End call
		if(curCom < 0 || curCom >= work.childSize())
		{
			//>> Stop all typical and call "stop" command
			var cL = comCntrO.nodeList("prm_");
			for(i_c = 0; i_c < cL.length; i_c++)
				comCntrO[cL[i_c]].run.set(false);

			curMode = mode = -2;
			SYS.messInfo("uprg"+prog,"Вдалий сеанс програми \""+prog+"\" : "+SYS.strftime(startTm)+" : "+SYS.strftime(SYS.time()));

			//> Place to program last execution time
			rez = SYS.BD.nodeAt(dbDB,".").SQLReq("SELECT prgTxt FROM "+dbProgs+" WHERE name='"+prog+"';");
			if(rez.length > 1)
			{
				//> Parse programm and insert procedure text and argument's labels to here
				comTree = SYS.XMLNode("prg");
				comTree.load(rez[1][0]);
				comTree.setAttr("wtm",SYS.time()-startTm);
				SYS.BD.nodeAt(dbDB,".").SQLReq("UPDATE "+dbProgs+" SET prgTxt='"+comTree.save().replace("'","''")+"' WHERE name='"+prog+"';");
			}
		}
	}
}
mode = curMode;


ID: test
NAME: test
FORMULA:
using Special.FLibSYS;

out+=10;
if(out>100) out=0;

test = (10).toString(16,2,true);
test = (-10.34).toFixed(4,8);

//Request prepare
//req = SYS.XMLNode("#").setAttr("ProtIt","DCON").setAttr("addr",10);
//Send request
//SYS.Transport["Serial"]["out_TestDCON"].messIO(req,"UserProtocol");
//if(!req.attr("err").length) SYS.messDebug("TEST REQ","RES: "+req.text());

//test = "Text \n value[\041abc\x21].";

//test = arguments[4];
//arguments[4] = 10;

//test="Java123Script".search(new RegExp("script","i"));
//text = "Javascript3\"sdf\"3javaScript __ javascript";
//test = text.replace(4,3,"67");
//test = text.replace("3","55");
//test = text.replace(new RegExp("javascript","ig"),"JavaScript");//
//test = text.replace(new RegExp("\"([^\"]*)\"","g"),"``$1''");
//text = "1 плюс 2 плюс 3";
//test = text.match("\\d+","g");
//text = "Посетите мою домашнюю страницу http://www.isp.com/~david";
//test = text.match("(\\w+):\\/\\/([\\w.]+)\\/(\\S*)");
//test = "1,2, 3 , 4 ,5".split(new RegExp("\\s*,\\s*"));
//test = "hello <b>world</b>".split(new RegExp("(<[^>]*>)"));
//var p = new RegExp("(\\d\\d)[-/](\\d\\d)[-/](\\d\\d(?:\\d\\d)?)","");
//test = p.test("abc12/30/1969def");

/*CRC = new Array(0,1,2,3,4,5);vSz = 3
hi=CRC[out%6];
test = hi;*/

//test = SYS.Transport.Sockets.out_testModBus.messIO("123456");

/*obj = new Object();
obj["test1"]=1;l
obj["test2"]=1;
for( var i in obj ) SYS.messDebug("test","Prop: "+i);
SYS.messDebug("test","Props test");*/

//vl = SYS.strFromCharCode(100,200,50,60);
//test = vl.charCodeAt(1);

//test = SYS.system("ps -Ao pid,comm");

//ModBus.Unidrive.pos.pos=out;
//ModBus.testRTU.test.pos=out;
//test = rand(offset*0.4);
//val="Test";
//if( val=="Test1" || val=="Test2" ) test="TestN"; else test="Test";

//test1=new Array(1,"a",2,"b",3,"c",4);
//test1[7]=new Array(5,6,7);
//test=test1[7][1];

//test1="ab;cde;fgh;jk;lm";
//test = test1.split(";").join();

//req = xmlNode("get").setAttr("path","/%2fgen%2fid");
//test = xmlCntrReq(req);
//test = req.text();

/*test1 = vArh("DAQ.System.AutoDA.CPULoad.load");
test2 = test1.FFT(0,60);
test = "";
for( i = 0; i < test2.length; i++ ) test += ""+test2[i]+";";*/

//messPut("cron",0,"Time: "+tmFStr(tmTime()));

/*req = SYS.XMLNode();
test = req.load("test1.xml",true);*/
//for( i = 0; i < req.childSize(); i++ )
//  test += req.childGet(i).attr("id")+"; ";
/*sutm = 0; stm = SYS.time(sutm);
req.save(0,"test2.xml");
eutm = 0; etm = SYS.time(eutm);
test = 1e6*(etm-stm)+(eutm-sutm);*/

//test = strDec4Bin(Transport.Sockets.out_testModBus.messIO(strEnc2Bin("15 01 00 00 00 06 01 03 00 00 00 05")));

/*req = SYS.XMLNode("GET");
req.setAttr("URI","/");
SYS.Transport.Sockets.out_testHTTP.messIO(req,"HTTP");
test = req.text();*/

/*req = SYS.XMLNode("POST");
req.setAttr("URI","/WebUser/FlowTec.txt");
cntNode = req.childAdd("cnt").setAttr("name","pole0").setAttr("filename","Object2-k001-100309-17.txt");
cntNode.childAdd("prm").setAttr("id","Content-Type").setText("text/plain");
cntText = "Object2-k001\r\n";
cntText += "\r\n";
cntText += "v002\r\n";
cntText += " n1\r\n";
cntText += "  09.03.10 16   Polnyj    7155.25    216.0  32.000  17.5\r\n";
cntText += "v005\r\n";
cntText += " n1\r\n";
cntText += "  09.03.10 16   Polnyj     188.81    350.0   4.000  40.0\r\n";
cntText += "\r\n";
cntNode.setText(cntText);
SYS.Transport.Sockets.out_testHTTP.messIO(req,"HTTP");*/

//test = SYS.UI.VCAEngine["ses_AGLKS"].alrmSndPlay();
//test = "1;2;5;7;9";
//test = "1;2;5;7;9".type();

//SYS.messDebug("test",strEnc2Bin("68 74 74 70 3a 2f 2f 77 77 77 2e 77 33 2e 6f 72 67 2f 32 30 30 30 2f 30 39 2f 78 6d 6c 64 73 69 67 23 72 73 61 2d 73 68 61 31"));

//test = SYS.DAQ.ModBus.testTCP.test.a_8_1_1_ПС_ОПД_стенд_температура__ОПД_.get();

/*req = SYS.XMLNode("get").setAttr("path","/%2fgen%2fid");
rez = SYS.cntrReq(req,"loop");
test = req.text();*/

/*DBTbl=SYS.BD.MySQL.GenDB.SQLReq("SELECT * from DB;");
for( var i_rw = 0; i_rw < DBTbl.length; i_rw++ )
{
  var rec = "";
  for( var i_fld = 0; i_fld < DBTbl[i_rw].length; i_fld++ )
    rec += DBTbl[i_rw][i_fld]+"\t";
  SYS.messDebug("TEST DB","Row "+i_rw+": "+rec);
}*/


ID: test1
NAME: test1
FORMULA:
//clc=0;
//First getting previous time
//if(!p_tm){ p_tm = Special.FLibSYS.tmTime(); break; }

//Get curent time
//c_tm = Special.FLibSYS.tmTime()-2;

//Open value archive
//a_id = Special.FLibSYS.avalOpen("Archive.va_test");
//if(a_id==-1) break;

//Calc average archive
//for(i_tm=p_tm;i_tm<c_tm;i_tm++)
//{ 
//  val = Special.FLibSYS.avalGetR(a_id,i_tm,0,"");
//  rez = (rez*(i_tm-p_tm)+val)/(i_tm-p_tm+1);
//  clc++;
//}

//Close value archive
//Special.FLibSYS.avalClose(a_id);
//p_tm=c_tm;


# lib_servProc

ID: procArh
NAME: Archives recalc
uk#NAME: Перерахунок архівів
ru#NAME: Пересчёт архивов
FORMULA:
using Special.FLibSYS;

//messPut("UserProc/ProcessArch",1,"Archive open");
a_src = vArh(fromarch);
a_dst = vArh(toarch);

//messPut("UserProc/ProcessArch",1,"Archive process");

bf_per = 100;	//Buffers period microseconds
bf_size = 100000;	//Buffers size

//Open value buffers
bf_src = vArhBuf(1,bf_size,bf_per,true,true);
bf_dst = vArhBuf(4,bf_size,bf_per,true,true);

//Parse time string
begtm = tmStrPTime(begs);
endtm = tmStrPTime(ends);

begwtm = begtm;
while( begwtm<endtm )
{
    //Get value
    endwtm = begwtm+bf_size*bf_per/1000000;
    if(endwtm>endtm) endwtm = endtm;
    messPut("UserProc/ProcessArch",1,"Values from: "+begwtm+", to: "+endwtm);
    bf_src.copy(a_src,begwtm,0,endwtm,0);

    buf_beg = begwtm; buf_beg_u = 0;
    buf_end = endwtm; buf_end_u = 0;
    while( !(buf_beg>=buf_end && buf_beg_u>buf_end_u) )
    {
        r_val = bf_src.get(buf_beg,buf_beg_u,true);
        if(r_val == EVAL_INT) bf_dst.set(EVAL_REAL,buf_beg,buf_beg_u);
        else bf_dst.set(200.*((10.*r_val/32768.)-1.)/4.,buf_beg,buf_beg_u);

        buf_beg_u++;
    }

    a_dst.copy(bf_dst,begwtm,0,endwtm,0);
    begwtm = endwtm;
}

uk#FORMULA:
using Special.FLibSYS;

//messPut("UserProc/ProcessArch",1,"Відкриття архівів");
a_src = vArh(fromarch);
a_dst = vArh(toarch);

//messPut("UserProc/ProcessArch",1,"Обробка архівів");

bf_per = 100;	//Buffers period microseconds
bf_size = 100000;	//Buffers size

//Open value buffers
bf_src = vArhBuf(1,bf_size,bf_per,true,true);
bf_dst = vArhBuf(4,bf_size,bf_per,true,true);

//Parse time string
begtm = tmStrPTime(begs);
endtm = tmStrPTime(ends);

begwtm = begtm;
while( begwtm<endtm )
{
    //Get value
    endwtm = begwtm+bf_size*bf_per/1000000;
    if(endwtm>endtm) endwtm = endtm;
    messPut("UserProc/ProcessArch",1,"Values from: "+begwtm+", to: "+endwtm);
    bf_src.copy(a_src,begwtm,0,endwtm,0);

    buf_beg = begwtm; buf_beg_u = 0;
    buf_end = endwtm; buf_end_u = 0;
    while( !(buf_beg>=buf_end && buf_beg_u>buf_end_u) )
    {
        r_val = bf_src.get(buf_beg,buf_beg_u,true);
        if(r_val == EVAL_INT) bf_dst.set(EVAL_REAL,buf_beg,buf_beg_u);
        else bf_dst.set(200.*((10.*r_val/32768.)-1.)/4.,buf_beg,buf_beg_u);

        buf_beg_u++;
    }

    a_dst.copy(bf_dst,begwtm,0,endwtm,0);
    begwtm = endwtm;
}

ru#FORMULA:
using Special.FLibSYS;

//messPut("UserProc/ProcessArch",1,"Открытие архивов");
a_src = vArh(fromarch);
a_dst = vArh(toarch);

//messPut("UserProc/ProcessArch",1,"Обработка архивов");

bf_per = 100;	//Buffers period microseconds
bf_size = 100000;	//Buffers size

//Open value buffers
bf_src = vArhBuf(1,bf_size,bf_per,true,true);
bf_dst = vArhBuf(4,bf_size,bf_per,true,true);

//Parse time string
begtm = tmStrPTime(begs);
endtm = tmStrPTime(ends);

begwtm = begtm;
while( begwtm<endtm )
{
    //Get value
    endwtm = begwtm+bf_size*bf_per/1000000;
    if(endwtm>endtm) endwtm = endtm;
    messPut("UserProc/ProcessArch",1,"Values from: "+begwtm+", to: "+endwtm);
    bf_src.copy(a_src,begwtm,0,endwtm,0);

    buf_beg = begwtm; buf_beg_u = 0;
    buf_end = endwtm; buf_end_u = 0;
    while( !(buf_beg>=buf_end && buf_beg_u>buf_end_u) )
    {
        r_val = bf_src.get(buf_beg,buf_beg_u,true);
        if(r_val == EVAL_INT) bf_dst.set(EVAL_REAL,buf_beg,buf_beg_u);
        else bf_dst.set(200.*((10.*r_val/32768.)-1.)/4.,buf_beg,buf_beg_u);

        buf_beg_u++;
    }

    a_dst.copy(bf_dst,begwtm,0,endwtm,0);
    begwtm = endwtm;
}


ID: crc16
NAME: CRC 16
FORMULA:
out = 0xFFFF;
for( i = 0; i < in.length; i++ )
{
  out = out^in.charCodeAt(i);
  for( j=0; j<8; j++ ) out = (out&1) ? ((out>>1)^0xA001) : out >> 1;
}


ID: releaseTests
NAME: Release tests
FORMULA:
nNm = "testNode";
node  = false;		//Process node
testREZ = "";		//Test rezult
rez = "";

//**********************************
//> Get config file name
SYS.cntrReq(req=SYS.XMLNode("get").setAttr("path","/%2fgen%2fconfig"));
configPath = req.text();
//> Save original config file
SYS.fileWrite(configPath+".orig",SYS.fileRead(configPath));
//> Load config file tree
cfgTree=SYS.XMLNode();
cfgTree.load(configPath,true,true);

//**********************************
//> System
if(sub <= 0)
{
	testREZ = SYS.Special.SystemTests.XML(configPath);
	rez += "<tr><td>Control interface: Test of the XML file parsing</td><td>"+testREZ+"</td></tr>\n";
	testREZ = SYS.Special.SystemTests.SysContrLang("/Archive/FSArch/mess_StatErrors/%2fprm%2fst");
	rez += "<tr><td>Control interface: Test of the control system language</td><td>"+testREZ+"</td></tr>\n";
	testREZ = SYS.Special.SystemTests.Base64Code();
	rez += "<tr><td>SYS: Tests of the Mime Base64 encoding algorithm</td><td>"+testREZ+"</td></tr>\n";
}

//**********************************
//> Security User/Group tests
if(sub < 0 || sub == 1)
{
	testREZ = "PASSED";
	//>> User
	nAddr = "/Security/usr_"+nNm;
	if(SYS.cntrReq(SYS.XMLNode("add").setAttr("path","/Security/%2fbr%2fusr_").setText(nNm)) != 0 || !(node=SYS.nodeAt(nAddr))) testREZ = "FAILED: user add";
	else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr+"/%2fprm%2fdscr").setText("Test")) != 0 || node.cfg("DESCR") != "Test") testREZ = "FAILED: change user";
	else if(SYS.cntrReq(SYS.XMLNode("save").setAttr("path",nAddr+"/%2fobj")) != 0) testREZ = "FAILED: save user";
	else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr+"/%2fprm%2fdscr").setText("Test 1")) != 0 || 
		SYS.cntrReq(SYS.XMLNode("load").setAttr("path",nAddr+"/%2fobj")) != 0 || node.cfg("DESCR") != "Test") testREZ = "FAILED: load user";
	else
	{
		node = false;
		if(SYS.cntrReq(SYS.XMLNode("del").setAttr("path","/Security/%2fbr%2fusr_").setText(nNm)) != 0 || SYS.nodeAt(nAddr)) testREZ = "FAILED: user delete";
		else
		{
			cfgTree.getElementBy("sub_Security").childAdd("tbl").setAttr("id","Security_user").childAdd("fld").setAttr("NAME",nNm+"_cfg");
			cfgTree.save(0x20, configPath);
			SYS.cntrReq(SYS.XMLNode("scan").setAttr("path","/%2fgen%2fconfig"));		//Reload config command
			if(!SYS.nodeAt(nAddr+"_cfg")) testREZ = "FAILED: load user from config";
		}
	}
	//> Group
	nAddr = "/Security/grp_"+nNm;
	if(testREZ == "PASSED" && (SYS.cntrReq(SYS.XMLNode("add").setAttr("path","/Security/%2fbr%2fgrp_").setText(nNm)) != 0 || !(node=SYS.nodeAt(nAddr)))) testREZ = "FAILED: group add";
	else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr+"/%2fprm%2fdscr").setText("Test")) != 0 || node.cfg("DESCR") != "Test") testREZ = "FAILED: change group";
	else if(SYS.cntrReq(SYS.XMLNode("save").setAttr("path",nAddr+"/%2fobj")) != 0) testREZ = "FAILED: save group";
	else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr+"/%2fprm%2fdscr").setText("Test 1")) != 0 || 
		SYS.cntrReq(SYS.XMLNode("load").setAttr("path",nAddr+"/%2fobj")) != 0 || node.cfg("DESCR") != "Test") testREZ = "FAILED: load group";
	else
	{
		node = false;
		if(SYS.cntrReq(SYS.XMLNode("del").setAttr("path","/Security/%2fbr%2fgrp_").setText(nNm)) != 0 || SYS.nodeAt(nAddr)) testREZ = "FAILED: group delete";
		else
		{
			cfgTree.getElementBy("sub_Security").childAdd("tbl").setAttr("id","Security_grp").childAdd("fld").setAttr("NAME",nNm+"_cfg").setAttr("USERS",nNm+"_cfg");
			cfgTree.save(0x20, configPath);
			SYS.cntrReq(SYS.XMLNode("scan").setAttr("path","/%2fgen%2fconfig"));		//Reload config command
			if(!SYS.nodeAt(nAddr+"_cfg")) testREZ = "FAILED: load group from config";
		}
	}
	rez += "<tr><td>Security: User/Group create/remove, change, load, save and load from config</td><td>"+testREZ+"</td></tr>\n";
}

//**********************************
//> Transport subsystem tests
if(sub < 0 || sub == 2)
{
	nList = SYS.Transport.nodeList("mod_");
	cfgTree.getElementBy("sub_Transport").childAdd("tbl").setAttr("id","Transport_in");
	cfgTree.getElementBy("sub_Transport").childAdd("tbl").setAttr("id","Transport_out");
	for(i_n = 0; i_n < nList.length; i_n++)
	{
		testREZ = "PASSED";
		//> Input transport
		nAddr = "/Transport/"+nList[i_n]+"/in_"+nNm;
		if(SYS.cntrReq(SYS.XMLNode("add").setAttr("path","/Transport/"+nList[i_n]+"/%2fbr%2fin_").setAttr("id",nNm)) != 0 || !(node=SYS.nodeAt(nAddr))) testREZ = "FAILED: input add";
		else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr+"/%2fprm%2fcfg%2fdscr").setText("Test")) != 0 || node.cfg("DESCRIPT") != "Test") testREZ = "FAILED: change input";
		else if(SYS.cntrReq(SYS.XMLNode("save").setAttr("path",nAddr+"/%2fobj")) != 0) testREZ = "FAILED: save input";
		else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr+"/%2fprm%2fcfg%2fdscr").setText("Test 1")) != 0 || 
			SYS.cntrReq(SYS.XMLNode("load").setAttr("path",nAddr+"/%2fobj")) != 0 || node.cfg("DESCRIPT") != "Test") testREZ = "FAILED: load input";
		else
		{
			node = false;
			if(SYS.cntrReq(SYS.XMLNode("del").setAttr("path","/Transport/"+nList[i_n]+"/%2fbr%2fin_").setAttr("id",nNm)) != 0 || SYS.nodeAt(nAddr)) testREZ = "FAILED: input delete";
			else
			{
				cfgTree.getElementBy("Transport_in").childAdd("fld").setAttr("ID",nNm+"_cfg").setAttr("MODULE",nList[i_n].slice(4));
				cfgTree.save(0x20, configPath);
				SYS.cntrReq(SYS.XMLNode("scan").setAttr("path","/%2fgen%2fconfig"));		//Reload config command
				if(!SYS.nodeAt(nAddr+"_cfg")) testREZ = "FAILED: load input from config";
			}
		}
		//> Output transport
		nAddr = "/Transport/"+nList[i_n]+"/out_"+nNm;
		if(testREZ == "PASSED" && (SYS.cntrReq(SYS.XMLNode("add").setAttr("path","/Transport/"+nList[i_n]+"/%2fbr%2fout_").setAttr("id",nNm)) != 0 || !(node=SYS.nodeAt(nAddr)))) testREZ = "FAILED: output add";
		else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr+"/%2fprm%2fcfg%2fdscr").setText("Test")) != 0 || node.cfg("DESCRIPT") != "Test") testREZ = "FAILED: change output";
		else if(SYS.cntrReq(SYS.XMLNode("save").setAttr("path",nAddr+"/%2fobj")) != 0) testREZ = "FAILED: save output";
		else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr+"/%2fprm%2fcfg%2fdscr").setText("Test 1")) != 0 || 
			SYS.cntrReq(SYS.XMLNode("load").setAttr("path",nAddr+"/%2fobj")) != 0 || node.cfg("DESCRIPT") != "Test") testREZ = "FAILED: load output";
		else
		{
			node = false;
			if(SYS.cntrReq(SYS.XMLNode("del").setAttr("path","/Transport/"+nList[i_n]+"/%2fbr%2fout_").setAttr("id",nNm)) != 0 || SYS.nodeAt(nAddr)) testREZ = "FAILED: output delete";
			else
			{
				cfgTree.getElementBy("Transport_out").childAdd("fld").setAttr("ID",nNm+"_cfg").setAttr("MODULE",nList[i_n].slice(4));
				cfgTree.save(0x20, configPath);
				SYS.cntrReq(SYS.XMLNode("scan").setAttr("path","/%2fgen%2fconfig"));		//Reload config command
				if(!SYS.nodeAt(nAddr+"_cfg")) testREZ = "FAILED: load output from config";
			}
		}
		rez += "<tr><td>Transport."+nList[i_n].slice(4)+": Input/Output create/remove, change, load, save and load from config</td><td>"+testREZ+"</td></tr>\n";

		//> Disconnect/Connect module
		req = SYS.XMLNode("get").setAttr("path","/Transport/"+nList[i_n]+"/%2fhelp%2fm_inf%2fSource");
		SYS.cntrReq(req);
		testREZ = SYS.Special.SystemTests.SOAttach(req.text(),0);
		testREZ += "/"+SYS.Special.SystemTests.SOAttach(req.text(),0);
		rez += "<tr><td>Transport."+nList[i_n].slice(4)+": Disconnect/Connect</td><td>"+testREZ+"</td></tr>\n";
	}
}

//**********************************
//> Archive subsystem tests
if(sub < 0 || sub == 3)
{
	testREZ = SYS.Special.SystemTests.ValBuf();
	rez += "<tr><td>Archive: Tests of the values' buffer.</td><td>"+testREZ+"</td></tr>\n";

	//>> Value archive
	testREZ = "PASSED";
	nAddr = "/Archive/va_"+nNm;
	if(SYS.cntrReq(SYS.XMLNode("add").setAttr("path","/Archive/%2fbr%2fva_").setAttr("id",nNm)) != 0 || !(node=SYS.nodeAt(nAddr))) testREZ = "FAILED: add";
	else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr+"/%2fprm%2fcfg%2fdscr").setText("Test")) != 0 || node.cfg("DESCR") != "Test") testREZ = "FAILED: change";
	else if(SYS.cntrReq(SYS.XMLNode("save").setAttr("path",nAddr+"/%2fobj")) != 0) testREZ = "FAILED: save";
	else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr+"/%2fprm%2fcfg%2fdscr").setText("Test 1")) != 0 || 
		SYS.cntrReq(SYS.XMLNode("load").setAttr("path",nAddr+"/%2fobj")) != 0 || node.cfg("DESCR") != "Test") testREZ = "FAILED: load";
	else
	{
		node = false;
		if(SYS.cntrReq(SYS.XMLNode("del").setAttr("path","/Archive/%2fbr%2fva_").setAttr("id",nNm)) != 0 || SYS.nodeAt(nAddr)) testREZ = "FAILED: delete";
		else
		{
			cfgTree.getElementBy("sub_Archive").childAdd("tbl").setAttr("id","Archive_val").childAdd("fld").setAttr("ID",nNm+"_cfg");
			cfgTree.save(0x20, configPath);
			SYS.cntrReq(SYS.XMLNode("scan").setAttr("path","/%2fgen%2fconfig"));		//Reload config command
			if(!SYS.nodeAt(nAddr+"_cfg")) testREZ = "FAILED: load from config";
		}
	}
	rez += "<tr><td>Archive: Value archive create/remove, change, load, save and load from config</td><td>"+testREZ+"</td></tr>\n";

	//>> Archivators
	nList = SYS.Archive.nodeList("mod_");
	cfgTree.getElementBy("sub_Archive").childAdd("tbl").setAttr("id","Archive_mess_proc");
	cfgTree.getElementBy("sub_Archive").childAdd("tbl").setAttr("id","Archive_val_proc");
	for(i_n = 0; i_n < nList.length; i_n++)
	{
		testREZ = "PASSED";
		//> Messages archivator
		nAddr = "/Archive/"+nList[i_n]+"/mess_"+nNm;
		if(SYS.cntrReq(SYS.XMLNode("add").setAttr("path","/Archive/"+nList[i_n]+"/%2fbr%2fmess_").setAttr("id",nNm)) != 0 || !(node=SYS.nodeAt(nAddr))) testREZ = "FAILED: messages add";
		else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr+"/%2fprm%2fcfg%2fdscr").setText("Test")) != 0 || node.cfg("DESCR") != "Test") testREZ = "FAILED: change messages";
		else if(SYS.cntrReq(SYS.XMLNode("save").setAttr("path",nAddr+"/%2fobj")) != 0) testREZ = "FAILED: save messages";
		else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr+"/%2fprm%2fcfg%2fdscr").setText("Test 1")) != 0 || 
			SYS.cntrReq(SYS.XMLNode("load").setAttr("path",nAddr+"/%2fobj")) != 0 || node.cfg("DESCR") != "Test") testREZ = "FAILED: load messages";
		else 
		{
			node = false;
			if(SYS.cntrReq(SYS.XMLNode("del").setAttr("path","/Archive/"+nList[i_n]+"/%2fbr%2fmess_").setAttr("id",nNm)) != 0 || SYS.nodeAt(nAddr)) testREZ = "FAILED: messages delete";
			else
			{
				cfgTree.getElementBy("Archive_mess_proc").childAdd("fld").setAttr("ID",nNm+"_cfg").setAttr("MODUL",nList[i_n].slice(4));
				cfgTree.save(0x20, configPath);
				SYS.cntrReq(SYS.XMLNode("scan").setAttr("path","/%2fgen%2fconfig"));		//Reload config command
				if(!SYS.nodeAt(nAddr+"_cfg")) testREZ = "FAILED: load messages from config";
			}
		}
		//> Value archivator
		nAddr = "/Archive/"+nList[i_n]+"/val_"+nNm;
		if(testREZ == "PASSED" && (SYS.cntrReq(SYS.XMLNode("add").setAttr("path","/Archive/"+nList[i_n]+"/%2fbr%2fval_").setAttr("id",nNm)) != 0 || !(node=SYS.nodeAt(nAddr)))) testREZ = "FAILED: values add";
		else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr+"/%2fprm%2fcfg%2fdscr").setText("Test")) != 0 || node.cfg("DESCR") != "Test") testREZ = "FAILED: change values";
		else if(SYS.cntrReq(SYS.XMLNode("save").setAttr("path",nAddr+"/%2fobj")) != 0) testREZ = "FAILED: save values";
		else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr+"/%2fprm%2fcfg%2fdscr").setText("Test 1")) != 0 || 
			SYS.cntrReq(SYS.XMLNode("load").setAttr("path",nAddr+"/%2fobj")) != 0 || node.cfg("DESCR") != "Test") testREZ = "FAILED: load values";
		else 
		{
			node = false;
			if(SYS.cntrReq(SYS.XMLNode("del").setAttr("path","/Archive/"+nList[i_n]+"/%2fbr%2fval_").setAttr("id",nNm)) != 0 || SYS.nodeAt(nAddr)) testREZ = "FAILED: values delete";
			else
			{
				cfgTree.getElementBy("Archive_val_proc").childAdd("fld").setAttr("ID",nNm+"_cfg").setAttr("MODUL",nList[i_n].slice(4));
				cfgTree.save(0x20, configPath);
				SYS.cntrReq(SYS.XMLNode("scan").setAttr("path","/%2fgen%2fconfig"));		//Reload config command
				if(!SYS.nodeAt(nAddr+"_cfg")) testREZ = "FAILED: load values from config";
			}
		}
		rez += "<tr><td>Archive."+nList[i_n].slice(4)+": Messages/Values create/remove, change, load, save and load from config</td><td>"+testREZ+"</td></tr>\n";

		//> Disconnect/Connect module
		req = SYS.XMLNode("get").setAttr("path","/Archive/"+nList[i_n]+"/%2fhelp%2fm_inf%2fSource");
		SYS.cntrReq(req);
		testREZ = SYS.Special.SystemTests.SOAttach(req.text(),0);
		testREZ += "/"+SYS.Special.SystemTests.SOAttach(req.text(),0);
		rez += "<tr><td>Archive."+nList[i_n].slice(4)+": Disconnect/Connect</td><td>"+testREZ+"</td></tr>\n";
	}
}

//**********************************
//> DB subsystem tests
if(sub < 0 || sub == 4)
{
	nList = SYS.BD.nodeList("mod_");
	for(i_n = 0; i_n < nList.length; i_n++)
	{
		testREZ = "PASSED";
		//> Messages archivator
		nAddr = "/BD/"+nList[i_n]+"/db_"+nNm;
		if(SYS.cntrReq(SYS.XMLNode("add").setAttr("path","/BD/"+nList[i_n]+"/%2fbr%2fdb_").setAttr("id",nNm)) != 0 || !(node=SYS.nodeAt(nAddr))) testREZ = "FAILED: add";
		else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr+"/%2fprm%2fcfg%2fdscr").setText("Test")) != 0 || node.cfg("DESCR") != "Test") testREZ = "FAILED: change";
		else if(SYS.cntrReq(SYS.XMLNode("save").setAttr("path",nAddr+"/%2fobj")) != 0) testREZ = "FAILED: save";
		else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr+"/%2fprm%2fcfg%2fdscr").setText("Test 1")) != 0 || 
			SYS.cntrReq(SYS.XMLNode("load").setAttr("path",nAddr+"/%2fobj")) != 0 || node.cfg("DESCR") != "Test") testREZ = "FAILED: load";
		else 
		{
			node = false;
			if(SYS.cntrReq(SYS.XMLNode("del").setAttr("path","/BD/"+nList[i_n]+"/%2fbr%2fdb_").setAttr("id",nNm)) != 0 || SYS.nodeAt(nAddr)) testREZ = "FAILED: delete";
			else
			{
				cfgTree.getElementBy("DB").childAdd("fld").setAttr("ID",nNm+"_cfg").setAttr("TYPE",nList[i_n].slice(4)).setAttr("EN",0);
				cfgTree.save(0x20, configPath);
				SYS.cntrReq(SYS.XMLNode("scan").setAttr("path","/%2fgen%2fconfig"));		//Reload config command
				if(!SYS.nodeAt(nAddr+"_cfg")) testREZ = "FAILED: load from config";
			}
		}
		rez += "<tr><td>DB."+nList[i_n].slice(4)+": create/remove, change, load, save and load from config</td><td>"+testREZ+"</td></tr>\n";

		//> Disconnect/Connect module
		req = SYS.XMLNode("get").setAttr("path","/BD/"+nList[i_n]+"/%2fhelp%2fm_inf%2fSource");
		SYS.cntrReq(req);
		testREZ = SYS.Special.SystemTests.SOAttach(req.text(),0);
		testREZ += "/"+SYS.Special.SystemTests.SOAttach(req.text(),0);
		rez += "<tr><td>DB."+nList[i_n].slice(4)+": Disconnect/Connect</td><td>"+testREZ+"</td></tr>\n";
	}
}

//**********************************
//> Protocol subsystem tests
if(sub < 0 || sub == 5)
{
	nList = SYS.Protocol.nodeList("mod_");
	for(i_n = 0; i_n < nList.length; i_n++)
	{
		//> Disconnect/Connect module
		req = SYS.XMLNode("get").setAttr("path","/Protocol/"+nList[i_n]+"/%2fhelp%2fm_inf%2fSource");
		SYS.cntrReq(req);
		testREZ = SYS.Special.SystemTests.SOAttach(req.text(),0);
		testREZ += "/"+SYS.Special.SystemTests.SOAttach(req.text(),0);
		rez += "<tr><td>Protocol."+nList[i_n].slice(4)+": Disconnect/Connect</td><td>"+testREZ+"</td></tr>\n";
	}
}

//**********************************
//> DAQ subsystem tests
if(sub < 0 || sub == 6)
{
	//>> Templates
	testREZ = "PASSED";
	nAddr = "/DAQ/tmplb_"+nNm;
	if(SYS.cntrReq(SYS.XMLNode("add").setAttr("path","/DAQ/%2fbr%2ftmplb_").setAttr("id",nNm)) != 0 || !(node=SYS.nodeAt(nAddr))) testREZ = "FAILED: template library add";
	else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr+"/%2flib%2fcfg%2fdescr").setText("Test")) != 0 || node.cfg("DESCR") != "Test") testREZ = "FAILED: change template library";
	else if(SYS.cntrReq(SYS.XMLNode("save").setAttr("path",nAddr+"/%2fobj")) != 0) testREZ = "FAILED: save template library";
	else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr+"/%2flib%2fcfg%2fdescr").setText("Test 1")) != 0 || 
		SYS.cntrReq(SYS.XMLNode("load").setAttr("path",nAddr+"/%2fobj")) != 0 || node.cfg("DESCR") != "Test") testREZ = "FAILED: load template library";
	else
	{
		node = false;

		//>> Template
		nAddrLb = nAddr+"/tmpl_"+nNm;
		if(SYS.cntrReq(SYS.XMLNode("add").setAttr("path",nAddr+"/%2fbr%2ftmpl_").setAttr("id",nNm)) != 0 || !(node=SYS.nodeAt(nAddrLb))) testREZ = "FAILED: template add";
		else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddrLb+"/%2ftmpl%2fcfg%2fdescr").setText("Test")) != 0 || node.cfg("DESCR") != "Test") testREZ = "FAILED: change template";
		else if(SYS.cntrReq(SYS.XMLNode("save").setAttr("path",nAddrLb+"/%2fobj")) != 0) testREZ = "FAILED: save template";
		else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddrLb+"/%2ftmpl%2fcfg%2fdescr").setText("Test 1")) != 0 || 
			SYS.cntrReq(SYS.XMLNode("load").setAttr("path",nAddrLb+"/%2fobj")) != 0 || node.cfg("DESCR") != "Test") testREZ = "FAILED: load template";
		node = false;

		if(SYS.cntrReq(SYS.XMLNode("del").setAttr("path","/DAQ/%2fbr%2ftmplb_").setAttr("id",nNm)) != 0 || SYS.nodeAt(nAddr)) testREZ = "FAILED: template library delete";
		else
		{
			cfgTree.getElementBy("sub_DAQ").childAdd("tbl").setAttr("id","tmplib").childAdd("fld").setAttr("ID",nNm+"_cfg").setAttr("DB","tmplib_"+nNm+"_cfg");
			cfgTree.getElementBy("sub_DAQ").childAdd("tbl").setAttr("id","tmplib_"+nNm+"_cfg").childAdd("fld").setAttr("ID",nNm+"_cfg");
			cfgTree.save(0x20, configPath);
			SYS.cntrReq(SYS.XMLNode("scan").setAttr("path","/%2fgen%2fconfig"));		//Reload config command
			if(!SYS.nodeAt(nAddr+"_cfg") || !SYS.nodeAt(nAddr+"_cfg/tmpl_"+nNm+"_cfg")) testREZ = "FAILED: load template library from config";
		}
	}
	rez += "<tr><td>DAQ: Templates library create/remove, change, load, save and load from config</td><td>"+testREZ+"</td></tr>\n";

	//>> Modules
	nList = SYS.DAQ.nodeList("mod_");
	for(i_n = 0; i_n < nList.length; i_n++)
	{
		testREZ = "PASSED";
		testREZ_ = "PASSED";
		//> Controller
		nAddr = "/DAQ/"+nList[i_n]+"/cntr_"+nNm;
		if(SYS.cntrReq(SYS.XMLNode("add").setAttr("path","/DAQ/"+nList[i_n]+"/%2fbr%2fcntr_").setAttr("id",nNm)) != 0 || !(node=SYS.nodeAt(nAddr))) testREZ = "FAILED: controller add";
		else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr+"/%2fcntr%2fcfg%2fDESCR").setText("Test")) != 0 || node.cfg("DESCR") != "Test") testREZ = "FAILED: controller change";
		else if(SYS.cntrReq(SYS.XMLNode("save").setAttr("path",nAddr+"/%2fobj")) != 0) testREZ = "FAILED: controller save";
		else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr+"/%2fcntr%2fcfg%2fDESCR").setText("Test 1")) != 0 || 
			SYS.cntrReq(SYS.XMLNode("load").setAttr("path",nAddr+"/%2fobj")) != 0 || node.cfg("DESCR") != "Test") testREZ = "FAILED: controller load";
		else 
		{
			node = false;

			//>> Parameter
			if(nList[i_n] != "mod_DAQGate")
			{
				nAddr1 = nAddr+"/prm_"+nNm;
				if(SYS.cntrReq(SYS.XMLNode("add").setAttr("path",nAddr+"/%2fbr%2fprm_").setAttr("id",nNm)) != 0 || !(node=SYS.nodeAt(nAddr1))) testREZ = "FAILED: parameter add";
				else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr1+"/%2fprm%2fcfg%2fDESCR").setText("Test")) != 0 || node.cfg("DESCR") != "Test") testREZ = "FAILED: parameter change";
				else if(SYS.cntrReq(SYS.XMLNode("save").setAttr("path",nAddr1+"/%2fobj")) != 0) testREZ = "FAILED: parameter save";
				else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr1+"/%2fprm%2fcfg%2fDESCR").setText("Test 1")) != 0 || 
					SYS.cntrReq(SYS.XMLNode("load").setAttr("path",nAddr1+"/%2fobj")) != 0 || node.cfg("DESCR") != "Test") testREZ = "FAILED: parameter load";
				node = false;
			}

			if(nList[i_n] == "mod_BlockCalc")
			{
				nAddr1 = nAddr+"/blk_"+nNm;
				if(SYS.cntrReq(SYS.XMLNode("add").setAttr("path",nAddr+"/%2fbr%2fblk_").setAttr("id",nNm)) != 0 || !(node=SYS.nodeAt(nAddr1))) testREZ_ = "FAILED: block add";
				else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr1+"/%2fblck%2fcfg%2fdescr").setText("Test")) != 0 || node.cfg("DESCR") != "Test") testREZ_ = "FAILED: block change";
				else if(SYS.cntrReq(SYS.XMLNode("save").setAttr("path",nAddr1+"/%2fobj")) != 0) testREZ_ = "FAILED: block save";
				else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr1+"/%2fblck%2fcfg%2fdescr").setText("Test 1")) != 0 || 
					SYS.cntrReq(SYS.XMLNode("load").setAttr("path",nAddr1+"/%2fobj")) != 0 || node.cfg("DESCR") != "Test") testREZ_ = "FAILED: block load";
				node = false;
			}
			if(nList[i_n] == "mod_JavaLikeCalc")
			{
				nAddr_ = "/DAQ/"+nList[i_n]+"/lib_"+nNm;
				if(SYS.cntrReq(SYS.XMLNode("add").setAttr("path","/DAQ/"+nList[i_n]+"/%2fbr%2flib_").setAttr("id",nNm)) != 0 || !(node=SYS.nodeAt(nAddr_))) testREZ_ = "FAILED: library add";
				else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr_+"/%2flib%2fcfg%2fdescr").setText("Test")) != 0 || node.cfg("DESCR") != "Test") testREZ_ = "FAILED: library change";
				else if(SYS.cntrReq(SYS.XMLNode("save").setAttr("path",nAddr_+"/%2fobj")) != 0) testREZ_ = "FAILED: library save";
				else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr_+"/%2flib%2fcfg%2fdescr").setText("Test 1")) != 0 || 
					SYS.cntrReq(SYS.XMLNode("load").setAttr("path",nAddr_+"/%2fobj")) != 0 || node.cfg("DESCR") != "Test") testREZ_ = "FAILED: library load";
				else
				{
					node = false;

					//>> Function
					nAddr_1 = nAddr_+"/fnc_"+nNm;
					if(SYS.cntrReq(SYS.XMLNode("add").setAttr("path",nAddr_+"/%2fbr%2ffnc_").setAttr("id",nNm)) != 0 || !(node=SYS.nodeAt(nAddr_1))) testREZ_ = "FAILED: function add";
					else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr_1+"/%2ffunc%2fcfg%2fdescr").setText("Test")) != 0 || node.cfg("DESCR") != "Test") testREZ_ = "FAILED: function change";
					else if(SYS.cntrReq(SYS.XMLNode("save").setAttr("path",nAddr_1+"/%2fobj")) != 0) testREZ_ = "FAILED: function save";
					else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr_1+"/%2ffunc%2fcfg%2fdescr").setText("Test 1")) != 0 || 
						SYS.cntrReq(SYS.XMLNode("load").setAttr("path",nAddr_1+"/%2fobj")) != 0 || node.cfg("DESCR") != "Test") testREZ_ = "FAILED: function load";
					node = false;
					if(SYS.cntrReq(SYS.XMLNode("del").setAttr("path","/DAQ/"+nList[i_n]+"/%2fbr%2flib_").setAttr("id",nNm)) != 0 || SYS.nodeAt(nAddr_)) testREZ_ = "FAILED: function delete";
				}			
			}

			if(SYS.cntrReq(SYS.XMLNode("del").setAttr("path","/DAQ/"+nList[i_n]+"/%2fbr%2fcntr_").setAttr("id",nNm)) != 0 || SYS.nodeAt(nAddr)) testREZ = "FAILED: controller delete";
			else
			{
				treeNd = cfgTree.getElementBy("sub_DAQ");
				if(!treeNd.getElementBy(nList[i_n])) treeNd.childAdd("node").setAttr("id",nList[i_n]);
				treeNd = treeNd.getElementBy(nList[i_n]);

				treeNd_t = treeNd.childAdd("tbl").setAttr("id","DAQ").childAdd("fld").setAttr("ID",nNm+"_cfg").setAttr("PRM_BD",nNm+"_cfg_prm").setAttr("ENABLE",1);
				if(nList[i_n] == "mod_JavaLikeCalc") treeNd_t.setAttr("FUNC","servProc.fnc_crc16");
				treeNd.childAdd("tbl").setAttr("id",nNm+"_cfg_prm").childAdd("fld").setAttr("SHIFR",nNm+"_cfg");
				if(nList[i_n] == "mod_BlockCalc")
				{
					treeNd_t.setAttr("BLOCK_SH",nNm+"_cfg_blcks");
					treeNd.childAdd("tbl").setAttr("id",nNm+"_cfg_blcks").childAdd("fld").setAttr("ID",nNm+"_cfg");
				}
				if(nList[i_n] == "mod_JavaLikeCalc")
				{
					treeNd.childAdd("tbl").setAttr("id","lib").childAdd("fld").setAttr("ID",nNm+"_cfg").setAttr("DB","lib_"+nNm+"_cfg");
					treeNd.childAdd("tbl").setAttr("id","lib_"+nNm+"_cfg").childAdd("fld").setAttr("ID",nNm+"_cfg");
				}

				cfgTree.save(0x20, configPath);
				SYS.cntrReq(SYS.XMLNode("scan").setAttr("path","/%2fgen%2fconfig"));		//Reload config command
				SYS.nodeAt(nAddr+"_cfg").enable(true);
				if(!SYS.nodeAt(nAddr+"_cfg")) testREZ = "FAILED: load controller from config";
				else
				{
					if(!SYS.nodeAt(nAddr+"_cfg/prm_"+nNm+"_cfg")) testREZ = "FAILED: load parameter from config";
					if(nList[i_n] == "mod_BlockCalc" && !SYS.nodeAt(nAddr+"_cfg/blk_"+nNm+"_cfg")) testREZ_ = "FAILED: load block from config";
					if(nList[i_n] == "mod_JavaLikeCalc")
					{
						if(!SYS.nodeAt(nAddr_+"_cfg")) testREZ_ = "FAILED: load library from config";
						else if(!SYS.nodeAt(nAddr_+"_cfg/fnc_"+nNm+"_cfg")) testREZ_ = "FAILED: load function from config";
					}
				}
			}
		}
		rez += "<tr><td>DAQ."+nList[i_n].slice(4)+": create/remove, change, load, save and load from config</td><td>"+testREZ+"</td></tr>\n";
		if(nList[i_n] == "mod_BlockCalc")
			rez += "<tr><td>DAQ."+nList[i_n].slice(4)+": Blocks create/remove, change, load, save and load from config</td><td>"+testREZ_+"</td></tr>\n";
		else if(nList[i_n] == "mod_JavaLikeCalc")
			rez += "<tr><td>DAQ."+nList[i_n].slice(4)+": Functions and its libraries create/remove, change, load, save and load from config</td><td>"+testREZ_+"</td></tr>\n";

		//> Disconnect/Connect module
		if(nList[i_n] != "mod_JavaLikeCalc")
		{
			req = SYS.XMLNode("get").setAttr("path","/DAQ/"+nList[i_n]+"/%2fhelp%2fm_inf%2fSource");
			SYS.cntrReq(req);
			testREZ = SYS.Special.SystemTests.SOAttach(req.text(),0);
			testREZ += "/"+SYS.Special.SystemTests.SOAttach(req.text(),0);
			rez += "<tr><td>DAQ."+nList[i_n].slice(4)+": Disconnect/Connect</td><td>"+testREZ+"</td></tr>\n";
		}
	}
}

//**********************************
//> UI subsystem tests
if(sub < 0 || sub == 7)
{
	nList = SYS.UI.nodeList("mod_");
	for(i_n = 0; i_n < nList.length; i_n++)
	{
		if(nList[i_n] == "mod_QTStarter" || nList[i_n] == "mod_QTCfg") continue;

		//> UI.VCAEngine tests
		if(nList[i_n] == "mod_VCAEngine")
		{
			//>> Widgets library
			testREZ = "PASSED";
			nAddr = "/UI/"+nList[i_n]+"/wlb_"+nNm;
			if(SYS.cntrReq(SYS.XMLNode("add").setAttr("path","/UI/"+nList[i_n]+"/%2fbr%2fwlb_").setAttr("id",nNm)) || !(node=SYS.nodeAt(nAddr))) testREZ = "FAILED: widgets library add";
			else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr+"/%2fobj%2fcfg%2fdescr").setText("Test")) || 
				SYS.cntrReq(req=SYS.XMLNode("get").setAttr("path",nAddr+"/%2fobj%2fcfg%2fdescr")) || req.text() != "Test") testREZ = "FAILED: change widgets library";
			else if(SYS.cntrReq(SYS.XMLNode("save").setAttr("path",nAddr+"/%2fobj"))) testREZ = "FAILED: save widgets library";
			else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr+"/%2fobj%2fcfg%2fdescr").setText("Test 1")) || 
				SYS.cntrReq(SYS.XMLNode("load").setAttr("path",nAddr+"/%2fobj")) || SYS.cntrReq(req=SYS.XMLNode("get").setAttr("path",nAddr+"/%2fobj%2fcfg%2fdescr")) ||
				req.text() != "Test") testREZ = "FAILED: load widgets library";
			else
			{
				node = false;

				//>> Widget
				nAddr1 = nAddr+"/wdg_"+nNm;
				if(SYS.cntrReq(SYS.XMLNode("add").setAttr("path",nAddr+"/%2fbr%2fwdg_").setAttr("id",nNm)) || !(node=SYS.nodeAt(nAddr1))) testREZ = "FAILED: widget add";
				else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr1+"/%2fwdg%2fcfg%2fdescr").setText("Test")) || 
					SYS.cntrReq(req=SYS.XMLNode("get").setAttr("path",nAddr1+"/%2fwdg%2fcfg%2fdescr")) || req.text() != "Test") testREZ = "FAILED: change widget";
				else if(SYS.cntrReq(SYS.XMLNode("save").setAttr("path",nAddr1+"/%2fobj"))) testREZ = "FAILED: save widget";
				else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr1+"/%2fwdg%2fcfg%2fdescr").setText("Test 1")) || 
					SYS.cntrReq(SYS.XMLNode("load").setAttr("path",nAddr1+"/%2fobj")) || SYS.cntrReq(req=SYS.XMLNode("get").setAttr("path",nAddr1+"/%2fwdg%2fcfg%2fdescr")) ||
						req.text() != "Test") testREZ = "FAILED: load widget";
				node = false;

				if(SYS.cntrReq(SYS.XMLNode("del").setAttr("path","/UI/"+nList[i_n]+"/%2fbr%2fwlb_").setAttr("id",nNm)) != 0 || SYS.nodeAt(nAddr)) testREZ = "FAILED: widgets library delete";
				else
				{
					cfgTree.getElementBy("mod_VCAEngine").childAdd("tbl").setAttr("id","LIB").childAdd("fld").setAttr("ID",nNm+"_cfg").setAttr("DB_TBL","wlib_"+nNm+"_cfg");
					cfgTree.getElementBy("mod_VCAEngine").childAdd("tbl").setAttr("id","wlib_"+nNm+"_cfg").childAdd("fld").setAttr("ID",nNm+"_cfg").setAttr("PARENT","/wlb_originals/wdg_Box");
					cfgTree.save(0x20, configPath);
					SYS.cntrReq(SYS.XMLNode("scan").setAttr("path","/%2fgen%2fconfig"));		//Reload config command
					if(!SYS.nodeAt(nAddr+"_cfg") || !SYS.nodeAt(nAddr+"_cfg/wdg_"+nNm+"_cfg")) testREZ = "FAILED: load widgets library from config";
				}
			}
			rez += "<tr><td>UI.VCAEngine: Widgets and widgets' library create/remove, change, load, save and load from config</td><td>"+testREZ+"</td></tr>\n";

			//>> Project
			testREZ = "PASSED";
			nAddr = "/UI/"+nList[i_n]+"/prj_"+nNm;
			if(SYS.cntrReq(SYS.XMLNode("add").setAttr("path","/UI/"+nList[i_n]+"/%2fbr%2fprj_").setAttr("id",nNm)) || !(node=SYS.nodeAt(nAddr))) testREZ = "FAILED: project add";
			else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr+"/%2fobj%2fcfg%2fdescr").setText("Test"))  || 
				SYS.cntrReq(req=SYS.XMLNode("get").setAttr("path",nAddr+"/%2fobj%2fcfg%2fdescr")) || req.text() != "Test") testREZ = "FAILED: change project";
			else if(SYS.cntrReq(SYS.XMLNode("save").setAttr("path",nAddr+"/%2fobj")) != 0) testREZ = "FAILED: save project";
			else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr+"/%2fobj%2fcfg%2fdescr").setText("Test 1")) != 0 || 
				SYS.cntrReq(SYS.XMLNode("load").setAttr("path",nAddr+"/%2fobj")) != 0 || SYS.cntrReq(req=SYS.XMLNode("get").setAttr("path",nAddr+"/%2fobj%2fcfg%2fdescr")) ||
				req.text() != "Test") testREZ = "FAILED: load project";
			else
			{
				node = false;

				//>> Page
				nAddr1 = nAddr+"/pg_"+nNm;
				if(SYS.cntrReq(SYS.XMLNode("add").setAttr("path",nAddr+"/%2fbr%2fpg_").setAttr("id",nNm)) != 0 || !(node=SYS.nodeAt(nAddr1))) testREZ = "FAILED: page add";
				else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr1+"/%2fwdg%2fst%2fparent").setText("/wlb_originals/wdg_Box")) != 0) testREZ = "FAILED: change page";
				else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr1+"/%2fwdg%2fst%2fen").setText(1)) != 0) testREZ = "FAILED: change page";
				else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr1+"/%2fwdg%2fcfg%2fdescr").setText("Test")) != 0 || 
					SYS.cntrReq(req=SYS.XMLNode("get").setAttr("path",nAddr1+"/%2fwdg%2fcfg%2fdescr")) || req.text() != "Test") testREZ = "FAILED: change page";
				else if(SYS.cntrReq(SYS.XMLNode("save").setAttr("path",nAddr1+"/%2fobj")) != 0) testREZ = "FAILED: save page";
				else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr1+"/%2fwdg%2fcfg%2fdescr").setText("Test 1")) != 0 || 
					SYS.cntrReq(SYS.XMLNode("load").setAttr("path",nAddr1+"/%2fobj")) != 0 || SYS.cntrReq(req=SYS.XMLNode("get").setAttr("path",nAddr1+"/%2fwdg%2fcfg%2fdescr")) ||
					req.text() != "Test") testREZ = "FAILED: load page";

				nAddr2 = nAddr1+"/wdg_"+nNm;
				if(SYS.cntrReq(SYS.XMLNode("add").setAttr("path",nAddr1+"/%2fbr%2fwdg_").setAttr("id",nNm)) != 0 || !(node=SYS.nodeAt(nAddr2))) testREZ = "FAILED: widget add";
				else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr2+"/%2fwdg%2fcfg%2fdescr").setText("Test")) != 0 || 
					SYS.cntrReq(req=SYS.XMLNode("get").setAttr("path",nAddr2+"/%2fwdg%2fcfg%2fdescr")) || req.text() != "Test") testREZ = "FAILED: change widget";
				else if(SYS.cntrReq(SYS.XMLNode("save").setAttr("path",nAddr2+"/%2fobj")) != 0) testREZ = "FAILED: save widget";
				else if(SYS.cntrReq(SYS.XMLNode("set").setAttr("path",nAddr2+"/%2fwdg%2fcfg%2fdescr").setText("Test 1")) != 0 || 
					SYS.cntrReq(SYS.XMLNode("load").setAttr("path",nAddr2+"/%2fobj")) != 0 || SYS.cntrReq(req=SYS.XMLNode("get").setAttr("path",nAddr2+"/%2fwdg%2fcfg%2fdescr")) ||
					req.text() != "Test") testREZ = "FAILED: load widget";
				node = false;

				if(SYS.cntrReq(SYS.XMLNode("del").setAttr("path","/UI/"+nList[i_n]+"/%2fbr%2fprj_").setAttr("id",nNm)) != 0 || SYS.nodeAt(nAddr)) testREZ = "FAILED: project delete";
				else
				{
					cfgTree.getElementBy("mod_VCAEngine").childAdd("tbl").setAttr("id","PRJ").childAdd("fld").setAttr("ID",nNm+"_cfg").setAttr("DB_TBL","prj_"+nNm+"_cfg");
					cfgTree.getElementBy("mod_VCAEngine").childAdd("tbl").setAttr("id","prj_"+nNm+"_cfg").childAdd("fld").setAttr("OWNER","/"+nNm+"_cfg").setAttr("ID",nNm+"_cfg").setAttr("PARENT","/wlb_originals/wdg_Box");//.setAttr("FLGS",1);
					cfgTree.getElementBy("mod_VCAEngine").childAdd("tbl").setAttr("id","prj_"+nNm+"_cfg_incl").childAdd("fld").setAttr("IDW","/prj_"+nNm+"_cfg/pg_"+nNm+"_cfg").setAttr("ID",nNm+"_cfg").setAttr("PARENT","/wlb_originals/wdg_Box");
					cfgTree.save(0x20, configPath);
					SYS.cntrReq(SYS.XMLNode("scan").setAttr("path","/%2fgen%2fconfig"));		//Reload config command
					if(!SYS.nodeAt(nAddr+"_cfg"))	testREZ = "FAILED: load project from config";
					else if(!SYS.nodeAt(nAddr+"_cfg/pg_"+nNm+"_cfg"))	testREZ = "FAILED: load page from config";
					else if(!SYS.nodeAt(nAddr+"_cfg/pg_"+nNm+"_cfg/wdg_"+nNm+"_cfg"))	testREZ = "FAILED: load widget from config";
				}
			}
			rez += "<tr><td>UI.VCAEngine: Project, pages and widgets create/remove, change, load, save and load from config</td><td>"+testREZ+"</td></tr>\n";

			//> Session
			testREZ = "PASSED";
			nAddr = "/UI/"+nList[i_n]+"/ses_"+nNm;
			req = SYS.XMLNode("CntrReqs").setAttr("path","/UI/"+nList[i_n]);
			req.childAdd("add").setAttr("path","/%2fbr%2fses_").setText(nNm);
			req.childAdd("set").setAttr("path","/ses_"+nNm+"/%2fobj%2fst%2fprj").setText("tmplSO");
			req.childAdd("set").setAttr("path","/ses_"+nNm+"/%2fobj%2fst%2fstart").setText(1);
			if(SYS.cntrReq(req) != 0 || !SYS.nodeAt(nAddr)) testREZ = "FAILED: session add/start";
			else if(SYS.cntrReq(req=SYS.XMLNode("del").setAttr("path","/UI/"+nList[i_n]+"/%2fbr%2fses_").setText(nNm)) || SYS.nodeAt(nAddr)) testREZ = "FAILED: session delete";
			rez += "<tr><td>UI.VCAEngine: Session create, start and remove</td><td>"+testREZ+"</td></tr>\n";
		}

		//> Disconnect/Connect module
		req = SYS.XMLNode("get").setAttr("path","/UI/"+nList[i_n]+"/%2fhelp%2fm_inf%2fSource");
		SYS.cntrReq(req);
		testREZ = SYS.Special.SystemTests.SOAttach(req.text(),0);
		testREZ += "/"+SYS.Special.SystemTests.SOAttach(req.text(),0);
		rez += "<tr><td>UI."+nList[i_n].slice(4)+": Disconnect/Connect</td><td>"+testREZ+"</td></tr>\n";
	}
}

//**********************************
//> Special subsystem tests
if(sub < 0 || sub == 8)
{
	nList = SYS.Special.nodeList("mod_");
	for(i_n = 0; i_n < nList.length; i_n++)
	{
		if(nList[i_n] == "mod_SystemTests") continue;
		//> Disconnect/Connect module
		req = SYS.XMLNode("get").setAttr("path","/Special/"+nList[i_n]+"/%2fhelp%2fm_inf%2fSource");
		SYS.cntrReq(req);
		testREZ = SYS.Special.SystemTests.SOAttach(req.text(),0);
		testREZ += "/"+SYS.Special.SystemTests.SOAttach(req.text(),0);
		rez += "<tr><td>Special."+nList[i_n].slice(4)+": Disconnect/Connect</td><td>"+testREZ+"</td></tr>\n";
	}
}

//> Restore original config file
SYS.fileWrite(configPath,SYS.fileRead(configPath+".orig"));

//Save result to file ReleaseTests.html
SYS.fileWrite("ReleaseTests.html", "<?xml version='1.0' ?>\n"
	"<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'\n"
	"'DTD/xhtml1-transitional.dtd'>\n"
	"<html xmlns='http://www.w3.org/1999/xhtml'>\n"
	"<head>\n"
	"  <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/>\n"
	"</head>\n"
	"<body>\n"
	"<h1>Release tests report table</h1>\n"
	"<TABLE border=\"1\" cellpadding=\"2\" cellspacing=\"0\" width=\"100%\">\n"
	"  <TR align=\"center\"><TH>Test</TH><TH>Result</TH></TR>\n"+
	rez+
	"</TABLE>\n"
	"</body>"
	"</html>");


# prescr_val

ID: work
VAL:
<XMLNodeObj:prg name="Тест" wtm="35">
<XMLNodeObj:com arg1="10" arg2="0" arg3="0" arg4="0" arg5="0" id="Таймер">
</XMLNodeObj:com>
<XMLNodeObj:com arg1="15" arg2="0" arg3="0" arg4="0" arg5="0" id="Фоновий таймер">
</XMLNodeObj:com>
<XMLNodeObj:com arg1="20" arg2="0" arg3="0" arg4="0" arg5="0" id="Таймер">
</XMLNodeObj:com>
</XMLNodeObj:prg>


ID: comLs
VAL:
<TVarObj>
<TVarObj p='Background timer'>
<str p='arg1'>Time (s)</str>
<str p='prmID'>backTimer</str>
</TVarObj>
<TVarObj p='Timer'>
<str p='arg1'>Time (s)</str>
<str p='prmID'>timer</str>
</TVarObj>
</TVarObj>


# techApp

ID: noise
NAME: Noise (2 harmonic + rand)
uk#NAME: Шум (2 гарм. + випадк.)
ru#NAME: Шум (2 гарм. + случ)
DESCR:
Noise model. Contain three parts:
- first harmonic part;
- second harmonic part;
- noise based on randomize generator of numbers.

FORMULA:
tmp_g1=(tmp_g1>6.28)?0:tmp_g1+6.28/(per_g1*f_frq);
tmp_g2=(tmp_g2>6.28)?0:tmp_g2+6.28/(per_g2*f_frq);
out=off+a_g1*sin(tmp_g1)+a_g2*sin(tmp_g2)+a_rnd*(rand(2)-1);

uk#DESCR:
Модель шуму. Містить три складові:
- перша гармоніка;
- друга гармоніка;
- шум на основі генератору випадкових чисел.

ru#DESCR:
Модель шума. Содержит три составляющие:
- первая гармоника;
- вторая гармоника;
- шум на основе генератора случайных чисел.


ID: ballCrane
NAME: Ball crane
DESCR: Ball crane model. Include going and estrangement time.
uk#NAME: Шаровий кран
uk#DESCR: Модель шарового крану. Включає час ходу та час відриву.
ru#NAME: Шаровой кран
ru#DESCR: Модель шарового крана. Включает время хода и время отрыва.
FORMULA:
if( !(st_close && !com) && !(st_open && com) )
{
  tmp_up=(pos>0&&pos<100)?0:(tmp_up>0&&lst_com==com)?tmp_up-1./f_frq:t_up;
  pos+=(tmp_up>0)?0:(100.*(com?1.:-1.))/(t_full*f_frq);
  pos=(pos>100)?100:(pos<0)?0:pos;
  st_open=(pos>=100)?true:false;
  st_close=(pos<=0)?true:false;
  lst_com=com;
}


ID: separator
NAME: Separator
DESCR: Separator model included two phase: liquid and gas.
uk#NAME: Сепаратор
uk#DESCR: Модель сепаратору з двома фазами рідинною та газовою.
ru#NAME: Сепаратор
ru#DESCR: Модель сепаратора с двумя фазами, жидкой и газовой.
FORMULA:
Fж=max(0,Fi*ProcЖ);
DAQ.JavaLikeCalc.lib_techApp.pipeBase(Fi,Pi,293,Si,Fo+Fж,Po,293,So,lo,Q0,0.95,0.01,f_frq);
Lж = max(0,min(100,Lж+0.27*(Fж-Fo_ж)/(Vap*Qж*f_frq)));
Po_ж = Po + Lж*Vap/Qж;


ID: klap
NAME: Valve
uk#NAME: Клапан
ru#NAME: Клапан
DESCR:
Valve model, include:
- two valve in one;
- super-critical speed;
- temperature change on baffling;
- work to one side, back valve;
- valve position speed control;
- nonlinear cut changing by open position.

FORMULA:
Qr=Q0+Q0*Kpr*(Pi-1);
tmp_l1 += (abs(l_kl1-tmp_l1) > 5) ? 100*sign(l_kl1-tmp_l1)/(t_kl1*f_frq) : (l_kl1-tmp_l1)/(t_kl1*f_frq);
tmp_l2 += (abs(l_kl2-tmp_l2) > 5) ? 100*sign(l_kl2-tmp_l2)/(t_kl2*f_frq) : (l_kl2-tmp_l2)/(t_kl2*f_frq);
Sr=(S_kl1*pow(tmp_l1,Kln)+S_kl2*pow(tmp_l2,Kln))/pow(100,Kln);

DAQ.JavaLikeCalc.lib_techApp.pipeBase(Fi,Pi,Ti,Sr,EVAL_REAL,Po,293,So,lo,Q0,Kpr,0.01,f_frq);
if( noBack ) Fi = max(0,Fi);
Po = max(0,min(100,Po+0.27*(Fi-Fo)/(Q0*Kpr*So*lo*f_frq)));

To = max(0,min(2e3,To+(abs(Fi)*(Ti*pow(Po/Pi,0.02)-To)+(Fwind+1)*(Twind-To)/Riz)/(Ct*So*lo*Qr*f_frq)));

uk#DESCR:
Модель клапану яка враховує:
- два клапана в одному; 
- зверхкритичне витікання; 
- зміна температури при дроселюванні; 
- робота тільки у одному напрямку, зворотний клапан;
- керування швидкісттю зміни положення;
- нелінійність прохідного перетину від положення.

ru#DESCR:
Модель клапана, учитывающая:
- два клапана в одном; 
- сверхкритическое истечение; 
- изменение температуры при дросселировании; 
- работа только в одном направлении, обратный клапан; 
- управляемая скорость изменения положения; 
- нелинейность проходного сечения от положения.


ID: lagClean
NAME: Lag (clear)
uk#NAME: Затримка (чиста)
ru#NAME: Запаздывание (чистое)
DESCR:
Model of clear lag (transportable). Realised by include some simple lag chains. Appointed for lags into long pipes.

FORMULA:
cl1-=(cl1-in)/(t_lg*f_frq/4);
cl2-=(cl2-cl1)/(t_lg*f_frq/4);
cl3-=(cl3-cl2)/(t_lg*f_frq/4);
out-=(out-cl3)/(t_lg*f_frq/4);

uk#DESCR:
Модель чистої(транспортної) затримки. Реалізується шляхом включення декількох ланцюгів простої затримки. Призначено для імітації затримок у довгих трубопроводах.

ru#DESCR:
Модель чистого(транспортного) запаздывания. Реализуется путём включения нескольких простых цепей запаздывания. Предназначен для имитации запаздывания в длинных трубопроводах.


ID: cooler
NAME: Air cooler
DESCR: Model of the air cooler for gas flow.
uk#NAME: Повітряний холодильник
uk#DESCR: Модель повітряного охолоджувача газового потоку.
ru#NAME: Возд. холодильник
ru#DESCR: Модель воздушного охладителя газового потока.
FORMULA:
DAQ.JavaLikeCalc.lib_techApp.pipeBase(Fi,Pi,293,Si,Fo,Po,293,So,lo,Q0,0.95,0.01,f_frq);
Qr = Q0+Q0*0.95*(Pi-1);
To+=(Fi*(Ti-To)+Wc*(Tair-To)/Rt)/(Ct*(Si*li+So*lo)*Qr*f_frq);


ID: compressor
NAME: Gas compressor
uk#NAME: Компресор газовий
ru#NAME: Компрессор газовый
DESCR:
Model of the gas compressor. Realised surge effect.
Sarge count from the dynamic-gas curve, and next count coefficient of sarge margin.

FORMULA:
Pmax = max(Pi,Po);
Pmin = min(Pi,Po);
Qr = Q0+Q0*Kpr*(Pi-1);
Qrf = Q0+Q0*Kpr*(Pmax-1);
Ftmp=(N>0.1)?(1-10*(Po-Pi)/(Qr*(pow(N,3)+0.1)*Kpmp)):1;
Kzp=1-Ftmp;  //Коэффиц. запаса
Fi=V*N*Qr*sign(Ftmp)*pow(abs(Ftmp),Kslp)+
     0.3*(4*So*Qrf/(0.01*lo*1.7724+4*Qrf))*sign(Pi-Po)*pow(Qrf*(Pmax-max(Pmax*0.528,Pmin)),0.5);
Fit -= (Fit-Fi)/max(1,(lo*f_frq)/max(1e-4,abs(Fi/(Qrf*So))));
Po = max(0,min(100,Po+0.27*(Fi-Fo)/(Q0*Kpr*So*lo*f_frq)));

To+=(abs(Fi)*(Ti*pow(Po/Pi,0.3)-To)+(Fwind+1)*(Twind-To)/Riz)/(Ct*(V+So*lo)*Qr*f_frq);

uk#DESCR:
Модель газового компресора. Враховує ефект помпажу. 
Помпаж розраховується за газово-динамічною кривою, виходячи з якої розраховується коефіцієнт запасу по помпажу.

ru#DESCR:
Модель газового компрессора. Учитывает эффект помпажа. Помпаж вычисляется по газо-динамической кривой, исходя из которой получается коэффициент запаса по помпажу.


ID: pipe1_1
NAME: Pipe 1->1
DESCR: Model of the pipe by scheme: 1 -> 1.
uk#NAME: Труба 1->1
uk#DESCR: Модель вузла труб за схемою: 1 -> 1.
ru#NAME: Труба 1->1
ru#DESCR: Модель узла труб по схеме: 1 -> 1.
FORMULA:
DAQ.JavaLikeCalc.lib_techApp.pipeBase(Fi,Pi,293,So,Ft1,Pti,293,So,0.33*lo,Q0,Kpr,0.01,f_frq);
DAQ.JavaLikeCalc.lib_techApp.pipeBase(Ft1,Pti,293,So,Fto,Pt1,293,So,0.33*lo,Q0,Kpr,0.01,f_frq);
DAQ.JavaLikeCalc.lib_techApp.pipeBase(Fto,Pt1,293,So,Fo,Po,293,So,0.33*lo,Q0,Kpr,0.01,f_frq);


ID: pipe1_2
NAME: Pipe 1->2
DESCR: Model of the pipe by scheme: 1 -> 2.
uk#NAME: Труба 1->2
uk#DESCR: Модель вузла труб за схемою: 1 -> 2.
ru#NAME: Труба 1->2
ru#DESCR: Модель узла труб по схеме: 1 -> 2.
FORMULA:
DAQ.JavaLikeCalc.lib_techApp.pipeBase(F1tmp,Pi,293,So1,Fo1,Po1,293,So1,lo1,Q0,Kpr,0.01,f_frq);
DAQ.JavaLikeCalc.lib_techApp.pipeBase(F2tmp,Pi,293,So2,Fo2,Po2,293,So2,lo2,Q0,Kpr,0.01,f_frq);
Fi=F1tmp+F2tmp;


ID: pipe1_3
NAME: Pipe 1->3
DESCR: Model of the pipe by scheme: 1 -> 3.
uk#NAME: Труба 1->3
uk#DESCR: Модель вузла труб за схемою: 1 -> 3.
ru#NAME: Труба 1->3
ru#DESCR: Модель узла труб по схеме: 1 -> 3.
FORMULA:
DAQ.JavaLikeCalc.lib_techApp.pipeBase(F1tmp,Pi,293,So1,Fo1,Po1,293,So1,lo1,Q0,Kpr,0.01,f_frq);
DAQ.JavaLikeCalc.lib_techApp.pipeBase(F2tmp,Pi,293,So2,Fo2,Po2,293,So2,lo2,Q0,Kpr,0.01,f_frq);
DAQ.JavaLikeCalc.lib_techApp.pipeBase(F3tmp,Pi,293,So3,Fo3,Po3,293,So3,lo3,Q0,Kpr,0.01,f_frq);
Fi=F1tmp+F2tmp+F3tmp;


ID: pipe1_4
NAME: Pipe 1->4
DESCR: Model of the pipe by scheme: 1 -> 4.
uk#NAME: Труба 1->4
uk#DESCR: Модель вузла труб за схемою: 1 -> 4.
ru#NAME: Труба 1->4
ru#DESCR: Модель узла труб по схеме: 1 -> 4.
FORMULA:
DAQ.JavaLikeCalc.lib_techApp.pipeBase(F1tmp,Pi,293,So1,Fo1,Po1,293,So1,lo1,Q0,Kpr,0.01,f_frq);
DAQ.JavaLikeCalc.lib_techApp.pipeBase(F2tmp,Pi,293,So2,Fo2,Po2,293,So2,lo2,Q0,Kpr,0.01,f_frq);
DAQ.JavaLikeCalc.lib_techApp.pipeBase(F3tmp,Pi,293,So3,Fo3,Po3,293,So3,lo3,Q0,Kpr,0.01,f_frq);
DAQ.JavaLikeCalc.lib_techApp.pipeBase(F4tmp,Pi,293,So4,Fo4,Po4,293,So4,lo4,Q0,Kpr,0.01,f_frq);
Fi=F1tmp+F2tmp+F3tmp+F4tmp;


ID: klapMech
NAME: Valve proc. mechanism
uk#NAME: Виконавчий мех. клапану
uk#DESCR: Модель виконавчого механізму клапана. Включає час ходу та час відриву.
ru#NAME: Исполн. мех. клапана
ru#DESCR: Модель исполнительного механизма клапана. Включает время хода и время отрыва.
DESCR:
Model of the valve process mechanism.
Include going time (aperiodic chain of two level) and estrangement time.

FORMULA:
if( (pos >= 99 && com >= 99) || (pos <= 1 && com <=1 ) )
{ 
  tmp_up = t_up;
  if(pos>=99) { pos=100; st_open=true; }
  else { pos = 0; st_close=true; }
}
else if( tmp_up > 0 ) tmp_up-=1./f_frq;
else
{
  st_open=st_close=false;
  lst_com+=(com-lst_com)/(0.5*t_full*f_frq);
  pos+=(lst_com-pos)/(0.5*t_full*f_frq);
}
pos_sensor+=(pos-pos_sensor)/(t_sensor*f_frq);


ID: diafragma
NAME: Diaphragm
DESCR: Diaphragm model.
uk#NAME: Діафрагма
uk#DESCR: Модель діафрагми.
ru#NAME: Диафрагма
ru#DESCR: Модель диафрагмы.
FORMULA:
DAQ.JavaLikeCalc.lib_techApp.pipeBase(Fi,Pi,293,Sdf,Fo,Po,293,So,lo,Q0,Kpr,0.01,f_frq);
dP -= (dP-100*(Pi-Po))/f_frq;


ID: pipe3_1
NAME: Pipe 3->1
DESCR: Model of the pipe by scheme: 3 -> 1.
uk#NAME: Труба 3->1
uk#DESCR: Модель вузла труб за схемою: 3 -> 1.
ru#NAME: Труба 3->1
ru#DESCR: Модель узла труб по схеме: 3 -> 1.
FORMULA:
DAQ.JavaLikeCalc.lib_techApp.pipeBase(Fi1,Pi1,293,Si1,EVAL_REAL,Po,293,So,lo,Q0,Kpr,0.01,f_frq);
DAQ.JavaLikeCalc.lib_techApp.pipeBase(Fi2,Pi2,293,Si2,EVAL_REAL,Po,293,So,lo,Q0,Kpr,0.01,f_frq);
DAQ.JavaLikeCalc.lib_techApp.pipeBase(Fi3,Pi3,293,Si3,EVAL_REAL,Po,293,So,lo,Q0,Kpr,0.01,f_frq);
Po = max(0,min(100,Po+0.27*(Fi1+Fi2+Fi3-Fo)/(Q0*Kpr*So*lo*f_frq)));
To = max(0,To+(Fi1*(Ti1-To)+Fi2*(Ti2-To)+Fi3*(Ti3-To)+(Fwind+1)*(Twind-To)/Riz)/(Ct*So*lo*Q0*f_frq));


ID: pipeBase
NAME: Pipe-base
uk#NAME: Труба-база
ru#NAME: Труба-база
DESCR:
Implementation of the basic foundations of the model pipe:
- Flow in the pipe, taking into account the speed, pressure drop, resistance due to friction and the critical flow.
- Calculation of pressure.
- Accounting for medium density and degree of compressibility for both gases and liquids.

FORMULA:
Pmax = max(Pi,Po);
Pmin = min(Pi,Po);
Qr = Q0+Q0*Kpr*(Pmax-1);
Fit = 630*(4*Si*So*Qr/(Ktr*lo*1.7724*Si+4*So*Qr))*sign(Pi-Po)*pow(Qr*(Pmax-max(Pmax*0.528,Pmin)),0.5);
Fi -= (Fi-Fit)/max(1,(lo*f_frq)/max(1,abs(Fit/(Qr*So))));
if( !Fo.isEVal() ) Po = max(0,min(100,Po+0.27*(Fi-Fo)/(Q0*Kpr*So*lo*f_frq)));

uk#DESCR:
Реалізація базових основ моделі труби:
- Витрати у трубі з урахуванням швидкості руху, різниці тиску, опору за рахунок тертя та критичної течі.
- Розрахунок тиску. 
- Урахування щільності середовища та ступеня його стиснення як для газів, так і для рідин.

ru#DESCR:
Реализация базовых основ модели трубы:
- Расход в трубе с учётом скорости движения, перепада давления, сопротивления за счёт трения и критического истечения.
- Расчёт давления.
- Учёт плотности среды и степени её сжимаемости как для газов, так и для жидкостей.


ID: heatExch
NAME: Heat exchanger
DESCR: The model of the heat exchanger, it calculates the heat exchange of the two streams.
uk#NAME: Теплообмінник
uk#DESCR: Модель теплообміннику, яка розраховує теплообмін двох потоків.
ru#NAME: Теплообменник
ru#DESCR: Модель теплообменника, рассчитывающая теплообмен двух потоков.
FORMULA:
DAQ.JavaLikeCalc.lib_techApp.pipeBase(Fi1,Pi1,Ti1,Si1,Fo1,Po1,293,So1,lo1,Q0i1,Kpr1,0.01,f_frq);
DAQ.JavaLikeCalc.lib_techApp.pipeBase(Fi2,Pi2,Ti2,Si2,Fo2,Po2,293,So2,lo2,Q0i2,Kpr2,0.01,f_frq);

To1=max(0,min(1e4,(Fi1*Ti1*Ci1+ki*Fi2*Ti2*Ci2)/(Fi1*Ci1+ki*Fi2*Ci2)));
To2=max(0,min(1e4,(ki*Fi1*Ti1*Ci1+Fi2*Ti2*Ci2)/(ki*Fi1*Ci1+Fi2*Ci2)));


ID: boilerBarrel
NAME: Boiler: barrel
DESCR: The model of the boiler's barrel.
uk#NAME: Котел: барабан
uk#DESCR: Модель барабану котлоагрегату.
ru#NAME: Котёл: барабан
ru#DESCR: Модель барабана котлоагрегата.
FORMULA:
// Water
DAQ.JavaLikeCalc.lib_techApp.pipeBase(Fi1,Pi1,293,Si1,EVAL_REAL,Po1,293,So1,lo1,1e3,0.001,0.01,f_frq);
Fi1 = max(0,Fi1);

// Steam
Lo = max(0,min(100,Lo+(Fi1-Fpara)*100/(Vi1*1000*f_frq)));
To1 = (100*pow(Po1,0.241)+5)+273;

if( Tv<To1 )
{
  Tv+=(k*S*(Ti2-Tv)-Fi1*0.00418*(Tv-Ti1))/f_frq;
  Fpara=0;
}
if( Tv >= To1 )
{
  Tv=To1;
  Lambda=2750.0-0.00418*(Tv-273);
  Fpara=(5*S*Fi2*(Ti2-Tv)-Fi1*0.00418*(Tv-Ti1))/(Po1*Lambda);
}

To2=Ti2-Tv/k;
Po1 = max(0,min(100,Po1+0.27*(Fpara-Fo)/(1.2*0.98*((1-Lo/100)*Vi1+So1*lo1)*f_frq)));

// Smoke gas
DAQ.JavaLikeCalc.lib_techApp.pipeBase(Fi2,Pi2,293,Si2,Fo2,Po2,293,Si2,30,1.2,0.98,0.01,f_frq);


ID: boilerBurner
NAME: Boiler: burner
uk#NAME: Котел: топка
ru#NAME: Котёл: топка
ru#DESCR: Модель топки котлоагрегата, работающего на трех видах топлива: доменном, коксовом и природном газе.
DESCR:
The fire chamber's of the boiler model which works with three fuels: blast-furnace gas, coke and natural gas. 

FORMULA:
using DAQ.JavaLikeCalc.lib_techApp;
pipeBase(Fi1,Pi1,Ti1,Si1,EVAL_REAL,Po,293,So,lo,1.2,0.95,0.01,f_frq); Fi1 = max(0,Fi1);
pipeBase(Fi2,Pi2,Ti2,Si2,EVAL_REAL,Po,293,So,lo,0.7,0.95,0.01,f_frq); Fi2 = max(0,Fi2);
pipeBase(Fi3,Pi3,Ti3,Si3,EVAL_REAL,Po,293,So,lo,1.33,0.95,0.01,f_frq); Fi3 = max(0,Fi3);
pipeBase(Fi4,Pi4,Ti4,Si4,EVAL_REAL,Po,293,So,lo,1.293,0.95,0.01,f_frq); Fi4 = max(0,Fi4);

Neobhod_vzd = Fi1+10*Fi2+4*Fi3;
F_DG = Fi1+Fi2+Fi3+Fi4;
O2 = max(0,min(100,(Fi4-Neobhod_vzd)*100/F_DG));
CO = min(100, (O2<1) ? (1.2*abs(O2)) : 0);
koef = min(1,Fi4/Neobhod_vzd);
Q = koef*(8050*Fi2+3900*Fi3+930*Fi1);
delta_t = Q/(F_DG*1.047);
To = max(0,min(2000,(delta_t+(Ti4-273)+(Ti3-273)*(Fi3/Fi1)+(Ti2-273)*(Fi2/Fi1)+(Ti1-273)*(Fi1/Fi4))+273));

Po = max(0,min(10,Po+0.27*(F_DG-Fo)/(1.2*0.95*(So*lo+V)*f_frq)));

uk#DESCR:
Модель топки котлоагрегату, який працює на трьох видах палива: доменному, коксовому та природному газах.


ID: pipe2_1
NAME: Pipe 2->1
DESCR: Model of the pipe by scheme: 2 -> 1.
uk#NAME: Труба 2->1
uk#DESCR: Модель вузла труб за схемою: 2 -> 1.
ru#NAME: Труба 2->1
ru#DESCR: Модель узла труб по схеме: 2 -> 1.
FORMULA:
DAQ.JavaLikeCalc.lib_techApp.pipeBase(Fi1,Pi1,293,Si1,EVAL_REAL,Po,293,So,lo,Q0,Kpr,0.01,f_frq);
DAQ.JavaLikeCalc.lib_techApp.pipeBase(Fi2,Pi2,293,Si2,EVAL_REAL,Po,293,So,lo,Q0,Kpr,0.01,f_frq);
Po = max(0,min(100,Po+0.27*(Fi1+Fi2-Fo)/(Q0*Kpr*So*lo*f_frq)));
To = max(0,To+(Fi1*(Ti1-To)+Fi2*(Ti2-To)+(Fwind+1)*(Twind-To)/Riz)/(Ct*So*lo*Q0*f_frq));


# tmplib_DevLib

ID: SCU750
DESCR: Typical EDWARDS TURBOMOLECULAR PUMPS data request by SCU750 Cotrol Unit protocol.
ru#DESCR: Типичный EDWARDS TURBOMOLECULAR PUMPS опрос данных для протокола управляющего модуля.
PROGRAM:
JavaLikeCalc.JavaScript
if(f_start)
{
	version = "";
	operModes = new Object();
	operModes[1] = "Levitation";
	operModes[2] = "No Levitation";
	operModes[3] = "Acceleration";
	operModes[4] = "Normal";
	operModes[5] = "Deceleration (Brake)";
	operModes[6] = "Autotest";
	operModes[7] = "Tuning";
	operModes[8] = "Tuning Complete";
}

tr = SYS.Transport.Serial.nodeAt("out_"+transport);
req = SYS.XMLNode("mess").setAttr("ProtIt","SCU750").setAttr("addr",addr);

//======= Commands =========
//> START, STOP and RESET process
if(comReset == true) req.setText(" E04");
else if(comStop == true) req.setText(" E02");
else if(comStart == true) req.setText(" E01");
else req.setText("");
if(req.text().length) { tr.messIO(req,"UserProtocol"); comReset=comStop=comStart=false; }

//> Speed setpoint set
if(spSpeed != spSpeedPrev)
{
	req.setText(" h"+spSpeed.toString(16,4));
	tr.messIO(req,"UserProtocol");
	spSpeedPrev = spSpeed;
}

//======= Data getting (by self bigger period) ========
if((cnt++)%max(1,perGet*f_frq))	return;
t_err = "";

//Read version, single
if(!version.length || version.isEVal())
{
	req.setText("?V");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); version = EVAL_STR; }
	else
	{
		if(req.text().length != 42) version = EVAL_STR;
		else
		{
			CUSv = "";
			lstNoSp = 0;
			for(i_s = 2; i_s < 32; i_s+=2)
			{
				cod = req.text().slice(i_s,i_s+2).toInt(16);
				CUSv += SYS.strFromCharCode(cod);
				if(cod != 0x20) lstNoSp = i_s/2;
			}
			version = "Contr. Unit Soft V.="+CUSv.slice(0,lstNoSp)+"; "
					    "Motor Drive Soft V.="+req.text().charAt(35)+"."+req.text().charAt(36)+"; "
					    "DSP Soft V.="+req.text().charAt(39)+"."+req.text().charAt(40);
		}
	}
}

//Read rotational speed.
if(t_err.length) tTMS = tMotor = rotSpeed = EVAL_INT;
else
{
	req.setText("?[");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); tTMS = tMotor = rotSpeed = EVAL_INT; }
	else
	{
		tTMS = req.text().slice(32,36).toInt(16);
		tMotor = req.text().slice(36,40).toInt(16);
		rotSpeed = req.text().slice(50,54).toInt(16);
	}
}

//Pump operation mode and errors read
if(t_err.length) { operMode = EVAL_INT; errors = EVAL_STR; }
else
{
	req.setText("?M");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); operMode = EVAL_INT; errors = EVAL_STR; }
	else
	{
		oMode = req.text().slice(2,4).toInt(16);
		operMode = oMode.toString()+":"+(operModes[oMode].isEVal()?"Unknown":operModes[oMode]);
		//SYS.messDebug("CNTR","pumpOperMode: "+pumpOperMode);
		
		errCnt = req.text().slice(4,6).toInt(16);
		errors = "";
		for(i_e = 0; i_e < errCnt; i_e++)
			errors += req.text().slice(6+i_e*2,8+i_e*2)+"; ";
	}
}

//Events read
if(t_err.length)	events = EVAL_STR;
else
{
	req.setText("?g");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); events = EVAL_STR; }
	else
	{
		errCnt = req.text().slice(2,4).toInt(16);
		events = "";
		for(i_e = 0; i_e < errCnt; i_e++)
			events += req.text().slice(4+i_e*2,6+i_e*2)+"; ";
	}
}

//Counters
if(t_err.length) { snCntrUnit = snPump = EVAL_STR; cntPumpHour = cntCntrUnitHour = cntStart = EVAL_REAL; }
else
{
	req.setText("?c");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); snCntrUnit = snPump = EVAL_STR; cntPumpHour = cntCntrUnitHour = cntStart = EVAL_REAL; }
	else
	{
		snCntrUnit = req.text().slice(2,12);
		snPump = req.text().slice(12,22);
		cntPumpHour = req.text().slice(22,30).toInt(16);
		cntCntrUnitHour = req.text().slice(30,38).toInt(16);
		cntStart = req.text().slice(38,46).toInt(16);
	}
}

//Read setpoints
if(t_err.length)	spSpeed = spSpeedPrev = spTMSt = EVAL_INT;
else
{
	req.setText("?d");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); spSpeed = spSpeedPrev = spTMSt = EVAL_INT; }
	else
	{
		spSpeed = spSpeedPrev = req.text().slice(2,6).toInt(16);
		spTMSt = req.text().slice(6,10).toInt(16);
	}
}

f_err = t_err;

ru#PROGRAM:
JavaLikeCalc.JavaScript
if(f_start)
{
	version = "";
	operModes = new Object();
	operModes[1] = "Levitation";
	operModes[2] = "No Levitation";
	operModes[3] = "Acceleration";
	operModes[4] = "Normal";
	operModes[5] = "Deceleration (Brake)";
	operModes[6] = "Autotest";
	operModes[7] = "Tuning";
	operModes[8] = "Tuning Complete";
}

tr = SYS.Transport.Serial.nodeAt("out_"+transport);
req = SYS.XMLNode("mess").setAttr("ProtIt","SCU750").setAttr("addr",addr);

//======= Commands =========
//> START, STOP and RESET process
if(comReset == true) req.setText(" E04");
else if(comStop == true) req.setText(" E02");
else if(comStart == true) req.setText(" E01");
else req.setText("");
if(req.text().length) { tr.messIO(req,"UserProtocol"); comReset=comStop=comStart=false; }

//> Speed setpoint set
if(spSpeed != spSpeedPrev)
{
	req.setText(" h"+spSpeed.toString(16,4));
	tr.messIO(req,"UserProtocol");
	spSpeedPrev = spSpeed;
}

//======= Data getting (by self bigger period) ========
if((cnt++)%max(1,perGet*f_frq))	return;
t_err = "";

//Read version, single
if(!version.length || version.isEVal())
{
	req.setText("?V");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); version = EVAL_STR; }
	else
	{
		if(req.text().length != 42) version = EVAL_STR;
		else
		{
			CUSv = "";
			lstNoSp = 0;
			for(i_s = 2; i_s < 32; i_s+=2)
			{
				cod = req.text().slice(i_s,i_s+2).toInt(16);
				CUSv += SYS.strFromCharCode(cod);
				if(cod != 0x20) lstNoSp = i_s/2;
			}
			version = "Contr. Unit Soft V.="+CUSv.slice(0,lstNoSp)+"; "
					    "Motor Drive Soft V.="+req.text().charAt(35)+"."+req.text().charAt(36)+"; "
					    "DSP Soft V.="+req.text().charAt(39)+"."+req.text().charAt(40);
		}
	}
}

//Read rotational speed.
if(t_err.length) tTMS = tMotor = rotSpeed = EVAL_INT;
else
{
	req.setText("?[");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); tTMS = tMotor = rotSpeed = EVAL_INT; }
	else
	{
		tTMS = req.text().slice(32,36).toInt(16);
		tMotor = req.text().slice(36,40).toInt(16);
		rotSpeed = req.text().slice(50,54).toInt(16);
	}
}

//Pump operation mode and errors read
if(t_err.length) { operMode = EVAL_INT; errors = EVAL_STR; }
else
{
	req.setText("?M");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); operMode = EVAL_INT; errors = EVAL_STR; }
	else
	{
		oMode = req.text().slice(2,4).toInt(16);
		operMode = oMode.toString()+":"+(operModes[oMode].isEVal()?"Unknown":operModes[oMode]);
		//SYS.messDebug("CNTR","pumpOperMode: "+pumpOperMode);
		
		errCnt = req.text().slice(4,6).toInt(16);
		errors = "";
		for(i_e = 0; i_e < errCnt; i_e++)
			errors += req.text().slice(6+i_e*2,8+i_e*2)+"; ";
	}
}

//Events read
if(t_err.length)	events = EVAL_STR;
else
{
	req.setText("?g");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); events = EVAL_STR; }
	else
	{
		errCnt = req.text().slice(2,4).toInt(16);
		events = "";
		for(i_e = 0; i_e < errCnt; i_e++)
			events += req.text().slice(4+i_e*2,6+i_e*2)+"; ";
	}
}

//Counters
if(t_err.length) { snCntrUnit = snPump = EVAL_STR; cntPumpHour = cntCntrUnitHour = cntStart = EVAL_REAL; }
else
{
	req.setText("?c");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); snCntrUnit = snPump = EVAL_STR; cntPumpHour = cntCntrUnitHour = cntStart = EVAL_REAL; }
	else
	{
		snCntrUnit = req.text().slice(2,12);
		snPump = req.text().slice(12,22);
		cntPumpHour = req.text().slice(22,30).toInt(16);
		cntCntrUnitHour = req.text().slice(30,38).toInt(16);
		cntStart = req.text().slice(38,46).toInt(16);
	}
}

//Read setpoints
if(t_err.length)	spSpeed = spSpeedPrev = spTMSt = EVAL_INT;
else
{
	req.setText("?d");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); spSpeed = spSpeedPrev = spTMSt = EVAL_INT; }
	else
	{
		spSpeed = spSpeedPrev = req.text().slice(2,6).toInt(16);
		spTMSt = req.text().slice(6,10).toInt(16);
	}
}

f_err = t_err;

uk#DESCR:
Опитування даних типових EDWARDS TURBOMOLECULAR PUMPS за допомогою протоколу контрольного модуля SCU750.

uk#PROGRAM:
JavaLikeCalc.JavaScript
if(f_start)
{
	version = "";
	operModes = new Object();
	operModes[1] = "Levitation";
	operModes[2] = "No Levitation";
	operModes[3] = "Acceleration";
	operModes[4] = "Normal";
	operModes[5] = "Deceleration (Brake)";
	operModes[6] = "Autotest";
	operModes[7] = "Tuning";
	operModes[8] = "Tuning Complete";
}

tr = SYS.Transport.Serial.nodeAt("out_"+transport);
req = SYS.XMLNode("mess").setAttr("ProtIt","SCU750").setAttr("addr",addr);

//======= Commands =========
//> START, STOP and RESET process
if(comReset == true) req.setText(" E04");
else if(comStop == true) req.setText(" E02");
else if(comStart == true) req.setText(" E01");
else req.setText("");
if(req.text().length) { tr.messIO(req,"UserProtocol"); comReset=comStop=comStart=false; }

//> Speed setpoint set
if(spSpeed != spSpeedPrev)
{
	req.setText(" h"+spSpeed.toString(16,4));
	tr.messIO(req,"UserProtocol");
	spSpeedPrev = spSpeed;
}

//======= Data getting (by self bigger period) ========
if((cnt++)%max(1,perGet*f_frq))	return;
t_err = "";

//Read version, single
if(!version.length || version.isEVal())
{
	req.setText("?V");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); version = EVAL_STR; }
	else
	{
		if(req.text().length != 42) version = EVAL_STR;
		else
		{
			CUSv = "";
			lstNoSp = 0;
			for(i_s = 2; i_s < 32; i_s+=2)
			{
				cod = req.text().slice(i_s,i_s+2).toInt(16);
				CUSv += SYS.strFromCharCode(cod);
				if(cod != 0x20) lstNoSp = i_s/2;
			}
			version = "Contr. Unit Soft V.="+CUSv.slice(0,lstNoSp)+"; "
					    "Motor Drive Soft V.="+req.text().charAt(35)+"."+req.text().charAt(36)+"; "
					    "DSP Soft V.="+req.text().charAt(39)+"."+req.text().charAt(40);
		}
	}
}

//Read rotational speed.
if(t_err.length) tTMS = tMotor = rotSpeed = EVAL_INT;
else
{
	req.setText("?[");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); tTMS = tMotor = rotSpeed = EVAL_INT; }
	else
	{
		tTMS = req.text().slice(32,36).toInt(16);
		tMotor = req.text().slice(36,40).toInt(16);
		rotSpeed = req.text().slice(50,54).toInt(16);
	}
}

//Pump operation mode and errors read
if(t_err.length) { operMode = EVAL_INT; errors = EVAL_STR; }
else
{
	req.setText("?M");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); operMode = EVAL_INT; errors = EVAL_STR; }
	else
	{
		oMode = req.text().slice(2,4).toInt(16);
		operMode = oMode.toString()+":"+(operModes[oMode].isEVal()?"Unknown":operModes[oMode]);
		//SYS.messDebug("CNTR","pumpOperMode: "+pumpOperMode);
		
		errCnt = req.text().slice(4,6).toInt(16);
		errors = "";
		for(i_e = 0; i_e < errCnt; i_e++)
			errors += req.text().slice(6+i_e*2,8+i_e*2)+"; ";
	}
}

//Events read
if(t_err.length)	events = EVAL_STR;
else
{
	req.setText("?g");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); events = EVAL_STR; }
	else
	{
		errCnt = req.text().slice(2,4).toInt(16);
		events = "";
		for(i_e = 0; i_e < errCnt; i_e++)
			events += req.text().slice(4+i_e*2,6+i_e*2)+"; ";
	}
}

//Counters
if(t_err.length) { snCntrUnit = snPump = EVAL_STR; cntPumpHour = cntCntrUnitHour = cntStart = EVAL_REAL; }
else
{
	req.setText("?c");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); snCntrUnit = snPump = EVAL_STR; cntPumpHour = cntCntrUnitHour = cntStart = EVAL_REAL; }
	else
	{
		snCntrUnit = req.text().slice(2,12);
		snPump = req.text().slice(12,22);
		cntPumpHour = req.text().slice(22,30).toInt(16);
		cntCntrUnitHour = req.text().slice(30,38).toInt(16);
		cntStart = req.text().slice(38,46).toInt(16);
	}
}

//Read setpoints
if(t_err.length)	spSpeed = spSpeedPrev = spTMSt = EVAL_INT;
else
{
	req.setText("?d");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); spSpeed = spSpeedPrev = spTMSt = EVAL_INT; }
	else
	{
		spSpeed = spSpeedPrev = req.text().slice(2,6).toInt(16);
		spTMSt = req.text().slice(6,10).toInt(16);
	}
}

f_err = t_err;


ID: TMH
NAME: TMP-xx03
DESCR: Power supply for turbomolecular pumps, model EI-R04M.
PROGRAM:
JavaLikeCalc.JavaScript
tr = SYS.Transport.Serial.nodeAt("out_"+transport);
req = SYS.XMLNode("mess").setAttr("ProtIt","TMH").setAttr("addr",addr);

if(f_start)
{
	modelID = "";
	operModes = new Object();
	//Modes
	operModes["NS"] = "1:Levitation";
	operModes["NA"] = "3:Acceleration";
	operModes["NN"] = "4:Normal";
	operModes["NB"] = "5:Deceleration";
	operModes["FS"] = "6:Stop operation failure";
	operModes["FF"] = "7:Idling failure";
	operModes["FR"] = "8:Regeneration breaking failure";
	operModes["FB"] = "9:Deceleration failure";
	//Conrols
	operModes["LL"] = "Local";
	operModes["LR"] = "Remote";
	operModes["LC"] = "RS-232C";
	operModes["LD"] = "RS-485";

	//Set to //> Interactive
	req.setText("LN");
	tr.messIO(req,"UserProtocol");
}

//======= Commands =========
//> START, STOP and RESET process
if(comReset == true) req.setText("RR");
else if(comStop == true) req.setText("RP");
else if(comStart == true) req.setText("RT");
else req.setText("");
if(req.text().length)	{ tr.messIO(req,"UserProtocol"); comReset=comStop=comStart=false; }

//> Interactive, Autonomous
if(comInteract == true) req.setText("LN");
else if(comAutonom == true) req.setText("LF");
else req.setText("");
if(req.text().length)	{ tr.messIO(req,"UserProtocol"); comInteract=comAutonom=false; }

//======= Data getting (by self bigger period) ========
if((cnt++)%max(1,perGet*f_frq))	return;
t_err = "0";

//> Oper mode
req.setText("CS");
tr.messIO(req,"UserProtocol");
if(req.attr("err").length) { t_err = req.attr("err"); operMode = EVAL_STR; }
else operMode = /*req.text().slice(2)+":"+*/operModes[req.text().slice(0,2)];

//> Oper control
if(t_err.toInt())	operCntr = EVAL_STR;
else
{
	req.setText("LS");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); operCntr = EVAL_STR; }
	else operCntr = operModes[req.text().slice(0,2)];
}

//> Alarms list obtain
if(t_err.toInt())	errors = EVAL_STR;
else
{
	errors = "";
	for(i = 0; true; i++)
	{
		req.setText("CF"+i.toString(10,2));
		tr.messIO(req,"UserProtocol");
		if(req.attr("err").length) { t_err = req.attr("err"); errors = EVAL_STR; break; }
		//SYS.messDebug("TMH","Result: "+req.text());
		if(req.text().slice(0,2) != "CA")	break;
		errors += req.text().slice(2)+";";
		continue;
	}
}

//> Get parameters
//>> Model ID
if(t_err.toInt())	modelID = EVAL_STR;
else if(!modelID.length || modelID == EVAL_STR)
{
	req.setText("PR01");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); modelID = EVAL_STR;}
	else if(req.text().slice(0,2) != "PA") modelID = EVAL_STR;
	else modelID = "TMP-"+req.text().slice(4);
}

//>> Rotation speed
if(t_err.toInt())	rotSpeed = EVAL_INT;
else
{
	req.setText("PR03");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); rotSpeed = EVAL_INT;}
	else if(req.text().slice(0,2) != "PA") rotSpeed = EVAL_INT;
	else rotSpeed = req.text().slice(4).toInt()*10;
}

//>> Current
if(t_err.toInt())	I = EVAL_REAL;
else
{
	req.setText("PR04");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); I = EVAL_REAL;}
	else if(req.text().slice(0,2) != "PA") I = EVAL_REAL;
	else I = req.text().slice(4).toInt()/10;
}

//>> Axle 1 disbalance
if(t_err.toInt())	axle1disb = EVAL_INT;
else
{
	req.setText("PR21");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); axle1disb = EVAL_INT;}
	else if(req.text().slice(0,2) != "PA") axle1disb = EVAL_INT;
	else axle1disb = req.text().slice(4).toInt();
}

//>> Axle 2 disbalance
if(t_err.toInt())	axle2disb = EVAL_INT;
else
{
	req.setText("PR22");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); axle2disb = EVAL_INT;}
	else if(req.text().slice(0,2) != "PA") axle2disb = EVAL_INT;
	else axle2disb = req.text().slice(4).toInt();
}

//>> MP X1
if(t_err.toInt())	MP_X1 = EVAL_INT;
else
{
	req.setText("PR26");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); MP_X1 = EVAL_INT;}
	else if(req.text().slice(0,2) != "PA") MP_X1 = EVAL_INT;
	else MP_X1 = req.text().slice(4).toInt();
}

//>> MP Y1
if(t_err.toInt())	MP_Y1 = EVAL_INT;
else
{
	req.setText("PR27");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); MP_Y1 = EVAL_INT;}
	else if(req.text().slice(0,2) != "PA") MP_Y1 = EVAL_INT;
	else MP_Y1 = req.text().slice(4).toInt();
}

//>> MP X2
if(t_err.toInt())	MP_X2 = EVAL_INT;
else
{
	req.setText("PR28");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); MP_X2 = EVAL_INT;}
	else if(req.text().slice(0,2) != "PA") MP_X2 = EVAL_INT;
	else MP_X2 = req.text().slice(4).toInt();
}

//>> MP Y2
if(t_err.toInt())	MP_Y2 = EVAL_INT;
else
{
	req.setText("PR29");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); MP_Y2 = EVAL_INT;}
	else if(req.text().slice(0,2) != "PA") MP_Y2 = EVAL_INT;
	else MP_Y2 = req.text().slice(4).toInt();
}

//>> MP Z
if(t_err.toInt())	MP_Z = EVAL_INT;
else
{
	req.setText("PR30");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length) { t_err = req.attr("err"); MP_Z = EVAL_INT;}
	else if(req.text().slice(0,2) != "PA") MP_Z = EVAL_INT;
	else MP_Z = req.text().slice(4).toInt();
}

f_err = t_err;


ID: TM510x
NAME: Elemer TM510x
DESCR: Elemer TM5102 and TM5103.
PROGRAM:
JavaLikeCalc.JavaScript
if(f_start)
{
	devTp = EVAL_INT;
}

tr = SYS.Transport.Serial.nodeAt("out_"+transport);
req = SYS.XMLNode("mess").setAttr("ProtIt","TM510x").setAttr("addr",addr);

t_err = "";

//> Device type get
if(devTp.isEVal() || !devTp)
{
	req.setText("0");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length)	t_err = req.attr("err");
	else devTp = req.text().toInt();
}

//> Inputs read
errors = "";
if(t_err.length) in1 = in2 = in3 = in4 = in5 = in6 = in7 = in8 = EVAL_REAL;
else
{
	req.setText("6;0;8");
	tr.messIO(req,"UserProtocol");
	if(req.attr("err").length)
	{ t_err = req.attr("err"); in1 = in2 = in3 = in4 = in5 = in6 = in7 = in8 = EVAL_REAL; }
	else
	{
		off = 0;
		tvl = "";
		in1 = ((tvl=req.text().parse(0, ";", off))[0] == "$") ? EVAL_INT : tvl.toReal();
		errors += ((tvl[0] == "$") ? tvl.slice(1) : "0")+";";
		in2 = ((tvl=req.text().parse(0, ";", off))[0] == "$") ? EVAL_INT : tvl.toReal();
		errors += ((tvl[0] == "$") ? tvl.slice(1) : "0")+";";
		in3 = ((tvl=req.text().parse(0, ";", off))[0] == "$") ? EVAL_INT : tvl.toReal();
		errors += ((tvl[0] == "$") ? tvl.slice(1) : "0")+";";
		in4 = ((tvl=req.text().parse(0, ";", off))[0] == "$") ? EVAL_INT : tvl.toReal();
		errors += ((tvl[0] == "$") ? tvl.slice(1) : "0")+";";
		in5 = ((tvl=req.text().parse(0, ";", off))[0] == "$") ? EVAL_INT : tvl.toReal();
		errors += ((tvl[0] == "$") ? tvl.slice(1) : "0")+";";
		in6 = ((tvl=req.text().parse(0, ";", off))[0] == "$") ? EVAL_INT : tvl.toReal();
		errors += ((tvl[0] == "$") ? tvl.slice(1) : "0")+";";
		in7 = ((tvl=req.text().parse(0, ";", off))[0] == "$") ? EVAL_INT : tvl.toReal();
		errors += ((tvl[0] == "$") ? tvl.slice(1) : "0")+";";
		in8 = ((tvl=req.text().parse(0, ";", off))[0] == "$") ? EVAL_INT : tvl.toReal();
		errors += ((tvl[0] == "$") ? tvl.slice(1) : "0")+";";
	}
}

f_err = t_err;


# tmplib_PrescrTempl

ID: timer
NAME: Timer
ru#NAME: Таймер
uk#NAME: Таймер
PROGRAM:
JavaLikeCalc.JavaScript
//> Reset to default
if(f_start || (!run && tmp1)) { run = pause = error = abort = false; tmp1 = 0; rez = 1; }
//> Run
if(run && !pause)
{
	if(tmp1 == 0) tmp1 = arg1+1/f_frq;
	tmp1 = max(0, tmp1 - 1/f_frq);
	if(tmp1 <= 0) { rez = "1:Waiting "+arg1.toPrecision(3)+"s expired"; run = false; }
	else rez = "0:Waiting "+tmp1.toPrecision(3)+"с";
}

ru#PROGRAM:
JavaLikeCalc.JavaScript
//> Reset to default
if(f_start || (!run && tmp1)) { run = pause = error = abort = false; tmp1 = 0; rez = 1; }
//> Run
if(run && !pause)
{
	if(tmp1 == 0) tmp1 = arg1+1/f_frq;
	tmp1 = max(0, tmp1 - 1/f_frq);
	if(tmp1 <= 0) { rez = "1:Ожидание "+arg1.toPrecision(3)+"с истекло"; run = false; }
	else rez = "0:Ожидание "+tmp1.toPrecision(3)+"с";
}

uk#PROGRAM:
JavaLikeCalc.JavaScript
//> Reset to default
if(f_start || (!run && tmp1)) { run = pause = error = abort = false; tmp1 = 0; rez = 1; }
//> Run
if(run && !pause)
{
	if(tmp1 == 0) tmp1 = arg1+1/f_frq;
	tmp1 = max(0, tmp1 - 1/f_frq);
	if(tmp1 <= 0) { rez = "1:Очікування "+arg1.toPrecision(3)+"с вичерпано"; run = false; }
	else rez = "0:Очікування "+tmp1.toPrecision(3)+"с";
}


ID: backTimer
NAME: Background timer
ru#NAME: Фоновый таймер
uk#NAME: Фоновий таймер
PROGRAM:
JavaLikeCalc.JavaScript
//> Reset to default
if(f_start || (!run && tmp1)) { run = pause = error = abort = false; tmp1 = 0; rez = 1; }
//> Run
if(run && !pause)
{
	if(tmp1 == 0) tmp1 = arg1+1/f_frq;
	tmp1 = max(0, tmp1 - 1/f_frq);
	//if(tmp1 <= 0) { rez = "1:Ожидание "+arg1.toPrecision(3)+"с истекло"; run = false; }
	if(tmp1 <= 10)	rez = "-1:Waiting "+arg1.toPrecision(3)+"s expired";
	else rez = "10:Background waiting "+tmp1.toPrecision(3)+"s";
}

ru#PROGRAM:
JavaLikeCalc.JavaScript
//> Reset to default
if(f_start || (!run && tmp1)) { run = pause = error = abort = false; tmp1 = 0; rez = 1; }
//> Run
if(run && !pause)
{
	if(tmp1 == 0) tmp1 = arg1+1/f_frq;
	tmp1 = max(0, tmp1 - 1/f_frq);
	//if(tmp1 <= 0) { rez = "1:Ожидание "+arg1.toPrecision(3)+"с истекло"; run = false; }
	if(tmp1 <= 10)	rez = "-1:Ожидание "+arg1.toPrecision(3)+"с истекло";
	else rez = "10:Фоновое ожидание "+tmp1.toPrecision(3)+"с";
}

uk#PROGRAM:
JavaLikeCalc.JavaScript
//> Reset to default
if(f_start || (!run && tmp1)) { run = pause = error = abort = false; tmp1 = 0; rez = 1; }
//> Run
if(run && !pause)
{
	if(tmp1 == 0) tmp1 = arg1+1/f_frq;
	tmp1 = max(0, tmp1 - 1/f_frq);
	//if(tmp1 <= 0) { rez = "1:Ожидание "+arg1.toPrecision(3)+"с истекло"; run = false; }
	if(tmp1 <= 10)	rez = "-1:Очікування "+arg1.toPrecision(3)+"с вичерпано";
	else rez = "10:Фонове очікування "+tmp1.toPrecision(3)+"с";
}


# tmplib_S7

ID: ai_simple
NAME: Simple AI
DESCR: Simple analog parameter.
uk#NAME: Простий AI
uk#DESCR: Простий аналоговий параметр.
ru#NAME: Простой AI
ru#DESCR: Простой аналоговый параметр.
PROGRAM:
JavaLikeCalc.JavaScript
val=val_cod;
if(val!=EVAL_REAL)
{
  val=bDwn+(bUp-bDwn)*(val/27648.0);
  if(bUp!=bDwn && val>bUp)		f_err="101:Upper work border violation";
  else if(bUp!=bDwn && val<bDwn)	f_err="102:Lower work border violation";
  else if(bErrUp!=bErrDwn && val>bErrUp)	f_err="103:Upper alarm border violation";
  else if(bErrUp!=bErrDwn && val<bErrDwn)	f_err="104:Lower alarm border violation";
  else if(bWUp!=bWDwn && val>bWUp)	f_err="105:Upper warning border violation";
  else if(bWUp!=bWDwn && val<bWDwn)	f_err="106:Lower warning border violation";
  else f_err="0";
}

uk#PROGRAM:
JavaLikeCalc.JavaScript
val=val_cod;
if(val!=EVAL_REAL)
{
  val=bDwn+(bUp-bDwn)*(val/27648.0);
  if(bUp!=bDwn && val>bUp)		f_err="101:Порушення верхньої робочої границі";
  else if(bUp!=bDwn && val<bDwn)	f_err="102:Порушення нижньої робочої границі";
  else if(bErrUp!=bErrDwn && val>bErrUp)	f_err="103:Порушення верхньої аварійної границі";
  else if(bErrUp!=bErrDwn && val<bErrDwn)	f_err="104:Порушення нижньої аварійної границі";
  else if(bWUp!=bWDwn && val>bWUp)	f_err="105:Порушення верхньої попереджувальної границі";
  else if(bWUp!=bWDwn && val<bWDwn)	f_err="106:Порушення нижньої попереджувальної границі";
  else f_err="0";
}

ru#PROGRAM:
JavaLikeCalc.JavaScript
val=val_cod;
if(val!=EVAL_REAL)
{
  val=bDwn+(bUp-bDwn)*(val/27648.0);
  if(bUp!=bDwn && val>bUp)		f_err="101:Нарушение верхней рабочей границы";
  else if(bUp!=bDwn && val<bDwn)	f_err="102:Нарушение нижней рабочей границы";
  else if(bErrUp!=bErrDwn && val>bErrUp)	f_err="103:Нарушение верхней аварийной границы";
  else if(bErrUp!=bErrDwn && val<bErrDwn)	f_err="104:Нарушение нижней аварийной границы";
  else if(bWUp!=bWDwn && val>bWUp)	f_err="105:Нарушение верхней предупредительной границы";
  else if(bWUp!=bWDwn && val<bWDwn)	f_err="106:Нарушение нижней предупредительной границы";
  else f_err="0";
}


ID: ai_man
NAME: Manual input of AI
DESCR: Manual input of a standard analog parameter.
uk#NAME: Ручний ввід AI
uk#DESCR: Стандартний аналоговий параметр ручного вводу.
ru#NAME: Ручной ввод AI
ru#DESCR: Стандартный аналоговый параметр ручного ввода.
PROGRAM:
JavaLikeCalc.JavaScript
//Check and write new value
if(val!=val_o)
{
  val_cod=(27648.0*(val-bDwn))/(bUp-bDwn);
  val_o=val;
}
else
{
  val=val_cod;
}

if(val!=EVAL_REAL)
{
  val=val_o=bDwn+(bUp-bDwn)*(val/27648.0);
  if(bUp!=bDwn && val>bUp)		f_err="101:Upper work border violation";
  else if(bUp!=bDwn && val<bDwn)	f_err="102:Lower work border violation";
  else if(bErrUp!=bErrDwn && val>bErrUp)	f_err="103:Upper alarm border violation";
  else if(bErrUp!=bErrDwn && val<bErrDwn)	f_err="104:Lower alarm border violation";
  else if(bWUp!=bWDwn && val>bWUp)	f_err="105:Upper warning border violation";
  else if(bWUp!=bWDwn && val<bWDwn)	f_err="106:Lower warning border violation";
  else f_err="0";
}

uk#PROGRAM:
JavaLikeCalc.JavaScript
//Check and write new value
if(val!=val_o)
{
  val_cod=(27648.0*(val-bDwn))/(bUp-bDwn);
  val_o=val;
}
else
{
  val=val_cod;
}

if(val!=EVAL_REAL)
{
  val=val_o=bDwn+(bUp-bDwn)*(val/27648.0);
  if(bUp!=bDwn && val>bUp)		f_err="101:Порушення верхньої робочої границі";
  else if(bUp!=bDwn && val<bDwn)	f_err="102:Порушення нижньої робочої границі";
  else if(bErrUp!=bErrDwn && val>bErrUp)	f_err="103:Порушення верхньої аварійної границі";
  else if(bErrUp!=bErrDwn && val<bErrDwn)	f_err="104:Порушення нижньої аварійної границі";
  else if(bWUp!=bWDwn && val>bWUp)	f_err="105:Порушення верхньої попереджувальної границі";
  else if(bWUp!=bWDwn && val<bWDwn)	f_err="106:Порушення нижньої попереджувальної границі";
  else f_err="0";
}

ru#PROGRAM:
JavaLikeCalc.JavaScript
//Check and write new value
if(val!=val_o)
{
  val_cod=(27648.0*(val-bDwn))/(bUp-bDwn);
  val_o=val;
}
else
{
  val=val_cod;
}

if(val!=EVAL_REAL)
{
  val=val_o=bDwn+(bUp-bDwn)*(val/27648.0);
  if(bUp!=bDwn && val>bUp)		f_err="101:Нарушение верхней рабочей границы";
  else if(bUp!=bDwn && val<bDwn)	f_err="102:Нарушение нижней рабочей границы";
  else if(bErrUp!=bErrDwn && val>bErrUp)	f_err="103:Нарушение верхней аварийной границы";
  else if(bErrUp!=bErrDwn && val<bErrDwn)f_err="104:Нарушение нижней аварийной границы";
  else if(bWUp!=bWDwn && val>bWUp)	f_err="105:Нарушение верхней предупредительной границы";
  else if(bWUp!=bWDwn && val<bWDwn)	f_err="106:Нарушение нижней предупредительной границы";
  else f_err="0";
}


# tmplib_base

ID: simleBoard
NAME: Analog alarm by borders
DESCR: The template of simple parameter included boders and dimension variable.
uk#NAME: Сигн. аналог. за границями
uk#DESCR: Шаблон простого параметру з перевіркою границь та одиницею виміру.
ru#NAME: Сигн. аналог. по границам
ru#DESCR: Шаблон простого параметра с проверкой границ и еденицей измерения.
PROGRAM:
JavaLikeCalc.JavaScript
var=iMult*(in+iAdd);
if(var>max)			f_err="1:Upper work border violation";
else if(var<min)			f_err="2:Bottom work border violation";
else if(aMax>aMin && var>aMax)		f_err="3:Upper alarm border violation";
else if(aMax>aMin && var<aMin)		f_err="4:Bottom alarm border violation";
else if(wMax>wMin && var>wMax)	f_err="5:Upper warning border violation";
else if(wMax>wMin && var<wMin)	f_err="6:Bottom warning border violation";
else f_err="0";

uk#PROGRAM:
JavaLikeCalc.JavaScript
var=iMult*(in+iAdd);
if(var>max)			f_err="1:Порушення верхньої робочої границі";
else if(var<min)			f_err="2:Порушення нижньої робочої границі";
else if(aMax>aMin && var>aMax)		f_err="3:Порушення верхньої аварійної границі";
else if(aMax>aMin && var<aMin)		f_err="4:Порушення нижньої аварійної границі";
else if(wMax>wMin && var>wMax)	f_err="5:Порушення верхньої попереджувальної границі";
else if(wMax>wMin && var<wMin)	f_err="6:Порушення нижньої попереджувальної границі";
else f_err="0";

ru#PROGRAM:
JavaLikeCalc.JavaScript
var=iMult*(in+iAdd);
if(var>max)		f_err="1:Нарушение верхней рабочей границы";
else if(var<min)	f_err="2:Нарушение нижней рабочей границы";
else if(aMax>aMin && var>aMax)	f_err="3:Нарушение верхней аварийной границы";
else if(aMax>aMin && var<aMin)	f_err="4:Нарушение нижней аварийной границы";
else if(wMax>wMin && var>wMax)	f_err="5:Нарушение верхней предупредительной границы";
else if(wMax>wMin && var<wMin)	f_err="6:Нарушение нижней предупредительной границы";
else f_err="0";


ID: digitBlock
NAME: Diskret parameters block
DESCR: The block for union of Diskret parameters for one device control.
uk#NAME: Блок дискр. параметрів
uk#DESCR: Блок для збору дискретних параметрів, керуючих одним апаратом.
ru#NAME: Блок дискр. параметров
ru#DESCR: Блок для сборки дискретных параметров управляющих одним аппаратом.
PROGRAM:
JavaLikeCalc.JavaScript
set=false;
if(cmdOpen && last_cmd!=1) { last_cmd=1; set=true; }
if(cmdClose && last_cmd!=2) { last_cmd=2; set=true; }
if(cmdStop && last_cmd!=3) { last_cmd=3; set=true; }
if(set && tCmd>0) w_tm=tCmd;
if(w_tm>0) w_tm-=1./f_frq;
else
{
  w_tm=0;
  if(tCmd>0)
  {
    if(last_cmd==1) cmdOpen=false;
    if(last_cmd==2) cmdClose=false;
    if(last_cmd==3) cmdStop=false;
  }
}

uk#PROGRAM:
JavaLikeCalc.JavaScript
set=false;
if(cmdOpen && last_cmd!=1) { last_cmd=1; set=true; }
if(cmdClose && last_cmd!=2) { last_cmd=2; set=true; }
if(cmdStop && last_cmd!=3) { last_cmd=3; set=true; }
if(set && tCmd>0) w_tm=tCmd;
if(w_tm>0) w_tm-=1./f_frq;
else
{
  w_tm=0;
  if(tCmd>0)
  {
    if(last_cmd==1) cmdOpen=false;
    if(last_cmd==2) cmdClose=false;
    if(last_cmd==3) cmdStop=false;
  }
}

ru#PROGRAM:
JavaLikeCalc.JavaScript
set=false;
if(cmdOpen && last_cmd!=1) { last_cmd=1; set=true; }
if(cmdClose && last_cmd!=2) { last_cmd=2; set=true; }
if(cmdStop && last_cmd!=3) { last_cmd=3; set=true; }
if(set && tCmd>0) w_tm=tCmd;
if(w_tm>0) w_tm-=1./f_frq;
else
{
  w_tm=0;
  if(tCmd>0)
  {
    if(last_cmd==1) cmdOpen=false;
    if(last_cmd==2) cmdClose=false;
    if(last_cmd==3) cmdStop=false;
  }
}


ID: gasPoint
NAME: Flow control point
uk#NAME: Витрато-вимірювальний вузол
ru#NAME: Расходомерный узел
PROGRAM:
JavaLikeCalc.JavaScript
F=200+(rand(5)-2.5);
Q+=F/3600;
P=9+(rand(2)-1);
T=15+(rand(2)-1);
dP=F/33;
DS=1+(rand(0.2)-0.1);

uk#PROGRAM:
JavaLikeCalc.JavaScript
F=200+(rand(5)-2.5);
Q+=F/3600;
P=9+(rand(2)-1);
T=15+(rand(2)-1);
dP=F/33;
DS=1+(rand(0.2)-0.1);

ru#PROGRAM:
JavaLikeCalc.JavaScript
F=200+(rand(5)-2.5);
Q+=F/3600;
P=9+(rand(2)-1);
T=15+(rand(2)-1);
dP=F/33;
DS=1+(rand(0.2)-0.1);


ID: manInUnif
NAME: Manual input (Unif)
DESCR: Unified template for manual input signals.
uk#NAME: Ручний ввід (Уніф)
uk#DESCR: Уніфікований шаблон для ручного вводу значень сигналів.
ru#NAME: Ручной ввод (Униф)
ru#DESCR: Унифицированный шаблон ручного ввода сигнала.
PROGRAM:
JavaLikeCalc.JavaScript
if( varIn != var ) 
{
  vCalibr = (varIn-min)/(max-min);
  vCalibr = plcMin+(scSqr?pow(vCalibr,2):vCalibr)*(plcMax-plcMin);
  inout = vCalibr/iMult-iAdd;
}

f_err = "0";
if( inout > (plcMax+plcExcess*(plcMax-plcMin)/100) ) f_err = "1:The signal exceed to upper hardware border";
else if( inout < (plcMin-plcExcess*(plcMax-plcMin)/100) ) f_err = "2:The signal exceed to bottom hardware border";
if( f_err ) 
{
  var = dmsk ? max+plcExcess*(max-min)/100 : min-plcExcess*(max-min)/100;
  return;
}

vCalibr = iMult*(inout+iAdd);

vCalibr = (vCalibr-plcMin)/(plcMax-plcMin);
varDt = min+(max-min)*(scSqr?pow(vCalibr,0.5):vCalibr)-var;
var += varDt/max(1,Tf*f_frq);
varIn = var;

if( aMax>aMin && var>=aMax )	  f_err="3:Upper alarm border error";
else if( aMax>aMin && var<=aMin ) f_err="4:Nether alarm border error";
else if( wMax>wMin && var>wMax )  f_err="5:Upper warning border error";
else if( wMax>wMin && var<wMin )  f_err="6:Nether warning border error";
else if( speed && varDt > speed ) f_err="7:Too big parameter's motion speed";

uk#PROGRAM:
JavaLikeCalc.JavaScript
if( varIn != var ) 
{
  vCalibr = (varIn-min)/(max-min);
  vCalibr = plcMin+(scSqr?pow(vCalibr,2):vCalibr)*(plcMax-plcMin);
  inout = vCalibr/iMult-iAdd;
}

f_err = "0";
if( inout > (plcMax+plcExcess*(plcMax-plcMin)/100) ) f_err = "1:Сигнал перевищив верхню апаратну границю";
else if( inout < (plcMin-plcExcess*(plcMax-plcMin)/100) ) f_err = "2:Сигнал перевищив нижню апаратну границю";
if( f_err ) 
{
  var = dmsk ? max+plcExcess*(max-min)/100 : min-plcExcess*(max-min)/100;
  return;
}

vCalibr = iMult*(inout+iAdd);

vCalibr = (vCalibr-plcMin)/(plcMax-plcMin);
varDt = min+(max-min)*(scSqr?pow(vCalibr,0.5):vCalibr)-var;
var += varDt/max(1,Tf*f_frq);
varIn = var;

if( aMax>aMin && var>=aMax )	  f_err="3:Помилка верхньої аварійної границі";
else if( aMax>aMin && var<=aMin ) f_err="4:Помилка нижньої аварійної границі";
else if( wMax>wMin && var>wMax )  f_err="5:Помилка верхньої поперджув. границі";
else if( wMax>wMin && var<wMin )  f_err="6:Помилка нижньої поперджув. границі";
else if( speed && varDt > speed ) f_err="7:Дуже велика швидкість зміни параметру";

ru#PROGRAM:
JavaLikeCalc.JavaScript
if( varIn != var ) 
{
  vCalibr = (varIn-min)/(max-min);
  vCalibr = plcMin+(scSqr?pow(vCalibr,2):vCalibr)*(plcMax-plcMin);
  inout = vCalibr/iMult-iAdd;
}

f_err = "0";
if( inout > (plcMax+plcExcess*(plcMax-plcMin)/100) ) f_err = "1:Выход сигнала за верхнюю аппаратную границу";
else if( inout < (plcMin-plcExcess*(plcMax-plcMin)/100) ) f_err = "2:Выход сигнала за нижнюю аппаратную границу";
if( f_err ) 
{
  var = dmsk ? max+plcExcess*(max-min)/100 : min-plcExcess*(max-min)/100;
  return;
}

vCalibr = iMult*(inout+iAdd);

vCalibr = (vCalibr-plcMin)/(plcMax-plcMin);
varDt = min+(max-min)*(scSqr?pow(vCalibr,0.5):vCalibr)-var;
var += varDt/max(1,Tf*f_frq);
varIn = var;

if( aMax>aMin && var>=aMax )	  f_err="3:Нарушение верхней аварийной границы";
else if( aMax>aMin && var<=aMin ) f_err="4:Нарушение нижней аварийной границы";
else if( wMax>wMin && var>wMax )  f_err="5:Нарушение верхней предупредительной границы";
else if( wMax>wMin && var<wMin )  f_err="6:Нарушение нижней предупредительной границы";
else if( speed && varDt > speed ) f_err="7:Очень большая скорость изменения параметра";


ID: anUnif
NAME: Analog sign. (Unif)
DESCR: Unified template for analog input signals processing.
uk#NAME: Аналог. сигнал (Уніф)
uk#DESCR: Уніфікований шаблон для обробки аналогових вхідних сигналів.
ru#NAME: Аналог. сигн. (Униф)
ru#DESCR: Унифицированный шаблон обработки аналогового сигнала.
PROGRAM:
JavaLikeCalc.JavaScript
if(f_start) f_err = "0";

if(plcImit)
{
  if(!plcImitIn.isEVal()) in = plcImitIn;
  else
  {
    plcDif = abs(plcMax-plcMin);
    in = plcMin + plcDif/2 + rand(plcDif/10)-plcDif/20;
  }
}

levErr = 0;
tErr = "0";
if(in.isEVal())	{ tErr = "1:No data or connection with source"; var = EVAL_REAL; levErr = -5; }
else if(in > (max(plcMax,plcMin)+plcExcess*abs(plcMax-plcMin)/100))
{ tErr = "1:The signal exceed to upper hardware border"; var = max+plcExcess*(max-min)/100; levErr = -5; }
else if(in < (min(plcMax,plcMin)-plcExcess*abs(plcMax-plcMin)/100))
{ tErr = "2:The signal exceed to bottom hardware border"; var = min-plcExcess*(max-min)/100; levErr = -5; }
if(tErr) 
{
  //var = dmsk ? max+plcExcess*(max-min)/100 : min-plcExcess*(max-min)/100;
}
else
{
	vCalibr = iMult*(in+iAdd);

	vCalibr = (vCalibr-min(plcMax,plcMin))/abs(plcMax-plcMin);
	if(plcMax < plcMin) vCalibr = 1-vCalibr;
	varDt = min+(max-min)*(scSqr?pow(vCalibr,0.5):vCalibr)-var;
	var += varDt/max(1,Tf*f_frq);

	bndVarHyst = (max-min)*HystBnd/100;
	if(aMax < max && aMax > aMin && (var >= aMax || (f_err.toInt() == 3 && var >= (aMax-bndVarHyst))))
	{ tErr="3:Upper alarm border error"; levErr = -4; }
	else if(aMin > min && aMax > aMin && (var <= aMin || (f_err.toInt() == 4 && var <= (aMin+bndVarHyst))))
	{ tErr="4:Nether alarm border error"; levErr = -4; }
	else if(wMax < max && wMax > wMin && (var >= wMax || (f_err.toInt() == 5 && var >= (wMax-bndVarHyst))))
	{ tErr="5:Upper warning border error"; levErr = -2; }
	else if(wMin > min && wMax > wMin && (var <= wMin || (f_err.toInt() == 6 && var <= (wMin+bndVarHyst))))
	{ tErr="6:Nether warning border error"; levErr = -2; }
	else if(speed && varDt > speed)	{ tErr="7:Too big parameter's motion speed"; levErr = -2; }
}

if(tErr.toInt() && tErr.toInt() != f_err.toInt()) this.nodePrev().alarmSet((NAME.length?NAME:SHIFR)+": "+DESCR+": "+tErr.parse(1,":"), levErr, SHIFR);
else if(f_err.toInt() && !tErr.toInt()) this.nodePrev().alarmSet((NAME.length?NAME:SHIFR)+": "+DESCR+": NORMA", 1, SHIFR);
f_err = tErr;

uk#PROGRAM:
JavaLikeCalc.JavaScript
if(f_start) f_err = "0";

if(plcImit)
{
  if(!plcImitIn.isEVal()) in = plcImitIn;
  else
  {
    plcDif = abs(plcMax-plcMin);
    in = plcMin + plcDif/2 + rand(plcDif/10)-plcDif/20;
  }
}

levErr = 0;
tErr = "0";
if(in.isEVal())	{ tErr = "1:Немає даних або зв'язку із джерелом"; var = EVAL_REAL; levErr = -5; }
else if(in > (max(plcMax,plcMin)+plcExcess*abs(plcMax-plcMin)/100))
{ tErr = "1:Сигнал перевищив верхню апаратну границю"; var = max+plcExcess*(max-min)/100; levErr = -5; }
else if(in < (min(plcMax,plcMin)-plcExcess*abs(plcMax-plcMin)/100))
{ tErr = "2:Сигнал перевищив нижню апаратну границю"; var = min-plcExcess*(max-min)/100; levErr = -5; }
if(tErr) 
{
  //var = dmsk ? max+plcExcess*(max-min)/100 : min-plcExcess*(max-min)/100;
}
else
{
	vCalibr = iMult*(in+iAdd);

	vCalibr = (vCalibr-min(plcMax,plcMin))/abs(plcMax-plcMin);
	if(plcMax<plcMin) vCalibr = 1-vCalibr;
	varDt = min+(max-min)*(scSqr?pow(vCalibr,0.5):vCalibr)-var;
	var += varDt/max(1,Tf*f_frq);

	bndVarHyst = (max-min)*HystBnd/100;
	if(aMax < max && aMax > aMin && (var >= aMax || (f_err.toInt() == 3 && var >= (aMax-bndVarHyst))))
	{ tErr="3:Помилка верхньої аварійної границі"; levErr = -4; }
	else if(aMin > min && aMax > aMin && (var <= aMin || (f_err.toInt() == 4 && var <= (aMin+bndVarHyst))))
	{ tErr="4:Помилка нижньої аварійної границі"; levErr = -4; }
	else if(wMax < max && wMax > wMin && (var >= wMax || (f_err.toInt() == 5 && var >= (wMax-bndVarHyst))))
	{ tErr="5:Помилка верхньої поперджув. границі"; levErr = -2; }
	else if(wMin > min && wMax > wMin && (var <= wMin || (f_err.toInt() == 6 && var <= (wMin+bndVarHyst))))
	{ tErr="6:Помилка нижньої поперджув. границі"; levErr = -2; }
	else if(speed && varDt > speed)	{ tErr="7:Дуже велика швидкість зміни параметру"; levErr = -2; }
}

if(tErr.toInt() && tErr.toInt() != f_err.toInt()) this.nodePrev().alarmSet((NAME.length?NAME:SHIFR)+": "+DESCR+": "+tErr.parse(1,":"), levErr, SHIFR);
else if(f_err.toInt() && !tErr.toInt()) this.nodePrev().alarmSet((NAME.length?NAME:SHIFR)+": "+DESCR+": НОРМА", 1, SHIFR);
f_err = tErr;

ru#PROGRAM:
JavaLikeCalc.JavaScript
if(f_start) f_err = "0";

if(plcImit)
{
  if(!plcImitIn.isEVal()) in = plcImitIn;
  else
  {
    plcDif = abs(plcMax-plcMin);
    in = plcMin + plcDif/2 + rand(plcDif/10)-plcDif/20;
  }
}

levErr = 0;
tErr = "0";
if(in.isEVal())	{ tErr = "1:Нет данных или связи с источником"; var = EVAL_REAL; levErr = -5; }
else if(in > (max(plcMax,plcMin)+plcExcess*abs(plcMax-plcMin)/100))
{ tErr = "1:Выход сигнала за верхнюю аппаратную границу"; var = max+plcExcess*(max-min)/100; levErr = -5; }
else if(in < (min(plcMax,plcMin)-plcExcess*abs(plcMax-plcMin)/100))
{ tErr = "2:Выход сигнала за нижнюю аппаратную границу"; var = min-plcExcess*(max-min)/100; levErr = -5; }
if(tErr) 
{
  //var = dmsk ? max+plcExcess*(max-min)/100 : min-plcExcess*(max-min)/100;
}
else
{
	vCalibr = iMult*(in+iAdd);

	vCalibr = (vCalibr-min(plcMax,plcMin))/abs(plcMax-plcMin);
	if(plcMax<plcMin) vCalibr = 1-vCalibr;
	varDt = min+(max-min)*(scSqr?pow(vCalibr,0.5):vCalibr)-var;
	var += varDt/max(1,Tf*f_frq);

	bndVarHyst = (max-min)*HystBnd/100;
	if(aMax < max && aMax > aMin && (var >= aMax || (f_err.toInt() == 3 && var >= (aMax-bndVarHyst))))
	{ tErr="3:Нарушение верхней аварийной границы"; levErr = -4; }
	else if(aMin > min && aMax > aMin && (var <= aMin || (f_err.toInt() == 4 && var <= (aMin+bndVarHyst))))
	{ tErr="4:Нарушение нижней аварийной границы"; levErr = -4; }
	else if(wMax < max && wMax > wMin && (var >= wMax || (f_err.toInt() == 5 && var >= (wMax-bndVarHyst))))
	{ tErr="5:Нарушение верхней предупредительной границы"; levErr = -2; }
	else if(wMin > min && wMax > wMin && (var <= wMin || (f_err.toInt() == 6 && var <= (wMin+bndVarHyst))))
	{ tErr="6:Нарушение нижней предупредительной границы"; levErr = -2; }
	else if(speed && varDt > speed)	{ tErr="7:Очень большая скорость изменения параметра"; levErr = -2; }
}

if(tErr.toInt() && tErr.toInt() != f_err.toInt()) this.nodePrev().alarmSet((NAME.length?NAME:SHIFR)+": "+DESCR+": "+tErr.parse(1,":"), levErr, SHIFR);
else if(f_err.toInt() && !tErr.toInt()) this.nodePrev().alarmSet((NAME.length?NAME:SHIFR)+": "+DESCR+": НОРМА", 1, SHIFR);
f_err = tErr;


ID: digitBlockUnif
NAME: Diskret block (Unif)
DESCR: The block for union of Diskret parameters for one device control.
uk#NAME: Блок дискретних (Уніф)
uk#DESCR: Блок поєднання дискретних сигналів контролю одним пристроєм.
ru#NAME: Блок дискр. (Униф)
ru#DESCR: Блок для дискретных параметров управляющих одним аппаратом.
PROGRAM:
JavaLikeCalc.JavaScript
set=false;
if( com != EVAL_BOOL && com && last_cmd!=1 ) { last_cmd=1; set=true; }
if( close != EVAL_BOOL && close && last_cmd!=2 ) { last_cmd=2; set=true; }
if( stop != EVAL_BOOL && stop && last_cmd!=3 ) { last_cmd=3; set=true; }
if( set && tCmd > 0 ) w_tm = tCmd;
if( w_tm > 0 ) w_tm -= 1./f_frq;
else
{
  w_tm=0;
  if( tCmd > 0 )
  {
    if( last_cmd==1 ) com = false;
    if( last_cmd==2 ) close = false;
    if( last_cmd==3 ) stop = false;
    last_cmd = 0;
  }
}

uk#PROGRAM:
JavaLikeCalc.JavaScript
set=false;
if( com != EVAL_BOOL && com && last_cmd!=1 ) { last_cmd=1; set=true; }
if( close != EVAL_BOOL && close && last_cmd!=2 ) { last_cmd=2; set=true; }
if( stop != EVAL_BOOL && stop && last_cmd!=3 ) { last_cmd=3; set=true; }
if( set && tCmd > 0 ) w_tm = tCmd;
if( w_tm > 0 ) w_tm -= 1./f_frq;
else
{
  w_tm=0;
  if( tCmd > 0 )
  {
    if( last_cmd==1 ) com = false;
    if( last_cmd==2 ) close = false;
    if( last_cmd==3 ) stop = false;
    last_cmd = 0;
  }
}

ru#PROGRAM:
JavaLikeCalc.JavaScript
set=false;
if( com != EVAL_BOOL && com && last_cmd!=1 ) { last_cmd=1; set=true; }
if( close != EVAL_BOOL && close && last_cmd!=2 ) { last_cmd=2; set=true; }
if( stop != EVAL_BOOL && stop && last_cmd!=3 ) { last_cmd=3; set=true; }
if( set && tCmd > 0 ) w_tm = tCmd;
if( w_tm > 0 ) w_tm -= 1./f_frq;
else
{
  w_tm=0;
  if( tCmd > 0 )
  {
    if( last_cmd==1 ) com = false;
    if( last_cmd==2 ) close = false;
    if( last_cmd==3 ) stop = false;
    last_cmd = 0;
  }
}


ID: pidUnifImp
NAME: Impulse PID sign. (Unif, stats)
DESCR: The unified template for process analog signals with properties impulse PID.
uk#NAME: Імпульсний ПІД сигнал (Уніф, стани)
uk#DESCR: Уніфікований шаблон для обробки аналогового сигналу з властивостями імпульсного ПІД.
ru#NAME: ПИД импульсный сигн. (Униф, состояния)
ru#DESCR: Унифицированный шаблон обработки аналогового сигнала со свойствами импульсного ПИД.
PROGRAM:
JavaLikeCalc.JavaScript
if(f_start) f_err = "0";

if(plcImit)
{
	if(plcImitIn != EVAL_REAL) in = plcImitIn;
	else
	{
		plcDif = plcMax-plcMin;
		in = plcMin + plcDif/2 + rand(plcDif/10)-plcDif/20;
	}
}

tErr = "0";
if( in > (plcMax+plcExcess*(plcMax-plcMin)/100) )
{ tErr = "1:The signal exceed to upper hardware border"; var = max+plcExcess*(max-min)/100;}
else if( in < (plcMin-plcExcess*(plcMax-plcMin)/100) )
{ tErr = "2:The signal exceed to bottom hardware border"; var = min-plcExcess*(max-min)/100;}
if( tErr ) 
{
  //var = dmsk ? max+plcExcess*(max-min)/100 : min-plcExcess*(max-min)/100;
  EVAL = true;
}
else
{
	vCalibr = iMult*(in+iAdd);

	vCalibr = (vCalibr-plcMin)/(plcMax-plcMin);
	varDt = min+(max-min)*(scSqr?pow(vCalibr,0.5):vCalibr)-var;
	var += varDt/max(1,Tf/1000*f_frq);

	bndVarHyst = (aMax-aMin)*HystBnd/100;
	if( aMax>aMin && (var>=aMax || (HH && var>=(aMax-bndVarHyst))) )
	{ tErr="3:Upper alarm border error"; HH=true; EVAL=H=LL=L=false; }
	else if( aMax>aMin && (var<=aMin || (LL && var<=(aMin+bndVarHyst))) )
	{ tErr="4:Bottom alarm border error"; LL=true; EVAL=HH=H=L=false; }
	else if( wMax>wMin && (var>=wMax || (H && var>=(wMax-bndVarHyst))) )
	{ tErr="5:Upper warning border error"; H=true; EVAL=HH=LL=L=false; }
	else if( wMax>wMin && (var<=wMin || (L && var<=(wMin+bndVarHyst))) )
	{ tErr="6:Bottom warning border error"; L=true; EVAL=HH=H=LL=false; }
	else if( speed && varDt > speed ) { tErr="7:Too big parameter's motion speed";   EVAL=true; HH=H=LL=L=false; }
	else EVAL=HH=H=LL=L=false;
}

if(!f_err.toInt() && tErr.toInt()) this.nodePrev().alarmSet((NAME.length?NAME:SHIFR)+": "+DESCR+": "+tErr.parse(1,":"), -4, SHIFR);
else if(f_err.toInt() && !tErr.toInt()) this.nodePrev().alarmSet((NAME.length?NAME:SHIFR)+": "+DESCR+": NORMA", 1, SHIFR);
f_err = tErr;

uk#PROGRAM:
JavaLikeCalc.JavaScript
if(f_start) f_err = "0";

if(plcImit)
{
	if(plcImitIn != EVAL_REAL) in = plcImitIn;
	else
	{
		plcDif = plcMax-plcMin;
		in = plcMin + plcDif/2 + rand(plcDif/10)-plcDif/20;
	}
}

tErr = "0";
if( in > (plcMax+plcExcess*(plcMax-plcMin)/100) )
{ tErr = "1:Сигнал перевищив верхню апаратну границю"; var = max+plcExcess*(max-min)/100;}
else if( in < (plcMin-plcExcess*(plcMax-plcMin)/100) )
{ tErr = "2:Сигнал перевищив нижню апаратну границю"; var = min-plcExcess*(max-min)/100;}
if( tErr ) 
{
  //var = dmsk ? max+plcExcess*(max-min)/100 : min-plcExcess*(max-min)/100;
  EVAL = true;
}
else
{
	vCalibr = iMult*(in+iAdd);

	vCalibr = (vCalibr-plcMin)/(plcMax-plcMin);
	varDt = min+(max-min)*(scSqr?pow(vCalibr,0.5):vCalibr)-var;
	var += varDt/max(1,Tf/1000*f_frq);

	bndVarHyst = (aMax-aMin)*HystBnd/100;
	if( aMax>aMin && (var>=aMax || (HH && var>=(aMax-bndVarHyst))) )
	{ tErr="3:Помилка верхньої границі аварії"; HH=true; EVAL=H=LL=L=false; }
	else if( aMax>aMin && (var<=aMin || (LL && var<=(aMin+bndVarHyst))) )
	{ tErr="4:Помилка нижньої границі аварії"; LL=true; EVAL=HH=H=L=false; }
	else if( wMax>wMin && (var>=wMax || (H && var>=(wMax-bndVarHyst))) )
	{ tErr="5:Помилка верхньої границі попередження"; H=true; EVAL=HH=LL=L=false; }
	else if( wMax>wMin && (var<=wMin || (L && var<=(wMin+bndVarHyst))) )
	{ tErr="6:Помилка нижньої границі попередження"; L=true; EVAL=HH=H=LL=false; }
	else if( speed && varDt > speed ) { tErr="7:Дуже велика швидкість зміни параметру";   EVAL=true; HH=H=LL=L=false; }
	else EVAL=HH=H=LL=L=false;
}

if(!f_err.toInt() && tErr.toInt()) this.nodePrev().alarmSet((NAME.length?NAME:SHIFR)+": "+DESCR+": "+tErr.parse(1,":"), -4, SHIFR);
else if(f_err.toInt() && !tErr.toInt()) this.nodePrev().alarmSet((NAME.length?NAME:SHIFR)+": "+DESCR+": NORMA", 1, SHIFR);
f_err = tErr;

ru#PROGRAM:
JavaLikeCalc.JavaScript
if(f_start) f_err = "0";

if(plcImit)
{
	if(plcImitIn != EVAL_REAL) in = plcImitIn;
	else
	{
		plcDif = plcMax-plcMin;
		in = plcMin + plcDif/2 + rand(plcDif/10)-plcDif/20;
	}
}

tErr = "0";
if(in > (plcMax+plcExcess*(plcMax-plcMin)/100))
{ tErr = "1:Выход сигнала за верхнюю аппаратную границу"; var = max+plcExcess*(max-min)/100;}
else if(in < (plcMin-plcExcess*(plcMax-plcMin)/100))
{ tErr = "2:Выход сигнала за нижнюю аппаратную границу"; var = min-plcExcess*(max-min)/100;}
if(tErr)
{
	//var = dmsk ? max+plcExcess*(max-min)/100 : min-plcExcess*(max-min)/100;
	EVAL = true;
}
else
{
	vCalibr = iMult*(in+iAdd);

	vCalibr = (vCalibr-plcMin)/(plcMax-plcMin);
	varDt = min+(max-min)*(scSqr?pow(vCalibr,0.5):vCalibr)-var;
	var += varDt/max(1,Tf/1000*f_frq);

	bndVarHyst = (aMax-aMin)*HystBnd/100;
	if(aMax>aMin && (var>=aMax || (HH && var>=(aMax-bndVarHyst))))
	{ tErr="3:Нарушение верхней аварийной границы"; HH=true; EVAL=H=LL=L=false; }
	else if(aMax>aMin && (var<=aMin || (LL && var<=(aMin+bndVarHyst))))
	{ tErr="4:Нарушение нижней аварийной границы"; LL=true; EVAL=HH=H=L=false; }
	else if(wMax>wMin && (var>=wMax || (H && var>=(wMax-bndVarHyst))))
	{ tErr="5:Нарушение верхней предупредительной границы"; H=true; EVAL=HH=LL=L=false; }
	else if(wMax>wMin && (var<=wMin || (L && var<=(wMin+bndVarHyst))))
	{ tErr="6:Нарушение нижней предупредительной границы"; L=true; EVAL=HH=H=LL=false; }
	else if(speed && varDt > speed) { tErr="7:Очень большая скорость изменения параметра";   EVAL=true; HH=H=LL=L=false; }
	else EVAL=HH=H=LL=L=false;
}

if(!f_err.toInt() && tErr.toInt()) this.nodePrev().alarmSet((NAME.length?NAME:SHIFR)+": "+DESCR+": "+tErr.parse(1,":"), -4, SHIFR);
else if(f_err.toInt() && !tErr.toInt()) this.nodePrev().alarmSet((NAME.length?NAME:SHIFR)+": "+DESCR+": НОРМА", 1, SHIFR);
f_err = tErr;


ID: anUnifSt
NAME: Analog sign. (Unif, stats)
DESCR: Unified template for analog input signals processing.
uk#NAME: Аналог. сигнал (Уніф, стани)
uk#DESCR: Уніфікований шаблон для обробки аналогових вхідних сигналів.
ru#NAME: Аналог. сигн. (Униф, состояния)
ru#DESCR: Унифицированный шаблон обработки аналогового сигнала.
PROGRAM:
JavaLikeCalc.JavaScript
if(f_start) f_err = "0";

if(plcImit)
{
	if(!plcImitIn.isEVal()) in = plcImitIn;
	else
	{
		plcDif = plcMax-plcMin;
		in = plcMin + plcDif/2 + rand(plcDif/10)-plcDif/20;
	}
}

tErr = "0";
if(in.isEVal())	{ tErr = "1:No data or conection to source"; var = EVAL_REAL; }
else if(in > (plcMax+plcExcess*(plcMax-plcMin)/100))
{ tErr = "1:The signal exceed to upper hardware border"; var = max+plcExcess*(max-min)/100; }
else if(in < (plcMin-plcExcess*(plcMax-plcMin)/100))
{ tErr = "2:The signal exceed to bottom hardware border"; var = min-plcExcess*(max-min)/100; }
if(tErr)
{
  //var = dmsk ? max+plcExcess*(max-min)/100 : min-plcExcess*(max-min)/100;
  EVAL = true;
  HH=H=LL=L=false;
}
else
{
	vCalibr = iMult*(in+iAdd);

	vCalibr = (vCalibr-plcMin)/(plcMax-plcMin);
	varDt = min+(max-min)*(scSqr?pow(vCalibr,0.5):vCalibr)-var;
	var += varDt/max(1,Tf*f_frq);

	bndVarHyst = (aMax-aMin)*HystBnd/100;
	if( aMax>aMin && (var>=aMax || (HH && var>=(aMax-bndVarHyst))) )
	{ tErr="3:Upper alarm border error"; HH=true; EVAL=H=LL=L=false; }
	else if( aMax>aMin && (var<=aMin || (LL && var<=(aMin+bndVarHyst))) )
	{ tErr="4:Bottom alarm border error"; LL=true; EVAL=HH=H=L=false; }
	else if( wMax>wMin && (var>=wMax || (H && var>=(wMax-bndVarHyst))) )
	{ tErr="5:Upper warning border error"; H=true; EVAL=HH=LL=L=false; }
	else if( wMax>wMin && (var<=wMin || (L && var<=(wMin+bndVarHyst))) )
	{ tErr="6:Bottom warning border error"; L=true; EVAL=HH=H=LL=false; }
	else if( speed && varDt > speed ) { tErr="7:Too big parameter's motion speed";   EVAL=true; HH=H=LL=L=false; }
	else EVAL=HH=H=LL=L=false;
}

if(!f_err.toInt() && tErr.toInt()) this.nodePrev().alarmSet((NAME.length?NAME:SHIFR)+": "+DESCR+": "+tErr.parse(1,":"), -4, SHIFR);
else if(f_err.toInt() && !tErr.toInt()) this.nodePrev().alarmSet((NAME.length?NAME:SHIFR)+": "+DESCR+": NORMA", 1, SHIFR);
f_err = tErr;

uk#PROGRAM:
JavaLikeCalc.JavaScript
if(f_start) f_err = "0";

if(plcImit)
{
	if(!plcImitIn.isEVal()) in = plcImitIn;
	else
	{
		plcDif = plcMax-plcMin;
		in = plcMin + plcDif/2 + rand(plcDif/10)-plcDif/20;
	}
}

tErr = "0";
if(in.isEVal())	{ tErr = "1:Немає даних або зв'язку із джерелом"; var = EVAL_REAL; }
else if(in > (plcMax+plcExcess*(plcMax-plcMin)/100))
{ tErr = "1:Сигнал перевищив верхню апаратну границю"; var = max+plcExcess*(max-min)/100; }
else if(in < (plcMin-plcExcess*(plcMax-plcMin)/100))
{ tErr = "2:Сигнал перевищив нижню апаратну границю"; var = min-plcExcess*(max-min)/100; }
if(tErr)
{
	//var = dmsk ? max+plcExcess*(max-min)/100 : min-plcExcess*(max-min)/100;
	EVAL = true;
	HH=H=LL=L=false;
}
else
{
	vCalibr = iMult*(in+iAdd);

	vCalibr = (vCalibr-plcMin)/(plcMax-plcMin);
	varDt = min+(max-min)*(scSqr?pow(vCalibr,0.5):vCalibr)-var;
	var += varDt/max(1,Tf*f_frq);

	bndVarHyst = (aMax-aMin)*HystBnd/100;
	if(aMax>aMin && (var>=aMax || (HH && var>=(aMax-bndVarHyst))))
	{ tErr="3:Помилка верхньої границі аварії"; HH=true; EVAL=H=LL=L=false; }
	else if(aMax>aMin && (var<=aMin || (LL && var<=(aMin+bndVarHyst))))
	{ tErr="4:Помилка нижньої границі аварії"; LL=true; EVAL=HH=H=L=false; }
	else if(wMax>wMin && (var>=wMax || (H && var>=(wMax-bndVarHyst))))
	{ tErr="5:Помилка верхньої границі попередження"; H=true; EVAL=HH=LL=L=false; }
	else if(wMax>wMin && (var<=wMin || (L && var<=(wMin+bndVarHyst))))
	{ tErr="6:Помилка нижньої границі попередження"; L=true; EVAL=HH=H=LL=false; }
	else if(speed && varDt > speed) { tErr="7:Дуже велика швидкість зміни параметру";   EVAL=true; HH=H=LL=L=false; }
	else EVAL=HH=H=LL=L=false;
}

if(!f_err.toInt() && tErr.toInt()) this.nodePrev().alarmSet((NAME.length?NAME:SHIFR)+": "+DESCR+": "+tErr.parse(1,":"), -4, SHIFR);
else if(f_err.toInt() && !tErr.toInt()) this.nodePrev().alarmSet((NAME.length?NAME:SHIFR)+": "+DESCR+": НОРМА", 1, SHIFR);
f_err = tErr;

ru#PROGRAM:
JavaLikeCalc.JavaScript
if(f_start) f_err = "0";

if(plcImit)
{
	if(!plcImitIn.isEVal()) in = plcImitIn;
	else
	{
		plcDif = plcMax-plcMin;
		in = plcMin + plcDif/2 + rand(plcDif/10)-plcDif/20;
	}
}

tErr = "0";
if(in.isEVal())	{ tErr = "1:Нет данных или связи с источником"; var = EVAL_REAL; }
else if(in > (plcMax+plcExcess*(plcMax-plcMin)/100))
{ tErr = "1:Выход сигнала за верхнюю аппаратную границу"; var = max+plcExcess*(max-min)/100; }
else if(in < (plcMin-plcExcess*(plcMax-plcMin)/100))
{ tErr = "2:Выход сигнала за нижнюю аппаратную границу"; var = min-plcExcess*(max-min)/100; }
if(tErr)
{
  //var = dmsk ? max+plcExcess*(max-min)/100 : min-plcExcess*(max-min)/100;
  EVAL = true;
  HH=H=LL=L=false;
}
else
{
	vCalibr = iMult*(in+iAdd);

	vCalibr = (vCalibr-plcMin)/(plcMax-plcMin);
	varDt = min+(max-min)*(scSqr?pow(vCalibr,0.5):vCalibr)-var;
	var += varDt/max(1,Tf*f_frq);

	bndVarHyst = (aMax-aMin)*HystBnd/100;
	if(aMax>aMin && (var>=aMax || (HH && var>=(aMax-bndVarHyst))))
	{ tErr="3:Нарушение верхней аварийной границы"; HH=true; EVAL=H=LL=L=false; }
	else if(aMax>aMin && (var<=aMin || (LL && var<=(aMin+bndVarHyst))))
	{ tErr="4:Нарушение нижней аварийной границы"; LL=true; EVAL=HH=H=L=false; }
	else if(wMax>wMin && (var>=wMax || (H && var>=(wMax-bndVarHyst))))
	{ tErr="5:Нарушение верхней предупредительной границы"; H=true; EVAL=HH=LL=L=false; }
	else if(wMax>wMin && (var<=wMin || (L && var<=(wMin+bndVarHyst))))
	{ tErr="6:Нарушение нижней предупредительной границы"; L=true; EVAL=HH=H=LL=false; }
	else if(speed && varDt > speed) { tErr="7:Очень большая скорость изменения параметра";   EVAL=true; HH=H=LL=L=false; }
	else EVAL=HH=H=LL=L=false;
}

if(!f_err.toInt() && tErr.toInt()) this.nodePrev().alarmSet((NAME.length?NAME:SHIFR)+": "+DESCR+": "+tErr.parse(1,":"), -4, SHIFR);
else if(f_err.toInt() && !tErr.toInt()) this.nodePrev().alarmSet((NAME.length?NAME:SHIFR)+": "+DESCR+": НОРМА", 1, SHIFR);
f_err = tErr;


ID: pidUnif
NAME: PID sign. (Unif, stats)
DESCR: The unified template for process analog signals with properties PID.
uk#NAME: ПІД сигнал (Уніф, стани)
uk#DESCR: Уніфікований шаблон для обробки аналогового сигналу з властивостями ПІД.
ru#NAME: ПИД сигн. (Униф, состояния)
ru#DESCR: Унифицированный шаблон обработки аналогового сигнала со свойствами ПИД.
PROGRAM:
JavaLikeCalc.JavaScript
if(f_start) f_err = "0";

if(plcImit)
{
	if(plcImitIn != EVAL_REAL) in = plcImitIn;
	else
	{
		plcDif = plcMax-plcMin;
		in = plcMin + plcDif/2 + rand(plcDif/10)-plcDif/20;
	}
}

tErr = "0";
if( in > (plcMax+plcExcess*(plcMax-plcMin)/100) )
{ tErr = "1:The signal exceed to upper hardware border"; var = max+plcExcess*(max-min)/100;}
else if( in < (plcMin-plcExcess*(plcMax-plcMin)/100) )
{ tErr = "2:The signal exceed to bottom hardware border"; var = min-plcExcess*(max-min)/100;}
if( tErr ) 
{
  //var = dmsk ? max+plcExcess*(max-min)/100 : min-plcExcess*(max-min)/100;
  EVAL = true;
}
else
{
	vCalibr = iMult*(in+iAdd);

	vCalibr = (vCalibr-plcMin)/(plcMax-plcMin);
	varDt = min+(max-min)*(scSqr?pow(vCalibr,0.5):vCalibr)-var;
	var += varDt/max(1,Tf/1000*f_frq);

	bndVarHyst = (aMax-aMin)*HystBnd/100;
	if( aMax>aMin && (var>=aMax || (HH && var>=(aMax-bndVarHyst))) )
	{ tErr="3:Upper alarm border error"; HH=true; EVAL=H=LL=L=false; }
	else if( aMax>aMin && (var<=aMin || (LL && var<=(aMin+bndVarHyst))) )
	{ tErr="4:Nether alarm border error"; LL=true; EVAL=HH=H=L=false; }
	else if( wMax>wMin && (var>=wMax || (H && var>=(wMax-bndVarHyst))) )
	{ tErr="5:Upper warning border error"; H=true; EVAL=HH=LL=L=false; }
	else if( wMax>wMin && (var<=wMin || (L && var<=(wMin+bndVarHyst))) )
	{ tErr="6:Nether warning border error"; L=true; EVAL=HH=H=LL=false; }
	else if( speed && varDt > speed ) { tErr="7:Too big parameter's motion speed";   EVAL=true; HH=H=LL=L=false; }
	else EVAL=HH=H=LL=L=false;
}

if(!f_err.toInt() && tErr.toInt()) this.nodePrev().alarmSet((NAME.length?NAME:SHIFR)+": "+DESCR+": "+tErr.parse(1,":"), -4, SHIFR);
else if(f_err.toInt() && !tErr.toInt()) this.nodePrev().alarmSet((NAME.length?NAME:SHIFR)+": "+DESCR+": NORMA", 1, SHIFR);
f_err = tErr;

uk#PROGRAM:
JavaLikeCalc.JavaScript
if(f_start) f_err = "0";

if(plcImit)
{
	if(plcImitIn != EVAL_REAL) in = plcImitIn;
	else
	{
		plcDif = plcMax-plcMin;
		in = plcMin + plcDif/2 + rand(plcDif/10)-plcDif/20;
	}
}

tErr = "0";
if( in > (plcMax+plcExcess*(plcMax-plcMin)/100) )
{ tErr = "1:Сигнал перевищив верхню апаратну границю"; var = max+plcExcess*(max-min)/100;}
else if( in < (plcMin-plcExcess*(plcMax-plcMin)/100) )
{ tErr = "2:Сигнал перевищив нижню апаратну границю"; var = min-plcExcess*(max-min)/100;}
if( tErr ) 
{
  //var = dmsk ? max+plcExcess*(max-min)/100 : min-plcExcess*(max-min)/100;
  EVAL = true;
}
else
{
	vCalibr = iMult*(in+iAdd);

	vCalibr = (vCalibr-plcMin)/(plcMax-plcMin);
	varDt = min+(max-min)*(scSqr?pow(vCalibr,0.5):vCalibr)-var;
	var += varDt/max(1,Tf/1000*f_frq);

	bndVarHyst = (aMax-aMin)*HystBnd/100;
	if( aMax>aMin && (var>=aMax || (HH && var>=(aMax-bndVarHyst))) )
	{ tErr="3:Помилка верхньої границі аварії"; HH=true; EVAL=H=LL=L=false; }
	else if( aMax>aMin && (var<=aMin || (LL && var<=(aMin+bndVarHyst))) )
	{ tErr="4:Помилка нижньої границі аварії"; LL=true; EVAL=HH=H=L=false; }
	else if( wMax>wMin && (var>=wMax || (H && var>=(wMax-bndVarHyst))) )
	{ tErr="5:Помилка верхньої границі попередження"; H=true; EVAL=HH=LL=L=false; }
	else if( wMax>wMin && (var<=wMin || (L && var<=(wMin+bndVarHyst))) )
	{ tErr="6:Помилка нижньої границі попередження"; L=true; EVAL=HH=H=LL=false; }
	else if( speed && varDt > speed ) { tErr="7:Дуже велика швидкість зміни параметру";   EVAL=true; HH=H=LL=L=false; }
	else EVAL=HH=H=LL=L=false;
}

if(!f_err.toInt() && tErr.toInt()) this.nodePrev().alarmSet((NAME.length?NAME:SHIFR)+": "+DESCR+": "+tErr.parse(1,":"), -4, SHIFR);
else if(f_err.toInt() && !tErr.toInt()) this.nodePrev().alarmSet((NAME.length?NAME:SHIFR)+": "+DESCR+": NORMA", 1, SHIFR);
f_err = tErr;

ru#PROGRAM:
JavaLikeCalc.JavaScript
if(f_start) f_err = "0";

if(plcImit)
{
	if(plcImitIn != EVAL_REAL) in = plcImitIn;
	else
	{
		plcDif = plcMax-plcMin;
		in = plcMin + plcDif/2 + rand(plcDif/10)-plcDif/20;
	}
}

tErr = "0";
if(in > (plcMax+plcExcess*(plcMax-plcMin)/100))
{ tErr = "1:Выход сигнала за верхнюю аппаратную границу"; var = max+plcExcess*(max-min)/100;}
else if(in < (plcMin-plcExcess*(plcMax-plcMin)/100))
{ tErr = "2:Выход сигнала за нижнюю аппаратную границу"; var = min-plcExcess*(max-min)/100;}
if(tErr) 
{
  //var = dmsk ? max+plcExcess*(max-min)/100 : min-plcExcess*(max-min)/100;
  EVAL = true;
}
else
{
	vCalibr = iMult*(in+iAdd);

	vCalibr = (vCalibr-plcMin)/(plcMax-plcMin);
	varDt = min+(max-min)*(scSqr?pow(vCalibr,0.5):vCalibr)-var;
	var += varDt/max(1,Tf/1000*f_frq);

	bndVarHyst = (aMax-aMin)*HystBnd/100;
	if(aMax>aMin && (var>=aMax || (HH && var>=(aMax-bndVarHyst))))
	{ tErr="3:Нарушение верхней аварийной границы"; HH=true; EVAL=H=LL=L=false; }
	else if(aMax>aMin && (var<=aMin || (LL && var<=(aMin+bndVarHyst))))
	{ tErr="4:Нарушение нижней аварийной границы"; LL=true; EVAL=HH=H=L=false; }
	else if(wMax>wMin && (var>=wMax || (H && var>=(wMax-bndVarHyst))))
	{ tErr="5:Нарушение верхней предупредительной границы"; H=true; EVAL=HH=LL=L=false; }
	else if(wMax>wMin && (var<=wMin || (L && var<=(wMin+bndVarHyst))))
	{ tErr="6:Нарушение нижней предупредительной границы"; L=true; EVAL=HH=H=LL=false; }
	else if(speed && varDt > speed) { tErr="7:Очень большая скорость изменения параметра";   EVAL=true; HH=H=LL=L=false; }
	else EVAL=HH=H=LL=L=false;
}

if(!f_err.toInt() && tErr.toInt()) this.nodePrev().alarmSet((NAME.length?NAME:SHIFR)+": "+DESCR+": "+tErr.parse(1,":"), -4, SHIFR);
else if(f_err.toInt() && !tErr.toInt()) this.nodePrev().alarmSet((NAME.length?NAME:SHIFR)+": "+DESCR+": НОРМА", 1, SHIFR);
f_err = tErr;


