using System;
using APS7100TestTool.Models;
using APS7100TestTool.Services;
namespace APS7100TestTool.Controllers
{
///
/// APS-7100 AC 可编程电源控制器
///
/// ⚠ 重要说明:APS7100 使用完整的、层级严格的 SCPI 命令树
/// 核心根节点:MEAS / SOUR / OUTP / STAT / DATA
///
/// 命令特点:
/// 1. 几乎都带二级/三级节点
/// 2. 不支持简写的无子节点查询(如 OUTP? 不行,必须 OUTP:STAT?)
/// 3. 测量命令必须走 SCALar 路径
///
public class APS7100Controller : IPowerSupplyController
{
private readonly ScpiDevice _device;
public DeviceType DeviceType => DeviceType.APS7100;
public DeviceInfo DeviceInfo => DeviceInfo.GetDeviceInfo(DeviceType.APS7100);
public APS7100Controller(ScpiDevice device)
{
_device = device ?? throw new ArgumentNullException(nameof(device));
}
#region IEEE 488.2 标准命令
///
/// 获取设备识别信息
/// ⚠ APS7100 在收到任何 SCPI 命令后会自动进入远程模式
///
public string GetIdentification()
{
string result = _device.Query("*IDN?");
// APS7100 收到 SCPI 命令后自动进入远程模式
_isInRemoteMode = true;
return result;
}
///
/// 重置设备到出厂状态
///
public void Reset()
{
_device.SendCommand("*RST");
System.Threading.Thread.Sleep(1000);
}
///
/// 清除状态寄存器
///
public void ClearStatus()
{
_device.SendCommand("*CLS");
}
///
/// 等待所有挂起操作完成
///
public void WaitComplete()
{
_device.SendCommand("*WAI");
}
///
/// 查询操作完成状态
///
public bool QueryOperationComplete()
{
string result = _device.Query("*OPC?");
return result.Trim() == "1";
}
///
/// 触发设备
///
public void Trigger()
{
_device.SendCommand("*TRG");
}
///
/// 自检
///
public int SelfTest()
{
string result = _device.Query("*TST?");
return int.TryParse(result.Trim(), out int code) ? code : -1;
}
///
/// 保存设置到指定位置
///
public void SaveSettings(int location)
{
_device.SendCommand($"*SAV {location}");
}
///
/// 从指定位置恢复设置
///
public void RecallSettings(int location)
{
_device.SendCommand($"*RCL {location}");
}
///
/// 查询事件状态寄存器
///
public int QueryEventStatusRegister()
{
string result = _device.Query("*ESR?");
return int.TryParse(result.Trim(), out int value) ? value : 0;
}
///
/// 设置事件状态使能寄存器
///
public void SetEventStatusEnable(int mask)
{
_device.SendCommand($"*ESE {mask}");
}
///
/// 查询状态字节
///
public int QueryStatusByte()
{
string result = _device.Query("*STB?");
return int.TryParse(result.Trim(), out int value) ? value : 0;
}
///
/// 设置服务请求使能
///
public void SetServiceRequestEnable(int mask)
{
_device.SendCommand($"*SRE {mask}");
}
#endregion
#region SYSTEM 系统命令
// 内部状态跟踪,避免重复发送 SYST:REM 导致 SCPI Error
private bool _isInRemoteMode = false;
///
/// 进入远程控制模式
/// ⚠ APS7100 如果已经是远程模式,再次发送 SYST:REM 会报错
///
public void SetRemoteMode()
{
// 如果已知在远程模式,跳过
if (_isInRemoteMode) return;
try
{
_device.SendCommand("SYST:REM");
_isInRemoteMode = true;
}
catch
{
// 如果报错,可能已经在远程模式,标记状态并忽略
_isInRemoteMode = true;
}
}
///
/// 返回本地控制模式
///
public void SetLocalMode()
{
try
{
_device.SendCommand("SYST:COMM:RLST LOCAL");
_isInRemoteMode = false;
}
catch
{
// 忽略错误
_isInRemoteMode = false;
}
}
///
/// 锁定/解锁前面板按键
/// ⚠ APS7100 使用 KLOC 命令,不是 RWLOCK
///
public void SetPanelLock(bool locked)
{
_device.SendCommand(locked ? "SYST:KLOC ON" : "SYST:KLOC OFF");
}
///
/// 查询系统错误
///
public string QueryError()
{
return _device.Query("SYST:ERR?");
}
///
/// 清除系统错误队列
///
public void ClearErrors()
{
// 循环读取直到没有错误
try
{
for (int i = 0; i < 10; i++) // 最多清除 10 个错误
{
string error = _device.Query("SYST:ERR?");
if (error.StartsWith("0") || error.Contains("No error"))
break;
}
}
catch { }
}
///
/// 查询 SCPI 版本
///
public string QueryVersion()
{
return _device.Query("SYST:VERS?");
}
///
/// 查询当前是否为远程模式
///
public bool IsRemoteMode()
{
// 返回内部跟踪的状态
// 如果能通讯就说明至少连接正常
try
{
_device.Query("*IDN?");
return _isInRemoteMode;
}
catch
{
return false;
}
}
#endregion
#region OUTPUT 输出控制
///
/// 设置输出开关
/// ⚠ APS7100 必须使用 OUTPut:STATe,不支持 OUTP ON
///
public void SetOutput(bool enable)
{
_device.SendCommand(enable ? "OUTP:STAT ON" : "OUTP:STAT OFF");
}
///
/// 获取输出状态
/// ⚠ APS7100 必须使用 OUTPut:STATe?,不支持 OUTP?
///
public bool GetOutputState()
{
string result = _device.Query("OUTP:STAT?");
return result.Trim() == "1" || result.ToUpper().Contains("ON");
}
///
/// 清除输出保护状态
///
public void ClearOutputProtection()
{
_device.SendCommand("OUTP:PROT:CLE");
}
#endregion
#region SOURCE 源设置 - 电压
///
/// 设置输出电压 (V)
///
public void SetVoltage(double voltage)
{
_device.SendCommand($"SOUR:VOLT {voltage}");
}
///
/// 获取电压设定值 (V)
///
public double GetVoltage()
{
string result = _device.Query("SOUR:VOLT?");
return double.TryParse(result.Trim(), out double value) ? value : 0;
}
///
/// 设置电压量程
/// ⚠ APS7100 量程选项:R155 / R310 / R600 / AUTO
/// ❌ 不支持 LOW / HIGH
///
public void SetVoltageRange(APS7100VoltageRange range)
{
string rangeStr = range switch
{
APS7100VoltageRange.R155 => "R155",
APS7100VoltageRange.R310 => "R310",
APS7100VoltageRange.R600 => "R600",
APS7100VoltageRange.Auto => "AUTO",
_ => "AUTO"
};
_device.SendCommand($"SOUR:VOLT:RANG {rangeStr}");
}
///
/// 获取电压量程
///
public APS7100VoltageRange GetVoltageRangeAPS()
{
string result = _device.Query("SOUR:VOLT:RANG?").Trim().ToUpper();
return result switch
{
"R155" or "155" => APS7100VoltageRange.R155,
"R310" or "310" => APS7100VoltageRange.R310,
"R600" or "600" => APS7100VoltageRange.R600,
"AUTO" => APS7100VoltageRange.Auto,
_ => APS7100VoltageRange.Auto
};
}
///
/// 设置电压量程(接口兼容方法)
/// ⚠ 注意:VoltageRange.Low 映射为 R155,High 映射为 R310
///
public void SetVoltageRange(VoltageRange range)
{
// 接口兼容:Low -> R155, High -> R310
SetVoltageRange(range == VoltageRange.Low ? APS7100VoltageRange.R155 : APS7100VoltageRange.R310);
}
///
/// 获取电压量程(接口兼容方法)
///
public VoltageRange GetVoltageRange()
{
var range = GetVoltageRangeAPS();
return range == APS7100VoltageRange.R155 ? VoltageRange.Low : VoltageRange.High;
}
#endregion
#region SOURCE 源设置 - 频率
///
/// 设置输出频率 (Hz)
/// 常用值:50 / 60 / 400 Hz
///
public void SetFrequency(double frequency)
{
_device.SendCommand($"SOUR:FREQ {frequency}");
}
///
/// 获取频率设定值 (Hz)
///
public double GetFrequency()
{
string result = _device.Query("SOUR:FREQ?");
return double.TryParse(result.Trim(), out double value) ? value : 50;
}
#endregion
#region SOURCE 源设置 - 相位
///
/// 设置输出相位 (度)
/// 用于多相或并机控制
///
public void SetPhase(double degrees)
{
_device.SendCommand($"SOUR:PHAS {degrees}");
}
///
/// 获取相位设定值 (度)
///
public double GetPhase()
{
string result = _device.Query("SOUR:PHAS?");
return double.TryParse(result.Trim(), out double value) ? value : 0;
}
#endregion
#region SOURCE 源设置 - 电流限制
///
/// 设置电流限值 (A)
/// ⚠ APS7100 只有电流限制,没有"电流设定"概念
/// 必须使用 SOURce:CURRent:LIMit
///
public void SetCurrent(double current)
{
_device.SendCommand($"SOUR:CURR:LIM:RMS {current}");
}
///
/// 设置电流限值 (A) - 显式方法
///
public void SetCurrentLimit(double current)
{
SetCurrent(current);
}
///
/// 获取电流限值 (A)
/// ⚠ 必须使用 SOURce:CURRent:LIMit?
/// ❌ SOUR:CURR? 不可用
///
public double GetCurrent()
{
string result = _device.Query("SOUR:CURR:LIM:RMS?");
return double.TryParse(result.Trim(), out double value) ? value : 0;
}
///
/// 获取电流限值 (A) - 显式方法
///
public double GetCurrentLimit()
{
return GetCurrent();
}
#endregion
#region MEASURE 测量命令
///
/// 测量实际输出电压 (V RMS)
/// ⚠ 必须使用 MEASure:SCALar 路径
///
public double MeasureVoltage()
{
string result = _device.Query("MEAS:SCAL:VOLT?");
return double.TryParse(result.Trim(), out double value) ? value : 0;
}
///
/// 测量实际输出电流 (A RMS)
/// ⚠ 必须使用 MEASure:SCALar 路径
///
public double MeasureCurrent()
{
string result = _device.Query("MEAS:SCAL:CURR?");
return double.TryParse(result.Trim(), out double value) ? value : 0;
}
///
/// 测量实际频率 (Hz)
/// ⚠ 必须使用 MEASure:SCALar 路径
///
public double MeasureFrequency()
{
string result = _device.Query("MEAS:SCAL:FREQ?");
return double.TryParse(result.Trim(), out double value) ? value : 0;
}
///
/// 测量有功功率 P (W)
/// ⚠ 必须使用完整路径 MEASure:SCALar:POWer:AC:REAL?
/// ❌ MEAS:POW? 不可用
///
public double MeasurePower()
{
string result = _device.Query("MEAS:SCAL:POW:AC:REAL?");
return double.TryParse(result.Trim(), out double value) ? value : 0;
}
///
/// 测量有功功率 P (W) - 别名
///
public double MeasureRealPower()
{
return MeasurePower();
}
///
/// 测量视在功率 S (VA)
///
public double MeasureApparentPower()
{
string result = _device.Query("MEAS:SCAL:POW:AC:APP?");
return double.TryParse(result.Trim(), out double value) ? value : 0;
}
///
/// 测量功率因数 PF
/// ⚠ 使用 MEASure:SCALar:POWer:AC:PFAC?
/// ❌ MEAS:PF? 不可用
///
public double MeasurePowerFactor()
{
string result = _device.Query("MEAS:SCAL:POW:AC:PFAC?");
return double.TryParse(result.Trim(), out double value) ? value : 0;
}
#endregion
#region INITIATE 触发/执行命令
///
/// 立即执行(启动 Sequence / Simulation / 瞬态测试)
///
public void InitiateImmediate()
{
_device.SendCommand("INIT:IMM");
}
///
/// 立即执行瞬态
///
public void InitiateTransient()
{
_device.SendCommand("INIT:IMM:TRAN");
}
#endregion
#region STATUS 状态命令
///
/// 查询操作状态寄存器
///
public int QueryOperationStatus()
{
string result = _device.Query("STAT:OPER?");
return int.TryParse(result.Trim(), out int value) ? value : 0;
}
///
/// 查询可疑状态寄存器
///
public int QueryQuestionableStatus()
{
string result = _device.Query("STAT:QUES?");
return int.TryParse(result.Trim(), out int value) ? value : 0;
}
#endregion
#region DATA/TRACE 序列和模拟命令
///
/// 清除序列数据
/// 用于:电压跌落、频率扫变、IEC测试波形等
///
public void SequenceClear()
{
_device.SendCommand("DATA:SEQ:CLE");
}
///
/// 存储序列到指定位置
///
public void SequenceStore(int index)
{
_device.SendCommand($"DATA:SEQ:STOR {index}");
}
///
/// 从指定位置调用序列
///
public void SequenceRecall(int index)
{
_device.SendCommand($"DATA:SEQ:REC {index}");
}
///
/// 清除模拟数据
///
public void SimulationClear()
{
_device.SendCommand("DATA:SIM:CLE");
}
///
/// 存储模拟到指定位置
///
public void SimulationStore(int index)
{
_device.SendCommand($"DATA:SIM:STOR {index}");
}
///
/// 从指定位置调用模拟
///
public void SimulationRecall(int index)
{
_device.SendCommand($"DATA:SIM:REC {index}");
}
#endregion
#region 波形设置(APS7100 不支持传统波形)
///
/// 设置波形 - APS7100 不支持传统波形设置
/// ⚠ APS7100 使用 DATA:SEQuence 和 DATA:SIMulation 进行
/// 电压跌落、频率扫变、IEC测试波形,不是 SINE/SQUARE
///
public void SetWaveform(Waveform waveform)
{
// APS7100 不支持传统的 SOUR:WAVE 命令
// 它的"波形"是通过序列和模拟功能实现的
throw new NotSupportedException(
"APS7100 不支持传统波形设置。" +
"请使用 SequenceStore/SequenceRecall 或 SimulationStore/SimulationRecall 进行波形模拟。");
}
///
/// 获取当前波形 - APS7100 不支持
///
public Waveform GetWaveform()
{
throw new NotSupportedException(
"APS7100 不支持传统波形查询。输出始终为正弦波。");
}
#endregion
#region 自定义命令
///
/// 发送自定义 SCPI 命令
///
public void SendCustomCommand(string command)
{
_device.SendCommand(command);
}
///
/// 发送自定义 SCPI 查询
///
public string SendCustomQuery(string command)
{
return _device.Query(command);
}
#endregion
}
#region APS7100 专用枚举
///
/// APS7100 电压量程
/// ⚠ 注意:与其他设备不同,APS7100 使用 R155/R310/R600/AUTO
///
public enum APS7100VoltageRange
{
/// 0-155V 量程
R155,
/// 0-310V 量程
R310,
/// 0-600V 量程(如果支持)
R600,
/// 自动量程
Auto
}
#endregion
#region 通用枚举(接口兼容)
///
/// 电压量程(通用接口)
///
public enum VoltageRange
{
/// 低档量程
Low,
/// 高档量程
High
}
///
/// 波形类型(通用接口)
/// ⚠ 注意:APS7100 不支持波形设置,仅用于接口兼容
///
public enum Waveform
{
/// 正弦波
Sine,
/// 方波
Square,
/// 三角波
Triangle
}
#endregion
}