using System.Collections.Generic; using System; using System.Drawing; using System.Diagnostics; using System.Data; using System.Collections; using System.Windows.Forms; using System.Net; using System.Net.Sockets; using System.Windows.Forms.DataVisualization.Charting; using System.Net.NetworkInformation; using AR; using System.Threading.Tasks; using System.Linq; //########################################################################################### //## //## 작성자 : tindevil(tindevil@nate.com) //## 최초작성일 : 2023-11-17 //## 설명 : DA100을 기반으로 데이터 변경 //## //########################################################################################### namespace vmsnet { public class GM10 : CMachine { public bool opt_synctime { get; set; } = false; public bool opt_lsb { get; set; } = false; System.Net.Sockets.TcpClient oSocket; ////데이터전송포트 NetworkStream myNts; ////데이터수집용 //System.Threading.Thread ReadWorker; ////데이터수신을위한 쓰레드(데이터) ////데이터출력변수 //int bufferi; //double bufferd; //double bufferd2; //string buffers; public string title = "이름"; public string unitch = ""; public int chcount = 0; //int Timeout = 65535; ////명령의 타임아웃시간 지정된초가 되면 오류를 낸다. public bool Disc = false; ////연결의종료를 의미 public int rowindex = 0; public long deadstart; ////연결종료된 시간 /// /// Create /// /// /// public GM10(string p_ip, int p_port, string p_title, string p_chcount, int p_rowindex) : base(p_ip, p_port, "GM10") { this.title = p_title; this.unitch = p_chcount; this.rowindex = p_rowindex; DoRequest = false; if (p_chcount.Trim() != "") { foreach (string c in this.unitch.Split(",".ToCharArray())) { chcount += System.Convert.ToInt32(c.Split("*".ToCharArray())[1]); } } else { chcount = 0; } } public bool SetBinaryLSB() { ////사용불가상태라면 반환하지 않는다. if (isOn == false || isLock == true) { return false; } ////다른작업중이라면 기다린다. while (DoRequest) { System.Threading.Thread.Sleep(50); Application.DoEvents(); } DoRequest = true; PUB.workmsg("Init LSB"); string msg = System.Convert.ToString("BO1" + "\r\n"); // BO : Sets the byte output order. [0=Measured data(ASCII), 1=Math data(binary), 2=Math data(ASCII), 3=Math channel(binary)] ESENDMSGRESULT SendResult = SendMsg(msg); bool retval = false; switch (SendResult) { case ESENDMSGRESULT.DISC: return false; case ESENDMSGRESULT.FAIL: return false; case ESENDMSGRESULT.SUC: string buffer = graptext(); if (buffer.Length > 1) { string Rlt = buffer.Substring(0, 2); if (Rlt == "E0") { retval = true; } } break; } DoRequest = false; return retval; } /// /// 날짜를 현재의 컴퓨터와 동기화 시킨다. /// /// /// public override bool SyncDate() { // 장치의 시간을 PC의 시간으로 동기화 bool Retval = false; ////사용불가상태라면 반환하지 않는다. if (isOn == false || isLock == true) { return false; } ////다른작업중이라면 기다린다. while (DoRequest) { System.Threading.Thread.Sleep(50); Application.DoEvents(); } DoRequest = true; ////시간동기화중 PUB.workmsg("시간 동기화중"); ////시간변경명령어 // SD : Sets the date and time. string msg = System.Convert.ToString(("SD" + DateTime.Now.ToString("yy/MM/dd,HH:mm:ss")).Replace("-", "/") + "\r\n"); ESENDMSGRESULT SendResult = SendMsg(msg); switch (SendResult) { case ESENDMSGRESULT.DISC: this.Disc = true; PUB.workmsg(""); UTIL.MsgE("장치와의 연결이 종료되었습니다." + "\r\n" + "프로그램이 중복 실행되었는지 확인하세요" + "\r\n" + "시간동기화는 실행되지 않습니다"); Retval = false; break; case ESENDMSGRESULT.SUC: ////명령어전송이 성공했다. 결과를 받도록 한다. try { byte[] buffer = new byte[5000]; char[] c = new char[] { '|' }; string temp = ""; while (true) { myNts.Read(buffer, 0, buffer.Length); temp = System.Text.Encoding.Default.GetString(buffer); if (temp.Trim() == "") { Application.DoEvents(); } else if (temp.Trim().Substring(0, 2) == "E0") { Retval = true; break; } else if (temp.Trim().Substring(0, 2) == "E1") { Retval = false; break; } else { } Application.DoEvents(); Array.Clear(buffer, 0, buffer.Length); } Application.DoEvents(); } catch (System.IO.IOException exio) { UTIL.MsgE(exio.Message.ToString()); this.Disc = true; } catch (Exception ex) { MessageBox.Show("1" + ex.Message.ToString()); } break; case ESENDMSGRESULT.FAIL: PUB.workmsg(""); Retval = false; break; } DoRequest = false; return Retval; } /// /// 장치를 재구성합니다. /// /// /// public bool Reconstrction() { ////사용불가상태라면 반환하지 않는다. if (isOn == false || isLock == true) { return false; } ////다른작업중이라면 기다린다. while (DoRequest) { System.Threading.Thread.Sleep(50); Application.DoEvents(); } DoRequest = true; PUB.workmsg("장치 재구성 준비중" + "\r\n" + "연결을 종료하고있습니다"); ////다른명령어를 막기위해 모든연결을 종료한다. isBusy = true; isOn = false; isLock = true; PUB.workmsg("Entering Operation MODE - " + IP); PUB.workmsg("[장치재구성] 재구성명령어를 전송합니다."); string msg = System.Convert.ToString("RS0" + "\r\n"); // RS : System reconfiguration. bool SendResult = SendMsg(msg) == ESENDMSGRESULT.SUC; if (SendResult == false) ////명령어전송을 하지못했다. 네트워크상에 문제가 생겼을수있따. { UTIL.MsgE("장치재구성 명령어를 전송하지 못했습니다"); PUB.workmsg(""); DoRequest = false; return false; } PUB.workmsg("[장치재구성] 응답을 기다리고있습니다."); ////작업중 bool retval = false; try { byte[] buffer = new byte[5000]; char[] c = new char[] { '|' }; string temp = ""; while (true) { myNts.Read(buffer, 0, buffer.Length); temp = System.Text.Encoding.Default.GetString(buffer); if (temp.Trim() == "") { Application.DoEvents(); } else if (temp.Trim().Substring(0, 2) == "E0") { UTIL.MsgI("장치재구성이 완료되었습니다"); retval = true; break; } else if (temp.Trim().Substring(0, 2) == "E1") { UTIL.MsgE("장치재구성이 실패되었습니다."); break; } else { MessageBox.Show("TEMP->" + temp); } Array.Clear(buffer, 0, buffer.Length); } } catch (Exception ex) { MessageBox.Show("RS->" + ex.Message.ToString()); } DoRequest = false; PUB.workmsg(""); return retval; } /// /// 각채널의 VOLT 및 KA디바이스정보를 설정합니다. /// /// KA장치의 정보를 반환(1,0,30 / 1,1,30) /// /// public bool ReSetting(string kadevice, string SNCOMMAND, string KACOMMAND, string CHCOMMAND) { ////사용불가상태라면 반환하지 않는다. if (isOn == false || isLock == true) { return false; } ////다른작업중이라면 기다린다. while (DoRequest) { System.Threading.Thread.Sleep(50); Application.DoEvents(); } ////이러면 chinfo 가 갱신된다. getChannelData(); DataTable chdt = getChannelData(); ////DOREQUEST 를 이전에 설정하면 이 명령어가 무한대기를 하게된다. DoRequest = true; ////작업중 PUB.workmsg("데이터수집포맷을 LSB로 설정합니다."); bool SendResult = SendMsg("BO1" + "\r\n") == ESENDMSGRESULT.SUC; if (SendResult == false) { UTIL.MsgE("데이터수집포맷(LSB)설정에 실패하였습니다"); PUB.workmsg(""); DoRequest = false; return false; } if (ReferenceEquals(chdt, null) || chdt.Rows.Count == 0) { UTIL.MsgE("채널정보를 확인할 수 없으므로 설정을 할 수 없습니다"); DoRequest = false; return false; } PUB.workmsg("장치 재구성 준비중" + "\r\n" + "연결을 종료하고있습니다"); ////다른명령어를 막기위해 모든연결을 종료한다. isBusy = true; isOn = false; isLock = true; System.Text.StringBuilder Errorlist = new System.Text.StringBuilder(); ////발생한에러목록 //bool retval ; ////KA채널을 설정합니다. //For Each S As String In kadevice.Split("/") '//각채널데이터는 /로 구분되어있으며 1,2,30 (디바이스,subunit,ch) // If S.Trim = "" Then Continue For // Dim info() As String = S.Split(",") // If info(0) = Me.rowindex Then '//해당 IDX값만 취한다. // Dim ch As String = info(1) & info(2) // '//SET SCALE // Dim cmd As String = KACOMMAND.Replace("[%CH%]", ch) & vbCrLf // workmsg("Set Scale(" & ch & ")") // SendResult = SendMsg(cmd, True) // If SendResult = False Then '//명령어전송을 하지못했다. 네트워크상에 문제가 생겼을수있따. // MsgBox("Scale 설정실패(" & ch & ")", MsgBoxStyle.Critical, "확인") // workmsg("") // Return False // End If // workmsg("응답을 기다리고있습니다.") // Sleep(100) // Try // Dim buffer(4999) As Byte // Dim c() As Char = {"|"c} // Dim temp As String // While (1) // mynts.Read(buffer, 0, buffer.Length) // temp = System.Text.Encoding.Default.GetString(buffer) // If temp.Trim = "" Then // My.Application.DoEvents() // ElseIf temp.Trim.Substring(0, 2) = "E0" Then // retval = True // Exit While // ElseIf temp.Trim.Substring(0, 2) = "E1" Then // MsgBox("스케일설정실패") // Errorlist.AppendLine(ch & " 채널의 설정이 실패되었습니다.") // Exit While // Else // MsgBox("스케일설정실패") // Errorlist.AppendLine(ch & " 채널의 설정을 확인할 수 없습니다") // End If // Array.Clear(buffer, 0, buffer.Length) // End While // My.Application.DoEvents() // Catch ex As Exception // MsgBox("Scale 설정중 오류가 발생하였습니다" & vbCrLf & "다시시도하세요" & vbCrLf & ex.Message.ToString, MsgBoxStyle.Critical, "확인") // Return False // End Try // '//SET SCALE UNIT // cmd = SNCOMMAND.Replace("[%CH%]", ch) & vbCrLf // workmsg("Set Scale UNIT(" & ch & ")") // SendResult = SendMsg(cmd, True) // If SendResult = False Then '//명령어전송을 하지못했다. 네트워크상에 문제가 생겼을수있따. // MsgBox("Scale UNIT 설정실패(" & ch & ")", MsgBoxStyle.Critical, "확인") // workmsg("") // Return False // End If // workmsg("응답을 기다리고있습니다.") // Sleep(100) // Try // Dim buffer(4999) As Byte // Dim c() As Char = {"|"c} // Dim temp As String // While (1) // mynts.Read(buffer, 0, buffer.Length) // temp = System.Text.Encoding.Default.GetString(buffer) // If temp.Trim = "" Then // My.Application.DoEvents() // ElseIf temp.Trim.Substring(0, 2) = "E0" Then // retval = True // Exit While // ElseIf temp.Trim.Substring(0, 2) = "E1" Then // MsgBox("유닛설정실패") // Errorlist.AppendLine(ch & " 채널의 설정이 실패되었습니다.") // Exit While // Else // MsgBox("유닛설정실패") // Errorlist.AppendLine(ch & " 채널의 설정을 확인할 수 없습니다") // End If // Array.Clear(buffer, 0, buffer.Length) // End While // My.Application.DoEvents() // Catch ex As Exception // MsgBox("Scale UNIT 설정중 오류가 발생하였습니다" & vbCrLf & "다시시도하세요" & vbCrLf & ex.Message.ToString, MsgBoxStyle.Critical, "확인") // Return False // End Try // End If //Next foreach (DataRow dr in chdt.Rows) { int unitno = System.Convert.ToInt32(dr["unitno"]); int chno = System.Convert.ToInt32(dr["chno"]); string cmdno = unitno.ToString("0") + chno.ToString("00"); PUB.workmsg(cmdno + "의 채널을 설정합니다."); string msg = "SR" + (cmdno + ",VOLT,20V" + "\r\n"); // SR : Sets the range. //msg = "SN030,KASDFSD" + vbCrLf SendResult = SendMsg(msg) == ESENDMSGRESULT.SUC; if (SendResult == false) ////명령어전송을 하지못했다. 네트워크상에 문제가 생겼을수있따. { UTIL.MsgE("장치재구성 명령어를 전송하지 못했습니다"); PUB.workmsg(""); DoRequest = false; return false; } System.Threading.Thread.Sleep(50); //workmsg("응답을 기다리고있습니다.") try { byte[] buffer = new byte[5000]; char[] c = new char[] { '|' }; string temp = ""; while (true) { myNts.Read(buffer, 0, buffer.Length); temp = System.Text.Encoding.Default.GetString(buffer); if (temp.Trim() == "") { Application.DoEvents(); } else if (temp.Trim().Substring(0, 2) == "E0") { // retval = true; break; } else if (temp.Trim().Substring(0, 2) == "E1") { Errorlist.AppendLine(cmdno + " 채널의 설정이 실패되었습니다."); break; } else { Errorlist.AppendLine(cmdno + " 채널의 설정을 확인할 수 없습니다"); } Array.Clear(buffer, 0, buffer.Length); } Application.DoEvents(); } catch (Exception ex) { UTIL.MsgE($"설정중 오류가 발생하였습니다\n다시시도하세요\n{ex.Message}"); goto endOfForLoop; } } endOfForLoop: if (Errorlist.ToString() != "") { UTIL.MsgE(Errorlist.ToString()); } DoRequest = false; PUB.workmsg(""); return System.Convert.ToBoolean(1); } /// /// get channel data 가 쓰는 함수로서 문자열 데이터를 가져온다. /// /// /// private string GetChannelString() { ////사용불가상태라면 반환하지 않는다. if (isOn == false || isLock == true || Disc == true) { return null; } ////다른작업중이라면 기다린다. while (DoRequest) { System.Threading.Thread.Sleep(50); Application.DoEvents(); } DoRequest = true; string bufferstr = ""; string msg = System.Convert.ToString("TS2" + "\r\n");//// TS2 : Selects the talker output data [0=Measured data, 1=Setting parameters, 2=Unit information, 5=System configuration information, 9=Setup mode setting parameter output] bool SendResult = SendMsg(msg) == ESENDMSGRESULT.SUC; if (SendResult == false) { DoRequest = false; return ""; } ////Data result bufferstr = graptext(); if (ReferenceEquals(bufferstr, null) || bufferstr.Trim() == "" || bufferstr.Substring(0, 2) != "E0") { DoRequest = false; return null; } string retval = ""; /* "Esc+T" 명령을 받으면 시간 동기화된 측정 값과 수학 값은 * 다음 "Esc+T" 명령을 받을 때까지 로컬 버퍼에 보관됩니다. */ //// 1st Area ////set trigger msg = '\u001B' + ("T" + "\r\n"); // "Esc+T" Command SendResult = SendMsg(msg) == ESENDMSGRESULT.SUC; if (SendResult == false) ////명령어전송을 하지못했다. 네트워크상에 문제가 생겼을수있다. { DoRequest = false; return null; } bufferstr = graptext(); if (ReferenceEquals(bufferstr, null) || bufferstr.Trim() == "" || bufferstr.Substring(0, 2) != "E0") { DoRequest = false; return null; } ////SET OUTDATA COMMAND /* LF001,160 ([프로그램설정]->설정값) : Sets the output channel for the setting parameter output, unit, and decimal place information. * (설정 매개변수 출력, 단위 및 소수 자릿수 정보에 대한 출력 채널을 설정합니다.) */ msg = System.Convert.ToString($"LF{PUB.CONFIG.meas_pri1:000},{PUB.CONFIG.meas_pri2:000}" + "\r\n"); SendResult = SendMsg(msg) == ESENDMSGRESULT.SUC; if (SendResult == false) ////명령어전송을 하지못했다. 네트워크상에 문제가 생겼을수있다. { DoRequest = false; return null; } bufferstr = graptext(); if (bufferstr.Length > 1 && bufferstr.Substring(0, 2) != "E1") { retval = bufferstr; } /////2nd AREA if(PUB.CONFIG.seconddata) { msg = '\u001B' + ("T" + "\r\n"); ////set trigger SendResult = SendMsg(msg) == ESENDMSGRESULT.SUC; if (SendResult == false) ////명령어전송을 하지못했다. 네트워크상에 문제가 생겼을수있다. { DoRequest = false; return retval; } bufferstr = graptext(); if (ReferenceEquals(bufferstr, null) || bufferstr.Trim() == "" || bufferstr.Substring(0, 2) != "E0") { DoRequest = false; return retval; } ////SET OUTDATA COMMAND /* LF201,320 ([프로그램설정]->설정값) : Sets the output channel for the setting parameter output, unit, and decimal place information. * (설정 매개변수 출력, 단위 및 소수 자릿수 정보에 대한 출력 채널을 설정합니다.) */ msg = System.Convert.ToString($"LF{PUB.CONFIG.meas_sec1:000},{PUB.CONFIG.meas_sec2:000}" + "\r\n"); SendResult = SendMsg(msg) == ESENDMSGRESULT.SUC; if (SendResult == false) ////명령어전송을 하지못했다. 네트워크상에 문제가 생겼을수있다. { DoRequest = false; return retval; } bufferstr = graptext(); if (bufferstr.Length > 1 && bufferstr.Substring(0, 2) != "E1") ////성공시에만 { if (string.IsNullOrEmpty(retval)) { retval = bufferstr; } else { retval += "\r\n" + bufferstr; } } } /////3rd AREA if (PUB.CONFIG.thirddata) { msg = '\u001B' + ("T" + "\r\n"); ////set trigger SendResult = SendMsg(msg) == ESENDMSGRESULT.SUC; if (SendResult == false) ////명령어전송을 하지못했다. 네트워크상에 문제가 생겼을수있다. { DoRequest = false; return retval; } bufferstr = graptext(); if (ReferenceEquals(bufferstr, null) || bufferstr.Trim() == "" || bufferstr.Substring(0, 2) != "E0") { DoRequest = false; return retval; } ////SET OUTDATA COMMAND /* LF401,560 ([프로그램설정]->설정값) : Sets the output channel for the setting parameter output, unit, and decimal place information. * (설정 매개변수 출력, 단위 및 소수 자릿수 정보에 대한 출력 채널을 설정합니다.) */ msg = System.Convert.ToString($"LF{PUB.CONFIG.meas_3rd1:000},{PUB.CONFIG.meas_3rd2:000}" + "\r\n"); SendResult = SendMsg(msg) == ESENDMSGRESULT.SUC; if (SendResult == false) ////명령어전송을 하지못했다. 네트워크상에 문제가 생겼을수있다. { DoRequest = false; return retval; } bufferstr = graptext(); if (bufferstr.Length > 1 && bufferstr.Substring(0, 2) != "E1") ////성공시에만 { if (string.IsNullOrEmpty(retval)) { retval = bufferstr; } else { retval += "\r\n" + bufferstr; } } } /////4th AREA if (PUB.CONFIG.getdata4) { msg = '\u001B' + ("T" + "\r\n"); ////set trigger SendResult = SendMsg(msg) == ESENDMSGRESULT.SUC; if (SendResult == false) ////명령어전송을 하지못했다. 네트워크상에 문제가 생겼을수있다. { DoRequest = false; return retval; } bufferstr = graptext(); if (ReferenceEquals(bufferstr, null) || bufferstr.Trim() == "" || bufferstr.Substring(0, 2) != "E0") { DoRequest = false; return retval; } ////SET OUTDATA COMMAND /* LF601,660 ([프로그램설정]->설정값) : Sets the output channel for the setting parameter output, unit, and decimal place information. * (설정 매개변수 출력, 단위 및 소수 자릿수 정보에 대한 출력 채널을 설정합니다.) */ msg = System.Convert.ToString($"LF{PUB.CONFIG.meas_4th1:000},{PUB.CONFIG.meas_4th2:000}" + "\r\n"); SendResult = SendMsg(msg) == ESENDMSGRESULT.SUC; if (SendResult == false) ////명령어전송을 하지못했다. 네트워크상에 문제가 생겼을수있다. { DoRequest = false; return retval; } bufferstr = graptext(); if (bufferstr.Length > 1 && bufferstr.Substring(0, 2) != "E1") ////성공시에만 { if (string.IsNullOrEmpty(retval)) { retval = bufferstr; } else { retval += "\r\n" + bufferstr; } } } DoRequest = false; return retval; } /// /// 채널의 데이터상태,(status,ch,scale,decpos,unitno,chno) /// /// /// public DataTable getChannelData() { string fullstring = GetChannelString(); DataTable CHINFO = new DataTable(); if (ReferenceEquals(fullstring, null)) { CHINFO = null; //MsgBox("채널정보를 확인할 수 없습니다" & vbCrLf & "장치와의 연결이 되지않았거나 통신오류입니다", MsgBoxStyle.Critical, "확인") } else { if (PUB.CONFIG.binarysave) { var fn = $"Channeldata{this.idx}_{DateTime.Now.ToString("yyMMddHHmmss")}.txt"; var fi = new System.IO.FileInfo(System.IO.Path.Combine(PUB.CONFIG.GetDatabasePath(), "MeasureData", fn)); fi.WriteText(fullstring); //FileSystem.WriteAllText(pub.CONFIG.databasefolder + "\\MeasureData\\Channeldata" + System.Convert.ToString(this.idx) + "_" + DateTime.Now.ToString("yyMMddHHmmss") + ".txt", fullstring, false); } } ////Return Data Structure DataTable DT = new DataTable(); DT.Columns.Add("status"); DT.Columns.Add("ch"); DT.Columns.Add("scale"); DT.Columns.Add("decpos"); DT.Columns.Add("unitno"); DT.Columns.Add("chno"); DT.Rows.Clear(); //string msg = ""; //bool SendResult = false; int chcnt = 0; foreach (string line in fullstring.Split("\r\n".ToCharArray())) { // line = System.Convert.ToString(line.Replace("\r\n", "").Replace(Constants.vbCr, "").Replace(Constants.vbLf, "")); VBConversions Warning: A foreach variable can't be assigned to in C#. if (string.IsNullOrEmpty(line)) { continue; } if (line.Length != 13) { continue; } var ds = line.Substring(0, 1); var ds2 = line.Substring(1, 1); string unitnochno = line.Substring(2, 3); string unitno = unitnochno.Substring(0, 1); string chno = unitnochno.Substring(1); string unit = line.Substring(5, 6).Trim(); string decpos = line.Substring(12, 1); if (string.IsNullOrEmpty(unitno) || string.IsNullOrEmpty(chno) || string.IsNullOrEmpty(unitnochno)) { continue; } chcnt++; ////일련번호 DT.Rows.Add(new object[] { ds, chcnt, unit, decpos, unitno, chno }); } return CHINFO; } public string graptext(bool wh = false) { //ReturnData[] Retval = null; byte[] buffer = new byte[5000]; ////readbuffer char[] c = new char[] { '|' }; if (wh) { string temp = ""; try { //ND: List newbuff = new List(0); while (myNts.DataAvailable) { myNts.Read(buffer, 0, buffer.Length); newbuff.AddRange(buffer); var temp2 = System.Text.Encoding.Default.GetString(newbuff.ToArray()); if (temp2.IndexOf("NE") != -1 && temp2.IndexOf("SE") != -1) { break; } } temp = System.Text.Encoding.Default.GetString(newbuff.ToArray()); //If temp.IndexOf("NE") = -1 AndAlso temp.IndexOf("SE") = -1 Then // MsgBox(temp) // GoTo ND //End If return temp; } catch (Exception) { return null; } } else { try { myNts.ReadTimeout = 3000; myNts.Read(buffer, 0, buffer.Length); string temp = System.Text.Encoding.Default.GetString(buffer); return temp; } catch (Exception) { return null; } } ////이데이터는 바이너리이다. } public byte[] grapbyte() { byte[] buffer = new byte[5000]; ////readbuffer ////이데이터는 바이너리이다. try { myNts.Read(buffer, 0, buffer.Length); //Dim msgbuffer As New List(Of Byte)(0) //While (1) // '//vbcrlf 가 올떄까지 읽은후 버퍼에 넣는다. // For i As Integer = 0 To buffer.Length - 1 // If Chr(buffer(i)) = vbCr OrElse Chr(buffer(i)) = vbLf Then // Array.Clear(buffer, 0, buffer.Length) // 'msgbuffer = New List(Of Byte)(0) // Exit While // Else // msgbuffer.Add(buffer(i)) // End If // Next //End While return buffer; } catch (Exception) { return null; } } /// /// 장치의 초기하를 담당한다. /// /// /// public override bool SetInit() { PUB.StatusMSG("Set DataOutput : Binary"); string bufferstr = ""; string msg = System.Convert.ToString("TS0" + "\r\n"); //// TS0 : 측정값을 요청한다 bool SendResult = SendMsg(msg) == ESENDMSGRESULT.SUC; bufferstr = graptext(); PUB.StatusMSG("Set BinaryData Order : LSB(CDAB)"); bufferstr = ""; msg = System.Convert.ToString("BO1" + "\r\n"); //// BO : Sets the byte output order. SendResult = SendMsg(msg) == ESENDMSGRESULT.SUC; bufferstr = graptext(); return true; } public override CMachine.ReturnData[] GetDataBinary(int unitchs, int unitche) { return GetDataBinary(unitchs.ToString("000"), unitche.ToString("000")); } /// /// 가공된데이터를 가져온다 /// /// /// /// /// public override CMachine.ReturnData[] GetDataBinary(string unitchs, string unitche) { ////사용불가상태라면 반환하지 않는다. if (isOn == false || isLock == true || Disc == true) { return null; } ////다른작업중이라면 기다린다. while (DoRequest) { System.Threading.Thread.Sleep(150); Application.DoEvents(); } DoRequest = true; string bufferstr = ""; string msg = "TS0\r\n"; ////TS:데이터요청방식 [0=측정데이터, 1=설정파라미터, 2=유닛정보, 5=시스템설정정보, 9=Setup mode setting parameter output] bool SendResult = SendMsg(msg) == ESENDMSGRESULT.SUC; if (SendResult == false) { DoRequest = false; return null; } bufferstr = graptext(); ////SET TRIGGER msg = '\u001B' + "T\r\n"; ////1B= ESC SendResult = SendMsg(msg) == ESENDMSGRESULT.SUC; if (SendResult == false) ////명령어전송을 하지못했다. 네트워크상에 문제가 생겼을수있따. { DoRequest = false; return null; } bufferstr = graptext(); if (bufferstr == null) { DoRequest = false; return null; } if (bufferstr.Length > 1) { string code = bufferstr.Substring(0, 2); if (code == "E1") { DoRequest = false; return null; } } else { DoRequest = false; return null; } ////SET OUTDATA COMMAND msg = $"FM1,{unitchs},{unitche}\r\n"; ////FM: 데이터방식 [0=Measured data(ASCII), 1=Math data(binary), 2=Math data(ASCII), 3=Math channel(binary)] SendResult = SendMsg(msg) == ESENDMSGRESULT.SUC; if (SendResult == false) ////명령어전송을 하지못했다. 네트워크상에 문제가 생겼을수있따. { DoRequest = false; return null; } byte[] buffer = grapbyte(); bufferstr = System.Text.Encoding.Default.GetString(buffer); if (buffer == null || buffer.Length < 1) { DoRequest = false; return null; } if (bufferstr.Length > 1 && (bufferstr.Substring(0, 2) == "E1" || bufferstr.Substring(0, 2) == "E0")) { DoRequest = false; return null; } ////Disconnect Check if (isOn == false || Disc) { DoRequest = false; return null; } ////Return DATA FORM ReturnData[] Retval = null; char[] c = new char[] { '|' }; UInt16 FrameLength = 0; System.IO.MemoryStream Ms = new System.IO.MemoryStream(buffer); System.IO.BinaryReader Br = new System.IO.BinaryReader(Ms, System.Text.Encoding.Default); if (BitConverter.IsLittleEndian) { byte[] lenbug = Br.ReadBytes(2); FrameLength = BitConverter.ToUInt16(lenbug.Reverse().ToArray(),0); } else FrameLength = Br.ReadUInt16();// BitConverter.ToUInt16(buffer, 0); if (FrameLength < 1) { Ms.Close(); Br.Close(); DoRequest = false; return null; } int DataCount = System.Convert.ToInt32((double)(FrameLength - 6) / 6); ////제거할 6바이트는 아래의 날짜 시간 정보임 Retval = new ReturnData[DataCount - 1 + 1]; ////데이터배열을 다시 변경 //bufferidx = 2; ////날짜시간정보 int syear = Br.ReadByte(); // CInt("&h" & Hex(buffer(bufferidx))) : bufferidx += 1 int smon = Br.ReadByte(); // CInt("&h" & Hex(buffer(bufferidx))) : bufferidx += 1 int sday = Br.ReadByte(); //CInt("&h" & Hex(buffer(bufferidx))) : bufferidx += 1 int shour = Br.ReadByte(); //CInt("&h" & Hex(buffer(bufferidx))) : bufferidx += 1 int smin = Br.ReadByte(); //CInt("&h" & Hex(buffer(bufferidx))) : bufferidx += 1 int ssec = Br.ReadByte(); //CInt("&h" & Hex(buffer(bufferidx))) : bufferidx += 1 ////saveorginal data format string filename = System.Convert.ToString(syear.ToString("00") + smon.ToString("00") + sday.ToString("00") + shour.ToString("00") + smin.ToString("00") + ssec.ToString("00")); if (PUB.CONFIG.binarysave) { var fi = new System.IO.FileInfo(System.IO.Path.Combine(PUB.CONFIG.GetDatabasePath(), "MeasureData", "Binary", filename + ".BIN")); if (fi.Directory.Exists == false) fi.Directory.Create(); System.IO.File.WriteAllBytes(fi.FullName, buffer); } for (int i = 0; i <= DataCount - 1; i++) { int unitno = Br.ReadByte(); ////base utni number int chno = Br.ReadByte(); ////channel number Br.ReadByte(); ////alarm level1/2 Br.ReadByte(); ////alarm level 3/4 short value = 0; if (BitConverter.IsLittleEndian) { byte[] lenbug = Br.ReadBytes(2); value = BitConverter.ToInt16(lenbug.Reverse().ToArray(), 0); } else value = Br.ReadInt16();// BitConverter.ToUInt16(buffer, 0); if (value > 32000) ////check error { value = (short)0; } Retval[i] = new ReturnData(); Retval[i].err = false; Retval[i].value = value; Retval[i].ch = (short)chno; Retval[i].unit = (short)unitno; Retval[i].time = (syear + 2000).ToString("0000") + "-" + smon.ToString("00") + "-" + sday.ToString("00") + " " + shour.ToString("00") + ":" + smin.ToString("00") + ":" + ssec.ToString("00"); if ((syear + 2000) != DateTime.Now.Year) { Retval[i].timeerror = true; } else { Retval[i].timeerror = false; } if (System.Diagnostics.Debugger.IsAttached) Console.WriteLine($"[{DateTime.Now.ToString("mm:ss.fff")}] unit:{unitno},ch:{chno}={value}"); } Ms.Close(); Br.Close(); DoRequest = false; return Retval; } /// /// 연결을시도합니다. 장치넘버와 채널번호를 할당합니다 /// /// /// override public async Task Connect() { if (myNts != null) { try { myNts.Flush(); } catch (Exception) { } try { myNts.Close(); } catch (Exception) { } } if (oSocket != null) { try { oSocket.Close(); } catch (Exception) { } } isOn = false; bool pingval = false; try { var pingSender = new Ping(); PingReply reply = await pingSender.SendPingAsync(IP); pingval = reply.Status == IPStatus.Success;// (new Microsoft.VisualBasic.Devices.Computer()).Network.Ping(IP); } catch (Exception) { PUB.log.AddE($"ping error IP:{IP}"); pingval = false; } if (pingval) { // closeDA100(rlt) try { oSocket = new TcpClient(); oSocket.Connect(IP, PORT); ////운영모드로 myNts = oSocket.GetStream(); isOn = true; } catch (Exception ex) { ////MsgBox(ex.Message.ToString) isOn = false; } } else { isOn = false; } return isOn; } /// /// 열려있는 장치를 닫고 isBusy 값이 해제된다. /// /// override public void Disconnect() { opt_lsb = false; opt_synctime = false; if (isOn == false) { return; } //if (!ReferenceEquals(ReadWorker, null)) //{ // try // { // ReadWorker.Abort(); // } // catch (Exception) // { // } //} System.Threading.Thread.Sleep(100); if (myNts != null) { try { myNts.Close(); } catch (Exception) { } } if (oSocket != null) { try { oSocket.Close(); } catch (Exception) { } } isOn = false; } public void Receive() { //Dim buffer(4999) As Byte //Dim c() As Char = {"|"c} //Dim msg() As String //Dim temp As String //Try // While (isOn) // myNts.Read(buffer, 0, buffer.Length) // temp = System.Text.Encoding.Default.GetString(buffer) // msg = temp.Split(c) // Select Case msg(0) // Case EProtocol.message '//메세지가 수신되었다. // Me.buffers = "" // Me.buffers = msg(1) // Case EProtocol.version '//버젼이 수신됨 // Me.buffers = "" // Me.buffers = msg(1) // Me.Version = msg(1) // Case EProtocol.interval // Me.bufferi = 0 // Me.bufferi = CInt(msg(1)) // Case EProtocol.channelcount // Me.bufferi = 0 // Me.bufferi = CInt(msg(1)) // Case EProtocol.gettime // Me.buffers = "" // Me.buffers = msg(1) // Case EProtocol.gettime2 // Me.bufferd = 0 // Me.bufferd = msg(1) // Case EProtocol.getdatatime // Me.buffers = "" // Me.buffers = msg(1) // Case EProtocol.getdatatime2 // Me.bufferd = 0 // Me.bufferd = msg(1) // Case EProtocol.getserial // Me.buffers = "" // Me.buffers = msg(1) // Case EProtocol.getdata // Me.bufferd = -99 // Me.bufferd2 = -99 // Me.bufferd = msg(1) // Me.bufferd2 = msg(1) // Case EProtocol.getversion // Me.buffers = "" // Me.buffers = msg(1) // 'Case Else // ' MsgBox(msg(0), MsgBoxStyle.Critical, "Sdf") // End Select // DoRequest = False // Array.Clear(buffer, 0, buffer.Length) // End While //Catch ex As Exception // Me.bufferd2 = -98 // 'MsgBox(ex.Message.ToString) //End Try } /// /// 네트워크 스트림에 데이터를 전송합니다. /// /// /// /// public ESENDMSGRESULT SendMsg(string msg) { ////운영모드에따른 네트워크 스트림할당 ////쓰기불가한상태라면 실패를 반환한다. if (myNts.CanWrite == false) { return ESENDMSGRESULT.FAIL; } try { byte[] byteSend = System.Text.Encoding.Default.GetBytes(msg.ToCharArray()); myNts.Write(byteSend, 0, byteSend.Length); myNts.Flush(); return ESENDMSGRESULT.SUC; } catch (System.IO.IOException) ////입출력오류는 연결종료로 판단한다. { return ESENDMSGRESULT.DISC; } catch (Exception) { //MsgBox(ex.ToString, MsgBoxStyle.Critical, "sendmsg") return ESENDMSGRESULT.FAIL; } //return ESENDMSGRESULT.FAIL; } /// /// /// /// /// /// /// public ESENDMSGRESULT SendByte(byte[] SendB, bool isoperation) { ////쓰기불가한상태라면 실패를 반환한다. if (myNts.CanWrite == false) return ESENDMSGRESULT.FAIL; try { myNts.Write(SendB, 0, SendB.Length); myNts.Flush(); return ESENDMSGRESULT.SUC; } catch (System.IO.IOException) ////입출력오류는 연결종료로 판단한다. { return ESENDMSGRESULT.DISC; } catch (Exception) { return ESENDMSGRESULT.FAIL; } } } }