Files
VacuumPressureMembranePoreS…/ViewModels/MainViewModel.cs

375 lines
12 KiB
C#
Raw Normal View History

2026-03-19 20:40:54 +08:00
using MembranePoreTester.Communication;
using System.Collections.ObjectModel;
using System.ComponentModel; // 用于 PropertyChanged
2026-03-26 19:43:52 +08:00
using System.Net;
2026-03-19 20:40:54 +08:00
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
2026-03-26 19:43:52 +08:00
using static OfficeOpenXml.ExcelErrorValue;
2026-03-02 18:50:30 +08:00
namespace MembranePoreTester.ViewModels
{
public class MainViewModel : ViewModelBase
{
public ObservableCollection<StationItem> Stations { get; } = new();
2026-03-26 21:37:34 +08:00
public class PressureModeItem
{
public string Text { get; set; }
public int Value { get; set; }
2026-03-02 18:50:30 +08:00
2026-03-26 21:37:34 +08:00
public override string ToString()
{
return Text; // 直接返回要显示的文本
}
}
2026-03-19 20:40:54 +08:00
public class StationItem : ViewModelBase
{
2026-03-26 21:37:34 +08:00
private PressureModeItem _selectedPressureMode;
private List<PressureModeItem> _pressureModeList;
public List<PressureModeItem> PressureModeList => _pressureModeList ??= new List<PressureModeItem>
{
new PressureModeItem { Text = "低压", Value = 1 },
new PressureModeItem { Text = "高压", Value = 0 }
};
public PressureModeItem SelectedPressureMode
{
get => _selectedPressureMode;
set
{
if (SetProperty(ref _selectedPressureMode, value))
{
Task.Run(async () => await WritePressureModeAsync(value?.Text ?? "低压"));
}
}
}
2026-03-19 20:40:54 +08:00
private readonly IPlcService _plcService;
private readonly PlcConfiguration _plcConfig;
private bool _isPressing;
private string _pressButtonText = "加压";
private string _highLowPressure = "低压";
private bool _enableStatus; // M21 状态
public string Name { get; set; }
public BubblePointViewModel BubblePointVM { get; set; }
public PoreDistributionViewModel PoreDistributionVM { get; set; }
public int StationId { get; set; }
public string HighLowPressure
{
2026-03-26 21:37:34 +08:00
get => _selectedPressureMode?.Text ?? "低压";
2026-03-19 20:40:54 +08:00
set
{
2026-03-26 21:37:34 +08:00
var mode = PressureModeList.FirstOrDefault(m => m.Text == value);
if (mode != null)
2026-03-19 20:40:54 +08:00
{
2026-03-26 21:37:34 +08:00
SelectedPressureMode = mode;
2026-03-19 20:40:54 +08:00
}
}
}
public string PressButtonText
{
get => _pressButtonText;
set => SetProperty(ref _pressButtonText, value);
}
public bool EnableStatus
{
get => _enableStatus;
2026-03-26 21:37:34 +08:00
private set
{
if (SetProperty(ref _enableStatus, value))
{
// 当 EnableStatus 变化时,通知依赖的属性也变化
OnPropertyChanged(nameof(EnableStatusText));
OnPropertyChanged(nameof(EnableStatusColor));
}
}
2026-03-19 20:40:54 +08:00
}
// 使能状态显示文本
public string EnableStatusText => EnableStatus ? "运行中" : "未启动";
// 使能状态显示颜色(绿色表示运行中,灰色表示未启动)
2026-03-26 21:37:34 +08:00
// 使能状态显示颜色(更亮的颜色)
public string EnableStatusColor => EnableStatus ? "#00FF00" : "#FF3333";
2026-03-19 20:40:54 +08:00
// 定时器,用于轮询 M21 状态
private System.Windows.Threading.DispatcherTimer _timer;
public ICommand PressCommand { get; }
//public ICommand BurstCommand { get; }
public ICommand StartCommand { get; }
public ICommand StopCommand { get; }
public ICommand EnableCommand { get; } // 备用,但可以使用复选框直接绑定
2026-03-26 21:37:34 +08:00
2026-04-02 10:13:01 +08:00
private double _pressureUpperLimit;
private double _pressureRate;
public double PressureUpperLimit
{
get => _pressureUpperLimit;
set
{
if (SetProperty(ref _pressureUpperLimit, value))
{
2026-04-02 14:34:29 +08:00
if (HighLowPressure == "低压")
{
if (value > 200)
{
MessageBox.Show("低压模式,加压上限不能超过200!");
return;
}
}
2026-04-02 10:13:01 +08:00
// 值改变时写入PLC
2026-04-02 14:34:29 +08:00
_ = _plcService.WriteMultipleRegistersAsync(_plcConfig.PressureUpperLimit, (float)value);
2026-04-02 10:13:01 +08:00
}
}
}
public double PressureRate
{
get => _pressureRate;
set
{
if (SetProperty(ref _pressureRate, value))
{
// 值改变时写入PLC
2026-04-02 14:34:29 +08:00
_ = _plcService.WriteMultipleRegistersAsync(_plcConfig.PressureRate, (float)value);
2026-04-02 10:13:01 +08:00
}
}
}
// 添加读取这两个参数的方法
private async Task ReadPressureParametersAsync()
{
try
{
float upperLimit = await _plcService.ReadFloatAsync(_plcConfig.PressureUpperLimit);
float rate = await _plcService.ReadFloatAsync(_plcConfig.PressureRate);
2026-04-02 14:34:29 +08:00
2026-04-02 10:13:01 +08:00
Application.Current.Dispatcher.Invoke(() =>
{
PressureUpperLimit = upperLimit;
PressureRate = rate;
});
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"读取压力参数失败: {ex.Message}");
}
}
2026-03-19 20:40:54 +08:00
public StationItem()
{
2026-03-26 21:37:34 +08:00
if (IsInDesignMode())
{
return; // 设计时跳过PLC初始化
}
2026-03-19 20:40:54 +08:00
_plcService = App.PlcService;
_plcConfig = App.PlcConfig;
PressCommand = new RelayCommand(async () => await TogglePressAsync());
2026-03-27 21:35:32 +08:00
// 在 StationItem 构造函数中
StartCommand = new RelayCommand(async () =>
{
// 启动PLC
await WriteCoilAsync(_plcConfig.StartCoil, true);
// 启动孔分布自动采集
PoreDistributionVM.StartCollecting();
});
StopCommand = new RelayCommand(async () =>
{
// 停止自动采集
PoreDistributionVM.StopCollecting();
// 停止PLC
await WriteCoilAsync(_plcConfig.StopCoil, true);
});
2026-03-19 20:40:54 +08:00
// 启动定时器,每秒读取一次 M21 状态
_timer = new System.Windows.Threading.DispatcherTimer();
_timer.Interval = TimeSpan.FromSeconds(1);
2026-04-02 14:34:29 +08:00
_timer.Tick += async (s, e) =>
2026-04-02 10:13:01 +08:00
{
await ReadEnableStatusAsync();
await ReadPressureParametersAsync(); // 新增:读取压力参数
};
2026-03-19 20:40:54 +08:00
_timer.Start();
2026-03-26 21:37:34 +08:00
// 延迟2秒后读取确保连接稳定
Task.Delay(2000).ContinueWith(async _ =>
{
await ReadPressureModeAsync();
2026-04-02 10:13:01 +08:00
await ReadPressureParametersAsync(); // 新增:读取压力参数
2026-03-26 21:37:34 +08:00
}, TaskScheduler.Default);
}
private async Task ReadPressureModeAsync()
{
2026-03-28 16:48:41 +08:00
await SafeExecuteAsync($"ReadPressureModeAsync{StationId}", async () =>
2026-03-26 21:37:34 +08:00
{
2026-03-28 16:48:41 +08:00
try
2026-03-26 21:37:34 +08:00
{
2026-03-28 16:48:41 +08:00
ushort[] values = await _plcService.ReadHoldingRegistersAsync(_plcConfig.PressureModeRegister, 1);
ushort val = values[0];
string newValue = val == 0 ? "高压" : "低压";
Application.Current.Dispatcher.Invoke(() =>
{
// 更新选中项
HighLowPressure = newValue;
});
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"读取压力模式失败: {ex.Message}");
}
});
2026-03-19 20:40:54 +08:00
}
private async Task TogglePressAsync()
{
2026-03-26 21:37:34 +08:00
try
{
// 先读取PLC当前的加压状态
bool currentStatus = await _plcService.ReadCoilAsync(_plcConfig.PressCoil);
2026-03-19 20:40:54 +08:00
2026-03-26 21:37:34 +08:00
// 切换状态
_isPressing = !currentStatus;
// 写入新状态到PLC
await WriteCoilAsync(_plcConfig.PressCoil, _isPressing);
// 更新按钮文字
PressButtonText = _isPressing ? "停止加压" : "加压";
}
catch (Exception ex)
{
MessageBox.Show($"读取加压状态失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
2026-03-28 16:48:41 +08:00
// 在 StationItem 类中添加字段
private bool _lastEnableReadFailed = false;
private DateTime _lastEnableErrorTime = DateTime.MinValue;
2026-03-19 20:40:54 +08:00
private async Task ReadEnableStatusAsync()
{
2026-03-28 16:48:41 +08:00
await SafeExecuteAsync($"ReadEnableStatus_Station{StationId}", async () =>
2026-03-19 20:40:54 +08:00
{
2026-03-28 16:48:41 +08:00
try
{
bool status = await _plcService.ReadCoilAsync(_plcConfig.EnableCoil); // 读取 M21
EnableStatus = status;
2026-03-26 21:37:34 +08:00
2026-03-28 16:48:41 +08:00
bool pressStatus = await _plcService.ReadCoilAsync(_plcConfig.PressCoil);//这里也要更新加压的按钮状态
2026-03-26 21:37:34 +08:00
2026-03-28 16:48:41 +08:00
_isPressing = pressStatus;
2026-03-26 21:37:34 +08:00
2026-03-28 16:48:41 +08:00
// 在UI线程更新按钮文字
Application.Current.Dispatcher.Invoke(() =>
{
PressButtonText = pressStatus ? "停止加压" : "加压";
});
2026-03-26 21:37:34 +08:00
2026-03-28 16:48:41 +08:00
}
catch (Exception ex)
{
// 读取出错时保持原状态或显示错误
System.Diagnostics.Debug.WriteLine($"读取使能状态失败: {ex.Message}");
}
});
2026-03-19 20:40:54 +08:00
}
private async Task WriteCoilAsync(ushort coil, bool value)
{
try
{
await _plcService.WriteCoilAsync(coil, value);
}
catch (Exception ex)
{
MessageBox.Show($"写线圈失败: {ex.Message}");
}
}
private async Task WritePressureModeAsync(string mode)
{
2026-03-26 19:43:52 +08:00
if (IsDisposed) return;
ushort val = mode.ToString().Contains("高压") ? (ushort)0 : (ushort)1;
2026-03-19 20:40:54 +08:00
try
{
2026-03-26 19:43:52 +08:00
await _plcService.WriteSingleRegisterAsync(_plcConfig.PressureModeRegister, val);
2026-03-19 20:40:54 +08:00
}
catch (Exception ex)
{
MessageBox.Show($"写压力模式失败: {ex.Message}");
}
2026-03-26 19:43:52 +08:00
2026-03-19 20:40:54 +08:00
}
2026-03-24 19:33:35 +08:00
2026-03-27 21:35:32 +08:00
private bool _isPoreDistributionActive;
public bool IsPoreDistributionActive
{
get => _isPoreDistributionActive;
set => SetProperty(ref _isPoreDistributionActive, value);
}
2026-03-24 19:33:35 +08:00
2026-03-19 20:40:54 +08:00
}
2026-03-24 19:33:35 +08:00
2026-03-02 18:50:30 +08:00
public MainViewModel()
{
2026-03-28 16:48:41 +08:00
for (int i = 1; i <= 3; i++)
2026-03-02 18:50:30 +08:00
{
2026-03-19 20:40:54 +08:00
var station = new StationItem
2026-03-02 18:50:30 +08:00
{
Name = $"工位 {i}",
BubblePointVM = new BubblePointViewModel { StationId = i },
2026-03-19 20:40:54 +08:00
PoreDistributionVM = new PoreDistributionViewModel { StationId = i },
StationId = i
};
Stations.Add(station);
2026-03-02 18:50:30 +08:00
}
}
}
}