/* * A JavaScript implementation of the datagram create and analyse */ var util = require('../utils/util.js'); var crc16 = require('../utils/crc16.js'); function crcCheck(datagram) { if (datagram.length > 4) { let content = datagram.substring(0, datagram.length - 4); let crcCode = datagram.substring(datagram.length - 4); crcCode = "" + crcCode.toLowerCase(); let crc = crc16.hexStrToCrc16(content) crc = "" + crc.toLowerCase(); if (crcCode === crc) { return true; } else { console.log("------------------------------------crc check error!----------------------------"); console.log("crc code:" + crcCode + " " + crc); console.log(datagram); return false; } } else { console.log("------------------------------------crc check error!----------------------------"); console.log(datagram); return false; } } /** * F6报文 ,与设备进行握手通信 */ function datagram_f6() { var datagram = "7E7E0000000000910000F680000205F728"; return datagram; } /** * F6 报文,报文解析 */ function datagram_f6_analyse(datagram) { if (datagram.length > 0) { if (datagram.indexOf("7e7e") >= 0) { if (datagram.length >= 50) { var funcode = datagram.substring(20, 22); if (funcode == 'f6') { var data = {} data['func'] = 'f6' return data; } } } } return null; } /** * 查询设备状态 */ function datagram_f7() { var datagram = "7E7E0000000000910000F7800002053715"; return datagram; } function datagram_f7_analyse(datagram) { console.log("------------------------------------find f7 datagram----------------------------"); console.log(datagram); var tmprtuInfo = { datagram_idx: '', collect_time: '', acc_rain: '', fiveMinute_rain: '', hour_rain: '', weater_level: '', power_v: '', rtu_ver: '', rtu_uuid: '', bt_v: '', rtu_rssi: '', rtu_temperature: '', lua_ver: '', func: 'f7' } var count = 20; var funcode = datagram.substring(count, count + 2); count += 2; //上行标识及长度 var len = datagram.substring(count, count + 4); count += 4; //起始符 var s = datagram.substring(count, count + 2); count += 2; //流水号 var idx = datagram.substring(count, count + 4); var idx_buff = util.HexStr2Bytes(idx); var idx_v = util.getView(idx_buff).getUint16(); tmprtuInfo['datagram_idx'] = idx_v.toString(); count += 4; //时间 var collect_time = datagram.substring(count, count + 12); tmprtuInfo['collect_time'] = "20" + collect_time.substring(0, 2) + "-" + collect_time.substring(2, 4) + "-" + collect_time.substring(4, 6) + " " + collect_time.substring(6, 8) + ":" + collect_time.substring(8, 10) + ":" + collect_time.substring(10, 12); count += 12; while (true) { if (count >= (datagram.length - 3 * 2)) { break } var value_code = datagram.substring(count, count + 2); count += 2; if (value_code == 'ff') { value_code = datagram.substring(count, count + 2); count += 2; var value_len = datagram.substring(count, count + 2); count += 2; let len_buff = util.HexStr2Bytes(value_len); let len_v = util.getView(len_buff).getUint8(); len_v = len_v >> 3; console.log("func ff" + value_code); if (value_code == '80') { //RTU版本 var value = datagram.substring(count, count + len_v * 2); var v_buff = util.HexStr2Bytes(value); var v = util.byteToString(v_buff); tmprtuInfo['rtu_ver'] = v; //count += 36; count += len_v * 2; } else if (value_code == '81') { //唯一识别码UID var value = datagram.substring(count, count + len_v * 2); var v_buff = util.HexStr2Bytes(value); var v = util.byteToString(v_buff); tmprtuInfo['rtu_uuid'] = v; // count += 18; count += len_v * 2; } else if (value_code == '50') { //信号强度 var value = datagram.substring(count, count + 4); value = value.substring(0, 2) + "." + value.substring(2, 4); var v = parseFloat(value) tmprtuInfo['rtu_rssi'] = v.toFixed(2) console.log('50' + value + " " + v + " " + v.toFixed(2)); count += 4; } else if (value_code == '51') { //电源电压 var value = datagram.substring(count, count + 4); value = value.substring(0, 2) + "." + value.substring(2, 4); var v = parseFloat(value) tmprtuInfo['power_v'] = v.toFixed(2) count += 4; } else if (value_code == '52') { //设备温度 var value = datagram.substring(count, count + 4); value = value.substring(0, 2) + "." + value.substring(2, 4); var v = parseFloat(value) tmprtuInfo['rtu_temperature'] = v.toFixed(2) count += 4; } else if (value_code == '82') { //LUA版本 var value = datagram.substring(count, count + len_v * 2); var v_buff = util.HexStr2Bytes(value); var v = util.byteToString(v_buff); tmprtuInfo['lua_ver'] = v; //count += 18; count += len_v * 2; } else { console.log("func unknrow ff " + value_code); count += len_v * 2; } } else if (value_code == '26') { console.log("func " + value_code); var value_len = datagram.substring(count, count + 2); count += 2; //累计雨量 var value = datagram.substring(count, count + 6); value = value.substring(0, 5) + "." + value.substring(5, 6); var v = parseFloat(value) tmprtuInfo['acc_rain'] = v.toFixed(1) count += 6; } else if (value_code == '39') { console.log("func " + value_code); var value_len = datagram.substring(count, count + 2); count += 2; //瞬时水位 var value = datagram.substring(count, count + 2); var sig = ""; if (value == 'ff') { count += 2; var value = datagram.substring(count, count + 8); sig = "-"; } else { var value = datagram.substring(count, count + 8); } value = sig + value.substring(0, 5) + "." + value.substring(5, 8); var v = parseFloat(value) tmprtuInfo['weater_level'] = v.toFixed(3) count += 8; } else if (value_code == '38') { console.log("func " + value_code); var value_len = datagram.substring(count, count + 2); count += 2; //电池电压 var value = datagram.substring(count, count + 4); value = value.substring(0, 2) + "." + value.substring(2, 4); var v = parseFloat(value) tmprtuInfo['bt_v'] = v.toFixed(2) count += 4; } else { console.log("func unknrow " + value_code); var value_len = datagram.substring(count, count + 2); count += 2; let len_buff = util.HexStr2Bytes(value_len); let len_v = util.getView(len_buff).getUint8(); len_v = len_v >> 3; count += len_v * 2; } } return tmprtuInfo; } /** * 查询版本号 */ function datagram_45() { var tsStr = util.datagramTime(); var rtuCode = "0000000000"; var message = "7E7E" + rtuCode; var funcCode = "45"; message = message + "91" + "0000" + funcCode + "8008" + "02" + "0000" + tsStr + "05"; var crc = crc16.hexStrToCrc16(message) message += crc; // message = "7E7E0000000001910000458008020000210428102601053B0E"; return message; } function datagram_45_analyse(datagram) { if (datagram.length > 0) { if (datagram.indexOf("7e7e") >= 0) { var count = 20; var funcode = datagram.substring(count, count + 2); count += 2; if (funcode == '45') { console.log("------------------------------------find 45 datagram----------------------------"); var tmprtuInfo = { datagram_idx: '', collect_time: '', rtu_ver: '', func: '45' } //上行标识及长度 var len = datagram.substring(count, count + 4); count += 4; //起始符 var s = datagram.substring(count, count + 2); count += 2; //流水号 var idx = datagram.substring(count, count + 4); var idx_buff = util.HexStr2Bytes(idx); var idx_v = util.getView(idx_buff).getUint16(); tmprtuInfo['datagram_idx'] = idx_v.toString(); count += 4; //时间 var collect_time = datagram.substring(count, count + 12); tmprtuInfo['collect_time'] = "20" + collect_time.substring(0, 2) + "-" + collect_time.substring(2, 4) + "-" + collect_time.substring(4, 6) + " " + collect_time.substring(6, 8) + ":" + collect_time.substring(8, 10) + ":" + collect_time.substring(10, 12); count += 12; //地址标识符 count += 4; //遥测站地址 count += 10; //长度 var lenBuff = util.HexStr2Bytes(datagram.substring(count, count + 2)); let dataView = new DataView(lenBuff); var len = dataView.getUint8(0); count += 2; var verBuff = util.HexStr2Bytes(datagram.substring(count, count + len * 2)); var ver = util.byteToString(verBuff); tmprtuInfo['rtu_ver'] = ver; return tmprtuInfo; } } } return null; } /** * 设备存储重置 */ function datagram_47() { var tsStr = util.datagramTime(); var rtuCode = "0000000000"; var message = "7E7E" + rtuCode; var funcCode = "47"; message = message + "91" + "0000" + funcCode + "800A" + "02" + "0000" + tsStr + "97" + "00" + "05"; var crc = crc16.hexStrToCrc16(message) message += crc; return message; } /** * 设备存储设置回包 */ function datagram_47_analyse(datagram) { if (datagram.length > 0) { if (datagram.indexOf("7e7e") >= 0) { var count = 20; var funcode = datagram.substring(count, count + 2); count += 2; if (funcode == '47') { console.log("------------------------------------find 47 datagram----------------------------"); var tmprtuInfo = { datagram_idx: '', collect_time: '', func: '47' } return tmprtuInfo; } } } return null; } /** * 恢复出厂 */ function datagram_48() { var tsStr = util.datagramTime(); var rtuCode = "0000000000"; var message = "7E7E" + rtuCode; var funcCode = "48"; message = message + "91" + "0000" + funcCode + "800A" + "02" + "0000" + tsStr + "98" + "00" + "05"; var crc = crc16.hexStrToCrc16(message) message += crc; return message; } function datagram_48_analyse(datagram) { if (datagram.length > 0) { if (datagram.indexOf("7e7e") >= 0) { var count = 20; var funcode = datagram.substring(count, count + 2); count += 2; if (funcode == '48') { console.log("------------------------------------find 48 datagram----------------------------"); var tmprtuInfo = { datagram_idx: '', collect_time: '', func: '48' } return tmprtuInfo; } } } return null; } /** * 查询基本参数报文 */ function datagram_41() { let tsStr = util.datagramTime(); let rtuCode = "0000000000"; let content = "0250" + "0450" + "0650" + "0850" + "0A50" + "3450" + "3550" + "3650" + "3750" + "3008" + "3108" + "3808"; let datagram = "7E7E"; datagram += rtuCode; datagram += "01"; datagram += "0000"; datagram += "41"; //报文长度 let len = content.length / 2 + 2 + 6; let lenHex = util.shortToHexStr(len); datagram += "8" + lenHex.substring(1, 4); //起始符 datagram += "02"; //流水号 datagram += "0001"; //发报时间 datagram += tsStr; //消息体 datagram += content; //结束符 datagram += "05"; var crc = crc16.hexStrToCrc16(datagram) datagram += crc; return datagram; } /** * 查询基本参数 * @param {} datagram */ function datagram_41_analyse(datagram) { if (datagram.length > 0) { if (datagram.indexOf("7e7e") >= 0) { var count = 20; var funcode = datagram.substring(count, count + 2); count += 2; if (funcode == '41') { console.log("------------------------------------find 41 datagram----------------------------"); var tmprtuInfo = { datagram_idx: '', collect_time: '', func: '41', rtu_code: '', ip1: '', ip1_port: '', ip2: '', ip2_port: '', ip3: '', ip3_port: '', ip4: '', ip4_port: '', net_model: '', collect_setting: {}, workModel: '', rtuKind: '', ipV6Checked1: false, ipV6Checked2: false, ipV6Checked3: false, ipV6Checked4: false, net_model: '00', } //上行标识及长度 var len = datagram.substring(count, count + 4); count += 4; //起始符 var s = datagram.substring(count, count + 2); count += 2; //流水号 var idx = datagram.substring(count, count + 4); var idx_buff = util.HexStr2Bytes(idx); var idx_v = util.getView(idx_buff).getUint16(); tmprtuInfo['datagram_idx'] = idx_v.toString(); count += 4; //时间 var collect_time = datagram.substring(count, count + 12); tmprtuInfo['collect_time'] = "20" + collect_time.substring(0, 2) + "-" + collect_time.substring(2, 4) + "-" + collect_time.substring(4, 6) + " " + collect_time.substring(6, 8) + ":" + collect_time.substring(8, 10) + ":" + collect_time.substring(10, 12); count += 12; //地址标识符 count += 4; //遥测站地址 count += 10; let content = datagram.substring(count, datagram.length - 3 * 2); let index = 0; while (true) { if (index >= content.length) { break; } let flagCode = content.substring(index, index + 2); index += 2; let lenStr = content.substring(index, index + 2); let len = util.hexStrToInt(lenStr, 8); let dataTotalLen = len >> 3; let decimalLen = len & 7; index += 2; if (flagCode == "01") { let value = content.substring(index, index + dataTotalLen * 2); index += dataTotalLen * 2; } else if (flagCode == "02") { let value = content.substring(index, index + dataTotalLen * 2); index += dataTotalLen * 2; tmprtuInfo['rtu_code'] = value; } else if (flagCode == "03") { let value = content.substring(index, index + dataTotalLen * 2); index += dataTotalLen * 2; } else if (flagCode == "34") { dataTotalLen = 41; let value = content.substring(index, index + dataTotalLen * 2); index += dataTotalLen * 2; let ip = value.substring(0, 78); let ipByte = util.HexStr2Bytes(ip); let ipString = util.byteToString(ipByte); let port = parseInt(value.substring(78, 82), 16); if (port > 0) { tmprtuInfo['ip1'] = ipString; tmprtuInfo['ip1_port'] = "" + port; tmprtuInfo['ipV6Checked1'] = true; } } else if (flagCode == "35") { dataTotalLen = 41; let value = content.substring(index, index + dataTotalLen * 2); index += dataTotalLen * 2; let ip = value.substring(0, 78); let ipByte = util.HexStr2Bytes(ip); let ipString = util.byteToString(ipByte); let port = parseInt(value.substring(78, 82), 16); if (port > 0) { tmprtuInfo['ip2'] = ipString; tmprtuInfo['ip2_port'] = "" + port; tmprtuInfo['ipV6Checked2'] = true; } } else if (flagCode == "36") { dataTotalLen = 41; let value = content.substring(index, index + dataTotalLen * 2); index += dataTotalLen * 2; let ip = value.substring(0, 78); let ipByte = util.HexStr2Bytes(ip); let ipString = util.byteToString(ipByte); let port = parseInt(value.substring(78, 82), 16); if (port > 0) { tmprtuInfo['ip3'] = ipString; tmprtuInfo['ip3_port'] = "" + port; tmprtuInfo['ipV6Checked3'] = true; } } else if (flagCode == "37") { dataTotalLen = 41; let value = content.substring(index, index + dataTotalLen * 2); index += dataTotalLen * 2; let ip = value.substring(0, 78); let ipByte = util.HexStr2Bytes(ip); let ipString = util.byteToString(ipByte); let port = parseInt(value.substring(78, 82), 16); if (port > 0) { tmprtuInfo['ip4'] = ipString; tmprtuInfo['ip4_port'] = "" + port; tmprtuInfo['ipV6Checked4'] = true; } } else if (flagCode == "38") { let value = content.substring(index, index + dataTotalLen * 2); tmprtuInfo['net_model'] = value; index += dataTotalLen * 2; } else if (flagCode == "04") { let value = content.substring(index, index + dataTotalLen * 2); index += dataTotalLen * 2; if (dataTotalLen == 10 && value.indexOf("00") != 0) { let ip = util.toIp(value.substring(2, 14)); let port = "" + parseInt(value.substring(14, 20), 10); tmprtuInfo['ip1'] = ip; tmprtuInfo['ip1_port'] = port; } } else if (flagCode == "05") { let value = content.substring(index, index + dataTotalLen * 2); index += dataTotalLen * 2; } else if (flagCode == "06") { let value = content.substring(index, index + dataTotalLen * 2); index += dataTotalLen * 2; if (dataTotalLen == 10 && value.indexOf("00") != 0) { let ip = util.toIp(value.substring(2, 14)); let port = "" + parseInt(value.substring(14, 20), 10); tmprtuInfo['ip2'] = ip; tmprtuInfo['ip2_port'] = port; } } else if (flagCode == "07") { let value = content.substring(index, index + dataTotalLen * 2); index += dataTotalLen * 2; } else if (flagCode == "08") { let value = content.substring(index, index + dataTotalLen * 2); index += dataTotalLen * 2; if (dataTotalLen == 10 && value.indexOf("00") != 0) { let ip = util.toIp(value.substring(2, 14)); let port = "" + parseInt(value.substring(14, 20), 10); tmprtuInfo['ip3'] = ip; tmprtuInfo['ip3_port'] = port; } } else if (flagCode == "09") { let value = content.substring(index, index + dataTotalLen * 2); index += dataTotalLen * 2; } else if (flagCode == "0A") { let value = content.substring(index, index + dataTotalLen * 2); index += dataTotalLen * 2; if (dataTotalLen == 10 && value.indexOf("00") != 0) { let ip = util.toIp(value.substring(2, 14)); let port = "" + parseInt(value.substring(14, 20), 10); tmprtuInfo['ip4'] = ip; tmprtuInfo['ip4_port'] = port; } } else if (flagCode == "0B") { let value = content.substring(index, index + dataTotalLen * 2); index += dataTotalLen * 2; } else if (flagCode == "0C") { let value = content.substring(index, index + dataTotalLen * 2); index += dataTotalLen * 2; } else if (flagCode == "0D") { let value = content.substring(index, index + dataTotalLen * 2); index += dataTotalLen * 2; if (value.length == 8) { let data = {}; tmprtuInfo['collect_setting'] = data; } } else if (flagCode == "0E") { let value = content.substring(index, index + dataTotalLen * 2); index += dataTotalLen * 2; } else if (flagCode == "0F") { let value = content.substring(index, index + dataTotalLen * 2); index += dataTotalLen * 2; } else if (flagCode == "30") { let value = content.substring(index, index + dataTotalLen * 2); index += dataTotalLen * 2; let m = parseInt(value, 10); if (m == 0) { tmprtuInfo['rtu_work_model'] = "0"; } else { tmprtuInfo['rtu_work_model'] = "1"; } } else if (flagCode == "31") { let value = content.substring(index, index + dataTotalLen * 2); index += dataTotalLen * 2; let k = util.hexStrToInt(value, 8); if (k == 0x50) { tmprtuInfo["rtu_kind"] = "P"; } else if (k == 0x50) { tmprtuInfo["rtu_kind"] = "H"; } else if (k == 0x48) { tmprtuInfo["rtu_kind"] = "H"; } else if (k == 0x4B) { tmprtuInfo["rtu_kind"] = "K"; } else if (k == 0x5A) { tmprtuInfo["rtu_kind"] = "Z"; } else if (k == 0x44) { tmprtuInfo["rtu_kind"] = "D"; } else if (k == 0x54) { tmprtuInfo["rtu_kind"] = "T"; } else if (k == 0x4D) { tmprtuInfo["rtu_kind"] = "M"; } else if (k == 0x47) { tmprtuInfo["rtu_kind"] = "G"; } else if (k == 0x51) { tmprtuInfo["rtu_kind"] = "Q"; } else if (k == 0x49) { tmprtuInfo["rtu_kind"] = "I"; } else if (k == 0x4F) { tmprtuInfo["rtu_kind"] = "O"; } } else { let value = content.substring(index, index + dataTotalLen * 2); index += dataTotalLen * 2; } } return tmprtuInfo; } } } return null; } /** * 设置基本参数报文 */ function datagram_40(jsonData) { let dataContent = ""; //测站编码 let v = jsonData["rtu_code"]; let buff = util.createBcdBytes("02", v); dataContent += buff; //IP地址1 let ip = jsonData['ip1']; let port = jsonData['ip1_port']; if (jsonData['ipV6Checked1']) { if (ip != undefined && ip.length > 0 && port != undefined && port.length > 0) { buff = util.createIpV6Bytes("34", ip, port); dataContent += buff; } else { // ip = "0000:0000:0000:0000:0000:0000:0000:0000"; // port = "000000"; } // buff = util.createIpV6Bytes("34", ip, port); // dataContent += buff; } else { if (ip != undefined && ip.length > 0 && port != undefined && port.length > 0) { v = ip + ":" + port; } else { v = "000.000.000.000:000000"; } buff = util.createIpBytes("04", v); dataContent += buff; } //IP地址2 ip = jsonData['ip2']; port = jsonData['ip2_port']; if (jsonData['ipV6Checked2']) { if (ip != undefined && ip.length > 0 && port != undefined && port.length > 0) { buff = util.createIpV6Bytes("35", ip, port); dataContent += buff; } else { // ip = "0000:0000:0000:0000:0000:0000:0000:0000"; // port = "000000"; } // buff = util.createIpV6Bytes("35", ip, port); // dataContent += buff; } else { if (ip != undefined && ip.length > 0 && port != undefined && port.length > 0) { v = ip + ":" + port; } else { v = "000.000.000.000:000000"; } buff = util.createIpBytes("06", v); dataContent += buff; } //IP地址3 ip = jsonData['ip3']; port = jsonData['ip3_port']; if (jsonData['ipV6Checked3']) { if (ip != undefined && ip.length > 0 && port != undefined && port.length > 0) { buff = util.createIpV6Bytes("36", ip, port); dataContent += buff; } else { // ip = "0000:0000:0000:0000:0000:0000:0000:0000"; // port = "000000"; } // buff = util.createIpV6Bytes("36", ip, port); // dataContent += buff; } else { if (ip != undefined && ip.length > 0 && port != undefined && port.length > 0) { v = ip + ":" + port; } else { v = "000.000.000.000:000000"; } buff = util.createIpBytes("08", v); dataContent += buff; } //IP地址4 ip = jsonData['ip4']; port = jsonData['ip4_port']; if (jsonData['ipV6Checked4']) { if (ip != undefined && ip.length > 0 && port != undefined && port.length > 0) { buff = util.createIpV6Bytes("37", ip, port); dataContent += buff; } else { // ip = "0000:0000:0000:0000:0000:0000:0000:0000"; // port = "000000"; } // buff = util.createIpV6Bytes("37", ip, port); // dataContent += buff; } else { if (ip != undefined && ip.length > 0 && port != undefined && port.length > 0) { v = ip + ":" + port; } else { v = "000.000.000.000:000000"; } buff = util.createIpBytes("0A", v); dataContent += buff; } dataContent += "3808" + jsonData['netModel']; // if (jsonData['ipV6Checked1'] || jsonData['ipV6Checked2'] || jsonData['ipV6Checked3'] || jsonData['ipV6Checked4']) { // dataContent += "380804"; // } else { // dataContent += "380800"; // } //工作模式 dataContent += "3008"; v = jsonData["rtu_work_model"]; if (v == "0") { dataContent += "00"; } else if (v == "1") { dataContent += "01"; } //测站类型 dataContent += "3108"; v = jsonData["rtu_kind"]; if (v == "P" || v == "p") { dataContent += "50"; } else if (v == "H" || v == "h") { dataContent += "48"; } else if (v == "K" || v == "k") { dataContent += "4B"; } else if (v == "Z" || v == "z") { dataContent += "5A"; } else if (v == "D" || v == "d") { dataContent += "44"; } else if (v == "T" || v == "t") { dataContent += "54"; } else if (v == "M" || v == "m") { dataContent += "4D"; } else if (v == "G" || v == "g") { dataContent += "47"; } else if (v == "Q" || v == "q") { dataContent += "51"; } else if (v == "I" || v == "i") { dataContent += "49"; } else if (v == "O" || v == "o") { dataContent += "4F"; } let rtuCode = "0000000000"; let tsStr = util.datagramTime(); let datagram = "7E7E"; datagram += rtuCode; datagram += "01"; datagram += "0000"; datagram += "40"; //报文长度 let len = dataContent.length / 2 + 2 + 6; let lenHex = util.shortToHexStr(len); datagram += "8" + lenHex.substring(1, 4); datagram += "02"; //起始符 datagram += "0001"; //流水号 datagram += tsStr; //发报时间 datagram += dataContent; //结束符 datagram += "05"; var crc = crc16.hexStrToCrc16(datagram) datagram += crc; return datagram; } function datagram_40_analyse(datagram) { if (datagram.length > 0) { if (datagram.indexOf("7e7e") >= 0) { var count = 20; var funcode = datagram.substring(count, count + 2); count += 2; if (funcode == '40') { console.log("------------------------------------find 40 datagram----------------------------"); var tmprtuInfo = { datagram_idx: '', collect_time: '', func: '40' } return tmprtuInfo; } } } return null; } /** * 查询运行参数报文 */ function datagram_43() { let tsStr = util.datagramTime(); let content = "2010" + "2110" + "2509" + "ff0108" + "ff0208" + "ff0310" + "ff0408" + "ff0508" + "ff0613" + "2210" + "2320" + "2410" + "2708" + "283B" + "302B" + "3810" + "4010" + "4110" + "4210" + "4310" + "4410" + "ff0723" + "ff0823" + "ff0923" + "ff0a23" + "ff0b23" + "ff0c23" + "ff0d23" + "ff0e23" + "ff0f23" + "ff1123" + "ff1223"; let rtuCode = "0000000000"; let datagram = "7E7E"; datagram += rtuCode; datagram += "01"; datagram += "0000"; datagram += "43"; //报文长度 let len = content.length / 2 + 2 + 6; let lenHex = util.shortToHexStr(len); datagram += "8" + lenHex.substring(1, 4); datagram += "02"; //起始符 datagram += "0001"; //流水号 datagram += tsStr; //发报时间 datagram += content; //结束符 datagram += "05"; var crc = crc16.hexStrToCrc16(datagram) datagram += crc; return datagram; } function datagram_43_analyse(datagram) { if (datagram.length > 0) { if (datagram.indexOf("7e7e") >= 0) { var count = 20; var funcode = datagram.substring(count, count + 2); count += 2; if (funcode == '43') { console.log("------------------------------------find 43 datagram----------------------------"); var tmprtuInfo = { datagram_idx: '', collect_time: '', func: '43' } //上行标识及长度 var len = datagram.substring(count, count + 4); count += 4; //起始符 var s = datagram.substring(count, count + 2); count += 2; //流水号 var idx = datagram.substring(count, count + 4); var idx_buff = util.HexStr2Bytes(idx); var idx_v = util.getView(idx_buff).getUint16(); tmprtuInfo['datagram_idx'] = idx_v.toString(); count += 4; //时间 var collect_time = datagram.substring(count, count + 12); tmprtuInfo['collect_time'] = "20" + collect_time.substring(0, 2) + "-" + collect_time.substring(2, 4) + "-" + collect_time.substring(4, 6) + " " + collect_time.substring(6, 8) + ":" + collect_time.substring(8, 10) + ":" + collect_time.substring(10, 12); count += 12; //地址标识符 count += 4; //遥测站地址 count += 10; let content = datagram.substring(count, datagram.length - 3 * 2); let index = 0; while (true) { if (index >= content.length) { break; } let flagCode = content.substring(index, index + 2); index += 2; if (flagCode == "FF" || flagCode == "ff") { flagCode += content.substring(index, index + 2); index += 2; } let lenStr = content.substring(index, index + 2); let len = util.hexStrToInt(lenStr, 8); let dataTotalLen = len >> 3; let decimalLen = len & 7; index += 2; let value = content.substring(index, index + dataTotalLen * 2); index += dataTotalLen * 2; if (flagCode == "20") { //定时报时间间隔 tmprtuInfo['intervalTime'] = "" + util.getBcdValue(value, decimalLen); } else if (flagCode == "21") { //加报时间间隔 tmprtuInfo['addIntervalTime'] = "" + util.getBcdValue(value, decimalLen); } else if (flagCode == "28") { //水位基值1 let dec = "" + util.getBcdValue(value, decimalLen); tmprtuInfo['water_level_base_point'] = dec; } else if (flagCode == "30") { //水位修正基值1 let dec = "" + util.getBcdValue(value, decimalLen); tmprtuInfo['water_level_correct_point'] = dec; } else if (flagCode == "25") { //雨量计分辨率 let dec = "" + util.getBcdValue(value, decimalLen); tmprtuInfo['rain_precision'] = dec; } else if (flagCode == "27") { //雨量计加报阈值 let dec = "" + util.getBcdValue(value, decimalLen); tmprtuInfo['rain_extra_datagram_threshold'] = dec; } else if (flagCode == "ff01") { //水位计协议 let dec = "" + util.getHexValue(value); tmprtuInfo['water_se_agreement'] = dec; } else if (flagCode == "ff02") { //水位计id let dec = "" + util.getHexValue(value); tmprtuInfo['water_se_id'] = dec; } else if (flagCode == "ff03") { //水位计地址 let dec = "" + value; tmprtuInfo['water_se_address'] = dec; } else if (flagCode == "ff04") { //水位计格式 let dec = "" + util.getHexValue(value); tmprtuInfo['water_se_format'] = dec; } else if (flagCode == "ff05") { //水位计调整 let dec = "" + util.getHexValue(value); tmprtuInfo['water_se_adjust'] = dec; } else if (flagCode == "ff06") { //水位计符号 let dec = "" + util.getBcdValue(value, decimalLen); tmprtuInfo['water_se_symbol'] = dec; } else if (flagCode == "ff07") { //河道深 let dec = "" + util.getBcdValue(value, decimalLen); tmprtuInfo['riverDeep'] = dec; } else if (flagCode == "ff08") { //河道宽 let dec = "" + util.getBcdValue(value, decimalLen); tmprtuInfo['riverWide'] = dec; } else if (flagCode == "ff09") { //河道坡度 let dec = "" + util.getBcdValue(value, decimalLen); tmprtuInfo['riverAngle'] = dec; } else if (flagCode == "ff0a") { //探头高 let dec = "" + util.getBcdValue(value, decimalLen); tmprtuInfo['radarHigh'] = dec; } else if (flagCode == "ff0b") { //断面系数 let dec = "" + util.getBcdValue(value, decimalLen); tmprtuInfo['faceCoe'] = dec; } else if (flagCode == "ff0c") { //流速系数 let dec = "" + util.getBcdValue(value, decimalLen); tmprtuInfo['speedCoe'] = dec; } else if (flagCode == "ff0d") { //流量模型系数 let dec = "" + util.getBcdValue(value, decimalLen); tmprtuInfo['flowModelCoe'] = dec; } else if (flagCode == "ff0e") { //水位计类型 let dec = util.getHexValue(value); tmprtuInfo['waterLevelSensorKind'] = dec; } else if (flagCode == "ff0f") { //流量计类型 let dec = util.getHexValue(value); tmprtuInfo['flowRateSensorKind'] = dec; } else if (flagCode == "ff11") { //流量计协议 let dec = util.getHexValue(value); tmprtuInfo['flowRateSensorProtocolType'] = dec; } else if (flagCode == "ff12") { //流量计ID let dec = util.getHexValue(value); tmprtuInfo['flowRateSensorId'] = "" + dec; } } return tmprtuInfo; } } } return null; } /** * 设置运行参数报文 */ function datagram_42(jsonData) { console.log(" 42 ", JSON.stringify(jsonData)) let dataContent = ""; //定时报时间间隔 let v = jsonData["intervalTime"]; if (v != null && v.length > 0) { let buff = util.createValueBytes("20", v, 0, 2); dataContent += buff; } //加报时间间隔 v = jsonData["addIntervalTime"]; if (v != null && v.length > 0) { let buff = util.createValueBytes("21", v, 0, 1); dataContent += buff; } //日降水量起始时间 //if (jsonData.containsKey("rainTime")) { // v = jsonData["rainTime"]; // buff = util.createValueBytes("22", v, 0, 1); // dataContent += buff; //} //采样间隔 //if (jsonData.containsKey("collectInterval")) { // let v = jsonData["collectInterval"]; // let buff = util.createValueBytes("23", v, 0, 2); // dataContent += buff; //} //数据存储间隔 // if (jsonData.containsKey("dataSaveInterval")) { // let v = jsonData["dataSaveInterval"]; // let buff = util.createValueBytes("24", v, 0, 1); // dataContent += buff; // } //雨量加报阀值 // if (jsonData.containsKey("rainAddValue")) { // let v = jsonData["rainAddValue"]; // let buff = util.createValueBytes("27", v, 0, 1); // dataContent += buff; // } //水位基值 v = jsonData["water_level_base_point"]; if (v != null && v.length > 0) { let buff = util.createValueBytes("28", v, 3, 4); dataContent += buff; } //水位修正基值 v = jsonData["water_level_correct_point"]; if (v != null && v.length > 0) { let buff = util.createValueBytes("30", v, 3, 4); dataContent += buff; } //雨量计分辨率 v = jsonData["rain_precision"]; if (v != null && v.length > 0) { let buff = util.createValueBytes("25", v, 0, 1); dataContent += buff; } //雨量计加报阈值 v = jsonData["rain_extra_datagram_threshold"]; if (v != null && v.length > 0) { let buff = util.createValueBytes("27", v, 0, 1); dataContent += buff; } //水位计协议 v = jsonData["water_se_agreement"]; if (v != null && v.length > 0) { let buff = util.createDecToValueBytes("FF01", v, 1); dataContent += buff; } //水位计id v = jsonData["water_se_id"]; if (v != null && v.length > 0) { let buff = util.createDecToValueBytes("FF02", v, 1); dataContent += buff; } //水位计地址 v = jsonData["water_se_address"]; if (v != null && v.length > 0) { let buff = util.createHexToValueBytes("FF03", v, 2); dataContent += buff; } //水位计格式 v = jsonData["water_se_format"]; if (v != null && v.length > 0) { let buff = util.createDecToValueBytes("FF04", v, 1); dataContent += buff; } //水位计调整 v = jsonData["water_se_adjust"]; if (v != null && v.length > 0) { let buff = util.createDecToValueBytes("FF05", v, 1); dataContent += buff; } //水位计符号 v = jsonData["water_se_symbol"]; if (v != null && v.length > 0) { let buff = util.createValueBytes("FF06", v, 3, 2); dataContent += buff; } //河道深 v = jsonData["riverDeep"]; if (v != null && v.length > 0) { let buff = util.createValueBytes("FF07", v, 3, 4); dataContent += buff; } //河道宽 v = jsonData["riverWide"]; if (v != null && v.length > 0) { let buff = util.createValueBytes("FF08", v, 3, 4); dataContent += buff; } //河道坡度 v = jsonData["riverAngle"]; if (v != null && v.length > 0) { let buff = util.createValueBytes("FF09", v, 3, 4); dataContent += buff; } //探头高 v = jsonData["radarHigh"]; if (v != null && v.length > 0) { let buff = util.createValueBytes("FF0A", v, 3, 4); dataContent += buff; } //断面系数 v = jsonData["faceCoe"]; if (v != null && v.length > 0) { let buff = util.createValueBytes("FF0B", v, 3, 4); dataContent += buff; } //流速系数 v = jsonData["speedCoe"]; if (v != null && v.length > 0) { let buff = util.createValueBytes("FF0C", v, 3, 4); dataContent += buff; } //流量模型系数 v = jsonData["flowModelCoe"]; if (v != null && v.length > 0) { let buff = util.createValueBytes("FF0D", v, 3, 4); dataContent += buff; } let waterLevelSensorKind = jsonData.waterLevelSensorKind; for (let i = 0; i < 3; i++) { if (waterLevelSensorKind[i].checked) { let buff = util.createDecToValueBytes("FF0E", "" + i, 1); dataContent += buff; break; } } let flowRateSensorKind = jsonData.flowRateSensorKind; for (let i = 0; i < 3; i++) { if (flowRateSensorKind[i].checked) { let buff = util.createDecToValueBytes("FF0F", "" + i, 1); dataContent += buff; break; } } let flowRateSensorProtocolType = jsonData.flowRateSensorProtocolType; for (let i = 0; i < 15; i++) { if (flowRateSensorProtocolType[i].checked) { let buff = util.createDecToValueBytes("FF11", "" + i, 1); dataContent += buff; break; } } let flowRateSensorId = jsonData.flowRateSensorId; if (flowRateSensorId != null && flowRateSensorId.length > 0) { let buff = util.createDecToValueBytes("FF12", flowRateSensorId, 1); dataContent += buff; } //} //加报水位 //if (jsonData.containsKey("addWaterLevel")) { // let v = jsonData["addWaterLevel"]; // let buff = util.createValueBytes("38", v, 2, 2); // dataContent += buff; // } //水位以上加报阀值 // if (jsonData.containsKey("addWaterUpValue")) { // let v = jsonData["addWaterUpValue"]; // let buff = util.createValueBytes("40", v, 2, 2); // dataContent += buff; // } //水位以下加报阀值 // if (jsonData.containsKey("addWaterDownValue")) { // let v = jsonData["addWaterDownValue"]; // let buff = util.createValueBytes("41", v, 2, 2); // dataContent += buff; // } //流量加报阀值 // if (jsonData.containsKey("flowValue")) { // let v = jsonData["flowValue"]; // let buff = util.createValueBytes("42", v, 3, 3); // dataContent += buff; // } //流速加报阀值 // if (jsonData.containsKey("flowSpeetValue")) { // let v = jsonData["flowSpeetValue"]; // let buff = util.createValueBytes("43", v, 3, 3); // dataContent += buff; // } //闸位加报阀值 // if (jsonData.containsKey("waterGateValue")) { // let v = jsonData["waterGateValue"]; // let buff = BytesHelp.createValueBytes("44", v, 2, 2); // dataContent += buff; // } let rtuCode = "0000000000"; let tsStr = util.datagramTime(); let datagram = "7E7E"; datagram += rtuCode; datagram += "01"; datagram += "0000"; datagram += "42"; //报文长度 let len = dataContent.length / 2 + 2 + 6; let lenHex = util.shortToHexStr(len); datagram += "8" + lenHex.substring(1, 4); datagram += "02"; //起始符 datagram += "0001"; //流水号 datagram += tsStr; //发报时间 datagram += dataContent; //结束符 datagram += "05"; var crc = crc16.hexStrToCrc16(datagram) datagram += crc; return datagram; // let datagram = "7E7E"; // datagram += "0000000000"; // datagram += "01"; // datagram += "0000"; // datagram += "42"; // //报文长度 // let len = dataContent.length / 2 + 2 + 6; // let lenHex = util.shortToHexStr(len); // datagram += "8" + lenHex.substring(1, 4); // datagram += "02"; //起始符 // datagram += "0001"; //流水号 // let tsStr = util.datagramTime(); // datagram += tsStr; //发报时间 // datagram += dataContent; // //结束符 // datagram += "05"; // var crc = crc16.hexStrToCrc16(datagram) // datagram += crc; // return datagram; } function datagram_42_analyse(datagram) { if (datagram.length > 0) { if (datagram.indexOf("7e7e") >= 0) { var count = 20; var funcode = datagram.substring(count, count + 2); count += 2; if (funcode == '42') { console.log("------------------------------------find 42 datagram----------------------------"); var tmprtuInfo = { datagram_idx: '', collect_time: '', func: '42' } return tmprtuInfo; } } } return null; } /** * 设置时钟 */ function datagram_4A(clock) { var tsStr = clock.substr(2, clock.length - 2); var rtuCode = "0000000000"; var message = "7E7E" + rtuCode; var funcCode = "4A"; message = message + "91" + "0000" + funcCode + "8008" + "02" + "0000" + tsStr + "05"; var crc = crc16.hexStrToCrc16(message) message += crc; return message; } function datagram_4A_analyse(datagram) { if (datagram.length > 0) { if (datagram.indexOf("7e7e") >= 0) { var count = 20; var funcode = datagram.substring(count, count + 2); count += 2; if (funcode == '4a') { console.log("------------------------------------find 4a datagram----------------------------"); var tmprtuInfo = { datagram_idx: '', collect_time: '', func: '4a' } return tmprtuInfo; } } } return null; } /** * 查询时钟 */ function datagram_51() { var tsStr = util.datagramTime(); var rtuCode = "0000000000"; var message = "7E7E" + rtuCode; var funcCode = "51"; message = message + "91" + "0000" + funcCode + "8008" + "02" + "0000" + tsStr + "05"; var crc = crc16.hexStrToCrc16(message) message += crc; return message; } function datagram_51_analyse(datagram) { if (datagram.length > 0) { if (datagram.indexOf("7e7e") >= 0) { var count = 20; var funcode = datagram.substring(count, count + 2); count += 2; if (funcode == '51') { console.log("------------------------------------find 51 datagram----------------------------"); var tmprtuInfo = { datagram_idx: '', collect_time: '', func: '51' } //上行标识及长度 var len = datagram.substring(count, count + 4); count += 4; //起始符 var s = datagram.substring(count, count + 2); count += 2; //流水号 var idx = datagram.substring(count, count + 4); var idx_buff = util.HexStr2Bytes(idx); var idx_v = util.getView(idx_buff).getUint16(); tmprtuInfo['datagram_idx'] = idx_v.toString(); count += 4; //时间 var collect_time = datagram.substring(count, count + 12); tmprtuInfo['collect_time'] = "20" + collect_time.substring(0, 2) + "-" + collect_time.substring(2, 4) + "-" + collect_time.substring(4, 6) + " " + collect_time.substring(6, 8) + ":" + collect_time.substring(8, 10) + ":" + collect_time.substring(10, 12); count += 12; //地址标识符 count += 4; //遥测站地址 count += 10; return tmprtuInfo; } } } return null; } /** * 重启 */ function datagram_f3() { var tsStr = util.datagramTime(); var rtuCode = "0000000000"; var message = "7E7E" + rtuCode; var funcCode = "F3"; message = message + "91" + "0000" + funcCode + "8008" + "02" + "0000" + tsStr + "05"; var crc = crc16.hexStrToCrc16(message) message += crc; return message; } function datagram_f3_analyse(datagram) { if (datagram.length > 0) { if (datagram.indexOf("7e7e") >= 0) { var count = 20; var funcode = datagram.substring(count, count + 2); count += 2; if (funcode == 'f3') { console.log("------------------------------------find f3 datagram----------------------------"); var tmprtuInfo = { datagram_idx: '', collect_time: '', func: 'f3' } return tmprtuInfo; } } } return null; } module.exports = { crcCheck: crcCheck, datagram_f6: datagram_f6, datagram_f6_analyse: datagram_f6_analyse, datagram_f7: datagram_f7, datagram_f7_analyse: datagram_f7_analyse, datagram_40: datagram_40, datagram_40_analyse: datagram_40_analyse, datagram_45: datagram_45, datagram_45_analyse: datagram_45_analyse, datagram_47: datagram_47, datagram_47_analyse: datagram_47_analyse, datagram_48: datagram_48, datagram_48_analyse: datagram_48_analyse, datagram_4A: datagram_4A, datagram_4A_analyse: datagram_4A_analyse, datagram_51: datagram_51, datagram_51_analyse: datagram_51_analyse, datagram_f3: datagram_f3, datagram_f3_analyse: datagram_f3_analyse, datagram_43: datagram_43, datagram_43_analyse: datagram_43_analyse, datagram_41: datagram_41, datagram_41_analyse: datagram_41_analyse, datagram_42_analyse: datagram_42_analyse, datagram_42: datagram_42 }