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)
{
// TODO(M2 / 13 §⑤ V1): control 端 ComBin(SerialHelper) 未含写 EEPROM(0x12);
// 写命令在 operate 侧 ComBin.WriteEEPROMhoriMtWellHorHorWait 存在,字节序/地址表未经对焦链验证。
// M1 不回写 EEPROM,返回 false,留 TODO + 待验证。
return false;
}
// ── 电机:垂直 ──
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)
{
// control 侧 SerialHelper ComBin 无 VerticalMotorForwardWait(仅 operate 侧有)。
// TODO(M2):对焦扫描相对运动需补;M1 采集/调试用绝对运动,返回 false。
return false;
}
public bool VerticalBackwardWait(int pulse, int delayMs = -1) => false; // 同上 TODO(M2)
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) => false; // TODO(M2):control SerialHelper 无相对运动
public bool HorizontalBackwardWait(int pulse, int delayMs = -1) => false; // TODO(M2)
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)
{
// TODO(M2): control 侧 SerialHelper ComBin 无 AutoWait(仅 operate 侧 ComBin 有)。
// 自动换气开关 M1 采集/调试不通过 HAL 切换,返回 false,留 TODO。
return false;
}
public void Dispose()
{
try { Close(); } catch { }
}
}
}