Files
Sleep-Multi-functionality/Window2.xaml.cs
2026-05-07 21:17:08 +08:00

949 lines
34 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 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
{
/// <summary>
/// 气阻测试与压力流量监控窗口Modbus通信+数据记录)
/// </summary>
public partial class Window2 : Window, IDisposable
{
private class FlowParameters
{
public float ExhaustP { get; set; }
}
DataChange c = new DataChange();
#region /线
// 压力相关地址
private readonly ushort _pressureRegisterAddress = 0x0780; // 连接口实时压力
private readonly ushort _noseRegisterAddress = 0x055C; // 鼻口实时压力
private readonly ushort _connectRegisterAddress = 73; // 连接口校准线圈M72
private readonly ushort _modifiedNoseRegisterAddress = 72; // 鼻口校准线圈M73
// 流量相关地址
private readonly ushort _flowAddress = 0x0078; // 实时流量读取
private readonly ushort _flowRegisterAddress = 364; // 流量记录地址
// 测试控制线圈
private readonly ushort _testStartAddress = 0x0050; // 测试启动M80
private readonly ushort _testStatusAddress = 0x0050; // 测试状态读取(同启动地址)
private readonly ushort _testStopAddress = 7; // 测试停止M41
#endregion
#region
private TcpClient _tcpClient;
private IModbusMaster _modbusMaster;
private System.Timers.Timer _pressureReadTimer; // 连接口压力定时器
private System.Timers.Timer _noseReadTimer; // 鼻口压力定时器
private System.Timers.Timer _flowReadTimer; // 实时流量定时器
private System.Timers.Timer startTimer; // 启动状态实时定时器
private readonly System.Timers.Timer _flowTimer = new System.Timers.Timer(1000); // 流量参数定时器1秒更新一次
private readonly FlowParameters _flowParams = new FlowParameters();
#endregion
Function fc;
public Window2()
{
InitializeComponent();
InitializeModbusTcp();
Loaded += Window_Loaded;
}
#region
/// <summary>
/// 初始化Modbus连接和定时器
/// </summary>
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;
// 初始化定时器1秒间隔
_pressureReadTimer = CreateTimer(1000, OnPressureTimerElapsed);
_noseReadTimer = CreateTimer(1000, OnNoseTimerElapsed);
_flowReadTimer = CreateTimer(1000, OnFlowTimerElapsed);
startTimer = CreateTimer(1000, OnStartTimerElapsed);
// 流量参数定时器
_flowTimer.Elapsed += FlowTimer_Elapsed;
_flowTimer.AutoReset = true; // 自动重复
fc = new Function(_modbusMaster);
// 初始化数据库
InitializeDatabase();
}
catch (Exception ex)
{
ShowError($"Modbus初始化失败: {ex.Message}");
}
}
private void FlowTimer_Elapsed(object sender, ElapsedEventArgs e)
{
try
{
// 从下位机读取流量参数(假设对应以下寄存器地址,实际地址需根据设备手册修改)
_flowParams.ExhaustP = (float)ReadFromModbus(0x01, 314, true); // 排气P浮点数
// 更新UI必须在UI线程
Dispatcher.Invoke(() => UpdateFlowParametersUI());
}
catch (Exception ex)
{
Console.WriteLine($"流量参数读取失败: {ex.Message}");
}
}
private void UpdateFlowParametersUI()
{
// 检查TextBox是否有焦点有焦点则不更新避免覆盖用户输入
if (!FowlTxt1.IsFocused) FowlTxt1.Text = _flowParams.ExhaustP.ToString("F2");
}
private object ReadFromModbus(byte slaveAddress, ushort registerAddress, bool isFloat)
{
try
{
// 读取保持寄存器浮点数占2个寄存器整数占1个
ushort[] data = _modbusMaster?.ReadHoldingRegisters(
slaveAddress,
registerAddress,
isFloat ? (ushort)2 : (ushort)1
);
if (data != null)
{
// 根据类型转换数据
return isFloat
? Convert.ToSingle(c.UshortToFloat(data[1], data[0]))
: data[0];
}
else
{
return 0;
}
}
catch (Exception ex)
{
Console.WriteLine($"Modbus读取失败: {ex.Message}");
return null; // 读取失败时返回null
}
}
/// <summary>
/// 通用定时器创建方法
/// </summary>
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;
}
/// <summary>
/// 释放资源
/// </summary>
public void Dispose()
{
// 释放定时器
_pressureReadTimer?.Dispose();
_noseReadTimer?.Dispose();
_flowReadTimer?.Dispose();
// 释放TCP连接
_tcpClient?.Close();
_tcpClient?.Dispose();
_modbusMaster = null;
}
/// <summary>
/// 窗口关闭时释放资源
/// </summary>
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
Dispose();
}
#endregion
#region
/// <summary>
/// 连接口压力读取定时器
/// </summary>
private void OnPressureTimerElapsed(object sender, ElapsedEventArgs e)
{
ReadAndUpdateRegister(
_pressureRegisterAddress, true,
value => UpdatePressureUI(value.ToString())
);
}
/// <summary>
/// 鼻口压力读取定时器
/// </summary>
private void OnNoseTimerElapsed(object sender, ElapsedEventArgs e)
{
ReadAndUpdateRegister(
_noseRegisterAddress, true,
value => UpdateNoseUI(value.ToString())
);
}
/// <summary>
/// 实时流量读取定时器
/// </summary>
private void OnFlowTimerElapsed(object sender, ElapsedEventArgs e)
{
ReadAndUpdateRegister(
_flowAddress, true,
value => UpdateFlowUI(value.ToString())
);
}
/// <summary>
/// 实时流量读取定时器
/// </summary>
private void OnStartTimerElapsed(object sender, ElapsedEventArgs e)
{
try
{
bool[] result = _modbusMaster?.ReadCoils(0x01, 81, 1);
bool isTestRunning = result != null && result.Length > 0 && result[0];
string testStartButtonText = "";
string ButtonStatus = "";
string currentLanguage = ConfigurationManager.AppSettings["Language"] ?? "zh-CN";
if (currentLanguage == "en-US")
{
testStartButtonText = "Test Start Success";
ButtonStatus = "Test initiation";
}
else if (currentLanguage == "zh-CN")
{
testStartButtonText = "测试启动成功";
ButtonStatus = "测试启动";
}
TestStartButton.Dispatcher.Invoke(() =>
{
if (isTestRunning)
{
TestStartButton.Content = testStartButtonText;
TestStartButton.Foreground = Brushes.LightGreen;
}
else
{
TestStartButton.Content = ButtonStatus;
TestStartButton.Foreground = Brushes.White;
}
});
}
catch (Exception ex)
{
Console.WriteLine($"读取线圈或更新UI失败{ex.Message}");
}
}
/// <summary>
/// 通用寄存器读取并更新UI支持16位整数和32位浮点数
/// </summary>
/// <param name="address">起始地址</param>
/// <param name="isFloat">是否为浮点型占用2个寄存器</param>
/// <param name="updateAction">更新UI的回调函数</param>
private void ReadAndUpdateRegister(ushort address, bool isFloat, Action<object> updateAction)
{
if (!IsModbusConnected())
{
updateAction?.Invoke(isFloat ? (object)float.NaN : (ushort)0);
return;
}
try
{
// 根据数据类型确定读取的寄存器数量
int registerCount = isFloat ? 2 : 1;
ushort[] data = _modbusMaster?.ReadHoldingRegisters(0x01, address, (ushort)registerCount);
if (isFloat)
{
// 浮点型转换2个16位寄存器组合为32位浮点数
if (data.Length >= 2)
{
// 2. 解析寄存器值data[0]是D312data[1]是D313
ushort a = data[0]; // 高位寄存器值
ushort b = data[1]; // 低位寄存器值
float floatValue = c.UshortToFloat(b, a);
floatValue = (float)Math.Round(floatValue, 2);
updateAction?.Invoke(floatValue);
}
else
{
updateAction?.Invoke(float.NaN);
}
}
else
{
// 16位整数直接返回
updateAction?.Invoke(data.Length > 0 ? data[0] : (ushort)0);
}
}
catch (Exception ex)
{
Console.WriteLine($"读取寄存器[{address:X4}]失败: {ex.Message}");
// 异常时根据类型返回对应的值
updateAction?.Invoke(isFloat ? (object)float.NaN : (ushort)0);
}
}
#endregion
#region UI更新线
private void UpdateConnectionTextUI(System.Windows.Controls.TextBox textBox, string value)
{
// 获取当前语言(默认中文)
string currentLanguage = ConfigurationManager.AppSettings["Language"] ?? "zh-CN";
// 多语言提示信息
string disconnectMsg = currentLanguage == "en-US" ? "Connection disconnected" : "连接断开";
// 安全更新UI
UpdateUiSafely(() =>
textBox.Text = IsModbusConnected() ? value : disconnectMsg
);
}
private void UpdateConnectionTextUI(System.Windows.Controls.TextBlock textBox, string value)
{
// 获取当前语言(默认中文)
string currentLanguage = ConfigurationManager.AppSettings["Language"] ?? "zh-CN";
// 多语言提示信息
string disconnectMsg = currentLanguage == "en-US" ? "Connection disconnected" : "连接断开";
// 安全更新UI
UpdateUiSafely(() =>
textBox.Text = IsModbusConnected() ? value : disconnectMsg
);
}
/// <summary>
/// 更新连接口压力UI
/// </summary>
private void UpdatePressureUI(string value)
{
UpdateUiSafely(() =>
UpdateConnectionTextUI(RealTimePressureTextBox, value)
);
}
/// <summary>
/// 更新鼻口压力UI
/// </summary>
private void UpdateNoseUI(string value)
{
UpdateUiSafely(() =>
UpdateConnectionTextUI(NoseTxt, value)
);
}
/// <summary>
/// 更新实时流量UI
/// </summary>
private void UpdateFlowUI(string value)
{
UpdateUiSafely(() =>
UpdateConnectionTextUI(flowTxt, value)
);
}
/// <summary>
/// 更新测试按钮状态UI
/// </summary>
private void UpdateButtonStatus(string text, Brush color)
{
UpdateUiSafely(() =>
{
TestStartButton.Content = text;
TestStartButton.Foreground = color;
});
}
/// <summary>
/// 线程安全的UI更新通用方法统一实现
/// </summary>
private void UpdateUiSafely(Action action)
{
if (action == null) return;
if (Dispatcher.HasShutdownStarted)
{
return;
}
try
{
if (!Dispatcher.CheckAccess())
{
Dispatcher.Invoke(action, TimeSpan.FromSeconds(2));
}
else
{
action.Invoke();
}
}
catch (TaskCanceledException)
{
}
catch (Exception ex)
{
Console.WriteLine($"UI更新失败{ex.Message}");
}
}
#endregion
#region
/// <summary>
/// 连接口压力校准M73线圈
/// </summary>
private async void Button_Click(object sender, RoutedEventArgs e)
{
string currentLanguage = ConfigurationManager.AppSettings["Language"] ?? "zh-CN";
string success = currentLanguage == "en-US"
? "Calibration command received (verified)"
: "校准指令已被设备接收并执行(二次验证通过)";
string fail = currentLanguage == "en-US"
? "Calibration timeout, abnormal status"
: "校准执行超时,状态异常";
string log = currentLanguage == "en-US"
? "Connection port pressure calibration success"
: "连接口压力校准指令执行成功";
await WriteCoilWithCheck(
_connectRegisterAddress,
true,
success,
fail,
log
);
}
/// <summary>
/// 鼻口压力校准M72线圈
/// </summary>
private async void Button_Click_1(object sender, RoutedEventArgs e)
{
string currentLanguage = ConfigurationManager.AppSettings["Language"] ?? "zh-CN";
string success = currentLanguage == "en-US"
? "Calibration command received (verified)"
: "校准指令已被设备接收并执行(二次验证通过)";
string fail = currentLanguage == "en-US"
? "Calibration timeout, abnormal status"
: "校准执行超时,状态异常";
string log = currentLanguage == "en-US"
? "Nose pressure calibration success"
: "鼻口压力校准指令执行成功";
await WriteCoilWithCheck(
_modifiedNoseRegisterAddress,
true,
success,
fail,
log
);
}
/// <summary>
/// 流量数据读取并保存AirTxt
/// </summary>
private async void Button_Click_2(object sender, RoutedEventArgs e)
{
string currentLanguage = ConfigurationManager.AppSettings["Language"] ?? "zh-CN";
string noConn = currentLanguage == "en-US" ? "Modbus TCP not connected" : "Modbus TCP 未连接";
string invalid = currentLanguage == "en-US" ? "Invalid pressure, not saved" : "当前压力值无效,未保存数据";
string noData = currentLanguage == "en-US" ? "No data to export" : "气阻表中无数据,无法导出";
string exportSuccess = currentLanguage == "en-US" ? "Export success" : "数据已成功导出到Excel";
if (!IsModbusConnected())
{
AirTxt.Text = currentLanguage == "en-US" ? "Disconnected" : "连接断开";
ShowError(noConn);
return;
}
fc.BtnClickFunctionForNew(Function.ButtonType., 191);
fc.BtnClickFunctionForNew(Function.ButtonType., 191);
ReadAndUpdateRegister(
_flowRegisterAddress, true,
value => UpdateFlowFlowUI(value.ToString()));
// 尝试将文本框内容转换为float
if (double.TryParse(AirTxt.Text, out double floatValue) &&
float.TryParse(flowTxt.Text, out float pressureValue))
{
SaveRecordToDatabase(floatValue, pressureValue);
}
else
{
ShowWarning(invalid);
}
// 步骤2读取CO2表数据
List<CO2Record> co2Records = ReadCO2RecordsFromDatabase();
if (co2Records == null || !co2Records.Any())
{
MessageBox.Show(noData, currentLanguage == "en-US" ? "Info" : "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
// 步骤3导出Excel
bool exportSuccessFlag = ExportCO2RecordsToExcel(co2Records);
if (exportSuccessFlag)
{
MessageBox.Show(exportSuccess, currentLanguage == "en-US" ? "Success" : "成功", MessageBoxButton.OK, MessageBoxImage.Information);
}
}
private bool ExportCO2RecordsToExcel(List<CO2Record> records)
{
try
{
SaveFileDialog saveDialog = new SaveFileDialog
{
Filter = "Excel文件 (*.xlsx)|*.xlsx",
FileName = $"气阻记录_{DateTime.Now:yyyyMMddHHmmss}.xlsx",
Title = "保存气阻记录"
};
bool? result = saveDialog.ShowDialog(); if (!(result ?? false)) return false;
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
using (ExcelPackage package = new ExcelPackage(new FileInfo(saveDialog.FileName)))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("气阻记录");
worksheet.Cells[1, 1].Value = "气阻hpa";
worksheet.Cells[1, 2].Value = "流量L/min";
worksheet.Cells[1, 3].Value = "时间";
using (var headerRange = worksheet.Cells[1, 1, 1, 6])
{
headerRange.Style.Font.Bold = true;
headerRange.Style.HorizontalAlignment = OfficeOpenXml.Style.ExcelHorizontalAlignment.Center;
}
for (int i = 0; i < records.Count; i++)
{
int row = i + 2;
var record = records[i];
worksheet.Cells[row, 1].Value = record.Flow;
worksheet.Cells[row, 2].Value = record.Pressure;
worksheet.Cells[row, 3].Value = record.RecordTime.ToString("yyyy-MM-dd HH:mm:ss");
}
worksheet.Cells.AutoFitColumns();
package.Save();
}
return true;
}
catch (Exception ex)
{
string currentLanguage = ConfigurationManager.AppSettings["Language"] ?? "zh-CN";
string err = currentLanguage == "en-US" ? "Export failed" : "导出失败";
MessageBox.Show($"{err}{ex.Message}", currentLanguage == "en-US" ? "Error" : "错误", MessageBoxButton.OK, MessageBoxImage.Error);
return false;
}
}
/// <summary>
///
/// </summary>
private List<CO2Record> ReadCO2RecordsFromDatabase()
{
List<CO2Record> records = new List<CO2Record>();
try
{
using (SQLiteConnection conn = new SQLiteConnection(CSConstant.DbConnectionString))
{
conn.Open();
// 查询CO2表所有记录按时间排序
string query = "SELECT Flow, Pressure, RecordTime FROM AirRecords ORDER BY RecordTime desc limit 1";
using (SQLiteCommand cmd = new SQLiteCommand(query, conn))
{
using (SQLiteDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
records.Add(new CO2Record
{
Flow = reader.GetDouble(0), // 二氧化碳浓度(%
Pressure = reader.GetDouble(1), // 压力pa
RecordTime = reader.GetDateTime(2) // 时间
});
}
}
}
}
return records;
}
catch (Exception ex)
{
MessageBox.Show($"读取气阻表失败:{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
return null;
}
}
/// <summary>
/// 更新实时流量UI
/// </summary>
private void UpdateFlowFlowUI(string value)
{
UpdateUiSafely(() =>
AirTxt.Text = IsModbusConnected() ? value : "连接断开"
);
}
/// <summary>
/// 返回主窗口
/// </summary>
private void Button_Click_3(object sender, RoutedEventArgs e)
{
var mainWindow = MainWindow.Instance;
// 检查窗口状态只在窗口未显示时调用ShowDialog
if (!mainWindow.IsVisible)
{
mainWindow.ShowDialog();
}
else
{
// 如果窗口已显示,可将其激活到前台
mainWindow.Activate();
}
Close();
}
/// <summary>
/// 测试启动M80线圈
/// </summary>
private async void Button_Click_4(object sender, RoutedEventArgs e)
{
string currentLanguage = ConfigurationManager.AppSettings["Language"] ?? "zh-CN";
if (!IsModbusConnected())
{
UpdateButtonStatus(currentLanguage == "en-US" ? "Disconnected" : "连接断开", Brushes.Red);
ShowError(currentLanguage == "en-US" ? "Modbus TCP not connected" : "Modbus TCP 未连接");
return;
}
try
{
UpdateButtonStatus(currentLanguage == "en-US" ? "Starting..." : "正在启动...", Brushes.LightGreen);
await Task.Run(() =>
_modbusMaster.WriteSingleCoilAsync(0x01, _testStartAddress, true)
);
await Task.Delay(100);
await Task.Run(() =>
_modbusMaster.WriteSingleCoilAsync(0x01, _testStatusAddress, false)
);
await Task.Delay(100);
UpdateButtonStatus(currentLanguage == "en-US" ? "Test started successfully" : "测试启动成功", Brushes.LightGreen);
}
catch (Exception ex)
{
UpdateButtonStatus(currentLanguage == "en-US" ? "Test start failed" : "测试启动失败", Brushes.Red);
ShowError(currentLanguage == "en-US" ? $"Operation error: {ex.Message}" : $"操作异常: {ex.Message}");
}
}
/// <summary>
/// 测试停止M41线圈
/// </summary>
private async void Button_Click_5(object sender, RoutedEventArgs e)
{
string currentLanguage = ConfigurationManager.AppSettings["Language"] ?? "zh-CN";
string failMsg = currentLanguage == "en-US"
? "Air resistance test stop timeout"
: "气阻测试停止超时,状态异常";
string logMsg = currentLanguage == "en-US"
? "Air resistance test stopped"
: "气阻测试停止";
await WriteCoilWithCheck(
_testStopAddress,
true,
null,
failMsg,
logMsg
);
TestStartButton.Content = currentLanguage == "en-US" ? "Test initiation" : "测试启动";
TestStartButton.Foreground = Brushes.White;
}
/// <summary>
/// 打开报告窗口
/// </summary>
private void Button_Click_6(object sender, RoutedEventArgs e)
{
new ReportWindow2().ShowDialog();
}
#endregion
#region
/// <summary>
/// 写入线圈并验证状态
/// </summary>
private async Task WriteCoilWithCheck(
ushort coilAddress,
bool value,
string successMsg,
string failMsg,
string logMsg)
{
string currentLanguage = ConfigurationManager.AppSettings["Language"] ?? "zh-CN";
string noConn = currentLanguage == "en-US" ? "Modbus TCP not connected" : "Modbus TCP 未连接";
string commError = currentLanguage == "en-US" ? "Communication error" : "通信错误";
if (!IsModbusConnected())
{
ShowError(noConn);
return;
}
try
{
await Task.Run(() =>
_modbusMaster.WriteSingleCoilAsync(0x01, coilAddress, value)
);
Thread.Sleep(200);
if (failMsg != null)
{
bool isStop = failMsg.Contains("停止") || failMsg.Equals("Stop", StringComparison.OrdinalIgnoreCase);
bool isCalib = failMsg.Contains("校准") || failMsg.Equals("Calibrate", StringComparison.OrdinalIgnoreCase);
if (isStop || isCalib)
{
await Task.Run(() =>
_modbusMaster.WriteSingleCoilAsync(0x01, coilAddress, false)
);
}
}
Thread.Sleep(100);
await Task.Delay(500);
bool[] status = await _modbusMaster?.ReadCoilsAsync(0x01, coilAddress, 1);
if (failMsg != null)
{
bool isStop = failMsg.Contains("停止") || failMsg.Equals("Stop", StringComparison.OrdinalIgnoreCase);
bool isCalib = failMsg.Contains("校准") || failMsg.Equals("Calibrate", StringComparison.OrdinalIgnoreCase);
if (!isStop && !isCalib)
{
if (status[0] == value)
{
WriteLog($"{logMsg} - Address{coilAddress}Status{value}");
if (!string.IsNullOrEmpty(successMsg)) ShowSuccess(successMsg);
}
else
{
ShowError(failMsg);
}
}
}
}
catch (Exception ex)
{
ShowError($"{commError}: {ex.Message}");
}
}
#endregion
#region
/// <summary>
/// 初始化数据库
/// </summary>
private void InitializeDatabase()
{
try
{
using (var conn = new SQLiteConnection(CSConstant.DbConnectionString))
{
conn.Open();
string createSql = @"
CREATE TABLE IF NOT EXISTS AirRecords (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
Flow REAL NOT NULL,
Pressure REAL NOT NULL,
RecordTime DATETIME NOT NULL
);";
using (var cmd = new SQLiteCommand(createSql, conn))
{
cmd.ExecuteNonQuery();
}
}
}
catch (Exception ex)
{
Console.WriteLine($"数据库初始化失败: {ex.Message}");
ShowError($"数据库错误: {ex.Message}");
}
}
/// <summary>
/// 保存记录到数据库
/// </summary>
private void SaveRecordToDatabase(double flow, double pressure)
{
try
{
flow = Math.Round(flow, 2);
pressure = Math.Round(pressure, 2);
using (var conn = new SQLiteConnection(CSConstant.DbConnectionString))
{
conn.Open();
string insertSql = @"
INSERT INTO AirRecords (Flow, Pressure, RecordTime)
VALUES (@Flow, @Pressure, @RecordTime);";
using (var cmd = new SQLiteCommand(insertSql, conn))
{
cmd.Parameters.AddWithValue("@Flow", flow);
cmd.Parameters.AddWithValue("@Pressure", pressure);
cmd.Parameters.AddWithValue("@RecordTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
cmd.ExecuteNonQuery();
}
}
}
catch (Exception ex)
{
Console.WriteLine($"保存数据库失败: {ex.Message}");
ShowWarning($"数据保存失败: {ex.Message}");
}
}
/// <summary>
/// 日志路径
/// </summary>
private string logPath => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "modbus_log.txt");
/// <summary>
/// 写入操作日志
/// </summary>
private void WriteLog(string content)
{
try
{
string log = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {content}\r\n";
File.AppendAllText(logPath, log);
}
catch (Exception ex)
{
Console.WriteLine($"写入日志失败: {ex.Message}");
}
}
#endregion
#region
/// <summary>
/// 检查Modbus连接状态
/// </summary>
private bool IsModbusConnected()
{
return _modbusMaster != null && _tcpClient?.Connected == true;
}
/// <summary>
/// 加载窗口背景
/// </summary>
private void Window_Loaded(object sender, RoutedEventArgs e)
{
_flowTimer.Start();
try
{
string imgPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources/sleep2.jpg");
if (File.Exists(imgPath))
{
Background = new ImageBrush
{
ImageSource = new BitmapImage(new Uri(imgPath, UriKind.Absolute))
};
}
else
{
Console.WriteLine($"背景图片不存在: {imgPath}");
}
}
catch (Exception ex)
{
Console.WriteLine($"加载背景失败: {ex.Message}");
}
}
// 消息提示封装
private void ShowSuccess(string msg) => MessageBox.Show(msg, "成功", MessageBoxButton.OK, MessageBoxImage.Information);
private void ShowWarning(string msg) => MessageBox.Show(msg, "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
private void ShowError(string msg) => MessageBox.Show(msg, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
#endregion
private void Button_Click_7(object sender, RoutedEventArgs e)
{
fc.WriteToPLCForNew(FowlTxt1.Text, 314, Function.DataType.);
}
}
}