using BPASmartClient.CustomResource.Pages.Model; using BPASmartClient.Helper; using BPASmartClient.JXJFoodBigStation.Model.HK_PLC; using BPASmartClient.JXJFoodBigStation.Model.Siemens; using BPASmartClient.Modbus; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Configuration; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace BPASmartClient.JXJFoodBigStation.Model { public class ProcessControl { private volatile static ProcessControl _Instance; public static ProcessControl GetInstance => _Instance ?? (_Instance = new ProcessControl()); private ProcessControl() { } public ObservableCollection RawMaterials { get; set; } = new ObservableCollection(); public SiemensDeviceStatus SiemensDevice = new SiemensDeviceStatus(); public HKDeviceStatus HKDevice = new HKDeviceStatus(); GVL_BigStation BigStation = new GVL_BigStation(); /// /// 配方数据 /// public ObservableCollection RemoteRecipes = new ObservableCollection(); /// /// 配方数据 /// public ObservableCollection IssuedComplete = new ObservableCollection(); /// /// 原料的名称和料仓的位置对应 /// public Dictionary RawMaterialsNamePos = new Dictionary(); /// /// 配方队列 /// public ConcurrentQueue RecipeQueue = new ConcurrentQueue(); /// /// AGV到达工站队列 /// public ConcurrentQueue AGVToWorkStationQueue = new ConcurrentQueue(); /// /// 接收原料数据 /// public RecipeRawMaterial RawMaterial; public void Init() { ActionManage.GetInstance.Register(new Action((res) => { if (SiemensDevice.IsConnected) { if (res != null) { RawMaterials.Clear(); for (int i = 0; i < 15; i++) { if (RawMaterialsNamePos.ContainsKey(res.RecipeName) { RawMaterials.Add(new RemoteRecipeRawMaterial() { RawMaterialName = res.Material[i].Material_Name, RawMaterialBarrelNum = res.Material[i].Material_BarrelNum, RawMaterialWeight = res.Material[i].Material_Weight, RawMaterialLocation = (int)RawMaterialsNamePos[res.Material[i].Material_Name] }); } else { //报警,配方的原料名称下发和设备不一致 } } Json.Data.Recipes.Add(new RemoteRecipeData() { RecipeName = res.RecipeName, RecipeCode = res.RecipeCode, RawMaterial = RawMaterials, TrayCode = res.TrayCode }); } } }), "西门子下发配方", true); ActionManage.GetInstance.Register(new Action((res) => { if (SiemensDevice.IsConnected) { if (res != null) { RawMaterials.Clear(); for (int i = 0; i < 15; i++) { if (RawMaterialsNamePos.ContainsKey(res.Material[i].Material_Name)) { RawMaterials.Add(new RemoteRecipeRawMaterial() { RawMaterialName = res.Material[i].Material_Name, RawMaterialBarrelNum = res.Material[i].Material_BarrelNum, RawMaterialWeight = res.Material[i].Material_Weight, RawMaterialLocation = (int)RawMaterialsNamePos[res.Material[i].Material_Name] }); } else { //报警,配方的原料名称下发和设备不一致 } } Json.Data.Recipes.Add(new RemoteRecipeData() { RecipeName = res.RecipeName, RecipeCode = res.RecipeCode, RawMaterial = RawMaterials, TrayCode = res.TrayCode }); } } }), "西门子下发配方", true); string HK_PLC_IP = ConfigurationManager.AppSettings["HKPlc_IP"]; string Siemens_PLC_IP = ConfigurationManager.AppSettings["Siemens_IP"]; try { //HKDevice.HK_PLC_S7.Connect(S7.Net.CpuType.S71500, HK_PLC_IP); //SiemensDevice.Siemens_PLC_S7.Connect(S7.Net.CpuType.S71500, Siemens_PLC_IP); if (HKDevice.IsConnected) { HKDevice.Init(); } if (SiemensDevice.IsConnected) { SiemensDevice.Init(); } } catch (Exception ex) { } RecipeQueue.Clear(); //Json.Data.Recipes = TestData.GetInstance.Recipes;//添加测试数据 ThreadManage.GetInstance().StartLong(new Action(() => { ReceviceData(); RecipeInfoToHKPLC(); Thread.Sleep(10); }), "流程处理", true); ThreadManage.GetInstance().StartLong(new Action(() => { if (HKDevice.IsConnected && SiemensDevice.IsConnected) { AgvGetInOut(); } Thread.Sleep(10); }), "AGV进站送取货", true); ThreadManage.GetInstance().StartLong(new Action(() => { ReadSiemensCommData(); ReadHKPLCCommData(); Thread.Sleep(10); }), "读取西门子和海科PLC的数据", true); } /// /// AGV送货 /// /// private void AGV_Delivery(int bitNum) { if ((ReadSiemens("M4002." + bitNum) is bool) && BigStation.AgvDeliveryPosition == 0) { BigStation.AgvDeliveryPosition = 1; WriteHKPLC("M4002." + bitNum, true); WriteSiemens("M4002." + bitNum, false); } else if (ReadHK("M5002." + bitNum) is bool && BigStation.AgvDeliveryPosition == 1) { BigStation.AgvDeliveryPosition = 2; WriteSiemens("M5002." + bitNum, true); WriteHKPLC("M5002." + bitNum, false); } else if (ReadSiemens("M4004." + bitNum) is bool && BigStation.AgvDeliveryPosition == 2) { BigStation.AgvDeliveryPosition = 3; WriteHKPLC("M4004." + bitNum, true); WriteSiemens("M4004." + bitNum, false); } else if (ReadHK("M5004." + bitNum) is bool && BigStation.AgvDeliveryPosition == 3) { BigStation.AgvDeliveryPosition = 4; WriteSiemens("M5004." + bitNum, true); WriteHKPLC("M5004." + bitNum, false); } else if (ReadSiemens("M4005." + bitNum) is bool && BigStation.AgvDeliveryPosition == 4) { BigStation.AgvDeliveryPosition = 5; WriteHKPLC("M4005." + bitNum, true); WriteSiemens("M4005." + bitNum, false); } else if (ReadHK("M5005." + bitNum) is bool && BigStation.AgvDeliveryPosition == 5) { WriteSiemens("M5005." + bitNum, true); WriteHKPLC("M5005." + bitNum, false); } } /// /// AGV取货 /// /// private void AGV_Pick(int bitNum) { if (ReadSiemens("M4003" + bitNum) is bool && BigStation.AgvPickUpPosition == 0) { BigStation.AgvPickUpPosition = 1; WriteHKPLC("M4003." + bitNum, true); WriteSiemens("M4003." + bitNum, false); } if (ReadHK("M5003" + bitNum) is bool && BigStation.AgvPickUpPosition == 1) { BigStation.AgvPickUpPosition = 2; WriteSiemens("M5003" + bitNum, true); WriteHKPLC("M5003" + bitNum, false); } if (ReadSiemens("M4006." + bitNum) is bool && BigStation.AgvPickUpPosition == 2) { BigStation.AgvPickUpPosition = 3; WriteHKPLC("M4006." + bitNum, true); WriteSiemens("M4006." + bitNum, false); } if (ReadHK("M5006." + bitNum) is bool && BigStation.AgvPickUpPosition == 3) { WriteSiemens("M5006." + bitNum, true); WriteHKPLC("M5006." + bitNum, false); } } /// /// AGV进站送货 /// private void AgvGetInOut() { //获取工位上是否有小车 SiemensDevice.Siemens_PLC_S7.Write(SiemensCommAddress.StationIsExistCar, (bool) HKDevice.HK_PLC_S7.Read(HKPlcCommAddress.StationIsExistTray)); //检测AGV到站信号 if (AGVToWorkStationQueue.Count > 0) { int index = Array.FindIndex(RemoteRecipes.ToArray(), p => p.RecipeCode == AGVToWorkStationQueue.ElementAt(0)); int TrayLocation = RemoteRecipes.ElementAt(index).TrayCode;//根据配方编号,找到托盘的ID 托盘ID1-6 string RecipeCode = (string)RemoteRecipes.ElementAt(index).RecipeCode; if (TrayLocation > 0 && TrayLocation < 7) { AGV_Delivery(TrayLocation - 1); if (BigStation.AgvDeliveryPosition == 5) { BigStation.AgvDeliveryPosition = 0; //AGVToWorkStationQueue.TryDequeue(out RecipeCode); } AGV_Pick(TrayLocation - 1); if (BigStation.AgvPickUpPosition == 3) { BigStation.AgvPickUpPosition = 0; AGVToWorkStationQueue.TryDequeue(out RecipeCode); } } } } private void ReceviceData() { if (!BigStation.IsAllowManual && RemoteRecipes.Count == 0)//一个配方执行完成后,再获取配方数据 { RemoteRecipes = Json.Data.Recipes; } else if (BigStation.IsAllowManual && RemoteRecipes.Count == 0) { RemoteRecipes = Json.Data.Recipes; } if (RemoteRecipes.Count > 0) { foreach (var data in RemoteRecipes) { if (!(RecipeQueue.Contains(data.RecipeCode))) RecipeQueue.Enqueue(data.RecipeCode); } } } short[] BarrelNum = new short[15]; short[] Location = new short[15]; short[] Weight = new short[15]; private void RecipeInfoToHKPLC() { if (RecipeQueue.Count > 0) { int index = Array.FindIndex(RemoteRecipes.ToArray(), p => p.RecipeCode == RecipeQueue.ElementAt(0)); if (index >= 0 && index <= RemoteRecipes.Count) { string code = RemoteRecipes.ElementAt(index).RecipeCode; if (HKDevice.HK_PLC_S7.Read("M5001.0") && BigStation.RecipeDosingStatus == 0)//配方1是否允许下发配发 { MessageLog.GetInstance.ShowRunLog($"配方状态:{code}允许下发"); BigStation.RecipeDosingStatus = 1; for (int i = 0; i < RemoteRecipes.ElementAt(index).RawMaterial.Count; i++) { BarrelNum[i] = (short)RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(i).RawMaterialBarrelNum; Location[i] = (short)RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(i).RawMaterialLocation; Weight[i] = (short)RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(i).RawMaterialWeight; } HKDevice.StockBinPar(BarrelNum, Location, Weight); HKDevice.HK_PLC_S7.Write("M4001.0", 1);//配发下发完成,to plc HKDevice.HK_PLC_S7.Write("M5001.0", 0);//复位允许下发配方1信号 BigStation.RecipeDosingStatus = 2; MessageLog.GetInstance.ShowRunLog($"配方状态:{code}下发完成"); } if (HKDevice.HK_PLC_S7.Read("M5001.4") && BigStation.RecipeDosingStatus == 2) { BigStation.RecipeDosingStatus = 3; HKDevice.HK_PLC_S7.Write("M5001.4", 0);//复位允许下发配方1信号 MessageLog.GetInstance.ShowRunLog($"配方状态:{code}配方配料"); } if (BigStation.RecipeDosingStatus == 3) { for (int i = 0; i < 12; i++) { if (i >= 0 && i < 8) { if (HKDevice.HK_PLC_S7.Read("M5008." + (i)))//根据配料完成信号, { int a = Array.FindIndex(RemoteRecipes.ElementAt(index).RawMaterial.ToArray(), p => p.RawMaterialLocation == i); if (a >= 0) { int barrelNum = RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(a).RawMaterialBarrelNum; string address = "MD" + 5060 + i * 4 + (barrelNum - 1) * 48; float weight = HKDevice.HK_PLC_S7.Read(address); } } } else { if (HKDevice.HK_PLC_S7.Read("M5009." + (i - 8))) { int a = Array.FindIndex(RemoteRecipes.ElementAt(index).RawMaterial.ToArray(), p => p.RawMaterialLocation == i); if (a >= 0) { int barrelNum = RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(a).RawMaterialBarrelNum; string address = "MD" + 5060 + i * 4 + (barrelNum - 1) * 48; float weight = HKDevice.HK_PLC_S7.Read(address); } } } } if (RTrig.GetInstance("StockState").Start(HKDevice.HK_PLC_S7.Read(HKPlcCommAddress.RecipeDosingFinish)) || true) { BigStation.RecipeDosingStatus = 4; MessageLog.GetInstance.ShowRunLog($"配方状态:{code}配料完成"); HKDevice.RecipeDosingFinishReset(); RecipeQueue.TryDequeue(out code); IssuedComplete.Add(RemoteRecipes.ElementAt(index));//将该配方添加到下 if (!BigStation.IsAllowManual) { Json.Data.Recipes.RemoveAt(index);//制作完成,移除当前配方 } else { Json.Data.Recipes.RemoveAt(index);//制作完成,移除当前配方 } BigStation.RecipeDosingStatus = 0; } } } } } public ConcurrentDictionary ReadHKPLCData = new ConcurrentDictionary(); public ConcurrentDictionary ReadSiemensData = new ConcurrentDictionary(); private void ReadSiemensCommData() { if (SiemensDevice.IsConnected) { GetSiemensStatus("", new Action((obj) => { if (obj is bool[] bools && bools.Length > 0) { } })); } } private void ReadHKPLCCommData() { if (HKDevice.IsConnected) { GetSiemensStatus("", new Action((obj) => { if (obj is bool[] bools && bools.Length > 0) { } })); } } private void GetHKStatus(string key, Action action) { if (ReadHKPLCData.ContainsKey(key)) { if (ReadHKPLCData[key] != null) { action?.Invoke(ReadHKPLCData[key]); } } } private void GetSiemensStatus(string key, Action action) { if (ReadSiemensData.ContainsKey(key)) { if (ReadSiemensData[key] != null) { action?.Invoke(ReadSiemensData[key]); } } } private void WriteSiemens(string Address, object Value) { if (SiemensDevice.IsConnected) { SiemensDevice.Siemens_PLC_S7.Write(Address, Value); } } private void WriteHKPLC(string Address, object Value) { HKDevice.HK_PLC_S7.Write(Address, Value); } private object ReadSiemens(string Address) { if (SiemensDevice.IsConnected) { return SiemensDevice.Siemens_PLC_S7.Read(Address); } else { return null; } } private bool[] ReadBoolsSiemens(int address, int count) { if (SiemensDevice.IsConnected) { return SiemensDevice.Siemens_PLC_S7.ReadBools(address, count); } else { return null; } } private object ReadHK(string Address) { if (HKDevice.IsConnected) { return HKDevice.HK_PLC_S7.Read(Address); } else { return null; } } private bool[] ReadBoolsHK(int address, int count) { if (HKDevice.IsConnected) { return HKDevice.HK_PLC_S7.ReadBools(address, count); } else { return null; } } /// /// 获取料仓的原料名称和原料位置 /// private void ReadPLCDeviceInfo() { for (int i = 0; i < 12; i++) { string RawMaterialName = HKDevice.HK_PLC_S7.Read(""); short RawMaterialLocation = HKDevice.HK_PLC_S7.Read(""); if (RawMaterialsNamePos.ContainsKey(RawMaterialName)) RawMaterialsNamePos.Add(RawMaterialName, RawMaterialLocation); } } } }