using System;
using System.Threading;
using System.Threading.Tasks;
using Prism.Events;
using XP.Hardware.Detector.Abstractions;
using XP.Hardware.Detector.Abstractions.Enums;
using XP.Hardware.Detector.Config;
using XP.Hardware.Detector.Factories;
using XP.Common.Logging.Interfaces;
namespace XP.Hardware.Detector.Services
{
///
/// 探测器服务实现 | Detector service implementation
/// 单例模式,封装业务逻辑,屏蔽厂商差异
///
public class DetectorService : IDetectorService, IDisposable
{
private readonly IDetectorFactory _factory;
private readonly IEventAggregator _eventAggregator;
private readonly ILoggerService _logger;
private readonly object _lock = new object();
private IAreaDetector _detector;
private DetectorConfig _config;
private DetectorResult _lastError;
private bool _disposed = false;
///
/// 当前探测器状态 | Current detector status
///
public DetectorStatus Status
{
get
{
lock (_lock)
{
return _detector?.Status ?? DetectorStatus.Uninitialized;
}
}
}
///
/// 当前探测器类型 | Current detector type
///
public DetectorType? Type
{
get
{
lock (_lock)
{
return _detector?.Type;
}
}
}
///
/// 探测器是否已连接 | Whether detector is connected
///
public bool IsConnected
{
get
{
lock (_lock)
{
return _detector != null && _detector.Status != DetectorStatus.Uninitialized;
}
}
}
///
/// 构造函数 | Constructor
///
/// 探测器工厂 | Detector factory
/// 事件聚合器 | Event aggregator
/// 日志服务 | Logger service
public DetectorService(IDetectorFactory factory, IEventAggregator eventAggregator, ILoggerService logger = null)
{
_factory = factory ?? throw new ArgumentNullException(nameof(factory));
_eventAggregator = eventAggregator ?? throw new ArgumentNullException(nameof(eventAggregator));
_logger = logger?.ForModule("DetectorService");
_logger?.Info("DetectorService 实例已创建 | DetectorService instance created");
}
///
/// 初始化探测器 | Initialize detector
///
/// 取消令牌 | Cancellation token
/// 操作结果 | Operation result
public async Task InitializeAsync(CancellationToken cancellationToken = default)
{
// 若已连接,先断开再重连 | If already connected, disconnect first then reconnect
bool alreadyConnected;
lock (_lock) { alreadyConnected = _detector != null; }
if (alreadyConnected)
{
_logger?.Info("探测器已连接,先断开再重新初始化 | Detector already connected, disconnecting before reinitializing");
await DisconnectAsync();
}
try
{
_logger?.Info("开始初始化探测器服务 | Starting to initialize detector service");
// 加载配置 | Load configuration
_logger?.Debug("加载配置文件 | Loading configuration file");
var configResult = ConfigLoader.LoadConfiguration();
if (!configResult.IsSuccess)
{
_lastError = configResult;
_logger?.Error(null, $"加载配置失败 | Failed to load configuration: {configResult.ErrorMessage}");
return configResult;
}
_logger?.Info($"配置加载成功,探测器类型:{configResult.Data.Type} | Configuration loaded successfully, detector type: {configResult.Data.Type}");
// 保存配置引用 | Save config reference
_config = configResult.Data;
// 创建探测器实例 | Create detector instance
_logger?.Debug("创建探测器实例 | Creating detector instance");
var createResult = _factory.CreateDetector(configResult.Data);
if (!createResult.IsSuccess)
{
_lastError = createResult;
_logger?.Error(createResult.Exception, $"创建探测器实例失败 | Failed to create detector instance: {createResult.ErrorMessage}");
return DetectorResult.Failure(createResult.ErrorMessage, createResult.Exception, createResult.ErrorCode);
}
lock (_lock)
{
_detector = createResult.Data;
}
// 初始化探测器 | Initialize detector
_logger?.Debug("初始化探测器硬件 | Initializing detector hardware");
var initResult = await _detector.InitializeAsync(cancellationToken);
if (!initResult.IsSuccess)
{
_lastError = initResult;
_logger?.Error(initResult.Exception, $"初始化探测器硬件失败 | Failed to initialize detector hardware: {initResult.ErrorMessage}");
}
else
{
_logger?.Info("探测器服务初始化成功 | Detector service initialized successfully");
}
return initResult;
}
catch (Exception ex)
{
var errorMsg = $"初始化服务失败 | Failed to initialize service: {ex.Message}";
_logger?.Error(ex, errorMsg);
var errorResult = DetectorResult.Failure(errorMsg, ex, -1);
_lastError = errorResult;
return errorResult;
}
}
///
/// 断开探测器连接 | Disconnect detector
///
public async Task DisconnectAsync()
{
try
{
IAreaDetector detector;
lock (_lock)
{
detector = _detector;
if (detector == null)
{
_logger?.Warn("探测器未连接,无需断开 | Detector not connected, no need to disconnect");
return DetectorResult.Success("探测器未连接 | Detector not connected");
}
}
_logger?.Info("开始断开探测器连接 | Starting to disconnect detector");
// 如果正在采集,先停止 | If acquiring, stop first
if (detector.Status == DetectorStatus.Acquiring)
{
_logger?.Info("探测器正在采集,先停止采集 | Detector is acquiring, stopping first");
await detector.StopAcquisitionAsync();
}
// 释放探测器资源 | Dispose detector resources
lock (_lock)
{
_detector?.Dispose();
_detector = null;
}
_config = null;
_logger?.Info("探测器已断开连接 | Detector disconnected");
return DetectorResult.Success("探测器已断开连接 | Detector disconnected");
}
catch (Exception ex)
{
var errorMsg = $"断开探测器连接异常 | Disconnect detector exception: {ex.Message}";
_logger?.Error(ex, errorMsg);
// 强制清理 | Force cleanup
lock (_lock)
{
_detector?.Dispose();
_detector = null;
}
_config = null;
var errorResult = DetectorResult.Failure(errorMsg, ex, -1);
_lastError = errorResult;
return errorResult;
}
}
///
/// 启动连续采集 | Start continuous acquisition
///
/// 取消令牌 | Cancellation token
/// 操作结果 | Operation result
public async Task StartAcquisitionAsync(CancellationToken cancellationToken = default)
{
try
{
_logger?.Info("服务层:启动连续采集 | Service layer: Starting continuous acquisition");
var detector = GetDetectorOrThrow();
var result = await detector.StartAcquisitionAsync(cancellationToken);
if (!result.IsSuccess)
{
_lastError = result;
_logger?.Error(result.Exception, $"启动采集失败 | Failed to start acquisition: {result.ErrorMessage}");
}
return result;
}
catch (Exception ex)
{
var errorMsg = $"服务层启动采集异常 | Service layer start acquisition exception: {ex.Message}";
_logger?.Error(ex, errorMsg);
var errorResult = DetectorResult.Failure(errorMsg, ex, -1);
_lastError = errorResult;
return errorResult;
}
}
///
/// 停止采集 | Stop acquisition
///
/// 取消令牌 | Cancellation token
/// 操作结果 | Operation result
public async Task StopAcquisitionAsync(CancellationToken cancellationToken = default)
{
try
{
_logger?.Info("服务层:停止采集 | Service layer: Stopping acquisition");
var detector = GetDetectorOrThrow();
var result = await detector.StopAcquisitionAsync(cancellationToken);
if (!result.IsSuccess)
{
_lastError = result;
_logger?.Error(result.Exception, $"停止采集失败 | Failed to stop acquisition: {result.ErrorMessage}");
}
return result;
}
catch (Exception ex)
{
var errorMsg = $"服务层停止采集异常 | Service layer stop acquisition exception: {ex.Message}";
_logger?.Error(ex, errorMsg);
var errorResult = DetectorResult.Failure(errorMsg, ex, -1);
_lastError = errorResult;
return errorResult;
}
}
///
/// 单帧采集 | Single frame acquisition
///
/// 取消令牌 | Cancellation token
/// 操作结果 | Operation result
public async Task AcquireSingleFrameAsync(CancellationToken cancellationToken = default)
{
try
{
_logger?.Debug("服务层:单帧采集 | Service layer: Single frame acquisition");
var detector = GetDetectorOrThrow();
var result = await detector.AcquireSingleFrameAsync(cancellationToken);
if (!result.IsSuccess)
{
_lastError = result;
_logger?.Error(result.Exception, $"单帧采集失败 | Failed to acquire single frame: {result.ErrorMessage}");
}
return result;
}
catch (Exception ex)
{
var errorMsg = $"服务层单帧采集异常 | Service layer single frame acquisition exception: {ex.Message}";
_logger?.Error(ex, errorMsg);
var errorResult = DetectorResult.Failure(errorMsg, ex, -1);
_lastError = errorResult;
return errorResult;
}
}
///
/// 暗场校正 | Dark field correction
///
/// 采集帧数 | Frame count
/// 取消令牌 | Cancellation token
/// 操作结果 | Operation result
public async Task DarkCorrectionAsync(int frameCount = 10, CancellationToken cancellationToken = default)
{
try
{
_logger?.Info("服务层:执行暗场校正,帧数:{FrameCount} | Service layer: Executing dark correction, frame count: {FrameCount}", frameCount);
var detector = GetDetectorOrThrow();
var result = await detector.DarkCorrectionAsync(frameCount, cancellationToken);
if (!result.IsSuccess)
{
_lastError = result;
_logger?.Error(result.Exception, "暗场校正失败:{Message} | Dark correction failed: {Message}", result.ErrorMessage);
}
return result;
}
catch (Exception ex)
{
var errorMsg = $"服务层暗场校正异常 | Service layer dark correction exception: {ex.Message}";
_logger?.Error(ex, errorMsg);
var errorResult = DetectorResult.Failure(errorMsg, ex, -1);
_lastError = errorResult;
return errorResult;
}
}
///
/// 增益校正(亮场校正)| Gain correction (bright field correction)
///
/// 采集帧数 | Frame count
/// 取消令牌 | Cancellation token
/// 操作结果 | Operation result
public async Task GainCorrectionAsync(int frameCount = 10, CancellationToken cancellationToken = default)
{
try
{
_logger?.Info("服务层:执行亮场校正,帧数:{FrameCount} | Service layer: Executing gain correction, frame count: {FrameCount}", frameCount);
var detector = GetDetectorOrThrow();
var result = await detector.GainCorrectionAsync(frameCount, cancellationToken);
if (!result.IsSuccess)
{
_lastError = result;
_logger?.Error(result.Exception, "亮场校正失败:{Message} | Gain correction failed: {Message}", result.ErrorMessage);
}
return result;
}
catch (Exception ex)
{
var errorMsg = $"服务层亮场校正异常 | Service layer gain correction exception: {ex.Message}";
_logger?.Error(ex, errorMsg);
var errorResult = DetectorResult.Failure(errorMsg, ex, -1);
_lastError = errorResult;
return errorResult;
}
}
///
/// 坏像素校正 | Bad pixel correction
///
/// 取消令牌 | Cancellation token
/// 操作结果 | Operation result
public async Task BadPixelCorrectionAsync(CancellationToken cancellationToken = default)
{
try
{
_logger?.Info("服务层:执行坏像素校正 | Service layer: Executing bad pixel correction");
var detector = GetDetectorOrThrow();
var result = await detector.BadPixelCorrectionAsync(cancellationToken);
if (!result.IsSuccess)
{
_lastError = result;
_logger?.Error(result.Exception, "坏像素校正失败:{Message} | Bad pixel correction failed: {Message}", result.ErrorMessage);
}
return result;
}
catch (Exception ex)
{
var errorMsg = $"服务层坏像素校正异常 | Service layer bad pixel correction exception: {ex.Message}";
_logger?.Error(ex, errorMsg);
var errorResult = DetectorResult.Failure(errorMsg, ex, -1);
_lastError = errorResult;
return errorResult;
}
}
///
/// 执行自动校正(暗场+增益+坏像素)| Execute auto correction (dark + gain + bad pixel)
///
/// 采集帧数 | Frame count
/// 取消令牌 | Cancellation token
/// 操作结果 | Operation result
public async Task AutoCorrectionAsync(int frameCount = 10, CancellationToken cancellationToken = default)
{
try
{
_logger?.Info("服务层:执行自动校正,帧数:{FrameCount} | Service layer: Executing auto correction, frame count: {FrameCount}", frameCount);
var detector = GetDetectorOrThrow();
var result = await detector.AutoCorrectionAsync(frameCount, cancellationToken);
if (!result.IsSuccess)
{
_lastError = result;
_logger?.Error(result.Exception, "自动校正失败:{Message} | Auto correction failed: {Message}", result.ErrorMessage);
}
return result;
}
catch (Exception ex)
{
var errorMsg = $"服务层自动校正异常 | Service layer auto correction exception: {ex.Message}";
_logger?.Error(ex, errorMsg);
var errorResult = DetectorResult.Failure(errorMsg, ex, -1);
_lastError = errorResult;
return errorResult;
}
}
///
/// 应用探测器参数(Binning/PGA/帧率统一下发)| Apply detector parameters (Binning/PGA/FrameRate)
///
public async Task ApplyParametersAsync(int binningIndex, int pga, decimal frameRate, CancellationToken cancellationToken = default)
{
try
{
_logger?.Info("服务层:应用参数,Binning={Binning},PGA={PGA},帧率={FrameRate} | Service layer: Applying parameters",
binningIndex, pga, frameRate);
var detector = GetDetectorOrThrow();
// 通过 IVarexDetector 接口下发参数 | Apply parameters via IVarexDetector interface
if (detector is IVarexDetector varexDetector)
{
// 设置 Binning | Set binning
var binningResult = await varexDetector.SetBinningModeAsync((BinningMode)binningIndex);
if (!binningResult.IsSuccess)
{
_lastError = binningResult;
return binningResult;
}
// 设置增益(PGA)| Set gain (PGA)
var gainResult = await varexDetector.SetGainModeAsync((GainMode)pga);
if (!gainResult.IsSuccess)
{
_lastError = gainResult;
return gainResult;
}
// 设置曝光时间(帧率→微秒:1000*1000/帧率)| Set exposure time (frame rate → microseconds)
uint exposureUs = frameRate > 0 ? (uint)(1_000_000m / frameRate) : 66667;
var exposureResult = await varexDetector.SetExposureTimeAsync(exposureUs);
if (!exposureResult.IsSuccess)
{
_lastError = exposureResult;
return exposureResult;
}
_logger?.Info("参数应用成功 | Parameters applied successfully");
return DetectorResult.Success("参数应用成功 | Parameters applied successfully");
}
return DetectorResult.Failure("当前探测器不支持参数下发 | Current detector does not support parameter application");
}
catch (Exception ex)
{
var errorMsg = $"服务层应用参数异常 | Service layer apply parameters exception: {ex.Message}";
_logger?.Error(ex, errorMsg);
var errorResult = DetectorResult.Failure(errorMsg, ex, -1);
_lastError = errorResult;
return errorResult;
}
}
///
/// 保存当前配置到文件 | Save current configuration to file
///
public void SaveParameters(int binningIndex, int pga, decimal frameRate, int avgFrames)
{
try
{
_logger?.Info("保存探测器参数,Binning={Binning},PGA={PGA},帧率={FrameRate},帧合并={AvgFrames} | Saving detector parameters",
binningIndex, pga, frameRate, avgFrames);
ConfigLoader.SaveParameters(binningIndex, pga, frameRate, avgFrames);
_logger?.Info("探测器参数保存成功 | Detector parameters saved successfully");
}
catch (Exception ex)
{
_logger?.Error(ex, "保存探测器参数失败:{Message} | Failed to save detector parameters: {Message}", ex.Message);
}
}
///
/// 获取探测器信息 | Get detector information
///
/// 探测器信息 | Detector information
public DetectorInfo GetInfo()
{
var detector = GetDetectorOrThrow();
return detector.GetInfo();
}
///
/// 获取最后的错误信息 | Get last error information
///
/// 错误结果 | Error result
public DetectorResult GetLastError()
{
return _lastError ?? DetectorResult.Success();
}
///
/// 获取当前探测器配置 | Get current detector configuration
/// 未初始化时尝试从配置文件加载(仅读取配置,不创建探测器实例)
///
public DetectorConfig GetCurrentConfig()
{
if (_config != null) return _config;
// 未初始化时,尝试从配置文件加载以提供 UI 选项 | If not initialized, try loading from config for UI options
try
{
var configResult = ConfigLoader.LoadConfiguration();
if (configResult.IsSuccess)
{
_config = configResult.Data;
return _config;
}
}
catch
{
// 忽略加载异常,返回 null | Ignore load exception, return null
}
return null;
}
///
/// 获取探测器实例或抛出异常 | Get detector instance or throw exception
///
/// 探测器实例 | Detector instance
/// 探测器未初始化 | Detector not initialized
private IAreaDetector GetDetectorOrThrow()
{
lock (_lock)
{
if (_detector == null)
{
throw new InvalidOperationException("探测器未初始化,请先调用 InitializeAsync | Detector not initialized, please call InitializeAsync first");
}
return _detector;
}
}
///
/// 释放资源 | Dispose resources
///
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
///
/// 释放资源 | Dispose resources
///
/// 是否释放托管资源 | Whether to dispose managed resources
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
// 释放托管资源 | Release managed resources
lock (_lock)
{
_detector?.Dispose();
_detector = null;
}
}
_disposed = true;
}
}
}
}