using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using Microsoft.Win32; using System.Net; using System.Diagnostics; using System.IO; using System.Collections; using System.Threading; using System.Media; using PushSharp; using PushSharp.Android; using PushSharp.Core; // cyim 2016.12.26 : UI 이탈방지 코드 추가 (후킹) using MouseKeyboardActivityMonitor; using MouseKeyboardActivityMonitor.WinApi; using System.Runtime.InteropServices; using System.Net.NetworkInformation; // cyim 2015.7.29 수신반 모드 // 수신반의 경우의 환경설정은 아래와 같다 // 수신기와 마찬가지로 레지스트리를 읽어서 현재 DB 정보를 읽도록 한다. ini 파일에 의해 수신반이 될지, 수신기가 될지 결정된다. // 동작 기본 : 기존과 동일하게 레지스트리값을 읽어 DB 를 읽고, 이 DB 는 수신기의 아이디 리스트 및 기본 디바이스 설정 정보를 가져오기 위한 용도로만 사용한다 // 주의해야 될 점은 소스측면에서는 수신반의 레지스트리에서 지정된 경로로 데이타베이스에 접속할때는 수신기 아이디가 0 으로 조회를 하게 된다, // 실제 데이타베이스에 조회하는 경우가 있을때는 각 수신기의 실제 DB 에 접속하여 접속하여 사용한다. 데몬을 통하는 것은 카운터, 이벤트 정보뿐이다. // 다만, DB 백업 및 기타 동작은 무시해도 된다. 수신반은 모니터링이 주 목적이다. // 수신기별 프로젝트 및 DB 파일 위치 : 각각 아이디별로 틀리다. DB 경로와 프로젝트 파일이 동일한 파일을 각각 폴더에 셋팅해두도록 한다 (Config.ini 을 참고해야됨) // 프로그램 모드 : Config.ini 파일에 mode 가 1로 되어 있으면 수신반, ini 파일이 없다면 기본으로 수신기 프로그램으로 동작된다 // cyim 2015.8.4 수신반을 위한 static 클래스 정리 // 수신반을 위한 Static 클래스 정리 // -> Static 을 허용하는 것은 오직 _Data.cs 와 _Ini.cs _Timer.cs_Data.cs 와 _Ini.cs _Timer.cs // 기존코드를 많이 수정하였다. 이는 결국 MdiParent 클래스를 독립적으로 관리하게 수정하는 것을 최종 목표로한다 // cyim 2015.9.15 수신반 1차 버전 완료 : 2.0.1.0 // 수신기 상태 및 제어 기능 // 카운터 통합 모니터링 기능 // 개별 수신기 복구 // 통합 현재 이벤트 표시 기능 // 통합 과거 내역 조회 기능 // cyim 2015.9.30 수신반은 ini 파일을 이용해서 데이타베이스 접속 : 2.0.1.1 namespace FPER { public partial class FireDesk_BigReceiver : Form { // 임시 아이디 리스트를 만들어서 폼을 load 완료하면 리스트에서 삭제하도록 하여 전체 폼을 다 미리 로드한다 public ArrayList LoadMdiparentFormList = new ArrayList(); // 폼을 로드한것이 진행중이라면 수신반 메인폼에서 계속 폼을 생성하지 못하게 한다 public bool FormLoadComplete = false; // 수신기폼을 로드시에 기다리는 팝업창을 생성 public frmWaitingMsg waitingForm_FireDesk = null; // cyim 2015.8.3 검토해본 결과 기존의 팝업창을 그대로 사용하도록 한다 // cyim 2015.8.4 수신반을 위한 static 클래스 정리 : 타이머 public _Timer_WindowBase Timer_WindowBase_FireDesk = new _Timer_WindowBase(); // cyim 2015.8.4 수신반을 위한 static 클래스 정리 : 이벤트 public _Event Event = new _Event(); // cyim 2015.9.1 1개의 수신기가 접속이 안되더라도 나머지는 접속시도할수 있도록 수정 public ArrayList CommErrorReceiver = new ArrayList(); // cyim 2015.9.15 수신반 하단 이벤트 표시 // 카운터 표시 (통합 카운터이다. 즉 모든 수신기의 카운터의 합이다) // // 아래의 변수 정보는 수신기로 부터 직접 전달받은 카운터를 합 한것이고, 일정 시간마다 갱신된다 public int fireCount = 0, facilityCount = 0, errorCount = 0, blockingCount = 0, cutCnt = 0, checkCnt = 0; public int fireCount_Accumulation = 0; // 아래의 리스트 정보는 각각 수신기의 이벤트가 발생할때마다 갱신된다 public ArrayList PreFireList = new ArrayList(); public ArrayList FireList = new ArrayList(); public ArrayList FireList_Accumulation = new ArrayList(); public ArrayList EquipList = new ArrayList(); // 상태 라벨 카운트 (미사용) public int LEDCount = 0; public ArrayList LEDList = new ArrayList(); // cyim 2015.9.23 시간정보 표시 오류 (갱신을 안함) public string MyTime = null; // cyim 2016.06.15 : 화재 음원 출력 //public SoundPlayer SoundPlayer_AlarmPopupSound = new SoundPlayer(Properties.Resources.emergency); public SoundPlayer SoundPlayer_AlarmPopupSound = null; public int SoundPlayer_AlarmPopupSound_Count = 0; // cyim 2016.12.20 : 푸시메세지 연동 기능 추가 : 화재 카운터 정보 public int timer_1000_Tick_Fire_Cnt_New = 0; public int timer_1000_Tick_Fire_Cnt_Old = 0; // cyim 2016.12.20 : 푸시메세지 연동 기능 추가 : 설비 카운터 정보 public int timer_1000_Tick_Facility_Cnt_New = 0; public int timer_1000_Tick_Facility_Cnt_Old = 0; // cyim 2016.12.20 : 푸시메세지 연동 기능 추가 : 통신에러 카운터 정보 public int timer_1000_Tick_ComError_Cnt_New = 0; public int timer_1000_Tick_ComError_Cnt_Old = 0; // cyim 2016.12.20 : 푸시메세지 연동 기능 추가 : 단선 카운터 정보 public int timer_1000_Tick_Block_Cnt_New = 0; public int timer_1000_Tick_Block_Cnt_Old = 0; // cyim 2016.12.20 : 푸시메세지 연동 기능 추가 : 차단 카운터 정보 public int timer_1000_Tick_Cut_Cnt_New = 0; public int timer_1000_Tick_Cut_Cnt_Old = 0; // cyim 2016.12.20 : 푸시메세지 연동 기능 추가 : 점검 카운터 정보 public int timer_1000_Tick_Check_Cnt_New = 0; public int timer_1000_Tick_Check_Cnt_Old = 0; // 푸시 메세지 발생 수신기 public ArrayList GCM_Fire_List = new ArrayList(); public ArrayList GCM_Facility_List = new ArrayList(); public ArrayList GCM_ComError_List = new ArrayList(); public ArrayList GCM_Block_List = new ArrayList(); public ArrayList GCM_Cut_List = new ArrayList(); public ArrayList GCM_Check_List = new ArrayList(); public ArrayList GCM_Fire_Clone = new ArrayList(); public ArrayList GCM_Facility_Clone = new ArrayList(); public ArrayList GCM_ComError_Clone = new ArrayList(); public ArrayList GCM_Block_Clone = new ArrayList(); public ArrayList GCM_Cut_Clone = new ArrayList(); public ArrayList GCM_Check_Clone = new ArrayList(); public System.Threading.Timer GCM_Thread_Timer = null; public TimerCallback GCM_CallBack = null; public int GCM_Sender_Tick_Cnt = 0; // cyim 2016.12.26 : UI 이탈방지 코드 추가 (후킹) public static KeyboardHookListener m_KeyboardHookManager; // cyim 2016.12.28 : 예외처리 추가 public _Ethernet Ethernet = new _Ethernet(); // 생성자 public FireDesk_BigReceiver() { InitializeComponent(); // cyim 2016.11.11 : 비상 음원 출력 음원 파일 없을때 대응 코드 추가 if (File.Exists(Environment.CurrentDirectory + "\\emergency.wav") == true) SoundPlayer_AlarmPopupSound = new SoundPlayer(Environment.CurrentDirectory + "\\emergency.wav");// cyim 2016.06.24 : 음원 출력시 교체 가능 // 이벤트 this.FormClosing += new FormClosingEventHandler(FireDesk_FormClosing); this.Load += new EventHandler(FireDesk_Load); Event.FireDesk_Update_SendMessage_Event += new _Event.FireDesk_Update_SendMessage_Handler(_Event_FireDesk_Update_SendMessage_Event); // cyim 2015.8.4 수신반을 위한 static 클래스 정리 // UI for (int id = 1; id <= 32; id++) { // 수신기 버튼 Button button_Receiver = (Button)Util.FineControl(panel_Receiver, "button_Receiver" + id.ToString()); button_Receiver.Tag = id.ToString(); button_Receiver.Click += new EventHandler(button_Receiver_Click); // 수신기 복구 버튼 Button button_Recover = (Button)Util.FineControl(panel_Receiver, "button_Recover" + id.ToString()); button_Recover.Tag = id.ToString(); button_Recover.Click += new EventHandler(button_Recover_Click); } // cyim 2016.12.29 : 화면 멈춤 문제 수정 : 오른쪽 상단의 시간 표시 타이머 Timer_WindowBase_FireDesk.Create("timer_1000_TimeLabelUpdate", 1000, timer_1000_TimeLabelUpdate_Tick, true); } // 소멸자 private void FireDesk_FormClosing(object sender, FormClosingEventArgs e) { // cyim 2016.12.26 : UI 이탈방지 코드 추가 (후킹) if (_Data.Hook_Enable != "OFF") { _Hook.Enable_TaskMgr(); _Hook.Enable_NoClose(); } // 타이머 Timer_WindowBase_FireDesk.Delete("timerDateTime"); // cyim 2015.8.4 수신반을 위한 static 클래스 정리 // // cyim 2016.11.11 : 수신반 프로세스 종료 코드 추가 // // 스레드 종료 Application.ExitThread(); for (int i = 0; i < 1000000; i++) {; } // 프로세스 종료 Application.Exit(); // 프로세스가 남아있다면 최종 종료 System.Diagnostics.Process[] mProcess = System.Diagnostics.Process.GetProcessesByName(Application.ProductName); foreach (System.Diagnostics.Process p in mProcess) p.Kill(); // 최종 정리 (보완코드 : 크로스 스레드 문제 발생 여지가 있으므로 사용주의) Environment.Exit(0); } // // 초기화 // private void FireDesk_Load(object sender, EventArgs e) { // cyim 2016.12.26 : UI 이탈방지 코드 추가 (후킹) if (_Data.Hook_Enable != "OFF") { _Hook.Disable_TaskMgr(); _Hook.Disable_NoClose(); GimmeTray(); m_KeyboardHookManager = new KeyboardHookListener(new GlobalHooker()); m_KeyboardHookManager.Enabled = true; } // cyim 2015.7.31 수신반 팝업창은 별도로 존재 ShowWaitingMsgForm("수신반을 시작합니다", 10); // cyim // 해당 DB 를 읽고 어떤 IP 에 어떤 수신기 ID 가 맵핑되어있는지 알아야한다 // 수신기에 원격으로 데몬이 붙어서 동작할수 있다. // 맨처음 가동단계는 현재 DB 를 읽어서 수신반 구동을 시작한다 // 현재 데이타베이스를 읽고 현재 설정된 수신기가 어떤 아이디들로 구성되어 있는지 알아야 한다 // 데이타베이스를 토대로 각각 수신기 정보를 알아야 되며, 레지스트리 값을 읽어서 쓰는 루틴은 그대로 이용하되, // 레지스트리 값중에 프로젝트 경로는 각 수신기별로 정보를 가지고 있도록 해야한다 // 수신반의 경우 중계기, 보드 정보, 수신기 설정값을 알필요가 없다. (물론 각 수신기에 접속하면 알수가 있지만 평상시에는 알 필요가 없다) // 수신기 아이디 해쉬 테이블 초기화 - Config.ini 기반 Initialize_Hash_Receiver(_Data.Hash_Receiver); // 수신기 아이디 키 배열 생성 _Data.Hash_Receiver_keys = new string[_Data.Hash_Receiver.Keys.Count]; _Data.Hash_Receiver.Keys.CopyTo(_Data.Hash_Receiver_keys, 0); // cyim 2017.01.03 : 연동기능 보완 _Data.Hash_Receiver_keys = Sort_StringArray(_Data.Hash_Receiver_keys); // 수신기 중에 마스터 모드로 셋팅된 아이디를 검색한다 // 수신반의 데이타베이스를 접근해야되는데 어차피 TB_CONFIG 테이블은 유일하게 내부 PC에 있는 수신반 DB를 이용하도록 한다. // 수신반 DB 를 접근하려면 아이디가 0으로 되어 있으면 내부적으로 접근 가능하도록 되어있고 경로는 레지스트리 값 경로를 이용하면 된다 ArrayList temp = new ArrayList(); foreach (string id in _Data.Hash_Receiver_keys) { _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[id]; DacReceiverConfig dacReceiverConfig = new DacReceiverConfig(0); DataTable dt = dacReceiverConfig.Config_Select(0); // 마스터 모드 foreach (DataRow dr in dt.Rows) { if (id == dr["RECEIVER_ID"].ToString()) { FireDesk_Receiver.MASTER_FLAG = dr["MASTER_FLAG"].ToString();//dt.Rows[0]["MASTER_FLAG"].ToString(); // cyim 2017.01.03 : 마스터 수신기 표시 if (FireDesk_Receiver.MASTER_FLAG == "Y" && temp.Contains(id) == false) temp.Add(id); } } } // cyim 2017.01.03 : 마스터 수신기 표시 this.label_Master.Text = string.Format("Master Receiver ID : {0}", _Convert.ArrayList_to_String(temp, ",")); // cyim 2015.9.11 : 과거내역 통합조회창에서 사용할 DB 에서 미리 읽은값을 사용하도록 수정함 // 공통정보를 데이타베이스에서 불러온다 ShowWaitingMsgForm("수신기 디바이스 DB를 읽고 있습니다..", 20); this.GetDeviceDB(); ShowWaitingMsgForm("수신기 중계기 DB를 읽고 있습니다..", 30); this.GetRepeaterDB(); //AnalogDetect.Get_TB_DAYTIME(0); // 수신반은 필요없다 this.GetAnalogDetecterLevelDB(); ShowWaitingMsgForm("수신기 통신 보드 설정을 읽고 있습니다..", 40); this.GetBoardDB(); ShowWaitingMsgForm("수신기 기본 설정값을 읽고 있습니다..", 50); // // UI // // cyim 2017.01.03 수신기 버튼 색상 정리 // 불필요한 수신기는 정리한다 for (int id = 1; id <= 32; id++) { // 사용하지 않는 수신기 if (_Data.Hash_Receiver.ContainsKey(id.ToString()) == false) { Panel p = (Panel)Util.FineControl(panel_Receiver, "panel_Receiver" + id.ToString()); p.Enabled = false; Button b = (Button)Util.FineControl(panel_Receiver, "button_Receiver" + id); b.Enabled = false; b.BackColor = Color.DarkGray; } } // 내부 클래스 로드 MDIParent_Load_Func(); // cyim 2015.7.31 수신반 팝업창은 별도로 존재 : 문구 출력 이후에 종료 ShowWaitingMsgForm("수신반을 시작합니다", 100); System.Threading.Thread.Sleep(1000); waitingForm_FireDesk.Close(); waitingForm_FireDesk = null; // cyim 2016.12.20 : 현장명 사용자 지정 this.label_BuildingName.Text = _Data.Site_Name; // 스레드 GCM_CallBack = new TimerCallback(GCM_Sender_CallBack); GCM_Thread_Timer = new System.Threading.Timer(GCM_CallBack, this, 1000, 1000); // cyim 2016.12.29 : 화면 멈춤 문제 수정 // 타이머중에 통신데몬 재접속 혹은 수신기 상태를 표시하는 타이머는 모든 MDIParent 가 준비가 된 이후부터 가동하도록 한다 // cyim 2017.01.04 : 수신기 통신체크 루틴 타이머 조정 int timer_cnt = 0; switch (_Data.Hash_Receiver.Keys.Count) { case 1: timer_cnt = 3000; break; case 2: timer_cnt = 3000; break; case 3: timer_cnt = 3000; break; case 4: timer_cnt = 3000; break; case 5: timer_cnt = 2500; break; default: timer_cnt = 2000; break; } // 통신 상태 체크 Timer_WindowBase_FireDesk.Create("ConnectCheck_Timer", timer_cnt, ConnectCheck_Timer_Tick, true); // 알람 상태 표시 Timer_WindowBase_FireDesk.Create("Display_Timer", 1000, Display_Timer_Tick, true); } // cyim 2017.01.03 : 연동기능 보완 - 수신기 아이디 정렬 private string[] Sort_StringArray(string[] Data) { ArrayList temp = new ArrayList(); foreach (string id in Data) temp.Add(id); temp.Sort(new _Sort.ID()); string[] result = new string[temp.Count]; temp.CopyTo(result); return result; } // cyim 2016.12.29 : 화면 멈춤 문제 수정 : 프로그램 시작시 클래스를 로드한다 private void MDIParent_Load_Func() { // 초기화 LoadMdiparentFormList.Clear(); while (true) { foreach (string id in _Data.Hash_Receiver_keys) { _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[id]; // 수신반에서 읽기 시도한다 if (FormLoadComplete == false) { // 하단의 mdi.show 함수에서 딜레이가 심하다. 코드 위치를 변경하면 안된다 FormLoadComplete = true; // 기존에 읽기 완료하지 않은 것만 시도한다 if (FireDesk_Receiver.LoadingOk == false) { // 네트워크에 연결되었다면 if (Ethernet.Ping_SyncCheck(FireDesk_Receiver.DATABASE_NAME_IP) == true) { Receiver_MDIParent_Load(FireDesk_Receiver, Int32.Parse(id)); UPDATE_TB_RECEIVER_ERROR_COUNT_DETAILS(id); Receiver_ComNormal(id.ToString()); } else { Receiver_MDIParent_Close(FireDesk_Receiver, Int32.Parse(id)); Receiver_ComError(id.ToString()); FormLoadComplete = false; } // 한번이라도 읽기 시도한 것은 리스트에 저장 if (LoadMdiparentFormList.Contains(id.ToString()) == false) LoadMdiparentFormList.Add(id.ToString()); System.Threading.Thread.Sleep(300); } } } // 읽기 시도 횟수와 등록된 수신기 개수가 맞다면 무한루프 종료 if (LoadMdiparentFormList.Count == _Data.Hash_Receiver_keys.Length) { break; } } } // cyim 2016.12.29 : 화면 멈춤 문제 수정 - 중간 업데이트전용 구분 private void MDIParent_Update_Func(string Receiver_ID) { // 예외처리 if (Receiver_ID == "" || Receiver_ID == "0" || _Data.Hash_Receiver.ContainsKey(Receiver_ID.ToString()) == false) return; // 팝업창이 있으면 닫아버린다 if (waitingForm_FireDesk != null && waitingForm_FireDesk.Visible == true) { waitingForm_FireDesk.Close(); waitingForm_FireDesk = null; } string id = Receiver_ID.ToString(); _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[id]; // 수신반에서 읽기 시도한다 if (FormLoadComplete == false) { // 하단의 mdi.show 함수에서 딜레이가 심하다. 코드 위치를 변경하면 안된다 FormLoadComplete = true; // 기존에 읽기 완료하지 않은 것만 시도한다 if (FireDesk_Receiver.LoadingOk == false) { if (Ethernet.Ping_SyncCheck(FireDesk_Receiver.DATABASE_NAME_IP) == true) { Receiver_MDIParent_Load(FireDesk_Receiver, Int32.Parse(id)); UPDATE_TB_RECEIVER_ERROR_COUNT_DETAILS(id); Receiver_ComNormal(id.ToString()); } else { // 처음에 잘 읽었던 것을 굳이 리소스를 삭제해야되나? //Receiver_MDIParent_Close(FireDesk_Receiver, Int32.Parse(id)); Receiver_ComError(id.ToString()); FormLoadComplete = false; } } else // 초기화 시도시에 이미 읽었다면 현재 이력 { if (Ethernet.Ping_SyncCheck(FireDesk_Receiver.DATABASE_NAME_IP) == true) { UPDATE_TB_RECEIVER_ERROR_COUNT_DETAILS(id); Receiver_ComNormal(id.ToString()); FormLoadComplete = false; } else { // 처음에 잘 읽었던 것을 굳이 리소스를 삭제해야되나? //Receiver_MDIParent_Close(FireDesk_Receiver, Int32.Parse(id)); Receiver_ComError(id.ToString()); FormLoadComplete = false; } } } } // // cyim 2016.12.16 : 통신 단절 및 통신 복구시 수신기 버튼의 색상이 변경된다 // private void Receiver_ComError(string id) { Button p = (Button)Util.FineControl(panel_Receiver, "button_Receiver" + id); p.Enabled = false; p.BackColor = Color.HotPink; if (CommErrorReceiver.Contains(id) == false) CommErrorReceiver.Add(id); } private void Receiver_ComNormal(string id) { Button p = (Button)Util.FineControl(panel_Receiver, "button_Receiver" + id); p.Enabled = true; p.BackColor = Color.WhiteSmoke; if (CommErrorReceiver.Contains(id) == true) CommErrorReceiver.Remove(id); } // // cyim 2016.12.29 : 화면 멈춤 문제 수정 // private void Receiver_MDIParent_Load(_FireDesk_Receiver FireDesk_Receiver, int id) { // cyim 2017.01.02 : Memory leak if (FireDesk_Receiver.mdi == null) { try { FireDesk_Receiver.mdi = new MDIParent(id, Event); FireDesk_Receiver.mdi.TopMost = false; FireDesk_Receiver.mdi.Show(); FireDesk_Receiver.mdi.Visible = false; FireDesk_Receiver.LoadingOk = true; } catch { FireDesk_Receiver.LoadingOk = false; FormLoadComplete = false; } } } private void Receiver_MDIParent_Close(_FireDesk_Receiver FireDesk_Receiver, int id) { FireDesk_Receiver.LoadingOk = false; if (FireDesk_Receiver.mdi != null) { FireDesk_Receiver.mdi.Close(); FireDesk_Receiver.mdi = null; } } // // 수신반 클래스 초기화 // private void Initialize_Hash_Receiver(Hashtable hashtable) { hashtable.Clear(); for (int i = 1; i <= 32; i++) { // USE 값이 1인 경우에만 읽도록 한다 string use = _Ini.Read_Ini("RECEIVER" + i.ToString(), "USE", 1024, Environment.CurrentDirectory + "\\Config.ini"); if (use == "1") { // 수신반 클래스 _FireDesk_Receiver firedesk_receiver = new _FireDesk_Receiver(); // 아이디 firedesk_receiver.RECEIVER_ID = i.ToString(); string Temp_DATABASE_NAME = _Ini.Read_Ini("RECEIVER" + i.ToString(), "DATABASE_NAME", 1024, Environment.CurrentDirectory + "\\Config.ini"); // IP + PATH firedesk_receiver.DATABASE_NAME = Temp_DATABASE_NAME; // IP firedesk_receiver.DATABASE_NAME_IP = Temp_DATABASE_NAME.Substring(0, Temp_DATABASE_NAME.IndexOf(":")); // PATH firedesk_receiver.DATABASE_NAME_PATH = Temp_DATABASE_NAME.Substring(Temp_DATABASE_NAME.IndexOf(":") + 1); string Temp_PROJECT_DIR = _Ini.Read_Ini("RECEIVER" + i.ToString(), "PROJECT_DIR", 1024, Environment.CurrentDirectory + "\\Config.ini"); // 프로젝트 경로 firedesk_receiver.PROJECT_DIRECTORY = Temp_PROJECT_DIR; // 해쉬에 추가 if (hashtable.ContainsKey(firedesk_receiver.RECEIVER_ID) == false) hashtable.Add(firedesk_receiver.RECEIVER_ID, firedesk_receiver); } } } // // 팝업창 // // cyim 2015.7.31 수신반 팝업창은 별도로 존재 // delegate void WaitingMsg_Callback(string msg, int processValue); public void ShowWaitingMsgForm(string msg, int processValue) { if (this.InvokeRequired) { WaitingMsg_Callback d = new WaitingMsg_Callback(ShowWaitingMsgForm); this.Invoke(d, new object[] { msg, processValue }); } else { if (this.waitingForm_FireDesk == null) { // cyim 2015.8.3 검토해본 결과 기존의 팝업창을 그대로 사용하도록 한다 // 다만 수신기별로 각각 팝업창이 계속 표시가 되면 될것같음. 즉 같은 팝업창의 진행도가 0~100 ->0~100 을 자동반복함 this.waitingForm_FireDesk = new frmWaitingMsg(); this.waitingForm_FireDesk.Text = Application.ProductName; this.waitingForm_FireDesk.TopMost = true; Point loc = new Point( (1280 - this.waitingForm_FireDesk.Size.Width) / 2 + this.Location.X, (1024 - this.waitingForm_FireDesk.Size.Height) / 2 + this.Location.Y ); this.waitingForm_FireDesk.Location = loc; this.waitingForm_FireDesk.Show(); } this.waitingForm_FireDesk.setMessage(msg, processValue); this.Update(); } } string GetDevicePositionName(CEventLogData eventLog, MDIParent mdi) { string ret = ""; { // 기본값으로 함 string DefaultValue = ""; switch (eventLog.ioType) { // // 마스터 수신기 // case "M": { //ret = "Master " + receiverID; ret = DefaultValue; } break; // // 로컬 수신기 // case "A": // 전체 //if (Convert.ToInt32(eventLog.receiverID) > 0) { // receiver.Name; //DBAccess.GetReceiverNameFromDB(this.receiverID); ret = DefaultValue; } break; case "C": // 통신 //if (Convert.ToInt32(eventLog.receiverID) > 0) { // receiver.Name; //ret = receiverID + "-통신"; if (eventLog.eventType == "DC") { // 설비연동 조작 if (eventLog.boardID == 0 && eventLog.repeaterID == 0 && eventLog.deviceID == 0) { ret = DefaultValue; } // 루프 차단 else if (eventLog.boardID != 0 && eventLog.repeaterID == 0 && eventLog.deviceID == 0) { ret = mdi.GetDeviceName(eventLog.boardID, eventLog.commID); if (eventLog.commID == 1) { ret += string.Format(":{0}계통", eventLog.loopNO.ToString()); } } // 중계기 차단 else if (eventLog.boardID != 0 && eventLog.repeaterID != 0 && eventLog.deviceID == 0) { ret = mdi.GetDevicePositionName(eventLog.boardID, eventLog.loopNO, eventLog.repeaterID); } else ret = DefaultValue; } } break; case "B": // 보드 { //deviceName = DBAccess.GetBoardNameFromDB(this.receiverID, this.boardID); //ret = receiverID + "-보드"; ret = DefaultValue; } break; case "L": // 루프 { //ret = receiver.board[eventLog.boardID - 1].Name; //ret += string.Format("{0}보드:{1}계통", eventLog.boardID, eventLog.loopNO.ToString()); //ret = receiverID + "-루프"; ret = DefaultValue; } break; case "R": //중계기 { //ret = receiver.board[eventLog.boardID - 1].loop[eventLog.loopNO].repeater[eventLog.repeaterID - 1].Name; // ret = "중계기"; // 중계기와 회로는 각건물내에 위치하므로 수신기 아이디 출력 제외함 // 데이타베이스에서 조회, 이름이 없다면 코드라도 출력 ret = mdi.GetDevicePositionName(eventLog.boardID, eventLog.loopNO, eventLog.repeaterID); } break; case "D": // 장치 { //ret = "장치"; //ret = receiverID + "-장치"; ret = DefaultValue; } break; case "I": //입력회로 case "O": //출력회로 { // cyim 2015.9.23 키패드조작에서 발생한 이벤트의 경우 회로정보는 null, 장치명은 수신기아이디 표시 if (eventLog.eventType == "MS" || eventLog.eventType == "LS" || eventLog.eventType == "EB" || eventLog.eventType == "RP" || eventLog.eventType == "BF" || eventLog.eventType == "ED" // cyim 2016.12.09 : IFC3300에서는 예비전원버튼 -> 설비전체연동조작버튼 ) { ret = DefaultValue; } else { // 중계기와 회로는 각건물내에 위치하므로 수신기 아이디 출력 제외함 ret = mdi.GetDevicePositionName(eventLog.boardID, eventLog.loopNO, eventLog.repeaterID, eventLog.deviceID, eventLog.ioType); } } break; default: { //ret = string.Format("수신기[{0}]", eventLog.receiverID); ret = DefaultValue; } break; } // 만약에 정보가 없다면 기본값 -> 2014.8.7 소방특성상 위치정보가 불확실하다면 표시안하는게 좋다는 의견 - 장성원부장님 //if (ret == null || ret.Length == 0) ret = DefaultValue; } return ret; } string GetRemarkInfo(string Original, string Attribute) { try { string result = ""; // Attribute 값은 아래와 같다 // APPLY RANGE // DEVICE TYPE // STATUS ArrayList temp_list = new ArrayList(); Hashtable temp_hash = new Hashtable(); // 문자열을 콤마로 구분해서 string[] temp_1th = Original.Split(','); char[] remove_char1 = { '(', ')' }; char[] remove_char2 = { '[', ']' }; foreach (string temp in temp_1th) { // 각 문자열중에 속성이름이 포함되어있다면 if (temp.Contains(Attribute) == true) { string[] temp_2st = temp.Split(':'); result = temp_2st[1].Trim(remove_char1);// 괄호 제거 return result.Trim(remove_char2);// 대괄호 제거 } } return result; } catch (Exception ex) { Util.UErrorMessage(ex, 0, 0); return ""; } } string GetDeviceName(CEventLogData eventLog, MDIParent mdi) { // get device name data string ret = ""; //if (FindReceiver(eventLog.receiverID) >= 0) { // 수신기 아이디 정보 추가 string receiverID = string.Format("수신기[{0}]", eventLog.receiverID); // 디바이스 타입 정보 추가 string remark_device_type = GetRemarkInfo(eventLog.eventRemark, "DEVICE TYPE"); if (remark_device_type.Length != 0) remark_device_type = "-" + remark_device_type; //Receiver receiver = this.LReceiver[FindReceiver(eventLog.receiverID)]; string DefaultValue = receiverID + remark_device_type; switch (eventLog.ioType) { // // 마스터 수신기 // case "M": { ret = "MASTER 수신기" + remark_device_type; } break; // // 로컬 수신기 // case "A": // 전체 if (Convert.ToInt32(eventLog.receiverID) > 0) { ret = DefaultValue;// receiver.Name; //DBAccess.GetReceiverNameFromDB(this.receiverID); } break; case "C": // 통신 { // 설비 차단 즉 DC 의 로그를 분석한 결과 4가지 차단은 총 아래와 같이 5가지 경우이다, 이때 InoutType 은 // 1.회로차단 I // 2.중계기차단 C // 3.루프차단 C // 4.보드차단 C // 5.설비연동 조작 C if (eventLog.eventType == "DC") { // 설비연동 조작 if (eventLog.boardID == 0 && eventLog.repeaterID == 0 && eventLog.deviceID == 0) { ret = DefaultValue; } // 루프 차단 else if (eventLog.boardID != 0 && eventLog.repeaterID == 0 && eventLog.deviceID == 0) { ret = mdi.GetDeviceName(eventLog.boardID, eventLog.commID); if (eventLog.commID == 1) { ret += string.Format(":{0}계통", eventLog.loopNO.ToString()); } } // 중계기 차단 else if (eventLog.boardID != 0 && eventLog.repeaterID != 0 && eventLog.deviceID == 0) { ret = mdi.GetDeviceName(eventLog.boardID, eventLog.loopNO, eventLog.repeaterID); } else ret = DefaultValue; } else if (Convert.ToInt32(eventLog.receiverID) > 0) { ret = DefaultValue;// receiver.Name; } } break; case "B": // 보드 { //deviceName = DBAccess.GetBoardNameFromDB(this.receiverID, this.boardID); ret = mdi.GetDeviceName(eventLog.boardID, eventLog.commID); } break; case "L":// 루프 { //ret = receiver.board[eventLog.boardID - 1].Name; ret = mdi.GetDeviceName(eventLog.boardID, eventLog.commID); if (eventLog.commID == 1) { ret += string.Format(":{0}계통", eventLog.loopNO.ToString()); } } break; case "R": //중계기 { //ret = receiver.board[eventLog.boardID - 1].loop[eventLog.loopNO].repeater[eventLog.repeaterID - 1].Name; ret = mdi.GetDeviceName(eventLog.boardID, eventLog.loopNO, eventLog.repeaterID); break; } case "D": // 장치 { ret = "장치"; break; } case "I": //입력회로 case "O": //출력회로 { // cyim 2015.9.23 키패드조작에서 발생한 이벤트의 경우 회로정보는 null, 장치명은 수신기아이디 표시 if (eventLog.eventType == "MS" || eventLog.eventType == "LS" || eventLog.eventType == "EB" || eventLog.eventType == "RP" || eventLog.eventType == "BF" || eventLog.eventType == "ED" // cyim 2016.12.09 : IFC3300에서는 예비전원버튼 -> 설비전체연동조작버튼 ) { ret = DefaultValue; } else { ret = mdi.GetDeviceName(eventLog.boardID, eventLog.loopNO, eventLog.repeaterID, eventLog.deviceID, eventLog.ioType); } break; } default: { break; } } // 만약에 정보가 없다면 기본값 if (ret == null || ret.Length == 0) ret = DefaultValue; } return ret; } // cyim 2016.12.16 : 모바일앱 연동 - 현재 이력 갱신 private void UPDATE_TB_RECEIVER_ERROR_COUNT_DETAILS(string ID) { if (_Data.Hash_Receiver.ContainsKey(ID) == false) return; // cyim 2016.12.28 : 예외처리 추가 if (_Data.MOBILE_ENABLE == "ON") { _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[ID]; // cyim 2016.12.28 : 예외처리 추가 : 통신데몬 접속상태가 양호하지 않아서 MDIParent 를 로딩하는 중간에 현재이력갱신코드에 접근하는 경우가 발생한다 if (FireDesk_Receiver.mdi == null) return; // cyim 2017.01.04 : 메모리릭을 위한 수정으로 인하여 소멸자로 인하여 이벤트 리스트안에 객체가 일부 소멸되버린다 using (DacReceiverConfig query_session = new DacReceiverConfig(0)) // cyim 2017.01.02 : Memory leak { // // 수신기 ID 에 해당하는 현재이력 정보들을 전부 삭제 // query_session.ExecuteNonQuery(string.Format("delete from TB_RECEIVER_ERROR_COUNT_DETAILS where IP_ADDRESS = '{0}'", FireDesk_Receiver.DATABASE_NAME_IP)); // // 수신기 ID 에 해당하는 현재이력 정보들을 전부 추가 // string IP_ADDRESS = FireDesk_Receiver.DATABASE_NAME_IP; string ERROR_TYPE = ""; string LOCATION = ""; string DEVICE_NAME = ""; string EVENT_TYPE = ""; string DEVICE_NUMBER = ""; Hashtable eventLogInfos_temp = (Hashtable)FireDesk_Receiver.mdi.AryEventLogs.Clone(); if (eventLogInfos_temp != null && eventLogInfos_temp.Count != 0) { foreach (DictionaryEntry d in eventLogInfos_temp) { // cyim 2017.01.04 : 메모리릭을 위한 수정으로 인하여 소멸자로 인하여 이벤트 리스트안에 객체가 일부 소멸되버린다 //using (EventLogInfo eventLogMsg = (EventLogInfo)d.Value) // cyim 2017.01.02 : Memory leak EventLogInfo eventLogMsg = (EventLogInfo)d.Value; { if (eventLogMsg.LiveMsgFlag) { // cyim 2017.01.04 : 메모리릭을 위한 수정으로 인하여 소멸자로 인하여 이벤트 리스트안에 객체가 일부 소멸되버린다 //using (CEventLogData elog = new CEventLogData(eventLogMsg)) // cyim 2017.01.02 : Memory leak CEventLogData elog = new CEventLogData(eventLogMsg); { elog.eventTypeName = eventLogMsg.EventTypeName; LOCATION = elog.devicePosition = GetDevicePositionName(elog, FireDesk_Receiver.mdi); DEVICE_NAME = elog.deviceName = GetDeviceName(elog, FireDesk_Receiver.mdi); // 회로번호 string temp_Report_EventPostion = ""; if (elog.EventPositon == null || elog.EventPositon.Length == 0 || elog.ioType == "M" || elog.EventPositon.Contains("수신기") == true) temp_Report_EventPostion = "없음"; // 만약 수신기 자체 혹은 타수신기 정보라면 회로번호 정보는 표시하지 않는다 else temp_Report_EventPostion = elog.EventPositon; // cyim 2016.01.07 아날로그 감지기 이력 조회시 표시 수정 string RepeaterType = FireDesk_Receiver.mdi.GetRepeaterType(elog.boardID, elog.loopNO, elog.repeaterID); // '1' = A : 2X2 // '2' = B : 4X4 // '4' = C : 아날로그연감지기 // '5' = D : 아날로그열감지기 if (RepeaterType == "4" || RepeaterType == "5") { elog.eventTypeName = elog.eventTypeName.Replace("중계기", "감지기"); // 타입 temp_Report_EventPostion = temp_Report_EventPostion.Replace("중계기", "감지기"); // 회로번호 } DEVICE_NUMBER = elog.Report_EventPositon = temp_Report_EventPostion; // 차단 기능의 경우 특별히 상태값을 알수가 없어서 Remark 정보를 추출해야한다 if (elog.eventType == "DC") { string temp = GetRemarkInfo(elog.eventRemark, "STATUS"); if (temp == "INACTIVE") // 차단 해제 elog.Report_EventErrorStatus = 0; else // 차단 조작 elog.Report_EventErrorStatus = 2; } // cyim 2015.9.23 키패드조작에서 발생한 이벤트의 경우 조작과 해제로 구분하여 표시 // 차단 기능과 마찬가지로 특별히 상태값을 알수가 없어서 Remark 정보를 추출해야한다 else if (elog.eventType == "MS" || elog.eventType == "LS" || elog.eventType == "EB" || elog.eventType == "RP" || elog.eventType == "BF" || elog.eventType == "ED" // cyim 2016.12.09 : IFC3300에서는 예비전원버튼 -> 설비전체연동조작버튼 ) { // KEY PAD MAIN SOUND STOP BUTTON! (OFF) string temp = elog.eventRemark; int idx1 = temp.LastIndexOf('('); int idx2 = temp.LastIndexOf(')'); string temp1 = temp.Substring(idx1); temp1 = temp1.Replace(")", ""); temp1 = temp1.Replace("(", ""); if (temp1 == "ON") // 조작 elog.Report_EventErrorStatus = 0; else // 해제 elog.Report_EventErrorStatus = 2; } // 상위 루틴과 관련없으면 그대로 레포트를 위한 변수에 저장한다 else elog.Report_EventErrorStatus = elog.EventErrorStatus; EVENT_TYPE = FireDesk_Receiver.mdi.EventTypeName.Hash_EventType[elog.eventType].ToString(); ERROR_TYPE = FireDesk_Receiver.mdi.EventTypeName.EventType_Division(elog.eventType); query_session.ExecuteSql(string.Format("insert into TB_RECEIVER_ERROR_COUNT_DETAILS (IP_ADDRESS,ERROR_TYPE,LOCATION,DEVICE_NAME,EVENT_TYPE,DEVICE_NUMBER,EVENT_TIME) values ('{0}','{1}','{2}','{3}','{4}','{5}',current_timestamp)", IP_ADDRESS, ERROR_TYPE, LOCATION, DEVICE_NAME, EVENT_TYPE, DEVICE_NUMBER)); } } } } } } } } // // 타이머 // // 1000 ms 타이머 private void timer_1000_TimeLabelUpdate_Tick(object sende, EventArgs e) { // cyim 2015.9.23 시간정보 표시 오류 (갱신을 안함) MyTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); // 현재 상태 갱신 : 시간표시 this.label_Time.Text = string.Format("{0:yyyy}년 {0:MM}월 {0:dd}일 {0:HH}:{0:mm}:{0:ss}", DateTime.Now); // cyim 2015.9.1 1개의 수신기가 접속이 안되더라도 나머지는 접속시도할수 있도록 수정 : 활성화된 수신기를 개수를 표시한다 if (CommErrorReceiver.Count != 0) label_ReceiverCount.Text = string.Format("전체 수신기 대수 : {0} 개 , 통신 불량 수신기 개수 : {1}", _Data.Hash_Receiver.Keys.Count, CommErrorReceiver.Count); else label_ReceiverCount.Text = string.Format("전체 수신기 대수 : {0} 개", _Data.Hash_Receiver.Keys.Count); } // 통신 체크 타이머 (1초타이머 주기가 아닐수도 있다 주의!) int ConnectCheck_Timer_Tick_Cnt = 0; // cyim 2017.01.05 : 수신기 아이디별 통신체크 루틴 보완 private void ConnectCheck_Timer_Tick(object sende, EventArgs e) { // cyim 2015.9.15 주기적으로 수신기 통신상태를 점검 : 주기마다 한번 수신기 통신 상태를 점검한다 if (ConnectCheck_Timer_Tick_Cnt >= _Data.Hash_Receiver_keys.Length - 1) ConnectCheck_Timer_Tick_Cnt = 0; else ConnectCheck_Timer_Tick_Cnt++; // 1초마다 수신기 체크 MDIParent_Update_Func(_Data.Hash_Receiver_keys[ConnectCheck_Timer_Tick_Cnt]); } // cyim 2016.12.20 : 푸시메세지 연동 기능 추가 public void GCM_Sender_CallBack(object target) { if (this.InvokeRequired) { this.Invoke(new TimerCallback(GCM_Sender_CallBack), new object[] { target }); } else { if (GCM_Sender_Tick_Cnt > 10) GCM_Sender_Tick_Cnt = 0; else GCM_Sender_Tick_Cnt++; if (_Data.MOBILE_ENABLE == "ON" && _Data.GCM_ENABLE == "ON" && _Data.GCM_API_KEY != null) // 둘다 값이 존재해야 한다 { string Comment = ""; // 화재 건수가 몇개인지 확인한다. 아래와 같은 시나리오로 동작하게 만든다 // 1. 화재 발생중인데 또 다른 화재가 발생하면 다시 푸시 메세지를 날린다. // 2. 화재 복구할때는 푸시 메세지를 날리지 않는다. // 3. 너무 짧은 주기로 GCM 을 보내지 않도록 한다. // 화재 if (_Data.GCM_INFO_FIRE == "ON" && GCM_Sender_Tick_Cnt == 0) { Comment = ""; if (GCM_Fire_Clone.Count != 0) Comment = string.Format("화재! 수신기ID:{0}", Receiver_ID_List_String(GCM_Fire_Clone)); if (timer_1000_Tick_Fire_Cnt_New != timer_1000_Tick_Fire_Cnt_Old && timer_1000_Tick_Fire_Cnt_New > timer_1000_Tick_Fire_Cnt_Old) GCM_Send(Comment); timer_1000_Tick_Fire_Cnt_Old = timer_1000_Tick_Fire_Cnt_New; } // 설비 if (_Data.GCM_INFO_FACILITY == "ON" && GCM_Sender_Tick_Cnt == 2) { Comment = ""; if (GCM_Facility_Clone.Count != 0) Comment = string.Format("설비! 수신기ID:{0}", Receiver_ID_List_String(GCM_Facility_Clone)); if (timer_1000_Tick_Facility_Cnt_New != timer_1000_Tick_Facility_Cnt_Old && timer_1000_Tick_Facility_Cnt_New > timer_1000_Tick_Facility_Cnt_Old) GCM_Send(Comment); timer_1000_Tick_Facility_Cnt_Old = timer_1000_Tick_Facility_Cnt_New; } // 통신에러 if (_Data.GCM_INFO_COMERROR == "ON" && GCM_Sender_Tick_Cnt == 4) { Comment = ""; if (GCM_ComError_Clone.Count != 0) Comment = string.Format("통신! 수신기ID:{0}", Receiver_ID_List_String(GCM_ComError_Clone)); if (timer_1000_Tick_ComError_Cnt_New != timer_1000_Tick_ComError_Cnt_Old && timer_1000_Tick_ComError_Cnt_New > timer_1000_Tick_ComError_Cnt_Old) GCM_Send(Comment); timer_1000_Tick_ComError_Cnt_Old = timer_1000_Tick_ComError_Cnt_New; } // 단선 if (_Data.GCM_INFO_BLOCK == "ON" && GCM_Sender_Tick_Cnt == 6) { Comment = ""; if (GCM_Block_Clone.Count != 0) Comment = string.Format("단선! 수신기ID:{0}", Receiver_ID_List_String(GCM_Block_Clone)); if (timer_1000_Tick_Block_Cnt_New != timer_1000_Tick_Block_Cnt_Old && timer_1000_Tick_Block_Cnt_New > timer_1000_Tick_Block_Cnt_Old) GCM_Send(Comment); timer_1000_Tick_Block_Cnt_Old = timer_1000_Tick_Block_Cnt_New; } // 차단 if (_Data.GCM_INFO_CUT == "ON" && GCM_Sender_Tick_Cnt == 8) { Comment = ""; if (GCM_Cut_Clone.Count != 0) Comment = string.Format("차단! 수신기ID:{0}", Receiver_ID_List_String(GCM_Cut_Clone)); if (timer_1000_Tick_Cut_Cnt_New != timer_1000_Tick_Cut_Cnt_Old && timer_1000_Tick_Cut_Cnt_New > timer_1000_Tick_Cut_Cnt_Old) GCM_Send(Comment); timer_1000_Tick_Cut_Cnt_Old = timer_1000_Tick_Cut_Cnt_New; } // 점검 if (_Data.GCM_INFO_CHECK == "ON" && GCM_Sender_Tick_Cnt == 10) { Comment = ""; if (GCM_Check_Clone.Count != 0) Comment = string.Format("점검! 수신기ID:{0}", Receiver_ID_List_String(GCM_Check_Clone)); if (timer_1000_Tick_Check_Cnt_New != timer_1000_Tick_Check_Cnt_Old && timer_1000_Tick_Check_Cnt_New > timer_1000_Tick_Check_Cnt_Old) GCM_Send(Comment); timer_1000_Tick_Check_Cnt_Old = timer_1000_Tick_Check_Cnt_New; } } } } // 수신기 아이디 리스트로 부터 문자열로 생성 private string Receiver_ID_List_String(ArrayList al) { string DataString = null; foreach (string datas in al) DataString += datas + " "; return DataString.Trim(); } // 데이타베이스에 등록된 모바일앱 디바이스 아이디를 조회하고, GCM 을 송출한다 public void GCM_Send(string Comment) { Thread WorkingThread = new Thread(new ParameterizedThreadStart(GCM_Send_Thread)); WorkingThread.Start(Comment); } // 스레드로 처리해야한다 public void GCM_Send_Thread(object Comment) { using (DacReceiverConfig push_info_select_query = new DacReceiverConfig(0)) { DataSet ds = push_info_select_query.Select("select * from TB_PUSH_DEVICE"); DataTable dt = ds.Tables[0]; foreach (DataRow dr in dt.Rows) { string Regid = dr["REG_ID"].ToString(); var push = new PushBroker(); push.OnNotificationSent += NotificationSent; push.OnChannelException += ChannelException; push.OnServiceException += ServiceException; push.OnNotificationFailed += NotificationFailed; push.OnDeviceSubscriptionExpired += DeviceSubscriptionExpired; push.OnDeviceSubscriptionChanged += DeviceSubscriptionChanged; push.OnChannelCreated += ChannelCreated; push.OnChannelDestroyed += ChannelDestroyed; //txtApiKey.Text is API KEY for server applications from Google Developers Console push.RegisterGcmService(new GcmPushChannelSettings(_Data.GCM_API_KEY)); //txtRegistrationID.Text is a value of e.regid from the onNotificationGCM function in the PushTest app push.QueueNotification(new GcmNotification() .ForDeviceRegistrationId(Regid) .WithJson("{\"message\":\"" + Comment.ToString() + "\"}")); push.StopAllServices(); } } } private void NotificationSent(object sender, INotification notification) { //txtLogs.Invoke((MethodInvoker)(() => { txtLogs.AppendText("NotificationSent" + Environment.NewLine); })); } private void ChannelException(object sender, IPushChannel pushChannel, Exception error) { //txtLogs.Invoke((MethodInvoker)(() => { txtLogs.AppendText("ChannelException: " + error.Message + Environment.NewLine); })); } private void ServiceException(object sender, Exception error) { //txtLogs.Invoke((MethodInvoker)(() => { txtLogs.AppendText("ServiceException: " + error.Message + Environment.NewLine); })); } private void NotificationFailed(object sender, INotification notification, Exception error) { //txtLogs.Invoke((MethodInvoker)(() => { txtLogs.AppendText("NotificationFailed: " + error.Message + Environment.NewLine); })); } private void DeviceSubscriptionExpired(object sender, string expiredSubscriptionId, DateTime expirationDateUtc, INotification notification) { //txtLogs.Invoke((MethodInvoker)(() => { txtLogs.AppendText("DeviceSubscriptionExpired" + Environment.NewLine); })); } private void DeviceSubscriptionChanged(object sender, string oldSubscriptionId, string newSubscriptionId, INotification notification) { //txtLogs.Invoke((MethodInvoker)(() => { txtLogs.AppendText("DeviceSubscriptionChanged" + Environment.NewLine); })); } private void ChannelCreated(object sender, IPushChannel pushChannel) { //txtLogs.Invoke((MethodInvoker)(() => { txtLogs.AppendText("ChannelCreated" + Environment.NewLine); })); } private void ChannelDestroyed(object sender) { //txtLogs.Invoke((MethodInvoker)(() => { txtLogs.AppendText("ChannelDestroyed" + Environment.NewLine); })); } // 알람 상태 표시 bool Display_Timer_toggle = false; // 500 ms 타이머 private void Display_Timer_Tick(object sende, EventArgs e) { // 초기화 팝업창때는 실행안됨 if (waitingForm_FireDesk != null && waitingForm_FireDesk.Visible == true) return; // 토글용 Display_Timer_toggle = !Display_Timer_toggle; // // 전체현황 카운터 표시 // fireCount = 0; facilityCount = 0; errorCount = 0; blockingCount = 0; cutCnt = 0; checkCnt = 0; fireCount_Accumulation = 0; PreFireList = new ArrayList(); // cyim 2016.12.20 : 푸시메세지 연동 기능 추가 GCM_Fire_List.Clear(); GCM_Facility_List.Clear(); GCM_ComError_List.Clear(); GCM_Block_List.Clear(); GCM_Cut_List.Clear(); GCM_Check_List.Clear(); foreach (string id in _Data.Hash_Receiver_keys) { _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[id]; // cyim 2015.9.1 1개의 수신기가 접속이 안되더라도 나머지는 접속시도할수 있도록 수정 if (FireDesk_Receiver.mdi != null) { // 화재 fireCount = fireCount + FireDesk_Receiver.mdi.fireCount; // 설비 facilityCount = facilityCount + FireDesk_Receiver.mdi.facilityCount; // 통신 errorCount = errorCount + FireDesk_Receiver.mdi.errorCount; // 단선 blockingCount = blockingCount + FireDesk_Receiver.mdi.blockingCount; // 차단 cutCnt = cutCnt + FireDesk_Receiver.mdi.CutCnt; // 축적화재 fireCount_Accumulation = fireCount_Accumulation + FireDesk_Receiver.mdi.fireCount_Accumulation; // 아날로그감지기의 PreFire foreach (string data in FireDesk_Receiver.mdi.PreFireList) PreFireList.Add(data); // cyim 2016.12.20 : 푸시메세지 연동 기능 추가 if (FireDesk_Receiver.mdi.fireCount > 0) GCM_Fire_List.Add(id); if (FireDesk_Receiver.mdi.facilityCount > 0) GCM_Facility_List.Add(id); if (FireDesk_Receiver.mdi.errorCount > 0) GCM_ComError_List.Add(id); if (FireDesk_Receiver.mdi.blockingCount > 0) GCM_Block_List.Add(id); if (FireDesk_Receiver.mdi.CutCnt > 0) GCM_Cut_List.Add(id); if (FireDesk_Receiver.mdi.fireCount > 0) GCM_Check_List.Add(id); if (FireDesk_Receiver.mdi.CheckBtn_Current_Status == true || FireDesk_Receiver.mdi.CommDaemon_ComStatus == false // 통신데몬연결이상 || FireDesk_Receiver.mdi.lblEmergencyBoardStatus_Visible == true // 비상방송연결이상 ) // cyim 2017.01.04 : 점검출력이 안되는 문제 수정 //|| FireDesk_Receiver.mdi.socketUI == null // cyim 2016.12.28 : 예외처리 추가 //|| FireDesk_Receiver.mdi.socketUI.myCntLabel.Visible == true) { // 점검 내용 checkCnt = checkCnt + 1; GCM_Check_List.Add(id); } } } // cyim 2016.12.20 : 푸시메세지 연동 기능 추가 timer_1000_Tick_Fire_Cnt_New = fireCount; timer_1000_Tick_Facility_Cnt_New = facilityCount; timer_1000_Tick_ComError_Cnt_New = errorCount; timer_1000_Tick_Block_Cnt_New = blockingCount; timer_1000_Tick_Cut_Cnt_New = cutCnt; timer_1000_Tick_Check_Cnt_New = checkCnt; GCM_Fire_Clone = (ArrayList)GCM_Fire_List.Clone(); GCM_Facility_Clone = (ArrayList)GCM_Facility_List.Clone(); GCM_ComError_Clone = (ArrayList)GCM_ComError_List.Clone(); GCM_Block_Clone = (ArrayList)GCM_Block_List.Clone(); GCM_Cut_Clone = (ArrayList)GCM_Cut_List.Clone(); GCM_Check_Clone = (ArrayList)GCM_Check_List.Clone(); // 전체 현황의 경우 카운터가 0이상이면 깜빡거리게 만든다 Toggle_ControlForeColor(this.label_CurrentStatus_Fire, fireCount, string.Format("화재({0})", fireCount)); Toggle_ControlForeColor(this.label_CurrentStatus_Facility, facilityCount, string.Format("설비({0})", facilityCount)); Toggle_ControlForeColor(this.label_CurrentStatus_Error, errorCount, string.Format("통신({0})", errorCount)); Toggle_ControlForeColor(this.label_CurrentStatus_Blocking, blockingCount, string.Format("단선({0})", blockingCount)); Toggle_ControlForeColor(this.label_CurrentStatus_Cut, cutCnt, string.Format("차단({0})", cutCnt)); // // 점검 표시 // foreach (string id in _Data.Hash_Receiver_keys) { _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[id]; Button btn = (Button)Util.FineControl(panel_Receiver, "button_Check" + id.ToString()); // cyim 2015.9.1 1개의 수신기가 접속이 안되더라도 나머지는 접속시도할수 있도록 수정 if (FireDesk_Receiver.mdi != null) { // 점검 if (FireDesk_Receiver.mdi.CheckBtn_Current_Status == true || FireDesk_Receiver.mdi.CommDaemon_ComStatus == false // 통신데몬연결이상 || FireDesk_Receiver.mdi.lblEmergencyBoardStatus_Visible == true // 비상방송연결이상 ) // cyim 2017.01.04 : 점검출력이 안되는 문제 수정 //|| FireDesk_Receiver.mdi.socketUI == null // cyim 2016.12.28 : 예외처리 추가 //|| FireDesk_Receiver.mdi.socketUI.myCntLabel.Visible == true) { Toggle_ControlBackColor(btn, 1, null); } else Toggle_ControlBackColor(btn, 0, null); } } // cyim 2015.9.15 수신반 하단 이벤트 표시 : 화재 및 설비 표시 FireFacilityEventCheck(); // cyim 2016.06.15 : 화재 음원 출력 if (SoundPlayer_AlarmPopupSound_Count > 6) { SoundPlayer_AlarmPopupSound_Count = 0; // 3초마다 AlarmPopup_PlaySound_Check(); } else { SoundPlayer_AlarmPopupSound_Count++; } } // cyim 2016.06.15 : 화재 음원 출력 public void AlarmPopup_PlaySound_Check() { if (SoundPlayer_AlarmPopupSound != null) // cyim 2016.11.11 : 비상 음원 출력 음원 파일 없을때 대응 코드 추가 { if (this.label_FireAlert.Visible == true || this.label_FacilityAlert.Visible == true) // cyim 2016.06.16 : 설비동작 발생시 음원 출력 포함 SoundPlayer_AlarmPopupSound.Play(); else SoundPlayer_AlarmPopupSound.Stop(); } } // 글자색을 토글 private void Toggle_ControlForeColor(Label label, int count, string text) { if (count > 0) { if (Display_Timer_toggle == true) label.ForeColor = Color.White; else label.ForeColor = Color.Red; } else { if (label.ForeColor != Color.White) label.ForeColor = Color.White; } if (text != null) label.Text = text; } // 배경색을 토글 private void Toggle_ControlBackColor(Control ctrl, int count, string text) { if (count > 0) { if (Display_Timer_toggle == true) ctrl.BackColor = Color.Transparent; else ctrl.BackColor = Color.Red; } else { if (ctrl.BackColor != Color.Transparent) ctrl.BackColor = Color.Transparent; } if (text != null) ctrl.Text = text; } // // cyim 2015.9.15 수신반 하단 이벤트 표시 : 화재 및 설비 표시루틴을 그대로 이용하도록 한다 MdiParent.cs 와 동일함 // public void FireFacilityEventCheck() { { // // 화재 // if (this.fireCount > 0) { this.label_FireAlert.Visible = true; //this.labelFireAlert.Image = null;//sdkim, 20120129, [MTS-47] this.label_FireAlert_inform_1th.Visible = true; this.txtFirstFireWarnningMessage.Visible = true; if (this.fireCount > 1) { this.label_FireAlert_inform_2th.Visible = true; this.cboSecondFireWarnningMessage.Visible = true; } else { this.label_FireAlert_inform_2th.Visible = false; this.cboSecondFireWarnningMessage.Visible = false; } if (Display_Timer_toggle == false) { this.label_FireAlert.BackColor = Color.Red; this.label_FireAlert.ForeColor = Color.Black; } else { this.label_FireAlert.BackColor = Color.Transparent; this.label_FireAlert.ForeColor = Color.Red; } } // cyim 2014.7.10 : 축적화재 표시 : KFI 요청사항 else if (this.fireCount_Accumulation > 0) { // 상위 화재와 동일한 코드이다. 굳이 상위와 합치지 않은 이유는 우선순위는 무조건 일반 화재가 높기 때문이다. (위험도 고려) this.label_FireAlert.Visible = true; //this.labelFireAlert.Image = null;//sdkim, 20120129, [MTS-47] this.label_FireAlert_inform_1th.Visible = true; this.txtFirstFireWarnningMessage.Visible = true; if (this.fireCount_Accumulation > 1) { this.label_FireAlert_inform_2th.Visible = true; this.cboSecondFireWarnningMessage.Visible = true; } else { this.label_FireAlert_inform_2th.Visible = false; this.cboSecondFireWarnningMessage.Visible = false; } if (Display_Timer_toggle == false) { this.label_FireAlert.BackColor = Color.Red; this.label_FireAlert.ForeColor = Color.Black; } else { this.label_FireAlert.BackColor = Color.Transparent; this.label_FireAlert.ForeColor = Color.Red; } } else { this.label_FireAlert.Visible = false; this.txtFirstFireWarnningMessage.Visible = false; this.label_FireAlert_inform_1th.Visible = false; this.cboSecondFireWarnningMessage.Visible = false; this.cboSecondFireWarnningMessage.Items.Clear(); this.label_FireAlert_inform_2th.Visible = false; } // // cyim 2015.7.9 PreFire 표시 문제 : 아날로그 감지기는 PreFire 단계가 있다 // if (this.PreFireList.Count > 0) { this.labelPreFireAlert.Visible = true; this.cboPreFireWarnningMessage.Visible = true; if (Display_Timer_toggle == false) { this.labelPreFireAlert.BackColor = Color.Red; this.labelPreFireAlert.ForeColor = Color.Black; } else { this.labelPreFireAlert.BackColor = Color.Transparent; this.labelPreFireAlert.ForeColor = Color.Red; } } else { this.labelPreFireAlert.Visible = false; this.cboPreFireWarnningMessage.Visible = false; this.cboPreFireWarnningMessage.Items.Clear(); } // // 설비 // if (this.facilityCount > 0) { this.label_FacilityAlert.Visible = true; //this.labelFacilityAlert.Image = null;//sdkim, 20120129, [MTS-47] this.cboWriteWarningMessage.Visible = true; this.label_FacilityAlert_inform_1th.Visible = true; if (Display_Timer_toggle == false) { this.label_FacilityAlert.BackColor = Color.Blue; this.label_FacilityAlert.ForeColor = Color.White; } else { this.label_FacilityAlert.BackColor = Color.Transparent; this.label_FacilityAlert.ForeColor = Color.LightSkyBlue; } } else { this.label_FacilityAlert.Visible = false; this.cboWriteWarningMessage.Visible = false; this.cboWriteWarningMessage.Items.Clear(); this.label_FacilityAlert_inform_1th.Visible = false; } LEDCount = LEDList.Count; if (this.LEDCount > 0) { this.lblLEDText.Text = LEDList[LEDCount - 1].ToString(); this.lblLEDText.Visible = true; //this.labelFacilityAlert.Image = null;//sdkim, 20120129, [MTS-47] if (Display_Timer_toggle == false) { this.lblLEDText.BackColor = Color.LightPink; this.lblLEDText.ForeColor = Color.White; } else { this.lblLEDText.BackColor = Color.Transparent; this.lblLEDText.ForeColor = Color.LightPink; } } else { this.lblLEDText.Visible = false; } } } // // cyim 2015.9.15 수신반 하단 이벤트 표시 // 현재 접속되어있는 데몬을 기준으로 화재 정보를 처리한다 // 화재,축적,아날로그 Prefire,설비 의 경우 이벤트가 발생하면 아래의 함수에서 글자를 셋팅한다 // public void FireEventProcess() { // 일반화재 int iFireEventCount = FireList.Count; // 축적화재 int iFireEventCount_Accumulation = FireList_Accumulation.Count; try { if (this.cboSecondFireWarnningMessage.InvokeRequired) { dCommandFuctionCallEvent d = new dCommandFuctionCallEvent(FireEventProcess); this.cboSecondFireWarnningMessage.Invoke(d, new object[] { }); } else { this.Focus(); // cyim 2014.5.15 : OutofRangeException this.cboSecondFireWarnningMessage.Items.Clear(); this.cboSecondFireWarnningMessage.Text = ""; if (iFireEventCount > 0) { // 2보 정리 for (int iLoop = 1; iLoop < iFireEventCount; iLoop++) this.cboSecondFireWarnningMessage.Items.Add(FireList[iLoop].ToString()); if (this.cboSecondFireWarnningMessage.Items.Count > 0) this.cboSecondFireWarnningMessage.Text = this.cboSecondFireWarnningMessage.Items[0].ToString(); // 1보 정리 this.txtFirstFireWarnningMessage.Text = FireList[0].ToString(); // 화재 타입 this.label_FireAlert.Text = "화재발생"; } // cyim 2014.7.10 : 축적화재 표시 : KFI 요청사항 else if (iFireEventCount_Accumulation > 0) { // 2보 정리 for (int iLoop = 1; iLoop < iFireEventCount_Accumulation; iLoop++) this.cboSecondFireWarnningMessage.Items.Add(FireList_Accumulation[iLoop].ToString()); if (this.cboSecondFireWarnningMessage.Items.Count > 0) this.cboSecondFireWarnningMessage.Text = this.cboSecondFireWarnningMessage.Items[0].ToString(); // 1보 정리 this.txtFirstFireWarnningMessage.Text = FireList_Accumulation[0].ToString(); // 화재 타입 this.label_FireAlert.Text = "화재축적상태 발생"; } } } catch (Exception ex) { Util.UErrorMessage(ex, 0, 0); } } public delegate void dCommandFuctionCallEvent_PreFireEventProcess(); public void PreFireEventProcess() { // PreFire int iPreFireListCount = PreFireList.Count; if (this.cboPreFireWarnningMessage.InvokeRequired) { dCommandFuctionCallEvent_PreFireEventProcess d = new dCommandFuctionCallEvent_PreFireEventProcess(PreFireEventProcess); this.cboPreFireWarnningMessage.Invoke(d, new object[] { }); } else { this.Focus(); // OutofRangeException 문제 수정 this.cboPreFireWarnningMessage.Items.Clear(); this.cboPreFireWarnningMessage.Text = ""; if (PreFireList.Count > 0) { for (int i = 0; i < iPreFireListCount; i++) this.cboPreFireWarnningMessage.Items.Add(PreFireList[i].ToString()); this.cboPreFireWarnningMessage.Text = PreFireList[0].ToString(); } } } public delegate void dCommandFuctionCallEvent(); public void EquipEventProcess() { int iEquipEventCount = EquipList.Count; try { if (this.cboWriteWarningMessage.InvokeRequired) { dCommandFuctionCallEvent d = new dCommandFuctionCallEvent(EquipEventProcess); this.cboWriteWarningMessage.Invoke(d, new object[] { }); } else { this.Focus(); // cyim 2014.5.15 : OutofRangeException this.cboWriteWarningMessage.Items.Clear(); this.cboWriteWarningMessage.Text = ""; if (iEquipEventCount > 0) { for (int iLoop = 0; iLoop < iEquipEventCount; iLoop++) { this.cboWriteWarningMessage.Items.Add(EquipList[iLoop].ToString()); } if (this.cboWriteWarningMessage.Items.Count > 0) { this.cboWriteWarningMessage.Text = this.cboWriteWarningMessage.Items[0].ToString(); } } } } catch (Exception ex) { Util.UErrorMessage(ex, 0, 0); } } // cyim 2016.12.16 : 모바일앱 연동 - 카운트 정보 갱신 private void UPDATE_TB_RECEIVER_ERROR_COUNT(int ID, string Type, int pValue) { if (_Data.MOBILE_ENABLE == "ON") { _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[ID.ToString()]; // cyim 2017.01.04 : 메모리릭을 위한 수정으로 인하여 소멸자로 인하여 이벤트 리스트안에 객체가 일부 소멸되버린다 string Value = pValue.ToString(); using (DacReceiverConfig query_session = new DacReceiverConfig(0)) { switch (Type) { case "FireDetect": query_session.ExecuteSql(string.Format("update TB_RECEIVER_ERROR_COUNT set {1} = {2} where IP_ADDRESS = '{0}'", FireDesk_Receiver.DATABASE_NAME_IP, "INFO1", Value)); break; case "DeviceInput": query_session.ExecuteSql(string.Format("update TB_RECEIVER_ERROR_COUNT set {1} = {2} where IP_ADDRESS = '{0}'", FireDesk_Receiver.DATABASE_NAME_IP, "INFO2", Value)); break; case "RepeaterError": query_session.ExecuteSql(string.Format("update TB_RECEIVER_ERROR_COUNT set {1} = {2} where IP_ADDRESS = '{0}'", FireDesk_Receiver.DATABASE_NAME_IP, "INFO3", Value)); break; case "DeviceCut": query_session.ExecuteSql(string.Format("update TB_RECEIVER_ERROR_COUNT set {1} = {2} where IP_ADDRESS = '{0}'", FireDesk_Receiver.DATABASE_NAME_IP, "INFO4", Value)); break; case "DeviceNotuse": query_session.ExecuteSql(string.Format("update TB_RECEIVER_ERROR_COUNT set {1} = {2} where IP_ADDRESS = '{0}'", FireDesk_Receiver.DATABASE_NAME_IP, "INFO5", Value)); break; } } } } // // 이벤트 // // 외부에서 화면을 변경하는 경우 private void _Event_FireDesk_Update_SendMessage_Event(int id, string cmd, string type, int data) { // 카운터 업데이트 if (cmd == "Count") { // cyim 2016.12.16 : 모바일앱 연동 - 카운트 정보 갱신 UPDATE_TB_RECEIVER_ERROR_COUNT(id, type, data); // 화재 if (type == "FireDetect") { Button btn = (Button)Util.FineControl(panel_Receiver, "button_FireDetect" + id.ToString()); btn.Text = string.Format("화재 : {0:0000}", data); if (data > 9999) btn.Text = String.Format("화재 : {0:00000}", data); else btn.Text = String.Format("화재 : {0:0000}", data); } // 설비 else if (type == "DeviceInput") { Button btn = (Button)Util.FineControl(panel_Receiver, "button_DeviceInput" + id.ToString()); btn.Text = string.Format("설비 : {0:0000}", data); if (data > 9999) btn.Text = String.Format("설비 : {0:00000}", data); else btn.Text = String.Format("설비 : {0:0000}", data); } // 통신 else if (type == "RepeaterError") { Button btn = (Button)Util.FineControl(panel_Receiver, "button_RepeaterError" + id.ToString()); btn.Text = string.Format("통신 : {0:0000}", data); if (data > 9999) btn.Text = String.Format("통신 : {0:00000}", data); else btn.Text = String.Format("통신 : {0:0000}", data); } // 단선 else if (type == "DeviceCut") { Button btn = (Button)Util.FineControl(panel_Receiver, "button_DeviceCut" + id.ToString()); btn.Text = string.Format("단선 : {0:0000}", data); if (data > 9999) btn.Text = String.Format("단선 : {0:00000}", data); else btn.Text = String.Format("단선 : {0:0000}", data); } // 차단 else if (type == "DeviceNotuse") { Button btn = (Button)Util.FineControl(panel_Receiver, "button_DeviceNotuse" + id.ToString()); btn.Text = string.Format("차단 : {0:0000}", data); if (data > 9999) btn.Text = String.Format("차단 : {0:00000}", data); else btn.Text = String.Format("차단 : {0:0000}", data); } } // 폼을 로드 else if (cmd == "FormLoad") { // 완료 if (type == "MDIParentComplete") { FormLoadComplete = false; // cyim 2016.12.29 : 화면 멈춤 문제 수정 : 주석처리 // 원래 용도는 로드이후 리스트에서 삭제하려고 했으나 // 네트워크 데이타베이스를 이용하는 상태에서 삭제 타이밍을 맞추기가 어렵다고 결론내림 //LoadMdiparentFormList.Remove(id.ToString()); } } // 팝업창을 로드 else if (cmd == "Popup") { ShowWaitingMsgForm(string.Format("수신기 [{0}]:", id) + type, data); } // cyim 2015.9.15 : 일반화재,축적화재,PreFire,설비,복구 의 경우 이벤트로 처리 (참고로 카운터 표시는 주기적으로 함) else if (cmd == "EventProcess") { if (type == "Fire") // 일반화재, 축적화재 { FireList.Clear(); FireList_Accumulation.Clear(); foreach (string ID in _Data.Hash_Receiver_keys) { _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[ID]; foreach (string item in FireDesk_Receiver.mdi.FireList) if (FireList.Contains(item) == false) FireList.Add(item); foreach (string item in FireDesk_Receiver.mdi.FireList_Accumulation) if (FireList_Accumulation.Contains(item) == false) FireList_Accumulation.Add(item); } FireEventProcess(); } else if (type == "PreFire") // PreFire { PreFireList.Clear(); foreach (string ID in _Data.Hash_Receiver_keys) { _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[ID]; foreach (string item in FireDesk_Receiver.mdi.PreFireList) if (PreFireList.Contains(item) == false) PreFireList.Add(item); } PreFireEventProcess(); } else if (type == "Equip") // 설비 { EquipList.Clear(); foreach (string ID in _Data.Hash_Receiver_keys) { _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[ID]; foreach (string item in FireDesk_Receiver.mdi.EquipList) if (EquipList.Contains(item) == false) EquipList.Add(item); } EquipEventProcess(); } else if (type == "Reset") // 복구 { FireList.Clear(); FireList_Accumulation.Clear(); PreFireList.Clear(); EquipList.Clear(); // 복구할 때는 현재 복구하는 수신기만 제외하고 다시 불러 읽어들인다 foreach (string ID in _Data.Hash_Receiver_keys) { if (id.ToString() != ID) { _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[ID]; foreach (string item in FireDesk_Receiver.mdi.FireList) if (FireList.Contains(item) == false) FireList.Add(item); foreach (string item in FireDesk_Receiver.mdi.FireList_Accumulation) if (FireList_Accumulation.Contains(item) == false) FireList_Accumulation.Add(item); foreach (string item in FireDesk_Receiver.mdi.PreFireList) if (PreFireList.Contains(item) == false) PreFireList.Add(item); foreach (string item in FireDesk_Receiver.mdi.EquipList) if (EquipList.Contains(item) == false) EquipList.Add(item); } } FireEventProcess(); PreFireEventProcess(); EquipEventProcess(); } } } // 수신기 버튼 private void button_Receiver_Click(object sender, EventArgs e) { Button btn = (Button)sender; string id = btn.Tag.ToString(); _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[id]; FireDesk_Receiver.mdi.Visible = true; } // 수신기 복구 버튼 private void button_Recover_Click(object sender, EventArgs e) { if (MessageBox.Show("수신기에 복구 명령을 수행하시겠습니까?", Application.ProductName, MessageBoxButtons.YesNo) == DialogResult.Yes) { Button btn = (Button)sender; string id = btn.Tag.ToString(); _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[id]; FireDesk_Receiver.mdi.Visible = true; // cyim 2015.8.18 수신기복구 기능 추가 // 해당 수신기의 화면으로 자동으로 들어가서 수신기 복구 팝업창을 확인하고 나올수 있도록 수정한다 FireDesk_Receiver.mdi.FireReset_Process(); FireDesk_Receiver.mdi.socketUI.ReceiverDemonReset(); } } // 주음향정지 private void button_MainSoundStop_Click(object sender, EventArgs e) { if (MessageBox.Show("모든 수신기에 주음향정지 명령을 수행하시겠습니까?", Application.ProductName, MessageBoxButtons.YesNo) == DialogResult.Yes) { foreach (string id in _Data.Hash_Receiver_keys) { _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[id]; FireDesk_Receiver.mdi.ShowControlWrite(true, 0); // cyim 2015.8.18 주경종정지 기능 추가 } } } // 연동상태조회 private void button_SearchControl_Click(object sender, EventArgs e) { if (_Data.FireDesk_Operation_Enable == false) // cyim 2015.8.3 수신반 연동기능 추가 { FireDesk_Operation Operation = new FireDesk_Operation(); Operation.Show(); } } // 과거내역통합조회 private void button_SearchHistory_Click(object sender, EventArgs e) { if (_Data.FireDesk_FormLogView_Enable == false) { FireDesk_FormLogView FormLogView = new FireDesk_FormLogView(this); FormLogView.Show(); } } // // cyim 2015.9.11 : 과거내역 통합조회창에서 사용할 DB 에서 미리 읽은값을 사용하도록 수정함 // DB 에서 보드, 중계기, 디바이스 정보를 가져온다 // // 보드 //DataTable dtBoardList = null; public void GetBoardDB() { DacBoardConfig dacBoardConfig = new DacBoardConfig(0); // cyim 2015.7.30 데이타베이스 접속 루틴 변경 _Data.dtBoardList = dacBoardConfig.SelectBoard(0); } // 중계기 //DataTable dtRepeaterList2 = null; public void GetRepeaterDB() { DacRepeaterConfig dacRepeaterConfig = new DacRepeaterConfig(0); // cyim 2015.7.30 데이타베이스 접속 루틴 변경 _Data.dtRepeaterList2 = dacRepeaterConfig.SelectRepeater2(0); } // 아날로그감지기 레벨 //DataTable dtAnalogDetecterLevel = null; public void GetAnalogDetecterLevelDB() { DacRepeaterConfig dacRepeaterConfig = new DacRepeaterConfig(0); // cyim 2015.7.30 데이타베이스 접속 루틴 변경 _Data.dtAnalogDetecterLevel = dacRepeaterConfig.SelectRepeater_AnalogDetecterLevel(0); } // 디바이스 //DataTable dtDeviceDBList2 = null; public void GetDeviceDB() { DacDeviceConfig dacDeviceConfig = new DacDeviceConfig(0); // cyim 2015.7.30 데이타베이스 접속 루틴 변경 _Data.dtDeviceDBList2 = dacDeviceConfig.SelectDevice2(0); } // cyim 2015.7.1 속도개선작업 // 데이타베이스 파일을 미리 읽도록 하되, DataTable 에 한해서 Foreach -> Select 으로 대체 // DataTable 에서 정보를 가져온다 // 중계기 이름을 얻어온다. public string GetDeviceName(int BOARD_ID, int LOOP_NO, int REPEATER_ID) { string ret = ""; if (_Data.dtRepeaterList2 != null) { // cyim 2015.7.1 속도개선작업 DataRow[] result = _Data.dtRepeaterList2.Select( string.Format("BOARD_ID={0} AND LOOP_NO={1} AND REPEATER_ID={2}", BOARD_ID, LOOP_NO, REPEATER_ID)); if (result != null && result.Length > 0) ret = result[0]["REPEATER_NAME"].ToString(); } return ret; } // 보드명을 가져온다 public string GetDeviceName(int BOARD_ID, int CommID) { string ret = ""; if (_Data.dtBoardList != null) { // cyim 2015.7.1 속도개선작업 DataRow[] result = _Data.dtBoardList.Select( string.Format("BOARD_ID={0} AND COMM_ID={1}", BOARD_ID, CommID)); if (result != null && result.Length > 0) ret = result[0]["BOARD_NAME"].ToString(); } return ret; } // 회로명을 가져온다 public string GetDeviceName(int BOARD_ID, int LOOP_NO, int REPEATER_ID, int DEVICE_ID, String INOUT_TYPE) { string ret = ""; if (_Data.dtDeviceDBList2 != null) { // cyim 2015.7.1 속도개선작업 DataRow[] result = _Data.dtDeviceDBList2.Select( string.Format("BOARD_ID={0} AND COMM_ID={1} AND LOOP_NO={2} AND REPEATER_ID={3} AND DEVICE_ID={4} AND INOUT_TYPE='{5}'", // cyim 2015.7.8 쿼리수정 , Inout 타입의 경우 ' ' 작은따옴표를 사용해야함, 이벤트로그가 안보이게됨 BOARD_ID, 1, LOOP_NO, REPEATER_ID, DEVICE_ID, INOUT_TYPE)); if (result != null && result.Length > 0) ret = result[0]["DEVICE_NAME"].ToString(); } return ret; } // 조건에 맞는 중계기의 위치명 / 위치 코드 / 중계기 명칭을 리턴한다. public string GetDevicePositionName(int BOARD_ID, int LOOP_NO, int REPEATER_ID) { string ret = ""; if (_Data.dtRepeaterList2 != null) { // cyim 2015.7.1 속도개선작업 DataRow[] result = _Data.dtRepeaterList2.Select( string.Format("BOARD_ID={0} AND LOOP_NO={2} AND REPEATER_ID={3}", BOARD_ID, 1, LOOP_NO, REPEATER_ID)); if (result != null && result.Length > 0) { // 만약 위치 명이 있으면, 위치명으로 리턴한다. if (result[0]["POSITION_NAME"].ToString() != "") ret = result[0]["POSITION_NAME"].ToString(); // 위치명이 없고.. 위치 코드가 있으면, 위치 코드를 리턴하도록 한다. else if (result[0]["POSITION_CODE"].ToString() != "") ret = result[0]["POSITION_CODE"].ToString(); // 기본값 RepeaterName을 리턴할 준비를 한다. else ret = result[0]["REPEATER_NAME"].ToString(); } } return ret; } // 디바이스 위치를 리턴한다. 만약 맞는 위치명이 없으면.. 위치 코드라도 리턴한다. public string GetDevicePositionName(int BOARD_ID, int LOOP_NO, int REPEATER_ID, int DEVICE_ID, String INOUT_TYPE) { string ret = ""; if (_Data.dtDeviceDBList2 != null) { // cyim 2015.7.1 속도개선작업 string SQL = string.Format("BOARD_ID={0} AND COMM_ID={1} AND LOOP_NO={2} AND REPEATER_ID={3} AND DEVICE_ID={4} AND INOUT_TYPE='{5}'", // cyim 2015.7.8 쿼리수정 , Inout 타입의 경우 ' ' 작은따옴표를 사용해야함, 이벤트로그가 안보이게됨 BOARD_ID, 1, LOOP_NO, REPEATER_ID, DEVICE_ID, INOUT_TYPE); DataRow[] result = _Data.dtDeviceDBList2.Select(SQL); if (result != null && result.Length > 0) { // 만약 위치 명이 있으면, 위치명으로 리턴한다. if (result[0]["POSITION_NAME"].ToString() != "") ret = result[0]["POSITION_NAME"].ToString(); // 위치명이 없고.. 위치 코드가 있으면, 위치 코드를 리턴하도록 한다. else if (result[0]["POSITION_CODE"].ToString() != "") ret = result[0]["POSITION_CODE"].ToString(); // 기본값 Device Name을 리턴할 준비를 한다. else ret = result[0]["DEVICE_NAME"].ToString(); } } return ret; } // cyim 2015.7.1 속도개선작업 // 해쉬테이블을 사용해서 아날로그 감지기를 미리 저장해두어야 한다 // 아날로그감지기 아이디를 모두 가져온다 (아이디로 구성된 키를 가지고, 데이터는 레벨값 FAULT_VALUE;PREFIRE_VALUE;FIRED_VALUE;FIREN_VALUE) public Hashtable GetAnalogDetecterRepeaterID(int RECEIVER_ID, int BOARD_ID, int LOOP_NO) { Hashtable ret = new Hashtable(); try { if (_Data.dtAnalogDetecterLevel != null) { DataRow[] result = _Data.dtAnalogDetecterLevel.Select( string.Format("RECEIVER_ID={0} AND BOARD_ID={1} AND LOOP_NO={2}", RECEIVER_ID, BOARD_ID, LOOP_NO)); if (result.Length > 0) { foreach (DataRow Data in result) { string key = Data["REPEATER_ID"].ToString(); AnalogLevel data = new AnalogLevel( Int32.Parse(Data["FAULT_VALUE"].ToString()), Int32.Parse(Data["PREFIRE_VALUE"].ToString()), Int32.Parse(Data["FIRED_VALUE"].ToString()), Int32.Parse(Data["FIREN_VALUE"].ToString())); ret.Add(key, data); } } } } catch (Exception ex) { Util.UErrorMessage(ex, 0, 0); } return ret; } // cyim 2016.01.07 아날로그 감지기 이력 조회시 표시 수정 : 중계기 타입을 조회할수 있도록 한다 public string GetRepeaterType(int BOARD_ID, int LOOP_NO, int REPEATER_ID) { string ret = ""; if (_Data.dtRepeaterList2 != null) { // cyim 2015.7.1 속도개선작업 DataRow[] result = _Data.dtRepeaterList2.Select( string.Format("BOARD_ID={0} AND LOOP_NO={2} AND REPEATER_ID={3}", BOARD_ID, 1, LOOP_NO, REPEATER_ID)); if (result != null && result.Length > 0) { ret = result[0]["REPEATER_TYPE"].ToString(); } } return ret; } // cyim 2016.12.20 : 푸시메세지 연동 기능 추가 : 테스트모드 private void pictureBox_CI_Click(object sender, EventArgs e) { if (_Data.GCM_TEST_MODE == "ON") { // 데이타베이스에 등록된 모바일앱 디바이스 아이디를 조회한다 using (DacReceiverConfig push_info_select_query = new DacReceiverConfig(0)) { DataSet ds = push_info_select_query.Select("select * from TB_PUSH_DEVICE"); DataTable dt = ds.Tables[0]; foreach (DataRow dr in dt.Rows) { string Regid = dr["REG_ID"].ToString(); var push = new PushBroker(); push.OnNotificationSent += NotificationSent; push.OnChannelException += ChannelException; push.OnServiceException += ServiceException; push.OnNotificationFailed += NotificationFailed; push.OnDeviceSubscriptionExpired += DeviceSubscriptionExpired; push.OnDeviceSubscriptionChanged += DeviceSubscriptionChanged; push.OnChannelCreated += ChannelCreated; push.OnChannelDestroyed += ChannelDestroyed; //txtApiKey.Text is API KEY for server applications from Google Developers Console push.RegisterGcmService(new GcmPushChannelSettings(_Data.GCM_API_KEY)); //txtRegistrationID.Text is a value of e.regid from the onNotificationGCM function in the PushTest app push.QueueNotification(new GcmNotification() .ForDeviceRegistrationId(Regid) .WithJson("{\"message\":\"" + "TEST" + "\"}")); push.StopAllServices(); } } } } // // cyim 2016.12.26 : UI 이탈방지 코드 추가 (후킹) // // Tray =============================================================================================================== private NotifyIcon trayIcon; private ContextMenu trayMenu; private void GimmeTray() { // Create a simple tray menu with only one item. trayMenu = new ContextMenu(); trayMenu.MenuItems.Add("Exit", OnExit); // Create a tray icon. trayIcon = new NotifyIcon(); trayIcon.Text = "Windows System Key Blocker"; trayIcon.Icon = new Icon(SystemIcons.Shield, 40, 40); // Add menu to tray icon and show it. trayIcon.ContextMenu = trayMenu; trayIcon.Visible = true; } private void OnExit(object sender, EventArgs e) { Console.WriteLine(" ! OSK exited."); trayIcon.Dispose(); m_KeyboardHookManager.Dispose(); Application.Exit(); ShowToolbars(); } // Toolbars =============================================================================================================== private const int SW_HIDE = 0; private const int SW_SHOW = 1; [DllImport("user32.dll")] private static extern int FindWindow(string className, string windowText); [DllImport("user32.dll")] private static extern int ShowWindow(int hwnd, int command); private void HideToolbars() { int hWnd = FindWindow("Shell_TrayWnd", ""); ShowWindow(hWnd, SW_HIDE); } private void ShowToolbars() { int hWnd = FindWindow("Shell_TrayWnd", ""); ShowWindow(hWnd, SW_SHOW); } } }