|
|
@@ -212,6 +212,17 @@ namespace TeamAAS_VP.Core
|
|
|
set { SetProperty(ref _dfc, value); }
|
|
|
}
|
|
|
|
|
|
+ private ObservableCollection<DataFormCtq> _dfc2 = new ObservableCollection<DataFormCtq>();
|
|
|
+ /// <summary>
|
|
|
+ /// CTQ数据集合
|
|
|
+ /// </summary>
|
|
|
+ public ObservableCollection<DataFormCtq> DFC2
|
|
|
+ {
|
|
|
+ get { return _dfc2; }
|
|
|
+ set { SetProperty(ref _dfc2, value); }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
private Int64 _ThrowNumber;
|
|
|
/// <summary>
|
|
|
/// 抛料数
|
|
|
@@ -1087,7 +1098,7 @@ namespace TeamAAS_VP.Core
|
|
|
monitorNodeIds.Add(string.Format(addressConfig.In_WorkDone.Address, i));
|
|
|
}
|
|
|
//订阅PLC地址变化
|
|
|
- plc.SubscribeNodes("AutoSensor", monitorNodeIds, PlcCommandTrigger);
|
|
|
+ plc.SubscribeNodes("AutoSensor", monitorNodeIds, PlcCommandTrigger, OpcUaSubscriptionMode.CustomPolling);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
@@ -1286,6 +1297,13 @@ namespace TeamAAS_VP.Core
|
|
|
/// </summary>
|
|
|
Dictionary<string, string> gapDict = new Dictionary<string, string>();
|
|
|
|
|
|
+ string[] dis = new string[10];
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 定位结果
|
|
|
+ /// </summary>
|
|
|
+ Dictionary<string, string> DISDict = new Dictionary<string, string>();
|
|
|
+
|
|
|
List<string> fileresult { get; set; } = new List<string>();
|
|
|
/// <summary>
|
|
|
/// 二次定位相机的工具坐标
|
|
|
@@ -1469,6 +1487,7 @@ namespace TeamAAS_VP.Core
|
|
|
float distance = (float)Math.Sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
|
|
|
|
SendTaskMessage($"屏幕长度: {distance:F4}", MessageLevel.Info);
|
|
|
+ dis[5] = distance.ToString();
|
|
|
|
|
|
_FixedUpCameraAngle = Common.CalculateAngleBetweenPointsDegrees(new PointF((float)visionResults[0].X, (float)visionResults[0].Y), new PointF((float)visionResults[1].X, (float)visionResults[1].Y));
|
|
|
SendTaskMessage($"屏幕中心点位:{toolX:F3},{toolY:F4},{_FixedUpCameraAngle:F4}", MessageLevel.Info);
|
|
|
@@ -1491,6 +1510,7 @@ namespace TeamAAS_VP.Core
|
|
|
item.X_Position += offsetX;
|
|
|
item.Y_Position += offsetY;
|
|
|
item.U_Position += offsetAngle;
|
|
|
+ await item.WriteToPlcAddress(addressConfig.Out_RemovePos, plc);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -2211,6 +2231,11 @@ namespace TeamAAS_VP.Core
|
|
|
var dist3 = RectangleCenterCalculator.Distance(center.BottomLeft, center.BottomRight);//长2
|
|
|
var dist4 = RectangleCenterCalculator.Distance(center.TopLeft, center.BottomLeft);//宽2
|
|
|
LogHelper.WriteLogInfo($"dist1={dist1};dist2={dist2};dist3={dist3};dist4={dist4};");
|
|
|
+
|
|
|
+ dis[0] = dist1.ToString();
|
|
|
+ dis[1] = dist2.ToString();
|
|
|
+ dis[2] = dist3.ToString();
|
|
|
+ dis[3] = dist4.ToString();
|
|
|
if (currentProduct.GlobalParamListCollection.Count >= 4)
|
|
|
{
|
|
|
var param = currentProduct.GlobalParamListCollection.FirstOrDefault(p => p.Number == 0);
|
|
|
@@ -2242,9 +2267,47 @@ namespace TeamAAS_VP.Core
|
|
|
SendTaskMessage($"外壳宽度防呆:宽1={dist2},宽2={dist4},para1={length},para2={limtDown},para3={LimtUp}", MessageLevel.Info);
|
|
|
}
|
|
|
}
|
|
|
+ SendTaskMessage($"固定相机锁附/组装拍照检测OK", MessageLevel.Debug);
|
|
|
+ SendTaskMessage($"固定相机流程1结果:{visionResults[0].dis}", MessageLevel.Debug);
|
|
|
+ SendTaskMessage($"固定相机流程2结果:{visionResults[1].dis}", MessageLevel.Debug);
|
|
|
+ SendTaskMessage($"固定相机流程3结果:{visionResults[2].dis}", MessageLevel.Debug);
|
|
|
+ SendTaskMessage($"固定相机流程4结果:{visionResults[3].dis}", MessageLevel.Debug);
|
|
|
+ DISDict.Clear();
|
|
|
+ DISDict.Add("DownDis1", visionResults[0].dis.Split(',')[1]);
|
|
|
+ DISDict.Add("LeftDis1", visionResults[0].dis.Split(',')[2]);
|
|
|
+
|
|
|
+ DISDict.Add("LeftDis2", visionResults[1].dis.Split(',')[1]);
|
|
|
+ DISDict.Add("UpDis1", visionResults[1].dis.Split(',')[2]);
|
|
|
+
|
|
|
+ DISDict.Add("DownDis2", visionResults[2].dis.Split(',')[1]);
|
|
|
+ DISDict.Add("RightDis1", visionResults[2].dis.Split(',')[2]);
|
|
|
+
|
|
|
+ DISDict.Add("UpDis2", visionResults[3].dis.Split(',')[1]);
|
|
|
+ DISDict.Add("RightDis2", visionResults[3].dis.Split(',')[2]);
|
|
|
+
|
|
|
+
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
+ SendTaskMessage($"固定相机锁附/组装拍照检测NG", MessageLevel.Error);
|
|
|
+ SendTaskMessage($"固定相机流程1结果:{visionResults[0].dis}", MessageLevel.Debug);
|
|
|
+ SendTaskMessage($"固定相机流程2结果:{visionResults[1].dis}", MessageLevel.Debug);
|
|
|
+ SendTaskMessage($"固定相机流程3结果:{visionResults[2].dis}", MessageLevel.Debug);
|
|
|
+ SendTaskMessage($"固定相机流程4结果:{visionResults[3].dis}", MessageLevel.Debug);
|
|
|
+ DISDict.Clear();
|
|
|
+ DISDict.Add("DownDis1", visionResults[0].dis.Split(',')[1]);
|
|
|
+ DISDict.Add("LeftDis1", visionResults[0].dis.Split(',')[2]);
|
|
|
+
|
|
|
+ DISDict.Add("LeftDis2", visionResults[1].dis.Split(',')[1]);
|
|
|
+ DISDict.Add("UpDis1", visionResults[1].dis.Split(',')[2]);
|
|
|
+
|
|
|
+ DISDict.Add("DownDis2", visionResults[2].dis.Split(',')[1]);
|
|
|
+ DISDict.Add("RightDis1", visionResults[2].dis.Split(',')[2]);
|
|
|
+
|
|
|
+ DISDict.Add("UpDis2", visionResults[3].dis.Split(',')[1]);
|
|
|
+ DISDict.Add("RightDis2", visionResults[3].dis.Split(',')[2]);
|
|
|
+
|
|
|
+
|
|
|
await plc.WriteNodeAsync(addressConfig.Out_FixedCameraPutStatus.Address, (Int16)2);
|
|
|
return;
|
|
|
}
|
|
|
@@ -2790,7 +2853,7 @@ namespace TeamAAS_VP.Core
|
|
|
if (currentProduct.ID != productId)
|
|
|
{
|
|
|
//切换产品
|
|
|
- await _productService.LoadProductAsync(productId);
|
|
|
+ _productService.LoadProduct(productId);
|
|
|
_productService.SetCurrentProduct(productId);
|
|
|
await WriteParameterToPlcExAsync();
|
|
|
SendTaskMessage($"切换产品成功", MessageLevel.Debug);
|
|
|
@@ -2897,7 +2960,7 @@ namespace TeamAAS_VP.Core
|
|
|
if (currentProduct.ID != productId)
|
|
|
{
|
|
|
//切换产品
|
|
|
- await _productService.LoadProductAsync(productId);
|
|
|
+ _productService.LoadProduct(productId);
|
|
|
_productService.SetCurrentProduct(productId);
|
|
|
await WriteParameterToPlcExAsync();
|
|
|
SendTaskMessage($"切换产品成功", MessageLevel.Debug);
|
|
|
@@ -3047,7 +3110,7 @@ namespace TeamAAS_VP.Core
|
|
|
}
|
|
|
else assyPresRes = false;
|
|
|
DFC.Clear();
|
|
|
-
|
|
|
+ DFC2.Clear();
|
|
|
string upLimitValue = "NA", downLimitValue = "NA", midValue = "NA", saveppid = "NA";
|
|
|
if (stationConfig.SaveCsvPPID) saveppid = ppid[i];
|
|
|
foreach (var item in gapDict)
|
|
|
@@ -3113,12 +3176,12 @@ namespace TeamAAS_VP.Core
|
|
|
{
|
|
|
PPID = saveppid,
|
|
|
PROCESS_NAME = stationConfig.DataInfo.PROCESS_NAME,
|
|
|
- PROCESS_START_TIME = _LastMesCheckTime[i].ToString("yyyy-MM-ddTHH:mm:ss.fffffff") + "+08:00",
|
|
|
+ PROCESS_START_TIME = _LastMesCheckTime[i].ToString("yyyy-MM-ddTHH:mm:ss") + "+08:00",
|
|
|
CTQ_NAME = item.Key,
|
|
|
CTQ_VALUE = item.Value,
|
|
|
CTQ_LSL = downLimitValue,
|
|
|
CTQ_USL = upLimitValue,
|
|
|
- PROCESS_END_TIME = serverTimeResult.Now.ToString("yyyy-MM-ddTHH:mm:ss.fffffff") + "+08:00",
|
|
|
+ PROCESS_END_TIME = serverTimeResult.Now.ToString("yyyy-MM-ddTHH:mm:ss") + "+08:00",
|
|
|
SUPPLIER_NAME = stationConfig.DataInfo.SUPPLIER_NAME,
|
|
|
COMMODITY_TYPE = stationConfig.DataInfo.COMMODITY_TYPE,
|
|
|
REVISION = stationConfig.DataInfo.REVISION+"_"+ revision[i],
|
|
|
@@ -3142,12 +3205,12 @@ namespace TeamAAS_VP.Core
|
|
|
{
|
|
|
PPID = saveppid,
|
|
|
PROCESS_NAME = stationConfig.DataInfo.PROCESS_NAME,
|
|
|
- PROCESS_START_TIME = _LastMesCheckTime[i].ToString("yyyy-MM-ddTHH:mm:ss.fffffff") + "+08:00",
|
|
|
+ PROCESS_START_TIME = _LastMesCheckTime[i].ToString("yyyy-MM-ddTHH:mm:ss") + "+08:00",
|
|
|
CTQ_NAME = "Assy_Pressure",
|
|
|
CTQ_VALUE = assypress,
|
|
|
CTQ_LSL = currentProduct.GlobalParamEx.AssemblyPressure.PressureDownLimit.ToString("F3"),
|
|
|
CTQ_USL = currentProduct.GlobalParamEx.AssemblyPressure.PressureUpLimit.ToString("F3"),
|
|
|
- PROCESS_END_TIME = serverTimeResult.Now.ToString("yyyy-MM-ddTHH:mm:ss.fffffff") + "+08:00",
|
|
|
+ PROCESS_END_TIME = serverTimeResult.Now.ToString("yyyy-MM-ddTHH:mm:ss") + "+08:00",
|
|
|
SUPPLIER_NAME = stationConfig.DataInfo.SUPPLIER_NAME,
|
|
|
COMMODITY_TYPE = stationConfig.DataInfo.COMMODITY_TYPE,
|
|
|
REVISION = stationConfig.DataInfo.REVISION + "_" + revision[i],
|
|
|
@@ -3164,6 +3227,53 @@ namespace TeamAAS_VP.Core
|
|
|
PD_ATTR_04 = code,
|
|
|
PD_ATTR_05 = "NA",
|
|
|
});
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ SendTaskMessage($"左1:{DISDict["LeftDis1"]},下1:{DISDict["DownDis1"]},左2:{DISDict["LeftDis2"]},上1:{DISDict["UpDis1"]},右1:{DISDict["RightDis1"]},下2:{DISDict["DownDis2"]},右2:{DISDict["RightDis2"]},上2:{DISDict["UpDis2"]}", MessageLevel.Info);
|
|
|
+ if (i == 0)
|
|
|
+ {
|
|
|
+ DFC2.Add(new DataFormCtq
|
|
|
+ {
|
|
|
+ PPID = saveppid,
|
|
|
+ PROCESS_NAME = ProductMainSN[i],
|
|
|
+ PROCESS_START_TIME = _LastMesCheckTime[i].ToString("yyyy-MM-ddTHH:mm:ss") + "+08:00",
|
|
|
+ CTQ_NAME = dis[0],//长1
|
|
|
+ CTQ_VALUE = dis[1],//宽1
|
|
|
+ CTQ_LSL = dis[2],//长2
|
|
|
+ CTQ_USL = dis[3],//宽2
|
|
|
+ PROCESS_END_TIME = serverTimeResult.Now.ToString("yyyy-MM-ddTHH:mm:ss") + "+08:00",
|
|
|
+ SUPPLIER_NAME = stationConfig.DeviceName,
|
|
|
+ COMMODITY_TYPE = code,
|
|
|
+ REVISION = dis[5],//屏幕长度
|
|
|
+ WO = "",//
|
|
|
+ MFG_LOT = stationConfig.DataInfo.MFG_LOT,//
|
|
|
+ MFG_ASSY_LINE = stationConfig.DataInfo.MFG_ASSY_LINE,
|
|
|
+ PROCESS_OUTCOME = "Pass",
|
|
|
+ PROCESS_MACHINE_ID = DISDict["LeftDis1"],//左1
|
|
|
+ CTQ_UNIT_OF_MEASURE = DISDict["DownDis1"],//下1
|
|
|
+ ERROR_MESSAGE = DISDict["LeftDis2"],///左2
|
|
|
+ PD_ATTR_01 = DISDict["UpDis1"],//上1
|
|
|
+ PD_ATTR_02 = DISDict["RightDis1"],//右1
|
|
|
+ PD_ATTR_03 = DISDict["DownDis2"],//下2
|
|
|
+ PD_ATTR_04 = DISDict["RightDis2"],//右2
|
|
|
+ PD_ATTR_05 = DISDict["UpDis2"],//上2
|
|
|
+ });
|
|
|
+ }
|
|
|
+ bool recordResult2 = RecordStationResult2(i, DFC2, ProductMainSN[i], serverTimeResult.Now.Subtract(_LastMesCheckTime[i]).TotalSeconds, _LastMesCheckTime[i], stationConfig.SaveCsvPath);
|
|
|
+ if (recordResult2)
|
|
|
+ {
|
|
|
+ SendTaskMessage("保存外壳屏幕数据成功", MessageLevel.Debug);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ SendTaskMessage("保存外壳屏幕数据失败", MessageLevel.Alarm);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch
|
|
|
+ {
|
|
|
+ SendTaskMessage("保存外壳屏幕数据出错", MessageLevel.Error);
|
|
|
+ }
|
|
|
#endregion
|
|
|
}
|
|
|
else if (i == 1)
|
|
|
@@ -3257,7 +3367,9 @@ namespace TeamAAS_VP.Core
|
|
|
PD_ATTR_05 = "NA",
|
|
|
});
|
|
|
#endregion
|
|
|
+
|
|
|
}
|
|
|
+
|
|
|
//gap-复检gap参数, press-保压站实际压力值, presstime-保压站保压时间, assypress-组装站实际压力值
|
|
|
(bool isSuccess, string response) = await _mesService.SubmitGetAsync(i, ProductMainSN[i], comp, resultIndex == 1 ? true : false, data,fileresult, _LastMesCheckTime[i], serverTimeResult.Now);
|
|
|
if (!stationConfig.EnableMES || isSuccess)
|
|
|
@@ -3391,7 +3503,7 @@ namespace TeamAAS_VP.Core
|
|
|
}
|
|
|
LogHelper.WriteLogMes($"【mes结束ADD】");
|
|
|
SendTaskMessage($"mes结束ADD", MessageLevel.Info);
|
|
|
- fileresult.Clear();
|
|
|
+ fileresult.Clear();
|
|
|
await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)3);
|
|
|
return;
|
|
|
}
|
|
|
@@ -3491,7 +3603,6 @@ namespace TeamAAS_VP.Core
|
|
|
LogHelper.WriteLogError("PLC命令执行时出错!", ex);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
#endregion
|
|
|
|
|
|
#region 方法
|
|
|
@@ -3897,6 +4008,78 @@ namespace TeamAAS_VP.Core
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
+ private bool RecordStationResult2(int stationIndex, IEnumerable<DataFormCtq> dfcs, string productMainSN, double ct, DateTime timestamp, string savePath, bool isFirstEnter = true)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ //获取当前工位的配置
|
|
|
+ DateTime dt = DateTime.Now;
|
|
|
+ var stationConfig = _configService.GetDeviceInfo(stationIndex);
|
|
|
+ if (stationConfig == null) return false;
|
|
|
+ //如果保存路径为空,则不保存
|
|
|
+ if (string.IsNullOrEmpty(savePath)) return false;
|
|
|
+ //savePath = $"D:\\Data\\{dt.ToString("yyyy-MM")}\\{dt.ToString("yyyy-MM-dd")}\\外壳数据\\{productMainSN}";
|
|
|
+ string fullPath = savePath;
|
|
|
+ //如果保存路径是一个文件路径,则直接保存,否则按照工位和日期进行保存
|
|
|
+ if (!File.Exists(savePath) || !Path.HasExtension(savePath))
|
|
|
+ {
|
|
|
+ fullPath = savePath;
|
|
|
+ //如果路径不存在,则创建
|
|
|
+ // 创建目录
|
|
|
+ string directory = Path.GetDirectoryName(fullPath);
|
|
|
+ if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
|
|
|
+ {
|
|
|
+ Directory.CreateDirectory(directory);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ string name = "屏幕外壳数据";
|
|
|
+ //结果保存至CSV文件,文件名格式:savePath\yyyy-MM\工位编号_工位名称_yyyy-MM-dd.csv
|
|
|
+ string datePath = timestamp.ToString("yyyy-MM") + "\\";
|
|
|
+ string dirPath = Path.Combine(savePath, datePath);
|
|
|
+ if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath);
|
|
|
+ string fileName = $"{name}_{timestamp.ToString("yyyy-MM-dd")}.csv";
|
|
|
+ fullPath = Path.Combine(dirPath, fileName);
|
|
|
+
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
+ if (!File.Exists(fullPath))
|
|
|
+ {
|
|
|
+ sb.Append("PPID,SN,PROCESS_START_TIME,dis1,dis2,dis3,dis4,PROCESS_END_TIME,Product_Name,CodeSn,dis5,WO#,MFG_LOT#," +
|
|
|
+ "MFG_ASSY_LINE,PROCESS_OUTCOME,Left1,Down1,Left2,Up1,Right1,Down2,Right2,Up2");
|
|
|
+ sb.AppendLine();
|
|
|
+ }
|
|
|
+ if (dfcs == null || dfcs.Count() == 0)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ foreach (var dfc in dfcs)
|
|
|
+ {
|
|
|
+ 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}");
|
|
|
+ sb.AppendLine();
|
|
|
+ }
|
|
|
+ // 使用 StreamWriter 以追加模式打开文件
|
|
|
+ StreamWriter sw = new StreamWriter(fullPath, true, Encoding.UTF8);
|
|
|
+ sw.Write(sb.ToString());
|
|
|
+ sw.Close();
|
|
|
+ sw.Dispose();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
public async Task<string> CheckConsecutiveLowCapacityAsync(string productName, int consecutiveHours, int targetPerHour)
|
|
|
{
|