using System; using System.Collections.Generic; using System.Text; using System.Data; using DBFactory; using CommonLib; using System.Threading; using System.Linq; namespace WcfControlMonitorLib { /// /// Creator:Richard.liu /// 动态计算路径可用状态 /// public static class CParsePLCData { public static event RefreshMonitorEventHandler RefreshMonitor; public static void OnRefreshMonitor(RefreshMonitorEventArgs e) { if (RefreshMonitor != null) { RefreshMonitor(e); } } public static event CDeviceStateChangeEventHandler DeviceStateChange; public static void OnDeviceStateChange(object sender,CDeviceStateChangeEventArgs e) { if (DeviceStateChange != null) { DeviceStateChange(sender, e); } } static StringBuilder sql = new StringBuilder(); static string _CParsePLCError = "";//监控调度类错误说明 public static string CParsePLCError { get { return _CParsePLCError; } set { _CParsePLCError = value; } } public class AltDeviceInfos { public int DeviceIndex; public int DeviceKind; public int RunState; public int TaskNo; public int ErrorCode; } static DBOperator dbo =new DBOperator();//20130926 static DBOperator dboMan = CStaticClass.dboM;//20130926 static Dictionary _modifyPathDeviceInfo; static object lockThis = new object(); /// /// 添加可以改道设备信息 /// public static void AddModifyPathDeviceInfo() { lock (lockThis) { DataView dv1 = new DataView(); _modifyPathDeviceInfo = new Dictionary(); sql.Remove(0, sql.Length); sql.Append("select * from T_Base_Device where (F_DeviceKindIndex=1 or F_DeviceKindIndex=2 or F_DeviceKindIndex=4) and F_DBW2Address is not null order by F_DeviceIndex asc");//20130226richard.liu DataView dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; for (int i = 0; i < dv.Count; i++) { AltDeviceInfos devinfo = new AltDeviceInfos(); devinfo.DeviceIndex = Convert.ToInt32(dv[i]["F_DeviceIndex"]); devinfo.DeviceKind = Convert.ToInt32(dv[i]["F_DeviceKindIndex"]); if (_modifyPathDeviceInfo.ContainsKey(Convert.ToInt32(dv[i]["F_DeviceIndex"])) == false) { _modifyPathDeviceInfo.Add(Convert.ToInt32(dv[i]["F_DeviceIndex"]), devinfo); } } } } public static void SetModifyPathDeviceInfo(int devindex,AltDeviceInfos altdev) { lock (lockThis) { _modifyPathDeviceInfo[devindex].ErrorCode = altdev.ErrorCode; _modifyPathDeviceInfo[devindex].RunState = altdev.RunState; _modifyPathDeviceInfo[devindex].TaskNo = altdev.TaskNo; } } //static Thread mythreadRoute; static Thread mythread; static bool exitThread = false;//20091107 private static void BeginListen() {//20091107 while (!exitThread ) { try { lock (lockThis) {//20130226richard.liu SetDeviceState(); } } catch (Exception ex) { _CParsePLCError =ex.StackTrace+ ex.Message; } finally { //add for CATL YB2 5000 Thread.Sleep(5000); } } } public static void EndListen() {//20091107 exitThread = true; // add for CATL YB2 线程停用方法有问题 if (mythread != null) { //add for CATL 阻塞调度用的所有线程,使当前线程终止 mythread.Join(); // stopped 当前线程 mythread.Interrupt(); if (mythread.ThreadState == ThreadState.Stopped) { // mythread.Abort(); mythread = null; } } } public static void StartListen() { AddModifyPathDeviceInfo(); //20091107 exitThread = false; mythread = new Thread(new ThreadStart(BeginListen)); mythread.IsBackground = true; mythread.Start(); } /// /// 取得指定设备索引的设备状态:[0]读写标志;[1]状态;[2]任务号;[3]X坐标;[4]Y坐标;[5]设备索引 /// /// 设备索引 /// public static int[] GetModifyPathDeviceState(int deviceIdx) { int[] states = new int[6] { 1, 0, 0, 0, 0, deviceIdx }; Model.MDevice mdevinfo = Model.CGetInfo.GetModifyPathDeviceInfo(deviceIdx); if (mdevinfo != null) { states[1] = mdevinfo.ErrorCode; states[2] = mdevinfo.TaskNo; return states; } else { return null; } } /// /// 设置所有设备的当前动态属性 /// public static void SetDeviceState() { DataView dvv = new DataView(); DataView dv = new DataView();//20130306richard.liu try { //如果运行程序后,在10秒钟以内打开命令开关updateroute = false,如果在10秒钟之后打开命令开关updateroute = true;,可以在打开命令开关时CStaticClass.routetime = DateTime.Now; bool updateroute = false; //if (CStaticClass.routetime.AddSeconds(10) <= DateTime.Now) if (CStaticClass.routetime.AddSeconds(5) <= DateTime.Now)//可能在10秒钟内申请任务,导致路径不可用C { updateroute = true; CStaticClass.routetime = DateTime.Now; } sql.Remove(0, sql.Length);//20130306richard.liu sql.Append("SELECT F_DeviceIndex FROM T_Base_Device WHERE (F_LockedState = - 1) and (F_DeviceKindIndex=1 or F_DeviceKindIndex=2 or F_DeviceKindIndex=4) and F_DBW2Address is not null");//20130306richard.liu// and F_DeviceIndex !=13007 and F_DeviceIndex != 13008 and F_DeviceIndex != 13023 and F_DeviceIndex !=13024 dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView;//20130306richard.liu dv.Sort = "F_DeviceIndex";//20130306richard.liu int[] States; foreach (int devindex in _modifyPathDeviceInfo.Keys) { AltDeviceInfos devinfo1 = _modifyPathDeviceInfo[devindex]; #region 增加设备停用状态代码 add for catl YB3 调试禁用时电气更新状态 调度状态变化 //设备停用时候电气上报状态 原来方法会将状态更新 禁用失效 所以增加这个 DataView errorCode = dbo.ExceSQL(string.Format("SELECT f_errorcode FROM T_BASE_DEVICE WHERE f_errorcode = '998' and f_deviceindex = {0}", devinfo1.DeviceIndex)).Tables[0].DefaultView; if (errorCode.Count > 0) { devinfo1.RunState = 4; } #endregion //if (devinfo1.DeviceKind >= 6 && devinfo1.DeviceKind <= 30) continue;//20130226richard.liu #region 设备被停用 //20130306richard.liu if (dv.Find(devindex) >= 0)//20130306richard.liu { // 这个瞎填的几个数 配置 不修改路径状态的 kkk //string NOCheck = "13250;13456;13123;13024"; //if (updateroute == true) //{//20100131 // UpdateErrorCode(devinfo1.DeviceIndex, 998); // if (!NOCheck.Contains(devindex.ToString())) // { // AlterRoute(devinfo1.DeviceIndex, 998); // } //} //20090926 if (devinfo1.ErrorCode != 998) { UpdateErrorCode(devinfo1.DeviceIndex, 998); //if (!NOCheck.Contains(devindex.ToString())) //{ AlterRoute(devinfo1.DeviceIndex, 998); //} devinfo1.RunState = 4; } devinfo1.ErrorCode = 998; } #endregion else { #region 输送机类 if (devinfo1.DeviceKind == 2)//20130226richard.liu { { States = GetModifyPathDeviceState(devinfo1.DeviceIndex); if (States == null) continue; if (States[1] >= 30) { if (updateroute == true) {//20100131 UpdateErrorCode(devinfo1.DeviceIndex, States[1]); AlterRoute(devinfo1.DeviceIndex, States[1]); } //20100131 //修改路径表 if (States[1] != devinfo1.ErrorCode) { UpdateErrorCode(devinfo1.DeviceIndex, States[1]); AlterRoute(devinfo1.DeviceIndex, States[1]); } devinfo1.ErrorCode = States[1]; devinfo1.RunState = 2; } else if ((States[1] == 0) || (States[1] == 1) || (States[1] == 2)) { if (updateroute == true) {//20100131 UpdateErrorCode(devinfo1.DeviceIndex, 0); AlterRoute(devinfo1.DeviceIndex, States[1]); } //20100131 //修改路径表 if (States[1] != devinfo1.ErrorCode) { UpdateErrorCode(devinfo1.DeviceIndex, 0); AlterRoute(devinfo1.DeviceIndex, States[1]); } //20090926 if (States[1] == 2) { //20090920 devinfo1.RunState = 5; } else { devinfo1.RunState = States[1]; } //20100131 //20091006 devinfo1.ErrorCode = States[1]; //20090926 } devinfo1.TaskNo = States[2]; //20101118 } } #endregion #region 移动设备类 if ((devinfo1.DeviceKind == 1) || (devinfo1.DeviceKind == 4)) { States = GetModifyPathDeviceState(devinfo1.DeviceIndex); if (States == null) continue; if (States[1] >= 30) { if (updateroute == true) {//20100131 UpdateErrorCode(devinfo1.DeviceIndex, States[1]); AlterRoute(devinfo1.DeviceIndex, States[1]); } //修改路径表 if (States[1] != devinfo1.ErrorCode) { //20100131 UpdateErrorCode(devinfo1.DeviceIndex, States[1]); AlterRoute(devinfo1.DeviceIndex, States[1]); } devinfo1.ErrorCode = States[1]; devinfo1.RunState = 2; } else if ((States[1] == 0) || (States[1] == 1) || (States[1] == 2)) { if (updateroute == true) {//20100131 UpdateErrorCode(devinfo1.DeviceIndex, 0); AlterRoute(devinfo1.DeviceIndex, States[1]); } //修改路径表 if (States[1] != devinfo1.ErrorCode) { //20100131 UpdateErrorCode(devinfo1.DeviceIndex, 0); AlterRoute(devinfo1.DeviceIndex, States[1]); } //20090926 if (States[1] == 2) { //20090920 devinfo1.RunState = 5; } else { devinfo1.RunState = States[1]; } //20100131 devinfo1.ErrorCode = States[1]; } devinfo1.TaskNo = States[2]; } #endregion } SetModifyPathDeviceInfo(devindex, devinfo1); } } catch (Exception exa) { _CParsePLCError = string.Format("解析PLC反馈数据的记录设备状态时发生错误:{0}", exa.StackTrace+exa.Message ); RefreshMonitorEventArgs rmea = new RefreshMonitorEventArgs("tsStatus", _CParsePLCError); OnRefreshMonitor(rmea); } finally { dvv.Dispose(); } } /// /// 修改本地路径表、反馈给管理的路径表 /// /// 发生故障的设备索引 /// public static bool AlterRoute(int devInx, int state) { DataView dvr = new DataView(); DataView dv1 = new DataView(); DataView dv = new DataView(); try { #region 根据堆垛机修改管理巷道是否可用 //if ((devInx >= 11001) && (devInx <= 11003)) //{//20110405表名:WH_LANEWAY 字段:WAREHOUSE_CODE:仓库编码-01、03、04 LANEWAY_CODE:巷道编码-1、2、3 // //DEVICE_FLAG:设备状态-0=不可用;1=可用 // string LANEWAY_CODE = devInx.ToString().Substring(4,1); // int DEVICE_FLAG=-1; // if (state >= 30) // { // DEVICE_FLAG =0; // } // else // { // DEVICE_FLAG =1; // } // sql.Remove(0, sql.Length); // sql.Append("update WH_LANEWAY set DEVICE_FLAG=").Append(DEVICE_FLAG).Append(" where WAREHOUSE_CODE='01' and LANEWAY_CODE='").Append(LANEWAY_CODE).Append("' and DEVICE_FLAG<>").Append(DEVICE_FLAG); // dboMan.ExceSQL(sql.ToString()); //} #endregion sql.Remove(0, sql.Length); sql.Append("select distinct F_RouteID from T_Base_Route_Device where F_DeviceOrder!=-1 and F_DeviceIndex=").Append(devInx);//F_DeviceOrder>0 and 20170927 //sql.Append("select distinct F_RouteID from T_Base_Route_Device where F_DeviceOrder>0 and F_DeviceIndex=").Append(devInx); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; for (int i = 0; i < dv.Count; i++) { if (state >= 30) { //所有子路径都不可用时,方才设定此路径真的不可用 sql.Remove(0, sql.Length); // " FROM T_Base_Route_Device,T_Base_Device where (F_DeviceKindIndex=1 or F_DeviceKindIndex=2 or F_DeviceKindIndex=4) and F_DBW2Address is not null and F_DeviceOrder >0 and T_Base_Route_Device.F_DeviceIndex = T_Base_Device.F_DeviceIndex").Append( sql.Append(" SELECT T_Base_Route_Device.F_RouteIDSub, SUM(T_Base_Device.F_ErrorCode) AS ErrorCodes ").Append( " FROM T_Base_Route_Device,T_Base_Device where ( F_DeviceOrder!=-1 ) and (F_DeviceKindIndex=1 or F_DeviceKindIndex=2 or F_DeviceKindIndex=4) and F_DBW2Address is not null and T_Base_Route_Device.F_DeviceIndex = T_Base_Device.F_DeviceIndex").Append( //20170927 " and T_Base_Route_Device.F_RouteID=").Append(dv[i]["F_RouteID"]).Append(" GROUP BY T_Base_Route_Device.F_RouteIDSub ");//20130226richard.liu dvr = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; bool ifUsable = false; for (int kk = 0; kk < dvr.Count; kk++) { if (Convert.ToInt32(dvr[kk]["ErrorCodes"]) <= 0) { ifUsable = true; break; } } if (ifUsable == false) { //20101011 sql.Remove(0, sql.Length); sql.Append("update t_base_route set F_Status=0 where f_routeid=").Append(dv[i]["F_RouteID"]).Append(" and F_Status=1 and F_AutoUpdate=1 "); int ups = dbo.ExecuteSql(sql.ToString()); //add for catl FD3 给管理更新路径永远可用 推土机设备正常 就路径可用 string[] NoRouteID1 = { "175", "176", "177", "178","179", "180", "181", "182","183","184","185","186"};//18001 string[] NoRouteID2= { "187", "188", "189", "190","191", "192", "193", "194","195","196","197","198"};//18002 string[] NoRouteID3 = { "233", "234", "235", "236","237", "238", "239", "240","241","242","243","244"};//18003 string[] NoRouteID4 = { "245", "246", "247", "248","249", "250", "251", "252","253","254","255","256"};//18004 if (NoRouteID1.Contains(dv[i]["F_RouteID"].ToString()) || NoRouteID2.Contains(dv[i]["F_RouteID"].ToString()) || NoRouteID3.Contains(dv[i]["F_RouteID"].ToString()) || NoRouteID4.Contains(dv[i]["F_RouteID"].ToString())) { int intRDevice = 0; if (NoRouteID1.Contains(dv[i]["F_RouteID"].ToString())) { intRDevice = 10001; } else if (NoRouteID2.Contains(dv[i]["F_RouteID"].ToString())) { intRDevice = 10002; } else if (NoRouteID3.Contains(dv[i]["F_RouteID"].ToString())) { intRDevice = 10003; } else if (NoRouteID4.Contains(dv[i]["F_RouteID"].ToString())) { intRDevice = 10004; } //sql.Remove(0, sql.Length); //sql.Append("select f_deviceindex from T_BASE_DEVICE where f_devicekindindex = 1 and f_deviceindex= ").Append(devInx); //DataView Route = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (intRDevice == 0) { return true; } //判断堆垛机状态 堆垛机可用路径就是可用 Model.MDevice devinforoute; devinforoute = Model.CGetInfo.GetDeviceInfo(intRDevice); if (devinforoute.RunState <= 1 && devinforoute.RunState !=5) { sql.Remove(0, sql.Length); sql.Append("update IO_CONTROL_ROUTE set CONTROL_ROUTE_STATUS=1 where CONTROL_ROUTE_ID='").Append(dv[i]["F_RouteID"]).Append("' and CONTROL_ROUTE_STATUS=0"); } else { sql.Remove(0, sql.Length); sql.Append("update IO_CONTROL_ROUTE set CONTROL_ROUTE_STATUS=0 where CONTROL_ROUTE_ID='").Append(dv[i]["F_RouteID"]).Append("' and CONTROL_ROUTE_STATUS=1"); } } else { sql.Remove(0, sql.Length); sql.Append("update IO_CONTROL_ROUTE set CONTROL_ROUTE_STATUS=0 where CONTROL_ROUTE_ID='").Append(dv[i]["F_RouteID"]).Append("' and CONTROL_ROUTE_STATUS=1"); } dboMan.ExceSQL(sql.ToString()); } else { //20120328有一条子路径可用,路径就可用 sql.Remove(0, sql.Length); sql.Append("update t_base_route set F_Status=1 where f_routeid=").Append(dv[i]["F_RouteID"]).Append(" and F_Status=0 and F_AutoUpdate=1 "); int ups = dbo.ExecuteSql(sql.ToString()); sql.Remove(0, sql.Length); sql.Append("update IO_CONTROL_ROUTE set CONTROL_ROUTE_STATUS=1 where CONTROL_ROUTE_ID='").Append(dv[i]["F_RouteID"]).Append("' and CONTROL_ROUTE_STATUS=0"); if (ups > 0) dboMan.ExceSQL(sql.ToString()); } } else { sql.Remove(0, sql.Length); sql.Append("SELECT SUM(T_Base_Device.F_ErrorCode) as errcode FROM T_Base_Device ,T_Base_Route_Device").Append( " where ( F_DeviceOrder!=-1 ) and (F_DeviceKindIndex=1 or F_DeviceKindIndex=2 or F_DeviceKindIndex=4) and F_DBW2Address is not null and T_Base_Device.F_DeviceIndex = T_Base_Route_Device.F_DeviceIndex and T_Base_Route_Device.F_RouteID=").Append(dv[i]["F_RouteID"]);//20170927 //" where (F_DeviceKindIndex=1 or F_DeviceKindIndex=2 or F_DeviceKindIndex=4) and F_DBW2Address is not null and F_DeviceOrder>0 and T_Base_Device.F_DeviceIndex = T_Base_Route_Device.F_DeviceIndex and T_Base_Route_Device.F_RouteID=").Append(dv[i]["F_RouteID"]);//20130226richard.liu dv1 = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; if (dv1.Count > 0) { int errcode = 0; int a = 0; if (int.TryParse(dv1[0]["errcode"].ToString(), out a) == true) { errcode = Convert.ToInt32(dv1[0]["errcode"]); } if (errcode <= 0) { //20101011 sql.Remove(0, sql.Length); sql.Append("update t_base_route set F_Status=1 where f_routeid=").Append(dv[i]["F_RouteID"]).Append(" and F_Status=0 and F_AutoUpdate=1 "); int ups = dbo.ExecuteSql(sql.ToString()); sql.Remove(0, sql.Length); sql.Append("update IO_CONTROL_ROUTE set CONTROL_ROUTE_STATUS=1 where CONTROL_ROUTE_ID='").Append(dv[i]["F_RouteID"]).Append("' and CONTROL_ROUTE_STATUS=0"); if (ups > 0) dboMan.ExceSQL(sql.ToString()); } } } } return true; } catch (Exception ex) { _CParsePLCError = string.Format("解析PLC反馈数据的修改路径时发生错误,设备:{0},状态:{1},异常:{2}", devInx,state, ex.StackTrace+ex.Message ); RefreshMonitorEventArgs rmea = new RefreshMonitorEventArgs("tsStatus", _CParsePLCError); OnRefreshMonitor(rmea); return false; } finally { dv.Dispose(); dvr.Dispose(); dv1.Dispose(); } } static void UpdateErrorCode(int devInx, int errorCode) { #region 原来的程序 ////20130226richard.liu //sql.Clear(); //sql.Append("SELECT F_DeviceErrorIndex FROM T_Base_Device_State where F_DeviceKindIndex=").Append(_modifyPathDeviceInfo[devInx].DeviceKind).Append(" and F_DeviceErrorIndex=").Append(errorCode); //DataView dv = dbo.程序ExceSQL(sql.ToString()).Tables[0].DefaultView; //if (dv.Count > 0) //{ // sql.Clear(); // sql.Append("UPDATE T_Base_Device SET F_ErrorCode = ").Append(errorCode).Append(" WHERE (F_DeviceIndex = ").Append(devInx).Append(")and (F_ErrorCode <> ").Append(errorCode).Append(")"); // CStaticClass.dbo.ExecuteSql(sql.ToString());//20130306richard.liu使用主线程数据连接修改,以免造成UPDATE并发 //} //dv.Dispose(); #endregion DataView dv = new DataView(); int errorindex = 0; try { string sqlstr = string.Format("SELECT F_DeviceIndex,F_ErrorTaskNo,F_ErrorCode FROM T_Base_Device where F_DeviceIndex={0} and F_ErrorCode!={1}", devInx, errorCode);//查找故障设备 dv = dbo.ExceSQL(sqlstr).Tables[0].DefaultView; //sql.Append("SELECT F_DeviceErrorIndex FROM T_Base_Device_State where F_DeviceKindIndex=").Append(_modifyPathDeviceInfo[devInx].DeviceKind).Append(" and F_DeviceErrorIndex=").Append(errorCode); if (dv.Count > 0)//状态发生变化之后才更新状态 { if (errorCode > 0) { Model.MError errs = Model.CGetInfo.GetErrorInfo(Convert.ToInt32(_modifyPathDeviceInfo[devInx].DeviceKind + errorCode.ToString())); if (errs == null) { return; } errorindex = errs.ErrorIndex; } string str = string.Empty; if (errorCode == 0) { str = string.Format(",F_ErrorTaskNo=0 "); } sqlstr = string.Format("UPDATE T_Base_Device SET F_ErrorCode = {0}{1} WHERE (F_DeviceIndex = {2})and (F_ErrorCode <> {3})", errorCode, str, devInx, errorCode); //sql.Clear(); //sql.Append("UPDATE T_Base_Device SET F_ErrorCode = ").Append(errorCode).Append(" WHERE (F_DeviceIndex = ").Append(devInx).Append(")and (F_ErrorCode <> ").Append(errorCode).Append(")"); int count = CStaticClass.dbo.ExecuteSql(sqlstr);//20130306richard.liu使用主线程数据连接修改,以免造成UPDATE并发 //全部注释 //if (count > 0) //故障解除时记录故障结束时间 //{ // 注释掉 //string dtime = DateTime.Now.ToString("u");//20110603 //dtime = dtime.Substring(0, dtime.Length - 1); ////新的故障发生时,先更改上一个故障的结束时间 //sqlstr = string.Format("UPDATE T_Base_Device_Error_Log SET F_End_DateTime ='{0}' Where F_End_DateTime is null and F_DeviceIndex={1} ", dtime, devInx); //CStaticClass.dbo.ExecuteSql(sqlstr);//20130306richard.liu使用主线程数据连接修改,以免造成UPDATE并发 ////新的故障发生,记录 //if (errorCode != 0 && errorCode != 998)//设备被禁用以后,也认为是无故障 //{ // int taskno = _modifyPathDeviceInfo[devInx].TaskNo; // sqlstr = string.Format("INSERT INTO T_Base_Device_Error_Log (F_TaskNo,F_DeviceIndex, F_ErrorIndex, F_DateTime) VALUES ({0},{1},{2},'{3}')", taskno, devInx, errorindex, dtime); // CStaticClass.dbo.ExecuteSql(sqlstr);//20130306richard.liu使用主线程数据连接修改,以免造成UPDATE并发 //} //} } } catch (Exception ex) { throw ex; } finally { dv.Dispose(); } } } }