ulysseskao
2016-05-03 410dc2d04dbecf019129cd8cd65a3be2c62b4d0c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
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;
        }
    }
}