JavaLikeCalc.JavaScript
//Same request to the device
function req(data, cmd, waitSz) {
	if(data == null || cmd == null || waitSz == null)	return tr("2:Empty request. ");
	req = "EM"+cmd+" !125m"+addr.toString(10,4)+data+SYS.strFromCharCode(0x0D,rand(255));
	//Calc and append the CRC
	CRC = Special.FLibSYS.CRC(req, 16, 0x8005);
	req += SYS.strFromCharCode(CRC&0xFF, CRC>>8);

	SYS.messDebug("/EM125/"+this.cfg("SHIFR"), tr("Request")+": "+SYS.strDecode(req,"Bin"," "));

	//Send and receive
	for(resp = tr.messIO(req); resp.length && (!waitSz || resp.length < (waitSz+1)) && (tresp=tr.messIO("")).length; )
		resp += tresp;
	if(!resp.length)	return tr("3:No response. ");
	else if(resp.length < (waitSz+1))	return tr("3:Response isn't completed. ");
	for(CRC = 0xA5, iCh = 0; iCh < (resp.length-1); iCh++)
		CRC = CRC^resp.charCodeAt(iCh);
	if(CRC != resp.charCodeAt(resp.length-1))
	//if(Special.FLibSYS.CRC(resp.slice(0,-2),16,0x8005) != resp.charCodeAt(resp.length-2,"UTF-16LE"))
		return tr("3:Error the response CRC. ");

	SYS.messDebug("/EM125/"+this.cfg("SHIFR"), tr("Response")+": "+SYS.strDecode(resp,"Bin"," "));

	data = resp.slice(0,-1);

	return "0";
}

//Seting value to the archive
function archSet(attr, vTm, vl, arh) {
	SYS.messDebug("/EM125/"+this.cfg("SHIFR"), "attr="+attr+"; vTm="+SYS.strftime(vTm)+"; arh="+arh+"; vl="+vl);
	atrO = this[attr];
	if(!atrO || atrO.isEVal()) return;
	arguments[attr] = vl;	//Set the current-last value
	//if(vTm > atrO.time())	atrO.set(vl,vTm,0,true);
	if(atrO.arch())	atrO.arch().setVal(vTm*1e6, vl, arh);
}

if(f_start) {
	reset = arhSelH = arhSelD = false;
	cTm = 0;
	arhThresH = 60*60;
	arhThresD = 2*24*60*60;
}

if(reset) {
	reset = arhSelH = arhSelD = false, arhLastD = arhLastH = 0;
	cTm = 0;
}

if(f_start || f_stop)	return;

tErr = "";

if(!(tr=SYS.Transport.outAt(transport)) || !tr.start(true))
	tErr = "1:"+tr("Output transport '%1' error.").replace("%1",transport);
else if(addr < 0 || addr > 9999)
	tErr = "2:"+tr("Address '%1' out of range [0...9999].").replace("%1",addr.toString());
else {
	tmCur = SYS.time();

	//Reading current values
	if((tmCur-cTm) > arhTryPer) {
		devDtTm = EVAL, devDtTm_ = 0;
		G1 = G2 = q1 = q2 = q3 = q4 = m1 = m2 = m3 = m4 = T1 = T2 = T3 = P1 = P2 = P3 = dT1 = dT2 = EVAL;
		Q1 = Q2 = V1 = V2 = V3 = V4 = M1 = M2 = M3 = M4 = EVAL;
		cTm = tmCur;
	}

	data = "";
	if(!devDtTm_ && !(tErr=req(data,"C",450)).toInt()) {
		io = Special.FLibSYS.IO(data); io.pos = 0;
		tmS = io.read("uint8", 1); tmM = io.read("uint8", 1); tmH = io.read("uint8", 1);
		dtD = io.read("uint8", 1); dtM = io.read("uint8", 1); dtY = io.read("uint8", 1);
		devDtTm = SYS.strftime(devDtTm_=SYS.mktime(tmS,tmM,tmH,dtD,dtM-1,2000+dtY));
		io.pos += 10;
		G1 = io.read("float", 1);
		G2 = io.read("float", 1);
		q1 = io.read("float", 1);
		q2 = io.read("float", 1);
		/*q3 =*/ io.read("float", 1);
		/*q4 =*/ io.read("float", 1);
		m1 = io.read("float", 1);
		m2 = io.read("float", 1);
		/*m3 =*/ io.read("float", 1);
		/*m4 =*/ io.read("float", 1);
		T1 = io.read("float", 1);
		T2 = io.read("float", 1);
		T3 = io.read("float", 1);
		P1 = io.read("float", 1);
		P2 = io.read("float", 1);
		P3 = io.read("float", 1);
		/*q1 =*/ io.read("float", 1);
		/*q2 =*/ io.read("float", 1);
		q3 = io.read("float", 1);
		q4 = io.read("float", 1);
		/*m1 =*/ io.read("float", 1);
		/*m2 =*/ io.read("float", 1);
		m3 = io.read("float", 1);
		m4 = io.read("float", 1);
		dT1 = io.read("float", 1);
		dT2 = io.read("float", 1);
		io.pos = 256;
		Q1 = io.read("long", 1);
		Q2 = io.read("long", 1);
		V1 = io.read("long", 1);
		V2 = io.read("long", 1);
		V3 = io.read("long", 1);
		V4 = io.read("long", 1);
		M1 = io.read("long", 1);
		M2 = io.read("long", 1);
		M3 = io.read("long", 1);
		M4 = io.read("long", 1);
		Q1 += io.read("float", 1);
		Q2 += io.read("float", 1);
		V1 += io.read("float", 1);
		V2 += io.read("float", 1);
		V3 += io.read("float", 1);
		V4 += io.read("float", 1);
		M1 += io.read("float", 1);
		M2 += io.read("float", 1);
		M3 += io.read("float", 1);
		M4 += io.read("float", 1);
	}

	//Requesting the hourly archive
	if(devDtTm_ && !arhSelD && arhH.length && !tErr.toInt() && (devDtTm_-arhLastH) > arhThresH) {
		toSave = false;

		if(!arhSelH)
			cmd = "A",	data = " %0 "+(arhLastH?SYS.strftime(arhLastH,"%d.%m.%y"):"1.01.00");
		else cmd = "F", data = "";
		while((SYS.time()-tmCur) < arhTmLim && !(tErr=req(data,cmd,130)).toInt()) {
			io = Special.FLibSYS.IO(data); io.pos = 2;
			tmH = io.read("uint8", 1);
			dtD = io.read("uint8", 1); dtM = io.read("uint8", 1); dtY = io.read("uint8", 1);

			if(tmH <= 24 && (arhLastH_=SYS.mktime(0,0,tmH,dtD,dtM-1,2000+dtY)) > arhLastH) {
				arhLastH = arhLastH_;

				archSet("dQ1", arhLastH, io.read("float", 1), arhH);
				archSet("dQ2", arhLastH, io.read("float", 1), arhH);
				archSet("dV1", arhLastH, io.read("float", 1), arhH);
				archSet("dV2", arhLastH, io.read("float", 1), arhH);
				archSet("dV3", arhLastH, io.read("float", 1), arhH);
				archSet("dV4", arhLastH, io.read("float", 1), arhH);
				archSet("dM1", arhLastH, io.read("float", 1), arhH);
				archSet("dM2", arhLastH, io.read("float", 1), arhH);
				archSet("dM3", arhLastH, io.read("float", 1), arhH);
				archSet("dM4", arhLastH, io.read("float", 1), arhH);
				archSet("dt1_work", arhLastH, io.read("long", 1), arhH);
				archSet("dt2_work", arhLastH, io.read("long", 1), arhH);
				archSet("dt3_work", arhLastH, io.read("long", 1), arhH);
				archSet("dt4_work", arhLastH, io.read("long", 1), arhH);
				archSet("dt1_idle", arhLastH, io.read("long", 1), arhH);
				archSet("dt2_idle", arhLastH, io.read("long", 1), arhH);
				archSet("dt3_idle", arhLastH, io.read("long", 1), arhH);
				archSet("dt4_idle", arhLastH, io.read("long", 1), arhH);
				archSet("dt1_cut", arhLastH, io.read("long", 1), arhH);
				archSet("dt2_cut", arhLastH, io.read("long", 1), arhH);
				archSet("dt1_rev", arhLastH, io.read("long", 1), arhH);
				archSet("dt2_rev", arhLastH, io.read("long", 1), arhH);
				archSet("dt1_up", arhLastH, io.read("long", 1), arhH);
				archSet("dt2_up", arhLastH, io.read("long", 1), arhH);
				archSet("dt_nopow", arhLastH, io.read("long", 1), arhH);
				archSet("dT1", arhLastH, io.read("float", 1), arhH);
				archSet("dT2", arhLastH, io.read("float", 1), arhH);
				archSet("dT3", arhLastH, io.read("float", 1), arhH);
				archSet("dP1", arhLastH, io.read("float", 1), arhH);
				archSet("dP2", arhLastH, io.read("float", 1), arhH);
				archSet("dP3", arhLastH, io.read("float", 1), arhH);

				toSave = true;
			}
			cmd = "F", data = "";
			arhSelH = ((devDtTm_-arhLastH) > arhThresH);
		}
		if(toSave)	SYS.cntrReq(SYS.XMLNode("save").setAttr("path",this.nodePath()+"/%2fobj").setAttr("force",1));
	}
	//Requesting the daily archive
	else if(devDtTm_ && !arhSelH && arhD.length && !tErr.toInt() && (devDtTm_-arhLastD) > arhThresD) {
		toSave = false;

		if(!arhSelD)
			cmd = "A",	data = " %1 "+(arhLastD?SYS.strftime(arhLastD,"%d.%m.%y"):"1.01.00");
		else cmd = "F", data = "";
		while((SYS.time()-tmCur) < arhTmLim && !(tErr=req(data,cmd,130)).toInt()) {
			io = Special.FLibSYS.IO(data); io.pos = 3;
			dtD = io.read("uint8", 1); dtM = io.read("uint8", 1); dtY = io.read("uint8", 1);

			if((arhLastD_=SYS.mktime(0,0,0,dtD,dtM-1,2000+dtY)) > arhLastD) {
				arhLastD = arhLastD_;

				archSet("dQ1", arhLastD, io.read("float", 1), arhD);
				archSet("dQ2", arhLastD, io.read("float", 1), arhD);
				archSet("dV1", arhLastD, io.read("float", 1), arhD);
				archSet("dV2", arhLastD, io.read("float", 1), arhD);
				archSet("dV3", arhLastD, io.read("float", 1), arhD);
				archSet("dV4", arhLastD, io.read("float", 1), arhD);
				archSet("dM1", arhLastD, io.read("float", 1), arhD);
				archSet("dM2", arhLastD, io.read("float", 1), arhD);
				archSet("dM3", arhLastD, io.read("float", 1), arhD);
				archSet("dM4", arhLastD, io.read("float", 1), arhD);
				archSet("dt1_work", arhLastD, io.read("long", 1), arhD);
				archSet("dt2_work", arhLastD, io.read("long", 1), arhD);
				archSet("dt3_work", arhLastD, io.read("long", 1), arhD);
				archSet("dt4_work", arhLastD, io.read("long", 1), arhD);
				archSet("dt1_idle", arhLastD, io.read("long", 1), arhD);
				archSet("dt2_idle", arhLastD, io.read("long", 1), arhD);
				archSet("dt3_idle", arhLastD, io.read("long", 1), arhD);
				archSet("dt4_idle", arhLastD, io.read("long", 1), arhD);
				archSet("dt1_cut", arhLastD, io.read("long", 1), arhD);
				archSet("dt2_cut", arhLastD, io.read("long", 1), arhD);
				archSet("dt1_rev", arhLastD, io.read("long", 1), arhD);
				archSet("dt2_rev", arhLastD, io.read("long", 1), arhD);
				archSet("dt1_up", arhLastD, io.read("long", 1), arhD);
				archSet("dt2_up", arhLastD, io.read("long", 1), arhD);
				archSet("dt_nopow", arhLastD, io.read("long", 1), arhD);
				archSet("dT1", arhLastD, io.read("float", 1), arhD);
				archSet("dT2", arhLastD, io.read("float", 1), arhD);
				archSet("dT3", arhLastD, io.read("float", 1), arhD);
				archSet("dP1", arhLastD, io.read("float", 1), arhD);
				archSet("dP2", arhLastD, io.read("float", 1), arhD);
				archSet("dP3", arhLastD, io.read("float", 1), arhD);

				toSave = true;
			}

			cmd = "F", data = "";
			arhSelD = ((devDtTm_-arhLastD) > arhThresD);
		}

		if(toSave)	SYS.cntrReq(SYS.XMLNode("save").setAttr("path",this.nodePath()+"/%2fobj").setAttr("force",1));
	}
}

//Error set
if(!tErr.length)	tErr = "0";
if(tErr.toInt()) {
	if(!tr.isEVal() && tr.start()) tr.start(false);
	if(f_err != tErr) {
		SYS.messDebug("/EM125/"+this.cfg("SHIFR"), tr("Error")+": "+tErr);

		//G1 = G2 = q1 = q2 = q3 = q4 = m1 = m2 = m3 = m4 = T1 = T2 = T3 = P1 = P2 = P3 = dT1 = dT2 = EVAL;
		//Q1 = Q2 = V1 = V2 = V3 = V4 = M1 = M2 = M3 = M4 = EVAL;
	}
}
prcSt = "";
if(arhD.length) {
	if(arhLastD && (devDtTm_-arhLastD) <= arhThresD)
		prcSt += tr("Days: ") + tr("Trace for current time=%1").replace("%1",SYS.strftime(arhLastD,"%Y-%m-%d")) + "; ";
	else {
		prcSt += tr("Days: ") + tr("Reading in time=%1").replace("%1",SYS.strftime(arhLastD,"%Y-%m-%d")) + "; ";
	}
}
if(arhH.length) {
	if(arhLastH && (devDtTm_-arhLastH) <= arhThresH)
		prcSt += tr("Hours: ") + tr("Trace for current time=%1").replace("%1",SYS.strftime(arhLastH,"%Y-%m-%d %H")) + "; ";
	else
		prcSt += tr("Hours: ") + tr("Reading in time=%1").replace("%1",SYS.strftime(arhLastH,"%Y-%m-%d %H")) + "; ";
}
f_err = tErr + (prcSt.length?((tErr=="0")?": ":" ")+prcSt:"");