Browse Source

代码优化

yinyujing 4 years ago
parent
commit
4368d1596c
2 changed files with 363 additions and 230 deletions
  1. 291 172
      NB_IOT_TCP_HP_SOCKET/MainForm_TCP.cs
  2. 72 58
      NB_IOT_TCP_HP_SOCKET/WWKJUtil/RemoteTask.cs

+ 291 - 172
NB_IOT_TCP_HP_SOCKET/MainForm_TCP.cs

@@ -20,9 +20,12 @@ namespace NB_IOT_TCP_HP_SOCKET
         private static Thread _SendThread;// 处理上报抄表数据的线程
         private static Thread heartBeatThread;// 断开超时链接的线程
         private static Thread setParamThread;// 处理电池供电设备设参的线程
+        private static Thread insourcingThread;// 处理内包数据的线程
         private static Queue _SendConidQueue = Queue.Synchronized(new Queue()); // 存储历史记录数据的队列
-        private static Queue SendruralWaterQueue = Queue.Synchronized(new Queue()); // 农村供水预付费系统接口(发送阀门状态和阀门状态控制指令执行情况)
-        private static Thread SendruralWaterCommd ; // 农村供水预付费系统接口(发送阀门状态和阀门状态控制指令执行情况)
+        private static Queue insourcingQueue = Queue.Synchronized(new Queue()); // 内包待处理数据的队列
+        //private static Queue SendruralWaterQueue = Queue.Synchronized(new Queue()); // 农村供水预付费系统接口(发送阀门状态和阀门状态控制指令执行情况)
+        //private static Thread SendruralWaterCommd; // 农村供水预付费系统接口(发送阀门状态和阀门状态控制指令执行情况)
+
         // 实例化Timer类,设置间隔时间(毫秒) 市电供电MODBUS主动获取数据定时器
         private static System.Timers.Timer timer;
         private static bool isTimeRuning = false; // MODBUS定时器是否执行中
@@ -117,10 +120,13 @@ namespace NB_IOT_TCP_HP_SOCKET
                     // 设备类型 1:电池供电;2:市电供电MODBUS;3:电池供电和市电供电MODBUS
                     string deviceType = ConfigurationManager.AppSettings["IsHaveModBus"];
 
+                    // 启动处理数据进程 外包和内包两个
+                    StartOrResumeSendThread();
+                    StartOrResumeInsourcingThread();
+
                     if ("1".Equals(deviceType))
                     {
                         StartOrResumeSetParamThread(); // 启动电池供电设备设参线程
-                        StartCommdSendThread(); // 启动处理回复阀门状态和控制阀门结果的队列
                     }
                     else if ("2".Equals(deviceType))
                     {
@@ -130,7 +136,6 @@ namespace NB_IOT_TCP_HP_SOCKET
                     else if ("3".Equals(deviceType))
                     {
                         StartOrResumeSetParamThread(); // 启动电池供电设备设参线程
-                        StartCommdSendThread(); // 启动处理回复阀门状态和控制阀门结果的队列
                         timer = new System.Timers.Timer(Convert.ToInt32(ConfigurationManager.AppSettings["ModBusQueryInterval"]));
                         StartModBusSendTimer(); // 启动ModBus定时发送读取数据任务
                     }
@@ -413,11 +418,13 @@ namespace NB_IOT_TCP_HP_SOCKET
                                     AddMsg($" > [{clientInfo.ConnId},OnSend] -> {clientInfo.IpAddress}:{clientInfo.Port} {psp.SourceNumber} ({bytes.Length} bytes) 历史记录回应成功 \n {BitConverter.ToString(buffer3, 0, buffer3.Length).Replace("-", " ")} ", lbReceiveData);
                                     server.Send(clientInfo.ConnId, buffer3, buffer3.Length);// 发送数据
                                 }
+
+                                StartOrResumeSendThread();
                             }
                         }
                     }
 
-                    StartOrResumeSendThread(); // 启动处理数据进程
+
                 }
                 else
                 {
@@ -527,7 +534,7 @@ namespace NB_IOT_TCP_HP_SOCKET
         }
 
         /// <summary>
-        /// 启动处理上报抄表数据的队列
+        /// 启动处理上报外包数据的队列
         /// </summary>
         private void StartOrResumeSendThread()
         {
@@ -549,22 +556,22 @@ namespace NB_IOT_TCP_HP_SOCKET
         }
 
         /// <summary>
-        /// 启动处理回复阀门状态和控制阀门结果的队列
+        /// 启动处理内包数据的队列
         /// </summary>
-        private void StartCommdSendThread()
+        private void StartOrResumeInsourcingThread()
         {
-            if (SendruralWaterCommd == null)
+            if (insourcingThread == null)
             {
-                SendruralWaterCommd = new Thread(new ThreadStart(CommdProcess));
+                insourcingThread = new Thread(new ThreadStart(InsourcingProcess));
             }
-            switch (SendruralWaterCommd.ThreadState)
+            switch (insourcingThread.ThreadState)
             {
                 case ThreadState.Stopped:
                 case ThreadState.Unstarted://未启动
-                    SendruralWaterCommd.Start();
+                    insourcingThread.Start();
                     break;
                 case ThreadState.Suspended://挂起
-                    SendruralWaterCommd.Resume();
+                    insourcingThread.Resume();
                     break;
 
             }
@@ -595,6 +602,12 @@ namespace NB_IOT_TCP_HP_SOCKET
                             if (allConnIds == null || Array.IndexOf(allConnIds, connId) == -1)
                             {
                                 disconnectId.Add(conn.Key);
+
+                                // 删除设参任务列表
+                                if (sendTaskList.ContainsKey(connId))
+                                {
+                                    sendTaskList.Remove(connId);
+                                }
                                 continue;
                             }
                             uint SilenceTime = 0;
@@ -603,6 +616,11 @@ namespace NB_IOT_TCP_HP_SOCKET
                                 if (SilenceTime > Convert.ToInt32(ConfigurationManager.AppSettings["ConnectionTimeOut"]))
                                 {
                                     server.Disconnect(connId);
+                                    // 删除设参任务列表
+                                    if (sendTaskList.ContainsKey(connId))
+                                    {
+                                        sendTaskList.Remove(connId);
+                                    }
                                     disconnectId.Add(conn.Key);
                                 }
                             }
@@ -712,7 +730,7 @@ namespace NB_IOT_TCP_HP_SOCKET
                                             modbusArr[Modbus.FunctionCode.F02.ToString()] = modbus;
                                         }
                                     }
-                                    
+
                                 }
                             }
                             if (sendFlag)
@@ -785,9 +803,15 @@ namespace NB_IOT_TCP_HP_SOCKET
                             }
                         }
 
+                        InsourcingData insourcingData = new InsourcingData();
+                        insourcingData.Data = psp.Data;
+                        insourcingData.ConnId = clientInfo.ConnId;
+                        insourcingData.DT = dt;
+                        insourcingData.AgreementParam = agreementParam;
                         // 电池供电类设备
                         if (agreement.Equals("CD_CellMonitor"))
                         {
+                            insourcingData.Type = "CD_CellMonitor";
                             CellMonitor cm = new CellMonitor();
                             // 抄表数据进行解包操作,解包后抄表数据存入cm.Record
                             ResMsg msg = ProtocolAnalysisTools.UnInnerPack(cm, psp.Data);
@@ -797,13 +821,13 @@ namespace NB_IOT_TCP_HP_SOCKET
                                 // 阀门控制回包
                                 if (msg.Message == "新参数包")
                                 {
+                                    insourcingData.DataType = "0";
                                     //1.解析参数包
                                     CJT188 cjt = new CJT188();
                                     ResMsg resMsg = CJT188.UnPack(cjt, psp.Data);
                                     //2.判断是否是阀门状态上报功能
                                     if (resMsg.Result)
                                     {
-
                                         if (cjt._cmdType == ParamCmdType.AutoReportValveState)
                                         {
                                             #region
@@ -828,57 +852,10 @@ namespace NB_IOT_TCP_HP_SOCKET
                                                     }
                                                 }
                                             }
-                                            
-                                            string sql = "";
-                                            //3.如果是阀门状态上报功能需要判断阀门状态,如果跟设置的阀门状态相同,则更新状态,设置阀门任务成功
-                                            if (cjt.Data.Length >= 1)//数据长度正确
-                                            {
-                                                string valveState = "";
-                                                string backValveSate = "";
-                                                switch (cjt.Data[0])
-                                                {
-                                                    case 0x55:
-                                                        valveState = "开阀";
-                                                        backValveSate = "OPEN";
-                                                        break;
-                                                    case 0x99:
-                                                        valveState = "关阀";
-                                                        backValveSate = "CLOSE";
-                                                        break;
-                                                    case 0xFF:
-                                                        valveState = "异常";
-                                                        backValveSate = "ERROR";
-                                                        break;
-                                                }
-                                                sql = "select Top 1 ID,isnull(阀门设置状态,'') as valveSetState,isnull(阀门状态,'') as valveState,isnull(考核表编码,'') as devCode from 设备信息 where 通讯设备ID=" + dt.Rows[0]["transId"].ToString();
-                                                DataTable dataTable = DBHelper.ExecuteDataTable(sql, CommandType.Text, null);
-                                                int num = dataTable.Rows.Count;
-                                                if (num > 0)//存在一条记录
-                                                {
-                                                    string devCode = dataTable.Rows[0]["devCode"].ToString();
-                                                    string devId = dataTable.Rows[0]["ID"].ToString();
-                                                    //回调预付费接口
-                                                    if (!string.IsNullOrEmpty(devCode) && !string.IsNullOrEmpty(backValveSate) && !string.IsNullOrEmpty(ruralWaterURL))
-                                                    {
-                                                        try
-                                                        {
-                                                            SendInfo sendInfo = new SendInfo();
-
-                                                            sendInfo.URL = ruralWaterURL;
-                                                            sendInfo.Params = "otherUniqueIdentification=" + devCode + "&status=" + backValveSate;
-                                                            SendruralWaterQueue.Enqueue(sendInfo);
-                                                        }
-                                                        catch (Exception ex)
-                                                        {
-                                                        }
-
-                                                    }
-                                                    //1.更新阀门状态
-                                                    sql = "update 设备信息 Set 阀门状态='" + valveState + "',阀门状态更新时间=getdate() Where ID=" + devId;
-                                                    DBHelper.Query(sql);
 
-                                                }
-                                            }
+                                            insourcingData.CJT188 = cjt;
+                                            // 加入内包数据处理队列
+                                            insourcingQueue.Enqueue(insourcingData);
                                             #endregion
                                         }
                                         else if (cjt._cmdType == ParamCmdType.ReadWorkMode)
@@ -910,6 +887,10 @@ namespace NB_IOT_TCP_HP_SOCKET
                                             // 写参返回指令
                                             else if (cjt._controlCode == 0xA4)
                                             {
+                                                insourcingData.CJT188 = cjt;
+                                                // 加入内包数据处理队列
+                                                insourcingQueue.Enqueue(insourcingData);
+
                                                 List<Task> taskList = new List<Task>();
                                                 if (sendTaskList.ContainsKey(clientInfo.ConnId))
                                                 {
@@ -922,23 +903,6 @@ namespace NB_IOT_TCP_HP_SOCKET
 
                                                     if (psp.Data.Length >= 6)
                                                     {
-                                                        task.TaskState = "完成";
-                                                        task.ReceiveCode = new byte[psp.Data.Length];
-                                                        psp.Data.CopyTo(task.ReceiveCode, 0);
-                                                        if (task.TaskType == 0) 
-                                                        {
-                                                            task.OutPutFile(task.FilePath, true);
-                                                            task.DeleteFile(task.FilePath);
-                                                        }
-                                                        else if (task.TaskType == 1)
-                                                        {
-                                                            SendInfo sendInfo = ProtocolAnalysisTools.UpdateCommdFinished(task);
-                                                            if (sendInfo != null)
-                                                            {
-                                                                SendruralWaterQueue.Enqueue(sendInfo);
-                                                            }
-                                                        }
-                                                        taskList.RemoveAt(0);
                                                         clientInfo.ParamRetrunStatus = 1;
                                                         server.SetExtra(clientInfo.ConnId, clientInfo);
                                                     }
@@ -956,6 +920,8 @@ namespace NB_IOT_TCP_HP_SOCKET
                             {
                                 AddMsg($" > [{clientInfo.ConnId},OnReceive] -> {clientInfo.IpAddress}:{clientInfo.Port} {sourceNumber} ({psp.Data.Length} bytes) CD_CellMonitor内包解包成功 \n {BitConverter.ToString(psp.Data, 0, psp.Data.Length).Replace("-", " ")}", lbReceiveData);
 
+                                insourcingData.DataType = "1";
+
                                 // 如果是最后一包则发送校时指令
                                 if (cm.IsEnd)
                                 {
@@ -966,52 +932,15 @@ namespace NB_IOT_TCP_HP_SOCKET
                                     server.SetExtra(clientInfo.ConnId, clientInfo);
                                 }
 
-                                List<HistoryRecord> list = new List<HistoryRecord>();
-
-                                // 获取配置的上报抄表数据的数据信息CONF/DataCellConfig.xml中CD_CellMonitor节点,根据传输设备中的设备协议参数关联取那些字段
-                                CellMonitorDeviceType cellMonitorDeviceType = new CellMonitorDeviceType(agreementParam);
-                                // 模拟量
-                                Dictionary<string, CommOption> _analogData = cellMonitorDeviceType.GetAnalogCommOptions();
-                                // 开关量
-                                Dictionary<string, CommOption> _switchData = cellMonitorDeviceType.GetSwitchCommOptions();
-
-                                for (int i = 0; i < cm.Record.Count; i++)
-                                {
-                                    List<CommData> list2 = new List<CommData>();
-
-                                    #region 将数据与配置的字段进行关联
-                                    foreach (MonitorValue value2 in cm.Record[i].Analog)
-                                    {
-                                        if (_analogData.ContainsKey(value2.Name))
-                                        {
-                                            _analogData[value2.Name].ExplainData(value2.Value);
-                                        }
-                                    }
-                                    foreach (MonitorValue value3 in cm.Record[i].Switch)
-                                    {
-                                        if (_switchData.ContainsKey(value3.Name))
-                                        {
-                                            _switchData[value3.Name].ExplainData(value3.Value);
-                                        }
-                                    }
-                                    #endregion
-
-                                    // 将数据进行封装,一条数据可能对于多个设备的数据,通过[设备信息表]中设备的[用户站参数]与CONF\UserStation_Config.xml进行匹配拆分
-                                    List<HistoryRecord> item = this.UpdateHistoryData(cm.Record[i].PickTime, cm, dt, _analogData, _switchData);
-                                    if (item != null && item.Count > 0)
-                                    {
-                                        list.AddRange(item);
-                                    }
-
-                                }
-
-                                // 保存抄表数据
-                                ProtocolAnalysisTools.SaveRecord(list);
+                                insourcingData.CellMonitor = cm;
+                                // 加入内包数据处理队列
+                                insourcingQueue.Enqueue(insourcingData);
                             }
                         }
                         // MODBUS类设备
                         else if (agreement.Equals("CD_PSController"))
                         {
+                            insourcingData.Type = "CD_PSController";
                             #region 根据上报数据的功能码区分获取对应的下发指令的MODBUS对象
                             Modbus.FunctionCode code = (Modbus.FunctionCode)psp.Data[1];
                             bool unPackFlag = false;
@@ -1021,7 +950,7 @@ namespace NB_IOT_TCP_HP_SOCKET
                             foreach (KeyValuePair<string, string> keyValuePair in trandevice)
                             {
                                 // 内包进行解包,解包后的数据存入modbus.UpDataArea
-                                ResMsg msg ;
+                                ResMsg msg;
                                 if (code == Modbus.FunctionCode.F10)
                                 {
                                     modbus = sendSetParamComm;
@@ -1041,7 +970,7 @@ namespace NB_IOT_TCP_HP_SOCKET
                                     }
                                     modbus = sendGetParamComm[maxKey];
                                     msg = Modbus.UnPack(psp.Data, modbus);
-                                    
+
                                     if (msg.Result)
                                     {
                                         foreach (byte rs in modbus.UpDataArea)
@@ -1056,9 +985,7 @@ namespace NB_IOT_TCP_HP_SOCKET
                                     modbus = sendComm[keyValuePair.Key][code.ToString()];
                                     msg = Modbus.UnPack(psp.Data, modbus);
                                 }
-                                
-                                
-                                
+
                                 if (msg.Result)
                                 {
                                     unPackFlag = true;
@@ -1078,7 +1005,7 @@ namespace NB_IOT_TCP_HP_SOCKET
                             }
                             else
                             {
-                                
+
                                 AddMsg($" > [{clientInfo.ConnId},OnReceive] -> {clientInfo.IpAddress}:{clientInfo.Port} {sourceNumber} ({psp.Data.Length} bytes) CD_PSController内包解包成功,数据类型{code} \n {BitConverter.ToString(modbus.UpDataArea, 0, modbus.UpDataArea.Length).Replace("-", " ")}", lbReceiveData);
                                 // 设参回包数据
                                 if (code == Modbus.FunctionCode.F10)
@@ -1089,40 +1016,28 @@ namespace NB_IOT_TCP_HP_SOCKET
                                 {
                                     if (sendGetParamComm.Count == 0)
                                     {
-                                        // 解析参数数据包并展示参数信息
-                                        DeviceControlForm.showParamData(paramByte.ToArray());
+                                        
+                                        insourcingData.DataType = "0";
+                                        insourcingData.Data = paramByte.ToArray();
+                                        // 加入内包数据处理队列
+                                        insourcingQueue.Enqueue(insourcingData);
                                         paramByte.Clear();
                                     }
                                 }
                                 // 抄表数据
                                 else
                                 {
-                                    // 获取配置的上报抄表数据的数据信息CONF/DataCellConfig.xml中CD_PSController节点,根据传输设备中的设备协议参数关联取那些字段
-                                    ModBusDeviceType modBusDeviceType = new ModBusDeviceType(agreementParam);
-                                    // 模拟量
-                                    Dictionary<string, CommOption> _analogData = modBusDeviceType.GetAnalogCommOptions();
-                                    // 开关量
-                                    Dictionary<string, CommOption> _switchData = modBusDeviceType.GetSwitchCommOptions();
+                                    modbus.FunCode = code;
+                                    insourcingData.DataType = "1";
+                                    insourcingData.Recordtime = clientInfo.ReceiveTime;
 
-                                    #region 将数据与配置的字段进行关联
-                                    if (code == Modbus.FunctionCode.F04)
-                                    {
-                                        ProtocolAnalysisTools.OrganizeAnalogData(modbus.UpDataArea, _analogData, Convert.ToInt32(modBusDeviceType.AnalogStartAddress));
-                                    }
-                                    else if (code == Modbus.FunctionCode.F02)
-                                    {
-                                        ProtocolAnalysisTools.OrganizeSwitchData(modbus.UpDataArea, _switchData, Convert.ToInt32(modBusDeviceType.SwitchStartAddress));
-                                    }
-                                    #endregion
-
-                                    // 将数据进行封装,一条数据可能对于多个设备的数据,通过[设备信息表]中设备的[用户站参数]与CONF\UserStation_Config.xml进行匹配拆分
-                                    List<HistoryRecord> item = this.UpdateHistoryData(clientInfo.ReceiveTime, null, dt, _analogData, _switchData);
-
-                                    // 保存抄表数据
-                                    ProtocolAnalysisTools.SaveRecord(item);
+                                    insourcingData.Modbus = modbus;
+                                    // 加入内包数据处理队列
+                                    insourcingQueue.Enqueue(insourcingData);
                                 }
                             }
                         }
+                        StartOrResumeInsourcingThread();
                     }
                 }
                 catch (Exception ex)
@@ -1133,30 +1048,218 @@ namespace NB_IOT_TCP_HP_SOCKET
         }
 
         /// <summary>
-        /// 通知农村供水营业收费系统接口阀门处理接口和状态
+        /// 处理内包数据
         /// </summary>
-        private void CommdProcess()
+        private void InsourcingProcess()
         {
             while (true)
             {
                 try
                 {
-                    if (SendruralWaterQueue.Count == 0)//队列数据为空的时候
+                    if (insourcingQueue.Count == 0)//队列数据为空的时候
                     {
-                        SendruralWaterCommd.Suspend();//挂起线程
+                        insourcingThread.Suspend();//挂起线程
                     }
                     else
                     {
-                        SendInfo sendInfo = (SendInfo)SendruralWaterQueue.Dequeue();
-                        ProtocolAnalysisTools.postSend(sendInfo.URL, sendInfo.Params);
+                        InsourcingData insourcingData = (InsourcingData)insourcingQueue.Dequeue();
+
+                        DataTable dt = insourcingData.DT;
+                        if ("CD_CellMonitor".Equals(insourcingData.Type))
+                        {
+                            // 参数包
+                            if ("0".Equals(insourcingData.DataType))
+                            {
+
+                                CJT188 cjt = insourcingData.CJT188;
+                                if (cjt._cmdType == ParamCmdType.AutoReportValveState)
+                                {
+                                    string sql = "";
+                                    // 如果是阀门状态上报功能需要判断阀门状态,如果跟设置的阀门状态相同,则更新状态,设置阀门任务成功
+                                    if (cjt.Data.Length >= 1)//数据长度正确
+                                    {
+                                        string valveState = "";
+                                        string backValveSate = "";
+                                        switch (cjt.Data[0])
+                                        {
+                                            case 0x55:
+                                                valveState = "开阀";
+                                                backValveSate = "OPEN";
+                                                break;
+                                            case 0x99:
+                                                valveState = "关阀";
+                                                backValveSate = "CLOSE";
+                                                break;
+                                            case 0xFF:
+                                                valveState = "异常";
+                                                backValveSate = "ERROR";
+                                                break;
+                                        }
+                                        sql = "select Top 1 ID,isnull(阀门设置状态,'') as valveSetState,isnull(阀门状态,'') as valveState,isnull(考核表编码,'') as devCode from 设备信息 where 通讯设备ID=" + dt.Rows[0]["transId"].ToString();
+                                        DataTable dataTable = DBHelper.ExecuteDataTable(sql, CommandType.Text, null);
+                                        int num = dataTable.Rows.Count;
+                                        if (num > 0)//存在一条记录
+                                        {
+                                            string devCode = dataTable.Rows[0]["devCode"].ToString();
+                                            string devId = dataTable.Rows[0]["ID"].ToString();
+
+                                            // 更新阀门状态
+                                            sql = "update 设备信息 Set 阀门状态='" + valveState + "',阀门状态更新时间=getdate() Where ID=" + devId;
+                                            DBHelper.Query(sql);
+
+                                            // 如果配置了第三方阀门状态同步接口,则回调接口
+                                            if (!string.IsNullOrEmpty(devCode) && !string.IsNullOrEmpty(backValveSate) && !string.IsNullOrEmpty(ruralWaterURL))
+                                            {
+                                                try
+                                                {
+                                                    ProtocolAnalysisTools.postSend(ruralWaterURL, "otherUniqueIdentification=" + devCode + "&status=" + backValveSate);
+                                                }
+                                                catch (Exception ex)
+                                                {
+                                                }
+
+                                            }
+
+                                        }
+                                    }
+                                }
+                                else if (cjt._cmdType == ParamCmdType.ReadWorkMode)
+                                {
+                                    // 设参参返回指令
+                                    if (cjt._controlCode == 0xA4)
+                                    {
+                                        List<Task> taskList = new List<Task>();
+                                        if (sendTaskList.ContainsKey(insourcingData.ConnId))
+                                        {
+                                            taskList = sendTaskList[insourcingData.ConnId];
+                                        }
+
+                                        if (taskList.Count > 0)
+                                        {
+                                            Task task = taskList[0];
+
+                                            if (insourcingData.Data.Length >= 6)
+                                            {
+                                                taskList.RemoveAt(0);
+
+                                                task.TaskState = "完成";
+                                                task.ReceiveCode = new byte[insourcingData.Data.Length];
+                                                insourcingData.Data.CopyTo(task.ReceiveCode, 0);
+                                                // 文件格式删除文件并记录返回结果
+                                                if (task.TaskType == 0)
+                                                {
+                                                    task.OutPutFile(task.FilePath, true);
+                                                    task.DeleteFile(task.FilePath);
+                                                }
+                                                // 数据库表记录格式更新状态并记录返回结果
+                                                else if (task.TaskType == 1)
+                                                {
+                                                    SendInfo sendInfo = ProtocolAnalysisTools.UpdateCommdFinished(task);
+                                                    // 如果是第三方控制指令则给第三方返回结果
+                                                    if (sendInfo != null)
+                                                    {
+                                                        ProtocolAnalysisTools.postSend(sendInfo.URL, sendInfo.Params);
+                                                    }
+                                                }
+
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                            // 抄表数据包
+                            else if ("1".Equals(insourcingData.DataType))
+                            {
+                                List<HistoryRecord> list = new List<HistoryRecord>();
+
+                                // 获取配置的上报抄表数据的数据信息CONF/DataCellConfig.xml中CD_CellMonitor节点,根据传输设备中的设备协议参数关联取那些字段
+                                CellMonitorDeviceType cellMonitorDeviceType = new CellMonitorDeviceType(insourcingData.AgreementParam);
+                                // 模拟量
+                                Dictionary<string, CommOption> _analogData = cellMonitorDeviceType.GetAnalogCommOptions();
+                                // 开关量
+                                Dictionary<string, CommOption> _switchData = cellMonitorDeviceType.GetSwitchCommOptions();
+
+                                CellMonitor cm = insourcingData.CellMonitor;
+
+                                for (int i = 0; i < cm.Record.Count; i++)
+                                {
+                                    List<CommData> list2 = new List<CommData>();
+
+                                    #region 将数据与配置的字段进行关联
+                                    foreach (MonitorValue value2 in cm.Record[i].Analog)
+                                    {
+                                        if (_analogData.ContainsKey(value2.Name))
+                                        {
+                                            _analogData[value2.Name].ExplainData(value2.Value);
+                                        }
+                                    }
+                                    foreach (MonitorValue value3 in cm.Record[i].Switch)
+                                    {
+                                        if (_switchData.ContainsKey(value3.Name))
+                                        {
+                                            _switchData[value3.Name].ExplainData(value3.Value);
+                                        }
+                                    }
+                                    #endregion
+
+                                    // 将数据进行封装,一条数据可能对于多个设备的数据,通过[设备信息表]中设备的[用户站参数]与CONF\UserStation_Config.xml进行匹配拆分
+                                    List<HistoryRecord> item = this.UpdateHistoryData(cm.Record[i].PickTime, cm, dt, _analogData, _switchData);
+                                    if (item != null && item.Count > 0)
+                                    {
+                                        list.AddRange(item);
+                                    }
+
+                                }
+
+                                // 保存抄表数据
+                                ProtocolAnalysisTools.SaveRecord(list);
+                            }
+                        }
+
+                        else if ("CD_PSController".Equals(insourcingData.Type))
+                        {
+                            // 读参返回数据
+                            if ("1".Equals(insourcingData.DataType))
+                            {
+                                // 解析参数数据包并展示参数信息
+                                DeviceControlForm.showParamData(insourcingData.Data);
+                            }
+                            // 上报抄表数据
+                            else if ("1".Equals(insourcingData.DataType))
+                            {
+                                Modbus modbus = insourcingData.Modbus;
+                                // 获取配置的上报抄表数据的数据信息CONF/DataCellConfig.xml中CD_PSController节点,根据传输设备中的设备协议参数关联取那些字段
+                                ModBusDeviceType modBusDeviceType = new ModBusDeviceType(insourcingData.AgreementParam);
+                                // 模拟量
+                                Dictionary<string, CommOption> _analogData = modBusDeviceType.GetAnalogCommOptions();
+                                // 开关量
+                                Dictionary<string, CommOption> _switchData = modBusDeviceType.GetSwitchCommOptions();
+
+                                #region 将数据与配置的字段进行关联
+                                if (modbus.FunCode == Modbus.FunctionCode.F04)
+                                {
+                                    ProtocolAnalysisTools.OrganizeAnalogData(modbus.UpDataArea, _analogData, Convert.ToInt32(modBusDeviceType.AnalogStartAddress));
+                                }
+                                else if (modbus.FunCode == Modbus.FunctionCode.F02)
+                                {
+                                    ProtocolAnalysisTools.OrganizeSwitchData(modbus.UpDataArea, _switchData, Convert.ToInt32(modBusDeviceType.SwitchStartAddress));
+                                }
+                                #endregion
+
+                                // 将数据进行封装,一条数据可能对于多个设备的数据,通过[设备信息表]中设备的[用户站参数]与CONF\UserStation_Config.xml进行匹配拆分
+                                List<HistoryRecord> item = this.UpdateHistoryData(insourcingData.Recordtime, null, dt, _analogData, _switchData);
+
+                                // 保存抄表数据
+                                ProtocolAnalysisTools.SaveRecord(item);
+                            }
+                        }
+
                     }
                 }
-                catch(Exception ex)
+                catch (Exception ex)
                 {
                 }
             }
-                    
-        
         }
 
         /// <summary>
@@ -1321,7 +1424,7 @@ namespace NB_IOT_TCP_HP_SOCKET
             {
                 TimeSpan span = (TimeSpan)(DateTime.Now - paramSendTime);
                 // 未发送;已发送&&发送次数小于配置的最大发送次数&&两次间隔时间大于配置的间隔时间
-                if (paramSendStatus == 0 || paramSendStatus == 1 && paramSendNum < paramSendNumTmp && span.TotalSeconds >= paramSendInterval)
+                if (clientInfo.ParamRetrunStatus == 0 && (paramSendStatus == 0 || (paramSendStatus == 1 && paramSendNum < paramSendNumTmp && span.TotalSeconds >= paramSendInterval)))
                 {
                     PSProtocol protocol2 = new PSProtocol(clientInfo.DestNumber, clientInfo.SourceNumber, task.SendCode);
                     protocol2.Type = FrameType.Battery_Param;
@@ -1347,11 +1450,11 @@ namespace NB_IOT_TCP_HP_SOCKET
                             }
                             else
                             {
-                                List<Task> list = new List<Task> ();
+                                List<Task> list = new List<Task>();
                                 list.Add(task);
                                 sendTaskList[clientInfo.ConnId] = list;
                             }
-                            
+
                         }
                         else
                         {
@@ -1366,7 +1469,7 @@ namespace NB_IOT_TCP_HP_SOCKET
                         server.SetExtra(clientInfo.ConnId, clientInfo);
                     }
                 }
-                else if (paramSendNum >= paramSendNumTmp)
+                else if (clientInfo.ParamRetrunStatus == 1 || paramSendNum >= paramSendNumTmp)
                 {
                     // 校时关机
                     TimingShutDown(clientInfo);
@@ -1380,10 +1483,10 @@ namespace NB_IOT_TCP_HP_SOCKET
                     else if (task.TaskType == 1)
                     {
                         SendInfo sendInfo = ProtocolAnalysisTools.UpdateCommdTimeOut(task);
-                        if (sendInfo != null)
-                        {
-                            SendruralWaterQueue.Enqueue(sendInfo);
-                        }
+                        //if (sendInfo != null)
+                        //{
+                        //    SendruralWaterQueue.Enqueue(sendInfo);
+                        //}
                     }
                 }
             }
@@ -1407,7 +1510,7 @@ namespace NB_IOT_TCP_HP_SOCKET
             {
 
                 AddMsg($" > [{clientInfo.ConnId},OnSend] -> {clientInfo.IpAddress}:{clientInfo.Port} {clientInfo.SourceNumber} ({buffer3.Length} bytes) CD_CellMonitor最后一包校时 \n {BitConverter.ToString(buffer3, 0, buffer3.Length).Replace("-", " ")} ", lbReceiveData);
-                if(server.Send(clientInfo.ConnId, buffer3, buffer3.Length)) // 发送数据
+                if (server.Send(clientInfo.ConnId, buffer3, buffer3.Length)) // 发送数据
                 {
                     clientInfo.IsEnd = false;
                     clientInfo.ParamSendNum = 0;
@@ -1431,7 +1534,7 @@ namespace NB_IOT_TCP_HP_SOCKET
         public IntPtr ConnId { get; set; } // 链接ID
         public IntPtr NewConnId { get; set; }
         public string IpAddress { get; set; } // 客户端IP
-        public ushort Port { get; set;  }// 客户端端口号
+        public ushort Port { get; set; }// 客户端端口号
         public PSProtocol pSProtocol { get; set; }
         public string DestNumber { get; set; } // 目标地址
         public string SourceNumber { get; set; } // 源地址
@@ -1446,6 +1549,22 @@ namespace NB_IOT_TCP_HP_SOCKET
         #endregion
     }
 
+    public class InsourcingData
+    {
+        public IntPtr ConnId { get; set; } // 链接ID
+        public string Type { get; set; } // 设备类型
+        public CellMonitor CellMonitor { get; set; }
+        public CJT188 CJT188 { get; set; }
+        public Modbus Modbus { get; set; }
+        public byte[] Data { get; set; } // 内包数据
+        public string DataType { get; set; } // 数据类型 0:参数 1:抄表数据
+        public string AgreementParam { get; set; } // 设备协议参数
+        public DateTime Recordtime { get; set; } // 数据接收时间
+        public DataTable DT { get; set; } // 传输设备对应的设备信息及通讯设备信息
+
+    }
+
+
     public class SendInfo
     {
         public string URL { get; set; } 

+ 72 - 58
NB_IOT_TCP_HP_SOCKET/WWKJUtil/RemoteTask.cs

@@ -40,53 +40,60 @@ namespace NB_IOT_TCP_HP_SOCKET.WWKJUtil
         /// <param name="name"></param>
         public void GetRemoteTaskList(string devId, string name)
         {
-            if (!Directory.Exists(this.paramPath))
-            {
-                return;
-            }
-            // 获取所有的设参文件夹
-            string[] directories = Directory.GetDirectories(this.paramPath);
-
-            if (directories.Length == 0)
+            try
             {
-                return;
-            }
+                if (!Directory.Exists(this.paramPath))
+                {
+                    return;
+                }
+                // 获取所有的设参文件夹
+                string[] directories = Directory.GetDirectories(this.paramPath);
 
-            string FilePath = "";
-            // 如果存在读取所有的设参文件内容
-            foreach (string str in directories)
-            {
-                if (str.Contains(devId + "_" + name + "_"))
+                if (directories.Length == 0)
                 {
-                    FilePath = str;
-                    break;
+                    return;
                 }
-            }
-            if (FilePath == "")
-            {
-                return;
-            }
 
-            DirectoryInfo info = new DirectoryInfo(FilePath);
-            if (info.Exists && ((info.GetDirectories("接收").Length != 0) && (info.GetDirectories("发送").Length != 0)))
-            {
-                FileInfo[] files = new DirectoryInfo(FilePath + @"\发送").GetFiles();
-                // 如果没有文件直接返回
-                if (files == null || files.Length == 0)
+                string FilePath = "";
+                // 如果存在读取所有的设参文件内容
+                foreach (string str in directories)
+                {
+                    if (str.Contains(devId + "_" + name + "_"))
+                    {
+                        FilePath = str;
+                        break;
+                    }
+                }
+                if (FilePath == "")
                 {
                     return;
                 }
-                // 将文件按创建时间进行排序
-                Array.Sort(files,new MyDateSorter());
-                foreach (FileInfo info3 in files)
+
+                DirectoryInfo info = new DirectoryInfo(FilePath);
+                if (info.Exists && ((info.GetDirectories("接收").Length != 0) && (info.GetDirectories("发送").Length != 0)))
                 {
-                    Task item = this.InitTask(info3.Name);
-                    item.FilePath = FilePath;
-                    this.Tasklist.Add(item);
-                    // 只取第一条处理后直接跳出循环
-                    break;
+                    FileInfo[] files = new DirectoryInfo(FilePath + @"\发送").GetFiles();
+                    // 如果没有文件直接返回
+                    if (files == null || files.Length == 0)
+                    {
+                        return;
+                    }
+                    // 将文件按创建时间进行排序
+                    Array.Sort(files, new MyDateSorter());
+                    foreach (FileInfo info3 in files)
+                    {
+                        Task item = this.InitTask(info3.Name);
+                        item.FilePath = FilePath;
+                        this.Tasklist.Add(item);
+                        // 只取第一条处理后直接跳出循环
+                        break;
+                    }
                 }
             }
+            catch (Exception)
+            {
+                LogUtil.WriteLog("获取文件类型指令报错,通讯设备ID:" + devId);
+            }
         }
 
         /// <summary>
@@ -95,31 +102,38 @@ namespace NB_IOT_TCP_HP_SOCKET.WWKJUtil
         /// <param name="devID"></param>
         public void GetDataBaseRemoteTaskList(string devID)
         {
-            // 1.获取正常任务
-            string sql = "select  top 1 * from TaskList a left join CommandList b on a.TaskID=b.TaskID where b.Type <> '工作模式' and a.State != '完成' and b.CtrlValveNum < " + ConfigurationManager.AppSettings["ParamSendMaxNum"] + " and a.PreDevID = " + devID + " Order By a.TaskID";
-            DataTable dataTable = DBHelper.ExecuteDataTable(sql, CommandType.Text, null);
-            int num = dataTable.Rows.Count;
-            for (int i = 0; i < num; i++)
-            {
-                DataRow row = dataTable.Rows[i];
-                Task item = this.InitDataBaseTask(row);
-                this.Tasklist.Add(item);
-            }
-            if (this.Tasklist.Count > 0)
+            try
             {
-                return;
+                // 1.获取正常任务
+                string sql = "select  top 1 * from TaskList a left join CommandList b on a.TaskID=b.TaskID where b.Type <> '工作模式' and a.State != '完成' and b.CtrlValveNum < " + ConfigurationManager.AppSettings["ParamSendMaxNum"] + " and a.PreDevID = " + devID + " Order By a.TaskID";
+                DataTable dataTable = DBHelper.ExecuteDataTable(sql, CommandType.Text, null);
+                int num = dataTable.Rows.Count;
+                for (int i = 0; i < num; i++)
+                {
+                    DataRow row = dataTable.Rows[i];
+                    Task item = this.InitDataBaseTask(row);
+                    this.Tasklist.Add(item);
+                }
+                if (this.Tasklist.Count > 0)
+                {
+                    return;
+                }
+                //2.获取阀门任务
+                string vsql = "select * from (select Top 1 a.TaskID,a.PreDevID,GPRSNumber,b.Type,a.Guid,a.returnUrl,a.ReplayStatus,b.SendCode,b.CtrlValveNum,b.State from TaskList a left join CommandList b on a.TaskID=b.TaskID where b.Type='工作模式' and a.PreDevID = " + devID + " Order By a.TaskID desc) Tab  where CtrlValveNum < " + ConfigurationManager.AppSettings["ParamSendMaxNum"] + " and State != '完成'";
+                //mSql = DBManager.CurrentConnectString;
+                DataTable vdataTable = DBHelper.ExecuteDataTable(vsql, CommandType.Text, null);
+                int vnum = vdataTable.Rows.Count;
+                //vn = vnum;
+                for (int i = 0; i < vnum; i++)
+                {
+                    DataRow row = vdataTable.Rows[i];
+                    Task item = this.InitDataBaseTask(row);
+                    this.Tasklist.Add(item);
+                }
             }
-            //2.获取阀门任务
-            string vsql = "select * from (select Top 1 a.TaskID,a.PreDevID,GPRSNumber,b.Type,a.Guid,a.returnUrl,a.ReplayStatus,b.SendCode,b.CtrlValveNum,b.State from TaskList a left join CommandList b on a.TaskID=b.TaskID where b.Type='工作模式' and a.PreDevID = " + devID + " Order By a.TaskID desc) Tab  where CtrlValveNum < " + ConfigurationManager.AppSettings["ParamSendMaxNum"] + " and State != '完成'";
-            //mSql = DBManager.CurrentConnectString;
-            DataTable vdataTable = DBHelper.ExecuteDataTable(vsql, CommandType.Text, null);
-            int vnum = vdataTable.Rows.Count;
-            //vn = vnum;
-            for (int i = 0; i < vnum; i++)
+            catch (Exception)
             {
-                DataRow row = vdataTable.Rows[i];
-                Task item = this.InitDataBaseTask(row);
-                this.Tasklist.Add(item);
+                LogUtil.WriteLog("查询数据库指令报错,通讯设备ID:" + devID);
             }
         }