查询返回数据转double
This commit is contained in:
@@ -208,9 +208,10 @@ namespace DeviceCommand.Devices
|
|||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>实际电压测量值 (单位: V)</returns>
|
/// <returns>实际电压测量值 (单位: V)</returns>
|
||||||
[Monitorable("交流电源电压")]
|
[Monitorable("交流电源电压")]
|
||||||
public virtual async Task<string> 查询实际电压(CancellationToken ct = default)
|
public virtual async Task<double> 查询实际电压(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
return await WriteReadAsync($":MEASure:VOLTage?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
|
string response = await WriteReadAsync($":MEASure:VOLTage?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return double.TryParse(response, out double result) ? result : double.NaN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -219,9 +220,10 @@ namespace DeviceCommand.Devices
|
|||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>实际电流测量值 (单位: A)</returns>
|
/// <returns>实际电流测量值 (单位: A)</returns>
|
||||||
[Monitorable("交流电源电流")]
|
[Monitorable("交流电源电流")]
|
||||||
public virtual async Task<string> 查询实际电流(CancellationToken ct = default)
|
public virtual async Task<double> 查询实际电流(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
return await WriteReadAsync($":MEASure:CURRent?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
|
string response = await WriteReadAsync($":MEASure:CURRent?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return double.TryParse(response, out double result) ? result : double.NaN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -230,9 +232,10 @@ namespace DeviceCommand.Devices
|
|||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>实际有功功率测量值 (单位: W)</returns>
|
/// <returns>实际有功功率测量值 (单位: W)</returns>
|
||||||
[Monitorable("交流电源功率")]
|
[Monitorable("交流电源功率")]
|
||||||
public virtual async Task<string> 查询实际功率(CancellationToken ct = default)
|
public virtual async Task<double> 查询实际功率(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
return await WriteReadAsync($":MEASure:POWer?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
|
string response = await WriteReadAsync($":MEASure:POWer?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return double.TryParse(response, out double result) ? result : double.NaN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -240,9 +243,10 @@ namespace DeviceCommand.Devices
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>视在功率测量值 (单位: VA)</returns>
|
/// <returns>视在功率测量值 (单位: VA)</returns>
|
||||||
public virtual async Task<string> 查询视在功率(CancellationToken ct = default)
|
public virtual async Task<double> 查询视在功率(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
return await WriteReadAsync($":MEASure:POWer:APParent?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
|
string response = await WriteReadAsync($":MEASure:POWer:APParent?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return double.TryParse(response, out double result) ? result : double.NaN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -250,9 +254,10 @@ namespace DeviceCommand.Devices
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>实际频率测量值 (单位: Hz)</returns>
|
/// <returns>实际频率测量值 (单位: Hz)</returns>
|
||||||
public virtual async Task<string> 查询实际频率(CancellationToken ct = default)
|
public virtual async Task<double> 查询实际频率(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
return await WriteReadAsync($":MEASure:FREQuency?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
|
string response = await WriteReadAsync($":MEASure:FREQuency?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return double.TryParse(response, out double result) ? result : double.NaN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -260,11 +265,11 @@ namespace DeviceCommand.Devices
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>功率因数测量值</returns>
|
/// <returns>功率因数测量值</returns>
|
||||||
public virtual async Task<string> 查询功率因数(CancellationToken ct = default)
|
public virtual async Task<double> 查询功率因数(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
return await WriteReadAsync($":MEASure:POWer:PFACtor?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
|
string response = await WriteReadAsync($":MEASure:POWer:PFACtor?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return double.TryParse(response, out double result) ? result : double.NaN;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region 5. 保护参数设置与系统监控
|
#region 5. 保护参数设置与系统监控
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using DeviceCommand.Base;
|
|||||||
using Model.Models;
|
using Model.Models;
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@@ -22,6 +23,25 @@ namespace DeviceCommand.Devices
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从设备返回的 SCPI 响应字符串中提取数值部分并转换为 double。
|
||||||
|
/// 先按逗号分割取数据段,再提取数值。
|
||||||
|
/// </summary>
|
||||||
|
private static double ExtractDouble(string raw)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(raw)) return 0;
|
||||||
|
|
||||||
|
string dataPart = raw;
|
||||||
|
int commaIdx = raw.LastIndexOf(',');
|
||||||
|
if (commaIdx >= 0 && commaIdx < raw.Length - 1)
|
||||||
|
dataPart = raw.Substring(commaIdx + 1);
|
||||||
|
|
||||||
|
var match = Regex.Match(dataPart, @"[+-]?(?:\d+\.?\d*|\.\d+)(?:[Ee][+-]?\d+)?");
|
||||||
|
return match.Success && double.TryParse(match.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out double val)
|
||||||
|
? val
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
#region 3.1. IEEE 488.2 公共命令
|
#region 3.1. IEEE 488.2 公共命令
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -270,9 +290,10 @@ namespace DeviceCommand.Devices
|
|||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>实时测量电压值 (单位: V)</returns>
|
/// <returns>实时测量电压值 (单位: V)</returns>
|
||||||
[Monitorable("高压直流电源电压")]
|
[Monitorable("高压直流电源电压")]
|
||||||
public virtual async Task<string> 查询实际电压(CancellationToken ct = default)
|
public virtual async Task<double> 查询实际电压(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
return await WriteReadAsync($"MEASure:VOLTage?{ScpiDelimiter}", ScpiDelimiter, ct);
|
string res = await WriteReadAsync($"MEASure:VOLTage?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return ExtractDouble(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -281,9 +302,10 @@ namespace DeviceCommand.Devices
|
|||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>实时测量电流值 (单位: A)</returns>
|
/// <returns>实时测量电流值 (单位: A)</returns>
|
||||||
[Monitorable("高压直流电源电流")]
|
[Monitorable("高压直流电源电流")]
|
||||||
public virtual async Task<string> 查询实际电流(CancellationToken ct = default)
|
public virtual async Task<double> 查询实际电流(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
return await WriteReadAsync($"MEASure:CURRent?{ScpiDelimiter}", ScpiDelimiter, ct);
|
string res = await WriteReadAsync($"MEASure:CURRent?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return ExtractDouble(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -291,10 +313,11 @@ namespace DeviceCommand.Devices
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>实时测量功率值 (单位: W)</returns>
|
/// <returns>实时测量功率值 (单位: W)</returns>
|
||||||
[Monitorable("高压直流电源功率")]
|
[Monitorable("高压直流电源功率")]
|
||||||
public virtual async Task<string> 查询实际功率(CancellationToken ct = default)
|
public virtual async Task<double> 查询实际功率(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
return await WriteReadAsync($"MEASure:POWer?{ScpiDelimiter}", ScpiDelimiter, ct);
|
string res = await WriteReadAsync($"MEASure:POWer?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return ExtractDouble(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -212,10 +212,10 @@ namespace DeviceCommand.Devices
|
|||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>实测直流电流值 (单位: A)</returns>
|
/// <returns>实测直流电流值 (单位: A)</returns>
|
||||||
[Monitorable("低压直流电源电流")]
|
[Monitorable("低压直流电源电流")]
|
||||||
public virtual async Task<string> 查询实际电流(CancellationToken ct = default)
|
public virtual async Task<double> 查询实际电流(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
// 修正:去除前缀冒号,改用标准 MEAS:CURR?
|
string response = await WriteReadAsync($"MEAS:CURR?{SCPIDelimiter}", SCPIDelimiter, ct);
|
||||||
return await WriteReadAsync($"MEAS:CURR?{SCPIDelimiter}", SCPIDelimiter, ct);
|
return double.TryParse(response, out double result) ? result : double.NaN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -224,10 +224,10 @@ namespace DeviceCommand.Devices
|
|||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>实测直流功率值 (单位: W)</returns>
|
/// <returns>实测直流功率值 (单位: W)</returns>
|
||||||
[Monitorable("低压直流电源功率")]
|
[Monitorable("低压直流电源功率")]
|
||||||
public virtual async Task<string> 查询实际功率(CancellationToken ct = default)
|
public virtual async Task<double> 查询实际功率(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
// 修正:去除前缀冒号,改用标准 MEAS:POW?
|
string response = await WriteReadAsync($"MEAS:POW?{SCPIDelimiter}", SCPIDelimiter, ct);
|
||||||
return await WriteReadAsync($"MEAS:POW?{SCPIDelimiter}", SCPIDelimiter, ct);
|
return double.TryParse(response, out double result) ? result : double.NaN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -236,10 +236,10 @@ namespace DeviceCommand.Devices
|
|||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>实测直流电压值 (单位: V)</returns>
|
/// <returns>实测直流电压值 (单位: V)</returns>
|
||||||
[Monitorable("低压直流电源电压")]
|
[Monitorable("低压直流电源电压")]
|
||||||
public virtual async Task<string> 查询实际电压(CancellationToken ct = default)
|
public virtual async Task<double> 查询实际电压(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
// 修正:去除前缀冒号,改用标准 MEAS:VOLT?
|
string response = await WriteReadAsync($"MEAS:VOLT?{SCPIDelimiter}", SCPIDelimiter, ct);
|
||||||
return await WriteReadAsync($"MEAS:VOLT?{SCPIDelimiter}", SCPIDelimiter, ct);
|
return double.TryParse(response, out double result) ? result : double.NaN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -253,16 +253,15 @@ namespace DeviceCommand.Devices
|
|||||||
return await WriteReadAsync($"MEAS:VAP?{SCPIDelimiter}", SCPIDelimiter, ct);
|
return await WriteReadAsync($"MEAS:VAP?{SCPIDelimiter}", SCPIDelimiter, ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 3.5.5 查询通道输出端子上测得的输出时间长度
|
/// 3.5.5 查询通道输出端子上测得的输出时间长度
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>输出时间长度</returns>
|
/// <returns>输出时间长度</returns>
|
||||||
public virtual async Task<string> 查询总输出时间长度(CancellationToken ct = default)
|
public virtual async Task<double> 查询总输出时间长度(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
// 修正:去除前缀冒号
|
string response = await WriteReadAsync($"MEAS:TIME:OUTP?{SCPIDelimiter}", SCPIDelimiter, ct);
|
||||||
return await WriteReadAsync($"MEAS:TIME:OUTP?{SCPIDelimiter}", SCPIDelimiter, ct);
|
return double.TryParse(response, out double result) ? result : double.NaN;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -435,6 +434,7 @@ namespace DeviceCommand.Devices
|
|||||||
string cmd = string.Format(CultureInfo.InvariantCulture, "VOLT:LIM {0:F3}{1}", 电压, SCPIDelimiter);
|
string cmd = string.Format(CultureInfo.InvariantCulture, "VOLT:LIM {0:F3}{1}", 电压, SCPIDelimiter);
|
||||||
await SendAsync(cmd, ct);
|
await SendAsync(cmd, ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 3.7.2.9 清除电压上限限制(恢复为设备物理允许的最大电压值)
|
/// 3.7.2.9 清除电压上限限制(恢复为设备物理允许的最大电压值)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -444,6 +444,7 @@ namespace DeviceCommand.Devices
|
|||||||
// 发送 MAXimum 设为最大值以达到"清除限制"的效果
|
// 发送 MAXimum 设为最大值以达到"清除限制"的效果
|
||||||
await SendAsync($"VOLT:LIMIT MAX{SCPIDelimiter}", ct); // 对应手册 3.7.2.8
|
await SendAsync($"VOLT:LIMIT MAX{SCPIDelimiter}", ct); // 对应手册 3.7.2.8
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 3.7.3.1 设置输出功率值 (W)
|
/// 3.7.3.1 设置输出功率值 (W)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -548,4 +549,4 @@ namespace DeviceCommand.Devices
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,7 @@ using DeviceCommand.Base;
|
|||||||
using Model.Models;
|
using Model.Models;
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@@ -21,6 +22,23 @@ namespace DeviceCommand.Devices
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 辅助方法:从带有单位的字符串中提取数值并转换为 double。
|
||||||
|
/// 例如将 "12.34A", "5.00 V", "1.2e-3 W" 转换为纯数字。解析失败返回 double.NaN。
|
||||||
|
/// </summary>
|
||||||
|
private double ParseResponseWithUnit(string response)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(response)) return double.NaN;
|
||||||
|
|
||||||
|
// 使用正则提取数字部分(支持正负号、小数点、科学计数法 e/E)
|
||||||
|
var match = Regex.Match(response, @"[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?");
|
||||||
|
if (match.Success && double.TryParse(match.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out double result))
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return double.NaN;
|
||||||
|
}
|
||||||
|
|
||||||
#region 3.1. IEEE 488.2 公共命令
|
#region 3.1. IEEE 488.2 公共命令
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -38,7 +56,7 @@ namespace DeviceCommand.Devices
|
|||||||
/// <returns>错误代码和描述信息</returns>
|
/// <returns>错误代码和描述信息</returns>
|
||||||
public virtual async Task<string> 查询错误信息(CancellationToken ct = default)
|
public virtual async Task<string> 查询错误信息(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
return await WriteReadAsync($":SYSTem:ERRor?{ScpiDelimiter}", ScpiDelimiter, ct); //[cite: 1]
|
return await WriteReadAsync($":SYSTem:ERRor?{ScpiDelimiter}", ScpiDelimiter, ct); //
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -190,9 +208,10 @@ namespace DeviceCommand.Devices
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>设定的拉载电流值 (单位: A)</returns>
|
/// <returns>设定的拉载电流值 (单位: A)</returns>
|
||||||
public virtual async Task<string> 查询恒电流CC设定(CancellationToken ct = default)
|
public virtual async Task<double> 查询恒电流CC设定(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
return await WriteReadAsync($"STATic:CC:HIGH:LEVel?{ScpiDelimiter}", ScpiDelimiter, ct);
|
string response = await WriteReadAsync($"STATic:CC:HIGH:LEVel?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return ParseResponseWithUnit(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -211,9 +230,10 @@ namespace DeviceCommand.Devices
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>设定的拉载电压值 (单位: V)</returns>
|
/// <returns>设定的拉载电压值 (单位: V)</returns>
|
||||||
public virtual async Task<string> 查询恒电压CV设定(CancellationToken ct = default)
|
public virtual async Task<double> 查询恒电压CV设定(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
return await WriteReadAsync($"STATic:CV:HIGH:LEVel?{ScpiDelimiter}", ScpiDelimiter, ct);
|
string response = await WriteReadAsync($"STATic:CV:HIGH:LEVel?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return ParseResponseWithUnit(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -232,9 +252,10 @@ namespace DeviceCommand.Devices
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>设定的拉载功率值 (单位: W)</returns>
|
/// <returns>设定的拉载功率值 (单位: W)</returns>
|
||||||
public virtual async Task<string> 查询恒功率CP设定(CancellationToken ct = default)
|
public virtual async Task<double> 查询恒功率CP设定(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
return await WriteReadAsync($"STATic:CP:HIGH:LEVel?{ScpiDelimiter}", ScpiDelimiter, ct);
|
string response = await WriteReadAsync($"STATic:CP:HIGH:LEVel?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return ParseResponseWithUnit(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -253,9 +274,10 @@ namespace DeviceCommand.Devices
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>设定的拉载电阻值 (单位: Ω)</returns>
|
/// <returns>设定的拉载电阻值 (单位: Ω)</returns>
|
||||||
public virtual async Task<string> 查询恒电阻CR设定(CancellationToken ct = default)
|
public virtual async Task<double> 查询恒电阻CR设定(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
return await WriteReadAsync($"STATic:CR:HIGH:LEVel?{ScpiDelimiter}", ScpiDelimiter, ct);
|
string response = await WriteReadAsync($"STATic:CR:HIGH:LEVel?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return ParseResponseWithUnit(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -268,9 +290,10 @@ namespace DeviceCommand.Devices
|
|||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>实时测量电压值 (单位: V)</returns>
|
/// <returns>实时测量电压值 (单位: V)</returns>
|
||||||
[Monitorable("高压直流负载电压")]
|
[Monitorable("高压直流负载电压")]
|
||||||
public virtual async Task<string> 查询实际电压(CancellationToken ct = default)
|
public virtual async Task<double> 查询实际电压(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
return await WriteReadAsync($"MEASure:VOLTage?{ScpiDelimiter}", ScpiDelimiter, ct);
|
string response = await WriteReadAsync($"MEASure:VOLTage?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return ParseResponseWithUnit(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -279,9 +302,10 @@ namespace DeviceCommand.Devices
|
|||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>实时测量电流值 (单位: A)</returns>
|
/// <returns>实时测量电流值 (单位: A)</returns>
|
||||||
[Monitorable("高压直流负载电流")]
|
[Monitorable("高压直流负载电流")]
|
||||||
public virtual async Task<string> 查询实际电流(CancellationToken ct = default)
|
public virtual async Task<double> 查询实际电流(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
return await WriteReadAsync($"MEASure:CURRent?{ScpiDelimiter}", ScpiDelimiter, ct);
|
string response = await WriteReadAsync($"MEASure:CURRent?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return ParseResponseWithUnit(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -290,9 +314,10 @@ namespace DeviceCommand.Devices
|
|||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>实时测量功率值 (单位: W)</returns>
|
/// <returns>实时测量功率值 (单位: W)</returns>
|
||||||
[Monitorable("高压直流负载功率")]
|
[Monitorable("高压直流负载功率")]
|
||||||
public virtual async Task<string> 查询实际功率(CancellationToken ct = default)
|
public virtual async Task<double> 查询实际功率(CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
return await WriteReadAsync($"MEASure:POWer?{ScpiDelimiter}", ScpiDelimiter, ct);
|
string response = await WriteReadAsync($"MEASure:POWer?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return ParseResponseWithUnit(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -650,16 +675,22 @@ namespace DeviceCommand.Devices
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>当前放电已持续时间 (单位: s)</returns>
|
/// <returns>当前放电已持续时间 (单位: s)</returns>
|
||||||
public virtual async Task<string> 查询放电实时时间(CancellationToken ct = default)
|
public virtual async Task<double> 查询放电实时时间(CancellationToken ct = default)
|
||||||
=> await WriteReadAsync($"DISCHarge:ECHO:TIMe?{ScpiDelimiter}", ScpiDelimiter, ct);
|
{
|
||||||
|
string response = await WriteReadAsync($"DISCHarge:ECHO:TIMe?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return ParseResponseWithUnit(response);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查询放电实时容量
|
/// 查询放电实时容量
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>当前放电已输出的容量 (单位: Ah)</returns>
|
/// <returns>当前放电已输出的容量 (单位: Ah)</returns>
|
||||||
public virtual async Task<string> 查询放电实时容量(CancellationToken ct = default)
|
public virtual async Task<double> 查询放电实时容量(CancellationToken ct = default)
|
||||||
=> await WriteReadAsync($"DISCHarge:ECHo:CAPacity?{ScpiDelimiter}", ScpiDelimiter, ct);
|
{
|
||||||
|
string response = await WriteReadAsync($"DISCHarge:ECHo:CAPacity?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return ParseResponseWithUnit(response);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置充电电流
|
/// 设置充电电流
|
||||||
@@ -734,8 +765,11 @@ namespace DeviceCommand.Devices
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>OCP测试触发时的电流值 (单位: A)</returns>
|
/// <returns>OCP测试触发时的电流值 (单位: A)</returns>
|
||||||
public virtual async Task<string> 读取OCP结果电流(CancellationToken ct = default)
|
public virtual async Task<double> 读取OCP结果电流(CancellationToken ct = default)
|
||||||
=> await WriteReadAsync($"OCP:RCURrent?{ScpiDelimiter}", ScpiDelimiter, ct);
|
{
|
||||||
|
string response = await WriteReadAsync($"OCP:RCURrent?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return ParseResponseWithUnit(response);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置OPP初始功率
|
/// 设置OPP初始功率
|
||||||
@@ -782,8 +816,11 @@ namespace DeviceCommand.Devices
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>OPP测试触发时的功率值 (单位: W)</returns>
|
/// <returns>OPP测试触发时的功率值 (单位: W)</returns>
|
||||||
public virtual async Task<string> 读取OPP结果功率(CancellationToken ct = default)
|
public virtual async Task<double> 读取OPP结果功率(CancellationToken ct = default)
|
||||||
=> await WriteReadAsync($"OPP:RPOWer?{ScpiDelimiter}", ScpiDelimiter, ct);
|
{
|
||||||
|
string response = await WriteReadAsync($"OPP:RPOWer?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return ParseResponseWithUnit(response);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -842,8 +879,11 @@ namespace DeviceCommand.Devices
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>当前扫频运行频率 (单位: Hz)</returns>
|
/// <returns>当前扫频运行频率 (单位: Hz)</returns>
|
||||||
public virtual async Task<string> 读取扫频当前运行频率(CancellationToken ct = default)
|
public virtual async Task<double> 读取扫频当前运行频率(CancellationToken ct = default)
|
||||||
=> await WriteReadAsync($"SWEEP:CFRequency?{ScpiDelimiter}", ScpiDelimiter, ct);
|
{
|
||||||
|
string response = await WriteReadAsync($"SWEEP:CFRequency?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return ParseResponseWithUnit(response);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 读取扫频测试结果
|
/// 读取扫频测试结果
|
||||||
@@ -950,8 +990,11 @@ namespace DeviceCommand.Devices
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>ESR测试结果 (单位: Ω)</returns>
|
/// <returns>ESR测试结果 (单位: Ω)</returns>
|
||||||
public virtual async Task<string> 读取ESR结果(CancellationToken ct = default)
|
public virtual async Task<double> 读取ESR结果(CancellationToken ct = default)
|
||||||
=> await WriteReadAsync($"ESR:RESult?{ScpiDelimiter}", ScpiDelimiter, ct);
|
{
|
||||||
|
string response = await WriteReadAsync($"ESR:RESult?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return ParseResponseWithUnit(response);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -994,40 +1037,55 @@ namespace DeviceCommand.Devices
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>最大功率值 (单位: W)</returns>
|
/// <returns>最大功率值 (单位: W)</returns>
|
||||||
public virtual async Task<string> 读取MPPT最大功率(CancellationToken ct = default)
|
public virtual async Task<double> 读取MPPT最大功率(CancellationToken ct = default)
|
||||||
=> await WriteReadAsync($"MPP:MPOWer?{ScpiDelimiter}", ScpiDelimiter, ct);
|
{
|
||||||
|
string response = await WriteReadAsync($"MPP:MPOWer?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return ParseResponseWithUnit(response);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 读取MPPT最大功率电压
|
/// 读取MPPT最大功率电压
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>最大功率点对应电压 (单位: V)</returns>
|
/// <returns>最大功率点对应电压 (单位: V)</returns>
|
||||||
public virtual async Task<string> 读取MPPT最大功率电压(CancellationToken ct = default)
|
public virtual async Task<double> 读取MPPT最大功率电压(CancellationToken ct = default)
|
||||||
=> await WriteReadAsync($"MPP:MVOLtage?{ScpiDelimiter}", ScpiDelimiter, ct);
|
{
|
||||||
|
string response = await WriteReadAsync($"MPP:MVOLtage?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return ParseResponseWithUnit(response);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 读取MPPT最大功率电流
|
/// 读取MPPT最大功率电流
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>最大功率点对应电流 (单位: A)</returns>
|
/// <returns>最大功率点对应电流 (单位: A)</returns>
|
||||||
public virtual async Task<string> 读取MPPT最大功率电流(CancellationToken ct = default)
|
public virtual async Task<double> 读取MPPT最大功率电流(CancellationToken ct = default)
|
||||||
=> await WriteReadAsync($"MPP:MCURrent?{ScpiDelimiter}", ScpiDelimiter, ct);
|
{
|
||||||
|
string response = await WriteReadAsync($"MPP:MCURrent?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return ParseResponseWithUnit(response);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 读取MPPT开路电压
|
/// 读取MPPT开路电压
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>开路电压值 (单位: V)</returns>
|
/// <returns>开路电压值 (单位: V)</returns>
|
||||||
public virtual async Task<string> 读取MPPT开路电压(CancellationToken ct = default)
|
public virtual async Task<double> 读取MPPT开路电压(CancellationToken ct = default)
|
||||||
=> await WriteReadAsync($"MPP:OVOLtage?{ScpiDelimiter}", ScpiDelimiter, ct);
|
{
|
||||||
|
string response = await WriteReadAsync($"MPP:OVOLtage?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return ParseResponseWithUnit(response);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 读取MPPT短路电流
|
/// 读取MPPT短路电流
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>短路电流值 (单位: A)</returns>
|
/// <returns>短路电流值 (单位: A)</returns>
|
||||||
public virtual async Task<string> 读取MPPT短路电流(CancellationToken ct = default)
|
public virtual async Task<double> 读取MPPT短路电流(CancellationToken ct = default)
|
||||||
=> await WriteReadAsync($"MPP:SCURrent?{ScpiDelimiter}", ScpiDelimiter, ct);
|
{
|
||||||
|
string response = await WriteReadAsync($"MPP:SCURrent?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return ParseResponseWithUnit(response);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Model.Models;
|
|||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@@ -22,6 +23,29 @@ namespace DeviceCommand.Devices
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从示波器返回的 SCPI 响应字符串中提取数值部分并转换为 double。
|
||||||
|
/// 响应格式示例: "C1:PAVA PKPK,2.48E-03V" → 按逗号分割后提取 2.48E-03
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="raw">示波器返回的原始字符串</param>
|
||||||
|
/// <returns>提取到的数值,解析失败时返回 0</returns>
|
||||||
|
private static double ExtractDouble(string raw)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(raw)) return 0;
|
||||||
|
|
||||||
|
string dataPart = raw;
|
||||||
|
// 按逗号分割,取最后一段(数值通常在逗号后面)
|
||||||
|
int commaIdx = raw.LastIndexOf(',');
|
||||||
|
if (commaIdx >= 0 && commaIdx < raw.Length - 1)
|
||||||
|
dataPart = raw.Substring(commaIdx + 1);
|
||||||
|
|
||||||
|
// 从数据段中提取数值(含正负号、小数点、科学计数法)
|
||||||
|
var match = Regex.Match(dataPart, @"[+-]?(?:\d+\.?\d*|\.\d+)(?:[Ee][+-]?\d+)?");
|
||||||
|
return match.Success && double.TryParse(match.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out double val)
|
||||||
|
? val
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
#region 1. IEEE 488.2 公共命令
|
#region 1. IEEE 488.2 公共命令
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -175,9 +199,10 @@ namespace DeviceCommand.Devices
|
|||||||
/// <param name="channel">通道号 (1 - 4)</param>
|
/// <param name="channel">通道号 (1 - 4)</param>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>当前电压档位值 (Volts/Div)</returns>
|
/// <returns>当前电压档位值 (Volts/Div)</returns>
|
||||||
public virtual async Task<string> 查询通道电压档位(int channel, CancellationToken ct = default)
|
public virtual async Task<double> 查询通道电压档位(int channel, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
return await WriteReadAsync($"C{channel}:VDIV?{ScpiDelimiter}", ScpiDelimiter, ct);
|
string res = await WriteReadAsync($"C{channel}:VDIV?{ScpiDelimiter}", ScpiDelimiter, ct);
|
||||||
|
return ExtractDouble(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -278,11 +303,12 @@ namespace DeviceCommand.Devices
|
|||||||
/// <param name="channel">通道号 (1 - 4)</param>
|
/// <param name="channel">通道号 (1 - 4)</param>
|
||||||
/// <param name="paramName">测量参数名称 (如 "PKPK", "FREQ", "RMS" 等)</param>
|
/// <param name="paramName">测量参数名称 (如 "PKPK", "FREQ", "RMS" 等)</param>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>测量参数的实时数值字符串</returns>
|
/// <returns>测量参数的实时数值 (double)</returns>
|
||||||
public virtual async Task<string> 查询通道测量项参数(int channel, string paramName, CancellationToken ct = default)
|
public virtual async Task<double> 查询通道测量项参数(int channel, string paramName, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
string query = string.Format(CultureInfo.InvariantCulture, "C{0}:PAVA? {1}{2}", channel, paramName.ToUpper(), ScpiDelimiter);
|
string query = string.Format(CultureInfo.InvariantCulture, "C{0}:PAVA? {1}{2}", channel, paramName.ToUpper(), ScpiDelimiter);
|
||||||
return await WriteReadAsync(query, ScpiDelimiter, ct);
|
string res = await WriteReadAsync(query, ScpiDelimiter, ct);
|
||||||
|
return ExtractDouble(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -291,7 +317,7 @@ namespace DeviceCommand.Devices
|
|||||||
/// <param name="channel">通道号 (1 - 4)</param>
|
/// <param name="channel">通道号 (1 - 4)</param>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>电压峰峰值 (Vpp)</returns>
|
/// <returns>电压峰峰值 (Vpp)</returns>
|
||||||
public virtual async Task<string> 查询实际电压峰峰值(int channel, CancellationToken ct = default)
|
public virtual async Task<double> 查询实际电压峰峰值(int channel, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
return await 查询通道测量项参数(channel, "PKPK", ct);
|
return await 查询通道测量项参数(channel, "PKPK", ct);
|
||||||
}
|
}
|
||||||
@@ -302,7 +328,7 @@ namespace DeviceCommand.Devices
|
|||||||
/// <param name="channel">通道号 (1 - 4)</param>
|
/// <param name="channel">通道号 (1 - 4)</param>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>频率值 (单位: Hz)</returns>
|
/// <returns>频率值 (单位: Hz)</returns>
|
||||||
public virtual async Task<string> 查询实际频率(int channel, CancellationToken ct = default)
|
public virtual async Task<double> 查询实际频率(int channel, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
return await 查询通道测量项参数(channel, "FREQ", ct);
|
return await 查询通道测量项参数(channel, "FREQ", ct);
|
||||||
}
|
}
|
||||||
@@ -313,7 +339,7 @@ namespace DeviceCommand.Devices
|
|||||||
/// <param name="channel">通道号 (1 - 4)</param>
|
/// <param name="channel">通道号 (1 - 4)</param>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>真均方根电压值 (Vrms)</returns>
|
/// <returns>真均方根电压值 (Vrms)</returns>
|
||||||
public virtual async Task<string> 查询实际电压均方根(int channel, CancellationToken ct = default)
|
public virtual async Task<double> 查询实际电压均方根(int channel, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
return await 查询通道测量项参数(channel, "RMS", ct);
|
return await 查询通道测量项参数(channel, "RMS", ct);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,21 @@ namespace DeviceCommand.Devices
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 辅助方法:解析科学计数法字符串为普通 double。解析失败返回 double.NaN。
|
||||||
|
/// </summary>
|
||||||
|
private double ParseScientificResponse(string response)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(response)) return double.NaN;
|
||||||
|
|
||||||
|
// 使用 NumberStyles.Float 允许原生的科学计数法解析 (例如 "1.23E+04")
|
||||||
|
if (double.TryParse(response.Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out double result))
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return double.NaN;
|
||||||
|
}
|
||||||
|
|
||||||
#region 1. IEEE 488.2 公共命令
|
#region 1. IEEE 488.2 公共命令
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -79,7 +94,7 @@ namespace DeviceCommand.Devices
|
|||||||
/// <param name="channel">通道号/单元号</param>
|
/// <param name="channel">通道号/单元号</param>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>实时 RMS 电压值 (单位: V)</returns>
|
/// <returns>实时 RMS 电压值 (单位: V)</returns>
|
||||||
public virtual async Task<string> 查询实际电压(int channel, CancellationToken ct = default)
|
public virtual async Task<double> 查询实际电压(int channel, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
// 1. 先配置 ITEM1 为指定通道的电压有效值 (URMS)
|
// 1. 先配置 ITEM1 为指定通道的电压有效值 (URMS)
|
||||||
string setItem = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:ITEM1 URMS,{0}{1}", channel, ScpiDelimiter);
|
string setItem = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:ITEM1 URMS,{0}{1}", channel, ScpiDelimiter);
|
||||||
@@ -87,7 +102,8 @@ namespace DeviceCommand.Devices
|
|||||||
|
|
||||||
// 2. 再读取 ITEM1 的值
|
// 2. 再读取 ITEM1 的值
|
||||||
string query = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:VALue? 1{0}", ScpiDelimiter);
|
string query = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:VALue? 1{0}", ScpiDelimiter);
|
||||||
return await WriteReadAsync(query, ScpiDelimiter, ct);
|
string response = await WriteReadAsync(query, ScpiDelimiter, ct);
|
||||||
|
return ParseScientificResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -96,7 +112,7 @@ namespace DeviceCommand.Devices
|
|||||||
/// <param name="channel">通道号/单元号</param>
|
/// <param name="channel">通道号/单元号</param>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>实时 RMS 电流值 (单位: A)</returns>
|
/// <returns>实时 RMS 电流值 (单位: A)</returns>
|
||||||
public virtual async Task<string> 查询实际电流(int channel, CancellationToken ct = default)
|
public virtual async Task<double> 查询实际电流(int channel, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
// 1. 配置 ITEM1 为指定通道的电流有效值 (IRMS)
|
// 1. 配置 ITEM1 为指定通道的电流有效值 (IRMS)
|
||||||
string setItem = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:ITEM1 IRMS,{0}{1}", channel, ScpiDelimiter);
|
string setItem = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:ITEM1 IRMS,{0}{1}", channel, ScpiDelimiter);
|
||||||
@@ -104,7 +120,8 @@ namespace DeviceCommand.Devices
|
|||||||
|
|
||||||
// 2. 读取 ITEM1 的值
|
// 2. 读取 ITEM1 的值
|
||||||
string query = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:VALue? 1{0}", ScpiDelimiter);
|
string query = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:VALue? 1{0}", ScpiDelimiter);
|
||||||
return await WriteReadAsync(query, ScpiDelimiter, ct);
|
string response = await WriteReadAsync(query, ScpiDelimiter, ct);
|
||||||
|
return ParseScientificResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -113,7 +130,7 @@ namespace DeviceCommand.Devices
|
|||||||
/// <param name="channel">通道号/单元号</param>
|
/// <param name="channel">通道号/单元号</param>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>实时有功功率值 (单位: W)</returns>
|
/// <returns>实时有功功率值 (单位: W)</returns>
|
||||||
public virtual async Task<string> 查询实际功率(int channel, CancellationToken ct = default)
|
public virtual async Task<double> 查询实际功率(int channel, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
// 1. 配置 ITEM1 为指定通道的有功功率 (P)
|
// 1. 配置 ITEM1 为指定通道的有功功率 (P)
|
||||||
string setItem = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:ITEM1 P,{0}{1}", channel, ScpiDelimiter);
|
string setItem = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:ITEM1 P,{0}{1}", channel, ScpiDelimiter);
|
||||||
@@ -121,7 +138,8 @@ namespace DeviceCommand.Devices
|
|||||||
|
|
||||||
// 2. 读取 ITEM1 的值
|
// 2. 读取 ITEM1 的值
|
||||||
string query = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:VALue? 1{0}", ScpiDelimiter);
|
string query = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:VALue? 1{0}", ScpiDelimiter);
|
||||||
return await WriteReadAsync(query, ScpiDelimiter, ct);
|
string response = await WriteReadAsync(query, ScpiDelimiter, ct);
|
||||||
|
return ParseScientificResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -130,7 +148,7 @@ namespace DeviceCommand.Devices
|
|||||||
/// <param name="channel">通道号/单元号</param>
|
/// <param name="channel">通道号/单元号</param>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>实时频率值 (单位: Hz)</returns>
|
/// <returns>实时频率值 (单位: Hz)</returns>
|
||||||
public virtual async Task<string> 查询频率(int channel, CancellationToken ct = default)
|
public virtual async Task<double> 查询频率(int channel, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
// 1. 配置 ITEM1 为指定通道的电压频率 (FU)
|
// 1. 配置 ITEM1 为指定通道的电压频率 (FU)
|
||||||
string setItem = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:ITEM1 FU,{0}{1}", channel, ScpiDelimiter);
|
string setItem = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:ITEM1 FU,{0}{1}", channel, ScpiDelimiter);
|
||||||
@@ -138,7 +156,8 @@ namespace DeviceCommand.Devices
|
|||||||
|
|
||||||
// 2. 读取 ITEM1 的值
|
// 2. 读取 ITEM1 的值
|
||||||
string query = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:VALue? 1{0}", ScpiDelimiter);
|
string query = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:VALue? 1{0}", ScpiDelimiter);
|
||||||
return await WriteReadAsync(query, ScpiDelimiter, ct);
|
string response = await WriteReadAsync(query, ScpiDelimiter, ct);
|
||||||
|
return ParseScientificResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -147,7 +166,7 @@ namespace DeviceCommand.Devices
|
|||||||
/// <param name="channel">通道号/单元号</param>
|
/// <param name="channel">通道号/单元号</param>
|
||||||
/// <param name="ct">取消令牌</param>
|
/// <param name="ct">取消令牌</param>
|
||||||
/// <returns>功率因数值</returns>
|
/// <returns>功率因数值</returns>
|
||||||
public virtual async Task<string> 查询功率因数(int channel, CancellationToken ct = default)
|
public virtual async Task<double> 查询功率因数(int channel, CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
// 1. 配置 ITEM1 为指定通道的功率因数 (LAMBda)
|
// 1. 配置 ITEM1 为指定通道的功率因数 (LAMBda)
|
||||||
string setItem = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:ITEM1 LAMBda,{0}{1}", channel, ScpiDelimiter);
|
string setItem = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:ITEM1 LAMBda,{0}{1}", channel, ScpiDelimiter);
|
||||||
@@ -155,7 +174,8 @@ namespace DeviceCommand.Devices
|
|||||||
|
|
||||||
// 2. 读取 ITEM1 的值
|
// 2. 读取 ITEM1 的值
|
||||||
string query = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:VALue? 1{0}", ScpiDelimiter);
|
string query = string.Format(CultureInfo.InvariantCulture, ":NUMeric:NORMal:VALue? 1{0}", ScpiDelimiter);
|
||||||
return await WriteReadAsync(query, ScpiDelimiter, ct);
|
string response = await WriteReadAsync(query, ScpiDelimiter, ct);
|
||||||
|
return ParseScientificResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -287,4 +307,4 @@ namespace DeviceCommand.Devices
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,29 +120,29 @@ namespace DeviceEditModule.ViewModels
|
|||||||
|
|
||||||
#region 测量结果属性
|
#region 测量结果属性
|
||||||
|
|
||||||
private string _measuredVoltage = "—";
|
private double _measuredVoltage;
|
||||||
public string MeasuredVoltage
|
public double MeasuredVoltage
|
||||||
{
|
{
|
||||||
get => _measuredVoltage;
|
get => _measuredVoltage;
|
||||||
set => SetProperty(ref _measuredVoltage, value);
|
set => SetProperty(ref _measuredVoltage, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _measuredCurrent = "—";
|
private double _measuredCurrent;
|
||||||
public string MeasuredCurrent
|
public double MeasuredCurrent
|
||||||
{
|
{
|
||||||
get => _measuredCurrent;
|
get => _measuredCurrent;
|
||||||
set => SetProperty(ref _measuredCurrent, value);
|
set => SetProperty(ref _measuredCurrent, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _measuredPower = "—";
|
private double _measuredPower;
|
||||||
public string MeasuredPower
|
public double MeasuredPower
|
||||||
{
|
{
|
||||||
get => _measuredPower;
|
get => _measuredPower;
|
||||||
set => SetProperty(ref _measuredPower, value);
|
set => SetProperty(ref _measuredPower, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _measuredFrequency = "—";
|
private double _measuredFrequency;
|
||||||
public string MeasuredFrequency
|
public double MeasuredFrequency
|
||||||
{
|
{
|
||||||
get => _measuredFrequency;
|
get => _measuredFrequency;
|
||||||
set => SetProperty(ref _measuredFrequency, value);
|
set => SetProperty(ref _measuredFrequency, value);
|
||||||
|
|||||||
@@ -118,22 +118,22 @@ namespace DeviceEditModule.ViewModels
|
|||||||
|
|
||||||
#region 测量结果属性
|
#region 测量结果属性
|
||||||
|
|
||||||
private string _measuredVoltage = "—";
|
private double _measuredVoltage;
|
||||||
public string MeasuredVoltage
|
public double MeasuredVoltage
|
||||||
{
|
{
|
||||||
get => _measuredVoltage;
|
get => _measuredVoltage;
|
||||||
set => SetProperty(ref _measuredVoltage, value);
|
set => SetProperty(ref _measuredVoltage, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _measuredCurrent = "—";
|
private double _measuredCurrent;
|
||||||
public string MeasuredCurrent
|
public double MeasuredCurrent
|
||||||
{
|
{
|
||||||
get => _measuredCurrent;
|
get => _measuredCurrent;
|
||||||
set => SetProperty(ref _measuredCurrent, value);
|
set => SetProperty(ref _measuredCurrent, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _measuredPower = "—";
|
private double _measuredPower;
|
||||||
public string MeasuredPower
|
public double MeasuredPower
|
||||||
{
|
{
|
||||||
get => _measuredPower;
|
get => _measuredPower;
|
||||||
set => SetProperty(ref _measuredPower, value);
|
set => SetProperty(ref _measuredPower, value);
|
||||||
|
|||||||
@@ -93,22 +93,22 @@ namespace DeviceEditModule.ViewModels
|
|||||||
|
|
||||||
#region 测量结果属性
|
#region 测量结果属性
|
||||||
|
|
||||||
private string _measuredVoltage = "—";
|
private double _measuredVoltage;
|
||||||
public string MeasuredVoltage
|
public double MeasuredVoltage
|
||||||
{
|
{
|
||||||
get => _measuredVoltage;
|
get => _measuredVoltage;
|
||||||
set => SetProperty(ref _measuredVoltage, value);
|
set => SetProperty(ref _measuredVoltage, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _measuredCurrent = "—";
|
private double _measuredCurrent;
|
||||||
public string MeasuredCurrent
|
public double MeasuredCurrent
|
||||||
{
|
{
|
||||||
get => _measuredCurrent;
|
get => _measuredCurrent;
|
||||||
set => SetProperty(ref _measuredCurrent, value);
|
set => SetProperty(ref _measuredCurrent, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _measuredPower = "—";
|
private double _measuredPower;
|
||||||
public string MeasuredPower
|
public double MeasuredPower
|
||||||
{
|
{
|
||||||
get => _measuredPower;
|
get => _measuredPower;
|
||||||
set => SetProperty(ref _measuredPower, value);
|
set => SetProperty(ref _measuredPower, value);
|
||||||
|
|||||||
@@ -94,22 +94,22 @@ namespace DeviceEditModule.ViewModels
|
|||||||
|
|
||||||
#region 测量结果属性
|
#region 测量结果属性
|
||||||
|
|
||||||
private string _measuredVoltage = "—";
|
private double _measuredVoltage;
|
||||||
public string MeasuredVoltage
|
public double MeasuredVoltage
|
||||||
{
|
{
|
||||||
get => _measuredVoltage;
|
get => _measuredVoltage;
|
||||||
set => SetProperty(ref _measuredVoltage, value);
|
set => SetProperty(ref _measuredVoltage, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _measuredCurrent = "—";
|
private double _measuredCurrent;
|
||||||
public string MeasuredCurrent
|
public double MeasuredCurrent
|
||||||
{
|
{
|
||||||
get => _measuredCurrent;
|
get => _measuredCurrent;
|
||||||
set => SetProperty(ref _measuredCurrent, value);
|
set => SetProperty(ref _measuredCurrent, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _measuredPower = "—";
|
private double _measuredPower;
|
||||||
public string MeasuredPower
|
public double MeasuredPower
|
||||||
{
|
{
|
||||||
get => _measuredPower;
|
get => _measuredPower;
|
||||||
set => SetProperty(ref _measuredPower, value);
|
set => SetProperty(ref _measuredPower, value);
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using Prism.Commands;
|
|||||||
using Prism.Ioc;
|
using Prism.Ioc;
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
@@ -113,22 +112,22 @@ namespace DeviceEditModule.ViewModels
|
|||||||
|
|
||||||
#region 测量结果属性
|
#region 测量结果属性
|
||||||
|
|
||||||
private string _measuredVpp = "—";
|
private double _measuredVpp;
|
||||||
public string MeasuredVpp
|
public double MeasuredVpp
|
||||||
{
|
{
|
||||||
get => _measuredVpp;
|
get => _measuredVpp;
|
||||||
set => SetProperty(ref _measuredVpp, value);
|
set => SetProperty(ref _measuredVpp, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _measuredFrequency = "—";
|
private double _measuredFrequency;
|
||||||
public string MeasuredFrequency
|
public double MeasuredFrequency
|
||||||
{
|
{
|
||||||
get => _measuredFrequency;
|
get => _measuredFrequency;
|
||||||
set => SetProperty(ref _measuredFrequency, value);
|
set => SetProperty(ref _measuredFrequency, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _measuredRms = "—";
|
private double _measuredRms;
|
||||||
public string MeasuredRms
|
public double MeasuredRms
|
||||||
{
|
{
|
||||||
get => _measuredRms;
|
get => _measuredRms;
|
||||||
set => SetProperty(ref _measuredRms, value);
|
set => SetProperty(ref _measuredRms, value);
|
||||||
@@ -207,40 +206,30 @@ namespace DeviceEditModule.ViewModels
|
|||||||
|
|
||||||
QueryMeasurementsCommand = new DelegateCommand(async () => await Exec(async () =>
|
QueryMeasurementsCommand = new DelegateCommand(async () => await Exec(async () =>
|
||||||
{
|
{
|
||||||
// 1. 保留设备原生吐出的完整原始字符串
|
// 设备层已自动提取纯数值并返回 double
|
||||||
string rawVpp = await _device!.查询实际电压峰峰值(Channel, Ct());
|
MeasuredVpp = await _device!.查询实际电压峰峰值(Channel, Ct());
|
||||||
string rawFreq = await _device!.查询实际频率(Channel, Ct());
|
MeasuredFrequency = await _device!.查询实际频率(Channel, Ct());
|
||||||
string rawRms = await _device!.查询实际电压均方根(Channel, Ct());
|
MeasuredRms = await _device!.查询实际电压均方根(Channel, Ct());
|
||||||
|
|
||||||
// 2. 清洗数据并将科学计数法转为常规小数后赋值给 UI 属性
|
AppendLog($"C{Channel} 测量结果 → Vpp:{MeasuredVpp:0.######}V Freq:{MeasuredFrequency:0.######}Hz RMS:{MeasuredRms:0.######}V");
|
||||||
MeasuredVpp = ParseMeasurement(rawVpp);
|
|
||||||
MeasuredFrequency = ParseMeasurement(rawFreq);
|
|
||||||
MeasuredRms = ParseMeasurement(rawRms);
|
|
||||||
|
|
||||||
// 3. 在日志中同时体现设备原始报文与解析呈现值,极方便联调
|
|
||||||
AppendLog($"C{Channel} 测量原始数据 → Vpp:{rawVpp.Trim()} Freq:{rawFreq.Trim()} RMS:{rawRms.Trim()}");
|
|
||||||
AppendLog($"C{Channel} 界面呈现数值 → Vpp:{MeasuredVpp}V Freq:{MeasuredFrequency}Hz RMS:{MeasuredRms}V");
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
QueryVppCommand = new DelegateCommand(async () => await Exec(async () =>
|
QueryVppCommand = new DelegateCommand(async () => await Exec(async () =>
|
||||||
{
|
{
|
||||||
string raw = await _device!.查询实际电压峰峰值(Channel, Ct());
|
MeasuredVpp = await _device!.查询实际电压峰峰值(Channel, Ct());
|
||||||
MeasuredVpp = ParseMeasurement(raw);
|
AppendLog($"C{Channel} Vpp: {MeasuredVpp:0.######} V");
|
||||||
AppendLog($"C{Channel} Vpp: {MeasuredVpp} (Raw: {raw.Trim()})");
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
QueryFrequencyCommand = new DelegateCommand(async () => await Exec(async () =>
|
QueryFrequencyCommand = new DelegateCommand(async () => await Exec(async () =>
|
||||||
{
|
{
|
||||||
string raw = await _device!.查询实际频率(Channel, Ct());
|
MeasuredFrequency = await _device!.查询实际频率(Channel, Ct());
|
||||||
MeasuredFrequency = ParseMeasurement(raw);
|
AppendLog($"C{Channel} Freq: {MeasuredFrequency:0.######} Hz");
|
||||||
AppendLog($"C{Channel} Freq: {MeasuredFrequency} (Raw: {raw.Trim()})");
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
QueryRmsCommand = new DelegateCommand(async () => await Exec(async () =>
|
QueryRmsCommand = new DelegateCommand(async () => await Exec(async () =>
|
||||||
{
|
{
|
||||||
string raw = await _device!.查询实际电压均方根(Channel, Ct());
|
MeasuredRms = await _device!.查询实际电压均方根(Channel, Ct());
|
||||||
MeasuredRms = ParseMeasurement(raw);
|
AppendLog($"C{Channel} RMS: {MeasuredRms:0.######} V");
|
||||||
AppendLog($"C{Channel} RMS: {MeasuredRms} (Raw: {raw.Trim()})");
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
Initialize();
|
Initialize();
|
||||||
@@ -330,52 +319,6 @@ namespace DeviceEditModule.ViewModels
|
|||||||
: line + "\n" + ResponseLog;
|
: line + "\n" + ResponseLog;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 清洗示波器原始返回的测量字符串(例如 "C1:PAVA RMS,5.57E-03V")并安全转化为无科学计数法的小数形式。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="rawResponse">设备原始应答数据</param>
|
|
||||||
/// <returns>可直接绑定到 UI 呈现的字符串数字</returns>
|
|
||||||
private string ParseMeasurement(string rawResponse)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(rawResponse)) return "—";
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string cleanData = rawResponse.Trim();
|
|
||||||
|
|
||||||
// 1. 斩断报头,提取逗号后面的具体内容(如 "5.57E-03V" 或 "****")
|
|
||||||
int commaIndex = cleanData.IndexOf(',');
|
|
||||||
if (commaIndex == -1) return "—";
|
|
||||||
|
|
||||||
string valStr = cleanData.Substring(commaIndex + 1);
|
|
||||||
|
|
||||||
var match = Regex.Match(valStr, @"[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?");
|
|
||||||
if (match.Success)
|
|
||||||
{
|
|
||||||
valStr = match.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 校验并拦截设备未测出时的无效星号 "****"
|
|
||||||
if (valStr.Contains("*") || string.IsNullOrWhiteSpace(valStr))
|
|
||||||
{
|
|
||||||
return "0"; // 回归为零或 "—",防止触发数据异常
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. 解析科学计数法,并重新以不带科学计数法的小数样式展开
|
|
||||||
if (double.TryParse(valStr, NumberStyles.Any, CultureInfo.InvariantCulture, out double result))
|
|
||||||
{
|
|
||||||
// "0.######" 样式会自动消除末尾无用的冗余零,并显示为普通小数(如 0.00557)
|
|
||||||
return result.ToString("0.######", CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// 捕获可能产生的边缘转换故障,保证轮询线程绝不崩溃
|
|
||||||
}
|
|
||||||
|
|
||||||
return "—";
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|||||||
@@ -101,36 +101,36 @@ namespace DeviceEditModule.ViewModels
|
|||||||
|
|
||||||
#region 测量结果属性
|
#region 测量结果属性
|
||||||
|
|
||||||
private string _measuredVoltage = "—";
|
private double _measuredVoltage;
|
||||||
public string MeasuredVoltage
|
public double MeasuredVoltage
|
||||||
{
|
{
|
||||||
get => _measuredVoltage;
|
get => _measuredVoltage;
|
||||||
set => SetProperty(ref _measuredVoltage, value);
|
set => SetProperty(ref _measuredVoltage, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _measuredCurrent = "—";
|
private double _measuredCurrent;
|
||||||
public string MeasuredCurrent
|
public double MeasuredCurrent
|
||||||
{
|
{
|
||||||
get => _measuredCurrent;
|
get => _measuredCurrent;
|
||||||
set => SetProperty(ref _measuredCurrent, value);
|
set => SetProperty(ref _measuredCurrent, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _measuredPower = "—";
|
private double _measuredPower;
|
||||||
public string MeasuredPower
|
public double MeasuredPower
|
||||||
{
|
{
|
||||||
get => _measuredPower;
|
get => _measuredPower;
|
||||||
set => SetProperty(ref _measuredPower, value);
|
set => SetProperty(ref _measuredPower, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _measuredFrequency = "—";
|
private double _measuredFrequency;
|
||||||
public string MeasuredFrequency
|
public double MeasuredFrequency
|
||||||
{
|
{
|
||||||
get => _measuredFrequency;
|
get => _measuredFrequency;
|
||||||
set => SetProperty(ref _measuredFrequency, value);
|
set => SetProperty(ref _measuredFrequency, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _measuredPowerFactor = "—";
|
private double _measuredPowerFactor;
|
||||||
public string MeasuredPowerFactor
|
public double MeasuredPowerFactor
|
||||||
{
|
{
|
||||||
get => _measuredPowerFactor;
|
get => _measuredPowerFactor;
|
||||||
set => SetProperty(ref _measuredPowerFactor, value);
|
set => SetProperty(ref _measuredPowerFactor, value);
|
||||||
@@ -196,20 +196,14 @@ namespace DeviceEditModule.ViewModels
|
|||||||
// 只修改这里:保持你原本的 5 次驱动查询调用不变,仅对读回来的科学计数法进行两位小数格式化
|
// 只修改这里:保持你原本的 5 次驱动查询调用不变,仅对读回来的科学计数法进行两位小数格式化
|
||||||
QueryAllMeasureCommand = new DelegateCommand(async () => await Exec(async () =>
|
QueryAllMeasureCommand = new DelegateCommand(async () => await Exec(async () =>
|
||||||
{
|
{
|
||||||
string rawU = await _device!.查询实际电压(Channel, Ct());
|
// 设备层已返回 double 数值
|
||||||
string rawI = await _device!.查询实际电流(Channel, Ct());
|
MeasuredVoltage = await _device!.查询实际电压(Channel, Ct());
|
||||||
string rawP = await _device!.查询实际功率(Channel, Ct());
|
MeasuredCurrent = await _device!.查询实际电流(Channel, Ct());
|
||||||
string rawF = await _device!.查询频率(Channel, Ct());
|
MeasuredPower = await _device!.查询实际功率(Channel, Ct());
|
||||||
string rawPF = await _device!.查询功率因数(Channel, Ct());
|
MeasuredFrequency = await _device!.查询频率(Channel, Ct());
|
||||||
|
MeasuredPowerFactor = await _device!.查询功率因数(Channel, Ct());
|
||||||
|
|
||||||
// 转换科学计数法格式,如果失败会自动保持原样
|
AppendLog($"CH{Channel} 测量 → U:{MeasuredVoltage:F2}V I:{MeasuredCurrent:F3}A P:{MeasuredPower:F2}W F:{MeasuredFrequency:F2}Hz PF:{MeasuredPowerFactor:F3}");
|
||||||
MeasuredVoltage = FormatToDecimal(rawU, "F2"); // 电压两位小数
|
|
||||||
MeasuredCurrent = FormatToDecimal(rawI, "F3"); // 电流通常较小,建议保留3位小数
|
|
||||||
MeasuredPower = FormatToDecimal(rawP, "F2"); // 功率两位小数
|
|
||||||
MeasuredFrequency = FormatToDecimal(rawF, "F2"); // 频率两位小数
|
|
||||||
MeasuredPowerFactor = FormatToDecimal(rawPF, "F3"); // 功率因数保留3位小数
|
|
||||||
|
|
||||||
AppendLog($"CH{Channel} 测量 → U:{MeasuredVoltage}V I:{MeasuredCurrent}A P:{MeasuredPower}W F:{MeasuredFrequency}Hz PF:{MeasuredPowerFactor}");
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
Initialize();
|
Initialize();
|
||||||
@@ -263,41 +257,6 @@ namespace DeviceEditModule.ViewModels
|
|||||||
|
|
||||||
private CancellationToken Ct() => (_cts = new CancellationTokenSource(TimeSpan.FromSeconds(10))).Token;
|
private CancellationToken Ct() => (_cts = new CancellationTokenSource(TimeSpan.FromSeconds(10))).Token;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 将科学计数法字符串转换为标准小数格式
|
|
||||||
/// </summary>
|
|
||||||
private string FormatToDecimal(string rawInput, string decimalFormat = "F2")
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(rawInput))
|
|
||||||
return "—";
|
|
||||||
|
|
||||||
// 去除可能夹杂的命令头,保留数据部分
|
|
||||||
string cleanInput = CleanResponseHeader(rawInput);
|
|
||||||
|
|
||||||
// 解析科学计数法(NumberStyles.Any 和 InvariantCulture 是关键)
|
|
||||||
if (double.TryParse(cleanInput, NumberStyles.Any, CultureInfo.InvariantCulture, out double value))
|
|
||||||
{
|
|
||||||
return value.ToString(decimalFormat, CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cleanInput;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 辅助清洗:剥离可能伴随吐回的命令头或双引号
|
|
||||||
/// </summary>
|
|
||||||
private string CleanResponseHeader(string response)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(response)) return string.Empty;
|
|
||||||
string result = response.Trim();
|
|
||||||
if (result.Contains(" "))
|
|
||||||
{
|
|
||||||
int lastSpaceIndex = result.LastIndexOf(' ');
|
|
||||||
result = result.Substring(lastSpaceIndex + 1).Trim();
|
|
||||||
}
|
|
||||||
return result.Replace("\"", "").Replace("'", "").Trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task Exec(Func<Task> action)
|
private async Task Exec(Func<Task> action)
|
||||||
{
|
{
|
||||||
if (_device == null)
|
if (_device == null)
|
||||||
|
|||||||
Reference in New Issue
Block a user