Files
XplorePlane/XP.Hardware.RaySource/Services/RaySourceService.cs
T

997 lines
43 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 Prism.Events;
using System;
using System.Threading.Tasks;
using XP.Common.Logging.Interfaces;
using XP.Hardware.RaySource.Abstractions;
using XP.Hardware.RaySource.Abstractions.Enums;
using XP.Hardware.RaySource.Abstractions.Events;
using XP.Hardware.RaySource.Config;
namespace XP.Hardware.RaySource.Services
{
/// <summary>
/// 射线源业务服务实现类 | X-Ray Source Business Service Implementation
/// 单例模式,调度工厂+业务规则校验+事件驱动 | Singleton pattern, factory dispatch + business rule validation + event-driven
/// </summary>
public class RaySourceService : IRaySourceService
{
private readonly IRaySourceFactory _factory;
private readonly RaySourceConfig _config;
private readonly IEventAggregator _eventAggregator;
private readonly ILoggerService _logger;
private readonly IFilamentLifetimeService _filamentLifetimeService;
private IXRaySource _currentSource;
private bool _isDisposed = false;
private readonly object _lockObj = new object();
/// <summary>
/// 上一次灯丝记录对应的射线状态(用于去重,防止设备推送抖动)| Last filament recording status (for dedup, prevents device push jitter)
/// </summary>
private RaySourceStatus? _lastFilamentRecordedStatus;
/// <summary>
/// 当前射线源实例 | Current X-ray source instance
/// </summary>
public IXRaySource CurrentSource => _currentSource;
/// <summary>
/// 是否已初始化(且连接正常)| Is initialized (and connected)
/// </summary>
public bool IsInitialized => _isInitializedFlag && _currentSource != null;
private bool _isInitializedFlag = false;
/// <summary>
/// 是否射线开启(由 CurrentStatus 派生,Opened 即为 true| Is X-ray on (derived from CurrentStatus, true when Opened)
/// </summary>
public bool IsXRayOn => CurrentStatus == RaySourceStatus.Opened;
/// <summary>
/// 射线源是否已建立完整连接(由设备层 RaySourceConnected 推送确认)| Whether RaySource has established full connection (confirmed by device RaySourceConnected push)
/// </summary>
public bool IsConnected => _currentSource?.IsConnected ?? false;
/// <summary>
/// 当前射线源状态 | Current X-ray source status
/// </summary>
public RaySourceStatus CurrentStatus { get; private set; } = RaySourceStatus.Unavailable;
/// <summary>
/// 构造函数 | Constructor
/// </summary>
public RaySourceService(
IRaySourceFactory factory,
RaySourceConfig config,
IEventAggregator eventAggregator,
ILoggerService logger,
IFilamentLifetimeService filamentLifetimeService)
{
_factory = factory ?? throw new ArgumentNullException(nameof(factory));
_config = config ?? throw new ArgumentNullException(nameof(config));
_eventAggregator = eventAggregator ?? throw new ArgumentNullException(nameof(eventAggregator));
_logger = (logger ?? throw new ArgumentNullException(nameof(logger))).ForModule("RaySource.Service");
_filamentLifetimeService = filamentLifetimeService ?? throw new ArgumentNullException(nameof(filamentLifetimeService));
_logger.Info("射线源服务已创建 | RaySource service created");
// 订阅射线源状态变更事件(处理状态同步和异常断联)| Subscribe to ray source status changed event
_eventAggregator.GetEvent<RaySourceStatusChangedEvent>().Subscribe(OnRaySourceStatusChangedFromDevice);
}
/// <summary>
/// 初始化射线源(射线源类型从配置文件读取)| Initialize X-ray source (source type read from configuration)
/// </summary>
public XRayResult Initialize()
{
var sourceType = _config.SourceType;
lock (_lockObj)
{
try
{
_logger.Info("开始初始化射线源,类型: {SourceType} | Starting X-ray source initialization, type: {SourceType}", sourceType);
if (IsInitialized)
{
_logger.Warn("射线源已初始化,请勿重复初始化 | X-ray source already initialized");
return XRayResult.Error("射线源已初始化,请勿重复初始化");
}
// 验证配置 | Validate configuration
_logger.Debug("验证配置参数 | Validating configuration parameters");
var (isValid, errorMessage) = _config.Validate();
if (!isValid)
{
_logger.Error(null, "配置验证失败: {ErrorMessage} | Configuration validation failed: {ErrorMessage}", errorMessage);
return XRayResult.Error($"配置验证失败: {errorMessage}");
}
// 复用已有实例或创建新实例 | Reuse existing instance or create new one
if (_currentSource == null)
{
_logger.Debug("创建射线源实例: {SourceType} | Creating X-ray source instance: {SourceType}", sourceType);
_currentSource = _factory.CreateRaySource(sourceType);
if (_currentSource == null)
{
_logger.Error(null, "创建射线源实例失败: {SourceType} | Failed to create X-ray source instance: {SourceType}", sourceType);
return XRayResult.Error($"创建射线源实例失败: {sourceType}");
}
}
else
{
_logger.Debug("复用已有射线源实例 | Reusing existing X-ray source instance");
}
// 初始化射线源 | Initialize X-ray source
_logger.Info("调用射线源初始化方法 | Calling X-ray source initialization method");
var result = _currentSource.Initialize();
if (result.Success)
{
_isInitializedFlag = true;
_logger.Info("射线源初始化成功: {SourceType} | X-ray source initialized successfully: {SourceType}", sourceType);
}
else
{
_logger.Error(null, "射线源初始化失败: {ErrorMessage} | X-ray source initialization failed: {ErrorMessage}", result.ErrorMessage);
}
return result;
}
catch (Exception ex)
{
var errorMsg = $"初始化异常: {ex.Message}";
_logger.Error(ex, "射线源初始化异常: {Message} | X-ray source initialization exception: {Message}", ex.Message);
_eventAggregator.GetEvent<ErrorOccurredEvent>().Publish(errorMsg);
return XRayResult.Error(errorMsg);
}
}
}
/// <summary>
/// 连接 PVI 变量并启动实时状态通讯 | Connect PVI variables and start real-time status communication
/// 必须在 Initialize 成功后、TurnOn 之前调用 | Must be called after Initialize succeeds and before TurnOn
/// </summary>
public XRayResult ConnectVariables()
{
if (!IsInitialized || _currentSource == null)
{
_logger.Warn("射线源未初始化,无法连接变量 | X-ray source not initialized, cannot connect variables");
return XRayResult.Error("射线源未初始化,无法连接变量");
}
lock (_lockObj)
{
try
{
_logger.Info("开始连接 PVI 变量 | Starting PVI variable connection");
var result = _currentSource.ConnectVariables();
if (result.Success)
{
_logger.Info("PVI 变量连接命令已发送,等待设备层确认 | PVI variable connection command sent, waiting for device confirmation");
}
else
{
_logger.Error(null, "PVI 变量连接失败: {ErrorMessage} | PVI variable connection failed: {ErrorMessage}", result.ErrorMessage);
}
return result;
}
catch (Exception ex)
{
var errorMsg = $"连接变量异常: {ex.Message}";
_logger.Error(ex, "连接变量异常: {Message} | Connect variables exception: {Message}", ex.Message);
_eventAggregator.GetEvent<ErrorOccurredEvent>().Publish(errorMsg);
return XRayResult.Error(errorMsg);
}
}
}
/// <summary>
/// 开启射线 | Turn on X-ray
/// </summary>
public XRayResult TurnOn()
{
// 业务规则校验:未初始化禁止操作 | Business rule: operation forbidden if not initialized
if (!IsInitialized || _currentSource == null)
{
_logger.Warn("射线源未初始化,无法开启射线 | X-ray source not initialized, cannot turn on");
return XRayResult.Error("射线源未初始化,无法开启射线");
}
// 快速检查:已开启则直接返回,避免不必要的锁竞争 | Quick check: return early if already opened
if (CurrentStatus == RaySourceStatus.Opened)
{
_logger.Warn("射线已处于开启状态,忽略重复请求 | X-ray already opened, ignoring duplicate request");
return XRayResult.Ok("射线已开启");
}
lock (_lockObj)
{
try
{
// 获取锁后再次检查状态,防止重复开启 | Double-check status after acquiring lock
if (CurrentStatus == RaySourceStatus.Opened)
{
_logger.Warn("射线已处于开启状态,忽略重复请求 | X-ray already opened, ignoring duplicate request");
return XRayResult.Ok("射线已开启");
}
_logger.Info("开始开启射线 | Starting to turn on X-ray");
var result = _currentSource.TurnOn();
if (result.Success)
{
CurrentStatus = RaySourceStatus.Opened;
_logger.Info("射线开启成功,状态更新为 Opened | X-ray turned on successfully, status updated to Opened");
_eventAggregator.GetEvent<RaySourceStatusChangedEvent>().Publish(CurrentStatus);
// 灯丝记录由 OnRaySourceStatusChangedFromDevice 统一处理,避免重复调用
}
else
{
_logger.Error(null, "射线开启失败: {ErrorMessage} | X-ray turn on failed: {ErrorMessage}", result.ErrorMessage);
}
return result;
}
catch (Exception ex)
{
_logger.Error(ex, "开启射线异常: {Message} | Exception turning on X-ray: {Message}", ex.Message);
throw;
}
}
}
/// <summary>
/// 关闭射线 | Turn off X-ray
/// </summary>
public XRayResult TurnOff()
{
// 业务规则校验:未初始化禁止操作 | Business rule: operation forbidden if not initialized
if (!IsInitialized || _currentSource == null)
{
_logger.Warn("射线源未初始化,无法关闭射线 | X-ray source not initialized, cannot turn off");
return XRayResult.Error("射线源未初始化,无法关闭射线");
}
// 快速检查:已关闭则直接返回,避免不必要的锁竞争 | Quick check: return early if already closed
if (CurrentStatus == RaySourceStatus.Closed)
{
_logger.Warn("射线已处于关闭状态,忽略重复请求 | X-ray already closed, ignoring duplicate request");
return XRayResult.Ok("射线已关闭");
}
lock (_lockObj)
{
try
{
// 获取锁后再次检查状态,防止重复关闭 | Double-check status after acquiring lock
if (CurrentStatus == RaySourceStatus.Closed)
{
_logger.Warn("射线已处于关闭状态,忽略重复请求 | X-ray already closed, ignoring duplicate request");
return XRayResult.Ok("射线已关闭");
}
_logger.Info("开始关闭射线 | Starting to turn off X-ray");
var result = _currentSource.TurnOff();
if (result.Success)
{
CurrentStatus = RaySourceStatus.Closed;
_logger.Info("射线关闭成功,状态更新为 Closed | X-ray turned off successfully, status updated to Closed");
_eventAggregator.GetEvent<RaySourceStatusChangedEvent>().Publish(CurrentStatus);
// 灯丝记录由 OnRaySourceStatusChangedFromDevice 统一处理,避免重复调用
}
else
{
_logger.Error(null, "射线关闭失败: {ErrorMessage} | X-ray turn off failed: {ErrorMessage}", result.ErrorMessage);
}
return result;
}
catch (Exception ex)
{
_logger.Error(ex, "关闭射线异常: {Message} | Exception turning off X-ray: {Message}", ex.Message);
throw;
}
}
}
/// <summary>
/// 断开射线源连接(保留实例以便重连)| Disconnect X-ray source (retain instance for reconnection)
/// </summary>
public XRayResult Disconnect()
{
lock (_lockObj)
{
try
{
_logger.Info("开始断开射线源连接 | Starting X-ray source disconnection");
if (_currentSource == null)
{
_logger.Warn("射线源实例不存在,无需断开 | X-ray source instance does not exist, no need to disconnect");
_isInitializedFlag = false;
CurrentStatus = RaySourceStatus.Unavailable;
_eventAggregator.GetEvent<RaySourceStatusChangedEvent>().Publish(CurrentStatus);
return XRayResult.Ok("射线源已断开");
}
// 同步调用 CloseOff 进行优雅关闭 | Call CloseOff for graceful shutdown
try
{
var closeResult = _currentSource.CloseOff();
if (!closeResult.Success)
{
_logger.Warn("优雅关闭返回失败: {ErrorMessage} | Graceful shutdown returned failure: {ErrorMessage}", closeResult.ErrorMessage);
}
}
catch (Exception ex)
{
_logger.Warn("优雅关闭异常: {Message} | Graceful shutdown exception: {Message}", ex.Message);
}
// 不 Dispose 实例,保留 PVI Service 以便重连 | Don't dispose instance, retain PVI Service for reconnection
_isInitializedFlag = false;
CurrentStatus = RaySourceStatus.Unavailable;
// 断开连接时停止灯丝使用记录 | Stop filament usage recording on disconnect
if (_filamentLifetimeService.IsInitialized && _filamentLifetimeService.IsFilamentOn)
{
_filamentLifetimeService.StopFilamentUsage();
_lastFilamentRecordedStatus = RaySourceStatus.Unavailable;
}
_logger.Info("射线源连接已断开,状态更新为 Unavailable | X-ray source disconnected, status updated to Unavailable");
_eventAggregator.GetEvent<RaySourceStatusChangedEvent>().Publish(CurrentStatus);
return XRayResult.Ok();
}
catch (Exception ex)
{
var errorMsg = $"断开连接异常: {ex.Message}";
_logger.Error(ex, "射线源断开连接异常: {Message} | X-ray source disconnection exception: {Message}", ex.Message);
_eventAggregator.GetEvent<ErrorOccurredEvent>().Publish(errorMsg);
return XRayResult.Error(errorMsg);
}
}
}
/// <summary>
/// 紧急关闭(最高优先级,强制中断所有操作)| Emergency shutdown (highest priority, force interrupt all operations)
/// </summary>
public XRayResult EmergencyShutdown()
{
try
{
_logger.Warn("执行紧急关闭程序 | Executing emergency shutdown");
if (_currentSource != null)
{
// 先关闭射线 | Turn off X-ray first
_logger.Info("紧急关闭:关闭射线 | Emergency shutdown: turning off X-ray");
_currentSource.TurnOff();
// 完全关闭设备 | Fully shut down device
_logger.Info("紧急关闭:完全关闭设备 | Emergency shutdown: fully shutting down device");
_currentSource.CloseOff();
}
_isInitializedFlag = false;
CurrentStatus = RaySourceStatus.Unavailable;
// 紧急关闭时停止灯丝使用记录 | Stop filament usage recording on emergency shutdown
if (_filamentLifetimeService.IsInitialized && _filamentLifetimeService.IsFilamentOn)
{
_filamentLifetimeService.StopFilamentUsage();
_lastFilamentRecordedStatus = RaySourceStatus.Unavailable;
}
_logger.Info("紧急关闭完成,状态更新为 Unavailable | Emergency shutdown completed, status updated to Unavailable");
_eventAggregator.GetEvent<RaySourceStatusChangedEvent>().Publish(CurrentStatus);
_eventAggregator.GetEvent<OperationResultEvent>()
.Publish(new OperationResultData("紧急关闭", true, "紧急关闭完成"));
return XRayResult.Ok("紧急关闭完成");
}
catch (Exception ex)
{
var errorMsg = $"紧急关闭异常: {ex.Message}";
_logger.Error(ex, "紧急关闭异常: {Message} | Emergency shutdown exception: {Message}", ex.Message);
_eventAggregator.GetEvent<ErrorOccurredEvent>().Publish(errorMsg);
return XRayResult.Error(errorMsg);
}
}
/// <summary>
/// 设置电压 | Set voltage
/// </summary>
public XRayResult SetVoltage(float voltage)
{
// 业务规则校验:未初始化禁止操作 | Business rule: operation forbidden if not initialized
if (!IsInitialized || _currentSource == null)
{
_logger.Warn("射线源未初始化,无法设置电压 | X-ray source not initialized, cannot set voltage");
return XRayResult.Error("射线源未初始化,无法设置电压");
}
// 参数范围校验 | Parameter range validation
if (voltage < _config.MinVoltage || voltage > _config.MaxVoltage)
{
_logger.Warn("电压参数超出范围: {Voltage}kV,有效范围: {Min}-{Max}kV | Voltage out of range: {Voltage}kV, valid range: {Min}-{Max}kV", voltage, _config.MinVoltage, _config.MaxVoltage);
return XRayResult.Error($"电压参数超出范围:{_config.MinVoltage}-{_config.MaxVoltage}kV");
}
lock (_lockObj)
{
try
{
_logger.Info("设置电压: {Voltage}kV | Setting voltage: {Voltage}kV", voltage);
var result = _currentSource.SetVoltage(voltage);
if (result.Success)
{
_logger.Info("电压设置成功: {Voltage}kV | Voltage set successfully: {Voltage}kV", voltage);
}
else
{
_logger.Error(null, "电压设置失败: {ErrorMessage} | Voltage setting failed: {ErrorMessage}", result.ErrorMessage);
}
return result;
}
catch (Exception ex)
{
_logger.Error(ex, "设置电压异常: {Message} | Exception setting voltage: {Message}", ex.Message);
throw;
}
}
}
/// <summary>
/// 设置电流 | Set current
/// </summary>
public XRayResult SetCurrent(float current)
{
// 业务规则校验:未初始化禁止操作 | Business rule: operation forbidden if not initialized
if (!IsInitialized || _currentSource == null)
{
_logger.Warn("射线源未初始化,无法设置电流 | X-ray source not initialized, cannot set current");
return XRayResult.Error("射线源未初始化,无法设置电流");
}
// 参数范围校验 | Parameter range validation
if (current < _config.MinCurrent || current > _config.MaxCurrent)
{
_logger.Warn("电流参数超出范围: {Current}μA,有效范围: {Min}-{Max}μA | Current out of range: {Current}μA, valid range: {Min}-{Max}μA", current, _config.MinCurrent, _config.MaxCurrent);
return XRayResult.Error($"电流参数超出范围:{_config.MinCurrent}-{_config.MaxCurrent}μA");
}
lock (_lockObj)
{
try
{
_logger.Info("设置电流: {Current}μA | Setting current: {Current}μA", current);
var result = _currentSource.SetCurrent(current);
if (result.Success)
{
_logger.Info("电流设置成功: {Current}μA | Current set successfully: {Current}μA", current);
}
else
{
_logger.Error(null, "电流设置失败: {ErrorMessage} | Current setting failed: {ErrorMessage}", result.ErrorMessage);
}
return result;
}
catch (Exception ex)
{
_logger.Error(ex, "设置电流异常: {Message} | Exception setting current: {Message}", ex.Message);
throw;
}
}
}
/// <summary>
/// 读取实际电压 | Read actual voltage
/// </summary>
public XRayResult ReadVoltage()
{
if (!IsInitialized || _currentSource == null)
{
_logger.Warn("射线源未初始化,无法读取电压 | X-ray source not initialized, cannot read voltage");
return XRayResult.Error("射线源未初始化");
}
try
{
_logger.Debug("读取实际电压 | Reading actual voltage");
var result = _currentSource.ReadVoltage();
if (result.Success)
{
_logger.Debug("电压读取成功: {Data}kV | Voltage read successfully: {Data}kV", result.Data);
}
else
{
_logger.Warn("电压读取失败: {ErrorMessage} | Voltage reading failed: {ErrorMessage}", result.ErrorMessage);
}
return result;
}
catch (Exception ex)
{
_logger.Error(ex, "读取电压异常: {Message} | Exception reading voltage: {Message}", ex.Message);
throw;
}
}
/// <summary>
/// 读取实际电流 | Read actual current
/// </summary>
public XRayResult ReadCurrent()
{
if (!IsInitialized || _currentSource == null)
{
_logger.Warn("射线源未初始化,无法读取电流 | X-ray source not initialized, cannot read current");
return XRayResult.Error("射线源未初始化");
}
try
{
_logger.Debug("读取实际电流 | Reading actual current");
var result = _currentSource.ReadCurrent();
if (result.Success)
{
_logger.Debug("电流读取成功: {Data}μA | Current read successfully: {Data}μA", result.Data);
}
else
{
_logger.Warn("电流读取失败: {ErrorMessage} | Current reading failed: {ErrorMessage}", result.ErrorMessage);
}
return result;
}
catch (Exception ex)
{
_logger.Error(ex, "读取电流异常: {Message} | Exception reading current: {Message}", ex.Message);
throw;
}
}
/// <summary>
/// 读取系统状态 | Read system status
/// </summary>
public XRayResult ReadSystemStatus()
{
if (!IsInitialized || _currentSource == null)
{
_logger.Warn("射线源未初始化,无法读取系统状态 | X-ray source not initialized, cannot read system status");
return XRayResult.Error("射线源未初始化");
}
try
{
_logger.Debug("读取系统状态 | Reading system status");
return _currentSource.ReadSystemStatus();
}
catch (Exception ex)
{
_logger.Error(ex, "读取系统状态异常: {Message} | Exception reading system status: {Message}", ex.Message);
throw;
}
}
/// <summary>
/// 检查错误 | Check errors
/// </summary>
public XRayResult CheckErrors()
{
if (!IsInitialized || _currentSource == null)
{
_logger.Warn("射线源未初始化,无法检查错误 | X-ray source not initialized, cannot check errors");
return XRayResult.Error("射线源未初始化");
}
try
{
_logger.Debug("检查错误状态 | Checking error status");
return _currentSource.CheckErrors();
}
catch (Exception ex)
{
_logger.Error(ex, "检查错误异常: {Message} | Exception checking errors: {Message}", ex.Message);
throw;
}
}
/// <summary>
/// 清除错误 | Clear errors
/// </summary>
public XRayResult ClearErrors()
{
if (!IsInitialized || _currentSource == null)
{
_logger.Warn("射线源未初始化,无法清除错误 | X-ray source not initialized, cannot clear errors");
return XRayResult.Error("射线源未初始化");
}
try
{
_logger.Info("开始清除错误 | Starting to clear errors");
_eventAggregator.GetEvent<OperationResultEvent>()
.Publish(new OperationResultData("清除错误", true));
_logger.Info("错误清除完成 | Errors cleared successfully");
return XRayResult.Ok("错误已清除");
}
catch (Exception ex)
{
var errorMsg = $"清除错误失败: {ex.Message}";
_logger.Error(ex, "清除错误异常: {Message} | Exception clearing errors: {Message}", ex.Message);
_eventAggregator.GetEvent<ErrorOccurredEvent>().Publish(errorMsg);
return XRayResult.Error(errorMsg);
}
}
/// <summary>
/// TXI 开启 | TXI On
/// </summary>
public XRayResult TxiOn()
{
if (!IsConnected || _currentSource == null)
{
_logger.Warn("射线源未连接,无法执行 TXI ON | X-ray source not connected, cannot execute TXI ON");
return XRayResult.Error("射线源未连接");
}
lock (_lockObj)
{
try
{
_logger.Info("开始执行 TXI ON | Starting TXI ON");
var result = _currentSource.TxiOn();
if (result.Success)
{
_logger.Info("TXI ON 执行成功 | TXI ON executed successfully");
}
else
{
_logger.Error(null, "TXI ON 执行失败: {ErrorMessage} | TXI ON failed: {ErrorMessage}", result.ErrorMessage);
}
return result;
}
catch (Exception ex)
{
_logger.Error(ex, "TXI ON 异常: {Message} | TXI ON exception: {Message}", ex.Message);
return XRayResult.Error($"TXI ON 异常:{ex.Message}");
}
}
}
/// <summary>
/// TXI 关闭 | TXI Off
/// </summary>
public XRayResult TxiOff()
{
if (!IsConnected || _currentSource == null)
{
_logger.Warn("射线源未连接,无法执行 TXI OFF | X-ray source not connected, cannot execute TXI OFF");
return XRayResult.Error("射线源未连接");
}
lock (_lockObj)
{
try
{
_logger.Info("开始执行 TXI OFF | Starting TXI OFF");
var result = _currentSource.TxiOff();
if (result.Success)
{
_logger.Info("TXI OFF 执行成功 | TXI OFF executed successfully");
}
else
{
_logger.Error(null, "TXI OFF 执行失败: {ErrorMessage} | TXI OFF failed: {ErrorMessage}", result.ErrorMessage);
}
return result;
}
catch (Exception ex)
{
_logger.Error(ex, "TXI OFF 异常: {Message} | TXI OFF exception: {Message}", ex.Message);
return XRayResult.Error($"TXI OFF 异常:{ex.Message}");
}
}
}
/// <summary>
/// 暖机设置 | Warm-up setting
/// </summary>
public XRayResult WarmUp()
{
if (!IsConnected || _currentSource == null)
{
_logger.Warn("射线源未连接,无法执行暖机 | X-ray source not connected, cannot execute warm-up");
return XRayResult.Error("射线源未连接");
}
lock (_lockObj)
{
try
{
_logger.Info("开始执行暖机设置 | Starting warm-up setting");
var result = _currentSource.WarmUp();
if (result.Success)
{
_logger.Info("暖机设置已发送 | Warm-up setting sent successfully");
}
else
{
_logger.Error(null, "暖机设置失败: {ErrorMessage} | Warm-up setting failed: {ErrorMessage}", result.ErrorMessage);
}
return result;
}
catch (Exception ex)
{
_logger.Error(ex, "暖机设置异常: {Message} | Warm-up setting exception: {Message}", ex.Message);
return XRayResult.Error($"暖机设置异常:{ex.Message}");
}
}
}
/// <summary>
/// 训机设置 | Training setting
/// </summary>
public XRayResult Training()
{
if (!IsConnected || _currentSource == null)
{
_logger.Warn("射线源未连接,无法执行训机 | X-ray source not connected, cannot execute training");
return XRayResult.Error("射线源未连接");
}
lock (_lockObj)
{
try
{
_logger.Info("开始执行训机设置 | Starting training setting");
var result = _currentSource.Training();
if (result.Success)
{
_logger.Info("训机设置已发送 | Training setting sent successfully");
}
else
{
_logger.Error(null, "训机设置失败: {ErrorMessage} | Training setting failed: {ErrorMessage}", result.ErrorMessage);
}
return result;
}
catch (Exception ex)
{
_logger.Error(ex, "训机设置异常: {Message} | Training setting exception: {Message}", ex.Message);
return XRayResult.Error($"训机设置异常:{ex.Message}");
}
}
}
/// <summary>
/// 灯丝校准 | Filament calibration
/// </summary>
public XRayResult FilamentCalibration()
{
if (!IsConnected || _currentSource == null)
{
_logger.Warn("射线源未连接,无法执行灯丝校准 | X-ray source not connected, cannot execute filament calibration");
return XRayResult.Error("射线源未连接");
}
lock (_lockObj)
{
try
{
_logger.Info("开始执行灯丝校准 | Starting filament calibration");
var result = _currentSource.FilamentCalibration();
if (result.Success)
{
_logger.Info("灯丝校准已发送 | Filament calibration sent successfully");
}
else
{
_logger.Error(null, "灯丝校准失败: {ErrorMessage} | Filament calibration failed: {ErrorMessage}", result.ErrorMessage);
}
return result;
}
catch (Exception ex)
{
_logger.Error(ex, "灯丝校准异常: {Message} | Filament calibration exception: {Message}", ex.Message);
return XRayResult.Error($"灯丝校准异常:{ex.Message}");
}
}
}
/// <summary>
/// 全部电压自动定心 | Auto-center all voltages
/// </summary>
public XRayResult AutoCenter()
{
if (!IsConnected || _currentSource == null)
{
_logger.Warn("射线源未连接,无法执行自动定心 | X-ray source not connected, cannot execute auto-center");
return XRayResult.Error("射线源未连接");
}
lock (_lockObj)
{
try
{
_logger.Info("开始执行全部电压自动定心 | Starting auto-center all voltages");
var result = _currentSource.AutoCenter();
if (result.Success)
{
_logger.Info("自动定心已发送 | Auto-center sent successfully");
}
else
{
_logger.Error(null, "自动定心失败: {ErrorMessage} | Auto-center failed: {ErrorMessage}", result.ErrorMessage);
}
return result;
}
catch (Exception ex)
{
_logger.Error(ex, "自动定心异常: {Message} | Auto-center exception: {Message}", ex.Message);
return XRayResult.Error($"自动定心异常:{ex.Message}");
}
}
}
/// <summary>
/// 设置功率模式 | Set power mode
/// </summary>
/// <param name="mode">功率模式值:1=Micro Focus2=High Power</param>
public XRayResult SetPowerMode(int mode)
{
if (!IsConnected || _currentSource == null)
{
_logger.Warn("射线源未连接,无法设置功率模式 | X-ray source not connected, cannot set power mode");
return XRayResult.Error("射线源未连接");
}
lock (_lockObj)
{
try
{
_logger.Info("开始设置功率模式: Mode={Mode} | Starting to set power mode: Mode={Mode}", mode);
var result = _currentSource.SetPowerMode(mode);
if (result.Success)
{
_logger.Info("功率模式设置成功: Mode={Mode} | Power mode set successfully: Mode={Mode}", mode);
}
else
{
_logger.Error(null, "功率模式设置失败: {ErrorMessage} | Power mode setting failed: {ErrorMessage}", result.ErrorMessage);
}
return result;
}
catch (Exception ex)
{
_logger.Error(ex, "功率模式设置异常: {Message} | Power mode setting exception: {Message}", ex.Message);
return XRayResult.Error($"功率模式设置异常:{ex.Message}");
}
}
}
/// <summary>
/// 异步执行初始化 + 连接变量的完整流程 | Async full sequence: Initialize + ConnectVariables
/// </summary>
public async Task<XRayResult> InitializeAndConnectAsync()
{
return await Task.Run(() =>
{
try
{
// 步骤1:初始化 | Step 1: Initialize
if (!IsInitialized)
{
_logger.Info("自动初始化:执行 Initialize | Auto-init: executing Initialize");
var initResult = Initialize();
if (!initResult.Success)
{
_logger.Warn("自动初始化失败: {Error} | Auto-initialization failed: {Error}", initResult.ErrorMessage);
return initResult;
}
_logger.Info("自动初始化成功 | Auto-initialization succeeded");
}
// 步骤2:连接变量 | Step 2: Connect Variables
if (!IsConnected)
{
_logger.Info("自动连接变量:执行 ConnectVariables | Auto-init: executing ConnectVariables");
var connectResult = ConnectVariables();
if (!connectResult.Success)
{
_logger.Warn("自动连接变量失败: {Error} | Auto connect variables failed: {Error}", connectResult.ErrorMessage);
return connectResult;
}
_logger.Info("自动连接变量成功 | Auto connect variables succeeded");
}
_logger.Info("自动初始化流程完成 | Auto-initialization sequence completed");
return XRayResult.Ok();
}
catch (Exception ex)
{
_logger.Error(ex, "自动初始化流程异常: {Message} | Auto-initialization sequence exception: {Message}", ex.Message);
return XRayResult.Error($"自动初始化异常: {ex.Message}");
}
});
}
/// <summary>
/// 射线源状态变更事件处理(设备层回调)| Ray source status changed event handler (device callback)
/// </summary>
private void OnRaySourceStatusChangedFromDevice(RaySourceStatus newStatus)
{
// 更新当前状态(IsXRayOn 由 CurrentStatus 自动派生)| Update current status (IsXRayOn is auto-derived from CurrentStatus)
CurrentStatus = newStatus;
_logger.Info("服务层状态更新: {Status} | Service layer status updated: {Status}", newStatus);
// 根据射线源状态变更记录灯丝使用(带去重,防止设备推送抖动)| Record filament usage with dedup
if (_filamentLifetimeService.IsInitialized && newStatus != _lastFilamentRecordedStatus)
{
if (newStatus == RaySourceStatus.Opened && !_filamentLifetimeService.IsFilamentOn)
{
if (_filamentLifetimeService.StartFilamentUsage())
_lastFilamentRecordedStatus = newStatus;
}
else if (newStatus != RaySourceStatus.Opened && _filamentLifetimeService.IsFilamentOn)
{
if (_filamentLifetimeService.StopFilamentUsage())
_lastFilamentRecordedStatus = newStatus;
}
}
if (newStatus == RaySourceStatus.Unavailable && _isInitializedFlag)
{
// 异常断联处理 | Handle unexpected disconnection
_logger.Error(null, "服务层检测到连接丢失(状态变为 Unavailable| Service layer detected connection lost (status changed to Unavailable)");
_isInitializedFlag = false;
// 通知 UI 更新状态 | Notify UI to update status
_eventAggregator.GetEvent<StatusUpdatedEvent>().Publish(new SystemStatusData
{
IsXRayOn = false,
ActualVoltage = 0,
ActualCurrent = 0
});
}
}
/// <summary>
/// 释放资源 | Dispose resources
/// </summary>
public void Dispose()
{
if (_isDisposed)
return;
try
{
// 先执行紧急关闭 | Execute emergency shutdown first
EmergencyShutdown();
// 释放射线源实例 | Dispose X-ray source instance
_currentSource?.Dispose();
_currentSource = null;
_isDisposed = true;
_logger.Info("服务层资源已释放 | Service layer resources disposed");
}
catch (Exception ex)
{
_logger.Warn("服务层资源释放异常: {Message} | Service layer resource disposal exception: {Message}", ex.Message);
}
}
}
}