diff --git a/cVMS.NET_CS/HMI/MainDisplay/DispCtrl.cs b/cVMS.NET_CS/HMI/MainDisplay/DispCtrl.cs index 5b24dd1..ab98b4d 100644 --- a/cVMS.NET_CS/HMI/MainDisplay/DispCtrl.cs +++ b/cVMS.NET_CS/HMI/MainDisplay/DispCtrl.cs @@ -13,6 +13,7 @@ using System.Diagnostics; using vmsnet.Attributes; using vmsnet.Configures; using AR; +using ScottPlot.TickGenerators.TimeUnits; namespace vmsnet.HMI { @@ -545,225 +546,292 @@ namespace vmsnet.HMI /// private void DrawCellMatrix(Graphics g, RectangleF srcrect, CGROUP grp, short cidx, Boolean isprint) { - Single height = (Single)srcrect.Height / grp.RowCount; //지정한 갯수를 나눈다. - Single newx = srcrect.Left; - - for (short j = 0; j < grp.RowCount; j++) + try { - int idx = cidx * grp.RowCount + j; - Single newy = j * height; + Single height = (Single)srcrect.Height / grp.RowCount; //지정한 갯수를 나눈다. + Single newx = srcrect.Left; - RectangleF R = - new RectangleF(newx + 1, newy + srcrect.Top, grp.Cell_Title_Width + grp.Cell_Value_Width + grp.Cell_Alam_Width - 1, height - 2); - - //번호와 영역을 재계산한다. - if (grp.Items.GetUpperBound(0) < idx) - Array.Resize(ref grp.itemarray, idx + 1); - - //항목초기화 - if (grp.Items[idx] == null) + for (short j = 0; j < grp.RowCount; j++) { - grp.Items[idx] = new CITEM() + int idx = cidx * grp.RowCount + j; + Single newy = j * height; + + RectangleF R = + new RectangleF(newx + 1, newy + srcrect.Top, grp.Cell_Title_Width + grp.Cell_Value_Width + grp.Cell_Alam_Width - 1, height - 2); + + //번호와 영역을 재계산한다. + if (grp.Items.GetUpperBound(0) < idx) + Array.Resize(ref grp.itemarray, idx + 1); + + //항목초기화 + if (grp.Items[idx] == null) { - 이름 = "--", - 알람형태 = COMM.EALAMTYPE.사용안함, - alamh = -999, - alaml = -999, - aalamh = -999, - aalaml = -999, - alamv = -999, - Onset = false, - //firstsave = true, - }; - } + grp.Items[idx] = new CITEM() + { + 이름 = "--", + 알람형태 = COMM.EALAMTYPE.사용안함, + alamh = -999, + alaml = -999, + aalamh = -999, + aalaml = -999, + alamv = -999, + Onset = false, + //firstsave = true, + }; + } - CITEM Item = grp.Items[idx]; + CITEM Item = grp.Items[idx]; - //Single Alamh=0,AlamL=0; - switch (Item.알람형태) - { - case COMM.EALAMTYPE.그룹설정을따름: - Item.alamh = grp.HIGH; - Item.alaml = grp.LOW; - Item.aalamh = grp.UP; - Item.aalaml = grp.UP; - //Item.alamv = -999; - break; - case COMM.EALAMTYPE.사용안함: - Item.alamh = -999; - Item.alaml = -999; - Item.aalamh = -999; - Item.aalaml = -999; - Item.alamv = -999; - break; + //Single Alamh=0,AlamL=0; + switch (Item.알람형태) + { + case COMM.EALAMTYPE.그룹설정을따름: + Item.alamh = grp.HIGH; + Item.alaml = grp.LOW; + Item.aalamh = grp.UP; + Item.aalaml = grp.UP; + //Item.alamv = -999; + break; + case COMM.EALAMTYPE.사용안함: + Item.alamh = -999; + Item.alaml = -999; + Item.aalamh = -999; + Item.aalaml = -999; + Item.alamv = -999; + break; - case COMM.EALAMTYPE.개별알람자동: //원본값을 그대로 사용한다. - case COMM.EALAMTYPE.개별알람: //원본값을 그대로 사용한다. - break; - } + case COMM.EALAMTYPE.개별알람자동: //원본값을 그대로 사용한다. + case COMM.EALAMTYPE.개별알람: //원본값을 그대로 사용한다. + break; + } - Item.row = j; - Item.column = cidx; - Item.rect = R; + Item.row = j; + Item.column = cidx; + Item.rect = R; - //기본배경색상(그라디언트) - Color BackColor = Color.WhiteSmoke; - var ApplyFont_CN = this.FONT_CN;// grp.셀글꼴; - var ApplyFont_CV = this.FONT_CV; - var ApplyFont_AV = this.FONT_AV; + //기본배경색상(그라디언트) + Color BackColor = Color.WhiteSmoke; + var ApplyFont_CN = this.FONT_CN;// grp.셀글꼴; + var ApplyFont_CV = this.FONT_CV; + var ApplyFont_AV = this.FONT_AV; - if (isprint) - { - //출력상태에서는 작게 출력한다. - ApplyFont_CN = new Font(ApplyFont_CN.FontFamily, 6, FontStyle.Bold); - ApplyFont_CV = new Font(ApplyFont_CV.FontFamily, 6, FontStyle.Bold); - ApplyFont_AV = new Font(ApplyFont_AV.FontFamily, 6, FontStyle.Bold); - } + if (isprint) + { + //출력상태에서는 작게 출력한다. + ApplyFont_CN = new Font(ApplyFont_CN.FontFamily, 6, FontStyle.Bold); + ApplyFont_CV = new Font(ApplyFont_CV.FontFamily, 6, FontStyle.Bold); + ApplyFont_AV = new Font(ApplyFont_AV.FontFamily, 6, FontStyle.Bold); + } - SizeF Fontsize_CN = g.MeasureString(Item.이름, ApplyFont_CN); - Single fnewx = R.Left + grp.Cell_Title_Width / 2 - Fontsize_CN.Width / 2; - Single fnewy = R.Top + R.Height / 2 - Fontsize_CN.Height / 2; + SizeF Fontsize_CN = g.MeasureString(Item.이름, ApplyFont_CN); + Single fnewx = R.Left + grp.Cell_Title_Width / 2 - Fontsize_CN.Width / 2; + Single fnewy = R.Top + R.Height / 2 - Fontsize_CN.Height / 2; - //알람발생여부초기화 - Item._p_onalamh = Item.onalamh; //이전값기록 - Item._p_onalaml = Item.onalaml; //이전값기록 - Item.onalamh = false; //현재알람초기화 - Item.onalaml = false; //현재알람초기화 + //알람발생여부초기화 + Item._p_onalamh = Item.onalamh; //이전값기록 + Item._p_onalaml = Item.onalaml; //이전값기록 + Item.onalamh = false; //현재알람초기화 + Item.onalaml = false; //현재알람초기화 - //데이터표시 - String ValueStr = ""; - Item.CurValue = 0; - Item.CurValue1 = 0; //140829 - String TimeStr = ""; + //데이터표시 + String ValueStr = ""; + Item.CurValue = 0; + Item.CurValue1 = 0; //140829 + String TimeStr = ""; - //글자표시색상 - Color BrColor = grp.셀글꼴색상; + //글자표시색상 + Color BrColor = grp.셀글꼴색상; - //값의 저장소가 아에없다면? - //Boolean OverDATA = false; - if (this.Values == null) - { - Item.value2 = 0; - Item.CurValue = 0f; - Item.CurValue1 = 0f; - TimeStr = "Null Error"; - BrColor = Color.LightGray; - } - else - { - Single Offset = 0; //수동으로입력된 옾셋 - - if (!Item.사용) //사용여부자체를 설정한다. + //값의 저장소가 아에없다면? + //Boolean OverDATA = false; + if (this.Values == null) { Item.value2 = 0; - Item.alamv = -999; - Item.CurValue = 0f; //미설정상태라면 값을 표시하지 않는다. + Item.CurValue = 0f; Item.CurValue1 = 0f; - TimeStr = "Not USE"; - grp._unusedcount += 1; - BackColor = Color.LightGray; - BrColor = Color.Gray; + TimeStr = "Null Error"; + BrColor = Color.LightGray; } - else //정상상태이다. + else { - //Br = new SolidBrush(Color.Black); - Offset = Item.Offset; //수동으로입력된 옾셋 + Single Offset = 0; //수동으로입력된 옾셋 - var u1 = this.Values.GetUpperBound(0); - var u2 = this.Values.GetUpperBound(1); - var u3 = this.Values.GetUpperBound(2); - if (Item.idx_dev >= 0 && Item.idx_unit >= 0 && Item.idx_ch >= 0 && - Item.idx_dev <= u1 && Item.idx_unit <= u2 && Item.idx_ch <= u3) + if (!Item.사용) //사용여부자체를 설정한다. { - Item.value2 = this.Values[Item.idx_dev, Item.idx_unit, Item.idx_ch]; //측정값 - TimeStr = this.Times[Item.idx_dev, Item.idx_unit, Item.idx_ch]; //측정시간 + Item.value2 = 0; + Item.alamv = -999; + Item.CurValue = 0f; //미설정상태라면 값을 표시하지 않는다. + Item.CurValue1 = 0f; + TimeStr = "Not USE"; + grp._unusedcount += 1; + BackColor = Color.LightGray; + BrColor = Color.Gray; + } + else //정상상태이다. + { + //Br = new SolidBrush(Color.Black); + Offset = Item.Offset; //수동으로입력된 옾셋 + + var u1 = this.Values.GetUpperBound(0); + var u2 = this.Values.GetUpperBound(1); + var u3 = this.Values.GetUpperBound(2); + if (Item.idx_dev >= 0 && Item.idx_unit >= 0 && Item.idx_ch >= 0 && + Item.idx_dev <= u1 && Item.idx_unit <= u2 && Item.idx_ch <= u3) + { + Item.value2 = this.Values[Item.idx_dev, Item.idx_unit, Item.idx_ch]; //측정값 + TimeStr = this.Times[Item.idx_dev, Item.idx_unit, Item.idx_ch]; //측정시간 + } + else + { + Item.value2 = 0; + TimeStr = ""; + } + + if (!Item.활성화) grp._disccount += 1; + } + + //backgroun Color + if (Offset != 0) BrColor = Color.Blue; + + //OVER DATA + if (Item.value2 >= 32000 || Item.value2 >= 65000) + { + Item._onalamover = true; + //CurValue = (Single)(Item.value2 / (Math.Pow(10, Item.decpos))) + Offset; + + //Over aalam + if (TimeStr != "" && TimeStr != "Not USE" && Item._p_onalamover == false) + { + String alamtimes = DateTime.Parse(TimeStr).ToString("yy-MM-dd HH:mm:ss"); + OnAlamChange(Item.idx, COMM.EALAMRAISETYPE.OVER_ON, Item.알람형태, "--", Item.CurValue, Item.alamh, Item.alaml); + Item._p_onalamover = true; + } + Item.CurValue = 0f; + Item.CurValue1 = 0f; } else { - Item.value2 = 0; - TimeStr = ""; + Item._onalamover = false; + + //if(Item.value2 != 9999) + + //Over aalam + if (TimeStr != "" && TimeStr != "Not USE" && Item._p_onalamover == true) + { + String alamtimes = DateTime.Parse(TimeStr).ToString("yy-MM-dd HH:mm:ss"); + OnAlamChange(Item.idx, COMM.EALAMRAISETYPE.OVER_OFF, Item.알람형태, "--", Item.CurValue, Item.alamh, Item.alaml); + Item._p_onalamover = false; + } } - if (!Item.활성화) grp._disccount += 1; - } + //현재값 + Item.CurValue = (Single)(Item.value2 / (Math.Pow(10, Item.decpos))) + Offset; + Item.CurValue1 = Item.CurValue; //데이터분주가 들어있지않은 값이다. - //backgroun Color - if (Offset != 0) BrColor = Color.Blue; + //140828 데이터분주값입력 + if (datadiv != 0 && datadiv != 1) + Item.CurValue = (Single)(Item.CurValue / (Single)datadiv); - //OVER DATA - if (Item.value2 >= 32000 || Item.value2 >= 65000) - { - Item._onalamover = true; - //CurValue = (Single)(Item.value2 / (Math.Pow(10, Item.decpos))) + Offset; - //Over aalam - if (TimeStr != "" && TimeStr != "Not USE" && Item._p_onalamover == false) + //최대,최소,합계VOLT 누적 + if (Item.사용 && Item.활성화) { - String alamtimes = DateTime.Parse(TimeStr).ToString("yy-MM-dd HH:mm:ss"); - OnAlamChange(Item.idx, COMM.EALAMRAISETYPE.OVER_ON, Item.알람형태, "--", Item.CurValue, Item.alamh, Item.alaml); - Item._p_onalamover = true; + if (Item.CurValue >= grp.Maxvolt) + { + grp._maxvolt = Item.CurValue; + grp._maxitem = Item; + + } + if (Item.CurValue <= grp.Minvolt) + { + grp._minvolt = Item.CurValue; + grp._minitem = Item; + } + grp._sumvolt += Item.CurValue1; //분주되기전의 sum값 140829 + grp._sumvolt1 += Item.CurValue; //분주된후의 sum값 140829 } - Item.CurValue = 0f; - Item.CurValue1 = 0f; - } - else - { - Item._onalamover = false; - - //if(Item.value2 != 9999) - - //Over aalam - if (TimeStr != "" && TimeStr != "Not USE" && Item._p_onalamover == true) - { - String alamtimes = DateTime.Parse(TimeStr).ToString("yy-MM-dd HH:mm:ss"); - OnAlamChange(Item.idx, COMM.EALAMRAISETYPE.OVER_OFF, Item.알람형태, "--", Item.CurValue, Item.alamh, Item.alaml); - Item._p_onalamover = false; + else + { /* 작성자: 이재웅, 작성일: 2024-10-11, 작성내용: 'Item.활성화' 되지 않아서 그룹 타이틀의 'grp.Maxvolt' 및 'grp.Minvolt' 표기 오류 정정 */ + grp._maxvolt = grp._minvolt = 0; } - } - //현재값 - Item.CurValue = (Single)(Item.value2 / (Math.Pow(10, Item.decpos))) + Offset; - Item.CurValue1 = Item.CurValue; //데이터분주가 들어있지않은 값이다. - - //140828 데이터분주값입력 - if (datadiv != 0 && datadiv != 1) - Item.CurValue = (Single)(Item.CurValue / (Single)datadiv); - - - //최대,최소,합계VOLT 누적 - if (Item.사용 && Item.활성화) - { - if (Item.CurValue >= grp.Maxvolt) + //알람활성화여부(오버데이터는 알람설정하지 않는다) + if (!Item._onalamover && Item.알람형태 != COMM.EALAMTYPE.사용안함 && Item.사용) { - grp._maxvolt = Item.CurValue; - grp._maxitem = Item; + switch (Item.알람형태) + { + case COMM.EALAMTYPE.그룹설정을따름: + if (grp.AlarmType == "AUTO") + { - } - if (Item.CurValue <= grp.Minvolt) - { - grp._minvolt = Item.CurValue; - grp._minitem = Item; - } - grp._sumvolt += Item.CurValue1; //분주되기전의 sum값 140829 - grp._sumvolt1 += Item.CurValue; //분주된후의 sum값 140829 - } - else - { /* 작성자: 이재웅, 작성일: 2024-10-11, 작성내용: 'Item.활성화' 되지 않아서 그룹 타이틀의 'grp.Maxvolt' 및 'grp.Minvolt' 표기 오류 정정 */ - grp._maxvolt = grp._minvolt = 0; - } + if (Item.alamv == -999) Item.alamv = Item.CurValue; - //알람활성화여부(오버데이터는 알람설정하지 않는다) - if (!Item._onalamover && Item.알람형태 != COMM.EALAMTYPE.사용안함 && Item.사용) - { - switch (Item.알람형태) - { - case COMM.EALAMTYPE.그룹설정을따름: - if (grp.AlarmType == "AUTO") - { + Item.적용형태 = "AUTO"; + if (Item.CurValue > Item.alamv) //큰값이 있을경우 상한선을 확인한다. + { + Single gap = Math.Abs(Item.CurValue - Item.alamv); + if (gap >= Math.Abs(Item.aalamh)) + { + Item.onalamh = true; + Item.onalaml = false; + BackColor = Color.Orange; //BackColor0 = Color.LightPink; + } + } + else if (Item.CurValue < Item.alamv) + { + Single gap = Math.Abs(Item.CurValue - Item.alamv); + if (gap >= Math.Abs(Item.aalaml)) + { + Item.onalamh = false; + Item.onalaml = true; + BackColor = Color.SkyBlue; //BackColor0 = Color.LightBlue; + } + } + } + else if (grp.AlarmType == "MANUAL") + { + Item.적용형태 = "MANUAL"; + if (Item.CurValue >= Item.alamh) + { + Item.onalamh = true; + Item.onalaml = false; + BackColor = Color.Orange;// BackColor0 = Color.LightPink; + } + else if (Item.CurValue < Item.alaml) + { + Item.onalamh = false; + Item.onalaml = true; + BackColor = Color.SkyBlue; //BackColor0 = Color.LightBlue; + } + } + else + { + Item.적용형태 = "STOP"; + Item.onalamh = false; + Item.onalaml = false; + } + break; + case COMM.EALAMTYPE.개별알람: + Item.적용형태 = "MANUAL"; + if (Item.CurValue >= Item.alamh) + { + Item.onalamh = true; + Item.onalaml = false; + BackColor = Color.Orange; //BackColor0 = Color.LightPink; + } + else if (Item.CurValue < Item.alaml) + { + Item.onalamh = false; + Item.onalaml = true; + BackColor = Color.SkyBlue;// BackColor0 = Color.LightBlue; + } + + break; + case COMM.EALAMTYPE.개별알람자동: + Item.적용형태 = "AUTO"; if (Item.alamv == -999) Item.alamv = Item.CurValue; - Item.적용형태 = "AUTO"; if (Item.CurValue > Item.alamv) //큰값이 있을경우 상한선을 확인한다. { Single gap = Math.Abs(Item.CurValue - Item.alamv); @@ -784,293 +852,252 @@ namespace vmsnet.HMI BackColor = Color.SkyBlue; //BackColor0 = Color.LightBlue; } } + break; + } + } + //CurValue = (Single)Math.Round(CurValue, 3); + } - } - else if (grp.AlarmType == "MANUAL") - { - Item.적용형태 = "MANUAL"; - if (Item.CurValue >= Item.alamh) - { - Item.onalamh = true; - Item.onalaml = false; - BackColor = Color.Orange;// BackColor0 = Color.LightPink; - } - else if (Item.CurValue < Item.alaml) - { - Item.onalamh = false; - Item.onalaml = true; - BackColor = Color.SkyBlue; //BackColor0 = Color.LightBlue; - } - } - else - { - Item.적용형태 = "STOP"; - Item.onalamh = false; - Item.onalaml = false; - } - break; - case COMM.EALAMTYPE.개별알람: - Item.적용형태 = "MANUAL"; - if (Item.CurValue >= Item.alamh) - { - Item.onalamh = true; - Item.onalaml = false; - BackColor = Color.Orange; //BackColor0 = Color.LightPink; - } - else if (Item.CurValue < Item.alaml) - { - Item.onalamh = false; - Item.onalaml = true; - BackColor = Color.SkyBlue;// BackColor0 = Color.LightBlue; - } - break; - case COMM.EALAMTYPE.개별알람자동: - Item.적용형태 = "AUTO"; - if (Item.alamv == -999) Item.alamv = Item.CurValue; + if (Item.활성화 && init == true && (Item.onalaml != Item._p_onalaml || Item._p_onalamh != Item.onalamh)) //이전과 알람상태가 변경된경우다. + { + String alamtimes; - if (Item.CurValue > Item.alamv) //큰값이 있을경우 상한선을 확인한다. - { - Single gap = Math.Abs(Item.CurValue - Item.alamv); - if (gap >= Math.Abs(Item.aalamh)) - { - Item.onalamh = true; - Item.onalaml = false; - BackColor = Color.Orange; //BackColor0 = Color.LightPink; - } - } - else if (Item.CurValue < Item.alamv) - { - Single gap = Math.Abs(Item.CurValue - Item.alamv); - if (gap >= Math.Abs(Item.aalaml)) - { - Item.onalamh = false; - Item.onalaml = true; - BackColor = Color.SkyBlue; //BackColor0 = Color.LightBlue; - } - } - break; + if (TimeStr != "" && TimeStr != "Not USE") alamtimes = DateTime.Parse(TimeStr).ToString("yy-MM-dd HH:mm:ss"); + else alamtimes = ""; + + Single AH, AL; + if (Item.적용형태 == "AUTO") + { + AH = Item.aalamh; + AL = Item.aalaml; + } + else + { + AH = Item.alamh; + AL = Item.alaml; + } + if (Item.onalamh && !Item._p_onalamh) + { + + OnAlamChange(Item.idx, COMM.EALAMRAISETYPE.HIGH_ON, Item.알람형태, Item.적용형태, Item.CurValue, AH, AL); + Item._p_onalamh = true; + } + else if (Item.onalaml && !Item._p_onalaml) + { + OnAlamChange(Item.idx, COMM.EALAMRAISETYPE.LOW_ON, Item.알람형태, Item.적용형태, Item.CurValue, AH, AL); + Item._p_onalaml = true; + } + else if (!Item.onalamh && Item._p_onalamh) + { + OnAlamChange(Item.idx, COMM.EALAMRAISETYPE.HIGH_OFF, Item.알람형태, Item.적용형태, Item.CurValue, AH, AL); + Item._p_onalamh = false; + } + else if (!Item.onalaml && Item._p_onalaml) + { + OnAlamChange(Item.idx, COMM.EALAMRAISETYPE.LOW_OFF, Item.알람형태, Item.적용형태, Item.CurValue, AH, AL); + Item._p_onalamh = false; } } - //CurValue = (Single)Math.Round(CurValue, 3); - } - - if (Item.활성화 && init == true && (Item.onalaml != Item._p_onalaml || Item._p_onalamh != Item.onalamh)) //이전과 알람상태가 변경된경우다. - { - String alamtimes; - - if (TimeStr != "" && TimeStr != "Not USE") alamtimes = DateTime.Parse(TimeStr).ToString("yy-MM-dd HH:mm:ss"); - else alamtimes = ""; - - Single AH, AL; - if (Item.적용형태 == "AUTO") + if (!Item.활성화 && Item.사용) { - AH = Item.aalamh; - AL = Item.aalaml; + Item._onalamover = false; + Item._onalamh = false; + Item._onalaml = false; + Item._p_onalamh = false; + Item._p_onalaml = false; + Item._p_onalamover = false; + + BackColor = Color.WhiteSmoke; + //BackColor0 = Color.LightGray; + BrColor = (Color.Gray); + } + + if (Item._onalamover) + { + ValueStr = $"{Item.CurValue:0.000}"; + BrColor = (Color.DarkMagenta); + grp._errorcount += 1; + } + else if (!Item.활성화) + { + ValueStr = "--"; + } + else ValueStr = $"{Item.CurValue:0.000}"; + + //초기화전상태라면 초기화된걸로 확인시킨다. + if (!Item.Onset) Item.Onset = true; + + //Draw Cell Background + using (var br = new SolidBrush(BackColor)) + g.FillRectangle(br, R); + + //Border + using (var pen = new Pen(Color.LightGray)) + { + g.DrawLine(pen, R.Left + grp.Cell_Title_Width, R.Top, R.Left + grp.Cell_Title_Width, R.Top + R.Height); + g.DrawLine(pen, R.Left + grp.Cell_Title_Width + grp.Cell_Value_Width, R.Top, R.Left + grp.Cell_Title_Width + grp.Cell_Value_Width, R.Top + R.Height); + } + + //Cell 제목줄 표시 + if (Item.사용) + { + Color cc; + if (Item.ismin) cc = Color.DarkBlue; + else if (Item.ismax) cc = Color.Red; + else cc = BrColor; + + using (var br = new SolidBrush(cc)) + g.DrawString(Item.이름, ApplyFont_CN, br, fnewx, fnewy); + } + + Item.Value = ValueStr; + Item.mtime = TimeStr; + + + if (idx < grp._null_itemseq) + { + if (Item.사용 && Item.활성화) + { + grp._sumvoltA += Item.CurValue1; + if (Item.알람형태 != COMM.EALAMTYPE.사용안함) + { + if (NullbalanceRealValue) grp._null_valueL += Item.CurValue1; //알람이 오프된경우라면 처리하지않게한다. + else grp._null_valueL += Item.CurValue; //알람이 오프된경우라면 처리하지않게한다. + + } + } } else { - AH = Item.alamh; - AL = Item.alaml; - } - if (Item.onalamh && !Item._p_onalamh) - { - - OnAlamChange(Item.idx, COMM.EALAMRAISETYPE.HIGH_ON, Item.알람형태, Item.적용형태, Item.CurValue, AH, AL); - Item._p_onalamh = true; - } - else if (Item.onalaml && !Item._p_onalaml) - { - OnAlamChange(Item.idx, COMM.EALAMRAISETYPE.LOW_ON, Item.알람형태, Item.적용형태, Item.CurValue, AH, AL); - Item._p_onalaml = true; - } - else if (!Item.onalamh && Item._p_onalamh) - { - OnAlamChange(Item.idx, COMM.EALAMRAISETYPE.HIGH_OFF, Item.알람형태, Item.적용형태, Item.CurValue, AH, AL); - Item._p_onalamh = false; - } - else if (!Item.onalaml && Item._p_onalaml) - { - OnAlamChange(Item.idx, COMM.EALAMRAISETYPE.LOW_OFF, Item.알람형태, Item.적용형태, Item.CurValue, AH, AL); - Item._p_onalamh = false; - } - } - - if (!Item.활성화 && Item.사용) - { - Item._onalamover = false; - Item._onalamh = false; - Item._onalaml = false; - Item._p_onalamh = false; - Item._p_onalaml = false; - Item._p_onalamover = false; - - BackColor = Color.WhiteSmoke; - //BackColor0 = Color.LightGray; - BrColor = (Color.Gray); - } - - if (Item._onalamover) - { - ValueStr = $"{Item.CurValue:0.000}"; - BrColor = (Color.DarkMagenta); - grp._errorcount += 1; - } - else if (!Item.활성화) - { - ValueStr = "--"; - } - else ValueStr = $"{Item.CurValue:0.000}"; - - //초기화전상태라면 초기화된걸로 확인시킨다. - if (!Item.Onset) Item.Onset = true; - - //Draw Cell Background - using (var br = new SolidBrush(BackColor)) - g.FillRectangle(br, R); - - //Border - using (var pen = new Pen(Color.LightGray)) - { - g.DrawLine(pen, R.Left + grp.Cell_Title_Width, R.Top, R.Left + grp.Cell_Title_Width, R.Top + R.Height); - g.DrawLine(pen, R.Left + grp.Cell_Title_Width + grp.Cell_Value_Width, R.Top, R.Left + grp.Cell_Title_Width + grp.Cell_Value_Width, R.Top + R.Height); - } - - //Cell 제목줄 표시 - if (Item.사용) - { - Color cc; - if (Item.ismin) cc = Color.DarkBlue; - else if (Item.ismax) cc = Color.Red; - else cc = BrColor; - - using (var br = new SolidBrush(cc)) - g.DrawString(Item.이름, ApplyFont_CN, br, fnewx, fnewy); - } - - Item.Value = ValueStr; - Item.mtime = TimeStr; - - - if (idx < grp._null_itemseq) - { - if (Item.사용 && Item.활성화) - { - grp._sumvoltA += Item.CurValue1; - if (Item.알람형태 != COMM.EALAMTYPE.사용안함) + if (Item.사용 && Item.활성화) { - if (NullbalanceRealValue) grp._null_valueL += Item.CurValue1; //알람이 오프된경우라면 처리하지않게한다. - else grp._null_valueL += Item.CurValue; //알람이 오프된경우라면 처리하지않게한다. - + grp._sumvoltB += Item.CurValue1; + if (Item.알람형태 != COMM.EALAMTYPE.사용안함) + { + if (NullbalanceRealValue) grp._null_valueR += Item.CurValue1; + else grp._null_valueR += Item.CurValue; + } } } - } - else - { - if (Item.사용 && Item.활성화) + + Fontsize_CN = g.MeasureString(ValueStr, ApplyFont_CV); + fnewx = R.Left + grp.Cell_Title_Width + grp.Cell_Value_Width / 2 - Fontsize_CN.Width / 2; + fnewy = R.Top + R.Height / 2 - Fontsize_CN.Height / 2; + + if (this.WINDOW.Debug) + ValueStr += cidx.ToString(); + + //display value + if (Item.사용) { - grp._sumvoltB += Item.CurValue1; - if (Item.알람형태 != COMM.EALAMTYPE.사용안함) - { - if (NullbalanceRealValue) grp._null_valueR += Item.CurValue1; - else grp._null_valueR += Item.CurValue; - } + using (var Br = new SolidBrush(BrColor)) + g.DrawString(ValueStr, ApplyFont_CV, Br, fnewx, fnewy); } - } - Fontsize_CN = g.MeasureString(ValueStr, ApplyFont_CV); - fnewx = R.Left + grp.Cell_Title_Width + grp.Cell_Value_Width / 2 - Fontsize_CN.Width / 2; - fnewy = R.Top + R.Height / 2 - Fontsize_CN.Height / 2; - - if (this.WINDOW.Debug) - ValueStr += cidx.ToString(); - - //display value - if (Item.사용) - { - using (var Br = new SolidBrush(BrColor)) - g.DrawString(ValueStr, ApplyFont_CV, Br, fnewx, fnewy); - } - - //display alam - String AlamstrH = ""; - String AlamstrL = ""; - switch (Item.알람형태) - { - case COMM.EALAMTYPE.사용안함: //직접사용안함 - BrColor = Color.Gray; - AlamstrH = "OFF"; - AlamstrL = "OFF"; - break; - - case COMM.EALAMTYPE.그룹설정을따름: - BrColor = Color.Black; - - if (grp.AlarmType == "AUTO") - { - AlamstrH = Item.aalamh.ToString(); - AlamstrL = Item.aalaml.ToString(); - } - else if (grp.AlarmType == "MANUAL") - { - AlamstrH = Item.alamh.ToString(); - AlamstrL = Item.alaml.ToString(); - } - else //그룹설정이 OFF된경우 - { + //display alam + String AlamstrH = ""; + String AlamstrL = ""; + switch (Item.알람형태) + { + case COMM.EALAMTYPE.사용안함: //직접사용안함 + BrColor = Color.Gray; AlamstrH = "OFF"; AlamstrL = "OFF"; + break; + + case COMM.EALAMTYPE.그룹설정을따름: + BrColor = Color.Black; + + if (grp.AlarmType == "AUTO") + { + AlamstrH = Item.aalamh.ToString(); + AlamstrL = Item.aalaml.ToString(); + } + else if (grp.AlarmType == "MANUAL") + { + AlamstrH = Item.alamh.ToString(); + AlamstrL = Item.alaml.ToString(); + } + else //그룹설정이 OFF된경우 + { + AlamstrH = "OFF"; + AlamstrL = "OFF"; + } + break; + + case COMM.EALAMTYPE.개별알람: + BrColor = (Color.Blue); + AlamstrH = "↑" + Item.alamh.ToString(); + AlamstrL = "↓" + Item.alaml.ToString(); + break; + + case COMM.EALAMTYPE.개별알람자동: + BrColor = (Color.Magenta); + AlamstrH = "+" + Item.aalamh.ToString(); + AlamstrL = "-" + Item.aalaml.ToString(); + break; + } + + Fontsize_CN = g.MeasureString(AlamstrH, ApplyFont_AV); + SizeF fontsize2 = g.MeasureString(AlamstrL, ApplyFont_AV); + + + fnewy = R.Top + R.Height / 2 - Fontsize_CN.Height / 2; + + if (Item.사용) + { + + if (Item.활성화) + { + if (Item._onalamh || Item._onalaml) grp._alamcount += 1; + } - break; - case COMM.EALAMTYPE.개별알람: - BrColor = (Color.Blue); - AlamstrH = "↑" + Item.alamh.ToString(); - AlamstrL = "↓" + Item.alaml.ToString(); - break; - - case COMM.EALAMTYPE.개별알람자동: - BrColor = (Color.Magenta); - AlamstrH = "+" + Item.aalamh.ToString(); - AlamstrL = "-" + Item.aalaml.ToString(); - break; - } - - Fontsize_CN = g.MeasureString(AlamstrH, ApplyFont_AV); - SizeF fontsize2 = g.MeasureString(AlamstrL, ApplyFont_AV); - - - fnewy = R.Top + R.Height / 2 - Fontsize_CN.Height / 2; - - if (Item.사용) - { - - if (Item.활성화) - { - if (Item._onalamh || Item._onalaml) grp._alamcount += 1; + Color SSBColor = BrColor; + if (!Item.활성화) SSBColor = Color.Gray; + using (var SSB = new SolidBrush(SSBColor)) + { + fnewx = R.Left + grp.Cell_Title_Width + grp.Cell_Value_Width + (grp.Cell_Alam_Width / 2 - Fontsize_CN.Width) / 2; + g.DrawString($"{AlamstrH}/{AlamstrL}", ApplyFont_AV, SSB, fnewx, fnewy); + } } - Color SSBColor = BrColor; - if (!Item.활성화) SSBColor = Color.Gray; + //Cell 테두리 + ////g.DrawRectangle(new Pen(Color.Gray), R.Left, R.Top, R.Width - 1, R.Height); - using (var SSB = new SolidBrush(SSBColor)) - { - fnewx = R.Left + grp.Cell_Title_Width + grp.Cell_Value_Width + (grp.Cell_Alam_Width / 2 - Fontsize_CN.Width) / 2; - g.DrawString($"{AlamstrH}/{AlamstrL}", ApplyFont_AV, SSB, fnewx, fnewy); - } + //Cell Underbar + g.DrawLine(Pens.Gray, R.Left, (R.Top + R.Height), R.Left + R.Width, (R.Top + R.Height)); + + + //버튼할당을위한 값할당 + this.Buttons.Add(new CButton(R, Item, EBUTTONTYPE.CELL)); } + } + catch (NullReferenceException ex1) + { + // 예외 메시지, 파일명, 행 번호를 로그에 기록 + var stackTrace = new System.Diagnostics.StackTrace(ex1, true); + var frame = stackTrace.GetFrame(0); + string fileName = frame.GetFileName(); + int lineNumber = frame.GetFileLineNumber(); - //Cell 테두리 - ////g.DrawRectangle(new Pen(Color.Gray), R.Left, R.Top, R.Width - 1, R.Height); - - //Cell Underbar - g.DrawLine(Pens.Gray, R.Left, (R.Top + R.Height), R.Left + R.Width, (R.Top + R.Height)); - + // UI 디스플레이 중, 예외발생 문제 + PUB.log.AddE($"NullReferenceException Message={ex1.Message}, 파일명={fileName}, 행번호={lineNumber}"); - //버튼할당을위한 값할당 - this.Buttons.Add(new CButton(R, Item, EBUTTONTYPE.CELL)); + } + catch (Exception ex2) + { + // 예외 메시지, 파일명, 행 번호를 로그에 기록 + var stackTrace = new System.Diagnostics.StackTrace(ex2, true); + var frame = stackTrace.GetFrame(0); + string fileName = frame.GetFileName(); + int lineNumber = frame.GetFileLineNumber(); + + // Else Error !!! + PUB.log.AddE($"Exception Message={ex2.Message}, 파일명={fileName}, 행번호={lineNumber}"); } } @@ -1085,516 +1112,541 @@ namespace vmsnet.HMI grp._minitem = null; grp._maxitem = null; - //그룹내의정보를 설정 - Single newx = WinRect.Left + 열번호 * ItemSize.Width; - Single newy = WinRect.Top + 줄번호 * ItemSize.Height; - grp.R = new RectangleF(newx + 4, newy + 4, ItemSize.Width * grp.열병합 - 8, ItemSize.Height * grp.줄병합 - 8); - - //그룹타이틀 - newy = grp.R.Top; - SizeF FontHeight = g.MeasureString(grp.이름, this.Font_Grouptitle); - Single newheigth = (FontHeight.Height * 4); - grp.Rect_Title = new RectangleF(grp.R.Left, newy, grp.R.Width, newheigth); - newy += newheigth; - - //전체아이템너비 - newy += 0; - newheigth = grp.R.Height + grp.R.Top - newy; - grp.Rect_body = new RectangleF(grp.R.Left, newy, grp.R.Width, newheigth); - - //각 셀그룹의 영역을 설정함 - Single LastX = 0; - int Gap = 6; - grp.CellGroup_Width = (grp.Rect_body.Width / grp.ColumnCount) - ((Gap * (grp.ColumnCount - 1) / grp.ColumnCount)); - grp.CellGroup_Height = grp.Rect_body.Height; - grp.CellGroup = new RectangleF[grp.ColumnCount]; - for (int ii = 1; ii <= grp.ColumnCount; ii++) + try { - if (ii == 1) + //그룹내의정보를 설정 + Single newx = WinRect.Left + 열번호 * ItemSize.Width; + Single newy = WinRect.Top + 줄번호 * ItemSize.Height; + grp.R = new RectangleF(newx + 4, newy + 4, ItemSize.Width * grp.열병합 - 8, ItemSize.Height * grp.줄병합 - 8); + + //그룹타이틀 + newy = grp.R.Top; + SizeF FontHeight = g.MeasureString(grp.이름, this.Font_Grouptitle); + Single newheigth = (FontHeight.Height * 4); + grp.Rect_Title = new RectangleF(grp.R.Left, newy, grp.R.Width, newheigth); + newy += newheigth; + + //전체아이템너비 + newy += 0; + newheigth = grp.R.Height + grp.R.Top - newy; + grp.Rect_body = new RectangleF(grp.R.Left, newy, grp.R.Width, newheigth); + + //각 셀그룹의 영역을 설정함 + Single LastX = 0; + int Gap = 6; + grp.CellGroup_Width = (grp.Rect_body.Width / grp.ColumnCount) - ((Gap * (grp.ColumnCount - 1) / grp.ColumnCount)); + grp.CellGroup_Height = grp.Rect_body.Height; + grp.CellGroup = new RectangleF[grp.ColumnCount]; + for (int ii = 1; ii <= grp.ColumnCount; ii++) { - //처음개체 - grp.CellGroup[ii - 1] = new RectangleF(grp.Rect_body.Left, grp.Rect_body.Top, grp.CellGroup_Width, grp.CellGroup_Height); - LastX = grp.CellGroup[ii - 1].Left + grp.CellGroup[ii - 1].Width + Gap; - } - else - { - //이후개체 - grp.CellGroup[ii - 1] = new RectangleF(LastX, grp.Rect_body.Top, grp.CellGroup_Width, grp.CellGroup_Height); - LastX += grp.CellGroup_Width + Gap; - } - } - // - RectangleF GrpRect = new RectangleF(grp.R.Left + margin.X, grp.R.Top + margin.Y, grp.R.Width, grp.R.Height); - - //그룹제목표시줄(title) - Single MaxTitleWidth = 0; - - Color GroupBackColor = Color.DarkMagenta; - if (this.WINDOW.IDX > 1) GroupBackColor = Color.DarkGreen; - - RectangleF newbackgrounrect = new RectangleF(grp.Rect_Title.Left + margin.X, - grp.Rect_Title.Top + margin.Y, - grp.Rect_Title.Width, - grp.Rect_Title.Height); - - if (IsVisible) - { - using (var lgb = new LinearGradientBrush(newbackgrounrect, Color.Black, GroupBackColor, LinearGradientMode.BackwardDiagonal)) - g.FillRectangle(lgb, newbackgrounrect); - } - - - Fontsize = g.MeasureString(grp.이름, this.font_grouptitle); - newx = grp.Rect_Title.Left + 10 + margin.X; - newy = grp.Rect_Title.Top + 7 + margin.Y;// -Fontsize.Height / 2 + grp.Rect_Title.Height / 2; - //g.DrawString(grp.이름 + this.Buttons.Count.ToString(), this.font_grouptitle, Brushes.Black, newx + 2, newy + 2); - if (IsVisible) - g.DrawString(grp.이름, this.font_grouptitle, Brushes.Yellow, newx, newy); - if (Fontsize.Width > MaxTitleWidth) MaxTitleWidth = Fontsize.Width; - - //그룹명클릭시에 그룹설정을 오픈하기위해서 버튼을 할당한다. - RectangleF GrpTITLE = new RectangleF(newx, newy, Fontsize.Width, Fontsize.Height); - if (IsVisible) this.Buttons.Add(new CButton(GrpTITLE, grp, EBUTTONTYPE.GROUP)); - //this.Buttonstag.Add(grp); - //this.Buttonstype.Add(EBUTTONTYPE.GROUP); - - //셀의 갯수를 표시 - newy += Fontsize.Height + 1f; - int usechcount = grp.Items.Length - grp._unusedcount; - - String Cellcount = "NO ITEMS"; - Cellcount = (grp.Items.Length - grp._unusedcount).ToString() + " Cell\n" + - grp._disccount.ToString() + " Disc.\n" + - (grp._errorcount).ToString() + " Over"; - - - using (Font CellCountfont = new Font(this.font_grouptitle.Name, this.font_grouptitle.Size - 5)) - { - Fontsize = g.MeasureString(Cellcount, CellCountfont); - //g.DrawString(Cellcount, CellCountfont, Brushes.Black, newx + 2, newy + 2); //shadow - if (IsVisible) g.DrawString(Cellcount, CellCountfont, Brushes.Yellow, newx, newy); - - newy += Fontsize.Height + 1.5f; - Fontsize = g.MeasureString("Print", CellCountfont); - - //프린터버튼추가 - RectangleF printbutrect = new RectangleF(newx, newy, (Single)(Fontsize.Width * 1.5), Fontsize.Height); - if (IsVisible) g.DrawString("Print", CellCountfont, Brushes.White, printbutrect.Left + (printbutrect.Width - Fontsize.Width) / 2, printbutrect.Top + (printbutrect.Height - Fontsize.Height) / 2); - if (IsVisible) g.DrawRectangle(Pens.White, new Rectangle((int)newx, (int)newy, (int)(Fontsize.Width * 1.5), (int)Fontsize.Height)); - if (IsVisible) Buttons.Add(new CButton(printbutrect, grp, EBUTTONTYPE.PRINT)); - } - - if (Fontsize.Width > MaxTitleWidth) MaxTitleWidth = Fontsize.Width; - - //그룹의정보(header) - Single HeaderWidth = (Single)(grp.Rect_Title.Width - MaxTitleWidth - 20); - Single HeaderHeigth = (Single)(grp.Rect_Title.Height * 0.8); - - //헤더정보를 표시 - newx = grp.Rect_Title.Left + margin.X + (grp.Rect_Title.Width - HeaderWidth) - 5; - newy = grp.Rect_Title.Top + margin.Y + (grp.Rect_Title.Height - HeaderHeigth) / 2; - - grp.Rect_Header = new RectangleF(newx, newy, HeaderWidth, HeaderHeigth); - //그림자//g.FillRectangle(new SolidBrush(Color.FromArgb(50,Color.Black)), grp.Rect_Header.Left+2,grp.Rect_Header.Top+2,grp.Rect_Header.Width,grp.Rect_Header.Height); - if (IsVisible) g.FillRectangle(new SolidBrush(Color.FromArgb(50, Color.Black)), grp.Rect_Header); - if (IsVisible) g.DrawRectangle(Pens.Black, grp.Rect_Header.Left, grp.Rect_Header.Top, grp.Rect_Header.Width, grp.Rect_Header.Height); - - //표시영역(body) - //셀아이템하위 그룹을 표시한다. - short gidx = 0; - grp._maxvolt = -999; - grp._minvolt = 999; - grp._avgvolt = 0; - grp._sumvolt = 0; - grp._sumvolt1 = 0; - grp._sumvoltA = 0; - grp._sumvoltB = 0; - grp._unusedcount = 0; //미사용채널수 - grp._null_valueL = 0; - grp._null_valueR = 0; - grp._errorcount = 0; - grp._disccount = 0; - grp._alamcount = 0; //알람발생셀수 - grp._alamcountlb = 0; - - foreach (RectangleF R in grp.CellGroup) - { - //해당그룹의 셀을 표시 - DrawItem(g, grp, new RectangleF(R.Left + margin.X, R.Top + margin.Y, R.Width - 1, R.Height), gidx, isprint, IsVisible); - - //border - if (IsVisible) g.DrawRectangle(Pens.DarkGray, (int)R.Left + margin.X, (int)R.Top + margin.Y, (int)R.Width - 1, (int)R.Height); - gidx += 1; - - //g.DrawString(this.window.disconnecttime.ToString(), this.Font, Brushes.Red, R.Left,R.Top); - } - - grp._amp = 0; - if (grp._ampidx != "" && grp._ampidx != null) - { - var buff = grp._ampidx.Split(new char[] { ',' }); - int di1 = int.Parse(buff[0]); - int di2 = int.Parse(buff[1]); - int di3 = int.Parse(buff[2]); - - try - { - grp._ampdecpos = 3; - grp._amp = (float)(this.Values[di1, di2, di3 - 1] / (Math.Pow(10, grp._ampdecpos))); - } - catch - { - grp._amp = -1f; - } - } - - if (usechcount == 0) grp._avgvolt = 0; - else grp._avgvolt = grp.Sumvolt1 / usechcount; - - Single nullvalue = (grp._null_valueR - grp._null_valueL) + grp.NullBalanceOffset; - String HeaderStr = $"▣ SUM : {grp.Sumvolt:#0.0}"; - if (Sumab) - { - HeaderStr += $"\n▣ SUMA : {grp._sumvoltA:#0.000}"; - HeaderStr += $"\n▣ SUMB : {grp._sumvoltB:#0.000}"; - } - HeaderStr += $"\n▣ AVG : {grp.Avgvolt:#0.000}"; - if (!Sumab) - { - HeaderStr += $"\n▣ MAX : {grp.Maxvolt:#0.000}"; - HeaderStr += $"\n▣ MIN : {grp.Minvolt:#0.000}"; - } - - //집계데이터출력 - Fontsize = g.MeasureString(HeaderStr, this.font_header); - newy = grp.Rect_Header.Top + 5; // -Fontsize.Height / 2 + grp.Rect_Header.Height / 2; - if (IsVisible) g.DrawString(HeaderStr, this.font_header, Brushes.White, grp.Rect_Header.Left + 5, newy); - - //NB데이터와의 SPLITER - newx = grp.Rect_Header.Left + 5 + Fontsize.Width + 5; - Single SpliiterY = newy; - Single SplliterH = newy + grp.Rect_Header.Height - (newy - grp.Rect_Header.Top) * 2; - if (IsVisible) g.DrawLine(Pens.Black, newx, newy, newx, SplliterH); - - //NB데이터출력 - newx += 3; - - //NB용 알람표시 - Single imgwidth = 30; - Single imgheight = 30; - if (!(grp.nbh == 0 && grp.nbl == 0)) - { - if (Math.Abs(nullvalue) > grp.nbl) - { - grp._nbalam_l = true; //a2 on - if (!grp._pre_nbalam_l) + if (ii == 1) { - if (grp.AlarmType != "STOP") OnAlamChange(grp.IDX, COMM.EALAMRAISETYPE.A2_ON, COMM.EALAMTYPE.사용안함, "NB", (Single)nullvalue, (Single)grp.nbl, (Single)grp.nbl); - grp._pre_nbalam_l = true; - A2 = false; - blink2 = 0; + //처음개체 + grp.CellGroup[ii - 1] = new RectangleF(grp.Rect_body.Left, grp.Rect_body.Top, grp.CellGroup_Width, grp.CellGroup_Height); + LastX = grp.CellGroup[ii - 1].Left + grp.CellGroup[ii - 1].Width + Gap; } - else //게속발생중이다. + else { - if (A2 == false) - { - if (blink2 >= 1) - { - A2 = true; - blink2 = 0; - } - else blink2 += 1; - } - else - { - if (blink2 >= 1) - { - A2 = false; - blink2 = 0; - } - else blink2 += 1; - } + //이후개체 + grp.CellGroup[ii - 1] = new RectangleF(LastX, grp.Rect_body.Top, grp.CellGroup_Width, grp.CellGroup_Height); + LastX += grp.CellGroup_Width + Gap; } } - else // a2영역보다는 낮으므로 a2를 해제한다. + // + RectangleF GrpRect = new RectangleF(grp.R.Left + margin.X, grp.R.Top + margin.Y, grp.R.Width, grp.R.Height); + + //그룹제목표시줄(title) + Single MaxTitleWidth = 0; + + Color GroupBackColor = Color.DarkMagenta; + if (this.WINDOW.IDX > 1) GroupBackColor = Color.DarkGreen; + + RectangleF newbackgrounrect = new RectangleF(grp.Rect_Title.Left + margin.X, + grp.Rect_Title.Top + margin.Y, + grp.Rect_Title.Width, + grp.Rect_Title.Height); + + if (IsVisible) { - grp._nbalam_l = false; //a2 off + using (var lgb = new LinearGradientBrush(newbackgrounrect, Color.Black, GroupBackColor, LinearGradientMode.BackwardDiagonal)) + g.FillRectangle(lgb, newbackgrounrect); + } - if (grp._pre_nbalam_l) //이전에 a2알람이 켜져잇엇다면 알람을 끈다. + + Fontsize = g.MeasureString(grp.이름, this.font_grouptitle); + newx = grp.Rect_Title.Left + 10 + margin.X; + newy = grp.Rect_Title.Top + 7 + margin.Y;// -Fontsize.Height / 2 + grp.Rect_Title.Height / 2; + //g.DrawString(grp.이름 + this.Buttons.Count.ToString(), this.font_grouptitle, Brushes.Black, newx + 2, newy + 2); + if (IsVisible) + g.DrawString(grp.이름, this.font_grouptitle, Brushes.Yellow, newx, newy); + if (Fontsize.Width > MaxTitleWidth) MaxTitleWidth = Fontsize.Width; + + //그룹명클릭시에 그룹설정을 오픈하기위해서 버튼을 할당한다. + RectangleF GrpTITLE = new RectangleF(newx, newy, Fontsize.Width, Fontsize.Height); + if (IsVisible) this.Buttons.Add(new CButton(GrpTITLE, grp, EBUTTONTYPE.GROUP)); + //this.Buttonstag.Add(grp); + //this.Buttonstype.Add(EBUTTONTYPE.GROUP); + + //셀의 갯수를 표시 + newy += Fontsize.Height + 1f; + int usechcount = grp.Items.Length - grp._unusedcount; + + String Cellcount = "NO ITEMS"; + Cellcount = (grp.Items.Length - grp._unusedcount).ToString() + " Cell\n" + + grp._disccount.ToString() + " Disc.\n" + + (grp._errorcount).ToString() + " Over"; + + + using (Font CellCountfont = new Font(this.font_grouptitle.Name, this.font_grouptitle.Size - 5)) + { + Fontsize = g.MeasureString(Cellcount, CellCountfont); + //g.DrawString(Cellcount, CellCountfont, Brushes.Black, newx + 2, newy + 2); //shadow + if (IsVisible) g.DrawString(Cellcount, CellCountfont, Brushes.Yellow, newx, newy); + + newy += Fontsize.Height + 1.5f; + Fontsize = g.MeasureString("Print", CellCountfont); + + //프린터버튼추가 + RectangleF printbutrect = new RectangleF(newx, newy, (Single)(Fontsize.Width * 1.5), Fontsize.Height); + if (IsVisible) g.DrawString("Print", CellCountfont, Brushes.White, printbutrect.Left + (printbutrect.Width - Fontsize.Width) / 2, printbutrect.Top + (printbutrect.Height - Fontsize.Height) / 2); + if (IsVisible) g.DrawRectangle(Pens.White, new Rectangle((int)newx, (int)newy, (int)(Fontsize.Width * 1.5), (int)Fontsize.Height)); + if (IsVisible) Buttons.Add(new CButton(printbutrect, grp, EBUTTONTYPE.PRINT)); + } + + if (Fontsize.Width > MaxTitleWidth) MaxTitleWidth = Fontsize.Width; + + //그룹의정보(header) + Single HeaderWidth = (Single)(grp.Rect_Title.Width - MaxTitleWidth - 20); + Single HeaderHeigth = (Single)(grp.Rect_Title.Height * 0.8); + + //헤더정보를 표시 + newx = grp.Rect_Title.Left + margin.X + (grp.Rect_Title.Width - HeaderWidth) - 5; + newy = grp.Rect_Title.Top + margin.Y + (grp.Rect_Title.Height - HeaderHeigth) / 2; + + grp.Rect_Header = new RectangleF(newx, newy, HeaderWidth, HeaderHeigth); + //그림자//g.FillRectangle(new SolidBrush(Color.FromArgb(50,Color.Black)), grp.Rect_Header.Left+2,grp.Rect_Header.Top+2,grp.Rect_Header.Width,grp.Rect_Header.Height); + if (IsVisible) g.FillRectangle(new SolidBrush(Color.FromArgb(50, Color.Black)), grp.Rect_Header); + if (IsVisible) g.DrawRectangle(Pens.Black, grp.Rect_Header.Left, grp.Rect_Header.Top, grp.Rect_Header.Width, grp.Rect_Header.Height); + + //표시영역(body) + //셀아이템하위 그룹을 표시한다. + short gidx = 0; + grp._maxvolt = -999; + grp._minvolt = 999; + grp._avgvolt = 0; + grp._sumvolt = 0; + grp._sumvolt1 = 0; + grp._sumvoltA = 0; + grp._sumvoltB = 0; + grp._unusedcount = 0; //미사용채널수 + grp._null_valueL = 0; + grp._null_valueR = 0; + grp._errorcount = 0; + grp._disccount = 0; + grp._alamcount = 0; //알람발생셀수 + grp._alamcountlb = 0; + + foreach (RectangleF R in grp.CellGroup) + { + //해당그룹의 셀을 표시 + DrawItem(g, grp, new RectangleF(R.Left + margin.X, R.Top + margin.Y, R.Width - 1, R.Height), gidx, isprint, IsVisible); + + //border + if (IsVisible) g.DrawRectangle(Pens.DarkGray, (int)R.Left + margin.X, (int)R.Top + margin.Y, (int)R.Width - 1, (int)R.Height); + gidx += 1; + + //g.DrawString(this.window.disconnecttime.ToString(), this.Font, Brushes.Red, R.Left,R.Top); + } + + grp._amp = 0; + if (grp._ampidx != "" && grp._ampidx != null) + { + var buff = grp._ampidx.Split(new char[] { ',' }); + int di1 = int.Parse(buff[0]); + int di2 = int.Parse(buff[1]); + int di3 = int.Parse(buff[2]); + + try { - OnAlamChange(grp.IDX, COMM.EALAMRAISETYPE.A2_OFF, COMM.EALAMTYPE.사용안함, "NB", (Single)nullvalue, (Single)grp.nbl, (Single)grp.nbl); - grp._pre_nbalam_l = false; - blink1 = 0; + grp._ampdecpos = 3; + grp._amp = (float)(this.Values[di1, di2, di3 - 1] / (Math.Pow(10, grp._ampdecpos))); } - - - if (Math.Abs(nullvalue) > grp.nbh) //a1영역보다 크다면 + catch { - grp._nbalam_h = true; - if (!grp._pre_nbalam_h) //이전에 발생안햇다면 + grp._amp = -1f; + } + } + + if (usechcount == 0) grp._avgvolt = 0; + else grp._avgvolt = grp.Sumvolt1 / usechcount; + + Single nullvalue = (grp._null_valueR - grp._null_valueL) + grp.NullBalanceOffset; + String HeaderStr = $"▣ SUM : {grp.Sumvolt:#0.0}"; + if (Sumab) + { + HeaderStr += $"\n▣ SUMA : {grp._sumvoltA:#0.000}"; + HeaderStr += $"\n▣ SUMB : {grp._sumvoltB:#0.000}"; + } + HeaderStr += $"\n▣ AVG : {grp.Avgvolt:#0.000}"; + if (!Sumab) + { + HeaderStr += $"\n▣ MAX : {grp.Maxvolt:#0.000}"; + HeaderStr += $"\n▣ MIN : {grp.Minvolt:#0.000}"; + } + + //집계데이터출력 + Fontsize = g.MeasureString(HeaderStr, this.font_header); + newy = grp.Rect_Header.Top + 5; // -Fontsize.Height / 2 + grp.Rect_Header.Height / 2; + if (IsVisible) g.DrawString(HeaderStr, this.font_header, Brushes.White, grp.Rect_Header.Left + 5, newy); + + //NB데이터와의 SPLITER + newx = grp.Rect_Header.Left + 5 + Fontsize.Width + 5; + Single SpliiterY = newy; + Single SplliterH = newy + grp.Rect_Header.Height - (newy - grp.Rect_Header.Top) * 2; + if (IsVisible) g.DrawLine(Pens.Black, newx, newy, newx, SplliterH); + + //NB데이터출력 + newx += 3; + + //NB용 알람표시 + Single imgwidth = 30; + Single imgheight = 30; + if (!(grp.nbh == 0 && grp.nbl == 0)) + { + if (Math.Abs(nullvalue) > grp.nbl) + { + grp._nbalam_l = true; //a2 on + if (!grp._pre_nbalam_l) { - if (grp.AlarmType != "STOP") OnAlamChange(grp.IDX, COMM.EALAMRAISETYPE.A1_ON, COMM.EALAMTYPE.사용안함, "NB", (Single)nullvalue, (Single)grp.nbh, (Single)grp.nbh); - grp._pre_nbalam_h = true; - blink1 = 0; + if (grp.AlarmType != "STOP") OnAlamChange(grp.IDX, COMM.EALAMRAISETYPE.A2_ON, COMM.EALAMTYPE.사용안함, "NB", (Single)nullvalue, (Single)grp.nbl, (Single)grp.nbl); + grp._pre_nbalam_l = true; + A2 = false; + blink2 = 0; } - else + else //게속발생중이다. { - if (A1 == false) + if (A2 == false) { - if (blink1 >= 1) + if (blink2 >= 1) { - A1 = true; - blink1 = 0; + A2 = true; + blink2 = 0; } - else blink1 += 1; + else blink2 += 1; } else { - if (blink1 >= 1) + if (blink2 >= 1) { - A1 = false; - blink1 = 0; + A2 = false; + blink2 = 0; } - else blink1 += 1; + else blink2 += 1; } } } - else //둘다적용안되는구역이다. + else // a2영역보다는 낮으므로 a2를 해제한다. { - grp._nbalam_h = false; //a1 off - if (grp._pre_nbalam_h) //이전에 a1알람이 켜져잇엇다면 알람을 끈다. + grp._nbalam_l = false; //a2 off + + if (grp._pre_nbalam_l) //이전에 a2알람이 켜져잇엇다면 알람을 끈다. { - OnAlamChange(grp.IDX, COMM.EALAMRAISETYPE.A1_OFF, COMM.EALAMTYPE.사용안함, "NB", (Single)nullvalue, (Single)grp.nbl, (Single)grp.nbl); - grp._pre_nbalam_h = false; + OnAlamChange(grp.IDX, COMM.EALAMRAISETYPE.A2_OFF, COMM.EALAMTYPE.사용안함, "NB", (Single)nullvalue, (Single)grp.nbl, (Single)grp.nbl); + grp._pre_nbalam_l = false; + blink1 = 0; + } + + + if (Math.Abs(nullvalue) > grp.nbh) //a1영역보다 크다면 + { + grp._nbalam_h = true; + if (!grp._pre_nbalam_h) //이전에 발생안햇다면 + { + if (grp.AlarmType != "STOP") OnAlamChange(grp.IDX, COMM.EALAMRAISETYPE.A1_ON, COMM.EALAMTYPE.사용안함, "NB", (Single)nullvalue, (Single)grp.nbh, (Single)grp.nbh); + grp._pre_nbalam_h = true; + blink1 = 0; + } + else + { + if (A1 == false) + { + if (blink1 >= 1) + { + A1 = true; + blink1 = 0; + } + else blink1 += 1; + } + else + { + if (blink1 >= 1) + { + A1 = false; + blink1 = 0; + } + else blink1 += 1; + } + } + } + else //둘다적용안되는구역이다. + { + grp._nbalam_h = false; //a1 off + if (grp._pre_nbalam_h) //이전에 a1알람이 켜져잇엇다면 알람을 끈다. + { + OnAlamChange(grp.IDX, COMM.EALAMRAISETYPE.A1_OFF, COMM.EALAMTYPE.사용안함, "NB", (Single)nullvalue, (Single)grp.nbl, (Single)grp.nbl); + grp._pre_nbalam_h = false; + } + blink1 = 0; + blink2 = 0; } - blink1 = 0; - blink2 = 0; } } - } - if (grp.AlarmType == "STOP") //그룹설정이 OFF인경우에는 모두 끈다. - { - grp._nbalam_h = false; - grp._nbalam_l = false; - } - - Bitmap B1; - if (grp._nbalam_h) - { - grp._alamcountlb += 1; - if (A1) B1 = vmsnet.Properties.Resources.Orange_Ball; - else B1 = vmsnet.Properties.Resources.Red_Ball; - } - else B1 = vmsnet.Properties.Resources.Blue_Ball; - - Bitmap B2; - if (grp._nbalam_l) - { - grp._alamcountlb += 1; - if (A2) B2 = vmsnet.Properties.Resources.Orange_Ball; - else B2 = vmsnet.Properties.Resources.Red_Ball; - } - else B2 = vmsnet.Properties.Resources.Blue_Ball; - - if (!isprint || WINDOW.CoulumnCount <= 2) - { - if (IsVisible) g.DrawImage(B1, newx + 25 * 0, newy, imgwidth, imgheight); - Fontsize = g.MeasureString("A1", alamfont); - if (IsVisible) g.DrawString("A1", alamfont, Brushes.Black, (newx + 25 * 0) + imgwidth / 2 - Fontsize.Width / 2, newy + imgheight / 2 - Fontsize.Height / 2); - - if (IsVisible) g.DrawImage(B2, newx + 25 * 1, newy, imgwidth, imgheight); - Fontsize = g.MeasureString("A2", alamfont); - if (IsVisible) g.DrawString("A2", alamfont, Brushes.Black, (newx + 25 * 1) + imgwidth / 2 - Fontsize.Width / 2, newy + imgheight / 2 - Fontsize.Height / 2); - - //ADJEST - if (IsVisible) g.DrawImage(vmsnet.Properties.Resources.Clear_Green_Button, newx + 25 * 0, newy + 2 + imgheight, imgwidth, imgheight); - if (IsVisible) Buttons.Add(new CButton(new RectangleF(newx + 25 * 0, newy + 2 + imgheight, imgwidth, imgheight), grp, EBUTTONTYPE.NBZERO)); - - //RESET - if (IsVisible) g.DrawImage(vmsnet.Properties.Resources.Backup_Green_Button, newx + 25 * 1, newy + imgheight, imgwidth, imgheight); - if (IsVisible) Buttons.Add(new CButton(new RectangleF(newx + 25 * 1, newy + imgheight, imgwidth, imgheight), grp, EBUTTONTYPE.NBRESET)); - } - - //끝부분에 KA 를 표시한다. - String Kaunit = grp._ampunit;// +grp._ampidx.ToString() + "/" + grp._ampdecpos.ToString(); - String MaxKA = grp._amp.ToString("#0.00"); - //Console.WriteLine($"{grp.이름} : {MaxKA} {grp._ampunit}"); - //if (grp.이름 == "EL2500E") MaxKA = "0.01"; - - - /**************************************************************************************/ - /* 작성자: 이재웅, 작성일: 2024-11-19, 작성내용: 8개 전해조의 합산 전류량[KA] Modbus 전송 부분 */ - /**************************************************************************************/ - - //using (var client = new JdModbus("COM3", new RtuConfigure() { BaudRate = 115200 })) - //{ - // client.Connect(); - - // ushort[] grpKA = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; // 전력량 배열 (예시) - // byte slaveaddr = 3; - // client.WriteHoldingRegisters(RelayControl.mKA, grpKA, slaveaddr); - //} - - /**************************************************************************************/ - - Fontsize = g.MeasureString(MaxKA, FONT_KA); - SizeF FontSizeu = g.MeasureString(Kaunit, FONT_KU); - RectangleF KARECT = new RectangleF(grp.Rect_Header.Left + grp.Rect_Header.Width - Fontsize.Width, grp.Rect_Header.Top + (grp.Rect_Header.Height - Fontsize.Height), Fontsize.Width, Fontsize.Height); - if (EnableKA == false) - KARECT = new RectangleF(grp.Rect_Header.Right, KARECT.Top, 0, 0); - //g.FillRectangle(Brushes.Black, KARECT); - if (IsVisible && KARECT.IsEmpty == false) - { - g.DrawString(MaxKA.ToString(), FONT_KA, Brushes.Black, KARECT.Left + 2, KARECT.Top + 2); - g.DrawString(MaxKA.ToString(), FONT_KA, Brushes.Yellow, KARECT.Left, KARECT.Top); - g.DrawString(Kaunit, FONT_KU, Brushes.Yellow, KARECT.Left + KARECT.Width - FontSizeu.Width - 10, KARECT.Top - 10); - } - - //NullBalance Display - if (!isprint || WINDOW.CoulumnCount <= 2) - { - newx = newx + 30 * 2; - String nullstring = nullvalue.ToString("#0.00"); - RectangleF rect_nullb = new RectangleF(newx, newy, KARECT.Left - newx, grp.Rect_Header.Height - 10); - Fontsize = g.MeasureString(nullstring, FONT_NB); - Single center = rect_nullb.Left + rect_nullb.Width / 2; - Single px = ((rect_nullb.Width / 2) * Math.Abs(nullvalue) / 5); - if (nullvalue < -5) + if (grp.AlarmType == "STOP") //그룹설정이 OFF인경우에는 모두 끈다. { - px = (rect_nullb.Width * (0) / (5 + 5)) - 1; - } - else if (nullvalue > 5) - { - px = (rect_nullb.Width * (5 + 5) / (5 + 5)) - 1; - } - else px = (rect_nullb.Width * (nullvalue + 5) / (5 + 5)) - 1; - - Color nbcolor = Color.White; - if (grp._nbalam_h) nbcolor = Color.Orange; - else if (grp._nbalam_l) nbcolor = Color.Red; - else nbcolor = Color.White; - - if (IsVisible) g.DrawString(nullstring, FONT_NB, new SolidBrush(Color.FromArgb(230, nbcolor)), newx + rect_nullb.Width / 2 - Fontsize.Width / 2, rect_nullb.Top + rect_nullb.Height / 2 - Fontsize.Height / 2); - - - Color NewSBColor; - if (grp.NullBalanceOffset != 0) NewSBColor = Color.FromArgb(180, Color.DarkBlue); - else NewSBColor = Color.FromArgb(180, Color.Red); - using (SolidBrush NewSB = new SolidBrush(NewSBColor)) - { - if (IsVisible) g.DrawLine(Pens.Red, px + rect_nullb.Left, rect_nullb.Top, px + rect_nullb.Left, rect_nullb.Top + rect_nullb.Height); - if (IsVisible) g.DrawLine(Pens.Red, px + rect_nullb.Left + 1, rect_nullb.Top, px + rect_nullb.Left + 1, rect_nullb.Top + rect_nullb.Height); - PointF[] sqp = new PointF[3]; - sqp[0] = new PointF(px + rect_nullb.Left - 10, rect_nullb.Top); - sqp[1] = new PointF(px + rect_nullb.Left, rect_nullb.Top + 10); - sqp[2] = new PointF(px + rect_nullb.Left + 10, rect_nullb.Top); - if (IsVisible) g.FillPolygon(Brushes.Red, sqp); - NewSB.Dispose(); + grp._nbalam_h = false; + grp._nbalam_l = false; } - //null balance 테두리 그림 - if (IsVisible) g.DrawRectangle(Pens.Orange, rect_nullb.Left, rect_nullb.Top, rect_nullb.Width, rect_nullb.Height); - var term = rect_nullb.Width / 10f; - for (int i = 1; i < 10; i++) + Bitmap B1; + if (grp._nbalam_h) { - var x = rect_nullb.Left + (i * term); - var y = (rect_nullb.Top + (rect_nullb.Height * 0.8f)); - var y2 = rect_nullb.Top + rect_nullb.Height; + grp._alamcountlb += 1; + if (A1) B1 = vmsnet.Properties.Resources.Orange_Ball; + else B1 = vmsnet.Properties.Resources.Red_Ball; + } + else B1 = vmsnet.Properties.Resources.Blue_Ball; - if (IsVisible) g.DrawLine(Pens.Orange, x - 1, y, x - 1, y2); - //String str = (i - 5).ToString(); + Bitmap B2; + if (grp._nbalam_l) + { + grp._alamcountlb += 1; + if (A2) B2 = vmsnet.Properties.Resources.Orange_Ball; + else B2 = vmsnet.Properties.Resources.Red_Ball; + } + else B2 = vmsnet.Properties.Resources.Blue_Ball; + + if (!isprint || WINDOW.CoulumnCount <= 2) + { + if (IsVisible) g.DrawImage(B1, newx + 25 * 0, newy, imgwidth, imgheight); + Fontsize = g.MeasureString("A1", alamfont); + if (IsVisible) g.DrawString("A1", alamfont, Brushes.Black, (newx + 25 * 0) + imgwidth / 2 - Fontsize.Width / 2, newy + imgheight / 2 - Fontsize.Height / 2); + + if (IsVisible) g.DrawImage(B2, newx + 25 * 1, newy, imgwidth, imgheight); + Fontsize = g.MeasureString("A2", alamfont); + if (IsVisible) g.DrawString("A2", alamfont, Brushes.Black, (newx + 25 * 1) + imgwidth / 2 - Fontsize.Width / 2, newy + imgheight / 2 - Fontsize.Height / 2); + + //ADJEST + if (IsVisible) g.DrawImage(vmsnet.Properties.Resources.Clear_Green_Button, newx + 25 * 0, newy + 2 + imgheight, imgwidth, imgheight); + if (IsVisible) Buttons.Add(new CButton(new RectangleF(newx + 25 * 0, newy + 2 + imgheight, imgwidth, imgheight), grp, EBUTTONTYPE.NBZERO)); + + //RESET + if (IsVisible) g.DrawImage(vmsnet.Properties.Resources.Backup_Green_Button, newx + 25 * 1, newy + imgheight, imgwidth, imgheight); + if (IsVisible) Buttons.Add(new CButton(new RectangleF(newx + 25 * 1, newy + imgheight, imgwidth, imgheight), grp, EBUTTONTYPE.NBRESET)); } - newx = newx + rect_nullb.Width + 3; - if (IsVisible) g.DrawLine(Pens.Black, newx, SpliiterY, newx, SplliterH); - } - else - { - if (IsVisible) + //끝부분에 KA 를 표시한다. + String Kaunit = grp._ampunit;// +grp._ampidx.ToString() + "/" + grp._ampdecpos.ToString(); + String MaxKA = grp._amp.ToString("#0.00"); + //Console.WriteLine($"{grp.이름} : {MaxKA} {grp._ampunit}"); + //if (grp.이름 == "EL2500E") MaxKA = "0.01"; + + + /**************************************************************************************/ + /* 작성자: 이재웅, 작성일: 2024-11-19, 작성내용: 8개 전해조의 합산 전류량[KA] Modbus 전송 부분 */ + /**************************************************************************************/ + + //using (var client = new JdModbus("COM3", new RtuConfigure() { BaudRate = 115200 })) + //{ + // client.Connect(); + + // ushort[] grpKA = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; // 전력량 배열 (예시) + // byte slaveaddr = 3; + // client.WriteHoldingRegisters(RelayControl.mKA, grpKA, slaveaddr); + //} + + /**************************************************************************************/ + + Fontsize = g.MeasureString(MaxKA, FONT_KA); + SizeF FontSizeu = g.MeasureString(Kaunit, FONT_KU); + RectangleF KARECT = new RectangleF(grp.Rect_Header.Left + grp.Rect_Header.Width - Fontsize.Width, grp.Rect_Header.Top + (grp.Rect_Header.Height - Fontsize.Height), Fontsize.Width, Fontsize.Height); + if (EnableKA == false) + KARECT = new RectangleF(grp.Rect_Header.Right, KARECT.Top, 0, 0); + //g.FillRectangle(Brushes.Black, KARECT); + if (IsVisible && KARECT.IsEmpty == false) { - String nullstring = "NB=" + nullvalue.ToString("#0.00"); - using (var nullbfont = new Font(FONT_NB.FontFamily, 10)) + g.DrawString(MaxKA.ToString(), FONT_KA, Brushes.Black, KARECT.Left + 2, KARECT.Top + 2); + g.DrawString(MaxKA.ToString(), FONT_KA, Brushes.Yellow, KARECT.Left, KARECT.Top); + g.DrawString(Kaunit, FONT_KU, Brushes.Yellow, KARECT.Left + KARECT.Width - FontSizeu.Width - 10, KARECT.Top - 10); + } + + //NullBalance Display + if (!isprint || WINDOW.CoulumnCount <= 2) + { + newx = newx + 30 * 2; + String nullstring = nullvalue.ToString("#0.00"); + RectangleF rect_nullb = new RectangleF(newx, newy, KARECT.Left - newx, grp.Rect_Header.Height - 10); + Fontsize = g.MeasureString(nullstring, FONT_NB); + Single center = rect_nullb.Left + rect_nullb.Width / 2; + Single px = ((rect_nullb.Width / 2) * Math.Abs(nullvalue) / 5); + if (nullvalue < -5) { - g.DrawString(nullstring, nullbfont, SB_White_200, KARECT.Left, KARECT.Top - 10); + px = (rect_nullb.Width * (0) / (5 + 5)) - 1; + } + else if (nullvalue > 5) + { + px = (rect_nullb.Width * (5 + 5) / (5 + 5)) - 1; + } + else px = (rect_nullb.Width * (nullvalue + 5) / (5 + 5)) - 1; + + Color nbcolor = Color.White; + if (grp._nbalam_h) nbcolor = Color.Orange; + else if (grp._nbalam_l) nbcolor = Color.Red; + else nbcolor = Color.White; + + if (IsVisible) g.DrawString(nullstring, FONT_NB, new SolidBrush(Color.FromArgb(230, nbcolor)), newx + rect_nullb.Width / 2 - Fontsize.Width / 2, rect_nullb.Top + rect_nullb.Height / 2 - Fontsize.Height / 2); + + + Color NewSBColor; + if (grp.NullBalanceOffset != 0) NewSBColor = Color.FromArgb(180, Color.DarkBlue); + else NewSBColor = Color.FromArgb(180, Color.Red); + using (SolidBrush NewSB = new SolidBrush(NewSBColor)) + { + if (IsVisible) g.DrawLine(Pens.Red, px + rect_nullb.Left, rect_nullb.Top, px + rect_nullb.Left, rect_nullb.Top + rect_nullb.Height); + if (IsVisible) g.DrawLine(Pens.Red, px + rect_nullb.Left + 1, rect_nullb.Top, px + rect_nullb.Left + 1, rect_nullb.Top + rect_nullb.Height); + PointF[] sqp = new PointF[3]; + sqp[0] = new PointF(px + rect_nullb.Left - 10, rect_nullb.Top); + sqp[1] = new PointF(px + rect_nullb.Left, rect_nullb.Top + 10); + sqp[2] = new PointF(px + rect_nullb.Left + 10, rect_nullb.Top); + if (IsVisible) g.FillPolygon(Brushes.Red, sqp); + NewSB.Dispose(); + } + + //null balance 테두리 그림 + if (IsVisible) g.DrawRectangle(Pens.Orange, rect_nullb.Left, rect_nullb.Top, rect_nullb.Width, rect_nullb.Height); + var term = rect_nullb.Width / 10f; + for (int i = 1; i < 10; i++) + { + var x = rect_nullb.Left + (i * term); + var y = (rect_nullb.Top + (rect_nullb.Height * 0.8f)); + var y2 = rect_nullb.Top + rect_nullb.Height; + + if (IsVisible) g.DrawLine(Pens.Orange, x - 1, y, x - 1, y2); + //String str = (i - 5).ToString(); + } + + newx = newx + rect_nullb.Width + 3; + if (IsVisible) g.DrawLine(Pens.Black, newx, SpliiterY, newx, SplliterH); + } + else + { + if (IsVisible) + { + String nullstring = "NB=" + nullvalue.ToString("#0.00"); + using (var nullbfont = new Font(FONT_NB.FontFamily, 10)) + { + g.DrawString(nullstring, nullbfont, SB_White_200, KARECT.Left, KARECT.Top - 10); + } } } - } - //현그룹의 테두리 그림 - //g.DrawRectangle(Pens.Black, (int)grp.R.Left, (int)grp.R.Top, (int)grp.R.Width+1, (int)grp.R.Height); - //grp.Showinfo = true; + //현그룹의 테두리 그림 + //g.DrawRectangle(Pens.Black, (int)grp.R.Left, (int)grp.R.Top, (int)grp.R.Width+1, (int)grp.R.Height); + //grp.Showinfo = true; - //추가헤더정보 - if (!isprint && grp.Showinfo && IsVisible) - { - using (var ifont = new Font(this.font_header, FontStyle.Bold)) + //추가헤더정보 + if (!isprint && grp.Showinfo && IsVisible) { - String nbstr = "▣ NULL BALANCE ▣"; - nbstr += "\n\n▶L:" + grp._null_valueL.ToString("#0.00") + "v"; - nbstr += ",R:" + grp._null_valueR.ToString("#0.00") + "v"; - nbstr += " ▶DEV(R-L):" + (grp._null_valueR - grp._null_valueL).ToString("#0.00") + "v"; - nbstr += " ▶Adj. Offset:" + (grp.NullBalanceOffset).ToString("#0.00") + "v"; - nbstr += "\n\n▶Null Balance : " + (grp._null_valueR - grp._null_valueL + grp.NullBalanceOffset).ToString("#0.00") + "v"; - nbstr += "\n▶Null Balance Alarm: A1(" + grp.nbh.ToString("#0.00") + "),A2(" + grp.nbl.ToString("#0.00") + ")"; - nbstr += "\n\n * 막대그래프의 구간은 -5v ~ 5v 입니다."; - nbstr += "\n * 막대그래프의 색상이 하늘색일경우에는 Adj.Offset 이 적용된 값입니다."; + using (var ifont = new Font(this.font_header, FontStyle.Bold)) + { + String nbstr = "▣ NULL BALANCE ▣"; + nbstr += "\n\n▶L:" + grp._null_valueL.ToString("#0.00") + "v"; + nbstr += ",R:" + grp._null_valueR.ToString("#0.00") + "v"; + nbstr += " ▶DEV(R-L):" + (grp._null_valueR - grp._null_valueL).ToString("#0.00") + "v"; + nbstr += " ▶Adj. Offset:" + (grp.NullBalanceOffset).ToString("#0.00") + "v"; + nbstr += "\n\n▶Null Balance : " + (grp._null_valueR - grp._null_valueL + grp.NullBalanceOffset).ToString("#0.00") + "v"; + nbstr += "\n▶Null Balance Alarm: A1(" + grp.nbh.ToString("#0.00") + "),A2(" + grp.nbl.ToString("#0.00") + ")"; + nbstr += "\n\n * 막대그래프의 구간은 -5v ~ 5v 입니다."; + nbstr += "\n * 막대그래프의 색상이 하늘색일경우에는 Adj.Offset 이 적용된 값입니다."; - SizeF fs = g.MeasureString(nbstr, ifont); - Single tx, ty, tw, th, Margin = 0; + SizeF fs = g.MeasureString(nbstr, ifont); + Single tx, ty, tw, th, Margin = 0; - tx = grp.Rect_Header.Left + 10; - ty = grp.Rect_Header.Top + grp.Rect_Header.Height - 6; - tw = (fs.Width * 1.1f); - th = (fs.Height * 1.1f + 60); + tx = grp.Rect_Header.Left + 10; + ty = grp.Rect_Header.Top + grp.Rect_Header.Height - 6; + tw = (fs.Width * 1.1f); + th = (fs.Height * 1.1f + 60); - RectangleF infoboxb = new RectangleF(tx + 1, ty + 1, tw, th); - RectangleF infoboxf = new RectangleF(tx, ty, tw, th); - RectangleF intoboxs = new RectangleF(tx + Margin + 3, ty + Margin, tw - (Margin * 2), th - (Margin * 2)); + RectangleF infoboxb = new RectangleF(tx + 1, ty + 1, tw, th); + RectangleF infoboxf = new RectangleF(tx, ty, tw, th); + RectangleF intoboxs = new RectangleF(tx + Margin + 3, ty + Margin, tw - (Margin * 2), th - (Margin * 2)); - //SolidBrush BRB = new SolidBrush(Color.FromArgb(150, Color.Black)); - //SolidBrush BRF = new SolidBrush(Color.FromArgb(200, Color.White)); + //SolidBrush BRB = new SolidBrush(Color.FromArgb(150, Color.Black)); + //SolidBrush BRF = new SolidBrush(Color.FromArgb(200, Color.White)); - g.FillRectangle(SB_Black_150, infoboxb); - g.FillRectangle(SB_White_200, infoboxf); + g.FillRectangle(SB_Black_150, infoboxb); + g.FillRectangle(SB_White_200, infoboxf); - g.DrawString(nbstr, ifont, Brushes.Black, intoboxs.Left + 1, intoboxs.Top + 3); - // g.DrawString(nbstr, this.font_header, Brushes.Orange, intoboxs.Left, intoboxs.Top + intoboxs.Height / 2 - fs.Height / 2); + g.DrawString(nbstr, ifont, Brushes.Black, intoboxs.Left + 1, intoboxs.Top + 3); + // g.DrawString(nbstr, this.font_header, Brushes.Orange, intoboxs.Left, intoboxs.Top + intoboxs.Height / 2 - fs.Height / 2); - Single Imagey = intoboxs.Top + fs.Height + 10; + Single Imagey = intoboxs.Top + fs.Height + 10; - g.DrawImage(vmsnet.Properties.Resources.Clear_Green_Button, intoboxs.Left, Imagey, imgwidth, imgheight); - g.DrawString("현재 Null Balance 값을 Adj.Offset 으로 설정하여 '0'이 되게 합니다.", ifont, Brushes.Black, intoboxs.Left + 35, Imagey + 5); + g.DrawImage(vmsnet.Properties.Resources.Clear_Green_Button, intoboxs.Left, Imagey, imgwidth, imgheight); + g.DrawString("현재 Null Balance 값을 Adj.Offset 으로 설정하여 '0'이 되게 합니다.", ifont, Brushes.Black, intoboxs.Left + 35, Imagey + 5); - Imagey += 25; - g.DrawImage(vmsnet.Properties.Resources.Backup_Green_Button, intoboxs.Left, Imagey, imgwidth, imgheight); - g.DrawString("입력된 Adj.Offset 을 제거하여 원래의 Null Balance가 보이게 합니다.", ifont, Brushes.Black, intoboxs.Left + 35, Imagey + 5); + Imagey += 25; + g.DrawImage(vmsnet.Properties.Resources.Backup_Green_Button, intoboxs.Left, Imagey, imgwidth, imgheight); + g.DrawString("입력된 Adj.Offset 을 제거하여 원래의 Null Balance가 보이게 합니다.", ifont, Brushes.Black, intoboxs.Left + 35, Imagey + 5); - //BRF.Dispose(); + //BRF.Dispose(); + } + } + + _raise_alarm_count += grp._alamcount; + _raise_alarm_nbcount += grp._alamcountlb; + + if (grp._maxitemp != null) + { + grp._maxitemp.ismax = false; + } + if (grp._minitemp != null) grp._minitemp.ismin = false; + if (grp._maxitem != null) + { + grp._maxitem.ismax = true; + grp._maxitemp = grp._maxitem; + } + if (grp._minitem != null) + { + grp._minitem.ismin = true; + grp._minitemp = grp._minitem; } } - - _raise_alarm_count += grp._alamcount; - _raise_alarm_nbcount += grp._alamcountlb; - - if (grp._maxitemp != null) + catch (NullReferenceException ex1) { - grp._maxitemp.ismax = false; - } - if (grp._minitemp != null) grp._minitemp.ismin = false; - if (grp._maxitem != null) - { - grp._maxitem.ismax = true; - grp._maxitemp = grp._maxitem; - } - if (grp._minitem != null) - { - grp._minitem.ismin = true; - grp._minitemp = grp._minitem; - } + // 예외 메시지, 파일명, 행 번호를 로그에 기록 + var stackTrace = new System.Diagnostics.StackTrace(ex1, true); + var frame = stackTrace.GetFrame(0); + string fileName = frame.GetFileName(); + int lineNumber = frame.GetFileLineNumber(); + // UI 디스플레이 중, 예외발생 문제 + PUB.log.AddE($"NullReferenceException Message={ex1.Message}, 파일명={fileName}, 행번호={lineNumber}"); + } + catch (Exception ex2) + { + // 예외 메시지, 파일명, 행 번호를 로그에 기록 + var stackTrace = new System.Diagnostics.StackTrace(ex2, true); + var frame = stackTrace.GetFrame(0); + string fileName = frame.GetFileName(); + int lineNumber = frame.GetFileLineNumber(); + + // Else Error !!! + PUB.log.AddE($"Exception Message={ex2.Message}, 파일명={fileName}, 행번호={lineNumber}"); + } } + private void DrawGroups(Graphics g) { _raise_alarm_count = 0; //알람카운트 @@ -1806,11 +1858,26 @@ namespace vmsnet.HMI } catch (NullReferenceException ex1) { + // 예외 메시지, 파일명, 행 번호를 로그에 기록 + var stackTrace = new System.Diagnostics.StackTrace(ex1, true); + var frame = stackTrace.GetFrame(0); + string fileName = frame.GetFileName(); + int lineNumber = frame.GetFileLineNumber(); + // UI 디스플레이 중, 예외발생 문제 + PUB.log.AddE($"NullReferenceException Message={ex1.Message}, 파일명={fileName}, 행번호={lineNumber}"); + } - catch (Exception ex) + catch (Exception ex2) { - // else error !!! + // 예외 메시지, 파일명, 행 번호를 로그에 기록 + var stackTrace = new System.Diagnostics.StackTrace(ex2, true); + var frame = stackTrace.GetFrame(0); + string fileName = frame.GetFileName(); + int lineNumber = frame.GetFileLineNumber(); + + // Else Error !!! + PUB.log.AddE($"Exception Message={ex2.Message}, 파일명={fileName}, 행번호={lineNumber}"); } } diff --git a/cVMS.NET_CS/Modbus/Configures/RtuConfigure.cs b/cVMS.NET_CS/Modbus/Configures/RtuConfigure.cs index 7360d6d..4edb757 100644 --- a/cVMS.NET_CS/Modbus/Configures/RtuConfigure.cs +++ b/cVMS.NET_CS/Modbus/Configures/RtuConfigure.cs @@ -10,18 +10,18 @@ namespace vmsnet.Configures public class RtuConfigure { public int BaudRate { get; set; } = 9600; + public int DataBits { get; set; } = 8; public Parity Parity { get; set; } = Parity.None; public StopBits StopBits { get; set; } = StopBits.One; - public int DataBits { get; set; } = 8; public RtuConfigure() { } public RtuConfigure(int baudRate, Parity parity, StopBits stopBits, int dataBits) { BaudRate = baudRate; + DataBits = dataBits; Parity = parity; StopBits = stopBits; - DataBits = dataBits; } } } \ No newline at end of file diff --git a/cVMS.NET_CS/Setting/Frm_Config.Designer.cs b/cVMS.NET_CS/Setting/Frm_Config.Designer.cs index 9f97f84..037c2f1 100644 --- a/cVMS.NET_CS/Setting/Frm_Config.Designer.cs +++ b/cVMS.NET_CS/Setting/Frm_Config.Designer.cs @@ -507,7 +507,7 @@ namespace vmsnet this.groupBox4.Size = new System.Drawing.Size(347, 218); this.groupBox4.TabIndex = 45; this.groupBox4.TabStop = false; - this.groupBox4.Text = "Indicator"; + this.groupBox4.Text = "KA Indicator"; // // button5 // diff --git a/cVMS.NET_CS/Setting/Frm_Config.cs b/cVMS.NET_CS/Setting/Frm_Config.cs index 495b58b..449f8d4 100644 --- a/cVMS.NET_CS/Setting/Frm_Config.cs +++ b/cVMS.NET_CS/Setting/Frm_Config.cs @@ -311,6 +311,12 @@ namespace vmsnet this.bs_normal.EndEdit(); this.bs_win.EndEdit(); + if (cmbIndiport.Text.Trim() == cmb_plcport.Text.Trim()) + { + UTIL.MsgE("「KA 인디게이터」와 「Alarm PLC」의 통신포트는\n\n동일하게 설정할 수 없습니다."); + cmbIndiport.Focus(); + return; + } if (nudPri1.Value < 1 || nudPri2.Value < 1) {