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(mbType).setAttr("id","EnronDaniel").setAttr("node",addr).setText(PDU);
	if((rez=tr.messIO(reqO,"ModBus")).length)	return "10:"+rez;
	PDU = reqO.text();

	return reqO.attr("err");
}

if(f_start) {
	transport_ = transport;
	tr = EVAL;
	dt = new Object();
	items_ = "";
}

//Parse the items set and create user attributes
if(items != items_) {
	items_ = items;
	// Mark for check to deletion needs
	for(var iDt in dt)
		if(iDt != "10000") dt[iDt].mark = false;
	// Append/Update present ones
	for(off = 0; (sIt=items.parseLine(0,off)).length; ) {
		if(sIt[0] == "#")	continue;
		off1 = 0;
		itO = new Object();
		itO.tp = sIt.parse(0, ":", off1);
		tmpAddr = sIt.parse(0, ":", off1);
		itO.addr = tmpAddr.toInt();
		itO.md = sIt.parse(0, ":", off1);
		itO.id = sIt.parse(0, ":", off1);
		itO.nm = sIt.slice(off1);
		dt[itO.addr.toString(16,5)] = itO;
		if(itO.tp == "u" || itO.tp == "i")	{ wTp = "integer"; itO.sz = 4; }
		else if(itO.tp == "s")	{ wTp = "string"; itO.sz = 16; }
		else { wTp = "real"; itO.sz = 4; }
		itO.rd = (itO.md.indexOf("r") >= 0); itO.wr = (itO.md.indexOf("w") >= 0);
		if(!itO.wr)	wTp += "|ro";
		if(itO.rd || itO.wr) {
			this.attrAdd(itO.id, itO.nm, wTp);
			if(itO.wr)	itO.val = this[itO.id].get();
			itO.mark = true;
			//SYS.messInfo("/ED","itO="+itO.id+"; tmpAddr="+tmpAddr+"; addr="+itO.addr);
		}
	}
	dt["10000"] = EVAL;
	// Check, remove item and set to EVAL the attribute
	for(var iDt in dt) {
		if(iDt == "10000" || dt[iDt].mark)	continue;
		this[dt[iDt].id].set(EVAL, 0, 0, true);
		delete dt[iDt];
	}
}

if(f_start || f_stop) return;

tErr = "";

//Checking for the transport change and connect
if(tr.isEVal() || transport != transport_)	{
	if(!transport.length) {
		if(!((tVl=this.cntr().cfg("PROT")) == "RTU" || tVl == "ASCII" || tVl == "TCP"))
			tErr = "1:"+tr("Output transport is empty and the controller object is not ModBus.");
		else {
			tr = new Object();
			maxBlkSz = this.cntr().cfg("MAX_BLKSZ");
			if(maxBlkSz.isEVal())	maxBlkSz = 12;
			fragMerge = this.cntr().cfg("FRAG_MERGE");
			if(fragMerge.isEVal())	fragMerge = false;
		}
	} else tr = SYS.Transport[transport.parse(0)]["out_"+transport.parse(1)];
	maxBlkSz = max(10, min(200,maxBlkSz));
	transport_ = transport;
}
if(tErr.toInt()) ;
else if(tr.isEVal())
	tErr = "1:"+tr("Output transport '%1' error.").replace("%1",transport);
else if(addr < 0 || addr > 247)
	tErr = "2:"+tr("Address '%1' out of range [0...247].").replace("%1",addr.toString());
else {
	//Check for changed attributes and perform writing
	for(var iDt in dt) {
		isEOL = (iDt == "10000");
		itO = dt[iDt];
		tVl = this[itO.id].get();
		if(isEOL || !itO.wr || tVl.isEVal() || itO.val == tVl)	continue;
		PDU = Special.FLibSYS.IO("", "", "b");
		PDU.wr(6,"uint8").wr(itO.addr,"uint16");
		if(itO.tp == "u")		PDU.wr(tVl,"uint32");
		else if(itO.tp == "i")	PDU.wr(tVl,"int32");
		else if(itO.tp == "s")	PDU.wr(tVl.slice(0,16),"char").wr(" ","char",16-min(16,tVl.length));
		else PDU.wr(tVl,"float");
		//SYS.messInfo("/ED","reqPDU="+SYS.strDecode(PDU.string,"Bin"," "));
		if(!req(PDU.string).toInt())	itO.val = tVl;
		//SYS.messInfo("/ED","respPDU="+SYS.strDecode(PDU.string,"Bin"," "));
	}

	//Same requests for the data
	blk = new Array();
	for(var iDt in dt) {
		isEOL = (iDt == "10000");
		itO = dt[iDt];
		//SYS.messInfo("/ED","iDt="+iDt+"; isEOL="+isEOL);
		if(!isEOL && (!blk.length || (
				itO.sz == blk[blk.length-1].sz &&
				(((itO.addr-blk[0].addr)+1)*itO.sz) < maxBlkSz && (fragMerge || (itO.addr-blk[blk.length-1].addr) <= 1) ))) {
			if(itO.rd) blk.push(itO);
			continue;
		}
		//Send request for this block
		if(blk.length) {
			regN = (blk[blk.length-1].addr - blk[0].addr) + 1;
			PDU = SYS.strFromCharCode(3, (blk[0].addr>>8)&0xFF, blk[0].addr&0xFF, 0, regN);
			//SYS.messInfo("/ED","reqPDU="+SYS.strDecode(PDU,"Bin"," "));
			if((tErr=req(PDU)).toInt()) break;
			//SYS.messInfo("/ED","respPDU="+SYS.strDecode(PDU,"Bin"," "));
			io = Special.FLibSYS.IO(PDU, "", "b");
			rF = io.read("uint8", 1); rN = io.read("uint8", 1);
			if(rF != 3 || (io.length-2) != rN || rN != regN*blk[0].sz) { tErr = "10:"+tr("Inconsistent respond's length."); break; }
			for(iB = 0; iB < blk.length; iB++) {
				itO1 = blk[iB];
				io.pos = 2 + (itO1.addr-blk[0].addr)*blk[0].sz;
				if(itO1.tp == "u")			tVl = io.read("uint32", 1);
				else if(itO1.tp == "i")	tVl = io.read("int32", 1);
				else if(itO1.tp == "s")	tVl = io.read("char", blk[0].sz);
				else tVl = io.read("float", 1);
				if(itO1.wr && itO1.val != this[itO1.id].get())	{ itO1.val = tVl; continue; }
				this[itO1.id].set(tVl, 0, 0, true);
				itO1.val = tVl;

				/*if(itO1.tp == "u")			this[itO1.id].set(io.read("uint32",1), 0, 0, true);
				else if(itO1.tp == "i")	this[itO1.id].set(io.read("int32",1), 0, 0, true);
				else if(itO1.tp == "s")	this[itO1.id].set(io.read("char",blk[0].sz), 0, 0, true);
				else this[itO1.id].set(io.read("float",1), 0, 0, true);
				if(itO1.wr)	itO1.val = this[itO1.id].get();*/
			}
			blk = new Array(); blk.push(itO);
		}
	}
}

f_err = tErr.length ? tErr : "0";