|
|
@@ -0,0 +1,216 @@ |
|
|
|
using BPASmart.Model; |
|
|
|
using BPASmartClient.Helper; |
|
|
|
using System; |
|
|
|
using System.Collections.Concurrent; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Collections.ObjectModel; |
|
|
|
using System.Linq; |
|
|
|
using System.Text; |
|
|
|
using System.Threading; |
|
|
|
using System.Threading.Tasks; |
|
|
|
|
|
|
|
namespace BPASmartClient.SmallBatchingSystem.Services |
|
|
|
{ |
|
|
|
/// <summary> |
|
|
|
/// 料仓服务线程 |
|
|
|
/// </summary> |
|
|
|
public class SiloServer |
|
|
|
{ |
|
|
|
public SiloServer() |
|
|
|
{ |
|
|
|
BusinessThread(); |
|
|
|
RefreshRecips(); |
|
|
|
MakeToRecipsID("2d1ac4da-110b-4d4d-9e94-36aac6d67124"); |
|
|
|
} |
|
|
|
|
|
|
|
#region 临时变量 |
|
|
|
/// <summary> |
|
|
|
/// 物料数据 |
|
|
|
/// </summary> |
|
|
|
public ObservableCollection<RecipeMaterials> RecipeMaterialsDic = new ObservableCollection<RecipeMaterials>(); |
|
|
|
/// <summary> |
|
|
|
/// 当前配方 |
|
|
|
/// </summary> |
|
|
|
public ObservableCollection<Recipes> RecipesDic = new ObservableCollection<Recipes>(); |
|
|
|
#endregion |
|
|
|
|
|
|
|
#region 订单管理 |
|
|
|
public ConcurrentQueue<Recipes> MakeOrderQueue { get; set; }=new ConcurrentQueue<Recipes>(); |
|
|
|
#endregion |
|
|
|
|
|
|
|
#region 业务 |
|
|
|
/// <summary> |
|
|
|
/// 业务线程 |
|
|
|
/// </summary> |
|
|
|
public void BusinessThread() |
|
|
|
{ |
|
|
|
|
|
|
|
ThreadManage.GetInstance().Start(new Action(() => |
|
|
|
{ |
|
|
|
PlcServer.GetInstance.Connect(); |
|
|
|
}), "启动PLC", false); |
|
|
|
|
|
|
|
ThreadManage.GetInstance().StartLong(new Action(() => |
|
|
|
{ |
|
|
|
// if (PlcServer.GetInstance.Communication.Connected) |
|
|
|
{ |
|
|
|
if (MakeOrderQueue.TryDequeue(out Recipes recipes)) |
|
|
|
{ |
|
|
|
Make(recipes); |
|
|
|
} |
|
|
|
} |
|
|
|
}), "配料线程启动", true); |
|
|
|
} |
|
|
|
#endregion |
|
|
|
|
|
|
|
#region 调用函数 |
|
|
|
/// <summary> |
|
|
|
/// 刷新配方数据 |
|
|
|
/// </summary> |
|
|
|
public void RefreshRecips() |
|
|
|
{ |
|
|
|
try |
|
|
|
{ |
|
|
|
//读取料仓物料数据 配方数据 |
|
|
|
Json<LocalMaterails>.Read(); |
|
|
|
Json<LocalRecipes>.Read(); |
|
|
|
RecipeMaterialsDic = Json<LocalMaterails>.Data.locaMaterails; |
|
|
|
RecipesDic = Json<LocalRecipes>.Data.locaRecipes; |
|
|
|
RecipesDic?.ToList().ForEach(par => { |
|
|
|
par.recipeMaterials?.ToList().ForEach((recipeMaterial) => |
|
|
|
{ |
|
|
|
RecipeMaterials recipe = RecipeMaterialsDic?.ToList().Find(k => k.ID == recipeMaterial.ID); |
|
|
|
if (recipe != null) |
|
|
|
{ |
|
|
|
recipeMaterial.MaterialType = recipe.MaterialType; |
|
|
|
recipeMaterial.MaterialPosion = recipe.MaterialPosion; |
|
|
|
recipeMaterial.PropertyCollections = recipe.PropertyCollections; |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
}); |
|
|
|
} |
|
|
|
catch (Exception ex) |
|
|
|
{ |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 根据配方ID制作流程 |
|
|
|
/// </summary> |
|
|
|
public void MakeToRecipsID(string id) |
|
|
|
{ |
|
|
|
try |
|
|
|
{ |
|
|
|
//chaxun 配方 |
|
|
|
Recipes info = RecipesDic?.ToList().Find(par => par.ID == id); |
|
|
|
if (info != null) |
|
|
|
{ |
|
|
|
//添加到队列 |
|
|
|
MakeOrderQueue.Enqueue(info); |
|
|
|
} |
|
|
|
} |
|
|
|
catch (Exception ex) |
|
|
|
{ |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 根据配方控制流程 |
|
|
|
/// </summary> |
|
|
|
/// <param name="recipes"></param> |
|
|
|
public async void Make(Recipes recipes) |
|
|
|
{ |
|
|
|
try |
|
|
|
{ |
|
|
|
//遍历配方物料集合 |
|
|
|
recipes?.recipeMaterials?.ToList().ForEach(recipe => |
|
|
|
{ |
|
|
|
//料仓位置 |
|
|
|
int recipesLoc = 1; int.TryParse(recipe.PropertyCollections?.First()?.PropertyValue, out recipesLoc); |
|
|
|
//原料位置 |
|
|
|
int storeLoc = 1; int.TryParse(recipe.MaterialPosion, out recipesLoc); |
|
|
|
//原料需求(g)数 |
|
|
|
int storeWeight = recipe.MaterialWeight; |
|
|
|
|
|
|
|
//1.写PLC VW302 目标位置 -> recipesLoc M10.0 定位启动 开始运行 |
|
|
|
//2.读取PLC M20.0 到达目标位置 <- 标志 (bool) 【等待】 |
|
|
|
//3.写PLC VW100 料口X需求 ->写入重量 storeWeight |
|
|
|
//4.写PLC M0.0 启动出料口xx ->storeLoc (bool) |
|
|
|
//5.读PLC M4.0 通道XX出料完成<-标志 (bool) 【等待】 |
|
|
|
|
|
|
|
if (storeWeight > 0) |
|
|
|
{ |
|
|
|
WriteData("VW302", recipesLoc); |
|
|
|
WriteData("M10.0",true); |
|
|
|
|
|
|
|
#region 读取是否到达目标位置,超时10秒 |
|
|
|
bool IsOver = false; |
|
|
|
int fade1 = 1000; |
|
|
|
while (fade1 != -1 && !IsOver) |
|
|
|
{ |
|
|
|
IsOver = (bool)ReadData("M20.0", 1); |
|
|
|
Thread.Sleep(10); |
|
|
|
fade1--; |
|
|
|
} |
|
|
|
#endregion |
|
|
|
|
|
|
|
if (IsOver)//到达指定位置 |
|
|
|
{ |
|
|
|
//写需求 |
|
|
|
string adder = $"VW{100 + 2 * (storeLoc - 1)}"; |
|
|
|
WriteData(adder, storeWeight); |
|
|
|
|
|
|
|
//写启动料口 |
|
|
|
adder = storeLoc <= 8 ? $"M0.{(storeLoc - 1)}" : $"M1.{(storeLoc - 9)}"; |
|
|
|
WriteData(adder, true); |
|
|
|
|
|
|
|
//读取通道下料是否完成 |
|
|
|
adder = storeLoc <= 8 ? $"M4.{(storeLoc - 1)}" : $"M5.{(storeLoc - 9)}"; |
|
|
|
#region 通道XX出料完成,超时10秒 |
|
|
|
bool IsXLOver = false; |
|
|
|
int fade1XL = 1000; |
|
|
|
while (fade1XL != -1 && !IsXLOver) |
|
|
|
{ |
|
|
|
IsXLOver = (bool)ReadData("M20.0", 1); |
|
|
|
Thread.Sleep(30); |
|
|
|
fade1XL--; |
|
|
|
} |
|
|
|
#endregion |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
//6.写PLC M10.4 上位机配料完成 |
|
|
|
} |
|
|
|
catch (Exception ex) { } |
|
|
|
} |
|
|
|
#endregion |
|
|
|
|
|
|
|
#region 调用外部PLC |
|
|
|
/// <summary> |
|
|
|
/// 写PLC |
|
|
|
/// </summary> |
|
|
|
/// <param name="address"></param> |
|
|
|
/// <param name="value"></param> |
|
|
|
public void WriteData(string address, object value) |
|
|
|
{ |
|
|
|
//PlcServer.GetInstance.WriteData(address, value); |
|
|
|
} |
|
|
|
/// <summary> |
|
|
|
/// 读PLC |
|
|
|
/// </summary> |
|
|
|
/// <param name="address"></param> |
|
|
|
/// <param name="length"></param> |
|
|
|
/// <returns></returns> |
|
|
|
public object ReadData(string address, int length) |
|
|
|
{ |
|
|
|
//return PlcServer.GetInstance.ReadData(address, length); |
|
|
|
return null; |
|
|
|
} |
|
|
|
#endregion |
|
|
|
|
|
|
|
} |
|
|
|
} |