Files
ACP/DeviceCommand/Devices/PW8001.cs
T

473 lines
19 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Common;
using Common.Attributes;
using DeviceCommand.Base;
using Model.Models;
using System;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
namespace DeviceCommand.Device
{
/// <summary>
/// 功率分析仪(型号:HIOKI PW8001) 一拖三,支持多通道电压/电流/功率及谐波测量
/// </summary>
[ACPCommand]
public class PW8001 : Tcp
{
/// <summary>
/// 构造函数:SCPI 通信使用端口 23
/// </summary>
public PW8001(TcpConfig config) : base(config)
{
}
/// <summary>
/// 执行引擎注入的设备实例会话键
/// </summary>
public string? SessionKey { get; set; }
/// <summary>
/// 从设备返回的 SCPI 响应字符串中提取数值部分并转换为 double。
/// 支持科学计数法(如 2.48E-03),结果保留两位小数。
/// </summary>
/// <param name="raw">设备返回的原始字符串</param>
/// <returns>提取到的数值(保留两位小数),解析失败时返回 0</returns>
private static double ExtractDouble(string raw)
{
if (string.IsNullOrWhiteSpace(raw)) return 0;
// 从响应中提取第一个数值(含正负号、小数点、科学计数法),可自动忽略单位后缀与命令头
var match = Regex.Match(raw, @"[+-]?(?:\d+\.?\d*|\.\d+)(?:[Ee][+-]?\d+)?");
return match.Success && double.TryParse(match.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out double val)
? Math.Round(val, 2)
: 0;
}
#region 1. IEEE 488.2 基础标准命令
/// <summary>
/// 查询仪器识别信息 (*IDN? 指令)
/// </summary>
/// <param name="ct">取消令牌</param>
/// <returns>设备标识字符串 (制造商, 型号, 序列号, 固件版本)</returns>
public virtual async Task<string> 查询机器信息(CancellationToken ct = default)
{
return await WriteReadAsync("*IDN?\r\n", "\n", ct);
}
/// <summary>
/// 查询仪器已安装的硬件选件 (*OPT? 指令)
/// </summary>
/// <param name="ct">取消令牌</param>
/// <returns>硬件选件列表字符串</returns>
public virtual async Task<string> 查询硬件选项(CancellationToken ct = default)
{
return await WriteReadAsync("*OPT?\r\n", "\n", ct);
}
/// <summary>
/// 复位仪器到默认状态 (*RST 指令)
/// </summary>
/// <param name="ct">取消令牌</param>
public virtual async Task 复位仪器(CancellationToken ct = default)
{
await SendAsync("*RST\r\n", ct);
}
/// <summary>
/// 清除状态寄存器和错误队列 (*CLS 指令)
/// </summary>
/// <param name="ct">取消令牌</param>
public virtual async Task 清除状态(CancellationToken ct = default)
{
await SendAsync("*CLS\r\n", ct);
}
#endregion
#region 2. 仪器系统与测试模式设置设置 (System & Mode)
/// <summary>
/// 设置测试模式为 WIDE 宽带测量模式 (:MODE WIDE 指令)
/// </summary>
/// <param name="ct">取消令牌</param>
public virtual async Task 设置测试模式_WIDE(CancellationToken ct = default)
{
await SendAsync(":MODE WIDE\r\n", ct);
}
/// <summary>
/// 设置测试模式为 IEC 标准测量模式 (:MODE IEC 指令)
/// </summary>
/// <param name="ct">取消令牌</param>
public virtual async Task 设置测试模式_IEC(CancellationToken ct = default)
{
await SendAsync(":MODE IEC\r\n", ct);
}
/// <summary>
/// 查询当前测试模式 (:MODE? 指令)
/// </summary>
/// <param name="ct">取消令牌</param>
/// <returns>测试模式字符串 (WIDE / IEC)</returns>
public virtual async Task<string> 查询测试模式(CancellationToken ct = default)
{
return await WriteReadAsync(":MODE?\r\n", "\n", ct);
}
/// <summary>
/// 设置同步源 (:SYNC:SOURce 指令)
/// </summary>
/// <param name="源">同步源标识</param>
/// <param name="ct">取消令牌</param>
public virtual async Task 设置同步源(string , CancellationToken ct = default)
{
await SendAsync($":SYNC:SOURce {源}\r\n", ct);
}
/// <summary>
/// 查询当前同步源 (:SYNC:SOURce? 指令)
/// </summary>
/// <param name="ct">取消令牌</param>
/// <returns>同步源标识字符串</returns>
public virtual async Task<string> 查询同步源(CancellationToken ct = default)
{
return await WriteReadAsync(":SYNC:SOURce?\r\n", "\n", ct);
}
/// <summary>
/// 设置零点调整状态 (:ZERO 指令)
/// </summary>
/// <param name="状态">零点调整状态 (ON / OFF)</param>
/// <param name="ct">取消令牌</param>
public virtual async Task 设置零点调整(string 状态, CancellationToken ct = default)
{
await SendAsync($":ZERO {状态}\r\n", ct);
}
/// <summary>
/// 查询零点调整状态 (:ZERO? 指令)
/// </summary>
/// <param name="ct">取消令牌</param>
/// <returns>零点调整状态字符串 (ON / OFF)</returns>
public virtual async Task<string> 查询零点调整(CancellationToken ct = default)
{
return await WriteReadAsync(":ZERO?\r\n", "\n", ct);
}
/// <summary>
/// 设置零点抑制状态 (:ZSP 指令)
/// </summary>
/// <param name="状态">零点抑制状态 (ON / OFF)</param>
/// <param name="ct">取消令牌</param>
public virtual async Task 设置零点抑制(string 状态, CancellationToken ct = default)
{
await SendAsync($":ZSP {状态}\r\n", ct);
}
/// <summary>
/// 查询零点抑制状态 (:ZSP? 指令)
/// </summary>
/// <param name="ct">取消令牌</param>
/// <returns>零点抑制状态字符串 (ON / OFF)</returns>
public virtual async Task<string> 查询零点抑制(CancellationToken ct = default)
{
return await WriteReadAsync(":ZSP?\r\n", "\n", ct);
}
/// <summary>
/// 设置响应消息头开关 (:HEADer 指令)
/// </summary>
/// <param name="状态">消息头开关状态 (ON / OFF)</param>
/// <param name="ct">取消令牌</param>
public virtual async Task 设置响应消息头(string 状态, CancellationToken ct = default)
{
await SendAsync($":HEADer {状态}\r\n", ct);
}
/// <summary>
/// 查询响应消息头开关状态 (:HEADer? 指令)
/// </summary>
/// <param name="ct">取消令牌</param>
/// <returns>消息头开关状态字符串 (ON / OFF)</returns>
public virtual async Task<string> 查询响应消息头(CancellationToken ct = default)
{
return await WriteReadAsync(":HEADer?\r\n", "\n", ct);
}
/// <summary>
/// 设置按键锁定状态 (:KLOCk 指令)
/// </summary>
/// <param name="状态">按键锁定状态 (ON / OFF)</param>
/// <param name="ct">取消令牌</param>
public virtual async Task 设置按键锁定(string 状态, CancellationToken ct = default)
{
await SendAsync($":KLOCk {状态}\r\n", ct);
}
/// <summary>
/// 查询按键锁定状态 (:KLOCk? 指令)
/// </summary>
/// <param name="ct">取消令牌</param>
/// <returns>按键锁定状态字符串 (ON / OFF)</returns>
public virtual async Task<string> 查询按键锁定(CancellationToken ct = default)
{
return await WriteReadAsync(":KLOCk?\r\n", "\n", ct);
}
#endregion
#region 3. 积分控制 (Integration)
/// <summary>
/// 设置积分控制模式 (:INTEG:CONTROL 指令)
/// </summary>
/// <param name="模式">积分控制模式</param>
/// <param name="ct">取消令牌</param>
public virtual async Task 设置积分控制(string 模式, CancellationToken ct = default)
{
await SendAsync($":INTEG:CONTROL {模式}\r\n", ct);
}
/// <summary>
/// 查询积分控制模式 (:INTEG:CONTROL? 指令)
/// </summary>
/// <param name="ct">取消令牌</param>
/// <returns>积分控制模式字符串</returns>
public virtual async Task<string> 查询积分控制(CancellationToken ct = default)
{
return await WriteReadAsync(":INTEG:CONTROL?\r\n", "\n", ct);
}
/// <summary>
/// 设置指定通道的积分模式 (:INTEG:MODE 指令)
/// </summary>
/// <param name="通道号">通道编号</param>
/// <param name="模式">积分模式</param>
/// <param name="ct">取消令牌</param>
public virtual async Task 设置积分模式(string 通道号, string 模式, CancellationToken ct = default)
{
await SendAsync($":INTEG:MODE{通道号} {模式}\r\n", ct);
}
/// <summary>
/// 查询指定通道的积分模式 (:INTEG:MODE? 指令)
/// </summary>
/// <param name="通道号">通道编号</param>
/// <param name="ct">取消令牌</param>
/// <returns>积分模式字符串</returns>
public virtual async Task<string> 查询积分模式(string 通道号, CancellationToken ct = default)
{
return await WriteReadAsync($":INTEG:MODE{通道号}?\r\n", "\n", ct);
}
#endregion
#region 4. 测量值查询 (Measurement Query)
// ---------------- 基础测量(不含变比) ----------------
/// <summary>
/// 查询指定通道的电压测量值(不含变比) (:MEAS:U? 指令)
/// </summary>
/// <param name="通道号">通道编号</param>
/// <param name="ct">取消令牌</param>
/// <returns>电压测量值 (单位: V,保留两位小数)</returns>
public virtual async Task<double> 查询电压_不含变比(int 通道号, CancellationToken ct = default)
{
string resp = await WriteReadAsync($":MEAS:U{通道号}?\r\n", "\n", ct);
return ExtractDouble(resp);
}
/// <summary>
/// 查询指定通道的电流测量值(不含变比) (:MEAS:I? 指令)
/// </summary>
/// <param name="通道号">通道编号</param>
/// <param name="ct">取消令牌</param>
/// <returns>电流测量值 (单位: A,保留两位小数)</returns>
public virtual async Task<double> 查询电流_不含变比(int 通道号, CancellationToken ct = default)
{
string resp = await WriteReadAsync($":MEAS:I{通道号}?\r\n", "\n", ct);
return ExtractDouble(resp);
}
/// <summary>
/// 查询指定通道的功率测量值(不含变比) (:MEAS:P? 指令)
/// </summary>
/// <param name="通道号">通道编号</param>
/// <param name="ct">取消令牌</param>
/// <returns>功率测量值 (单位: W,保留两位小数)</returns>
public virtual async Task<double> 查询功率_不含变比(int 通道号, CancellationToken ct = default)
{
string resp = await WriteReadAsync($":MEAS:P{通道号}?\r\n", "\n", ct);
return ExtractDouble(resp);
}
// ---------------- 基础测量(含变比 CT ----------------
/// <summary>
/// 查询指定通道的电压测量值(含变比) (:MEAS:U:CT? 指令)
/// </summary>
/// <param name="通道号">通道编号</param>
/// <param name="ct">取消令牌</param>
/// <returns>电压测量值 (单位: V,保留两位小数)</returns>
public virtual async Task<double> 查询电压_含变比(int 通道号, CancellationToken ct = default)
{
string resp = await WriteReadAsync($":MEAS:U{通道号}:CT?\r\n", "\n", ct);
return ExtractDouble(resp);
}
/// <summary>
/// 查询指定通道的电流测量值(含变比) (:MEAS:I:CT? 指令)
/// </summary>
/// <param name="通道号">通道编号</param>
/// <param name="ct">取消令牌</param>
/// <returns>电流测量值 (单位: A,保留两位小数)</returns>
public virtual async Task<double> 查询电流_含变比(int 通道号, CancellationToken ct = default)
{
string resp = await WriteReadAsync($":MEAS:I{通道号}:CT?\r\n", "\n", ct);
return ExtractDouble(resp);
}
/// <summary>
/// 查询指定通道的功率测量值(含变比) (:MEAS:P:CT? 指令)
/// </summary>
/// <param name="通道号">通道编号</param>
/// <param name="ct">取消令牌</param>
/// <returns>功率测量值 (单位: W,保留两位小数)</returns>
public virtual async Task<double> 查询功率_含变比(int 通道号, CancellationToken ct = default)
{
string resp = await WriteReadAsync($":MEAS:P{通道号}:CT?\r\n", "\n", ct);
return ExtractDouble(resp);
}
// ---------------- 其他高阶参数测量 ----------------
/// <summary>
/// 查询指定通道的有功功率积分值 (:MEAS:WP? 指令)
/// </summary>
/// <param name="通道号">通道编号</param>
/// <param name="ct">取消令牌</param>
/// <returns>有功功率积分值 (单位: Wh,保留两位小数)</returns>
public virtual async Task<double> 查询有功功率积分(int 通道号, CancellationToken ct = default)
{
string resp = await WriteReadAsync($":MEAS:WP{通道号}?\r\n", "\n", ct);
return ExtractDouble(resp);
}
/// <summary>
/// 查询指定通道的电压总谐波失真 (THD) (:MEAS:UTHD? 指令)
/// </summary>
/// <param name="通道号">通道编号</param>
/// <param name="ct">取消令牌</param>
/// <returns>电压 THD 值 (单位: %,保留两位小数)</returns>
public virtual async Task<double> 查询电压THD(int 通道号, CancellationToken ct = default)
{
string resp = await WriteReadAsync($":MEAS:UTHD{通道号}?\r\n", "\n", ct);
return ExtractDouble(resp);
}
/// <summary>
/// 查询指定通道的电流总谐波失真 (THD) (:MEAS:ITHD? 指令)
/// </summary>
/// <param name="通道号">通道编号</param>
/// <param name="ct">取消令牌</param>
/// <returns>电流 THD 值 (单位: %,保留两位小数)</returns>
public virtual async Task<double> 查询电流THD(int 通道号, CancellationToken ct = default)
{
string resp = await WriteReadAsync($":MEAS:ITHD{通道号}?\r\n", "\n", ct);
return ExtractDouble(resp);
}
/// <summary>
/// 查询线电压 U12 (:MEAS:U12? 指令)
/// </summary>
/// <param name="ct">取消令牌</param>
/// <returns>线电压 U12 值 (单位: V,保留两位小数)</returns>
public virtual async Task<double> 查询线电压U12(CancellationToken ct = default)
{
string resp = await WriteReadAsync(":MEAS:U12?\r\n", "\n", ct);
return ExtractDouble(resp);
}
/// <summary>
/// 查询三相总功率 P123 (:MEAS:P123? 指令)
/// </summary>
/// <param name="ct">取消令牌</param>
/// <returns>三相总功率值 (单位: W,保留两位小数)</returns>
public virtual async Task<double> 查询总功率P123(CancellationToken ct = default)
{
string resp = await WriteReadAsync(":MEAS:P123?\r\n", "\n", ct);
return ExtractDouble(resp);
}
// ---------------- 整流平均值 ----------------
/// <summary>
/// 查询指定通道的电压整流平均值(不含变比) (:MEAS:UMN? 指令)
/// </summary>
/// <param name="通道号">通道编号</param>
/// <param name="ct">取消令牌</param>
/// <returns>电压整流平均值 (单位: V,保留两位小数)</returns>
public virtual async Task<double> 查询电压整流平均值(int 通道号, CancellationToken ct = default)
{
string resp = await WriteReadAsync($":MEAS:UMN{通道号}?\r\n", "\n", ct);
return ExtractDouble(resp);
}
/// <summary>
/// 查询指定通道的电流整流平均值(不含变比) (:MEAS:IMN? 指令)
/// </summary>
/// <param name="通道号">通道编号</param>
/// <param name="ct">取消令牌</param>
/// <returns>电流整流平均值 (单位: A,保留两位小数)</returns>
public virtual async Task<double> 查询电流整流平均值(int 通道号, CancellationToken ct = default)
{
string resp = await WriteReadAsync($":MEAS:IMN{通道号}?\r\n", "\n", ct);
return ExtractDouble(resp);
}
/// <summary>
/// 查询指定通道的电压整流平均值(含变比) (:MEAS:UMN:CT? 指令)
/// </summary>
/// <param name="通道号">通道编号</param>
/// <param name="ct">取消令牌</param>
/// <returns>电压整流平均值 (单位: V,保留两位小数)</returns>
public virtual async Task<double> 查询电压整流平均值_含变比(int 通道号, CancellationToken ct = default)
{
string resp = await WriteReadAsync($":MEAS:UMN{通道号}:CT?\r\n", "\n", ct);
return ExtractDouble(resp);
}
/// <summary>
/// 查询指定通道的电流整流平均值(含变比) (:MEAS:IMN:CT? 指令)
/// </summary>
/// <param name="通道号">通道编号</param>
/// <param name="ct">取消令牌</param>
/// <returns>电流整流平均值 (单位: A,保留两位小数)</returns>
public virtual async Task<double> 查询电流整流平均值_含变比(int 通道号, CancellationToken ct = default)
{
string resp = await WriteReadAsync($":MEAS:IMN{通道号}:CT?\r\n", "\n", ct);
return ExtractDouble(resp);
}
#endregion
#region 5. 自定义透传指令
/// <summary>
/// 发送自定义命令(透传任意 SCPI 指令)
/// </summary>
/// <param name="命令">自定义命令字符串</param>
/// <param name="ct">取消令牌</param>
public virtual async Task 发送自定义命令(string 命令, CancellationToken ct = default)
{
await SendAsync($"{命令}\r\n", ct);
}
#endregion
}
}