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 AR;
using System.Net.NetworkInformation;
using System.Threading.Tasks;

//###########################################################################################
//##
//##   작성자 : tindevil(tindevil@nate.com , tindevil@jdtek.co.kr)
//##   소유자 : 작성자 , JDTEK
//##   최초작성일 : 2011-11-16
//##   설명 : DA100사용을 위한 데이터변경
//##
//###########################################################################################
namespace vmsnet
{

    public class CDA100 : CMachine
    {

        public bool opt_synctime { get; set; } = false;
        public bool opt_lsb { get; set; } = false;
        //Private Const STATUSPORT = "34159"      '//connetion infomation port
        //Private Const REALPORT = "34151"        '//datareceive port
        private string DATAPORT = "34150"; ////OPeration PORT

        System.Net.Sockets.TcpClient oSocket; ////데이터전송포트
                                              //WithEvents oSocketOP As System.Net.Sockets.TcpClient    '//데이터운영모드

        NetworkStream myNts; ////데이터수집용
                             //WithEvents myNtsOP As NetworkStream     '//운영모드용

        //System.Threading.Thread ReadWorker; ////데이터수신을위한 쓰레드(데이터)
        //WithEvents ReadWorkerOP As Threading.Thread  '//데이터수신을위한 쓰레드(운영)

        //string Version;

       

        ////데이터출력변수
        //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 bool disableitem = true;
        public long deadstart; ////연결종료된 시간

        /// <summary>
        /// Create
        /// </summary>
        /// <param name="p_ip"></param>
        /// <remarks></remarks>
        public CDA100(string p_ip, int p_port, string p_title, string p_chcount, int p_rowindex) : base(p_ip, p_port, "DA100")
        {
            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");
            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;
        }


        /// <summary>
        /// 날짜를 현재의 컴퓨터와 동기화 시킨다.
        /// </summary>
        /// <returns></returns>
        /// <remarks></remarks>
        public override bool SyncDate()
        {
            bool Retval = false;

            ////사용불가상태라면 반환하지 않는다.
            if (isOn == false || isLock == true)
            {
                return false;
            }

            ////다른작업중이라면 기다린다.
            while (DoRequest)
            {
                System.Threading.Thread.Sleep(50);
                Application.DoEvents();
            }
            DoRequest = true;

            ////시간동기화중
            PUB.workmsg("시간 동기화중");

            ////시간변경명령어
            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;
        }

        /// <summary>
        /// 장치를 재구성합니다.
        /// </summary>
        /// <returns></returns>
        /// <remarks></remarks>
        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");
            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;
        }


        /// <summary>
        /// 각채널의 VOLT 및 KA디바이스정보를 설정합니다.
        /// </summary>
        /// <param name="kadevice">KA장치의 정보를 반환(1,0,30 / 1,1,30)</param>
        /// <returns></returns>
        /// <remarks></remarks>
        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 = true;

            ////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");
                //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);
        }


        /// <summary>
        /// get channel data 가 쓰는 함수로서 문자열 데이터를 가져온다.
        /// </summary>
        /// <returns></returns>
        /// <remarks></remarks>
        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"); ////unit data
            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 = "";

            ////set trigger
            msg = '\u001B' + ("T" + "\r\n");
            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
            msg = System.Convert.ToString("LF001,260" + "\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;
            }

            /////SECOND AREA
            ////set trigger
            msg = '\u001B' + ("T" + "\r\n");
            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
            msg = System.Convert.ToString("LF301,560" + "\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;
        }

        /// <summary>
        /// 채널의 데이터상태,(status,ch,scale,decpos,unitno,chno)
        /// </summary>
        /// <returns></returns>
        /// <remarks></remarks>
        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{idx}_{DateTime.Now.ToString("yyMMddHHmmss")}.txt";
                    fn += System.IO.Path.Combine(PUB.CONFIG.GetDatabasePath(), "MeasureData", "Channeldata", fn);
                    var fi = new System.IO.FileInfo(fn);
                    fi.WriteText(fullstring);
                    //(new Microsoft.VisualBasic.Devices.ServerComputer()).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<byte> newbuff = new List<byte>(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.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;
            }
        }


        /// <summary>
        /// 장치의 초기하를 담당한다.
        /// </summary>
        /// <returns></returns>
        /// <remarks></remarks>
        public override bool SetInit()
        {


            PUB.StatusMSG("Set DataOutput : Binary");

            string bufferstr = "";
            string msg = System.Convert.ToString("TS0" + "\r\n");
            bool SendResult = SendMsg(msg) == ESENDMSGRESULT.SUC;
            bufferstr = graptext();


            PUB.StatusMSG("Set BinaryData Order : LSB(CDAB)");

            bufferstr = "";
            msg = System.Convert.ToString("BO1" + "\r\n");
            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"));
        }
        /// <summary>
        /// 가공된데이터를 가져온다
        /// </summary>
        /// <param name="unitchs"></param>
        /// <param name="unitche"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public override CMachine.ReturnData[] GetDataBinary(string unitchs, string unitche)
        {
            ////사용불가상태라면 반환하지 않는다.
            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("TS0" + "\r\n");
            bool SendResult = SendMsg(msg) == ESENDMSGRESULT.SUC;
            if (SendResult == false)
            {
                DoRequest = false;
                return null;
            }
            bufferstr = graptext();

            ////SET TRIGGER
            msg = '\u001B' + ("T" + "\r\n");
            SendResult = SendMsg(msg) == ESENDMSGRESULT.SUC;
            if (SendResult == false) ////명령어전송을 하지못했다. 네트워크상에 문제가 생겼을수있따.
            {
                DoRequest = false;
                return null;
            }
            bufferstr = graptext();
            if (ReferenceEquals(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 = System.Convert.ToString("FM1," + unitchs + "," + unitche + "\r\n");
            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.GetUpperBound(0) < 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[] { '|' };

            var Ms = new System.IO.MemoryStream(buffer);
            var Br = new System.IO.BinaryReader(Ms, System.Text.Encoding.Default);

            ////dataread
            //   int bufferidx = 0;
            int datalength = Br.ReadUInt16();

            if (datalength < 1)
            {
                Ms.Close();
                Br.Close();
                DoRequest = false;
                return null;
            }

            //datalength = CInt("&h" & Hex(buffer(0)).Trim & Hex(buffer(1)).Trim)


            int DataCount = System.Convert.ToInt32((double)(datalength - 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 fn = System.IO.Path.Combine(PUB.CONFIG.GetDatabasePath(), "MeasureData", "Binary", $"{filename}.BIN");
                System.IO.File.WriteAllBytes(fn, buffer);
                //(new Microsoft.VisualBasic.Devices.ServerComputer()).FileSystem.WriteAllBytes(pub.CONFIG.databasefolder + "\\MeasureData\\Binary\\" + filename + ".BIN", buffer, false);
            }

            for (int i = 0; i <= DataCount - 1; i++)
            {
                int unitno = Br.ReadByte(); ////base utni number
                int chno = Br.ReadByte(); ////channel number
                int c1 = Br.ReadByte(); ////alarm level1/2
                int d1 = Br.ReadByte(); ////alarm level 3/4
                ushort value = Br.ReadUInt16(); ////measure data

                if (value > 32000) ////check error
                {
                    value = 0;// System.Convert.ToUInt16(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");
                Retval[i].time = $"{(syear + 2000):0000}-{smon:00}-{sday:00} {shour:00}:{smin:00}:{ssec:00}";

                if ((syear + 2000) != DateTime.Now.Year)
                {
                    Retval[i].timeerror = true;
                }
                else
                {
                    Retval[i].timeerror = false;
                }

            }

            Ms.Close();
            Br.Close();

            DoRequest = false;
            return Retval;


        }



        /// <summary>
        /// 연결을시도합니다. 장치넘버와 채널번호를 할당합니다
        /// </summary>
        /// <returns></returns>
        /// <remarks></remarks>
        override public async Task<bool> Connect()
        {

            try
            {
                if(myNts != null) myNts.Flush();
            }
            catch (Exception)
            {

            }
            try
            {
                if (myNts != null) myNts.Close();
            }
            catch (Exception)
            {

            }
            try
            {
                if (oSocket != null) 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;
            }
            catch (Exception)
            {
                PUB.log.AddE($"ping error IP:{IP}");
                pingval = false;
            }

            if (pingval)
            {
                // closeDA100(rlt)
                try
                {
                    oSocket = new TcpClient();
                    oSocket.Connect(IP, int.Parse(DATAPORT)); ////운영모드로
                    myNts = oSocket.GetStream();
                    isOn = true;
                }
                catch (Exception)
                {
                    ////MsgBox(ex.Message.ToString)
                    isOn = false;
                }
            }
            else
            {
                isOn = false;
            }
            return isOn;

        }

        /// <summary>
        /// 열려있는 장치를 닫고 isBusy 값이 해제된다.
        /// </summary>
        /// <remarks></remarks>
        override public void Disconnect()
        {
            opt_lsb = false;
            opt_synctime = false;
            if (isOn == false)
            {
                return;
            }
            //try
            //{
            //    ReadWorker.Abort();
            //}
            //catch (Exception)
            //{

            //}
            //System.Threading.Thread.Sleep(100);
            try
            {
                if(myNts != null)
                myNts.Close();
            }
            catch (Exception)
            {

            }
            try
            {
                if (oSocket != null)
                    oSocket.Close();
            }
            catch (Exception)
            {

            }
            isOn = false;

        }



        /// <summary>
        /// 네트워크 스트림에 데이터를 전송합니다.
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        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;
        }



        /// <summary>
        ///
        /// </summary>
        /// <param name="SendB"></param>
        /// <param name="isoperation"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        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)
            {
                //MsgBox(ex.ToString, MsgBoxStyle.Critical, "sendmsg")
                return ESENDMSGRESULT.FAIL;
            }


            //return ESENDMSGRESULT.FAIL;
        }

    }

}
