Newer
Older
SensorHub / SensorHub.Dig / DigServer.cs
root on 17 Sep 2021 15 KB first commit
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;
        }
    }
}