1761 lines
68 KiB
C#
1761 lines
68 KiB
C#
using Dapper;
|
||
using Microsoft.Win32;
|
||
using Modbus.Device;
|
||
using MySql.Data.MySqlClient;
|
||
using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime;
|
||
using Sunny.UI;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel;
|
||
using System.Data;
|
||
using System.Diagnostics;
|
||
using System.Drawing;
|
||
using System.Linq;
|
||
using System.Net.Sockets;
|
||
using System.Text;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
using System.Timers;
|
||
using System.Windows.Forms;
|
||
using 全自动水压检测仪.Data;
|
||
using 全自动水压检测仪.DATA;
|
||
using 材料热传导系数;
|
||
|
||
namespace 全自动水压检测仪
|
||
{
|
||
public partial class NormalTemperatureMode : UIForm
|
||
{
|
||
BoolSignal boolSignal1 = new BoolSignal();
|
||
private Coeffiicientsetting _coeffiicientsetting;
|
||
private ScanImport _scanImport;
|
||
private StatusSettingsForm _statusSettingsForm; // 新增状态设置窗体
|
||
private ChartManager _chartManager; // 图表管理器
|
||
|
||
public List<ConductivityTestData> CurrentReport;
|
||
private Report _report;
|
||
private Stopwatch pressStopwatch;
|
||
private const int LONG_PRESS_THRESHOLD = 1000; // 1000毫秒=1秒
|
||
|
||
#region 私有字段
|
||
private TcpClient _tcpClient => ModbusResourceManager.Instance.TcpClient;
|
||
private IModbusMaster _modbusMaster => ModbusResourceManager.Instance.ModbusMaster;
|
||
#endregion
|
||
|
||
Function ma;
|
||
DataChange c;
|
||
|
||
private System.Windows.Forms.Timer _readTimer;
|
||
private System.Windows.Forms.Timer _readTimerTwo; // 第二个定时器引用
|
||
private bool _isManualInput = false; // 手动输入标记
|
||
private bool _isSwitchingWindow = false; // 窗口切换标记,避免并发
|
||
|
||
private ConductivityRepository _repository;
|
||
|
||
#region 报警监控相关字段和属性
|
||
// 报警寄存器地址定义(根据图片内容)
|
||
private const ushort PRESSURE_PROTECTION_ADDR = 10200; // M200 压力保护大于
|
||
private const ushort TEMPERATURE_PROTECTION_ADDR = 10205; // M205 温度保护大于
|
||
private const ushort HIGH_TEMP_LEVEL_LIMIT_ADDR = 10230; // M230 高温液位极限大于
|
||
private const ushort NORMAL_TEMP_LEVEL_LIMIT_ADDR = 10235; // M235 常温液位极限大于
|
||
private const ushort HIGH_TEMP_LEVEL_MAX_ADDR = 10210; // M210 高温液位上限大于
|
||
private const ushort NORMAL_TEMP_LEVEL_MAX_ADDR = 10215; // M215 常温液位上限大于
|
||
|
||
// 报警状态记录
|
||
private Dictionary<ushort, bool> _alarmStatus = new Dictionary<ushort, bool>
|
||
{
|
||
{ PRESSURE_PROTECTION_ADDR, false },
|
||
{ TEMPERATURE_PROTECTION_ADDR, false },
|
||
{ HIGH_TEMP_LEVEL_LIMIT_ADDR, false },
|
||
{ NORMAL_TEMP_LEVEL_LIMIT_ADDR, false },
|
||
{ HIGH_TEMP_LEVEL_MAX_ADDR, false },
|
||
{ NORMAL_TEMP_LEVEL_MAX_ADDR, false }
|
||
};
|
||
|
||
// 报警描述映射
|
||
private Dictionary<ushort, string> _alarmDescriptions = new Dictionary<ushort, string>
|
||
{
|
||
{ PRESSURE_PROTECTION_ADDR, "压力保护报警" },
|
||
{ TEMPERATURE_PROTECTION_ADDR, "温度保护报警" },
|
||
{ HIGH_TEMP_LEVEL_LIMIT_ADDR, "高温液位极限报警" },
|
||
{ NORMAL_TEMP_LEVEL_LIMIT_ADDR, "常温液位极限报警" },
|
||
{ HIGH_TEMP_LEVEL_MAX_ADDR, "高温液位上限报警" },
|
||
{ NORMAL_TEMP_LEVEL_MAX_ADDR, "常温液位上限报警" }
|
||
};
|
||
|
||
// 报警定时器
|
||
private System.Windows.Forms.Timer _alarmMonitorTimer;
|
||
private bool _isCheckingAlarm = false;
|
||
#endregion
|
||
|
||
|
||
public NormalTemperatureMode()
|
||
{
|
||
InitializeComponent();
|
||
pressStopwatch = new Stopwatch();
|
||
// 只创建定时器,不在构造器中启动,避免在 Load 前访问未初始化的资源
|
||
_readTimer = InitTimer(); // 保存引用
|
||
_readTimerTwo = InitTimerTwo(); // 保存第二个定时器引用
|
||
|
||
// 初始化报警监控定时器
|
||
_alarmMonitorTimer = InitAlarmMonitorTimer();
|
||
|
||
_repository = new ConductivityRepository();
|
||
CurrentReport = new List<ConductivityTestData>();
|
||
|
||
// 初始化图表管理器
|
||
_chartManager = new ChartManager();
|
||
}
|
||
|
||
private System.Windows.Forms.Timer InitAlarmMonitorTimer()
|
||
{
|
||
var timer = new System.Windows.Forms.Timer()
|
||
{
|
||
Interval = 2000 // 每2秒检查一次报警
|
||
};
|
||
timer.Tick += async (s, e) =>
|
||
{
|
||
if (!_isCheckingAlarm && _modbusMaster != null)
|
||
{
|
||
try
|
||
{
|
||
await CheckAlarmStatusAsync();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine($"报警监控异常: {ex.Message}");
|
||
}
|
||
}
|
||
};
|
||
return timer;
|
||
}
|
||
|
||
|
||
private async Task CheckAlarmStatusAsync()
|
||
{
|
||
if (_isCheckingAlarm || _modbusMaster == null) return;
|
||
|
||
_isCheckingAlarm = true;
|
||
|
||
try
|
||
{
|
||
// 批量读取所有报警点的状态
|
||
var alarmAddresses = new List<ushort>
|
||
{
|
||
PRESSURE_PROTECTION_ADDR,
|
||
TEMPERATURE_PROTECTION_ADDR,
|
||
HIGH_TEMP_LEVEL_LIMIT_ADDR,
|
||
NORMAL_TEMP_LEVEL_LIMIT_ADDR,
|
||
HIGH_TEMP_LEVEL_MAX_ADDR,
|
||
NORMAL_TEMP_LEVEL_MAX_ADDR
|
||
};
|
||
|
||
foreach (var address in alarmAddresses)
|
||
{
|
||
try
|
||
{
|
||
bool[] alarmStatus = await Task.Run(() =>
|
||
{
|
||
// 注意:ReadCoils的参数是起始地址和数量
|
||
return _modbusMaster.ReadCoils(1, address, 1);
|
||
});
|
||
|
||
if (alarmStatus != null && alarmStatus.Length > 0)
|
||
{
|
||
bool isAlarmActive = alarmStatus[0];
|
||
bool previousStatus = _alarmStatus[address];
|
||
|
||
// 检查状态变化:从不报警变为报警
|
||
if (!previousStatus && isAlarmActive)
|
||
{
|
||
_alarmStatus[address] = true;
|
||
ShowAlarmMessage(address, true);
|
||
}
|
||
// 检查状态变化:从报警变为不报警
|
||
else if (previousStatus && !isAlarmActive)
|
||
{
|
||
_alarmStatus[address] = false;
|
||
ShowAlarmMessage(address, false);
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine($"读取地址{address}报警状态失败: {ex.Message}");
|
||
}
|
||
|
||
// 短暂延迟避免频繁访问
|
||
await Task.Delay(100);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine($"报警检查失败: {ex.Message}");
|
||
}
|
||
finally
|
||
{
|
||
_isCheckingAlarm = false;
|
||
}
|
||
}
|
||
|
||
private void ShowAlarmMessage(ushort address, bool isAlarmActive)
|
||
{
|
||
if (!_alarmDescriptions.ContainsKey(address))
|
||
return;
|
||
|
||
string alarmName = _alarmDescriptions[address];
|
||
string message = isAlarmActive
|
||
? $"{alarmName}已触发!请立即检查设备状态。"
|
||
: $"{alarmName}已解除。";
|
||
|
||
string title = isAlarmActive ? "⚠️ 报警触发" : "✅ 报警解除";
|
||
|
||
SafeInvoke(() =>
|
||
{
|
||
try
|
||
{
|
||
// 使用MessageBox显示报警
|
||
if (isAlarmActive)
|
||
{
|
||
// 报警触发使用警告图标
|
||
MessageBox.Show(message, title,
|
||
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
}
|
||
else
|
||
{
|
||
// 报警解除使用信息图标
|
||
MessageBox.Show(message, title,
|
||
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||
}
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine($"显示报警消息失败: {ex.Message}");
|
||
}
|
||
});
|
||
}
|
||
|
||
private void SafeInvoke(Action action)
|
||
{
|
||
if (action == null) return;
|
||
|
||
// 检查窗体是否已释放/句柄是否创建
|
||
if (this.IsDisposed || !this.IsHandleCreated)
|
||
{
|
||
Debug.WriteLine("窗体已释放或句柄未创建,跳过UI操作");
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
// 如果已经在UI线程,直接执行;否则Invoke
|
||
if (this.InvokeRequired)
|
||
{
|
||
this.Invoke(action);
|
||
}
|
||
else
|
||
{
|
||
action();
|
||
}
|
||
}
|
||
catch (ObjectDisposedException ex)
|
||
{
|
||
Debug.WriteLine($"UI操作时控件已释放: {ex.Message}");
|
||
}
|
||
catch (InvalidOperationException ex)
|
||
{
|
||
Debug.WriteLine($"UI操作异常: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
// 重载:支持BeginInvoke(异步UI更新)
|
||
private void SafeBeginInvoke(Action action)
|
||
{
|
||
if (action == null) return;
|
||
|
||
if (this.IsDisposed || !this.IsHandleCreated)
|
||
{
|
||
Debug.WriteLine("窗体已释放或句柄未创建,跳过异步UI操作");
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
if (this.InvokeRequired)
|
||
{
|
||
this.BeginInvoke(action);
|
||
}
|
||
else
|
||
{
|
||
action();
|
||
}
|
||
}
|
||
catch (ObjectDisposedException ex)
|
||
{
|
||
Debug.WriteLine($"异步UI操作时控件已释放: {ex.Message}");
|
||
}
|
||
catch (InvalidOperationException ex)
|
||
{
|
||
Debug.WriteLine($"异步UI操作异常: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
private System.Windows.Forms.Timer InitTimer()
|
||
{
|
||
var timer = new System.Windows.Forms.Timer()
|
||
{
|
||
Interval = 1000
|
||
};
|
||
timer.Tick += async (s, e) =>
|
||
{
|
||
if (!_isManualInput && _modbusMaster != null)
|
||
{
|
||
try
|
||
{
|
||
await ReadLeakTestParametersAsync();
|
||
}
|
||
catch { }
|
||
}
|
||
};
|
||
// 不在此处 Start
|
||
return timer;
|
||
}
|
||
private System.Windows.Forms.Timer InitTimerTwo()
|
||
{
|
||
var timer = new System.Windows.Forms.Timer()
|
||
{
|
||
Interval = 1000
|
||
};
|
||
timer.Tick += async (s, e) =>
|
||
{
|
||
if (!_isManualInput && _modbusMaster != null)
|
||
{
|
||
try
|
||
{
|
||
await ReadLeakTestParametersAsyncTwo();
|
||
}
|
||
catch { }
|
||
}
|
||
};
|
||
// 不在此处 Start
|
||
return timer;
|
||
}
|
||
|
||
private async Task ReadLeakTestParametersAsync()
|
||
{
|
||
// 检查连接状态
|
||
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
|
||
{
|
||
SafeInvoke(() =>
|
||
{
|
||
MessageBox.Show("TCP未连接或ModbusMaster未初始化", "提示");
|
||
});
|
||
return;
|
||
}
|
||
|
||
// 检查UI控件是否可用(避免在窗体释放前调用)
|
||
if (!this.IsHandleCreated || this.IsDisposed)
|
||
{
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
var modbusData = await Task.Run(() =>
|
||
{
|
||
try
|
||
{
|
||
return new
|
||
{
|
||
//读取所需要的寄存器(同步操作,但在后台线程)
|
||
Real1 = SafelyReadRegisters(1, 3130, 2),// 实时压力
|
||
Real2 = SafelyReadRegisters(1, 3080, 2),// 常温实时液位
|
||
Real3 = SafelyReadRegisters(1, 2100, 2),// 初始化压力
|
||
Real4 = SafelyReadRegisters(1, 2102, 2),// 结束压力
|
||
Real5 = SafelyReadRegisters(1, 2104, 2),// 压差
|
||
Real6 = SafelyReadRegisters(1, 2082, 2),// 计时s
|
||
Real7 = SafelyReadRegisters(1, 2084, 2),// 计时min
|
||
Real8 = SafelyReadRegisters(1, 2086, 2),// 计时h
|
||
Real9 = SafelyReadRegisters(1, 3030, 2),// 高温实时液位
|
||
Real10 = SafelyReadRegisters(1, 3480, 2),// 箱体温度
|
||
Real11 = SafelyReadRegisters(1, 3180, 2),// 出口温度
|
||
Real12 = SafelyReadRegisters(1, 2400, 2),// 压力设定值
|
||
CurrentTime = DateTime.Now
|
||
};
|
||
}
|
||
catch
|
||
{
|
||
return null; // 读取失败返回 null
|
||
}
|
||
});
|
||
|
||
// 检查是否成功读取
|
||
if (modbusData == null)
|
||
{
|
||
throw new InvalidOperationException("Modbus数据读取失败");
|
||
}
|
||
|
||
// 检查数据转换工具是否可用
|
||
if (c == null)
|
||
{
|
||
throw new InvalidOperationException("数据转换工具未初始化");
|
||
}
|
||
|
||
// 使用安全的异步UI更新方法
|
||
SafeBeginInvoke(() =>
|
||
{
|
||
try
|
||
{
|
||
// 时间显示
|
||
if (uiLabel5 != null && !uiLabel5.IsDisposed)
|
||
uiLabel5.Text = modbusData.CurrentTime.ToString("yyyy-MM-dd HH:mm:ss");
|
||
|
||
// 实时压力
|
||
if (uiLabel28 != null && !uiLabel28.IsDisposed &&
|
||
modbusData.Real1 != null && modbusData.Real1.Length >= 2)
|
||
{
|
||
var value0 = c.UshortToFloat(modbusData.Real1[1], modbusData.Real1[0]);
|
||
uiLabel28.Text = value0.ToString("F2");
|
||
}
|
||
|
||
// 常温实时液位
|
||
if (uiLabel12 != null && !uiLabel12.IsDisposed &&
|
||
modbusData.Real2 != null && modbusData.Real2.Length >= 2)
|
||
{
|
||
var value1 = c.UshortToFloat(modbusData.Real2[1], modbusData.Real2[0]);
|
||
float percentage = (value1 / 150f) * 100f;
|
||
|
||
// 限制百分比在0-100之间
|
||
if (percentage < 0) percentage = 0;
|
||
if (percentage > 100) percentage = 100;
|
||
|
||
// 更新进度条
|
||
if (uiProcessBar1 != null && !uiProcessBar1.IsDisposed)
|
||
uiProcessBar1.Value = (int)percentage;
|
||
|
||
uiLabel12.Text = value1.ToString("F2");
|
||
}
|
||
|
||
// 初始压力
|
||
if (uiLabel14 != null && !uiLabel14.IsDisposed &&
|
||
modbusData.Real3 != null && modbusData.Real3.Length >= 2)
|
||
{
|
||
var value2 = c.UshortToFloat(modbusData.Real3[1], modbusData.Real3[0]);
|
||
uiLabel14.Text = value2.ToString("F2");
|
||
}
|
||
|
||
// 结束压力
|
||
if (uiLabel19 != null && !uiLabel19.IsDisposed &&
|
||
modbusData.Real4 != null && modbusData.Real4.Length >= 2)
|
||
{
|
||
var value3 = c.UshortToFloat(modbusData.Real4[1], modbusData.Real4[0]);
|
||
uiLabel19.Text = value3.ToString("F2");
|
||
}
|
||
|
||
// 压差
|
||
if (uiLabel22 != null && !uiLabel22.IsDisposed &&
|
||
modbusData.Real5 != null && modbusData.Real5.Length >= 2)
|
||
{
|
||
var value4 = c.UshortToFloat(modbusData.Real5[1], modbusData.Real5[0]);
|
||
uiLabel22.Text = value4.ToString("F2");
|
||
}
|
||
|
||
// 合并显示时间(格式:hh:mm:ss)
|
||
if (uiLabel9 != null && !uiLabel9.IsDisposed)
|
||
{
|
||
// 使用0作为缺省值
|
||
int seconds = (modbusData.Real6 != null && modbusData.Real6.Length >= 1) ? modbusData.Real6[0] : 0;
|
||
int minutes = (modbusData.Real7 != null && modbusData.Real7.Length >= 1) ? modbusData.Real7[0] : 0;
|
||
int hours = (modbusData.Real8 != null && modbusData.Real8.Length >= 1) ? modbusData.Real8[0] : 0;
|
||
|
||
// 格式化为00:00:00
|
||
string timeString = $"{hours:D2}:{minutes:D2}:{seconds:D2}";
|
||
uiLabel9.Text = timeString;
|
||
}
|
||
|
||
// 高温实时液位
|
||
if (uiLabel7 != null && !uiLabel7.IsDisposed &&
|
||
modbusData.Real9 != null && modbusData.Real9.Length >= 2)
|
||
{
|
||
var value8 = c.UshortToFloat(modbusData.Real9[1], modbusData.Real9[0]);
|
||
float percentage = (value8 / 150f) * 100f;
|
||
|
||
// 限制百分比在0-100之间
|
||
if (percentage < 0) percentage = 0;
|
||
if (percentage > 100) percentage = 100;
|
||
|
||
// 更新进度条
|
||
if (uiProcessBar2 != null && !uiProcessBar2.IsDisposed)
|
||
uiProcessBar2.Value = (int)percentage;
|
||
|
||
uiLabel7.Text = value8.ToString("F2");
|
||
}
|
||
|
||
// 箱体温度
|
||
if (uiLabel42 != null && !uiLabel42.IsDisposed &&
|
||
modbusData.Real10 != null && modbusData.Real10.Length >= 2)
|
||
{
|
||
var value9 = c.UshortToFloat(modbusData.Real10[1], modbusData.Real10[0]);
|
||
uiLabel42.Text = value9.ToString("F1");
|
||
}
|
||
|
||
// 出口温度
|
||
if (uiLabel38 != null && !uiLabel38.IsDisposed &&
|
||
modbusData.Real11 != null && modbusData.Real11.Length >= 2)
|
||
{
|
||
var value10 = c.UshortToFloat(modbusData.Real11[1], modbusData.Real11[0]);
|
||
uiLabel38.Text = value10.ToString("F1");
|
||
}
|
||
|
||
// 更新图表数据(实时压力和压力设定值)
|
||
if (modbusData.Real1 != null && modbusData.Real1.Length >= 2 &&
|
||
modbusData.Real12 != null && modbusData.Real12.Length >= 2)
|
||
{
|
||
try
|
||
{
|
||
var pressure = c.UshortToFloat(modbusData.Real1[1], modbusData.Real1[0]);
|
||
var pressureSetValue = c.UshortToFloat(modbusData.Real12[1], modbusData.Real12[0]);
|
||
|
||
// 获取测试时间(从PLC读取的时分秒)
|
||
int seconds = (modbusData.Real6 != null && modbusData.Real6.Length >= 1) ? modbusData.Real6[0] : 0;
|
||
int minutes = (modbusData.Real7 != null && modbusData.Real7.Length >= 1) ? modbusData.Real7[0] : 0;
|
||
int hours = (modbusData.Real8 != null && modbusData.Real8.Length >= 1) ? modbusData.Real8[0] : 0;
|
||
string testTime = $"{hours:D2}:{minutes:D2}:{seconds:D2}";
|
||
|
||
_chartManager?.AddDataPoint(pressure, pressureSetValue, testTime);
|
||
}
|
||
catch (Exception chartEx)
|
||
{
|
||
Debug.WriteLine($"图表更新异常: {chartEx.Message}");
|
||
}
|
||
}
|
||
}
|
||
catch (Exception uiEx)
|
||
{
|
||
Debug.WriteLine($"UI更新异常: {uiEx.Message}");
|
||
}
|
||
});
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
// 安全地停止定时器
|
||
try
|
||
{
|
||
_readTimer?.Stop();
|
||
}
|
||
catch { }
|
||
|
||
SafeInvoke(() =>
|
||
{
|
||
MessageBox.Show($"读取调试参数失败:{ex.Message}", "错误",
|
||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
});
|
||
}
|
||
}
|
||
|
||
bool isAddTag = false;
|
||
// 辅助方法:安全读取寄存器
|
||
private ushort[] SafelyReadRegisters(byte slaveAddress, ushort startAddress, ushort numberOfPoints)
|
||
{
|
||
try
|
||
{
|
||
if (_modbusMaster != null)
|
||
{
|
||
return _modbusMaster.ReadHoldingRegisters(slaveAddress, startAddress, numberOfPoints);
|
||
}
|
||
}
|
||
catch
|
||
{
|
||
// 读取失败返回空数组
|
||
}
|
||
return new ushort[numberOfPoints]; // 返回默认值数组
|
||
}
|
||
|
||
private string GetStatusText(int statusValue)
|
||
{
|
||
switch (statusValue)
|
||
{
|
||
case 0:
|
||
return "空闲中";
|
||
case 1:
|
||
return "水循环中";
|
||
case 2:
|
||
return "加压中";
|
||
case 3:
|
||
return "保压测试中";
|
||
case 4:
|
||
return "空闲中"; // 根据您的要求,4也显示"空闲中"
|
||
default:
|
||
return $"未知状态({statusValue})";
|
||
}
|
||
}
|
||
|
||
private async Task ReadLeakTestParametersAsyncTwo()
|
||
{
|
||
//是否连接
|
||
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null) return;
|
||
|
||
//测试步骤
|
||
try
|
||
{
|
||
ushort[] testslip = await Task.Run(() =>
|
||
_modbusMaster?.ReadHoldingRegisters(1, 2080, 2)
|
||
);
|
||
if (testslip == null || testslip.Length == 0) return;
|
||
|
||
int testvalue = testslip[0];
|
||
string statusText = GetStatusText(testvalue);
|
||
|
||
// 使用安全的UI更新方法
|
||
SafeInvoke(() =>
|
||
{
|
||
if (uiLabel3 != null && !uiLabel3.IsDisposed)
|
||
uiLabel3.Text = statusText;
|
||
});
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine($"[错误] 读取测试步(地址80)失败: {ex.Message}");
|
||
}
|
||
|
||
//压力设定
|
||
try
|
||
{
|
||
ushort[] registers = await Task.Run(() =>
|
||
_modbusMaster?.ReadHoldingRegisters(1, 2400, 2)
|
||
);
|
||
if (registers == null || registers.Length == 0) return;
|
||
|
||
float pressureValue = c.UshortToFloat(registers[1], registers[0]);
|
||
|
||
SafeInvoke(() =>
|
||
{
|
||
if (uiTextBox1 != null && !uiTextBox1.IsDisposed)
|
||
uiTextBox1.Text = pressureValue.ToString("F2");
|
||
});
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine($"[错误] 读取压力设定(地址400)失败: {ex.Message}");
|
||
}
|
||
|
||
//箱体温度
|
||
try
|
||
{
|
||
ushort[] registers = await Task.Run(() =>
|
||
_modbusMaster?.ReadHoldingRegisters(1, 2402, 2)
|
||
);
|
||
if (registers == null || registers.Length == 0) return;
|
||
|
||
float registerValue = c.UshortToFloat(registers[1], registers[0]);
|
||
|
||
SafeInvoke(() =>
|
||
{
|
||
if (uiTextBox4 != null && !uiTextBox4.IsDisposed)
|
||
uiTextBox4.Text = registerValue.ToString("F2");
|
||
});
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine($"[错误] 读取箱体温度(地址402)失败: {ex.Message}");
|
||
}
|
||
|
||
//保压时间
|
||
try
|
||
{
|
||
ushort[] registers = await Task.Run(() =>
|
||
_modbusMaster?.ReadHoldingRegisters(1, 2404, 2)
|
||
);
|
||
if (registers == null || registers.Length == 0) return;
|
||
|
||
int pressureValue = registers[0];
|
||
|
||
SafeInvoke(() =>
|
||
{
|
||
if (uiTextBox5 != null && !uiTextBox5.IsDisposed)
|
||
uiTextBox5.Text = pressureValue.ToString();
|
||
});
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine($"[错误] 读取保压时间设置(地址404)失败: {ex.Message}");
|
||
}
|
||
|
||
//出口温度设置
|
||
try
|
||
{
|
||
ushort[] registers = await Task.Run(() =>
|
||
_modbusMaster?.ReadHoldingRegisters(1, 2412, 2)
|
||
);
|
||
if (registers == null || registers.Length == 0) return;
|
||
|
||
float temperatureValue = c.UshortToFloat(registers[1], registers[0]);
|
||
|
||
SafeInvoke(() =>
|
||
{
|
||
if (uiTextBox9 != null && !uiTextBox9.IsDisposed)
|
||
uiTextBox9.Text = temperatureValue.ToString("F2");
|
||
});
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine($"[错误] 读取出口温度设置(地址412)失败: {ex.Message}");
|
||
}
|
||
|
||
try
|
||
{
|
||
// 所有Modbus读取操作移到后台线程
|
||
var modbusResults = await Task.Run(() =>
|
||
{
|
||
try
|
||
{
|
||
return new
|
||
{
|
||
TestStatus = _modbusMaster?.ReadCoils(1, 10081, 1),
|
||
ButtonStatus = _modbusMaster?.ReadCoils(1, 10030, 1),
|
||
LowStatus = _modbusMaster?.ReadCoils(1, 10031, 1),
|
||
HighStatus = _modbusMaster?.ReadCoils(1, 10032, 1),
|
||
Valve2 = _modbusMaster?.ReadCoils(1, 10008, 1),
|
||
Valve13 = _modbusMaster?.ReadCoils(1, 10001, 1),
|
||
Valve3 = _modbusMaster?.ReadCoils(1, 10006, 1),
|
||
Valve4 = _modbusMaster?.ReadCoils(1, 10013, 1),
|
||
Valve5 = _modbusMaster?.ReadCoils(1, 10005, 1),
|
||
Valve6 = _modbusMaster?.ReadCoils(1, 10007, 1),
|
||
Valve7 = _modbusMaster?.ReadCoils(1, 10004, 1),
|
||
Valve8 = _modbusMaster?.ReadCoils(1, 10010, 1),
|
||
Valve9 = _modbusMaster?.ReadCoils(1, 10012, 1),
|
||
Valve10 = _modbusMaster?.ReadCoils(1, 10009, 1),
|
||
Valve12 = _modbusMaster?.ReadCoils(1, 10004, 1)
|
||
};
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine($"Modbus读取阀门状态失败: {ex.Message}");
|
||
return null;
|
||
}
|
||
});
|
||
|
||
if (modbusResults == null) return;
|
||
|
||
// 统一用SafeInvoke更新所有UI控件
|
||
SafeInvoke(() =>
|
||
{
|
||
//测试按键
|
||
if (modbusResults.TestStatus != null && modbusResults.TestStatus.Length > 0)
|
||
{
|
||
if (uiButton2 != null && !uiButton2.IsDisposed)
|
||
{
|
||
if (modbusResults.TestStatus[0])
|
||
{
|
||
uiButton2.Text = "测试中";
|
||
uiButton2.ForeColor = System.Drawing.Color.Red;
|
||
boolSignal1.Value = true;
|
||
boolSignal1.CheckRisingEdge();
|
||
}
|
||
else
|
||
{
|
||
uiButton2.Text = "启动测试";
|
||
uiButton2.ForeColor = System.Drawing.Color.White;
|
||
boolSignal1.CheckRisingEdge();
|
||
boolSignal1.Value = false;
|
||
}
|
||
}
|
||
}
|
||
|
||
//高低温切换
|
||
if (modbusResults.ButtonStatus != null && modbusResults.ButtonStatus.Length > 0 && uiSwitch1 != null && !uiSwitch1.IsDisposed)
|
||
{
|
||
bool newSwitchState = modbusResults.ButtonStatus[0];
|
||
bool currentSwitchState = uiSwitch1.Active;
|
||
|
||
// 只有状态真正改变时才更新
|
||
if (newSwitchState != currentSwitchState)
|
||
{
|
||
uiSwitch1.Active = newSwitchState;
|
||
}
|
||
}
|
||
|
||
//低温指示
|
||
if (modbusResults.LowStatus != null && modbusResults.LowStatus.Length > 0 && uiLight1 != null && !uiLight1.IsDisposed)
|
||
{
|
||
bool previousLowTempState = uiLight1.State == UILightState.On;
|
||
bool currentLowTempState = modbusResults.LowStatus[0];
|
||
|
||
uiLight1.State = currentLowTempState ? UILightState.On : UILightState.Off;
|
||
|
||
// 如果温度模式状态发生变化,更新控件可见性
|
||
if (previousLowTempState != currentLowTempState)
|
||
{
|
||
UpdateControlsVisibilityByMode();
|
||
}
|
||
}
|
||
|
||
//高温指示
|
||
if (modbusResults.HighStatus != null && modbusResults.HighStatus.Length > 0 && uiLight2 != null && !uiLight2.IsDisposed)
|
||
{
|
||
bool previousHighTempState = uiLight2.State == UILightState.On;
|
||
bool currentHighTempState = modbusResults.HighStatus[0];
|
||
|
||
uiLight2.State = currentHighTempState ? UILightState.On : UILightState.Off;
|
||
|
||
// 如果温度模式状态发生变化,更新控件可见性
|
||
if (previousHighTempState != currentHighTempState)
|
||
{
|
||
UpdateControlsVisibilityByMode();
|
||
}
|
||
}
|
||
|
||
//高压进阀指示
|
||
if (modbusResults.Valve2 != null && modbusResults.Valve2.Length > 0 && uiLight4 != null && !uiLight4.IsDisposed)
|
||
{
|
||
uiLight4.State = modbusResults.Valve2[0] ? UILightState.On : UILightState.Off;
|
||
}
|
||
|
||
//高压出阀
|
||
if (modbusResults.Valve13 != null && modbusResults.Valve13.Length > 0 && uiLight3 != null && !uiLight3.IsDisposed)
|
||
{
|
||
uiLight3.State = modbusResults.Valve13[0] ? UILightState.On : UILightState.Off;
|
||
}
|
||
|
||
//常温抽水阀指示
|
||
if (modbusResults.Valve3 != null && modbusResults.Valve3.Length > 0 && uiLight5 != null && !uiLight5.IsDisposed)
|
||
{
|
||
uiLight5.State = modbusResults.Valve3[0] ? UILightState.On : UILightState.Off;
|
||
}
|
||
|
||
//常温水箱加水指示
|
||
if (modbusResults.Valve4 != null && modbusResults.Valve4.Length > 0)
|
||
{
|
||
if (uiLight6 != null && !uiLight6.IsDisposed)
|
||
uiLight6.State = modbusResults.Valve4[0] ? UILightState.On : UILightState.Off;
|
||
|
||
if (uiButton13 != null && !uiButton13.IsDisposed)
|
||
{
|
||
if (modbusResults.Valve4[0])
|
||
{
|
||
uiButton13.ForeColor = Color.Red;
|
||
uiButton13.Text = "常温加水中";
|
||
}
|
||
else
|
||
{
|
||
uiButton13.ForeColor = Color.White;
|
||
uiButton13.Text = "常温加水";
|
||
}
|
||
}
|
||
}
|
||
|
||
//高温抽水阀指示
|
||
if (modbusResults.Valve5 != null && modbusResults.Valve5.Length > 0 && uiLight7 != null && !uiLight7.IsDisposed)
|
||
{
|
||
uiLight7.State = modbusResults.Valve5[0] ? UILightState.On : UILightState.Off;
|
||
}
|
||
|
||
//空气抽气阀指示
|
||
if (modbusResults.Valve6 != null && modbusResults.Valve6.Length > 0 && uiLight8 != null && !uiLight8.IsDisposed)
|
||
{
|
||
uiLight8.State = modbusResults.Valve6[0] ? UILightState.On : UILightState.Off;
|
||
}
|
||
|
||
//加热状态指示
|
||
if (modbusResults.Valve7 != null && modbusResults.Valve7.Length > 0 && uiLight9 != null && !uiLight9.IsDisposed)
|
||
{
|
||
uiLight9.State = modbusResults.Valve7[0] ? UILightState.On : UILightState.Off;
|
||
}
|
||
|
||
//常温回水阀指示
|
||
if (modbusResults.Valve8 != null && modbusResults.Valve8.Length > 0 && uiLight10 != null && !uiLight10.IsDisposed)
|
||
{
|
||
uiLight10.State = modbusResults.Valve8[0] ? UILightState.On : UILightState.Off;
|
||
}
|
||
|
||
//高温水箱加水指示
|
||
if (modbusResults.Valve9 != null && modbusResults.Valve9.Length > 0)
|
||
{
|
||
if (uiLight11 != null && !uiLight11.IsDisposed)
|
||
uiLight11.State = modbusResults.Valve9[0] ? UILightState.On : UILightState.Off;
|
||
|
||
if (uiButton5 != null && !uiButton5.IsDisposed)
|
||
{
|
||
if (modbusResults.Valve9[0])
|
||
{
|
||
uiButton5.ForeColor = Color.Red;
|
||
uiButton5.Text = "高温加水中";
|
||
}
|
||
else
|
||
{
|
||
uiButton5.ForeColor = Color.White;
|
||
uiButton5.Text = "高温加水";
|
||
}
|
||
}
|
||
}
|
||
|
||
//高温回水阀指示
|
||
if (modbusResults.Valve10 != null && modbusResults.Valve10.Length > 0 && uiLight12 != null && !uiLight12.IsDisposed)
|
||
{
|
||
uiLight12.State = modbusResults.Valve10[0] ? UILightState.On : UILightState.Off;
|
||
}
|
||
|
||
//水箱加热指示
|
||
if (modbusResults.Valve12 != null && modbusResults.Valve12.Length > 0 && uiButton4 != null && !uiButton4.IsDisposed)
|
||
{
|
||
if (modbusResults.Valve12[0])
|
||
{
|
||
uiButton4.ForeColor = Color.Red;
|
||
uiButton4.Text = "加热中";
|
||
}
|
||
else
|
||
{
|
||
uiButton4.ForeColor = Color.White;
|
||
uiButton4.Text = "水箱加热";
|
||
}
|
||
}
|
||
|
||
// 更新温度模式
|
||
// uiLabel11 已移除,温度模式通过 uiSwitch1 切换按钮显示
|
||
});
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine($"[错误] 读取阀门状态失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
|
||
private void NormalTemperatureMode_Load(object sender, EventArgs e)
|
||
{
|
||
// 权限检查:只有管理员才能看到"录入系统"按钮
|
||
if (!LoginData.IsAdmin())
|
||
{
|
||
// 普通用户隐藏"录入系统"按钮
|
||
uiButton7.Visible = false;
|
||
|
||
// 调试输出
|
||
System.Diagnostics.Debug.WriteLine($"[NormalTemperatureMode] 普通用户登录,隐藏录入系统按钮");
|
||
}
|
||
else
|
||
{
|
||
// 管理员显示"录入系统"按钮
|
||
uiButton7.Visible = true;
|
||
|
||
// 调试输出
|
||
System.Diagnostics.Debug.WriteLine($"[NormalTemperatureMode] 管理员登录,显示录入系统按钮");
|
||
}
|
||
|
||
string plcIp = "192.168.1.10";
|
||
// string plcIp = "127.0.0.1";
|
||
bool initSuccess = Data.ModbusResourceManager.Instance.Init(plcIp, 502);
|
||
if (!initSuccess)
|
||
{
|
||
MessageBox.Show("连接Modbus服务器失败!", "错误");
|
||
this.Close();
|
||
return;
|
||
}
|
||
|
||
// 检查连接状态
|
||
if (_tcpClient == null || !_tcpClient.Connected)
|
||
{
|
||
MessageBox.Show("Modbus连接异常!", "错误");
|
||
this.Close();
|
||
return;
|
||
}
|
||
|
||
|
||
ma = new Function(_modbusMaster);
|
||
c = new DataChange();
|
||
// 暂时注释
|
||
_modbusMaster?.WriteSingleCoil(1, 10030, true);
|
||
boolSignal1.OnRisingEdge += BoolSignal1_OnRisingEdge;
|
||
|
||
// 初始化图表
|
||
try
|
||
{
|
||
_chartManager.InitializeChart(uiPanel_ChartPlaceholder);
|
||
Debug.WriteLine("[NormalTemperatureMode] 图表初始化成功");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine($"[NormalTemperatureMode] 图表初始化失败: {ex.Message}");
|
||
}
|
||
|
||
// 在 Load 完成初始化后再启动定时器,避免定时器在 c / ma 未就绪时触发访问导致异常
|
||
//_readTimer?.Start();
|
||
//_readTimerTwo?.Start();
|
||
}
|
||
|
||
void BoolSignal1_OnRisingEdge()
|
||
{
|
||
if (isAddTag) return;
|
||
|
||
// 使用SafeInvoke确保UI读取操作在UI线程执行
|
||
SafeInvoke(() =>
|
||
{
|
||
uiTextBox3.Text = uiLabel14.Text;//初始压力
|
||
uiTextBox8.Text = uiTextBox5.Text;//保压时间
|
||
uiTextBox6.Text = uiLabel22.Text;//压差
|
||
uiTextBox7.Text = uiLabel19.Text;//结束压力
|
||
|
||
// 获取联络单号和件号
|
||
string contactNumber = uiTextBox2.Text.Trim();
|
||
string itemNumber = uiTextBox10.Text.Trim();
|
||
// 组合条码用于兼容性
|
||
string barcode = $"{contactNumber}-{itemNumber}";
|
||
|
||
CurrentReport.Add(new ConductivityTestData
|
||
{
|
||
barcode = barcode,
|
||
ContactNumber = contactNumber,
|
||
ItemNumber = itemNumber,
|
||
CreateTime = DateTime.Now,
|
||
diffpressure = uiTextBox6.Text.ToDouble(),
|
||
dwelltime = uiTextBox8.Text.ToDouble(),
|
||
temperature = uiTextBox4.Text.ToDouble(),
|
||
endpressure = uiTextBox7.Text.ToDouble(),
|
||
startpressure = uiTextBox3.Text.ToDouble(),
|
||
Type = uiLight1.State == UILightState.On ? 1 : 0
|
||
});
|
||
|
||
_repository.InsertReportItems(new ConductivityTestData
|
||
{
|
||
barcode = barcode,
|
||
ContactNumber = contactNumber,
|
||
ItemNumber = itemNumber,
|
||
CreateTime = DateTime.Now,
|
||
diffpressure = uiTextBox6.Text.ToDouble(),
|
||
dwelltime = uiTextBox8.Text.ToDouble(),
|
||
temperature = uiTextBox4.Text.ToDouble(),
|
||
endpressure = uiTextBox7.Text.ToDouble(),
|
||
startpressure = uiTextBox3.Text.ToDouble(),
|
||
Type = uiLight1.State == UILightState.On ? 1 : 0
|
||
});
|
||
|
||
uiTextBox2.Text = string.Empty;
|
||
uiTextBox10.Text = string.Empty;
|
||
});
|
||
|
||
isAddTag = true;
|
||
}
|
||
private bool TryReconnect()
|
||
{
|
||
try
|
||
{
|
||
string plcIp = "192.168.1.10";
|
||
//string plcIp = "127.0.0.1";
|
||
bool initSuccess = Data.ModbusResourceManager.Instance.Init(plcIp, 502);
|
||
if (initSuccess)
|
||
{
|
||
ma = new Function(_modbusMaster);
|
||
return true;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine($"[错误] 重连失败: {ex.Message}");
|
||
}
|
||
return false;
|
||
}
|
||
//private void SwitchWindow<T>(ref T windowInstance, Func<T> createFunc) where T : UIForm
|
||
//{
|
||
// _isSwitchingWindow = true;
|
||
// _readTimer?.Stop();
|
||
// _readTimerTwo?.Stop(); // 停止第二个定时器
|
||
|
||
// // 2. 检查资源是否可用(添加重连机制)
|
||
// if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
|
||
// {
|
||
// //尝试重新连接
|
||
// bool reconnectSuccess = TryReconnect();
|
||
// if (!reconnectSuccess)
|
||
// {
|
||
// MessageBox.Show("TCP连接已断开,请重新连接!", "提示");
|
||
// return;
|
||
// }
|
||
// }
|
||
|
||
// // 3. 复用窗口实例:不存在则创建,存在则激活
|
||
// if (windowInstance == null || windowInstance.IsDisposed)
|
||
// {
|
||
// windowInstance = createFunc();
|
||
// windowInstance.FormClosed += (s, e) =>
|
||
// {
|
||
// this.Invoke(new Action(() =>
|
||
// {
|
||
// _isSwitchingWindow = false;
|
||
// _readTimer?.Start();
|
||
// _readTimerTwo?.Start(); // 恢复第二个定时器
|
||
// this.Show();
|
||
// this.Activate();
|
||
// }));
|
||
// };
|
||
// }
|
||
// else
|
||
// {
|
||
// windowInstance.Activate();
|
||
// return;
|
||
// }
|
||
|
||
// this.Hide();
|
||
// windowInstance.Show();
|
||
//}
|
||
|
||
private void SwitchWindow<T>(T windowInstance, Func<T> createFunc) where T : UIForm
|
||
{
|
||
_isSwitchingWindow = true;
|
||
_readTimer?.Stop();
|
||
_readTimerTwo?.Stop();
|
||
_alarmMonitorTimer?.Stop();
|
||
|
||
// 检查资源是否可用
|
||
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
|
||
{
|
||
bool reconnectSuccess = TryReconnect();
|
||
if (!reconnectSuccess)
|
||
{
|
||
SafeInvoke(() =>
|
||
{
|
||
MessageBox.Show("TCP连接已断开,请重新连接!", "提示");
|
||
});
|
||
return;
|
||
}
|
||
}
|
||
|
||
// 需要将 windowInstance 声明为局部变量
|
||
T localInstance = windowInstance;
|
||
|
||
// 复用窗口实例
|
||
if (localInstance == null || localInstance.IsDisposed)
|
||
{
|
||
localInstance = createFunc();
|
||
localInstance.FormClosed += (s, e) =>
|
||
{
|
||
SafeInvoke(() =>
|
||
{
|
||
_isSwitchingWindow = false;
|
||
_readTimer?.Start();
|
||
_readTimerTwo?.Start();
|
||
_alarmMonitorTimer?.Start();
|
||
this.Show();
|
||
this.Activate();
|
||
});
|
||
};
|
||
}
|
||
else
|
||
{
|
||
SafeInvoke(() => localInstance.Activate());
|
||
return;
|
||
}
|
||
|
||
SafeInvoke(() =>
|
||
{
|
||
this.Hide();
|
||
localInstance.Show();
|
||
});
|
||
|
||
// 如果需要更新外部引用,可以返回实例
|
||
// return localInstance;
|
||
}
|
||
|
||
private void NormalTemperatureMode_FormClosing(object sender, FormClosingEventArgs e)
|
||
{
|
||
// 停止定时器
|
||
_readTimer?.Stop();
|
||
_readTimer?.Dispose();
|
||
_readTimerTwo?.Stop();
|
||
_readTimerTwo?.Dispose();
|
||
|
||
// 停止报警监控定时器
|
||
_alarmMonitorTimer?.Stop();
|
||
_alarmMonitorTimer?.Dispose();
|
||
|
||
// 释放图表资源
|
||
_chartManager?.Dispose();
|
||
|
||
// 仅用户主动关闭时退出应用
|
||
if (e.CloseReason == CloseReason.UserClosing)
|
||
{
|
||
ModbusResourceManager.Instance?.Dispose();
|
||
Application.Exit();
|
||
}
|
||
}
|
||
|
||
private void NormalTemperatureMode_FormClosed_1(object sender, FormClosedEventArgs e)
|
||
{
|
||
_coeffiicientsetting?.Dispose();
|
||
}
|
||
|
||
//压力设置
|
||
private void uiTextBox1_Click(object sender, EventArgs e)
|
||
{
|
||
SafeInvoke(() =>
|
||
{
|
||
ma?.WriteToPLCForNew(uiTextBox1.Text.Trim(), 2400, Function.DataType.浮点型);
|
||
});
|
||
}
|
||
|
||
//测试保压时间设置
|
||
private void uiTextBox5_Click(object sender, EventArgs e)
|
||
{
|
||
SafeInvoke(() =>
|
||
{
|
||
ma?.WriteToPLCForNew(uiTextBox5.Text.Trim(), 2404, Function.DataType.整形);
|
||
});
|
||
}
|
||
|
||
#region 按钮控件
|
||
|
||
//常温加水
|
||
private void uiButton13_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.BtnClickFunctionForNew(Function.ButtonType.切换型, 10013);
|
||
}
|
||
|
||
//隐藏
|
||
private void uiButton14_MouseDown(object sender, MouseEventArgs e)
|
||
{
|
||
if (e.Button == MouseButtons.Left)
|
||
{
|
||
pressStopwatch.Restart();
|
||
}
|
||
}
|
||
private void uiButton14_MouseUp(object sender, MouseEventArgs e)
|
||
{
|
||
if (e.Button == MouseButtons.Left)
|
||
{
|
||
pressStopwatch.Stop();
|
||
if (pressStopwatch.ElapsedMilliseconds >= LONG_PRESS_THRESHOLD)
|
||
{
|
||
// 执行长按操作 - 打开系数设置
|
||
EnterFunction();
|
||
}
|
||
else
|
||
{
|
||
// 执行点击操作 - 打开状态设置窗体
|
||
OpenStatusSettingsForm();
|
||
}
|
||
}
|
||
}
|
||
private void EnterFunction()
|
||
{
|
||
// 长按后进入的功能
|
||
SwitchWindow(_coeffiicientsetting, () => new Coeffiicientsetting());
|
||
}
|
||
|
||
//切换报告界面
|
||
private void uiButton1_Click(object sender, EventArgs e)
|
||
{
|
||
SwitchWindow(_report, () => new Report(CurrentReport));
|
||
}
|
||
|
||
//箱体温度设置
|
||
private void uiTextBox4_Click(object sender, EventArgs e)
|
||
{
|
||
SafeInvoke(() =>
|
||
{
|
||
ma?.WriteToPLCForNew(uiTextBox4.Text.Trim(), 2402, Function.DataType.浮点型);
|
||
});
|
||
}
|
||
|
||
//启动测试
|
||
private void uiButton2_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.BtnClickFunctionForNew(Function.ButtonType.切换型, 10080);
|
||
isAddTag = false;
|
||
|
||
// 清除图表数据,开始新的测试
|
||
_chartManager?.ClearData();
|
||
Debug.WriteLine("[NormalTemperatureMode] 启动测试,清除图表数据");
|
||
}
|
||
|
||
//停止测试
|
||
private void uiButton3_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.BtnClickFunctionForNew(Function.ButtonType.复归型, 10082);
|
||
}
|
||
|
||
//切换实验模式
|
||
private async void uiSwitch1_Click(object sender, EventArgs e)
|
||
{
|
||
try
|
||
{
|
||
// 暂停定时器,避免并发访问Modbus
|
||
_readTimer?.Stop();
|
||
_readTimerTwo?.Stop();
|
||
_alarmMonitorTimer?.Stop();
|
||
|
||
// 在后台线程执行Modbus操作
|
||
await Task.Run(() =>
|
||
{
|
||
try
|
||
{
|
||
ma?.BtnClickFunctionForNew(Function.ButtonType.切换型, 10030);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine($"[uiSwitch1_Click] 切换模式失败: {ex.Message}");
|
||
SafeInvoke(() =>
|
||
{
|
||
MessageBox.Show($"切换模式失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
});
|
||
}
|
||
});
|
||
|
||
// 延迟等待PLC状态更新
|
||
await Task.Delay(800);
|
||
|
||
// 更新控件可见性
|
||
SafeInvoke(() =>
|
||
{
|
||
UpdateControlsVisibilityByMode();
|
||
|
||
// 更新图表模式
|
||
bool isHighTempMode = uiLight2 != null && uiLight2.State == UILightState.On;
|
||
_chartManager?.UpdateChartMode(isHighTempMode);
|
||
});
|
||
|
||
// 恢复定时器
|
||
_readTimer?.Start();
|
||
_readTimerTwo?.Start();
|
||
_alarmMonitorTimer?.Start();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine($"[uiSwitch1_Click] 异常: {ex.Message}");
|
||
|
||
// 确保定时器恢复
|
||
_readTimer?.Start();
|
||
_readTimerTwo?.Start();
|
||
_alarmMonitorTimer?.Start();
|
||
}
|
||
}
|
||
|
||
//出口温度设置
|
||
private void uiTextBox9_Click(object sender, EventArgs e)
|
||
{
|
||
SafeInvoke(() =>
|
||
{
|
||
ma?.WriteToPLCForNew(uiTextBox9.Text.Trim(), 2412, Function.DataType.浮点型);
|
||
});
|
||
}
|
||
|
||
//高温加水
|
||
private void uiButton5_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.BtnClickFunctionForNew(Function.ButtonType.切换型, 10012);
|
||
}
|
||
|
||
//高温加热
|
||
private void uiButton4_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.BtnClickFunctionForNew(Function.ButtonType.切换型, 10004);
|
||
}
|
||
|
||
//清除报警
|
||
private void uiButton6_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.BtnClickFunctionForNew(Function.ButtonType.复归型, 10025);
|
||
|
||
// 同时清除本地记录的报警状态
|
||
ClearAllAlarms();
|
||
}
|
||
#endregion
|
||
|
||
private void ClearAllAlarms()
|
||
{
|
||
// 重置所有报警状态
|
||
foreach (var address in _alarmStatus.Keys.ToList())
|
||
{
|
||
_alarmStatus[address] = false;
|
||
}
|
||
|
||
SafeInvoke(() =>
|
||
{
|
||
MessageBox.Show("所有报警状态已重置", "提示");
|
||
});
|
||
}
|
||
|
||
private void NormalTemperatureMode_Shown(object sender, EventArgs e)
|
||
{
|
||
if (_modbusMaster != null)
|
||
{
|
||
|
||
_readTimer.Start();
|
||
_readTimerTwo.Start();
|
||
|
||
if (_alarmMonitorTimer != null)
|
||
{
|
||
_alarmMonitorTimer.Start();
|
||
}
|
||
}
|
||
|
||
// 初始化时根据当前模式更新控件可见性
|
||
UpdateControlsVisibilityByMode();
|
||
}
|
||
|
||
//返回录入系统
|
||
private void uiButton7_Click(object sender, EventArgs e)
|
||
{
|
||
SwitchWindow(_scanImport, () => new ScanImport());
|
||
}
|
||
|
||
|
||
private string _currentTemperatureMode = ""; // 保存当前温度模式
|
||
private string _currentBarcode = ""; // 保存当前条码
|
||
|
||
|
||
private void uiButton8_Click(object sender, EventArgs e)
|
||
{
|
||
try
|
||
{
|
||
// 1. 获取联络单号和件号输入(确保在UI线程读取)
|
||
string contactNumber = "";
|
||
string itemNumber = "";
|
||
SafeInvoke(() =>
|
||
{
|
||
contactNumber = uiTextBox2.Text.Trim();
|
||
itemNumber = uiTextBox10.Text.Trim();
|
||
});
|
||
|
||
if (string.IsNullOrEmpty(contactNumber))
|
||
{
|
||
SafeInvoke(() =>
|
||
{
|
||
MessageBox.Show("请输入联络单号!");
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (string.IsNullOrEmpty(itemNumber))
|
||
{
|
||
SafeInvoke(() =>
|
||
{
|
||
MessageBox.Show("请输入件号!");
|
||
});
|
||
return;
|
||
}
|
||
|
||
// 组合成完整的条码(联络单号-件号)
|
||
string barcode = $"{contactNumber}-{itemNumber}";
|
||
|
||
// 2. 从数据库查询数据
|
||
ScanData scanData = GetScanDataByBarcode(barcode);
|
||
|
||
if (scanData == null)
|
||
{
|
||
SafeInvoke(() =>
|
||
{
|
||
MessageBox.Show($"未找到联络单号 {contactNumber} 和件号 {itemNumber} 的记录!");
|
||
});
|
||
return;
|
||
}
|
||
|
||
// 3. 连接到PLC并写入数据
|
||
WriteScanDataToPLC(scanData);
|
||
|
||
// 4. 保存当前条码和温度模式
|
||
_currentBarcode = barcode;
|
||
_currentTemperatureMode = scanData.TemperatureMode.ToString();
|
||
|
||
// 5. 更新显示
|
||
SafeInvoke(() =>
|
||
{
|
||
// uiLabel11 已移除,温度模式通过 uiSwitch1 切换按钮显示
|
||
});
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
SafeInvoke(() =>
|
||
{
|
||
MessageBox.Show($"操作失败:{ex.Message}");
|
||
});
|
||
}
|
||
|
||
}
|
||
|
||
private ScanData GetScanDataByBarcode(string barcode)
|
||
{
|
||
using (var connection = new MySqlConnection(_repository._connectionString))
|
||
{
|
||
connection.Open();
|
||
var sql = @"SELECT * FROM scandata
|
||
WHERE barcode = @barcode
|
||
ORDER BY CreateTime DESC
|
||
LIMIT 1";
|
||
|
||
return connection.QueryFirstOrDefault<ScanData>(sql, new { barcode });
|
||
}
|
||
}
|
||
|
||
private void WriteScanDataToPLC(ScanData data)
|
||
{
|
||
// 写入压力到PLC地址2400(浮点型)
|
||
//ma?.WriteToPLCForNew(data.diffpressure.ToString(), 2400, Function.DataType.浮点型);
|
||
|
||
//// 写入测试保压时间到PLC地址2404(整形)
|
||
//ma?.WriteToPLCForNew(data.dwelltime.ToString("F0"), 2404, Function.DataType.整形);
|
||
|
||
//// 写入温度到PLC地址2402(浮点型)
|
||
//ma?.WriteToPLCForNew(data.temperature.ToString(), 2402, Function.DataType.浮点型);
|
||
|
||
//// 写入出口温度到PLC地址2412(浮点型)
|
||
//ma?.WriteToPLCForNew(data.exit_temperature.ToString(), 2412, Function.DataType.浮点型);
|
||
|
||
// 1. 写入压力到PLC地址2400(浮点型)
|
||
float pressure = data.diffpressure;
|
||
ushort[] pressureRegisters = ConvertFloatToRegisters(pressure);
|
||
_modbusMaster.WriteMultipleRegisters(1, 2400, pressureRegisters);
|
||
|
||
// 2. 写入测试保压时间到PLC地址2404(整形)
|
||
int dwellTime = (int)data.dwelltime;
|
||
ushort[] dwellTimeRegisters = ConvertIntToRegisters(dwellTime);
|
||
_modbusMaster.WriteMultipleRegisters(1, 2404, dwellTimeRegisters);
|
||
|
||
// 3. 写入温度到PLC地址2402(浮点型)
|
||
float temperature = data.temperature;
|
||
ushort[] temperatureRegisters = ConvertFloatToRegisters(temperature);
|
||
_modbusMaster.WriteMultipleRegisters(1, 2402, temperatureRegisters);
|
||
|
||
// 4. 写入出口温度到PLC地址2412(浮点型)
|
||
float exitTemperature = data.exit_temperature;
|
||
ushort[] exitTempRegisters = ConvertFloatToRegisters(exitTemperature);
|
||
_modbusMaster.WriteMultipleRegisters(1, 2412, exitTempRegisters);
|
||
|
||
|
||
}
|
||
|
||
// 将浮点数转换为寄存器数组(2个寄存器)
|
||
private ushort[] ConvertFloatToRegisters(float value)
|
||
{
|
||
byte[] bytes = BitConverter.GetBytes(value);
|
||
ushort[] registers = new ushort[2];
|
||
registers[0] = BitConverter.ToUInt16(bytes, 0); // 第一个寄存器(低位)
|
||
registers[1] = BitConverter.ToUInt16(bytes, 2); // 第二个寄存器(高位)
|
||
return registers;
|
||
|
||
}
|
||
|
||
// 将整数转换为寄存器数组(2个寄存器)
|
||
private ushort[] ConvertIntToRegisters(int value)
|
||
{
|
||
byte[] bytes = BitConverter.GetBytes(value);
|
||
ushort[] registers = new ushort[2];
|
||
registers[0] = BitConverter.ToUInt16(bytes, 0); // 第一个寄存器(低位)
|
||
registers[1] = BitConverter.ToUInt16(bytes, 2); // 第二个寄存器(高位)
|
||
return registers;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 更新状态设置窗体的显示
|
||
/// </summary>
|
||
public void UpdateStatusSettingsForm(StatusSettingsForm form)
|
||
{
|
||
if (form == null || form.IsDisposed)
|
||
return;
|
||
|
||
try
|
||
{
|
||
// 更新温度模式状态
|
||
var light1State = uiLight1 != null ? uiLight1.State : UILightState.Off;
|
||
var light2State = uiLight2 != null ? uiLight2.State : UILightState.Off;
|
||
var modeText = _currentTemperatureMode ?? "";
|
||
|
||
form.UpdateTempModeStatus(light1State, light2State, modeText);
|
||
|
||
// 更新阀门状态
|
||
form.UpdateValveStatus(
|
||
uiLight3 != null ? uiLight3.State : UILightState.Off,
|
||
uiLight4 != null ? uiLight4.State : UILightState.Off,
|
||
uiLight5 != null ? uiLight5.State : UILightState.Off,
|
||
uiLight6 != null ? uiLight6.State : UILightState.Off,
|
||
uiLight7 != null ? uiLight7.State : UILightState.Off,
|
||
uiLight8 != null ? uiLight8.State : UILightState.Off,
|
||
uiLight9 != null ? uiLight9.State : UILightState.Off,
|
||
uiLight10 != null ? uiLight10.State : UILightState.Off,
|
||
uiLight11 != null ? uiLight11.State : UILightState.Off,
|
||
uiLight12 != null ? uiLight12.State : UILightState.Off
|
||
);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine($"更新状态设置窗体失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 打开状态设置窗体
|
||
/// </summary>
|
||
private void OpenStatusSettingsForm()
|
||
{
|
||
if (_statusSettingsForm == null || _statusSettingsForm.IsDisposed)
|
||
{
|
||
_statusSettingsForm = new StatusSettingsForm(this);
|
||
_statusSettingsForm.Show();
|
||
}
|
||
else
|
||
{
|
||
_statusSettingsForm.Activate();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置按钮点击事件 - 打开状态设置窗体
|
||
/// </summary>
|
||
private void uiButton_Settings_Click(object sender, EventArgs e)
|
||
{
|
||
OpenStatusSettingsForm();
|
||
}
|
||
|
||
public event EventHandler ReturnToLoginRequested;
|
||
//返回登录
|
||
private void uiButton9_Click(object sender, EventArgs e)
|
||
{
|
||
// 停止所有操作
|
||
_readTimer?.Stop();
|
||
_readTimerTwo?.Stop();
|
||
_alarmMonitorTimer?.Stop();
|
||
|
||
// 释放资源
|
||
ModbusResourceManager.Instance?.Dispose();
|
||
|
||
// 直接重新启动应用程序
|
||
Application.Restart();
|
||
|
||
// 关闭当前窗口
|
||
Environment.Exit(0);
|
||
}
|
||
|
||
/// <summary>
|
||
/// <summary>
|
||
/// 根据温度模式更新控件可见性
|
||
/// 常温模式:显示常温相关参数(常温实时液位、常温加水)
|
||
/// 高温模式:显示高温相关参数(高温实时液位、箱体温度、出口温度、高温加水、水箱加热)
|
||
/// </summary>
|
||
private void UpdateControlsVisibilityByMode()
|
||
{
|
||
try
|
||
{
|
||
// 判断当前是否为高温模式(uiLight2亮起表示高温模式)
|
||
bool isHighTempMode = uiLight2 != null && uiLight2.State == UILightState.On;
|
||
bool isLowTempMode = uiLight1 != null && uiLight1.State == UILightState.On;
|
||
|
||
Debug.WriteLine($"[UpdateControlsVisibilityByMode] 开始更新 - 高温模式: {isHighTempMode}, 常温模式: {isLowTempMode}");
|
||
|
||
// ========== 高温模式专属控件(高温模式显示,常温模式隐藏) ==========
|
||
|
||
// 高温实时液位(mm) - uiPanel31包含uiLabel7, uiLabel8, uiLabel34, uiProcessBar2
|
||
if (uiPanel31 != null && !uiPanel31.IsDisposed)
|
||
{
|
||
uiPanel31.Visible = isHighTempMode;
|
||
Debug.WriteLine($"[UpdateControlsVisibilityByMode] uiPanel31(高温液位) Visible = {isHighTempMode}");
|
||
}
|
||
|
||
// 箱体温度(°C) - uiPanel35包含uiLabel42, uiLabel43(实时数据监控区域)
|
||
if (uiPanel35 != null && !uiPanel35.IsDisposed)
|
||
{
|
||
uiPanel35.Visible = isHighTempMode;
|
||
Debug.WriteLine($"[UpdateControlsVisibilityByMode] uiPanel35(箱体温度) Visible = {isHighTempMode}");
|
||
}
|
||
|
||
// 出口温度(°C) - uiPanel33包含uiLabel38, uiLabel39(实时数据监控区域)
|
||
if (uiPanel33 != null && !uiPanel33.IsDisposed)
|
||
{
|
||
uiPanel33.Visible = isHighTempMode;
|
||
Debug.WriteLine($"[UpdateControlsVisibilityByMode] uiPanel33(出口温度) Visible = {isHighTempMode}");
|
||
}
|
||
|
||
// 高温加水按钮 - uiButton5
|
||
if (uiButton5 != null && !uiButton5.IsDisposed)
|
||
{
|
||
uiButton5.Visible = isHighTempMode;
|
||
Debug.WriteLine($"[UpdateControlsVisibilityByMode] uiButton5(高温加水) Visible = {isHighTempMode}");
|
||
}
|
||
|
||
// 高温加水指示灯 - uiLight11
|
||
if (uiPanel43 != null && !uiPanel43.IsDisposed)
|
||
{
|
||
uiPanel43.Visible = isHighTempMode;
|
||
Debug.WriteLine($"[UpdateControlsVisibilityByMode] uiPanel43(高温加水指示灯) Visible = {isHighTempMode}");
|
||
}
|
||
|
||
// 水箱加热按钮 - uiButton4(用户操作设定区域)
|
||
if (uiButton4 != null && !uiButton4.IsDisposed)
|
||
{
|
||
uiButton4.Visible = isHighTempMode;
|
||
Debug.WriteLine($"[UpdateControlsVisibilityByMode] uiButton4(水箱加热) Visible = {isHighTempMode}");
|
||
}
|
||
|
||
// 出口温度判定设置 - uiLabel48和uiTextBox9(用户操作设定区域)
|
||
if (uiLabel48 != null && !uiLabel48.IsDisposed)
|
||
{
|
||
uiLabel48.Visible = isHighTempMode;
|
||
Debug.WriteLine($"[UpdateControlsVisibilityByMode] uiLabel48(出口温度标签) Visible = {isHighTempMode}");
|
||
}
|
||
if (uiTextBox9 != null && !uiTextBox9.IsDisposed)
|
||
{
|
||
uiTextBox9.Visible = isHighTempMode;
|
||
Debug.WriteLine($"[UpdateControlsVisibilityByMode] uiTextBox9(出口温度输入) Visible = {isHighTempMode}");
|
||
}
|
||
|
||
// 写入按钮 - uiButton8(用于写入联络单号和件号数据到PLC,常温和高温模式都需要)
|
||
// 注意:写入按钮应该始终显示,因为联络单号和件号在两种模式下都需要
|
||
if (uiButton8 != null && !uiButton8.IsDisposed)
|
||
{
|
||
uiButton8.Visible = true; // 始终显示写入按钮
|
||
Debug.WriteLine($"[UpdateControlsVisibilityByMode] uiButton8(写入按钮) Visible = true (始终显示)");
|
||
}
|
||
|
||
// 箱体温度设置 - uiLabel37和uiTextBox4(用户操作设定区域)
|
||
if (uiLabel37 != null && !uiLabel37.IsDisposed)
|
||
{
|
||
uiLabel37.Visible = isHighTempMode;
|
||
Debug.WriteLine($"[UpdateControlsVisibilityByMode] uiLabel37(箱体温度标签) Visible = {isHighTempMode}");
|
||
}
|
||
if (uiTextBox4 != null && !uiTextBox4.IsDisposed)
|
||
{
|
||
uiTextBox4.Visible = isHighTempMode;
|
||
Debug.WriteLine($"[UpdateControlsVisibilityByMode] uiTextBox4(箱体温度输入) Visible = {isHighTempMode}");
|
||
}
|
||
|
||
// ========== 常温模式专属控件(常温模式显示,高温模式隐藏) ==========
|
||
|
||
// 常温实时液位(mm) - uiPanel23包含uiLabel12, uiLabel16, uiLabel17, uiProcessBar1
|
||
if (uiPanel23 != null && !uiPanel23.IsDisposed)
|
||
{
|
||
uiPanel23.Visible = !isHighTempMode;
|
||
Debug.WriteLine($"[UpdateControlsVisibilityByMode] uiPanel23(常温液位) Visible = {!isHighTempMode}");
|
||
}
|
||
|
||
// 常温加水按钮 - uiButton13
|
||
if (uiButton13 != null && !uiButton13.IsDisposed)
|
||
{
|
||
uiButton13.Visible = !isHighTempMode;
|
||
Debug.WriteLine($"[UpdateControlsVisibilityByMode] uiButton13(常温加水) Visible = {!isHighTempMode}");
|
||
}
|
||
|
||
// 常温加水指示灯 - uiLight6
|
||
if (uiPanel38 != null && !uiPanel38.IsDisposed)
|
||
{
|
||
uiPanel38.Visible = !isHighTempMode;
|
||
Debug.WriteLine($"[UpdateControlsVisibilityByMode] uiPanel38(常温加水指示灯) Visible = {!isHighTempMode}");
|
||
}
|
||
|
||
Debug.WriteLine($"[UpdateControlsVisibilityByMode] 模式切换完成 - 高温模式: {isHighTempMode}");
|
||
}
|
||
catch (ObjectDisposedException ex)
|
||
{
|
||
Debug.WriteLine($"[UpdateControlsVisibilityByMode] 控件已释放: {ex.Message}");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine($"[UpdateControlsVisibilityByMode] 更新控件可见性失败: {ex.Message}");
|
||
Debug.WriteLine($"[UpdateControlsVisibilityByMode] 堆栈跟踪: {ex.StackTrace}");
|
||
}
|
||
}
|
||
}
|
||
} |