小版本:
返回URL链接, 后面就不需要了,直接客户端查看数据
This commit is contained in:
@@ -433,7 +433,6 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Data\" />
|
<Folder Include="Data\" />
|
||||||
<Folder Include="Model\" />
|
<Folder Include="Model\" />
|
||||||
<Folder Include="Services\" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
23
FATrace.OEMApp/MainApp.Designer.cs
generated
23
FATrace.OEMApp/MainApp.Designer.cs
generated
@@ -57,7 +57,6 @@ namespace FATrace.OEMApp
|
|||||||
label8 = new Label();
|
label8 = new Label();
|
||||||
materialCard2 = new ReaLTaiizor.Controls.MaterialCard();
|
materialCard2 = new ReaLTaiizor.Controls.MaterialCard();
|
||||||
gridRULog = new DataGridView();
|
gridRULog = new DataGridView();
|
||||||
((System.ComponentModel.ISupportInitialize)gridRULog).BeginInit();
|
|
||||||
btnRawStopLoadVideo = new Button();
|
btnRawStopLoadVideo = new Button();
|
||||||
DownloadProgressBarMain = new ProgressBar();
|
DownloadProgressBarMain = new ProgressBar();
|
||||||
btnTestAction = new Button();
|
btnTestAction = new Button();
|
||||||
@@ -91,6 +90,7 @@ namespace FATrace.OEMApp
|
|||||||
materialCard4.SuspendLayout();
|
materialCard4.SuspendLayout();
|
||||||
materialCard3.SuspendLayout();
|
materialCard3.SuspendLayout();
|
||||||
materialCard2.SuspendLayout();
|
materialCard2.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)gridRULog).BeginInit();
|
||||||
tabPage2.SuspendLayout();
|
tabPage2.SuspendLayout();
|
||||||
((System.ComponentModel.ISupportInitialize)dataGridView1).BeginInit();
|
((System.ComponentModel.ISupportInitialize)dataGridView1).BeginInit();
|
||||||
materialCard1.SuspendLayout();
|
materialCard1.SuspendLayout();
|
||||||
@@ -410,22 +410,21 @@ namespace FATrace.OEMApp
|
|||||||
//
|
//
|
||||||
// gridRULog
|
// gridRULog
|
||||||
//
|
//
|
||||||
gridRULog = new DataGridView();
|
|
||||||
gridRULog.Location = new Point(557, 9);
|
|
||||||
gridRULog.Name = "gridRULog";
|
|
||||||
gridRULog.Size = new Size(1309, 338);
|
|
||||||
gridRULog.TabIndex = 8;
|
|
||||||
gridRULog.AllowUserToAddRows = false;
|
gridRULog.AllowUserToAddRows = false;
|
||||||
gridRULog.AllowUserToDeleteRows = false;
|
gridRULog.AllowUserToDeleteRows = false;
|
||||||
|
gridRULog.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
|
||||||
|
gridRULog.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
||||||
|
gridRULog.Location = new Point(557, 9);
|
||||||
|
gridRULog.Name = "gridRULog";
|
||||||
gridRULog.ReadOnly = true;
|
gridRULog.ReadOnly = true;
|
||||||
gridRULog.RowHeadersVisible = false;
|
gridRULog.RowHeadersVisible = false;
|
||||||
gridRULog.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
|
gridRULog.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
|
||||||
gridRULog.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
gridRULog.Size = new Size(1309, 338);
|
||||||
gridRULog.Anchor = ((AnchorStyles.Top | AnchorStyles.Bottom) | AnchorStyles.Left) | AnchorStyles.Right;
|
gridRULog.TabIndex = 8;
|
||||||
//
|
//
|
||||||
// btnRawStopLoadVideo
|
// btnRawStopLoadVideo
|
||||||
//
|
//
|
||||||
btnRawStopLoadVideo.Location = new Point(189, 223);
|
btnRawStopLoadVideo.Location = new Point(292, 271);
|
||||||
btnRawStopLoadVideo.Name = "btnRawStopLoadVideo";
|
btnRawStopLoadVideo.Name = "btnRawStopLoadVideo";
|
||||||
btnRawStopLoadVideo.Size = new Size(142, 44);
|
btnRawStopLoadVideo.Size = new Size(142, 44);
|
||||||
btnRawStopLoadVideo.TabIndex = 7;
|
btnRawStopLoadVideo.TabIndex = 7;
|
||||||
@@ -435,14 +434,14 @@ namespace FATrace.OEMApp
|
|||||||
//
|
//
|
||||||
// DownloadProgressBarMain
|
// DownloadProgressBarMain
|
||||||
//
|
//
|
||||||
DownloadProgressBarMain.Location = new Point(1, 324);
|
DownloadProgressBarMain.Location = new Point(7, 321);
|
||||||
DownloadProgressBarMain.Name = "DownloadProgressBarMain";
|
DownloadProgressBarMain.Name = "DownloadProgressBarMain";
|
||||||
DownloadProgressBarMain.Size = new Size(540, 23);
|
DownloadProgressBarMain.Size = new Size(540, 23);
|
||||||
DownloadProgressBarMain.TabIndex = 6;
|
DownloadProgressBarMain.TabIndex = 6;
|
||||||
//
|
//
|
||||||
// btnTestAction
|
// btnTestAction
|
||||||
//
|
//
|
||||||
btnTestAction.Location = new Point(41, 223);
|
btnTestAction.Location = new Point(144, 271);
|
||||||
btnTestAction.Name = "btnTestAction";
|
btnTestAction.Name = "btnTestAction";
|
||||||
btnTestAction.Size = new Size(142, 44);
|
btnTestAction.Size = new Size(142, 44);
|
||||||
btnTestAction.TabIndex = 5;
|
btnTestAction.TabIndex = 5;
|
||||||
@@ -746,13 +745,13 @@ namespace FATrace.OEMApp
|
|||||||
materialCard3.PerformLayout();
|
materialCard3.PerformLayout();
|
||||||
materialCard2.ResumeLayout(false);
|
materialCard2.ResumeLayout(false);
|
||||||
materialCard2.PerformLayout();
|
materialCard2.PerformLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)gridRULog).EndInit();
|
||||||
tabPage2.ResumeLayout(false);
|
tabPage2.ResumeLayout(false);
|
||||||
((System.ComponentModel.ISupportInitialize)dataGridView1).EndInit();
|
((System.ComponentModel.ISupportInitialize)dataGridView1).EndInit();
|
||||||
materialCard1.ResumeLayout(false);
|
materialCard1.ResumeLayout(false);
|
||||||
materialCard1.PerformLayout();
|
materialCard1.PerformLayout();
|
||||||
((System.ComponentModel.ISupportInitialize)videoView1).EndInit();
|
((System.ComponentModel.ISupportInitialize)videoView1).EndInit();
|
||||||
tabPage3.ResumeLayout(false);
|
tabPage3.ResumeLayout(false);
|
||||||
((System.ComponentModel.ISupportInitialize)gridRULog).EndInit();
|
|
||||||
ResumeLayout(false);
|
ResumeLayout(false);
|
||||||
PerformLayout();
|
PerformLayout();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,22 +2,23 @@ using FATrace.Com;
|
|||||||
using FATrace.HKNetLib.Hardware;
|
using FATrace.HKNetLib.Hardware;
|
||||||
using FATrace.HKNetLib.Wrapper;
|
using FATrace.HKNetLib.Wrapper;
|
||||||
using FATrace.Model;
|
using FATrace.Model;
|
||||||
using LibVLCSharp.Shared;
|
|
||||||
using ReaLTaiizor.Forms;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using FATrace.OEMApp.Services;
|
using FATrace.OEMApp.Services;
|
||||||
using System.Threading;
|
using LibVLCSharp.Shared;
|
||||||
using System.Threading.Tasks;
|
using NLog;
|
||||||
|
using ReaLTaiizor.Forms;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Linq;
|
using System.ComponentModel;
|
||||||
using TaskStatus = FATrace.Model.TaskStatus;
|
using TaskStatus = FATrace.Model.TaskStatus;
|
||||||
using System.Windows.Forms;
|
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
namespace FATrace.OEMApp
|
namespace FATrace.OEMApp
|
||||||
{
|
{
|
||||||
public partial class MainApp : MaterialForm
|
public partial class MainApp : MaterialForm
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 日志
|
||||||
|
/// </summary>
|
||||||
|
private Logger Logger { get; set; } = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 海康Camera 客户端
|
/// 海康Camera 客户端
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -64,7 +65,6 @@ namespace FATrace.OEMApp
|
|||||||
//NVR登录
|
//NVR登录
|
||||||
NVRLogin();
|
NVRLogin();
|
||||||
|
|
||||||
|
|
||||||
InitMediaPlayer();
|
InitMediaPlayer();
|
||||||
InitHistoryGridBinding();
|
InitHistoryGridBinding();
|
||||||
|
|
||||||
|
|||||||
@@ -128,7 +128,7 @@
|
|||||||
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
||||||
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
||||||
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAaiEAAAJNU0Z0AUkBTAIBAQgB
|
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAaiEAAAJNU0Z0AUkBTAIBAQgB
|
||||||
AAFIAQEBSAEBARABAAEQAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAATADAAEBAQABIAYAATD/
|
AAFQAQEBUAEBARABAAEQAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAATADAAEBAQABIAYAATD/
|
||||||
AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AFIAAdsBlgESAf8B2wGWARIB/wQAAxIBGANJAYgB
|
AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AFIAAdsBlgESAf8B2wGWARIB/wQAAxIBGANJAYgB
|
||||||
2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wQAAdsB
|
2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wQAAdsB
|
||||||
lgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8UAAHbAZYB
|
lgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8UAAHbAZYB
|
||||||
@@ -217,7 +217,7 @@
|
|||||||
2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wMqAUAY
|
2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wMqAUAY
|
||||||
AAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wgAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B
|
AAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wgAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B
|
||||||
2wGWARIB/xgAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsB
|
2wGWARIB/xgAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsB
|
||||||
lgESAf8B2wGWARIB/wJ8AVkB+BAAAXMBbwFRAfcB2wGWARIB/wwAAzMBUAHbAZYBEgH/BAAB2wGWARIB
|
lgESAf8B2wGWARIB/wJ8AVoB+BAAAXEBbwFRAfcB2wGWARIB/wwAAzMBUAHbAZYBEgH/BAAB2wGWARIB
|
||||||
/xAAAdsBlgESAf8QAAJbAVkBwCAAAkcBRgGAAyoBQBQAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsB
|
/xAAAdsBlgESAf8QAAJbAVkBwCAAAkcBRgGAAyoBQBQAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsB
|
||||||
lgESAf8MAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8IAAHbAZYBEgH/AdsB
|
lgESAf8MAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8IAAHbAZYBEgH/AdsB
|
||||||
lgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB
|
lgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB
|
||||||
|
|||||||
291
FATrace.OEMApp/Services/PLCDataService.cs
Normal file
291
FATrace.OEMApp/Services/PLCDataService.cs
Normal file
@@ -0,0 +1,291 @@
|
|||||||
|
using FATrace.Com;
|
||||||
|
using HslCommunication;
|
||||||
|
using HslCommunication.Profinet.Keyence;
|
||||||
|
using NLog;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FATrace.OEMApp.Services
|
||||||
|
{
|
||||||
|
public class PLCDataService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 日志
|
||||||
|
/// </summary>
|
||||||
|
private Logger Logger { get; set; } = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
public PLCDataService()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
PLCLinkInitial();
|
||||||
|
StartPlcScan();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 扫码事件
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<string> ScanCodeEventHandler;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// PLC连接状态事件
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<string> PlcConnectedEventHandler;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 基恩士通信组件
|
||||||
|
/// </summary>
|
||||||
|
private KeyenceMcNet KeyencePlcMcNet { get; set; } = null;
|
||||||
|
|
||||||
|
private bool _PlcConnected;
|
||||||
|
/// <summary>
|
||||||
|
/// PLC连接状态
|
||||||
|
/// </summary>
|
||||||
|
public bool PlcConnected
|
||||||
|
{
|
||||||
|
get { return _PlcConnected; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_PlcConnected != value)
|
||||||
|
{
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
PlcConnectedEventHandler.Invoke(this, "OK");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PlcConnectedEventHandler.Invoke(this, "NG");
|
||||||
|
}
|
||||||
|
_PlcConnected = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 扫描控制
|
||||||
|
private CancellationTokenSource? _plcScanCts;
|
||||||
|
private Task? _plcScanTask;
|
||||||
|
private volatile bool _isScanning = false;
|
||||||
|
public bool IsScanning => _isScanning;
|
||||||
|
private bool _disposed = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// PLC通信初始化
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="PLCIp"></param>
|
||||||
|
/// <param name="Port"></param>
|
||||||
|
private void PLCLinkInitial()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 读取 PLC 配置(大小写敏感,采用公共 ConfigHelper 并提供默认值)
|
||||||
|
string PLCIP = ConfigHelper.GetStringOrDefault("PLCIP", "192.0.1.10");
|
||||||
|
int Port = ConfigHelper.GetIntOrDefault("PLCPort", 5000);
|
||||||
|
|
||||||
|
//PLC通信的连接
|
||||||
|
KeyencePlcMcNet = new KeyenceMcNet();
|
||||||
|
KeyencePlcMcNet.IpAddress = PLCIP;
|
||||||
|
KeyencePlcMcNet.Port = Port;
|
||||||
|
KeyencePlcMcNet.ConnectClose();
|
||||||
|
|
||||||
|
KeyencePlcMcNet.ConnectTimeOut = 3000; // 连接3秒超时
|
||||||
|
OperateResult connect = KeyencePlcMcNet.ConnectServer();
|
||||||
|
if (connect.IsSuccess)//初始连接状态的显示判断
|
||||||
|
{
|
||||||
|
Console.WriteLine($"PLC-连接 OK");
|
||||||
|
PlcConnected = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBox.Show(connect.Message + Environment.NewLine + "ErrorCode: " + connect.ErrorCode);
|
||||||
|
PlcConnected = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.Error(String.Format("ErrSource : {0} ErrMsg : {1}", ex.StackTrace.ToString(), ex.Message.ToString()));
|
||||||
|
//insertLogToDBDelegate.BeginInvoke(1, "UpdateUIMethod异常", ex.Message.ToString() + ex.StackTrace.Substring(ex.StackTrace.Length - 40, 40), null, null);
|
||||||
|
PlcConnected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 启动PLC扫描。若已在扫描则忽略重复启动。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="scanPeriod">扫描周期,若为 null 则读取 App.config 的 PLCScan(毫秒),默认600ms</param>
|
||||||
|
/// <param name="externalToken">可选:外部取消令牌,用于联动取消</param>
|
||||||
|
public void StartPlcScan(TimeSpan? scanPeriod = null, CancellationToken externalToken = default)
|
||||||
|
{
|
||||||
|
if (_isScanning) return;
|
||||||
|
|
||||||
|
var period = scanPeriod ?? ConfigHelper.GetTimeSpanOrDefault("PLCScan", TimeSpan.FromMilliseconds(600));
|
||||||
|
|
||||||
|
_plcScanCts = CancellationTokenSource.CreateLinkedTokenSource(externalToken);
|
||||||
|
var token = _plcScanCts.Token;
|
||||||
|
_isScanning = true;
|
||||||
|
|
||||||
|
_plcScanTask = Task.Run(() => PlcScanLoopAsync(period, token), token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 停止PLC扫描,等待后台任务结束。
|
||||||
|
/// </summary>
|
||||||
|
public async Task StopPlcScanAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_plcScanCts != null)
|
||||||
|
{
|
||||||
|
_plcScanCts.Cancel();
|
||||||
|
}
|
||||||
|
if (_plcScanTask != null)
|
||||||
|
{
|
||||||
|
try { await _plcScanTask.ConfigureAwait(false); } catch { /* ignore */ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_isScanning = false;
|
||||||
|
_plcScanTask = null;
|
||||||
|
_plcScanCts?.Dispose();
|
||||||
|
_plcScanCts = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 扫描循环:按周期轮询PLC寄存器并更新模型。
|
||||||
|
/// - 读取配置项 Addr_WeightPhotoEnable(默认 M100)为布尔量
|
||||||
|
/// - 读失败时尝试重连一次
|
||||||
|
/// </summary>
|
||||||
|
private async Task PlcScanLoopAsync(TimeSpan period, CancellationToken token)
|
||||||
|
{
|
||||||
|
string addrWeight = ConfigHelper.GetStringOrDefault("Addr_WeightPhotoEnable", "M100");
|
||||||
|
bool? lastWeight = null;
|
||||||
|
|
||||||
|
while (!token.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (KeyencePlcMcNet == null)
|
||||||
|
{
|
||||||
|
PLCLinkInitial();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.Error($"PLC 扫描异常: {ex}");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await Task.Delay(period, token).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
// 不允许从 finally 中 break/return,
|
||||||
|
// 这里吞掉异常,循环将在下一次 while 判断时依据 token 自动退出
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_isScanning = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 尝试重连 PLC(快速一次)
|
||||||
|
/// </summary>
|
||||||
|
private async Task TryReconnectAsync(CancellationToken token)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (KeyencePlcMcNet == null) { PLCLinkInitial(); return; }
|
||||||
|
KeyencePlcMcNet.ConnectClose();
|
||||||
|
await Task.Delay(100, token).ConfigureAwait(false);
|
||||||
|
KeyencePlcMcNet.ConnectTimeOut = 3000;
|
||||||
|
var ret = KeyencePlcMcNet.ConnectServer();
|
||||||
|
if (!ret.IsSuccess)
|
||||||
|
{
|
||||||
|
Logger.Warn($"PLC重连失败: {ret.Message} (Code: {ret.ErrorCode})");
|
||||||
|
PlcConnected = false;
|
||||||
|
}
|
||||||
|
else { PlcConnected = true; }
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.Error($"PLC重连异常: {ex.Message}");
|
||||||
|
PlcConnected = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 释放资源,确保扫描停止并断开PLC连接。
|
||||||
|
/// </summary>
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (_disposed) return;
|
||||||
|
_disposed = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 停止扫描
|
||||||
|
try { StopPlcScanAsync().GetAwaiter().GetResult(); } catch { }
|
||||||
|
|
||||||
|
// 解除事件订阅(当前未订阅自定义事件,保留占位以便后续扩展)
|
||||||
|
// try { /* no event to unsubscribe */ } catch { }
|
||||||
|
|
||||||
|
// 关闭PLC连接
|
||||||
|
try { KeyencePlcMcNet?.ConnectClose(); } catch { }
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
KeyencePlcMcNet = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 把字符串对调
|
||||||
|
/// </summary>
|
||||||
|
public string RevData(string Code)
|
||||||
|
{
|
||||||
|
// 需求:PLC 字符串按“字”(2字节)进行高低字节对调,导致 ABCDEF -> BADCFE
|
||||||
|
// 纠正方式:按两个字符一组交换顺序,奇数长度保留最后一个字符
|
||||||
|
if (string.IsNullOrEmpty(Code)) return string.Empty;
|
||||||
|
|
||||||
|
// 去掉读取中可能包含的 '\0' 空字符
|
||||||
|
var src = Code.Replace("\0", string.Empty);
|
||||||
|
|
||||||
|
var sb = new System.Text.StringBuilder(src.Length);
|
||||||
|
for (int i = 0; i < src.Length; i += 2)
|
||||||
|
{
|
||||||
|
if (i + 1 < src.Length)
|
||||||
|
{
|
||||||
|
sb.Append(src[i + 1]);
|
||||||
|
sb.Append(src[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 奇数长度,最后一个字符原样保留
|
||||||
|
//sb.Append((char)0x0);
|
||||||
|
sb.Append('\0');
|
||||||
|
sb.Append(src[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user