using Modbus.Device;
using Modbus;
using OxyPlot.Series;
using OxyPlot;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;
using OxyPlot.Axes;
using OxyPlot.Legends;
using 口罩泄露定制款;
using 睡眠呼吸暂停治疗面罩多功能测试仪.Data;
namespace ShanghaiEnvironmentalTechnology
{
///
/// Window6.xaml 的交互逻辑
///
public partial class Window6 : Window
{
DataChange c = new DataChange();
#region 寄存器/线圈地址定义(按功能分组,标注物理意义)
// 控制线圈(M代码)
private readonly ushort _OutBreathUpAddress = 0x0011; // 呼上(M17)
private readonly ushort _OutBreathDownAddress = 0x0010; // 呼下(M16)
private readonly ushort _InBreathUpAddress = 0x001E; // 吸上(M30)
private readonly ushort _InBreathDownAddress = 0x001F; // 吸下(M31)
private readonly ushort _HandInBreathUpAddress = 0x0013; // 手动吸(M19)
private readonly ushort _HandInBreathDownAddress = 0x0012; // 手动呼(M18)
private readonly ushort _BreathUpAddress = 0x002A; // 呼气校准(M42)
private readonly ushort _BreathDownAddress = 0x002B; // 吸气校准(M43)
private readonly ushort _PressCheckAddress = 41; // 压力校准(M41)
Function fc;
#endregion
#region 寄存器/线圈地址定义
// 控制线圈(D代码)
private readonly ushort _handSpeedAddress = 218; // 手动速度(D218)
//潮气量系数
private readonly ushort _moistureAddress = 3700;
//设置呼气流量系数 D1218呼流量系数
private readonly ushort _OutFowRateAddress = 1218; // 手动速度(D1218呼流量系数)
//设置吸气流量系数 D1318呼流量系数
private readonly ushort _InFowRateAddress = 1318; // 手动速度(D1318呼流量系数)
//设置压力系数 D1118
private readonly ushort _PressRateAddress = 1118; // 手动速度(D1118)
//位置
private readonly ushort _PositionAddress = 0x002A; // D42
//压力
private readonly ushort _PressAddress = 0x0BD6; // 手动速度(D3030)
//呼气流量
private readonly ushort _OutBreathAddress = 0x1398; // D5016
//吸气流量
private readonly ushort _InBreathAddress = 0x1396; // D5014
//复位
private readonly ushort _resetAddress = 0x0002; // D5014
#endregion
// 定时器(按功能分组)
private System.Timers.Timer _ReadTimer; // 实时监控数据
// Modbus通信
private TcpClient _tcpClient;
private IModbusMaster _modbusMaster;
private System.Timers.Timer resetTimer; // 启动状态实时定时器
string currentLang = LanguageManager.CurrentLanguage;
#region 统计相关
private PlotModel _plotModel;
private LineSeries _exhalationSeries;
private LineSeries _inhalationSeries;
private List _exhalationData;
private List _inhalationData;
private int _timeCounter;
#region 私有字段(编辑状态+定时器+寄存器地址)
// 编辑状态标志位(控制定时器是否更新)
private bool _isEditingHandmovement; // 手动速度
private bool _isEditingMoisture; // 潮气量系数
private bool _isEditingOutFlow; // 呼气流量系数
private bool _isEditingInFlow; // 吸气流量系数
private bool _isEditingPress; // 压力系数
// 实时读取定时器(1个定时器管理5个参数)
private System.Timers.Timer _paramReadTimer;
// 下位机寄存器地址(根据实际PLC地址修改)
//private readonly ushort _handmovementAddr = 0x0300; // 手动速度
//private readonly ushort _moistureAddr = 0x0301; // 潮气量系数
//private readonly ushort _outFlowAddr = 0x0302; // 呼气流量系数
//private readonly ushort _inFlowAddr = 0x0303; // 吸气流量系数
//private readonly ushort _pressAddr = 0x0304; // 压力系数
#endregion
private void OnResetTimerElapsed(object sender, ElapsedEventArgs e)
{
try
{
bool[] result = _modbusMaster?.ReadCoils(0x01, 3, 1);
bool isTestRunning = result != null && result.Length > 0 && result[0];
ResetBtn.Dispatcher.Invoke(() =>
{
if (isTestRunning)
{
ResetBtn.Content = "复位成功";
ResetBtn.Foreground = Brushes.LightGreen;
}
else
{
if (LanguageManager.IsEnglish)
{
// 英文逻辑
ResetBtn.Content = "Reset";
}
else if (LanguageManager.IsChinese)
{
// 中文逻辑
ResetBtn.Content = "复位";
}
//ResetBtn.Content = "复位";
ResetBtn.Foreground = Brushes.White;
}
});
}
catch (Exception ex)
{
Console.WriteLine($"读取线圈或更新UI失败:{ex.Message}");
}
}
#endregion
public Window6()
{
InitializeComponent();
InitializeModbusTcp();
InitializePlot();
StartDataUpdate();
_paramReadTimer = new System.Timers.Timer(1000) { AutoReset = true, Enabled = true };
_paramReadTimer.Elapsed += OnParamTimerElapsed; // 绑定定时读取事件
resetTimer = CreateTimer(1000, OnResetTimerElapsed);
Loaded += (s, e) => _paramReadTimer.Start();
//Hertbean();
}
#region 定时器实时读取下位机数据(核心:根据编辑状态判断是否更新UI)
private void OnParamTimerElapsed(object sender, ElapsedEventArgs e)
{
// 1. 手动速度(焦点不在时更新)
if (!_isEditingHandmovement)
{
ReadAndUpdateParam(
address: _handSpeedAddress,
isFloat: true,
updateAction: (value) => UpdateTextBox(handmovementTxt, value.ToString())
);
}
// 2. 潮气量系数
if (!_isEditingMoisture)
{
ReadAndUpdateParam(
address: _moistureAddress,
isFloat: true,
updateAction: (value) => UpdateTextBox(moistureTxt, value.ToString())
);
}
// 3. 呼气流量系数
if (!_isEditingOutFlow)
{
ReadAndUpdateParam(
address: _OutFowRateAddress,
isFloat: true,
updateAction: (value) => UpdateTextBox(OutFowRateTxt, value.ToString())
);
}
// 4. 吸气流量系数
if (!_isEditingInFlow)
{
ReadAndUpdateParam(
address: _InFowRateAddress,
isFloat: true,
updateAction: (value) => UpdateTextBox(InFowRateTxt, value.ToString())
);
}
// 5. 压力系数
if (!_isEditingPress)
{
ReadAndUpdateParam(
address: _PressRateAddress,
isFloat: true,
updateAction: (value) => UpdateTextBox(PressRateTxt, value.ToString())
);
}
}
#endregion
// 读取下位机参数通用方法
private void ReadAndUpdateParam(ushort address, bool isFloat, Action