468 lines
15 KiB
C#
468 lines
15 KiB
C#
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.Globalization;
|
||
using System.Linq;
|
||
using System.Net.Sockets;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using System.Windows.Forms;
|
||
using 外科辅料和患者防护罩激光抗性测试仪.Data;
|
||
using 外科辅料和患者防护罩激光抗性测试仪.Model;
|
||
|
||
namespace 外科辅料和患者防护罩激光抗性测试仪
|
||
{
|
||
public partial class PrimaryIgnitionForm : UIForm
|
||
{
|
||
#region 私有字段
|
||
private TcpClient _tcpClient => ModbusResourceManager.Instance.TcpClient;
|
||
private IModbusMaster _modbusMaster => ModbusResourceManager.Instance.ModbusMaster;
|
||
#endregion
|
||
|
||
Function ma;
|
||
DataChange c = new DataChange();
|
||
|
||
private System.Windows.Forms.Timer _readtimer;
|
||
private readonly SemaphoreSlim _asyncLock = new SemaphoreSlim(1, 1);
|
||
|
||
public PrimaryIgnitionForm()
|
||
{
|
||
InitializeComponent();
|
||
|
||
InitComboBoxPattern();
|
||
|
||
InitTimer();
|
||
|
||
}
|
||
|
||
private void PrimaryIgnitionForm_Load(object sender, EventArgs e)
|
||
{
|
||
string plcIp = "192.168.1.10";
|
||
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);
|
||
|
||
_readtimer = InitTimer();
|
||
if (_modbusMaster != null)
|
||
{
|
||
_readtimer.Start();
|
||
}
|
||
|
||
this.FormClosed += (s, args) =>
|
||
{
|
||
// 当子窗体关闭时,显示主窗体
|
||
Application.OpenForms["MainForm"]?.Show();
|
||
};
|
||
}
|
||
|
||
private System.Windows.Forms.Timer InitTimer()
|
||
{
|
||
var timer = new System.Windows.Forms.Timer()
|
||
{
|
||
Interval = 1000,
|
||
};
|
||
timer.Tick += async (s, e) =>
|
||
{
|
||
if (_modbusMaster != null)
|
||
{
|
||
try
|
||
{
|
||
await ReadDataAsync();
|
||
}
|
||
catch { }
|
||
}
|
||
};
|
||
return timer;
|
||
|
||
}
|
||
|
||
private async System.Threading.Tasks.Task ReadDataAsync()
|
||
{
|
||
try
|
||
{
|
||
if (_modbusMaster == null || _tcpClient == null || !_tcpClient.Connected)
|
||
{
|
||
return;
|
||
}
|
||
var tasks = new List<Task>
|
||
{
|
||
|
||
ReadFloatAsync(30,1,uiLabel10,"F0",""),//测试项
|
||
ReadFloatAsync(38,2,uiLabel7,"F0",""),//点火时间
|
||
ReadFloatAsync(44,2,uiLabel8,"F0",""),//余焰时间
|
||
ReadFloatAsync(48,2,uiLabel12,"F0",""),//余辉时间
|
||
|
||
|
||
ReadLightStatusAsync(),
|
||
|
||
ReadtimeAsync(),//实时时间
|
||
|
||
ReadStartStatusAsync()
|
||
|
||
};
|
||
await Task.WhenAll(tasks);
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
//ShowError($"读取数据失败:{ex.Message}");
|
||
}
|
||
}
|
||
|
||
private async Task ReadFloatAsync(int address, int length, Label control, string format, string unit)
|
||
{
|
||
if (control == null) return;
|
||
|
||
try
|
||
{
|
||
var modbusMaster = _modbusMaster;
|
||
if (modbusMaster == null) return;
|
||
|
||
ushort[] registers = await modbusMaster.ReadHoldingRegistersAsync(1, (ushort)address, (ushort)length)
|
||
.ConfigureAwait(false);
|
||
|
||
if (registers == null || registers.Length == 0)
|
||
{
|
||
System.Diagnostics.Debug.WriteLine($"读取地址{address}失败:未获取到有效寄存器数据");
|
||
return;
|
||
}
|
||
|
||
string text;
|
||
if (registers.Length >= 2 && length >= 2)
|
||
{
|
||
float value = c.UshortToFloat(registers[1], registers[0]);
|
||
text = $"{value.ToString(format, CultureInfo.InvariantCulture)}{unit}";
|
||
}
|
||
else if (registers.Length >= 1)
|
||
{
|
||
int value = registers[0];
|
||
text = $"{value.ToString(format, CultureInfo.InvariantCulture)}{unit}";
|
||
}
|
||
else
|
||
{
|
||
return;
|
||
}
|
||
|
||
UpdateControlText(control, text);
|
||
}
|
||
catch (OperationCanceledException)
|
||
{
|
||
return;
|
||
}
|
||
catch (Exception ex) when (ex is TimeoutException ||
|
||
ex is InvalidOperationException ||
|
||
ex.Message.Contains("Modbus", StringComparison.OrdinalIgnoreCase))
|
||
{
|
||
Debug.WriteLine($"Modbus通信错误 - 地址{address}: {ex.Message}");
|
||
UpdateControlText(control, "通信错误");
|
||
}
|
||
catch (ObjectDisposedException)
|
||
{
|
||
return;
|
||
}
|
||
}
|
||
private void UpdateControlText(Label control, string text)
|
||
{
|
||
if (control.IsDisposed) return;
|
||
|
||
if (control.InvokeRequired)
|
||
{
|
||
try
|
||
{
|
||
control.BeginInvoke(new Action(() =>
|
||
{
|
||
if (!control.IsDisposed)
|
||
control.Text = text;
|
||
}));
|
||
}
|
||
catch (ObjectDisposedException)
|
||
{
|
||
}
|
||
}
|
||
else
|
||
{
|
||
control.Text = text;
|
||
}
|
||
}
|
||
|
||
private async Task ReadLightStatusAsync()
|
||
{
|
||
try
|
||
{
|
||
bool[] registers1 = await Task.Run(async () =>
|
||
{
|
||
if (_modbusMaster == null)
|
||
return null;
|
||
return await _modbusMaster?.ReadCoilsAsync(1, 10, 1);
|
||
});
|
||
if (registers1 != null && registers1.Length >= 1)
|
||
{
|
||
bool value = registers1[0];
|
||
this.Invoke(new Action(() =>
|
||
{
|
||
if (value)
|
||
{
|
||
uiLight1.State = UILightState.On;
|
||
|
||
|
||
}
|
||
else
|
||
{
|
||
uiLight1.State = UILightState.Off;
|
||
}
|
||
}));
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine($"读取状态失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
private bool _lastRunStatus = false;
|
||
private bool _isReported = false;
|
||
|
||
private async Task ReadStartStatusAsync()
|
||
{
|
||
try
|
||
{
|
||
bool[] registers2 = await Task.Run(async () =>
|
||
{
|
||
if (_modbusMaster == null)
|
||
return null;
|
||
return await _modbusMaster?.ReadCoilsAsync(1, 51, 1);
|
||
});
|
||
|
||
if (registers2 != null && registers2.Length >= 1)
|
||
{
|
||
bool currentRunStatus = registers2[0]; // 当前运行状态
|
||
this.Invoke(new Action(() =>
|
||
{
|
||
uiLabel23.Text = currentRunStatus ? "运行中" : "空闲中";
|
||
}));
|
||
|
||
if (!_lastRunStatus && currentRunStatus)
|
||
{
|
||
_isReported = false;
|
||
Debug.WriteLine("检测到运行开始,重置报表插入标记");
|
||
}
|
||
|
||
if (_lastRunStatus && !currentRunStatus && !_isReported)
|
||
{
|
||
_ = InsertReportAsync();
|
||
_isReported = true;
|
||
}
|
||
|
||
_lastRunStatus = currentRunStatus;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine($"读取状态失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
List<PrimaryIgnitionModel> reportList = new List<PrimaryIgnitionModel>();
|
||
private async Task InsertReportAsync()
|
||
{
|
||
try
|
||
{
|
||
reportList.Add(new PrimaryIgnitionModel
|
||
{
|
||
costTime = 1,
|
||
FireDate = DateTime.Now,
|
||
Iszixi = false,
|
||
O2 = 100,
|
||
result = "I1",
|
||
sampleType = uiComboBox3.Text.Contains("1") ? 1
|
||
: uiComboBox3.Text.Contains("2") ? 2
|
||
: uiComboBox3.Text.Contains("3") ? 3
|
||
: uiComboBox3.Text.Contains("4") ? 4
|
||
: uiComboBox3.Text.Contains("5") ? 5 : 0,
|
||
yuhui = 1,
|
||
yuyan = 1
|
||
});
|
||
await Task.Delay(100);
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine($"报表插入失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
private async Task ReadtimeAsync()
|
||
{
|
||
try
|
||
{
|
||
|
||
string currentTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||
|
||
// 跨线程更新UI(异步方法中仍需检查Invoke,避免跨线程异常)
|
||
if (uiLabel25.InvokeRequired)
|
||
{
|
||
uiLabel25.Invoke(new Action(() =>
|
||
{
|
||
uiLabel25.Text = currentTime;
|
||
}));
|
||
}
|
||
else
|
||
{
|
||
uiLabel25.Text = currentTime;
|
||
}
|
||
|
||
// 等待1秒再更新(异步等待,不阻塞UI线程)
|
||
await Task.Delay(1000);
|
||
|
||
}
|
||
|
||
catch (Exception ex)
|
||
{
|
||
uiLabel25.Text = $"错误:{ex.Message}";
|
||
}
|
||
}
|
||
|
||
private void InitComboBoxPattern()
|
||
{
|
||
// 清空原有选项(可选,避免重复添加)
|
||
//Combox_pattern.Items.Clear();
|
||
|
||
// 定义需要添加的选项数组
|
||
string[] options = {
|
||
"环境空气 (21%)",
|
||
"富氧环境 (60%)",
|
||
"富氧环境 (98%)",
|
||
"无氧环境/灭火 (0%)"
|
||
};
|
||
uiComboBox1.Items.AddRange(options);
|
||
|
||
}
|
||
|
||
|
||
private void uiButton10_Click(object sender, EventArgs e)
|
||
{
|
||
this.Close();//返回主页面
|
||
}
|
||
|
||
private void PrimaryIgnitionForm_FormClosed(object sender, FormClosedEventArgs e)
|
||
{
|
||
foreach (Form form in Application.OpenForms)
|
||
{
|
||
if (form.Name == "MainForm" || form.Text.Contains("主界面"))
|
||
{
|
||
form.Show();
|
||
form.Activate(); // 激活窗体
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
private void uiButton4_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.BtnClickFunctionForNew(Function.ButtonType.切换型, 5);//余焰开始
|
||
}
|
||
|
||
private void uiButton5_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.BtnClickFunctionForNew(Function.ButtonType.复归型, 6);//余焰结束
|
||
}
|
||
|
||
private void uiButton6_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.BtnClickFunctionForNew(Function.ButtonType.复归型, 7);//实验结束
|
||
}
|
||
|
||
private void uiComboBox1_SelectedIndexChanged(object sender, EventArgs e)
|
||
{
|
||
ushort selectedIndex = ushort.Parse(uiComboBox1.SelectedIndex.ToString());
|
||
_modbusMaster?.WriteSingleRegister(1, 10, selectedIndex);//下拉框
|
||
}
|
||
|
||
private void uiButton7_Click(object sender, EventArgs e)
|
||
{
|
||
string message = "请目测是否有余辉:\n有余辉请立即点击“余辉开始”按钮,余辉时间开始计时;\n余辉结束,请立即点击“余辉结束”按钮,余辉时间计时结束。";
|
||
|
||
Font font = new Font("Microsoft YaHei", 12, FontStyle.Regular);
|
||
|
||
// 创建一个自定义的消息框
|
||
TaskDialogPage page = new TaskDialogPage
|
||
{
|
||
Text = message,
|
||
Caption = "帮助",
|
||
SizeToContent = true
|
||
};
|
||
|
||
TaskDialog.ShowDialog(this, page);
|
||
}
|
||
|
||
private void uiButton1_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.BtnClickFunctionForNew(Function.ButtonType.复归型, 50);//开始
|
||
}
|
||
|
||
private void uiButton2_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.BtnClickFunctionForNew(Function.ButtonType.复归型, 7);//手动停止
|
||
}
|
||
|
||
private void uiButton3_Click(object sender, EventArgs e)
|
||
{
|
||
ma?.BtnClickFunctionForNew(Function.ButtonType.切换型, 99);//灭火
|
||
}
|
||
|
||
private void PrimaryIgnitionForm_FormClosing(object sender, FormClosingEventArgs e)
|
||
{
|
||
if (_readtimer != null)
|
||
{
|
||
_readtimer.Stop();
|
||
_readtimer.Dispose();
|
||
}
|
||
}
|
||
|
||
private void uiComboBox2_SelectedIndexChanged(object sender, EventArgs e)
|
||
{
|
||
string value = uiComboBox2.SelectedItem.ToString();
|
||
|
||
switch (value)
|
||
{
|
||
case "样品1":
|
||
{
|
||
var data = reportList?.FirstOrDefault(x => x.sampleType == 1);
|
||
uiLabel21.Text = value;
|
||
uiLabel21.Text = data.FireDate.ToString();
|
||
//等等
|
||
break;
|
||
}
|
||
case "样品2":
|
||
{
|
||
var data = reportList?.FirstOrDefault(x => x.sampleType == 2);
|
||
uiLabel21.Text = value;
|
||
uiLabel21.Text = data.FireDate.ToString();
|
||
//等等
|
||
break;
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|