From 364355ac9921e6626fb8ad65ef3a25653d49c8e6 Mon Sep 17 00:00:00 2001 From: NXX <447201003@qq> Date: Tue, 2 Aug 2022 10:50:32 +0800 Subject: [PATCH 1/5] MmorkT --- SmartClient.sln | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/SmartClient.sln b/SmartClient.sln index 55b52975..5d8e17d6 100644 --- a/SmartClient.sln +++ b/SmartClient.sln @@ -120,7 +120,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.MilkWithTea" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ElectricCurrentTestDemo", "..\..\TEST\ElectricCurrentTestDemo\ElectricCurrentTestDemo.csproj", "{75B55300-ABC3-4CA1-B9B6-DF954E6C7B44}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.KHKJ", "BPASmartClient.KHKJ\BPASmartClient.KHKJ.csproj", "{C0060FB3-7AEA-4D14-ADCE-DB78D3665D5B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.KHKJ", "BPASmartClient.KHKJ\BPASmartClient.KHKJ.csproj", "{C0060FB3-7AEA-4D14-ADCE-DB78D3665D5B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.MorkTM", "BPASmartClient.MorkTM\BPASmartClient.MorkTM.csproj", "{1612F583-D328-45C6-8BB1-5D41B8F1D216}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -1156,6 +1158,26 @@ Global {C0060FB3-7AEA-4D14-ADCE-DB78D3665D5B}.Release|x64.Build.0 = Release|Any CPU {C0060FB3-7AEA-4D14-ADCE-DB78D3665D5B}.Release|x86.ActiveCfg = Release|Any CPU {C0060FB3-7AEA-4D14-ADCE-DB78D3665D5B}.Release|x86.Build.0 = Release|Any CPU + {1612F583-D328-45C6-8BB1-5D41B8F1D216}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1612F583-D328-45C6-8BB1-5D41B8F1D216}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1612F583-D328-45C6-8BB1-5D41B8F1D216}.Debug|ARM.ActiveCfg = Debug|Any CPU + {1612F583-D328-45C6-8BB1-5D41B8F1D216}.Debug|ARM.Build.0 = Debug|Any CPU + {1612F583-D328-45C6-8BB1-5D41B8F1D216}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {1612F583-D328-45C6-8BB1-5D41B8F1D216}.Debug|ARM64.Build.0 = Debug|Any CPU + {1612F583-D328-45C6-8BB1-5D41B8F1D216}.Debug|x64.ActiveCfg = Debug|Any CPU + {1612F583-D328-45C6-8BB1-5D41B8F1D216}.Debug|x64.Build.0 = Debug|Any CPU + {1612F583-D328-45C6-8BB1-5D41B8F1D216}.Debug|x86.ActiveCfg = Debug|Any CPU + {1612F583-D328-45C6-8BB1-5D41B8F1D216}.Debug|x86.Build.0 = Debug|Any CPU + {1612F583-D328-45C6-8BB1-5D41B8F1D216}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1612F583-D328-45C6-8BB1-5D41B8F1D216}.Release|Any CPU.Build.0 = Release|Any CPU + {1612F583-D328-45C6-8BB1-5D41B8F1D216}.Release|ARM.ActiveCfg = Release|Any CPU + {1612F583-D328-45C6-8BB1-5D41B8F1D216}.Release|ARM.Build.0 = Release|Any CPU + {1612F583-D328-45C6-8BB1-5D41B8F1D216}.Release|ARM64.ActiveCfg = Release|Any CPU + {1612F583-D328-45C6-8BB1-5D41B8F1D216}.Release|ARM64.Build.0 = Release|Any CPU + {1612F583-D328-45C6-8BB1-5D41B8F1D216}.Release|x64.ActiveCfg = Release|Any CPU + {1612F583-D328-45C6-8BB1-5D41B8F1D216}.Release|x64.Build.0 = Release|Any CPU + {1612F583-D328-45C6-8BB1-5D41B8F1D216}.Release|x86.ActiveCfg = Release|Any CPU + {1612F583-D328-45C6-8BB1-5D41B8F1D216}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1212,6 +1234,7 @@ Global {BFA4E222-BBCC-4AC7-9EA4-4549AEF3174B} = {8712125E-14CD-4E1B-A1CE-4BDE03805942} {75B55300-ABC3-4CA1-B9B6-DF954E6C7B44} = {8712125E-14CD-4E1B-A1CE-4BDE03805942} {C0060FB3-7AEA-4D14-ADCE-DB78D3665D5B} = {666CB1A9-562E-453A-A2C7-FD9D77CFDFDD} + {1612F583-D328-45C6-8BB1-5D41B8F1D216} = {9FB27073-61A0-4FE3-94DB-5FDDE062332F} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {9AEC9B81-0222-4DE9-B642-D915C29222AC} From a04e3d455c185f7c1c311c4120ded5e818229480 Mon Sep 17 00:00:00 2001 From: taoye Date: Tue, 9 Aug 2022 18:32:33 +0800 Subject: [PATCH 2/5] =?UTF-8?q?180=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BPASmartClient.AGV/AGVHelper.cs | 246 ++++ .../Pages/Model/PlcVariableInfoManage.cs | 3 +- .../Pages/View/VariableConfigView.xaml | 453 ++++++- .../Pages/View/VariableConfigView.xaml.cs | 88 +- .../Pages/ViewModel/VariableViewModel.cs | 34 +- FryPot_DosingSystem/Control/DeviceOperate.cs | 242 +++- .../Control/DosingLogicControl.cs | 1155 +++++++++++++---- FryPot_DosingSystem/Control/GlobalVariable.cs | 70 +- .../Model/FlowProcessManage.cs | 16 + FryPot_DosingSystem/Model/FlowProcessModel.cs | 48 + FryPot_DosingSystem/Model/RecipeModel.cs | 7 +- .../Resources/fonts/demo_index.html | 94 +- .../Resources/fonts/iconfont.ttf | Bin 4300 -> 5720 bytes FryPot_DosingSystem/View/DebugView.xaml | 48 +- FryPot_DosingSystem/View/FlowProcessView.xaml | 75 ++ .../View/FlowProcessView.xaml.cs | 35 + FryPot_DosingSystem/View/NewRecipeView.xaml | 26 +- .../View/RecipeManageView.xaml | 1 + .../ViewModel/DebugViewModel.cs | 47 + .../ViewModel/DeviceListViewModel.cs | 2 +- .../ViewModel/FlowProcessSetViewModel.cs | 77 ++ .../ViewModel/NewRecipeViewModel.cs | 2 +- .../ViewModel/RecipeSetViewModel.cs | 16 + 23 files changed, 2510 insertions(+), 275 deletions(-) create mode 100644 FryPot_DosingSystem/Model/FlowProcessManage.cs create mode 100644 FryPot_DosingSystem/Model/FlowProcessModel.cs create mode 100644 FryPot_DosingSystem/View/FlowProcessView.xaml create mode 100644 FryPot_DosingSystem/View/FlowProcessView.xaml.cs create mode 100644 FryPot_DosingSystem/ViewModel/FlowProcessSetViewModel.cs diff --git a/BPASmartClient.AGV/AGVHelper.cs b/BPASmartClient.AGV/AGVHelper.cs index 54afe569..29a8c7ce 100644 --- a/BPASmartClient.AGV/AGVHelper.cs +++ b/BPASmartClient.AGV/AGVHelper.cs @@ -239,6 +239,55 @@ namespace BPASmartClient.AGV return "Analysis Error"; } /// + /// AGV从清洗台到4号线体卸桶 + /// + /// + public string AgvFromCleanToLineFourUnLoadRoller(string robotJobId) + { + //string url = AGVRequestUrl.GetInstance.TaskSendUrl; + ////请求报文头 + //HttpRequestHeaderModel.GetInstance.appKey = ""; + //HttpRequestHeaderModel.GetInstance.appSecret = ""; + //HttpRequestHeaderModel.GetInstance.requestId = ""; + //HttpRequestHeaderModel.GetInstance.timestamp = ""; + //HttpRequestHeaderModel.GetInstance.version = "2.8"; + //string head = JsonConvert.SerializeObject(HttpRequestHeaderModel.GetInstance); + ////请求报文体 + //AGVModel.GetInstance.robotJobId = robotJobId;//上游提供 + //AGVModel.GetInstance.warehouseId = 123; //仓库编号 + //AGVModel.GetInstance.jobPriority = 1;//任务执行的优先级 + //AGVModel.GetInstance.jobPriorityType = 1;//0:根据优先级来执行,1:强制执行 + //AGVModel.GetInstance.jobType = "POINT_ROLLER_MOVE"; //SLOT_ROLLER_MOVE / POINT_ROLLER_MOVE + ////详细任务数据 + ////点到点 + //AGV_PointRollerJobData.GetInstance.startPoint = "";//起点点位 + //AGV_PointRollerJobData.GetInstance.endPoint = "";//目的点位 + //AGV_PointRollerJobData.GetInstance.autoLoad = true;//是否自动上料 true:自动上料 false:人工上料 + //AGV_PointRollerJobData.GetInstance.enableIOLoad = true;//上料交互方式 false:接口交互 true:光电交互 + //AGV_PointRollerJobData.GetInstance.autoUnload = true;//是否自动下料 true:自动下料 false:人工下料 + //AGV_PointRollerJobData.GetInstance.enableIOUnload = true;//下料交互方式 false:接口交互 true:光电交互 + //AGVModel.GetInstance.jobData = AGV_PointRollerJobData.GetInstance; + //string body = JsonConvert.SerializeObject(AGVModel.GetInstance); + ////货位到货位 + ////AGV_SlotRollerJobData.GetInstance.startSlotCode = "";//起点槽位编号 + ////AGV_SlotRollerJobData.GetInstance.endSlotCode = "";//目的槽位编号 + ////AGV_SlotRollerJobData.GetInstance.autoLoad = true;//是否自动上料 true:自动上料 false:人工上料 + ////AGV_SlotRollerJobData.GetInstance.enableIOLoad=true;//上料交互方式 false:接口交互 true:光电交互 + ////AGV_SlotRollerJobData.GetInstance.autoUnload = true;//是否自动下料 true:自动下料 false:人工下料 + ////AGV_SlotRollerJobData.GetInstance.enableIOUnload=true;//下料交互方式 false:接口交互 true:光电交互 + ////AGVModel.GetInstance.jobData = AGV_SlotRollerJobData.GetInstance; + ////string body = JsonConvert.SerializeObject(AGVModel.GetInstance); + ////启用签名 + ////url = url + "?sign=" + MD5Deal(body); + //string data = HttpRequest(url, head, body); + //object objData = JsonConvert.DeserializeObject(data); + //if (objData != null && objData is HttpResponseBodyModel response) + //{ + // return response.code; + //} + return "Analysis Error"; + } + /// /// AGV离开炒锅1 /// /// @@ -483,6 +532,203 @@ namespace BPASmartClient.AGV //} return "Analysis Error"; } + + /// + /// AGV从1号线运空桶洗桶 + /// + /// + public string AgvLeaveLOneToClean(string robotJobId) + { + //string url = AGVRequestUrl.GetInstance.TaskSendUrl; + ////请求报文头 + //HttpRequestHeaderModel.GetInstance.appKey = ""; + //HttpRequestHeaderModel.GetInstance.appSecret = ""; + //HttpRequestHeaderModel.GetInstance.requestId = ""; + //HttpRequestHeaderModel.GetInstance.timestamp = ""; + //HttpRequestHeaderModel.GetInstance.version = "2.8"; + //string head = JsonConvert.SerializeObject(HttpRequestHeaderModel.GetInstance); + ////请求报文体 + //AGVModel.GetInstance.robotJobId = robotJobId;//上游提供 + //AGVModel.GetInstance.warehouseId = 123; //仓库编号 + //AGVModel.GetInstance.jobPriority = 1;//任务执行的优先级 + //AGVModel.GetInstance.jobPriorityType = 1;//0:根据优先级来执行,1:强制执行 + //AGVModel.GetInstance.jobType = "POINT_ROLLER_MOVE"; //SLOT_ROLLER_MOVE / POINT_ROLLER_MOVE + ////详细任务数据 + ////点到点 + //AGV_PointRollerJobData.GetInstance.startPoint = "";//起点点位 + //AGV_PointRollerJobData.GetInstance.endPoint = "";//目的点位 + //AGV_PointRollerJobData.GetInstance.autoLoad = true;//是否自动上料 true:自动上料 false:人工上料 + //AGV_PointRollerJobData.GetInstance.enableIOLoad = true;//上料交互方式 false:接口交互 true:光电交互 + //AGV_PointRollerJobData.GetInstance.autoUnload = true;//是否自动下料 true:自动下料 false:人工下料 + //AGV_PointRollerJobData.GetInstance.enableIOUnload = true;//下料交互方式 false:接口交互 true:光电交互 + //AGVModel.GetInstance.jobData = AGV_PointRollerJobData.GetInstance; + //string body = JsonConvert.SerializeObject(AGVModel.GetInstance); + ////货位到货位 + ////AGV_SlotRollerJobData.GetInstance.startSlotCode = "";//起点槽位编号 + ////AGV_SlotRollerJobData.GetInstance.endSlotCode = "";//目的槽位编号 + ////AGV_SlotRollerJobData.GetInstance.autoLoad = true;//是否自动上料 true:自动上料 false:人工上料 + ////AGV_SlotRollerJobData.GetInstance.enableIOLoad=true;//上料交互方式 false:接口交互 true:光电交互 + ////AGV_SlotRollerJobData.GetInstance.autoUnload = true;//是否自动下料 true:自动下料 false:人工下料 + ////AGV_SlotRollerJobData.GetInstance.enableIOUnload=true;//下料交互方式 false:接口交互 true:光电交互 + ////AGVModel.GetInstance.jobData = AGV_SlotRollerJobData.GetInstance; + ////string body = JsonConvert.SerializeObject(AGVModel.GetInstance); + ////启用签名 + ////url = url + "?sign=" + MD5Deal(body); + //string data = HttpRequest(url, head, body); + //object objData = JsonConvert.DeserializeObject(data); + //if (objData != null && objData is HttpResponseBodyModel response) + //{ + // return response.code; + //} + return "Analysis Error"; + } + /// + /// AGV从2号线运空桶洗桶 + /// + /// + public string AgvLeaveLTwoToClean(string robotJobId) + { + //string url = AGVRequestUrl.GetInstance.TaskSendUrl; + ////请求报文头 + //HttpRequestHeaderModel.GetInstance.appKey = ""; + //HttpRequestHeaderModel.GetInstance.appSecret = ""; + //HttpRequestHeaderModel.GetInstance.requestId = ""; + //HttpRequestHeaderModel.GetInstance.timestamp = ""; + //HttpRequestHeaderModel.GetInstance.version = "2.8"; + //string head = JsonConvert.SerializeObject(HttpRequestHeaderModel.GetInstance); + ////请求报文体 + //AGVModel.GetInstance.robotJobId = robotJobId;//上游提供 + //AGVModel.GetInstance.warehouseId = 123; //仓库编号 + //AGVModel.GetInstance.jobPriority = 1;//任务执行的优先级 + //AGVModel.GetInstance.jobPriorityType = 1;//0:根据优先级来执行,1:强制执行 + //AGVModel.GetInstance.jobType = "POINT_ROLLER_MOVE"; //SLOT_ROLLER_MOVE / POINT_ROLLER_MOVE + ////详细任务数据 + ////点到点 + //AGV_PointRollerJobData.GetInstance.startPoint = "";//起点点位 + //AGV_PointRollerJobData.GetInstance.endPoint = "";//目的点位 + //AGV_PointRollerJobData.GetInstance.autoLoad = true;//是否自动上料 true:自动上料 false:人工上料 + //AGV_PointRollerJobData.GetInstance.enableIOLoad = true;//上料交互方式 false:接口交互 true:光电交互 + //AGV_PointRollerJobData.GetInstance.autoUnload = true;//是否自动下料 true:自动下料 false:人工下料 + //AGV_PointRollerJobData.GetInstance.enableIOUnload = true;//下料交互方式 false:接口交互 true:光电交互 + //AGVModel.GetInstance.jobData = AGV_PointRollerJobData.GetInstance; + //string body = JsonConvert.SerializeObject(AGVModel.GetInstance); + ////货位到货位 + ////AGV_SlotRollerJobData.GetInstance.startSlotCode = "";//起点槽位编号 + ////AGV_SlotRollerJobData.GetInstance.endSlotCode = "";//目的槽位编号 + ////AGV_SlotRollerJobData.GetInstance.autoLoad = true;//是否自动上料 true:自动上料 false:人工上料 + ////AGV_SlotRollerJobData.GetInstance.enableIOLoad=true;//上料交互方式 false:接口交互 true:光电交互 + ////AGV_SlotRollerJobData.GetInstance.autoUnload = true;//是否自动下料 true:自动下料 false:人工下料 + ////AGV_SlotRollerJobData.GetInstance.enableIOUnload=true;//下料交互方式 false:接口交互 true:光电交互 + ////AGVModel.GetInstance.jobData = AGV_SlotRollerJobData.GetInstance; + ////string body = JsonConvert.SerializeObject(AGVModel.GetInstance); + ////启用签名 + ////url = url + "?sign=" + MD5Deal(body); + //string data = HttpRequest(url, head, body); + //object objData = JsonConvert.DeserializeObject(data); + //if (objData != null && objData is HttpResponseBodyModel response) + //{ + // return response.code; + //} + return "Analysis Error"; + } + /// + /// AGV从3号线运空桶洗桶 + /// + /// + public string AgvLeaveLThreeToClean(string robotJobId) + { + //string url = AGVRequestUrl.GetInstance.TaskSendUrl; + ////请求报文头 + //HttpRequestHeaderModel.GetInstance.appKey = ""; + //HttpRequestHeaderModel.GetInstance.appSecret = ""; + //HttpRequestHeaderModel.GetInstance.requestId = ""; + //HttpRequestHeaderModel.GetInstance.timestamp = ""; + //HttpRequestHeaderModel.GetInstance.version = "2.8"; + //string head = JsonConvert.SerializeObject(HttpRequestHeaderModel.GetInstance); + ////请求报文体 + //AGVModel.GetInstance.robotJobId = robotJobId;//上游提供 + //AGVModel.GetInstance.warehouseId = 123; //仓库编号 + //AGVModel.GetInstance.jobPriority = 1;//任务执行的优先级 + //AGVModel.GetInstance.jobPriorityType = 1;//0:根据优先级来执行,1:强制执行 + //AGVModel.GetInstance.jobType = "POINT_ROLLER_MOVE"; //SLOT_ROLLER_MOVE / POINT_ROLLER_MOVE + ////详细任务数据 + ////点到点 + //AGV_PointRollerJobData.GetInstance.startPoint = "";//起点点位 + //AGV_PointRollerJobData.GetInstance.endPoint = "";//目的点位 + //AGV_PointRollerJobData.GetInstance.autoLoad = true;//是否自动上料 true:自动上料 false:人工上料 + //AGV_PointRollerJobData.GetInstance.enableIOLoad = true;//上料交互方式 false:接口交互 true:光电交互 + //AGV_PointRollerJobData.GetInstance.autoUnload = true;//是否自动下料 true:自动下料 false:人工下料 + //AGV_PointRollerJobData.GetInstance.enableIOUnload = true;//下料交互方式 false:接口交互 true:光电交互 + //AGVModel.GetInstance.jobData = AGV_PointRollerJobData.GetInstance; + //string body = JsonConvert.SerializeObject(AGVModel.GetInstance); + ////货位到货位 + ////AGV_SlotRollerJobData.GetInstance.startSlotCode = "";//起点槽位编号 + ////AGV_SlotRollerJobData.GetInstance.endSlotCode = "";//目的槽位编号 + ////AGV_SlotRollerJobData.GetInstance.autoLoad = true;//是否自动上料 true:自动上料 false:人工上料 + ////AGV_SlotRollerJobData.GetInstance.enableIOLoad=true;//上料交互方式 false:接口交互 true:光电交互 + ////AGV_SlotRollerJobData.GetInstance.autoUnload = true;//是否自动下料 true:自动下料 false:人工下料 + ////AGV_SlotRollerJobData.GetInstance.enableIOUnload=true;//下料交互方式 false:接口交互 true:光电交互 + ////AGVModel.GetInstance.jobData = AGV_SlotRollerJobData.GetInstance; + ////string body = JsonConvert.SerializeObject(AGVModel.GetInstance); + ////启用签名 + ////url = url + "?sign=" + MD5Deal(body); + //string data = HttpRequest(url, head, body); + //object objData = JsonConvert.DeserializeObject(data); + //if (objData != null && objData is HttpResponseBodyModel response) + //{ + // return response.code; + //} + return "Analysis Error"; + } + /// + /// AGV从洗桶处运桶到4号洗桶线 + /// + /// + public string AgvLeaveCleanToLFour(string robotJobId) + { + //string url = AGVRequestUrl.GetInstance.TaskSendUrl; + ////请求报文头 + //HttpRequestHeaderModel.GetInstance.appKey = ""; + //HttpRequestHeaderModel.GetInstance.appSecret = ""; + //HttpRequestHeaderModel.GetInstance.requestId = ""; + //HttpRequestHeaderModel.GetInstance.timestamp = ""; + //HttpRequestHeaderModel.GetInstance.version = "2.8"; + //string head = JsonConvert.SerializeObject(HttpRequestHeaderModel.GetInstance); + ////请求报文体 + //AGVModel.GetInstance.robotJobId = robotJobId;//上游提供 + //AGVModel.GetInstance.warehouseId = 123; //仓库编号 + //AGVModel.GetInstance.jobPriority = 1;//任务执行的优先级 + //AGVModel.GetInstance.jobPriorityType = 1;//0:根据优先级来执行,1:强制执行 + //AGVModel.GetInstance.jobType = "POINT_ROLLER_MOVE"; //SLOT_ROLLER_MOVE / POINT_ROLLER_MOVE + ////详细任务数据 + ////点到点 + //AGV_PointRollerJobData.GetInstance.startPoint = "";//起点点位 + //AGV_PointRollerJobData.GetInstance.endPoint = "";//目的点位 + //AGV_PointRollerJobData.GetInstance.autoLoad = true;//是否自动上料 true:自动上料 false:人工上料 + //AGV_PointRollerJobData.GetInstance.enableIOLoad = true;//上料交互方式 false:接口交互 true:光电交互 + //AGV_PointRollerJobData.GetInstance.autoUnload = true;//是否自动下料 true:自动下料 false:人工下料 + //AGV_PointRollerJobData.GetInstance.enableIOUnload = true;//下料交互方式 false:接口交互 true:光电交互 + //AGVModel.GetInstance.jobData = AGV_PointRollerJobData.GetInstance; + //string body = JsonConvert.SerializeObject(AGVModel.GetInstance); + ////货位到货位 + ////AGV_SlotRollerJobData.GetInstance.startSlotCode = "";//起点槽位编号 + ////AGV_SlotRollerJobData.GetInstance.endSlotCode = "";//目的槽位编号 + ////AGV_SlotRollerJobData.GetInstance.autoLoad = true;//是否自动上料 true:自动上料 false:人工上料 + ////AGV_SlotRollerJobData.GetInstance.enableIOLoad=true;//上料交互方式 false:接口交互 true:光电交互 + ////AGV_SlotRollerJobData.GetInstance.autoUnload = true;//是否自动下料 true:自动下料 false:人工下料 + ////AGV_SlotRollerJobData.GetInstance.enableIOUnload=true;//下料交互方式 false:接口交互 true:光电交互 + ////AGVModel.GetInstance.jobData = AGV_SlotRollerJobData.GetInstance; + ////string body = JsonConvert.SerializeObject(AGVModel.GetInstance); + ////启用签名 + ////url = url + "?sign=" + MD5Deal(body); + //string data = HttpRequest(url, head, body); + //object objData = JsonConvert.DeserializeObject(data); + //if (objData != null && objData is HttpResponseBodyModel response) + //{ + // return response.code; + //} + return "Analysis Error"; + } /// /// 任务取消 /// diff --git a/BPASmartClient.CustomResource/Pages/Model/PlcVariableInfoManage.cs b/BPASmartClient.CustomResource/Pages/Model/PlcVariableInfoManage.cs index b8c11c6c..80834923 100644 --- a/BPASmartClient.CustomResource/Pages/Model/PlcVariableInfoManage.cs +++ b/BPASmartClient.CustomResource/Pages/Model/PlcVariableInfoManage.cs @@ -1,5 +1,6 @@ using Microsoft.Toolkit.Mvvm.ComponentModel; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; @@ -10,6 +11,6 @@ namespace BPASmartClient.CustomResource.Pages.Model { public class PlcVariableInfoManage:ObservableObject { - public ObservableCollection VariablesInfo { get; set; } = new ObservableCollection(); + public ConcurrentDictionary> VariablesInfo { get; set; } = new ConcurrentDictionary>(); } } diff --git a/BPASmartClient.CustomResource/Pages/View/VariableConfigView.xaml b/BPASmartClient.CustomResource/Pages/View/VariableConfigView.xaml index 33526ec6..9abfd756 100644 --- a/BPASmartClient.CustomResource/Pages/View/VariableConfigView.xaml +++ b/BPASmartClient.CustomResource/Pages/View/VariableConfigView.xaml @@ -5,12 +5,14 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:BPASmartClient.CustomResource.Pages.View" xmlns:vm="clr-namespace:BPASmartClient.CustomResource.Pages.ViewModel" + xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero2" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + - @@ -124,6 +408,165 @@ --> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BPASmartClient.CustomResource/Pages/View/VariableConfigView.xaml.cs b/BPASmartClient.CustomResource/Pages/View/VariableConfigView.xaml.cs index f133e9ba..51a962d4 100644 --- a/BPASmartClient.CustomResource/Pages/View/VariableConfigView.xaml.cs +++ b/BPASmartClient.CustomResource/Pages/View/VariableConfigView.xaml.cs @@ -29,7 +29,93 @@ namespace BPASmartClient.CustomResource.Pages.View { e.Row.Header = e.Row.GetIndex() + 1; } + private void fryOne_LoadingRow(object sender, DataGridRowEventArgs e) + { + e.Row.Header = e.Row.GetIndex() + 1; + } + + private void fryTwo_LoadingRow(object sender, DataGridRowEventArgs e) + { + e.Row.Header = e.Row.GetIndex() + 1; + } + + private void fryThree_LoadingRow(object sender, DataGridRowEventArgs e) + { + e.Row.Header = e.Row.GetIndex() + 1; + } + + private void fryFour_LoadingRow(object sender, DataGridRowEventArgs e) + { + e.Row.Header = e.Row.GetIndex() + 1; + } + + private void fryFive_LoadingRow(object sender, DataGridRowEventArgs e) + { + e.Row.Header = e.Row.GetIndex() + 1; + } + + private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + ComboBox cbo= sender as ComboBox; + if (cbo != null) + { + switch (cbo.SelectedValue) + { + case "滚筒输送线": + this.GT.Visibility = Visibility.Visible; + this.fryOne.Visibility = Visibility.Collapsed; + this.fryTwo.Visibility=Visibility.Collapsed; + this.fryThree.Visibility = Visibility.Collapsed; + this.fryFour.Visibility = Visibility.Collapsed; + this.fryFive.Visibility = Visibility.Collapsed; + break; + case "炒锅1": + this.GT.Visibility = Visibility.Collapsed; + this.fryOne.Visibility = Visibility.Visible; + this.fryTwo.Visibility = Visibility.Collapsed; + this.fryThree.Visibility = Visibility.Collapsed; + this.fryFour.Visibility = Visibility.Collapsed; + this.fryFive.Visibility = Visibility.Collapsed; + break; + case "炒锅2": + this.GT.Visibility = Visibility.Collapsed; + this.fryOne.Visibility = Visibility.Collapsed; + this.fryTwo.Visibility = Visibility.Visible; + this.fryThree.Visibility = Visibility.Collapsed; + this.fryFour.Visibility = Visibility.Collapsed; + this.fryFive.Visibility = Visibility.Collapsed; + break; + case "炒锅3": + this.GT.Visibility = Visibility.Collapsed; + this.fryOne.Visibility = Visibility.Collapsed; + this.fryTwo.Visibility = Visibility.Collapsed; + this.fryThree.Visibility = Visibility.Visible; + this.fryFour.Visibility = Visibility.Collapsed; + this.fryFive.Visibility = Visibility.Collapsed; + break; + case "炒锅4": + this.GT.Visibility = Visibility.Collapsed; + this.fryOne.Visibility = Visibility.Collapsed; + this.fryTwo.Visibility = Visibility.Collapsed; + this.fryThree.Visibility = Visibility.Collapsed; + this.fryFour.Visibility = Visibility.Visible; + this.fryFive.Visibility = Visibility.Collapsed; + break; + case "炒锅5": + this.GT.Visibility = Visibility.Collapsed; + this.fryOne.Visibility = Visibility.Collapsed; + this.fryTwo.Visibility = Visibility.Collapsed; + this.fryThree.Visibility = Visibility.Collapsed; + this.fryFour.Visibility = Visibility.Collapsed; + this.fryFive.Visibility = Visibility.Visible; + break; + } + + + } + + } - + } } diff --git a/BPASmartClient.CustomResource/Pages/ViewModel/VariableViewModel.cs b/BPASmartClient.CustomResource/Pages/ViewModel/VariableViewModel.cs index f8ff0489..afaae21d 100644 --- a/BPASmartClient.CustomResource/Pages/ViewModel/VariableViewModel.cs +++ b/BPASmartClient.CustomResource/Pages/ViewModel/VariableViewModel.cs @@ -15,15 +15,45 @@ namespace BPASmartClient.CustomResource.Pages.ViewModel public class VariableViewModel : ObservableObject { public ObservableCollection Variables { get; set; } = new ObservableCollection(); - + + public ObservableCollection FryOneVariables { get; set; } = new ObservableCollection(); + public ObservableCollection FryTwoVariables { get; set; } = new ObservableCollection(); + public ObservableCollection FryThreeVariables { get; set; } = new ObservableCollection(); + public ObservableCollection FryFourVariables { get; set; } = new ObservableCollection(); + public ObservableCollection FryFiveVariables { get; set; } = new ObservableCollection(); + + public List DeviceName { get; set; } = new List { "滚筒输送线", "炒锅1", "炒锅2", "炒锅3", "炒锅4", "炒锅5" }; public RelayCommand SaveDataCommand { get; set; } public VariableViewModel() { Json.Read(); - Variables = Json.Data.VariablesInfo; + + try + { + if (Json.Data.VariablesInfo.Count>0) + { + Variables = Json.Data.VariablesInfo["滚筒输送线"]; + FryOneVariables = Json.Data.VariablesInfo["炒锅1"]; + FryTwoVariables = Json.Data.VariablesInfo["炒锅2"]; + FryThreeVariables = Json.Data.VariablesInfo["炒锅3"]; + FryFourVariables = Json.Data.VariablesInfo["炒锅4"]; + FryFiveVariables = Json.Data.VariablesInfo["炒锅5"]; + } + } + catch (Exception) + { + + + } SaveDataCommand = new RelayCommand(() => { + Json.Data.VariablesInfo["滚筒输送线"] = Variables; + Json.Data.VariablesInfo["炒锅1"] = FryOneVariables; + Json.Data.VariablesInfo["炒锅2"]=FryTwoVariables; + Json.Data.VariablesInfo["炒锅3"] = FryThreeVariables; + Json.Data.VariablesInfo["炒锅4"]= FryFourVariables; + Json.Data.VariablesInfo["炒锅5"] = FryFiveVariables; Json.Save(); MessageBox.Show("保存成功","提示",MessageBoxButton.OK,MessageBoxImage.Information); }); diff --git a/FryPot_DosingSystem/Control/DeviceOperate.cs b/FryPot_DosingSystem/Control/DeviceOperate.cs index 7a33ee88..c5eb9758 100644 --- a/FryPot_DosingSystem/Control/DeviceOperate.cs +++ b/FryPot_DosingSystem/Control/DeviceOperate.cs @@ -20,15 +20,35 @@ namespace FryPot_DosingSystem.Control private static DeviceOperate _instance; public static DeviceOperate GetInstance => _instance ??= new DeviceOperate(); public bool IsConfig { get; set; }//设备plc数据是否配置 - ModbusTcp modbus = new ModbusTcp(); - private string Ip { get; set; } - private string Port { get; set; } + ModbusTcp modbus = new ModbusTcp();//滚筒线Modbus通讯对象 + ModbusTcp fryOneModbus = new ModbusTcp();//炒锅1Modbus通讯对象 + ModbusTcp fryTwoModbus = new ModbusTcp();//炒锅2Modbus通讯对象 + ModbusTcp fryThreeModbus = new ModbusTcp();//炒锅3Modbus通讯对象 + ModbusTcp fryFourModbus = new ModbusTcp();//炒锅4Modbus通讯对象 + ModbusTcp fryFiveModbus = new ModbusTcp();//炒锅5Modbus通讯对象 + // private string Ip { get; set; } + // private string Port { get; set; } public bool Connected { get; set; } + public bool FryOneConnected { get; set; } + public bool FryTwoConnected { get; set; } + public bool FryThreeConnected { get; set; } + public bool FryFourConnected { get; set; } + public bool FryFiveConnected { get; set; } - private string DeviceName { get; set; } + // private string DeviceName { get; set; } public ConcurrentDictionary Data { get; set; } = new ConcurrentDictionary(); + public ConcurrentDictionary FryOneData { get; set; } = new ConcurrentDictionary(); + public ConcurrentDictionary FryTwoData { get; set; } = new ConcurrentDictionary(); + public ConcurrentDictionary FryThreeData { get; set; } = new ConcurrentDictionary(); + public ConcurrentDictionary FryFourData { get; set; } = new ConcurrentDictionary(); + public ConcurrentDictionary FryFiveData { get; set; } = new ConcurrentDictionary(); public ObservableCollection Variables { get; set; } = new ObservableCollection(); + public ObservableCollection FryOneVariables { get; set; } = new ObservableCollection(); + public ObservableCollection FryTwoVariables { get; set; } = new ObservableCollection(); + public ObservableCollection FryThreeVariables { get; set; } = new ObservableCollection(); + public ObservableCollection FryFourVariables { get; set; } = new ObservableCollection(); + public ObservableCollection FryFiveVariables { get; set; } = new ObservableCollection(); public DeviceOperate() { Init(); @@ -37,18 +57,69 @@ namespace FryPot_DosingSystem.Control } public void Init() { - if (Variables.Count > 0) - { - Variables.Clear(); - } + Variables.Clear(); + FryOneVariables.Clear(); + FryTwoVariables.Clear(); + FryThreeVariables.Clear(); + FryFourVariables.Clear(); + FryFiveVariables.Clear(); + Json.Read(); if (Json.Data.VariablesInfo.Count > 0) { try { - foreach (var item in Json.Data.VariablesInfo) + if (Json.Data.VariablesInfo["滚筒输送线"].Count>0) { - Variables.Add(new PlcVariableModel { Address = item.PlcAddress, Length = (ushort)(item.Length == null ? 0 : item.Length) }); + //foreach (var item in Json.Data.VariablesInfo["滚筒运输线"]) + //{ + // Variables.Add(new PlcVariableModel { Address = item.PlcAddress, Length = (ushort)(item.Length == null ? 0 : item.Length) }); + //} + foreach (KeyValuePair> dic in Json.Data.VariablesInfo) + { + if (string.Equals(dic.Key, "滚筒输送线")) + { + foreach (var item in dic.Value) + { + Variables.Add(new PlcVariableModel { Address = item.PlcAddress, Length = (ushort)(item.Length == null ? 0 : item.Length) }); + } + } + if (string.Equals(dic.Key, "炒锅1")) + { + foreach (var item in dic.Value) + { + FryOneVariables.Add(new PlcVariableModel { Address = item.PlcAddress, Length = (ushort)(item.Length == null ? 0 : item.Length) }); + } + } + if (string.Equals(dic.Key, "炒锅2")) + { + foreach (var item in dic.Value) + { + FryTwoVariables.Add(new PlcVariableModel { Address = item.PlcAddress, Length = (ushort)(item.Length == null ? 0 : item.Length) }); + } + } + if (string.Equals(dic.Key, "炒锅3")) + { + foreach (var item in dic.Value) + { + FryThreeVariables.Add(new PlcVariableModel { Address = item.PlcAddress, Length = (ushort)(item.Length == null ? 0 : item.Length) }); + } + } + if (string.Equals(dic.Key, "炒锅4")) + { + foreach (var item in dic.Value) + { + FryFourVariables.Add(new PlcVariableModel { Address = item.PlcAddress, Length = (ushort)(item.Length == null ? 0 : item.Length) }); + } + } + if (string.Equals(dic.Key, "炒锅5")) + { + foreach (var item in dic.Value) + { + FryFiveVariables.Add(new PlcVariableModel { Address = item.PlcAddress, Length = (ushort)(item.Length == null ? 0 : item.Length) }); + } + } + } } IsConfig = true; } @@ -59,8 +130,8 @@ namespace FryPot_DosingSystem.Control } } else - { - IsConfig= false; + { + IsConfig = false; } //Variables.Add(new PlcVariableModel() { Address = "D2001", Length = 8 });//1号线体滚筒工位号 //Variables.Add(new PlcVariableModel() { Address = "D2011", Length = 8 });//2号线体滚筒工位号 @@ -88,13 +159,26 @@ namespace FryPot_DosingSystem.Control { if (devices.Devices.Count > 0) { - Ip = devices.Devices[0].Ip; - Port = devices.Devices[0].Port; - DeviceName = devices.Devices[0].DeviceName; - Task.Run(() => { modbus.ModbusTcpConnect(Ip, Convert.ToInt32(Port)); }); - // Task.Run(() => { modbus.ModbusTcpConnect(Ip, Convert.ToInt32(Port)); App.Current.Dispatcher.Invoke(new Action(() => { BPASmartClient.CustomResource.Pages.Model.MessageLog.GetInstance.RunLog("PLC连接成功"); })); }); + for (int i = 0; i < devices.Devices.Count; i++) + { + string Ip = devices.Devices[i].Ip; + string Port = devices.Devices[i].Port; + string DeviceName = devices.Devices[i].DeviceName; + switch (DeviceName) + { + case "滚筒输送线": Task.Run(() => { modbus.ModbusTcpConnect(Ip, Convert.ToInt32(Port)); }); break; + case "炒锅1": Task.Run(() => { fryOneModbus.ModbusTcpConnect(Ip, Convert.ToInt32(Port)); }); break; + case "炒锅2": Task.Run(() => { fryTwoModbus.ModbusTcpConnect(Ip, Convert.ToInt32(Port)); }); break; + case "炒锅3": Task.Run(() => { fryThreeModbus.ModbusTcpConnect(Ip, Convert.ToInt32(Port)); }); break; + case "炒锅4": Task.Run(() => { fryFourModbus.ModbusTcpConnect(Ip, Convert.ToInt32(Port)); }); break; + case "炒锅5": Task.Run(() => { fryFiveModbus.ModbusTcpConnect(Ip, Convert.ToInt32(Port)); }); break; + + } + + } + // Task.Run(() => { modbus.ModbusTcpConnect(Ip, Convert.ToInt32(Port)); App.Current.Dispatcher.Invoke(new Action(() => { BPASmartClient.CustomResource.Pages.Model.MessageLog.GetInstance.RunLog("PLC连接成功"); })); }); } - } + } } } public void ReadData() @@ -103,6 +187,7 @@ namespace FryPot_DosingSystem.Control { ThreadManage.GetInstance().StartLong(new Action(() => { + //滚筒线 Connected = modbus.Connected; while (Connected) { @@ -118,11 +203,106 @@ namespace FryPot_DosingSystem.Control Data.TryAdd(item.Address, res); } } - Thread.Sleep(500); + Thread.Sleep(50); + + } + //炒锅1 + FryOneConnected = fryOneModbus.Connected; + while (FryOneConnected) + { + foreach (var item in FryOneVariables) + { + var res = fryOneModbus.Read(item.Address, item.Length);//读取plc数据 + if (FryOneData.ContainsKey(item.Address)) + { + FryOneData[item.Address] = res; + } + else + { + FryOneData.TryAdd(item.Address, res); + } + } + Thread.Sleep(50); } - Thread.Sleep(1000); - }), $"设备【{DeviceName}】PLC实时数据读取线程"); + //炒锅2 + FryTwoConnected = fryTwoModbus.Connected; + while (FryTwoConnected) + { + foreach (var item in FryTwoVariables) + { + var res = fryTwoModbus.Read(item.Address, item.Length);//读取plc数据 + if (FryTwoData.ContainsKey(item.Address)) + { + FryTwoData[item.Address] = res; + } + else + { + FryTwoData.TryAdd(item.Address, res); + } + } + Thread.Sleep(50); + + } + //炒锅3 + FryThreeConnected = fryThreeModbus.Connected; + while (FryThreeConnected) + { + foreach (var item in FryThreeVariables) + { + var res = fryThreeModbus.Read(item.Address, item.Length);//读取plc数据 + if (FryThreeData.ContainsKey(item.Address)) + { + FryThreeData[item.Address] = res; + } + else + { + FryThreeData.TryAdd(item.Address, res); + } + } + Thread.Sleep(50); + + } + //炒锅4 + FryFourConnected = fryFourModbus.Connected; + while (FryFourConnected) + { + foreach (var item in FryFourVariables) + { + var res = fryFourModbus.Read(item.Address, item.Length);//读取plc数据 + if (FryFourData.ContainsKey(item.Address)) + { + FryFourData[item.Address] = res; + } + else + { + FryFourData.TryAdd(item.Address, res); + } + } + Thread.Sleep(50); + + } + //炒锅5 + FryFiveConnected = fryFiveModbus.Connected; + while (FryFiveConnected) + { + foreach (var item in FryFiveVariables) + { + var res = fryFiveModbus.Read(item.Address, item.Length);//读取plc数据 + if (FryFiveData.ContainsKey(item.Address)) + { + FryFiveData[item.Address] = res; + } + else + { + FryFiveData.TryAdd(item.Address, res); + } + } + Thread.Sleep(50); + + } + Thread.Sleep(500); + }), $"PLC实时数据读取线程"); } } public void WritePlcData(string address, ushort value) @@ -136,5 +316,25 @@ namespace FryPot_DosingSystem.Control { return Data; } + public ConcurrentDictionary GetFryOneData() + { + return FryOneData; + } + public ConcurrentDictionary GetFryTwoData() + { + return FryTwoData; + } + public ConcurrentDictionary GetFryThreeData() + { + return FryThreeData; + } + public ConcurrentDictionary GetFryFourData() + { + return FryFourData; + } + public ConcurrentDictionary GetFryFiveData() + { + return FryFiveData; + } } } diff --git a/FryPot_DosingSystem/Control/DosingLogicControl.cs b/FryPot_DosingSystem/Control/DosingLogicControl.cs index 4ca858f2..753df165 100644 --- a/FryPot_DosingSystem/Control/DosingLogicControl.cs +++ b/FryPot_DosingSystem/Control/DosingLogicControl.cs @@ -29,7 +29,16 @@ namespace FryPot_DosingSystem.Control { public static DosingLogicControl _instance; public static DosingLogicControl GetInstance => _instance ??= new DosingLogicControl(); + /// + /// 滚筒线PLC数据 + /// public ConcurrentDictionary PlcReadData = new ConcurrentDictionary(); + + public ConcurrentDictionary FryOneData = new ConcurrentDictionary(); + public ConcurrentDictionary FryTwoData = new ConcurrentDictionary(); + public ConcurrentDictionary FryThreeData = new ConcurrentDictionary(); + public ConcurrentDictionary FryFourData = new ConcurrentDictionary(); + public ConcurrentDictionary FryFiveData = new ConcurrentDictionary(); /// /// 线体1配方队列 /// @@ -126,18 +135,81 @@ namespace FryPot_DosingSystem.Control //bool LTwoagvFryPotEmptyRollerArrive = false; //线体2的agv是否拿到炒锅空桶 //bool LThreeagvFryPotEmptyRollerArrive = false;//线体3的agv是否拿到炒锅空桶 - string LOnerobotJobId = String.Empty;//线体1当前上游系统任务号,全局唯一 - string LTworobotJobId = String.Empty;//线体2当前上游系统任务号,全局唯一 - string LThreerobotJobId = String.Empty;//线体3当前上游系统任务号,全局唯一 - string LFourrobotJobId = String.Empty;//线体4当前上游系统任务号,全局唯一 + string LOnerobotJobId = string.Empty;//线体1当前上游系统任务号,全局唯一 从线体1到炒锅路径 + string LTworobotJobId = string.Empty;//线体2当前上游系统任务号,全局唯一 从线体2到炒锅路径 + string LThreerobotJobId = string.Empty;//线体3当前上游系统任务号,全局唯一 从线体3到炒锅路径 + string LFourrobotJobId = string.Empty;//线体4当前上游系统任务号,全局唯一 从炒锅1、4到线体4路径 + string LFiverobotJobId = string.Empty; //从炒锅2、5到线体4路径 + string LSixrobotJobId = string.Empty; //从炒锅3到线体4路径 + string LSevenrobotJobId = string.Empty; //从线体1到清洗台路径 + string LEightrobotJobId = string.Empty; //从线体2到清洗台路径 + string LNinerobotJobId = string.Empty; //从线体3到清洗台路径 + string LTenrobotJobId = string.Empty; //从清洗台到线体4路径 - //bool loadInteractive = false;// fasle:不需要上料交互 true:需要上料交互 #endregion /// /// 调试命令注册 /// public void CommandRegist() { + + #region 线体空桶清洗及回收调试 + ActionManage.GetInstance.Register(new Action(() => + { + globalVar.agvArriveLineOneLoadEmptyRoller = true; + + }), "AgvArriveLineOneEmptyRollerLoc"); + ActionManage.GetInstance.Register(new Action(() => + { + globalVar.agvArriveLineTwoLoadEmptyRoller = true; + + }), "AgvArriveLineTwoEmptyRollerLoc"); + ActionManage.GetInstance.Register(new Action(() => + { + globalVar.agvArriveLineThreeLoadEmptyRoller = true; + + }), "AgvArriveLineThreeEmptyRollerLoc"); + ActionManage.GetInstance.Register(new Action(() => + { + globalVar.CleanComplete = 1; + + }), "CleanPlateCallAgv"); + ActionManage.GetInstance.Register(new Action(() => + { + globalVar.agvArriveCleanUnLoad = true;//清洗台空桶下料就位 + + }), "AgvArriveCleanPlateLoc"); + ActionManage.GetInstance.Register(new Action(() => + { + globalVar.agvArriveCleanLoad = true;//清洗台空桶上料就位 + + }), "AgvArriveCleanPlateLocLoad"); + ActionManage.GetInstance.Register(new Action(() => + { + globalVar.agvArriveLineFour = true; + + }), "AgvArriveLineFourLoc"); + + #endregion + //接口调试 + ActionManage.GetInstance.Register(new Action(() => + { + string id = Guid.NewGuid().ToString(); + string errorCode=AGVHelper._Instance.AgvToLineOneLoadRoller(id); + if (errorCode == "SUCCESS") + { + MessageLog.GetInstance.ShowRunLog($"AGV任务下发成功"); + } + else if (errorCode == "Analysis Error") + { + MessageLog.GetInstance.ShowRunLog($"提示:AGV 调用API失败,请检查请求报文"); + } + else + { + MessageLog.GetInstance.ShowRunLog($"提示:AGV任务下发失败,错误码:{errorCode}"); + } + }), "AgvDebug"); + ActionManage.GetInstance.Register(new Action(() => { globalVar.rollerLineOne.OutMaterialingSingle = 1; @@ -279,25 +351,62 @@ namespace FryPot_DosingSystem.Control /// private void FileRegClean() { + int days = 5; //清除期限 string[] filesOne = Directory.GetFiles("AccessFile//DB//炒锅1状态数据"); if (filesOne.Count() > 0) { - + foreach (var item in filesOne) + { + FileInfo info = new FileInfo(item); + DateTime createTime = info.CreationTime; + DateTime timeNow = DateTime.Now; + if (TimeDiff(timeNow, createTime) != 0 && TimeDiff(timeNow, createTime) > days) + { + Directory.Delete(item); + } + } } string[] filesTwo = Directory.GetFiles("AccessFile//DB//炒锅2状态数据"); if (filesTwo.Count() > 0) { - + foreach (var item in filesTwo) + { + FileInfo info = new FileInfo(item); + DateTime createTime = info.CreationTime; + DateTime timeNow = DateTime.Now; + if (TimeDiff(timeNow, createTime) != 0 && TimeDiff(timeNow, createTime) > days) + { + Directory.Delete(item); + } + } } string[] filesThree = Directory.GetFiles("AccessFile//DB//炒锅3状态数据"); if (filesThree.Count() > 0) { - + foreach (var item in filesThree) + { + FileInfo info = new FileInfo(item); + DateTime createTime = info.CreationTime; + DateTime timeNow = DateTime.Now; + if (TimeDiff(timeNow, createTime) != 0 && TimeDiff(timeNow, createTime) > days) + { + Directory.Delete(item); + } + } } string[] filesFour = Directory.GetFiles("AccessFile//DB//炒锅4状态数据"); if (filesFour.Count() > 0) { - + foreach (var item in filesFour) + { + FileInfo info = new FileInfo(item); + DateTime createTime = info.CreationTime; + DateTime timeNow = DateTime.Now; + if (TimeDiff(timeNow, createTime) != 0 && TimeDiff(timeNow, createTime) > days) + { + Directory.Delete(item); + } + } } string[] filesFive = Directory.GetDirectories("AccessFile//DB//炒锅5状态数据"); if (filesFive.Count() > 0) @@ -307,7 +416,7 @@ namespace FryPot_DosingSystem.Control FileInfo info = new FileInfo(item); DateTime createTime = info.CreationTime; DateTime timeNow = DateTime.Now; - if (TimeDiff(timeNow, createTime) != 0 && TimeDiff(timeNow, createTime) > 30) + if (TimeDiff(timeNow, createTime) != 0 && TimeDiff(timeNow, createTime) > days) { Directory.Delete(item); } @@ -330,12 +439,12 @@ namespace FryPot_DosingSystem.Control { //计算时间差 //DateDiff = TimeValue.Subtract(NowValue).Duration(); - DateDiff = NowValue.Subtract(TimeValue); - int h= DateDiff.Hours; - int m= DateDiff.Minutes; - return DateDiff.Days; + DateDiff = NowValue.Subtract(TimeValue); + int h = DateDiff.Hours; + int m = DateDiff.Minutes; + return DateDiff.Days; } - catch + catch { return -1; } @@ -500,6 +609,7 @@ namespace FryPot_DosingSystem.Control if (objData != null) { + #region 线体到炒锅 //线体1请求上下料 if (objData.robotJobId == LOnerobotJobId && objData.command == "LOAD")//同一任务号且处于上料阶段,AGV请求上料 { @@ -531,8 +641,84 @@ namespace FryPot_DosingSystem.Control if (objData.robotJobId == LThreerobotJobId && objData.command == "UNLOAD")//同一任务号且处于下料阶段 { globalVar.LThreeagvArriveUnLoad = true;//AGV到达下料位置 + } + #endregion + + #region 炒锅到线体4请求上下料 + if (objData.robotJobId == LFourrobotJobId && objData.command == "LOAD")//同一任务号且处于上料阶段,AGV请求上料 + { + globalVar.agvArriveUpLoad = true;//AGV到达上料位置 + + } + if (objData.robotJobId == LFourrobotJobId && objData.command == "UNLOAD")//同一任务号且处于下料阶段 + { + globalVar.agvArriveLineFour = true;//AGV到达下料位置 + + } + + if (objData.robotJobId == LFiverobotJobId && objData.command == "LOAD") + { + globalVar.agvArriveLTwoUpLoad = true;//AGV到达上料位置 + + } + if (objData.robotJobId == LFiverobotJobId && objData.command == "UNLOAD")//同一任务号且处于下料阶段 + { + globalVar.agvArriveLineFour = true;//AGV到达下料位置 + + } + + if (objData.robotJobId == LSixrobotJobId && objData.command == "LOAD") + { + globalVar.agvArriveLThreeUpLoad = true;//AGV到达上料位置 + + } + if (objData.robotJobId == LSixrobotJobId && objData.command == "UNLOAD")//同一任务号且处于下料阶段 + { + globalVar.agvArriveLineFour = true;//AGV到达下料位置 + } + #endregion + #region 线体到清洗台 + if (objData.robotJobId == LSevenrobotJobId && objData.command == "LOAD")//同一任务号且处于上料阶段,AGV请求上料 + { + globalVar.agvArriveLineOneLoadEmptyRoller = true;//AGV到达上料位置 } + if (objData.robotJobId == LSevenrobotJobId && objData.command == "UNLOAD")//同一任务号且处于下料阶段 + { + globalVar.agvArriveCleanUnLoad = true;//AGV到达下料位置 + + } + + if (objData.robotJobId == LEightrobotJobId && objData.command == "LOAD") + { + globalVar.agvArriveLineTwoLoadEmptyRoller = true;//AGV到达上料位置 + + } + if (objData.robotJobId == LEightrobotJobId && objData.command == "UNLOAD")//同一任务号且处于下料阶段 + { + globalVar.agvArriveCleanUnLoad = true;//AGV到达下料位置 + + } + + if (objData.robotJobId == LSixrobotJobId && objData.command == "LOAD") + { + globalVar.agvArriveLineThreeLoadEmptyRoller = true;//AGV到达上料位置 + + } + if (objData.robotJobId == LSixrobotJobId && objData.command == "UNLOAD")//同一任务号且处于下料阶段 + { + globalVar.agvArriveCleanUnLoad = true;//AGV到达下料位置 + } + #endregion + + if (objData.robotJobId == LTenrobotJobId && objData.command == "LOAD") + { + globalVar.agvArriveCleanLoad = true;//agv到达清洗台下料位置 + } + if (objData.robotJobId == LTenrobotJobId && objData.command == "UNLOAD") + { + globalVar.agvArriveLineFour = true;//agv到达清洗台下料位置 + } } } @@ -551,24 +737,40 @@ namespace FryPot_DosingSystem.Control { #region 线体上下料任务信息回报 //线体1任务上报 - if (objData.state == "ROLLER_LOAD_DOING" && objData.robotJobId == LOnerobotJobId && objData.jobData.startPointCode == "")// AGV正在上料,指线体上料 + if (objData.state == "ROLLER_LOAD_DOING" && objData.robotJobId == LOnerobotJobId && objData.jobData.startPointCode == "" && objData.jobData.targetPointCode == "")// AGV正在上料,指线体上料 { } //线体2任务上报 - if (objData.state == "ROLLER_LOAD_DOING" && objData.robotJobId == LTworobotJobId && objData.jobData.startPointCode == "")// AGV正在上料,指线体上料 + if (objData.state == "ROLLER_LOAD_DOING" && objData.robotJobId == LTworobotJobId && objData.jobData.startPointCode == "" && objData.jobData.targetPointCode == "")// AGV正在上料,指线体上料 { //日志 } //线体3任务上报 - if (objData.state == "ROLLER_LOAD_DOING" && objData.robotJobId == LThreerobotJobId && objData.jobData.startPointCode == "")// AGV正在上料,指线体上料 + if (objData.state == "ROLLER_LOAD_DOING" && objData.robotJobId == LThreerobotJobId && objData.jobData.startPointCode == "" && objData.jobData.targetPointCode == "")// AGV正在上料,指线体上料 { //日志 } - + //---------------------空桶从线体去清洗-------------------------------// + //线体1任务上报 + if (objData.state == "ROLLER_LOAD_DOING" && objData.robotJobId == LOnerobotJobId && objData.jobData.startPointCode == "" && objData.jobData.targetPointCode == "")// AGV正在上料,指线体空桶上料 + { + // globalVar.rollerLineOne.IsEpmtyBefore = false; + } + //线体2任务上报 + if (objData.state == "ROLLER_LOAD_DOING" && objData.robotJobId == LTworobotJobId && objData.jobData.startPointCode == "" && objData.jobData.targetPointCode == "")// AGV正在上料,指线体空桶上料 + { + // globalVar.rollerLineTwo.IsEpmtyBefore = false; + } + //线体3任务上报 + if (objData.state == "ROLLER_LOAD_DOING" && objData.robotJobId == LThreerobotJobId && objData.jobData.startPointCode == "" && objData.jobData.targetPointCode == "")// AGV正在上料,指线体空桶上料 + { + // globalVar.rollerLineThree.IsEpmtyBefore = false; + } //线体1任务上报 - if (objData.state == "ROLLER_LOAD_FINISH" && objData.robotJobId == LOnerobotJobId && objData.jobData.startPointCode == "")//指定上料点上料完成,这里指线体上料 + if (objData.state == "ROLLER_LOAD_FINISH" && objData.robotJobId == LOnerobotJobId && objData.jobData.startPointCode == "" && objData.jobData.targetPointCode == "")//指定上料点上料完成,这里指线体上料 { + AgvViewModel.GetInstance().Set滚筒线上数量(1, (globalVar.LOneMaterialNum - 1).ToString()); AgvViewModel.GetInstance().Set小车是否承载物品(1, IsBool.Yes); if (globalVar.LOneFryPotSerial == 1) @@ -579,11 +781,12 @@ namespace FryPot_DosingSystem.Control { AgvViewModel.GetInstance().Set小车运动(1, CartMotionTrajectory.yc_1_4); } - } + //线体2任务上报 - if (objData.state == "ROLLER_LOAD_FINISH" && objData.robotJobId == LTworobotJobId && objData.jobData.startPointCode == "")//指定上料点上料完成,这里指线体上料 + if (objData.state == "ROLLER_LOAD_FINISH" && objData.robotJobId == LTworobotJobId && objData.jobData.startPointCode == "" && objData.jobData.targetPointCode == "")//指定上料点上料完成,这里指线体上料 { + AgvViewModel.GetInstance().Set滚筒线上数量(2, (globalVar.LTwoMaterialNum - 1).ToString()); AgvViewModel.GetInstance().Set小车是否承载物品(2, IsBool.Yes); if (globalVar.LTwoFryPotSerial == 2) @@ -594,14 +797,41 @@ namespace FryPot_DosingSystem.Control { AgvViewModel.GetInstance().Set小车运动(2, CartMotionTrajectory.yc_2_5); } + } //线体3任务上报 - if (objData.state == "ROLLER_LOAD_FINISH" && objData.robotJobId == LThreerobotJobId && objData.jobData.startPointCode == "")//指定上料点上料完成,这里指线体上料 + if (objData.state == "ROLLER_LOAD_FINISH" && objData.robotJobId == LThreerobotJobId && objData.jobData.startPointCode == "" && objData.jobData.targetPointCode == "")//指定上料点上料完成,这里指线体上料 { + AgvViewModel.GetInstance().Set滚筒线上数量(3, (globalVar.LThreeMaterialNum - 1).ToString()); AgvViewModel.GetInstance().Set小车是否承载物品(3, IsBool.Yes); AgvViewModel.GetInstance().Set小车运动(3, CartMotionTrajectory.yc_3_3); + } + + //线体1任务上报 + if (objData.state == "ROLLER_LOAD_FINISH" && objData.robotJobId == LSevenrobotJobId && objData.jobData.startPointCode == "" && objData.jobData.targetPointCode == "")//指定上料点上料完成,这里指线体1空桶上料 + { + AgvViewModel.GetInstance().Set滚筒线上数量(1, (globalVar.LOneMaterialNum - 1).ToString()); + AgvViewModel.GetInstance().Set小车是否承载物品(4, IsBool.OnllYes); + //到清洗处 + } + //线体2任务上报 + if (objData.state == "ROLLER_LOAD_FINISH" && objData.robotJobId == LEightrobotJobId && objData.jobData.startPointCode == "" && objData.jobData.targetPointCode == "")//指定上料点上料完成,这里指线体2空桶上料 + { + AgvViewModel.GetInstance().Set滚筒线上数量(2, (globalVar.LTwoMaterialNum - 1).ToString()); + AgvViewModel.GetInstance().Set小车是否承载物品(4, IsBool.OnllYes); + + //到清洗处 + + } + //线体3任务上报 + if (objData.state == "ROLLER_LOAD_FINISH" && objData.robotJobId == LThreerobotJobId && objData.jobData.startPointCode == "" && objData.jobData.targetPointCode == "")//指定上料点上料完成,这里指线体3空桶上料 + { + AgvViewModel.GetInstance().Set滚筒线上数量(3, (globalVar.LThreeMaterialNum - 1).ToString()); + AgvViewModel.GetInstance().Set小车是否承载物品(4, IsBool.OnllYes); + //到清洗处 + } //线体1任务上报 if (objData.state == "ROLLER_UNLOAD_DOING" && objData.robotJobId == LOnerobotJobId && objData.jobData.targetPointCode == "")//指定下料点正在下料,指线体下料 @@ -637,23 +867,23 @@ namespace FryPot_DosingSystem.Control #region 空桶上下料任务信息回报 //线体1任务上报 - if (objData.state == "ROLLER_LOAD_DOING" && objData.robotJobId == LOnerobotJobId && objData.jobData.startPointCode == "")// AGV正在上料,指空桶上料 + if (objData.state == "ROLLER_LOAD_DOING" && objData.robotJobId == LOnerobotJobId && objData.jobData.startPointCode == "")// AGV正在上料,指炒锅空桶上料 { //日志 } //线体2任务上报 - if (objData.state == "ROLLER_LOAD_DOING" && objData.robotJobId == LTworobotJobId && objData.jobData.startPointCode == "")// AGV正在上料,指空桶上料 + if (objData.state == "ROLLER_LOAD_DOING" && objData.robotJobId == LTworobotJobId && objData.jobData.startPointCode == "")// AGV正在上料,指炒锅空桶上料 { //日志 } //线体3任务上报 - if (objData.state == "ROLLER_LOAD_DOING" && objData.robotJobId == LThreerobotJobId && objData.jobData.startPointCode == "")// AGV正在上料,指空桶上料 + if (objData.state == "ROLLER_LOAD_DOING" && objData.robotJobId == LThreerobotJobId && objData.jobData.startPointCode == "")// AGV正在上料,指炒锅空桶上料 { //日志 } //线体1任务上报 - if (objData.state == "ROLLER_LOAD_FINISH" && objData.robotJobId == LOnerobotJobId && objData.jobData.startPointCode == "")//指定上料点上料完成,这里指空桶上料 + if (objData.state == "ROLLER_LOAD_FINISH" && objData.robotJobId == LFourrobotJobId && objData.jobData.startPointCode == "")//指定上料点上料完成,这里指炒锅空桶上料 { globalVar.agvFryPotEmptyRollerArrive = true; AgvViewModel.GetInstance().Set小车是否承载物品(1, IsBool.OnllYes); @@ -667,7 +897,7 @@ namespace FryPot_DosingSystem.Control } } //线体2任务上报 - if (objData.state == "ROLLER_LOAD_FINISH" && objData.robotJobId == LTworobotJobId && objData.jobData.startPointCode == "")//指定上料点上料完成,这里指空桶上料 + if (objData.state == "ROLLER_LOAD_FINISH" && objData.robotJobId == LFiverobotJobId && objData.jobData.startPointCode == "")//指定上料点上料完成,这里指炒锅空桶上料 { globalVar.LTwoagvFryPotEmptyRollerArrive = true; AgvViewModel.GetInstance().Set小车是否承载物品(2, IsBool.OnllYes); @@ -681,16 +911,18 @@ namespace FryPot_DosingSystem.Control } } //线体3任务上报 - if (objData.state == "ROLLER_LOAD_FINISH" && objData.robotJobId == LThreerobotJobId && objData.jobData.startPointCode == "")//指定上料点上料完成,这里指空桶上料 + if (objData.state == "ROLLER_LOAD_FINISH" && objData.robotJobId == LSixrobotJobId && objData.jobData.startPointCode == "")//指定上料点上料完成,这里指炒锅空桶上料 { globalVar.LThreeagvFryPotEmptyRollerArrive = true; AgvViewModel.GetInstance().Set小车是否承载物品(3, IsBool.OnllYes); AgvViewModel.GetInstance().Set小车运动(3, CartMotionTrajectory.hs_3); } + + //线体1任务上报 - if (objData.state == "ROLLER_UNLOAD_DOING" && objData.robotJobId == LOnerobotJobId && objData.jobData.targetPointCode == "")//指定下料点正在下料,指空桶下料 + if (objData.state == "ROLLER_UNLOAD_DOING" && objData.robotJobId == LFourrobotJobId && objData.jobData.targetPointCode == "")//指定下料点正在下料,指炒锅空桶下料 { - AgvViewModel.GetInstance().Set滚筒线状态(1, IsRun.Start); + AgvViewModel.GetInstance().Set滚筒线状态(4, IsRun.Start); AgvViewModel.GetInstance().Set小车是否承载物品(1, IsBool.No); if (globalVar.LFourRollerNum >= 8) { @@ -702,9 +934,9 @@ namespace FryPot_DosingSystem.Control } } //线体2任务上报 - if (objData.state == "ROLLER_UNLOAD_DOING" && objData.robotJobId == LTworobotJobId && objData.jobData.targetPointCode == "")//指定下料点正在下料,指空桶下料 + if (objData.state == "ROLLER_UNLOAD_DOING" && objData.robotJobId == LFiverobotJobId && objData.jobData.targetPointCode == "")//指定下料点正在下料,指炒锅空桶下料 { - AgvViewModel.GetInstance().Set滚筒线状态(2, IsRun.Start); + AgvViewModel.GetInstance().Set滚筒线状态(4, IsRun.Start); AgvViewModel.GetInstance().Set小车是否承载物品(2, IsBool.No); if (globalVar.LFourRollerNum >= 8) { @@ -716,9 +948,9 @@ namespace FryPot_DosingSystem.Control } } //线体3任务上报 - if (objData.state == "ROLLER_UNLOAD_DOING" && objData.robotJobId == LThreerobotJobId && objData.jobData.targetPointCode == "")//指定下料点正在下料,指空桶下料 + if (objData.state == "ROLLER_UNLOAD_DOING" && objData.robotJobId == LSixrobotJobId && objData.jobData.targetPointCode == "")//指定下料点正在下料,指炒锅空桶下料 { - AgvViewModel.GetInstance().Set滚筒线状态(3, IsRun.Start); + AgvViewModel.GetInstance().Set滚筒线状态(4, IsRun.Start); AgvViewModel.GetInstance().Set小车是否承载物品(3, IsBool.No); if (globalVar.LFourRollerNum >= 8) { @@ -730,29 +962,77 @@ namespace FryPot_DosingSystem.Control } } //线体1任务上报 - if (objData.state == "DONE" && objData.robotJobId == LOnerobotJobId && objData.jobData.targetPointCode == "")//指定下料位置下料完成,指空桶下料 + if (objData.state == "DONE" && objData.robotJobId == LFourrobotJobId && objData.jobData.startPointCode == "" && objData.jobData.targetPointCode == "")//指定下料位置下料完成,指炒锅空桶下料 { - globalVar.EmptyRollerUnLoadcCom = true; + // globalVar.EmptyRollerUnLoadcCom = true; AgvViewModel.GetInstance().Set小车运动(1, AgvViewModel.GetInstance().GetCommandValue("hj")); AgvViewModel.GetInstance().Set小车停止(1); AgvViewModel.GetInstance().Set停车桩(1, IsBool.Yes); + } //线体2任务上报 - if (objData.state == "DONE" && objData.robotJobId == LTworobotJobId && objData.jobData.targetPointCode == "")//指定下料位置下料完成,指空桶下料 + if (objData.state == "DONE" && objData.robotJobId == LFiverobotJobId && objData.jobData.startPointCode == "" && objData.jobData.targetPointCode == "")//指定下料位置下料完成,指炒锅空桶下料 { - globalVar.LTwoEmptyRollerUnLoadcCom = true; + // globalVar.EmptyRollerUnLoadcCom = true; AgvViewModel.GetInstance().Set小车运动(2, AgvViewModel.GetInstance().GetCommandValue("hj")); AgvViewModel.GetInstance().Set小车停止(2); AgvViewModel.GetInstance().Set停车桩(2, IsBool.Yes); } //线体3任务上报 - if (objData.state == "DONE" && objData.robotJobId == LThreerobotJobId && objData.jobData.targetPointCode == "")//指定下料位置下料完成,指空桶下料 + if (objData.state == "DONE" && objData.robotJobId == LSixrobotJobId && objData.jobData.startPointCode == "" && objData.jobData.targetPointCode == "")//指定下料位置下料完成,指炒锅空桶下料 { - globalVar.LThreeEmptyRollerUnLoadcCom = true; + // globalVar.EmptyRollerUnLoadcCom = true; AgvViewModel.GetInstance().Set小车运动(3, AgvViewModel.GetInstance().GetCommandValue("hj")); AgvViewModel.GetInstance().Set小车停止(3); AgvViewModel.GetInstance().Set停车桩(3, IsBool.Yes); } + + if (objData.state == "DONE" && objData.robotJobId == LSevenrobotJobId && objData.jobData.startPointCode == "" && objData.jobData.targetPointCode == "")//指定下料位置下料完成,指从线体1到清戏台空桶下料 + { + AgvViewModel.GetInstance().Set小车运动(4, AgvViewModel.GetInstance().GetCommandValue("hj")); + AgvViewModel.GetInstance().Set小车停止(4); + AgvViewModel.GetInstance().Set停车桩(4, IsBool.Yes); + } + if (objData.state == "DONE" && objData.robotJobId == LEightrobotJobId && objData.jobData.startPointCode == "" && objData.jobData.targetPointCode == "")//指定下料位置下料完成,指从线体2到清戏台空桶下料 + { + AgvViewModel.GetInstance().Set小车运动(4, AgvViewModel.GetInstance().GetCommandValue("hj")); + AgvViewModel.GetInstance().Set小车停止(4); + AgvViewModel.GetInstance().Set停车桩(4, IsBool.Yes); + } + if (objData.state == "DONE" && objData.robotJobId == LNinerobotJobId && objData.jobData.startPointCode == "" && objData.jobData.targetPointCode == "")//指定下料位置下料完成,指从线体3到清戏台空桶下料 + { + AgvViewModel.GetInstance().Set小车运动(4, AgvViewModel.GetInstance().GetCommandValue("hj")); + AgvViewModel.GetInstance().Set小车停止(4); + AgvViewModel.GetInstance().Set停车桩(4, IsBool.Yes); + } + if (objData.state == "ROLLER_LOAD_FINISH" && objData.robotJobId == LTenrobotJobId && objData.jobData.startPointCode == "" && objData.jobData.targetPointCode == "")//指定上料位置上料完成,指清戏台空桶到上料 + { + AgvViewModel.GetInstance().Set小车是否承载物品(4, IsBool.OnllYes); + AgvViewModel.GetInstance().Set小车运动(4, CartMotionTrajectory.hs_4);//去四号空桶线 + + } + if (objData.state == "ROLLER_UNLOAD_DOING" && objData.robotJobId == LTenrobotJobId && objData.jobData.targetPointCode == "")//指定下料点正在下料,指清洗台空桶到线体4下料 + { + AgvViewModel.GetInstance().Set滚筒线状态(4, IsRun.Start); + AgvViewModel.GetInstance().Set小车是否承载物品(4, IsBool.No); + if (globalVar.LFourRollerNum >= 8) + { + AgvViewModel.GetInstance().Set滚筒线上数量(4, "8"); + } + else + { + AgvViewModel.GetInstance().Set滚筒线上数量(4, (globalVar.LFourRollerNum + 1).ToString()); + } + } + + if (objData.state == "DONE" && objData.robotJobId == LTenrobotJobId && objData.jobData.startPointCode == "" && objData.jobData.targetPointCode == "")//指定下料位置下料完成,指清戏台空桶到线体4下料 + { + AgvViewModel.GetInstance().Set小车运动(4, AgvViewModel.GetInstance().GetCommandValue("hj")); + AgvViewModel.GetInstance().Set小车停止(4); + AgvViewModel.GetInstance().Set停车桩(4, IsBool.Yes); + + } + #endregion @@ -773,9 +1053,9 @@ namespace FryPot_DosingSystem.Control ThreadManage.GetInstance().StopTask("MainViewReadPlcData", new Action(() => { - //ActionManage.GetInstance.CancelRegister("RecipeSetDown"); - //ActionManage.GetInstance.Register(new Action(RecipeDataParse), "RecipeSetDown"); - // ActionManage.GetInstance.Send("ClearRecipes"); + //ActionManage.GetInstance.CancelRegister("RecipeSetDown"); + //ActionManage.GetInstance.Register(new Action(RecipeDataParse), "RecipeSetDown"); + // ActionManage.GetInstance.Send("ClearRecipes"); ThreadManage.GetInstance().StopTask("滚筒线1任务线程", new Action(() => { ThreadManage.GetInstance().StopTask("滚筒线2任务线程", new Action(() => @@ -935,9 +1215,9 @@ namespace FryPot_DosingSystem.Control globalVar.rollerLineOne.OutMaterialingSingle = data[3]; globalVar.rollerLineTwo.OutMaterialingSingle = data[4]; globalVar.rollerLineThree.OutMaterialingSingle = data[5]; - //globalVar.rollerLineOne.OutMaterialingTroubleSingle = data[6]; - //globalVar.rollerLineTwo.OutMaterialingTroubleSingle = data[7]; - //globalVar.rollerLineThree.OutMaterialingTroubleSingle = data[8]; + //globalVar.rollerLineOne.OutMaterialingTroubleSingle = data[6]; + //globalVar.rollerLineTwo.OutMaterialingTroubleSingle = data[7]; + //globalVar.rollerLineThree.OutMaterialingTroubleSingle = data[8]; AlarmHelper.Alarm.LOneRollerTrouble = data[6]; AlarmHelper.Alarm.LTwoRollerTrouble = data[7]; AlarmHelper.Alarm.LThreeRollerTrouble = data[8]; @@ -977,11 +1257,11 @@ namespace FryPot_DosingSystem.Control })); GetAddressData("D2070", new Action((data) => { - //globalVar.fryPotOne.RollerTroubleSingle = data[0]; - //globalVar.fryPotTwo.RollerTroubleSingle = data[1]; - //globalVar.fryPotThree.RollerTroubleSingle = data[2]; - //globalVar.fryPotFour.RollerTroubleSingle = data[3]; - //globalVar.fryPotFive.RollerTroubleSingle = data[4]; + //globalVar.fryPotOne.RollerTroubleSingle = data[0]; + //globalVar.fryPotTwo.RollerTroubleSingle = data[1]; + //globalVar.fryPotThree.RollerTroubleSingle = data[2]; + //globalVar.fryPotFour.RollerTroubleSingle = data[3]; + //globalVar.fryPotFive.RollerTroubleSingle = data[4]; AlarmHelper.Alarm.FryPotOneRollerTrouble = data[0]; AlarmHelper.Alarm.FryPotTwoRollerTrouble = data[1]; AlarmHelper.Alarm.FryPotThreeRollerTrouble = data[2]; @@ -1004,6 +1284,45 @@ namespace FryPot_DosingSystem.Control globalVar.CleadBarrelExitSingle = data[0]; })); + //炒锅1状态数据 + GetFryOneData("D2001", new Action(data => + { + + })); + //炒锅2状态数据 + GetFryTwoData("D2001", new Action(data => + { + + })); + //炒锅3状态数据 + GetFryThreeData("D2001", new Action(data => + { + + })); + //炒锅4状态数据 + GetFryFourData("D2001", new Action(data => + { + + })); + //炒锅5状态数据 + GetFryFiveData("D2001", new Action(data => + { + + })); + //线体上放空桶 + if (globalVar.rollerLineOne.EmptyRollerConfirmSingle == 1 && globalVar.rollerLineOne.EmptyRollerNum != 0) + { + globalVar.rollerLineOne.EmptyRollerNums.Add(globalVar.rollerLineOne.EmptyRollerNum); + } + if (globalVar.rollerLineTwo.EmptyRollerConfirmSingle == 1 && globalVar.rollerLineTwo.EmptyRollerNum != 0) + { + globalVar.rollerLineTwo.EmptyRollerNums.Add(globalVar.rollerLineTwo.EmptyRollerNum); + } + if (globalVar.rollerLineThree.EmptyRollerConfirmSingle == 1 && globalVar.rollerLineThree.EmptyRollerNum != 0) + { + globalVar.rollerLineThree.EmptyRollerNums.Add(globalVar.rollerLineThree.EmptyRollerNum); + } + //炒锅状态数据 if (globalVar.fryPotOne.OilConfirm == 1) { FryPotMonitorManage.GetInstance.fryOne.OilCapacity = globalVar.fryPotOne.OilCapacity; @@ -1029,7 +1348,7 @@ namespace FryPot_DosingSystem.Control FryPotMonitorManage.GetInstance.fryFive.OilCapacity = globalVar.fryPotFive.OilCapacity; FryPotMonitorManage.GetInstance.fryFive.TotalOilCapactiy += globalVar.fryPotFive.OilCapacity; } - //炒锅状态实时显示 + //炒锅状态实时显示 FryPotStatusDisplay(); RollerLineStatusDisplay(); Thread.Sleep(10); @@ -1361,7 +1680,7 @@ namespace FryPot_DosingSystem.Control } /// - /// 返回指定地址指定长度的数据 + /// 返回滚筒线PLC指定地址指定长度的数据 /// /// /// @@ -1373,6 +1692,46 @@ namespace FryPot_DosingSystem.Control action((ushort[])(PlcReadData[address])); } } + public void GetFryOneData(string address, Action action) + { + FryOneData = DeviceOperate.GetInstance.GetFryOneData(); + if (FryOneData.ContainsKey(address)) + { + action((ushort[])(FryOneData[address])); + } + } + public void GetFryTwoData(string address, Action action) + { + FryTwoData = DeviceOperate.GetInstance.GetFryTwoData(); + if (FryTwoData.ContainsKey(address)) + { + action((ushort[])(FryTwoData[address])); + } + } + public void GetFryThreeData(string address, Action action) + { + FryThreeData = DeviceOperate.GetInstance.GetFryThreeData(); + if (FryThreeData.ContainsKey(address)) + { + action((ushort[])(FryThreeData[address])); + } + } + public void GetFryFourData(string address, Action action) + { + FryFourData = DeviceOperate.GetInstance.GetFryFourData(); + if (FryFourData.ContainsKey(address)) + { + action((ushort[])(FryFourData[address])); + } + } + public void GetFryFiveData(string address, Action action) + { + FryFiveData = DeviceOperate.GetInstance.GetFryFiveData(); + if (FryFiveData.ContainsKey(address)) + { + action((ushort[])(FryFiveData[address])); + } + } /// /// 写Plc数据 /// @@ -1448,9 +1807,12 @@ namespace FryPot_DosingSystem.Control ThreadManage.GetInstance().StartLong(new Action(() => { LineOneProcessExecute(); Thread.Sleep(10); }), "滚筒线1任务线程"); ThreadManage.GetInstance().StartLong(new Action(() => { LineTwoProcessExecute(); Thread.Sleep(10); }), "滚筒线2任务线程"); ThreadManage.GetInstance().StartLong(new Action(() => { LineThreeProcessExecute(); Thread.Sleep(10); }), "滚筒线3任务线程"); - + ThreadManage.GetInstance().StartLong(new Action(() => { LineFourProcessExecute(); Thread.Sleep(10); }), "清洗台任务线程"); } + + + /// /// 线体1的执行流程 /// @@ -1505,37 +1867,173 @@ namespace FryPot_DosingSystem.Control //} } + private void LineFourProcessExecute() + { + AgvFromLineToCleanPlate(); + CleanPlateUpLoad(); + EmptyRollerToLinFour(); + CallAgvToLineFour(); + AgvArriveCleanPlate(); + } + + private void CleanPlateUpLoad() + { + if (globalVar.agvArriveCleanLoad) + { + globalVar.agvArriveCleanLoad = false; + MessageLog.GetInstance.ShowRunLog("清洗台空桶装载完成"); + } + } /// - /// 3号滚筒线数据下发 2022/7/4 新增 + /// 线体到清洗台 /// - /// - private void LThreeRecipeDataToPlc() + private void AgvFromLineToCleanPlate() { - if (LThreeOutputMaterialQuene.Count == 0 && LThreeInputMaterialQuene.Count == 0 && !LThreeErrorRecipe) + if (AlarmHelper.Alarm.LOneRollerTrouble == 0)//输送线无故障 { - if (globalVar.LThreeCurrentRecipeName != string.Empty) + //线体1到清洗台 + if (!globalVar.rollerLineOne.IsEpmtyBefore) { - MessageLog.GetInstance.ShowUserLog($"【3】号滚筒线【{globalVar.LThreeCurrentRecipeName}】 配方制作完成"); - if (globalVar.LThreeFryPotSerial == 3) + var res = InputMaterialQuene.FirstOrDefault(p => p.materialType.MaterialLoc == globalVar.rollerLineOne.StationEight); + if (res == null && globalVar.rollerLineOne.StationEight != 0 && globalVar.rollerLineOne.EmptyRollerNums.Count > 0 && globalVar.rollerLineOne.StationEight == globalVar.rollerLineOne.EmptyRollerNums.ElementAt(0))//工位8上面有桶且不是配方上的原料桶且工位8的桶号和plc上报的桶号一致,即空桶 { - FryPotMonitorManage.GetInstance.fryThree.TotalProduct++; - using (StreamWriter txtWriter = new StreamWriter("AccessFile//" + "Statistic//" + "FryThree.txt", false, Encoding.UTF8)) - { - txtWriter.WriteLine(DateTime.Now.ToShortDateString()); - txtWriter.WriteLine(FryPotMonitorManage.GetInstance.fryThree.TotalProduct + "/" + FryPotMonitorManage.GetInstance.fryThree.TotalOilCapactiy);//炒锅1产量以及总油量记录 - } - //Sqlite.GetInstance.Base.Add(new PotThreeStatus { Temperature = FryPotMonitorManage.GetInstance.fryThree.Temperature, HotPower = FryPotMonitorManage.GetInstance.fryThree.HotPower, Speed = FryPotMonitorManage.GetInstance.fryThree.Speed, FryPotWeight = FryPotMonitorManage.GetInstance.fryThree.FryPotWeight, OilCapacity = FryPotMonitorManage.GetInstance.fryThree.OilCapacity, TotalOilCapactiy = FryPotMonitorManage.GetInstance.fryThree.TotalOilCapactiy, TotalProduct = FryPotMonitorManage.GetInstance.fryThree.TotalProduct, Time = DateTime.Now.ToShortDateString() });//向表中新增数据 - //Sqlite.GetInstance.Save();//保存数据 + //下发AGV去空桶线洗桶任务 + e: string id = Guid.NewGuid().ToString("N"); + if (id == LOnerobotJobId || id == LTworobotJobId || id == LThreerobotJobId || id == LFourrobotJobId || id == LFiverobotJobId || id == LSixrobotJobId || id == LSevenrobotJobId || id == LEightrobotJobId || id == LNinerobotJobId || id == LTenrobotJobId) + goto e; + + string info = AGVHelper.GetInstance.AgvLeaveLOneToClean(id);//1号线到洗桶处 + LFourrobotJobId = id; + Thread.Sleep(500); + LineToCleanCarryTaskErrorCodeAnalysis(info, 1); + globalVar.rollerLineOne.IsEpmtyBefore = true; + AgvFromLineOneToClean(globalVar.rollerLineOne.EmptyRollerNums.ElementAt(0));//AGV从线体1到清洗处 } - globalVar.LThreeCurrentRecipeName = string.Empty; - Task.Run(() => { Thread.Sleep(1500); fryThreeRecipe = string.Empty; }); + } + else + { + AgvFromLineOneToClean(globalVar.rollerLineOne.EmptyRollerNums.ElementAt(0));//AGV从线体1到清洗处 } } - if (LThreeRecipeQuene.Count > 0 && LThreeOutputMaterialQuene.Count == 0 && LThreeInputMaterialQuene.Count == 0)//后续添加其它限制条件 + // 线体2到清洗台 + if (AlarmHelper.Alarm.LTwoRollerTrouble == 0)//输送线无故障 { - Application.Current.Dispatcher.Invoke(new Action(() => { AgvViewModel.GetInstance().wokModel_3.goodsName = string.Empty; })); - Application.Current.Dispatcher.Invoke(new Action(() => { AgvViewModel.GetInstance().wokModel_3.workflows = new ObservableCollection(); })); + if (!globalVar.rollerLineTwo.IsEpmtyBefore) + { + var res = LTwoInputMaterialQuene.FirstOrDefault(p => p.materialType.MaterialLoc == globalVar.rollerLineTwo.StationEight); + if (res == null && globalVar.rollerLineTwo.StationEight != 0 && globalVar.rollerLineTwo.EmptyRollerNums.Count > 0 && globalVar.rollerLineTwo.StationEight == globalVar.rollerLineTwo.EmptyRollerNums.ElementAt(0))//工位8上面有桶且不是配方上的原料桶,即空桶 + { + //下发AGV去空桶线洗桶任务 + e: string id = Guid.NewGuid().ToString("N"); + if (id == LOnerobotJobId || id == LTworobotJobId || id == LThreerobotJobId || id == LFourrobotJobId || id == LFiverobotJobId || id == LSixrobotJobId || id == LSevenrobotJobId || id == LEightrobotJobId || id == LNinerobotJobId || id == LTenrobotJobId) + goto e; + + string info = AGVHelper.GetInstance.AgvLeaveLTwoToClean(id);//2号线到洗桶处 + LFiverobotJobId = id; + Thread.Sleep(500); + LineToCleanCarryTaskErrorCodeAnalysis(info, 2); + globalVar.rollerLineTwo.IsEpmtyBefore = true; + AgvFromLineTwoToClean(globalVar.rollerLineTwo.EmptyRollerNums.ElementAt(0));//AGV从线体2到清洗处 + } + } + else + { + AgvFromLineTwoToClean(globalVar.rollerLineTwo.EmptyRollerNums.ElementAt(0));//AGV从线体1到清洗处 + } + } + //线体3到清洗台 + if (AlarmHelper.Alarm.LThreeRollerTrouble == 0)//输送线无故障 + { + if (!globalVar.rollerLineThree.IsEpmtyBefore) + { + var res = LThreeInputMaterialQuene.FirstOrDefault(p => p.materialType.MaterialLoc == globalVar.rollerLineThree.StationEight); + if (res == null && globalVar.rollerLineThree.StationEight != 0 && globalVar.rollerLineThree.EmptyRollerNums.Count > 0 && globalVar.rollerLineThree.StationEight == globalVar.rollerLineThree.EmptyRollerNums.ElementAt(0))//工位8上面有桶且不是配方上的原料桶,即空桶 + { + //下发AGV去空桶线洗桶任务 + e: string id = Guid.NewGuid().ToString("N"); + if (id == LOnerobotJobId || id == LTworobotJobId || id == LThreerobotJobId || id == LFourrobotJobId || id == LFiverobotJobId || id == LSixrobotJobId || id == LSevenrobotJobId || id == LEightrobotJobId || id == LNinerobotJobId || id == LTenrobotJobId) + goto e; + + string info = AGVHelper.GetInstance.AgvLeaveLThreeToClean(id);//3号线到洗桶处 + LSixrobotJobId = id; + Thread.Sleep(500); + LineToCleanCarryTaskErrorCodeAnalysis(info, 3); + globalVar.rollerLineThree.IsEpmtyBefore = true; + AgvFromLineThreeToClean(globalVar.rollerLineThree.EmptyRollerNums.ElementAt(0));//AGV从线体3到清洗处 + } + } + else + { + AgvFromLineThreeToClean(globalVar.rollerLineThree.EmptyRollerNums.ElementAt(0));//AGV从线体3到清洗处 + } + } + } + + /// + /// AGV到达清洗台下料位置 + /// + private void AgvArriveCleanPlate() + { + if (globalVar.agvArriveCleanUnLoad) + { + globalVar.agvArriveCleanUnLoad = false; + MessageLog.GetInstance.ShowRunLog("空桶到达清洗位置,准备卸桶"); + MessageLog.GetInstance.ShowRunLog("卸桶完成"); + //plc交互 + } + } + + /// + /// 呼叫Agv从清洗台运洗好的空桶到四号线体 + /// + public void CallAgvToLineFour() + { + if (globalVar.CleanComplete == 1) + { + //是否需要手动给PLC置位?? + globalVar.CleanComplete = 0; + e: string id = Guid.NewGuid().ToString("N"); + if (id == LOnerobotJobId || id == LTworobotJobId || id == LThreerobotJobId || id == LFourrobotJobId || id == LFiverobotJobId || id == LSixrobotJobId || id == LSevenrobotJobId || id == LEightrobotJobId || id == LNinerobotJobId || id == LTenrobotJobId) + goto e; + + string info = AGVHelper.GetInstance.AgvFromCleanToLineFourUnLoadRoller(id); + LTenrobotJobId = id; + Thread.Sleep(500); + MessageLog.GetInstance.ShowRunLog("清洗台呼叫AGV取桶"); + CleanToLineCarryTaskErrorCodeAnalysis(info, 4); + } + } + /// + /// 3号滚筒线数据下发 2022/7/4 新增 + /// + /// + private void LThreeRecipeDataToPlc() + { + if (LThreeOutputMaterialQuene.Count == 0 && LThreeInputMaterialQuene.Count == 0 && !LThreeErrorRecipe) + { + if (globalVar.LThreeCurrentRecipeName != string.Empty) + { + MessageLog.GetInstance.ShowUserLog($"【3】号滚筒线【{globalVar.LThreeCurrentRecipeName}】 配方制作完成"); + if (globalVar.LThreeFryPotSerial == 3) + { + FryPotMonitorManage.GetInstance.fryThree.TotalProduct++; + using (StreamWriter txtWriter = new StreamWriter("AccessFile//" + "Statistic//" + "FryThree.txt", false, Encoding.UTF8)) + { + txtWriter.WriteLine(DateTime.Now.ToShortDateString()); + txtWriter.WriteLine(FryPotMonitorManage.GetInstance.fryThree.TotalProduct + "/" + FryPotMonitorManage.GetInstance.fryThree.TotalOilCapactiy);//炒锅1产量以及总油量记录 + } + //Sqlite.GetInstance.Base.Add(new PotThreeStatus { Temperature = FryPotMonitorManage.GetInstance.fryThree.Temperature, HotPower = FryPotMonitorManage.GetInstance.fryThree.HotPower, Speed = FryPotMonitorManage.GetInstance.fryThree.Speed, FryPotWeight = FryPotMonitorManage.GetInstance.fryThree.FryPotWeight, OilCapacity = FryPotMonitorManage.GetInstance.fryThree.OilCapacity, TotalOilCapactiy = FryPotMonitorManage.GetInstance.fryThree.TotalOilCapactiy, TotalProduct = FryPotMonitorManage.GetInstance.fryThree.TotalProduct, Time = DateTime.Now.ToShortDateString() });//向表中新增数据 + //Sqlite.GetInstance.Save();//保存数据 + } + globalVar.LThreeCurrentRecipeName = string.Empty; + Task.Run(() => { Thread.Sleep(1500); fryThreeRecipe = string.Empty; }); + } + } + if (LThreeRecipeQuene.Count > 0 && LThreeOutputMaterialQuene.Count == 0 && LThreeInputMaterialQuene.Count == 0)//后续添加其它限制条件 + { + Application.Current.Dispatcher.Invoke(new Action(() => { AgvViewModel.GetInstance().wokModel_3.goodsName = string.Empty; })); + Application.Current.Dispatcher.Invoke(new Action(() => { AgvViewModel.GetInstance().wokModel_3.workflows = new ObservableCollection(); })); AgvViewModel.GetInstance().Set启动或停止炒锅(3, IsRun.Stop); //if (globalVar.LThreeCurrentRecipeName != string.Empty) // MessageLog.GetInstance.ShowUserLog($"【3】号滚筒线【{globalVar.LThreeCurrentRecipeName}】 配方制作完成"); @@ -1572,7 +2070,7 @@ namespace FryPot_DosingSystem.Control } } DeviceOperate.GetInstance.WritePlcData("D1043", (ushort)result.materialCollection.Count);//发送3号滚筒线工序数据 - //AgvViewModel.GetInstance().Set启动或停止炒锅(globalVar.LThreeFryPotSerial, IsRun.Stop); + //AgvViewModel.GetInstance().Set启动或停止炒锅(globalVar.LThreeFryPotSerial, IsRun.Stop); } } @@ -1964,11 +2462,9 @@ namespace FryPot_DosingSystem.Control { Application.Current.Dispatcher.Invoke(new Action(() => { AgvViewModel.GetInstance().wokModel_1.workflows.Add(new WorkflowModel { id = globalVar.LOneCurrentCookingStep, Name = OutputMaterialQuene.ElementAt(0).materialType.MaterialName, isBool = IsBool.Yes }); })); - } else { - Application.Current.Dispatcher.Invoke(new Action(() => { AgvViewModel.GetInstance().wokModel_4.workflows.Add(new WorkflowModel { id = globalVar.LOneCurrentCookingStep, Name = OutputMaterialQuene.ElementAt(0).materialType.MaterialName, isBool = IsBool.Yes }); })); } AgvViewModel.GetInstance().Set小车是否承载物品(1, IsBool.No); @@ -2228,7 +2724,6 @@ namespace FryPot_DosingSystem.Control { if (LThreeOutputMaterialQuene.Count > 0 && globalVar.LThreeInOrOutputLock && globalVar.agvArriveLThreeUpLoad && globalVar.LThreePotOutputRollerArrive && !globalVar.LThreeAgvArrivePot) { - MessageLog.GetInstance.ShowRunLog($"AGV到达【{globalVar.LThreeFryPotSerial}】号炒锅空桶上料位置"); AgvArriveFryPotThreeOutEmptyRollerSingleSetDown();//暂时考虑agv送完料后原地等待,不加条件,直接发送到位信号 globalVar.agvArriveLThreeUpLoad = false; @@ -2269,58 +2764,48 @@ namespace FryPot_DosingSystem.Control } /// - /// 1号线体对应空桶清洗 + /// 4号线体下料 /// - public void LOneEmptyRollerToClean() + public void EmptyRollerToLinFour() { - if (globalVar.EmptyRollerUnLoadcCom)//agv在4号线体下料完成 + if (globalVar.agvArriveLineFour)//agv到达线体4下料位置 { - erp: string id = Guid.NewGuid().ToString("N");//上游唯一ID - if (id == LOnerobotJobId || id == LTworobotJobId || id == LThreerobotJobId || id == LFourrobotJobId) - { - goto erp; - } - string info = AGVHelper.GetInstance.AgvLeaveFryPotOne(id); - LOnerobotJobId = id; - FryCarryTaskErrorCodeAnalysis(info, 1); - globalVar.AllowAgvToLineLoadRoller = true; - globalVar.LoadRoller = false; - globalVar.AgvToFryPot = false; - globalVar.PotOneInputMaterialArrive = false; - globalVar.PotOneOutputRollerArrive = false; - globalVar.AgvArrivePot = false; - } - } - /// - /// 2号线体对应空桶清洗 - /// - public void LTwoEmptyRollerToClean() - { - if (globalVar.LTwoEmptyRollerUnLoadcCom)//agv在4号线体下料完成 - { - globalVar.AllowAgvToLineTwoLoadRoller = true; - globalVar.LTwoLoadRoller = false; - globalVar.LTwoAgvToFryPot = false; - globalVar.LTwoPotInputMaterialArrive = false; - globalVar.LTwoPotOutputRollerArrive = false; - globalVar.LTwoAgvArrivePot = false; - } - } - /// - /// 3号线体对应空桶清洗 - /// - public void LThreeEmptyRollerToClean() - { - if (globalVar.LThreeEmptyRollerUnLoadcCom)//agv在4号线体下料完成 - { - globalVar.AllowAgvToLineThreeLoadRoller = true; - globalVar.LThreeLoadRoller = false; - globalVar.LThreeAgvToFryPot = false; - globalVar.LThreePotInputMaterialArrive = false; - globalVar.LThreePotOutputRollerArrive = false; - globalVar.LThreeAgvArrivePot = false; + globalVar.agvArriveLineFour = false; + //线体四信号交互 + MessageLog.GetInstance.ShowRunLog("空桶到达空桶回收线体,准备卸桶"); + MessageLog.GetInstance.ShowRunLog("卸桶完成"); } } + ///// + ///// 2号线体对应空桶清洗 + ///// + //public void LTwoEmptyRollerToLineFour() + //{ + // if (globalVar.LTwoEmptyRollerUnLoadcCom)//agv在4号线体下料完成 + // { + // globalVar.AllowAgvToLineTwoLoadRoller = true; + // globalVar.LTwoLoadRoller = false; + // globalVar.LTwoAgvToFryPot = false; + // globalVar.LTwoPotInputMaterialArrive = false; + // globalVar.LTwoPotOutputRollerArrive = false; + // globalVar.LTwoAgvArrivePot = false; + // } + //} + ///// + ///// 3号线体对应空桶清洗 + ///// + //public void LThreeEmptyRollerToLinFour() + //{ + // if (globalVar.LThreeEmptyRollerUnLoadcCom)//agv在4号线体下料完成 + // { + // globalVar.AllowAgvToLineThreeLoadRoller = true; + // globalVar.LThreeLoadRoller = false; + // globalVar.LThreeAgvToFryPot = false; + // globalVar.LThreePotInputMaterialArrive = false; + // globalVar.LThreePotOutputRollerArrive = false; + // globalVar.LThreeAgvArrivePot = false; + // } + //} /// /// 炒锅滚筒进料运行到位处理 @@ -2603,60 +3088,60 @@ namespace FryPot_DosingSystem.Control { DeviceOperate.GetInstance.WritePlcData("D1062", 1);//agv到炒锅3送料就位信号 } - /// - /// AGV离开炒锅运送空桶任务 - /// - public void AgvFromFryPotToClean(ConcurrentQueue queue) - { - switch (queue.ElementAt(0).materialType.MaterialLoc / 100) - { - case 1: - erp: string id = Guid.NewGuid().ToString("N");//上游唯一ID - if (id == LOnerobotJobId || id == LTworobotJobId || id == LThreerobotJobId || id == LFourrobotJobId) - { - goto erp; - } - string info = AGVHelper.GetInstance.AgvLeaveFryPotOne(id); - LOnerobotJobId = id; - FryCarryTaskErrorCodeAnalysis(info, 1); break; - case 2: - erp1: string id1 = Guid.NewGuid().ToString("N");//上游唯一ID - if (id1 == LTworobotJobId) - { - goto erp1; - } - string info1 = AGVHelper.GetInstance.AgvLeaveFryPotTwo(id1); - LTworobotJobId = id1; - FryCarryTaskErrorCodeAnalysis(info1, 2); break; - case 3: - erp2: string id2 = Guid.NewGuid().ToString("N");//上游唯一ID - if (id2 == LThreerobotJobId) - { - goto erp2; - } - string info2 = AGVHelper.GetInstance.AgvLeaveFryPotThree(id2); - LThreerobotJobId = id2; - FryCarryTaskErrorCodeAnalysis(info2, 3); break; - case 4: - erp3: string id3 = Guid.NewGuid().ToString("N");//上游唯一ID - if (id3 == LOnerobotJobId) - { - goto erp3; - } - string info3 = AGVHelper.GetInstance.AgvLeaveFryPotFour(id3); - LOnerobotJobId = id3; - FryCarryTaskErrorCodeAnalysis(info3, 4); break; - case 5: - erp4: string id4 = Guid.NewGuid().ToString("N");//上游唯一ID - if (id4 == LTworobotJobId) - { - goto erp4; - } - string info4 = AGVHelper.GetInstance.AgvLeaveFryPotFive(id4); - LTworobotJobId = id4; - FryCarryTaskErrorCodeAnalysis(info4, 5); break; - } - } + ///// + ///// AGV离开炒锅运送空桶任务 + ///// + //public void AgvFromFryPotToClean(ConcurrentQueue queue) + //{ + // switch (queue.ElementAt(0).materialType.MaterialLoc / 100) + // { + // case 1: + // erp: string id = Guid.NewGuid().ToString("N");//上游唯一ID + // if (id == LOnerobotJobId || id == LTworobotJobId || id == LThreerobotJobId || id == LFourrobotJobId) + // { + // goto erp; + // } + // string info = AGVHelper.GetInstance.AgvLeaveFryPotOne(id); + // LOnerobotJobId = id; + // FryCarryTaskErrorCodeAnalysis(info, 1); break; + // case 2: + // erp1: string id1 = Guid.NewGuid().ToString("N");//上游唯一ID + // if (id1 == LTworobotJobId) + // { + // goto erp1; + // } + // string info1 = AGVHelper.GetInstance.AgvLeaveFryPotTwo(id1); + // LTworobotJobId = id1; + // FryCarryTaskErrorCodeAnalysis(info1, 2); break; + // case 3: + // erp2: string id2 = Guid.NewGuid().ToString("N");//上游唯一ID + // if (id2 == LThreerobotJobId) + // { + // goto erp2; + // } + // string info2 = AGVHelper.GetInstance.AgvLeaveFryPotThree(id2); + // LThreerobotJobId = id2; + // FryCarryTaskErrorCodeAnalysis(info2, 3); break; + // case 4: + // erp3: string id3 = Guid.NewGuid().ToString("N");//上游唯一ID + // if (id3 == LOnerobotJobId) + // { + // goto erp3; + // } + // string info3 = AGVHelper.GetInstance.AgvLeaveFryPotFour(id3); + // LOnerobotJobId = id3; + // FryCarryTaskErrorCodeAnalysis(info3, 4); break; + // case 5: + // erp4: string id4 = Guid.NewGuid().ToString("N");//上游唯一ID + // if (id4 == LTworobotJobId) + // { + // goto erp4; + // } + // string info4 = AGVHelper.GetInstance.AgvLeaveFryPotFive(id4); + // LTworobotJobId = id4; + // FryCarryTaskErrorCodeAnalysis(info4, 5); break; + // } + //} /// /// AGV离开炒锅1,4运送空桶任务 /// @@ -2666,23 +3151,23 @@ namespace FryPot_DosingSystem.Control { case 1: erp: string id = Guid.NewGuid().ToString("N");//上游唯一ID - if (id == LOnerobotJobId || id == LTworobotJobId || id == LThreerobotJobId || id == LFourrobotJobId) + if (id == LOnerobotJobId || id == LTworobotJobId || id == LThreerobotJobId || id == LFourrobotJobId || id == LFiverobotJobId || id == LSixrobotJobId || id == LSevenrobotJobId || id == LEightrobotJobId || id == LNinerobotJobId || id == LTenrobotJobId) { goto erp; } MessageLog.GetInstance.ShowRunLog("AGV执行【1】号炒锅空桶回收任务"); string info = AGVHelper.GetInstance.AgvLeaveFryPotOne(id); - LOnerobotJobId = id; + LFourrobotJobId = id; FryCarryTaskErrorCodeAnalysis(info, 1); break; case 4: erp3: string id3 = Guid.NewGuid().ToString("N");//上游唯一ID - if (id3 == LOnerobotJobId || id3 == LTworobotJobId || id3 == LThreerobotJobId || id3 == LFourrobotJobId) + if (id3 == LOnerobotJobId || id3 == LTworobotJobId || id3 == LThreerobotJobId || id3 == LFourrobotJobId || id3 == LFiverobotJobId || id3 == LSixrobotJobId || id3 == LSevenrobotJobId || id3 == LEightrobotJobId || id3 == LNinerobotJobId || id3 == LTenrobotJobId) { goto erp3; } MessageLog.GetInstance.ShowRunLog("AGV执行【4】号炒锅空桶回收任务"); string info3 = AGVHelper.GetInstance.AgvLeaveFryPotFour(id3); - LOnerobotJobId = id3; + LFourrobotJobId = id3; FryCarryTaskErrorCodeAnalysis(info3, 4); break; } } @@ -2695,23 +3180,23 @@ namespace FryPot_DosingSystem.Control { case 2: erp1: string id1 = Guid.NewGuid().ToString("N");//上游唯一ID - if (id1 == LOnerobotJobId || id1 == LTworobotJobId || id1 == LThreerobotJobId || id1 == LFourrobotJobId) + if (id1 == LOnerobotJobId || id1 == LTworobotJobId || id1 == LThreerobotJobId || id1 == LFourrobotJobId || id1 == LFiverobotJobId || id1 == LSixrobotJobId || id1 == LSevenrobotJobId || id1 == LEightrobotJobId || id1 == LNinerobotJobId || id1 == LTenrobotJobId) { goto erp1; } MessageLog.GetInstance.ShowRunLog("AGV执行【2】号炒锅空桶回收任务"); string info1 = AGVHelper.GetInstance.AgvLeaveFryPotTwo(id1); - LTworobotJobId = id1; + LFiverobotJobId = id1; FryCarryTaskErrorCodeAnalysis(info1, 2); break; case 5: erp4: string id4 = Guid.NewGuid().ToString("N");//上游唯一ID - if (id4 == LOnerobotJobId || id4 == LTworobotJobId || id4 == LThreerobotJobId || id4 == LFourrobotJobId) + if (id4 == LOnerobotJobId || id4 == LTworobotJobId || id4 == LThreerobotJobId || id4 == LFourrobotJobId || id4 == LFiverobotJobId || id4 == LSixrobotJobId || id4 == LSevenrobotJobId || id4 == LEightrobotJobId || id4 == LNinerobotJobId || id4 == LTenrobotJobId) { goto erp4; } MessageLog.GetInstance.ShowRunLog("AGV执行【5】号炒锅空桶回收任务"); string info4 = AGVHelper.GetInstance.AgvLeaveFryPotFive(id4); - LTworobotJobId = id4; + LFiverobotJobId = id4; FryCarryTaskErrorCodeAnalysis(info4, 5); break; } } @@ -2721,13 +3206,13 @@ namespace FryPot_DosingSystem.Control public void AgvFromFryPotThreeToClean() { erp2: string id2 = Guid.NewGuid().ToString("N");//上游唯一ID - if (id2 == LOnerobotJobId || id2 == LTworobotJobId || id2 == LThreerobotJobId || id2 == LFourrobotJobId) + if (id2 == LOnerobotJobId || id2 == LTworobotJobId || id2 == LThreerobotJobId || id2 == LFourrobotJobId || id2 == LFiverobotJobId || id2 == LSixrobotJobId || id2 == LSevenrobotJobId || id2 == LEightrobotJobId || id2 == LNinerobotJobId || id2 == LTenrobotJobId) { goto erp2; } MessageLog.GetInstance.ShowRunLog("AGV执行【3】号炒锅空桶回收任务"); string info2 = AGVHelper.GetInstance.AgvLeaveFryPotThree(id2); - LThreerobotJobId = id2; + LSixrobotJobId = id2; FryCarryTaskErrorCodeAnalysis(info2, 3); } /// @@ -2754,6 +3239,7 @@ namespace FryPot_DosingSystem.Control //原料到位,agv到位,agv自行运料到炒锅 } } + } else//有故障 { @@ -2769,6 +3255,40 @@ namespace FryPot_DosingSystem.Control } } /// + /// Agv从1号线体运空桶到清洗处 + /// + public void AgvFromLineOneToClean(ushort emptyRollerNum) + { + erp: if (AlarmHelper.Alarm.LOneRollerTrouble == 0)//无故障 + { + if (globalVar.agvArriveLineOneLoadEmptyRoller)//agv到达上料位置 + { + MessageLog.GetInstance.ShowRunLog("AGV到达【1】号滚筒线装桶位置"); + DeviceOperate.GetInstance.WritePlcData("D1052", 1);//agv到达线体1上料位置信号下发plc + MessageLog.GetInstance.ShowRunLog($"AGV正在装载{emptyRollerNum}号空料桶"); + AgvViewModel.GetInstance().Set滚筒线状态(1, IsRun.Start); + globalVar.LOneMaterialNum--; + globalVar.agvArriveLineOneLoadEmptyRoller = false; + globalVar.rollerLineOne.IsEpmtyBefore = false; + globalVar.rollerLineOne.EmptyRollerNums.RemoveAt(0); + //原料到位,agv到位,agv自行运料到清洗处 + } + } + else//有故障 + { + while (AlarmHelper.Alarm.LOneRollerTrouble == 1) + { + Thread.Sleep(5); + if (globalVar.ExitLineOneTask) + return; + } + MessageLog.GetInstance.ShowRunLog("线体【1】滚筒故障解除,继续运行"); + //lineAlarm = 1; + goto erp; + } + + } + /// /// 处理agv从线体2到送料到炒锅的条件 /// /// @@ -2809,6 +3329,40 @@ namespace FryPot_DosingSystem.Control } } /// + /// Agv从2号线体运空桶到清洗处 + /// + public void AgvFromLineTwoToClean(ushort emptyRollerNum) + { + erp: if (AlarmHelper.Alarm.LTwoRollerTrouble == 0)//无故障 + { + if (globalVar.agvArriveLineTwoLoadEmptyRoller)//agv到达上料位置 + { + MessageLog.GetInstance.ShowRunLog("AGV到达【2】号滚筒线装桶位置"); + DeviceOperate.GetInstance.WritePlcData("D1053", 1);//agv到达线体2上料位置信号下发plc + MessageLog.GetInstance.ShowRunLog($"AGV正在装载{emptyRollerNum}号空料桶"); + AgvViewModel.GetInstance().Set滚筒线状态(2, IsRun.Start); + globalVar.LTwoMaterialNum--; + globalVar.agvArriveLineTwoLoadEmptyRoller = false; + globalVar.rollerLineTwo.IsEpmtyBefore = false; + globalVar.rollerLineTwo.EmptyRollerNums.RemoveAt(0); + //原料到位,agv到位,agv自行运料到清洗处 + } + } + else//有故障 + { + while (AlarmHelper.Alarm.LTwoRollerTrouble == 1) + { + Thread.Sleep(5); + if (globalVar.ExitLineOneTask) + return; + } + MessageLog.GetInstance.ShowRunLog("线体【2】滚筒故障解除,继续运行"); + //lineAlarm = 1; + goto erp; + } + + } + /// /// 处理agv从线体3到送料到炒锅的条件 /// /// @@ -2849,7 +3403,41 @@ namespace FryPot_DosingSystem.Control } } /// - /// 线体搬运任务错误码分析 + /// Agv从3号线体运空桶到清洗处 + /// + public void AgvFromLineThreeToClean(ushort emptyRollerNum) + { + erp: if (AlarmHelper.Alarm.LThreeRollerTrouble == 0)//无故障 + { + if (globalVar.agvArriveLineThreeLoadEmptyRoller)//agv到达上料位置 + { + MessageLog.GetInstance.ShowRunLog("AGV到达【3】号滚筒线装桶位置"); + DeviceOperate.GetInstance.WritePlcData("D1054", 1);//agv到达线体3上料位置信号下发plc + MessageLog.GetInstance.ShowRunLog($"AGV正在装载{emptyRollerNum}号空料桶"); + AgvViewModel.GetInstance().Set滚筒线状态(3, IsRun.Start); + globalVar.LThreeMaterialNum--; + globalVar.agvArriveLineThreeLoadEmptyRoller = false; + globalVar.rollerLineThree.IsEpmtyBefore = false; + globalVar.rollerLineThree.EmptyRollerNums.RemoveAt(0); + //原料到位,agv到位,agv自行运料到清洗处 + } + } + else//有故障 + { + while (AlarmHelper.Alarm.LThreeRollerTrouble == 1) + { + Thread.Sleep(5); + if (globalVar.ExitLineOneTask) + return; + } + MessageLog.GetInstance.ShowRunLog("线体【3】滚筒故障解除,继续运行"); + //lineAlarm = 1; + goto erp; + } + + } + /// + /// 线体到炒锅搬运任务错误码分析 /// /// /// @@ -2873,6 +3461,52 @@ namespace FryPot_DosingSystem.Control } } /// + /// 线体到清洗台搬运任务错误码分析 + /// + /// + /// + public void LineToCleanCarryTaskErrorCodeAnalysis(string errorCode, int num) + { + if (errorCode == "SUCCESS") + { + AgvViewModel.GetInstance().Set停车桩(num, IsBool.No); + AgvViewModel.GetInstance().Set小车是否承载物品(num, IsBool.No); + AgvViewModel.GetInstance().Set小车运动(num, AgvViewModel.GetInstance().GetCommandValue($"qc_{num}")); + MessageLog.GetInstance.ShowRunLog($"AGV去{num}号滚筒线装桶"); + } + else if (errorCode == "Analysis Error") + { + MessageLog.GetInstance.ShowRunLog($"提示:AGV去{num}号滚筒线API调用失败,请检查请求报文"); + } + else + { + MessageLog.GetInstance.ShowRunLog($"提示:AGV去{num}号滚筒线失败,错误码:{errorCode}"); + } + } + /// + /// 清洗台到线体搬运任务错误码分析 + /// + /// + /// + public void CleanToLineCarryTaskErrorCodeAnalysis(string errorCode, int num) + { + if (errorCode == "SUCCESS") + { + AgvViewModel.GetInstance().Set停车桩(num, IsBool.No); + AgvViewModel.GetInstance().Set小车是否承载物品(num, IsBool.No); + AgvViewModel.GetInstance().Set小车运动(num, AgvViewModel.GetInstance().GetCommandValue($"qc_{num}")); + MessageLog.GetInstance.ShowRunLog($"AGV去{num}号滚筒线卸桶"); + } + else if (errorCode == "Analysis Error") + { + MessageLog.GetInstance.ShowRunLog($"提示:AGV去{num}号滚筒线API调用失败,请检查请求报文"); + } + else + { + MessageLog.GetInstance.ShowRunLog($"提示:AGV去{num}号滚筒线失败,错误码:{errorCode}"); + } + } + /// /// 炒锅搬运任务错误码分析 /// /// @@ -2899,16 +3533,43 @@ namespace FryPot_DosingSystem.Control { if (InputMaterialQuene.Count > 0 && globalVar.AllowAgvToLineLoadRoller && globalVar.rollerLineOne.OutMaterialingSingle == 1 && !globalVar.LoadRoller) { - e: string id = Guid.NewGuid().ToString("N"); - if (id == LOnerobotJobId || id == LTworobotJobId || id == LThreerobotJobId || id == LFourrobotJobId) - goto e; - - string info = AGVHelper.GetInstance.AgvToLineOneLoadRoller(id); - LOnerobotJobId = id; - Thread.Sleep(500); - LineCarryTaskErrorCodeAnalysis(info, 1); - globalVar.LoadRoller = true; - + if (globalVar.rollerLineOne.StationEight == InputMaterialQuene.ElementAt(0).materialType.MaterialLoc && !globalVar.rollerLineOne.IsEpmtyBefore)//工位8上面是配方料桶 + { + e: string id = Guid.NewGuid().ToString("N"); + if (id == LOnerobotJobId || id == LTworobotJobId || id == LThreerobotJobId || id == LFourrobotJobId || id == LFiverobotJobId || id == LSixrobotJobId || id == LSevenrobotJobId || id == LEightrobotJobId || id == LNinerobotJobId || id == LTenrobotJobId) + goto e; + + string info = AGVHelper.GetInstance.AgvToLineOneLoadRoller(id); + LOnerobotJobId = id; + Thread.Sleep(500); + LineCarryTaskErrorCodeAnalysis(info, 1); + globalVar.LoadRoller = true; + } + //else // 工位8上面不是配方料桶或没有桶时 + //{ + // if (!globalVar.rollerLineOne.IsEpmtyBefore) + // { + // var res = InputMaterialQuene.FirstOrDefault(p => p.materialType.MaterialLoc == globalVar.rollerLineOne.StationEight); + // if (res == null && globalVar.rollerLineOne.StationEight != 0 && globalVar.rollerLineOne.StationEight == globalVar.rollerLineOne.EmptyRollerNums.ElementAt(0))//工位8上面有桶且不是配方上的原料桶且工位8的桶号和plc上报的桶号一致,即空桶 + // { + // //下发AGV去空桶线洗桶任务 + // e: string id = Guid.NewGuid().ToString("N"); + // if (id == LOnerobotJobId || id == LTworobotJobId || id == LThreerobotJobId || id == LFourrobotJobId || id == LFiverobotJobId || id == LSixrobotJobId || id == LSevenrobotJobId || id == LEightrobotJobId || id == LNinerobotJobId || id == LTenrobotJobId) + // goto e; + + // string info = AGVHelper.GetInstance.AgvLeaveLOneToClean(id);//1号线到洗桶处 + // LFourrobotJobId = id; + // Thread.Sleep(500); + // LineToCleanCarryTaskErrorCodeAnalysis(info, 1); + // globalVar.rollerLineOne.IsEpmtyBefore = true; + // AgvFromLineOneToClean(globalVar.rollerLineOne.EmptyRollerNums.ElementAt(0));//AGV从线体1到清洗处 + // } + // } + // else + // { + // AgvFromLineOneToClean(globalVar.rollerLineOne.EmptyRollerNums.ElementAt(0));//AGV从线体1到清洗处 + // } + //} } } @@ -2925,16 +3586,44 @@ namespace FryPot_DosingSystem.Control { if (LTwoInputMaterialQuene.Count > 0 && globalVar.AllowAgvToLineTwoLoadRoller && globalVar.rollerLineTwo.OutMaterialingSingle == 1 && !globalVar.LTwoLoadRoller) { - e: string id = Guid.NewGuid().ToString("N"); - if (id == LOnerobotJobId || id == LTworobotJobId || id == LThreerobotJobId || id == LFourrobotJobId) - goto e; - - string info = AGVHelper.GetInstance.AgvToLineTwoLoadRoller(id); - LTworobotJobId = id; - Thread.Sleep(500); - LineCarryTaskErrorCodeAnalysis(info, 2); - globalVar.LTwoLoadRoller = true; + if (globalVar.rollerLineTwo.StationEight == LTwoInputMaterialQuene.ElementAt(0).materialType.MaterialLoc && !globalVar.rollerLineTwo.IsEpmtyBefore)//工位8上面是配方料桶 + { + e: string id = Guid.NewGuid().ToString("N"); + if (id == LOnerobotJobId || id == LTworobotJobId || id == LThreerobotJobId || id == LFourrobotJobId || id == LFiverobotJobId || id == LSixrobotJobId || id == LSevenrobotJobId || id == LEightrobotJobId || id == LNinerobotJobId || id == LTenrobotJobId) + goto e; + + string info = AGVHelper.GetInstance.AgvToLineTwoLoadRoller(id); + LTworobotJobId = id; + Thread.Sleep(500); + LineCarryTaskErrorCodeAnalysis(info, 2); + globalVar.LTwoLoadRoller = true; + } } + //else// 工位8上面不是配方料桶或没有桶时 + //{ + // if (!globalVar.rollerLineTwo.IsEpmtyBefore) + // { + // var res = LTwoInputMaterialQuene.FirstOrDefault(p => p.materialType.MaterialLoc == globalVar.rollerLineTwo.StationEight); + // if (res == null && globalVar.rollerLineTwo.StationEight != 0 && globalVar.rollerLineTwo.StationEight == globalVar.rollerLineTwo.EmptyRollerNums.ElementAt(0))//工位8上面有桶且不是配方上的原料桶,即空桶 + // { + // //下发AGV去空桶线洗桶任务 + // e: string id = Guid.NewGuid().ToString("N"); + // if (id == LOnerobotJobId || id == LTworobotJobId || id == LThreerobotJobId || id == LFourrobotJobId || id == LFiverobotJobId || id == LSixrobotJobId || id == LSevenrobotJobId || id == LEightrobotJobId || id == LNinerobotJobId || id == LTenrobotJobId) + // goto e; + + // string info = AGVHelper.GetInstance.AgvLeaveLTwoToClean(id);//2号线到洗桶处 + // LFiverobotJobId = id; + // Thread.Sleep(500); + // LineToCleanCarryTaskErrorCodeAnalysis(info, 2); + // globalVar.rollerLineTwo.IsEpmtyBefore = true; + // AgvFromLineTwoToClean(globalVar.rollerLineTwo.EmptyRollerNums.ElementAt(0));//AGV从线体2到清洗处 + // } + // } + // else + // { + // AgvFromLineTwoToClean(globalVar.rollerLineTwo.EmptyRollerNums.ElementAt(0));//AGV从线体1到清洗处 + // } + //} } } public void AgvToLineThreeLoadRoller() @@ -2943,15 +3632,43 @@ namespace FryPot_DosingSystem.Control { if (LThreeInputMaterialQuene.Count > 0 && globalVar.AllowAgvToLineThreeLoadRoller && globalVar.rollerLineThree.OutMaterialingSingle == 1 && !globalVar.LThreeLoadRoller) { - e: string id = Guid.NewGuid().ToString("N"); - if (id == LOnerobotJobId || id == LTworobotJobId || id == LThreerobotJobId || id == LFourrobotJobId) - goto e; - - string info = AGVHelper.GetInstance.AgvToLineThreeLoadRoller(id); - LThreerobotJobId = id; - Thread.Sleep(500); - LineCarryTaskErrorCodeAnalysis(info, 3); - globalVar.LThreeLoadRoller = true; + if (globalVar.rollerLineThree.StationEight == LThreeInputMaterialQuene.ElementAt(0).materialType.MaterialLoc && !globalVar.rollerLineThree.IsEpmtyBefore)//工位8上面是配方料桶 + { + e: string id = Guid.NewGuid().ToString("N"); + if (id == LOnerobotJobId || id == LTworobotJobId || id == LThreerobotJobId || id == LFourrobotJobId || id == LFiverobotJobId || id == LSixrobotJobId || id == LSevenrobotJobId || id == LEightrobotJobId || id == LNinerobotJobId || id == LTenrobotJobId) + goto e; + + string info = AGVHelper.GetInstance.AgvToLineThreeLoadRoller(id); + LThreerobotJobId = id; + Thread.Sleep(500); + LineCarryTaskErrorCodeAnalysis(info, 3); + globalVar.LThreeLoadRoller = true; + } + //else // 工位8上面不是配方料桶或没有桶时 + //{ + // if (!globalVar.rollerLineThree.IsEpmtyBefore) + // { + // var res = LThreeInputMaterialQuene.FirstOrDefault(p => p.materialType.MaterialLoc == globalVar.rollerLineThree.StationEight); + // if (res == null && globalVar.rollerLineThree.StationEight != 0 && globalVar.rollerLineThree.StationEight == globalVar.rollerLineThree.EmptyRollerNums.ElementAt(0))//工位8上面有桶且不是配方上的原料桶,即空桶 + // { + // //下发AGV去空桶线洗桶任务 + // e: string id = Guid.NewGuid().ToString("N"); + // if (id == LOnerobotJobId || id == LTworobotJobId || id == LThreerobotJobId || id == LFourrobotJobId || id == LFiverobotJobId || id == LSixrobotJobId || id == LSevenrobotJobId || id == LEightrobotJobId || id == LNinerobotJobId || id == LTenrobotJobId) + // goto e; + + // string info = AGVHelper.GetInstance.AgvLeaveLThreeToClean(id);//3号线到洗桶处 + // LSixrobotJobId = id; + // Thread.Sleep(500); + // LineToCleanCarryTaskErrorCodeAnalysis(info, 3); + // globalVar.rollerLineThree.IsEpmtyBefore = true; + // AgvFromLineThreeToClean(globalVar.rollerLineThree.EmptyRollerNums.ElementAt(0));//AGV从线体3到清洗处 + // } + // } + // else + // { + // AgvFromLineThreeToClean(globalVar.rollerLineThree.EmptyRollerNums.ElementAt(0));//AGV从线体3到清洗处 + // } + //} } } diff --git a/FryPot_DosingSystem/Control/GlobalVariable.cs b/FryPot_DosingSystem/Control/GlobalVariable.cs index 1e149760..d1962539 100644 --- a/FryPot_DosingSystem/Control/GlobalVariable.cs +++ b/FryPot_DosingSystem/Control/GlobalVariable.cs @@ -57,6 +57,10 @@ namespace FryPot_DosingSystem.Control /// PLC初始化状态 /// public ushort PlcInite { get; set; } + /// + /// 清洗台清洗完成信号 + /// + public ushort CleanComplete { get; set; } #region 上位机内部逻辑条件 /// /// 退出线体1任务 @@ -178,8 +182,17 @@ namespace FryPot_DosingSystem.Control public bool LThreeagvFryPotEmptyRollerArrive { get; set; } public bool LThreeEmptyRollerUnLoadcCom { get; set; }//AGV空桶4号线体下料完成 - public int LFourRollerNum { get; set; } = 0; - #endregion + public int LFourRollerNum { get; set; } = 0;//4号线体空桶数量 + //新增 + public bool agvArriveLineFour { get; set; }//agv到达线体4下料位置从清戏台或炒锅 + public bool agvArriveCleanUnLoad { get; set; }//agv到达清洗台下料位置 + public bool agvArriveCleanLoad { get; set; }//agv到达清洗台上料位置 + + public bool agvArriveLineOneLoadEmptyRoller { get; set; }//agv到达线体1空桶上料位置 + public bool agvArriveLineTwoLoadEmptyRoller { get; set; }//agv到达线体2空桶上料位置 + + public bool agvArriveLineThreeLoadEmptyRoller { get; set; }//agv到达线体3空桶上料位置 + #endregion } /// /// 滚筒线1相关变量 @@ -230,8 +243,23 @@ namespace FryPot_DosingSystem.Control /// 当前线体配方完成信号 /// public ushort RecipeCompleteSingle { get; set; } + /// + /// 线体1上空桶确认信号 + /// + public ushort EmptyRollerConfirmSingle { get; set; } + /// + /// 线体1上单个空桶编号 + /// + public ushort EmptyRollerNum { get; set; } - + /// + /// 上一个桶是否是空桶 + /// + public bool IsEpmtyBefore { get; set; } + /// + /// 线体1上所有空桶的编号集合 + /// + public List EmptyRollerNums { get; set; } = new List() {108}; } /// /// 滚筒线2相关变量 @@ -282,6 +310,24 @@ namespace FryPot_DosingSystem.Control /// 当前线体配方完成信号 /// public ushort RecipeCompleteSingle { get; set; } + + /// + /// 线体1上空桶确认信号 + /// + public ushort EmptyRollerConfirmSingle { get; set; } + /// + /// 线体1上单个空桶编号 + /// + public ushort EmptyRollerNum { get; set; } + /// + /// 上一个同时否是空桶 + /// + public bool IsEpmtyBefore { get; set; } + + /// + /// 线体2上所有空桶的编号集合 + /// + public List EmptyRollerNums { get; set; }=new List(); } /// /// 滚筒线3相关变量 @@ -332,6 +378,24 @@ namespace FryPot_DosingSystem.Control /// 当前线体配方完成信号 /// public ushort RecipeCompleteSingle { get; set; } + + /// + /// 线体1上空桶确认信号 + /// + public ushort EmptyRollerConfirmSingle { get; set; } + /// + /// 线体1上单个空桶编号 + /// + public ushort EmptyRollerNum { get; set; } + /// + /// 上一个同时否是空桶 + /// + public bool IsEpmtyBefore { get; set; } + + /// + /// 线体3上所有空桶的编号集合 + /// + public List EmptyRollerNums { get; set; } = new List(); } /// /// 滚筒线4相关变量 diff --git a/FryPot_DosingSystem/Model/FlowProcessManage.cs b/FryPot_DosingSystem/Model/FlowProcessManage.cs new file mode 100644 index 00000000..d27924cb --- /dev/null +++ b/FryPot_DosingSystem/Model/FlowProcessManage.cs @@ -0,0 +1,16 @@ +using Microsoft.Toolkit.Mvvm.ComponentModel; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FryPot_DosingSystem.Model +{ + internal class FlowProcessManage:ObservableObject + { + public string RecipeName { get; set; } + public ObservableCollection fpModels { get; set; } = new ObservableCollection(); + } +} diff --git a/FryPot_DosingSystem/Model/FlowProcessModel.cs b/FryPot_DosingSystem/Model/FlowProcessModel.cs new file mode 100644 index 00000000..fb2a0a33 --- /dev/null +++ b/FryPot_DosingSystem/Model/FlowProcessModel.cs @@ -0,0 +1,48 @@ +using Microsoft.Toolkit.Mvvm.ComponentModel; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FryPot_DosingSystem.Model +{ + internal class FlowProcessModel:ObservableObject + { + /// + /// 工艺对应配方名称 + /// + public string RecipeName { get { return _recipeName; }set { _recipeName = value;OnPropertyChanged(); } } + private string _recipeName; + /// + /// 工艺步骤 + /// + public int Id { get; set; } + + /// + /// 炒制原料/桶号 + /// + public string FryMaterialNum { get { return _fryMaterialNum; } set { _fryMaterialNum = value;OnPropertyChanged(); } } + private string _fryMaterialNum; + /// + /// 炒制速度 + /// + public double FrySpeed { get { return _frySpeed; }set { _frySpeed = value;OnPropertyChanged(); } } + private double _frySpeed; + /// + /// 炒制重量 + /// + public double FryWeight { get { return _fryMaterialWeight; }set { _fryMaterialWeight = value;OnPropertyChanged(); } } + private double _fryMaterialWeight; + /// + /// 炒制温度 + /// + public double FryTemperature { get { return _fryTemperature; } set { _fryTemperature = value;OnPropertyChanged(); } } + private double _fryTemperature; + /// + /// 炒制时间 + /// + public double FryPeriodTime { get { return _fryPeriodTime; } set { _fryPeriodTime = value;OnPropertyChanged(); } } + private double _fryPeriodTime; + } +} diff --git a/FryPot_DosingSystem/Model/RecipeModel.cs b/FryPot_DosingSystem/Model/RecipeModel.cs index 922bd717..053c0dc4 100644 --- a/FryPot_DosingSystem/Model/RecipeModel.cs +++ b/FryPot_DosingSystem/Model/RecipeModel.cs @@ -29,7 +29,12 @@ namespace FryPot_DosingSystem.Model private string _updateTime; public string UpdateTime { get { return _updateTime; } set { _updateTime = value;OnPropertyChanged(); } } - + /// + /// 工艺流程 + /// + public FlowProcessManage FlowProcess { get { return _flowProcessManage; } set { _flowProcessManage = value;OnPropertyChanged(); } } + private FlowProcessManage _flowProcessManage; + /// /// 配方下发状况信息 /// diff --git a/FryPot_DosingSystem/Resources/fonts/demo_index.html b/FryPot_DosingSystem/Resources/fonts/demo_index.html index 555de870..9e093e12 100644 --- a/FryPot_DosingSystem/Resources/fonts/demo_index.html +++ b/FryPot_DosingSystem/Resources/fonts/demo_index.html @@ -52,12 +52,30 @@
    +
  • + +
    节点-子流程
    +
    &#xe6e2;
    +
  • + +
  • + +
    流程
    +
    &#xe64c;
    +
  • +
  • 下载
    &#xe622;
  • +
  • + +
    232编辑、输入
    +
    &#xe8cc;
    +
  • +
  • 账号信息
    @@ -118,6 +136,12 @@
    &#xe6b7;
  • +
  • + +
    工艺流程_0
    +
    &#xe7ab;
    +
  • +
  • 166-NFC
    @@ -142,7 +166,7 @@
    @font-face {
       font-family: 'iconfont';
    -  src: url('iconfont.ttf?t=1659497763775') format('truetype');
    +  src: url('iconfont.ttf?t=1659942239310') format('truetype');
     }
     

    第二步:定义使用 iconfont 的样式

    @@ -168,6 +192,24 @@
      +
    • + +
      + 节点-子流程 +
      +
      .icon-jiedianziliucheng +
      +
    • + +
    • + +
      + 流程 +
      +
      .icon-liucheng +
      +
    • +
    • @@ -177,6 +219,15 @@
    • +
    • + +
      + 232编辑、输入 +
      +
      .icon-bianjishuru +
      +
    • +
    • @@ -267,6 +318,15 @@
    • +
    • + +
      + 工艺流程_0 +
      +
      .icon-gongyiliucheng_0 +
      +
    • +
    • @@ -303,6 +363,22 @@
        +
      • + +
        节点-子流程
        +
        #icon-jiedianziliucheng
        +
      • + +
      • + +
        流程
        +
        #icon-liucheng
        +
      • +
      • #icon-xiazai
      • +
      • + +
        232编辑、输入
        +
        #icon-bianjishuru
        +
      • +
      • #icon-mianxingmima
      • +
      • + +
        工艺流程_0
        +
        #icon-gongyiliucheng_0
        +
      • +
      • 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

        y%F?BW_lO`Xe;?kH~ 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 W6y^`h8G%?E8=x$&fvS|XK>shzrp}W9 literal 0 HcmV?d00001 diff --git a/BPASmartClient.CustomResource/Image/按钮/添加.png b/BPASmartClient.CustomResource/Image/按钮/添加.png new file mode 100644 index 0000000000000000000000000000000000000000..d6e062989fedcee6b9affe714024f723d1f58236 GIT binary patch literal 10013 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 + /// 重置密码页面传值 + ///

+ public static UserInfo changeUserInfo { get; set; } = null; } } diff --git a/BPASmartClient.CustomResource/Pages/Model/MenuManage.cs b/BPASmartClient.CustomResource/Pages/Model/MenuManage.cs index 143f5b24..c834e150 100644 --- a/BPASmartClient.CustomResource/Pages/Model/MenuManage.cs +++ b/BPASmartClient.CustomResource/Pages/Model/MenuManage.cs @@ -91,7 +91,7 @@ namespace BPASmartClient.CustomResource.Pages.Model /// 子菜单的显示隐藏设置 ///
public Visibility SubMenuVisibility { get { return _mSubMenuVisibility; } set { _mSubMenuVisibility = value; OnPropertyChanged(); } } - private Visibility _mSubMenuVisibility; + private Visibility _mSubMenuVisibility = Visibility.Collapsed; } diff --git a/BPASmartClient.CustomResource/Pages/Model/UserInfo.cs b/BPASmartClient.CustomResource/Pages/Model/UserInfo.cs index 1164d95f..6cec8d19 100644 --- a/BPASmartClient.CustomResource/Pages/Model/UserInfo.cs +++ b/BPASmartClient.CustomResource/Pages/Model/UserInfo.cs @@ -12,6 +12,8 @@ namespace BPASmartClient.CustomResource.Pages.Model public Permission permission { get; set; } public string UserName { get; set; } public string Password { get; set; } + public String LastLogInTime { get; set; } = "无"; + public List userTreeViewModels { get; set; } } } diff --git a/BPASmartClient.CustomResource/Pages/Model/UserManager.cs b/BPASmartClient.CustomResource/Pages/Model/UserManager.cs index 1baf3908..f07f7f37 100644 --- a/BPASmartClient.CustomResource/Pages/Model/UserManager.cs +++ b/BPASmartClient.CustomResource/Pages/Model/UserManager.cs @@ -10,5 +10,6 @@ namespace BPASmartClient.CustomResource.Pages.Model public class UserManager { public ObservableCollection userInfos { get; set; } = new ObservableCollection(); + } } diff --git a/BPASmartClient.CustomResource/Pages/Model/UserTreeViewModel.cs b/BPASmartClient.CustomResource/Pages/Model/UserTreeViewModel.cs new file mode 100644 index 00000000..4fb56aae --- /dev/null +++ b/BPASmartClient.CustomResource/Pages/Model/UserTreeViewModel.cs @@ -0,0 +1,16 @@ +using Microsoft.Toolkit.Mvvm.ComponentModel; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.CustomResource.Pages.Model +{ + public class UserTreeViewModel: ObservableObject + { + public string Name { get; set; } + + public List TreeViewItems { get; set; } + } +} diff --git a/BPASmartClient.CustomResource/Pages/View/AddNewUser.xaml b/BPASmartClient.CustomResource/Pages/View/AddNewUser.xaml new file mode 100644 index 00000000..8ffed030 --- /dev/null +++ b/BPASmartClient.CustomResource/Pages/View/AddNewUser.xaml @@ -0,0 +1,330 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +