Files
VacuumPressureMembranePoreS…/ViewModels/BubblePointViewModel.cs
2026-04-09 21:43:30 +08:00

401 lines
13 KiB
C#

using MembranePoreTester.Communication;
using MembranePoreTester.Helpers;
using MembranePoreTester.Models;
using Microsoft.Win32;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;
namespace MembranePoreTester.ViewModels
{
public class BubblePointViewModel : ViewModelBase
{
private BubblePointRecord _record = new();
private TestLiquid _selectedLiquid;
private bool _isCustomLiquid;
private double _customSurfaceTension = 30.0;
// 添加字段
private readonly IPlcService _plcService;
private readonly PlcConfiguration _plcConfig;
public ICommand ReadPlcCommand { get; }
public BubblePointRecord Record
{
get => _record;
set => SetProperty(ref _record, value);
}
// 初始化,确保 StationId 在读取PLC前已设置
public void Initialize(int stationId)
{
StationId = stationId;
// 延迟读取当前PLC值以确保连接稳定
Task.Run(async () =>
{
await Task.Delay(200);
await ReadCurrentPlcAsync();
await ReadSpeedRateAsync();
});
}
public List<TestLiquid> Liquids => TestLiquid.Predefined;
public List<string> PressureUnits => new() { "Pa", "cmHg", "psi" };
public List<string> MembraneTypes => new() { "平板膜", "中空纤维膜" };
public TestLiquid SelectedLiquid
{
get => _selectedLiquid;
set
{
if (SetProperty(ref _selectedLiquid, value))
{
Record.Liquid = value;
OnPropertyChanged(nameof(Record.MaxPoreSize));
}
}
}
public bool IsCustomLiquid
{
get => _isCustomLiquid;
set
{
if (SetProperty(ref _isCustomLiquid, value))
{
UpdateCustomLiquid();
}
}
}
public double CustomSurfaceTension
{
get => _customSurfaceTension;
set
{
if (SetProperty(ref _customSurfaceTension, value))
{
UpdateCustomLiquid();
}
}
}
private void UpdateCustomLiquid()
{
if (IsCustomLiquid)
{
Record.Liquid = new TestLiquid
{
Name = "自定义",
SurfaceTension = CustomSurfaceTension
};
OnPropertyChanged(nameof(Record.MaxPoreSize));
}
}
public ICommand CalculateCommand { get; }
public ICommand GenerateReportCommand { get; }
public ICommand OpenPressureCalibCommand { get; }
public ICommand OpenPressureCalibCommand2 { get; }
private System.Windows.Threading.DispatcherTimer _timer; // 添加定时器字段
public BubblePointViewModel()
{
if (IsInDesignMode())
{
return; // 设计时跳过PLC初始化
}
_plcService = App.PlcService;
_plcConfig = App.PlcConfig;
CalculateCommand = new RelayCommand(Calculate);
GenerateReportCommand = new RelayCommand(GenerateReport);
SelectedLiquid = Liquids[0];
ReadPlcCommand = new RelayCommand(async () => await ReadPlcAsync());
SaveCommand = new RelayCommand(SaveToDatabase);
ExportCommand = new RelayCommand(ExportToExcel);
OpenPressureCalibCommand = new RelayCommand(OpenPressureCalibration);
OpenPressureCalibCommand2 = new RelayCommand(OpenPressureCalibration2);
// 启动定时器,每秒读取一次
_timer = new System.Windows.Threading.DispatcherTimer();
_timer.Interval = TimeSpan.FromSeconds(1);
_timer.Tick += async (s, e) =>
{
if (StationId > 0 && !IsDisposed)
{
await ReadCurrentPlcAsync();
await ReadSpeedRateAsync(); // 新增:读取加压速率
}
};
_timer.Start();
//// 立即读取一次
//Task.Run(async () =>
//{
// await Task.Delay(1000); // 等待2秒确保PLC连接稳定
// await ReadCurrentPlcAsync();
//}
//);
}
// 新增:读取加压速率并赋值给 Record.SpeedRate1
private async Task ReadSpeedRateAsync()
{
try
{
float speedRate = 0;
ushort address = 0;
switch (StationId)
{
case 1:
address = _plcConfig.HPCoeff11;
speedRate = await _plcService.ReadFloatAsync(address);
Record.SpeedRate1 = speedRate.ToString("F3");
break;
case 2:
address = _plcConfig.HPCoeff12;
speedRate = await _plcService.ReadFloatAsync(address);
Record.SpeedRate1 = speedRate.ToString("F3");
break;
case 3:
address = _plcConfig.HPCoeff13;
speedRate = await _plcService.ReadFloatAsync(address);
Record.SpeedRate1 = speedRate.ToString("F3");
break;
}
OnPropertyChanged(nameof(Record));
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"读取加压速率失败: {ex.Message}");
}
}
public override void Dispose()
{
_timer?.Stop();
base.Dispose();
}
private async Task ReadCurrentPlcAsync()
{
await SafeExecuteAsync("ReadCurrentPressure", async () =>
{
if (IsDisposed || _plcService == null) return;
await Task.Delay(100); // 小延迟避免过快读取
float rawPressure = await _plcService.ReadPressureAsync(StationId);
Record.BubbleCurrentPressure = Math.Round(rawPressure, 2);
OnPropertyChanged(nameof(Record.BubbleCurrentPressure));
});
}
private async Task ReadPlcAsync()
{
try
{
double rawPressure = await _plcService.ReadPressureAsync(StationId);
rawPressure = Math.Round((double)rawPressure, 2);
double pressure = rawPressure * _plcConfig.PressureFactor;
// 更新当前压力显示
Record.BubbleCurrentPressure = pressure;
// 同时将泡点压力设为该值(符合涨破测试逻辑)
Record.BubblePointPressure = pressure;
OnPropertyChanged(nameof(Record.BubblePointPressure));
OnPropertyChanged(nameof(Record.BubbleCurrentPressure));
}
catch (Exception ex)
{
MessageBox.Show($"读取PLC失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
public double MaxPoreSize => Record.MaxPoreSize;
private void Calculate()
{
// 触发最大孔径重新计算(通过绑定已自动刷新)
OnPropertyChanged(nameof(Record.MaxPoreSize));
}
private void GenerateReport()
{
ReportGenerator.GenerateBubblePointReport(Record);
}
public void UpdateBubblePointPressure(double pressure)
{
Record.BubblePointPressure = pressure;
OnPropertyChanged(nameof(Record.BubblePointPressure));
OnPropertyChanged(nameof(MaxPoreSize)); // 最大孔径依赖于压力
}
private int _stationId;
public int StationId
{
get => _stationId;
set => SetProperty(ref _stationId, value);
}
// 保存当前记录到数据库
public void SaveToDatabase()
{
var entity = new BubblePointEntity
{
StationId = StationId,
TestDate = Record.TestDate,
Tester = Record.Tester ?? "系统操作员",
SampleType = Record.SampleType ?? "缺省值",
SampleSpec = Record.SampleSpec ?? "缺省值",
RoomTemperature = Record.RoomTemperature,
SoakingTime = Record.SoakingTime,
LiquidName = Record.Liquid?.Name ?? "缺省值",
LiquidSurfaceTension = Record.Liquid?.SurfaceTension ?? 0,
LiquidManufacturer = Record.LiquidManufacturer,
BubblePointPressure = Record.BubblePointPressure,
PressureUnit = Record.PressureUnit,
MaxPoreSize = Record.MaxPoreSize
};
using var db = new AppDbContext();
db.BubblePointRecords.Add(entity);
db.SaveChanges();
}
public void LoadFromDatabase(int recordId)
{
using var db = new AppDbContext();
var entity = db.BubblePointRecords.Find(recordId);
if (entity == null) return;
Record.SampleType = entity.SampleType;
Record.SampleSpec = entity.SampleSpec;
Record.RoomTemperature = entity.RoomTemperature ?? 0;
Record.SoakingTime = entity.SoakingTime ?? 0;
Record.Liquid = TestLiquid.Predefined.FirstOrDefault(l => l.Name == entity.LiquidName)
?? new TestLiquid { Name = entity.LiquidName, SurfaceTension = entity.LiquidSurfaceTension ?? 0 };
Record.LiquidManufacturer = entity.LiquidManufacturer;
Record.BubblePointPressure = entity.BubblePointPressure ?? 0;
Record.PressureUnit = entity.PressureUnit;
Record.TestDate = entity.TestDate;
Record.Tester = entity.Tester;
OnPropertyChanged(nameof(Record));
OnPropertyChanged(nameof(MaxPoreSize)); // 触发界面更新
}
public ICommand SaveCommand { get; }
public ICommand ExportCommand { get; }
private void OpenPressureCalibration()
{
ushort address = new ushort();
switch (StationId)
{
case 1:
{
address = _plcConfig.High1;
break;
}
case 2:
{
address = _plcConfig.High2;
break;
}
case 3:
{
address = _plcConfig.High3;
break;
}
}
Task.Run(async () =>
{
await _plcService.WriteCoilAsync(address, true);
});
}
private void OpenPressureCalibration2()
{
ushort address = new ushort();
switch (StationId)
{
case 1:
{
address = _plcConfig.Low1;
break;
}
case 2:
{
address = _plcConfig.Low2;
break;
}
case 3:
{
address = _plcConfig.Low3;
break;
}
}
Task.Run(async () =>
{
await _plcService.WriteCoilAsync(address, true);
});
}
private void ExportToExcel()
{
var saveFileDialog = new SaveFileDialog
{
Filter = "Excel文件|*.xlsx",
FileName = $"泡点法_工位{StationId}_{DateTime.Now:yyyyMMddHHmmss}.xlsx"
};
if (saveFileDialog.ShowDialog() == true)
{
// 将 Record 转换为 Entity
var entity = new BubblePointEntity
{
StationId = this.StationId,
TestDate = Record.TestDate,
Tester = Record.Tester,
SampleType = Record.SampleType,
SampleSpec = Record.SampleSpec,
RoomTemperature = Record.RoomTemperature,
SoakingTime = Record.SoakingTime,
LiquidName = Record.Liquid?.Name,
LiquidSurfaceTension = Record.Liquid?.SurfaceTension,
LiquidManufacturer = Record.LiquidManufacturer,
BubblePointPressure = Record.BubblePointPressure,
PressureUnit = Record.PressureUnit,
MaxPoreSize = Record.MaxPoreSize
};
ExportHelper.ExportBubblePoint(entity, saveFileDialog.FileName);
MessageBox.Show("导出成功");
}
}
}
}