using MathWorks.MATLAB.NET.Arrays; using mExcaMonitor; using Newtonsoft.Json; using SensorHub.Config; using SensorHub.Servers; using SensorHub.Servers.Commands.CASICCommands; using SensorHub.Servers.JsonFormat; using SensorHub.Utility; using SuperSocket.SocketBase.Command; using SuperSocket.SocketBase.Protocol; using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace SensorHub.Dig { public class Dig : CommandBase<CasicSession, StringRequestInfo> { private static Dictionary<string, float[]> digDataValueMap = new Dictionary<string, float[]>(); private static Dictionary<string, List<Object[]>> calResult = new Dictionary<string, List<Object[]>>();//计算结果 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 devType = "开挖监测仪"; String operType = Common.getOpeTypeByPdu(pduType); session.Logger.Info("AD接收数据:" + requestInfo.Body); session.Logger.Info("设备类型:" + devType); session.Logger.Info("操作类型:" + operType); session.Logger.Info("序号:" + seq); session.Logger.Info("会话:" + session.HubAddr + "," + session.SessionID); //判断是返回的设置确认数据帧, 回复第三方 if (operType == "SetResponse") { Common.sendSetResponse(session, devCode, "Dig"); return; } if (session.HubAddr == null)//新连接到来 { if (DigServer.digWithSessionIdMap.ContainsKey(devCode)) { String sessionID = DigServer.digWithSessionIdMap[devCode]; CasicSession s = session.AppServer.GetSessionByID(sessionID); if (s != null && s.Connected) { s.HubAddr = null; s.Close(); } DigServer.digWithSessionIdMap[devCode] = session.SessionID; //该设备之前已连接,更新会话,断开旧连接 //byte[] btPdu = new byte[2]; //btPdu[0] = Common.getRespOperType(operType, true); //btPdu[1] = 0x92; //Common.sender433Config(session, devCode, btPdu, 0x03); //return; } else { DigServer.digWithSessionIdMap.Add(devCode, session.SessionID); DateTime now = DateTime.Now; DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); //当地时区 long timeStamp = (long)(now - startTime).TotalMilliseconds; //相差毫秒数 String logtime = now.ToString("yyyy") + now.ToString("MM") + now.ToString("dd") + now.ToString("HH") + now.ToString("mm") + now.ToString("ss"); String message = JsonConvert.SerializeObject(new Json("Event", "Dig", devCode, new DataJson("DigOnline", -1, null, logtime), timeStamp)); if (Common.SendMessage(message)) { session.Logger.Info("往第三方发送数据:" + message); } else { session.Logger.Info("未连接上第三方服务器"); } } session.HubAddr = devCode; } List<Tag> tags = Common.getTags(settings, session); //具体业务处理 String collectDate = ""; List<String> eventList = new List<String>(); List<DatasJson> datasList = new List<DatasJson>(); String timestamp = "";//16进制形式 foreach (Tag tag in tags) { if (!(tag is UploadTag)) { //非业务处理 if (tag != null && tag is SystemDateTag) { SystemDateTag systemDateTag = tag as SystemDateTag; collectDate = systemDateTag.CollectDate; continue; } //非业务处理10000051,时间戳 if (tag != null && tag is SystemTimeTag) { SystemTimeTag systemTimeTag = (SystemTimeTag)tag; timestamp = systemTimeTag.SysTime; continue; } if (tag != null && tag is SensorException0Tag) { SensorException0Tag sensorException0 = tag as SensorException0Tag; int state = sensorException0.state; if (state == 0) continue; redis.Publish("DigAlarm", devCode);//主动发布消息 eventList.Add(getDigAlarm(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; eventList.Add(getDigAlarm(2));//DigLowBatteryAlarm:20 session.Logger.Info("通道二发送容错信息:oid:" + tag.Oid + ";value:" + state); continue; } } else { //业务处理 UploadTag uploadTag = tag as UploadTag; switch (uploadTag.BizType) { case 20: //速度 TagHandler speedHandler = new SpeedTagHandler(); speedHandler.resolve(tag, session); int Seq = Convert.ToInt32(seq, 16) - 1; if (speedHandler.Data != null) { if (!digDataValueMap.ContainsKey(devCode)) { digDataValueMap.Add(devCode, new float[3750 * 10]); //7500 } if (Seq < 10)//只接收10s的数据 { (speedHandler.Data as float[]).CopyTo(digDataValueMap[devCode], 3750 * Seq); } } break; case 6: session.Logger.Info("开挖监测仪心跳"); break; default: session.Logger.Info("未知业务类型!"); break; } } } Common.sendMessage(session, "Dig", devCode, -1, eventList, datasList, null); CasicSender sender = new CasicSender(null); byte[] config = sender.build433RspConfigFrame(devCode); byte oper = Common.getRespOperType(operType, true);//PDUType if (oper == 0xFF)//未知操作类型,不返回下发 return; config[13] = oper;//操作类型 config[10] = 0x03;//通信方式 config[14] = 0x92; config[15] = 0x01;//Seq 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); if (seq == "0A")//10s数据接收完毕 { if (DigServer.digDataFinishMap.ContainsKey(devCode)) { DigServer.digDataFinishMap[devCode] = true; } else { session.Logger.Info("设备[" + devCode + "]未在当前唤醒组中!"); return; } if (DigServer.digGroupDevcodeMap.ContainsKey(timestamp)) { foreach (var devcode in DigServer.digGroupDevcodeMap[timestamp]) { if (DigServer.digDataFinishMap.ContainsKey(devcode) && DigServer.digDataFinishMap[devcode]) { continue; } else { return;//数据未接收完成,不满足计算条件,直接退出 } } //调用算法进行计算 calculate(session, timestamp); } return; } //判断如果是心跳,检查是否需要下发参数 if (operType == "OnlineRequest") { RedisHelper redis = new RedisHelper(0); String configItem = redis.StringGet(devCode); if (string.IsNullOrEmpty(configItem)) { return; } Thread.Sleep(5000);//延迟5s下发 config = ConfigBuild.buildConfigFrame(devCode, configItem); config[10] = 0x03; config[13] = 0x03; config[14] = 0x92; SystemTimeConfig sysTimeConfig1 = new SystemTimeConfig(null); byte[] btConfig1 = sysTimeConfig1.getConfig(new byte[0]); btConfig1.CopyTo(config, 16); session.Logger.Info("主动下发配置信息:" + BitConverter.ToString(config).Replace("-", "")); session.Send(Common.CRC(config), 0, config.Length + 2); } } private void calculate(CasicSession session, String timestamp) { String[] devCodes = DigServer.digGroupDevcodeMap[timestamp]; if (devCodes.Length != 5) { session.Logger.Info("错误,不是5个设备编号,不满足计算条件"); return; } session.Logger.Info("将数据存入文件!"); string decTimestamp = StringUtil.Hex2DecTime(timestamp);//转换为直观的10进制时间戳 foreach (var devcode in devCodes) { writeFile(devcode, decTimestamp); } session.Logger.Info("开始调用算法!"); String devcodes = devCodes[0] + "," + devCodes[1] + "," + devCodes[2] + "," + devCodes[3] + "," + devCodes[4];//关键字 try { mExcaMonitor.excavationMonitoring exc = new mExcaMonitor.excavationMonitoring(); Object[] outList = exc.mExcaMonitor(3, (MWNumericArray)digDataValueMap[devCodes[0]], (MWNumericArray)digDataValueMap[devCodes[1]], (MWNumericArray)digDataValueMap[devCodes[2]], (MWNumericArray)digDataValueMap[devCodes[3]], (MWNumericArray)digDataValueMap[devCodes[4]]); session.Logger.Info("调用算法计算结果:" + outList[0] + "," + outList[1] + "," + outList[2]); //String devcodes = devCodes[0] + "," + devCodes[1] + "," + devCodes[2] + "," + devCodes[3] + "," + devCodes[4];//关键字 if (!calResult.ContainsKey(devcodes)) { calResult.Add(devcodes, new List<Object[]>()); } calResult[devcodes].Add(outList); } catch (Exception ex) { throw ex; } foreach (var devcode in devCodes) { digDataValueMap.Remove(devcode); DigServer.digDataFinishMap.Remove(devcode); } DigServer.digGroupDevcodeMap.Remove(timestamp);//初始化,清除状态 session.Logger.Info("计算结果组数:" + calResult[devcodes].Count); //calResult.Remove(devcodes);//暂时 if (calResult[devcodes].Count >= 5) { session.Logger.Info("计算结果大于等于5组,开始分析!"); int mark = 0; double distance = 0.0; //开挖距离 double angle = 0.0; //开挖角度 double manuallyDistance = 0.0; //人工开挖距离 double manuallyAngle = 0.0; //人工开挖角度 double mechanicallyDistance = 0.0; //机械开挖距离 double mechanicallyAngle = 0.0; //机械开挖角度 int no = 0; int manually = 0; int mechanically = 0; foreach (Object[] v in calResult[devcodes]) { session.Logger.Info("转换开始!"); int _mark = int.Parse(v[0].ToString()); double _distance = double.Parse(v[1].ToString()); double _angle = double.Parse(v[2].ToString()); session.Logger.Info("转换结果:" + _mark + "," + _distance + "," + _angle); if (_mark == 0) { no++; } else if (_mark == 1) { manually++; manuallyDistance = _distance; manuallyAngle = _angle; } else if (_mark == 2) { mechanically++; mechanicallyDistance = _distance; mechanicallyAngle = _angle; } } if (no > manually + mechanically) { //无开挖 mark = 0; } else if (manually > mechanically) { //人工开挖 mark = 1; distance = manuallyDistance; angle = manuallyAngle; } else { //机械开挖 mark = 2; distance = mechanicallyDistance; angle = mechanicallyAngle; } //往第三方发送json字符串 List<DatasJson> datasList = new List<DatasJson>(); datasList.Add(new DigDatasJson(mark, distance, angle)); Common.sendMessage(session, "Dig", devCodes[0], -1, null, datasList, null); calResult.Remove(devcodes); session.Logger.Info("开挖类型mark:" + mark + ",距离distance:" + distance + ",角度angle:" + angle); } else { session.Logger.Info("计算结果不足5次,继续下发唤醒点名指令:" + devcodes); redis.Publish("DigGroup", devcodes); } } private void writeFile(string devcode, string timestamp) { StringBuilder sb = new StringBuilder(); foreach (double data in digDataValueMap[devcode]) { sb.Append(data + " "); } String path = AppDomain.CurrentDomain.BaseDirectory + "File\\"; String filename = devcode + "_" + timestamp + ".txt"; File.AppendAllText(path + filename, sb.ToString()); } private String getDigAlarm(int state) { switch (state) { case 0: return "DigNormal";//正常 case 1: return "DigAlarm"; //报警 case 2: return "DigLowBatteryAlarm"; //低电量报警 default: return "DigUnknown"; //未知异常 } } } }