Files
VacuumPressureMembranePoreS…/ViewModels/MainViewModel.cs
2026-03-28 16:48:41 +08:00

307 lines
10 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 MembranePoreTester.Communication;
using System.Collections.ObjectModel;
using System.ComponentModel; // 用于 PropertyChanged
using System.Net;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using static OfficeOpenXml.ExcelErrorValue;
namespace MembranePoreTester.ViewModels
{
public class MainViewModel : ViewModelBase
{
public ObservableCollection<StationItem> Stations { get; } = new();
public class PressureModeItem
{
public string Text { get; set; }
public int Value { get; set; }
public override string ToString()
{
return Text; // 直接返回要显示的文本
}
}
public class StationItem : ViewModelBase
{
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 ?? "低压"));
}
}
}
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
{
get => _selectedPressureMode?.Text ?? "低压";
set
{
var mode = PressureModeList.FirstOrDefault(m => m.Text == value);
if (mode != null)
{
SelectedPressureMode = mode;
}
}
}
public string PressButtonText
{
get => _pressButtonText;
set => SetProperty(ref _pressButtonText, value);
}
public bool EnableStatus
{
get => _enableStatus;
private set
{
if (SetProperty(ref _enableStatus, value))
{
// 当 EnableStatus 变化时,通知依赖的属性也变化
OnPropertyChanged(nameof(EnableStatusText));
OnPropertyChanged(nameof(EnableStatusColor));
}
}
}
// 使能状态显示文本
public string EnableStatusText => EnableStatus ? "运行中" : "未启动";
// 使能状态显示颜色(绿色表示运行中,灰色表示未启动)
// 使能状态显示颜色(更亮的颜色)
public string EnableStatusColor => EnableStatus ? "#00FF00" : "#FF3333";
// 定时器,用于轮询 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; } // 备用,但可以使用复选框直接绑定
public StationItem()
{
if (IsInDesignMode())
{
return; // 设计时跳过PLC初始化
}
_plcService = App.PlcService;
_plcConfig = App.PlcConfig;
PressCommand = new RelayCommand(async () => await TogglePressAsync());
// 在 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);
});
// 启动定时器,每秒读取一次 M21 状态
_timer = new System.Windows.Threading.DispatcherTimer();
_timer.Interval = TimeSpan.FromSeconds(1);
_timer.Tick += async (s, e) => await ReadEnableStatusAsync();
_timer.Start();
// 延迟2秒后读取确保连接稳定
Task.Delay(2000).ContinueWith(async _ =>
{
await ReadPressureModeAsync();
}, TaskScheduler.Default);
}
private async Task ReadPressureModeAsync()
{
await SafeExecuteAsync($"ReadPressureModeAsync{StationId}", async () =>
{
try
{
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}");
}
});
}
private async Task TogglePressAsync()
{
try
{
// 先读取PLC当前的加压状态
bool currentStatus = await _plcService.ReadCoilAsync(_plcConfig.PressCoil);
// 切换状态
_isPressing = !currentStatus;
// 写入新状态到PLC
await WriteCoilAsync(_plcConfig.PressCoil, _isPressing);
// 更新按钮文字
PressButtonText = _isPressing ? "停止加压" : "加压";
}
catch (Exception ex)
{
MessageBox.Show($"读取加压状态失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
// 在 StationItem 类中添加字段
private bool _lastEnableReadFailed = false;
private DateTime _lastEnableErrorTime = DateTime.MinValue;
private async Task ReadEnableStatusAsync()
{
await SafeExecuteAsync($"ReadEnableStatus_Station{StationId}", async () =>
{
try
{
bool status = await _plcService.ReadCoilAsync(_plcConfig.EnableCoil); // 读取 M21
EnableStatus = status;
bool pressStatus = await _plcService.ReadCoilAsync(_plcConfig.PressCoil);//这里也要更新加压的按钮状态
_isPressing = pressStatus;
// 在UI线程更新按钮文字
Application.Current.Dispatcher.Invoke(() =>
{
PressButtonText = pressStatus ? "停止加压" : "加压";
});
}
catch (Exception ex)
{
// 读取出错时保持原状态或显示错误
System.Diagnostics.Debug.WriteLine($"读取使能状态失败: {ex.Message}");
}
});
}
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)
{
if (IsDisposed) return;
ushort val = mode.ToString().Contains("高压") ? (ushort)0 : (ushort)1;
try
{
await _plcService.WriteSingleRegisterAsync(_plcConfig.PressureModeRegister, val);
}
catch (Exception ex)
{
MessageBox.Show($"写压力模式失败: {ex.Message}");
}
}
private bool _isPoreDistributionActive;
public bool IsPoreDistributionActive
{
get => _isPoreDistributionActive;
set => SetProperty(ref _isPoreDistributionActive, value);
}
}
public MainViewModel()
{
for (int i = 1; i <= 3; i++)
{
var station = new StationItem
{
Name = $"工位 {i}",
BubblePointVM = new BubblePointViewModel { StationId = i },
PoreDistributionVM = new PoreDistributionViewModel { StationId = i },
StationId = i
};
Stations.Add(station);
}
}
}
}