/// <summary> /// 取得1.0协议的sn /// </summary> /// <param name="msg"></param> /// <returns></returns> public static string getSn(string msg) { if (msg.StartsWith("6969")) { return(""); //2.0协议返回空 } string _CollectorCode; string sbUnitID = ""; bool isNormal = false; string tmpchar; //将后面是00的抛弃 for (int i = 18; i >= 4; i--) { tmpchar = msg.Substring(i * 2, 2); if (!isNormal && !tmpchar.Equals("00")) { isNormal = true; } if (isNormal) { sbUnitID = ASCII.Chr((int)SystemCode.HexNumberToDenary(tmpchar, false, 8, 'u')) + sbUnitID; } } _CollectorCode = sbUnitID.ToString(); _CollectorCode = _CollectorCode.Replace("\0", "0");//临时处理非法测试数据 return(_CollectorCode); }
/// <summary> /// 取得当个信息地址的值,字符串表示 /// </summary> /// <param name="valuestr"></param> /// <param name="infounitAddress"></param> /// <param name="bytetype"></param> /// <returns></returns> private static string getValue(string valuestr, InfoUnitAddress infounitAddress, int bytetype) { double value = (double)SystemCode.HexNumberToDenary(valuestr, infounitAddress.reversionType, bytetype, infounitAddress.signtype); if (infounitAddress.dotnum > 0) { value = Math.Round(value / Math.Pow(10, infounitAddress.dotnum), 1); } return(value.ToString()); }
/// <summary> /// 解析单个信息体 /// </summary> /// <param name="body"></param> /// <returns></returns> public static string[] analyze(string body, int infoType, InfoUnitAddress infounitAddress) { string valuestr = "", value = ""; switch (infoType) { case DataType.yaoce: valuestr = body.Substring(3 * 2, 4 * 2); value = getValue(valuestr, infounitAddress, 32); break; case DataType.yaoxin: //对于遥信的信息体,放回值和时间 valuestr = body.Substring(3 * 2, 1 * 2); value = getValue(valuestr, infounitAddress, 8); //再取得故障时间 valuestr = body.Substring(5 * 2, 7 * 2); int year = 2000 + (int)SystemCode.HexNumberToDenary(valuestr.Substring(12, 2), false, 8, 'u') % 99; int moth = (int)SystemCode.HexNumberToDenary(valuestr.Substring(10, 2), false, 8, 'u'); if (moth > 12) { moth = 12; } int day = (int)SystemCode.HexNumberToDenary(valuestr.Substring(8, 2), false, 8, 'u'); if (day > 31) { day = 28; } int hh = (int)SystemCode.HexNumberToDenary(valuestr.Substring(6, 2), false, 8, 'u'); if (hh > 23) { hh = 23; } int mm = (int)SystemCode.HexNumberToDenary(valuestr.Substring(4, 2), false, 8, 'u'); if (mm > 60) { mm = 59; } int ss = (int)SystemCode.HexNumberToDenary(valuestr.Substring(2, 2), false, 8, 'u'); if (ss > 60) { ss = 59; } value += ":" + new DateTime(year, moth, day, hh, mm, ss).ToString("yyyy-mm-dd HH:mm:ss"); break; case DataType.yaomai: valuestr = body.Substring(3 * 2, 4 * 2); value = getValue(valuestr, infounitAddress, 32); break; default: break; } return((infounitAddress.address + ":" + value).Split(':')); }
/// <summary> /// 取得单个信息体的解析规则 /// </summary> /// <param name="body"></param> /// <returns></returns> public static InfoUnitAddress getInfoUnitAddress(string body) { try { //取出测点 int address = (int)SystemCode.HexNumberToDenary(body.Substring(1 * 2, 2 * 2), true, 16, 'u'); //取得不同信息单元地址对应的解析规则 DataType dy = new DataType(); if (DataType.deviceTypeMap.ContainsKey(address)) { return((InfoUnitAddress)DataType.deviceTypeMap[address]); } } catch (Exception ee) { Console.WriteLine(ee.StackTrace); } return(null); }
/// <summary> /// 构造tcp 消息对象,并解析消息 /// 一个字节两个字符 /// </summary> /// <param name="content"></param> public TCPMessage(string msgkey, string content) { this.msgkey = msgkey; content = content.Replace("0x", string.Empty).Replace(" ", string.Empty).Replace("\r", string.Empty).Replace("\n", string.Empty); this.messageContent = content; string headbefore = this.messageContent.Substring(0, 4);//用头部分4个字符表示协议版本 //add by qhb in 20120415 for 2.0新协议,暂时不处理小版本号,等以后有升级了在做区分 if (headbefore.Equals("6969")) { largeVersion = 2; smallVersion = 0; } else if (headbefore.Equals("6868")) //旧协议区分版本号,因为就协议1.1版本的告警较之多了两个字段 //largeVersion = 1; //smallVersion = 0; { largeVersion = (int)SystemCode.HexNumberToDenary(this.messageContent.Substring(versionLength, 1 * hexbytecharnum), false, 8, 'u'); //协议版本占两个字节, 即两个四个字符,大版本在前 smallVersion = (int)SystemCode.HexNumberToDenary(this.messageContent.Substring(versionLength + 1 * hexbytecharnum, 1 * hexbytecharnum), false, 8, 'u'); //协议版本占两个字节, 即两个四个字符,大版本在前 } analysis(); }
/// <summary> /// 1.0和0.1都用同一种协议解析 /// </summary> private void analysis1_0or0_1() { int alllength = (int)SystemCode.HexNumberToDenary(this.messageContent.Substring(2 * 2, 2 * 2), true, 32, 'u') * 2; if (this.messageContent.Length >= (istart + icount) && alllength == (this.messageContent.Length - 2 * 2)) { messageHeader = new TcpHeader(); messageHeader.analyze(this.messageContent.Substring(istart, icount)); istart = istart + icount; //循环解析多个设备 listTcpbody = new List<DeviceDataBase>(); for (int i = 0; i < this.messageHeader.DevicesNum; i++) { DeviceDataBase ddb = null; if (istart > messageContent.Length) break; int type = (int)SystemCode.HexNumberToDenary(this.messageContent.Substring(istart + 2 * 2, 1 * 2), true, 32, 'u'); switch (type) { case DeviceData.TYPE_MODBUS_BUSBAR://modbus协议汇流箱 icount = ProtocolConst.LENGTH_MODBUS_BUSBAR * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new ModbusBusbar(this.messageContent.Substring(istart, icount), this); istart = istart + icount; break; } case DeviceData.TYPE_MODBUS15_BUSBAR://光伏阵列汇流箱通讯协议(Modbus)V1.1.1.0-2011.8.30.pdf add by qianhb in 20111220 icount = ProtocolConst.LENGTH_MODBUS15_BUSBAR * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new Modbus15Busbar(this.messageContent.Substring(istart, icount), this); istart = istart + icount; break; } case DeviceData.TYPE_MODBUS_CABINET://modbus协议配电柜 icount = ProtocolConst.LENGTH_MODBUS_CABINET * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new ModbusCabinet(this.messageContent.Substring(istart, icount), this); istart = istart + icount; break; } case DeviceData.TYPE_MODBUS16_CABINET://光伏直流配电柜通信协议(Modbus)V1.0-柴达木-2011.8.30.pdf add by qianhb in 20111220 icount = ProtocolConst.LENGTH_MODBUS16_CABINET * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new Modbus16Cabinet(this.messageContent.Substring(istart, icount), this); istart = istart + icount; break; } case DeviceData.TYPE_MODBUS_DETECTOR://设备类型0x22对应的数据区格式,环境检测仪(MODBUS协议) add by qianhb in 20111220 icount = ProtocolConst.LENGTH_MODBUS_DETECTOR * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new ModbusDetector(this.messageContent.Substring(istart, icount), this); istart = istart + icount; break; } case DeviceData.TYPE_MODBUS_DETECTOR_V1020://设备类型0x23对应的数据区格式,环境检测仪(MODBUS协议) add by qianhb in 20120314 icount = ProtocolConst.LENGTH_MODBUS_DETECTOR_1020 * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new ModbusDetector1020(this.messageContent.Substring(istart, icount), this); istart = istart + icount; break; } case DeviceData.TYPE_MODBUS_INVERTER://modbus协议逆变器 icount = ProtocolConst.LENGTH_MODBUS_INVERTER * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new ModbusInverter(this.messageContent.Substring(istart, icount),this); istart = istart + icount; break; } case DeviceData.TYPE_SUNGROW_BUSBAR://sungrows协议汇流箱 icount = ProtocolConst.LENGTH_SUNGROW_BUSBAR * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new SungrowBusbar(this.messageContent.Substring(istart, icount), this); istart = istart + icount; break; } case DeviceData.TYPE_SUNGROW_CABINET://sungrows协议配电柜 icount = ProtocolConst.LENGTH_SUNGROW_CABINET * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new SungrowCabinet(this.messageContent.Substring(istart, icount), this); istart = istart + icount; break; } case DeviceData.TYPE_SUNGROW_DETECTOR://sungrow协议检测仪 icount = ProtocolConst.LENGTH_SUNGROW_DETECTOR * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new SungrowDetector(this.messageContent.Substring(istart, icount), this); istart = istart + icount; break; } case DeviceData.TYPE_SUNGROW_INVERTER://sungrow协议逆变器 icount = ProtocolConst.LENGTH_SUNGROW_INVERTER * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new SungrowInverter(this.messageContent.Substring(istart, icount),this); istart = istart + icount; break; } case DeviceData.TYPE_AMMETER://电表协议 icount = ProtocolConst.LENGTH_AMMETER * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new Ammeter(this.messageContent.Substring(istart, icount), this); istart = istart + icount; break; } default: istart = istart + this.messageContent.Length; break; } if (ddb != null) listTcpbody.Add(ddb); } //取得告警信息 listTcpbug = new List<Bug>(); if (this.messageContent.Length > (ProtocolConst.LENGTH_BUG + ProtocolConst.LENGTH_HEAD) * 2) { istart = this.messageContent.Length - ProtocolConst.LENGTH_BUG * 2 * (this.messageHeader.BugNum); for (int i = 0; i < this.messageHeader.BugNum; i++) { Bug tcpb = new TcpBug(this.messageContent.Substring(istart + i * ProtocolConst.LENGTH_BUG * 2, ProtocolConst.LENGTH_BUG * 2)); listTcpbug.Add(tcpb); } } } else { base.messageHeader = new TcpHeader(); listTcpbody = new List<DeviceDataBase>(); listTcpbug = new List<Bug>(); } }
/// <summary> /// 1.0和0.1都用同一种协议解析 /// </summary> private void analysis1_0or0_1() { int alllength = (int)SystemCode.HexNumberToDenary(this.messageContent.Substring(2 * 2, 2 * 2), true, 32, 'u') * 2; if (this.messageContent.Length >= (istart + icount) && alllength == (this.messageContent.Length - 2 * 2)) { messageHeader = new TcpHeader(); messageHeader.analyze(this.messageContent.Substring(istart, icount)); //add by hbqian int 20130418 for其实0。1分的发电量是昨天,按道理不应该发的,但是现在LOG有个换存,导致0:到15分的这个时间发的发电量可能还是上一天的 if (messageHeader.TimeNow.Hour == 0 && messageHeader.TimeNow.Minute < 15) { return; } istart = istart + icount; //循环解析多个设备 listTcpbody = new List <DeviceDataBase>(); for (int i = 0; i < this.messageHeader.DevicesNum; i++) { DeviceDataBase ddb = null; if (istart > messageContent.Length) { break; } int type = (int)SystemCode.HexNumberToDenary(this.messageContent.Substring(istart + 2 * 2, 1 * 2), true, 32, 'u'); switch (type) { case DeviceData.TYPE_MODBUS_BUSBAR: //modbus协议汇流箱 icount = ProtocolConst.LENGTH_MODBUS_BUSBAR * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new ModbusBusbar(this.messageContent.Substring(istart, icount), this); istart = istart + icount; break; } case DeviceData.TYPE_MODBUS15_BUSBAR: //光伏阵列汇流箱通讯协议(Modbus)V1.1.1.0-2011.8.30.pdf add by qianhb in 20111220 icount = ProtocolConst.LENGTH_MODBUS15_BUSBAR * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new Modbus15Busbar(this.messageContent.Substring(istart, icount), this); istart = istart + icount; break; } case DeviceData.TYPE_MODBUS17_BUSBAR: //光伏汇流箱通信协议(Modbus)V1.7设置定稿.doc add by ZHOUHUI in 20121118 icount = ProtocolConst.LENGTH_MODBUS17_BUSBAR * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new Modbus17Busbar(this.messageContent.Substring(istart, icount), this); istart = istart + icount; break; } case DeviceData.TYPE_MODBUS_CABINET: //modbus协议配电柜 icount = ProtocolConst.LENGTH_MODBUS_CABINET * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new ModbusCabinet(this.messageContent.Substring(istart, icount), this); istart = istart + icount; break; } case DeviceData.TYPE_MODBUS16_CABINET: //光伏直流配电柜通信协议(Modbus)V1.0-柴达木-2011.8.30.pdf add by qianhb in 20111220 icount = ProtocolConst.LENGTH_MODBUS16_CABINET * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new Modbus16Cabinet(this.messageContent.Substring(istart, icount), this); istart = istart + icount; break; } case DeviceData.TYPE_MODBUS_DETECTOR: //设备类型0x22对应的数据区格式,环境检测仪(MODBUS协议) add by qianhb in 20111220 icount = ProtocolConst.LENGTH_MODBUS_DETECTOR * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new ModbusDetector(this.messageContent.Substring(istart, icount), this); istart = istart + icount; break; } case DeviceData.TYPE_MODBUS_DETECTOR_V1020: //设备类型0x23对应的数据区格式,环境检测仪(MODBUS协议) add by qianhb in 20120314 icount = ProtocolConst.LENGTH_MODBUS_DETECTOR_1020 * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new ModbusDetector1020(this.messageContent.Substring(istart, icount), this); istart = istart + icount; break; } case DeviceData.TYPE_MODBUS_INVERTER: //modbus协议逆变器 icount = ProtocolConst.LENGTH_MODBUS_INVERTER * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new ModbusInverter(this.messageContent.Substring(istart, icount), this); istart = istart + icount; break; } case DeviceData.TYPE_MODBUS_INVERTER03: //modbus协议逆变器03,由于03协议只是在02基础上增加数据,前面完全一样,对于新增的数据不处理,所以暂用02协议解析类处理 icount = ProtocolConst.LENGTH_MODBUS_INVERTER03 * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new ModbusInverter03(this.messageContent.Substring(istart, icount), this); istart = istart + icount; break; } case DeviceData.TYPE_SUNGROW_BUSBAR: //sungrows协议汇流箱 icount = ProtocolConst.LENGTH_SUNGROW_BUSBAR * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new SungrowBusbar(this.messageContent.Substring(istart, icount), this); istart = istart + icount; break; } case DeviceData.TYPE_SUNGROW_CABINET: //sungrows协议配电柜 icount = ProtocolConst.LENGTH_SUNGROW_CABINET * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new SungrowCabinet(this.messageContent.Substring(istart, icount), this); istart = istart + icount; break; } case DeviceData.TYPE_SUNGROW_DETECTOR: //sungrow协议检测仪 icount = ProtocolConst.LENGTH_SUNGROW_DETECTOR * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new SungrowDetector(this.messageContent.Substring(istart, icount), this); istart = istart + icount; break; } case DeviceData.TYPE_SUNGROW_INVERTER: //sungrow协议逆变器 icount = ProtocolConst.LENGTH_SUNGROW_INVERTER * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new SungrowInverter(this.messageContent.Substring(istart, icount), this); istart = istart + icount; break; } case DeviceData.TYPE_AMMETER: //电表协议 icount = ProtocolConst.LENGTH_AMMETER * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new Ammeter(this.messageContent.Substring(istart, icount), this); istart = istart + icount; break; } case DeviceData.TYPE_AMMETER_11: //电表协议1.1 icount = ProtocolConst.LENGTH_AMMETER_11 * 2; if (istart + icount > this.messageContent.Length) { istart = istart + icount; break; } else { ddb = new Ammeter11(this.messageContent.Substring(istart, icount), this); istart = istart + icount; break; } default: istart = istart + this.messageContent.Length; break; } if (ddb != null) { listTcpbody.Add(ddb); } } //取得告警信息 listTcpbug = new List <Bug>(); int faultInfoLength = getFaultInfoLength(); if (this.messageContent.Length > (faultInfoLength + ProtocolConst.LENGTH_HEAD) * 2) { istart = this.messageContent.Length - faultInfoLength * 2 * (this.messageHeader.BugNum); for (int i = 0; i < this.messageHeader.BugNum; i++) { string bugmsg = this.messageContent.Substring(istart + i * faultInfoLength * 2, faultInfoLength * 2); try { Bug tcpb = parseBug(bugmsg); listTcpbug.Add(tcpb); } catch (Exception buge) { LogUtil.error("告警信息解析错误:" + bugmsg + ":" + buge.Message); } } } } else { base.messageHeader = new TcpHeader(); listTcpbody = new List <DeviceDataBase>(); listTcpbug = new List <Bug>(); } }
/// <summary> /// 起始版本是2.0 /// </summary> public void analysis2_0() { //取得从协议号到数据部分的长度(到具体字符了) int datalen = (int)SystemCode.HexNumberToDenary(this.messageContent.Substring(4 * 2, 4 * 2), SystemCode.ReversionType_all, 32, 'u') * 2; //先简单做数据长度校验,即协议中给出的数据长度和实际是否一致 LogUtil.info("msg len:" + messageContent.Length); //取得数据 int istart20 = 8 * hexbytecharnum; string data = this.messageContent.Substring(istart20, datalen).Substring(datalencount20); //数据类型码 int datatypecode = (int)SystemCode.HexNumberToDenary(this.messageContent.Substring(14 * hexbytecharnum, 2 * hexbytecharnum), true, 16, 'u'); //判断类别标识 int innertypemark = (int)SystemCode.HexNumberToDenary(data.Substring(0 * hexbytecharnum, 2 * hexbytecharnum), true, 16, 'u'); switch (datatypecode) { case DataType.DataType_plantinfo: //电站信息数据 if (innertypemark == 11) { //从key中取得sn this.messageHeader = new TcpHeader20(); this.messageHeader.CollectorCode = msgkey.Substring(DataType.memcacheddata_affix_plantinfo.Length); this.messageHeader.CollectorCode = this.messageHeader.CollectorCode.Substring(0, this.messageHeader.CollectorCode.IndexOf("_")); //暂时屏蔽电站信息 //this.plantInfo = PlantInfoHandler11.analysis(data); } break; case DataType.DataType_rundata: //实时数据 //循环解析多个设备 listTcpbody = new List <DeviceDataBase>(); if (innertypemark == 41) { //从key中取得sn this.messageHeader = new TcpHeader20(); this.messageHeader.CollectorCode = msgkey.Substring(DataType.memcacheddata_affix_run.Length); this.messageHeader.CollectorCode = this.messageHeader.CollectorCode.Substring(0, this.messageHeader.CollectorCode.IndexOf("_")); //取得公共地址 int deviceAddress = (int)SystemCode.HexNumberToDenary(data.Substring(2 * hexbytecharnum, 2 * hexbytecharnum), true, 16, 'u'); if (deviceAddress == 0 || deviceAddress == 65535) //表示是电站实时数据 { this.messageHeader.analyze(data); } else { string ssss = data.Substring(6 * 2, 6 * 2); int year = 2000 + (int)SystemCode.HexNumberToDenary(ssss.Substring(10, 2), false, 8, 'u') % 99; int moth = (int)SystemCode.HexNumberToDenary(ssss.Substring(8, 2), false, 8, 'u'); if (moth > 12) { moth = 12; } int day = (int)SystemCode.HexNumberToDenary(ssss.Substring(6, 2), false, 8, 'u'); if (day > 31) { day = 28; } int hh = (int)SystemCode.HexNumberToDenary(ssss.Substring(4, 2), false, 8, 'u'); if (hh > 23) { hh = 23; } int mm = (int)SystemCode.HexNumberToDenary(ssss.Substring(2, 2), false, 8, 'u'); if (mm > 60) { mm = 59; } int ss = (int)SystemCode.HexNumberToDenary(ssss.Substring(0, 2), false, 8, 'u'); if (ss > 60) { ss = 59; } this.messageHeader.TimeNow = new DateTime(year, moth, day, hh, mm, ss); //add by hbqian int 20130418 for其实0。1分的发电量是昨天,按道理不应该发的,但是现在LOG有个换存,导致0:到15分的这个时间发的发电量可能还是上一天的 if (hh == 0 && mm < 15) { return; } this.messageHeader.issub = true; this.messageHeader.hasData = false; //设备实时数据 DeviceDataBase ddb = new DynamicDevice(data, this); if (ddb.deviceType > -1) //设备的所有信息单元都不符合要求则忽略 { listTcpbody.Add(ddb); } //故障数据 foreach (string[] fault in ddb.faultList) { Bug tcpb = new TcpBug20(fault, deviceAddress.ToString()); listTcpbug.Add(tcpb); } } } break; case DataType.DataType_historydata: //历史数据 break; case DataType.DataType_deviceinfo: //设备数据 if (innertypemark == 31) { //从key中取得sn this.messageHeader = new TcpHeader20(); this.messageHeader.CollectorCode = msgkey.Substring(DataType.memcacheddata_affix_deviceinfo.Length); this.messageHeader.CollectorCode = this.messageHeader.CollectorCode.Substring(0, this.messageHeader.CollectorCode.IndexOf("_")); this.deviceInfos = DeviceInfoHandler31.analysis(data); } break; default: //do nothing break; } }
/// <summary> /// 更加2.0实时数据基本码表动态解析设备实时数据 /// </summary> public void analysis() { message.messageHeader.hasData = false;//设备数据是头部标识为无数据,不再处理 //deviceData="2900010000001E3B0A1A060C050003031900000000010305190000000001010619000000000101071900000000010108190000000001"; //地址即新协议中的公共地址 u16 base.deviceAddress = SystemCode.HexNumberToDenary(deviceData.Substring(2 * 2, 2 * 2), true, 16, 'u').ToString(); //设备版本 int largeVersion = 2; // (int)SystemCode.HexNumberToDenary(deviceData.Substring(3 * hexbytecharnum, 1 * hexbytecharnum), true, 8, 'u'); int smallVersion = 0; // (int)SystemCode.HexNumberToDenary(deviceData.Substring(4 * hexbytecharnum, 1 * hexbytecharnum), true, 8, 'u'); base.deviceVersion = largeVersion + "." + smallVersion; string infoData = deviceData.Substring(14 * 2); //解析多个信息体 //每个信息体开始下标 int startIndex = 0; //每个信息体结束下标 int endIndex = 0; int infotype = 0; //逐个取出信息体 string info; string[] infoResult; int mcode; base.deviceType = -1; while (infoData.Length > 0) { //取得不同信息单元地址对应的解析规则 infotype = InfoBodyUtil.getInfotype(infoData); endIndex = InfoBodyUtil.getInfotypeLen(infotype); info = infoData.Substring(startIndex * 2, endIndex * 2); //没有数据就退出 if (string.IsNullOrEmpty(info)) { break; } InfoUnitAddress infoUnitAddress = InfoBodyUtil.getInfoUnitAddress(info); //没有解析规则跳过 if (infoUnitAddress == null) { infoData = infoData.Substring(endIndex * 2); continue; } //if (infoUnitAddress.address == 203) //{ // Console.WriteLine(""); //} //解析单个信息体 infoResult = InfoBodyUtil.analyze(info, infotype, infoUnitAddress); mcode = infoUnitAddress.mcode; if (infoResult.Length > 0) { if (infoResult.Length > 2)//是故障 { faultList.Add(infoResult); } else { realMonitorMap[mcode] = infoResult[1]; if (MonitorType.historyMonitorList.Contains(mcode)) { historyMonitorMap[mcode] = infoResult[1]; } if (mcode == MonitorType.MIC_DETECTOR_SUNLINGHT) { //最近环境监测仪数据到header数据中 message.realMonitorMap[MonitorType.PLANT_MONITORITEM_LINGT_CODE] = infoResult[1]; message.historyMonitorMap[MonitorType.PLANT_MONITORITEM_LINGT_CODE] = infoResult[1]; message.messageHeader.issub = true; } if (mcode == MonitorType.MIC_DETECTOR_ENRIONMENTTEMPRATURE) { //最近环境监测仪数据到header数据中 message.realMonitorMap[MonitorType.PLANT_MONITORITEM_AMBIENTTEMP_CODE] = infoResult[1]; message.historyMonitorMap[MonitorType.PLANT_MONITORITEM_AMBIENTTEMP_CODE] = infoResult[1]; message.messageHeader.issub = true; } //记录日发电量,用于年月汇总 if (mcode == MonitorType.MIC_INVERTER_TODAYENERGY) { base.todayEnergy = double.Parse(infoResult[1]); } //记录日累计增量日照,用于年月汇总 if (mcode == MonitorType.MIC_DETECTOR_DAYRADIATION) { base.todaySunshine = double.Parse(infoResult[1]); } } } infoData = infoData.Substring(endIndex * 2); tableType = TableUtil.getTableNamebyDeviceType(infoUnitAddress.deviceType); base.deviceType = infoUnitAddress.deviceType; } }
/// <summary> /// 覆写解析方法 /// </summary> /// <param name="header"></param> public override void analyze(string header) { this._Header = header; //StringBuilder sbUnitID = new StringBuilder(); //for (int i = 4; i < 19; i++) //{ // sbUnitID.Append(ASCII.Chr((int)SystemCode.HexNumberToDenary(this._Header.Substring(i * 2, 2), false, 8, 'u'))); //} string sbUnitID = ""; bool isNormal = false; string tmpchar; //将后面是00的抛弃 for (int i = 18; i >= 4; i--) { tmpchar = this._Header.Substring(i * 2, 2); if (!isNormal && !tmpchar.Equals("00")) { isNormal = true; } if (isNormal) { sbUnitID = ASCII.Chr((int)SystemCode.HexNumberToDenary(tmpchar, false, 8, 'u')) + sbUnitID; } } _CollectorCode = sbUnitID.ToString(); _CollectorCode = _CollectorCode.Replace("\0", "0");//临时处理非法测试数据 _Version = SystemCode.HexNumberToDenary(this._Header.Substring(19 * 2, 2 * 2), true, 16, 'u').ToString(); if (debug_collector.Equals(_CollectorCode)) { Console.WriteLine(""); } string ssss = this._Header.Substring(21 * 2, 6 * 2); int year = 2000 + (int)SystemCode.HexNumberToDenary(ssss.Substring(0, 2), true, 16, 'u') % 99; int moth = (int)SystemCode.HexNumberToDenary(ssss.Substring(2, 2), true, 16, 'u'); if (moth > 12) { moth = 12; } int day = (int)SystemCode.HexNumberToDenary(ssss.Substring(4, 2), true, 16, 'u'); if (day > 31) { day = 28; } int hh = (int)SystemCode.HexNumberToDenary(ssss.Substring(6, 2), true, 16, 'u'); if (hh > 23) { hh = 23; } int mm = (int)SystemCode.HexNumberToDenary(ssss.Substring(8, 2), true, 16, 'u'); if (mm > 60) { mm = 59; } int ss = (int)SystemCode.HexNumberToDenary(ssss.Substring(10, 2), true, 16, 'u'); if (ss > 60) { ss = 59; } this.TimeNow = new DateTime(year, moth, day, hh, mm, ss); string dayestr = SystemCode.ReversionAll(this._Header.Substring(31 * 2, 4 * 2)); _dayEnergy = (float)SystemCode.HexNumberToDenary(dayestr, false, 32, 'u'); //add in 8/6 for 原来是4字节无符号整形,改为无符号带一位小数整形 _dayEnergy = _dayEnergy * 0.1F; LogUtil.info("collector energy " + _dayEnergy); string totalstr = SystemCode.ReversionAll(this._Header.Substring(35 * 2, 4 * 2)); _totalEnergy = SystemCode.HexNumberToDenary(totalstr, false, 32, 'U'); string powerstr = SystemCode.ReversionAll(this._Header.Substring(27 * 2, 4 * 2)); _power = (int)SystemCode.HexNumberToDenary(powerstr, false, 32, 'u'); _power = float.Parse(Math.Round(_power / 1000, 3).ToString());//换算成kw _DevicesNum = (int)SystemCode.HexNumberToDenary(this._Header.Substring(39 * 2, 1 * 2), false, 8, 'u'); BugNum = (int)SystemCode.HexNumberToDenary(this._Header.Substring(40 * 2, 1 * 2), false, 8, 'u'); }
/// <summary> /// 覆写解析方法 /// </summary> /// <param name="header"></param> public override void analyze(string header) { this.issub = false; this.hasData = true; this._Header = header; _CollectorCode = _CollectorCode.Replace("\0", "0");//临时处理非法测试数据 if (debug_collector.Equals(_CollectorCode)) { Console.WriteLine(""); } string ssss = this._Header.Substring(6 * 2, 6 * 2); int year = 2000 + (int)SystemCode.HexNumberToDenary(ssss.Substring(10, 2), false, 8, 'u') % 99; int moth = (int)SystemCode.HexNumberToDenary(ssss.Substring(8, 2), false, 8, 'u'); if (moth > 12) { moth = 12; } int day = (int)SystemCode.HexNumberToDenary(ssss.Substring(6, 2), false, 8, 'u'); if (day > 31) { day = 28; } int hh = (int)SystemCode.HexNumberToDenary(ssss.Substring(4, 2), false, 8, 'u'); if (hh > 23) { hh = 23; } int mm = (int)SystemCode.HexNumberToDenary(ssss.Substring(2, 2), false, 8, 'u'); if (mm > 60) { mm = 59; } int ss = (int)SystemCode.HexNumberToDenary(ssss.Substring(0, 2), false, 8, 'u'); if (ss > 60) { ss = 59; } this.TimeNow = new DateTime(year, moth, day, hh, mm, ss); if (DateTime.Now.AddDays(2) < this.TimeNow) //超过服务器时间两天的实时数据抛弃 { this.hasData = false; return; } string infoData = header.Substring(14 * 2); //解析多个信息体 //每个信息体开始下标 int startIndex = 0; //每个信息体结束下标 int endIndex = 0; int infotype = 0; //逐个取出信息体 string info; string[] infoResult; base.hasData = false; while (infoData.Length > 0) { infotype = InfoBodyUtil.getInfotype(infoData); endIndex = InfoBodyUtil.getInfotypeLen(infotype); info = infoData.Substring(startIndex * 2, endIndex * 2); //没有数据就退出 if (string.IsNullOrEmpty(info)) { break; } InfoUnitAddress infounitAddress = InfoBodyUtil.getInfoUnitAddress(info); //没有解析规则跳过 if (infounitAddress == null) { infoData = infoData.Substring(endIndex * 2); continue; } //解析单个信息体 infoResult = InfoBodyUtil.analyze(info, infotype, infounitAddress); if (infoResult.Length > 0) { switch (int.Parse(infoResult[0])) { //发电量 case DataType.plant_dayenergy: this.DayEnergy = float.Parse(infoResult[1]); LogUtil.info("collector energy " + _dayEnergy); break; //总发电量 case DataType.plant_totalenergy: try { this.TotalEnergy = float.Parse(infoResult[1]); } catch (Exception e) { this.TotalEnergy = 0; } break; //功率 case DataType.plant_power: _power = float.Parse(infoResult[1]); //_power = float.Parse(Math.Round(_power / 1000, 3).ToString());//新协议无需换算成kw break; //日照 case DataType.plant_sunlight: try { this.sunStrength = int.Parse(infoResult[1]); } catch (Exception e) { this.sunStrength = null; } break; //环境温度 case DataType.plant_temperature: try { this.temperature = float.Parse(infoResult[1]); } catch (Exception e) { this.temperature = null; } break; default: break; } base.hasData = true; } infoData = infoData.Substring(endIndex * 2); } //string totalstr = SystemCode.ReversionAll(this._Header.Substring(35 * 2, 4 * 2)); //_totalEnergy = SystemCode.HexNumberToDenary(totalstr, false, 32, 'U'); _DevicesNum = 0; BugNum = 0; }
/// <summary> /// 覆写解析方法 /// </summary> /// <param name="header"></param> public override void analyze(string header) { this._Header = header; this.hasData = true; CollectorCode = getSn(header); _Version = SystemCode.HexNumberToDenary(this._Header.Substring(19 * 2, 2 * 2), true, 16, 'u').ToString(); if (debug_collector.Equals(_CollectorCode)) { Console.WriteLine(""); } string ssss = this._Header.Substring(21 * 2, 6 * 2); int year = 2000 + (int)SystemCode.HexNumberToDenary(ssss.Substring(0, 2), true, 16, 'u') % 99; int moth = (int)SystemCode.HexNumberToDenary(ssss.Substring(2, 2), true, 16, 'u'); if (moth > 12) { moth = 12; } int day = (int)SystemCode.HexNumberToDenary(ssss.Substring(4, 2), true, 16, 'u'); if (day > 31) { day = 28; } int hh = (int)SystemCode.HexNumberToDenary(ssss.Substring(6, 2), true, 16, 'u'); if (hh > 23) { hh = 23; } int mm = (int)SystemCode.HexNumberToDenary(ssss.Substring(8, 2), true, 16, 'u'); if (mm > 60) { mm = 59; } int ss = (int)SystemCode.HexNumberToDenary(ssss.Substring(10, 2), true, 16, 'u'); if (ss > 60) { ss = 59; } //临时代码 //if (day == 2) day = 4; //else if (day == 3) day = 5; this.TimeNow = new DateTime(year, moth, day, hh, mm, ss); LogUtil.info("collector TimeNow " + TimeNow.ToString()); string dayestr = SystemCode.ReversionAll(this._Header.Substring(31 * 2, 4 * 2)); _dayEnergy = (float)SystemCode.HexNumberToDenary(dayestr, false, 32, 'u'); //add in 8/6 for 原来是4字节无符号整形,改为无符号带一位小数整形 _dayEnergy = _dayEnergy * 0.1F; LogUtil.info("collector energy " + _dayEnergy); string totalstr = SystemCode.ReversionAll(this._Header.Substring(35 * 2, 4 * 2)); _totalEnergy = SystemCode.HexNumberToDenary(totalstr, false, 32, 'U'); string powerstr = SystemCode.ReversionAll(this._Header.Substring(27 * 2, 4 * 2)); _power = (int)SystemCode.HexNumberToDenary(powerstr, false, 32, 'u'); _power = float.Parse(Math.Round(_power.Value / 1000, 3).ToString());//换算成kw _DevicesNum = (int)SystemCode.HexNumberToDenary(this._Header.Substring(39 * 2, 1 * 2), false, 8, 'u'); BugNum = (int)SystemCode.HexNumberToDenary(this._Header.Substring(40 * 2, 1 * 2), false, 8, 'u'); base.hasData = true; this.issub = false; }
/// <summary> /// 取得多个信息体串的第一个信息体类型 /// </summary> /// <param name="bodys"></param> /// <returns></returns> public static int getInfotype(string bodys) { return((int)SystemCode.HexNumberToDenary(bodys.Substring(0, 2), false, 8, 'u')); }