using SuperSocket.SocketBase; using SuperSocket.SocketBase.Protocol; using System.Collections.Generic; using System; using SensorHub.Utility; using System.Timers; using Newtonsoft.Json.Linq; using Newtonsoft.Json; using SensorHub.Servers.JsonFormat; using SensorHub.Servers.Commands.CASICCommands; using StackExchange.Redis; using System.Threading; using System.Diagnostics; using SensorHub.Servers; using mExcaMonitor; //using MathWorks.MATLAB.NET.Arrays; using System.Collections; using MathWorks.MATLAB.NET.Arrays; namespace SensorHub.Dig { public class DigServer : AppServer<CasicSession> { RedisHelper redis = new RedisHelper(0); public static Dictionary<String, String> digWithSessionIdMap = new Dictionary<String, String>(); static int interval = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["Interval"]);//调用算法时间间隔 System.Timers.Timer timer = new System.Timers.Timer(interval); private List<String> messageList = new List<String>(); public static Dictionary<string, string[]> digGroupDevcodeMap = new Dictionary<string, string[]>();//组号(时间戳)-设备编号 public static Dictionary<string, bool> digDataFinishMap = new Dictionary<string, bool>();//设备编号-数据接收状态(true:10s已接收完成;false:未接收完成) public DigServer() : base(new DefaultReceiveFilterFactory<DigReceiveFilter, StringRequestInfo>()) { } protected override void OnStarted() { redis.Subscribe("DigGroup", (channel, message) => { //输出收到的订阅消息 Logger.Info("收到订阅的消息,channel:" + channel + ",message:" + message); if (messageList.Contains(message)) { Logger.Info("该消息已接收缓存"); return; } messageList.Add(message); Thread.Sleep(500);//延迟0.5秒下发 String[] devCodes = message.ToString().Split(','); foreach (var devcode in devCodes)//检查设备是否都是连接状态 { if (!digWithSessionIdMap.ContainsKey(devcode)) { Logger.Info("设备[" + devcode + "]连接未建立!"); messageList.Remove(message); return; } } //下发配置组帧 CasicSender casicSender = new CasicSender(null); byte[] frame = casicSender.buildConfigFrame(); int length = frame.Length + 7; byte[] config = new byte[length]; frame.CopyTo(config, 0); config[10] = 0x03;//通信方式 config[15] = 0x01;//Seq byte[] btPdu = new byte[2]; //2个字节 btPdu[0] = 0x0A; btPdu[1] = 0x92; btPdu.CopyTo(config, 13); byte[] btLens = new byte[2];//数据帧长度 byte[] btlens0 = BitConverter.GetBytes(length - 4); btLens[0] = btlens0[1]; btLens[1] = btlens0[0]; btLens.CopyTo(config, 2); byte[] sysTag = { StringUtil.YEAR_Delay, StringUtil.MON_Delay, StringUtil.DAY_Delay, StringUtil.HOR_Delay, StringUtil.MIN_Delay, StringUtil.SEC_Delay }; //byte[] sysTag = { 0x13, 0x07, 0x18, 0x0F, 0x00, 0x00 }; sysTag.CopyTo(config, 22); byte[] tag = { 0x30, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00 }; tag.CopyTo(config, frame.Length); foreach (var devcode in devCodes) { if (!digDataFinishMap.ContainsKey(devcode)) { digDataFinishMap.Add(devcode, false); } else { digDataFinishMap[devcode] = false; } byte[] btDevCode = CodeUtils.String2ByteArray(devcode); btDevCode.CopyTo(config, 4); Array.Copy(btDevCode, 4, config, 11, 2); //增加CRC校验 String strCrc = StringUtil.To16HexString(String.Format("{0:X}", (int)CodeUtils.CRC16_AD(config))); byte[] btcrc = { CodeUtils.String2Byte(strCrc.Substring(0, 2)), CodeUtils.String2Byte(strCrc.Substring(2, 2)) }; byte[] afcrc = new byte[config.Length + 2]; config.CopyTo(afcrc, 0); btcrc.CopyTo(afcrc, config.Length); //if (digWithSessionIdMap.ContainsKey(devcode)) //{ CasicSession s = this.GetSessionByID(digWithSessionIdMap[devcode]); if (s == null) { s.Logger.Info("设备[" + devcode + "]连接未建立!"); messageList.Remove(message); return; } s.Logger.Info("主动下发配置信息:" + BitConverter.ToString(afcrc).Replace("-", "")); s.Send(afcrc, 0, afcrc.Length); //} } string timestamp = BitConverter.ToString(sysTag, 0, sysTag.Length).Replace("-", ""); if (digGroupDevcodeMap.ContainsKey(timestamp)) { digGroupDevcodeMap[timestamp] = devCodes; } else { digGroupDevcodeMap.Add(timestamp, devCodes); } messageList.Remove(message); //Thread.Sleep(10000); //int num = 0;//调用接口计算的次数 //SetInterval(delegate //{ // if (DigDatas.calResult.Count > 5 || num > 7)//一轮循环计算结束 // { // timer.Enabled = false; // messageList.Remove(message);//移除 // DigDatas.digDataSeqMap.Clear(); // DigDatas.digDataValueMap.Clear(); // return; // } // Logger.Info("第" + num + "次计算"); // calculate(num++, devCodes); //}); }); } protected override void OnSessionClosed(CasicSession session, CloseReason reason) { if (session.HubAddr != null) { //设备离线,给第三方发信息 if (digWithSessionIdMap.ContainsKey(session.HubAddr)) { digWithSessionIdMap.Remove(session.HubAddr); } 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", session.HubAddr, new DataJson("DigOffline", -1, null, logtime), timeStamp)); if (Common.SendMessage(message)) { session.Logger.Info("往第三方发送数据:" + message); } else { session.Logger.Info("未连接上第三方服务器"); } } base.OnSessionClosed(session, reason); } //private void calculate(int num, String[] devCodess) //{ // //if(devCodes.Length < 5) // //{ // // Logger.Info("错误,不是5个设备编号"); // // return; // //} // string[] devCodes={"612019050001","612019050002","612019050003","612019050004","612019050005"}; // if (!DigDatas.digDataSeqMap.ContainsKey(devCodes[0]) || !DigDatas.digDataSeqMap.ContainsKey(devCodes[1]) || // !DigDatas.digDataSeqMap.ContainsKey(devCodes[2]) ||!DigDatas.digDataSeqMap.ContainsKey(devCodes[3]) || // !DigDatas.digDataSeqMap.ContainsKey(devCodes[4]) ) // { // Logger.Info("数据不全"); // return; // } // BitArray ba1 = new BitArray(10); // BitArray ba2 = new BitArray(10); // BitArray ba3 = new BitArray(10); // BitArray ba4 = new BitArray(10); // BitArray ba5 = new BitArray(10); // for (int i = 0; i < 10;i++ ) // { // ba1.Set(i, DigDatas.digDataSeqMap[devCodes[0]].Get(i + num * 10)); // ba2.Set(i, DigDatas.digDataSeqMap[devCodes[1]].Get(i + num * 10)); // ba3.Set(i, DigDatas.digDataSeqMap[devCodes[2]].Get(i + num * 10)); // ba4.Set(i, DigDatas.digDataSeqMap[devCodes[3]].Get(i + num * 10)); // ba5.Set(i, DigDatas.digDataSeqMap[devCodes[4]].Get(i + num * 10)); // } // ba1 = ba1.And(ba2).And(ba3).And(ba4).And(ba5); // int count = 0; // int start = 1; // for (int i = 0; i < ba1.Length;i++ ) // { // if (ba1.Get(i)) // { // count++; // } // else // { // count = 0; // start = i+1; // } // } // if(count >= 5) // { // Logger.Info("存在" + count + "个连续有效数据"); // float[] calData1 = new float[count * 7500]; // float[] calData2 = new float[count * 7500]; // float[] calData3 = new float[count * 7500]; // float[] calData4 = new float[count * 7500]; // float[] calData5 = new float[count * 7500]; // for (int i = 0; i < count;i++ ) // { // int seq = start + num * 10 + i; // DigDatas.digDataValueMap[devCodes[0] + seq].CopyTo(calData1, i * 7500); // DigDatas.digDataValueMap[devCodes[1] + seq].CopyTo(calData2, i * 7500); // DigDatas.digDataValueMap[devCodes[2] + seq].CopyTo(calData3, i * 7500); // DigDatas.digDataValueMap[devCodes[3] + seq].CopyTo(calData4, i * 7500); // DigDatas.digDataValueMap[devCodes[4] + seq].CopyTo(calData5, i * 7500); // } // Logger.Info("开始调用算法!"); // mExcaMonitor.excavationMonitoring exc = new mExcaMonitor.excavationMonitoring(); // Object[] outList = exc.mExcaMonitor(3, (MWNumericArray)calData1, (MWNumericArray)calData2, // (MWNumericArray)calData3, (MWNumericArray)calData4, (MWNumericArray)calData5); // Logger.Info("调用算法计算结果:" + outList[0] + "," + outList[1] + "," + outList[2]); // DigDatas.calResult.Add(outList); // if (DigDatas.calResult.Count >= 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 DigDatas.calResult) // { // if ((int)v[0] == 0) // { // no++; // } // else if ((int)v[0] == 1) // { // manually++; // manuallyDistance = (double)v[1]; // manuallyAngle = (double)v[2]; // } // else if ((int)v[0] == 2) // { // mechanically++; // mechanicallyDistance = (double)v[1]; // mechanicallyAngle = (double)v[2]; // } // else // { // } // } // 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)); // sendMessage("Dig", devCodes[0], -1, datasList); // timer.Enabled = false; // } // } // else // { // Logger.Info("不存在5个以上的连续数据!"); // } //} private void sendMessage(String devName, String devCode, int cell, List<DatasJson> datasList) { 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", devName, devCode, new DataJson(devName + "Data", cell, datasList, logtime), timeStamp)); if (Common.SendMessage(message)) { Logger.Info("往第三方发送数据:" + message); } else { Logger.Info("未连接上第三方服务器"); } } } catch (Exception ex) { Logger.Error("往第三方发送数据出错:" + ex.Message); } } /// <summary> /// 在指定时间周期重复执行指定的表达式 /// </summary> /// <param name="interval">事件之间经过的时间(以毫秒为单位)</param> /// <param name="action">要执行的表达式</param> public void SetInterval(Action<ElapsedEventArgs> action) { timer.Elapsed += delegate(object sender, System.Timers.ElapsedEventArgs e) { action(e); }; timer.Enabled = true; } } }