using BR.AN.PviServices;
using System;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
// 解决 BR.AN.PviServices.Exception 与 System.Exception 的歧义
using Exception = System.Exception;
namespace XP.Hardware.RaySource.Comet
{
///
/// Comet PVI 通讯客户端静态类
/// 封装 BR.AN.PviServices 的所有直接调用
/// 包含:Service/CPU 连接管理、Variable 创建/激活/绑定、ValueChanged 回调处理
///
public static class CometPviClient
{
#region 日志回调委托
///
/// 日志回调委托(由 .NET 8 层注入)
///
private static Action _logger;
#endregion
#region PVI 核心对象
private static Service _service;
private static Cpu _cpu;
#endregion
#region 连接参数
private static string _ipAddress;
private static int _port;
private static string _cpuName;
private static int _sourcePort;
private static int _stationNumber;
#endregion
#region 连接状态
private static bool _isConnected;
private static bool _isVariablesConnected;
private static PviConnectionState _currentConnectionState = PviConnectionState.Disconnected;
#endregion
#region PVI 变量 - 电压/电流
private static Variable _varKVS; // 设置电压 PC_cmd.r32_TubeVoltage_kV
private static Variable _varKVR; // 电压反馈 PLC_stat.r32_TubeVoltage_kV_ist
private static Variable _varMAS; // 设置电流 PC_cmd.r32_TubeCurrent_uA
private static Variable _varMAR; // 电流反馈 PLC_stat.r32_TubeCurrent_uA_ist
#endregion
#region PVI 变量 - 射线开关
private static Variable _varXonS; // 开高压 PC_cmd.xrayON
private static Variable _varXoffS; // 关高压 PC_cmd.xrayOFF
private static Variable _varXonR; // 高压开关反馈 PLC_stat.bo_Xray_on
#endregion
#region PVI 变量 - 维护操作(暖机/真空/训机)
private static Variable _varWarmUpS; // 暖机设定 PC_cmd.warmUP
private static Variable _varWarmUpR; // 暖机状态反馈 PLC_stat.u32_warmup
private static Variable _varVaconS; // 真空设定 Vacon
private static Variable _varVaconR; // 真空状态反馈 PLC_stat.u32_vacuum
private static Variable _varVaconRV; // 真空值 Vac.ist_mbar
private static Variable _varStartUpS; // 训机设定 PC_cmd.startUP
private static Variable _varStartUpR; // 训机状态反馈 PLC_stat.u32_startup
#endregion
#region PVI 变量 - 校准(自动定心/灯丝调整)
private static Variable _varCurrentKVAutoCenter; // 当前电压自动定心 PC_cmd.autocentkV
private static Variable _varALLKVCenter; // 全部电压自动定心 PC_cmd.autocentALL
private static Variable _varAutoCenterR; // 自动定心反馈 PLC_stat.u32_autocenter
private static Variable _varFilamentAdjust; // 灯丝调整 PC_cmd.filamentadjust
private static Variable _varFilamentAdjustR; // 灯丝调整反馈 PLC_stat.u32_filamentadjust
#endregion
#region PVI 变量 - 状态监控
private static Variable _varInterLockR; // 连锁状态 Di_Interlock
private static Variable _varWatchingDog; // 看门狗 PLC_stat.bo_Watchdog
private static Variable _varPowerModeR; // 功率模式反馈 PLC_stat.u32_current_modenumber
private static Variable _varPowerModeS; // 功率模式设定 Mode.current_mode_number
private static Variable _varTxiR; // TXI 反馈 PLC_stat.bo_TXI
private static Variable _varTxiOpenS; // TXI 开启设定 PC_cmd.Ti_reg_on
private static Variable _varTxiCloseS; // TXI 关闭设定 PC_cmd.Ti_reg_off
#endregion
#region PVI 变量 - 错误监控
private static Variable _sysErrR; // 系统错误读取 Sys_error[0]
private static Variable _sysErrS; // 系统错误确认 Sys_errorquit
private static Variable _HSGErrR; // 高压错误读取 HSG_error[0]
private static Variable _HSGErrS; // 高压错误确认 HSG_errorquit
private static Variable _tubeErrR; // 管子错误读取 Tube_error[0]
private static Variable _tubeErrS; // 管子错误确认 Tube_errorquit
private static Variable _tubeACErrR; // 管子真空错误读取 TubeVac_error[0]
private static Variable _tubeACErrS; // 管子真空错误确认 Vac_errorquit
#endregion
#region 内部缓存状态
private static float _actualVoltage;
private static float _actualCurrent;
private static float _setVoltage;
private static float _setCurrent;
private static bool _isXRayOn;
// 原始 code 码(多语言映射由 .NET 8 侧处理)| Raw code (localization handled by .NET 8 side)
private static string _warmUpCode = "0";
private static string _vacuumCode = "0";
private static string _startUpCode = "0";
private static string _autoCenterCode = "0";
private static string _filamentAdjustCode = "0";
private static bool _isInterlockActive;
private static string _watchdogStatus = "";
private static string _powerModeCode = "";
private static string _txiCode = "False";
#endregion
#region 事件通知
///
/// 状态更新事件(电压、电流、各子系统状态变化时触发)
///
public static event EventHandler StatusChanged;
///
/// 射线开关状态变更事件
///
public static event EventHandler XRayStateChanged;
///
/// PVI 连接错误事件
///
public static event EventHandler ErrorOccurred;
///
/// PVI 连接状态变更事件(未连接、Service已连接、变量已连接)
///
public static event EventHandler ConnectionStateChanged;
#endregion
#region 属性
///
/// PVI 连接是否已建立
///
public static bool IsConnected => _isConnected;
///
/// PVI 变量是否已连接
///
public static bool IsVariablesConnected => _isVariablesConnected;
///
/// 当前 PVI 连接状态
///
public static PviConnectionState CurrentConnectionState => _currentConnectionState;
#endregion
#region 日志方法
///
/// 设置日志回调委托
///
public static void SetLogger(Action logger)
{
_logger = logger;
}
///
/// 内部日志输出辅助方法
/// 如果未注入日志回调,则静默忽略
///
private static void Log(CometLogLevel level, string message, params object[] args)
{
_logger?.Invoke(level, message, args);
}
#endregion
#region Initialize - PVI Service → CPU 回调链式连接
///
/// 初始化 PVI Service 和 CPU 连接
///
public static void Initialize(string ipAddress, int port, string cpuName, int sourcePort, int stationNumber)
{
// 保存连接参数
_ipAddress = ipAddress;
_port = port;
_cpuName = cpuName;
_sourcePort = sourcePort;
_stationNumber = stationNumber;
Log(CometLogLevel.Info, $"开始初始化 Comet PVI 连接,IP={ipAddress}, Port={port}, CPU={cpuName}");
try
{
if (_service == null)
{
// 创建 PVI Service 对象并注册回调
_service = new Service("service");
_service.Connected += new PviEventHandler(Service_Connected);
_service.Error += new PviEventHandler(Service_Error);
}
_service.Connect();
Log(CometLogLevel.Info, "PVI Service.Connect() 已调用,等待回调链完成");
}
catch (Exception ex)
{
Log(CometLogLevel.Error, "PVI 连接初始化异常:{0}", ex.Message);
ErrorOccurred?.Invoke(null, $"PVI 连接初始化异常:{ex.Message}");
throw;
}
}
///
/// PVI Service Connected 回调:创建 CPU 对象,设置 TCP/IP 参数,连接 CPU
///
private static void Service_Connected(object sender, PviEventArgs e)
{
Log(CometLogLevel.Info, "PVI Service 连接成功,开始创建 CPU 对象");
try
{
if (_cpu == null)
{
_cpu = new Cpu(_service, _cpuName);
_cpu.Connected += new PviEventHandler(Cpu_Connected);
_cpu.Connection.DeviceType = DeviceType.TcpIp;
_cpu.Connection.TcpIp.DestinationIpAddress = _ipAddress;
_cpu.Connection.TcpIp.DestinationPort = (short)_port;
_cpu.Connection.TcpIp.SourcePort = (short)_sourcePort;
_cpu.Connection.TcpIp.SourceStation = (byte)_stationNumber;
}
_cpu.Connect();
Log(CometLogLevel.Info, $"CPU.Connect() 已调用,目标地址:{_ipAddress}:{_port}");
}
catch (Exception ex)
{
Log(CometLogLevel.Error, "创建 CPU 对象异常:{0}", ex.Message);
ErrorOccurred?.Invoke(null, $"创建 CPU 对象异常:{ex.Message}");
}
}
///
/// CPU Connected 回调:确认连接成功,触发连接状态变更事件
///
private static void Cpu_Connected(object sender, PviEventArgs e)
{
try
{
_cpu.ReadDateTime();
_isConnected = true;
Log(CometLogLevel.Info, "CPU 连接成功,PVI 回调链完成");
ConnectionStateChanged?.Invoke(null, PviConnectionState.ServiceConnected);
}
catch (Exception ex)
{
Log(CometLogLevel.Error, "CPU 连接确认异常:{0}", ex.Message);
}
}
///
/// PVI Service Error 回调:记录错误并触发错误事件
///
private static void Service_Error(object sender, PviEventArgs e)
{
int errorCode = _service.ErrorCode;
if (errorCode != 0)
{
string errorText = _service.GetErrorText(errorCode);
Log(CometLogLevel.Error, $"PVI Service 错误,错误码:{errorCode},错误信息:{errorText}");
ErrorOccurred?.Invoke(null, $"PVI Service 错误[{errorCode}]:{errorText}");
}
}
#endregion
#region ConnectVariables - 创建和激活所有 PVI 变量
///
/// 创建、激活并绑定所有 PVI 变量
///
public static void ConnectVariables()
{
Log(CometLogLevel.Info, "开始创建和连接 PVI 变量");
try
{
// 创建变量
CreateVariables();
// 激活变量并连接
ActivateVariables();
// 绑定事件处理
BindEventHandlers();
_isVariablesConnected = true;
Log(CometLogLevel.Info, "所有 PVI 变量创建、激活和事件绑定完成");
// 主动读取一次当前功率模式和 TXI 状态(ValueChanged 仅在值变化时触发)
// Actively read current power mode and TXI status (ValueChanged only fires on change)
try
{
if (_varPowerModeR?.Value != null)
{
_powerModeCode = _varPowerModeR.Value.ToString()?.Trim() ?? "";
Log(CometLogLevel.Debug, "初始功率模式原始值: '{0}'", _powerModeCode);
}
if (_varTxiR?.Value != null)
{
_txiCode = _varTxiR.Value.ToString() ?? "False";
}
}
catch (Exception readEx)
{
Log(CometLogLevel.Warn, "初始读取功率模式/TXI状态异常: {0}", readEx.Message);
}
ConnectionStateChanged?.Invoke(null, PviConnectionState.VariablesConnected);
}
catch (Exception ex)
{
Log(CometLogLevel.Error, "PVI 变量连接异常:{0}", ex.Message);
ErrorOccurred?.Invoke(null, $"PVI 变量连接异常:{ex.Message}");
throw;
}
}
///
/// 创建所有 PVI Variable 对象
///
private static void CreateVariables()
{
// 电压/电流
_varKVS = new Variable(_cpu, "PC_cmd.r32_TubeVoltage_kV");
_varKVR = new Variable(_cpu, "PLC_stat.r32_TubeVoltage_kV_ist");
_varMAS = new Variable(_cpu, "PC_cmd.r32_TubeCurrent_uA");
_varMAR = new Variable(_cpu, "PLC_stat.r32_TubeCurrent_uA_ist");
// 射线开关
_varXonS = new Variable(_cpu, "PC_cmd.xrayON");
_varXoffS = new Variable(_cpu, "PC_cmd.xrayOFF");
_varXonR = new Variable(_cpu, "PLC_stat.bo_Xray_on");
// 暖机
_varWarmUpS = new Variable(_cpu, "PC_cmd.warmUP");
_varWarmUpR = new Variable(_cpu, "PLC_stat.u32_warmup");
// 真空
_varVaconS = new Variable(_cpu, "Vacon");
_varVaconR = new Variable(_cpu, "PLC_stat.u32_vacuum");
_varVaconRV = new Variable(_cpu, "Vac.ist_mbar");
// 训机
_varStartUpS = new Variable(_cpu, "PC_cmd.startUP");
_varStartUpR = new Variable(_cpu, "PLC_stat.u32_startup");
// 自动定心
_varCurrentKVAutoCenter = new Variable(_cpu, "PC_cmd.autocentkV");
_varALLKVCenter = new Variable(_cpu, "PC_cmd.autocentALL");
_varAutoCenterR = new Variable(_cpu, "PLC_stat.u32_autocenter");
// 灯丝调整
_varFilamentAdjust = new Variable(_cpu, "PC_cmd.filamentadjust");
_varFilamentAdjustR = new Variable(_cpu, "PLC_stat.u32_filamentadjust");
// 状态监控
_varInterLockR = new Variable(_cpu, "Di_Interlock");
_varWatchingDog = new Variable(_cpu, "PLC_stat.bo_Watchdog");
_varPowerModeR = new Variable(_cpu, "PLC_stat.u32_current_modenumber");
_varPowerModeS = new Variable(_cpu, "Mode.current_mode_number");
_varTxiR = new Variable(_cpu, "PLC_stat.bo_TXI");
_varTxiOpenS = new Variable(_cpu, "PC_cmd.Ti_reg_on");
_varTxiCloseS = new Variable(_cpu, "PC_cmd.Ti_reg_off");
// 错误监控
_sysErrR = new Variable(_cpu, "Sys_error[0]");
_sysErrS = new Variable(_cpu, "Sys_errorquit");
_HSGErrR = new Variable(_cpu, "HSG_error[0]");
_HSGErrS = new Variable(_cpu, "HSG_errorquit");
_tubeErrR = new Variable(_cpu, "Tube_error[0]");
_tubeErrS = new Variable(_cpu, "Tube_errorquit");
_tubeACErrR = new Variable(_cpu, "TubeVac_error[0]");
_tubeACErrS = new Variable(_cpu, "Vac_errorquit");
Log(CometLogLevel.Info, "所有 PVI 变量对象创建完成");
}
///
/// 激活所有变量并调用 Connect
///
private static void ActivateVariables()
{
Variable[] allVariables = {
_varKVS, _varKVR, _varMAS, _varMAR,
_varXonS, _varXoffS, _varXonR,
_varWarmUpS, _varWarmUpR,
_varVaconS, _varVaconR, _varVaconRV,
_varStartUpS, _varStartUpR,
_varCurrentKVAutoCenter, _varALLKVCenter, _varAutoCenterR,
_varFilamentAdjust, _varFilamentAdjustR,
_varInterLockR, _varWatchingDog,
_varPowerModeR, _varPowerModeS, _varTxiR,
_varTxiOpenS, _varTxiCloseS,
_sysErrR, _sysErrS,
_HSGErrR, _HSGErrS,
_tubeErrR, _tubeErrS,
_tubeACErrR, _tubeACErrS
};
foreach (var variable in allVariables)
{
variable.Active = true;
variable.Connect();
}
Log(CometLogLevel.Info, "所有 PVI 变量已激活并连接");
}
///
/// 为所有反馈类变量绑定 ValueChanged 事件处理程序
///
private static void BindEventHandlers()
{
// 电压/电流反馈
_varKVR.ValueChanged += new VariableEventHandler(VarKVR_ValueChanged);
_varMAR.ValueChanged += new VariableEventHandler(VarMAR_ValueChanged);
// 电压/电流设定值反馈(用于同步滑块显示)| Set value feedback (for slider sync)
_varKVS.ValueChanged += new VariableEventHandler(VarKVS_ValueChanged);
_varMAS.ValueChanged += new VariableEventHandler(VarMAS_ValueChanged);
// 射线开关反馈
_varXonR.ValueChanged += new VariableEventHandler(VarXonR_ValueChanged);
// 暖机反馈
_varWarmUpR.ValueChanged += new VariableEventHandler(VarWarmUpR_ValueChanged);
// 真空反馈
_varVaconR.ValueChanged += new VariableEventHandler(VarVaconR_ValueChanged);
// 训机反馈
_varStartUpR.ValueChanged += new VariableEventHandler(VarStartUpR_ValueChanged);
// 自动定心反馈
_varAutoCenterR.ValueChanged += new VariableEventHandler(VarAutoCenterR_ValueChanged);
// 灯丝调整反馈
_varFilamentAdjustR.ValueChanged += new VariableEventHandler(VarFilamentAdjustR_ValueChanged);
// 连锁状态
_varInterLockR.ValueChanged += new VariableEventHandler(VarInterLockR_ValueChanged);
// 看门狗
_varWatchingDog.ValueChanged += new VariableEventHandler(VarWatchingDog_ValueChanged);
// 功率模式
_varPowerModeR.ValueChanged += new VariableEventHandler(VarPowerModeR_ValueChanged);
// TXI
_varTxiR.ValueChanged += new VariableEventHandler(VarTxiR_ValueChanged);
Log(CometLogLevel.Info, "所有反馈类变量 ValueChanged 事件已绑定");
}
#endregion
#region ValueChanged 回调处理方法
private static void VarKVR_ValueChanged(object sender, VariableEventArgs e)
{
Variable v = (Variable)sender;
_actualVoltage = (float)Math.Round(double.Parse(v.Value.ToString()), 2);
PublishStatusUpdate();
}
private static void VarMAR_ValueChanged(object sender, VariableEventArgs e)
{
Variable v = (Variable)sender;
_actualCurrent = (float)Math.Round(double.Parse(v.Value.ToString()), 2);
PublishStatusUpdate();
}
private static void VarKVS_ValueChanged(object sender, VariableEventArgs e)
{
Variable v = (Variable)sender;
_setVoltage = (float)Math.Round(double.Parse(v.Value.ToString()), 2);
PublishStatusUpdate();
}
private static void VarMAS_ValueChanged(object sender, VariableEventArgs e)
{
Variable v = (Variable)sender;
_setCurrent = (float)Math.Round(double.Parse(v.Value.ToString()), 2);
PublishStatusUpdate();
}
private static void VarXonR_ValueChanged(object sender, VariableEventArgs e)
{
Variable v = (Variable)sender;
_isXRayOn = bool.Parse(v.Value.ToString());
XRayStateChanged?.Invoke(null, _isXRayOn);
PublishStatusUpdate();
}
private static void VarWarmUpR_ValueChanged(object sender, VariableEventArgs e)
{
Variable v = (Variable)sender;
_warmUpCode = v.Value?.ToString() ?? "0";
PublishStatusUpdate();
}
private static void VarVaconR_ValueChanged(object sender, VariableEventArgs e)
{
Variable v = (Variable)sender;
_vacuumCode = v.Value?.ToString() ?? "0";
PublishStatusUpdate();
}
private static void VarStartUpR_ValueChanged(object sender, VariableEventArgs e)
{
Variable v = (Variable)sender;
_startUpCode = v.Value?.ToString() ?? "0";
PublishStatusUpdate();
}
private static void VarAutoCenterR_ValueChanged(object sender, VariableEventArgs e)
{
Variable v = (Variable)sender;
_autoCenterCode = v.Value?.ToString() ?? "0";
PublishStatusUpdate();
}
private static void VarFilamentAdjustR_ValueChanged(object sender, VariableEventArgs e)
{
Variable v = (Variable)sender;
_filamentAdjustCode = v.Value?.ToString() ?? "0";
PublishStatusUpdate();
}
private static void VarInterLockR_ValueChanged(object sender, VariableEventArgs e)
{
Variable v = (Variable)sender;
string val = v.Value.ToString();
_isInterlockActive = val == "True";
PublishStatusUpdate();
}
private static void VarWatchingDog_ValueChanged(object sender, VariableEventArgs e)
{
Variable v = (Variable)sender;
_watchdogStatus = v.Value.ToString();
// 注意:看门狗不触发 PublishStatusUpdate
}
private static void VarPowerModeR_ValueChanged(object sender, VariableEventArgs e)
{
Variable v = (Variable)sender;
_powerModeCode = v.Value?.ToString()?.Trim() ?? "";
Log(CometLogLevel.Debug, "功率模式原始值: '{0}'", _powerModeCode);
PublishStatusUpdate();
}
private static void VarTxiR_ValueChanged(object sender, VariableEventArgs e)
{
Variable v = (Variable)sender;
_txiCode = v.Value?.ToString() ?? "False";
PublishStatusUpdate();
}
///
/// 构建状态数据并触发 StatusChanged 事件
///
private static void PublishStatusUpdate()
{
StatusChanged?.Invoke(null, BuildStatusData());
}
///
/// 构建当前状态数据快照
///
private static CometStatusData BuildStatusData()
{
return new CometStatusData
{
SetVoltage = _setVoltage,
ActualVoltage = _actualVoltage,
SetCurrent = _setCurrent,
ActualCurrent = _actualCurrent,
IsXRayOn = _isXRayOn,
WarmUpStatus = _warmUpCode,
VacuumStatus = _vacuumCode,
StartUpStatus = _startUpCode,
AutoCenterStatus = _autoCenterCode,
FilamentAdjustStatus = _filamentAdjustCode,
IsInterlockActive = _isInterlockActive,
WatchdogStatus = _watchdogStatus,
PowerMode = _powerModeCode,
TxiStatus = _txiCode
};
}
#endregion
#region 状态码映射方法
///
/// 暖机状态码映射
///
internal static string MapWarmUpStatus(string code)
{
switch (code)
{
case "0": return "初始状态";
case "1": return "暖机中";
case "2": return "暖机完成到最大电压";
case "3": return "暖机因故障失败";
case "33": return "需要暖机";
default: return "未知状态";
}
}
///
/// 真空状态码映射
///
internal static string MapVacuumStatus(string code)
{
switch (code)
{
case "0": return "初始状态";
case "1": return "抽真空中";
case "2": return "真空准备好";
case "22": return "真空值<1e-5mbar";
case "30": return "真空泵未使能";
case "40": return "真空泵通风能";
default: return "未知状态";
}
}
///
/// 训机状态码映射
///
internal static string MapStartUpStatus(string code)
{
switch (code)
{
case "0": return "初始状态";
case "1": return "训机中";
case "2": return "训机完成";
case "3": return "训机因故障失败";
default: return "未知状态";
}
}
///
/// 自动定心状态码映射
///
internal static string MapAutoCenterStatus(string code)
{
switch (code)
{
case "0": return "初始状态";
case "1": return "自动定心中";
case "2": return "自动定心完成";
case "3": return "定心因故障失败";
default: return "未知状态";
}
}
///
/// 灯丝调整状态码映射
///
internal static string MapFilamentAdjustStatus(string code)
{
switch (code)
{
case "0": return "初始状态";
case "1": return "灯丝校准中";
case "2": return "灯丝校准完成";
case "3": return "灯丝校准因故障失败";
case "33": return "需要灯丝校准";
default: return "未知状态";
}
}
///
/// 功率模式映射
///
internal static string MapPowerMode(string value)
{
// PVI 变量可能返回带空格或小数的值,统一处理 | PVI variable may return value with spaces or decimals
var trimmed = (value ?? "").Trim();
// 尝试解析为数字后再比较 | Try parsing as number before comparing
if (int.TryParse(trimmed, out var intVal))
{
switch (intVal)
{
case 1: return "Micro Focus";
case 2: return "High Power";
}
}
else if (double.TryParse(trimmed, out var dblVal))
{
switch ((int)dblVal)
{
case 1: return "Micro Focus";
case 2: return "High Power";
}
}
return $"Unknown({trimmed})";
}
///
/// TXI 状态映射
///
internal static string MapTxiStatus(string value)
{
switch (value)
{
case "True": return "TXI is on";
case "False": return "TXI is off";
default: return "未知状态";
}
}
#endregion
#region 射线控制和参数设置方法
///
/// 开启高压
///
public static void TurnOn()
{
Log(CometLogLevel.Info, "执行 TurnOn 操作");
try
{
_varXonS.Value = "True";
_varXonS.WriteValue();
Log(CometLogLevel.Info, "TurnOn 操作完成");
}
catch (Exception ex)
{
Log(CometLogLevel.Error, "TurnOn 操作异常:{0}", ex.Message);
ErrorOccurred?.Invoke(null, $"TurnOn 操作异常:{ex.Message}");
throw;
}
}
///
/// 关闭高压
///
public static void TurnOff()
{
Log(CometLogLevel.Info, "执行 TurnOff 操作");
try
{
_varXoffS.Value = "True";
_varXoffS.WriteValue();
Log(CometLogLevel.Info, "TurnOff 操作完成");
}
catch (Exception ex)
{
Log(CometLogLevel.Error, "TurnOff 操作异常:{0}", ex.Message);
ErrorOccurred?.Invoke(null, $"TurnOff 操作异常:{ex.Message}");
throw;
}
}
///
/// 设置电压(kV)
///
public static void SetVoltage(float voltage)
{
Log(CometLogLevel.Info, "执行 SetVoltage 操作,目标电压:{0}kV", voltage);
try
{
_varKVS.Value = voltage.ToString();
_varKVS.WriteValue();
_setVoltage = voltage;
Log(CometLogLevel.Info, "SetVoltage 操作完成,电压:{0}kV", voltage);
}
catch (Exception ex)
{
Log(CometLogLevel.Error, "SetVoltage 操作异常:{0}", ex.Message);
ErrorOccurred?.Invoke(null, $"SetVoltage 操作异常:{ex.Message}");
throw;
}
}
///
/// 设置电流(μA)
///
public static void SetCurrent(float current)
{
Log(CometLogLevel.Info, "执行 SetCurrent 操作,目标电流:{0}μA", current);
try
{
_varMAS.Value = current.ToString();
_varMAS.WriteValue();
_setCurrent = current;
Log(CometLogLevel.Info, "SetCurrent 操作完成,电流:{0}μA", current);
}
catch (Exception ex)
{
Log(CometLogLevel.Error, "SetCurrent 操作异常:{0}", ex.Message);
ErrorOccurred?.Invoke(null, $"SetCurrent 操作异常:{ex.Message}");
throw;
}
}
public static void SetWatchDog()
{
if (_cpu != null)
{
if (_cpu.IsConnected)
{
if (_isVariablesConnected)
{
_varWatchingDog.Value = "0";
_varWatchingDog.WriteValue();
}
}
}
}
///
/// TXI 开启
///
public static void TxiOn()
{
Log(CometLogLevel.Info, "执行 TXI ON 操作");
try
{
_varTxiOpenS.Value = "True";
_varTxiOpenS.WriteValue();
Log(CometLogLevel.Info, "TXI ON 操作完成");
}
catch (Exception ex)
{
Log(CometLogLevel.Error, "TXI ON 操作异常:{0}", ex.Message);
ErrorOccurred?.Invoke(null, $"TXI ON 操作异常:{ex.Message}");
throw;
}
}
///
/// TXI 关闭
///
public static void TxiOff()
{
Log(CometLogLevel.Info, "执行 TXI OFF 操作");
try
{
_varTxiCloseS.Value = "True";
_varTxiCloseS.WriteValue();
Log(CometLogLevel.Info, "TXI OFF 操作完成");
}
catch (Exception ex)
{
Log(CometLogLevel.Error, "TXI OFF 操作异常:{0}", ex.Message);
ErrorOccurred?.Invoke(null, $"TXI OFF 操作异常:{ex.Message}");
throw;
}
}
///
/// 暖机设置
///
public static void WarmUp()
{
Log(CometLogLevel.Info, "执行暖机设置操作");
try
{
_varWarmUpS.Value = "True";
_varWarmUpS.WriteValue();
Log(CometLogLevel.Info, "暖机设置操作完成");
}
catch (Exception ex)
{
Log(CometLogLevel.Error, "暖机设置操作异常:{0}", ex.Message);
ErrorOccurred?.Invoke(null, $"暖机设置操作异常:{ex.Message}");
throw;
}
}
///
/// 训机设置
///
public static void Training()
{
Log(CometLogLevel.Info, "执行训机设置操作");
try
{
_varStartUpS.Value = "True";
_varStartUpS.WriteValue();
Log(CometLogLevel.Info, "训机设置操作完成");
}
catch (Exception ex)
{
Log(CometLogLevel.Error, "训机设置操作异常:{0}", ex.Message);
ErrorOccurred?.Invoke(null, $"训机设置操作异常:{ex.Message}");
throw;
}
}
///
/// 灯丝校准
///
public static void FilamentCalibration()
{
Log(CometLogLevel.Info, "执行灯丝校准操作");
try
{
_varFilamentAdjust.Value = "True";
_varFilamentAdjust.WriteValue();
Log(CometLogLevel.Info, "灯丝校准操作完成");
}
catch (Exception ex)
{
Log(CometLogLevel.Error, "灯丝校准操作异常:{0}", ex.Message);
ErrorOccurred?.Invoke(null, $"灯丝校准操作异常:{ex.Message}");
throw;
}
}
///
/// 全部电压自动定心
///
public static void AutoCenter()
{
Log(CometLogLevel.Info, "执行全部电压自动定心操作");
try
{
_varALLKVCenter.Value = "True";
_varALLKVCenter.WriteValue();
Log(CometLogLevel.Info, "全部电压自动定心操作完成");
}
catch (Exception ex)
{
Log(CometLogLevel.Error, "全部电压自动定心操作异常:{0}", ex.Message);
ErrorOccurred?.Invoke(null, $"全部电压自动定心操作异常:{ex.Message}");
throw;
}
}
///
/// 设置功率模式
///
/// 功率模式值:1=Micro Focus,2=High Power
public static void SetPowerMode(int mode)
{
Log(CometLogLevel.Info, "执行设置功率模式操作,Mode={0}", mode);
try
{
_varPowerModeS.Value = mode.ToString();
_varPowerModeS.WriteValue();
Log(CometLogLevel.Info, "设置功率模式操作完成,Mode={0}", mode);
}
catch (Exception ex)
{
Log(CometLogLevel.Error, "设置功率模式操作异常:{0}", ex.Message);
ErrorOccurred?.Invoke(null, $"设置功率模式操作异常:{ex.Message}");
throw;
}
}
#endregion
#region 状态读取方法
///
/// 读取实际电压反馈值
///
public static float ReadVoltage()
{
return _actualVoltage;
}
///
/// 读取实际电流反馈值
///
public static float ReadCurrent()
{
return _actualCurrent;
}
///
/// 读取完整系统状态
///
public static CometStatusData ReadSystemStatus()
{
return BuildStatusData();
}
///
/// 读取连接状态
///
/// true=已连接,false=未连接
public static bool ReadRaySourceConnectStatus()
{
PviConnectionState newState = PviConnectionState.Disconnected;
bool result = false;
if (_cpu != null)
{
if (_cpu.IsConnected && _isVariablesConnected)
{
newState = PviConnectionState.RaySourceConnected;
result = true;
}
else if (_isVariablesConnected)
{
newState = PviConnectionState.VariablesConnected;
}
else if (_isConnected)
{
newState = PviConnectionState.ServiceConnected;
}
}
// 仅在状态变化时触发事件
if (newState != _currentConnectionState)
{
_currentConnectionState = newState;
ConnectionStateChanged?.Invoke(null, _currentConnectionState);
}
return result;
}
///
/// 读取错误状态
///
public static CometErrorData ReadErrors()
{
return new CometErrorData
{
SystemError = _sysErrR?.Value?.ToString() ?? "",
HSGError = _HSGErrR?.Value?.ToString() ?? "",
TubeError = _tubeErrR?.Value?.ToString() ?? "",
TubeVacError = _tubeACErrR?.Value?.ToString() ?? ""
};
}
#endregion
#region Disconnect 和 Dispose 资源释放
///
/// 断开所有 PVI 变量并释放资源
///
public static void Disconnect()
{
Log(CometLogLevel.Info, "执行 Disconnect 操作,断开所有 PVI 变量");
try
{
// 如果射线仍处于开启状态,先关闭高压再断开连接
if (_isXRayOn)
{
Log(CometLogLevel.Warn, "检测到射线仍处于开启状态,先执行 TurnOff 关闭高压");
TurnOff();
}
Variable[] allVariables = {
_varKVS, _varKVR, _varMAS, _varMAR,
_varXonS, _varXoffS, _varXonR,
_varWarmUpS, _varWarmUpR,
_varVaconS, _varVaconR, _varVaconRV,
_varStartUpS, _varStartUpR,
_varCurrentKVAutoCenter, _varALLKVCenter, _varAutoCenterR,
_varFilamentAdjust, _varFilamentAdjustR,
_varInterLockR, _varWatchingDog,
_varPowerModeR, _varPowerModeS, _varTxiR,
_varTxiOpenS, _varTxiCloseS,
_sysErrR, _sysErrS,
_HSGErrR, _HSGErrS,
_tubeErrR, _tubeErrS,
_tubeACErrR, _tubeACErrS
};
foreach (var variable in allVariables)
{
if (variable != null)
{
variable.Active = false;
variable.Disconnected += new PviEventHandler(Variable_Disconnected);
variable.Disconnect();
}
}
_isConnected = false;
_isVariablesConnected = false;
ConnectionStateChanged?.Invoke(null, PviConnectionState.Disconnected);
Log(CometLogLevel.Info, "Disconnect 操作完成,所有变量已断开");
}
catch (Exception ex)
{
Log(CometLogLevel.Warn, "Disconnect 过程中发生异常:{0}", ex.Message);
ErrorOccurred?.Invoke(null, $"Disconnect 异常:{ex.Message}");
_isConnected = false;
_isVariablesConnected = false;
}
}
///
/// 变量断开回调:释放变量资源
///
private static void Variable_Disconnected(object sender, PviEventArgs e)
{
try
{
var variable = sender as Variable;
variable?.Dispose();
}
catch (Exception ex)
{
Log(CometLogLevel.Warn, "变量 Dispose 异常:{0}", ex.Message);
}
}
///
/// 释放所有资源
///
public static void Dispose()
{
Disconnect();
// 释放 CPU
try { _cpu?.Dispose(); } catch { }
// 释放 Service
try { _service?.Dispose(); } catch { }
}
#endregion
}
}