Files
FullAutoWaterCheck/全自动水压检测仪/NormalTemperatureMode.cs
2026-01-07 13:42:17 +08:00

618 lines
21 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 Modbus.Device;
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.Windows.Forms;
using .Data;
using .DATA;
using ;
namespace
{
public partial class NormalTemperatureMode : UIForm
{
BoolSignal boolSignal1 = new BoolSignal();
private Coeffiicientsetting _coeffiicientsetting;
private HighTemperatureMode _highTemperatureMode;
public List<ConductivityTestData> CurrentReport;
private Report _report;
private Stopwatch pressStopwatch;
private const int LONG_PRESS_THRESHOLD = 1000; // 1000毫秒=1秒
private TcpClient _tcpClient => ModbusResourceManager.Instance.TcpClient;
private IModbusMaster _modbusMaster => ModbusResourceManager.Instance.ModbusMaster;
Function ma;
DataChange c;
private System.Windows.Forms.Timer _readTimer;
private bool _isManualInput = false; // 手动输入标记
private bool _isSwitchingWindow = false; // 窗口切换标记,避免并发
private ConductivityRepository _repository;
public NormalTemperatureMode()
{
InitializeComponent();
pressStopwatch = new Stopwatch();
InitTimer(); // 初始化定时器
InitTimerTwo(); // 初始化定时器
_repository = new ConductivityRepository();
CurrentReport = new List<ConductivityTestData>();
}
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 { }
}
};
timer.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 { }
}
};
timer.Start();
return timer;
}
private async System.Threading.Tasks.Task ReadLeakTestParametersAsync()
{
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
{
return;
}
try
{
// 核心将CPU/IO密集的Modbus读取操作放到后台线程执行
// 避免阻塞UI线程await等待执行完成
var modbusData = await Task.Run(() =>
{
// 此匿名方法在后台线程执行不能访问UI控件
return new
{
// 读取所有需要的寄存器(同步操作,但是在后台线程)
Real1 = _modbusMaster.ReadHoldingRegisters(1, 1130, 2),
Real2 = _modbusMaster.ReadHoldingRegisters(1, 1080, 2),
Real3 = _modbusMaster.ReadHoldingRegisters(1, 100, 2),
Real4 = _modbusMaster.ReadHoldingRegisters(1, 102, 2),
Real5 = _modbusMaster.ReadHoldingRegisters(1, 104, 2),
Real6 = _modbusMaster.ReadHoldingRegisters(1, 82, 2),
Real7 = _modbusMaster.ReadHoldingRegisters(1, 84, 2),
Real8 = _modbusMaster.ReadHoldingRegisters(1, 86, 2),
Real9 = _modbusMaster.ReadHoldingRegisters(1, 1030, 2),
Real10 = _modbusMaster.ReadHoldingRegisters(1, 1480, 2),
Real11 = _modbusMaster.ReadHoldingRegisters(1, 1180, 2),
Real12 = _modbusMaster.ReadHoldingRegisters(1, 402, 2),
CurrentTime = DateTime.Now // 后台线程获取时间不影响
};
});
// 数据读取完成后回到UI线程更新控件await会自动捕获上下文此处已是UI线程
// 时间显示
uiLabel5.Text = modbusData.CurrentTime.ToString("yyyy-MM-dd HH:mm:ss");
// 实时压力
var value0 = c.UshortToFloat(modbusData.Real1[1], modbusData.Real1[0]);
uiLabel28.Text = value0.ToString("F2");
// 常温实时液位
var value1 = c.UshortToFloat(modbusData.Real2[1], modbusData.Real2[0]);
uiLabel12.Text = value1.ToString("F2");
// 初始压力
var value2 = c.UshortToFloat(modbusData.Real3[1], modbusData.Real3[0]);
uiLabel14.Text = value2.ToString("F2");
// 结束压力
var value3 = c.UshortToFloat(modbusData.Real4[1], modbusData.Real4[0]);
uiLabel19.Text = value3.ToString("F2");
// 压差
var value4 = c.UshortToFloat(modbusData.Real5[1], modbusData.Real5[0]);
uiLabel22.Text = value4.ToString("F2");
// 计时s
int value5 = modbusData.Real6[0];
uiLabel25.Text = value5.ToString();
// 计时min
int value6 = modbusData.Real7[0];
uiLabel9.Text = value6.ToString();
// 计时h
int value7 = modbusData.Real8[0];
uiLabel31.Text = value7.ToString();
// 高温实时液位
var value8 = c.UshortToFloat(modbusData.Real9[1], modbusData.Real9[0]);
uiLabel7.Text = value8.ToString("F2");
// 箱体温度
var value9 = c.UshortToFloat(modbusData.Real10[1], modbusData.Real10[0]);
uiLabel42.Text = value9.ToString("F1");
// 出口温度
var value10 = c.UshortToFloat(modbusData.Real11[1], modbusData.Real11[0]);
uiLabel38.Text = value10.ToString("F1");
// 出口温度
var value12 = c.UshortToFloat(modbusData.Real12[1], modbusData.Real12[0]);
uiLabel4.Text = value12.ToString("F1");
}
catch (Exception ex)
{
MessageBox.Show($"读取调试参数失败:{ex.Message}", "错误",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private async System.Threading.Tasks.Task ReadLeakTestParametersAsyncTwo()
{
if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null)
{
return;
}
try
{
//测试步
ushort[] testslip = _modbusMaster?.ReadHoldingRegisters(1, 80, 2);
int testvalue = testslip[0];
uiLabel3.Text = testvalue.ToString();
// 读取压力设置 (D-400)
ushort[] set1 = await System.Threading.Tasks.Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 400, 2)
);
if (set1 != null && set1.Length >= 2)
{
float Value0 = c.UshortToFloat(set1[1], set1[0]);
this.Invoke(new Action(() => uiTextBox1.Text = Value0.ToString("F2")));
}
// 读取压力设置 (D-402)
ushort[] set11 = await System.Threading.Tasks.Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 402, 1)
);
if (set11 != null && set11.Length >= 1)
{
float Value0 = set11[0];
this.Invoke(new Action(() => uiTextBox4.Text = Value0.ToString("F2")));
}
// 读取测试保压时间 (D-404)
ushort[] set2 = await System.Threading.Tasks.Task.Run(() =>
_modbusMaster?.ReadHoldingRegisters(1, 404, 2)
);
if (set2 != null && set2.Length >= 2)
{
float Value1 = c.UshortToFloat(set2[1], set2[0]);
this.Invoke(new Action(() => uiTextBox5.Text = Value1.ToString("F2")));
}
//测试按钮
bool[] testStatus = _modbusMaster?.ReadCoils(1, 81, 1);
if (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.Value = false;
}
//高低温切换
bool[] buttonStatus = _modbusMaster?.ReadCoils(1, 30, 1);
if (buttonStatus[0])
{
uiSwitch1.Active = false;
}
else
{
uiSwitch1.Active = true;
}
//低温指示
bool[] lowStatus = _modbusMaster?.ReadCoils(1, 31, 1);
if (lowStatus[0])
{
uiLight1.State = UILightState.On;
}
else
{
uiLight1.State = UILightState.Off;
}
//高温指示
bool[] highStatus = _modbusMaster?.ReadCoils(1, 32, 1);
if (highStatus[0])
{
uiLight2.State = UILightState.On;
}
else
{
uiLight2.State = UILightState.Off;
}
//进气阀指示
bool[] valve1 = _modbusMaster?.ReadCoils(1, 14, 1);
if (valve1[0])
{
uiLight3.State = UILightState.On;
}
else
{
uiLight3.State = UILightState.Off;
}
//测试高压阀指示
bool[] valve2 = _modbusMaster?.ReadCoils(1, 8, 1);
if (valve2[0])
{
uiLight4.State = UILightState.On;
}
else
{
uiLight4.State = UILightState.Off;
}
//常温抽水阀指示
bool[] valve3 = _modbusMaster?.ReadCoils(1, 6, 1);
if (valve3[0])
{
uiLight5.State = UILightState.On;
}
else
{
uiLight5.State = UILightState.Off;
}
//常温水箱加水阀指示
bool[] valve4 = _modbusMaster?.ReadCoils(1, 13, 1);
if (valve4[0])
{
uiLight6.State = UILightState.On;
}
else
{
uiLight6.State = UILightState.Off;
}
//高温抽水阀指示
bool[] valve5 = _modbusMaster?.ReadCoils(1, 5, 1);
if (valve5[0])
{
uiLight7.State = UILightState.On;
}
else
{
uiLight7.State = UILightState.Off;
}
//空气抽气阀指示
bool[] valve6 = _modbusMaster?.ReadCoils(1, 7, 1);
if (valve6[0])
{
uiLight8.State = UILightState.On;
}
else
{
uiLight8.State = UILightState.Off;
}
//升温阀
//常温回水阀指示
bool[] valve8 = _modbusMaster?.ReadCoils(1, 10, 1);
if (valve8[0])
{
uiLight10.State = UILightState.On;
}
else
{
uiLight10.State = UILightState.Off;
}
//高温水箱加水阀指示
bool[] valve9 = _modbusMaster?.ReadCoils(1, 12, 1);
if (valve9[0])
{
uiLight11.State = UILightState.On;
}
else
{
uiLight11.State = UILightState.Off;
}
//高温回水阀指示
bool[] valve10 = _modbusMaster?.ReadCoils(1, 9, 1);
if (valve10[0])
{
uiLight12.State = UILightState.On;
}
else
{
uiLight12.State = UILightState.Off;
}
}
catch (Exception ex)
{
this.Invoke(new Action(() =>
MessageBox.Show($"读取调试参数失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error)));
}
}
//系数页
private void uiButton14_Click(object sender, EventArgs e)
{
//FormManager.Instance.SwitchTo<Coeffiicientsetting>();
SwitchWindow(ref _coeffiicientsetting, () => new Coeffiicientsetting());
}
private void NormalTemperatureMode_Load(object sender, EventArgs e)
{
//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, 30, true);
boolSignal1.OnRisingEdge += BoolSignal1_OnRisingEdge;
}
void BoolSignal1_OnRisingEdge()
{
uiTextBox3.Text = uiLabel14.Text;//初始压力
uiTextBox8.Text = uiTextBox5.Text;//保压时间
uiTextBox6.Text = uiLabel22.Text;//压差
uiTextBox7.Text = uiLabel19.Text;//结束压力
CurrentReport.Add(new ConductivityTestData
{
barcode = uiTextBox2.Text,
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 = uiTextBox2.Text,
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
});
}
private bool TryReconnect()
{
try
{
string plcIp = "192.168.1.10";
bool initSuccess = Data.ModbusResourceManager.Instance.Init(plcIp, 502);
if (initSuccess)
{
ma = new Function(_modbusMaster);
return true;
}
}
catch (Exception ex)
{
//ShowErrorMsg($"重新连接失败:{ex.Message}");
}
return false;
}
private void SwitchWindow<T>(ref T windowInstance, Func<T> createFunc) where T : UIForm
{
_isSwitchingWindow = true;
_readTimer?.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();
this.Show();
this.Activate();
}));
};
}
else
{
windowInstance.Activate();
return;
}
this.Hide();
windowInstance.Show();
}
private void NormalTemperatureMode_FormClosing(object sender, FormClosingEventArgs e)
{
// 停止定时器
_readTimer?.Stop();
_readTimer?.Dispose();
// 仅用户主动关闭时退出应用
if (e.CloseReason == CloseReason.UserClosing)
{
ModbusResourceManager.Instance?.Dispose();
Application.Exit();
}
}
private void NormalTemperatureMode_FormClosed_1(object sender, FormClosedEventArgs e)
{
_coeffiicientsetting?.Dispose();
_highTemperatureMode?.Dispose();
}
//压力设置
private void uiTextBox1_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox1.Text.Trim(), 400, Function.DataType.);
}
//测试保压时间设置
private void uiTextBox5_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox5.Text.Trim(), 404, Function.DataType.);
}
//系统排气
private void uiButton11_Click_1(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 70);
}
//系统加水
private void uiButton13_Click(object sender, EventArgs e)
{
//ma?.BtnClickFunctionForNew(Function.ButtonType.切换型, 11);
}
//高温模式
private void uiSwitch1_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 30);
}
//测试按钮
private void uiButton2_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 80);
}
//停止按钮
private void uiButton3_Click(object sender, EventArgs e)
{
ma?.BtnClickFunctionForNew(Function.ButtonType., 82);
}
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
//{
// // 执行点击操作(可选)
// ClickFunction();
//}
}
}
private void EnterFunction()
{
// 长按后进入的功能
SwitchWindow(ref _coeffiicientsetting, () => new Coeffiicientsetting());
}
private void uiButton1_Click(object sender, EventArgs e)
{
SwitchWindow(ref _report, () => new Report(CurrentReport));
}
private void uiTextBox4_Click(object sender, EventArgs e)
{
ma?.WriteToPLCForNew(uiTextBox4.Text.Trim(), 402, Function.DataType.);
}
}
}