Files
XplorePlane/XP.Hardware.RaySource.Comet.Host/Comet/CometPviClient.cs
T

1169 lines
41 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
{
/// <summary>
/// Comet PVI 通讯客户端静态类
/// 封装 BR.AN.PviServices 的所有直接调用
/// 包含:Service/CPU 连接管理、Variable 创建/激活/绑定、ValueChanged 回调处理
/// </summary>
public static class CometPviClient
{
#region
/// <summary>
/// 日志回调委托(由 .NET 8 层注入)
/// </summary>
private static Action<CometLogLevel, string, object[]> _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
/// <summary>
/// 状态更新事件(电压、电流、各子系统状态变化时触发)
/// </summary>
public static event EventHandler<CometStatusData> StatusChanged;
/// <summary>
/// 射线开关状态变更事件
/// </summary>
public static event EventHandler<bool> XRayStateChanged;
/// <summary>
/// PVI 连接错误事件
/// </summary>
public static event EventHandler<string> ErrorOccurred;
/// <summary>
/// PVI 连接状态变更事件(未连接、Service已连接、变量已连接)
/// </summary>
public static event EventHandler<PviConnectionState> ConnectionStateChanged;
#endregion
#region
/// <summary>
/// PVI 连接是否已建立
/// </summary>
public static bool IsConnected => _isConnected;
/// <summary>
/// PVI 变量是否已连接
/// </summary>
public static bool IsVariablesConnected => _isVariablesConnected;
/// <summary>
/// 当前 PVI 连接状态
/// </summary>
public static PviConnectionState CurrentConnectionState => _currentConnectionState;
#endregion
#region
/// <summary>
/// 设置日志回调委托
/// </summary>
public static void SetLogger(Action<CometLogLevel, string, object[]> logger)
{
_logger = logger;
}
/// <summary>
/// 内部日志输出辅助方法
/// 如果未注入日志回调,则静默忽略
/// </summary>
private static void Log(CometLogLevel level, string message, params object[] args)
{
_logger?.Invoke(level, message, args);
}
#endregion
#region Initialize - PVI Service CPU
/// <summary>
/// 初始化 PVI Service 和 CPU 连接
/// </summary>
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;
}
}
/// <summary>
/// PVI Service Connected 回调:创建 CPU 对象,设置 TCP/IP 参数,连接 CPU
/// </summary>
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}");
}
}
/// <summary>
/// CPU Connected 回调:确认连接成功,触发连接状态变更事件
/// </summary>
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);
}
}
/// <summary>
/// PVI Service Error 回调:记录错误并触发错误事件
/// </summary>
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
/// <summary>
/// 创建、激活并绑定所有 PVI 变量
/// </summary>
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;
}
}
/// <summary>
/// 创建所有 PVI Variable 对象
/// </summary>
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 变量对象创建完成");
}
/// <summary>
/// 激活所有变量并调用 Connect
/// </summary>
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 变量已激活并连接");
}
/// <summary>
/// 为所有反馈类变量绑定 ValueChanged 事件处理程序
/// </summary>
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();
}
/// <summary>
/// 构建状态数据并触发 StatusChanged 事件
/// </summary>
private static void PublishStatusUpdate()
{
StatusChanged?.Invoke(null, BuildStatusData());
}
/// <summary>
/// 构建当前状态数据快照
/// </summary>
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
/// <summary>
/// 暖机状态码映射
/// </summary>
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 "未知状态";
}
}
/// <summary>
/// 真空状态码映射
/// </summary>
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 "未知状态";
}
}
/// <summary>
/// 训机状态码映射
/// </summary>
internal static string MapStartUpStatus(string code)
{
switch (code)
{
case "0": return "初始状态";
case "1": return "训机中";
case "2": return "训机完成";
case "3": return "训机因故障失败";
default: return "未知状态";
}
}
/// <summary>
/// 自动定心状态码映射
/// </summary>
internal static string MapAutoCenterStatus(string code)
{
switch (code)
{
case "0": return "初始状态";
case "1": return "自动定心中";
case "2": return "自动定心完成";
case "3": return "定心因故障失败";
default: return "未知状态";
}
}
/// <summary>
/// 灯丝调整状态码映射
/// </summary>
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 "未知状态";
}
}
/// <summary>
/// 功率模式映射
/// </summary>
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})";
}
/// <summary>
/// TXI 状态映射
/// </summary>
internal static string MapTxiStatus(string value)
{
switch (value)
{
case "True": return "TXI is on";
case "False": return "TXI is off";
default: return "未知状态";
}
}
#endregion
#region 线
/// <summary>
/// 开启高压
/// </summary>
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;
}
}
/// <summary>
/// 关闭高压
/// </summary>
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;
}
}
/// <summary>
/// 设置电压(kV
/// </summary>
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;
}
}
/// <summary>
/// 设置电流(μA
/// </summary>
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();
}
}
}
}
/// <summary>
/// TXI 开启
/// </summary>
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;
}
}
/// <summary>
/// TXI 关闭
/// </summary>
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;
}
}
/// <summary>
/// 暖机设置
/// </summary>
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;
}
}
/// <summary>
/// 训机设置
/// </summary>
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;
}
}
/// <summary>
/// 灯丝校准
/// </summary>
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;
}
}
/// <summary>
/// 全部电压自动定心
/// </summary>
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;
}
}
/// <summary>
/// 设置功率模式
/// </summary>
/// <param name="mode">功率模式值:1=Micro Focus2=High Power</param>
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
/// <summary>
/// 读取实际电压反馈值
/// </summary>
public static float ReadVoltage()
{
return _actualVoltage;
}
/// <summary>
/// 读取实际电流反馈值
/// </summary>
public static float ReadCurrent()
{
return _actualCurrent;
}
/// <summary>
/// 读取完整系统状态
/// </summary>
public static CometStatusData ReadSystemStatus()
{
return BuildStatusData();
}
/// <summary>
/// 读取连接状态
/// </summary>
/// <returns>true=已连接,false=未连接</returns>
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;
}
/// <summary>
/// 读取错误状态
/// </summary>
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
/// <summary>
/// 断开所有 PVI 变量并释放资源
/// </summary>
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;
}
}
/// <summary>
/// 变量断开回调:释放变量资源
/// </summary>
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);
}
}
/// <summary>
/// 释放所有资源
/// </summary>
public static void Dispose()
{
Disconnect();
// 释放 CPU
try { _cpu?.Dispose(); } catch { }
// 释放 Service
try { _service?.Dispose(); } catch { }
}
#endregion
}
}