using Microsoft.Win32;
using Modbus.Device;
using Modbus;
using OfficeOpenXml;
using System;
using System.Configuration;
using System.Data.SQLite;
using System.IO;
using System.Net.Sockets;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using 口罩泄露定制款;
using static ShanghaiEnvironmentalTechnology.Window5;
namespace ShanghaiEnvironmentalTechnology
{
///
/// 气阻测试相关参数监控窗口(Modbus通信+数据处理)
///
public partial class Window4 : Window, IDisposable
{
DataChange c = new DataChange();
#region 寄存器/线圈地址定义(按功能分组,对应物理意义)
// 基础参数地址
private readonly ushort _pressureSettingRegisterAddress = 0x013A; // 单一故障气阻设置流量(D314)
private readonly ushort _noseRegisterAddress = 0x055C; // 鼻口压力地址
private readonly ushort _modifiedNoseRegisterAddress = 0x0048; // 鼻口压力校准地址(M72)
private readonly ushort _outRegisterAddress = 120; // 呼流量地址
private readonly ushort _inRegisterAddress = 1400; // 吸流量地址
private readonly ushort _flowRegisterAddress = 0x013C; // 呼气阻力记录(D136)
private readonly ushort _flowInRegisterAddress = 0x013E; // 吸气阻力记录(D318)
private readonly ushort _BreathOutRegisterAddress = 316; // 记录呼气阻力实时显示
private readonly ushort _BreathInRegisterAddress = 318; // 记录吸气阻力实时显示
// 线圈地址(控制指令)
private readonly ushort _testStartAddress = 0x0020; // 单一故障气阻测试启动(M32)
private readonly ushort _testStopAddress = 0x0022; // 单一故障气阻测试停止(M34)
#endregion
#region 私有字段
private TcpClient _tcpClient;
private IModbusMaster _modbusMaster;
Function fc;
// 定时器
private System.Timers.Timer _outReadTimer; // 呼流量读取
private System.Timers.Timer _inReadTimer; // 吸流量读取
private System.Timers.Timer _noseReadTimer; // 鼻口压力读取
private System.Timers.Timer _settingReadTimer2; //
private System.Timers.Timer startTimer; // 启动状态实时定时器
#endregion
public Window4()
{
InitializeComponent();
InitializeModbusTcp();
Loaded += Window_Loaded;
}
#region 初始化与资源释放
///
/// 初始化Modbus连接和定时器
///
private void InitializeModbusTcp()
{
try
{
string plcIp = ConfigurationManager.AppSettings["PLC1_IP"];
int plcPort = int.Parse(ConfigurationManager.AppSettings["PLC1_Port"]);
_tcpClient = new TcpClient(plcIp, plcPort);
_modbusMaster = ModbusIpMaster.CreateIp(_tcpClient);
_modbusMaster.Transport.ReadTimeout = 3000;
_modbusMaster.Transport.WriteTimeout = 3000;
// 初始化定时器
InitializeTimers();
fc = new Function(_modbusMaster);
// 初始化数据库
InitializeDatabase();
}
catch (Exception ex)
{
ShowError($"Modbus初始化失败: {ex.Message}");
}
}
///
/// 统一初始化所有定时器
///
private void InitializeTimers()
{
_outReadTimer = CreateTimer(1000, OnOutTimerElapsed);
_inReadTimer = CreateTimer(1000, OnInTimerElapsed);
_noseReadTimer = CreateTimer(1000, OnNoseTimerElapsed);
_settingReadTimer2 = CreateTimer(1000, OnSettingReadTimerTimerElapsed2);
startTimer = CreateTimer(1000, OnStartTimerElapsed);
}
///
/// 实时流量读取定时器(修正跨线程访问UI问题)
///
private void OnStartTimerElapsed(object sender, ElapsedEventArgs e)
{
try
{
bool[] result = _modbusMaster?.ReadCoils(0x01, 33, 1);
bool isTestRunning = result != null && result.Length > 0 && result[0];
TestStartButton.Dispatcher.Invoke(() =>
{
if (isTestRunning)
{
TestStartButton.Content = "测试启动成功";
TestStartButton.Foreground = Brushes.LightGreen;
}
else
{
TestStartButton.Content = "测试启动";
TestStartButton.Foreground = Brushes.White;
}
});
}
catch (Exception ex)
{
Console.WriteLine($"读取线圈或更新UI失败:{ex.Message}");
}
}
private void OnSettingReadTimerTimerElapsed2(object sender, ElapsedEventArgs e)
{
ReadAndUpdateRegister(
_pressureSettingRegisterAddress, true,
value => UpdateSettingUI2(value.ToString())
);
}
private void UpdateSettingUI2(string value)
{
UpdateUiSafely(() =>
clostTxt.Text = IsModbusConnected() ? value : "连接断开"
);
}
///
/// 通用定时器创建方法
///
private System.Timers.Timer CreateTimer(int intervalMs, ElapsedEventHandler elapsedAction)
{
var timer = new System.Timers.Timer(intervalMs)
{
AutoReset = true,
Enabled = true
};
timer.Elapsed += elapsedAction;
return timer;
}
///
/// 释放资源
///
public void Dispose()
{
// 释放定时器
_outReadTimer?.Dispose();
_inReadTimer?.Dispose();
_noseReadTimer?.Dispose();
// 释放Modbus连接
_tcpClient?.Close();
_tcpClient?.Dispose();
_modbusMaster = null;
}
///
/// 窗口关闭时释放资源
///
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
Dispose();
}
#endregion
#region 定时器读取逻辑(寄存器读取+UI更新)
///
/// 呼流量读取定时器
///
private void OnOutTimerElapsed(object sender, ElapsedEventArgs e)
{
ReadAndUpdateRegister(
_outRegisterAddress, true,
value => UpdateOutUI(value.ToString())
);
}
///
/// 吸流量读取定时器
///
private void OnInTimerElapsed(object sender, ElapsedEventArgs e)
{
ReadAndUpdateRegister(
_inRegisterAddress, true,
value => UpdateInUI(value.ToString())
);
}
///
/// 鼻口压力读取定时器
///
private void OnNoseTimerElapsed(object sender, ElapsedEventArgs e)
{
ReadAndUpdateRegister(
_noseRegisterAddress, true,
value => UpdateNoseUI(value.ToString())
);
}
///
/// 通用寄存器读取并更新UI,支持16位整数和32位浮点数
///
/// 起始地址
/// 是否为浮点型(占用2个寄存器)
/// 更新UI的回调函数
private void ReadAndUpdateRegister(ushort address, bool isFloat, Action