|
@@ -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; }
|