干度2的计算和多日期历史数据的选择的增加

This commit is contained in:
2025-11-27 18:09:57 +08:00
parent b9085c4a93
commit 231801ccc3
4 changed files with 262 additions and 42 deletions

View File

@@ -93,12 +93,19 @@ namespace CapMachine.Wpf.Services
{
LiqRefFlowTag = LiqRefFlowShortTag!;
}
//kg/h
if (TagManager.TryGetShortTagByName("冷媒流量[kg/h]", out ShortValueTag? VRVShortTag))
{
VRVTag = VRVShortTag!;
}
//润滑油流量
if (TagManager.TryGetShortTagByName("润滑油流量[kg/h]", out ShortValueTag? LubeFlowShortTag))
{
LubeFlowTag = LubeFlowShortTag!;
}
// 气路阀前 P/T用于质量流量加权混合焓的计算LabVIEW 流程)
if (TagManager.TryGetShortTagByName("气路阀前压力[BarA]", out ShortValueTag? gasPreP))
{
@@ -185,6 +192,15 @@ namespace CapMachine.Wpf.Services
/// </summary>
public ShortValueTag DrynessTag { get; set; }
private double _DrynessTag2Value;
/// <summary>
/// 干度2无量纲 [-]
/// </summary>
public double DrynessTag2Value
{
get { return _DrynessTag2Value; }
set { _DrynessTag2Value = value; RaisePropertyChanged(); }
}
/// <summary>
/// 气路阀前压力BarA
@@ -207,6 +223,10 @@ namespace CapMachine.Wpf.Services
/// </summary>
public ShortValueTag LiqRefFlowTag { get; set; }
/// <summary>
/// 润滑油流量kg/h
/// </summary>
public ShortValueTag LubeFlowTag { get; set; }
/// <summary>
/// 风量数据-乘以系数的后的最终结果
@@ -274,7 +294,7 @@ namespace CapMachine.Wpf.Services
p1 = (TxvFrPressTag.PVModel.EngValue) * 100.0;// 保持你原有流程
//p1 = Convert.ToDouble(textBox3.Text) * 1000.0;//textBox3 Evap.膨胀阀前压力Mpa
// 统一放入同一把锁中,避免并发导致的 Fortran 读文件/状态竞态
// 统一放入同一把锁中,避免并发导致的 Fortran 读文件/状态竞态
string herr = new string(' ', 255); long herrLen = 255; iErr = 0;
lock (_refpropLock)
{
@@ -373,6 +393,26 @@ namespace CapMachine.Wpf.Services
// 处理 err
}
//计算干度2
// 气相焓 h_vap_kJkg由 TPRHO 气相 + THERM
// 液相焓 h_liq_kJkg由 TPRHO 液相 + THERM
// 饱和液 / 气焓 h_l / h_v由 SATP +THERM
//气/液质量流量 mg/ml
if (TryComputeDrynessByEnthalpy2(
Gas_kJkgK, Liquid_kJkg,//气相质量焓 h vap [k/kg] 液相质量焓 h liq [kJ/kg]
GasFlowKgPerH, LubeFlowTag.PVModel.EngValue, //气体质量流量 mg [kg/h] 润滑油流量
LiqRefFlowTag.PVModel.EngValue,// 液体质量流量 ml [kg/h]
Liquid_h_liq, Gas_h_vap, //饱和液质量焓 h liq [kJ/kg] 饱和气质量焓 h vap [kJ/kg]
out var GasValue2, out var hMix2, out var err2))
{
// x 为最终干度 [0..1]hMix 为混合后比焓
DrynessTag2Value = GasValue2 * 100.0;
}
else
{
// 处理 err2
}
}
catch (Exception ex)
{
@@ -902,5 +942,89 @@ namespace CapMachine.Wpf.Services
return true;
}
/// <summary>
/// 按图片的最终流程计算干度2
/// 干度2的计算临时用作为对比使用
/// 1) 质量流量加权混合焓 h_mix = (h_vap*mg + h_liq*ml) / (mg + ml)
/// 2) 干度 x = (h_mix - h_l) / (h_v - h_l),并限幅到 [0,1]
///
/// 入参单位:
/// - hVap_kJkg, hLiq_kJkg, hSatL_kJkg, hSatV_kJkg 均为 kJ/kg
/// - mGas_kg_h, mLiq_kg_h 均为 kg/h
/// 返回true 表示成功,输出 x∈[0,1] 与 h_mixfalse 返回 error
/// </summary>
/// <param name="hVap_kJkg">气相质量焓 h_vap [kJ/kg]</param>
/// <param name="hLiq_kJkg">液相质量焓 h_liq [kJ/kg]</param>
/// <param name="mGas_kg_h">气体质量流量 mg [kg/h]</param>
/// <param name="mLiq_kg_h">液体质量流量 ml [kg/h]</param>
/// <param name="hSatL_kJkg">饱和液质量焓 h_l [kJ/kg]</param>
/// <param name="hSatV_kJkg">饱和气质量焓 h_v [kJ/kg]</param>
/// <param name="dryness">输出干度 x ∈ [0,1]</param>
/// <param name="hMix_kJkg">输出混合后总比焓 h_mix [kJ/kg]</param>
/// <param name="error">Err</param>
/// <returns></returns>
public bool TryComputeDrynessByEnthalpy2(
double hVap_kJkg, // 气相质量焓 h_vap [kJ/kg]
double hLiq_kJkg, // 液相质量焓 h_liq [kJ/kg]
double mGas_kg_h, // 气体质量流量 mg [kg/h]
double lubeFlow_kg_h, // 润滑油流量 mg [kg/h]
double mLiq_kg_h, // 液体质量流量 ml [kg/h]
double hSatL_kJkg, // 饱和液质量焓 h_l [kJ/kg]
double hSatV_kJkg, // 饱和气质量焓 h_v [kJ/kg]
out double dryness, // 输出干度 x ∈ [0,1]
out double hMix_kJkg, // 输出混合后总比焓 h_mix [kJ/kg]
out string error)
{
dryness = double.NaN;
hMix_kJkg = double.NaN;
error = string.Empty;
// 1) 合法性校验
if (double.IsNaN(hVap_kJkg) || double.IsNaN(hLiq_kJkg) || double.IsNaN(hSatL_kJkg) || double.IsNaN(hSatV_kJkg))
{
error = "输入焓值存在 NaN";
return false;
}
if (double.IsNaN(mGas_kg_h) || double.IsNaN(mLiq_kg_h))
{
error = "输入质量流量存在 NaN";
return false;
}
// 负值处理:小于 0 视为 0避免传感器噪声或符号错误影响
//double mg1 = Math.Max(0.0, mGas_kg_h);
double mg = Math.Max(0.0, mGas_kg_h) + Math.Max(0.0, lubeFlow_kg_h); // 这个是改动 气体流量再加上润滑油流量
double ml = Math.Max(0.0, mLiq_kg_h);
double mSum = mg + ml;
if (mSum <= 0)
{
error = "气液质量流量之和为 0无法进行加权混合焓计算";
return false;
}
// 2) 质量流量加权混合焓(严格按图片:上、下两路相加后除以总流量)
hMix_kJkg = (hVap_kJkg * mg + hLiq_kJkg * ml) / mSum;
// 3) 干度计算x = (h_mix - h_l) / (h_v - h_l)
double denom = (hSatV_kJkg - hSatL_kJkg);
const double eps = 1e-9;
if (Math.Abs(denom) < eps)
{
error = "饱和气/液焓差过小,无法计算干度(可能接近临界点或输入异常)";
return false;
}
double x = (hMix_kJkg - hSatL_kJkg) / denom;
// 4) 限幅到 [0,1]
if (double.IsNaN(x) || double.IsInfinity(x))
{
error = "干度计算结果异常NaN/Inf";
return false;
}
dryness = Math.Min(1.0, Math.Max(0.0, x));
return true;
}
}
}

View File

@@ -132,6 +132,20 @@ namespace CapMachine.Wpf.ViewModels
set { _IsLeftDrawerOpen = value; RaisePropertyChanged(); }
}
private bool _IsBusy;
public bool IsBusy
{
get { return _IsBusy; }
set { _IsBusy = value; RaisePropertyChanged(); }
}
private string _BusyMessage = "正在加载,请稍候...";
public string BusyMessage
{
get { return _BusyMessage; }
set { _BusyMessage = value; RaisePropertyChanged(); }
}
/// <summary>
@@ -417,7 +431,7 @@ namespace CapMachine.Wpf.ViewModels
/// <summary>
/// 获取试验数据的命令的执行方法
/// </summary>
private void HistoryDataFileCmdMethod()
private async void HistoryDataFileCmdMethod()
{
if (SelectedHistoryExp == null)
{
@@ -449,58 +463,82 @@ namespace CapMachine.Wpf.ViewModels
return;
}
CsvRecordModels = new List<CsvRecordModel>();
BusyMessage = "正在加载CSV数据请稍候...";
IsBusy = true;
var loaded = new List<CsvRecordModel>();
string errorText = string.Empty;
stopwatch.Start();
var errors = new StringBuilder();
foreach (var f in files)
try
{
try
await Task.Run(() =>
{
if (f == null) continue;
if (string.IsNullOrWhiteSpace(f.FilePath))
var errors = new StringBuilder();
for (int i = 0; i < files.Count; i++)
{
errors.AppendLine("发现空的文件地址");
continue;
}
if (!File.Exists(f.FilePath))
{
errors.AppendLine($"没有发现地址对应的文件: {f.FilePath}");
continue;
}
var f = files[i];
try
{
Application.Current.Dispatcher.Invoke(() =>
{
BusyMessage = $"正在加载({i + 1}/{files.Count}){System.IO.Path.GetFileName(f?.FilePath)}";
});
var rec = ReadCsvFile(f.FilePath);
if (rec != null && rec.Count > 0)
{
CsvRecordModels.AddRange(rec);
if (f == null) continue;
if (string.IsNullOrWhiteSpace(f.FilePath))
{
errors.AppendLine("发现空的文件地址");
continue;
}
if (!File.Exists(f.FilePath))
{
errors.AppendLine($"没有发现地址对应的文件: {f.FilePath}");
continue;
}
var rec = ReadCsvFile(f.FilePath);
if (rec != null && rec.Count > 0)
{
loaded.AddRange(rec);
}
}
catch (Exception ex)
{
errors.AppendLine($"读取CSV失败: {ex.Message}");
}
}
}
catch (Exception ex)
errorText = errors.ToString();
});
if (!string.IsNullOrWhiteSpace(errorText))
{
errors.AppendLine($"读取CSV失败: {ex.Message}");
System.Windows.MessageBox.Show(errorText, "读取提示", MessageBoxButton.OK, MessageBoxImage.Warning);
}
CsvRecordModels = new List<CsvRecordModel>();
if (loaded != null && loaded.Count > 0)
{
CsvRecordModels = loaded
.Where(r => r != null)
.OrderBy(r => r.CreateTime)
.ToList();
Application.Current.Dispatcher.Invoke(() =>
{
EventAggregator.GetEvent<HistoryDataToChartEvent>().Publish(new HistoryDataToChartMsg() { Machine = "History", Data = CsvRecordModels });
});
}
}
if (errors.Length > 0)
finally
{
System.Windows.MessageBox.Show(errors.ToString(), "读取提示", MessageBoxButton.OK, MessageBoxImage.Warning);
stopwatch.Stop();
Console.WriteLine("加载CSV数据耗时:{0}", stopwatch.Elapsed.TotalSeconds.ToString());
stopwatch.Reset();
IsBusy = false;
IsLeftDrawerOpen = false;
}
if (CsvRecordModels.Count > 0)
{
CsvRecordModels = CsvRecordModels
.Where(r => r != null)
.OrderBy(r => r.CreateTime)
.ToList();
EventAggregator.GetEvent<HistoryDataToChartEvent>().Publish(new HistoryDataToChartMsg() { Machine = "History", Data = CsvRecordModels });
}
stopwatch.Stop();
Console.WriteLine("加载CSV数据耗时:{0}", stopwatch.Elapsed.TotalSeconds.ToString());
stopwatch.Reset();
IsLeftDrawerOpen = false;
}
private List<CsvRecordModel> ReadCsvFile(string filePath)

View File

@@ -26,6 +26,7 @@
<Setter Property="BorderThickness" Value="0" />
<Setter Property="BorderBrush" Value="Transparent" />
</Style>
<BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter" />
</UserControl.Resources>
<materialDesign:DrawerHost
x:Name="HistoryDrawerHost"
@@ -320,9 +321,40 @@
</DataGrid.Columns>
<!-- CommandParameter="{Binding ElementName=MainDatagrid, Path=SelectedItem}" -->
</DataGrid>
<!-- 忙碌遮罩 -->
<Grid
x:Name="BusyOverlay"
Grid.Row="1"
Panel.ZIndex="999"
Background="#66000000"
Visibility="{Binding IsBusy, Converter={StaticResource BoolToVisibilityConverter}}">
<Border
Padding="16"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="White"
CornerRadius="6">
<StackPanel>
<ProgressBar
Width="220"
Height="6"
IsIndeterminate="True" />
<TextBlock
Margin="0,10,0,0"
HorizontalAlignment="Center"
FontSize="14"
Foreground="Black"
Text="{Binding BusyMessage}" />
</StackPanel>
</Border>
</Grid>
</Grid>
</Grid>
</Grid>

View File

@@ -211,7 +211,7 @@
</Grid.ColumnDefinitions>
<materialDesign:Card
Grid.ColumnSpan="6"
Grid.ColumnSpan="5"
Margin="3"
Background="{DynamicResource MaterialDesignLightBackground}"
Foreground="{DynamicResource PrimaryHueLightForegroundBrush}"
@@ -232,6 +232,32 @@
</StackPanel>
</materialDesign:Card>
<materialDesign:Card
Grid.Column="5"
Margin="3"
Background="{DynamicResource MaterialDesignLightBackground}"
Foreground="{DynamicResource PrimaryHueLightForegroundBrush}"
UniformCornerRadius="5">
<StackPanel Orientation="Horizontal">
<TextBlock
Margin="10,0,0,0"
VerticalAlignment="Center"
FontFamily="/Assets/Fonts/#iconfont"
FontSize="26"
Foreground="Blue"
Text="&#xe9f8;" />
<TextBlock
Foreground="Blue"
Style="{StaticResource TitelStyle}"
Text="干度2:" />
<TextBlock
VerticalAlignment="Center"
FontSize="26"
FontWeight="Bold"
Text="{Binding PPCService.DrynessTag2Value}" />
</StackPanel>
</materialDesign:Card>
<!--<materialDesign:Card
Grid.Column="3"
Grid.ColumnSpan="3"