573 lines
19 KiB
C#
573 lines
19 KiB
C#
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|||
|
|
using CommunityToolkit.Mvvm.Input;
|
|||
|
|
using HME_MoistureLossMeter.Models;
|
|||
|
|
using HME_MoistureLossMeter.Services;
|
|||
|
|
using Serilog;
|
|||
|
|
using System;
|
|||
|
|
using System.Collections.ObjectModel;
|
|||
|
|
using System.Data;
|
|||
|
|
using System.Threading;
|
|||
|
|
using System.Threading.Tasks;
|
|||
|
|
using System.Windows;
|
|||
|
|
using System.Windows.Media.Media3D;
|
|||
|
|
|
|||
|
|
namespace HME_MoistureLossMeter.ViewModels
|
|||
|
|
{
|
|||
|
|
public partial class TestViewModel : ViewModelBase
|
|||
|
|
{
|
|||
|
|
private readonly IPlcService _plcService;
|
|||
|
|
private readonly IMesService _mesService;
|
|||
|
|
private readonly DeviceConfiguration _deviceConfig;
|
|||
|
|
private CancellationTokenSource _cts;
|
|||
|
|
private bool _isDataLoopRunning;
|
|||
|
|
private float _totalWaterTemp;
|
|||
|
|
private float _totalChamberTemp;
|
|||
|
|
private float _totalTidalVolume;
|
|||
|
|
private float _totalFrequency;
|
|||
|
|
private float _totalAirVolume;
|
|||
|
|
private float _totalOutletFlow;
|
|||
|
|
private int _dataSampleCount;
|
|||
|
|
|
|||
|
|
// 实时数据属性
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private float _waterTemp;
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private float _chamberTemp;
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private float _weight;
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private float _airVolume;
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private float _outletFlow;
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private int _presetHour;
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private int _presetMinute;
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private int _displayHour;
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private int _displayMinute;
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private int _displaySecond;
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private float _initialMass;
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private float _finalMass;
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private float _moistureLoss;
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private string _batchNo = "";
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private int _operatorId;
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private int _experimentId;
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private float _tidalVolume;
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private float _frequency;
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private int _breathCount;
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private float _dryAirFlow;
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private bool _isTesting;
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private bool _isHeating;
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private bool _isInhale;
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private bool _isExhale;
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private bool _isRising;
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private bool _isFalling;
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private bool _isConnected;
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private string _connectionStatus = "未连接";
|
|||
|
|
|
|||
|
|
[ObservableProperty]
|
|||
|
|
private DateTime _currentTime = DateTime.Now;
|
|||
|
|
|
|||
|
|
public ObservableCollection<HistoryRecordModel> TestRecords { get; } = new();
|
|||
|
|
|
|||
|
|
|
|||
|
|
[RelayCommand]
|
|||
|
|
private async Task MoveUp() => await ExecuteCoilCommand(ModbusTcpPlcService.COIL_UP, "上升");
|
|||
|
|
|
|||
|
|
[RelayCommand]
|
|||
|
|
private async Task MoveDown() => await ExecuteCoilCommand(ModbusTcpPlcService.COIL_DOWN, "下降");
|
|||
|
|
|
|||
|
|
[RelayCommand]
|
|||
|
|
private async Task ManualInhale() => await ExecuteCoilCommand(ModbusTcpPlcService.COIL_MANUAL_INHALE, "手动吸气");
|
|||
|
|
|
|||
|
|
[RelayCommand]
|
|||
|
|
private async Task ManualExhale() => await ExecuteCoilCommand(ModbusTcpPlcService.COIL_MANUAL_EXHALE, "手动呼气");
|
|||
|
|
|
|||
|
|
// 辅助方法
|
|||
|
|
private async Task ExecuteCoilCommand(ushort coilAddress, string commandName)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
IsBusy = true;
|
|||
|
|
await _plcService.WriteCoilAsync(coilAddress, true);
|
|||
|
|
StatusMessage = $"{commandName}已执行";
|
|||
|
|
await Task.Delay(200);
|
|||
|
|
await _plcService.WriteCoilAsync(coilAddress, false);
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
StatusMessage = $"{commandName}失败: {ex.Message}";
|
|||
|
|
Log.Error(ex, "{Command}失败", commandName);
|
|||
|
|
MessageBox.Show($"{commandName}失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
|||
|
|
}
|
|||
|
|
finally
|
|||
|
|
{
|
|||
|
|
IsBusy = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
public TestViewModel(IPlcService plcService, IMesService mesService, DeviceConfiguration deviceConfig)
|
|||
|
|
{
|
|||
|
|
_plcService = plcService;
|
|||
|
|
_mesService = mesService;
|
|||
|
|
_deviceConfig = deviceConfig;
|
|||
|
|
|
|||
|
|
// 初始化定时更新
|
|||
|
|
var timer = new System.Timers.Timer(1000);
|
|||
|
|
timer.Elapsed += (s, e) => CurrentTime = DateTime.Now;
|
|||
|
|
timer.Start();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
partial void OnIsTestingChanged(bool value)
|
|||
|
|
{
|
|||
|
|
if (value)
|
|||
|
|
{
|
|||
|
|
// 开始测试时重置数据
|
|||
|
|
_dataSampleCount = 0;
|
|||
|
|
_totalWaterTemp = 0;
|
|||
|
|
_totalChamberTemp = 0;
|
|||
|
|
_totalTidalVolume = 0;
|
|||
|
|
_totalFrequency = 0;
|
|||
|
|
_totalAirVolume = 0;
|
|||
|
|
_totalOutletFlow = 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[RelayCommand]
|
|||
|
|
private async Task Connect()
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
IsBusy = true;
|
|||
|
|
StatusMessage = "正在连接PLC...";
|
|||
|
|
await _plcService.EnsureConnectedAsync();
|
|||
|
|
IsConnected = true;
|
|||
|
|
ConnectionStatus = "已连接";
|
|||
|
|
StatusMessage = "PLC连接成功";
|
|||
|
|
Log.Information("PLC连接成功");
|
|||
|
|
|
|||
|
|
// 启动数据循环
|
|||
|
|
StartDataLoop();
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
IsConnected = false;
|
|||
|
|
ConnectionStatus = "连接失败";
|
|||
|
|
StatusMessage = $"连接失败: {ex.Message}";
|
|||
|
|
Log.Error(ex, "PLC连接失败");
|
|||
|
|
MessageBox.Show($"PLC连接失败: {ex.Message}", "错误",
|
|||
|
|
MessageBoxButton.OK, MessageBoxImage.Error);
|
|||
|
|
}
|
|||
|
|
finally
|
|||
|
|
{
|
|||
|
|
IsBusy = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[RelayCommand]
|
|||
|
|
private void Disconnect()
|
|||
|
|
{
|
|||
|
|
StopDataLoop();
|
|||
|
|
IsConnected = false;
|
|||
|
|
ConnectionStatus = "已断开";
|
|||
|
|
StatusMessage = "已断开PLC连接";
|
|||
|
|
Log.Information("PLC连接已断开");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void StartDataLoop()
|
|||
|
|
{
|
|||
|
|
if (_isDataLoopRunning) return;
|
|||
|
|
|
|||
|
|
_cts = new CancellationTokenSource();
|
|||
|
|
_isDataLoopRunning = true;
|
|||
|
|
|
|||
|
|
Task.Run(async () =>
|
|||
|
|
{
|
|||
|
|
while (!_cts.Token.IsCancellationRequested && IsConnected)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
await ReadAllData();
|
|||
|
|
await Task.Delay(_deviceConfig.UpdateIntervalMs, _cts.Token);
|
|||
|
|
}
|
|||
|
|
catch (OperationCanceledException)
|
|||
|
|
{
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
Log.Error(ex, "读取数据异常");
|
|||
|
|
StatusMessage = $"读取数据异常: {ex.Message}";
|
|||
|
|
await Task.Delay(2000);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}, _cts.Token);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void StopDataLoop()
|
|||
|
|
{
|
|||
|
|
_isDataLoopRunning = false;
|
|||
|
|
_cts?.Cancel();
|
|||
|
|
_cts?.Dispose();
|
|||
|
|
_cts = null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private async Task ReadAllData()
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
// 读取浮点数数据
|
|||
|
|
WaterTemp = await _plcService.ReadFloatAsync(ModbusTcpPlcService.ADDR_WATER_TEMP);
|
|||
|
|
ChamberTemp = await _plcService.ReadFloatAsync(ModbusTcpPlcService.ADDR_CHAMBER_TEMP);
|
|||
|
|
Weight = await _plcService.ReadFloatAsync(ModbusTcpPlcService.ADDR_WEIGHT);
|
|||
|
|
AirVolume = await _plcService.ReadFloatAsync(ModbusTcpPlcService.ADDR_AIR_VOLUME);
|
|||
|
|
OutletFlow = await _plcService.ReadFloatAsync(ModbusTcpPlcService.ADDR_OUTLET_FLOW);
|
|||
|
|
TidalVolume = await _plcService.ReadFloatAsync(ModbusTcpPlcService.ADDR_TIDAL_VOLUME);
|
|||
|
|
Frequency = await _plcService.ReadFloatAsync(ModbusTcpPlcService.ADDR_FREQUENCY);
|
|||
|
|
DryAirFlow = await _plcService.ReadFloatAsync(ModbusTcpPlcService.ADDR_DRY_AIR_FLOW);
|
|||
|
|
InitialMass = await _plcService.ReadFloatAsync(ModbusTcpPlcService.ADDR_INITIAL_MASS);
|
|||
|
|
FinalMass = await _plcService.ReadFloatAsync(ModbusTcpPlcService.ADDR_FINAL_MASS);
|
|||
|
|
MoistureLoss = await _plcService.ReadFloatAsync(ModbusTcpPlcService.ADDR_MOISTURE_LOSS);
|
|||
|
|
|
|||
|
|
// 读取整数数据
|
|||
|
|
PresetHour = await _plcService.ReadInt32Async(ModbusTcpPlcService.ADDR_PRESET_HOUR);
|
|||
|
|
PresetMinute = await _plcService.ReadInt32Async(ModbusTcpPlcService.ADDR_PRESET_MINUTE);
|
|||
|
|
DisplayHour = await _plcService.ReadInt32Async(ModbusTcpPlcService.ADDR_DISPLAY_HOUR);
|
|||
|
|
DisplayMinute = await _plcService.ReadInt32Async(ModbusTcpPlcService.ADDR_DISPLAY_MINUTE);
|
|||
|
|
DisplaySecond = await _plcService.ReadInt32Async(ModbusTcpPlcService.ADDR_DISPLAY_SECOND);
|
|||
|
|
BreathCount = await _plcService.ReadInt32Async(ModbusTcpPlcService.ADDR_BREATH_COUNT);
|
|||
|
|
OperatorId = await _plcService.ReadInt32Async(ModbusTcpPlcService.ADDR_OPERATOR_ID);
|
|||
|
|
ExperimentId = await _plcService.ReadInt32Async(ModbusTcpPlcService.ADDR_EXPERIMENT_ID);
|
|||
|
|
|
|||
|
|
// 读取字符串(批号)
|
|||
|
|
var batchRegs = await _plcService.ReadHoldingRegistersAsync(ModbusTcpPlcService.ADDR_BATCH_NO, 10);
|
|||
|
|
BatchNo = RegistersToString(batchRegs);
|
|||
|
|
|
|||
|
|
// 读取线圈状态
|
|||
|
|
IsTesting = await _plcService.ReadCoilAsync(ModbusTcpPlcService.COIL_TEST);
|
|||
|
|
IsHeating = await _plcService.ReadCoilAsync(ModbusTcpPlcService.COIL_HEAT);
|
|||
|
|
IsInhale = await _plcService.ReadCoilAsync(ModbusTcpPlcService.COIL_INHALE);
|
|||
|
|
IsExhale = await _plcService.ReadCoilAsync(ModbusTcpPlcService.COIL_EXHALE);
|
|||
|
|
IsRising = await _plcService.ReadCoilAsync(ModbusTcpPlcService.COIL_UP);
|
|||
|
|
IsFalling = await _plcService.ReadCoilAsync(ModbusTcpPlcService.COIL_DOWN);
|
|||
|
|
|
|||
|
|
// 如果正在测试,收集数据用于平均值计算
|
|||
|
|
if (IsTesting)
|
|||
|
|
{
|
|||
|
|
_dataSampleCount++;
|
|||
|
|
_totalWaterTemp += WaterTemp;
|
|||
|
|
_totalChamberTemp += ChamberTemp;
|
|||
|
|
_totalTidalVolume += TidalVolume;
|
|||
|
|
_totalFrequency += Frequency;
|
|||
|
|
_totalAirVolume += AirVolume;
|
|||
|
|
_totalOutletFlow += OutletFlow;
|
|||
|
|
|
|||
|
|
// 发送实时数据到MES
|
|||
|
|
await SendRealtimeDataToMes();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
StatusMessage = "数据读取成功";
|
|||
|
|
IsConnected = true;
|
|||
|
|
ConnectionStatus = "已连接";
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
IsConnected = false;
|
|||
|
|
ConnectionStatus = "通信异常";
|
|||
|
|
Log.Error(ex, "读取数据失败");
|
|||
|
|
throw;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private string RegistersToString(ushort[] registers)
|
|||
|
|
{
|
|||
|
|
var bytes = new byte[registers.Length * 2];
|
|||
|
|
for (int i = 0; i < registers.Length; i++)
|
|||
|
|
{
|
|||
|
|
var regBytes = BitConverter.GetBytes(registers[i]);
|
|||
|
|
bytes[i * 2] = regBytes[0];
|
|||
|
|
bytes[i * 2 + 1] = regBytes[1];
|
|||
|
|
}
|
|||
|
|
return System.Text.Encoding.ASCII.GetString(bytes).TrimEnd('\0');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private async Task SendRealtimeDataToMes()
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
var data = new RealtimeDataModel
|
|||
|
|
{
|
|||
|
|
DeviceId = _deviceConfig.DeviceId,
|
|||
|
|
Timestamp = DateTime.Now.ToString("o"),
|
|||
|
|
Realtime = new RealtimeData
|
|||
|
|
{
|
|||
|
|
WaterTemp = WaterTemp,
|
|||
|
|
ChamberTemp = ChamberTemp,
|
|||
|
|
Weight = Weight,
|
|||
|
|
AirVolume = AirVolume,
|
|||
|
|
OutletFlow = OutletFlow,
|
|||
|
|
TidalVolume = TidalVolume,
|
|||
|
|
Frequency = Frequency,
|
|||
|
|
BreathRate = BreathCount,
|
|||
|
|
DryAirFlow = DryAirFlow
|
|||
|
|
},
|
|||
|
|
Settings = new SettingsData
|
|||
|
|
{
|
|||
|
|
PresetHour = PresetHour,
|
|||
|
|
PresetMinute = PresetMinute,
|
|||
|
|
PresetSecond = DisplaySecond,
|
|||
|
|
OperatorId = OperatorId,
|
|||
|
|
BatchNo = BatchNo,
|
|||
|
|
ExperimentId = ExperimentId
|
|||
|
|
},
|
|||
|
|
Status = new StatusData
|
|||
|
|
{
|
|||
|
|
IsTesting = IsTesting,
|
|||
|
|
IsFault = false
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
await _mesService.SendRealtimeDataAsync(data);
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
Log.Error(ex, "发送实时数据到MES失败");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 测试控制命令
|
|||
|
|
[RelayCommand]
|
|||
|
|
private async Task StartTest()
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
IsBusy = true;
|
|||
|
|
await _plcService.WriteCoilAsync(ModbusTcpPlcService.COIL_TEST, true);
|
|||
|
|
StatusMessage = "测试已启动";
|
|||
|
|
Log.Information("测试启动");
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
Log.Error(ex, "启动测试失败");
|
|||
|
|
MessageBox.Show($"启动测试失败: {ex.Message}", "错误",
|
|||
|
|
MessageBoxButton.OK, MessageBoxImage.Error);
|
|||
|
|
}
|
|||
|
|
finally
|
|||
|
|
{
|
|||
|
|
IsBusy = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[RelayCommand]
|
|||
|
|
private async Task StopTest()
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
IsBusy = true;
|
|||
|
|
await _plcService.WriteCoilAsync(ModbusTcpPlcService.COIL_STOP, true);
|
|||
|
|
StatusMessage = "测试已停止";
|
|||
|
|
Log.Information("测试停止");
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
Log.Error(ex, "停止测试失败");
|
|||
|
|
MessageBox.Show($"停止测试失败: {ex.Message}", "错误",
|
|||
|
|
MessageBoxButton.OK, MessageBoxImage.Error);
|
|||
|
|
}
|
|||
|
|
finally
|
|||
|
|
{
|
|||
|
|
IsBusy = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[RelayCommand]
|
|||
|
|
private async Task Reset()
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
IsBusy = true;
|
|||
|
|
await _plcService.WriteCoilAsync(ModbusTcpPlcService.COIL_RESET, true);
|
|||
|
|
StatusMessage = "已复位";
|
|||
|
|
Log.Information("设备复位");
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
Log.Error(ex, "复位失败");
|
|||
|
|
MessageBox.Show($"复位失败: {ex.Message}", "错误",
|
|||
|
|
MessageBoxButton.OK, MessageBoxImage.Error);
|
|||
|
|
}
|
|||
|
|
finally
|
|||
|
|
{
|
|||
|
|
IsBusy = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[RelayCommand]
|
|||
|
|
private async Task Clear()
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
IsBusy = true;
|
|||
|
|
await _plcService.WriteCoilAsync(ModbusTcpPlcService.COIL_CLEAR, true);
|
|||
|
|
StatusMessage = "已清零";
|
|||
|
|
Log.Information("数据清零");
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
Log.Error(ex, "清零失败");
|
|||
|
|
MessageBox.Show($"清零失败: {ex.Message}", "错误",
|
|||
|
|
MessageBoxButton.OK, MessageBoxImage.Error);
|
|||
|
|
}
|
|||
|
|
finally
|
|||
|
|
{
|
|||
|
|
IsBusy = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[RelayCommand]
|
|||
|
|
private async Task ToggleHeat()
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
IsBusy = true;
|
|||
|
|
bool currentState = await _plcService.ReadCoilAsync(ModbusTcpPlcService.COIL_HEAT);
|
|||
|
|
await _plcService.WriteCoilAsync(ModbusTcpPlcService.COIL_HEAT, !currentState);
|
|||
|
|
StatusMessage = currentState ? "加热关闭" : "加热开启";
|
|||
|
|
Log.Information("加热切换: {State}", !currentState);
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
Log.Error(ex, "切换加热失败");
|
|||
|
|
MessageBox.Show($"切换加热失败: {ex.Message}", "错误",
|
|||
|
|
MessageBoxButton.OK, MessageBoxImage.Error);
|
|||
|
|
}
|
|||
|
|
finally
|
|||
|
|
{
|
|||
|
|
IsBusy = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[RelayCommand]
|
|||
|
|
private async Task RecordP1()
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
IsBusy = true;
|
|||
|
|
await _plcService.WriteCoilAsync(ModbusTcpPlcService.COIL_P1_RECORD, true);
|
|||
|
|
StatusMessage = "P1记录已触发";
|
|||
|
|
Log.Information("P1记录触发");
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
Log.Error(ex, "P1记录失败");
|
|||
|
|
MessageBox.Show($"P1记录失败: {ex.Message}", "错误",
|
|||
|
|
MessageBoxButton.OK, MessageBoxImage.Error);
|
|||
|
|
}
|
|||
|
|
finally
|
|||
|
|
{
|
|||
|
|
IsBusy = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[RelayCommand]
|
|||
|
|
private async Task RecordP2()
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
IsBusy = true;
|
|||
|
|
await _plcService.WriteCoilAsync(ModbusTcpPlcService.COIL_P2_RECORD, true);
|
|||
|
|
StatusMessage = "P2记录已触发";
|
|||
|
|
Log.Information("P2记录触发");
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
Log.Error(ex, "P2记录失败");
|
|||
|
|
MessageBox.Show($"P2记录失败: {ex.Message}", "错误",
|
|||
|
|
MessageBoxButton.OK, MessageBoxImage.Error);
|
|||
|
|
}
|
|||
|
|
finally
|
|||
|
|
{
|
|||
|
|
IsBusy = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
[RelayCommand]
|
|||
|
|
private async Task Print()
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
IsBusy = true;
|
|||
|
|
await _plcService.WriteCoilAsync(ModbusTcpPlcService.COIL_PRINT, true);
|
|||
|
|
StatusMessage = "打印已触发";
|
|||
|
|
Log.Information("打印触发");
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
Log.Error(ex, "打印失败");
|
|||
|
|
MessageBox.Show($"打印失败: {ex.Message}", "错误",
|
|||
|
|
MessageBoxButton.OK, MessageBoxImage.Error);
|
|||
|
|
}
|
|||
|
|
finally
|
|||
|
|
{
|
|||
|
|
IsBusy = false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void Dispose()
|
|||
|
|
{
|
|||
|
|
StopDataLoop();
|
|||
|
|
_plcService?.Dispose();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|