using System; using XP.Hardware.RaySource.Comet; using XP.Hardware.RaySource.Comet.Messages.Commands; using XP.Hardware.RaySource.Comet.Messages.Responses; namespace XP.Hardware.RaySource.Comet.Host.Pipe { /// /// 命令分发器 /// 根据命令类型分发到 CometPviClient 对应方法 /// static class CommandDispatcher { /// /// 退出标志,DisconnectCommand 处理后设置为 true /// public static bool ShouldExit { get; private set; } /// /// 分发命令到 CometPviClient 对应方法 /// /// 待处理的命令 /// 处理结果响应 public static RaySourceResponse Dispatch(RaySourceCommand command) { try { switch (command.CommandType) { case "Initialize": return HandleInitialize((InitializeCommand)command); case "ConnectVariables": return HandleConnectVariables(); case "TurnOn": return HandleTurnOn(); case "TurnOff": return HandleTurnOff(); case "SetVoltage": return HandleSetVoltage((SetVoltageCommand)command); case "SetCurrent": return HandleSetCurrent((SetCurrentCommand)command); case "ReadVoltage": return HandleReadVoltage(); case "ReadCurrent": return HandleReadCurrent(); case "ReadSystemStatus": return HandleReadSystemStatus(); case "ReadErrors": return HandleReadErrors(); case "Disconnect": return HandleDisconnect(); case "TxiOn": return HandleTxiOn(); case "TxiOff": return HandleTxiOff(); case "WarmUp": return HandleWarmUp(); case "Training": return HandleTraining(); case "FilamentCalibration": return HandleFilamentCalibration(); case "AutoCenter": return HandleAutoCenter(); case "SetPowerMode": return HandleSetPowerMode((SetPowerModeCommand)command); default: return new OperationResponse { Success = false, ErrorMessage = $"未知的命令类型:{command.CommandType}" }; } } catch (Exception ex) { return new OperationResponse { Success = false, ErrorMessage = $"命令处理异常:{ex.Message}" }; } } /// /// 等待 PVI 回调链完成的超时时间(毫秒) /// PVI Service.Connect() → Service_Connected → CPU.Connect() → Cpu_Connected 整个链路需要时间 /// private const int PviConnectTimeoutMs = 30000; private static RaySourceResponse HandleInitialize(InitializeCommand cmd) { // PVI 回调链依赖 WinForms 消息泵派发事件 // 不能用 ManualResetEventSlim.Wait() 阻塞 UI 线程,否则回调无法触发 // 改用带消息泵的轮询等待,保持 Application.DoEvents() 运转 bool completed = false; bool errorOccurred = false; string errorMessage = null; // 订阅连接状态变更事件 EventHandler stateHandler = (sender, state) => { if (state == PviConnectionState.ServiceConnected) { Console.Error.WriteLine("[Host] PVI 回调链完成,ServiceConnected"); completed = true; } }; // 订阅错误事件(PVI 连接可能失败) EventHandler errorHandler = (sender, msg) => { errorOccurred = true; errorMessage = msg; Console.Error.WriteLine($"[Host] PVI 连接错误:{msg}"); completed = true; }; CometPviClient.ConnectionStateChanged += stateHandler; CometPviClient.ErrorOccurred += errorHandler; try { CometPviClient.Initialize(cmd.IpAddress, cmd.Port, cmd.CpuName, cmd.SourcePort, cmd.StationNumber); // 带消息泵的等待循环,保持 UI 消息派发,让 PVI 回调能触发 var deadline = DateTime.UtcNow.AddMilliseconds(PviConnectTimeoutMs); while (!completed && DateTime.UtcNow < deadline) { System.Windows.Forms.Application.DoEvents(); System.Threading.Thread.Sleep(50); } if (!completed) { return new OperationResponse { Success = false, ErrorMessage = "PVI 连接超时,回调链未在规定时间内完成" }; } if (errorOccurred) { return new OperationResponse { Success = false, ErrorMessage = $"PVI 连接失败:{errorMessage}" }; } return new OperationResponse { Success = true }; } finally { CometPviClient.ConnectionStateChanged -= stateHandler; CometPviClient.ErrorOccurred -= errorHandler; } } private static RaySourceResponse HandleConnectVariables() { CometPviClient.ConnectVariables(); return new OperationResponse { Success = true }; } private static RaySourceResponse HandleTurnOn() { CometPviClient.TurnOn(); return new OperationResponse { Success = true }; } private static RaySourceResponse HandleTurnOff() { CometPviClient.TurnOff(); return new OperationResponse { Success = true }; } private static RaySourceResponse HandleSetVoltage(SetVoltageCommand cmd) { CometPviClient.SetVoltage(cmd.Voltage); return new OperationResponse { Success = true }; } private static RaySourceResponse HandleSetCurrent(SetCurrentCommand cmd) { CometPviClient.SetCurrent(cmd.Current); return new OperationResponse { Success = true }; } private static RaySourceResponse HandleReadVoltage() { var voltage = CometPviClient.ReadVoltage(); return new OperationResponse { Success = true, Data = voltage }; } private static RaySourceResponse HandleReadCurrent() { var current = CometPviClient.ReadCurrent(); return new OperationResponse { Success = true, Data = current }; } private static RaySourceResponse HandleReadSystemStatus() { var status = CometPviClient.ReadSystemStatus(); return new StatusResponse { Success = true, SetVoltage = status.SetVoltage, ActualVoltage = status.ActualVoltage, SetCurrent = status.SetCurrent, ActualCurrent = status.ActualCurrent, IsXRayOn = status.IsXRayOn, WarmUpStatus = status.WarmUpStatus, VacuumStatus = status.VacuumStatus, StartUpStatus = status.StartUpStatus, AutoCenterStatus = status.AutoCenterStatus, FilamentAdjustStatus = status.FilamentAdjustStatus, IsInterlockActive = status.IsInterlockActive, WatchdogStatus = status.WatchdogStatus, PowerMode = status.PowerMode, TxiStatus = status.TxiStatus }; } private static RaySourceResponse HandleReadErrors() { var errors = CometPviClient.ReadErrors(); return new ErrorDataResponse { Success = true, SystemError = errors.SystemError, HSGError = errors.HSGError, TubeError = errors.TubeError, TubeVacError = errors.TubeVacError }; } private static RaySourceResponse HandleDisconnect() { CometPviClient.Disconnect(); ShouldExit = true; return new OperationResponse { Success = true }; } private static RaySourceResponse HandleTxiOn() { CometPviClient.TxiOn(); return new OperationResponse { Success = true }; } private static RaySourceResponse HandleTxiOff() { CometPviClient.TxiOff(); return new OperationResponse { Success = true }; } private static RaySourceResponse HandleWarmUp() { CometPviClient.WarmUp(); return new OperationResponse { Success = true }; } private static RaySourceResponse HandleTraining() { CometPviClient.Training(); return new OperationResponse { Success = true }; } private static RaySourceResponse HandleFilamentCalibration() { CometPviClient.FilamentCalibration(); return new OperationResponse { Success = true }; } private static RaySourceResponse HandleAutoCenter() { CometPviClient.AutoCenter(); return new OperationResponse { Success = true }; } private static RaySourceResponse HandleSetPowerMode(SetPowerModeCommand cmd) { CometPviClient.SetPowerMode(cmd.Mode); return new OperationResponse { Success = true }; } } }