using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MegaRobo.C00225155.ControlDevices
{
    /// <summary>
    /// 高温温度模块 485 uart 定制HCM通信协议封装类（PC→主控板指令构建 + 主控板→PC指令解析）
    /// </summary>
    public static class LowTemperatureUartHCM
    {
        #region 协议常量定义（码表及指令规范）
        private const byte ST = 0x5E;               // 帧头
        private const byte HELLO = 0x01;            // 握手指令
        private const byte STATUS = 0x05;           // 读取报错状态
        private const byte SETTEMP = 0x06;          // 制冷温度控制
        private const byte MOTOR = 0x07;            // 电机控制
        private const byte RDTEMP = 0x08;           // 读取温度
        private const byte RDADC = 0x09;            // 读取传感器AD
        private const byte RDEE = 0x11;             // 读取EEPROM
        private const byte WREE = 0x12;             // 写入EEPROM
        private const byte RDMotSpeed = 0x13;       // 获取实际转速
        private const byte RDIOStatus = 0x14;       // 获取开关盖状态
        private const byte Calb = 0x15;             // 校准温度
        private const byte SETHOTTEMP = 0x16;       // 加热温度控制（补充遗漏指令）
        private const byte RelayControl = 0x17;     // 电磁阀控制（补充遗漏指令）
        private const byte RESPONSE_FLAG = 0x80;    // 上传指令标志（指令码 | 0x80）
        #endregion

        #region 
        private static byte _cmdSequence = 0;              // 指令序号（0-255自动溢出）
        private static readonly object _lock = new object();// 线程安全锁（避免多线程序号混乱）
        #endregion

        #region 校验和计算（协议第6点：前n-1字节之和的低8位）
        /// <summary>
        /// 计算帧的校验和（核心：前length字节之和的低8位）
        /// </summary>
        /// <param name="data">待计算的帧数据</param>
        /// <param name="length">参与计算的字节数（前n-1字节）</param>
        /// <returns>校验和字节</returns>
        private static byte CalculateChecksum(byte[] data, int length)
        {
            if (data == null || length <= 0 || length > data.Length)
                throw new ArgumentException("校验和计算参数无效");

            int sum = 0;
            for (int i = 0; i < length; i++)
                sum += data[i];
            return (byte)(sum & 0xFF); // 取低8位，确保是1字节
        }
        #endregion

        #region 指令序号自增（线程安全）
        /// <summary>
        /// 指令序号自增（0-255自动溢出，确保除溢出外无重复指令）
        /// </summary>
        private static void IncrementCmdSequence()
        {
            lock (_lock)
            {
                _cmdSequence++; // 字节类型自动溢出（255→0）

                // 确保序号不超过0x7F（避免下发指令CMD被误认为上传指令）
                if (_cmdSequence >= 0x80)
                    _cmdSequence = 0;
            }
        }

        /// <summary>
        /// 获取当前指令序号（带线程安全）
        /// </summary>
        private static byte GetCurrentCmdSequence()
        {
            lock (_lock)
            {
                return _cmdSequence;
            }
        }
        #endregion

        #region 下传指令构建（PC→主控板，返回byte[]帧）
        /// <summary>
        /// 握手指令（系统开机必发）
        /// </summary>
        /// <param name="deviceId">设备ID（0-255，默认0）</param>
        /// <returns>握手指令帧（5字节）</returns>
        public static byte[] SendHello(byte deviceId = 0)
        {
            byte[] frame = new byte[5]; // 帧长固定5字节
            byte seq = GetCurrentCmdSequence();

            // 按协议填充帧结构：ST → HELLO+序号 → 设备ID → LTH=5 → 校验和
            frame[0] = ST;
            frame[1] = (byte)(HELLO | seq);
            frame[2] = deviceId;
            frame[3] = 5; // LTH固定为5
            frame[4] = CalculateChecksum(frame, 4); // 前4字节求和取低8位

            IncrementCmdSequence(); // 序号自增
            AddFrameInterval(); // 帧间隔>2ms
            return frame;
        }

        /// <summary>
        /// 读取报错状态指令
        /// </summary>
        /// <param name="deviceId">设备ID（0-255，默认0）</param>
        /// <returns>报错状态指令帧（5字节）</returns>
        public static byte[] SendStatusRequest(byte deviceId = 0)
        {
            byte[] frame = new byte[5]; // 帧长固定5字节
            byte seq = GetCurrentCmdSequence();

            // 帧结构：ST → STATUS+序号 → 设备ID → LTH=5 → 校验和
            frame[0] = ST;
            frame[1] = (byte)(STATUS | seq);
            frame[2] = deviceId;
            frame[3] = 5; // LTH固定为5
            frame[4] = CalculateChecksum(frame, 4);

            IncrementCmdSequence();
            AddFrameInterval();
            return frame;
        }

        /// <summary>
        /// 温度控制指令（下发后主控板直接执行温度控制）
        /// </summary>
        /// <param name="targetTemp">目标温度（10.0-180.0℃，精度0.1）</param>
        /// <param name="deviceId">设备ID（0-255，默认0）</param>
        /// <param name="releaseControl">是否释放控制（true=0xFFFF，关断功率）关闭温度</param>
        /// <returns>温度控制指令帧（7字节）</returns>
        public static byte[] SendSetTemp(double targetTemp, byte deviceId = 0, bool releaseControl=false)
        {
            byte[] frame = new byte[7]; // 帧长固定7字节
            byte seq = GetCurrentCmdSequence();
            int tempParam = 0; // 温度参数（16位：高8位+低8位）

            // 处理参数：释放控制/正常温度
            if (releaseControl)
            {
                tempParam = 0xFFFF; // 协议约定：释放控制=0xFFFF
            }
            else
            {
                // 参数校验：温度范围10.0-180.0℃（对应1000-18000）
                if (targetTemp < -50.0 || targetTemp > 50.0)
                    throw new ArgumentOutOfRangeException(nameof(targetTemp), "温度必须在[-50 , 50]℃之间");
                tempParam = (short)(targetTemp * 100); // 放大100倍（精度0.1）
            }

            // 帧结构：ST → SETTEMP+序号 → 设备ID → LTH=7 → 参数1(高8) → 参数2(低8) → 校验和
            frame[0] = ST;
            frame[1] = (byte)(SETTEMP | seq);
            frame[2] = deviceId;
            frame[3] = 7; // LTH固定为7
            frame[4] = (byte)(tempParam >> 8); // 参数1（高8位）
            frame[5] = (byte)(tempParam & 0xFF); // 参数2（低8位）
            frame[6] = CalculateChecksum(frame, 6); // 前6字节求和

            IncrementCmdSequence();
            AddFrameInterval();
            return frame;
        }

        /// <summary>
        /// 电机控制指令（设置电机转速）
        /// </summary>
        /// <param name="motorSpeed">电机转速（200-1500，16位参数）</param>
        /// <param name="deviceId">设备ID（0-255，默认0）</param>
        /// <returns>电机控制指令帧（11字节，0x0B=11）</returns>
        public static byte[] SendMotorControl(int motorSpeed, byte deviceId = 0)
        {
            // 参数校验：转速范围100-1500
            if (motorSpeed < 100 || motorSpeed > 1500)
                throw new ArgumentOutOfRangeException(nameof(motorSpeed), "转速必须在100-1500之间");

            byte[] frame = new byte[11]; // 帧长固定0x0B（11字节）
            byte seq = GetCurrentCmdSequence();
            ushort speedParam = (ushort)motorSpeed; // 转速参数（16位）

            // 帧结构：ST → MOTOR+序号 → 设备ID → LTH=0x0B → 0x10 → 预留0×3 → 参数4(高8) → 参数5(低8) → 校验和
            frame[0] = ST;
            frame[1] = (byte)(MOTOR | seq);
            frame[2] = deviceId;
            frame[3] = 0x0B; // LTH固定为11
            frame[4] = 0x10; // 协议固定值
            frame[5] = 0;    // 预留位1
            frame[6] = 0;    // 预留位2
            frame[7] = 0;    // 预留位3
            frame[8] = (byte)(speedParam >> 8); // 参数4（高8位）
            frame[9] = (byte)(speedParam & 0xFF); // 参数5（低8位）
            frame[10] = CalculateChecksum(frame, 10); // 前10字节求和

            IncrementCmdSequence();
            AddFrameInterval();
            return frame;
        }

        /// <summary>
        /// 读取温度指令（获取设置温度、实际温度、到温标志）
        /// </summary>
        /// <param name="deviceId">设备ID（0-255，默认0）</param>
        /// <returns>读取温度指令帧（5字节）</returns>
        public static byte[] SendReadTempRequest(byte deviceId = 0)
        {
            byte[] frame = new byte[5]; // 帧长固定5字节
            byte seq = GetCurrentCmdSequence();

            // 帧结构：ST → RDTEMP+序号 → 设备ID → LTH=5 → 校验和
            frame[0] = ST;
            frame[1] = (byte)(RDTEMP | seq);
            frame[2] = deviceId;
            frame[3] = 5; // LTH固定为5
            frame[4] = CalculateChecksum(frame, 4);

            IncrementCmdSequence();
            AddFrameInterval();
            return frame;
        }

        /// <summary>
        /// 读取传感器AD指令（获取AD值）
        /// </summary>
        /// <param name="deviceId">设备ID（0-255，默认0）</param>
        /// <returns>读取AD指令帧（5字节）</returns>
        public static byte[] SendReadAdcRequest(byte deviceId = 0)
        {
            byte[] frame = new byte[5]; // 帧长固定5字节（协议3.6）
            byte seq = GetCurrentCmdSequence();

            // 帧结构：ST → RDADC+序号 → 设备ID → LTH=5 → 校验和
            frame[0] = ST;
            frame[1] = (byte)(RDADC | seq);
            frame[2] = deviceId;
            frame[3] = 5; // LTH固定为5
            frame[4] = CalculateChecksum(frame, 4);

            IncrementCmdSequence();
            AddFrameInterval();
            return frame;
        }

        /// <summary>
        /// 读取EEPROM指令（获取指定地址的硬件/调试信息）
        /// </summary>
        /// <param name="addrHigh">地址高位字节</param>
        /// <param name="addrMid">地址中位字节</param>
        /// <param name="addrLow">地址低位字节</param>
        /// <param name="readLength">读取长度（字节数）</param>
        /// <param name="deviceId">设备ID（0-255，默认0）</param>
        /// <returns>读取EEPROM指令帧（变长，9 + readLength字节）</returns>
        public static byte[] SendReadEepromRequest(byte addrHigh, byte addrMid, byte addrLow, int readLength, byte deviceId = 0)
        {
            // 参数校验：读取长度≥1（避免空数据）
            if (readLength < 1)
                throw new ArgumentOutOfRangeException(nameof(readLength), "读取长度必须≥1");

            int frameLength = 9 + readLength; // 帧长N=9（固定段）+ 读取长度
            byte[] frame = new byte[frameLength];
            byte seq = GetCurrentCmdSequence();

            // 帧结构：ST → RDEE+序号 → 设备ID → LTH=N → 地址高→中→低 → 读取长度 → 校验和
            frame[0] = ST;
            frame[1] = (byte)(RDEE | seq);
            frame[2] = deviceId;
            frame[3] = (byte)frameLength; // LTH=N（实际帧长）
            frame[4] = addrHigh;          // 地址高位
            frame[5] = addrMid;           // 地址中位
            frame[6] = addrLow;           // 地址低位
            frame[7] = (byte)readLength;  // 读取长度
            // 校验和：前（frameLength-1）字节求和（帧长-1 = 8 + readLength）
            frame[frameLength - 1] = CalculateChecksum(frame, frameLength - 1);

            IncrementCmdSequence();
            AddFrameInterval();
            return frame;
        }

        /// <summary>
        /// 写入EEPROM指令（写入硬件/调试/标定参数）
        /// </summary>
        /// <param name="addrHigh">地址高位字节</param>
        /// <param name="addrMid">地址中位字节</param>
        /// <param name="addrLow">地址低位字节</param>
        /// <param name="writeData">待写入的数据（字节数组）</param>
        /// <param name="deviceId">设备ID（0-255，默认0）</param>
        /// <returns>写入EEPROM指令帧（变长，9 + writeData.Length字节）</returns>
        public static byte[] SendWriteEepromRequest(byte addrHigh, byte addrMid, byte addrLow, byte[] writeData, byte deviceId = 0)
        {
            // 参数校验：写入数据非空
            if (writeData == null || writeData.Length == 0)
                throw new ArgumentException("写入数据不能为空", nameof(writeData));

            int frameLength = 9 + writeData.Length; // 帧长N=9（固定段）+ 数据长度
            byte[] frame = new byte[frameLength];
            byte seq = GetCurrentCmdSequence();

            // 帧结构：ST → WREE+序号 → 设备ID → LTH=N → 地址高→中→低 → 写入数据 → 校验和
            frame[0] = ST;
            frame[1] = (byte)(WREE | seq);
            frame[2] = deviceId;
            frame[3] = (byte)frameLength; // LTH=N（实际帧长）
            frame[4] = addrHigh;          // 地址高位
            frame[5] = addrMid;           // 地址中位
            frame[6] = addrLow;           // 地址低位
            // 填充写入数据（从第8字节开始，索引7）
            Array.Copy(writeData, 0, frame, 7, writeData.Length);
            // 校验和：前（frameLength-1）字节求和
            frame[frameLength - 1] = CalculateChecksum(frame, frameLength - 1);

            IncrementCmdSequence();
            AddFrameInterval();
            return frame;
        }

        /// <summary>
        /// 获取实际转速指令
        /// </summary>
        /// <param name="deviceId">设备ID（0-255，默认0）</param>
        /// <returns>获取转速指令帧（5字节）</returns>
        public static byte[] SendReadMotorSpeedRequest(byte deviceId = 0)
        {
            byte[] frame = new byte[5]; // 帧长固定5字节
            byte seq = GetCurrentCmdSequence();

            // 帧结构：ST → RDMotSpeed+序号 → 设备ID → LTH=5 → 校验和
            frame[0] = ST;
            frame[1] = (byte)(RDMotSpeed | seq);
            frame[2] = deviceId;
            frame[3] = 5; // LTH固定为5
            frame[4] = CalculateChecksum(frame, 4);

            IncrementCmdSequence();
            AddFrameInterval();
            return frame;
        }

        /// <summary>
        /// 获取开关盖状态指令
        /// </summary>
        /// <param name="deviceId">设备ID（0-255，默认0）</param>
        /// <returns>获取开关盖状态指令帧（5字节）</returns>
        public static byte[] SendReadIoStatusRequest(byte deviceId = 0)
        {
            byte[] frame = new byte[5]; // 帧长固定5字节
            byte seq = GetCurrentCmdSequence();

            // 帧结构：ST → RDIOStatus+序号 → 设备ID → LTH=5 → 校验和
            frame[0] = ST;
            frame[1] = (byte)(RDIOStatus | seq);
            frame[2] = deviceId;
            frame[3] = 5; // LTH固定为5
            frame[4] = CalculateChecksum(frame, 4);

            IncrementCmdSequence();
            AddFrameInterval();
            return frame;
        }

        /// <summary>
        /// 校准温度指令（设置温度校准B值）
        /// </summary>
        /// <param name="calibBValue">校准B值（16位：B=(实际温度-目标温度)×100）</param>
        /// <param name="deviceId">设备ID（0-255，默认0）</param>
        /// <returns>校准温度指令帧（7字节）</returns>
        public static byte[] SendCalibrateTempRequest(int calibBValue, byte deviceId = 0)
        {
            // 参数校验：B值为16位有符号范围（-32768~32767）
            if (calibBValue < short.MinValue || calibBValue > short.MaxValue)
                throw new ArgumentOutOfRangeException(nameof(calibBValue), "校准B值必须在-32768~32767之间");

            byte[] frame = new byte[7]; // 帧长固定7字节
            byte seq = GetCurrentCmdSequence();
            ushort bParam = (ushort)calibBValue; // 转换为16位无符号（高位在前）

            // 帧结构：ST → Calb+序号 → 设备ID → LTH=7 → 参数1(高8) → 参数2(低8) → 校验和
            frame[0] = ST;
            frame[1] = (byte)(Calb | seq);
            frame[2] = deviceId;
            frame[3] = 7; // LTH固定为7
            frame[4] = (byte)(bParam >> 8); // 参数1（高8位）
            frame[5] = (byte)(bParam & 0xFF); // 参数2（低8位）
            frame[6] = CalculateChecksum(frame, 6); // 前6字节求和

            IncrementCmdSequence();
            AddFrameInterval();
            return frame;
        }

        /// <summary>
        /// 加热温度控制
        /// </summary>
        public static byte[] SendSetHotTemp(double targetTemp, byte deviceId = 0, bool releaseControl = false)
        {
            byte[] frame = new byte[7];
            byte seq = GetCurrentCmdSequence();
            ushort tempParam;

            if (releaseControl)
            {
                tempParam = 0xFFFF; // 释放控制
            }
            else
            {
                // 协议范围：室温~100℃（对应室温*100~10000）
                if (targetTemp < 20.0 || targetTemp > 100.0) // 室温暂以20℃为参考下限
                    throw new ArgumentOutOfRangeException(nameof(targetTemp), "温度必须在[20.0 , 100]℃之间（参考室温）");
                tempParam = (ushort)(targetTemp * 100);
            }

            frame[0] = ST;
            frame[1] = (byte)(SETHOTTEMP | seq);
            frame[2] = deviceId;
            frame[3] = 7; // LTH=7
            frame[4] = (byte)(tempParam >> 8);
            frame[5] = (byte)(tempParam & 0xFF);
            frame[6] = CalculateChecksum(frame, 6);

            IncrementCmdSequence();
            AddFrameInterval();
            return frame;
        }

        /// <summary>
        /// 电磁阀控制指令
        /// </summary>
        public static byte[] SendRelayControl(bool isOpen, byte deviceId = 0)
        {
            byte[] frame = new byte[6];
            byte seq = GetCurrentCmdSequence();
            byte param = (byte)(isOpen ? 1 : 0); // 1=开启，0=关闭

            frame[0] = ST;
            frame[1] = (byte)(RelayControl | seq);
            frame[2] = deviceId;
            frame[3] = 6; // LTH=6
            frame[4] = param;
            frame[5] = CalculateChecksum(frame, 5);

            IncrementCmdSequence();
            AddFrameInterval();
            return frame;
        }
        #endregion

        #region 指令解析（主控板→PC，返回结构化结果）
        /// <summary>
        /// 解析主控板返回的帧数据（入口方法）
        /// </summary>
        /// <param name="receivedFrame">主控板返回的原始字节数组</param>
        /// <returns>解析结果（结构化对象，包含指令类型、状态、数据）</returns>
        public static ParseResult ParseReceivedFrame(byte[] receivedFrame)
        {
            // 基础校验：帧非空、帧长≥5（最短帧为5字节）
            if (receivedFrame == null || receivedFrame.Length < 5)
                return new ParseResult(false, "无效帧：数据为空或长度不足", null);

            // 1. 校验帧头（必须为ST=0x5E）
            if (receivedFrame[0] != ST)
                return new ParseResult(false, $"帧头错误：实际0x{receivedFrame[0]:X2}，期望0x{ST:X2}", null);

            // 2. 提取核心字段
            byte cmdWithFlag = receivedFrame[1]; // 带0x80标志的指令码
            byte deviceId = receivedFrame[2];    // 设备ID
            byte frameLength = receivedFrame[3]; // 帧长LTH
            byte checksum = receivedFrame[frameLength - 1]; // 帧中校验和

            // 3. 校验帧长（实际长度必须等于帧长字段）
            if (receivedFrame.Length != frameLength)
                return new ParseResult(false, $"帧长不匹配：实际{receivedFrame.Length}字节，期望{frameLength}字节", null);

            // 4. 校验和验证
            byte calculatedChecksum = CalculateChecksum(receivedFrame, frameLength - 1);
            if (calculatedChecksum != checksum)
                return new ParseResult(false, $"校验和错误：实际0x{checksum:X2}，计算0x{calculatedChecksum:X2}", null);

            // 5. 去除响应标志，获取原始指令码
            byte originalCmd = (byte)(cmdWithFlag & ~RESPONSE_FLAG);

            // 6. 按指令类型分发解析
            switch (originalCmd)
            {
                case HELLO:
                    return ParseHelloResponse(receivedFrame, deviceId);
                case STATUS:
                    return ParseStatusResponse(receivedFrame, deviceId);
                case SETTEMP:
                    return ParseSetTempResponse(receivedFrame, deviceId);
                case MOTOR:
                    return ParseMotorResponse(receivedFrame, deviceId);
                case RDTEMP:
                    return ParseReadTempResponse(receivedFrame, deviceId);
                case RDADC:
                    return ParseReadAdcResponse(receivedFrame, deviceId);
                case RDEE:
                    return ParseReadEepromResponse(receivedFrame, deviceId);
                case WREE:
                    return ParseWriteEepromResponse(receivedFrame, deviceId);
                case RDMotSpeed:
                    return ParseReadMotorSpeedResponse(receivedFrame, deviceId);
                case RDIOStatus:
                    return ParseReadIoStatusResponse(receivedFrame, deviceId);
                case Calb:
                    return ParseCalibrateTempResponse(receivedFrame, deviceId);
                case SETHOTTEMP:
                    return ParseSetHotTempResponse(receivedFrame, deviceId);
                case RelayControl:
                    return ParseRelayControlResponse(receivedFrame, deviceId);
                default:
                    return new ParseResult(false, $"未知指令：0x{originalCmd:X2}", null);
            }
        }

        #region 各指令解析实现
        /// <summary>
        /// 解析握手响应
        /// </summary>
        private static ParseResult ParseHelloResponse(byte[] frame, byte deviceId)
        {
            // 响应帧长固定6字节（协议3.1）
            if (frame.Length != 6)
                return new ParseResult(false, "握手响应帧长错误（需6字节）", null);

            byte status = frame[4]; // 状态位（0=成功）
            var data = new Dictionary<string, object>
            {
                { "设备ID", deviceId },
                { "状态码", status },
                { "状态描述", status == 0 ? "握手成功" : $"握手失败（错误码：{status}）" }
            };
            return new ParseResult(true, "握手响应解析成功", data);
        }

        /// <summary>
        /// 解析报错状态响应
        /// </summary>
        private static ParseResult ParseStatusResponse(byte[] frame, byte deviceId)
        {
            // 响应帧长固定8字节（协议3.2）
            if (frame.Length != 8)
                return new ParseResult(false, "报错状态响应帧长错误（需8字节）", null);

            // 提取Error（2字节：Bit0-11）和状态位
            ushort error = (ushort)((frame[4] << 8) | frame[5]);
            byte status = frame[6];

            // 解析Error按位含义（协议3.2）
            var errorDesc = new Dictionary<string, bool>
            {
                { "测温传感器故障（Bit0）", (error & (1 << 0)) != 0 },
                { "温度过高>200℃（Bit1）", (error & (1 << 1)) != 0 },
                { "温度过低≤0℃（Bit2）", (error & (1 << 2)) != 0 },
                { "电机故障（Bit3）", (error & (1 << 3)) != 0 },
                { "预留Bit4", (error & (1 << 4)) != 0 },
                { "预留Bit5", (error & (1 << 5)) != 0 }
            };

            var data = new Dictionary<string, object>
            {
                { "设备ID", deviceId },
                { "状态码", status },
                { "状态描述", status == 0 ? "读取报错状态成功" : $"读取失败（错误码：{status}）" },
                { "报错详情", errorDesc },
                { "原始Error值", $"0x{error:X4}" }
            };
            return new ParseResult(true, "报错状态响应解析成功", data);
        }

        /// <summary>
        /// 解析温度控制响应
        /// </summary>
        private static ParseResult ParseSetTempResponse(byte[] frame, byte deviceId)
        {
            // 响应帧长固定6字节（协议3.3）
            if (frame.Length != 6)
                return new ParseResult(false, "温度控制响应帧长错误（需6字节）", null);

            byte status = frame[4]; // 状态位（0=成功）
            var data = new Dictionary<string, object>
            {
                { "设备ID", deviceId },
                { "状态码", status },
                { "状态描述", status == 0 ? "温度控制指令接收成功" : $"接收失败（错误码：{status}）" }
            };
            return new ParseResult(true, "温度控制响应解析成功", data);
        }

        /// <summary>
        /// 解析电机控制响应
        /// </summary>
        private static ParseResult ParseMotorResponse(byte[] frame, byte deviceId)
        {
            // 响应帧长固定6字节（协议3.4）
            if (frame.Length != 6)
                return new ParseResult(false, "电机控制响应帧长错误（需6字节）", null);

            byte status = frame[4]; // 状态位（0=成功）
            var data = new Dictionary<string, object>
            {
                { "设备ID", deviceId },
                { "状态码", status },
                { "状态描述", status == 0 ? "电机控制指令接收成功" : $"接收失败（错误码：{status}）" }
            };
            return new ParseResult(true, "电机控制响应解析成功", data);
        }

        /// <summary>
        /// 解析读取温度响应
        /// </summary>
        private static ParseResult ParseReadTempResponse(byte[] frame, byte deviceId)
        {
            // 响应帧长固定0x0D（13字节，协议3.5）
            if (frame.Length != 0x0D)
                return new ParseResult(false, $"读取温度响应帧长错误（需13字节，实际{frame.Length}字节）", null);

            // 提取数据：设置温度（5-6字节）、实际温度（7-8字节）、预留（9-10）、标志位（11）、状态位（12）
            ushort setTempParam = (ushort)((frame[4] << 8) | frame[5]);
            ushort actualTempParam = (ushort)((frame[6] << 8) | frame[7]);
            byte flag = frame[10]; // 0=未到温，1=到温
            byte status = frame[11];

            // 转换为实际温度（除以100，精度0.1）
            double setTemp = setTempParam / 100.0;
            double actualTemp = actualTempParam / 100.0;

            var data = new Dictionary<string, object>
            {
                { "设备ID", deviceId },
                { "状态码", status },
                { "状态描述", status == 0 ? "读取温度成功" : $"读取失败（错误码：{status}）" },
                { "设置温度（℃）", setTemp },
                { "实际温度（℃）", actualTemp },
                { "到温标志", flag == 0 ? "未到温" : "已到温" },
                { "原始设置温度参数", $"0x{setTempParam:X4}" },
                { "原始实际温度参数", $"0x{actualTempParam:X4}" }
            };
            return new ParseResult(true, "读取温度响应解析成功", data);
        }

        /// <summary>
        /// 解析读取AD响应
        /// </summary>
        private static ParseResult ParseReadAdcResponse(byte[] frame, byte deviceId)
        {
            // 响应帧长固定0x0D（13字节，协议3.6）
            if (frame.Length != 0x0D)
                return new ParseResult(false, $"读取AD响应帧长错误（需13字节，实际{frame.Length}字节）", null);

            // 提取数据：AD值（5-6字节）、预留（7-8）、状态位（9）
            ushort adcValue = (ushort)((frame[4] << 8) | frame[5]);
            byte status = frame[8];

            var data = new Dictionary<string, object>
            {
                { "设备ID", deviceId },
                { "状态码", status },
                { "状态描述", status == 0 ? "读取AD成功" : $"读取失败（错误码：{status}）" },
                { "AD值", adcValue },
                { "原始AD参数", $"0x{adcValue:X4}" }
            };
            return new ParseResult(true, "读取AD响应解析成功", data);
        }

        /// <summary>
        /// 解析读取EEPROM响应
        /// </summary>
        private static ParseResult ParseReadEepromResponse(byte[] frame, byte deviceId)
        {
            // 响应帧长N≥6（协议3.7：返回长度-6为数据字节数）
            if (frame.Length < 6)
                return new ParseResult(false, "读取EEPROM响应帧长不足（需≥6字节）", null);

            // 提取数据：参数1~参数n（5到N-2字节）、状态位（N-2字节）
            int dataLength = frame.Length - 6; // 数据字节数（N-6）
            byte[] eepromData = new byte[dataLength];
            Array.Copy(frame, 4, eepromData, 0, dataLength); // 从第5字节（索引4）开始复制
            byte status = frame[frame.Length - 2]; // 状态位（N-2字节）

            var data = new Dictionary<string, object>
            {
                { "设备ID", deviceId },
                { "状态码", status },
                { "状态描述", status == 0 ? "读取EEPROM成功" : $"读取失败（错误码：{status}）" },
                { "读取数据长度（字节）", dataLength },
                { "读取数据（十六进制）", BitConverter.ToString(eepromData).Replace("-", " ") },
                { "原始数据数组", eepromData }
            };
            return new ParseResult(true, "读取EEPROM响应解析成功", data);
        }

        /// <summary>
        /// 解析写入EEPROM响应
        /// </summary>
        private static ParseResult ParseWriteEepromResponse(byte[] frame, byte deviceId)
        {
            // 响应帧长固定6字节（协议3.8）
            if (frame.Length != 6)
                return new ParseResult(false, "写入EEPROM响应帧长错误（需6字节）", null);

            byte status = frame[4]; // 状态位（0=成功）
            var data = new Dictionary<string, object>
            {
                { "设备ID", deviceId },
                { "状态码", status },
                { "状态描述", status == 0 ? "写入EEPROM成功" : $"写入失败（错误码：{status}）" }
            };
            return new ParseResult(true, "写入EEPROM响应解析成功", data);
        }

        /// <summary>
        /// 解析获取实际转速响应
        /// </summary>
        private static ParseResult ParseReadMotorSpeedResponse(byte[] frame, byte deviceId)
        {
            // 响应帧长固定8字节（协议3.9）
            if (frame.Length != 8)
                return new ParseResult(false, "获取转速响应帧长错误（需8字节）", null);

            // 提取数据：转速参数（5-6字节）、状态位（7字节）
            ushort speedParam = (ushort)((frame[4] << 8) | frame[5]);
            byte status = frame[6];

            var data = new Dictionary<string, object>
            {
                { "设备ID", deviceId },
                { "状态码", status },
                { "状态描述", status == 0 ? "获取转速成功" : $"获取失败（错误码：{status}）" },
                { "实际转速", speedParam },
                { "原始转速参数", $"0x{speedParam:X4}" }
            };
            return new ParseResult(true, "获取转速响应解析成功", data);
        }

        /// <summary>
        /// 解析获取开关盖状态响应
        /// </summary>
        private static ParseResult ParseReadIoStatusResponse(byte[] frame, byte deviceId)
        {
            // 响应帧长固定7字节（协议3.10）
            if (frame.Length != 7)
                return new ParseResult(false, "获取开关盖状态响应帧长错误（需7字节）", null);

            // 提取数据：开关盖参数（5字节）、状态位（6字节）
            byte ioParam = frame[4]; // 0=关盖，1=开盖
            byte status = frame[5];

            var data = new Dictionary<string, object>
            {
                { "设备ID", deviceId },
                { "状态码", status },
                { "状态描述", status == 0 ? "获取开关盖状态成功" : $"获取失败（错误码：{status}）" },
                { "开关盖状态", ioParam == 0 ? "关盖" : "开盖" },
                { "原始状态参数", $"0x{ioParam:X2}" }
            };
            return new ParseResult(true, "获取开关盖状态响应解析成功", data);
        }

        /// <summary>
        /// 解析校准温度响应
        /// </summary>
        private static ParseResult ParseCalibrateTempResponse(byte[] frame, byte deviceId)
        {
            // 响应帧长固定6字节（协议3.11）
            if (frame.Length != 6)
                return new ParseResult(false, "校准温度响应帧长错误（需6字节）", null);

            byte status = frame[4]; // 状态位（0=成功）
            var data = new Dictionary<string, object>
            {
                { "设备ID", deviceId },
                { "状态码", status },
                { "状态描述", status == 0 ? "温度校准指令接收成功" : $"接收失败（错误码：{status}）" }
            };
            return new ParseResult(true, "校准温度响应解析成功", data);
        }

        /// <summary>
        /// 加热温度控制响应解析
        /// </summary>
        private static ParseResult ParseSetHotTempResponse(byte[] frame, byte deviceId)
        {
            if (frame.Length != 6)
                return new ParseResult(false, "加热温度响应帧长错误（需6字节）", null);

            byte status = frame[4];
            var data = new Dictionary<string, object>
        {
            { "设备ID", deviceId },
            { "状态码", status },
            { "状态描述", status == 0 ? "加热温度指令接收成功" : $"接收失败（错误码：{status}）" }
        };
            return new ParseResult(true, "加热温度响应解析成功", data);
        }

        /// <summary>
        /// 电磁阀控制响应解析
        /// </summary>
        private static ParseResult ParseRelayControlResponse(byte[] frame, byte deviceId)
        {
            if (frame.Length != 6)
                return new ParseResult(false, "电磁阀控制响应帧长错误（需6字节）", null);

            byte status = frame[4];
            var data = new Dictionary<string, object>
        {
            { "设备ID", deviceId },
            { "状态码", status },
            { "状态描述", status == 0 ? "电磁阀指令接收成功" : $"接收失败（错误码：{status}）" }
        };
            return new ParseResult(true, "电磁阀控制响应解析成功", data);
        }
        #endregion
        #endregion
        /// <summary>
        /// 帧间隔时间（协议要求>2ms，留3ms余量）
        /// </summary>
        private static void AddFrameInterval()
        {
            Task.Delay(3);
        }

        /// <summary>
        /// CRC16校验（用户原类中定义，协议未使用，保留以备扩展）
        /// </summary>
        public static byte[] CRC16(byte[] data)
        {
            int len = data.Length;
            if (len <= 0)
                return new byte[] { 0, 0 };

            ushort crc = 0xFFFF;
            for (int i = 0; i < len; i++)
            {
                crc = (ushort)(crc ^ data[i]);
                for (int j = 0; j < 8; j++)
                {
                    crc = (crc & 1) != 0 ? (ushort)((crc >> 1) ^ 0xA001) : (ushort)(crc >> 1);
                }
            }

            byte hi = (byte)((crc & 0xFF00) >> 8);
            byte lo = (byte)(crc & 0x00FF);
            return BitConverter.IsLittleEndian ? new byte[] { lo, hi } : new byte[] { hi, lo };
        }
    }
}
