using System; using IvfTl.Control.Entity; using IvfTl.Control.Entity.GlobalEnums; using ivf_tl_SerialHelper.Util; namespace IvfTl.Hardware.Impl { /// /// ISerialChannel 实现,内部包装 control 的 ivf_tl_SerialHelper.Util.ComBin(不改其内部逻辑)。 /// ComBin 自带发送队列线程 + RingBuffer + taskAutoResetEvent 同步等待,本层只转发 + 统一返回值/延时语义。 /// 每个 ISerialChannel 实例唯一对应一个 COM 口(由 HAL 字典缓存保证唯一持有,杜绝同口重复 Open)。 /// 一个 COM 口同一时刻一条在途指令:用 _ioLock 实例锁串行化本通道所有 Wait 调用。 /// 返回值约定(13 §3.2):位置/计数失败 -1,温压失败 -1m,布尔操作失败 false。 /// public sealed class SerialChannelImpl : ISerialChannel { private readonly ComBin _com; // 包装的旧具体串口栈 private readonly object _ioLock = new object(); private readonly string _portName; public SerialChannelImpl(int houseId, string portName) { _portName = portName; _com = new ComBin(houseId, portName); } public string PortName => _portName; public bool IsOpen { get; private set; } public Action Log { get; set; } public object RawComBin => _com; // 13 §3.5/3 读超时与到位延时(属性化,禁止写死)。M1 暂不下推到旧 ComBin 的固定 milliseconds(旧栈固定超时), // 仅作为电机延时缺省值来源;下推到旧栈属 M2 真机标定(V-010 系列)。 public int MoveReadTimeoutMs { get; set; } = 12000; public int QueryReadTimeoutMs { get; set; } = 3000; public int MotorSettleMs { get; set; } = 1500; private int Delay(int delayMs) => delayMs < 0 ? MotorSettleMs : delayMs; // ── 生命周期 ── public bool Open() { lock (_ioLock) { IsOpen = _com.OpenPort(); return IsOpen; } } public void Close() { lock (_ioLock) { _com.IsStop = true; _com.ClosePort(); IsOpen = false; } } // ── 通用收发 ── public byte[] SendWait(byte[] frame, int extraWaitMs = 0) { // TODO(M2): 旧 ComBin 不暴露"裸帧发送 + 取回复缓冲"入口(均经 CustomProtocol + Create*Command); // 裸帧通道供扩展协议/自动对焦自定义命令用,M1 不需要,留 TODO + 待验证。 return null; } // ── 握手 ── public int ShakeHandsWait() { lock (_ioLock) { var c = new CustomProtocol(); return _com.ShakeHandsWait(c); } } // ── EEPROM ── public int ReadCcdSnWait() { lock (_ioLock) { return _com.GetCCDSNWait(new CustomProtocol()); } } public int ReadLightBrightnessWait() { lock (_ioLock) { return _com.ReadEEPROMLightNumWait(new CustomProtocol()); } } public int ReadWellHorizontalPosWait(int well) { lock (_ioLock) { return _com.ReadEEPROMhoriMtWellHorHorWait(new CustomProtocol(), well); } } public int ReadWellFocusZeroWait(int well) { // control ComBin 的 Z 对焦零点为整舱单值(ReadEEPROMvertMtStartPulseWait,未按 well 分), // 与 af 按 well 读零点存在差异——well 入参 M1 暂忽略;按 well 区分零点属 M2 对焦链验证。 lock (_ioLock) { return _com.ReadEEPROMvertMtStartPulseWait(new CustomProtocol()); } } public int ReadScanStepWait() { lock (_ioLock) { return _com.ReadEEPROMvertMtScanPluseWait(new CustomProtocol()); } } public bool WriteWellHorizontalPosWait(int well, int pulseValue) { // M1-B2:control ComBin 已补 WriteEEPROMhoriMtWellHorHorWait(调既有 CreateWriteEEPROMhoriMtWellHoriPos, // T1.1 子代理逐字节核实与 operate 完全一致:0x12 + 同 well 地址表 + 小端 pulse + 同 CreateORC)。 // 写命令无显式成功出口(旧栈 void),阻塞收到回复即视为已下发,返回 true。 // ⚠ 待真机 V-010:写E方破坏性,0x12 回包长度 control/operate 有差异,"写成功"判定真机核对。 lock (_ioLock) { _com.WriteEEPROMhoriMtWellHorHorWait(new CustomProtocol(), well, pulseValue); return true; } } public bool WriteScanStepWait(int pulseValue) { lock (_ioLock) { _com.WriteEEPROMvertMtScanPluseWait(new CustomProtocol(), pulseValue); return true; } } public bool WriteOpenIntakeTimeWait(int newValue, bool isBuffer = false) { lock (_ioLock) { if (isBuffer) _com.WriteEEPROOpenIntakeTimeBufferWait(new CustomProtocol(), newValue); else _com.WriteEEPROOpenIntakeTimeWait(new CustomProtocol(), newValue); return true; } } public bool WriteOpenVentTimeWait(int newValue) { // M-01 已补:control Commander/ComBin 补齐 CreateWriteEEPROOpenVentTimeCommand + WriteEEPROOpenVentTimeWait // (builder 地址 00 03 08,与合并前 operate 逐字节一致)。写命令旧栈无显式成功出口(void), // 阻塞收到回复即视为已下发,返回 true。 lock (_ioLock) { _com.WriteEEPROOpenVentTimeWait(new CustomProtocol(), newValue); return true; } } public int ReadOpenVentTimeWait() { // M-02 已补:control 补齐 CreateReadEEPROMVentNum + ReadEEPROMVentWait(地址 00 03 08)。失败返回 -1。 lock (_ioLock) { return _com.ReadEEPROMVentWait(new CustomProtocol()); } } public bool WriteLightBrightnessWait(int newValue) { // M-03 已补:control 补齐 CreateWriteEEPROMLightNum + WriteEEPROMLightNumWait(地址 00 05 34)。 lock (_ioLock) { _com.WriteEEPROMLightNumWait(new CustomProtocol(), newValue); return true; } } // ── 电机:垂直 ── public bool VerticalMoveToWait(int pulse, int delayMs = -1) { lock (_ioLock) { // control VerticalMotorAbsoluteWait 需 (custom, waitTime, currentVer, currentHor, pictureId, well, focal); // HAL 简化签名只给目标脉冲,附带参数用 0/-1 占位(调试/对焦走采集流程时按需另传,见 M2)。 return _com.VerticalMotorAbsoluteWait(new CustomProtocol(), Delay(delayMs), pulse, 0, 0, 0, 0); } } public bool VerticalForwardWait(int pulse, int delayMs = -1) { // M2: control SerialHelper ComBin 已补 VerticalMotorForwardWait(忠实搬运 operate 实现)。 lock (_ioLock) { return _com.VerticalMotorForwardWait(new CustomProtocol(), Delay(delayMs), pulse); } } public bool VerticalBackwardWait(int pulse, int delayMs = -1) { lock (_ioLock) { return _com.VerticalMotorBackwardWait(new CustomProtocol(), Delay(delayMs), pulse); } } public bool VerticalResetWait(int delayMs = -1) { lock (_ioLock) { return _com.VerticalMotorResetWait(new CustomProtocol(), Delay(delayMs)); } } public int ReadVerticalPositionWait() { lock (_ioLock) { return _com.ReadVerticalMotorWait(new CustomProtocol()); } } // ── 电机:水平 ── public bool HorizontalMoveToWait(int pulse, int delayMs = -1) { lock (_ioLock) { return _com.HorizontalMotorAbsoluteWait(new CustomProtocol(), Delay(delayMs), pulse); } } public bool HorizontalForwardWait(int pulse, int delayMs = -1) { // M2: control SerialHelper ComBin 已补 HorizontalMotorForwardWait(忠实搬运 operate 实现)。 lock (_ioLock) { return _com.HorizontalMotorForwardWait(new CustomProtocol(), Delay(delayMs), pulse); } } public bool HorizontalBackwardWait(int pulse, int delayMs = -1) { lock (_ioLock) { return _com.HorizontalMotorBackwardWait(new CustomProtocol(), Delay(delayMs), pulse); } } public bool HorizontalResetWait(int delayMs = -1) { lock (_ioLock) { return _com.HorizontalMotorResetWait(new CustomProtocol(), Delay(delayMs)); } } public int ReadHorizontalPositionWait() { lock (_ioLock) { return _com.ReadHorizontalMotorWait(new CustomProtocol()); } } // ── 环境量 ── public decimal TemperatureWait() { lock (_ioLock) { return _com.TemperatureWait(new CustomProtocol()); } } public decimal ShangTemperatureWait() { lock (_ioLock) { return _com.ShangTemperatureWait(new CustomProtocol()); } } public decimal BoLiTemperatureWait() { lock (_ioLock) { return _com.BoLiTemperatureWait(new CustomProtocol()); } } public decimal PressureWait() { lock (_ioLock) { return _com.PressureWait(new CustomProtocol()); } } public (decimal pressure, decimal t1, decimal t2) BufferBottleStateWait() { lock (_ioLock) { var (p, a, b) = _com.BufferBottleState(new CustomProtocol()); return (p, a, b); } } public DoorState DoorStatusWait() { lock (_ioLock) { State s = _com.DoorStatusWait(new CustomProtocol()); switch (s) { case State.打开: return DoorState.打开; case State.关闭: return DoorState.关闭; default: return DoorState.未知; } } } // ── IO / LED / 气阀 ── public bool OpenLedWait() { // 旧 OpenLEDWait 返回 void:阻塞等待回复后即视为成功(无 IsSuccess 出口可读)。 lock (_ioLock) { _com.OpenLEDWait(new CustomProtocol()); return true; } } public bool CloseLedWait() { lock (_ioLock) { _com.CloseLEDWait(new CustomProtocol()); return true; } } public bool OpenIntakeValveWait() { lock (_ioLock) { return _com.OpenIntakeValveWait(new CustomProtocol(), 0); } } public bool CloseIntakeValveWait() { lock (_ioLock) { return _com.CloseIntakeValveWait(new CustomProtocol(), 0); } } public bool OpenExhaustValveWait() { lock (_ioLock) { return _com.OpenExhaustValveWait(new CustomProtocol(), 0); } } public bool CloseExhaustValveWait() { // 旧 CloseExhaustValveWait 返回 void。 lock (_ioLock) { _com.CloseExhaustValveWait(new CustomProtocol(), 0); return true; } } public bool HouseAerationWait() { lock (_ioLock) { return _com.HouseAerationWait(new CustomProtocol()); } } public bool HouseVentWait() { lock (_ioLock) { return _com.HouseVentWait(new CustomProtocol()); } } public bool BufferBottleAerationWait() { lock (_ioLock) { return _com.BufferBottleAerationWait(new CustomProtocol()); } } public bool AutoAirSwapWait(bool on) { // M2: control SerialHelper ComBin 已补 AutoWait(忠实搬运 operate 实现,命令 0x16)。 lock (_ioLock) { return _com.AutoWait(new CustomProtocol(), on); } } public void Dispose() { try { Close(); } catch { } } } }