using System;
|
using System.Data;
|
using System.Configuration;
|
using System.Web;
|
using System.Web.Security;
|
using System.Web.UI;
|
using System.Web.UI.HtmlControls;
|
using System.Web.UI.WebControls;
|
using System.Web.UI.WebControls.WebParts;
|
using System.Collections;
|
using TRACEROBJECTLib;
|
using System.Data.OracleClient;
|
|
namespace CCSTrace.CCS.EventAI
|
{
|
public class TraceSubject
|
{
|
static String DEFAULTDBSTR;
|
static bool IsNewCase;
|
static ArrayList m_LinkList; // store the switch of the new case path
|
static TraceEngine m_tEngine;
|
static Hashtable m_TreeMap; // store the switch of the old case path
|
static int s_Fsc;
|
static int s_Ufid;
|
private RecordLog _Plogger;
|
private ArrayList m_Tmp = new ArrayList();
|
private NetworkContext m_pContext;
|
|
private OracleConnection _ConnectionTPC = null;
|
private OracleTransaction _Transaction;
|
|
public TraceSubject(OracleConnection _Conn, OracleTransaction _Trx, RecordLog _Log)
|
{
|
_ConnectionTPC = _Conn;
|
_Transaction = _Trx;
|
_Plogger = _Log;
|
|
try
|
{
|
if (m_tEngine == null) {
|
m_tEngine = new TraceEngine();
|
}
|
}
|
catch (Exception ex) {
|
_Plogger.Error(ex.Message);
|
throw ex;
|
}
|
}
|
|
public void discardEngine() {
|
if (m_tEngine != null) {
|
m_tEngine = null;
|
}
|
}
|
|
public ArrayList getNewResult() {
|
return m_LinkList;
|
}
|
|
public Hashtable getOldResult() {
|
return m_TreeMap;
|
}
|
|
// for EOS(only get the reverse tree)
|
public void startTrace(int Start_Fsc, int Start_Ufid, bool m_IsNew) {
|
s_Fsc = Start_Fsc;
|
s_Ufid = Start_Ufid;
|
IsNewCase = m_IsNew;
|
m_TreeMap = new Hashtable();
|
m_LinkList = new ArrayList();
|
|
try
|
{
|
this.setReverseTree(Trace(true));
|
}
|
catch (Exception e) {
|
_Plogger.Error(e.Message);
|
Console.WriteLine(e.StackTrace);
|
throw e;
|
}
|
}
|
|
private bool getSwitchOn(int UFID) {
|
String SqlStmt;
|
|
SqlStmt = "SELECT M.OSTATUS as OSTATUS FROM (SELECT UFID,OSTATUS FROM BASEDB.CONNECTIVITY WHERE FSC = 114) M,"
|
+ "BASEDB.SWITCH S WHERE M.UFID = S.UFID AND S.NSTATUS <> 0 AND M.UFID = " + UFID;
|
|
OracleCommand Command = null;
|
OracleDataReader reader = null;
|
|
try
|
{
|
Command = new OracleCommand(SqlStmt, _ConnectionTPC, _Transaction);
|
reader = Command.ExecuteReader();
|
|
if (reader.Read())
|
{
|
if (Convert.ToInt32(reader["OSTATUS"]) == 1)
|
return true;
|
}
|
reader.Close();
|
}
|
catch (Exception e)
|
{
|
_Plogger.Error(e.Message);
|
Console.WriteLine(e.StackTrace);
|
}
|
finally
|
{
|
if (Command != null)
|
Command.Dispose();
|
|
if (reader != null)
|
reader.Close();
|
}
|
return false;
|
}
|
|
private bool getJumperOn(int UFID) {
|
String SqlStmt;
|
|
SqlStmt = "SELECT OSTATUS FROM BASEDB.CONNECTIVITY WHERE FSC = 109 AND UFID = " + UFID;
|
|
OracleCommand Command = null;
|
OracleDataReader reader = null;
|
|
try
|
{
|
Command = new OracleCommand(SqlStmt, _ConnectionTPC, _Transaction);
|
reader = Command.ExecuteReader();
|
|
if (reader.Read())
|
{
|
if (Convert.ToInt32(reader["OSTATUS"]) == 1)
|
return true;
|
}
|
reader.Close();
|
}
|
catch (Exception e)
|
{
|
_Plogger.Error(e.Message);
|
Console.WriteLine(e.StackTrace);
|
}
|
finally
|
{
|
if (Command != null)
|
Command.Dispose();
|
|
if (reader != null)
|
reader.Close();
|
}
|
return false;
|
}
|
|
private Hashtable TraceCounts = new Hashtable();
|
|
private void setReverseTree(ResultTree tree) {
|
int i = 0;
|
TreeIterator iti = null;
|
bool ostatus = true;
|
|
if (tree != null) {
|
i = 0;
|
iti = tree.CreateTreeIterator();
|
bool isNotEnd = true;
|
|
while (isNotEnd) {
|
|
if (getTraceCount(iti.Value.ClassID, iti.Value.ObjectID) > 5)
|
throw new TraceLoopException("追蹤產生迴圈狀況。(Fsc,Ufid) = (" + iti.Value.ClassID + "," + iti.Value.ObjectID + ")");
|
else
|
AddTraceCount(iti.Value.ClassID, iti.Value.ObjectID);
|
|
while (iti.IsLeaf == 0)
|
{
|
TRACEROBJECTLib.TreeNode node = iti.Value;
|
|
if ((node.ClassID == 114) || (node.ClassID == 108) || (node.ClassID == 109))
|
{
|
Equipment Equip = new Equipment(node.ClassID, node.ObjectID);
|
|
if (IsNewCase)
|
m_LinkList.Add(Equip);
|
else {
|
m_TreeMap.Add(node.ObjectID, Equip);
|
m_Tmp.Add(Equip);
|
}
|
i++;
|
|
/* if (getTraceCount(node.ClassID, node.ObjectID) > 2)
|
throw new Exception("追蹤產生迴圈狀況。(Fsc,Ufid) = (" + node.ClassID + "," + node.ObjectID + ")");
|
else
|
AddTraceCount(node.ClassID, node.ObjectID);
|
*/ }
|
|
Console.WriteLine(node.ClassID + "----->" + node.ObjectID);
|
_Plogger.Info(node.ClassID + "----->" + node.ObjectID);
|
|
iti.MoveDescent((short) 0);
|
}
|
|
// 當從breaker出來的導線不只一條時,breaker可能會不被add(因為breaker是leaf但其parent的DescentCount > 1,所以被忽略)
|
/*
|
* if ( ((com.origo.TraceModel.ITreeNode)iti.get_Value()).get_ClassID() == EOS.LocalVariable.Breaker ) {
|
* com.origo.TraceModel.ITreeNode node = iti.get_Value(); Equipment Equip = new Equipment(node.get_ClassID(),node.get_ObjectID()); if (
|
* IsNewCase ) m_LinkList.add(i,Equip); else { m_TreeMap.put(new Integer(node.get_ObjectID()),Equip); m_Tmp.add(Equip); }
|
* System.out.println(node.get_ClassID() + "----->" + node.get_ObjectID()); System.out.println("Trace Finish...."); i++; break; }
|
*/
|
|
if ((iti.Value).ClassID == CCS.LocalVariable.Breaker) {
|
TRACEROBJECTLib.TreeNode node = iti.Value;
|
Equipment Equip = new Equipment(node.ClassID, node.ObjectID);
|
|
if (IsNewCase)
|
m_LinkList.Add(Equip);
|
else
|
{
|
m_TreeMap.Add(node.ObjectID, Equip);
|
m_Tmp.Add(Equip);
|
}
|
i++; //後面直接就FINISH,所以就不用判斷tracecount
|
|
Console.WriteLine(node.ClassID + "----->" + node.ObjectID);
|
_Plogger.Info(node.ClassID + "----->" + node.ObjectID);
|
Console.WriteLine("Trace Finish....");
|
_Plogger.Info("Trace Finish....");
|
break;
|
}
|
// 當追蹤到被切開的開關且該上一層設備只有該開關一個child)
|
else if (iti.Value.ClassID == CCS.LocalVariable.Switch || iti.Value.ClassID == CCS.LocalVariable.Jumper ) {
|
TRACEROBJECTLib.TreeNode node = iti.Value;
|
iti.MoveAscent();
|
|
Equipment Equip = new Equipment(node.ClassID, node.ObjectID);
|
|
if (isEndEquip(Equip))
|
{
|
if (IsNewCase)
|
m_LinkList.Add(Equip);
|
else
|
{
|
m_TreeMap.Add(node.ObjectID, Equip);
|
m_Tmp.Add(Equip);
|
}
|
i++; //後面直接就FINISH,所以就不用判斷tracecount
|
|
Console.WriteLine(node.ClassID + "----->" + node.ObjectID);
|
_Plogger.Info(node.ClassID + "----->" + node.ObjectID);
|
Console.WriteLine("Trace Finish....");
|
_Plogger.Info("Trace Finish....");
|
break;
|
}
|
|
//switch (node.ClassID)
|
//{
|
// case 114:
|
// ostatus = getSwitchOn(node.ObjectID);
|
// break;
|
// case 109:
|
// ostatus = getJumperOn(node.ObjectID);
|
// break;
|
//}
|
|
//if (!ostatus && (iti.DescentCount == 1)) {
|
// Equipment Equip = new Equipment(node.ClassID, node.ObjectID);
|
|
// if (IsNewCase)
|
// m_LinkList.Add(Equip);
|
// else {
|
// m_TreeMap.Add(node.ObjectID, Equip);
|
// m_Tmp.Add(Equip);
|
// }
|
// i++;
|
|
// Console.WriteLine(node.ClassID + "----->" + node.ObjectID);
|
// _Plogger.Info(node.ClassID + "----->" + node.ObjectID);
|
// Console.WriteLine("Trace Finish....");
|
// _Plogger.Info("Trace Finish....");
|
// break;
|
//}
|
}
|
else
|
{
|
TRACEROBJECTLib.TreeNode node = iti.Value;
|
iti.MoveAscent();
|
|
if (iti.DescentCount == 1)
|
throw new Exception("追蹤到非開關類斷開之設備(Fsc = " + node.ClassID + ",Ufid = " + node.ObjectID);
|
}
|
|
for (int j = 1; j < iti.DescentCount; j++) {
|
iti.MoveDescent((short) j);
|
|
if (iti.IsLeaf == 1) {
|
TRACEROBJECTLib.TreeNode node = iti.Value;
|
Equipment Equip = new Equipment(node.ClassID, node.ObjectID);
|
|
switch (node.ClassID) {
|
case 108:
|
if (IsNewCase)
|
m_LinkList.Add(Equip);
|
else
|
{
|
m_TreeMap.Add(node.ObjectID, Equip);
|
m_Tmp.Add(Equip);
|
}
|
|
Console.WriteLine(node.ClassID + "----->" + node.ObjectID);
|
_Plogger.Info(node.ClassID + "----->" + node.ObjectID);
|
i++;
|
|
/* if (getTraceCount(node.ClassID, node.ObjectID) > 2)
|
throw new Exception("追蹤產生迴圈狀況。(Fsc,Ufid) = (" + node.ClassID + "," + node.ObjectID + ")");
|
else
|
AddTraceCount(node.ClassID, node.ObjectID);
|
*/
|
break;
|
case 109:
|
case 114:
|
switch (node.ClassID)
|
{
|
case 114:
|
ostatus = getSwitchOn(node.ObjectID);
|
break;
|
case 109:
|
ostatus = getJumperOn(node.ObjectID);
|
break;
|
}
|
|
// Only for switch because the breaker only has one node to descent
|
if (!ostatus) {
|
if (IsNewCase)
|
m_LinkList.Add(Equip);
|
else {
|
m_TreeMap.Add(node.ObjectID, Equip);
|
m_Tmp.Add(Equip);
|
}
|
|
Console.WriteLine(node.ClassID + "----->" + node.ObjectID);
|
_Plogger.Info(node.ClassID + "----->" + node.ObjectID);
|
i++;
|
|
/* if (getTraceCount(node.ClassID, node.ObjectID) > 2)
|
throw new Exception("追蹤產生迴圈狀況。(Fsc,Ufid) = (" + node.ClassID + "," + node.ObjectID + ")");
|
else
|
AddTraceCount(node.ClassID, node.ObjectID);
|
*/
|
}
|
break;
|
default:
|
break;
|
} // switch
|
|
iti.MoveAscent();
|
isNotEnd = false;
|
} else {
|
isNotEnd = true;
|
break;
|
}
|
} // for
|
} // while
|
Console.WriteLine("Tree Node Count = " + i);
|
_Plogger.Info("Tree Node Count = " + i);
|
} else
|
{
|
Console.WriteLine("Tree is null");
|
_Plogger.Info("Tree is null");
|
throw new Exception("無法追蹤到任何設備,可能是該用戶所在變壓器設備連結性有問題。");
|
}
|
|
}
|
|
private ResultTree Trace(bool Reverse) {
|
ResultTree tree = null;
|
|
try {
|
configTrace();
|
_Plogger.Info("configTrace OK.");
|
}
|
catch (Exception e)
|
{
|
_Plogger.Error(e.Message);
|
Console.WriteLine(e.StackTrace);
|
return tree;
|
}
|
|
try {
|
tree = ModeTrace(Reverse);
|
}
|
catch (Exception e) {
|
_Plogger.Error(e.Message);
|
Console.WriteLine(e.StackTrace);
|
}
|
|
return tree;
|
}
|
|
void configTrace() {
|
if (DEFAULTDBSTR == null) {
|
DEFAULTDBSTR = "basedb/basedb000@nntpc";
|
}
|
try {
|
if (m_pContext == null) m_pContext = m_tEngine.teoCreateContext();
|
|
if (m_pContext.IsConnected == 0) {
|
m_pContext.Connect("", DEFAULTDBSTR);
|
}
|
}
|
catch (Exception ex) {
|
_Plogger.Error(ex.Message);
|
}
|
}
|
|
private ResultTree ModeTrace(bool Reverse) {
|
TravelContext tContext = new TravelContext();
|
TravelStartCriterion sCriterion = new TravelStartCriterion();
|
TravelTerminateCriterion eCriterion = new TravelTerminateCriterion();
|
|
sCriterion.ClsID = (short) s_Fsc;
|
sCriterion.ObjID = s_Ufid;
|
|
if (Reverse) // 反向上追
|
{
|
sCriterion.StartMode = (TRAVELSTARTCRITERIONTYPE)(Convert.ToInt32(TRAVELSTARTCRITERIONTYPE.TRAVELBYNEGDIR) + Convert.ToInt32(TRAVELSTARTCRITERIONTYPE.TRAVELWITHFOLLOW));
|
|
eCriterion.ClsID = (short)CCS.LocalVariable.Breaker;
|
eCriterion.EndMode = TRAVELTERMCRITERIONTYPE.TRAVELTOTHISCLASS;
|
} else // 順向追蹤
|
{
|
sCriterion.StartMode = TRAVELSTARTCRITERIONTYPE.TRAVELBYCURDIR;
|
|
eCriterion.EndMode = TRAVELTERMCRITERIONTYPE.TRAVELTOTHISCLASS;
|
}
|
|
tContext.addCriterion(sCriterion);
|
tContext.addCriterion(eCriterion);
|
|
m_pContext.ResetContext();
|
|
_Plogger.Info("Set ModeTrace OK.");
|
ResultTreeBuilder trBuilder = m_pContext.CreateTreeBuilder();
|
if (!trBuilder.constructResultTree(tContext, TRAVELTHREADMODE.CONMODE_SYNCHRONOUS)) { return null; }
|
_Plogger.Info("ConstructResultTree OK.");
|
ResultTree result = trBuilder.ResultTree;
|
|
_Plogger.Info("getResultTree OK.");
|
return result;
|
}
|
|
//判斷是否為最終設備(逆向追到已經無child的設備時,檢查該設備是否為最終設備(查驗該設備的同層設備,是否仍有可繼續逆向追蹤的設備,若無,則該設備為最終設備
|
private bool isEndEquip(Equipment SelfEquip)
|
{
|
String SqlStmt;
|
OracleCommand Command = null;
|
OracleDataReader reader = null;
|
long N_Value = 0;
|
|
SqlStmt = "SELECT DIR,OSTATUS,N1,N2 FROM BASEDB.CONNECTIVITY WHERE FSC = " + SelfEquip.getFSC() + " AND UFID = " + SelfEquip.getUFID();
|
|
try
|
{
|
Command = new OracleCommand(SqlStmt, _ConnectionTPC, _Transaction);
|
reader = Command.ExecuteReader();
|
|
if (reader.Read())
|
{
|
if (Convert.ToInt32(reader["OSTATUS"]) == 1) //如果設備本身為非切開的設備,那應該繼續往逆向追
|
return false;
|
else
|
{
|
if (Convert.ToInt32(reader["DIR"]) == 3) //順向無電 N1-->N2,所以逆向的上游N值抓N2
|
N_Value = Convert.ToInt32(reader["N2"]);
|
else
|
N_Value = Convert.ToInt32(reader["N1"]);
|
}
|
}
|
reader.Close();
|
|
SqlStmt = "SELECT FSC,UFID,DIR,OSTATUS,N1,N2 FROM BASEDB.CONNECTIVITY WHERE N1 <> N2 AND ( N1 = " + N_Value + " OR N2 = " + N_Value + ")";
|
Command.CommandText = SqlStmt;
|
|
reader = Command.ExecuteReader();
|
|
while (reader.Read())
|
{
|
if (Convert.ToInt32(reader["FSC"]) == SelfEquip.getFSC() && Convert.ToInt32(reader["UFID"]) == SelfEquip.getUFID())
|
continue;
|
|
if (Convert.ToInt32(reader["OSTATUS"]) == 0) //切開的設備不可能為逆向的上游
|
continue;
|
|
if (Convert.ToInt32(reader["N1"]) == N_Value)
|
{
|
switch (Convert.ToInt32(reader["DIR"]))
|
{
|
case 1:
|
case 3:
|
break;
|
case 2:
|
case 4:
|
return false; //如果逆向的上游連接點為N1,一定要N2-->N1才可能還有需要逆向追蹤設備
|
case 99:
|
break; //未供電設備不可能是逆向上游
|
}
|
}
|
else if (Convert.ToInt32(reader["N2"]) == N_Value)
|
{
|
switch (Convert.ToInt32(reader["DIR"]))
|
{
|
case 1:
|
case 3:
|
return false; //如果逆向的上游連接點為N2,一定要N1-->N2才可能還有需要逆向追蹤設備
|
case 2:
|
case 4:
|
break;
|
case 99:
|
return false; //未供電設備不可能是逆向上游
|
}
|
}
|
}
|
reader.Close();
|
}
|
catch (Exception e)
|
{
|
_Plogger.Error(e.Message);
|
Console.WriteLine(e.StackTrace);
|
return false;
|
}
|
finally
|
{
|
if (Command != null)
|
Command.Dispose();
|
|
if (reader != null)
|
reader.Close();
|
}
|
|
|
return true;
|
}
|
|
private int getTraceCount(int Fsc, int Ufid)
|
{
|
if (TraceCounts.ContainsKey(Fsc + "|" + Ufid))
|
return Int32.Parse(TraceCounts[Fsc + "|" + Ufid].ToString());
|
else
|
return 0;
|
}
|
|
private void AddTraceCount(int Fsc, int Ufid)
|
{
|
int Count = 1;
|
|
if (TraceCounts.ContainsKey(Fsc + "|" + Ufid))
|
{
|
Count = Int32.Parse(TraceCounts[Fsc + "|" + Ufid].ToString());
|
Count++;
|
TraceCounts.Remove(Fsc + "|" + Ufid);
|
}
|
|
TraceCounts.Add(Fsc + "|" + Ufid, Count.ToString());
|
}
|
|
}
|
|
public class TraceLoopException : Exception
|
{
|
public String Message = "";
|
|
public TraceLoopException(String _Message)
|
{
|
Message = _Message;
|
}
|
}
|
}
|