| using System;  | 
|   | 
| using System.Collections;  | 
| using System.Data.OracleClient;  | 
| using NLog;  | 
|   | 
| namespace CCSTrace.CCS.EventAI  | 
| {  | 
|     public class JudgeCase  | 
|     {  | 
|         private static readonly Logger Logger = LogManager.GetCurrentClassLogger();  | 
|   | 
|         private TraceSubject _mTraceSubject;  | 
|         private readonly ArrayList _mCase = new ArrayList();  | 
|         private readonly int _damageFdrId;  | 
|         private readonly int _damageFsc; // 新案件的損壞設備種類  | 
|         private readonly int _damageUfid; // 新案件的損壞設備編號  | 
|         private int _newCaseId;  | 
|         private string _acceptDate;  | 
|         private ArrayList _newCase;  | 
|         private Hashtable _oldCase;  | 
|         private int _inferFsc; // 推測出可能受損的設備種類  | 
|         private int _inferUfid; // 推測出可能受損的設備編號  | 
|         private int _parentCaseId = 0;  | 
|         private Equipment _equip;  | 
|   | 
|         private readonly OracleConnection _connectionTpc;  | 
|         private readonly OracleTransaction _transaction;  | 
|         private readonly string _traceConnectionString;  | 
|   | 
|         // int Range = 360; //比事故案件還早多久時間內的案件才作合併 單位:分  | 
|   | 
|         public JudgeCase(int fdrId, int fsc, int ufid, int caseId, string acceptDate, OracleConnection connection, OracleTransaction trx, string traceConnection)  | 
|         {  | 
|             _damageFdrId = fdrId;  | 
|             _damageFsc = fsc;  | 
|             _damageUfid = ufid;  | 
|             _newCaseId = caseId;  | 
|             _acceptDate = acceptDate;  | 
|   | 
|             _connectionTpc = connection;  | 
|             _transaction = trx;  | 
|             _traceConnectionString = traceConnection;  | 
|         }  | 
|   | 
|         public void AiBegin()  | 
|         {  | 
|             Logger.Info("進行案件追蹤合併.");  | 
|             // String ToTime = AcceptDate;  | 
|   | 
|             var sqlStmt = "SELECT R.ACCEPTNUM,R.CASEID as CASEID,R.FDRID as FDRID,R.FSC as FSC,R.UFID as UFID,E.CASESTATUS as CASESTATUS,R.EVENTBRIEF as BRIEF "  | 
|                              + "FROM EOS.EVENTRECORD R,EOS.EVENTS E WHERE E.CASEID = R.CASEID AND R.TRACE_FINISH = " + GlobalVariable.TraceStill  | 
|                              + " AND E.CASETYPE <> " + GlobalVariable.ChildCase + " AND R.FDRID = " + _damageFdrId;  | 
|   | 
|             OracleCommand command = null;  | 
|             OracleDataReader reader = null;  | 
|   | 
|             try  | 
|             {  | 
|                 Logger.Info("搜尋同一饋線上可供合併之母案件.");  | 
|                 command = new OracleCommand(sqlStmt, _connectionTpc, _transaction);  | 
|                 reader = command.ExecuteReader();  | 
|   | 
|                 // 找出同一饋線上處理中的母案件(可作合併的)  | 
|                 // 該饋線上有可能有二件或兩件以上的母案件  | 
|                 while (reader.Read())  | 
|                 {  | 
|                     ArrayList record = new ArrayList();  | 
|                     record.Add(Convert.ToInt32(reader["CASEID"].ToString()));  | 
|                     record.Add(Convert.ToInt32(reader["FDRID"].ToString()));  | 
|                     record.Add(Convert.ToInt32(reader["FSC"].ToString()));  | 
|                     record.Add(Convert.ToInt32(reader["UFID"].ToString()));  | 
|                     record.Add(Convert.ToInt32(reader["CASESTATUS"].ToString()));  | 
|                     Equipment tmp = new Equipment(Convert.ToInt32(reader["FSC"].ToString()), Convert.ToInt32(reader["UFID"].ToString()));  | 
|                     record.Add(tmp);  | 
|                     record.Add(reader["BRIEF"].ToString());  | 
|                     record.Add(reader["ACCEPTNUM"].ToString());  | 
|                     _mCase.Add(record);  | 
|                     Logger.Info(record[7].ToString() + ", " + record[0]);  | 
|                 }  | 
|                 reader.Close();  | 
|             }  | 
|             catch (Exception e)  | 
|             {  | 
|                 Logger.Error(e, e.Message);  | 
|                 Logger.Error("尋找母案件時發生錯誤.");  | 
|                 throw ;  | 
|             }  | 
|             finally  | 
|             {  | 
|                 command?.Dispose();  | 
|   | 
|                 reader?.Close();  | 
|             }  | 
|   | 
|             // 若事故案件為該饋線上的第一件事故案件時,無須再作追蹤比較  | 
|             if (_mCase.Count == 0)  | 
|             {  | 
|                 _inferFsc = _damageFsc;  | 
|                 _inferUfid = _damageUfid;  | 
|                 Logger.Info("此案件為饋線上第一件案件");  | 
|                 Logger.Info("追蹤合併結束.");  | 
|                 return;  | 
|             }  | 
|   | 
|             // 判斷是否為同一變壓器,如果是就不必作追蹤  | 
|             try  | 
|             {  | 
|                 for (int i = 0; i < _mCase.Count; i++)  | 
|                 {  | 
|                     if ((Convert.ToInt32(((ArrayList)_mCase[i])[2].ToString()) == _damageFsc) &&  | 
|                          (Convert.ToInt32(((ArrayList)_mCase[i])[3].ToString()) == _damageUfid))  | 
|                     {  | 
|                         if (((ArrayList)_mCase[i])[6].ToString().StartsWith("A"))  // 若母案件事故原因為A類才做合併  | 
|                         {  | 
|                             _parentCaseId = Convert.ToInt32(((ArrayList)_mCase[i])[0].ToString());  | 
|                             _inferFsc = Convert.ToInt32(((ArrayList)_mCase[i])[2].ToString());  | 
|                             _inferUfid = Convert.ToInt32(((ArrayList)_mCase[i])[3].ToString());  | 
|                             Logger.Info("相同變壓器");  | 
|                             Logger.Info("與案件" + ((ArrayList)_mCase[i])[7] + "合併,故障點Fsc: " + _inferFsc + " Ufid: " + _inferUfid);  | 
|                             return;  | 
|                         }  | 
|                     }  | 
|                 }  | 
|             }  | 
|             catch (Exception ex)  | 
|             {  | 
|                 Logger.Error(ex.Message);  | 
|                 throw;  | 
|             }  | 
|             Logger.Info("不同變壓器,開始追蹤(New Version)...");  | 
|   | 
|             TraceCase();  | 
|             Logger.Warn("追蹤合併結束");  | 
|         }  | 
|   | 
|         private void TraceCase()  | 
|         {  | 
|             int mKey;  | 
|   | 
|             try  | 
|             {  | 
|                 _mTraceSubject = new TraceSubject(_connectionTpc, _transaction, _traceConnectionString);  | 
|                 Logger.Info("TraceSubject Startup....");  | 
|             }  | 
|             catch (Exception ex)  | 
|             {  | 
|                 Logger.Error("TraceObject.dll無法初始化,請確認該元件是否存在或jre是否為 1.4 版,並確認是否註冊.");  | 
|                 throw ex;  | 
|             }  | 
|   | 
|             try  | 
|             {  | 
|                 _mTraceSubject.StartTrace(_damageFsc, _damageUfid, true);  | 
|                 _newCase = _mTraceSubject.GetNewResult(); // 新案件所建出來的linkedlist(往上追到breaker)  | 
|                 Logger.Info("追蹤新案件完成");  | 
|   | 
|                 for (int i = 0; i < _mCase.Count; i++)  | 
|                 {  | 
|                     if (AlreadyFinishCase(Convert.ToInt32(((ArrayList)_mCase[i])[0].ToString())))  | 
|                     {  | 
|                         continue;  | 
|                     }  | 
|   | 
|                     ArrayList facilitySet = RealDamageEquipment(Convert.ToInt32(((ArrayList)_mCase[i])[0].ToString())); // 切開的設備  | 
|   | 
|                     if (facilitySet.Count == 0)  | 
|                     {  | 
|                         _mTraceSubject.StartTrace(Convert.ToInt32(((ArrayList)_mCase[i])[2].ToString()),  | 
|                                                        Convert.ToInt32(((ArrayList)_mCase[i])[3].ToString()), false);  | 
|                         _oldCase = _mTraceSubject.GetOldResult(); // 母案件所建出來的TreeMap(往上追到breaker)  | 
|                         Logger.Info("追蹤母案件完成");  | 
|   | 
|                         for (int j = 0; j < _newCase.Count; j++)  | 
|                         {  | 
|                             mKey = ((Equipment)_newCase[j]).Ufid;  | 
|   | 
|                             if (_oldCase.ContainsKey(mKey))  | 
|                             {  | 
|                                 if (((ArrayList)_mCase[i])[6].ToString().StartsWith("A"))  // 若母案件事故原因為A類才做合併  | 
|                                 {  | 
|                                     _parentCaseId = Convert.ToInt32(((ArrayList)_mCase[i])[0].ToString());  | 
|                                     _inferFsc = ((Equipment)_newCase[j]).Fsc;  | 
|                                     _inferUfid = ((Equipment)_newCase[j]).Ufid;  | 
|                                     _equip = (Equipment)((ArrayList)_mCase[i])[5];  | 
|                                     Logger.Info("與案件" + ((ArrayList)_mCase[i])[7] + "合併,故障點Fsc: " + _inferFsc + " Ufid: " + _inferUfid);  | 
|                                     return;  | 
|                                 }  | 
|                             }  | 
|                         }  | 
|                     }  | 
|                     else  | 
|                     {  | 
|                         foreach (object t1 in facilitySet)  | 
|                         {  | 
|                             bool merge = false; // 損壞設備是否在所切開的設備下游  | 
|                             Equipment damageEquipment = (Equipment)t1; // 切開的設備  | 
|   | 
|                             foreach (object t in _newCase)  | 
|                             {  | 
|                                 if ((((Equipment)t).Fsc== damageEquipment.Fsc) &&  | 
|                                     (((Equipment)t).Ufid== damageEquipment.Ufid))  | 
|                                 {  | 
|                                     merge = true;  | 
|                                     break;  | 
|                                 }  | 
|                             }  | 
|   | 
|                             // 當發現在所切開開關的下游,就將損壞設備指向切開的設備並return  | 
|                             if (merge)  | 
|                             {  | 
|                                 if (((ArrayList)_mCase[i])[6].ToString().StartsWith("A"))  // 若母案件事故原因為A類才做合併  | 
|                                 {  | 
|                                     _parentCaseId = Convert.ToInt32(((ArrayList)_mCase[i])[0].ToString());  | 
|                                     _inferFsc = damageEquipment.Fsc;  | 
|                                     _inferUfid = damageEquipment.Ufid;  | 
|                                     _equip = (Equipment)((ArrayList)_mCase[i])[5];  | 
|                                     Logger.Info("與案件" + ((ArrayList)_mCase[i])[7] + "合併,故障點Fsc: " + _inferFsc + " Ufid: " + _inferUfid);  | 
|                                     return;  | 
|                                 }  | 
|                             }  | 
|                         }  | 
|                     } // else  | 
|                 } // for loop(i)  | 
|             }  | 
|             catch (Exception ex)  | 
|             {  | 
|                 Logger.Error(ex, ex.Message);  | 
|                 Logger.Error("追蹤時發生錯誤.");  | 
|                 throw;  | 
|             }  | 
|             finally  | 
|             {  | 
|                 _mTraceSubject.DiscardEngine();  | 
|             }  | 
|   | 
|             _inferFsc = _damageFsc;  | 
|             _inferUfid = _damageUfid;  | 
|             _mTraceSubject.DiscardEngine();  | 
|         }  | 
|   | 
|         public Equipment GetInferEquipment()  | 
|         {  | 
|             Equipment equip = new Equipment(_inferFsc, _inferUfid);  | 
|             return equip;  | 
|         }  | 
|   | 
|         public Equipment GetOldrEquipment()  | 
|         {  | 
|             return _equip;  | 
|         }  | 
|   | 
|         public int GetParentCaseId()  | 
|         {  | 
|             return _parentCaseId;  | 
|         }  | 
|   | 
|         private bool AlreadyFinishCase(int caseId)  | 
|         {  | 
|             bool result = false;  | 
|   | 
|             var sqlStmt = "SELECT TO_CHAR(CLOSETIME,'YYYY/MM/DD HH24:MI:SS') as CLOSETIME,COUNT(*) as COUNT FROM EOS.EVENTFACILITY " + "WHERE CASEID = "  | 
|                              + caseId + " GROUP BY CLOSETIME ORDER BY CLOSETIME DESC";  | 
|   | 
|             OracleCommand command = null;  | 
|             OracleDataReader reader = null;  | 
|   | 
|             try  | 
|             {  | 
|                 command = new OracleCommand(sqlStmt, _connectionTpc, _transaction);  | 
|                 reader = command.ExecuteReader();  | 
|   | 
|                 if (reader.Read())  | 
|                 {  | 
|                     if (Convert.ToString(reader["CLOSETIME"]).Equals("null") || Convert.ToString(reader["CLOSETIME"]).Length == 0)  | 
|                         result = false; // 有切開開關未恢復(Case in Process)  | 
|                     else  | 
|                         result = true; // 有切開關但全都恢復(Case Finish)  | 
|                 }  | 
|                 else  | 
|                     result = false; // 未切過開關  | 
|   | 
|                 reader.Close();  | 
|             }  | 
|             catch (Exception e)  | 
|             {  | 
|                 Logger.Error(e, "Problems occur: " + e.Message);  | 
|             }  | 
|             finally  | 
|             {  | 
|                 command?.Dispose();  | 
|   | 
|                 reader?.Close();  | 
|             }  | 
|             return result;  | 
|         }  | 
|   | 
|         private ArrayList RealDamageEquipment(int caseId)  | 
|         {  | 
|             ArrayList result = new ArrayList();  | 
|   | 
|             var sqlStmt = "SELECT FSC,UFID FROM EOS.EVENTFACILITY WHERE CASEID = " + caseId + " AND CLOSETIME IS NULL";  | 
|   | 
|             OracleCommand command = null;  | 
|             OracleDataReader reader = null;  | 
|   | 
|             try  | 
|             {  | 
|                 command = new OracleCommand(sqlStmt, _connectionTpc, _transaction);  | 
|                 reader = command.ExecuteReader();  | 
|   | 
|                 while (reader.Read())  | 
|                 {  | 
|                     Equipment tmp = new Equipment(Convert.ToInt32(reader["FSC"]), Convert.ToInt32(reader["UFID"]));  | 
|                     result.Add(tmp);  | 
|                 }  | 
|             }  | 
|             catch (Exception e)  | 
|             {  | 
|                 // CCS.GlobalVariable.ErrorLog.setErrorLog("Error in JudgeCase(RealDamageEquipment) :" + e.getMessage());  | 
|                 Logger.Error(e, "Problems occur: " + e.Message);  | 
|             }  | 
|             finally  | 
|             {  | 
|                 reader?.Close();  | 
|   | 
|                 command?.Dispose();  | 
|             }  | 
|             return result;  | 
|         }  | 
|     }  | 
| } |