Ver código fonte

电池供电设参功能开发

yinyujing 5 anos atrás
pai
commit
eeeee023ec

+ 7 - 1
NB_IOT_TCP_HP_SOCKET/App.config

@@ -9,12 +9,18 @@
     <!--执行断开静默链接间隔时间毫秒-->
     <add key="ConnectionTimeOutInterval" value="10000" />
 
-    <!--是否有MODBUS类设备1:有;0:无-->
+    <!--设备类型 1:电池供电;2:市电供电MODBUS;3:电池供电和市电供电MODBUS-->
     <add key="IsHaveModBus" value="1" />
     
     <!--MODBUS轮询获取抄表数据时间毫秒-->
     <add key="ModBusQueryInterval" value="120000" />
 
+    <!--电池供电最大下发指令次数-->
+    <add key="ParamSendNum" value="3" />
+
+    <!--电池供电同一设备下发指令每次间隔时间(秒)-->
+    <add key="ParamSendInterval" value="5" />
+
   </appSettings>
   <startup> 
     <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />

NB_IOT_TCP_HP_SOCKET/CONF/DataCellConfig.xml → NB_IOT_TCP_HP_SOCKET/CONF/CommDevice_Config.xml


+ 162 - 0
NB_IOT_TCP_HP_SOCKET/CONF/TransDevice_Config.xml

@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Configration>
+  <浙江协议>
+    <模板ID>1</模板ID>
+    <心跳间隔>300</心跳间隔>
+    <心跳发送方>终端</心跳发送方>
+  </浙江协议>
+  <TD_SZYProtocol>
+    <模板ID>1</模板ID>
+    <地址种类>行政区划码</地址种类>
+    <心跳重发次数>0</心跳重发次数>
+    <心跳间隔>20</心跳间隔>
+  </TD_SZYProtocol>
+  <TD_DXProtocol>
+    <是否转码>是</是否转码>
+    <是否看反馈信息>否</是否看反馈信息>
+    <短信发送间隔>10</短信发送间隔>
+  </TD_DXProtocol>
+  <TD_BDProtocol>
+    <CNSSID>123456</CNSSID>
+    <Interval>700</Interval>
+  </TD_BDProtocol>
+  <TD_NOProtocol>
+    <TemplateID>1</TemplateID>
+    <DataChannelUnEnabledCheckInterval>300</DataChannelUnEnabledCheckInterval>
+  </TD_NOProtocol>
+  <TD_SLProtocol>
+    <TemplateID>1</TemplateID>
+    <HeartBeatInterval>300</HeartBeatInterval>
+  </TD_SLProtocol>
+  <TD_PSProtocol>
+    <TemplateID>1</TemplateID>
+    <SysIdentifyCode>123456</SysIdentifyCode>
+    <SourceAddress>00000000001</SourceAddress>
+    <HeartBeatInterval>1800</HeartBeatInterval>
+    <UsingPSProtocol>true</UsingPSProtocol>
+    <GPRSDeviceType>公网专线</GPRSDeviceType>
+    <UsingSystemKey>TRUE</UsingSystemKey>
+    <DataChannelUnEnabledCheckInterval>1800</DataChannelUnEnabledCheckInterval>
+  </TD_PSProtocol>
+  <TD_PSProtocol>
+    <TemplateID>2</TemplateID>
+    <SysIdentifyCode>123456</SysIdentifyCode>
+    <SourceAddress>00000000001</SourceAddress>
+    <HeartBeatInterval>3600</HeartBeatInterval>
+    <UsingPSProtocol>true</UsingPSProtocol>
+    <GPRSDeviceType>专网</GPRSDeviceType>
+    <UsingSystemKey>TRUE</UsingSystemKey>
+    <DataChannelUnEnabledCheckInterval>120</DataChannelUnEnabledCheckInterval>
+  </TD_PSProtocol>
+  <TD_PSProtocol>
+    <TemplateID>3</TemplateID>
+    <SysIdentifyCode>123456</SysIdentifyCode>
+    <SourceAddress>00000000001</SourceAddress>
+    <HeartBeatInterval>3600</HeartBeatInterval>
+    <UsingPSProtocol>true</UsingPSProtocol>
+    <GPRSDeviceType>短信</GPRSDeviceType>
+    <UsingSystemKey>TRUE</UsingSystemKey>
+    <DataChannelUnEnabledCheckInterval>120</DataChannelUnEnabledCheckInterval>
+    <!--激活码参数,短信时看此参数-->
+    <ActiveCode>
+      <!--是否发送激活码,true或false-->
+      <Using>false</Using>
+      <!--激活码发送周期,单位秒-->
+      <SendCycle>60</SendCycle>
+      <!--周期内间隔多长时间发一次,单位秒-->
+      <SendFrequency>2</SendFrequency>
+      <!--接收超时,本周期内如超过此时间仍收不到短信,则不再发送激活码,单位秒-->
+      <ReceiveTimeOut>5</ReceiveTimeOut>
+    </ActiveCode>
+  </TD_PSProtocol>
+  <TD_PSProtocol>
+    <TemplateID>4</TemplateID>
+    <SysIdentifyCode>ABCDEF</SysIdentifyCode>
+    <SourceAddress>00000000001</SourceAddress>
+    <HeartBeatInterval>150</HeartBeatInterval>
+    <UsingPSProtocol>true</UsingPSProtocol>
+    <GPRSDeviceType>设参软件</GPRSDeviceType>
+    <UsingSystemKey>FALSE</UsingSystemKey>
+    <DataChannelUnEnabledCheckInterval>120</DataChannelUnEnabledCheckInterval>
+  </TD_PSProtocol>
+  <TD_SXProtocol>
+    <TemplateID>1</TemplateID>
+    <HeartBeatInterval>150</HeartBeatInterval>
+    <Version>30 31 32</Version>
+    <HeartSender>从站</HeartSender>
+  </TD_SXProtocol>
+  <TD_FourFaithProtocol>
+    <模板ID>1</模板ID>
+    <心跳超时>180</心跳超时>
+    <终端标识>ID</终端标识>
+  </TD_FourFaithProtocol>
+  <TD_TransparentProtocol>
+    <模板ID>1</模板ID>
+    <心跳超时>180</心跳超时>
+    <标识格式>ASCII</标识格式>
+    <注册发送包>
+      <是否启用>TRUE</是否启用>
+      <是否包含标识>TRUE</是否包含标识>
+      <前缀>24 23 2A 72 65 67 2C</前缀>
+      <后缀>
+      </后缀>
+    </注册发送包>
+    <注册回应包>
+      <是否启用>TRUE</是否启用>
+      <是否包含标识>FALSE</是否包含标识>
+      <前缀>
+      </前缀>
+      <后缀>
+      </后缀>
+    </注册回应包>
+    <心跳发送包>
+      <是否启用>TRUE</是否启用>
+      <是否包含标识>FALSE</是否包含标识>
+      <前缀>24 23 2A 62 65 61 74</前缀>
+      <后缀>
+      </后缀>
+    </心跳发送包>
+    <心跳回应包>
+      <是否启用>FALSE</是否启用>
+      <是否包含标识>FALSE</是否包含标识>
+      <前缀>
+      </前缀>
+      <后缀>
+      </后缀>
+    </心跳回应包>
+  </TD_TransparentProtocol>
+  <TD_LQProtocol>
+    <TemplateID>1</TemplateID>
+    <HeartBeatInterval>180</HeartBeatInterval>
+    <UsingLQProtocol>true</UsingLQProtocol>
+    <GPRSDeviceType>专线</GPRSDeviceType>
+  </TD_LQProtocol>
+  <TD_SZY2008>
+    <心跳间隔>90</心跳间隔>
+    <心跳超时>15</心跳超时>
+	<心跳重发次数>2</心跳重发次数>
+    <心跳发送者>中心</心跳发送者>
+  </TD_SZY2008>
+  <TD_HBJSGG>
+    <模板ID>1</模板ID>
+    <心跳间隔>3700</心跳间隔>
+  </TD_HBJSGG>
+  <TD_HBJSGG>
+    <模板ID>2</模板ID>
+    <心跳间隔>3700</心跳间隔>
+  </TD_HBJSGG>
+  <TD_Hydrologic>
+    <模板ID>1</模板ID>
+    <心跳间隔>300</心跳间隔>
+	<!--水文编码、行政编码-->
+	<地址编码种类>水文编码</地址编码种类>
+	<!--HEX、ASCII-->
+    <报文编码方式>HEX</报文编码方式>
+  </TD_Hydrologic>
+  <TD_JJGGSZY>
+    <心跳间隔>90</心跳间隔>
+    <心跳超时>15</心跳超时>
+    <心跳重发次数>2</心跳重发次数>
+    <心跳发送者>中心</心跳发送者>
+  </TD_JJGGSZY>
+</Configration>

NB_IOT_TCP_HP_SOCKET/CONF/US_Common.xml → NB_IOT_TCP_HP_SOCKET/CONF/UserStation_Config.xml


+ 359 - 135
NB_IOT_TCP_HP_SOCKET/MainForm_TCP.cs

@@ -6,6 +6,7 @@ using System.Collections.Generic;
 using System.Configuration;
 using System.Data;
 using System.Drawing;
+using System.IO;
 using System.Runtime.InteropServices;
 using System.Threading;
 using System.Windows.Forms;
@@ -16,9 +17,12 @@ namespace NB_IOT_TCP_HP_SOCKET
     {
         #region 定义变量
         private AppState appState = AppState.Stoped;
-        private static Thread _SendThread;// 发送的线程
+        private static Thread _SendThread;// 处理上报抄表数据的线程
         private static Thread heartBeatThread;// 断开超时链接的线程
+        private static Thread setParamThread;// 处理电池供电设备设参的线程
         private static Queue _SendConidQueue = Queue.Synchronized(new Queue()); // 存储历史记录数据的队列
+        // 实例化Timer类,设置间隔时间(毫秒) 市电供电MODBUS主动获取数据定时器
+        private static System.Timers.Timer timer;
         private static bool isTimeRuning = false; // MODBUS定时器是否执行中
         private static bool isHeartBeatRuning = false; // 心跳进程是否执行中
 
@@ -28,6 +32,9 @@ namespace NB_IOT_TCP_HP_SOCKET
 
         // 设备对应的最新链接ID
         private static Dictionary<string, IntPtr> deveiceConnId = new Dictionary<string, IntPtr>();
+        private byte[] _paramData = new byte[0];
+        private string paramPath = AppDomain.CurrentDomain.BaseDirectory + @"远程设参\";
+
 
         TcpServer server = new TcpServer();
 
@@ -92,8 +99,22 @@ namespace NB_IOT_TCP_HP_SOCKET
 
                     deviceTypes = ProtocolAnalysisTools.GetDeviceTypes();
 
-                    if ("1".Equals(ConfigurationManager.AppSettings["IsHaveModBus"]))
+                    // 设备类型 1:电池供电;2:市电供电MODBUS;3:电池供电和市电供电MODBUS
+                    string deviceType = ConfigurationManager.AppSettings["IsHaveModBus"];
+
+                    if ("1".Equals(deviceType))
+                    {
+                        StartOrResumeSetParamThread(); // 启动电池供电设备设参线程
+                    }
+                    else if ("2".Equals(deviceType))
+                    {
+                        timer = new System.Timers.Timer(Convert.ToInt32(ConfigurationManager.AppSettings["ModBusQueryInterval"]));
+                        StartModBusSendTimer(); // 启动ModBus定时发送读取数据任务
+                    }
+                    else if ("3".Equals(deviceType))
                     {
+                        StartOrResumeSetParamThread(); // 启动电池供电设备设参线程
+                        timer = new System.Timers.Timer(Convert.ToInt32(ConfigurationManager.AppSettings["ModBusQueryInterval"]));
                         StartModBusSendTimer(); // 启动ModBus定时发送读取数据任务
                     }
 
@@ -124,12 +145,32 @@ namespace NB_IOT_TCP_HP_SOCKET
             if (server.Stop())
             {
                 AddMsg($" > Server Stop 服务停止成功", lbReceiveData);
-                heartBeatThread.Suspend();
+                // 设备类型 1:电池供电;2:市电供电MODBUS;3:电池供电和市电供电MODBUS
+                string deviceType = ConfigurationManager.AppSettings["IsHaveModBus"];
+
+                if ("1".Equals(deviceType))
+                {
+                    setParamThread.Suspend(); // 挂起电池供电设参线程
+                }
+                else if ("2".Equals(deviceType))
+                {
+                    isTimeRuning = false;
+                    timer.Enabled = false; // 停止市电供电MODBUS主动获取数据定时器
+                }
+                else if ("3".Equals(deviceType))
+                {
+                    setParamThread.Suspend(); // 挂起电池供电设参线程
+                    isTimeRuning = false;
+                    timer.Enabled = false; // 停止市电供电MODBUS主动获取数据定时器
+                }
+
+                isHeartBeatRuning = false;
+                heartBeatThread.Suspend(); // 挂起监控心跳线程
                 SetAppState(AppState.Stoped);
             }
             else
             {
-                AddMsg($" > Stop Error -> {server.ErrorMessage}({server.ErrorCode})", lbErrorData);
+                AddMsg($" > Stop Error 服务停止失败 -> {server.ErrorMessage}({server.ErrorCode})", lbErrorData);
             }
         }
 
@@ -205,7 +246,7 @@ namespace NB_IOT_TCP_HP_SOCKET
             }
             else
             {
-                if (lb.Items.Count > 100)
+                if (lb.Items.Count > 300)
                 {
                     lb.Items.RemoveAt(0);
                 }
@@ -244,6 +285,7 @@ namespace NB_IOT_TCP_HP_SOCKET
             clientInfo.ConnId = connId;
             clientInfo.IpAddress = ip;
             clientInfo.Port = port;
+            clientInfo.IsEnd = false;
             if (server.SetExtra(connId, clientInfo) == false)
             {
                 AddMsg($" > [{connId},OnAccept] -> SetConnectionExtra fail", lbErrorData);
@@ -291,17 +333,15 @@ namespace NB_IOT_TCP_HP_SOCKET
                 if (clientInfo != null)
                 {
                     // clientInfo 就是accept里传入的附加数据了
-
                     AddMsg($" > [{clientInfo.ConnId},OnReceive] -> {clientInfo.IpAddress}:{clientInfo.Port} 接收数据 ({bytes.Length} bytes) \n {BitConverter.ToString(bytes, 0, bytes.Length).Replace("-", " ")}", lbReceiveData);
 
-
                     PSProtocol psp = new PSProtocol();
                     // 接外包操作
                     ResMsg msg = ProtocolAnalysisTools.UnOuterPack(bytes, psp);
 
                     if (!msg.Result)
                     {
-                        AddMsg($" > [{clientInfo.ConnId},OnReceive] -> {clientInfo.IpAddress}:{clientInfo.Port} {psp.SourceNumber} ({bytes.Length} bytes) 外包解包失败 \n {msg.Message}", lbReceiveData);
+                        AddMsg($" > [{clientInfo.ConnId},OnReceive] -> {clientInfo.IpAddress}:{clientInfo.Port} {psp.SourceNumber} ({bytes.Length} bytes) 外包解包失败 \n {msg.Message}", lbErrorData);
 
                     }
                     else
@@ -321,7 +361,7 @@ namespace NB_IOT_TCP_HP_SOCKET
                             if (!ProtocolAnalysisTools.OuterPack(protocol2, out byte[] buffer2).Result)
                             {
 
-                                AddMsg($" > [{clientInfo.ConnId},OnReceive] -> {clientInfo.IpAddress}:{clientInfo.Port} {psp.SourceNumber} ({bytes.Length} bytes) 心跳回应打包失败 ", lbReceiveData);
+                                AddMsg($" > [{clientInfo.ConnId},OnReceive] -> {clientInfo.IpAddress}:{clientInfo.Port} {psp.SourceNumber} ({bytes.Length} bytes) 心跳回应打包失败 ", lbErrorData);
                             }
                             else
                             {
@@ -331,10 +371,10 @@ namespace NB_IOT_TCP_HP_SOCKET
                         }
                         else
                         {
-                            if (psp.Type == FrameType.Battery_GPRS_Report || psp.Type == FrameType.GPRS_Data)
+                            if (psp.Type == FrameType.Battery_GPRS_Report || psp.Type == FrameType.GPRS_Data || psp.Type == FrameType.Battery_Param)
                             {
                                 clientInfo.pSProtocol = psp;
-                                clientInfo.receiveTime = DateTime.Now; // 收到数据时间,MODBUS设备使用
+                                clientInfo.ReceiveTime = DateTime.Now; // 收到数据时间,MODBUS设备使用
                                 _SendConidQueue.Enqueue(clientInfo); // 将解包数据压入队列
 
                                 byte[] buffer3;
@@ -346,7 +386,7 @@ namespace NB_IOT_TCP_HP_SOCKET
                                 if (!ProtocolAnalysisTools.OuterPack(protocol2, out buffer3).Result)
                                 {
 
-                                    AddMsg($" > [{clientInfo.ConnId},OnReceive] -> {clientInfo.IpAddress}:{clientInfo.Port} {psp.SourceNumber} ({bytes.Length} bytes) 历史记录回应打包失败 ", lbReceiveData);
+                                    AddMsg($" > [{clientInfo.ConnId},OnReceive] -> {clientInfo.IpAddress}:{clientInfo.Port} {psp.SourceNumber} ({bytes.Length} bytes) 历史记录回应打包失败 ", lbErrorData);
 
                                 }
                                 else
@@ -364,7 +404,7 @@ namespace NB_IOT_TCP_HP_SOCKET
                 else
                 {
 
-                    AddMsg($" > [{connId},OnReceive] -> 获取链接附加数据失败 ({bytes.Length} bytes)", lbReceiveData);
+                    AddMsg($" > [{connId},OnReceive] -> 获取链接附加数据失败 ({bytes.Length} bytes)", lbErrorData);
                 }
 
                 return HandleResult.Ok;
@@ -415,28 +455,38 @@ namespace NB_IOT_TCP_HP_SOCKET
         }
         #endregion
 
-        #region 启动 发送线程
-        private void StarSendThread()
-        {
-            _SendThread = new Thread(new ThreadStart(DealWithSendThread));
-            var a = _SendThread.ThreadState;
-            _SendThread.Start();
-        }
-        #endregion
 
         /// <summary>
         /// 启动MODBUS轮询获取数据记录
         /// </summary>
         private void StartModBusSendTimer()
         {
-            int intervalTime = Convert.ToInt32(ConfigurationManager.AppSettings["ModBusQueryInterval"]);
-            // 实例化Timer类,设置间隔时间(毫秒)
-            System.Timers.Timer timer = new System.Timers.Timer(intervalTime);
             timer.Elapsed += GetDeviceData; // 到达时间的时候执行事件;
             timer.AutoReset = true; // 设置是执行一次(false)还是一直执行(true);
             timer.Enabled = true; // 启动计时器
         }
 
+        /// <summary>
+        /// 启动电池供电设备设参线程
+        /// </summary>
+        private void StartOrResumeSetParamThread()
+        {
+            if (setParamThread == null)
+            {
+                setParamThread = new Thread(new ThreadStart(SetParamThread));
+            }
+            switch (setParamThread.ThreadState)
+            {
+                case ThreadState.Stopped:
+                case ThreadState.Unstarted://未启动
+                    setParamThread.Start();
+                    break;
+                case ThreadState.Suspended://挂起
+                    setParamThread.Resume();
+                    break;
+            }
+        }
+
         /// <summary>
         /// 启动监控心跳是否超时进程
         /// </summary>
@@ -455,6 +505,27 @@ namespace NB_IOT_TCP_HP_SOCKET
                 case ThreadState.Suspended: // 挂起
                     heartBeatThread.Resume();
                     break;
+            }
+        }
+
+        /// <summary>
+        /// 启动处理上报抄表数据的队列
+        /// </summary>
+        private void StartOrResumeSendThread()
+        {
+            if (_SendThread == null)
+            {
+                _SendThread = new Thread(new ThreadStart(DealWithSendThread));
+            }
+            switch (_SendThread.ThreadState)
+            {
+                case ThreadState.Stopped:
+                case ThreadState.Unstarted://未启动
+                    _SendThread.Start();
+                    break;
+                case ThreadState.Suspended://挂起
+                    _SendThread.Resume();
+                    break;
 
             }
         }
@@ -516,30 +587,6 @@ namespace NB_IOT_TCP_HP_SOCKET
             }
         }
 
-        #region 启动或者恢复发送线程
-        /// <summary>
-        /// 启动处理上报抄表数据的队列
-        /// </summary>
-        private void StartOrResumeSendThread()
-        {
-            if (_SendThread == null)
-            {
-                _SendThread = new Thread(new ThreadStart(DealWithSendThread));
-            }
-            switch (_SendThread.ThreadState)
-            {
-                case ThreadState.Stopped:
-                case ThreadState.Unstarted://未启动
-                    _SendThread.Start();
-                    break;
-                case ThreadState.Suspended://挂起
-                    _SendThread.Resume();
-                    break;
-
-            }
-        }
-        #endregion
-
         /// <summary>
         /// 循环处理发送读取抄表数据的指令
         /// </summary>
@@ -659,13 +706,13 @@ namespace NB_IOT_TCP_HP_SOCKET
 
                         string agreement = ""; // 设备协议
                         string agreementParam = ""; // 设备协议参数
-                        string trandId = ""; // 通讯设备ID
+                        Dictionary<string, string> trandevice = new Dictionary<string, string>(); // 通讯设备信息
                         for (int i = 0; i < dt.Rows.Count; i++)
                         {
 
                             string agreementTmp = dt.Rows[i]["设备协议"].ToString();
                             string agreementParamTmp = dt.Rows[i]["设备协议参数"].ToString();
-                            trandId = dt.Rows[i]["trandId"].ToString();
+                            trandevice[dt.Rows[i]["transId"].ToString()] = dt.Rows[i]["名称"].ToString();
                             // 如果一个通讯设备下挂载多个设备,判断多个设备的传输协议是否一致,如果不一致则配置错误,无法进行数据转换
                             if ("".Equals(agreement) && "".Equals(agreementParam))
                             {
@@ -689,16 +736,55 @@ namespace NB_IOT_TCP_HP_SOCKET
                             {
                                 if (msg.Message == "参数包")
                                 {
-                                    //this._paramData = new byte[data.Length];
-                                    //data.CopyTo(this._paramData, 0);
-                                    //if (this.DeviceDebug != null)
-                                    //{
-                                    //    this.DeviceDebug(this, new CommDeviceDebugArgs(msg.Message, CommDeviceDebugArgs.DebugType.ReceiveData, data));
-                                    //}
+                                    // 如果是参数包,记录回包内容,后面发送设参时判断回包内容用
+                                    if (!Directory.Exists(this.paramPath))
+                                    {
+                                        return;
+                                    }
+                                    // 获取所有的设参文件夹
+                                    string[] directories = Directory.GetDirectories(this.paramPath);
+
+                                    if (directories.Length == 0)
+                                    {
+                                        return;
+                                    }
+                                    string destNumber = clientInfo.DestNumber;
+                                    // 一个传输设备可能对应多个设备信息及通讯设备
+                                    foreach (KeyValuePair<string, string> keyValuePair in trandevice)
+                                    {
+
+                                        RemoteTask remoteTask = new RemoteTask();
+                                        string filePath = "";
+                                        // 如果存在读取所有的设参文件内容
+                                        foreach (string str in directories)
+                                        {
+                                            if (str.Contains(keyValuePair.Key + "_" + keyValuePair.Value + "_"))
+                                            {
+                                                filePath = str;
+                                                remoteTask.GetRemoteTaskList(str, true);
+                                                break;
+                                            }
+                                        }
+
+                                        foreach (Task task in remoteTask.Tasklist)
+                                        {
+                                            if (psp.Data.Length >= 6)
+                                            {
+                                                task.TaskState = "完成";
+                                                task.ReceiveCode = new byte[psp.Data.Length];
+                                                psp.Data.CopyTo(task.ReceiveCode, 0);
+                                                task.OutPutFile(filePath, true);
+                                                task.DeleteFile(filePath);
+
+                                                clientInfo.ParamRetrunStatus = 1;
+                                                server.SetExtra(clientInfo.ConnId, clientInfo);
+                                            }
+                                        }
+                                    }
                                 }
                                 else
                                 {
-                                    AddMsg($" > [{clientInfo.ConnId},OnReceive] -> {clientInfo.IpAddress}:{clientInfo.Port} {sourceNumber} ({psp.Data.Length} bytes) CD_CellMonitor内包解包失败 \n {msg.Message}", lbReceiveData);
+                                    AddMsg($" > [{clientInfo.ConnId},OnReceive] -> {clientInfo.IpAddress}:{clientInfo.Port} {sourceNumber} ({psp.Data.Length} bytes) CD_CellMonitor内包解包失败 \n {msg.Message}", lbErrorData);
                                 }
                             }
                             else
@@ -708,20 +794,11 @@ namespace NB_IOT_TCP_HP_SOCKET
                                 // 如果是最后一包则发送校时指令
                                 if (cm.IsEnd)
                                 {
-                                    PSProtocol protocol2 = new PSProtocol(psp.DestNumber, psp.SourceNumber, RandomTime());
-                                    protocol2.Type = FrameType.Battery_EndComm;
-
-                                    if (!ProtocolAnalysisTools.OuterPack(protocol2, out byte[] buffer3).Result)
-                                    {
-                                        AddMsg($" > [{clientInfo.ConnId},OnSend] -> {clientInfo.IpAddress}:{clientInfo.Port} {sourceNumber} ({psp.Data.Length} bytes) CD_CellMonitor最后一包校时打包失败 \n", lbReceiveData);
-
-                                    }
-                                    else
-                                    {
-
-                                        AddMsg($" > [{clientInfo.ConnId},OnSend] -> {clientInfo.IpAddress}:{clientInfo.Port} {sourceNumber} ({psp.Data.Length} bytes) CD_CellMonitor最后一包校时 \n {BitConverter.ToString(buffer3, 0, buffer3.Length).Replace("-", " ")} ", lbReceiveData);
-                                        server.Send(clientInfo.ConnId, buffer3, buffer3.Length);// 发送数据
-                                    }
+                                    clientInfo.IsEnd = true;
+                                    clientInfo.TranDevice = trandevice;
+                                    clientInfo.DestNumber = psp.DestNumber;
+                                    clientInfo.SourceNumber = psp.SourceNumber;
+                                    server.SetExtra(clientInfo.ConnId, clientInfo);
                                 }
 
                                 List<HistoryRecord> list = new List<HistoryRecord>();
@@ -754,7 +831,7 @@ namespace NB_IOT_TCP_HP_SOCKET
                                     }
                                     #endregion
 
-                                    // 将数据进行封装,一条数据可能对于多个设备的数据,通过[设备信息表]中设备的[用户站参数]与CONF\US_Common.xml进行匹配拆分
+                                    // 将数据进行封装,一条数据可能对于多个设备的数据,通过[设备信息表]中设备的[用户站参数]与CONF\UserStation_Config.xml进行匹配拆分
                                     List<HistoryRecord> item = this.UpdateHistoryData(cm.Record[i].PickTime, cm, dt, _analogData, _switchData);
                                     if (item != null && item.Count > 0)
                                     {
@@ -772,27 +849,42 @@ namespace NB_IOT_TCP_HP_SOCKET
                         {
                             #region 根据上报数据的功能码区分获取对应的下发指令的MODBUS对象
                             Modbus.FunctionCode code = (Modbus.FunctionCode)psp.Data[1];
+                            bool unPackFlag = false;
+                            string unPackRs = "";
                             Modbus modbus = new Modbus();
-                            if (code == Modbus.FunctionCode.F04)
-                            {
-                                modbus = sendComm[trandId][0];
-                            }
-                            else if (code == Modbus.FunctionCode.F02)
+                            // 一个传输设备可能对应多个设备信息及通讯设备
+                            foreach (KeyValuePair<string, string> keyValuePair in trandevice)
                             {
-                                modbus = sendComm[trandId][1];
+                                if (code == Modbus.FunctionCode.F04)
+                                {
+                                    modbus = sendComm[keyValuePair.Key][0];
+                                }
+                                else if (code == Modbus.FunctionCode.F02)
+                                {
+                                    modbus = sendComm[keyValuePair.Key][1];
+                                }
+                                // 内包进行解包,解包后的数据存入modbus.UpDataArea
+                                ResMsg msg = Modbus.UnPack(psp.Data, modbus);
+                                if (msg.Result)
+                                {
+                                    unPackFlag = true;
+                                    break;
+                                }
+                                else
+                                {
+                                    unPackRs = msg.Message; ;
+                                }
                             }
                             #endregion
 
-                            // 内包进行解包,解包后的数据存入modbus.UpDataArea
-                            ResMsg msg = Modbus.UnPack(psp.Data, modbus);
 
-                            if (!msg.Result)
+                            if (!unPackFlag)
                             {
-                                AddMsg($" > [{clientInfo.ConnId},OnReceive] -> {clientInfo.IpAddress}:{clientInfo.Port} {sourceNumber} ({modbus.UpDataArea.Length} bytes) CD_PSController内包解包失败,数据类型{code} \n {msg.Message}", lbReceiveData);
+                                AddMsg($" > [{clientInfo.ConnId},OnReceive] -> {clientInfo.IpAddress}:{clientInfo.Port} {sourceNumber} ({psp.Data.Length} bytes) CD_PSController内包解包失败,数据类型{code} \n {unPackRs}", lbErrorData);
                             }
                             else
                             {
-                                AddMsg($" > [{clientInfo.ConnId},OnReceive] -> {clientInfo.IpAddress}:{clientInfo.Port} {sourceNumber} ({modbus.UpDataArea.Length} bytes) CD_PSController内包解包成功,数据类型{code} \n {BitConverter.ToString(modbus.UpDataArea, 0, modbus.UpDataArea.Length).Replace("-", " ")}", lbReceiveData);
+                                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);
 
                                 // 获取配置的上报抄表数据的数据信息CONF/DataCellConfig.xml中CD_PSController节点,根据传输设备中的设备协议参数关联取那些字段
                                 ModBusDeviceType modBusDeviceType = new ModBusDeviceType(agreementParam);
@@ -812,8 +904,8 @@ namespace NB_IOT_TCP_HP_SOCKET
                                 }
                                 #endregion
 
-                                // 将数据进行封装,一条数据可能对于多个设备的数据,通过[设备信息表]中设备的[用户站参数]与CONF\US_Common.xml进行匹配拆分
-                                List<HistoryRecord> item = this.UpdateHistoryData(clientInfo.receiveTime, null, dt, _analogData, _switchData);
+                                // 将数据进行封装,一条数据可能对于多个设备的数据,通过[设备信息表]中设备的[用户站参数]与CONF\UserStation_Config.xml进行匹配拆分
+                                List<HistoryRecord> item = this.UpdateHistoryData(clientInfo.ReceiveTime, null, dt, _analogData, _switchData);
 
                                 // 保存抄表数据
                                 ProtocolAnalysisTools.SaveRecord(item);
@@ -828,6 +920,57 @@ namespace NB_IOT_TCP_HP_SOCKET
             }
         }
 
+        /// <summary>
+        /// 电池供电设备发送设参及校时指令进程
+        /// </summary>
+        private void SetParamThread()
+        {
+            while (true)
+            {
+                // 获取所有链接ID
+                IntPtr[] allConnIds = server.GetAllConnectionIDs();
+                if (allConnIds == null || allConnIds.Length == 0)
+                {
+                    Thread.Sleep(1000);
+                    continue;
+                }
+
+                foreach (IntPtr connId in allConnIds)
+                {
+                    ClientInfo clientInfo = (ClientInfo)server.GetExtra(connId);
+                    if (clientInfo == null)
+                    {
+                        continue;
+                    }
+                    // 如果链接中数据包是最后一包进行下发设参和校时指令
+                    if (!clientInfo.IsEnd)
+                    {
+                        continue;
+                    }
+                    if (clientInfo.TranDevice == null)
+                    {
+                        continue;
+                    }
+                    Dictionary<string, string> trandevice = clientInfo.TranDevice;
+                    string destNumber = clientInfo.DestNumber;
+                    string sourceNumber = clientInfo.SourceNumber;
+                    // 一个传输设备可能对应多个设备信息及通讯设备
+                    foreach (KeyValuePair<string, string> keyValuePair in trandevice)
+                    {
+                        try
+                        {
+                            // 发送设参指令
+                            SendSetParam(clientInfo, keyValuePair.Key, keyValuePair.Value);
+                        }
+                        catch (Exception ex)
+                        {
+                            AddMsg($" > [{clientInfo.ConnId},OnSend] -> {clientInfo.IpAddress}:{clientInfo.Port} {sourceNumber}  CD_CellMonitor最后发送设参指令失败 \n {ex.Message}", lbErrorData);
+                        }
+                    }
+                }
+            }
+        }
+
         /// <summary>
         /// 
         /// </summary>
@@ -891,24 +1034,11 @@ namespace NB_IOT_TCP_HP_SOCKET
             return hislist;
         }
 
-        private byte[] RandomTime()
-        {
-            int num = new Random().Next(5);
-            TimeSpan span = (TimeSpan)(DateTime.Now.AddSeconds((double)num) - Convert.ToDateTime("2000-01-01 00:00:00"));
-            int totalSeconds = (int)span.TotalSeconds;
-            byte[] buffer = new byte[4];
-            for (int i = 0; i < 4; i++)
-            {
-                buffer[4 - (i + 1)] = (byte)(totalSeconds >> (i * 8));
-            }
-            return buffer;
-        }
-
         private void timer1_Tick(object sender, EventArgs e)
         {
             this.toolStripStatusLabel6.Text = "系统时间:" + DateTime.Now.ToString();
             TimeSpan span = (TimeSpan)(DateTime.Now - this.dtStartTime);
-            this.toolStripStatusLabel4.Text = this.RunTime((int)span.TotalSeconds);
+            this.toolStripStatusLabel4.Text = ProtocolAnalysisTools.RunTime((int)span.TotalSeconds);
             string coonNum = "0";
             if (server.IsStarted && server.GetAllConnectionIDs() != null)
             {
@@ -917,61 +1047,155 @@ namespace NB_IOT_TCP_HP_SOCKET
             this.toolStripStatusLabel3.Text = "客户端连接数:" + coonNum;
         }
 
-        private string RunTime(int s)
+        private void button3_Click(object sender, EventArgs e)
         {
-            int num = 0;
-            int num2 = 0;
-            int num3 = 0;
-            int num4 = 0;
-            if (s < 60)
+            ParamSetForm paramSetForm = new ParamSetForm();
+            paramSetForm.ShowDialog();
+        }
+
+        /// <summary>
+        /// 下发设参指令
+        /// </summary>
+        /// <param name="clientInfo"></param>
+        /// <param name="id"></param>
+        /// <param name="name"></param>
+        private void SendSetParam(ClientInfo clientInfo, string id, string name)
+        {
+            if (!Directory.Exists(this.paramPath))
             {
-                num4 = s;
+                // 没有设参指令则校时关机
+                TimingShutDown(clientInfo);
+                return;
             }
-            else if ((60 <= s) && (s <= 0xe10))
+            // 获取所有的设参文件夹
+            string[] directories = Directory.GetDirectories(this.paramPath);
+
+            if (directories.Length == 0)
             {
-                num3 = s / 60;
-                num4 = s % 60;
+                // 没有设参指令则校时关机
+                TimingShutDown(clientInfo);
+                return;
             }
-            else if ((0xe10 <= s) && (s <= 0x15180))
+
+            RemoteTask remoteTask = new RemoteTask();
+            string filePath = "";
+            // 如果存在读取所有的设参文件内容
+            foreach (string str in directories)
             {
-                num2 = s / 0xe10;
-                num3 = (s % 0xe10) / 60;
-                num4 = (s % 0xe10) % 60;
+                if (str.Contains(id + "_" + name + "_"))
+                {
+                    filePath = str;
+                    // 获取所有待发送的参数文件内容
+                    remoteTask.GetRemoteTaskList(str, true);
+                    break;
+                }
             }
-            else
+
+            if (remoteTask.Tasklist == null || remoteTask.Tasklist.Count == 0)
             {
-                num = s / 0x15180;
-                num2 = (s % 0x15180) / 0xe10;
-                num3 = ((s % 0x15180) % 0xe10) / 60;
-                num4 = ((s % 0x15180) % 0xe10) % 60;
+                // 没有设参指令则校时关机
+                TimingShutDown(clientInfo);
+                return;
+            }
+
+            int paramSendNum = clientInfo.ParamSendNum; // 已发送次数
+            int paramSendStatus = clientInfo.ParamSendStatus; // 发送状态
+            DateTime paramSendTime = clientInfo.ParamSendTime; // 上次发送时间
+
+            int paramSendNumTmp = Convert.ToInt32(ConfigurationManager.AppSettings["ParamSendNum"]); // 电池供电最大下发指令次数
+            int paramSendInterval = Convert.ToInt32(ConfigurationManager.AppSettings["ParamSendInterval"]); // 电池供电同一设备下发指令每次间隔时间(秒)
+
+            // 循环下发设参指令
+            foreach (Task task in remoteTask.Tasklist)
+            {
+                TimeSpan span = (TimeSpan)(DateTime.Now - paramSendTime);
+                // 未发送;已发送&&发送次数小于配置的最大发送次数&&两次间隔时间大于配置的间隔时间
+                if (paramSendStatus == 0 || paramSendStatus == 1 && paramSendNum < paramSendNumTmp && span.TotalSeconds >= paramSendInterval)
+                {
+                    PSProtocol protocol2 = new PSProtocol(clientInfo.DestNumber, clientInfo.SourceNumber, task.SendCode);
+                    protocol2.Type = FrameType.Battery_Param;
+
+                    if (!ProtocolAnalysisTools.OuterPack(protocol2, out byte[] buffer3).Result)
+                    {
+                        AddMsg($" > [{clientInfo.ConnId},OnSend] -> {clientInfo.IpAddress}:{clientInfo.Port} {clientInfo.SourceNumber} ({buffer3.Length} bytes) CD_CellMonitor下发设参打包失败 \n", lbErrorData);
+
+                    }
+                    else
+                    {
+                        // 下发设参数
+                        bool sendFlag = server.Send(clientInfo.ConnId, buffer3, buffer3.Length);
+                        // 发送成功更新发送次数和发送时间
+                        if (sendFlag)
+                        {
+                            clientInfo.ParamSendStatus = 1;
+                        }
+                        else
+                        {
+                            clientInfo.ParamSendStatus = 0;
+                        }
+                        clientInfo.ParamSendTime = DateTime.Now;
+                        clientInfo.ParamSendNum = paramSendNum + 1;
+                        server.SetExtra(clientInfo.ConnId, clientInfo);
+                    }
+                }
+                else if (paramSendNum >= paramSendNumTmp)
+                {
+                    task.TaskState = "超时";
+                    task.OutPutFile(filePath, false);
+                    // 校时关机
+                    TimingShutDown(clientInfo);
+                }
             }
-            return ("系统持续运行:" + num.ToString() + "天" + num2.ToString() + "小时" + num3.ToString() + "分" + num4.ToString() + "秒");
         }
 
-        private void button3_Click(object sender, EventArgs e)
+        /// <summary>
+        /// 发送校时关机指令
+        /// </summary>
+        /// <param name="clientInfo"></param>
+        private void TimingShutDown(ClientInfo clientInfo)
         {
-            ParamSetForm paramSetForm = new ParamSetForm();
-            paramSetForm.ShowDialog();
+            PSProtocol protocol2 = new PSProtocol(clientInfo.DestNumber, clientInfo.SourceNumber, ProtocolAnalysisTools.RandomTime());
+            protocol2.Type = FrameType.Battery_EndComm;
+
+            if (!ProtocolAnalysisTools.OuterPack(protocol2, out byte[] buffer3).Result)
+            {
+                AddMsg($" > [{clientInfo.ConnId},OnSend] -> {clientInfo.IpAddress}:{clientInfo.Port} {clientInfo.SourceNumber} ({buffer3.Length} bytes) CD_CellMonitor最后一包校时打包失败 \n", lbErrorData);
+
+            }
+            else
+            {
+
+                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)) // 发送数据
+                {
+                    clientInfo.IsEnd = false;
+                    clientInfo.ParamSendNum = 0;
+                    clientInfo.ParamSendStatus = 0;
+                    clientInfo.ParamRetrunStatus = 0;
+                    server.SetExtra(clientInfo.ConnId, clientInfo);
+                }
+            }
         }
     }
 
     [StructLayout(LayoutKind.Sequential)]
     public class ClientInfo
     {
-        public IntPtr ConnId { get; set; }
+        public IntPtr ConnId { get; set; } // 链接ID
         public IntPtr NewConnId { get; set; }
-        public string IpAddress { get; set; }
-        public ushort Port { get; set; }
+        public string IpAddress { get; set; } // 客户端IP
+        public ushort Port { get; set;  }// 客户端端口号
         public PSProtocol pSProtocol { get; set; }
-        public byte[] BArr { get; set; }// 存储最新数据
-        public byte[] BSendArr { get; set; }// 存储发送的数据域的数据
-        public string Address { get; set; }// 水表地址
-        public CmdType CmdType { get; set; }// 指令类型
-        public bool flag { get; set; } // 指令是否正确
-        public string msg { get; set; } // 返回信息
-        public int meterId { get; set; }
-        public DateTime receiveTime { get; set; }
-        public int SendCmdRecordId { get; set; }// 发送的缓存命令的id
-        public int SendCmdParentId { get; set; }// 发送缓存命令的母id
+        public string DestNumber { get; set; } // 目标地址
+        public string SourceNumber { get; set; } // 源地址
+        public bool IsEnd { get; set; } // 是否是最后一包数据
+        public Dictionary<string, string> TranDevice { get; set; }
+        public DateTime ReceiveTime { get; set; }
+        #region 设参指令发送时使用属性
+        public DateTime ParamSendTime { get; set; } // 设参发送时间
+        public int ParamSendStatus { get; set; } // 设参发送状态 0:未发送;1:已发送
+        public int ParamRetrunStatus { get; set; } // 设参回包状态 0:未回包;1:已回包
+        public int ParamSendNum { get; set; } // 设参发送次数
+        #endregion
     }
 }

+ 7 - 2
NB_IOT_TCP_HP_SOCKET/NB_IOT_TCP_HP_SOCKET.csproj

@@ -68,8 +68,10 @@
     <Compile Include="WWKJUtil\CellRecord.cs" />
     <Compile Include="WWKJUtil\CommData.cs" />
     <Compile Include="WWKJUtil\CommOption.cs" />
+    <Compile Include="WWKJUtil\ConfigInfo.cs" />
     <Compile Include="WWKJUtil\ControlOption.cs" />
     <Compile Include="WWKJUtil\CellMonitorConvertByType.cs" />
+    <Compile Include="WWKJUtil\DeviceType.cs" />
     <Compile Include="WWKJUtil\ModBusConvertByType.cs" />
     <Compile Include="WWKJUtil\DBHelper.cs" />
     <Compile Include="WWKJUtil\CellMonitorDeviceType.cs" />
@@ -85,9 +87,11 @@
     <Compile Include="WWKJUtil\ParamOption.cs" />
     <Compile Include="WWKJUtil\ProtocolAnalysisTools.cs" />
     <Compile Include="WWKJUtil\PSProtocol.cs" />
+    <Compile Include="WWKJUtil\RemoteTask.cs" />
     <Compile Include="WWKJUtil\ResMsg.cs" />
     <Compile Include="WWKJUtil\StationType.cs" />
     <Compile Include="WWKJUtil\SubDevice.cs" />
+    <Compile Include="WWKJUtil\Task.cs" />
     <Compile Include="WWKJUtil\ValueToHex.cs" />
     <EmbeddedResource Include="MainForm_TCP.resx">
       <DependentUpon>MainForm_TCP.cs</DependentUpon>
@@ -120,8 +124,9 @@
     </None>
   </ItemGroup>
   <ItemGroup>
-    <Content Include="CONF\DataCellConfig.xml" />
-    <Content Include="CONF\US_Common.xml" />
+    <Content Include="CONF\CommDevice_Config.xml" />
+    <Content Include="CONF\TransDevice_Config.xml" />
+    <Content Include="CONF\UserStation_Config.xml" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\HPSocketCS\HPSocketCS.csproj">

+ 17 - 4
NB_IOT_TCP_HP_SOCKET/ParamSetForm.Designer.cs

@@ -48,6 +48,7 @@
             this.connectionTimeOut = new System.Windows.Forms.TextBox();
             this.button1 = new System.Windows.Forms.Button();
             this.button2 = new System.Windows.Forms.Button();
+            this.isBatteryDevice = new System.Windows.Forms.CheckBox();
             this.groupBox1.SuspendLayout();
             this.groupBox2.SuspendLayout();
             this.SuspendLayout();
@@ -135,6 +136,7 @@
             // 
             // groupBox2
             // 
+            this.groupBox2.Controls.Add(this.isBatteryDevice);
             this.groupBox2.Controls.Add(this.isHaveModBus);
             this.groupBox2.Controls.Add(this.label5);
             this.groupBox2.Controls.Add(this.connectionTimeOutInterval);
@@ -155,9 +157,9 @@
             this.isHaveModBus.AutoSize = true;
             this.isHaveModBus.Location = new System.Drawing.Point(70, 173);
             this.isHaveModBus.Name = "isHaveModBus";
-            this.isHaveModBus.Size = new System.Drawing.Size(144, 16);
+            this.isHaveModBus.Size = new System.Drawing.Size(108, 16);
             this.isHaveModBus.TabIndex = 16;
-            this.isHaveModBus.Text = "电供电MODBUS设备";
+            this.isHaveModBus.Text = "市电MODBUS设备";
             this.isHaveModBus.UseVisualStyleBackColor = true;
             // 
             // label5
@@ -197,9 +199,9 @@
             this.label7.AutoSize = true;
             this.label7.Location = new System.Drawing.Point(33, 144);
             this.label7.Name = "label7";
-            this.label7.Size = new System.Drawing.Size(149, 12);
+            this.label7.Size = new System.Drawing.Size(53, 12);
             this.label7.TabIndex = 11;
-            this.label7.Text = "是否有市电供电MODBUS设备";
+            this.label7.Text = "设备类型";
             // 
             // label8
             // 
@@ -237,6 +239,16 @@
             this.button2.UseVisualStyleBackColor = true;
             this.button2.Click += new System.EventHandler(this.button2_Click);
             // 
+            // isBatteryDevice
+            // 
+            this.isBatteryDevice.AutoSize = true;
+            this.isBatteryDevice.Location = new System.Drawing.Point(182, 173);
+            this.isBatteryDevice.Name = "isBatteryDevice";
+            this.isBatteryDevice.Size = new System.Drawing.Size(96, 16);
+            this.isBatteryDevice.TabIndex = 17;
+            this.isBatteryDevice.Text = "电池供电设备";
+            this.isBatteryDevice.UseVisualStyleBackColor = true;
+            // 
             // ParamSetForm
             // 
             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
@@ -281,5 +293,6 @@
         private System.Windows.Forms.Label label8;
         private System.Windows.Forms.TextBox connectionTimeOut;
         private System.Windows.Forms.CheckBox isHaveModBus;
+        private System.Windows.Forms.CheckBox isBatteryDevice;
     }
 }

+ 27 - 2
NB_IOT_TCP_HP_SOCKET/ParamSetForm.cs

@@ -23,7 +23,20 @@ namespace NB_IOT_TCP_HP_SOCKET
             var cfg = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
             cfg.AppSettings.Settings["ConnectionTimeOut"].Value = (this.connectionTimeOut.Text.Trim() == "" ? "0" : this.connectionTimeOut.Text.Trim());
             cfg.AppSettings.Settings["ConnectionTimeOutInterval"].Value = (this.connectionTimeOutInterval.Text.Trim() == "" ? "0" : this.connectionTimeOutInterval.Text.Trim());
-            cfg.AppSettings.Settings["IsHaveModBus"].Value = (this.isHaveModBus.Checked == true ? "1" : "0");
+            string deviceType = "";
+            if (this.isHaveModBus.Checked && this.isBatteryDevice.Checked)
+            {
+                deviceType = "3";
+            }
+            else if (this.isHaveModBus.Checked && !this.isBatteryDevice.Checked)
+            {
+                deviceType = "2";
+            }
+            else if (this.isBatteryDevice.Checked && !this.isHaveModBus.Checked)
+            {
+                deviceType = "1";
+            }
+            cfg.AppSettings.Settings["IsHaveModBus"].Value = deviceType;
             cfg.AppSettings.Settings["ModBusQueryInterval"].Value = (this.modBusQueryInterval.Text.Trim() == "" ? "0" : this.modBusQueryInterval.Text.Trim());
             string db = ConfigurationManager.AppSettings["db"];
             string[] dbParamArr = db.Split(';');
@@ -106,7 +119,19 @@ namespace NB_IOT_TCP_HP_SOCKET
             }
             this.connectionTimeOut.Text = ConnectionTimeOut;
             this.connectionTimeOutInterval.Text = ConnectionTimeOutInterval;
-            this.isHaveModBus.Checked = (IsHaveModBus == "1");
+            if ("1".Equals(IsHaveModBus))
+            {
+                this.isBatteryDevice.Checked = true;
+            }
+            else if ("2".Equals(IsHaveModBus))
+            {
+                this.isHaveModBus.Checked = true;
+            }
+            else if ("3".Equals(IsHaveModBus))
+            {
+                this.isHaveModBus.Checked = true;
+                this.isBatteryDevice.Checked = true;
+            }
             this.modBusQueryInterval.Text = ModBusQueryInterval;
         }
 

+ 1 - 1
NB_IOT_TCP_HP_SOCKET/WWKJUtil/CellMonitorDeviceType.cs

@@ -176,7 +176,7 @@ namespace NB_IOT_TCP_HP_SOCKET.WWKJUtil
 
         private static void LoadXML()
         {
-            xmlDoc.Load(AppDomain.CurrentDomain.BaseDirectory + @"\CONF\DataCellConfig.xml");
+            xmlDoc.Load(AppDomain.CurrentDomain.BaseDirectory + @"\CONF\CommDevice_Config.xml");
         }
 
         public string AnalogRegisterCount

+ 131 - 0
NB_IOT_TCP_HP_SOCKET/WWKJUtil/ConfigInfo.cs

@@ -0,0 +1,131 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Xml;
+
+namespace NB_IOT_TCP_HP_SOCKET.WWKJUtil
+{
+    public static class ConfigInfo
+    {
+        public static Dictionary<string, List<string>> DicAddress = new Dictionary<string, List<string>>();
+        private static string FileName = (AppDomain.CurrentDomain.BaseDirectory + @"\CONF\TransDevice_Config.xml");
+        private static Dictionary<string, DeviceType> list = new Dictionary<string, DeviceType>();
+        private static XmlDocument XmlDoc = new XmlDocument();
+
+        static ConfigInfo()
+        {
+            try
+            {
+                XmlDoc.Load(FileName);
+                XmlNodeList list = XmlDoc.SelectNodes("/Configration/TD_PSProtocol");
+                foreach (XmlNode node in list)
+                {
+                    DeviceType type = new DeviceType(node["TemplateID"].InnerText, node["SysIdentifyCode"].InnerText, node["SourceAddress"].InnerText, node["HeartBeatInterval"].InnerText, node["UsingPSProtocol"].InnerText, node["GPRSDeviceType"].InnerText, node["UsingSystemKey"].InnerText);
+                    if ((node["DataChannelUnEnabledCheckInterval"] != null) && (node["DataChannelUnEnabledCheckInterval"].InnerText.Trim() != ""))
+                    {
+                        type.DataChannelUnEnabledCheckInterval = node["DataChannelUnEnabledCheckInterval"].InnerText.Trim();
+                    }
+                    if (type.GPRSDeviceType == "短信")
+                    {
+                        XmlNode xnParent = node["ActiveCode"];
+                        if (xnParent == null)
+                        {
+                            xnParent = CreateNewParamNodeReturn(node, "ActiveCode", "", "激活码参数,短信时看此参数");
+                            CreateNewParamNode(xnParent, "Using", "false", "是否发送激活码,true或false");
+                            CreateNewParamNode(xnParent, "SendCycle", "60", "激活码发送周期,单位秒");
+                            CreateNewParamNode(xnParent, "SendFrequency", "2", "周期内间隔多长时间发一次,单位秒");
+                            CreateNewParamNode(xnParent, "ReceiveTimeOut", "5", "接收超时,本周期内如超过此时间仍收不到短信,则不再发送激活码,单位秒");
+                            XmlDoc.Save(FileName);
+                        }
+                        else
+                        {
+                            XmlNodeList childNodes = xnParent.ChildNodes;
+                            foreach (XmlNode node3 in childNodes)
+                            {
+                                string localName = node3.LocalName;
+                                if (localName != null)
+                                {
+                                    if (!(localName == "Using"))
+                                    {
+                                        if (localName == "SendCycle")
+                                        {
+                                            goto Label_027D;
+                                        }
+                                        if (localName == "SendFrequency")
+                                        {
+                                            goto Label_028D;
+                                        }
+                                        if (localName == "ReceiveTimeOut")
+                                        {
+                                            goto Label_029D;
+                                        }
+                                    }
+                                    else
+                                    {
+                                        type.ActiveCode_Using = node3.InnerText;
+                                    }
+                                }
+                                goto Label_02AF;
+                            Label_027D:
+                                type.ActiveCode_SendCycle = node3.InnerText;
+                                goto Label_02AF;
+                            Label_028D:
+                                type.ActiveCode_SendFrequency = node3.InnerText;
+                                goto Label_02AF;
+                            Label_029D:
+                                type.ActiveCode_ReceiveTimeOut = node3.InnerText;
+                            Label_02AF: ;
+                            }
+                        }
+                    }
+                    if (!ConfigInfo.list.ContainsKey(type.TemplateID))
+                    {
+                        ConfigInfo.list.Add(type.TemplateID, type);
+                    }
+                }
+                XmlNodeList list3 = XmlDoc.SelectNodes("/Configration/TD_PSProtocolAddress/设备起始地址");
+                if (list3 != null)
+                {
+                    foreach (XmlNode node4 in list3)
+                    {
+                        List<string> list4 = new List<string>();
+                        list4.Add(node4["起始地址"].InnerText);
+                        list4.Add(node4["设备地址"].InnerText);
+                        DicAddress.Add(node4["设备型号"].InnerText, list4);
+                    }
+                }
+            }
+            catch (Exception)
+            {
+            }
+        }
+
+        private static void CreateNewParamNode(XmlNode xnParent, string strNewParamName, string strNewParamValue, string strComment)
+        {
+            XmlComment newChild = XmlDoc.CreateComment(strComment);
+            XmlElement element = XmlDoc.CreateElement(strNewParamName);
+            element.InnerText = strNewParamValue;
+            xnParent.AppendChild(newChild);
+            xnParent.AppendChild(element);
+        }
+
+        private static XmlElement CreateNewParamNodeReturn(XmlNode xnParent, string strNewParamName, string strNewParamValue, string strComment)
+        {
+            XmlComment newChild = XmlDoc.CreateComment(strComment);
+            XmlElement element = XmlDoc.CreateElement(strNewParamName);
+            element.InnerText = strNewParamValue;
+            xnParent.AppendChild(newChild);
+            xnParent.AppendChild(element);
+            return element;
+        }
+
+        public static DeviceType GetDeviceType(string id)
+        {
+            if (list.ContainsKey(id))
+            {
+                return list[id];
+            }
+            return null;
+        }
+    }
+}

+ 149 - 0
NB_IOT_TCP_HP_SOCKET/WWKJUtil/DeviceType.cs

@@ -0,0 +1,149 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace NB_IOT_TCP_HP_SOCKET.WWKJUtil
+{
+    public class DeviceType
+    {
+        private string _activeCode_ReceiveTimeOut = "5";
+        private string _activeCode_SendCycle = "60";
+        private string _activeCode_SendFrequency = "2";
+        private string _activeCode_Using = "false";
+        private string _dataChannelUnEnabledCheckInterval = "120";
+        private string _GPRSDeviceType = "专线";
+        private string _heartBeatInterval = "";
+        private string _sourceAddress = "";
+        private string _sysIdentifyCode = "";
+        private string _templateID = "";
+        private string _usingPSProtocol = "";
+        private string _usingSystemKey = "";
+
+        public DeviceType(string id, string syscode, string sourcecode, string heart, string usingps, string gprstype, string systemkey)
+        {
+            this._templateID = id;
+            this._sysIdentifyCode = syscode;
+            this._sourceAddress = sourcecode;
+            this._heartBeatInterval = heart;
+            this._usingPSProtocol = usingps;
+            this._GPRSDeviceType = gprstype;
+            this._usingSystemKey = systemkey;
+        }
+
+        public string ActiveCode_ReceiveTimeOut
+        {
+            get
+            {
+                return this._activeCode_ReceiveTimeOut;
+            }
+            set
+            {
+                this._activeCode_ReceiveTimeOut = value;
+            }
+        }
+
+        public string ActiveCode_SendCycle
+        {
+            get
+            {
+                return this._activeCode_SendCycle;
+            }
+            set
+            {
+                this._activeCode_SendCycle = value;
+            }
+        }
+
+        public string ActiveCode_SendFrequency
+        {
+            get
+            {
+                return this._activeCode_SendFrequency;
+            }
+            set
+            {
+                this._activeCode_SendFrequency = value;
+            }
+        }
+
+        public string ActiveCode_Using
+        {
+            get
+            {
+                return this._activeCode_Using;
+            }
+            set
+            {
+                this._activeCode_Using = value;
+            }
+        }
+
+        public string DataChannelUnEnabledCheckInterval
+        {
+            get
+            {
+                return this._dataChannelUnEnabledCheckInterval;
+            }
+            set
+            {
+                this._dataChannelUnEnabledCheckInterval = value;
+            }
+        }
+
+        public string GPRSDeviceType
+        {
+            get
+            {
+                return this._GPRSDeviceType;
+            }
+        }
+
+        public string HeartBeatInterval
+        {
+            get
+            {
+                return this._heartBeatInterval;
+            }
+        }
+
+        public string SourceAddress
+        {
+            get
+            {
+                return this._sourceAddress;
+            }
+        }
+
+        public string SysIdentifyCode
+        {
+            get
+            {
+                return this._sysIdentifyCode;
+            }
+        }
+
+        public string TemplateID
+        {
+            get
+            {
+                return this._templateID;
+            }
+        }
+
+        public string UsingPSProtocol
+        {
+            get
+            {
+                return this._usingPSProtocol;
+            }
+        }
+
+        public string UsingSystemKey
+        {
+            get
+            {
+                return this._usingSystemKey;
+            }
+        }
+    }
+}

+ 1 - 1
NB_IOT_TCP_HP_SOCKET/WWKJUtil/EnumCommonClass.cs

@@ -57,7 +57,7 @@
         Battery_Cross = 0x33,
         Battery_EndComm = 0x34,
         Battery_GPRS_Report = 0x31,
-        Battery_Param = 50,
+        Battery_Param = 0x32,
         Battery_SMS_Report = 0x35,
         Battery_SMS_Timing = 0x36,
         Dail_Link = 5,

+ 1 - 1
NB_IOT_TCP_HP_SOCKET/WWKJUtil/ModBusDeviceType.cs

@@ -318,7 +318,7 @@ namespace NB_IOT_TCP_HP_SOCKET.WWKJUtil
                 if (xmlDoc == null)
                 {
                     xmlDoc = new XmlDocument();
-                    xmlDoc.Load(AppDomain.CurrentDomain.BaseDirectory + @"\CONF\DataCellConfig.xml");
+                    xmlDoc.Load(AppDomain.CurrentDomain.BaseDirectory + @"\CONF\CommDevice_Config.xml");
                 }
             }
             catch

+ 50 - 1
NB_IOT_TCP_HP_SOCKET/WWKJUtil/ProtocolAnalysisTools.cs

@@ -186,6 +186,11 @@ namespace NB_IOT_TCP_HP_SOCKET.WWKJUtil
         {
             char ch;
             char ch2;
+            if ((((data[0] == 0x68) && (data[1] == 0xb0))) && (SumCheck(data, 0, data.Length - 2) == data[data.Length - 2]))
+            {
+                return new ResMsg(false, "参数包");
+            }
+
             if (data.Length < 0x17)
             {
                 return new ResMsg(false, "长度过小");
@@ -654,7 +659,7 @@ namespace NB_IOT_TCP_HP_SOCKET.WWKJUtil
         /// <returns></returns>
         public static DataTable GetDeviceList(string transId)
         {
-            string sql = "SELECT a.传输协议参数,c.ID as trandId,c.设备地址,c.设备协议,c.设备协议参数,b.ID as deviceId,b.用户站参数 FROM [传输设备] a, 设备信息 b, 通讯设备 c where b.传输设备ID = a.ID and b.通讯设备ID = c.ID and a.是否启用 = '是' and b.是否启用 = '是'and c.是否启用 = '是' and a.传输协议参数 like '%" + transId +"%'";
+            string sql = "SELECT a.传输协议参数,c.ID as transId,c.名称,c.设备地址,c.设备协议,c.设备协议参数,b.ID as deviceId,b.用户站参数 FROM [传输设备] a, 设备信息 b, 通讯设备 c where b.传输设备ID = a.ID and b.通讯设备ID = c.ID and a.是否启用 = '是' and b.是否启用 = '是'and c.是否启用 = '是' and a.传输协议参数 like '%" + transId +"%'";
             return DBHelper.ExecuteDataTable(sql, CommandType.Text, null);
         }
 
@@ -806,5 +811,49 @@ namespace NB_IOT_TCP_HP_SOCKET.WWKJUtil
                 }
             }
         }
+
+        public static byte[] RandomTime()
+        {
+            int num = new Random().Next(5);
+            TimeSpan span = (TimeSpan)(DateTime.Now.AddSeconds((double)num) - Convert.ToDateTime("2000-01-01 00:00:00"));
+            int totalSeconds = (int)span.TotalSeconds;
+            byte[] buffer = new byte[4];
+            for (int i = 0; i < 4; i++)
+            {
+                buffer[4 - (i + 1)] = (byte)(totalSeconds >> (i * 8));
+            }
+            return buffer;
+        }
+
+        public static string RunTime(int s)
+        {
+            int num = 0;
+            int num2 = 0;
+            int num3 = 0;
+            int num4 = 0;
+            if (s < 60)
+            {
+                num4 = s;
+            }
+            else if ((60 <= s) && (s <= 0xe10))
+            {
+                num3 = s / 60;
+                num4 = s % 60;
+            }
+            else if ((0xe10 <= s) && (s <= 0x15180))
+            {
+                num2 = s / 0xe10;
+                num3 = (s % 0xe10) / 60;
+                num4 = (s % 0xe10) % 60;
+            }
+            else
+            {
+                num = s / 0x15180;
+                num2 = (s % 0x15180) / 0xe10;
+                num3 = ((s % 0x15180) % 0xe10) / 60;
+                num4 = ((s % 0x15180) % 0xe10) % 60;
+            }
+            return ("系统持续运行:" + num.ToString() + "天" + num2.ToString() + "小时" + num3.ToString() + "分" + num4.ToString() + "秒");
+        }
     }
 }

+ 116 - 0
NB_IOT_TCP_HP_SOCKET/WWKJUtil/RemoteTask.cs

@@ -0,0 +1,116 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+namespace NB_IOT_TCP_HP_SOCKET.WWKJUtil
+{
+    public class RemoteTask
+    {
+        public string TaskDirectory = "";
+        public List<Task> Tasklist = new List<Task>();
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="FilePath"></param>
+        /// <param name="isFirst">是否取第一条</param>
+        public void GetRemoteTaskList(string FilePath, bool isFirst)
+        {
+            this.Tasklist.Clear();
+            this.TaskDirectory = FilePath;
+            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)
+                {
+                    return;
+                }
+                // 将文件按创建时间进行排序
+                Array.Sort(files,new MyDateSorter());
+                foreach (FileInfo info3 in files)
+                {
+                    Task item = this.InitTask(info3.Name);
+                    this.Tasklist.Add(item);
+                    // 如果是只取第一条处理后直接跳出循环
+                    if (isFirst)
+                    {
+                        break;
+                    }
+                }
+            }
+        }
+
+        private Task InitTask(string fileName)
+        {
+            Task task = new Task();
+            task.OPDFileName = fileName;
+            string[] strArray = fileName.Split(new char[] { '_' });
+            task.CommDeviceID = strArray[0];
+            task.RunningNumber = strArray[1];
+            task.CommandType = strArray[3];
+            try
+            {
+                FileStream stream = new FileStream(this.TaskDirectory + @"\发送\" + fileName, FileMode.Open, FileAccess.Read);
+                task.SendCode = new byte[stream.Length];
+                stream.Read(task.SendCode, 0, task.SendCode.Length);
+                stream.Close();
+            }
+            catch
+            {
+                return null;
+            }
+            return task;
+        }
+
+        public bool TaskComplete
+        {
+            get
+            {
+                foreach (Task task in this.Tasklist)
+                {
+                    if (task.TaskState != "完成")
+                    {
+                        return false;
+                    }
+                }
+                return true;
+            }
+        }
+    }
+
+    public class MyDateSorter : IComparer
+    {
+        #region IComparer Members  
+        public int Compare(object x, object y)
+        {
+            if (x == null && y == null)
+            {
+                return 0;
+            }
+            if (x == null)
+            {
+                return -1;
+            }
+            if (y == null)
+            {
+                return 1;
+            }
+            FileInfo xInfo = (FileInfo)x;
+            FileInfo yInfo = (FileInfo)y;
+
+
+            //依名稱排序  
+            return xInfo.FullName.CompareTo(yInfo.FullName);//遞增  
+                                                            //return yInfo.FullName.CompareTo(xInfo.FullName);//遞減  
+
+            //依修改日期排序  
+            //return xInfo.LastWriteTime.CompareTo(yInfo.LastWriteTime);//遞增  
+            //return yInfo.LastWriteTime.CompareTo(xInfo.LastWriteTime);//遞減  
+        }
+        #endregion
+    }
+}

+ 1 - 1
NB_IOT_TCP_HP_SOCKET/WWKJUtil/StationType.cs

@@ -240,7 +240,7 @@ namespace NB_IOT_TCP_HP_SOCKET.WWKJUtil
             if (xmlDoc == null)
             {
                 xmlDoc = new XmlDocument();
-                xmlDoc.Load(AppDomain.CurrentDomain.BaseDirectory + @"\CONF\US_Common.xml");
+                xmlDoc.Load(AppDomain.CurrentDomain.BaseDirectory + @"\CONF\UserStation_Config.xml");
             }
         }
 

+ 51 - 0
NB_IOT_TCP_HP_SOCKET/WWKJUtil/Task.cs

@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+namespace NB_IOT_TCP_HP_SOCKET.WWKJUtil
+{
+    public class Task
+    {
+        public string CommandType = "down";
+        public string CommDeviceID = "";
+        public string OPDFileName = "";
+        public byte[] ReceiveCode = new byte[0];
+        public string RunningNumber = "";
+        public byte[] SendCode = new byte[0];
+        public string TaskState = "未完成";
+
+        public void DeleteFile(string directory)
+        {
+            try
+            {
+                File.Delete(directory + @"\发送\" + this.OPDFileName);
+            }
+            catch
+            {
+            }
+        }
+
+        public void OutPutFile(string directory, bool result)
+        {
+            string str = "";
+            if (result)
+            {
+                str = this.OPDFileName.Replace("down", "up");
+            }
+            else
+            {
+                str = this.OPDFileName.Replace("down", "err");
+            }
+            try
+            {
+                FileStream stream = new FileStream(directory + @"\接收\" + str, FileMode.Create, FileAccess.Write);
+                stream.Write(this.ReceiveCode, 0, this.ReceiveCode.Length);
+                stream.Close();
+            }
+            catch
+            {
+            }
+        }
+    }
+}