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(5000); } } } 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 { //如果运行程序后,在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)//20170926 九牧卫浴现场可能在10秒钟内申请任务,导致路径不可用 { 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]; //if (devinfo1.DeviceKind >= 6 && devinfo1.DeviceKind <= 30) continue;//20130226richard.liu #region 设备被停用 //20130306richard.liu if (dv.Find(devindex) >= 0)//20130306richard.liu { string NOCheck = "13007;13008;13023;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()); 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"); 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_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 { //if (devInx == 14102) //{ //} 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) //故障解除时记录故障结束时间 { //20181025 注释掉 //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(); } } } }