|
|
@ -14,40 +14,131 @@ public sealed class EquipmentMeasurementService |
|
|
_settings = settings; |
|
|
_settings = settings; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public async Task<string> RunPreBoardCommandAsync() |
|
|
|
|
|
{ |
|
|
|
|
|
var log = new StringBuilder(); |
|
|
|
|
|
if (IsDisabled(_settings.Current) || string.IsNullOrWhiteSpace(_settings.PreBoardCommand)) |
|
|
|
|
|
{ |
|
|
|
|
|
return string.Empty; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
using var client = await CreateClientAsync("CURRENT", _settings.Current); |
|
|
|
|
|
log.AppendLine($"> CURRENT PRE-BOARD CONNECT: {DescribeClient(client, _settings.Current)}"); |
|
|
|
|
|
log.AppendLine($"> CURRENT PRE-BOARD SETUP: {_settings.PreBoardCommand}"); |
|
|
|
|
|
await SendCommandListAsync(client, _settings.PreBoardCommand); |
|
|
|
|
|
return log.ToString(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public async Task<string> RunLogoutCommandAsync() |
|
|
|
|
|
{ |
|
|
|
|
|
var log = new StringBuilder(); |
|
|
|
|
|
if (IsDisabled(_settings.Current) || string.IsNullOrWhiteSpace(_settings.LogoutCommand)) |
|
|
|
|
|
{ |
|
|
|
|
|
return string.Empty; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
using var client = await CreateClientAsync("CURRENT", _settings.Current); |
|
|
|
|
|
log.AppendLine($"> CURRENT LOGOUT CONNECT: {DescribeClient(client, _settings.Current)}"); |
|
|
|
|
|
log.AppendLine($"> CURRENT LOGOUT: {_settings.LogoutCommand}"); |
|
|
|
|
|
await SendCommandListAsync(client, _settings.LogoutCommand); |
|
|
|
|
|
return log.ToString(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
public async Task<BoardMeasurementResult> ReadAsync() |
|
|
public async Task<BoardMeasurementResult> ReadAsync() |
|
|
{ |
|
|
{ |
|
|
var log = new StringBuilder(); |
|
|
var log = new StringBuilder(); |
|
|
|
|
|
IScpiClient? currentClient = null; |
|
|
|
|
|
|
|
|
if (_settings.SettleMilliseconds > 0) |
|
|
try |
|
|
|
|
|
{ |
|
|
|
|
|
if (!IsDisabled(_settings.Current) && !string.IsNullOrWhiteSpace(_settings.Current.SetupCommand)) |
|
|
|
|
|
{ |
|
|
|
|
|
currentClient = await CreateClientAsync("CURRENT", _settings.Current); |
|
|
|
|
|
log.AppendLine($"> CURRENT PRE-READ CONNECT: {DescribeClient(currentClient, _settings.Current)}"); |
|
|
|
|
|
log.AppendLine($"> CURRENT PRE-READ SETUP: {_settings.Current.SetupCommand}"); |
|
|
|
|
|
await SendCommandListAsync(currentClient, _settings.Current.SetupCommand); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (_settings.SettleMilliseconds > 0) |
|
|
|
|
|
{ |
|
|
|
|
|
await Task.Delay(_settings.SettleMilliseconds); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var voltage = await ReadChannelAsync("VOLTAGE", _settings.Voltage, log); |
|
|
|
|
|
var current = currentClient is null |
|
|
|
|
|
? await ReadChannelAsync("CURRENT", _settings.Current, log) |
|
|
|
|
|
: await ReadChannelWithClientAsync("CURRENT", _settings.Current, currentClient, log, skipSetupCommand: true); |
|
|
|
|
|
|
|
|
|
|
|
return new BoardMeasurementResult |
|
|
|
|
|
{ |
|
|
|
|
|
Voltage = voltage, |
|
|
|
|
|
Current = current, |
|
|
|
|
|
RawLog = log.ToString() |
|
|
|
|
|
}; |
|
|
|
|
|
} |
|
|
|
|
|
finally |
|
|
{ |
|
|
{ |
|
|
await Task.Delay(_settings.SettleMilliseconds); |
|
|
await SendCleanupCommandAsync(currentClient, _settings.Current, log); |
|
|
|
|
|
currentClient?.Dispose(); |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
var voltage = await ReadChannelAsync("VOLTAGE", _settings.Voltage, log); |
|
|
private static async Task SendCleanupCommandAsync(IScpiClient? client, ScpiChannelSettings channel, StringBuilder log) |
|
|
var current = await ReadChannelAsync("CURRENT", _settings.Current, log); |
|
|
{ |
|
|
|
|
|
if (client is null || string.IsNullOrWhiteSpace(channel.CleanupCommand)) |
|
|
|
|
|
{ |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
return new BoardMeasurementResult |
|
|
try |
|
|
{ |
|
|
{ |
|
|
Voltage = voltage, |
|
|
log.AppendLine($"> CURRENT CLEANUP: {channel.CleanupCommand}"); |
|
|
Current = current, |
|
|
await SendCommandListAsync(client, channel.CleanupCommand); |
|
|
RawLog = log.ToString() |
|
|
} |
|
|
}; |
|
|
catch (Exception ex) |
|
|
|
|
|
{ |
|
|
|
|
|
log.AppendLine($"> CURRENT CLEANUP FAILED: {ex.Message}"); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private async Task<decimal> ReadChannelAsync(string label, ScpiChannelSettings channel, StringBuilder log) |
|
|
private async Task<decimal> ReadChannelAsync( |
|
|
|
|
|
string label, |
|
|
|
|
|
ScpiChannelSettings channel, |
|
|
|
|
|
StringBuilder log, |
|
|
|
|
|
bool skipSetupCommand = false) |
|
|
{ |
|
|
{ |
|
|
|
|
|
if (IsDisabled(channel)) |
|
|
|
|
|
{ |
|
|
|
|
|
log.AppendLine($"> {label} SKIP: disabled in Hardware.ini"); |
|
|
|
|
|
return 0m; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(channel.ReadCommand)) |
|
|
if (string.IsNullOrWhiteSpace(channel.ReadCommand)) |
|
|
{ |
|
|
{ |
|
|
throw new InvalidOperationException($"Hardware.ini [Equipment] {label} ReadCommand 값을 확인하세요."); |
|
|
throw new InvalidOperationException($"Hardware.ini [Equipment] {label} ReadCommand 값을 확인하세요."); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
using var client = await CreateClientAsync(label, channel); |
|
|
using var client = await CreateClientAsync(label, channel); |
|
|
log.AppendLine($"> {label} CONNECT: {DescribeClient(client, channel)}"); |
|
|
return await ReadChannelWithClientAsync(label, channel, client, log, skipSetupCommand); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static async Task<decimal> ReadChannelWithClientAsync( |
|
|
|
|
|
string label, |
|
|
|
|
|
ScpiChannelSettings channel, |
|
|
|
|
|
IScpiClient client, |
|
|
|
|
|
StringBuilder log, |
|
|
|
|
|
bool skipSetupCommand = false) |
|
|
|
|
|
{ |
|
|
|
|
|
if (string.IsNullOrWhiteSpace(channel.ReadCommand)) |
|
|
|
|
|
{ |
|
|
|
|
|
throw new InvalidOperationException($"Hardware.ini [Equipment] {label} ReadCommand 값을 확인하세요."); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(channel.SetupCommand)) |
|
|
log.AppendLine($"> {label} CONNECT: {DescribeClient(client, channel)}"); |
|
|
|
|
|
if (!skipSetupCommand && !string.IsNullOrWhiteSpace(channel.SetupCommand)) |
|
|
{ |
|
|
{ |
|
|
log.AppendLine($"> {label} SETUP: {channel.SetupCommand}"); |
|
|
log.AppendLine($"> {label} SETUP: {channel.SetupCommand}"); |
|
|
await client.SendAsync(channel.SetupCommand); |
|
|
await SendCommandListAsync(client, channel.SetupCommand); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
log.AppendLine($"> {label} READ: {channel.ReadCommand}"); |
|
|
log.AppendLine($"> {label} READ: {channel.ReadCommand}"); |
|
|
@ -63,7 +154,7 @@ public sealed class EquipmentMeasurementService |
|
|
return connection switch |
|
|
return connection switch |
|
|
{ |
|
|
{ |
|
|
"TCP" or "LAN" => CreateTcpClientAsync(label, channel), |
|
|
"TCP" or "LAN" => CreateTcpClientAsync(label, channel), |
|
|
"SERIAL" or "COM" => Task.FromResult<IScpiClient>(new SerialScpiClient(channel.PortName, channel.BaudRate, _settings.Timeout, channel.GetIdnMatches())), |
|
|
"SERIAL" or "COM" => Task.FromResult<IScpiClient>(new SerialScpiClient(channel.PortName, channel.BaudRate, _settings.Timeout, channel.GetIdnMatches(), channel.GetTerminator())), |
|
|
"VISA" or "USB" => CreateVisaClientAsync(channel), |
|
|
"VISA" or "USB" => CreateVisaClientAsync(channel), |
|
|
_ => throw new InvalidOperationException($"{label} 장비 연결 방식은 Visa, Serial, Tcp 중 하나로 설정하세요.") |
|
|
_ => throw new InvalidOperationException($"{label} 장비 연결 방식은 Visa, Serial, Tcp 중 하나로 설정하세요.") |
|
|
}; |
|
|
}; |
|
|
@ -135,4 +226,29 @@ public sealed class EquipmentMeasurementService |
|
|
|
|
|
|
|
|
return decimal.Parse(match.Value, NumberStyles.Float, CultureInfo.InvariantCulture); |
|
|
return decimal.Parse(match.Value, NumberStyles.Float, CultureInfo.InvariantCulture); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static async Task SendCommandListAsync(IScpiClient client, string commands) |
|
|
|
|
|
{ |
|
|
|
|
|
foreach (var command in SplitCommands(commands)) |
|
|
|
|
|
{ |
|
|
|
|
|
await client.SendAsync(command); |
|
|
|
|
|
await Task.Delay(100); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static IEnumerable<string> SplitCommands(string commands) |
|
|
|
|
|
{ |
|
|
|
|
|
return commands |
|
|
|
|
|
.Split(';') |
|
|
|
|
|
.Select(command => command.Trim()) |
|
|
|
|
|
.Where(command => !string.IsNullOrWhiteSpace(command)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static bool IsDisabled(ScpiChannelSettings channel) |
|
|
|
|
|
{ |
|
|
|
|
|
var connection = channel.Connection.Trim(); |
|
|
|
|
|
return string.Equals(connection, "None", StringComparison.OrdinalIgnoreCase) || |
|
|
|
|
|
string.Equals(connection, "Disabled", StringComparison.OrdinalIgnoreCase) || |
|
|
|
|
|
string.Equals(connection, "Off", StringComparison.OrdinalIgnoreCase); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|