using System; using System.Collections.Generic; using System.Text; using System.Data; using DBFactory; using CommonLib; using System.Threading; 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 { Thread.Sleep(200); } } //if (mythread != null && exitThread == true) //{ // mythread.Abort(); // mythread = null; //} } public static void EndListen() {//20091107 exitThread = true; if (mythread != null) { 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 { bool updateroute = false; if (CStaticClass.routetime.AddSeconds(10) <= DateTime.Now) { 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 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]; //if (devinfo1.DeviceKind >= 6 && devinfo1.DeviceKind <= 30) continue;//20130226richard.liu #region 设备被停用 //20130306richard.liu if (dv.Find(devindex) >= 0)//20130306richard.liu { if (updateroute == true) {//20100131 UpdateErrorCode(devinfo1.DeviceIndex, 998); AlterRoute(devinfo1.DeviceIndex, 998); } //20090926 if (devinfo1.ErrorCode != 998) { UpdateErrorCode(devinfo1.DeviceIndex, 998); 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>0 and F_DeviceIndex=").Append(devInx); dv = dbo.ExceSQL(sql.ToString()).Tables[0].DefaultView; for (int i = 0; i < dv.Count; i++) { string stardev = dbo.GetSingle("select f_startdevice from t_base_route where f_routeid=" + dv[i]["f_routeid"]).ToString(); string enddev = dbo.GetSingle("select f_enddevice from t_base_route where f_routeid=" + dv[i]["f_routeid"]).ToString(); if (state >= 30) { //所有子路径都不可用时,方才设定此路径真的不可用 sql.Remove(0, sql.Length); 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_DeviceKindIndex=1 or F_DeviceKindIndex=2 ) and F_DBW2Address is not null and F_DeviceOrder >0 and T_Base_Route_Device.F_DeviceIndex = T_Base_Device.F_DeviceIndex").Append( " 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()); sql.Remove(0, sql.Length); sql.Append("update IO_CONTROL_ROUTE set CONTROL_ROUTE_STATUS=0 where CONTROL_ROUTE_CODE='").Append(stardev).Append("-").Append(enddev).Append("' and CONTROL_ROUTE_STATUS=1"); if (ups > 0) 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_CODE='").Append(stardev).Append("-").Append(enddev).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_DeviceKindIndex=1 or F_DeviceKindIndex=2 ) 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_CODE='").Append(stardev).Append("-").Append(enddev).Append("' and CONTROL_ROUTE_STATUS=0"); if (ups > 0) dboMan.ExceSQL(sql.ToString()); } } } } return true; } catch (Exception ex) { _CParsePLCError = string.Format("解析PLC反馈数据的修改路径时发生错误:{0}", 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) { //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(); } } }