/// <summary> /// 执行DTU控制任务 /// </summary> /// <param name="state"></param> private static void ExecuteDtuOrder(object state) { //1.锁住客户端对象 //2.找出客户端对应的数据库,并找出需要执行的控制指令。 //3.循环发送指令到客户端,再接收返回的数据,存入数据库。 //4.释放客户端对象 DTUClientInfo client = (DTUClientInfo)state; using (MyLock mylock = new MyLock(client, 20000, false)) { if (mylock.IsTimeout == false) { //LogManager.AddDebug("ControlCommandThread线程:" + Thread.CurrentThread.ManagedThreadId + " 开始锁了 是否超时" + mylock.IsTimeout); //找出这个站点对应的数据库, 并获取数据库连接 SqlConnection connection = GetDbConnectionByTel(client.TelOrGprsId); if (connection == null) //找不到对应的数据库连接 { LogMg.AddDebug(string.Format("根据Tel={0}的设备唯一id,在sysconfig.xml中找不到对应的数据库连接", client.TelOrGprsId.ToString())); return; } SWSDataContext db = new SWSDataContext(connection); takePhoto(db, client.StationId, client); //把那些不需要执行了的数据 state=1 就当这行指令已经执行过了 List <int> giveUpCommands = db.ExecuteQuery <int>("SELECT id FROM dbo.control_command WHERE station_id=" + client.StationId + " AND (state=0 OR state IS NULL) AND id NOT IN (SELECT MAX(id) FROM dbo.control_command WHERE station_id=" + client.StationId + " AND (state=0 OR state IS NULL) GROUP BY gong_kuang_id,read_or_write) ").ToList(); if (giveUpCommands.Count > 0) { db.ExecuteCommand("UPDATE dbo.control_command SET state=1 WHERE id in(" + string.Join(", ", giveUpCommands) + ")"); } //db.ExecuteCommand("UPDATE dbo.control_command SET state=1 WHERE station_id=" + client.StationId + " AND (state=0 OR state IS NULL) AND id NOT IN (SELECT MAX(id) FROM dbo.control_command WHERE station_id=" + client.StationId + " AND (state=0 OR state IS NULL) GROUP BY gong_kuang_id,read_or_write) "); //获取需要执行的指令 List <control_command> commands = db.ExecuteQuery <control_command>("SELECT * FROM dbo.control_command WHERE id IN(SELECT MAX(id) FROM dbo.control_command WHERE station_id=" + client.StationId + " AND communication_mode=2 AND (state=0 OR state IS NULL) GROUP BY gong_kuang_id,read_or_write) ORDER BY add_datetime").ToList(); List <gong_kuang_config> gongKuangs = db.gong_kuang_config.Where(c => c.station_id == client.StationId).ToList(); foreach (control_command command in commands) //循环发送指令 { if (command.COUNT == null) { command.COUNT = 0; } try { gong_kuang_config gongkuang = gongKuangs.SingleOrDefault(c => c.id == command.gong_kuang_id); if (gongkuang == null) //如果找不到command对应和gongkuangid,则把这条command标记为执行失败。 { LogMg.AddError("找不到控制命令所对应的工况配置信息"); command.execute_result = 0; //标记为执行失败 command.state = 1; // 就当已经执行过 command.execute_comment = "执行失败,找不到控制命令所对应的工况配置信息"; command.complete_datetime = DateTime.Now; db.SubmitChanges(); continue; } byte address = (byte)gongkuang.address; ClearSocketCache(client.socket);//清除缓冲区 LogMg.AddDebug("hashcode=" + client.socket.GetHashCode()); ModbusReturn modbusReturn = new ModbusReturn(); if (command.read_or_write == 0) //读读读读读读读读读读读 { while (modbusReturn.success == false && command.COUNT < SysConfig.userProfile.ExecuteFailureCount) { modbusReturn.clear(); modbus.readdata(client.Protocol, client.socket, "", address, ushort.Parse(gongkuang.read_register), int.Parse(gongkuang.function_code), gongkuang.data_type, gongkuang.decode_order, (int)gongkuang.receive_timeout, modbusReturn); //LogManager.AddDebug(String.Format("执行读命令 GPRSID:{0} gongkuangid:{1} address{2} 读寄存器编号:{3} 读取的值{4} 方法的返回bool值:{5}", client.TelOrGprsId, gongkuang.id, address, gongkuang.read_register, value.ToString(), flag)); command.COUNT++; } command.state = 1; //标志为已发送 if (modbusReturn.success == true) { DTU_ClientManager.UpdateLastVisitTime(client, DateTime.Now); command.execute_result = 1; //标记为执行成功 command.value = Convert.ToString(modbusReturn.value); gongkuang.read_value = Convert.ToString(modbusReturn.value); gongkuang.execute_comment = "执行读取操作成功"; if (gongkuang.config_type == "05") { try { test test = db.test.Single(c => c.testid == gongkuang.testid); test.value = Convert.ToString(modbusReturn.value * gongkuang.Multiple + gongkuang.AddNumber); } catch (Exception ex) { LogMg.AddError(ex); LogMg.AddDebug("找不到工况对应的检测点,gongkuangid=" + gongkuang.id + " testid=" + gongkuang.testid); } } } else { command.execute_result = 0; //标记为执行失败 gongkuang.execute_comment = "执行读取操作失败"; } command.execute_comment = modbusReturn.ToString(); } else //写写写写写写写写写写写写写写写 { while (modbusReturn.success == false && command.COUNT < SysConfig.userProfile.ExecuteFailureCount) { modbusReturn.clear(); modbus.writedata(client.Protocol, client.socket, "", address, ushort.Parse(gongkuang.write_register), gongkuang.data_type, (int)gongkuang.receive_timeout, short.Parse(command.value), modbusReturn); //LogManager.AddDebug(String.Format("执行写命令 GPRSID:{0} address{1} 写寄存器编号:{2} 写入的值{3} 方法的返回bool值:{4}", client.TelOrGprsId, address, gongkuang.write_register, command.value, flag)); command.COUNT++; } command.state = 1; //标志为已发送 if (modbusReturn.success == true) { DTU_ClientManager.UpdateLastVisitTime(client, DateTime.Now); command.execute_result = 1; //标记为执行成功 gongkuang.write_value = command.value; gongkuang.execute_comment = "执行写操作成功"; } else { command.execute_result = 0; //标记为执行失败 gongkuang.execute_comment = "执行写操作失败"; } command.execute_comment = modbusReturn.ToString(); } gongkuang.execute_datetime = DateTime.Now; command.complete_datetime = DateTime.Now; } catch (Exception ex) { command.execute_result = 0; //标记为执行失败 command.execute_comment = "执行命令失败,服务程序出现了异常"; // MessageQueue.Enqueue_DataInfo(string.Format("接收时间:【{0}】,站点:{1}, 执行工况配置失败.程序出现异常,请查看日志. ", DateTime.Now, station.name)); LogMg.AddError(ex); } finally { command.complete_datetime = DateTime.Now; } db.SubmitChanges(); } //LogManager.AddDebug("ControlCommandThread线程:" + Thread.CurrentThread.ManagedThreadId + " 释放锁了 "); } else { LogMg.AddDebug("ControlCommandThread 锁失败了"); } } }
private static void ExecuteGD透传Order(object state) { GD_Station gd_station = (GD_Station)state; List <XML_Org> orgs = SysConfig.orgConfig.Orgs.Where(c => c.OrgId == gd_station.OrgId).ToList(); if (orgs == null || orgs.Count == 0) { LogMg.AddError("找不到orgId:" + gd_station.OrgId); return; } XML_Org org = orgs[0]; GuangDaiService.CorePlatformWebServiceClient ws = new GuangDaiService.CorePlatformWebServiceClient(org.gdServerCfg); if (gd_station != null && gd_station.tests != null) { foreach (Clazz.Config.XML_Test test in gd_station.tests) { try { ModbusReturn modbusReturn = new ModbusReturn(); int count = 0; //执行错误的次数 while (modbusReturn.success == false && count < SysConfig.userProfile.ExecuteFailureCount) { modbusReturn.clear(); //LogManager.AddDebug(string.Format("开始接收 时间:{0},站点:{1} testid:{2}", DateTime.Now.ToString(), gd_station.name, test.TestId)); GuangDaiCommunicationModbus.readdata(ws, gd_station.wscId, test.Address, test.RegisterNo, test.FunctionCode, test.DataType, test.DecodeOrder, modbusReturn); // result = modbus.readdata(gd_station.Protocol, gd_station.socket, gd_station.TelOrGprsId, test.Address, test.RegisterNo, test.FunctionCode, test.DataType, test.DecodeOrder, test.ReceiveTimeout, ref value); log.Info("wscId=" + gd_station.wscId + " testid=" + test.TestId + " address=" + test.Address + " " + modbusReturn.ToString()); count++; } if (modbusReturn.success) //接收数据成功 { if (Between(modbusReturn.value * test.Multiple + test.AddNumber, test.Min, test.Max)) //如果值不在取值范围内,则不要 { SWSDataContext db = new SWSDataContext(Util.ServerSocketHelper.GetConnection(gd_station.dbName)); SaveToDatabase(db, test.TestId, modbusReturn.value * test.Multiple + test.AddNumber); //保存数据 LogMg.AddDebug(string.Format("接收时间:{0}, 站点:{1},value:{2},testid:{3}", DateTime.Now.ToString(), gd_station.name, modbusReturn.value * test.Multiple + test.AddNumber, test.TestId)); // MessageQueue.Enqueue_DataInfo(string.Format("接收时间:【{0}】,站点:{1},testid:{2},值:{3}", DateTime.Now.ToString(), station.Name, test.TestId, value * test.Multiple + test.AddNumber)); updateStationOnlineInfo(db, gd_station.stationId); } else { LogMg.AddDebug(string.Format("接收时间:【{0}】,站点:{1},testid:{2},乘以倍率之后的值:{3} 由于值不在范围内[{4},{5}],丢弃", DateTime.Now.ToString(), gd_station.name, test.TestId, modbusReturn.value * test.Multiple + test.AddNumber, test.Min, test.Max)); } } else { //接收数据失败 LogMg.AddDebug(string.Format("数据库名:{0} testid:{1} 接收数据失败 原因:{2}", gd_station.dbName, test.TestId, modbusReturn.ErrorMsg)); // MessageQueue.Enqueue_DataInfo(string.Format("接收时间:【{0}】,站点:{1},testid:{2}, 接收数据失败", DateTime.Now.ToString(), station.Name, test.TestId)); } } catch (SocketException) { } catch (Exception ex) { LogMg.AddError(ex); DEBUG.MsgBox(ex.ToString()); } } } }
private static void ExecuteGuangDai透传Order(object state) { try { Args arg = (Args)state; SWSDataContext db = new SWSDataContext(ConnectStringHelper.GetConnection(SysConfig.userProfile.DbAddress, arg.dbName, SysConfig.userProfile.DbUserName, SysConfig.userProfile.DbPassword)); GuangDaiService.CorePlatformWebServiceClient ws = new GuangDaiService.CorePlatformWebServiceClient(arg.gdServerCfg); SWS_DBDataContext SWS_DB = new SWS_DBDataContext(ConnectStringHelper.GetConnection(SysConfig.userProfile.DbAddress, SysConfig.userProfile.DbName, SysConfig.userProfile.DbUserName, SysConfig.userProfile.DbPassword)); List <guangdai_station_link> links = SWS_DB.guangdai_station_link.ToList(); String wscid = getWscId(arg, db, links); if (String.IsNullOrEmpty(wscid)) { LogMg.AddDebug("站点id=" + arg.station_id + " 找不到对应的wscId"); return; } //把那些不需要执行了的数据 state=1 就当这行指令已经执行过了 List <int> giveUpCommands = db.ExecuteQuery <int>("SELECT id FROM dbo.control_command WHERE station_id=" + arg.station_id + " AND (state=0 OR state IS NULL) AND id NOT IN (SELECT MAX(id) FROM dbo.control_command WHERE station_id=" + arg.station_id + " AND (state=0 OR state IS NULL) GROUP BY gong_kuang_id,read_or_write) ").ToList(); if (giveUpCommands.Count > 0) { db.ExecuteCommand("UPDATE dbo.control_command SET state=1 WHERE id in(" + string.Join(", ", giveUpCommands) + ")"); } //db.ExecuteCommand("UPDATE dbo.control_command SET state=1 WHERE station_id=" + arg.station_id + " AND (state=0 OR state IS NULL) AND id NOT IN (SELECT MAX(id) FROM dbo.control_command WHERE station_id=" + arg.station_id + " AND (state=0 OR state IS NULL) GROUP BY gong_kuang_id,read_or_write) "); //获取需要执行的指令 List <control_command> commands = db.ExecuteQuery <control_command>("SELECT * FROM dbo.control_command WHERE id IN(SELECT MAX(id) as id FROM dbo.control_command WHERE station_id=" + arg.station_id + " AND communication_mode in (5,6) AND tp is Null AND (state=0 OR state IS NULL) GROUP BY gong_kuang_id,read_or_write) ORDER BY add_datetime").ToList(); TakePhotoTp5(db, ws, arg.station_id, wscid); for (int i = 0; i < commands.Count; i++) { control_command command = commands[i]; if (command.COUNT == null) { command.COUNT = 0; } try { gong_kuang_config gongkuang = db.gong_kuang_config.SingleOrDefault(c => c.id == command.gong_kuang_id); if (gongkuang == null) //如果找不到command对应和gongkuangid,则把这条command标记为执行失败。 { LogMg.AddError("找不到控制命令所对应的工况配置信息"); command.execute_result = 0; //标记为执行失败 command.state = 1; // 就当已经执行过 command.execute_comment = "执行失败,找不到控制命令所对应的工况配置信息"; command.complete_datetime = DateTime.Now; db.SubmitChanges(); continue; } ModbusReturn modbusReturn = new ModbusReturn(); byte address = (byte)gongkuang.address; if (command.read_or_write == 0) //读读读读读读读读读读读 { GuangDaiCommunicationModbus.readdata(ws, wscid, address, ushort.Parse(gongkuang.read_register), int.Parse(gongkuang.function_code), gongkuang.data_type, gongkuang.decode_order, modbusReturn); command.state = 1; //标志为已发送 if (modbusReturn.success == true) { command.execute_result = 1; //标记为执行成功 command.value = Convert.ToString(modbusReturn.value); gongkuang.read_value = Convert.ToString(modbusReturn.value); gongkuang.execute_comment = "执行读取操作成功"; if (gongkuang.config_type == "05") { try { test test = db.test.Single(c => c.testid == gongkuang.testid); double multiple = gongkuang.Multiple == null ? 1 : (double)gongkuang.Multiple; double addNumber = gongkuang.AddNumber == null ? 0 : (double)gongkuang.AddNumber; test.value = Convert.ToString(modbusReturn.value * multiple + addNumber); } catch (Exception ex) { LogMg.AddError(ex); LogMg.AddDebug("找不到工况对应的检测点,gongkuangid=" + gongkuang.id + " testid=" + gongkuang.testid); } } } else { command.execute_result = 0; //标记为执行失败 gongkuang.execute_comment = "执行读取操作失败"; } command.execute_comment = modbusReturn.ToString(); } if (command.read_or_write == 1) //写写写写写写写写写写写写写写写 { GuangDaiCommunicationModbus.writedata(ws, wscid, address, ushort.Parse(gongkuang.read_register), int.Parse(gongkuang.function_code), gongkuang.data_type, gongkuang.decode_order, short.Parse(command.value), modbusReturn); // GuangDaiService.config config = ws.doConfig(wscid, Convert.ToInt32(gongkuang.write_register), (int)command.read_or_write, Convert.ToInt32(command.value), ""); // LogManager.AddDebug(String.Format("ws.transmitTransparently({0},{1}, {2}, {3}, {4}) 返回结果是 {5} ", wscid, gongkuang.write_register, command.read_or_write, "-1", "", flag)); command.state = 1; //标志为已发送 if (modbusReturn.success == true) { command.execute_result = 1; //标记为执行成功 gongkuang.write_value = command.value; gongkuang.execute_comment = "执行写操作成功"; } else { command.execute_result = 0; //标记为执行失败 gongkuang.execute_comment = "执行写操作失败"; } command.execute_comment = modbusReturn.ToString(); } gongkuang.execute_datetime = DateTime.Now; command.complete_datetime = DateTime.Now; } catch (Exception ex) { command.execute_result = 0; //标记为执行失败 command.execute_comment = "执行命令失败,服务程序出现了异常"; // MessageQueue.Enqueue_DataInfo(string.Format("接收时间:【{0}】,站点:{1}, 执行工况配置失败.程序出现异常,请查看日志. ", DateTime.Now, station.name)); LogMg.AddError(ex); } finally { command.complete_datetime = DateTime.Now; } try { db.SubmitChanges(); } catch (Exception ex) { LogMg.AddError(ex.ToString()); } } } catch (Exception ex) { Args arg = (Args)state; LogMg.AddError("异常数据库是:" + arg.dbName + " 站点id=" + arg.station_id); LogMg.AddError(ex); } }
private static void ExecuteOrder(object state) { ///第一步:找出需要采集的指标 ///第二步:循环采集的指标,取出一个指标, ///第三步:锁住客户端 ///第四步:采集 ///第五步:释放客户端 ///第六步:回到第二步 ///结束 DTUClientInfo client = (DTUClientInfo)state; Clazz.Config.XML_Station station = SysConfig.DTU_StationConfig.GetStationByTel(client.TelOrGprsId); if (station == null) { return; } List <Clazz.Config.XML_Test> listTest = station.ListTest; if (station != null && listTest != null) { foreach (Clazz.Config.XML_Test test in listTest) { using (MyLock mylock = new MyLock(client, 3000, false)) // 在循环内锁 { if (mylock.IsTimeout == false) { //LogManager.AddDebug("AutoCollectionThread 线程:" + Thread.CurrentThread.ManagedThreadId + " 开始锁了 是否超时" + mylock.IsTimeout); try { ModbusReturn modbusReturn = new ModbusReturn(); int count = 0; //执行错误的次数 while (modbusReturn.success == false && count < SysConfig.userProfile.ExecuteFailureCount) { modbusReturn.clear(); LogMg.AddDebug(string.Format("开始接收 时间:{0},站点:{1} tel:{2},testid:{3}", DateTime.Now.ToString(), client.Name, client.TelOrGprsId.ToString(), test.TestId)); modbus.readdata(client.Protocol, client.socket, client.TelOrGprsId, test.Address, test.RegisterNo, test.FunctionCode, test.DataType, test.DecodeOrder, test.ReceiveTimeout, modbusReturn); count++; } if (modbusReturn.success) //接收数据成功 { DTU_ClientManager.UpdateLastVisitTime(client, DateTime.Now); if (Between(modbusReturn.value * test.Multiple + test.AddNumber, test.Min, test.Max)) //如果值不在取值范围内,则不要 { SWSDataContext db = new SWSDataContext(Util.ServerSocketHelper.GetConnection(station.Org.DBName)); SaveToDatabase(db, test.TestId, modbusReturn.value * test.Multiple + test.AddNumber); //保存数据 LogMg.AddDebug(string.Format("接收时间:{0}, tel:{1},value:{2},testid:{3}", DateTime.Now.ToString(), client.TelOrGprsId.ToString(), modbusReturn.value * test.Multiple + test.AddNumber, test.TestId)); // MessageQueue.Enqueue_DataInfo(string.Format("接收时间:【{0}】,站点:{1},testid:{2},值:{3}", DateTime.Now.ToString(), station.Name, test.TestId, value * test.Multiple + test.AddNumber)); } else { LogMg.AddDebug(string.Format("接收时间:【{0}】,站点:{1},testid:{2},乘以倍率之后的值:{3} 由于值不在范围内[{4},{5}],丢弃", DateTime.Now.ToString(), station.Name, test.TestId, modbusReturn.value * test.Multiple + test.AddNumber, test.Min, test.Max)); } } else { //接收数据失败 LogMg.AddDebug(string.Format("接收数据失败")); // MessageQueue.Enqueue_DataInfo(string.Format("接收时间:【{0}】,站点:{1},testid:{2}, 接收数据失败", DateTime.Now.ToString(), station.Name, test.TestId)); if (modbusReturn.ErrorMsg.Contains("设备未在线")) { return; } } } catch (SocketException) { } catch (Exception ex) { LogMg.AddError(ex); DEBUG.MsgBox(ex.ToString()); } //LogManager.AddDebug("AutoCollectionThread 线程:" + Thread.CurrentThread.ManagedThreadId + " 释放锁了 "); } else { LogMg.AddDebug("AutoCollectionThread 锁失败了"); } } } } }