# Power Supply Related Code This file is a reference-only extraction. It is not compiled by the Housing app. ## Source Files - `Services/EquipmentMeasurementSettings.cs` - `Services/EquipmentMeasurementService.cs` - `Services/IScpiClient.cs` - `Services/TcpScpiClient.cs` - `Services/SerialScpiClient.cs` - `Services/VisaScpiClient.cs` ## Hardware.ini Keys ```ini [Equipment] Timeout=5000 SettleMilliseconds=300 PreBoardCommand=VOLT 5, (@2);OUTP ON, (@2) PreBoardDelayMilliseconds=2000 LogoutCommand=OUTP OFF, (@1) ; E36233A Power Supply CurrentConnection=LAN CurrentResource= CurrentIdnMatch=E36233A CurrentHost=192.168.10.12 CurrentPort=5025 CurrentPortName= CurrentBaudRate=9600 CurrentTerminator=LF CurrentSetupCommand=OUTP ON, (@1) CurrentCleanupCommand=OUTP OFF, (@1) CurrentReadCommand=MEAS:CURR? (@1) ``` ## Settings Load Code ```csharp PreBoardCommand = GetString(values, "PreBoardCommand", string.Empty); PreBoardDelayMilliseconds = GetInt(values, "PreBoardDelayMilliseconds", 0); LogoutCommand = GetString(values, "LogoutCommand", string.Empty); Current = LoadChannel(values, "Current", "MEAS:CURR? CH1", "E362"); ``` ## Pre-Board Output Control ```csharp public async Task 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(); } ``` ## Current Read Flow ```csharp 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); } var current = currentClient is null ? await ReadChannelAsync("CURRENT", _settings.Current, log) : await ReadChannelWithClientAsync("CURRENT", _settings.Current, currentClient, log, skipSetupCommand: true); ``` ## Cleanup And Logout ```csharp private static async Task SendCleanupCommandAsync(IScpiClient? client, ScpiChannelSettings channel, StringBuilder log) { if (client is null || string.IsNullOrWhiteSpace(channel.CleanupCommand)) { return; } try { log.AppendLine($"> CURRENT CLEANUP: {channel.CleanupCommand}"); await SendCommandListAsync(client, channel.CleanupCommand); } catch (Exception ex) { log.AppendLine($"> CURRENT CLEANUP FAILED: {ex.Message}"); } } ``` ```csharp public async Task 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(); } ``` ## Protected Power-Off Command Guard ```csharp private static async Task SendCommandListAsync(IScpiClient client, string commands) { foreach (var command in SplitCommands(commands)) { if (IsProtectedPowerOffCommand(command)) { continue; } await client.SendAsync(command); await Task.Delay(100); } } ``` ```csharp private static bool IsProtectedPowerOffCommand(string command) { return Regex.IsMatch(command, @"^\s*OUTP(?:UT)?\s+OFF\s*,?\s*\(@2\)\s*$", RegexOptions.IgnoreCase); } ```