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 _mEquip; private readonly OracleConnection _connectionTpc; private readonly OracleTransaction _transaction; private readonly string _traceConnectionString; // int Range = 360; //比事故案件還早多久時間內的案件才作合併 單位:分 public JudgeCase(int mFdrId, int mFsc, int mUfid, int mCaseId, string mAcceptDate, OracleConnection connection, OracleTransaction trx, string traceConnection) { _damageFdrId = mFdrId; _damageFsc = mFsc; _damageUfid = mUfid; _newCaseId = mCaseId; _acceptDate = mAcceptDate; _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.Message); Console.WriteLine(e.StackTrace); Logger.Error("尋找母案件時發生錯誤."); throw e; } finally { if (command != null) command.Dispose(); if (reader != null) 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 ex; } 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; _mEquip = (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; _mEquip = (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 _mEquip; } 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("Problems occur: " + e.Message); Console.WriteLine(e.StackTrace); } 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("Problems occur: " + e.Message); Console.WriteLine(e.StackTrace); } finally { reader?.Close(); command?.Dispose(); } return result; } } }