using Newtonsoft.Json; using SensorHub.Config; using SensorHub.Servers; using SensorHub.Servers.Commands.CASICCommands; using SensorHub.Servers.JsonFormat; using SuperSocket.SocketBase.Command; using SuperSocket.SocketBase.Protocol; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Caching; using System.Text; using System.Threading; using System.Threading.Tasks; namespace SensorHub.MultiLeak { public class MultiLeak : CommandBase<CasicSession, StringRequestInfo> { private static MemoryCache memoryCache = new MemoryCache("MultiLeak"); private readonly object SyncObj = new object(); private RedisHelper redis = new RedisHelper(0); public override void ExecuteCommand(CasicSession session, StringRequestInfo requestInfo) { //TODO: construct the receving casic data String preamble = requestInfo.Parameters[0]; String version = requestInfo.Parameters[1]; String leng = requestInfo.Parameters[2]; String devCode = requestInfo.Parameters[3]; String routeFlag = requestInfo.Parameters[4]; String dstNodeAddr = requestInfo.Parameters[5]; String pduType = requestInfo.Parameters[6]; String seq = requestInfo.Parameters[7]; String settings = requestInfo.Parameters[8]; String source = requestInfo.Parameters[9]; String devName = "MultiLeak"; if (source.Contains("-")) { session.Send("HTTP/1.1 200 OK\r\n\r\n\r\n"); session.Close(); } //print the receving data String devType = "多功能漏损监测仪"; String operType = Common.getOpeTypeByPdu(pduType); session.Logger.Info("AD接收数据:" + requestInfo.Body); session.Logger.Info("设备类型:" + devType); session.Logger.Info("操作类型:" + operType); session.Logger.Info("会话:" + session.HubAddr + "," + session.SessionID); //判断是返回的设置确认数据帧, 回复第三方 if (operType == "SetResponse") { for (int type = 1; type < 4; type++) { if (string.IsNullOrEmpty(redis.StringGet(devCode + "-" + type))) { continue; } Common.sendSetResponse(session, devCode + "-" + type, devName); if (source != "433") { for (int t = type + 1; t < 4; t++) { if (!string.IsNullOrEmpty(redis.StringGet(devCode + "-" + t))) { Thread.Sleep(5000); senderGPRSConfig(session, devCode, new byte[2] { 0x03, 0x81 }, source); break; } } } return; } return; } if (!isfinishe(pduType) || seq != "01")//不分包不缓存 { //多功能分包传输,对各个数据分包进行缓存 var item = memoryCache.Get(devCode); if (item != null && (((int)item >> (Convert.ToInt32(seq, 16) - 1)) & 0x01) == 1) { session.Logger.Info("已缓存数据序列号:" + Convert.ToString((int)item, 2)); session.Logger.Info("该数据已缓存!"); return; } else { lock (this.SyncObj)//锁定 { item = memoryCache.Get(devCode); if (item != null) { session.Logger.Info("已缓存数据序列号:" + Convert.ToString((int)item, 2)); if ((((int)item >> (Convert.ToInt32(seq, 16) - 1)) & 0x01) == 1) { session.Logger.Info("该数据已缓存!"); return; } else { var cachePolicy = new CacheItemPolicy(); cachePolicy.AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(1); int Seq = (int)item; Seq |= (1 << (Convert.ToInt32(seq, 16) - 1)); memoryCache.Set(devCode, Seq, cachePolicy); session.Logger.Info("设置已经接收数据序列号:" + Convert.ToString(Seq, 2)); } } else { var cachePolicy = new CacheItemPolicy(); cachePolicy.AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(1); int Seq = 0; Seq |= (1 << (Convert.ToInt32(seq, 16) - 1)); memoryCache.Set(devCode, Seq, cachePolicy); session.Logger.Info("设置已经接收数据序列号:" + Convert.ToString(Seq, 2)); } } } } List<Tag> tags = Common.getTags(settings, session); //具体业务处理 String collectDate = ""; String uptime = ""; int? pci = null; int? rsrp = null; int? snr = null; String softwareVersion = ""; uint offset = 0; uint size = 0; List<String> eventList = new List<String>(); List<DatasJson> datasList = new List<DatasJson>(); foreach (Tag tag in tags) { if (!(tag is UploadTag)) { if (tag != null && tag is PCITag) { PCITag pciTag = (PCITag)tag; pci = pciTag.PCI; continue; } if (tag != null && tag is RSRPTag) { RSRPTag rsrpTag = (RSRPTag)tag; rsrp = rsrpTag.RSRP; continue; } if (tag != null && tag is SNRTag) { SNRTag snrTag = (SNRTag)tag; snr = snrTag.SNR; continue; } if (tag != null && tag is CellTag) //多功能电量单独发送 { CellTag cellTag = tag as CellTag; DateTime now = DateTime.Now; String logtime = now.ToString("yyyy") + now.ToString("MM") + now.ToString("dd") + now.ToString("HH") + now.ToString("mm") + now.ToString("ss"); DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); //当地时区 long timeStamp = (long)(now - startTime).TotalMilliseconds; //相差毫秒数 try { String message = JsonConvert.SerializeObject(new Json("Data", devName, devCode, new DataJson("MultiLeakCellData", cellTag.Cell, null, logtime), timeStamp)); if (Common.SendMessage(message)) { session.Logger.Info("往第三方发送数据:" + message); } else { session.Logger.Info("未连接上第三方服务器"); } } catch (Exception ex) { session.Logger.Error("往第三方发送数据出错:" + ex.Message); } break; } //非业务处理 if (tag != null && tag is SystemDateTag) { SystemDateTag systemDateTag = tag as SystemDateTag; collectDate = systemDateTag.CollectDate; continue; } if (tag != null && tag is SensorException0Tag) { SensorException0Tag sensorException0 = tag as SensorException0Tag; int state = sensorException0.state; if (state == 0) continue; eventList.Add(getMultiLeakAlarm(state)); session.Logger.Info("通道一发送容错信息:oid:" + tag.Oid + ";value:" + state); continue; } if (tag != null && tag is SensorException1Tag) { SensorException1Tag sensorException1 = tag as SensorException1Tag; int state = sensorException1.state; if (state == 0) continue; eventList.Add(getMultiLeakAlarm(state + 3)); session.Logger.Info("通道二发送容错信息:oid:" + tag.Oid + ";value:" + state); continue; } if (tag != null && tag is SensorException2Tag) { SensorException2Tag sensorException2 = tag as SensorException2Tag; int state = sensorException2.state; if (state == 0) continue; eventList.Add(getMultiLeakAlarm(state + 6)); session.Logger.Info("通道三发送容错信息:oid:" + tag.Oid + ";value:" + state); continue; } //非业务处理 if (tag != null && tag is SoftwareVersionTag) { SoftwareVersionTag versionTag = (SoftwareVersionTag)tag; softwareVersion = versionTag.Version; continue; } if (tag != null && tag is OffsetTag) { OffsetTag offsetTag = (OffsetTag)tag; offset = offsetTag.Offset; continue; } if (tag != null && tag is SizeTag) { SizeTag sizeTag = (SizeTag)tag; size = sizeTag.Size; continue; } } else { //业务处理 UploadTag uploadTag = tag as UploadTag; switch (uploadTag.BizType) { case 1: //流量 TagHandler flowHandler = new FlowTagHandler(); flowHandler.resolve(tag, session); DateTime baseTime1 = Convert.ToDateTime(collectDate + " " + flowHandler.CollecTime); datasList.Clear(); for (int i = 0; i < flowHandler.DataList.Count / 3; i++) { DateTime upTime = baseTime1.AddMinutes(i * flowHandler.Interval); uptime = upTime.ToString("yyyy") + upTime.ToString("MM") + upTime.ToString("dd") + upTime.ToString("HH") + upTime.ToString("mm") + upTime.ToString("ss"); datasList.Add(new MultiLeakFlowDatasJson(uptime, (float)flowHandler.DataList[i * 3], (float)flowHandler.DataList[i * 3 + 1], (float)flowHandler.DataList[i * 3 + 2])); } sendMessage(session, "MultiLeakFlow", devCode, -1, pci, rsrp, snr, null, datasList, null); break; case 2: //压力 TagHandler pressHandler = new PressTagHandler(); pressHandler.resolve(tag, session); DateTime baseTime2 = Convert.ToDateTime(collectDate + " " + pressHandler.CollecTime); datasList.Clear(); for (int i = 0; i < pressHandler.DataList.Count; i++) { DateTime upTime = baseTime2.AddMinutes(i * pressHandler.Interval); uptime = upTime.ToString("yyyy") + upTime.ToString("MM") + upTime.ToString("dd") + upTime.ToString("HH") + upTime.ToString("mm") + upTime.ToString("ss"); datasList.Add(new MultiLeakPressureDatasJson(uptime, (float)pressHandler.DataList[i])); } sendMessage(session, "MultiLeakPressure", devCode, -1, pci, rsrp, snr, null, datasList, null); break; case 4: //噪声 TagHandler noiseHandler = new NoiseTagHandler(); noiseHandler.resolve(tag, session); DateTime baseTime3 = Convert.ToDateTime(collectDate + " " + noiseHandler.CollecTime); datasList.Clear(); for (int i = 0; i < noiseHandler.DataList.Count; i++) { DateTime upTime = baseTime3.AddMinutes(i * noiseHandler.Interval); uptime = upTime.ToString("yyyy") + upTime.ToString("MM") + upTime.ToString("dd") + upTime.ToString("HH") + upTime.ToString("mm") + upTime.ToString("ss"); datasList.Add(new MultiLeakNoiseDatasJson(uptime, (double)noiseHandler.DataList[i])); } sendMessage(session, "MultiLeakNoise", devCode, -1, pci, rsrp, snr, null, datasList, null); break; default: session.Logger.Info("未知业务类型!"); break; } } } byte[] btPdu = new byte[2]; //2个字节 btPdu[0] = Common.getRespOperType(operType, source == "433" ? true : false); btPdu[1] = 0x81; if (btPdu[0] == 0xFF)//未知操作类型 { return; } if (softwareVersion != "" || size != 0 || offset != 0)//进入远程升级流程 { Common.remoteUpgrade(session, operType, devName, devCode, btPdu, softwareVersion, size, offset, source); return; } sendMessage(session, devName, devCode, -1, pci, rsrp, snr, eventList, null, null); if (isfinishe(pduType)) { try { if (routeFlag == "03") //GPRS,3G网络,电信平台 { memoryCache.Remove(devCode); senderGPRSConfig(session, devCode, btPdu, source); } else //433 { sender433Config(session, devCode, btPdu, 0x01); } } catch (Exception e) { session.Logger.Error(e.ToString()); } } } private void sendMessage(CasicSession session, String devName, String devCode, int cell, int? pci, int? rsrp, int? snr, List<String> eventList, List<DatasJson> datasList, List<String> startupList) { DateTime now = DateTime.Now; String logtime = now.ToString("yyyy") + now.ToString("MM") + now.ToString("dd") + now.ToString("HH") + now.ToString("mm") + now.ToString("ss"); DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); //当地时区 long timeStamp = (long)(now - startTime).TotalMilliseconds; //相差毫秒数 try { //往第三方发送数据 if (datasList != null && datasList.Count > 0) { String message = JsonConvert.SerializeObject(new Json("Data", "MultiLeak", devCode, new DataJson(devName + "Data", cell, pci, rsrp, snr, datasList, logtime), timeStamp)); if (Common.SendMessage(message)) { session.Logger.Info("往第三方发送数据:" + message); } else { session.Logger.Info("未连接上第三方服务器"); } } if (eventList != null && eventList.Count > 0) { String message = JsonConvert.SerializeObject(new Json("Event", devName, devCode, new EventJson(devName + "Event", eventList, logtime), timeStamp)); if (Common.SendMessage(message)) { session.Logger.Info("往第三方发送数据:" + message); } else { session.Logger.Info("未连接上第三方服务器"); } } if (startupList != null && startupList.Count == 2) { String message = JsonConvert.SerializeObject(new Json("StartupRequest", devName, devCode, new StartupJson(devName + "Data", startupList[0], startupList[1]), timeStamp)); if (Common.SendMessage(message)) { session.Logger.Info("往第三方发送数据:" + message); } else { session.Logger.Info("未连接上第三方服务器"); } } } catch (Exception ex) { session.Logger.Error("往第三方发送数据出错:" + ex.Message); } } private void sender433Config(CasicSession session, string devCode, byte[] btPdu, byte routeflag) { CasicSender sender = new CasicSender(null); byte[] config = sender.build433RspConfigFrame(devCode); config[10] = routeflag;//通信方式 btPdu.CopyTo(config, 13); var item = memoryCache.Get(devCode); if (item != null) { byte[] value = BitConverter.GetBytes((int)item); config[34] = value[1]; config[35] = value[0]; } SystemTimeConfig sysTimeConfig = new SystemTimeConfig(null); byte[] btConfig = sysTimeConfig.getConfig(new byte[0]); btConfig.CopyTo(config, 16); session.Logger.Info("下发回复信息:" + BitConverter.ToString(config).Replace("-", "")); session.Send(Common.CRC(config), 0, config.Length + 2); memoryCache.Remove(devCode);//移除上一次缓存的分包状态 } private void senderGPRSConfig(CasicSession session, string devCode, byte[] btPdu, string source) { for (int type = 1; type <= 4; type++) { String configItem = null; if (redis.Conn != null) { configItem = redis.StringGet(devCode + "-" + type); } if (string.IsNullOrEmpty(configItem) && type < 4) { continue; } byte[] config = ConfigBuild.buildConfigFrame(devCode, configItem); config[10] = 0x03; config[13] = btPdu[0]; config[14] = btPdu[1]; SystemTimeConfig sysTimeConfig = new SystemTimeConfig(null); byte[] btConfig = sysTimeConfig.getConfig(new byte[0]); btConfig.CopyTo(config, 16); session.Logger.Info("下发回复配置信息:" + BitConverter.ToString(config).Replace("-", "")); if (source == "4G") { session.Send(Common.CRC(config), 0, config.Length + 2); return; } byte[] tag = new byte[config.Length - 16]; byte[] enTag; Array.Copy(config, 16, tag, 0, config.Length - 16); int a = tag.Length % 8; if (a != 0) { enTag = new byte[tag.Length + 8 - a]; tag.CopyTo(enTag, 0); for (int i = 0; i < 8 - a; i++) { enTag[tag.Length + i] = 0; } } else { enTag = new byte[tag.Length]; tag.CopyTo(enTag, 0); } TEA.encrypt(ref enTag, enTag.Length); byte[] result = new byte[1 + 1 + 2 + 6 + 1 + 2 + 2 + 1 + enTag.Length]; Array.Copy(config, result, 16); enTag.CopyTo(result, 16); byte[] afcrc = Common.CRC(result); //TODO:发送数据 if (source == "OTHER") { session.Send(afcrc, 0, afcrc.Length); } else { String strBase64Value = Convert.ToBase64String(afcrc); int ret = Common.SendNACommand(session, strBase64Value, source); if (ret != 201) { session.Logger.Info("电信平台下发配置信息失败,返回的Http状态码:" + ret); } else { session.Logger.Info("电信平台下发配置信息成功!"); } } break; } } private bool isfinishe(String pduType) { Int16 btpduType = Int16.Parse(pduType, System.Globalization.NumberStyles.HexNumber); int flag = btpduType & 0x80; return flag == 128 ? true : false; } private String getMultiLeakAlarm(int state) { switch (state) { case 0: return "MultiLeakFlowNormal";//流量探头正常 case 1: return "MultiLeakFlowFail"; //流量探头采集失败 case 2: return "MultiLeakFlowError"; //流量探头数据异常 case 3: return "MultiLeakPressureNormal";//压力探头正常 case 4: return "MultiLeakPressureFail"; //压力探头采集失败 case 5: return "MultiLeakPressureError"; //压力探头数据异常 case 6: return "MultiLeakNoiseNormal";//噪声探头正常 case 7: return "MultiLeakNoiseFail"; //噪声探头采集失败 case 8: return "MultiLeakNoiseError"; //噪声探头数据异常 default: return "MultiLeakUnknown"; //未知异常 } } } }