844184169 6 月之前
父節點
當前提交
a5fe64c273

+ 76 - 16
TeamAAS-VM/Core/Management.cs

@@ -1208,7 +1208,7 @@ namespace TeamAAS_VP.Core
             {
                 foreach (var item in current.PickPoints)
                 {
-                    await item.WriteToPlcAddress(addressConfig.Out_Pick, plc);
+                    await item.WriteToPlcAddress(addressConfig.Out_Pick, plc,item.Feeder);
                 }
             }
             if (current.SecPosCameraPoints != null && current.SecPosCameraPoints.Count > 0)
@@ -1267,6 +1267,8 @@ namespace TeamAAS_VP.Core
         Int16[] _LastMesCheck = new Int16[10];
         Int16 _LastPickINC = 0;
         DateTime[] _LastMesCheckTime = new DateTime[10];
+        string ProductMainSN = "";//产品主sn
+        string wo = "";
         /// <summary>
         /// PLC命令触发时
         /// </summary>
@@ -1582,9 +1584,19 @@ namespace TeamAAS_VP.Core
                                 return;
                             }
 
+                            // 获取机器人当前坐标
+                            var robot = _robotService.GetAllRobots().FirstOrDefault();
+                            if (robot == null)
+                            {
+                                SendTaskMessage("未找到机器人无法执行 上相机检测拍照视觉任务", MessageLevel.Alarm);
+                                await plc.WriteNodeAsync(addressConfig.Out_UpCameraPutStatus.Address, (Int16)2);
+                                return;
+                            }
+                            var currentPosition = robot.GetRobotPos();
+
                             // 执行视觉任务
                             var _cts = new CancellationTokenSource();
-                            var visionResult = await _remoteCommandService.ExecutePhotoGetSinglePoint(process, null, null, _cts.Token, cameraIndex, null);
+                            var visionResult = await _remoteCommandService.ExecutePhotoGetSinglePoint(process, null, new double[] { currentPosition.X, currentPosition.Y, currentPosition.U }, _cts.Token, cameraIndex, null);
                             if (visionResult.IsSucceed)
                             {
                                 await plc.WriteNodeAsync(addressConfig.Out_UPCameracheckStatus.Address, (Int16)1);
@@ -1876,7 +1888,7 @@ namespace TeamAAS_VP.Core
                                     SUPPLIER_NAME = cdata.SUPPLIER_NAME,
                                     COMMODITY_TYPE = cdata.COMMODITY_TYPE,
                                     REVISION = cdata.REVISION,
-                                    WO = cdata.WO,
+                                    WO = wo,
                                     MFG_LOT = cdata.MFG_LOT,
                                     MFG_ASSY_LINE = cdata.MFG_ASSY_LINE,
                                     PROCESS_OUTCOME = torqueRes ? "PASS" : "FAIL",
@@ -1897,7 +1909,7 @@ namespace TeamAAS_VP.Core
                                     SUPPLIER_NAME = cdata.SUPPLIER_NAME,
                                     COMMODITY_TYPE = cdata.COMMODITY_TYPE,
                                     REVISION = cdata.REVISION,
-                                    WO = cdata.WO,
+                                    WO = wo,
                                     MFG_LOT = cdata.MFG_LOT,
                                     MFG_ASSY_LINE = cdata.MFG_ASSY_LINE,
                                     PROCESS_OUTCOME = turnRes ? "PASS" : "FAIL",
@@ -1918,7 +1930,7 @@ namespace TeamAAS_VP.Core
                                     SUPPLIER_NAME = cdata.SUPPLIER_NAME,
                                     COMMODITY_TYPE = cdata.COMMODITY_TYPE,
                                     REVISION = cdata.REVISION,
-                                    WO = cdata.WO,
+                                    WO = wo,
                                     MFG_LOT = cdata.MFG_LOT,
                                     MFG_ASSY_LINE = cdata.MFG_ASSY_LINE,
                                     PROCESS_OUTCOME = pressureRes ? "PASS" : "FAIL",
@@ -2147,6 +2159,7 @@ namespace TeamAAS_VP.Core
                                     if (qrCodeResult && outputCollection.Contains("QR"))
                                     {
                                         code = outputCollection["QR"].Value as string;
+                                        code = code.ToUpper();
                                         if (!string.IsNullOrEmpty(code))
                                         {
                                             SendTaskMessage($"二维码扫码成功:{code}", MessageLevel.Info);
@@ -2183,7 +2196,7 @@ namespace TeamAAS_VP.Core
                                     _LastMesCheckTime[i] = DateTime.UtcNow;
                                     LogHelper.WriteLogMes($"【mes开始QUERY】");
                                     SendTaskMessage($"mes开始QUERY", MessageLevel.Info);
-                                    (bool isSuccess, string response) = await _mesService.StationGetAsync(code, "", 2);//询问mes
+                                    (bool isSuccess, string response) = await _mesService.StationGetExAsync(code, "", 2);//基于电池的SN获取产品SN,询问mes
                                     if (i == 0)
                                     {
                                         SendTaskMessage($"收到当前过站检查请求(当站是否生产)...", MessageLevel.Debug);
@@ -2194,21 +2207,68 @@ namespace TeamAAS_VP.Core
                                     }
                                     if (isSuccess)
                                     {
-                                        //产品发生改变并且供料器发生了变化时,需要通知PLC进行取料更改
-                                        await plc.WriteNodeAsync(addressConfig.Out_ScrewFeederIsChanged.Address, (Int16)1); //不发生改变
-                                        await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)1);
+                                        string ProductMainSN_Temp = "";
+                                        LogHelper.WriteLogMes($"询问mes成功");
+                                        SendTaskMessage($"询问mes成功:{response}", MessageLevel.Debug);
 
+                                        if (response != "MES功能未启用!")
+                                        {
+                                            string[] item= response.Split('\n');
+                                            if (item[2].Contains("sn="))
+                                            {
+                                                ProductMainSN_Temp = item[2].Replace("sn=", "");
+                                                SendTaskMessage($"电池sn:{ProductMainSN_Temp}", MessageLevel.Info);
+                                            }
+                                        }
                                         LogHelper.WriteLogMes($"询问mes成功");
-                                        SendTaskMessage($"询问mes成功", MessageLevel.Debug);
+                                        SendTaskMessage($"询问mes成功:{response}", MessageLevel.Debug);
+
+                                        //20260214,螺丝机特别版(电池组装)
+                                        (bool isSuccess2, string response2) = await _mesService.StationGetAsync(ProductMainSN_Temp, "", 2);//询问mes
+                                        if (isSuccess2)
+                                        {
+                                            LogHelper.WriteLogMes($"询问mes成功");
+                                            SendTaskMessage($"询问mes成功:{response2}", MessageLevel.Debug);
+
+                                            if (response2 != "MES功能未启用!")
+                                            {
+                                                string[] item = response2.Split('\n');
+                                                if (item[3].Contains("sn="))
+                                                {
+                                                    ProductMainSN = item[3].Replace("sn=", "");
+                                                    SendTaskMessage($"产品主sn:{ProductMainSN}", MessageLevel.Info);
+                                                }
+                                                if (item[5].Contains("wo="))
+                                                {
+                                                    wo = item[5].Replace("wo=", "");
+                                                    SendTaskMessage($"产品主wo:{wo}", MessageLevel.Info);
+                                                }
+                                            }
+                                            LogHelper.WriteLogMes($"第二次询问mes成功");
+                                            SendTaskMessage($"第二次询问mes成功:{response2}", MessageLevel.Debug);
+
+                                            //产品发生改变并且供料器发生了变化时,需要通知PLC进行取料更改
+                                            await plc.WriteNodeAsync(addressConfig.Out_ScrewFeederIsChanged.Address, (Int16)1); //不发生改变
+                                            await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)1);
+                                        }
+                                        else
+                                        {
+                                            LogHelper.WriteLogMes($"第二次询问mes失败");
+                                            SendTaskMessage($"第二次询问mes失败:{response2}", MessageLevel.Error);
+
+                                            //产品发生改变并且供料器发生了变化时,需要通知PLC进行取料更改
+                                            await plc.WriteNodeAsync(addressConfig.Out_ScrewFeederIsChanged.Address, (Int16)1); //不发生改变
+                                            await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)2);
+                                        }
                                     }
                                     else
                                     {
+                                        LogHelper.WriteLogMes($"询问mes失败");
+                                        SendTaskMessage($"询问mes失败:{response}", MessageLevel.Error);
+
                                         //产品发生改变并且供料器发生了变化时,需要通知PLC进行取料更改
                                         await plc.WriteNodeAsync(addressConfig.Out_ScrewFeederIsChanged.Address, (Int16)1); //不发生改变
                                         await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)2);
-
-                                        LogHelper.WriteLogMes($"询问mes失败");
-                                        SendTaskMessage($"询问mes失败:{response}", MessageLevel.Error);
                                     }
                                     LogHelper.WriteLogMes($"【mes结束QUERY】");
                                     SendTaskMessage($"mes结束QUERY", MessageLevel.Info);
@@ -2233,7 +2293,7 @@ namespace TeamAAS_VP.Core
                                         await _systemDatabaseService.RecordProductionAsync(new ProductionRecord()
                                         {
                                             ProductName = currentProduct.Name,
-                                            ProductCode = code,
+                                            ProductCode = ProductMainSN,
                                             DeviceId = i,
                                             DeviceName = "",
                                             Category = resultIndex == 1 ? "OK" : "NG",
@@ -2247,7 +2307,7 @@ namespace TeamAAS_VP.Core
                                     string torque = string.Join(",", torqueList);
                                     string pressure = string.Join(",", pressureList);
                                     string turn = string.Join(",", turnList);
-                                    (bool isSuccess, string response) = await _mesService.SubmitGetAsync(code, "", torque, pressure, turn, resultIndex == 1 ? true : false, _LastMesCheckTime[i], DateTime.UtcNow);
+                                    (bool isSuccess, string response) = await _mesService.SubmitGetAsync(ProductMainSN, "", torque, pressure, turn, resultIndex == 1 ? true : false, _LastMesCheckTime[i], DateTime.UtcNow);
                                     if (isSuccess)
                                     {
                                         LogHelper.WriteLogMes($"上传mes成功");
@@ -2260,7 +2320,7 @@ namespace TeamAAS_VP.Core
                                     }
                                     await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)3);
 
-                                    WriteProductLog(lockResultsAll, code, CTtime);
+                                    WriteProductLog(lockResultsAll, ProductMainSN, CTtime);
 
                                     LogHelper.WriteLogMes($"【mes结束ADD】");
                                     SendTaskMessage($"mes结束ADD", MessageLevel.Info);

+ 2 - 0
TeamAAS-VM/Interfaces/IMesService.cs

@@ -45,6 +45,8 @@ namespace TeamAAS_VP.Interfaces
         /// </remarks>
         Task<(bool IsSuccess, string Response)> StationGetAsync(string sn,string comp, double timeoutInSeconds);
 
+        Task<(bool IsSuccess, string Response)> StationGetExAsync(string sn, string comp, double timeoutInSeconds);
+
         /// <summary>
         /// 使用配置的提交(Submit)URL 发起 GET 请求,提交过站结果及时间信息。
         /// </summary>

+ 27 - 0
TeamAAS-VM/Models/PLC/PlcPoint.cs

@@ -361,6 +361,33 @@ namespace TeamAAS_VP.Models.PLC
             return await pLC.WriteNodesAsync(nodeValues);
         }
 
+        /// <summary>
+        /// 将点位数据写入到PLC地址
+        /// </summary>
+        /// <param name="plcAddress"></param>
+        /// <param name="pLC"></param>
+        /// <returns></returns>
+        public async Task<bool> WriteToPlcAddress(PlcPointAddress plcAddress, OpcUaClientPLC pLC,int index)
+        {
+            Dictionary<string, object> nodeValues = new Dictionary<string, object>();
+            nodeValues.Add(string.Format(plcAddress.X_Position.Address, index), X_Position + X_Offset);
+            nodeValues.Add(string.Format(plcAddress.X_Velocity.Address, index), X_Velocity);
+            nodeValues.Add(string.Format(plcAddress.Y_Position.Address, index), Y_Position + Y_Offset);
+            nodeValues.Add(string.Format(plcAddress.Y_Velocity.Address, index), Y_Velocity);
+            nodeValues.Add(string.Format(plcAddress.Z_Position_Start.Address, index), Z_Position_Start + Z_Start_Offset);
+            nodeValues.Add(string.Format(plcAddress.Z_Velocity_Start.Address, index), Z_Velocity_Start);
+            nodeValues.Add(string.Format(plcAddress.Z_Position_Stop.Address, index), Z_Position_Stop + Z_Stop_Offset);
+            nodeValues.Add(string.Format(plcAddress.Z_Velocity_Stop.Address, index), Z_Velocity_Stop);
+            nodeValues.Add(string.Format(plcAddress.U_Position.Address, index), U_Position + U_Offset);
+            nodeValues.Add(string.Format(plcAddress.U_Velocity.Address, index), U_Velocity);
+            nodeValues.Add(string.Format(plcAddress.R_Position.Address, index), R_Position + R_Offset);
+            nodeValues.Add(string.Format(plcAddress.R_Velocity.Address, index), R_Velocity);
+            nodeValues.Add(string.Format(plcAddress.Torque.Address, index), Torque);
+            nodeValues.Add(string.Format(plcAddress.Feeder.Address, index), Feeder);
+            nodeValues.Add(string.Format(plcAddress.ScrewProNum.Address, index), ScrewProNum);
+            return await pLC.WriteNodesAsync(nodeValues);
+        }
+
         /// <summary>
         /// 将点位数据写入到PLC地址
         /// </summary>

+ 83 - 2
TeamAAS-VM/Services/MesService.cs

@@ -102,11 +102,11 @@ namespace TeamAAS_VP.Services
             string url = "";
             if (device.F == "PTL")
             {
-                url = $"{device.MesUrl}?c=QUERY_RECORD&line={device.Line}&station={device.Station}&fixtureid={device.FixtureId}&sn={sn}&comp={device.comp}:{comp}&p=unit_process_check,message,model";
+                url = $"{device.MesUrl}?c=QUERY_RECORD&line={device.Line}&station={device.Station}&fixtureid={device.FixtureId}&sn={sn}&comp={device.comp}:{comp}&p=unit_process_check,message,model,sn,wo";
             }
             else
             {
-                url = $"{device.MesUrl}?c=QUERY_RECORD&line={device.Line}&station={device.Station}&fixtureid={device.FixtureId}&sn={sn}&p=unit_process_check,message,model";
+                url = $"{device.MesUrl}?c=QUERY_RECORD&line={device.Line}&station={device.Station}&fixtureid={device.FixtureId}&sn={sn}&p=unit_process_check,message,model,sn,wo";
             }
             
             LogHelper.WriteLogMes($"【询问URL】{url}");
@@ -146,6 +146,79 @@ namespace TeamAAS_VP.Services
             return result;
         }
 
+        /// <summary>
+        /// 向配置中指定的 MES 站点 URL 发起 GET 请求(用于过站查询)。
+        /// </summary>
+        /// <param name="sn">要查询的序列号(SN)。</param>
+        /// <param name="cancellationToken">可选的取消令牌,用于请求超时或取消。</param>
+        /// <returns>
+        /// 返回元组 (IsSuccess, Response):
+        /// - IsSuccess: 请求是否视为成功(即 MES 返回了预期的 "SFC_OK" 且包含 "unit_process_check=OK")。
+        /// - Response: 原始响应文本或错误信息说明(如 "MES功能未启用!"、"Missing MES station URL"、"Canceled" 等)。
+        /// </returns>
+        /// <remarks>
+        /// 行为说明:
+        /// - 从配置获取设备信息,若 MES 未启用则直接返回 IsSuccess=true 且 Response 为提示文本(不视为错误)。
+        /// - 若未配置 MES URL 则返回 IsSuccess=false 与错误文本。
+        /// - 使用配置的 URL(通过 <see cref="string.Format"/> 填充 sn)发起 GET 请求,最多重试 10 次。
+        /// - 只有当响应包含 "SFC_OK" 且包含 "unit_process_check=OK" 时视为成功并立即返回。
+        /// - 捕获 <see cref="OperationCanceledException"/> 返回 "Canceled",捕获其它异常则返回异常消息。
+        /// - 若实例已被释放则抛出 <see cref="ObjectDisposedException"/>。
+        /// </remarks>
+        public async Task<(bool IsSuccess, string Response)> StationGetExAsync(string sn, string comp, CancellationToken cancellationToken = default)
+        {
+            // 如果已经释放,则抛出异常,防止在已释放资源上继续操作。
+            if (_disposed) throw new ObjectDisposedException(nameof(MesService));
+
+            var device = _configService.GetDeviceInfo();
+            if (device == null || !device.EnableMES)
+            {
+                return (true, "MES功能未启用!");
+            }
+            if (string.IsNullOrWhiteSpace(device.MesUrl))
+                return (false, "Missing MES station URL");
+
+            string url = "";
+            url = $"{device.MesUrl}?c=QUERY_RECORD&line={device.Line}&station={device.Station}&fixtureid={device.FixtureId}&sn={sn}&p=sn,message";
+
+            LogHelper.WriteLogMes($"【询问URL】{url}");
+            SendTaskMessage($"【询问URL】{url}", MessageLevel.Info);
+            (bool IsSuccess, string Response) result = (false, string.Empty);
+
+            for (int i = 0; i < 3; i++)
+            {
+                try
+                {
+                    using (var rsp = await _httpClient.GetAsync(url))
+                    {
+                        var text = await rsp.Content.ReadAsStringAsync();
+                        LogHelper.WriteLogMes($"【HTTP接收】{text}");
+                        SendTaskMessage($"【HTTP接收】{text}", MessageLevel.Info);
+
+                        // "SFC_OK" 代表和 MES 连接成功
+                        if (text.Contains("SFC_OK"))
+                        {
+                            if (text.Contains("message=OK"))
+                            {
+                                return (true, text);
+                            }
+                        }
+                        result = (false, text);
+                    }
+                }
+                catch (OperationCanceledException)
+                {
+                    result = (false, "Canceled");
+                }
+                catch (Exception ex)
+                {
+                    result = (false, ex.Message);
+                }
+            }
+            return result;
+        }
+
+
         /// <summary>
         /// 向 MES 发起站点查询请求,使用超时(秒)作为便捷重载。
         /// </summary>
@@ -160,6 +233,14 @@ namespace TeamAAS_VP.Services
             }
         }
 
+        public async Task<(bool IsSuccess, string Response)> StationGetExAsync(string sn, string comp, double timeoutInSeconds)
+        {
+            using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(timeoutInSeconds)))
+            {
+                return await StationGetExAsync(sn, comp, cts.Token);
+            }
+        }
+
         /// <summary>
         /// 向配置中指定的 MES 提交 URL 发起 GET 请求(用于提交测试结果/记录)。
         /// </summary>

+ 2 - 2
TeamAAS-VM/Views/SettingView.xaml

@@ -410,7 +410,7 @@
                                  Text="{Binding DataInfo.REVISION, Mode=TwoWay}"
                                  Margin="6" />
 
-                        <TextBlock Grid.Row="6"
+                        <!--<TextBlock Grid.Row="6"
                                    Grid.Column="0"
                                    Text="WO#:"
                                    HorizontalAlignment="Right"
@@ -418,7 +418,7 @@
                         <TextBox Grid.Row="6"
                                  Grid.Column="1"
                                  Text="{Binding DataInfo.WO, Mode=TwoWay}"
-                                 Margin="6" />
+                                 Margin="6" />-->
 
                         <TextBlock Grid.Row="7"
                                    Grid.Column="0"