JavaLikeCalc.JavaScript
//Request form:
//<mess addr="16" try="1" err="1:Error">{req}</mess> - message tag
//req - request/respond data;
//addr - remote device address [16...254];
//try - tries for the request;
//err - sets for the request result.

if(!io.text().length) { io.setAttr("err","1:"+tr("Message empty")); return; }
addr = io.attr("addr").toInt();
try = min(5,max(1,io.attr("try").toInt()));
request = "\x02"+SYS.strFromCharCode(addr) + io.text();
//Calc CHKSUM
CRC = 0;
for(i = 1; i < request.length; i++) CRC += request.charCodeAt(i);
request += SYS.strFromCharCode((CRC>>4&0xF)+0x30,(CRC&0xF)+0x30,0x0D);

SYS.messDebug("/UserProt/SMDP",tr("Request:")+" "+Special.FLibSYS.strDec4Bin(request));

for( ; try > 0; try--) {
	//Send the request
	resp = tr.messIO(request);
	while(resp.length && resp.charCodeAt(resp.length-1) != 0x0D)
		if((tresp=tr.messIO("")).length) resp += tresp;
		else break;

	if(!resp.length)	{ io.setAttr("err","2:"+tr("No respond")); continue; }
	if(resp.length < 6 || resp.charCodeAt(resp.length-1) != 0x0D)	{ io.setAttr("err","3:"+tr("Not full respond")); continue; }
	if(resp.charCodeAt(0) != 0x02 || resp.charCodeAt(1) != addr)	{ io.setAttr("err","4:"+tr("Wrong respond")); continue; }

	SYS.messDebug("/UserProt/SMDP",tr("Respond:")+" "+Special.FLibSYS.strDec4Bin(resp));

	CRC = 0;
	for(i = 1; i < (resp.length-3); i++) CRC += resp.charCodeAt(i);
	if((CRC&0xFF) != (((resp.charCodeAt(resp.length-3)-0x30)<<4)|(resp.charCodeAt(resp.length-2)-0x30)))
	{ io.setAttr("err","6:"+tr("CRC error.")); continue; }
	break;
}
if(try <= 0)	return;

errCd = resp.charCodeAt(2)&0x7;
if(errCd == 1) io.setAttr("err","").setText(resp.slice(2,-2));
else if(errCd == 2) io.setAttr("err",""+(10+errCd)+":Err_inv_cmd: "+tr("Illegal command (CMD code not valid)."));
else if(errCd == 3) io.setAttr("err",""+(10+errCd)+":Err_syntax: "+tr("Syntax error. (Too many bytes in data field, not enough bytes, etc)."));
else if(errCd == 4) io.setAttr("err",""+(10+errCd)+":Err_range: "+tr("Data range error."));
else if(errCd == 5) io.setAttr("err",""+(10+errCd)+":Err_inhibited: "+tr("Inhibited."));
else if(errCd == 6) io.setAttr("err",""+(10+errCd)+":Err_obso: "+tr("Obsolete command. No action taken, but not really an error."));
else io.setAttr("err",""+(10+errCd)+":"+tr("Unknown error."));