/// <summary>
        /// Qna_3E地址解析
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        private MitsubishiMCAddress ConvertArg_Qna_3E(string address)
        {
            address = address.ToUpper();
            var addressInfo = new MitsubishiMCAddress();

            switch (address[0])
            {
            case 'M':    //M中间继电器
            {
                addressInfo.TypeCode     = new byte[] { 0x90 };
                addressInfo.DataType     = 0x01;
                addressInfo.Format       = 10;
                addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format);
            }
            break;

            case 'X':    // X输入继电器
            {
                addressInfo.TypeCode     = new byte[] { 0x9C };
                addressInfo.DataType     = 0x01;
                addressInfo.Format       = 16;
                addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format);
            }
            break;

            case 'Y':    //Y输出继电器
            {
                addressInfo.TypeCode     = new byte[] { 0x9D };
                addressInfo.DataType     = 0x01;
                addressInfo.Format       = 16;
                addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format);
            }
            break;

            case 'D':    //D数据寄存器
            {
                addressInfo.TypeCode     = new byte[] { 0xA8 };
                addressInfo.DataType     = 0x00;
                addressInfo.Format       = 10;
                addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format);
            }
            break;

            case 'W':    //W链接寄存器
            {
                addressInfo.TypeCode     = new byte[] { 0xB4 };
                addressInfo.DataType     = 0x00;
                addressInfo.Format       = 16;
                addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format);
            }
            break;

            case 'L':    //L锁存继电器
            {
                addressInfo.TypeCode     = new byte[] { 0x92 };
                addressInfo.DataType     = 0x01;
                addressInfo.Format       = 10;
                addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format);
            }
            break;

            case 'F':    //F报警器
            {
                addressInfo.TypeCode     = new byte[] { 0x93 };
                addressInfo.DataType     = 0x01;
                addressInfo.Format       = 10;
                addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format);
            }
            break;

            case 'V':    //V边沿继电器
            {
                addressInfo.TypeCode     = new byte[] { 0x94 };
                addressInfo.DataType     = 0x01;
                addressInfo.Format       = 10;
                addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format);
            }
            break;

            case 'B':    //B链接继电器
            {
                addressInfo.TypeCode     = new byte[] { 0xA0 };
                addressInfo.DataType     = 0x01;
                addressInfo.Format       = 16;
                addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format);
            }
            break;

            case 'R':    //R文件寄存器
            {
                addressInfo.TypeCode     = new byte[] { 0xAF };
                addressInfo.DataType     = 0x00;
                addressInfo.Format       = 10;
                addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format);
            }
            break;

            case 'S':
            {
                //累计定时器的线圈
                if (address[1] == 'C')
                {
                    addressInfo.TypeCode     = new byte[] { 0xC6 };
                    addressInfo.DataType     = 0x01;
                    addressInfo.Format       = 10;
                    addressInfo.BeginAddress = Convert.ToInt32(address.Substring(2), addressInfo.Format);
                }
                //累计定时器的触点
                else if (address[1] == 'S')
                {
                    addressInfo.TypeCode     = new byte[] { 0xC7 };
                    addressInfo.DataType     = 0x01;
                    addressInfo.Format       = 10;
                    addressInfo.BeginAddress = Convert.ToInt32(address.Substring(2), addressInfo.Format);
                }
                //累计定时器的当前值
                else if (address[1] == 'N')
                {
                    addressInfo.TypeCode     = new byte[] { 0xC8 };
                    addressInfo.DataType     = 0x00;
                    addressInfo.Format       = 100;
                    addressInfo.BeginAddress = Convert.ToInt32(address.Substring(2), addressInfo.Format);
                }
                // S步进继电器
                else
                {
                    addressInfo.TypeCode     = new byte[] { 0x98 };
                    addressInfo.DataType     = 0x01;
                    addressInfo.Format       = 10;
                    addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format);
                }
                break;
            }

            case 'Z':
            {
                //文件寄存器ZR区
                if (address[1] == 'R')
                {
                    addressInfo.TypeCode     = new byte[] { 0xB0 };
                    addressInfo.DataType     = 0x00;
                    addressInfo.Format       = 16;
                    addressInfo.BeginAddress = Convert.ToInt32(address.Substring(2), addressInfo.Format);
                }
                //变址寄存器
                else
                {
                    addressInfo.TypeCode     = new byte[] { 0xCC };
                    addressInfo.DataType     = 0x00;
                    addressInfo.Format       = 10;
                    addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format);
                }
                break;
            }

            case 'T':
            {
                // 定时器的当前值
                if (address[1] == 'N')
                {
                    addressInfo.TypeCode     = new byte[] { 0xC2 };
                    addressInfo.DataType     = 0x00;
                    addressInfo.Format       = 10;
                    addressInfo.BeginAddress = Convert.ToInt32(address.Substring(2), addressInfo.Format);
                }
                //定时器的触点
                else if (address[1] == 'S')
                {
                    addressInfo.TypeCode     = new byte[] { 0xC1 };
                    addressInfo.DataType     = 0x01;
                    addressInfo.Format       = 10;
                    addressInfo.BeginAddress = Convert.ToInt32(address.Substring(2), addressInfo.Format);
                }
                //定时器的线圈
                else if (address[1] == 'C')
                {
                    addressInfo.TypeCode     = new byte[] { 0xC0 };
                    addressInfo.DataType     = 0x01;
                    addressInfo.Format       = 10;
                    addressInfo.BeginAddress = Convert.ToInt32(address.Substring(2), addressInfo.Format);
                }
                break;
            }

            case 'C':
            {
                //计数器的当前值
                if (address[1] == 'N')
                {
                    addressInfo.TypeCode     = new byte[] { 0xC5 };
                    addressInfo.DataType     = 0x00;
                    addressInfo.Format       = 10;
                    addressInfo.BeginAddress = Convert.ToInt32(address.Substring(2), addressInfo.Format);
                }
                //计数器的触点
                else if (address[1] == 'S')
                {
                    addressInfo.TypeCode     = new byte[] { 0xC4 };
                    addressInfo.DataType     = 0x01;
                    addressInfo.Format       = 10;
                    addressInfo.BeginAddress = Convert.ToInt32(address.Substring(2), addressInfo.Format);
                }
                //计数器的线圈
                else if (address[1] == 'C')
                {
                    addressInfo.TypeCode     = new byte[] { 0xC3 };
                    addressInfo.DataType     = 0x01;
                    addressInfo.Format       = 10;
                    addressInfo.BeginAddress = Convert.ToInt32(address.Substring(2), addressInfo.Format);
                }
                break;
            }
            }
            return(addressInfo);
        }
        /// <summary>
        /// 读取数据
        /// </summary>
        /// <param name="address">地址</param>
        /// <param name="length"></param>
        /// <param name="isBit"></param>
        /// <param name="setEndian"></param>
        /// <returns></returns>
        public Result <byte[]> Read(string address, ushort length, bool isBit = false, bool setEndian = true)
        {
            if (!socket?.Connected ?? true)
            {
                Connect();
            }
            var result = new Result <byte[]>();

            try
            {
                //发送读取信息
                MitsubishiMCAddress arg = null;
                byte[] command          = null;

                switch (version)
                {
                case MitsubishiVersion.A_1E:
                    arg     = ConvertArg_A_1E(address);
                    command = GetReadCommand_A_1E(arg.BeginAddress, arg.TypeCode, length, isBit);
                    break;

                case MitsubishiVersion.Qna_3E:
                    arg     = ConvertArg_Qna_3E(address);
                    command = GetReadCommand_Qna_3E(arg.BeginAddress, arg.TypeCode, length, isBit);
                    break;
                }
                result.Requst = string.Join(" ", command.Select(t => t.ToString("X2")));

                Result <byte[]> sendResult = new Result <byte[]>();
                switch (version)
                {
                case MitsubishiVersion.A_1E:
                    var lenght = command[10] + command[11] * 256;
                    if (isBit)
                    {
                        sendResult = SendPackage(command, (int)Math.Ceiling(lenght * 0.5) + 2);
                    }
                    else
                    {
                        sendResult = SendPackage(command, lenght * 2 + 2);
                    }
                    break;

                case MitsubishiVersion.Qna_3E:
                    sendResult = SendPackage(command);
                    break;
                }
                if (!sendResult.IsSucceed)
                {
                    return(sendResult);
                }

                byte[] dataPackage = sendResult.Value;
                result.Response = string.Join(" ", dataPackage.Select(t => t.ToString("X2")));

                var    bufferLength  = length;
                byte[] responseValue = null;

                switch (version)
                {
                case MitsubishiVersion.A_1E:
                    responseValue = new byte[dataPackage.Length - 2];
                    Array.Copy(dataPackage, 2, responseValue, 0, responseValue.Length);
                    break;

                case MitsubishiVersion.Qna_3E:

                    if (isBit)
                    {
                        bufferLength = (ushort)Math.Ceiling(bufferLength * 0.5);
                    }
                    responseValue = new byte[bufferLength];
                    Array.Copy(dataPackage, dataPackage.Length - bufferLength, responseValue, 0, bufferLength);
                    break;
                }

                result.Value = responseValue;
            }
            catch (SocketException ex)
            {
                result.IsSucceed = false;
                if (ex.SocketErrorCode == SocketError.TimedOut)
                {
                    result.Err = "连接超时";
                    result.ErrList.Add("连接超时");
                }
                else
                {
                    result.Err = ex.Message;
                    result.ErrList.Add(ex.Message);
                }
                socket?.SafeClose();
            }
            finally
            {
                if (isAutoOpen)
                {
                    Dispose();
                }
            }
            return(result.EndTime());
        }
        /// <summary>
        /// 写入数据
        /// </summary>
        /// <param name="address"></param>
        /// <param name="data"></param>
        /// <param name="isBit"></param>
        /// <returns></returns>
        public Result Write(string address, byte[] data, bool isBit = false)
        {
            if (!socket?.Connected ?? true)
            {
                var connectResult = Connect();
                if (!connectResult.IsSucceed)
                {
                    return(connectResult);
                }
            }
            Result result = new Result();

            try
            {
                Array.Reverse(data);

                //发送写入信息
                MitsubishiMCAddress arg = null;
                byte[] command          = null;
                switch (version)
                {
                case MitsubishiVersion.A_1E:
                    arg     = ConvertArg_A_1E(address);
                    command = GetWriteCommand_A_1E(arg.BeginAddress, arg.TypeCode, data, isBit);
                    break;

                case MitsubishiVersion.Qna_3E:
                    arg     = ConvertArg_Qna_3E(address);
                    command = GetWriteCommand_Qna_3E(arg.BeginAddress, arg.TypeCode, data, isBit);
                    break;
                }
                result.Requst = string.Join(" ", command.Select(t => t.ToString("X2")));

                Result <byte[]> sendResult = new Result <byte[]>();
                switch (version)
                {
                case MitsubishiVersion.A_1E:
                    sendResult = SendPackage(command, 2);
                    break;

                case MitsubishiVersion.Qna_3E:
                    sendResult = SendPackage(command);
                    break;
                }
                if (!sendResult.IsSucceed)
                {
                    return(sendResult);
                }

                byte[] dataPackage = sendResult.Value;
                result.Response = string.Join(" ", dataPackage.Select(t => t.ToString("X2")));
            }
            catch (SocketException ex)
            {
                result.IsSucceed = false;
                if (ex.SocketErrorCode == SocketError.TimedOut)
                {
                    result.Err = "连接超时";
                    result.ErrList.Add("连接超时");
                }
                else
                {
                    result.Err       = ex.Message;
                    result.Exception = ex;
                    result.ErrList.Add(ex.Message);
                }
                socket?.SafeClose();
            }
            catch (Exception ex)
            {
                result.IsSucceed = false;
                result.Err       = ex.Message;
                result.Exception = ex;
                result.ErrList.Add(ex.Message);
                socket?.SafeClose();
            }
            finally
            {
                if (isAutoOpen)
                {
                    Dispose();
                }
            }
            return(result.EndTime());
        }
        /// <summary>
        /// A_1E地址解析
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        private MitsubishiMCAddress ConvertArg_A_1E(string address)
        {
            address = address.ToUpper();
            var addressInfo = new MitsubishiMCAddress();

            switch (address[0])
            {
            case 'X':    //X输入寄存器
            {
                addressInfo.TypeCode     = new byte[] { 0x58, 0x20 };
                addressInfo.DataType     = 0x01;
                addressInfo.Format       = 8;
                addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format);
            }
            break;

            case 'Y':    //Y输出寄存器
            {
                addressInfo.TypeCode     = new byte[] { 0x59, 0x20 };
                addressInfo.DataType     = 0x01;
                addressInfo.Format       = 8;
                addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format);
            }
            break;

            case 'M':    //M中间寄存器
            {
                addressInfo.TypeCode     = new byte[] { 0x4D, 0x20 };
                addressInfo.DataType     = 0x01;
                addressInfo.Format       = 10;
                addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format);
            }
            break;

            case 'S':    //S状态寄存器
            {
                addressInfo.TypeCode     = new byte[] { 0x53, 0x20 };
                addressInfo.DataType     = 0x01;
                addressInfo.Format       = 10;
                addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format);
            }
            break;

            case 'D':    //D数据寄存器
            {
                addressInfo.TypeCode     = new byte[] { 0x44, 0x20 };
                addressInfo.DataType     = 0x00;
                addressInfo.Format       = 10;
                addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format);
            }
            break;

            case 'R':    //R文件寄存器
            {
                addressInfo.TypeCode     = new byte[] { 0x52, 0x20 };
                addressInfo.DataType     = 0x00;
                addressInfo.Format       = 10;
                addressInfo.BeginAddress = Convert.ToInt32(address.Substring(1), addressInfo.Format);
            }
            break;
            }
            return(addressInfo);
        }