|
|
@@ -12,6 +12,7 @@ using Prism.Events;
|
|
|
using Prism.Ioc;
|
|
|
using Prism.Mvvm;
|
|
|
using Prism.Regions;
|
|
|
+using Prism.Services.Dialogs;
|
|
|
using SqlSugar;
|
|
|
using SqlSugar.SplitTableExtensions;
|
|
|
using System;
|
|
|
@@ -23,12 +24,14 @@ using System.Drawing;
|
|
|
using System.IO;
|
|
|
using System.IO.Compression;
|
|
|
using System.IO.MemoryMappedFiles;
|
|
|
+using System.IO.MemoryMappedFiles;
|
|
|
using System.Linq;
|
|
|
using System.Text;
|
|
|
using System.Text.Json;
|
|
|
using System.Threading;
|
|
|
using System.Threading.Tasks;
|
|
|
using System.Web.UI.WebControls;
|
|
|
+using System.Windows;
|
|
|
using System.Windows.Media;
|
|
|
using Team.FFFeederService.Interfaces;
|
|
|
using TeamAAS_VP.Controls;
|
|
|
@@ -44,7 +47,6 @@ using TeamAAS_VP.ViewModels.Home;
|
|
|
using TouchSocket.Core;
|
|
|
using TouchSocket.SerialPorts;
|
|
|
using TouchSocket.Sockets;
|
|
|
-using System.IO.MemoryMappedFiles;
|
|
|
|
|
|
namespace TeamAAS_VP.Core
|
|
|
{
|
|
|
@@ -66,6 +68,7 @@ namespace TeamAAS_VP.Core
|
|
|
IRemoteCommandService _remoteCommandService;
|
|
|
ISystemDatabaseService _systemDatabaseService;
|
|
|
IMesService _mesService;
|
|
|
+ IDialogService _dialogService;
|
|
|
|
|
|
Timer yieldtimer;
|
|
|
/// <summary>
|
|
|
@@ -292,7 +295,7 @@ namespace TeamAAS_VP.Core
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
- public Management(IRegionManager regionManager, IEventAggregator ea, IContainerProvider container, IConfigService configService,
|
|
|
+ public Management(IRegionManager regionManager, IEventAggregator ea, IContainerProvider container, IConfigService configService, IDialogService dialogService,
|
|
|
IRobotService robotService, ICameraService cameraService, IFeederService feederService, IPlcService plcService, IProductService productService,
|
|
|
ICalibrationService calibrationService, IRemoteCommandService remoteCommandService, ISystemDatabaseService systemDatabaseService, ILightManagerService lightManagerService, IMesService mesService, IScannerService scannerService)
|
|
|
{
|
|
|
@@ -306,6 +309,7 @@ namespace TeamAAS_VP.Core
|
|
|
_cameraService = cameraService;
|
|
|
_feederService = feederService;
|
|
|
_plcService = plcService;
|
|
|
+ _dialogService = dialogService;
|
|
|
_calibrationService = calibrationService;
|
|
|
yieldtimer = new Timer(DoYieldTime, null, 10000, 1000);
|
|
|
_messageFlushTimer = new Timer(_ => FlushMessageQueue(), null, 200, 200);
|
|
|
@@ -542,8 +546,8 @@ namespace TeamAAS_VP.Core
|
|
|
{
|
|
|
|
|
|
var camera = _configService.GetCamera(cameraId);
|
|
|
- SendTaskMessage($"相机[{camera.CameraName}]图像接收完成!", MessageLevel.Info);
|
|
|
-
|
|
|
+ //SendTaskMessage($"相机[{camera.CameraName}]图像接收完成!", MessageLevel.Info);
|
|
|
+ LogHelper.WriteLogInfo($"相机[{camera.CameraName}]图像接收完成!");
|
|
|
//if (camera.CameraNo == 1)
|
|
|
//{
|
|
|
// ImageData[1] = 1;
|
|
|
@@ -1526,7 +1530,7 @@ namespace TeamAAS_VP.Core
|
|
|
private void PlcCommandTrigger((string key, string nodeId, object value) tuple)
|
|
|
{
|
|
|
// 立即释放OPC UA回调线程,避免阻塞Session导致后续WriteNodeAsync无法派发
|
|
|
- LogHelper.WriteLogInfo($"[PLC-TRACE] Trigger queued key={tuple.key}, node={tuple.nodeId}, value={tuple.value}, thread={Thread.CurrentThread.ManagedThreadId}, time={DateTime.Now:HH:mm:ss.fff}");
|
|
|
+ //LogHelper.WriteLogInfo($"[PLC-TRACE] Trigger queued key={tuple.key}, node={tuple.nodeId}, value={tuple.value}, thread={Thread.CurrentThread.ManagedThreadId}, time={DateTime.Now:HH:mm:ss.fff}");
|
|
|
_ = Task.Run(async () =>
|
|
|
{
|
|
|
try
|
|
|
@@ -1578,13 +1582,12 @@ namespace TeamAAS_VP.Core
|
|
|
|
|
|
if (state)
|
|
|
{
|
|
|
- SendTaskMessage($"写入3D相机长度...", MessageLevel.Debug);
|
|
|
//相机的编号
|
|
|
//Int16 cameraIndex = plc.ReadNode<Int16>(addressConfig.In_FixedCameracheckNum.Address);
|
|
|
// 读取相机编号
|
|
|
|
|
|
Int16 cameraIndex = plc.ReadNode<Int16>(addressConfig.In_FixedCameracheckNum.Address);
|
|
|
- SendTaskMessage($"编号:{cameraIndex}", MessageLevel.Info);
|
|
|
+ SendTaskMessage($"写入3D相机长度...编号:{cameraIndex}", MessageLevel.Debug);
|
|
|
|
|
|
// 找到对应编号的 PlcPoint
|
|
|
var targetPoint = currentProduct.AoiPoints?.FirstOrDefault(p => p.Number == cameraIndex);
|
|
|
@@ -1653,10 +1656,9 @@ namespace TeamAAS_VP.Core
|
|
|
{
|
|
|
LockResult lockResult = new LockResult();
|
|
|
lockResult.TimeStart = DateTime.Now;
|
|
|
- SendTaskMessage($"触发固定相机检测拍照...", MessageLevel.Debug);
|
|
|
// 读取相机编号
|
|
|
Int16 cameraIndex = plc.ReadNode<Int16>(addressConfig.In_FixedCameracheckNum.Address);
|
|
|
- SendTaskMessage($"编号:{cameraIndex}", MessageLevel.Info);
|
|
|
+ SendTaskMessage($"触发固定相机检测拍照...编号:{cameraIndex}", MessageLevel.Debug);
|
|
|
|
|
|
// 找到对应编号的 PlcPoint
|
|
|
var targetPoint = currentProduct.AoiPoints?.FirstOrDefault(p => p.Number == cameraIndex);
|
|
|
@@ -1689,14 +1691,10 @@ namespace TeamAAS_VP.Core
|
|
|
}
|
|
|
catch { }
|
|
|
var sysConfig = _configService.GetSystemConfiguration();
|
|
|
- string fixedCameraTraceId = $"FC-{cameraIndex}-{DateTime.Now:HHmmss.fff}";
|
|
|
- LogHelper.WriteLogInfo($"[PLC-TRACE] {fixedCameraTraceId} fixed camera trigger start, node={tuple.nodeId}, value={tuple.value}, procCount={procIds.Count}, PhotosUse={sysConfig.PhotosUse}, cameraIndex={cameraIndex}, PhotoCountStop={currentProduct.PhotoCountStop}, thread={Thread.CurrentThread.ManagedThreadId}");
|
|
|
-
|
|
|
+
|
|
|
#region 扫码枪扫码
|
|
|
if (sysConfig.ScannerUse == true && cameraIndex == 1 && sysConfig.CodeUse2 == true)
|
|
|
{
|
|
|
- FinalResultStatus = "检测中";
|
|
|
- FinalResultText = "检测中";
|
|
|
ScanValue = "";
|
|
|
_scanDoneEvent.Reset(); // 重要:先关门
|
|
|
|
|
|
@@ -1779,6 +1777,8 @@ namespace TeamAAS_VP.Core
|
|
|
kb_pn[0] = kbpnsnitem.Replace("KB_PN=", "").Trim();
|
|
|
SendTaskMessage($"KB_PN:{kb_pn[0]}", MessageLevel.Info);
|
|
|
}
|
|
|
+ FinalResultStatus = "检测中";
|
|
|
+ FinalResultText = "检测中";
|
|
|
var item1 = await _systemDatabaseService.QueryProductWithMesALLAsync();
|
|
|
foreach (var q in item1)
|
|
|
{
|
|
|
@@ -1800,10 +1800,20 @@ namespace TeamAAS_VP.Core
|
|
|
if (currentProduct.ID != productId && q.ProductLoad.Contains(kb_pn[0]))
|
|
|
{
|
|
|
//切换产品
|
|
|
- SendTaskMessage($"开始切换产品{q.ProductKBSN}", MessageLevel.Error);
|
|
|
- _productService.LoadProduct(productId);
|
|
|
+ SendTaskMessage($"开始切换产品{q.ProductName}", MessageLevel.Error);
|
|
|
+ var _ = Application.Current.Dispatcher.BeginInvoke(new Action(() => { _dialogService.ShowDialog("UProgressBar", rst => { }); }));
|
|
|
+ await Task.Delay(50);
|
|
|
+ _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
|
|
|
+ {
|
|
|
+ _eventAggregator.GetEvent<ProgressNotification>().Publish(new UProgressBar.ProgressParameter { Maximum = 2, Minimum = 0, SubTitle = $"切换产品...", Message = $"切换{q.ProductName}产品中...", Value = 0 });
|
|
|
+ }));
|
|
|
+ await _productService.LoadProductAsync(productId);
|
|
|
_productService.SetCurrentProduct(productId);
|
|
|
await WritePositionToPlcAsync();
|
|
|
+ _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
|
|
|
+ {
|
|
|
+ _eventAggregator.GetEvent<ProgressNotification>().Publish(new UProgressBar.ProgressParameter { Maximum = 2, Minimum = 0, SubTitle = $"切换产品...", Message = $"{Lang.完成}", Value = -1 });
|
|
|
+ }));
|
|
|
SendTaskMessage($"切换产品成功", MessageLevel.Debug);
|
|
|
break;
|
|
|
}
|
|
|
@@ -1814,9 +1824,19 @@ namespace TeamAAS_VP.Core
|
|
|
{
|
|
|
//切换产品
|
|
|
SendTaskMessage($"开始切换产品{q.ProductCode}", MessageLevel.Error);
|
|
|
- _productService.LoadProduct(productId);
|
|
|
+ var _ = Application.Current.Dispatcher.BeginInvoke(new Action(() => { _dialogService.ShowDialog("UProgressBar", rst => { }); }));
|
|
|
+ await Task.Delay(50);
|
|
|
+ _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
|
|
|
+ {
|
|
|
+ _eventAggregator.GetEvent<ProgressNotification>().Publish(new UProgressBar.ProgressParameter { Maximum = 2, Minimum = 0, SubTitle = $"切换产品...", Message = $"切换{q.ProductName}产品中...", Value = 0 });
|
|
|
+ }));
|
|
|
+ await _productService.LoadProductAsync(productId);
|
|
|
_productService.SetCurrentProduct(productId);
|
|
|
await WritePositionToPlcAsync();
|
|
|
+ _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
|
|
|
+ {
|
|
|
+ _eventAggregator.GetEvent<ProgressNotification>().Publish(new UProgressBar.ProgressParameter { Maximum = 2, Minimum = 0, SubTitle = $"切换产品...", Message = $"{Lang.完成}", Value = -1 });
|
|
|
+ }));
|
|
|
SendTaskMessage($"切换产品成功", MessageLevel.Debug);
|
|
|
break;
|
|
|
}
|
|
|
@@ -1846,8 +1866,6 @@ namespace TeamAAS_VP.Core
|
|
|
|
|
|
if (sysConfig.ScannerUse == true && cameraIndex == 1 && sysConfig.CodeUse == true)
|
|
|
{
|
|
|
- FinalResultStatus = "检测中";
|
|
|
- FinalResultText = "检测中";
|
|
|
ScanValue = "";
|
|
|
_scanDoneEvent.Reset(); // 重要:先关门
|
|
|
|
|
|
@@ -1954,7 +1972,8 @@ namespace TeamAAS_VP.Core
|
|
|
kb_pn[0] = kbpnsnitem.Replace("KB_PN=", "").Trim();
|
|
|
SendTaskMessage($"KB_PN:{kb_pn[0]}", MessageLevel.Info);
|
|
|
}
|
|
|
-
|
|
|
+ FinalResultStatus = "检测中";
|
|
|
+ FinalResultText = "检测中";
|
|
|
var item1 = await _systemDatabaseService.QueryProductWithMesALLAsync();
|
|
|
foreach (var q in item1)
|
|
|
{
|
|
|
@@ -1976,10 +1995,20 @@ namespace TeamAAS_VP.Core
|
|
|
if (currentProduct.ID != productId && q.ProductLoad.Contains(kb_pn[0]))
|
|
|
{
|
|
|
//切换产品
|
|
|
- SendTaskMessage($"开始切换产品{q.ProductKBSN}", MessageLevel.Error);
|
|
|
- _productService.LoadProduct(productId);
|
|
|
+ SendTaskMessage($"开始切换产品{q.ProductName}", MessageLevel.Error);
|
|
|
+ var _ = Application.Current.Dispatcher.BeginInvoke(new Action(() => { _dialogService.ShowDialog("UProgressBar", rst => { }); }));
|
|
|
+ await Task.Delay(50);
|
|
|
+ _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
|
|
|
+ {
|
|
|
+ _eventAggregator.GetEvent<ProgressNotification>().Publish(new UProgressBar.ProgressParameter { Maximum = 2, Minimum = 0, SubTitle = $"切换产品...", Message = $"切换{q.ProductName}产品中...", Value = 0 });
|
|
|
+ }));
|
|
|
+ await _productService.LoadProductAsync(productId);
|
|
|
_productService.SetCurrentProduct(productId);
|
|
|
await WritePositionToPlcAsync();
|
|
|
+ _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
|
|
|
+ {
|
|
|
+ _eventAggregator.GetEvent<ProgressNotification>().Publish(new UProgressBar.ProgressParameter { Maximum = 2, Minimum = 0, SubTitle = $"切换产品...", Message = $"{Lang.完成}", Value = -1 });
|
|
|
+ }));
|
|
|
SendTaskMessage($"切换产品成功", MessageLevel.Debug);
|
|
|
break;
|
|
|
}
|
|
|
@@ -1990,9 +2019,19 @@ namespace TeamAAS_VP.Core
|
|
|
{
|
|
|
//切换产品
|
|
|
SendTaskMessage($"开始切换产品{q.ProductCode}", MessageLevel.Error);
|
|
|
- _productService.LoadProduct(productId);
|
|
|
+ var _ = Application.Current.Dispatcher.BeginInvoke(new Action(() => { _dialogService.ShowDialog("UProgressBar", rst => { }); }));
|
|
|
+ await Task.Delay(50);
|
|
|
+ _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
|
|
|
+ {
|
|
|
+ _eventAggregator.GetEvent<ProgressNotification>().Publish(new UProgressBar.ProgressParameter { Maximum = 2, Minimum = 0, SubTitle = $"切换产品...", Message = $"切换{q.ProductName}产品中...", Value = 0 });
|
|
|
+ }));
|
|
|
+ await _productService.LoadProductAsync(productId);
|
|
|
_productService.SetCurrentProduct(productId);
|
|
|
await WritePositionToPlcAsync();
|
|
|
+ _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
|
|
|
+ {
|
|
|
+ _eventAggregator.GetEvent<ProgressNotification>().Publish(new UProgressBar.ProgressParameter { Maximum = 2, Minimum = 0, SubTitle = $"切换产品...", Message = $"{Lang.完成}", Value = -1 });
|
|
|
+ }));
|
|
|
SendTaskMessage($"切换产品成功", MessageLevel.Debug);
|
|
|
break;
|
|
|
}
|
|
|
@@ -2085,7 +2124,8 @@ namespace TeamAAS_VP.Core
|
|
|
}
|
|
|
count = AllProcId.Count + isscan;
|
|
|
countdown = new CountdownEvent(count);
|
|
|
- SendTaskMessage($"需要执行模板数:{count}", MessageLevel.Alarm);
|
|
|
+ //SendTaskMessage($"需要执行模板数:{count}", MessageLevel.Alarm);
|
|
|
+ LogHelper.WriteLogInfo($"需要执行模板数:{count}");
|
|
|
_ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
|
|
|
{
|
|
|
_eventAggregator.GetEvent<LockResetNotification>().Publish();
|
|
|
@@ -2095,8 +2135,6 @@ namespace TeamAAS_VP.Core
|
|
|
#region 相机扫码
|
|
|
if (sysConfig.CodeUse == true && cameraIndex == 1)
|
|
|
{
|
|
|
- FinalResultStatus = "检测中";
|
|
|
- FinalResultText = "检测中";
|
|
|
var cts = new CancellationTokenSource();
|
|
|
// CameraProcedureId 存储的是具体的视觉流程 Id(ProcedureModel.Id),
|
|
|
// 需要在所有 CameraProcedures 的 ProcedureModels 中查找匹配的流程。
|
|
|
@@ -2230,6 +2268,8 @@ namespace TeamAAS_VP.Core
|
|
|
kb_pn[0] = kbpnsnitem.Replace("KB_PN=", "").Trim();
|
|
|
SendTaskMessage($"KB_PN:{kb_pn[0]}", MessageLevel.Info);
|
|
|
}
|
|
|
+ FinalResultStatus = "检测中";
|
|
|
+ FinalResultText = "检测中";
|
|
|
var item1 = await _systemDatabaseService.QueryProductWithMesALLAsync();
|
|
|
foreach (var q in item1)
|
|
|
{
|
|
|
@@ -2251,10 +2291,20 @@ namespace TeamAAS_VP.Core
|
|
|
if (currentProduct.ID != productId && q.ProductLoad.Contains(kb_pn[0]))
|
|
|
{
|
|
|
//切换产品
|
|
|
- SendTaskMessage($"开始切换产品{q.ProductKBSN}", MessageLevel.Error);
|
|
|
- _productService.LoadProduct(productId);
|
|
|
+ SendTaskMessage($"开始切换产品{q.ProductName}", MessageLevel.Error);
|
|
|
+ var _ = Application.Current.Dispatcher.BeginInvoke(new Action(() => { _dialogService.ShowDialog("UProgressBar", rst => { }); }));
|
|
|
+ await Task.Delay(50);
|
|
|
+ _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
|
|
|
+ {
|
|
|
+ _eventAggregator.GetEvent<ProgressNotification>().Publish(new UProgressBar.ProgressParameter { Maximum = 2, Minimum = 0, SubTitle = $"切换产品...", Message = $"切换{q.ProductName}产品中...", Value = 0 });
|
|
|
+ }));
|
|
|
+ await _productService.LoadProductAsync(productId);
|
|
|
_productService.SetCurrentProduct(productId);
|
|
|
await WritePositionToPlcAsync();
|
|
|
+ _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
|
|
|
+ {
|
|
|
+ _eventAggregator.GetEvent<ProgressNotification>().Publish(new UProgressBar.ProgressParameter { Maximum = 2, Minimum = 0, SubTitle = $"切换产品...", Message = $"{Lang.完成}", Value = -1 });
|
|
|
+ }));
|
|
|
SendTaskMessage($"切换产品成功", MessageLevel.Debug);
|
|
|
break;
|
|
|
}
|
|
|
@@ -2265,9 +2315,19 @@ namespace TeamAAS_VP.Core
|
|
|
{
|
|
|
//切换产品
|
|
|
SendTaskMessage($"开始切换产品{q.ProductCode}", MessageLevel.Error);
|
|
|
- _productService.LoadProduct(productId);
|
|
|
+ var _ = Application.Current.Dispatcher.BeginInvoke(new Action(() => { _dialogService.ShowDialog("UProgressBar", rst => { }); }));
|
|
|
+ await Task.Delay(50);
|
|
|
+ _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
|
|
|
+ {
|
|
|
+ _eventAggregator.GetEvent<ProgressNotification>().Publish(new UProgressBar.ProgressParameter { Maximum = 2, Minimum = 0, SubTitle = $"切换产品...", Message = $"切换{q.ProductName}产品中...", Value = 0 });
|
|
|
+ }));
|
|
|
+ await _productService.LoadProductAsync(productId);
|
|
|
_productService.SetCurrentProduct(productId);
|
|
|
await WritePositionToPlcAsync();
|
|
|
+ _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
|
|
|
+ {
|
|
|
+ _eventAggregator.GetEvent<ProgressNotification>().Publish(new UProgressBar.ProgressParameter { Maximum = 2, Minimum = 0, SubTitle = $"切换产品...", Message = $"{Lang.完成}", Value = -1 });
|
|
|
+ }));
|
|
|
SendTaskMessage($"切换产品成功", MessageLevel.Debug);
|
|
|
break;
|
|
|
}
|
|
|
@@ -2325,8 +2385,6 @@ namespace TeamAAS_VP.Core
|
|
|
|
|
|
if (sysConfig.CodeUse2 == true && cameraIndex == 1)
|
|
|
{
|
|
|
- FinalResultStatus = "检测中";
|
|
|
- FinalResultText = "检测中";
|
|
|
var cts = new CancellationTokenSource();
|
|
|
// CameraProcedureId 存储的是具体的视觉流程 Id(ProcedureModel.Id),
|
|
|
// 需要在所有 CameraProcedures 的 ProcedureModels 中查找匹配的流程。
|
|
|
@@ -2436,6 +2494,8 @@ namespace TeamAAS_VP.Core
|
|
|
kb_pn[0] = kbpnsnitem.Replace("KB_PN=", "").Trim();
|
|
|
SendTaskMessage($"KB_PN:{kb_pn[0]}", MessageLevel.Info);
|
|
|
}
|
|
|
+ FinalResultStatus = "检测中";
|
|
|
+ FinalResultText = "检测中";
|
|
|
var item1 = await _systemDatabaseService.QueryProductWithMesALLAsync();
|
|
|
foreach (var q in item1)
|
|
|
{
|
|
|
@@ -2457,10 +2517,20 @@ namespace TeamAAS_VP.Core
|
|
|
if (currentProduct.ID != productId && q.ProductLoad.Contains(kb_pn[0]))
|
|
|
{
|
|
|
//切换产品
|
|
|
- SendTaskMessage($"开始切换产品{q.ProductKBSN}", MessageLevel.Error);
|
|
|
- _productService.LoadProduct(productId);
|
|
|
+ SendTaskMessage($"开始切换产品{q.ProductName}", MessageLevel.Error);
|
|
|
+ var _ = Application.Current.Dispatcher.BeginInvoke(new Action(() => { _dialogService.ShowDialog("UProgressBar", rst => { }); }));
|
|
|
+ await Task.Delay(50);
|
|
|
+ _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
|
|
|
+ {
|
|
|
+ _eventAggregator.GetEvent<ProgressNotification>().Publish(new UProgressBar.ProgressParameter { Maximum = 2, Minimum = 0, SubTitle = $"切换产品...", Message = $"切换{q.ProductName}产品中...", Value = 0 });
|
|
|
+ }));
|
|
|
+ await _productService.LoadProductAsync(productId);
|
|
|
_productService.SetCurrentProduct(productId);
|
|
|
await WritePositionToPlcAsync();
|
|
|
+ _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
|
|
|
+ {
|
|
|
+ _eventAggregator.GetEvent<ProgressNotification>().Publish(new UProgressBar.ProgressParameter { Maximum = 2, Minimum = 0, SubTitle = $"切换产品...", Message = $"{Lang.完成}", Value = -1 });
|
|
|
+ }));
|
|
|
SendTaskMessage($"切换产品成功", MessageLevel.Debug);
|
|
|
break;
|
|
|
}
|
|
|
@@ -2471,9 +2541,19 @@ namespace TeamAAS_VP.Core
|
|
|
{
|
|
|
//切换产品
|
|
|
SendTaskMessage($"开始切换产品{q.ProductCode}", MessageLevel.Error);
|
|
|
- _productService.LoadProduct(productId);
|
|
|
+ var _ = Application.Current.Dispatcher.BeginInvoke(new Action(() => { _dialogService.ShowDialog("UProgressBar", rst => { }); }));
|
|
|
+ await Task.Delay(50);
|
|
|
+ _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
|
|
|
+ {
|
|
|
+ _eventAggregator.GetEvent<ProgressNotification>().Publish(new UProgressBar.ProgressParameter { Maximum = 2, Minimum = 0, SubTitle = $"切换产品...", Message = $"切换{q.ProductName}产品中...", Value = 0 });
|
|
|
+ }));
|
|
|
+ await _productService.LoadProductAsync(productId);
|
|
|
_productService.SetCurrentProduct(productId);
|
|
|
await WritePositionToPlcAsync();
|
|
|
+ _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
|
|
|
+ {
|
|
|
+ _eventAggregator.GetEvent<ProgressNotification>().Publish(new UProgressBar.ProgressParameter { Maximum = 2, Minimum = 0, SubTitle = $"切换产品...", Message = $"{Lang.完成}", Value = -1 });
|
|
|
+ }));
|
|
|
SendTaskMessage($"切换产品成功", MessageLevel.Debug);
|
|
|
break;
|
|
|
}
|
|
|
@@ -2518,7 +2598,6 @@ namespace TeamAAS_VP.Core
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
-
|
|
|
//不能使用全局变量,不然并发的时候会被清除掉,所以局部变量
|
|
|
var _ImageTaskList = new List<Task<(bool IsSucceed, ICogImage[] Images, string Message, int cameraIndex, Guid procedureId)>>();
|
|
|
|
|
|
@@ -2548,36 +2627,23 @@ namespace TeamAAS_VP.Core
|
|
|
if (sysConfig.PhotosUse == true)
|
|
|
{
|
|
|
bool Is3dPhoto = Is3D(prcId);
|
|
|
- var grabWatch = Stopwatch.StartNew();
|
|
|
- LogHelper.WriteLogInfo($"[PLC-TRACE] {fixedCameraTraceId} GrabImageEx start, cameraIndex={cameraIndex}, procedureId={prcId}, is3D={Is3dPhoto}, thread={Thread.CurrentThread.ManagedThreadId}");
|
|
|
var tt = await GrabImageEx(cameraIndex, prcId, Is3dPhoto, currentProduct, sysConfig);
|
|
|
- grabWatch.Stop();
|
|
|
- LogHelper.WriteLogInfo($"[PLC-TRACE] {fixedCameraTraceId} GrabImageEx done, cameraIndex={cameraIndex}, procedureId={prcId}, success={tt.IsSucceed}, elapsedMs={grabWatch.ElapsedMilliseconds}, msg={tt.Message}");
|
|
|
+
|
|
|
if (tt.IsSucceed == false)
|
|
|
{
|
|
|
SendTaskMessage($"图像采集失败!{cameraIndex}: {prcId}", MessageLevel.Alarm);
|
|
|
- LogHelper.WriteLogInfo($"[PLC-TRACE] {fixedCameraTraceId} return before status write because GrabImageEx failed, cameraIndex={cameraIndex}, procedureId={prcId}");
|
|
|
return;
|
|
|
}
|
|
|
- var executeWatch = Stopwatch.StartNew();
|
|
|
- LogHelper.WriteLogInfo($"[PLC-TRACE] {fixedCameraTraceId} ExecuteProcedureAsync start, cameraIndex={cameraIndex}, procedureId={prcId}, imageCount={(tt.imges == null ? 0 : tt.imges.Length)}");
|
|
|
await ExecuteProcedureAsync(cameraIndex, prcId, tt.imges, Is3dPhoto, currentProduct);
|
|
|
- executeWatch.Stop();
|
|
|
- LogHelper.WriteLogInfo($"[PLC-TRACE] {fixedCameraTraceId} ExecuteProcedureAsync done, cameraIndex={cameraIndex}, procedureId={prcId}, elapsedMs={executeWatch.ElapsedMilliseconds}");
|
|
|
if (targetPoint.AiVision == 1)
|
|
|
{
|
|
|
var targetPoint2 = currentProduct.AoiPoints?.FirstOrDefault(p => p.Number == targetPoint.AiVision);
|
|
|
- var aiExecuteWatch = Stopwatch.StartNew();
|
|
|
- LogHelper.WriteLogInfo($"[PLC-TRACE] {fixedCameraTraceId} AiVision ExecuteProcedureAsync start, aiPoint={targetPoint.AiVision}, procedureId={targetPoint2?.CameraProcedureId1}");
|
|
|
await ExecuteProcedureAsync(targetPoint.AiVision, targetPoint2.CameraProcedureId1, tt.imges, Is3dPhoto, currentProduct);
|
|
|
- aiExecuteWatch.Stop();
|
|
|
- LogHelper.WriteLogInfo($"[PLC-TRACE] {fixedCameraTraceId} AiVision ExecuteProcedureAsync done, aiPoint={targetPoint.AiVision}, elapsedMs={aiExecuteWatch.ElapsedMilliseconds}");
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
bool Is3dPhoto = Is3D(prcId);
|
|
|
- LogHelper.WriteLogInfo($"[PLC-TRACE] {fixedCameraTraceId} enqueue GrabImageEx task, cameraIndex={cameraIndex}, procedureId={prcId}, is3D={Is3dPhoto}");
|
|
|
_ImageTaskList.Add(GrabImageEx(cameraIndex, prcId, Is3dPhoto, currentProduct, sysConfig));
|
|
|
if (targetPoint.AiVision == 1)
|
|
|
{
|
|
|
@@ -2591,27 +2657,18 @@ namespace TeamAAS_VP.Core
|
|
|
// await _remoteCommandService.TurnOffLightAfterPhoto(selectedProcedure);
|
|
|
// }
|
|
|
}
|
|
|
-
|
|
|
if (cameraIndex != currentProduct.PhotoCountStop)
|
|
|
{
|
|
|
//直接放行,执行下一个检测点
|
|
|
- var statusWriteWatch = Stopwatch.StartNew();
|
|
|
- LogHelper.WriteLogInfo($"[PLC-TRACE] {fixedCameraTraceId} status write start, node={addressConfig.Out_FixedCameraPickStatus.Address}, value=1, beforeImageTaskCount={_ImageTaskList.Count}, thread={Thread.CurrentThread.ManagedThreadId}");
|
|
|
- bool statusWriteResult = await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)1);
|
|
|
- statusWriteWatch.Stop();
|
|
|
- LogHelper.WriteLogInfo($"[PLC-TRACE] {fixedCameraTraceId} status write done, node={addressConfig.Out_FixedCameraPickStatus.Address}, value=1, result={statusWriteResult}, elapsedMs={statusWriteWatch.ElapsedMilliseconds}");
|
|
|
+ await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPickStatus.Address, (Int16)1);
|
|
|
}
|
|
|
-
|
|
|
if (_ImageTaskList.Count > 0)//如果2D取图有队列
|
|
|
{
|
|
|
//并发
|
|
|
- LogHelper.WriteLogInfo($"[PLC-TRACE] {fixedCameraTraceId} image task batch start, taskCount={_ImageTaskList.Count}");
|
|
|
_ = Task.Run(async () =>
|
|
|
{
|
|
|
- var imageBatchWatch = Stopwatch.StartNew();
|
|
|
+
|
|
|
var ImageTaskResults = await Task.WhenAll(_ImageTaskList);
|
|
|
- imageBatchWatch.Stop();
|
|
|
- LogHelper.WriteLogInfo($"[PLC-TRACE] {fixedCameraTraceId} image task batch done, taskCount={ImageTaskResults.Length}, elapsedMs={imageBatchWatch.ElapsedMilliseconds}");
|
|
|
// 并发执行所有 ToolBlock(每个 ToolBlock 在独立 STA 线程中运行)
|
|
|
var procedureTasks = new List<Task>();
|
|
|
foreach (var item in ImageTaskResults)
|
|
|
@@ -2634,12 +2691,8 @@ namespace TeamAAS_VP.Core
|
|
|
}
|
|
|
}
|
|
|
// 等待所有并发 ToolBlock 执行完成
|
|
|
- var concurrentWatch = Stopwatch.StartNew();
|
|
|
- LogHelper.WriteLogInfo($"[PLC-TRACE] {fixedCameraTraceId} concurrent ToolBlock execution starting, taskCount={procedureTasks.Count}, thread={Thread.CurrentThread.ManagedThreadId}, time={DateTime.Now:HH:mm:ss.fff}");
|
|
|
await Task.WhenAll(procedureTasks);
|
|
|
- concurrentWatch.Stop();
|
|
|
- LogHelper.WriteLogInfo($"[PLC-TRACE] {fixedCameraTraceId} concurrent ToolBlock execution done, taskCount={procedureTasks.Count}, elapsedMs={concurrentWatch.ElapsedMilliseconds}, thread={Thread.CurrentThread.ManagedThreadId}, time={DateTime.Now:HH:mm:ss.fff}");
|
|
|
- });
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
//如果最后一个拍照点,则需要等待前面所有的拍照处理完成
|
|
|
@@ -2650,8 +2703,7 @@ namespace TeamAAS_VP.Core
|
|
|
//等待所有的图像处理流程处理完成
|
|
|
//之前版本使用的是lock机制无法进行并发操作,目前能完美进行并发且能等待所有任务完成
|
|
|
// 异步等待 countdown,避免同步阻塞线程池线程
|
|
|
- LogHelper.WriteLogInfo($"[PLC-TRACE] {fixedCameraTraceId} countdown wait start, expected={countdown.InitialCount}, current={countdown.CurrentCount}, thread={Thread.CurrentThread.ManagedThreadId}, time={DateTime.Now:HH:mm:ss.fff}");
|
|
|
- bool countdownCompleted;
|
|
|
+ bool countdownCompleted;
|
|
|
using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)))
|
|
|
{
|
|
|
try
|
|
|
@@ -2664,7 +2716,6 @@ namespace TeamAAS_VP.Core
|
|
|
countdownCompleted = false;
|
|
|
}
|
|
|
}
|
|
|
- LogHelper.WriteLogInfo($"[PLC-TRACE] {fixedCameraTraceId} countdown wait done, completed={countdownCompleted}, remaining={countdown.CurrentCount}, thread={Thread.CurrentThread.ManagedThreadId}, time={DateTime.Now:HH:mm:ss.fff}");
|
|
|
if (!countdownCompleted)
|
|
|
{
|
|
|
SendTaskMessage($"检测流程超时!预期{countdown.InitialCount}个模板完成,实际仅完成{countdown.InitialCount - countdown.CurrentCount}个,按NG处理", MessageLevel.Alarm);
|
|
|
@@ -2688,12 +2739,10 @@ namespace TeamAAS_VP.Core
|
|
|
resultFlog = false;
|
|
|
break;
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
-
|
|
|
foreach (var item in AllResult)
|
|
|
{
|
|
|
if (!item)
|
|
|
@@ -2975,8 +3024,6 @@ namespace TeamAAS_VP.Core
|
|
|
//过站检查
|
|
|
if (state == 1)
|
|
|
{
|
|
|
- FinalResultStatus = "检测中";
|
|
|
- FinalResultText = "检测中";
|
|
|
//这里缺少从MES获取产品配方的内容,需要补充
|
|
|
_LastMesCheckTime[i] = (await _mesService.GetServerTimeAsync(code, 2)).Now;
|
|
|
DeviceInfo stationConfig2 = new DeviceInfo();
|
|
|
@@ -3078,7 +3125,8 @@ namespace TeamAAS_VP.Core
|
|
|
SendTaskMessage($"KB_PN:{kb_pn[i]}", MessageLevel.Info);
|
|
|
}
|
|
|
ShowMes_Query = true;
|
|
|
-
|
|
|
+ FinalResultStatus = "检测中";
|
|
|
+ FinalResultText = "检测中";
|
|
|
if (stationConfig2.EnableMES)
|
|
|
{
|
|
|
//切换产品
|
|
|
@@ -3108,10 +3156,20 @@ namespace TeamAAS_VP.Core
|
|
|
if (currentProduct.ID != productId && q.ProductLoad.Contains(kb_pn[i]))
|
|
|
{
|
|
|
//切换产品
|
|
|
- SendTaskMessage($"开始切换产品{q.ProductKBSN}", MessageLevel.Error);
|
|
|
- _productService.LoadProduct(productId);
|
|
|
+ SendTaskMessage($"开始切换产品{q.ProductName}", MessageLevel.Error);
|
|
|
+ var _ = Application.Current.Dispatcher.BeginInvoke(new Action(() => { _dialogService.ShowDialog("UProgressBar", rst => { }); }));
|
|
|
+ await Task.Delay(50);
|
|
|
+ _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
|
|
|
+ {
|
|
|
+ _eventAggregator.GetEvent<ProgressNotification>().Publish(new UProgressBar.ProgressParameter { Maximum = 2, Minimum = 0, SubTitle = $"切换产品...", Message = $"切换{q.ProductName}产品中...", Value = 0 });
|
|
|
+ }));
|
|
|
+ await _productService.LoadProductAsync(productId);
|
|
|
_productService.SetCurrentProduct(productId);
|
|
|
await WritePositionToPlcAsync();
|
|
|
+ _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
|
|
|
+ {
|
|
|
+ _eventAggregator.GetEvent<ProgressNotification>().Publish(new UProgressBar.ProgressParameter { Maximum = 2, Minimum = 0, SubTitle = $"切换产品...", Message = $"{Lang.完成}", Value = -1 });
|
|
|
+ }));
|
|
|
SendTaskMessage($"切换产品成功", MessageLevel.Debug);
|
|
|
break;
|
|
|
}
|
|
|
@@ -3122,9 +3180,19 @@ namespace TeamAAS_VP.Core
|
|
|
{
|
|
|
//切换产品
|
|
|
SendTaskMessage($"开始切换产品{q.ProductCode}", MessageLevel.Error);
|
|
|
- _productService.LoadProduct(productId);
|
|
|
+ var _ = Application.Current.Dispatcher.BeginInvoke(new Action(() => { _dialogService.ShowDialog("UProgressBar", rst => { }); }));
|
|
|
+ await Task.Delay(50);
|
|
|
+ _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
|
|
|
+ {
|
|
|
+ _eventAggregator.GetEvent<ProgressNotification>().Publish(new UProgressBar.ProgressParameter { Maximum = 2, Minimum = 0, SubTitle = $"切换产品...", Message = $"切换{q.ProductName}产品中...", Value = 0 });
|
|
|
+ }));
|
|
|
+ await _productService.LoadProductAsync(productId);
|
|
|
_productService.SetCurrentProduct(productId);
|
|
|
await WritePositionToPlcAsync();
|
|
|
+ _ = App.Current.Dispatcher.BeginInvoke(new Action(() =>
|
|
|
+ {
|
|
|
+ _eventAggregator.GetEvent<ProgressNotification>().Publish(new UProgressBar.ProgressParameter { Maximum = 2, Minimum = 0, SubTitle = $"切换产品...", Message = $"{Lang.完成}", Value = -1 });
|
|
|
+ }));
|
|
|
SendTaskMessage($"切换产品成功", MessageLevel.Debug);
|
|
|
break;
|
|
|
}
|
|
|
@@ -3176,13 +3244,16 @@ namespace TeamAAS_VP.Core
|
|
|
var stationConfig = _configService.GetDeviceInfo(0);
|
|
|
|
|
|
List<DataFormCtq> DFC = new List<DataFormCtq>();
|
|
|
+ List<DataFormCtq> NGDFC = new List<DataFormCtq>();
|
|
|
SendTaskMessage($"收到{i}上传本站数据请求...", MessageLevel.Debug);
|
|
|
//读取产品结果
|
|
|
-
|
|
|
Int16 resultIndex = plc.ReadNode<Int16>(string.Format(addressConfig.In_Result.Address, i));
|
|
|
SendTaskMessage($"读取plc结果{resultIndex}", MessageLevel.Debug);
|
|
|
|
|
|
- await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)3);
|
|
|
+ if (!sysConfig.IsInOut)
|
|
|
+ {
|
|
|
+ await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)3);
|
|
|
+ }
|
|
|
|
|
|
//这里缺少上传MES的本站数据结果及开始和结束时间,需要补充
|
|
|
//从服务器中获取当前时间
|
|
|
@@ -3215,16 +3286,16 @@ namespace TeamAAS_VP.Core
|
|
|
LogHelper.WriteLogMes($"【mes开始ADD】");
|
|
|
SendTaskMessage($"mes开始ADD", MessageLevel.Info);
|
|
|
|
|
|
+ string Error = "";
|
|
|
StringBuilder submitDataError = new StringBuilder();
|
|
|
foreach (var item in lockResultsAll)
|
|
|
{
|
|
|
if (item.PhotoPassed == "NG")
|
|
|
{
|
|
|
submitDataError.Append(item.PhotoName + "_" + item.ResultData + "_Fail,");
|
|
|
+ Error += item.PhotoName + "_" + item.ResultData + "_Fail;";
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
StringBuilder submitData = new StringBuilder();
|
|
|
StringBuilder submitData2 = new StringBuilder();
|
|
|
StringBuilder submitData3 = new StringBuilder();
|
|
|
@@ -3332,7 +3403,10 @@ namespace TeamAAS_VP.Core
|
|
|
LogHelper.WriteLogMes($"上传mes失败");
|
|
|
SendTaskMessage($"上传mes失败", MessageLevel.Error);
|
|
|
}
|
|
|
-
|
|
|
+ if (sysConfig.IsInOut)
|
|
|
+ {
|
|
|
+ await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)3);
|
|
|
+ }
|
|
|
//是否保存当前的产品记录至CSV?
|
|
|
if (stationConfig.SaveCsv)
|
|
|
{
|
|
|
@@ -3413,7 +3487,7 @@ namespace TeamAAS_VP.Core
|
|
|
PROCESS_END_TIME = serverTimeResult.Now.ToString("yyyy-MM-ddTHH:mm:ss.fffffff") + "+08:00",
|
|
|
SUPPLIER_NAME = stationConfig.DataInfo.SUPPLIER_NAME,
|
|
|
COMMODITY_TYPE = temp_COMMODITY_TYPE,
|
|
|
- REVISION = stationConfig.DataInfo.REVISION + "_" + stage,//
|
|
|
+ REVISION = stationConfig.DataInfo.REVISION + "_" + stage[i],//
|
|
|
WO = wo[i],//
|
|
|
MFG_LOT = stationConfig.DataInfo.MFG_LOT,//
|
|
|
MFG_ASSY_LINE = stationConfig.DataInfo.MFG_ASSY_LINE,
|
|
|
@@ -3448,7 +3522,7 @@ namespace TeamAAS_VP.Core
|
|
|
PROCESS_END_TIME = serverTimeResult.Now.ToString("yyyy-MM-ddTHH:mm:ss.fffffff") + "+08:00",
|
|
|
SUPPLIER_NAME = stationConfig.DataInfo.SUPPLIER_NAME,
|
|
|
COMMODITY_TYPE = stationConfig.DataInfo.COMMODITY_TYPE,
|
|
|
- REVISION = stationConfig.DataInfo.REVISION + "_" + stage,//
|
|
|
+ REVISION = stationConfig.DataInfo.REVISION + "_" + stage[i],//
|
|
|
WO = wo[i],//
|
|
|
MFG_LOT = stationConfig.DataInfo.MFG_LOT,//
|
|
|
MFG_ASSY_LINE = stationConfig.DataInfo.MFG_ASSY_LINE,
|
|
|
@@ -3480,7 +3554,7 @@ namespace TeamAAS_VP.Core
|
|
|
PROCESS_END_TIME = serverTimeResult.Now.ToString("yyyy-MM-ddTHH:mm:ss.fffffff") + "+08:00",
|
|
|
SUPPLIER_NAME = stationConfig.DataInfo.SUPPLIER_NAME,
|
|
|
COMMODITY_TYPE = stationConfig.DataInfo.COMMODITY_TYPE,
|
|
|
- REVISION = stationConfig.DataInfo.REVISION + "_" + stage,//
|
|
|
+ REVISION = stationConfig.DataInfo.REVISION + "_" + stage[i],//
|
|
|
WO = wo[i],//
|
|
|
MFG_LOT = stationConfig.DataInfo.MFG_LOT,//
|
|
|
MFG_ASSY_LINE = stationConfig.DataInfo.MFG_ASSY_LINE,
|
|
|
@@ -3503,13 +3577,24 @@ namespace TeamAAS_VP.Core
|
|
|
//{
|
|
|
// resultToMes.Clear();
|
|
|
//}
|
|
|
- bool recordResult = RecordStationResult(i, DFC, ProductMainSN, serverTimeResult.Now.Subtract(_LastMesCheckTime[i]).TotalSeconds, _LastMesCheckTime[i], stationConfig.SaveCsvPath);
|
|
|
+ bool recordResult = RecordStationResult(i, DFC, ProductMainSN, serverTimeResult.Now.Subtract(_LastMesCheckTime[i]).TotalSeconds, _LastMesCheckTime[i], stationConfig.SaveCsvPath, out string actualCsvPath);
|
|
|
// bool recordResult1 = WriteProductLog( ProductMainSN, serverTimeResult.Now.Subtract(_LastMesCheckTime[i]).TotalSeconds, _LastMesCheckTime[i], stationConfig.SaveCsvPath, DFC);
|
|
|
|
|
|
//keyData.Clear();
|
|
|
if (recordResult)
|
|
|
{
|
|
|
SendTaskMessage($"{i}:{stationConfig.DeviceName}产品记录保存成功", MessageLevel.Debug);
|
|
|
+ if (Error != "")
|
|
|
+ {
|
|
|
+ NGDFC.Add(new DataFormCtq
|
|
|
+ {
|
|
|
+ PROCESS_START_TIME = _LastMesCheckTime[i].ToString("yyyy-MM-ddTHH:mm:ss.fffffff") + "+08:00",
|
|
|
+ PROCESS_END_TIME = serverTimeResult.Now.ToString("yyyy-MM-ddTHH:mm:ss.fffffff") + "+08:00",
|
|
|
+ ERROR_MESSAGE = Error,
|
|
|
+ PD_ATTR_01 = ProductMainSN,//
|
|
|
+ });
|
|
|
+ RecordStationNGResult(NGDFC, _LastMesCheckTime[i]);
|
|
|
+ }
|
|
|
//上传数据
|
|
|
try
|
|
|
{
|
|
|
@@ -3528,20 +3613,34 @@ namespace TeamAAS_VP.Core
|
|
|
|
|
|
//filePath = $"D:\\Image\\Recored\\{dt.ToString("yyyy-MM")}\\{dt.ToString("MM-dd")}\\{currentProduct.Name}\\{ProductMainSN}";
|
|
|
filePath = $"{PhotoPath}\\Recored\\{dt.ToString("yyyy-MM")}\\{dt.ToString("MM-dd")}\\{currentProduct.Name}\\{ProductMainSN}";
|
|
|
- //string source_csv2 = $"{stationConfig.SaveCsvPath}\\{dt.ToString("yyyy-MM")}\\{i}_{stationConfig.DeviceName}_{dt.ToString("yyyy-MM-dd")}";
|
|
|
string csvfilename = $"{i}_{stationConfig.DeviceName}_{dt.ToString("yyyy-MM-dd")}";
|
|
|
- //复制csv
|
|
|
- string source_csv = $"{stationConfig.SaveCsvPath}\\{dt.ToString("yyyy-MM")}\\{i}_{stationConfig.DeviceName}_{dt.ToString("yyyy-MM-dd")}.csv";
|
|
|
- //string source_csv1 = $"{stationConfig.SaveCsvPath}\\{dt.ToString("yyyy-MM")}";
|
|
|
- string target_csv = Path.Combine(filePath, Path.GetFileName(source_csv));
|
|
|
- File.Copy(source_csv, target_csv, true);
|
|
|
+ //复制csv — 使用 actualCsvPath(可能是备份路径)
|
|
|
+ string target_csv = Path.Combine(filePath, Path.GetFileName(actualCsvPath));
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (!Directory.Exists(filePath))
|
|
|
+ Directory.CreateDirectory(filePath);
|
|
|
+ File.Copy(actualCsvPath, target_csv, true);
|
|
|
+ }
|
|
|
+ catch (Exception copyEx)
|
|
|
+ {
|
|
|
+ LogHelper.WriteLogError($"复制CSV到上传目录失败: src={actualCsvPath}, dst={target_csv}", copyEx);
|
|
|
+ }
|
|
|
//复制log
|
|
|
- string source_log = $"..\\Log\\LogInfo\\{dt.ToString("yyyy-MM")}\\{dt.ToString("yyyy-MM-dd")}.txt";
|
|
|
- string target_log = Path.Combine(filePath, Path.GetFileName(source_log));
|
|
|
- File.Copy(source_log, target_log, true);
|
|
|
+ try
|
|
|
+ {
|
|
|
+ string source_log = $"..\\Log\\LogInfo\\{dt.ToString("yyyy-MM")}\\{dt.ToString("yyyy-MM-dd")}.txt";
|
|
|
+ string target_log = Path.Combine(filePath, Path.GetFileName(source_log));
|
|
|
+ File.Copy(source_log, target_log, true);
|
|
|
+ }
|
|
|
+ catch (Exception copyLogEx)
|
|
|
+ {
|
|
|
+ LogHelper.WriteLogError($"复制Log到上传目录失败", copyLogEx);
|
|
|
+ }
|
|
|
|
|
|
|
|
|
- CompressionImage(filePath, filename, device.Station, device.FixtureId);
|
|
|
+ try { CompressionImage(filePath, filename, device.Station, device.FixtureId); }
|
|
|
+ catch (Exception zipEx) { LogHelper.WriteLogError($"压缩图片文件夹失败", zipEx); }
|
|
|
//上传csv
|
|
|
bool isAfter20 = dt.Hour >= 20;
|
|
|
//判断是否是新的一天
|
|
|
@@ -3549,12 +3648,16 @@ namespace TeamAAS_VP.Core
|
|
|
//当天还没执行过压缩
|
|
|
if (isAfter20 && isNewDay && !_hasCompressedToday)
|
|
|
{
|
|
|
- // 执行压缩
|
|
|
- CompressionSingleCsv(source_csv, csvfilename, device.Station, device.FixtureId);
|
|
|
- _lastCompressDate = dt;
|
|
|
- _hasCompressedToday = true;
|
|
|
- LogHelper.WriteLogMes("csv上传数据成功");
|
|
|
- SendTaskMessage($"csv上传数据成功", MessageLevel.Debug);
|
|
|
+ // 执行压缩 — 使用 actualCsvPath
|
|
|
+ try
|
|
|
+ {
|
|
|
+ CompressionSingleCsv(actualCsvPath, csvfilename, device.Station, device.FixtureId);
|
|
|
+ _lastCompressDate = dt;
|
|
|
+ _hasCompressedToday = true;
|
|
|
+ LogHelper.WriteLogMes("csv上传数据成功");
|
|
|
+ SendTaskMessage($"csv上传数据成功", MessageLevel.Debug);
|
|
|
+ }
|
|
|
+ catch (Exception csvZipEx) { LogHelper.WriteLogError($"压缩CSV文件失败", csvZipEx); }
|
|
|
}
|
|
|
// 跨天后重置当天执行标记
|
|
|
if (!isNewDay && _hasCompressedToday)
|
|
|
@@ -5682,8 +5785,9 @@ namespace TeamAAS_VP.Core
|
|
|
/// <param name="savePath"></param>
|
|
|
/// <param name="isFirstEnter"></param>
|
|
|
/// <returns></returns>
|
|
|
- private bool RecordStationResult(int stationIndex, IEnumerable<DataFormCtq> dfcs, string productMainSN, double ct, DateTime timestamp, string savePath, bool isFirstEnter = true)
|
|
|
+ private bool RecordStationResult(int stationIndex, IEnumerable<DataFormCtq> dfcs, string productMainSN, double ct, DateTime timestamp, string savePath, out string actualPath, bool isFirstEnter = true)
|
|
|
{
|
|
|
+ actualPath = null;
|
|
|
try
|
|
|
{
|
|
|
//获取当前工位的配置
|
|
|
@@ -5734,6 +5838,75 @@ namespace TeamAAS_VP.Core
|
|
|
sb.Append($"{dfc.PPID},{dfc.PROCESS_NAME},{dfc.PROCESS_START_TIME},{dfc.CTQ_NAME},{dfc.CTQ_VALUE},{dfc.CTQ_LSL},{dfc.CTQ_USL},{dfc.PROCESS_END_TIME},{dfc.SUPPLIER_NAME},{dfc.COMMODITY_TYPE},{dfc.REVISION},{dfc.WO},{dfc.MFG_LOT},{dfc.MFG_ASSY_LINE},{dfc.PROCESS_OUTCOME},{dfc.PROCESS_MACHINE_ID},{dfc.CTQ_UNIT_OF_MEASURE},{dfc.ERROR_MESSAGE},{dfc.PD_ATTR_01},{dfc.PD_ATTR_02},{dfc.PD_ATTR_03},{dfc.PD_ATTR_04},{dfc.PD_ATTR_05},{dfc.PD_ATTR_06}");
|
|
|
sb.AppendLine();
|
|
|
}
|
|
|
+ // 使用 StreamWriter 以追加模式写入,使用 using 确保异常时句柄不泄漏
|
|
|
+ try
|
|
|
+ {
|
|
|
+ using (StreamWriter sw = new StreamWriter(fullPath, true, Encoding.UTF8))
|
|
|
+ {
|
|
|
+ sw.Write(sb.ToString());
|
|
|
+ }
|
|
|
+ actualPath = fullPath;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ catch (IOException ioEx) when (ioEx.Message.Contains("另一进程") || ioEx.Message.Contains("being used"))
|
|
|
+ {
|
|
|
+ // 主文件被占用,生成备份文件写入
|
|
|
+ string mainDir = Path.GetDirectoryName(fullPath);
|
|
|
+ if (string.IsNullOrEmpty(mainDir))
|
|
|
+ mainDir = savePath;
|
|
|
+ string backupDir = Path.Combine(mainDir, "Backup");
|
|
|
+ if (!Directory.Exists(backupDir))
|
|
|
+ Directory.CreateDirectory(backupDir);
|
|
|
+ string backupFileName = $"{stationIndex}_{stationConfig.DeviceName}_{DateTime.Now:yyyy-MM-dd_HHmmssfff}.csv";
|
|
|
+ string backupPath = Path.Combine(backupDir, backupFileName);
|
|
|
+ using (StreamWriter sw = new StreamWriter(backupPath, false, Encoding.UTF8))
|
|
|
+ {
|
|
|
+ sw.Write(sb.ToString());
|
|
|
+ }
|
|
|
+ actualPath = backupPath;
|
|
|
+ SendTaskMessage($"主CSV文件被占用,已写入备份文件: {backupPath}", MessageLevel.Alarm);
|
|
|
+ LogHelper.WriteLogInfo($"CSV主文件被占用,已写备份: 主={fullPath}, 备份={backupPath}");
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ LogHelper.WriteLogError("记录其他工位结果时出错!", ex);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 记录工位的NG结果
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="dfcs">NG数据</param>
|
|
|
+ /// <param name="timestamp">时间</param>
|
|
|
+ /// <returns></returns>
|
|
|
+ private bool RecordStationNGResult(IEnumerable<DataFormCtq> dfcs, DateTime timestamp)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ string datePath = timestamp.ToString("yyyy-MM") + "\\";
|
|
|
+ string dirPath = Path.Combine(@"D:\NG", datePath);
|
|
|
+ if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath);
|
|
|
+ string fileName = $"NG_{timestamp.ToString("yyyy-MM-dd")}.csv";
|
|
|
+ string fullPath = Path.Combine(dirPath, fileName);
|
|
|
+ // ============================================================
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
+ if (!File.Exists(fullPath))
|
|
|
+ {
|
|
|
+ sb.Append("PD_ATTR_01,ERROR_MESSAGE,PROCESS_START_TIME,PROCESS_END_TIME");
|
|
|
+ sb.AppendLine();
|
|
|
+ }
|
|
|
+ if (dfcs == null || dfcs.Count() == 0)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ foreach (var dfc in dfcs)
|
|
|
+ {
|
|
|
+ sb.Append($"{dfc.PD_ATTR_01},{dfc.ERROR_MESSAGE},{dfc.PROCESS_START_TIME},{dfc.PROCESS_END_TIME}");
|
|
|
+ sb.AppendLine();
|
|
|
+ }
|
|
|
// 使用 StreamWriter 以追加模式打开文件
|
|
|
StreamWriter sw = new StreamWriter(fullPath, true, Encoding.UTF8);
|
|
|
sw.Write(sb.ToString());
|
|
|
@@ -5743,17 +5916,7 @@ namespace TeamAAS_VP.Core
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
- if (!isFirstEnter)
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
LogHelper.WriteLogError("记录其他工位结果时出错!", ex);
|
|
|
- //我希望在这里生成一个临时文件来保存这次的记录,因为如果本地文件被打开时可能会导致无法写入,如果不保存的话可能会丢失这次的记录,所以我想在这里生成一个临时文件来保存这次的记录
|
|
|
- //生成临时文件的路径,格式为savePath\yyyy-MM\工位编号_yyyy-MM-dd_temp\工位编号_yyyy-MM-dd_HH-mm-ss-fff_temp.csv
|
|
|
- string datePath = timestamp.ToString("yyyy-MM") + "\\";
|
|
|
- string tempDirPath = Path.Combine(savePath, datePath, $"{stationIndex}_{timestamp.ToString("yyyy-MM-dd")}_temp");
|
|
|
- string tempFileName = $"{stationIndex}_{timestamp.ToString("yyyy-MM-dd_HH-mm-ss-fff")}_temp.csv";
|
|
|
- RecordStationResult(stationIndex, dfcs, productMainSN, ct, timestamp, tempFileName, false);
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
@@ -5949,7 +6112,6 @@ namespace TeamAAS_VP.Core
|
|
|
/// <returns></returns>
|
|
|
private async Task<(bool IsSucceed, ICogImage[] imges, string Message, int pointIndex, Guid procedureId)> GrabImageEx(int pointIndex, Guid procedureId, bool Is3dPhoto, ProductModel currentProduct, SystemConfiguration sysConfig)
|
|
|
{
|
|
|
- var grabExWatch = Stopwatch.StartNew();
|
|
|
// 获取当前产品
|
|
|
//var currentProduct = _productService.GetCurrentProduct();
|
|
|
if (currentProduct == null)
|
|
|
@@ -5966,7 +6128,7 @@ namespace TeamAAS_VP.Core
|
|
|
|
|
|
try
|
|
|
{
|
|
|
- var procFindWatch = Stopwatch.StartNew();
|
|
|
+
|
|
|
ProcedureModel selectedProcedure = null;
|
|
|
try
|
|
|
{
|
|
|
@@ -5982,9 +6144,7 @@ namespace TeamAAS_VP.Core
|
|
|
{
|
|
|
LogHelper.WriteLogError("查找 AOI 点位对应视觉流程时出错", ex);
|
|
|
}
|
|
|
- procFindWatch.Stop();
|
|
|
- LogHelper.WriteLogInfo($"[PLC-TRACE] GrabImageEx procFind done, pointIndex={pointIndex}, procId={procedureId}, is3D={Is3dPhoto}, elapsedMs={procFindWatch.ElapsedMilliseconds}, thread={Thread.CurrentThread.ManagedThreadId}");
|
|
|
-
|
|
|
+
|
|
|
if (selectedProcedure == null)
|
|
|
{
|
|
|
SendTaskMessage($"未找到 AOI 点位对应的视觉流程,Point#{pointIndex} ProcedureId={pointIndex}", MessageLevel.Alarm);
|
|
|
@@ -5997,19 +6157,10 @@ namespace TeamAAS_VP.Core
|
|
|
//var sysConfig = _configService.GetSystemConfiguration();
|
|
|
if (selectedProcedure.Id == currentProduct.FixedDownCameraProcedureId && sysConfig.TurnOnAllLightUse == true)
|
|
|
{
|
|
|
- var lightWatch = Stopwatch.StartNew();
|
|
|
await _remoteCommandService.SetLightBeforePhoto(selectedProcedure);
|
|
|
- lightWatch.Stop();
|
|
|
- LogHelper.WriteLogInfo($"[PLC-TRACE] GrabImageEx SetLightBeforePhoto done, pointIndex={pointIndex}, elapsedMs={lightWatch.ElapsedMilliseconds}");
|
|
|
}
|
|
|
//1. 执行拍照
|
|
|
- var grabAsyncWatch = Stopwatch.StartNew();
|
|
|
- LogHelper.WriteLogInfo($"[PLC-TRACE] GrabImageEx ExecuteGrabImageAsync start, pointIndex={pointIndex}, procedureId={procedureId}, is3D={Is3dPhoto}, cameraId={selectedProcedure.CameraId}, photoCount={selectedProcedure.PhotoCount}, thread={Thread.CurrentThread.ManagedThreadId}");
|
|
|
var res = await _remoteCommandService.ExecuteGrabImageAsync(selectedProcedure, Is3dPhoto, sysConfig);
|
|
|
- grabAsyncWatch.Stop();
|
|
|
- LogHelper.WriteLogInfo($"[PLC-TRACE] GrabImageEx ExecuteGrabImageAsync done, pointIndex={pointIndex}, procedureId={procedureId}, success={res.IsSucceed}, elapsedMs={grabAsyncWatch.ElapsedMilliseconds}, msg={res.Msg}");
|
|
|
- grabExWatch.Stop();
|
|
|
- LogHelper.WriteLogInfo($"[PLC-TRACE] GrabImageEx total done, pointIndex={pointIndex}, procedureId={procedureId}, totalElapsedMs={grabExWatch.ElapsedMilliseconds}");
|
|
|
return (res.IsSucceed, res.Image, res.Msg, pointIndex, procedureId);
|
|
|
}
|
|
|
catch (Exception ex)
|