FireDesk_BigReceiver.cs 107 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Text;
  7. using System.Windows.Forms;
  8. using Microsoft.Win32;
  9. using System.Net;
  10. using System.Diagnostics;
  11. using System.IO;
  12. using System.Collections;
  13. using System.Threading;
  14. using System.Media;
  15. using PushSharp;
  16. using PushSharp.Android;
  17. using PushSharp.Core;
  18. // cyim 2016.12.26 : UI 이탈방지 코드 추가 (후킹)
  19. using MouseKeyboardActivityMonitor;
  20. using MouseKeyboardActivityMonitor.WinApi;
  21. using System.Runtime.InteropServices;
  22. using System.Net.NetworkInformation;
  23. // cyim 2015.7.29 수신반 모드
  24. // 수신반의 경우의 환경설정은 아래와 같다
  25. // 수신기와 마찬가지로 레지스트리를 읽어서 현재 DB 정보를 읽도록 한다. ini 파일에 의해 수신반이 될지, 수신기가 될지 결정된다.
  26. // 동작 기본 : 기존과 동일하게 레지스트리값을 읽어 DB 를 읽고, 이 DB 는 수신기의 아이디 리스트 및 기본 디바이스 설정 정보를 가져오기 위한 용도로만 사용한다
  27. // 주의해야 될 점은 소스측면에서는 수신반의 레지스트리에서 지정된 경로로 데이타베이스에 접속할때는 수신기 아이디가 0 으로 조회를 하게 된다,
  28. // 실제 데이타베이스에 조회하는 경우가 있을때는 각 수신기의 실제 DB 에 접속하여 접속하여 사용한다. 데몬을 통하는 것은 카운터, 이벤트 정보뿐이다.
  29. // 다만, DB 백업 및 기타 동작은 무시해도 된다. 수신반은 모니터링이 주 목적이다.
  30. // 수신기별 프로젝트 및 DB 파일 위치 : 각각 아이디별로 틀리다. DB 경로와 프로젝트 파일이 동일한 파일을 각각 폴더에 셋팅해두도록 한다 (Config.ini 을 참고해야됨)
  31. // 프로그램 모드 : Config.ini 파일에 mode 가 1로 되어 있으면 수신반, ini 파일이 없다면 기본으로 수신기 프로그램으로 동작된다
  32. // cyim 2015.8.4 수신반을 위한 static 클래스 정리
  33. // 수신반을 위한 Static 클래스 정리
  34. // -> Static 을 허용하는 것은 오직 _Data.cs 와 _Ini.cs _Timer.cs_Data.cs 와 _Ini.cs _Timer.cs
  35. // 기존코드를 많이 수정하였다. 이는 결국 MdiParent 클래스를 독립적으로 관리하게 수정하는 것을 최종 목표로한다
  36. // cyim 2015.9.15 수신반 1차 버전 완료 : 2.0.1.0
  37. // 수신기 상태 및 제어 기능
  38. // 카운터 통합 모니터링 기능
  39. // 개별 수신기 복구
  40. // 통합 현재 이벤트 표시 기능
  41. // 통합 과거 내역 조회 기능
  42. // cyim 2015.9.30 수신반은 ini 파일을 이용해서 데이타베이스 접속 : 2.0.1.1
  43. namespace FPER
  44. {
  45. public partial class FireDesk_BigReceiver : Form
  46. {
  47. // 임시 아이디 리스트를 만들어서 폼을 load 완료하면 리스트에서 삭제하도록 하여 전체 폼을 다 미리 로드한다
  48. public ArrayList LoadMdiparentFormList = new ArrayList();
  49. // 폼을 로드한것이 진행중이라면 수신반 메인폼에서 계속 폼을 생성하지 못하게 한다
  50. public bool FormLoadComplete = false;
  51. // 수신기폼을 로드시에 기다리는 팝업창을 생성
  52. public frmWaitingMsg waitingForm_FireDesk = null; // cyim 2015.8.3 검토해본 결과 기존의 팝업창을 그대로 사용하도록 한다
  53. // cyim 2015.8.4 수신반을 위한 static 클래스 정리 : 타이머
  54. public _Timer_WindowBase Timer_WindowBase_FireDesk = new _Timer_WindowBase();
  55. // cyim 2015.8.4 수신반을 위한 static 클래스 정리 : 이벤트
  56. public _Event Event = new _Event();
  57. // cyim 2015.9.1 1개의 수신기가 접속이 안되더라도 나머지는 접속시도할수 있도록 수정
  58. public ArrayList CommErrorReceiver = new ArrayList();
  59. // cyim 2015.9.15 수신반 하단 이벤트 표시
  60. // 카운터 표시 (통합 카운터이다. 즉 모든 수신기의 카운터의 합이다)
  61. //
  62. // 아래의 변수 정보는 수신기로 부터 직접 전달받은 카운터를 합 한것이고, 일정 시간마다 갱신된다
  63. public int fireCount = 0, facilityCount = 0, errorCount = 0, blockingCount = 0, cutCnt = 0, checkCnt = 0;
  64. public int fireCount_Accumulation = 0;
  65. // 아래의 리스트 정보는 각각 수신기의 이벤트가 발생할때마다 갱신된다
  66. public ArrayList PreFireList = new ArrayList();
  67. public ArrayList FireList = new ArrayList();
  68. public ArrayList FireList_Accumulation = new ArrayList();
  69. public ArrayList EquipList = new ArrayList();
  70. // 상태 라벨 카운트 (미사용)
  71. public int LEDCount = 0;
  72. public ArrayList LEDList = new ArrayList();
  73. // cyim 2015.9.23 시간정보 표시 오류 (갱신을 안함)
  74. public string MyTime = null;
  75. // cyim 2016.06.15 : 화재 음원 출력
  76. //public SoundPlayer SoundPlayer_AlarmPopupSound = new SoundPlayer(Properties.Resources.emergency);
  77. public SoundPlayer SoundPlayer_AlarmPopupSound = null;
  78. public int SoundPlayer_AlarmPopupSound_Count = 0;
  79. // cyim 2016.12.20 : 푸시메세지 연동 기능 추가 : 화재 카운터 정보
  80. public int timer_1000_Tick_Fire_Cnt_New = 0;
  81. public int timer_1000_Tick_Fire_Cnt_Old = 0;
  82. // cyim 2016.12.20 : 푸시메세지 연동 기능 추가 : 설비 카운터 정보
  83. public int timer_1000_Tick_Facility_Cnt_New = 0;
  84. public int timer_1000_Tick_Facility_Cnt_Old = 0;
  85. // cyim 2016.12.20 : 푸시메세지 연동 기능 추가 : 통신에러 카운터 정보
  86. public int timer_1000_Tick_ComError_Cnt_New = 0;
  87. public int timer_1000_Tick_ComError_Cnt_Old = 0;
  88. // cyim 2016.12.20 : 푸시메세지 연동 기능 추가 : 단선 카운터 정보
  89. public int timer_1000_Tick_Block_Cnt_New = 0;
  90. public int timer_1000_Tick_Block_Cnt_Old = 0;
  91. // cyim 2016.12.20 : 푸시메세지 연동 기능 추가 : 차단 카운터 정보
  92. public int timer_1000_Tick_Cut_Cnt_New = 0;
  93. public int timer_1000_Tick_Cut_Cnt_Old = 0;
  94. // cyim 2016.12.20 : 푸시메세지 연동 기능 추가 : 점검 카운터 정보
  95. public int timer_1000_Tick_Check_Cnt_New = 0;
  96. public int timer_1000_Tick_Check_Cnt_Old = 0;
  97. // 푸시 메세지 발생 수신기
  98. public ArrayList GCM_Fire_List = new ArrayList();
  99. public ArrayList GCM_Facility_List = new ArrayList();
  100. public ArrayList GCM_ComError_List = new ArrayList();
  101. public ArrayList GCM_Block_List = new ArrayList();
  102. public ArrayList GCM_Cut_List = new ArrayList();
  103. public ArrayList GCM_Check_List = new ArrayList();
  104. public ArrayList GCM_Fire_Clone = new ArrayList();
  105. public ArrayList GCM_Facility_Clone = new ArrayList();
  106. public ArrayList GCM_ComError_Clone = new ArrayList();
  107. public ArrayList GCM_Block_Clone = new ArrayList();
  108. public ArrayList GCM_Cut_Clone = new ArrayList();
  109. public ArrayList GCM_Check_Clone = new ArrayList();
  110. public System.Threading.Timer GCM_Thread_Timer = null;
  111. public TimerCallback GCM_CallBack = null;
  112. public int GCM_Sender_Tick_Cnt = 0;
  113. // cyim 2016.12.26 : UI 이탈방지 코드 추가 (후킹)
  114. public static KeyboardHookListener m_KeyboardHookManager;
  115. // cyim 2016.12.28 : 예외처리 추가
  116. public _Ethernet Ethernet = new _Ethernet();
  117. // 생성자
  118. public FireDesk_BigReceiver()
  119. {
  120. InitializeComponent();
  121. // cyim 2016.11.11 : 비상 음원 출력 음원 파일 없을때 대응 코드 추가
  122. if (File.Exists(Environment.CurrentDirectory + "\\emergency.wav") == true)
  123. SoundPlayer_AlarmPopupSound = new SoundPlayer(Environment.CurrentDirectory + "\\emergency.wav");// cyim 2016.06.24 : 음원 출력시 교체 가능
  124. // 이벤트
  125. this.FormClosing += new FormClosingEventHandler(FireDesk_FormClosing);
  126. this.Load += new EventHandler(FireDesk_Load);
  127. Event.FireDesk_Update_SendMessage_Event += new _Event.FireDesk_Update_SendMessage_Handler(_Event_FireDesk_Update_SendMessage_Event); // cyim 2015.8.4 수신반을 위한 static 클래스 정리
  128. // UI
  129. for (int id = 1; id <= 32; id++)
  130. {
  131. // 수신기 버튼
  132. Button button_Receiver = (Button)Util.FineControl(panel_Receiver, "button_Receiver" + id.ToString());
  133. button_Receiver.Tag = id.ToString();
  134. button_Receiver.Click += new EventHandler(button_Receiver_Click);
  135. // 수신기 복구 버튼
  136. Button button_Recover = (Button)Util.FineControl(panel_Receiver, "button_Recover" + id.ToString());
  137. button_Recover.Tag = id.ToString();
  138. button_Recover.Click += new EventHandler(button_Recover_Click);
  139. }
  140. // cyim 2016.12.29 : 화면 멈춤 문제 수정 : 오른쪽 상단의 시간 표시 타이머
  141. Timer_WindowBase_FireDesk.Create("timer_1000_TimeLabelUpdate", 1000, timer_1000_TimeLabelUpdate_Tick, true);
  142. }
  143. // 소멸자
  144. private void FireDesk_FormClosing(object sender, FormClosingEventArgs e)
  145. {
  146. // cyim 2016.12.26 : UI 이탈방지 코드 추가 (후킹)
  147. if (_Data.Hook_Enable != "OFF")
  148. {
  149. _Hook.Enable_TaskMgr();
  150. _Hook.Enable_NoClose();
  151. }
  152. // 타이머
  153. Timer_WindowBase_FireDesk.Delete("timerDateTime"); // cyim 2015.8.4 수신반을 위한 static 클래스 정리
  154. //
  155. // cyim 2016.11.11 : 수신반 프로세스 종료 코드 추가
  156. //
  157. // 스레드 종료
  158. Application.ExitThread();
  159. for (int i = 0; i < 1000000; i++) {; }
  160. // 프로세스 종료
  161. Application.Exit();
  162. // 프로세스가 남아있다면 최종 종료
  163. System.Diagnostics.Process[] mProcess = System.Diagnostics.Process.GetProcessesByName(Application.ProductName);
  164. foreach (System.Diagnostics.Process p in mProcess)
  165. p.Kill();
  166. // 최종 정리 (보완코드 : 크로스 스레드 문제 발생 여지가 있으므로 사용주의)
  167. Environment.Exit(0);
  168. }
  169. //
  170. // 초기화
  171. //
  172. private void FireDesk_Load(object sender, EventArgs e)
  173. {
  174. // cyim 2016.12.26 : UI 이탈방지 코드 추가 (후킹)
  175. if (_Data.Hook_Enable != "OFF")
  176. {
  177. _Hook.Disable_TaskMgr();
  178. _Hook.Disable_NoClose();
  179. GimmeTray();
  180. m_KeyboardHookManager = new KeyboardHookListener(new GlobalHooker());
  181. m_KeyboardHookManager.Enabled = true;
  182. }
  183. // cyim 2015.7.31 수신반 팝업창은 별도로 존재
  184. ShowWaitingMsgForm("수신반을 시작합니다", 10);
  185. // cyim
  186. // 해당 DB 를 읽고 어떤 IP 에 어떤 수신기 ID 가 맵핑되어있는지 알아야한다
  187. // 수신기에 원격으로 데몬이 붙어서 동작할수 있다.
  188. // 맨처음 가동단계는 현재 DB 를 읽어서 수신반 구동을 시작한다
  189. // 현재 데이타베이스를 읽고 현재 설정된 수신기가 어떤 아이디들로 구성되어 있는지 알아야 한다
  190. // 데이타베이스를 토대로 각각 수신기 정보를 알아야 되며, 레지스트리 값을 읽어서 쓰는 루틴은 그대로 이용하되,
  191. // 레지스트리 값중에 프로젝트 경로는 각 수신기별로 정보를 가지고 있도록 해야한다
  192. // 수신반의 경우 중계기, 보드 정보, 수신기 설정값을 알필요가 없다. (물론 각 수신기에 접속하면 알수가 있지만 평상시에는 알 필요가 없다)
  193. // 수신기 아이디 해쉬 테이블 초기화 - Config.ini 기반
  194. Initialize_Hash_Receiver(_Data.Hash_Receiver);
  195. // 수신기 아이디 키 배열 생성
  196. _Data.Hash_Receiver_keys = new string[_Data.Hash_Receiver.Keys.Count];
  197. _Data.Hash_Receiver.Keys.CopyTo(_Data.Hash_Receiver_keys, 0);
  198. // cyim 2017.01.03 : 연동기능 보완
  199. _Data.Hash_Receiver_keys = Sort_StringArray(_Data.Hash_Receiver_keys);
  200. // 수신기 중에 마스터 모드로 셋팅된 아이디를 검색한다
  201. // 수신반의 데이타베이스를 접근해야되는데 어차피 TB_CONFIG 테이블은 유일하게 내부 PC에 있는 수신반 DB를 이용하도록 한다.
  202. // 수신반 DB 를 접근하려면 아이디가 0으로 되어 있으면 내부적으로 접근 가능하도록 되어있고 경로는 레지스트리 값 경로를 이용하면 된다
  203. ArrayList temp = new ArrayList();
  204. foreach (string id in _Data.Hash_Receiver_keys)
  205. {
  206. _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[id];
  207. DacReceiverConfig dacReceiverConfig = new DacReceiverConfig(0);
  208. DataTable dt = dacReceiverConfig.Config_Select(0);
  209. // 마스터 모드
  210. foreach (DataRow dr in dt.Rows)
  211. {
  212. if (id == dr["RECEIVER_ID"].ToString())
  213. {
  214. FireDesk_Receiver.MASTER_FLAG = dr["MASTER_FLAG"].ToString();//dt.Rows[0]["MASTER_FLAG"].ToString();
  215. // cyim 2017.01.03 : 마스터 수신기 표시
  216. if (FireDesk_Receiver.MASTER_FLAG == "Y" && temp.Contains(id) == false) temp.Add(id);
  217. }
  218. }
  219. }
  220. // cyim 2017.01.03 : 마스터 수신기 표시
  221. this.label_Master.Text = string.Format("Master Receiver ID : {0}", _Convert.ArrayList_to_String(temp, ","));
  222. // cyim 2015.9.11 : 과거내역 통합조회창에서 사용할 DB 에서 미리 읽은값을 사용하도록 수정함
  223. // 공통정보를 데이타베이스에서 불러온다
  224. ShowWaitingMsgForm("수신기 디바이스 DB를 읽고 있습니다..", 20);
  225. this.GetDeviceDB();
  226. ShowWaitingMsgForm("수신기 중계기 DB를 읽고 있습니다..", 30);
  227. this.GetRepeaterDB();
  228. //AnalogDetect.Get_TB_DAYTIME(0); // 수신반은 필요없다
  229. this.GetAnalogDetecterLevelDB();
  230. ShowWaitingMsgForm("수신기 통신 보드 설정을 읽고 있습니다..", 40);
  231. this.GetBoardDB();
  232. ShowWaitingMsgForm("수신기 기본 설정값을 읽고 있습니다..", 50);
  233. //
  234. // UI
  235. //
  236. // cyim 2017.01.03 수신기 버튼 색상 정리
  237. // 불필요한 수신기는 정리한다
  238. for (int id = 1; id <= 32; id++)
  239. {
  240. // 사용하지 않는 수신기
  241. if (_Data.Hash_Receiver.ContainsKey(id.ToString()) == false)
  242. {
  243. Panel p = (Panel)Util.FineControl(panel_Receiver, "panel_Receiver" + id.ToString());
  244. p.Enabled = false;
  245. Button b = (Button)Util.FineControl(panel_Receiver, "button_Receiver" + id);
  246. b.Enabled = false;
  247. b.BackColor = Color.DarkGray;
  248. }
  249. }
  250. // 내부 클래스 로드
  251. MDIParent_Load_Func();
  252. // cyim 2015.7.31 수신반 팝업창은 별도로 존재 : 문구 출력 이후에 종료
  253. ShowWaitingMsgForm("수신반을 시작합니다", 100);
  254. System.Threading.Thread.Sleep(1000);
  255. waitingForm_FireDesk.Close();
  256. waitingForm_FireDesk = null;
  257. // cyim 2016.12.20 : 현장명 사용자 지정
  258. this.label_BuildingName.Text = _Data.Site_Name;
  259. // 스레드
  260. GCM_CallBack = new TimerCallback(GCM_Sender_CallBack);
  261. GCM_Thread_Timer = new System.Threading.Timer(GCM_CallBack, this, 1000, 1000);
  262. // cyim 2016.12.29 : 화면 멈춤 문제 수정
  263. // 타이머중에 통신데몬 재접속 혹은 수신기 상태를 표시하는 타이머는 모든 MDIParent 가 준비가 된 이후부터 가동하도록 한다
  264. // cyim 2017.01.04 : 수신기 통신체크 루틴 타이머 조정
  265. int timer_cnt = 0;
  266. switch (_Data.Hash_Receiver.Keys.Count)
  267. {
  268. case 1: timer_cnt = 3000; break;
  269. case 2: timer_cnt = 3000; break;
  270. case 3: timer_cnt = 3000; break;
  271. case 4: timer_cnt = 3000; break;
  272. case 5: timer_cnt = 2500; break;
  273. default: timer_cnt = 2000; break;
  274. }
  275. // 통신 상태 체크
  276. Timer_WindowBase_FireDesk.Create("ConnectCheck_Timer", timer_cnt, ConnectCheck_Timer_Tick, true);
  277. // 알람 상태 표시
  278. Timer_WindowBase_FireDesk.Create("Display_Timer", 1000, Display_Timer_Tick, true);
  279. }
  280. // cyim 2017.01.03 : 연동기능 보완 - 수신기 아이디 정렬
  281. private string[] Sort_StringArray(string[] Data)
  282. {
  283. ArrayList temp = new ArrayList();
  284. foreach (string id in Data)
  285. temp.Add(id);
  286. temp.Sort(new _Sort.ID());
  287. string[] result = new string[temp.Count];
  288. temp.CopyTo(result);
  289. return result;
  290. }
  291. // cyim 2016.12.29 : 화면 멈춤 문제 수정 : 프로그램 시작시 클래스를 로드한다
  292. private void MDIParent_Load_Func()
  293. {
  294. // 초기화
  295. LoadMdiparentFormList.Clear();
  296. while (true)
  297. {
  298. foreach (string id in _Data.Hash_Receiver_keys)
  299. {
  300. _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[id];
  301. // 수신반에서 읽기 시도한다
  302. if (FormLoadComplete == false)
  303. {
  304. // 하단의 mdi.show 함수에서 딜레이가 심하다. 코드 위치를 변경하면 안된다
  305. FormLoadComplete = true;
  306. // 기존에 읽기 완료하지 않은 것만 시도한다
  307. if (FireDesk_Receiver.LoadingOk == false)
  308. {
  309. // 네트워크에 연결되었다면
  310. if (Ethernet.Ping_SyncCheck(FireDesk_Receiver.DATABASE_NAME_IP) == true)
  311. {
  312. Receiver_MDIParent_Load(FireDesk_Receiver, Int32.Parse(id));
  313. UPDATE_TB_RECEIVER_ERROR_COUNT_DETAILS(id);
  314. Receiver_ComNormal(id.ToString());
  315. }
  316. else
  317. {
  318. Receiver_MDIParent_Close(FireDesk_Receiver, Int32.Parse(id));
  319. Receiver_ComError(id.ToString());
  320. FormLoadComplete = false;
  321. }
  322. // 한번이라도 읽기 시도한 것은 리스트에 저장
  323. if (LoadMdiparentFormList.Contains(id.ToString()) == false)
  324. LoadMdiparentFormList.Add(id.ToString());
  325. System.Threading.Thread.Sleep(300);
  326. }
  327. }
  328. }
  329. // 읽기 시도 횟수와 등록된 수신기 개수가 맞다면 무한루프 종료
  330. if (LoadMdiparentFormList.Count == _Data.Hash_Receiver_keys.Length)
  331. {
  332. break;
  333. }
  334. }
  335. }
  336. // cyim 2016.12.29 : 화면 멈춤 문제 수정 - 중간 업데이트전용 구분
  337. private void MDIParent_Update_Func(string Receiver_ID)
  338. {
  339. // 예외처리
  340. if (Receiver_ID == "" || Receiver_ID == "0" || _Data.Hash_Receiver.ContainsKey(Receiver_ID.ToString()) == false)
  341. return;
  342. // 팝업창이 있으면 닫아버린다
  343. if (waitingForm_FireDesk != null && waitingForm_FireDesk.Visible == true)
  344. {
  345. waitingForm_FireDesk.Close();
  346. waitingForm_FireDesk = null;
  347. }
  348. string id = Receiver_ID.ToString();
  349. _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[id];
  350. // 수신반에서 읽기 시도한다
  351. if (FormLoadComplete == false)
  352. {
  353. // 하단의 mdi.show 함수에서 딜레이가 심하다. 코드 위치를 변경하면 안된다
  354. FormLoadComplete = true;
  355. // 기존에 읽기 완료하지 않은 것만 시도한다
  356. if (FireDesk_Receiver.LoadingOk == false)
  357. {
  358. if (Ethernet.Ping_SyncCheck(FireDesk_Receiver.DATABASE_NAME_IP) == true)
  359. {
  360. Receiver_MDIParent_Load(FireDesk_Receiver, Int32.Parse(id));
  361. UPDATE_TB_RECEIVER_ERROR_COUNT_DETAILS(id);
  362. Receiver_ComNormal(id.ToString());
  363. }
  364. else
  365. {
  366. // 처음에 잘 읽었던 것을 굳이 리소스를 삭제해야되나?
  367. //Receiver_MDIParent_Close(FireDesk_Receiver, Int32.Parse(id));
  368. Receiver_ComError(id.ToString());
  369. FormLoadComplete = false;
  370. }
  371. }
  372. else // 초기화 시도시에 이미 읽었다면 현재 이력
  373. {
  374. if (Ethernet.Ping_SyncCheck(FireDesk_Receiver.DATABASE_NAME_IP) == true)
  375. {
  376. UPDATE_TB_RECEIVER_ERROR_COUNT_DETAILS(id);
  377. Receiver_ComNormal(id.ToString());
  378. FormLoadComplete = false;
  379. }
  380. else
  381. {
  382. // 처음에 잘 읽었던 것을 굳이 리소스를 삭제해야되나?
  383. //Receiver_MDIParent_Close(FireDesk_Receiver, Int32.Parse(id));
  384. Receiver_ComError(id.ToString());
  385. FormLoadComplete = false;
  386. }
  387. }
  388. }
  389. }
  390. //
  391. // cyim 2016.12.16 : 통신 단절 및 통신 복구시 수신기 버튼의 색상이 변경된다
  392. //
  393. private void Receiver_ComError(string id)
  394. {
  395. Button p = (Button)Util.FineControl(panel_Receiver, "button_Receiver" + id);
  396. p.Enabled = false;
  397. p.BackColor = Color.HotPink;
  398. if (CommErrorReceiver.Contains(id) == false) CommErrorReceiver.Add(id);
  399. }
  400. private void Receiver_ComNormal(string id)
  401. {
  402. Button p = (Button)Util.FineControl(panel_Receiver, "button_Receiver" + id);
  403. p.Enabled = true;
  404. p.BackColor = Color.WhiteSmoke;
  405. if (CommErrorReceiver.Contains(id) == true) CommErrorReceiver.Remove(id);
  406. }
  407. //
  408. // cyim 2016.12.29 : 화면 멈춤 문제 수정
  409. //
  410. private void Receiver_MDIParent_Load(_FireDesk_Receiver FireDesk_Receiver, int id)
  411. {
  412. // cyim 2017.01.02 : Memory leak
  413. if (FireDesk_Receiver.mdi == null)
  414. {
  415. try
  416. {
  417. FireDesk_Receiver.mdi = new MDIParent(id, Event);
  418. FireDesk_Receiver.mdi.TopMost = false;
  419. FireDesk_Receiver.mdi.Show();
  420. FireDesk_Receiver.mdi.Visible = false;
  421. FireDesk_Receiver.LoadingOk = true;
  422. }
  423. catch
  424. {
  425. FireDesk_Receiver.LoadingOk = false;
  426. FormLoadComplete = false;
  427. }
  428. }
  429. }
  430. private void Receiver_MDIParent_Close(_FireDesk_Receiver FireDesk_Receiver, int id)
  431. {
  432. FireDesk_Receiver.LoadingOk = false;
  433. if (FireDesk_Receiver.mdi != null)
  434. {
  435. FireDesk_Receiver.mdi.Close();
  436. FireDesk_Receiver.mdi = null;
  437. }
  438. }
  439. //
  440. // 수신반 클래스 초기화
  441. //
  442. private void Initialize_Hash_Receiver(Hashtable hashtable)
  443. {
  444. hashtable.Clear();
  445. for (int i = 1; i <= 32; i++)
  446. {
  447. // USE 값이 1인 경우에만 읽도록 한다
  448. string use = _Ini.Read_Ini("RECEIVER" + i.ToString(), "USE", 1024, Environment.CurrentDirectory + "\\Config.ini");
  449. if (use == "1")
  450. {
  451. // 수신반 클래스
  452. _FireDesk_Receiver firedesk_receiver = new _FireDesk_Receiver();
  453. // 아이디
  454. firedesk_receiver.RECEIVER_ID = i.ToString();
  455. string Temp_DATABASE_NAME = _Ini.Read_Ini("RECEIVER" + i.ToString(), "DATABASE_NAME", 1024, Environment.CurrentDirectory + "\\Config.ini");
  456. // IP + PATH
  457. firedesk_receiver.DATABASE_NAME = Temp_DATABASE_NAME;
  458. // IP
  459. firedesk_receiver.DATABASE_NAME_IP = Temp_DATABASE_NAME.Substring(0, Temp_DATABASE_NAME.IndexOf(":"));
  460. // PATH
  461. firedesk_receiver.DATABASE_NAME_PATH = Temp_DATABASE_NAME.Substring(Temp_DATABASE_NAME.IndexOf(":") + 1);
  462. string Temp_PROJECT_DIR = _Ini.Read_Ini("RECEIVER" + i.ToString(), "PROJECT_DIR", 1024, Environment.CurrentDirectory + "\\Config.ini");
  463. // 프로젝트 경로
  464. firedesk_receiver.PROJECT_DIRECTORY = Temp_PROJECT_DIR;
  465. // 해쉬에 추가
  466. if (hashtable.ContainsKey(firedesk_receiver.RECEIVER_ID) == false)
  467. hashtable.Add(firedesk_receiver.RECEIVER_ID, firedesk_receiver);
  468. }
  469. }
  470. }
  471. //
  472. // 팝업창
  473. //
  474. // cyim 2015.7.31 수신반 팝업창은 별도로 존재
  475. //
  476. delegate void WaitingMsg_Callback(string msg, int processValue);
  477. public void ShowWaitingMsgForm(string msg, int processValue)
  478. {
  479. if (this.InvokeRequired)
  480. {
  481. WaitingMsg_Callback d = new WaitingMsg_Callback(ShowWaitingMsgForm);
  482. this.Invoke(d, new object[] { msg, processValue });
  483. }
  484. else
  485. {
  486. if (this.waitingForm_FireDesk == null)
  487. {
  488. // cyim 2015.8.3 검토해본 결과 기존의 팝업창을 그대로 사용하도록 한다
  489. // 다만 수신기별로 각각 팝업창이 계속 표시가 되면 될것같음. 즉 같은 팝업창의 진행도가 0~100 ->0~100 을 자동반복함
  490. this.waitingForm_FireDesk = new frmWaitingMsg();
  491. this.waitingForm_FireDesk.Text = Application.ProductName;
  492. this.waitingForm_FireDesk.TopMost = true;
  493. Point loc = new Point(
  494. (1280 - this.waitingForm_FireDesk.Size.Width) / 2 + this.Location.X,
  495. (1024 - this.waitingForm_FireDesk.Size.Height) / 2 + this.Location.Y
  496. );
  497. this.waitingForm_FireDesk.Location = loc;
  498. this.waitingForm_FireDesk.Show();
  499. }
  500. this.waitingForm_FireDesk.setMessage(msg, processValue);
  501. this.Update();
  502. }
  503. }
  504. string GetDevicePositionName(CEventLogData eventLog, MDIParent mdi)
  505. {
  506. string ret = "";
  507. {
  508. // 기본값으로 함
  509. string DefaultValue = "";
  510. switch (eventLog.ioType)
  511. {
  512. //
  513. // 마스터 수신기
  514. //
  515. case "M":
  516. {
  517. //ret = "Master " + receiverID;
  518. ret = DefaultValue;
  519. }
  520. break;
  521. //
  522. // 로컬 수신기
  523. //
  524. case "A": // 전체
  525. //if (Convert.ToInt32(eventLog.receiverID) > 0)
  526. {
  527. // receiver.Name;
  528. //DBAccess.GetReceiverNameFromDB(this.receiverID);
  529. ret = DefaultValue;
  530. }
  531. break;
  532. case "C": // 통신
  533. //if (Convert.ToInt32(eventLog.receiverID) > 0)
  534. {
  535. // receiver.Name;
  536. //ret = receiverID + "-통신";
  537. if (eventLog.eventType == "DC")
  538. {
  539. // 설비연동 조작
  540. if (eventLog.boardID == 0 && eventLog.repeaterID == 0 && eventLog.deviceID == 0)
  541. {
  542. ret = DefaultValue;
  543. }
  544. // 루프 차단
  545. else if (eventLog.boardID != 0 && eventLog.repeaterID == 0 && eventLog.deviceID == 0)
  546. {
  547. ret = mdi.GetDeviceName(eventLog.boardID, eventLog.commID);
  548. if (eventLog.commID == 1)
  549. {
  550. ret += string.Format(":{0}계통", eventLog.loopNO.ToString());
  551. }
  552. }
  553. // 중계기 차단
  554. else if (eventLog.boardID != 0 && eventLog.repeaterID != 0 && eventLog.deviceID == 0)
  555. {
  556. ret = mdi.GetDevicePositionName(eventLog.boardID, eventLog.loopNO, eventLog.repeaterID);
  557. }
  558. else
  559. ret = DefaultValue;
  560. }
  561. }
  562. break;
  563. case "B": // 보드
  564. {
  565. //deviceName = DBAccess.GetBoardNameFromDB(this.receiverID, this.boardID);
  566. //ret = receiverID + "-보드";
  567. ret = DefaultValue;
  568. }
  569. break;
  570. case "L": // 루프
  571. {
  572. //ret = receiver.board[eventLog.boardID - 1].Name;
  573. //ret += string.Format("{0}보드:{1}계통", eventLog.boardID, eventLog.loopNO.ToString());
  574. //ret = receiverID + "-루프";
  575. ret = DefaultValue;
  576. }
  577. break;
  578. case "R": //중계기
  579. {
  580. //ret = receiver.board[eventLog.boardID - 1].loop[eventLog.loopNO].repeater[eventLog.repeaterID - 1].Name;
  581. // ret = "중계기";
  582. // 중계기와 회로는 각건물내에 위치하므로 수신기 아이디 출력 제외함
  583. // 데이타베이스에서 조회, 이름이 없다면 코드라도 출력
  584. ret = mdi.GetDevicePositionName(eventLog.boardID, eventLog.loopNO, eventLog.repeaterID);
  585. }
  586. break;
  587. case "D": // 장치
  588. {
  589. //ret = "장치";
  590. //ret = receiverID + "-장치";
  591. ret = DefaultValue;
  592. }
  593. break;
  594. case "I": //입력회로
  595. case "O": //출력회로
  596. {
  597. // cyim 2015.9.23 키패드조작에서 발생한 이벤트의 경우 회로정보는 null, 장치명은 수신기아이디 표시
  598. if (eventLog.eventType == "MS"
  599. || eventLog.eventType == "LS"
  600. || eventLog.eventType == "EB"
  601. || eventLog.eventType == "RP"
  602. || eventLog.eventType == "BF"
  603. || eventLog.eventType == "ED" // cyim 2016.12.09 : IFC3300에서는 예비전원버튼 -> 설비전체연동조작버튼
  604. )
  605. {
  606. ret = DefaultValue;
  607. }
  608. else
  609. {
  610. // 중계기와 회로는 각건물내에 위치하므로 수신기 아이디 출력 제외함
  611. ret = mdi.GetDevicePositionName(eventLog.boardID, eventLog.loopNO, eventLog.repeaterID, eventLog.deviceID, eventLog.ioType);
  612. }
  613. }
  614. break;
  615. default:
  616. {
  617. //ret = string.Format("수신기[{0}]", eventLog.receiverID);
  618. ret = DefaultValue;
  619. }
  620. break;
  621. }
  622. // 만약에 정보가 없다면 기본값 -> 2014.8.7 소방특성상 위치정보가 불확실하다면 표시안하는게 좋다는 의견 - 장성원부장님
  623. //if (ret == null || ret.Length == 0) ret = DefaultValue;
  624. }
  625. return ret;
  626. }
  627. string GetRemarkInfo(string Original, string Attribute)
  628. {
  629. try
  630. {
  631. string result = "";
  632. // Attribute 값은 아래와 같다
  633. // APPLY RANGE
  634. // DEVICE TYPE
  635. // STATUS
  636. ArrayList temp_list = new ArrayList();
  637. Hashtable temp_hash = new Hashtable();
  638. // 문자열을 콤마로 구분해서
  639. string[] temp_1th = Original.Split(',');
  640. char[] remove_char1 = { '(', ')' };
  641. char[] remove_char2 = { '[', ']' };
  642. foreach (string temp in temp_1th)
  643. {
  644. // 각 문자열중에 속성이름이 포함되어있다면
  645. if (temp.Contains(Attribute) == true)
  646. {
  647. string[] temp_2st = temp.Split(':');
  648. result = temp_2st[1].Trim(remove_char1);// 괄호 제거
  649. return result.Trim(remove_char2);// 대괄호 제거
  650. }
  651. }
  652. return result;
  653. }
  654. catch (Exception ex)
  655. {
  656. Util.UErrorMessage(ex, 0, 0);
  657. return "";
  658. }
  659. }
  660. string GetDeviceName(CEventLogData eventLog, MDIParent mdi)
  661. {
  662. // get device name data
  663. string ret = "";
  664. //if (FindReceiver(eventLog.receiverID) >= 0)
  665. {
  666. // 수신기 아이디 정보 추가
  667. string receiverID = string.Format("수신기[{0}]", eventLog.receiverID);
  668. // 디바이스 타입 정보 추가
  669. string remark_device_type = GetRemarkInfo(eventLog.eventRemark, "DEVICE TYPE");
  670. if (remark_device_type.Length != 0) remark_device_type = "-" + remark_device_type;
  671. //Receiver receiver = this.LReceiver[FindReceiver(eventLog.receiverID)];
  672. string DefaultValue = receiverID + remark_device_type;
  673. switch (eventLog.ioType)
  674. {
  675. //
  676. // 마스터 수신기
  677. //
  678. case "M":
  679. {
  680. ret = "MASTER 수신기" + remark_device_type;
  681. }
  682. break;
  683. //
  684. // 로컬 수신기
  685. //
  686. case "A": // 전체
  687. if (Convert.ToInt32(eventLog.receiverID) > 0)
  688. {
  689. ret = DefaultValue;// receiver.Name;
  690. //DBAccess.GetReceiverNameFromDB(this.receiverID);
  691. }
  692. break;
  693. case "C": // 통신
  694. {
  695. // 설비 차단 즉 DC 의 로그를 분석한 결과 4가지 차단은 총 아래와 같이 5가지 경우이다, 이때 InoutType 은
  696. // 1.회로차단 I
  697. // 2.중계기차단 C
  698. // 3.루프차단 C
  699. // 4.보드차단 C
  700. // 5.설비연동 조작 C
  701. if (eventLog.eventType == "DC")
  702. {
  703. // 설비연동 조작
  704. if (eventLog.boardID == 0 && eventLog.repeaterID == 0 && eventLog.deviceID == 0)
  705. {
  706. ret = DefaultValue;
  707. }
  708. // 루프 차단
  709. else if (eventLog.boardID != 0 && eventLog.repeaterID == 0 && eventLog.deviceID == 0)
  710. {
  711. ret = mdi.GetDeviceName(eventLog.boardID, eventLog.commID);
  712. if (eventLog.commID == 1)
  713. {
  714. ret += string.Format(":{0}계통", eventLog.loopNO.ToString());
  715. }
  716. }
  717. // 중계기 차단
  718. else if (eventLog.boardID != 0 && eventLog.repeaterID != 0 && eventLog.deviceID == 0)
  719. {
  720. ret = mdi.GetDeviceName(eventLog.boardID, eventLog.loopNO, eventLog.repeaterID);
  721. }
  722. else
  723. ret = DefaultValue;
  724. }
  725. else if (Convert.ToInt32(eventLog.receiverID) > 0)
  726. {
  727. ret = DefaultValue;// receiver.Name;
  728. }
  729. }
  730. break;
  731. case "B": // 보드
  732. {
  733. //deviceName = DBAccess.GetBoardNameFromDB(this.receiverID, this.boardID);
  734. ret = mdi.GetDeviceName(eventLog.boardID, eventLog.commID);
  735. }
  736. break;
  737. case "L":// 루프
  738. {
  739. //ret = receiver.board[eventLog.boardID - 1].Name;
  740. ret = mdi.GetDeviceName(eventLog.boardID, eventLog.commID);
  741. if (eventLog.commID == 1)
  742. {
  743. ret += string.Format(":{0}계통", eventLog.loopNO.ToString());
  744. }
  745. }
  746. break;
  747. case "R": //중계기
  748. {
  749. //ret = receiver.board[eventLog.boardID - 1].loop[eventLog.loopNO].repeater[eventLog.repeaterID - 1].Name;
  750. ret = mdi.GetDeviceName(eventLog.boardID, eventLog.loopNO, eventLog.repeaterID);
  751. break;
  752. }
  753. case "D": // 장치
  754. {
  755. ret = "장치";
  756. break;
  757. }
  758. case "I": //입력회로
  759. case "O": //출력회로
  760. {
  761. // cyim 2015.9.23 키패드조작에서 발생한 이벤트의 경우 회로정보는 null, 장치명은 수신기아이디 표시
  762. if (eventLog.eventType == "MS"
  763. || eventLog.eventType == "LS"
  764. || eventLog.eventType == "EB"
  765. || eventLog.eventType == "RP"
  766. || eventLog.eventType == "BF"
  767. || eventLog.eventType == "ED" // cyim 2016.12.09 : IFC3300에서는 예비전원버튼 -> 설비전체연동조작버튼
  768. )
  769. {
  770. ret = DefaultValue;
  771. }
  772. else
  773. {
  774. ret = mdi.GetDeviceName(eventLog.boardID, eventLog.loopNO, eventLog.repeaterID, eventLog.deviceID, eventLog.ioType);
  775. }
  776. break;
  777. }
  778. default:
  779. {
  780. break;
  781. }
  782. }
  783. // 만약에 정보가 없다면 기본값
  784. if (ret == null || ret.Length == 0) ret = DefaultValue;
  785. }
  786. return ret;
  787. }
  788. // cyim 2016.12.16 : 모바일앱 연동 - 현재 이력 갱신
  789. private void UPDATE_TB_RECEIVER_ERROR_COUNT_DETAILS(string ID)
  790. {
  791. if (_Data.Hash_Receiver.ContainsKey(ID) == false) return; // cyim 2016.12.28 : 예외처리 추가
  792. if (_Data.MOBILE_ENABLE == "ON")
  793. {
  794. _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[ID];
  795. // cyim 2016.12.28 : 예외처리 추가 : 통신데몬 접속상태가 양호하지 않아서 MDIParent 를 로딩하는 중간에 현재이력갱신코드에 접근하는 경우가 발생한다
  796. if (FireDesk_Receiver.mdi == null)
  797. return;
  798. // cyim 2017.01.04 : 메모리릭을 위한 수정으로 인하여 소멸자로 인하여 이벤트 리스트안에 객체가 일부 소멸되버린다
  799. using (DacReceiverConfig query_session = new DacReceiverConfig(0)) // cyim 2017.01.02 : Memory leak
  800. {
  801. //
  802. // 수신기 ID 에 해당하는 현재이력 정보들을 전부 삭제
  803. //
  804. query_session.ExecuteNonQuery(string.Format("delete from TB_RECEIVER_ERROR_COUNT_DETAILS where IP_ADDRESS = '{0}'", FireDesk_Receiver.DATABASE_NAME_IP));
  805. //
  806. // 수신기 ID 에 해당하는 현재이력 정보들을 전부 추가
  807. //
  808. string IP_ADDRESS = FireDesk_Receiver.DATABASE_NAME_IP;
  809. string ERROR_TYPE = "";
  810. string LOCATION = "";
  811. string DEVICE_NAME = "";
  812. string EVENT_TYPE = "";
  813. string DEVICE_NUMBER = "";
  814. Hashtable eventLogInfos_temp = (Hashtable)FireDesk_Receiver.mdi.AryEventLogs.Clone();
  815. if (eventLogInfos_temp != null && eventLogInfos_temp.Count != 0)
  816. {
  817. foreach (DictionaryEntry d in eventLogInfos_temp)
  818. {
  819. // cyim 2017.01.04 : 메모리릭을 위한 수정으로 인하여 소멸자로 인하여 이벤트 리스트안에 객체가 일부 소멸되버린다
  820. //using (EventLogInfo eventLogMsg = (EventLogInfo)d.Value) // cyim 2017.01.02 : Memory leak
  821. EventLogInfo eventLogMsg = (EventLogInfo)d.Value;
  822. {
  823. if (eventLogMsg.LiveMsgFlag)
  824. {
  825. // cyim 2017.01.04 : 메모리릭을 위한 수정으로 인하여 소멸자로 인하여 이벤트 리스트안에 객체가 일부 소멸되버린다
  826. //using (CEventLogData elog = new CEventLogData(eventLogMsg)) // cyim 2017.01.02 : Memory leak
  827. CEventLogData elog = new CEventLogData(eventLogMsg);
  828. {
  829. elog.eventTypeName = eventLogMsg.EventTypeName;
  830. LOCATION = elog.devicePosition = GetDevicePositionName(elog, FireDesk_Receiver.mdi);
  831. DEVICE_NAME = elog.deviceName = GetDeviceName(elog, FireDesk_Receiver.mdi);
  832. // 회로번호
  833. string temp_Report_EventPostion = "";
  834. if (elog.EventPositon == null
  835. || elog.EventPositon.Length == 0
  836. || elog.ioType == "M"
  837. || elog.EventPositon.Contains("수신기") == true)
  838. temp_Report_EventPostion = "없음"; // 만약 수신기 자체 혹은 타수신기 정보라면 회로번호 정보는 표시하지 않는다
  839. else temp_Report_EventPostion = elog.EventPositon;
  840. // cyim 2016.01.07 아날로그 감지기 이력 조회시 표시 수정
  841. string RepeaterType = FireDesk_Receiver.mdi.GetRepeaterType(elog.boardID, elog.loopNO, elog.repeaterID);
  842. // '1' = A : 2X2
  843. // '2' = B : 4X4
  844. // '4' = C : 아날로그연감지기
  845. // '5' = D : 아날로그열감지기
  846. if (RepeaterType == "4" || RepeaterType == "5")
  847. {
  848. elog.eventTypeName = elog.eventTypeName.Replace("중계기", "감지기"); // 타입
  849. temp_Report_EventPostion = temp_Report_EventPostion.Replace("중계기", "감지기"); // 회로번호
  850. }
  851. DEVICE_NUMBER = elog.Report_EventPositon = temp_Report_EventPostion;
  852. // 차단 기능의 경우 특별히 상태값을 알수가 없어서 Remark 정보를 추출해야한다
  853. if (elog.eventType == "DC")
  854. {
  855. string temp = GetRemarkInfo(elog.eventRemark, "STATUS");
  856. if (temp == "INACTIVE") // 차단 해제
  857. elog.Report_EventErrorStatus = 0;
  858. else // 차단 조작
  859. elog.Report_EventErrorStatus = 2;
  860. }
  861. // cyim 2015.9.23 키패드조작에서 발생한 이벤트의 경우 조작과 해제로 구분하여 표시
  862. // 차단 기능과 마찬가지로 특별히 상태값을 알수가 없어서 Remark 정보를 추출해야한다
  863. else if (elog.eventType == "MS"
  864. || elog.eventType == "LS"
  865. || elog.eventType == "EB"
  866. || elog.eventType == "RP"
  867. || elog.eventType == "BF"
  868. || elog.eventType == "ED" // cyim 2016.12.09 : IFC3300에서는 예비전원버튼 -> 설비전체연동조작버튼
  869. )
  870. {
  871. // KEY PAD MAIN SOUND STOP BUTTON! (OFF)
  872. string temp = elog.eventRemark;
  873. int idx1 = temp.LastIndexOf('(');
  874. int idx2 = temp.LastIndexOf(')');
  875. string temp1 = temp.Substring(idx1);
  876. temp1 = temp1.Replace(")", "");
  877. temp1 = temp1.Replace("(", "");
  878. if (temp1 == "ON") // 조작
  879. elog.Report_EventErrorStatus = 0;
  880. else // 해제
  881. elog.Report_EventErrorStatus = 2;
  882. }
  883. // 상위 루틴과 관련없으면 그대로 레포트를 위한 변수에 저장한다
  884. else
  885. elog.Report_EventErrorStatus = elog.EventErrorStatus;
  886. EVENT_TYPE = FireDesk_Receiver.mdi.EventTypeName.Hash_EventType[elog.eventType].ToString();
  887. ERROR_TYPE = FireDesk_Receiver.mdi.EventTypeName.EventType_Division(elog.eventType);
  888. 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)",
  889. IP_ADDRESS, ERROR_TYPE, LOCATION, DEVICE_NAME, EVENT_TYPE, DEVICE_NUMBER));
  890. }
  891. }
  892. }
  893. }
  894. }
  895. }
  896. }
  897. }
  898. //
  899. // 타이머
  900. //
  901. // 1000 ms 타이머
  902. private void timer_1000_TimeLabelUpdate_Tick(object sende, EventArgs e)
  903. {
  904. // cyim 2015.9.23 시간정보 표시 오류 (갱신을 안함)
  905. MyTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
  906. // 현재 상태 갱신 : 시간표시
  907. this.label_Time.Text = string.Format("{0:yyyy}년 {0:MM}월 {0:dd}일 {0:HH}:{0:mm}:{0:ss}", DateTime.Now);
  908. // cyim 2015.9.1 1개의 수신기가 접속이 안되더라도 나머지는 접속시도할수 있도록 수정 : 활성화된 수신기를 개수를 표시한다
  909. if (CommErrorReceiver.Count != 0)
  910. label_ReceiverCount.Text = string.Format("전체 수신기 대수 : {0} 개 , 통신 불량 수신기 개수 : {1}", _Data.Hash_Receiver.Keys.Count, CommErrorReceiver.Count);
  911. else
  912. label_ReceiverCount.Text = string.Format("전체 수신기 대수 : {0} 개", _Data.Hash_Receiver.Keys.Count);
  913. }
  914. // 통신 체크 타이머 (1초타이머 주기가 아닐수도 있다 주의!)
  915. int ConnectCheck_Timer_Tick_Cnt = 0;
  916. // cyim 2017.01.05 : 수신기 아이디별 통신체크 루틴 보완
  917. private void ConnectCheck_Timer_Tick(object sende, EventArgs e)
  918. {
  919. // cyim 2015.9.15 주기적으로 수신기 통신상태를 점검 : 주기마다 한번 수신기 통신 상태를 점검한다
  920. if (ConnectCheck_Timer_Tick_Cnt >= _Data.Hash_Receiver_keys.Length - 1)
  921. ConnectCheck_Timer_Tick_Cnt = 0;
  922. else
  923. ConnectCheck_Timer_Tick_Cnt++;
  924. // 1초마다 수신기 체크
  925. MDIParent_Update_Func(_Data.Hash_Receiver_keys[ConnectCheck_Timer_Tick_Cnt]);
  926. }
  927. // cyim 2016.12.20 : 푸시메세지 연동 기능 추가
  928. public void GCM_Sender_CallBack(object target)
  929. {
  930. if (this.InvokeRequired)
  931. {
  932. this.Invoke(new TimerCallback(GCM_Sender_CallBack), new object[] { target });
  933. }
  934. else
  935. {
  936. if (GCM_Sender_Tick_Cnt > 10)
  937. GCM_Sender_Tick_Cnt = 0;
  938. else
  939. GCM_Sender_Tick_Cnt++;
  940. if (_Data.MOBILE_ENABLE == "ON" && _Data.GCM_ENABLE == "ON" && _Data.GCM_API_KEY != null) // 둘다 값이 존재해야 한다
  941. {
  942. string Comment = "";
  943. // 화재 건수가 몇개인지 확인한다. 아래와 같은 시나리오로 동작하게 만든다
  944. // 1. 화재 발생중인데 또 다른 화재가 발생하면 다시 푸시 메세지를 날린다.
  945. // 2. 화재 복구할때는 푸시 메세지를 날리지 않는다.
  946. // 3. 너무 짧은 주기로 GCM 을 보내지 않도록 한다.
  947. // 화재
  948. if (_Data.GCM_INFO_FIRE == "ON" && GCM_Sender_Tick_Cnt == 0)
  949. {
  950. Comment = ""; if (GCM_Fire_Clone.Count != 0) Comment = string.Format("화재! 수신기ID:{0}", Receiver_ID_List_String(GCM_Fire_Clone));
  951. 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);
  952. timer_1000_Tick_Fire_Cnt_Old = timer_1000_Tick_Fire_Cnt_New;
  953. }
  954. // 설비
  955. if (_Data.GCM_INFO_FACILITY == "ON" && GCM_Sender_Tick_Cnt == 2)
  956. {
  957. Comment = ""; if (GCM_Facility_Clone.Count != 0) Comment = string.Format("설비! 수신기ID:{0}", Receiver_ID_List_String(GCM_Facility_Clone));
  958. 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);
  959. timer_1000_Tick_Facility_Cnt_Old = timer_1000_Tick_Facility_Cnt_New;
  960. }
  961. // 통신에러
  962. if (_Data.GCM_INFO_COMERROR == "ON" && GCM_Sender_Tick_Cnt == 4)
  963. {
  964. Comment = ""; if (GCM_ComError_Clone.Count != 0) Comment = string.Format("통신! 수신기ID:{0}", Receiver_ID_List_String(GCM_ComError_Clone));
  965. 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);
  966. timer_1000_Tick_ComError_Cnt_Old = timer_1000_Tick_ComError_Cnt_New;
  967. }
  968. // 단선
  969. if (_Data.GCM_INFO_BLOCK == "ON" && GCM_Sender_Tick_Cnt == 6)
  970. {
  971. Comment = ""; if (GCM_Block_Clone.Count != 0) Comment = string.Format("단선! 수신기ID:{0}", Receiver_ID_List_String(GCM_Block_Clone));
  972. 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);
  973. timer_1000_Tick_Block_Cnt_Old = timer_1000_Tick_Block_Cnt_New;
  974. }
  975. // 차단
  976. if (_Data.GCM_INFO_CUT == "ON" && GCM_Sender_Tick_Cnt == 8)
  977. {
  978. Comment = ""; if (GCM_Cut_Clone.Count != 0) Comment = string.Format("차단! 수신기ID:{0}", Receiver_ID_List_String(GCM_Cut_Clone));
  979. 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);
  980. timer_1000_Tick_Cut_Cnt_Old = timer_1000_Tick_Cut_Cnt_New;
  981. }
  982. // 점검
  983. if (_Data.GCM_INFO_CHECK == "ON" && GCM_Sender_Tick_Cnt == 10)
  984. {
  985. Comment = ""; if (GCM_Check_Clone.Count != 0) Comment = string.Format("점검! 수신기ID:{0}", Receiver_ID_List_String(GCM_Check_Clone));
  986. 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);
  987. timer_1000_Tick_Check_Cnt_Old = timer_1000_Tick_Check_Cnt_New;
  988. }
  989. }
  990. }
  991. }
  992. // 수신기 아이디 리스트로 부터 문자열로 생성
  993. private string Receiver_ID_List_String(ArrayList al)
  994. {
  995. string DataString = null;
  996. foreach (string datas in al)
  997. DataString += datas + " ";
  998. return DataString.Trim();
  999. }
  1000. // 데이타베이스에 등록된 모바일앱 디바이스 아이디를 조회하고, GCM 을 송출한다
  1001. public void GCM_Send(string Comment)
  1002. {
  1003. Thread WorkingThread = new Thread(new ParameterizedThreadStart(GCM_Send_Thread));
  1004. WorkingThread.Start(Comment);
  1005. }
  1006. // 스레드로 처리해야한다
  1007. public void GCM_Send_Thread(object Comment)
  1008. {
  1009. using (DacReceiverConfig push_info_select_query = new DacReceiverConfig(0))
  1010. {
  1011. DataSet ds = push_info_select_query.Select("select * from TB_PUSH_DEVICE");
  1012. DataTable dt = ds.Tables[0];
  1013. foreach (DataRow dr in dt.Rows)
  1014. {
  1015. string Regid = dr["REG_ID"].ToString();
  1016. var push = new PushBroker();
  1017. push.OnNotificationSent += NotificationSent;
  1018. push.OnChannelException += ChannelException;
  1019. push.OnServiceException += ServiceException;
  1020. push.OnNotificationFailed += NotificationFailed;
  1021. push.OnDeviceSubscriptionExpired += DeviceSubscriptionExpired;
  1022. push.OnDeviceSubscriptionChanged += DeviceSubscriptionChanged;
  1023. push.OnChannelCreated += ChannelCreated;
  1024. push.OnChannelDestroyed += ChannelDestroyed;
  1025. //txtApiKey.Text is API KEY for server applications from Google Developers Console
  1026. push.RegisterGcmService(new GcmPushChannelSettings(_Data.GCM_API_KEY));
  1027. //txtRegistrationID.Text is a value of e.regid from the onNotificationGCM function in the PushTest app
  1028. push.QueueNotification(new GcmNotification()
  1029. .ForDeviceRegistrationId(Regid)
  1030. .WithJson("{\"message\":\"" + Comment.ToString() + "\"}"));
  1031. push.StopAllServices();
  1032. }
  1033. }
  1034. }
  1035. private void NotificationSent(object sender, INotification notification)
  1036. {
  1037. //txtLogs.Invoke((MethodInvoker)(() => { txtLogs.AppendText("NotificationSent" + Environment.NewLine); }));
  1038. }
  1039. private void ChannelException(object sender, IPushChannel pushChannel, Exception error)
  1040. {
  1041. //txtLogs.Invoke((MethodInvoker)(() => { txtLogs.AppendText("ChannelException: " + error.Message + Environment.NewLine); }));
  1042. }
  1043. private void ServiceException(object sender, Exception error)
  1044. {
  1045. //txtLogs.Invoke((MethodInvoker)(() => { txtLogs.AppendText("ServiceException: " + error.Message + Environment.NewLine); }));
  1046. }
  1047. private void NotificationFailed(object sender, INotification notification, Exception error)
  1048. {
  1049. //txtLogs.Invoke((MethodInvoker)(() => { txtLogs.AppendText("NotificationFailed: " + error.Message + Environment.NewLine); }));
  1050. }
  1051. private void DeviceSubscriptionExpired(object sender, string expiredSubscriptionId, DateTime expirationDateUtc, INotification notification)
  1052. {
  1053. //txtLogs.Invoke((MethodInvoker)(() => { txtLogs.AppendText("DeviceSubscriptionExpired" + Environment.NewLine); }));
  1054. }
  1055. private void DeviceSubscriptionChanged(object sender, string oldSubscriptionId, string newSubscriptionId, INotification notification)
  1056. {
  1057. //txtLogs.Invoke((MethodInvoker)(() => { txtLogs.AppendText("DeviceSubscriptionChanged" + Environment.NewLine); }));
  1058. }
  1059. private void ChannelCreated(object sender, IPushChannel pushChannel)
  1060. {
  1061. //txtLogs.Invoke((MethodInvoker)(() => { txtLogs.AppendText("ChannelCreated" + Environment.NewLine); }));
  1062. }
  1063. private void ChannelDestroyed(object sender)
  1064. {
  1065. //txtLogs.Invoke((MethodInvoker)(() => { txtLogs.AppendText("ChannelDestroyed" + Environment.NewLine); }));
  1066. }
  1067. // 알람 상태 표시
  1068. bool Display_Timer_toggle = false;
  1069. // 500 ms 타이머
  1070. private void Display_Timer_Tick(object sende, EventArgs e)
  1071. {
  1072. // 초기화 팝업창때는 실행안됨
  1073. if (waitingForm_FireDesk != null && waitingForm_FireDesk.Visible == true) return;
  1074. // 토글용
  1075. Display_Timer_toggle = !Display_Timer_toggle;
  1076. //
  1077. // 전체현황 카운터 표시
  1078. //
  1079. fireCount = 0;
  1080. facilityCount = 0;
  1081. errorCount = 0;
  1082. blockingCount = 0;
  1083. cutCnt = 0;
  1084. checkCnt = 0;
  1085. fireCount_Accumulation = 0;
  1086. PreFireList = new ArrayList();
  1087. // cyim 2016.12.20 : 푸시메세지 연동 기능 추가
  1088. GCM_Fire_List.Clear();
  1089. GCM_Facility_List.Clear();
  1090. GCM_ComError_List.Clear();
  1091. GCM_Block_List.Clear();
  1092. GCM_Cut_List.Clear();
  1093. GCM_Check_List.Clear();
  1094. foreach (string id in _Data.Hash_Receiver_keys)
  1095. {
  1096. _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[id];
  1097. // cyim 2015.9.1 1개의 수신기가 접속이 안되더라도 나머지는 접속시도할수 있도록 수정
  1098. if (FireDesk_Receiver.mdi != null)
  1099. {
  1100. // 화재
  1101. fireCount = fireCount + FireDesk_Receiver.mdi.fireCount;
  1102. // 설비
  1103. facilityCount = facilityCount + FireDesk_Receiver.mdi.facilityCount;
  1104. // 통신
  1105. errorCount = errorCount + FireDesk_Receiver.mdi.errorCount;
  1106. // 단선
  1107. blockingCount = blockingCount + FireDesk_Receiver.mdi.blockingCount;
  1108. // 차단
  1109. cutCnt = cutCnt + FireDesk_Receiver.mdi.CutCnt;
  1110. // 축적화재
  1111. fireCount_Accumulation = fireCount_Accumulation + FireDesk_Receiver.mdi.fireCount_Accumulation;
  1112. // 아날로그감지기의 PreFire
  1113. foreach (string data in FireDesk_Receiver.mdi.PreFireList)
  1114. PreFireList.Add(data);
  1115. // cyim 2016.12.20 : 푸시메세지 연동 기능 추가
  1116. if (FireDesk_Receiver.mdi.fireCount > 0) GCM_Fire_List.Add(id);
  1117. if (FireDesk_Receiver.mdi.facilityCount > 0) GCM_Facility_List.Add(id);
  1118. if (FireDesk_Receiver.mdi.errorCount > 0) GCM_ComError_List.Add(id);
  1119. if (FireDesk_Receiver.mdi.blockingCount > 0) GCM_Block_List.Add(id);
  1120. if (FireDesk_Receiver.mdi.CutCnt > 0) GCM_Cut_List.Add(id);
  1121. if (FireDesk_Receiver.mdi.fireCount > 0) GCM_Check_List.Add(id);
  1122. if (FireDesk_Receiver.mdi.CheckBtn_Current_Status == true
  1123. || FireDesk_Receiver.mdi.CommDaemon_ComStatus == false // 통신데몬연결이상
  1124. || FireDesk_Receiver.mdi.lblEmergencyBoardStatus_Visible == true // 비상방송연결이상
  1125. ) // cyim 2017.01.04 : 점검출력이 안되는 문제 수정
  1126. //|| FireDesk_Receiver.mdi.socketUI == null // cyim 2016.12.28 : 예외처리 추가
  1127. //|| FireDesk_Receiver.mdi.socketUI.myCntLabel.Visible == true)
  1128. {
  1129. // 점검 내용
  1130. checkCnt = checkCnt + 1;
  1131. GCM_Check_List.Add(id);
  1132. }
  1133. }
  1134. }
  1135. // cyim 2016.12.20 : 푸시메세지 연동 기능 추가
  1136. timer_1000_Tick_Fire_Cnt_New = fireCount;
  1137. timer_1000_Tick_Facility_Cnt_New = facilityCount;
  1138. timer_1000_Tick_ComError_Cnt_New = errorCount;
  1139. timer_1000_Tick_Block_Cnt_New = blockingCount;
  1140. timer_1000_Tick_Cut_Cnt_New = cutCnt;
  1141. timer_1000_Tick_Check_Cnt_New = checkCnt;
  1142. GCM_Fire_Clone = (ArrayList)GCM_Fire_List.Clone();
  1143. GCM_Facility_Clone = (ArrayList)GCM_Facility_List.Clone();
  1144. GCM_ComError_Clone = (ArrayList)GCM_ComError_List.Clone();
  1145. GCM_Block_Clone = (ArrayList)GCM_Block_List.Clone();
  1146. GCM_Cut_Clone = (ArrayList)GCM_Cut_List.Clone();
  1147. GCM_Check_Clone = (ArrayList)GCM_Check_List.Clone();
  1148. // 전체 현황의 경우 카운터가 0이상이면 깜빡거리게 만든다
  1149. Toggle_ControlForeColor(this.label_CurrentStatus_Fire, fireCount, string.Format("화재({0})", fireCount));
  1150. Toggle_ControlForeColor(this.label_CurrentStatus_Facility, facilityCount, string.Format("설비({0})", facilityCount));
  1151. Toggle_ControlForeColor(this.label_CurrentStatus_Error, errorCount, string.Format("통신({0})", errorCount));
  1152. Toggle_ControlForeColor(this.label_CurrentStatus_Blocking, blockingCount, string.Format("단선({0})", blockingCount));
  1153. Toggle_ControlForeColor(this.label_CurrentStatus_Cut, cutCnt, string.Format("차단({0})", cutCnt));
  1154. //
  1155. // 점검 표시
  1156. //
  1157. foreach (string id in _Data.Hash_Receiver_keys)
  1158. {
  1159. _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[id];
  1160. Button btn = (Button)Util.FineControl(panel_Receiver, "button_Check" + id.ToString());
  1161. // cyim 2015.9.1 1개의 수신기가 접속이 안되더라도 나머지는 접속시도할수 있도록 수정
  1162. if (FireDesk_Receiver.mdi != null)
  1163. {
  1164. // 점검
  1165. if (FireDesk_Receiver.mdi.CheckBtn_Current_Status == true
  1166. || FireDesk_Receiver.mdi.CommDaemon_ComStatus == false // 통신데몬연결이상
  1167. || FireDesk_Receiver.mdi.lblEmergencyBoardStatus_Visible == true // 비상방송연결이상
  1168. ) // cyim 2017.01.04 : 점검출력이 안되는 문제 수정
  1169. //|| FireDesk_Receiver.mdi.socketUI == null // cyim 2016.12.28 : 예외처리 추가
  1170. //|| FireDesk_Receiver.mdi.socketUI.myCntLabel.Visible == true)
  1171. {
  1172. Toggle_ControlBackColor(btn, 1, null);
  1173. }
  1174. else
  1175. Toggle_ControlBackColor(btn, 0, null);
  1176. }
  1177. }
  1178. // cyim 2015.9.15 수신반 하단 이벤트 표시 : 화재 및 설비 표시
  1179. FireFacilityEventCheck();
  1180. // cyim 2016.06.15 : 화재 음원 출력
  1181. if (SoundPlayer_AlarmPopupSound_Count > 6)
  1182. {
  1183. SoundPlayer_AlarmPopupSound_Count = 0; // 3초마다
  1184. AlarmPopup_PlaySound_Check();
  1185. }
  1186. else
  1187. {
  1188. SoundPlayer_AlarmPopupSound_Count++;
  1189. }
  1190. }
  1191. // cyim 2016.06.15 : 화재 음원 출력
  1192. public void AlarmPopup_PlaySound_Check()
  1193. {
  1194. if (SoundPlayer_AlarmPopupSound != null) // cyim 2016.11.11 : 비상 음원 출력 음원 파일 없을때 대응 코드 추가
  1195. {
  1196. if (this.label_FireAlert.Visible == true || this.label_FacilityAlert.Visible == true) // cyim 2016.06.16 : 설비동작 발생시 음원 출력 포함
  1197. SoundPlayer_AlarmPopupSound.Play();
  1198. else
  1199. SoundPlayer_AlarmPopupSound.Stop();
  1200. }
  1201. }
  1202. // 글자색을 토글
  1203. private void Toggle_ControlForeColor(Label label, int count, string text)
  1204. {
  1205. if (count > 0)
  1206. {
  1207. if (Display_Timer_toggle == true) label.ForeColor = Color.White;
  1208. else label.ForeColor = Color.Red;
  1209. }
  1210. else
  1211. {
  1212. if (label.ForeColor != Color.White)
  1213. label.ForeColor = Color.White;
  1214. }
  1215. if (text != null)
  1216. label.Text = text;
  1217. }
  1218. // 배경색을 토글
  1219. private void Toggle_ControlBackColor(Control ctrl, int count, string text)
  1220. {
  1221. if (count > 0)
  1222. {
  1223. if (Display_Timer_toggle == true) ctrl.BackColor = Color.Transparent;
  1224. else ctrl.BackColor = Color.Red;
  1225. }
  1226. else
  1227. {
  1228. if (ctrl.BackColor != Color.Transparent)
  1229. ctrl.BackColor = Color.Transparent;
  1230. }
  1231. if (text != null)
  1232. ctrl.Text = text;
  1233. }
  1234. //
  1235. // cyim 2015.9.15 수신반 하단 이벤트 표시 : 화재 및 설비 표시루틴을 그대로 이용하도록 한다 MdiParent.cs 와 동일함
  1236. //
  1237. public void FireFacilityEventCheck()
  1238. {
  1239. {
  1240. //
  1241. // 화재
  1242. //
  1243. if (this.fireCount > 0)
  1244. {
  1245. this.label_FireAlert.Visible = true;
  1246. //this.labelFireAlert.Image = null;//sdkim, 20120129, [MTS-47]
  1247. this.label_FireAlert_inform_1th.Visible = true;
  1248. this.txtFirstFireWarnningMessage.Visible = true;
  1249. if (this.fireCount > 1)
  1250. {
  1251. this.label_FireAlert_inform_2th.Visible = true;
  1252. this.cboSecondFireWarnningMessage.Visible = true;
  1253. }
  1254. else
  1255. {
  1256. this.label_FireAlert_inform_2th.Visible = false;
  1257. this.cboSecondFireWarnningMessage.Visible = false;
  1258. }
  1259. if (Display_Timer_toggle == false)
  1260. {
  1261. this.label_FireAlert.BackColor = Color.Red;
  1262. this.label_FireAlert.ForeColor = Color.Black;
  1263. }
  1264. else
  1265. {
  1266. this.label_FireAlert.BackColor = Color.Transparent;
  1267. this.label_FireAlert.ForeColor = Color.Red;
  1268. }
  1269. }
  1270. // cyim 2014.7.10 : 축적화재 표시 : KFI 요청사항
  1271. else if (this.fireCount_Accumulation > 0)
  1272. {
  1273. // 상위 화재와 동일한 코드이다. 굳이 상위와 합치지 않은 이유는 우선순위는 무조건 일반 화재가 높기 때문이다. (위험도 고려)
  1274. this.label_FireAlert.Visible = true;
  1275. //this.labelFireAlert.Image = null;//sdkim, 20120129, [MTS-47]
  1276. this.label_FireAlert_inform_1th.Visible = true;
  1277. this.txtFirstFireWarnningMessage.Visible = true;
  1278. if (this.fireCount_Accumulation > 1)
  1279. {
  1280. this.label_FireAlert_inform_2th.Visible = true;
  1281. this.cboSecondFireWarnningMessage.Visible = true;
  1282. }
  1283. else
  1284. {
  1285. this.label_FireAlert_inform_2th.Visible = false;
  1286. this.cboSecondFireWarnningMessage.Visible = false;
  1287. }
  1288. if (Display_Timer_toggle == false)
  1289. {
  1290. this.label_FireAlert.BackColor = Color.Red;
  1291. this.label_FireAlert.ForeColor = Color.Black;
  1292. }
  1293. else
  1294. {
  1295. this.label_FireAlert.BackColor = Color.Transparent;
  1296. this.label_FireAlert.ForeColor = Color.Red;
  1297. }
  1298. }
  1299. else
  1300. {
  1301. this.label_FireAlert.Visible = false;
  1302. this.txtFirstFireWarnningMessage.Visible = false;
  1303. this.label_FireAlert_inform_1th.Visible = false;
  1304. this.cboSecondFireWarnningMessage.Visible = false;
  1305. this.cboSecondFireWarnningMessage.Items.Clear();
  1306. this.label_FireAlert_inform_2th.Visible = false;
  1307. }
  1308. //
  1309. // cyim 2015.7.9 PreFire 표시 문제 : 아날로그 감지기는 PreFire 단계가 있다
  1310. //
  1311. if (this.PreFireList.Count > 0)
  1312. {
  1313. this.labelPreFireAlert.Visible = true;
  1314. this.cboPreFireWarnningMessage.Visible = true;
  1315. if (Display_Timer_toggle == false)
  1316. {
  1317. this.labelPreFireAlert.BackColor = Color.Red;
  1318. this.labelPreFireAlert.ForeColor = Color.Black;
  1319. }
  1320. else
  1321. {
  1322. this.labelPreFireAlert.BackColor = Color.Transparent;
  1323. this.labelPreFireAlert.ForeColor = Color.Red;
  1324. }
  1325. }
  1326. else
  1327. {
  1328. this.labelPreFireAlert.Visible = false;
  1329. this.cboPreFireWarnningMessage.Visible = false;
  1330. this.cboPreFireWarnningMessage.Items.Clear();
  1331. }
  1332. //
  1333. // 설비
  1334. //
  1335. if (this.facilityCount > 0)
  1336. {
  1337. this.label_FacilityAlert.Visible = true;
  1338. //this.labelFacilityAlert.Image = null;//sdkim, 20120129, [MTS-47]
  1339. this.cboWriteWarningMessage.Visible = true;
  1340. this.label_FacilityAlert_inform_1th.Visible = true;
  1341. if (Display_Timer_toggle == false)
  1342. {
  1343. this.label_FacilityAlert.BackColor = Color.Blue;
  1344. this.label_FacilityAlert.ForeColor = Color.White;
  1345. }
  1346. else
  1347. {
  1348. this.label_FacilityAlert.BackColor = Color.Transparent;
  1349. this.label_FacilityAlert.ForeColor = Color.LightSkyBlue;
  1350. }
  1351. }
  1352. else
  1353. {
  1354. this.label_FacilityAlert.Visible = false;
  1355. this.cboWriteWarningMessage.Visible = false;
  1356. this.cboWriteWarningMessage.Items.Clear();
  1357. this.label_FacilityAlert_inform_1th.Visible = false;
  1358. }
  1359. LEDCount = LEDList.Count;
  1360. if (this.LEDCount > 0)
  1361. {
  1362. this.lblLEDText.Text = LEDList[LEDCount - 1].ToString();
  1363. this.lblLEDText.Visible = true;
  1364. //this.labelFacilityAlert.Image = null;//sdkim, 20120129, [MTS-47]
  1365. if (Display_Timer_toggle == false)
  1366. {
  1367. this.lblLEDText.BackColor = Color.LightPink;
  1368. this.lblLEDText.ForeColor = Color.White;
  1369. }
  1370. else
  1371. {
  1372. this.lblLEDText.BackColor = Color.Transparent;
  1373. this.lblLEDText.ForeColor = Color.LightPink;
  1374. }
  1375. }
  1376. else
  1377. {
  1378. this.lblLEDText.Visible = false;
  1379. }
  1380. }
  1381. }
  1382. //
  1383. // cyim 2015.9.15 수신반 하단 이벤트 표시
  1384. // 현재 접속되어있는 데몬을 기준으로 화재 정보를 처리한다
  1385. // 화재,축적,아날로그 Prefire,설비 의 경우 이벤트가 발생하면 아래의 함수에서 글자를 셋팅한다
  1386. //
  1387. public void FireEventProcess()
  1388. {
  1389. // 일반화재
  1390. int iFireEventCount = FireList.Count;
  1391. // 축적화재
  1392. int iFireEventCount_Accumulation = FireList_Accumulation.Count;
  1393. try
  1394. {
  1395. if (this.cboSecondFireWarnningMessage.InvokeRequired)
  1396. {
  1397. dCommandFuctionCallEvent d = new dCommandFuctionCallEvent(FireEventProcess);
  1398. this.cboSecondFireWarnningMessage.Invoke(d, new object[] { });
  1399. }
  1400. else
  1401. {
  1402. this.Focus(); // cyim 2014.5.15 : OutofRangeException
  1403. this.cboSecondFireWarnningMessage.Items.Clear();
  1404. this.cboSecondFireWarnningMessage.Text = "";
  1405. if (iFireEventCount > 0)
  1406. {
  1407. // 2보 정리
  1408. for (int iLoop = 1; iLoop < iFireEventCount; iLoop++)
  1409. this.cboSecondFireWarnningMessage.Items.Add(FireList[iLoop].ToString());
  1410. if (this.cboSecondFireWarnningMessage.Items.Count > 0)
  1411. this.cboSecondFireWarnningMessage.Text = this.cboSecondFireWarnningMessage.Items[0].ToString();
  1412. // 1보 정리
  1413. this.txtFirstFireWarnningMessage.Text = FireList[0].ToString();
  1414. // 화재 타입
  1415. this.label_FireAlert.Text = "화재발생";
  1416. }
  1417. // cyim 2014.7.10 : 축적화재 표시 : KFI 요청사항
  1418. else if (iFireEventCount_Accumulation > 0)
  1419. {
  1420. // 2보 정리
  1421. for (int iLoop = 1; iLoop < iFireEventCount_Accumulation; iLoop++)
  1422. this.cboSecondFireWarnningMessage.Items.Add(FireList_Accumulation[iLoop].ToString());
  1423. if (this.cboSecondFireWarnningMessage.Items.Count > 0)
  1424. this.cboSecondFireWarnningMessage.Text = this.cboSecondFireWarnningMessage.Items[0].ToString();
  1425. // 1보 정리
  1426. this.txtFirstFireWarnningMessage.Text = FireList_Accumulation[0].ToString();
  1427. // 화재 타입
  1428. this.label_FireAlert.Text = "화재축적상태 발생";
  1429. }
  1430. }
  1431. }
  1432. catch (Exception ex)
  1433. {
  1434. Util.UErrorMessage(ex, 0, 0);
  1435. }
  1436. }
  1437. public delegate void dCommandFuctionCallEvent_PreFireEventProcess();
  1438. public void PreFireEventProcess()
  1439. {
  1440. // PreFire
  1441. int iPreFireListCount = PreFireList.Count;
  1442. if (this.cboPreFireWarnningMessage.InvokeRequired)
  1443. {
  1444. dCommandFuctionCallEvent_PreFireEventProcess d = new dCommandFuctionCallEvent_PreFireEventProcess(PreFireEventProcess);
  1445. this.cboPreFireWarnningMessage.Invoke(d, new object[] { });
  1446. }
  1447. else
  1448. {
  1449. this.Focus(); // OutofRangeException 문제 수정
  1450. this.cboPreFireWarnningMessage.Items.Clear();
  1451. this.cboPreFireWarnningMessage.Text = "";
  1452. if (PreFireList.Count > 0)
  1453. {
  1454. for (int i = 0; i < iPreFireListCount; i++)
  1455. this.cboPreFireWarnningMessage.Items.Add(PreFireList[i].ToString());
  1456. this.cboPreFireWarnningMessage.Text = PreFireList[0].ToString();
  1457. }
  1458. }
  1459. }
  1460. public delegate void dCommandFuctionCallEvent();
  1461. public void EquipEventProcess()
  1462. {
  1463. int iEquipEventCount = EquipList.Count;
  1464. try
  1465. {
  1466. if (this.cboWriteWarningMessage.InvokeRequired)
  1467. {
  1468. dCommandFuctionCallEvent d = new dCommandFuctionCallEvent(EquipEventProcess);
  1469. this.cboWriteWarningMessage.Invoke(d, new object[] { });
  1470. }
  1471. else
  1472. {
  1473. this.Focus(); // cyim 2014.5.15 : OutofRangeException
  1474. this.cboWriteWarningMessage.Items.Clear();
  1475. this.cboWriteWarningMessage.Text = "";
  1476. if (iEquipEventCount > 0)
  1477. {
  1478. for (int iLoop = 0; iLoop < iEquipEventCount; iLoop++)
  1479. {
  1480. this.cboWriteWarningMessage.Items.Add(EquipList[iLoop].ToString());
  1481. }
  1482. if (this.cboWriteWarningMessage.Items.Count > 0)
  1483. {
  1484. this.cboWriteWarningMessage.Text = this.cboWriteWarningMessage.Items[0].ToString();
  1485. }
  1486. }
  1487. }
  1488. }
  1489. catch (Exception ex)
  1490. {
  1491. Util.UErrorMessage(ex, 0, 0);
  1492. }
  1493. }
  1494. // cyim 2016.12.16 : 모바일앱 연동 - 카운트 정보 갱신
  1495. private void UPDATE_TB_RECEIVER_ERROR_COUNT(int ID, string Type, int pValue)
  1496. {
  1497. if (_Data.MOBILE_ENABLE == "ON")
  1498. {
  1499. _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[ID.ToString()];
  1500. // cyim 2017.01.04 : 메모리릭을 위한 수정으로 인하여 소멸자로 인하여 이벤트 리스트안에 객체가 일부 소멸되버린다
  1501. string Value = pValue.ToString();
  1502. using (DacReceiverConfig query_session = new DacReceiverConfig(0))
  1503. {
  1504. switch (Type)
  1505. {
  1506. case "FireDetect":
  1507. query_session.ExecuteSql(string.Format("update TB_RECEIVER_ERROR_COUNT set {1} = {2} where IP_ADDRESS = '{0}'", FireDesk_Receiver.DATABASE_NAME_IP, "INFO1", Value));
  1508. break;
  1509. case "DeviceInput":
  1510. query_session.ExecuteSql(string.Format("update TB_RECEIVER_ERROR_COUNT set {1} = {2} where IP_ADDRESS = '{0}'", FireDesk_Receiver.DATABASE_NAME_IP, "INFO2", Value));
  1511. break;
  1512. case "RepeaterError":
  1513. query_session.ExecuteSql(string.Format("update TB_RECEIVER_ERROR_COUNT set {1} = {2} where IP_ADDRESS = '{0}'", FireDesk_Receiver.DATABASE_NAME_IP, "INFO3", Value));
  1514. break;
  1515. case "DeviceCut":
  1516. query_session.ExecuteSql(string.Format("update TB_RECEIVER_ERROR_COUNT set {1} = {2} where IP_ADDRESS = '{0}'", FireDesk_Receiver.DATABASE_NAME_IP, "INFO4", Value));
  1517. break;
  1518. case "DeviceNotuse":
  1519. query_session.ExecuteSql(string.Format("update TB_RECEIVER_ERROR_COUNT set {1} = {2} where IP_ADDRESS = '{0}'", FireDesk_Receiver.DATABASE_NAME_IP, "INFO5", Value));
  1520. break;
  1521. }
  1522. }
  1523. }
  1524. }
  1525. //
  1526. // 이벤트
  1527. //
  1528. // 외부에서 화면을 변경하는 경우
  1529. private void _Event_FireDesk_Update_SendMessage_Event(int id, string cmd, string type, int data)
  1530. {
  1531. // 카운터 업데이트
  1532. if (cmd == "Count")
  1533. {
  1534. // cyim 2016.12.16 : 모바일앱 연동 - 카운트 정보 갱신
  1535. UPDATE_TB_RECEIVER_ERROR_COUNT(id, type, data);
  1536. // 화재
  1537. if (type == "FireDetect")
  1538. {
  1539. Button btn = (Button)Util.FineControl(panel_Receiver, "button_FireDetect" + id.ToString());
  1540. btn.Text = string.Format("화재 : {0:0000}", data);
  1541. if (data > 9999) btn.Text = String.Format("화재 : {0:00000}", data);
  1542. else btn.Text = String.Format("화재 : {0:0000}", data);
  1543. }
  1544. // 설비
  1545. else if (type == "DeviceInput")
  1546. {
  1547. Button btn = (Button)Util.FineControl(panel_Receiver, "button_DeviceInput" + id.ToString());
  1548. btn.Text = string.Format("설비 : {0:0000}", data);
  1549. if (data > 9999) btn.Text = String.Format("설비 : {0:00000}", data);
  1550. else btn.Text = String.Format("설비 : {0:0000}", data);
  1551. }
  1552. // 통신
  1553. else if (type == "RepeaterError")
  1554. {
  1555. Button btn = (Button)Util.FineControl(panel_Receiver, "button_RepeaterError" + id.ToString());
  1556. btn.Text = string.Format("통신 : {0:0000}", data);
  1557. if (data > 9999) btn.Text = String.Format("통신 : {0:00000}", data);
  1558. else btn.Text = String.Format("통신 : {0:0000}", data);
  1559. }
  1560. // 단선
  1561. else if (type == "DeviceCut")
  1562. {
  1563. Button btn = (Button)Util.FineControl(panel_Receiver, "button_DeviceCut" + id.ToString());
  1564. btn.Text = string.Format("단선 : {0:0000}", data);
  1565. if (data > 9999) btn.Text = String.Format("단선 : {0:00000}", data);
  1566. else btn.Text = String.Format("단선 : {0:0000}", data);
  1567. }
  1568. // 차단
  1569. else if (type == "DeviceNotuse")
  1570. {
  1571. Button btn = (Button)Util.FineControl(panel_Receiver, "button_DeviceNotuse" + id.ToString());
  1572. btn.Text = string.Format("차단 : {0:0000}", data);
  1573. if (data > 9999) btn.Text = String.Format("차단 : {0:00000}", data);
  1574. else btn.Text = String.Format("차단 : {0:0000}", data);
  1575. }
  1576. }
  1577. // 폼을 로드
  1578. else if (cmd == "FormLoad")
  1579. {
  1580. // 완료
  1581. if (type == "MDIParentComplete")
  1582. {
  1583. FormLoadComplete = false;
  1584. // cyim 2016.12.29 : 화면 멈춤 문제 수정 : 주석처리
  1585. // 원래 용도는 로드이후 리스트에서 삭제하려고 했으나
  1586. // 네트워크 데이타베이스를 이용하는 상태에서 삭제 타이밍을 맞추기가 어렵다고 결론내림
  1587. //LoadMdiparentFormList.Remove(id.ToString());
  1588. }
  1589. }
  1590. // 팝업창을 로드
  1591. else if (cmd == "Popup")
  1592. {
  1593. ShowWaitingMsgForm(string.Format("수신기 [{0}]:", id) + type, data);
  1594. }
  1595. // cyim 2015.9.15 : 일반화재,축적화재,PreFire,설비,복구 의 경우 이벤트로 처리 (참고로 카운터 표시는 주기적으로 함)
  1596. else if (cmd == "EventProcess")
  1597. {
  1598. if (type == "Fire") // 일반화재, 축적화재
  1599. {
  1600. FireList.Clear();
  1601. FireList_Accumulation.Clear();
  1602. foreach (string ID in _Data.Hash_Receiver_keys)
  1603. {
  1604. _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[ID];
  1605. foreach (string item in FireDesk_Receiver.mdi.FireList)
  1606. if (FireList.Contains(item) == false) FireList.Add(item);
  1607. foreach (string item in FireDesk_Receiver.mdi.FireList_Accumulation)
  1608. if (FireList_Accumulation.Contains(item) == false) FireList_Accumulation.Add(item);
  1609. }
  1610. FireEventProcess();
  1611. }
  1612. else if (type == "PreFire") // PreFire
  1613. {
  1614. PreFireList.Clear();
  1615. foreach (string ID in _Data.Hash_Receiver_keys)
  1616. {
  1617. _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[ID];
  1618. foreach (string item in FireDesk_Receiver.mdi.PreFireList)
  1619. if (PreFireList.Contains(item) == false) PreFireList.Add(item);
  1620. }
  1621. PreFireEventProcess();
  1622. }
  1623. else if (type == "Equip") // 설비
  1624. {
  1625. EquipList.Clear();
  1626. foreach (string ID in _Data.Hash_Receiver_keys)
  1627. {
  1628. _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[ID];
  1629. foreach (string item in FireDesk_Receiver.mdi.EquipList)
  1630. if (EquipList.Contains(item) == false) EquipList.Add(item);
  1631. }
  1632. EquipEventProcess();
  1633. }
  1634. else if (type == "Reset") // 복구
  1635. {
  1636. FireList.Clear();
  1637. FireList_Accumulation.Clear();
  1638. PreFireList.Clear();
  1639. EquipList.Clear();
  1640. // 복구할 때는 현재 복구하는 수신기만 제외하고 다시 불러 읽어들인다
  1641. foreach (string ID in _Data.Hash_Receiver_keys)
  1642. {
  1643. if (id.ToString() != ID)
  1644. {
  1645. _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[ID];
  1646. foreach (string item in FireDesk_Receiver.mdi.FireList)
  1647. if (FireList.Contains(item) == false) FireList.Add(item);
  1648. foreach (string item in FireDesk_Receiver.mdi.FireList_Accumulation)
  1649. if (FireList_Accumulation.Contains(item) == false) FireList_Accumulation.Add(item);
  1650. foreach (string item in FireDesk_Receiver.mdi.PreFireList)
  1651. if (PreFireList.Contains(item) == false) PreFireList.Add(item);
  1652. foreach (string item in FireDesk_Receiver.mdi.EquipList)
  1653. if (EquipList.Contains(item) == false) EquipList.Add(item);
  1654. }
  1655. }
  1656. FireEventProcess();
  1657. PreFireEventProcess();
  1658. EquipEventProcess();
  1659. }
  1660. }
  1661. }
  1662. // 수신기 버튼
  1663. private void button_Receiver_Click(object sender, EventArgs e)
  1664. {
  1665. Button btn = (Button)sender;
  1666. string id = btn.Tag.ToString();
  1667. _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[id];
  1668. FireDesk_Receiver.mdi.Visible = true;
  1669. }
  1670. // 수신기 복구 버튼
  1671. private void button_Recover_Click(object sender, EventArgs e)
  1672. {
  1673. if (MessageBox.Show("수신기에 복구 명령을 수행하시겠습니까?", Application.ProductName, MessageBoxButtons.YesNo) == DialogResult.Yes)
  1674. {
  1675. Button btn = (Button)sender;
  1676. string id = btn.Tag.ToString();
  1677. _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[id];
  1678. FireDesk_Receiver.mdi.Visible = true;
  1679. // cyim 2015.8.18 수신기복구 기능 추가
  1680. // 해당 수신기의 화면으로 자동으로 들어가서 수신기 복구 팝업창을 확인하고 나올수 있도록 수정한다
  1681. FireDesk_Receiver.mdi.FireReset_Process();
  1682. FireDesk_Receiver.mdi.socketUI.ReceiverDemonReset();
  1683. }
  1684. }
  1685. // 주음향정지
  1686. private void button_MainSoundStop_Click(object sender, EventArgs e)
  1687. {
  1688. if (MessageBox.Show("모든 수신기에 주음향정지 명령을 수행하시겠습니까?", Application.ProductName, MessageBoxButtons.YesNo) == DialogResult.Yes)
  1689. {
  1690. foreach (string id in _Data.Hash_Receiver_keys)
  1691. {
  1692. _FireDesk_Receiver FireDesk_Receiver = (_FireDesk_Receiver)_Data.Hash_Receiver[id];
  1693. FireDesk_Receiver.mdi.ShowControlWrite(true, 0); // cyim 2015.8.18 주경종정지 기능 추가
  1694. }
  1695. }
  1696. }
  1697. // 연동상태조회
  1698. private void button_SearchControl_Click(object sender, EventArgs e)
  1699. {
  1700. if (_Data.FireDesk_Operation_Enable == false) // cyim 2015.8.3 수신반 연동기능 추가
  1701. {
  1702. FireDesk_Operation Operation = new FireDesk_Operation();
  1703. Operation.Show();
  1704. }
  1705. }
  1706. // 과거내역통합조회
  1707. private void button_SearchHistory_Click(object sender, EventArgs e)
  1708. {
  1709. if (_Data.FireDesk_FormLogView_Enable == false)
  1710. {
  1711. FireDesk_FormLogView FormLogView = new FireDesk_FormLogView(this);
  1712. FormLogView.Show();
  1713. }
  1714. }
  1715. //
  1716. // cyim 2015.9.11 : 과거내역 통합조회창에서 사용할 DB 에서 미리 읽은값을 사용하도록 수정함
  1717. // DB 에서 보드, 중계기, 디바이스 정보를 가져온다
  1718. //
  1719. // 보드
  1720. //DataTable dtBoardList = null;
  1721. public void GetBoardDB()
  1722. {
  1723. DacBoardConfig dacBoardConfig = new DacBoardConfig(0); // cyim 2015.7.30 데이타베이스 접속 루틴 변경
  1724. _Data.dtBoardList = dacBoardConfig.SelectBoard(0);
  1725. }
  1726. // 중계기
  1727. //DataTable dtRepeaterList2 = null;
  1728. public void GetRepeaterDB()
  1729. {
  1730. DacRepeaterConfig dacRepeaterConfig = new DacRepeaterConfig(0); // cyim 2015.7.30 데이타베이스 접속 루틴 변경
  1731. _Data.dtRepeaterList2 = dacRepeaterConfig.SelectRepeater2(0);
  1732. }
  1733. // 아날로그감지기 레벨
  1734. //DataTable dtAnalogDetecterLevel = null;
  1735. public void GetAnalogDetecterLevelDB()
  1736. {
  1737. DacRepeaterConfig dacRepeaterConfig = new DacRepeaterConfig(0); // cyim 2015.7.30 데이타베이스 접속 루틴 변경
  1738. _Data.dtAnalogDetecterLevel = dacRepeaterConfig.SelectRepeater_AnalogDetecterLevel(0);
  1739. }
  1740. // 디바이스
  1741. //DataTable dtDeviceDBList2 = null;
  1742. public void GetDeviceDB()
  1743. {
  1744. DacDeviceConfig dacDeviceConfig = new DacDeviceConfig(0); // cyim 2015.7.30 데이타베이스 접속 루틴 변경
  1745. _Data.dtDeviceDBList2 = dacDeviceConfig.SelectDevice2(0);
  1746. }
  1747. // cyim 2015.7.1 속도개선작업
  1748. // 데이타베이스 파일을 미리 읽도록 하되, DataTable 에 한해서 Foreach -> Select 으로 대체
  1749. // DataTable 에서 정보를 가져온다
  1750. // 중계기 이름을 얻어온다.
  1751. public string GetDeviceName(int BOARD_ID, int LOOP_NO, int REPEATER_ID)
  1752. {
  1753. string ret = "";
  1754. if (_Data.dtRepeaterList2 != null)
  1755. {
  1756. // cyim 2015.7.1 속도개선작업
  1757. DataRow[] result = _Data.dtRepeaterList2.Select(
  1758. string.Format("BOARD_ID={0} AND LOOP_NO={1} AND REPEATER_ID={2}", BOARD_ID, LOOP_NO, REPEATER_ID));
  1759. if (result != null && result.Length > 0)
  1760. ret = result[0]["REPEATER_NAME"].ToString();
  1761. }
  1762. return ret;
  1763. }
  1764. // 보드명을 가져온다
  1765. public string GetDeviceName(int BOARD_ID, int CommID)
  1766. {
  1767. string ret = "";
  1768. if (_Data.dtBoardList != null)
  1769. {
  1770. // cyim 2015.7.1 속도개선작업
  1771. DataRow[] result = _Data.dtBoardList.Select(
  1772. string.Format("BOARD_ID={0} AND COMM_ID={1}", BOARD_ID, CommID));
  1773. if (result != null && result.Length > 0)
  1774. ret = result[0]["BOARD_NAME"].ToString();
  1775. }
  1776. return ret;
  1777. }
  1778. // 회로명을 가져온다
  1779. public string GetDeviceName(int BOARD_ID, int LOOP_NO, int REPEATER_ID, int DEVICE_ID, String INOUT_TYPE)
  1780. {
  1781. string ret = "";
  1782. if (_Data.dtDeviceDBList2 != null)
  1783. {
  1784. // cyim 2015.7.1 속도개선작업
  1785. DataRow[] result = _Data.dtDeviceDBList2.Select(
  1786. 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 타입의 경우 ' ' 작은따옴표를 사용해야함, 이벤트로그가 안보이게됨
  1787. BOARD_ID, 1, LOOP_NO, REPEATER_ID, DEVICE_ID, INOUT_TYPE));
  1788. if (result != null && result.Length > 0)
  1789. ret = result[0]["DEVICE_NAME"].ToString();
  1790. }
  1791. return ret;
  1792. }
  1793. // 조건에 맞는 중계기의 위치명 / 위치 코드 / 중계기 명칭을 리턴한다.
  1794. public string GetDevicePositionName(int BOARD_ID, int LOOP_NO, int REPEATER_ID)
  1795. {
  1796. string ret = "";
  1797. if (_Data.dtRepeaterList2 != null)
  1798. {
  1799. // cyim 2015.7.1 속도개선작업
  1800. DataRow[] result = _Data.dtRepeaterList2.Select(
  1801. string.Format("BOARD_ID={0} AND LOOP_NO={2} AND REPEATER_ID={3}",
  1802. BOARD_ID, 1, LOOP_NO, REPEATER_ID));
  1803. if (result != null && result.Length > 0)
  1804. {
  1805. // 만약 위치 명이 있으면, 위치명으로 리턴한다.
  1806. if (result[0]["POSITION_NAME"].ToString() != "")
  1807. ret = result[0]["POSITION_NAME"].ToString();
  1808. // 위치명이 없고.. 위치 코드가 있으면, 위치 코드를 리턴하도록 한다.
  1809. else if (result[0]["POSITION_CODE"].ToString() != "")
  1810. ret = result[0]["POSITION_CODE"].ToString();
  1811. // 기본값 RepeaterName을 리턴할 준비를 한다.
  1812. else
  1813. ret = result[0]["REPEATER_NAME"].ToString();
  1814. }
  1815. }
  1816. return ret;
  1817. }
  1818. // 디바이스 위치를 리턴한다. 만약 맞는 위치명이 없으면.. 위치 코드라도 리턴한다.
  1819. public string GetDevicePositionName(int BOARD_ID, int LOOP_NO, int REPEATER_ID, int DEVICE_ID, String INOUT_TYPE)
  1820. {
  1821. string ret = "";
  1822. if (_Data.dtDeviceDBList2 != null)
  1823. {
  1824. // cyim 2015.7.1 속도개선작업
  1825. 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 타입의 경우 ' ' 작은따옴표를 사용해야함, 이벤트로그가 안보이게됨
  1826. BOARD_ID, 1, LOOP_NO, REPEATER_ID, DEVICE_ID, INOUT_TYPE);
  1827. DataRow[] result = _Data.dtDeviceDBList2.Select(SQL);
  1828. if (result != null && result.Length > 0)
  1829. {
  1830. // 만약 위치 명이 있으면, 위치명으로 리턴한다.
  1831. if (result[0]["POSITION_NAME"].ToString() != "")
  1832. ret = result[0]["POSITION_NAME"].ToString();
  1833. // 위치명이 없고.. 위치 코드가 있으면, 위치 코드를 리턴하도록 한다.
  1834. else if (result[0]["POSITION_CODE"].ToString() != "")
  1835. ret = result[0]["POSITION_CODE"].ToString();
  1836. // 기본값 Device Name을 리턴할 준비를 한다.
  1837. else
  1838. ret = result[0]["DEVICE_NAME"].ToString();
  1839. }
  1840. }
  1841. return ret;
  1842. }
  1843. // cyim 2015.7.1 속도개선작업
  1844. // 해쉬테이블을 사용해서 아날로그 감지기를 미리 저장해두어야 한다
  1845. // 아날로그감지기 아이디를 모두 가져온다 (아이디로 구성된 키를 가지고, 데이터는 레벨값 FAULT_VALUE;PREFIRE_VALUE;FIRED_VALUE;FIREN_VALUE)
  1846. public Hashtable GetAnalogDetecterRepeaterID(int RECEIVER_ID, int BOARD_ID, int LOOP_NO)
  1847. {
  1848. Hashtable ret = new Hashtable();
  1849. try
  1850. {
  1851. if (_Data.dtAnalogDetecterLevel != null)
  1852. {
  1853. DataRow[] result = _Data.dtAnalogDetecterLevel.Select(
  1854. string.Format("RECEIVER_ID={0} AND BOARD_ID={1} AND LOOP_NO={2}", RECEIVER_ID, BOARD_ID, LOOP_NO));
  1855. if (result.Length > 0)
  1856. {
  1857. foreach (DataRow Data in result)
  1858. {
  1859. string key = Data["REPEATER_ID"].ToString();
  1860. AnalogLevel data = new AnalogLevel(
  1861. Int32.Parse(Data["FAULT_VALUE"].ToString()),
  1862. Int32.Parse(Data["PREFIRE_VALUE"].ToString()),
  1863. Int32.Parse(Data["FIRED_VALUE"].ToString()),
  1864. Int32.Parse(Data["FIREN_VALUE"].ToString()));
  1865. ret.Add(key, data);
  1866. }
  1867. }
  1868. }
  1869. }
  1870. catch (Exception ex)
  1871. {
  1872. Util.UErrorMessage(ex, 0, 0);
  1873. }
  1874. return ret;
  1875. }
  1876. // cyim 2016.01.07 아날로그 감지기 이력 조회시 표시 수정 : 중계기 타입을 조회할수 있도록 한다
  1877. public string GetRepeaterType(int BOARD_ID, int LOOP_NO, int REPEATER_ID)
  1878. {
  1879. string ret = "";
  1880. if (_Data.dtRepeaterList2 != null)
  1881. {
  1882. // cyim 2015.7.1 속도개선작업
  1883. DataRow[] result = _Data.dtRepeaterList2.Select(
  1884. string.Format("BOARD_ID={0} AND LOOP_NO={2} AND REPEATER_ID={3}",
  1885. BOARD_ID, 1, LOOP_NO, REPEATER_ID));
  1886. if (result != null && result.Length > 0)
  1887. {
  1888. ret = result[0]["REPEATER_TYPE"].ToString();
  1889. }
  1890. }
  1891. return ret;
  1892. }
  1893. // cyim 2016.12.20 : 푸시메세지 연동 기능 추가 : 테스트모드
  1894. private void pictureBox_CI_Click(object sender, EventArgs e)
  1895. {
  1896. if (_Data.GCM_TEST_MODE == "ON")
  1897. {
  1898. // 데이타베이스에 등록된 모바일앱 디바이스 아이디를 조회한다
  1899. using (DacReceiverConfig push_info_select_query = new DacReceiverConfig(0))
  1900. {
  1901. DataSet ds = push_info_select_query.Select("select * from TB_PUSH_DEVICE");
  1902. DataTable dt = ds.Tables[0];
  1903. foreach (DataRow dr in dt.Rows)
  1904. {
  1905. string Regid = dr["REG_ID"].ToString();
  1906. var push = new PushBroker();
  1907. push.OnNotificationSent += NotificationSent;
  1908. push.OnChannelException += ChannelException;
  1909. push.OnServiceException += ServiceException;
  1910. push.OnNotificationFailed += NotificationFailed;
  1911. push.OnDeviceSubscriptionExpired += DeviceSubscriptionExpired;
  1912. push.OnDeviceSubscriptionChanged += DeviceSubscriptionChanged;
  1913. push.OnChannelCreated += ChannelCreated;
  1914. push.OnChannelDestroyed += ChannelDestroyed;
  1915. //txtApiKey.Text is API KEY for server applications from Google Developers Console
  1916. push.RegisterGcmService(new GcmPushChannelSettings(_Data.GCM_API_KEY));
  1917. //txtRegistrationID.Text is a value of e.regid from the onNotificationGCM function in the PushTest app
  1918. push.QueueNotification(new GcmNotification()
  1919. .ForDeviceRegistrationId(Regid)
  1920. .WithJson("{\"message\":\"" + "TEST" + "\"}"));
  1921. push.StopAllServices();
  1922. }
  1923. }
  1924. }
  1925. }
  1926. //
  1927. // cyim 2016.12.26 : UI 이탈방지 코드 추가 (후킹)
  1928. //
  1929. // Tray ===============================================================================================================
  1930. private NotifyIcon trayIcon;
  1931. private ContextMenu trayMenu;
  1932. private void GimmeTray()
  1933. {
  1934. // Create a simple tray menu with only one item.
  1935. trayMenu = new ContextMenu();
  1936. trayMenu.MenuItems.Add("Exit", OnExit);
  1937. // Create a tray icon.
  1938. trayIcon = new NotifyIcon();
  1939. trayIcon.Text = "Windows System Key Blocker";
  1940. trayIcon.Icon = new Icon(SystemIcons.Shield, 40, 40);
  1941. // Add menu to tray icon and show it.
  1942. trayIcon.ContextMenu = trayMenu;
  1943. trayIcon.Visible = true;
  1944. }
  1945. private void OnExit(object sender, EventArgs e)
  1946. {
  1947. Console.WriteLine(" ! OSK exited.");
  1948. trayIcon.Dispose();
  1949. m_KeyboardHookManager.Dispose();
  1950. Application.Exit();
  1951. ShowToolbars();
  1952. }
  1953. // Toolbars ===============================================================================================================
  1954. private const int SW_HIDE = 0;
  1955. private const int SW_SHOW = 1;
  1956. [DllImport("user32.dll")]
  1957. private static extern int FindWindow(string className, string windowText);
  1958. [DllImport("user32.dll")]
  1959. private static extern int ShowWindow(int hwnd, int command);
  1960. private void HideToolbars()
  1961. {
  1962. int hWnd = FindWindow("Shell_TrayWnd", "");
  1963. ShowWindow(hWnd, SW_HIDE);
  1964. }
  1965. private void ShowToolbars()
  1966. {
  1967. int hWnd = FindWindow("Shell_TrayWnd", "");
  1968. ShowWindow(hWnd, SW_SHOW);
  1969. }
  1970. }
  1971. }