JavaLikeCalc.JavaScript
//Same request to the device
function req(PDU) {
	// For placing into the module ModBus
	if(!transport.length)	return this.cntr().messIO(PDU);

	// For other logical level
	reqO = SYS.XMLNode("RTU").setAttr("id","Ultramag").setAttr("node",addr).setText(PDU);
	if((rez=tr.messIO(reqO,"ModBus")).length)	return "10:"+rez;
	PDU = reqO.text();

	return reqO.attr("err");
}

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

//Main process
if(f_start) {
	f_err = "0:"+tr("Waiting for the full call");
	transport_ = transport;
	tr = EVAL;
	arhSt = "";
	cTm = 0;
	devManuf = devNameVer = devSN = curTm = EVAL;
	p = t = coefCor = vWork = vAccWork = vResult = vAccResult = fWork = fResult = EVAL;
	reset = false;
}

if((f_start && typeof(arhs) != "array") || reset) {
	reset = false;
	//Archives init
	tmCur = SYS.time();
	arhs = new Array();
	arhs.tmPrev = 0;
	a = new Object();
	a.id = "Hours"; a.numb = 1; a.cnt = 14400; a.per = 3600; a.arh = arhH; a.pos = -1; a.tm = 0; a.tmTrc = 0;
	arhs.push(a);
	a = new Object();
	a.id = "Days"; a.numb = 2; a.cnt = 1800; a.per = 24*3600; a.arh = arhD; a.pos = -1; a.tm = 0; a.tmTrc = 0;
	arhs.push(a);
	a = new Object();
	a.id = "Months"; a.numb = 3; a.cnt = 2000; a.per = 31*24*3600; a.arh = arhM; a.pos = -1; a.tm = 0; a.tmTrc = 0;
	arhs.push(a);
}
if(f_start || f_stop) return;

t_err = "0:";

//Check for the transport change and connect
if(tr.isEVal() || transport != transport_)	{
	if(!transport.length) {
		if(this.cntr().cfg("PROT") != "RTU")
			t_err = "1:"+tr("Output transport is empty and the controller object is not ModBus RTU.");
		else tr = new Object();
	}
	else tr = SYS.Transport[transport.parse(0)]["out_"+transport.parse(1)];
	transport_ = transport;
}
if(t_err.toInt()) ;
else if(tr.isEVal())
	t_err = "1:"+tr("Output transport '%1' error.").replace("%1",transport);
else if(addr < 0 || addr > 247)
	t_err = "2:"+tr("Address '%1' out of range [0...247].").replace("%1",addr.toString());
else {

	tmCur = SYS.time();
	//Settings write
	// Concentration N2
	/*if(!stN2.isEVal() && stN2 != stN2_ && !t_err.toInt()) {
		data = "6E36" + floatSet(stN2);
		if(!(t_err=req(tr,15,data,true)).toInt() && data == "OKEY")	stN2_ = stN2;
	}*/

	//Settings read
	// Concentration N2 and CO2
	/*data = "6E3600000000";
	if(!t_err.toInt() && (stN2.isEVal() || stCO2.isEVal()) && !(t_err=req(tr,6,data)).toInt()) {
		stN2 = stN2_ = floatGet(data);
		stCO2 = stCO2_ = floatGet(data.slice(8));
	}*/

	//Current values request
	if((tmCur-cTm) > arhTryPer) {
		devManuf = devNameVer = devSN = curTm = EVAL;
		p = t = coefCor = vWork = vAccWork = vResult = vAccResult = fWork = fResult = EVAL;
		cTm = tmCur;
	}
	// Manufacturer name
	data = SYS.strFromCharCode(0x4, 0x2, 0x59, 0, 15);
	if(devManuf.isEVal() && !t_err.toInt() && !(t_err=req(data)).toInt())
		devManuf = SYS.strCodeConv(data.slice(2), "CP866", "");
	// Device number
	data = SYS.strFromCharCode(0x4, 0x2, 0x77, 0, 5);
	if(devSN.isEVal() && !t_err.toInt() && !(t_err=req(data)).toInt())
		devSN = SYS.strCodeConv(data.slice(2), "CP866", "");
	// Sensor P SN
	data = SYS.strFromCharCode(0x4, 0x2, 0x81, 0, 5);
	if(sensP_SN.isEVal() && !t_err.toInt() && !(t_err=req(data)).toInt())
		sensP_SN = SYS.strCodeConv(data.slice(2), "CP866", "");
	// Sensor T SN
	data = SYS.strFromCharCode(0x4, 0x2, 0x8B, 0, 5);
	if(sensT_SN.isEVal() && !t_err.toInt() && !(t_err=req(data)).toInt())
		sensT_SN = SYS.strCodeConv(data.slice(2), "CP866", "");
	// Flow: work
	data = SYS.strFromCharCode(0x4, 0, 0xF, 0, 4);
	if(fWork.isEVal() && !t_err.toInt() && !(t_err=req(data)).toInt())
	{ io = Special.FLibSYS.IO(data.slice(2), "", "b"); fWork = io.read("double", 1); }
	// Flow: resume
	data = SYS.strFromCharCode(0x4, 0, 0x17, 0, 4);
	if(fResult.isEVal() && !t_err.toInt() && !(t_err=req(data)).toInt())
	{ io = Special.FLibSYS.IO(data.slice(2), "", "b"); fResult = io.read("double", 1); }
	// Gas P
	data = SYS.strFromCharCode(0x4, 0, 0x1F, 0, 4);
	if(p.isEVal() && !t_err.toInt() && !(t_err=req(data)).toInt())
	{ io = Special.FLibSYS.IO(data.slice(2), "", "b"); p = io.read("double", 1); }
	// Gas T
	data = SYS.strFromCharCode(0x4, 0, 0x27, 0, 4);
	if(t.isEVal() && !t_err.toInt() && !(t_err=req(data)).toInt())
	{ io = Special.FLibSYS.IO(data.slice(2), "", "b"); t = io.read("double", 1); }
	// Coefficient of the correction
	data = SYS.strFromCharCode(0x4, 0, 0x3F, 0, 4);
	if(coefCor.isEVal() && !t_err.toInt() && !(t_err=req(data)).toInt())
	{ io = Special.FLibSYS.IO(data.slice(2), "", "b"); coefCor = io.read("double", 1); }
	// Volume work
	data = SYS.strFromCharCode(0x4, 0, 0x4F, 0, 4);
	if(vWork.isEVal() && !t_err.toInt() && !(t_err=req(data)).toInt())
	{ io = Special.FLibSYS.IO(data.slice(2), "", "b"); vWork = io.read("double", 1); }
	// Volume standard
	data = SYS.strFromCharCode(0x4, 0, 0x47, 0, 4);
	if(vResult.isEVal() && !t_err.toInt() && !(t_err=req(data)).toInt())
	{ io = Special.FLibSYS.IO(data.slice(2), "", "b"); vResult = io.read("double", 1); }
	// Current time
	data = SYS.strFromCharCode(0x4, 0, 0x1, 0, 6);
	if(curTm.isEVal() && !t_err.toInt() && !(t_err=req(data)).toInt())
		curTm = (data.charCodeAt(1+5)*256+data.charCodeAt(1+6)).toString()+"-"+data.charCodeAt(1+4).toString(10,2)+"-"+data.charCodeAt(1+2).toString(10,2)+"T"+data.charCodeAt(1+8)+":"+data.charCodeAt(1+10).toString(10,2)+":"+data.charCodeAt(1+12).toString(10,2);

	//Archives array processing
	arhSt = "";
	for(iA = 0; iA < arhs.length; iA++) {
		aO = arhs[iA];
		arhSt += (arhSt.length?"; ":"")+aO.id + ": ";
		//SYS.messDebug("/GB","Archive "+aO.id+"; arh="+aO.arh);
		if(!aO.arh.length)	{ arhSt += tr("Disabled"); continue; }

		//Initiate the archive reading current point
		if(aO.pos < 0)	aO.pos = aO.cnt;
		if(arhs.tmPrev && (tVl=(tmCur-arhs.tmPrev)/aO.per) > 1)	//compensate the long shut down
			aO.pos = min(aO.cnt, aO.pos+floor(tVl));

		if(t_err.toInt())	arhSt += tr("Missed by error - ");
		else if(aO.pos > 1 || (tmCur-aO.tmTrc) >= arhTryPer) {
			//Set the archive number
			data = SYS.strFromCharCode(0x10, 0x01, 0x2F, 0, 1, 2, 0, aO.numb);
			if(!(t_err=req(data)).toInt()) {
				//Requests
				while(!t_err.toInt() && (SYS.time()-tmCur) < arhTmLim) {
					//Set the item number
					data = SYS.strFromCharCode(0x10, 0x01, 0x31, 0, 1, 2, aO.pos/256, aO.pos%256);
					if(!(t_err=req(data)).toInt())	{
						//Requesting the needed data
						data = SYS.strFromCharCode(0x4, 0x1, 0x41, 0, 18);
						if(!(t_err=req(data)).toInt())	{
							io = Special.FLibSYS.IO(data.slice(2), "", "b");
							dtD = io.read("uint8", 1);
							dtM = io.read("uint8", 1);
							dtY = 2000+io.read("uint8", 1);
							dtH = io.read("uint8", 1);
							if(dtD >= 1 && dtD <= 31 && dtM >= 1 && dtM <= 12 && dtH <= 23) {
								dtTm = (aO.per >= 24*3600) ? SYS.timegm(0, 0, dtH, dtD, dtM-1, dtY) : SYS.mktime(0, 0, dtH, dtD, dtM-1, dtY);
								aO.tm = max(aO.tm, dtTm);
								//SYS.messDebug("/UM","Archive "+aO.id+"; arh="+aO.arh+"; tm="+SYS.strftime(dtTm)+"; dtSrc="+dtD);
								if(aO.numb == 1) {	//hours
									archSet("p", dtTm, aO.arh, io.read("float",1));
									archSet("t", dtTm, aO.arh, io.read("float",1));
									archSet("vAccWork", dtTm, aO.arh, io.read("double",1));
									archSet("vAccResult", dtTm, aO.arh, io.read("double",1));
								}
								else if(aO.numb == 2) {	//days
									archSet("p", dtTm, aO.arh, io.read("float",1));
									archSet("t", dtTm, aO.arh, io.read("float",1));
									archSet("vWork", dtTm, aO.arh, io.read("float",1));
									archSet("vResult", dtTm, aO.arh, io.read("float",1));
									archSet("vAccWork", dtTm, aO.arh, io.read("double",1));
									archSet("vAccResult", dtTm, aO.arh, io.read("double",1));
								}
								else if(aO.numb == 3) {	//months
									archSet("vWork", dtTm, aO.arh, io.read("float",1));
									archSet("vResult", dtTm, aO.arh, io.read("float",1));
									archSet("vAccWork", dtTm, aO.arh, io.read("double",1));
									archSet("vAccResult", dtTm, aO.arh, io.read("double",1));
								}
							}
							if(aO.pos > 1)	aO.pos--;
							else { aO.tmTrc = tmCur; break; }
						}
					}
				}
			}
		}
		if(aO.per > 24*3600)		dtForm = "%Y-%m";
		else if(aO.per > 3600)	dtForm = "%Y-%m-%d";
		else if(aO.per > 60)		dtForm = "%Y-%m-%d %H";
		else									dtForm = "%Y-%m-%d %H %M";
		if(aO.pos == 1) arhSt += tr("Trace for current time=%1").replace("%1",SYS.strftime(aO.tm,dtForm));
		else arhSt += tr("Initial reading in position %1, time=%2").replace("%1",aO.pos.toString()).replace("%2",SYS.strftime(aO.tm,dtForm));
		SYS.cntrReq(SYS.XMLNode("save").setAttr("path",this.nodePath()+"/%2fobj").setAttr("force",1));
	}

	arhs.tmPrev = tmCur;
}

f_err = t_err + arhSt;