/// <summary>
        /// 组帧
        /// </summary>
        /// <param name="obis">obis码</param>
        /// <param name="isWrite">true:WriteCommand, false:ReadCommand</param>
        /// <param name="parameter">obis参数</param>
        /// <returns>待发送的数据帧</returns>
        private byte[] GetCommand(string obis, bool isWrite, string parameter)
        {
            List <byte> command = new List <byte>();

            if (isWrite)
            {
                command.AddRange(new byte[] { 0x01, 0x57, 0x31, 0x02 }); //SOH W1 STX
            }
            else
            {
                command.AddRange(new byte[] { 0x01, 0x52, 0x31, 0x02 }); //SOH R1 STX
            }

            command.AddRange(Encoding.ASCII.GetBytes(obis)); //OBIS码

            command.Add(0x28);                               //左括号
            if (!string.IsNullOrEmpty(parameter))
            {
                command.AddRange(Encoding.ASCII.GetBytes(parameter)); //obis参数
            }
            command.Add(0x29);                                        //右括号
            command.Add(0x03);                                        //ETX

            //计算数据帧的BCC值
            byte bcc = IecBcc.Calculate(command.ToArray(), 1, command.Count - 1);

            command.Add(bcc); //BCC

            return(command.ToArray());
        }
        public void Write(string obis, byte[] binData, uint address)
        {
            List <byte> sendBuffer = new List <byte>();

            sendBuffer.AddRange(new byte[] { 0x01, 0x57, 0x31, 0x02 });
            sendBuffer.AddRange(Encoding.ASCII.GetBytes(obis));

            sendBuffer.AddRange(new byte[] { 0x28, 0x30, 0x78 }); //左括号

            sendBuffer.AddRange(Encoding.ASCII.GetBytes(address.ToString("X")));
            sendBuffer.Add(0x2C);

            StringBuilder sb = new StringBuilder();

            foreach (byte b in binData)
            {
                sb.AppendFormat("{0:X2}", b);
            }
            //sendBuffer.AddRange(binData);
            sendBuffer.AddRange(Encoding.ASCII.GetBytes(sb.ToString()));

            sendBuffer.Add(0x29); //右括号
            sendBuffer.Add(0x03); //ETX

            //计算数据帧的BCC值
            byte bcc = IecBcc.Calculate(sendBuffer.ToArray(), 1, sendBuffer.Count - 1);

            sendBuffer.Add(bcc); //BCC

            WriteCommand(sendBuffer.ToArray(), timeoutValue);
        }
        /// <summary>
        /// 解析完整应答信息
        /// </summary>
        /// <param name="recvData">应答数据帧</param>
        /// <returns>返回应答信息括号里面的内容</returns>
        public string ParseReply(byte[] recvData)
        {
            int head = Array.IndexOf(recvData, (byte)0x02);
            int tail = Array.IndexOf(recvData, (byte)0x03);

            if (head == -1 || tail == -1 || tail - head < 3) //未找到帧头、帧尾,数据帧不完整。完整帧:STX (data) ETX BCC,至少6位
            {
                throw new CommunicationException(Resources.IncompleteData);
            }

            //计算数据帧BCC值
            byte bcc = IecBcc.Calculate(recvData, head + 1, tail);

            if (tail == recvData.Length - 1) //无校验位
            {
                throw new CommunicationException(Resources.IncorrectResponse);
            }

            //检验失败,BCC错误
            if (bcc != recvData[tail + 1])
            {
                throw new CommunicationException(Resources.IncorrectResponse);
            }

            //以下处理的是正确帧

            //找左括号
            int leftBracketIndex = Array.IndexOf(recvData, (byte)0x28);
            //找右括号
            int rightBracketIndex = Array.IndexOf(recvData, (byte)0x29);

            byte[] resultArray = new byte[rightBracketIndex - leftBracketIndex - 1];

            //将括号里的内容拷贝到结果数组resultArray中
            Array.ConstrainedCopy(recvData, leftBracketIndex + 1, resultArray, 0, rightBracketIndex - leftBracketIndex - 1);

            return(Encoding.ASCII.GetString(resultArray));
        }