127 lines
7.6 KiB
C#
127 lines
7.6 KiB
C#
|
|
using Microsoft.Extensions.Options;
|
||
|
|
using SSPCTester.Devices.Config;
|
||
|
|
using SSPCTester.Devices.Drivers.Mock;
|
||
|
|
using SSPCTester.Devices.Drivers.Real;
|
||
|
|
using SSPCTester.Devices.Interfaces;
|
||
|
|
|
||
|
|
namespace SSPCTester.Devices.Drivers;
|
||
|
|
|
||
|
|
/// <summary>根据可变设置在 Mock 与真实 SSPC 间切换。</summary>
|
||
|
|
public sealed class ConfigurableSspc : ISspc
|
||
|
|
{
|
||
|
|
private readonly DeviceOptions _options;
|
||
|
|
private readonly MockSspc _mock;
|
||
|
|
private readonly SspcModbus _real;
|
||
|
|
|
||
|
|
public ConfigurableSspc(IOptions<DeviceOptions> options, MockSspc mock, SspcModbus real)
|
||
|
|
{
|
||
|
|
_options = options.Value;
|
||
|
|
_mock = mock;
|
||
|
|
_real = real;
|
||
|
|
_mock.ConnectionChanged += Forward;
|
||
|
|
_real.ConnectionChanged += Forward;
|
||
|
|
}
|
||
|
|
|
||
|
|
private ISspc Current => _options.Sspc.UseMock ? _mock : _real;
|
||
|
|
public int ChannelCount => 24;
|
||
|
|
public bool IsConnected => Current.IsConnected;
|
||
|
|
public string DisplayName => Current.DisplayName;
|
||
|
|
public event EventHandler<bool>? ConnectionChanged;
|
||
|
|
public Task<bool> ConnectAsync(CancellationToken ct = default) => Current.ConnectAsync(ct);
|
||
|
|
public async Task DisconnectAsync()
|
||
|
|
{
|
||
|
|
await _mock.DisconnectAsync().ConfigureAwait(false);
|
||
|
|
await _real.DisconnectAsync().ConfigureAwait(false);
|
||
|
|
}
|
||
|
|
public Task TurnOnAsync(int physicalSlot, CancellationToken ct = default) => Current.TurnOnAsync(physicalSlot, ct);
|
||
|
|
public Task TurnOffAsync(int physicalSlot, CancellationToken ct = default) => Current.TurnOffAsync(physicalSlot, ct);
|
||
|
|
public Task FlashAsync(int physicalSlot, int milliseconds, CancellationToken ct = default) => Current.FlashAsync(physicalSlot, milliseconds, ct);
|
||
|
|
public Task<bool> GetChannelStateAsync(int physicalSlot, CancellationToken ct = default) => Current.GetChannelStateAsync(physicalSlot, ct);
|
||
|
|
public Task<ChannelMeasurement> ReadMeasurementAsync(int physicalSlot, CancellationToken ct = default) => Current.ReadMeasurementAsync(physicalSlot, ct);
|
||
|
|
public Task<IReadOnlyList<ChannelMeasurement>> ReadMeasurementsAsync(CancellationToken ct = default) => Current.ReadMeasurementsAsync(ct);
|
||
|
|
private void Forward(object? sender, bool connected) => ConnectionChanged?.Invoke(this, connected);
|
||
|
|
}
|
||
|
|
|
||
|
|
public sealed class ConfigurablePowerSupply : IPowerSupply
|
||
|
|
{
|
||
|
|
private readonly DeviceOptions _options;
|
||
|
|
private readonly MockPowerSupply _mock;
|
||
|
|
private readonly Udp5080 _real;
|
||
|
|
public ConfigurablePowerSupply(IOptions<DeviceOptions> options, MockPowerSupply mock, Udp5080 real)
|
||
|
|
{
|
||
|
|
_options = options.Value; _mock = mock; _real = real;
|
||
|
|
_mock.ConnectionChanged += Forward; _real.ConnectionChanged += Forward;
|
||
|
|
}
|
||
|
|
private IPowerSupply Current => _options.PowerSupply.UseMock ? _mock : _real;
|
||
|
|
public bool IsConnected => Current.IsConnected;
|
||
|
|
public string DisplayName => Current.DisplayName;
|
||
|
|
public event EventHandler<bool>? ConnectionChanged;
|
||
|
|
public Task<bool> ConnectAsync(CancellationToken ct = default) => Current.ConnectAsync(ct);
|
||
|
|
public async Task DisconnectAsync() { await _mock.DisconnectAsync(); await SafeDisconnect(_real); }
|
||
|
|
public Task SetVoltageAsync(double volts, CancellationToken ct = default) => Current.SetVoltageAsync(volts, ct);
|
||
|
|
public Task SetCurrentLimitAsync(double amps, CancellationToken ct = default) => Current.SetCurrentLimitAsync(amps, ct);
|
||
|
|
public Task OutputAsync(bool on, CancellationToken ct = default) => Current.OutputAsync(on, ct);
|
||
|
|
public Task<(double volts, double amps)> ReadAsync(CancellationToken ct = default) => Current.ReadAsync(ct);
|
||
|
|
public Task<string> QueryIdentityAsync(CancellationToken ct = default) => Current.QueryIdentityAsync(ct);
|
||
|
|
private void Forward(object? sender, bool connected) => ConnectionChanged?.Invoke(this, connected);
|
||
|
|
private static async Task SafeDisconnect(IDeviceConnection device) { try { await device.DisconnectAsync(); } catch (NotImplementedException) { } }
|
||
|
|
}
|
||
|
|
|
||
|
|
public sealed class ConfigurableLoad : ILoad
|
||
|
|
{
|
||
|
|
private readonly DeviceOptions _options;
|
||
|
|
private readonly MockLoad _mock;
|
||
|
|
private readonly It87xxLoad _real;
|
||
|
|
public ConfigurableLoad(IOptions<DeviceOptions> options, MockLoad mock, It87xxLoad real)
|
||
|
|
{
|
||
|
|
_options = options.Value; _mock = mock; _real = real;
|
||
|
|
_mock.ConnectionChanged += Forward; _real.ConnectionChanged += Forward;
|
||
|
|
}
|
||
|
|
private ILoad Current => _options.Load.UseMock ? _mock : _real;
|
||
|
|
public bool IsConnected => Current.IsConnected;
|
||
|
|
public string DisplayName => Current.DisplayName;
|
||
|
|
public event EventHandler<bool>? ConnectionChanged;
|
||
|
|
public Task<bool> ConnectAsync(CancellationToken ct = default) => Current.ConnectAsync(ct);
|
||
|
|
public async Task DisconnectAsync() { await _mock.DisconnectAsync(); await SafeDisconnect(_real); }
|
||
|
|
public Task SetModeAsync(LoadMode mode, CancellationToken ct = default) => Current.SetModeAsync(mode, ct);
|
||
|
|
public Task SetValueAsync(double value, CancellationToken ct = default) => Current.SetValueAsync(value, ct);
|
||
|
|
public Task InputAsync(bool on, CancellationToken ct = default) => Current.InputAsync(on, ct);
|
||
|
|
public Task<(double volts, double amps)> ReadAsync(CancellationToken ct = default) => Current.ReadAsync(ct);
|
||
|
|
public Task<PowerReading> ReadPowerAsync(CancellationToken ct = default) => Current.ReadPowerAsync(ct);
|
||
|
|
public Task<string> QueryIdentityAsync(CancellationToken ct = default) => Current.QueryIdentityAsync(ct);
|
||
|
|
private void Forward(object? sender, bool connected) => ConnectionChanged?.Invoke(this, connected);
|
||
|
|
private static async Task SafeDisconnect(IDeviceConnection device) { try { await device.DisconnectAsync(); } catch (NotImplementedException) { } }
|
||
|
|
}
|
||
|
|
|
||
|
|
public sealed class ConfigurableDaq : IDaq
|
||
|
|
{
|
||
|
|
private readonly DeviceOptions _options;
|
||
|
|
private readonly MockDaq _mock;
|
||
|
|
private readonly Pcie8586Daq _real;
|
||
|
|
public ConfigurableDaq(IOptions<DeviceOptions> options, MockDaq mock, Pcie8586Daq real)
|
||
|
|
{
|
||
|
|
_options = options.Value; _mock = mock; _real = real;
|
||
|
|
_mock.ConnectionChanged += Forward; _real.ConnectionChanged += Forward;
|
||
|
|
_mock.SampleReceived += ForwardSample; _real.SampleReceived += ForwardSample;
|
||
|
|
}
|
||
|
|
private IDaq Current => _options.Daq.UseMock ? _mock : _real;
|
||
|
|
public bool IsConnected => Current.IsConnected;
|
||
|
|
public string DisplayName => Current.DisplayName;
|
||
|
|
public event EventHandler<bool>? ConnectionChanged;
|
||
|
|
public event EventHandler<CurveSample>? SampleReceived;
|
||
|
|
public Task<IReadOnlyList<DaqDeviceDescriptor>> EnumerateDevicesAsync(CancellationToken ct = default) =>
|
||
|
|
Current.EnumerateDevicesAsync(ct);
|
||
|
|
public Task<bool> ConnectAsync(CancellationToken ct = default) => Current.ConnectAsync(ct);
|
||
|
|
public async Task DisconnectAsync() { await _mock.DisconnectAsync(); await SafeDisconnect(_real); }
|
||
|
|
public Task<CurveData> CaptureAsync(int[] channels, int sampleRateHz, double durationSec, CancellationToken ct = default) =>
|
||
|
|
Current.CaptureAsync(channels, sampleRateHz, durationSec, ct);
|
||
|
|
public Task<double[]> ReadInstantAsync(int[] channels, CancellationToken ct = default) => Current.ReadInstantAsync(channels, ct);
|
||
|
|
public Task<CurveData> CaptureAroundActionAsync(
|
||
|
|
DaqActionCaptureRequest request,
|
||
|
|
Func<CancellationToken, Task> action,
|
||
|
|
CancellationToken ct = default) => Current.CaptureAroundActionAsync(request, action, ct);
|
||
|
|
private void Forward(object? sender, bool connected) => ConnectionChanged?.Invoke(this, connected);
|
||
|
|
private void ForwardSample(object? sender, CurveSample sample) => SampleReceived?.Invoke(this, sample);
|
||
|
|
private static async Task SafeDisconnect(IDeviceConnection device) { try { await device.DisconnectAsync(); } catch (NotImplementedException) { } }
|
||
|
|
}
|