|
|
@@ -1,4 +1,6 @@
|
|
|
using Cognex.VisionPro.ToolBlock;
|
|
|
+using NPOI.OpenXmlFormats.Vml;
|
|
|
+using Org.BouncyCastle.Crypto;
|
|
|
using Prism.Events;
|
|
|
using Prism.Ioc;
|
|
|
using Prism.Mvvm;
|
|
|
@@ -25,6 +27,7 @@ using TeamAAS_VP.Models;
|
|
|
using TeamAAS_VP.Models.PLC;
|
|
|
using TeamAAS_VP.Models.Torque;
|
|
|
using TeamAAS_VP.Resources.Languages;
|
|
|
+using TeamAAS_VP.Views.Product;
|
|
|
using TouchSocket.Core;
|
|
|
using TouchSocket.SerialPorts;
|
|
|
using TouchSocket.Sockets;
|
|
|
@@ -57,15 +60,15 @@ namespace TeamAAS_VP.Core
|
|
|
/// <summary>
|
|
|
/// 压力采集信号控制CTS
|
|
|
/// </summary>
|
|
|
- private CancellationTokenSource _pressureCts;
|
|
|
+ private CancellationTokenSource[] _pressureCts = new CancellationTokenSource[100];
|
|
|
/// <summary>
|
|
|
/// 压力采集超时CTS
|
|
|
/// </summary>
|
|
|
- private CancellationTokenSource _pressureTimeoutCts;
|
|
|
+ private CancellationTokenSource[] _pressureTimeoutCts = new CancellationTokenSource[100];
|
|
|
/// <summary>
|
|
|
/// 压力采集CTS
|
|
|
/// </summary>
|
|
|
- private CancellationTokenSource _pressureLinkedCts;
|
|
|
+ private CancellationTokenSource[] _pressureLinkedCts = new CancellationTokenSource[100];
|
|
|
/// <summary>
|
|
|
/// 压力数据集合
|
|
|
/// </summary>
|
|
|
@@ -78,6 +81,7 @@ namespace TeamAAS_VP.Core
|
|
|
/// 超时自动停止秒数
|
|
|
/// </summary>
|
|
|
private int _pressureMaxDurationSeconds = 30; //超时自动停止秒数
|
|
|
+ DateTime[] StartCtqTime = new DateTime[3];//开始采集Ctq数据的时间
|
|
|
List<LockResult> lockResultsAll = new List<LockResult>();//一个产品的总结果
|
|
|
string productSn = "";//产品sn
|
|
|
DateTime StartScrewTime = DateTime.Now;//开始锁附的时间
|
|
|
@@ -1800,6 +1804,7 @@ namespace TeamAAS_VP.Core
|
|
|
// 开始锁付
|
|
|
else if (addressConfig.In_WorkStart.Address.Contains(tuple.nodeId))
|
|
|
{
|
|
|
+
|
|
|
if (tuple.value is Int16 state)
|
|
|
{
|
|
|
if (_LastWorkStart != state)
|
|
|
@@ -1810,6 +1815,7 @@ namespace TeamAAS_VP.Core
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
+ var code = plc.ReadNode<string>(string.Format(addressConfig.In_Code.Address, 0));
|
|
|
if (state == 1)
|
|
|
{
|
|
|
SendTaskMessage(Lang.收到开始锁付信号, MessageLevel.Debug);
|
|
|
@@ -1818,7 +1824,7 @@ namespace TeamAAS_VP.Core
|
|
|
Int16 positionIndex = plc.ReadNode<Int16>(addressConfig.In_ProductNum.Address);
|
|
|
SendTaskMessage(string.Format(Lang.编号0, positionIndex), MessageLevel.Info);
|
|
|
// 开始采集压力值
|
|
|
- StartPressureCollection(currentProduct.Name, _productService.CurrentProductCode, positionIndex);
|
|
|
+ StartPressureCollection(currentProduct.Name, _productService.CurrentProductCode, 0);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
@@ -1857,7 +1863,7 @@ namespace TeamAAS_VP.Core
|
|
|
var robot = _robotService.GetAllRobots().FirstOrDefault();
|
|
|
var currentPosition = robot.GetRobotPos();
|
|
|
//读取压力值
|
|
|
- float pressure = plc.ReadNode<float>(addressConfig.In_PressureValue.Address);
|
|
|
+ float pressure = _maxPressure;
|
|
|
//当前用户名
|
|
|
string currentUserName = _systemDatabaseService.GetCurrentUser().UserName;
|
|
|
|
|
|
@@ -1901,6 +1907,8 @@ namespace TeamAAS_VP.Core
|
|
|
lockResult.OperatorName = currentUserName;
|
|
|
lockResult.ProductImagePath = "";
|
|
|
lockResult.WaveDatas = ScrewDriver.WaveDatas;
|
|
|
+
|
|
|
+ //pressure = 0;
|
|
|
//获取系统参数
|
|
|
var systemConfig = _configService.GetSystemConfiguration();
|
|
|
//判断是否保存锁付曲线
|
|
|
@@ -1957,7 +1965,7 @@ namespace TeamAAS_VP.Core
|
|
|
resultToMes.Add($"Screw{lockResult.Number}_Fail");
|
|
|
}
|
|
|
SendTaskMessage($"螺丝序号:{lockResult.Number},扭力:{lockResult.LockTorque},压力:{lockResult.Pressure},圈数:{lockResult.LockTurns}", MessageLevel.Info);
|
|
|
-
|
|
|
+ _maxPressure = 0;
|
|
|
lockResultsAll.Add(lockResult);
|
|
|
App.Current.Dispatcher.Invoke(() =>
|
|
|
{
|
|
|
@@ -1974,6 +1982,7 @@ namespace TeamAAS_VP.Core
|
|
|
await plc.WriteNodeAsync(addressConfig.In_WorkDone.Address, (Int16)0);
|
|
|
// 停止采集压力并保存
|
|
|
await StopAndSavePressureCollectionAsync(currentProduct.Name, _productService.CurrentProductCode, positionIndex);
|
|
|
+ pressure = 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
@@ -2807,7 +2816,7 @@ namespace TeamAAS_VP.Core
|
|
|
_eventAggregator.GetEvent<TaskMessageNotification>().Publish(new Models.MessageStruct() { Message = msg, level = level });
|
|
|
});
|
|
|
}
|
|
|
-
|
|
|
+ private float _maxPressure = float.MinValue;
|
|
|
#region Pressure collection helpers
|
|
|
/// <summary>
|
|
|
/// 开始采集压力值
|
|
|
@@ -2817,29 +2826,36 @@ namespace TeamAAS_VP.Core
|
|
|
/// <param name="positionIndex">锁付点编号</param>
|
|
|
private void StartPressureCollection(string productName, string productCode, int positionIndex)
|
|
|
{
|
|
|
+
|
|
|
try
|
|
|
{
|
|
|
// cancel existing if any
|
|
|
- _pressureCts?.Cancel();
|
|
|
- _pressureTimeoutCts?.Cancel();
|
|
|
- _pressureLinkedCts?.Dispose();
|
|
|
+ //_pressureCts?.Cancel();
|
|
|
+ //_pressureTimeoutCts?.Cancel();
|
|
|
+ //_pressureLinkedCts?.Dispose();
|
|
|
+ //_pressureSamples?.Clear();
|
|
|
+ //_pressureTimeoutCts[positionIndex]?.Cancel();
|
|
|
_pressureSamples?.Clear();
|
|
|
|
|
|
- _pressureCts = new CancellationTokenSource();
|
|
|
- _pressureTimeoutCts = new CancellationTokenSource();
|
|
|
+ _pressureCts[positionIndex] = new CancellationTokenSource();
|
|
|
+ _pressureTimeoutCts[positionIndex] = new CancellationTokenSource();
|
|
|
+
|
|
|
+ //_pressureCts = new CancellationTokenSource();
|
|
|
+ //_pressureTimeoutCts = new CancellationTokenSource();
|
|
|
|
|
|
// timeout after configured seconds
|
|
|
- _pressureTimeoutCts.CancelAfter(TimeSpan.FromSeconds(_pressureMaxDurationSeconds));
|
|
|
+ _pressureTimeoutCts[positionIndex].CancelAfter(TimeSpan.FromSeconds(_pressureMaxDurationSeconds));
|
|
|
|
|
|
// link tokens so either stop or timeout cancels
|
|
|
- _pressureLinkedCts = CancellationTokenSource.CreateLinkedTokenSource(_pressureCts.Token, _pressureTimeoutCts.Token);
|
|
|
+ _pressureLinkedCts[positionIndex] = CancellationTokenSource.CreateLinkedTokenSource(_pressureCts[positionIndex].Token, _pressureTimeoutCts[positionIndex].Token);
|
|
|
|
|
|
- var token = _pressureLinkedCts.Token;
|
|
|
+ var token = _pressureLinkedCts[positionIndex].Token;
|
|
|
var addressConfig = _configService.GetPlcAddresses();
|
|
|
var plc = _plcService.GetPlcByNumber(addressConfig.PlcNo) as OpcUaClientPLC;
|
|
|
if (plc == null || !plc.IsConnected) return;
|
|
|
Task.Run(async () =>
|
|
|
{
|
|
|
+
|
|
|
SendTaskMessage($"Pressure collection started for position {positionIndex}", MessageLevel.Debug);
|
|
|
while (!token.IsCancellationRequested)
|
|
|
{
|
|
|
@@ -2848,7 +2864,13 @@ namespace TeamAAS_VP.Core
|
|
|
float pressure = plc.ReadNode<float>(addressConfig.In_PressureValue.Address);
|
|
|
lock (_pressureSamples)
|
|
|
{
|
|
|
+ //SendTaskMessage($"压力采集时出错:{pressure}", MessageLevel.Info);
|
|
|
_pressureSamples.Add((DateTime.Now, pressure));
|
|
|
+ if (pressure > _maxPressure)
|
|
|
+ {
|
|
|
+ _maxPressure = pressure;
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
@@ -2857,8 +2879,9 @@ namespace TeamAAS_VP.Core
|
|
|
}
|
|
|
await Task.Delay(_pressureSampleIntervalMs);
|
|
|
}
|
|
|
+ SendTaskMessage($"Pressure {_pressureSamples}", MessageLevel.Debug);
|
|
|
// if cancelled due to timeout
|
|
|
- if (_pressureTimeoutCts.IsCancellationRequested && !_pressureCts.IsCancellationRequested)
|
|
|
+ if (_pressureTimeoutCts[positionIndex].IsCancellationRequested && !_pressureCts[positionIndex].IsCancellationRequested)
|
|
|
{
|
|
|
SendTaskMessage("Pressure collection timed out, saving collected data.", MessageLevel.Alarm);
|
|
|
await StopAndSavePressureCollectionAsync(productName, productCode, positionIndex);
|
|
|
@@ -2868,6 +2891,7 @@ namespace TeamAAS_VP.Core
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
LogHelper.WriteLogError("StartPressureCollection error", ex);
|
|
|
+ SendTaskMessage($"压力采集时出错:{ex.Message}", MessageLevel.Error);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -2882,8 +2906,15 @@ namespace TeamAAS_VP.Core
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
+ // 获取当前产品
|
|
|
+ var currentProduct = _productService.GetCurrentProduct();
|
|
|
+ if (currentProduct == null)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
// cancel sampling
|
|
|
- _pressureCts?.Cancel();
|
|
|
+ //_pressureCts?.Cancel();
|
|
|
// allow worker to observe cancel
|
|
|
await Task.Delay(50);
|
|
|
|
|
|
@@ -2898,31 +2929,59 @@ namespace TeamAAS_VP.Core
|
|
|
SendTaskMessage("No pressure samples collected.", MessageLevel.Info);
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// save to file under configured path
|
|
|
try
|
|
|
{
|
|
|
//获取系统参数
|
|
|
var systemConfig = _configService.GetSystemConfiguration();
|
|
|
+
|
|
|
+ string datePath = DateTime.Now.ToString("yyyy-MM") + "\\" + DateTime.Now.ToString("yyyy-MM-dd") + "\\";
|
|
|
+ string dirPath = System.IO.Path.Combine(systemConfig.ScrewCurvePath, datePath, currentProduct.Name, positionIndex.ToString());
|
|
|
+ if (!Directory.Exists(dirPath))
|
|
|
+ {
|
|
|
+ Directory.CreateDirectory(dirPath);
|
|
|
+ }
|
|
|
+ string fileName = $"pressure-{productCode}-{positionIndex}-{DateTime.Now.ToString("HHmmss")}.csv";
|
|
|
+ string fullPath = Path.Combine(dirPath, fileName);
|
|
|
+ string pngfileName = $"pressure-{productCode}-{positionIndex}-{DateTime.Now.ToString("HHmmss")}.png";
|
|
|
+ string pngPath = Path.Combine(dirPath, pngfileName);
|
|
|
+ if (!systemConfig.IsSaveScrewCurve)
|
|
|
+ {
|
|
|
+ fullPath = string.Empty;
|
|
|
+ pngPath = string.Empty;
|
|
|
+ }
|
|
|
+ App.Current.Dispatcher.Invoke(() =>
|
|
|
+ {
|
|
|
+ _eventAggregator.GetEvent<PressureFinishNotification>().Publish((true, snapshot.ToArray(), pngPath));
|
|
|
+ });
|
|
|
+
|
|
|
//判断是否保存锁付曲线
|
|
|
if (systemConfig.IsSaveScrewCurve)
|
|
|
{
|
|
|
- string basePath = systemConfig?.ScrewCurvePath ?? Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
|
|
|
- string datePath = DateTime.Now.ToString("yyyy-MM") + "\\" + DateTime.Now.ToString("yyyy-MM-dd") + "\\";
|
|
|
- string dirPath = Path.Combine(basePath, datePath, productName ?? "UnknownProduct", productCode ?? DateTime.Now.ToString("yyyyMMddHHmmssfff"));
|
|
|
- if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath);
|
|
|
- string fileName = $"pressure-{productCode}-{positionIndex}-{DateTime.Now.ToString("HHmmss")}.csv";
|
|
|
- string fullPath = Path.Combine(dirPath, fileName);
|
|
|
- var sb = new StringBuilder();
|
|
|
- sb.AppendLine("Timestamp,Value");
|
|
|
- foreach (var s in snapshot)
|
|
|
+ if (!string.IsNullOrEmpty(fullPath))
|
|
|
{
|
|
|
- sb.AppendLine($"{s.Timestamp:O},{s.Value}");
|
|
|
- }
|
|
|
+ var sb = new StringBuilder();
|
|
|
+ sb.AppendLine("Timestamp,Value");
|
|
|
+ foreach (var s in snapshot)
|
|
|
+ {
|
|
|
+ sb.AppendLine($"{s.Timestamp:O},{s.Value}");
|
|
|
+ }
|
|
|
|
|
|
- File.WriteAllText(fullPath, sb.ToString());
|
|
|
- SendTaskMessage($"Pressure samples saved to {fullPath}", MessageLevel.Debug);
|
|
|
+ File.WriteAllText(fullPath, sb.ToString());
|
|
|
+ SendTaskMessage($"Pressure samples saved to {fullPath}", MessageLevel.Debug);
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+ //var sb = new StringBuilder();
|
|
|
+ //sb.AppendLine("Timestamp,Value");
|
|
|
+ //foreach (var s in snapshot)
|
|
|
+ //{
|
|
|
+ // sb.AppendLine($"{s.Timestamp:O},{s.Value}");
|
|
|
+ //}
|
|
|
+
|
|
|
+ //File.WriteAllText(fullPath, sb.ToString());
|
|
|
+ // SendTaskMessage($"Pressure samples saved to {fullPath}", MessageLevel.Debug);
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
@@ -2938,11 +2997,12 @@ namespace TeamAAS_VP.Core
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
- _pressureLinkedCts?.Cancel();
|
|
|
- _pressureLinkedCts?.Dispose();
|
|
|
- _pressureTimeoutCts?.Dispose();
|
|
|
- _pressureCts?.Dispose();
|
|
|
+ _pressureLinkedCts[positionIndex]?.Cancel();
|
|
|
+ _pressureLinkedCts[positionIndex]?.Dispose();
|
|
|
+ _pressureTimeoutCts[positionIndex]?.Dispose();
|
|
|
+ _pressureCts[positionIndex]?.Dispose();
|
|
|
_pressureSamples?.Clear();
|
|
|
+ //_maxPressure = 0;
|
|
|
}
|
|
|
catch { }
|
|
|
}
|