using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Windows.Forms.DataVisualization.Charting; namespace FPER { public partial class Form_AnalogDetecter : Form { // 메인 MDIParent mdi = null; _Popup Popup = new _Popup(null); // mdi 는 널로 대체함 // 초기화 버튼을 누를때 되돌리는 값 string Current_Fault = ""; string Current_PreFire = ""; string Current_FireDay = ""; string Current_FireNight = ""; // 갱신되는 데이터 int[] Data = new int[44]; string tempReceiverID, tempCommBoard, tempLoop, tempRepeaterID; //string ReceiverID = null; // cyim 2015.8.4 수신반을 위한 static 클래스 정리 // cyim 2016.04.06 : mdi 신규창에서 windows base timer 리소스 접근 문제 public Timer t = new Timer(); public Form_AnalogDetecter(string ReceiverID, string CommBoard, string Loop, string RepeaterID, string RepeaterType, MDIParent mdiparent) { InitializeComponent(); // 라이팅에 대한 응답 _Event.AnalogDetecter_SendMessage_Event += new _Event.AnalogDetecter_SendMessage_Handler(_Event_AnalogDetecter_SendMessage); // 이벤트 핸들러 등록 this.FormClosing += new FormClosingEventHandler(Form_AnalogDetecter_FormClosing); // cyim 2015.8.4 수신반을 위한 static 클래스 정리 mdi = mdiparent; ReceiverID = mdi.MyReceiverID.ToString(); tempReceiverID = ReceiverID; tempCommBoard = CommBoard; tempLoop = Loop; tempRepeaterID = RepeaterID; // UI this.TopMost = true; this.label_AnalogDetecter_Receiver_Value.Text = ReceiverID; this.label_AnalogDetecter_CommBoard_Value.Text = CommBoard; this.label_AnalogDetecter_Loop_Value.Text = Loop; this.label_AnalogDetecter_ID_Value.Text = RepeaterID; // cyim 2016.11.23 : 아날로그 감지기 레벨값 설정 제한 if (RepeaterType == "C") { this.label_AnalogDetecter_Type_Value.Text = "연감지기"; this.label_FireDay_MinMax.Text = "(34~64)"; this.label_FireNight_MinMax.Text = "(34~64)"; } else if (RepeaterType == "D") { this.label_AnalogDetecter_Type_Value.Text = "열감지기"; this.label_FireDay_MinMax.Text = "(80~95)"; this.label_FireNight_MinMax.Text = "(80~95)"; } else this.label_AnalogDetecter_Type_Value.Text = "감지기"; this.label_Information_Current_Color.Text = "None"; this.label_Information_Current_Color.BackColor = Color.Transparent; string Day = (mdi.AnalogDetect.FireDayTime == true) ? "낮" : "밤"; this.label_Information_Current.Text = string.Format("▶ 현재상태 : {0} ({1})", "None", Day); this.label_Information_Average.Text = string.Format("▶ 평균값 : {0}", "None"); this.label_Information_Max.Text = string.Format("▶ 최대값 : {0}", "None"); this.label_Information_Min.Text = string.Format("▶ 최소값 : {0}", "None"); // 레벨값은 편집 불가 상태 (편집버튼 누른 이후에만 텍스트 박스 및 저장버튼 사용가능함) Level_Edit_Enable(false); // 그래프 속성 Chart_Setup(); // // 현재 데이타 베이스 조회하여 설정값을 가져온다 // // 해당 아날로그 디바이스의 레벨값 DacUIProcess dacUIProcess_TB_ANALOG_DEVICE = new DacUIProcess(Int32.Parse(ReceiverID));// cyim 2015.7.30 데이타베이스 접속 루틴 변경 String SQL = ""; SQL += " SELECT FAULT_VALUE,PREFIRE_VALUE,FIRED_VALUE,FIREN_VALUE"; SQL += " FROM TB_ANALOG_DEVICE_2 "; SQL += string.Format(" WHERE RECEIVER_ID='{0}' AND COMM_ID='{1}' AND BOARD_ID='{2}' AND LOOP_NO='{3}' AND REPEATER_ID='{4}'", ReceiverID, "1", CommBoard, Loop, RepeaterID); // cyim 2016.06.15 : 아날로그 감지기 출력 포인트 고려 : 레벨값은 입력포인트만 고려한다 // 출력포인트가 있을경우에는 레벨값 조회시 중계기 아이디가 중복되어 버린다 SQL += " AND INOUT_TYPE ='I' "; DataSet dao_TB_ANALOG_DEVICE = dacUIProcess_TB_ANALOG_DEVICE.Select(SQL); DataTable dt_TB_ANALOG_DEVICE = dao_TB_ANALOG_DEVICE.Tables[0]; if (dt_TB_ANALOG_DEVICE.Rows.Count != 0) { foreach (DataRow dr in dt_TB_ANALOG_DEVICE.Rows) { Current_Fault = this.textbox_Level_Fault.Text = dr["FAULT_VALUE"].ToString(); Current_PreFire = this.textbox_Level_PreFire.Text = dr["PREFIRE_VALUE"].ToString(); Current_FireDay = this.textbox_Level_FireDay.Text = dr["FIRED_VALUE"].ToString(); Current_FireNight = this.textbox_Level_FireNight.Text = dr["FIREN_VALUE"].ToString(); } } // 그래프 초기화 int[] Init_Data = new int[44]; System.Array.Clear(Init_Data, 0, 44); Trend_Update(Init_Data); // 트렌드 값 요청 Trend_Read(); // 기타 // cyim 2015.8.4 수신반을 위한 static 클래스 정리 mdi.AnalogDetect.Form_Active_AnalogDetecter = true; // // 타이머 // // 트렌드 값 갱신 //mdi.Timer_WindowBase.Create(ReceiverID + ":" + "Trend_Read_Timer", 15000, Trend_Read_Timer_Tick, true); // cyim 2015.8.4 수신반을 위한 static 클래스 정리 // cyim 2016.04.06 : mdi 신규창에서 windows base timer 리소스 접근 문제 // 아날로그 감지기 창 정보와 같이 mdi 기반에서 새롭게 생성된 창의 정보에서는 // 전역 타이머로 접근하려면 리소스 접근에 문제가 있다 (라벨 정보를 알수가 없다) // 아래와 같이 내부적으로 직접 타이머를 직접 생성하고 관리해야만 리소스에 접근이 가능하다 // 위와 같이 처리하게 되면 처음만 가동된다. t.Interval = 15000; t.Tick += new EventHandler(Trend_Read_Timer_Tick); t.Enabled = true; } // 폼이 종료 private void Form_AnalogDetecter_FormClosing(object sender, FormClosingEventArgs e) { // cyim 2015.8.4 수신반을 위한 static 클래스 정리 mdi.AnalogDetect.Form_Active_AnalogDetecter = false; // cyim 2016.04.06 : mdi 신규창에서 windows base timer 리소스 접근 문제 //mdi.Timer_WindowBase.Delete(ReceiverID + ":" + "Trend_Read_Timer"); // 라이팅에 대한 응답 _Event.AnalogDetecter_SendMessage_Event -= new _Event.AnalogDetecter_SendMessage_Handler(_Event_AnalogDetecter_SendMessage); } public void _Event_AnalogDetecter_SendMessage(CmdInfo cmd) { Level_Write_Complete(cmd); } // // UI // // 레벨값은 편집 가능 상태 private void Level_Edit_Enable(bool Enable) { this.button_Level_Save.Enabled = Enable; this.textbox_Level_Fault.Enabled = Enable; this.textbox_Level_PreFire.Enabled = Enable; this.textbox_Level_FireDay.Enabled = Enable; this.textbox_Level_FireNight.Enabled = Enable; } // 그래프 속성 셋팅 private void Chart_Setup() { // 축 최대값 this.chart_trend.ChartAreas[0].AxisY.Maximum = 140; this.chart_trend.ChartAreas[0].AxisX.Maximum = 44; // this.chart_trend.Series[0].ChartType = SeriesChartType.Column; this.chart_trend.Series[0].BorderWidth = 3; this.chart_trend.Series[0].XValueType = ChartValueType.Int32; this.chart_trend.Series[0].IsXValueIndexed = false; } // 챠트에 트렌드 데이타를 적용한다 private void Trend_Update(int[] Data) { this.chart_trend.Series[0].Points.Clear(); // 데이타는 총 44개이다 // 시간별 : 24 // 10분별 : 6 // 1분별 : 10 // 15초별 : 4 for (int i = 0; i < 44; i++) { DataPoint Point = new DataPoint(i, Data[43 - i]); this.chart_trend.Series[0].Points.Add(Point); } } // 정보창을 업데이트 한다 private void Information_Update() { string Day = (mdi.AnalogDetect.FireDayTime == true) ? "낮" : "밤"; // cyim 2015.8.4 수신반을 위한 static 클래스 정리 this.label_Information_Current.Text = string.Format("▶ 현재상태 : {0} ({1})", Data[0], Day); this.label_Information_Average.Text = string.Format("▶ 평균값 : {0}", Get_AverageValue(Data)); this.label_Information_Max.Text = string.Format("▶ 최대값 : {0}", Get_MaxValue(Data)); this.label_Information_Min.Text = string.Format("▶ 최소값 : {0}", Get_MinValue(Data)); AnalogLevel Level = new AnalogLevel( Int32.Parse(Current_Fault), Int32.Parse(Current_PreFire), Int32.Parse(Current_FireDay), Int32.Parse(Current_FireNight)); // 레벨에 따라 변경 (Normal : 0, Fault :1, PreFire : 2, Fire : 3) switch (mdi.AnalogDetect.Get_LevelStatus(Data[0], Level)) // cyim 2015.8.4 수신반을 위한 static 클래스 정리 { case 0: this.label_Information_Current_Color.Text = "Normal"; this.label_Information_Current_Color.BackColor = Color.Lime; break; case 1: this.label_Information_Current_Color.Text = "Fault"; this.label_Information_Current_Color.BackColor = Color.Silver; break; case 2: this.label_Information_Current_Color.Text = "PreFire"; this.label_Information_Current_Color.BackColor = Color.HotPink; break; case 3: this.label_Information_Current_Color.Text = "Fire"; this.label_Information_Current_Color.BackColor = Color.Red; break; } } // 최대값 구하기 private int Get_MaxValue(int[] Data) { int result = 0; for (int i = 0; i < 44; i++) if (result < Data[i]) result = Data[i]; return result; } // 최소값 구하기 private int Get_MinValue(int[] Data) { int result = 127; for (int i = 0; i < 44; i++) if (result > Data[i]) result = Data[i]; return result; } // 평균값 구하기 private int Get_AverageValue(int[] Data) { // 24시간 데이터만 수집 // // 그래프 : 참고로 24시간 데이터 인덱스는 20~43 까지이다 //int[] Data = new int[44]{ // // 시간별 : 24 // 10,10,10,10,10,10,10,10,10,10,10,10, // 10,10,10,10,10,10,10,10,10,10,10,10, // // 10분별 : 6 // 10,10,10,10,10,10, // // 1분별 : 10 // 10,10,10,10,10,10,10,10,10,10, // // 15초별 : 4 // 10,10,10,10 // }; int result = 0; for (int i = 20; i < 44; i++) result = result + Data[i]; return result / 24; } // // 이벤트 // // 레벨 편집 private void button_Level_Edit_Click(object sender, EventArgs e) { // 저장버튼은 사용 Level_Edit_Enable(true); } // 레벨 초기화 (처음 설정된 값으로) private void button_Level_Init_Click(object sender, EventArgs e) { // UI this.textbox_Level_Fault.Text = Current_Fault; this.textbox_Level_PreFire.Text = Current_PreFire; this.textbox_Level_FireDay.Text = Current_FireDay; this.textbox_Level_FireNight.Text = Current_FireNight; // 편집불가 Level_Edit_Enable(false); } // 레벨 저장 private void button_Level_Save_Click(object sender, EventArgs e) { try { // 잘못된 값을 내리면 안된다. int falut = Int32.Parse(this.textbox_Level_Fault.Text.Trim()); int prefire = Int32.Parse(this.textbox_Level_PreFire.Text.Trim()); int fireday = Int32.Parse(this.textbox_Level_FireDay.Text.Trim()); int firenight = Int32.Parse(this.textbox_Level_FireNight.Text.Trim()); // Falut 값은 반드시 양수여야 한다 if (falut < 0) MessageBox.Show("Falut 값은 반드시 양수여야 한다"); else if (prefire <= falut) MessageBox.Show("PreFire 값은 반드시 Falut값보다 커야 한다"); else if (fireday <= prefire || firenight <= prefire) MessageBox.Show("Fire Day 및 Fire Night 값은 PreFire 값보다 커야 한다"); // cyim 2016.11.23 : 아날로그 감지기 레벨값 설정 제한 else if (this.label_AnalogDetecter_Type_Value.Text == "열감지기" && (fireday < 80 || fireday > 95)) MessageBox.Show("Fire Day 레벨 값은 80 ~ 95 사이 값이어야 한다"); else if (this.label_AnalogDetecter_Type_Value.Text == "열감지기" && (firenight < 80 || firenight > 95)) MessageBox.Show("Fire Night 레벨 값은 80 ~ 95 사이 값이어야 한다"); else if (this.label_AnalogDetecter_Type_Value.Text == "연감지기" && (fireday < 34 || fireday > 64)) MessageBox.Show("Fire Day 레벨 값은 34 ~ 64 사이 값이어야 한다"); else if (this.label_AnalogDetecter_Type_Value.Text == "연감지기" && (firenight < 34 || firenight > 64)) MessageBox.Show("Fire Night 레벨 값은 34 ~ 64 사이 값이어야 한다"); else { if (MessageBox.Show("저장하시겠습니까?", "", MessageBoxButtons.OKCancel) == DialogResult.OK) { // 편집불가 Level_Edit_Enable(false); // 레벨값 쓰기 명령 Level_Write(); } } } catch (Exception ex) { Util.UErrorMessage(ex, 0, 0); MessageBox.Show("입력값은 반드시 정수타입이어야 합니다"); } } // // 타이머 // private void Trend_Read_Timer_Tick(object sender, EventArgs e) { Trend_Read(); } // // 통신부 // // 데몬에 현재 트랜드 값을 요청한다 private void Trend_Read() { try { // cyim 2016.01.07 중계기상태보기 화면에서 에러팝업출력 if (this.label_AnalogDetecter_Loop_Value.Text == null || this.label_AnalogDetecter_Loop_Value.Text.Length == 0 || this.label_AnalogDetecter_CommBoard_Value.Text == null || this.label_AnalogDetecter_CommBoard_Value.Text.Length == 0 || this.label_AnalogDetecter_ID_Value.Text == null || this.label_AnalogDetecter_ID_Value.Text.Length == 0) return; // 완료 이벤트 dCommandResponse d = new dCommandResponse(Trend_Read_Complete); // cyim 2016.12.07 : 수신기 모델별 내부 로직 변경 //if (mdi.ReceiverModel == "IFC3300") //{ // // 명령어 생성 // CmdInfo cmd = new CmdInfo( // // 0x24 // prt_cmd_define.read_analogdetecter_trend, // // 수신기 아이디 // mdi.myReceiverID, // // Comm ID // 1, // // Loop No // Int32.Parse(this.label_AnalogDetecter_Loop_Value.Text), // // Board ID // Int32.Parse(this.label_AnalogDetecter_CommBoard_Value.Text), // // Repeater ID // Int32.Parse(this.label_AnalogDetecter_ID_Value.Text), // // Event // d // ); // // 데몬에 요청 // this.mdi.ui.runCommand(cmd); //} //else //{ // cyim 2016.10.27 : 대용량 수신기 아날로그 감지기 트랜드 읽기 // 하단 주석은 삭제 금지 // 명령어 생성 CmdInfo cmd = new CmdInfo( // 0x76 prt_cmd_define.read_command_status, // 수신기 아이디 mdi.myReceiverID, // Comm ID 1, // Loop No Int32.Parse(this.label_AnalogDetecter_Loop_Value.Text), // Board ID Int32.Parse(this.label_AnalogDetecter_CommBoard_Value.Text), // Repeater ID Int32.Parse(this.label_AnalogDetecter_ID_Value.Text), // Event d ); // 감지기트렌드 읽기 명령 cmd.CommandType = "TR"; // 데몬에 요청 this.mdi.ui.runCommand(cmd); //} } catch (Exception ex) { Util.UErrorMessage(ex, 0, 0); } } public void Trend_Read_Complete(CmdInfo cmd) { try { // 오류는 처리안함 if (cmd.ErrResponse == true) return; int BoardID = Int32.Parse(this.label_AnalogDetecter_CommBoard_Value.Text); int Loop = Int32.Parse(this.label_AnalogDetecter_Loop_Value.Text); int RepeaterID = Int32.Parse(this.label_AnalogDetecter_ID_Value.Text); if (BoardID == cmd.boardNo && cmd.loopNo == Loop && RepeaterID == cmd.repeaterNo && cmd.ResCommand == prt_res_define.read_command_status) { RCVData_ReadCommandStatus ResponseData = (RCVData_ReadCommandStatus)cmd.ResponseData; // 트렌드 값 반영 for (int i = 0; i < 44; i++) Data[i] = ResponseData.AnalogDetecterTrend[i]; Trend_Update(Data); Information_Update(); } } catch (Exception ex) { Util.UErrorMessage(ex, 0, 0); } } // 아날로그 감지기 레벨값 쓰기 명령 private void Level_Write() { try { // 완료 이벤트 CmdInfo cmd; if (mdi.ReceiverModel == "IFC3300") {// 0x22, 3300 // 명령어 생성 RepeaterDataAll RepaterDataAll = new RepeaterDataAll(); cmd = new CmdInfo( // 0x22 prt_cmd_define.write_analogdetecter_level_all, // 수신기 아이디 mdi.myReceiverID, // Comm ID 1, // Loop No Int32.Parse(this.label_AnalogDetecter_Loop_Value.Text), // Board ID Int32.Parse(this.label_AnalogDetecter_CommBoard_Value.Text), // Repeater ID //Int32.Parse(this.label_AnalogDetecter_ID_Value.Text), // Event null ); //cmd.dEvent = deleg; // 레벨값 int iRepeaterID = Int32.Parse(this.label_AnalogDetecter_ID_Value.Text); RepaterDataAll.Data[iRepeaterID - 1].Set_Level_AnalogDetecter( Convert.ToByte(this.textbox_Level_Fault.Text.Trim()), Convert.ToByte(this.textbox_Level_PreFire.Text.Trim()), Convert.ToByte(this.textbox_Level_FireNight.Text.Trim()), Convert.ToByte(this.textbox_Level_FireDay.Text.Trim()) ); cmd.CommandData = RepaterDataAll; } else // 0x78, 3000 { // 명령어 생성 cmd = new CmdInfo( // 0x78 prt_cmd_define.write_analogdetecter_level, // 수신기 아이디 mdi.myReceiverID, // Comm ID 1, // Loop No Int32.Parse(this.label_AnalogDetecter_Loop_Value.Text), // Board ID Int32.Parse(this.label_AnalogDetecter_CommBoard_Value.Text), // Repeater ID Int32.Parse(this.label_AnalogDetecter_ID_Value.Text), // Event null ); cmd.AnalogDetecterFault = Convert.ToByte(this.textbox_Level_Fault.Text.Trim()); cmd.AnalogDetecterPreFire = Convert.ToByte(this.textbox_Level_PreFire.Text.Trim()); cmd.AnalogDetecterFireNight = Convert.ToByte(this.textbox_Level_FireNight.Text.Trim()); cmd.AnalogDetecterFireDay = Convert.ToByte(this.textbox_Level_FireDay.Text.Trim()); } Popup.CommonPopupShow(this); // 데몬에 요청 this.mdi.ui.runCommand(cmd); } catch (Exception ex) { Util.UErrorMessage(ex, 0, 0); } } // 크로스 스레드 해결 delegate void CallBack_Cross(CmdInfo cmd); private void Delegate_Cross(CmdInfo cmd) { if (this.InvokeRequired) { CallBack_Cross d = new CallBack_Cross(Delegate_Cross); this.Invoke(d, new object[] { cmd }); } else { try { // 오류는 처리안함 if (cmd.ErrResponse == true) return; int BoardID = Int32.Parse(this.label_AnalogDetecter_CommBoard_Value.Text); int Loop = Int32.Parse(this.label_AnalogDetecter_Loop_Value.Text); int RepeaterID = Int32.Parse(this.label_AnalogDetecter_ID_Value.Text); if (mdi.ReceiverModel == "IFC3300") { if (BoardID == cmd.boardNo && cmd.loopNo == Loop && cmd.ResCommand == prt_res_define.write_analogdetecter_level_all)//A2 {//RepeaterID == cmd.repeaterNo RCVData_WriteAnalogDetecterLevel2 ResponseData = (RCVData_WriteAnalogDetecterLevel2)cmd.ResponseData; Current_Fault = Convert.ToInt32(ResponseData.Fault).ToString(); Current_PreFire = Convert.ToInt32(ResponseData.PreFire).ToString(); Current_FireNight = Convert.ToInt32(ResponseData.FireNight).ToString(); Current_FireDay = Convert.ToInt32(ResponseData.FireDay).ToString(); // 해쉬테이블을 갱신해야됨 mdi.GetAnalogDetecterLevelDB(); // cyim 2015.7.6 레벨값 갱신 이벤트 추가 : 중계기 상태보기 화면에 레벨값 갱신을 통보해야 한다 mdi.Event.AnalogLevel_Update_SendMessage_Write(mdi); // cyim 2015.8.4 수신반을 위한 static 클래스 정리 // 정보창 갱신 (중계기상태보기 화면보다 갱신이 늦을수 있다 Information_Update(); Popup.CommonPopupClose(this); // UI 에는 이미 반영되어있음 MessageBox.Show("설정되었습니다"); } } else { if (BoardID == cmd.boardNo && cmd.loopNo == Loop && RepeaterID == cmd.repeaterNo && cmd.ResCommand == prt_res_define.write_analogdetecter_level)//F8 { //request_init = false; Current_Fault = Convert.ToInt32(cmd.AnalogDetecterFault).ToString(); Current_PreFire = Convert.ToInt32(cmd.AnalogDetecterPreFire).ToString(); Current_FireNight = Convert.ToInt32(cmd.AnalogDetecterFireNight).ToString(); Current_FireDay = Convert.ToInt32(cmd.AnalogDetecterFireDay).ToString(); // 해쉬테이블을 갱신해야됨 mdi.GetAnalogDetecterLevelDB(); // cyim 2015.7.6 레벨값 갱신 이벤트 추가 : 중계기 상태보기 화면에 레벨값 갱신을 통보해야 한다 mdi.Event.AnalogLevel_Update_SendMessage_Write(mdi); // cyim 2015.8.4 수신반을 위한 static 클래스 정리 // 정보창 갱신 (중계기상태보기 화면보다 갱신이 늦을수 있다 Information_Update(); Popup.CommonPopupClose(this); // UI 에는 이미 반영되어있음 MessageBox.Show("설정되었습니다"); } } } catch (Exception ex) { Util.UErrorMessage(ex, 0, 0); } } } public void Level_Write_Complete(CmdInfo cmd) { Delegate_Cross(cmd); } } }