diff --git a/BPA.Model/Recipe/RecipeData.cs b/BPA.Model/Recipe/RecipeData.cs
index 706e454..b789bcf 100644
--- a/BPA.Model/Recipe/RecipeData.cs
+++ b/BPA.Model/Recipe/RecipeData.cs
@@ -26,7 +26,10 @@ namespace BPA.Model.Recipe
/// 各个设备是否下料完成。
///
public bool[] IsMakeComplete { get; set; }
-
+ ///
+ /// 下发时间
+ ///
+ public DateTime IssueTime { get; set; }
public Dictionary BatchStatus { get; set; }
public RecipeData(string id,string name, Dictionary materialData,int stationCount=5)
{
@@ -35,7 +38,7 @@ namespace BPA.Model.Recipe
MaterialData = materialData;
//取决于工位数量,本案例中,有五个工位,但是第三个工位没有设备。
IsMakeComplete = new bool[stationCount];
-
+ IssueTime = DateTime.Now;
BatchStatus = new();
for (int i = 1; i <= stationCount; i++)
{
diff --git a/BPA.Model/TaskServer.cs b/BPA.Model/TaskServer.cs
index 1f86f3a..624f17b 100644
--- a/BPA.Model/TaskServer.cs
+++ b/BPA.Model/TaskServer.cs
@@ -1,4 +1,5 @@
-using System;
+using BPA.Model.Recipe;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -12,7 +13,10 @@ namespace BPA.Model
///
public class TaskServer
{
- public int ID { get; set; }
+ ///
+ /// 任务ID,本程序中直接使用配方的下发时间Ticks做标识。
+ ///
+ public long ID { get; set; }
///
/// 任务名称
///
@@ -26,5 +30,9 @@ namespace BPA.Model
/// 任务取消标识
///
public CancellationTokenSource Cts { get; set; } = new CancellationTokenSource();
+ ///
+ /// 当前线程执行的配方。
+ ///
+ public RecipeData CurrentRecipe { get; set; }
}
}
diff --git a/BPA.SingleDevice/App.xaml.cs b/BPA.SingleDevice/App.xaml.cs
index 339dd29..8aefde9 100644
--- a/BPA.SingleDevice/App.xaml.cs
+++ b/BPA.SingleDevice/App.xaml.cs
@@ -61,6 +61,7 @@ namespace BPA.SingleDevice
protected override void OnExit(ExitEventArgs e)
{
base.OnExit(e);
+
//MainControl.GetInstance.Stop();
}
diff --git a/BPA.SingleDevice/Business/Batcher.cs b/BPA.SingleDevice/Business/Batcher.cs
index c572117..7580088 100644
--- a/BPA.SingleDevice/Business/Batcher.cs
+++ b/BPA.SingleDevice/Business/Batcher.cs
@@ -47,6 +47,7 @@ namespace BPA.SingleDevice.Business
}
catch (Exception ex)
{
+ MessageLog.GetInstance.Show(ex.Message);
return false;
}
}
@@ -60,6 +61,7 @@ namespace BPA.SingleDevice.Business
}
catch(Exception ex)
{
+ MessageLog.GetInstance.Show(ex.Message);
return false;
}
}
diff --git a/BPA.SingleDevice/Business/Conveyer.cs b/BPA.SingleDevice/Business/Conveyer.cs
index d52fb97..c9ce1cf 100644
--- a/BPA.SingleDevice/Business/Conveyer.cs
+++ b/BPA.SingleDevice/Business/Conveyer.cs
@@ -25,8 +25,11 @@ namespace BPA.SingleDevice.Business
public bool IsConnected => modbus.IsConnected();
+
+ private readonly object mocelock = new();
+
string iP = "192.168.6.104";
- int port = 502;
+ int port = 508;
ModbusTcp modbus = new();
public async Task Initial()
{
@@ -45,8 +48,8 @@ namespace BPA.SingleDevice.Business
HaveVessel[0] = haveVessel.GetBitValue(1);
HaveVessel[1] = haveVessel.GetBitValue(2);
//HaveVessel[2] = false;
- HaveVessel[3] = haveVessel.GetBitValue(4);
- HaveVessel[4] = haveVessel.GetBitValue(5);
+ HaveVessel[3] = haveVessel.GetBitValue(3);
+ HaveVessel[4] = haveVessel.GetBitValue(4);
});
modbus.Read("M0.2".ToModbusAdd()).OnSuccess((moveComplete) =>
@@ -76,23 +79,27 @@ namespace BPA.SingleDevice.Business
}
catch (Exception ex)
{
+ MessageLog.GetInstance.Show(ex.Message);
-
}
}
}
public bool MoveOnce()
{
- if (IsConnected)
+ if (IsConnected && AllowMove)
{
try
{
- return modbus.Write("VW0".ToModbusAdd(), 2).IsSuccess;
+ lock (mocelock)
+ {
+ return modbus.Write("VW0".ToModbusAdd(), 2).IsSuccess;
+ }
+
}
catch (Exception ex)
{
-
+ MessageLog.GetInstance.Show(ex.Message);
}
}
return false;
@@ -110,7 +117,7 @@ namespace BPA.SingleDevice.Business
}
catch (Exception ex)
{
-
+ MessageLog.GetInstance.Show(ex.Message);
}
}
return false;
@@ -129,7 +136,23 @@ namespace BPA.SingleDevice.Business
}
catch (Exception ex)
{
+ MessageLog.GetInstance.Show(ex.Message);
+ }
+ }
+ return false;
+ }
+ public bool InitalMoveParam()
+ {
+ if (IsConnected && AllowMove)
+ {
+ try
+ {
+ return modbus.Write("VW0".ToModbusAdd(), 0).IsSuccess;
+ }
+ catch (Exception ex)
+ {
+ MessageLog.GetInstance.Show(ex.Message);
}
}
return false;
diff --git a/BPA.SingleDevice/Business/ProcessControl.cs b/BPA.SingleDevice/Business/ProcessControl.cs
index 7321133..e5ee00e 100644
--- a/BPA.SingleDevice/Business/ProcessControl.cs
+++ b/BPA.SingleDevice/Business/ProcessControl.cs
@@ -1,6 +1,8 @@
-using BPA.Model.Enums;
+using Amazon.SecurityToken.Model;
+using BPA.Model.Enums;
using BPA.Model.Recipe;
using BPA.SingleDevice.Interface;
+using BPA.SingleDevice.Json;
using BPA.SingleDevice.Services;
using System;
using System.Collections.Generic;
@@ -27,62 +29,89 @@ namespace BPA.SingleDevice.Business
///
ConcurrentDictionary batchers = new();
- //List currentTask = new();
+ List currentTask = new();
//ConcurrentDictionary test = new();
+
IConveyer conveyer = new Conveyer();
private readonly ILogService logService;
private GlobalData global;
- RecipeData currentRecipe;
+ //RecipeData currentRecipe;
- CancellationTokenSource cts;
+ //CancellationTokenSource cts;
- Task runTask;
+ //Task runTask;
public async void Inital()
{
+ Json.Read();
+ if (Json.Data.BatcherConfigs.Count==0)
+ {
+ InitBatcherConfig();
+ Json.Save();
+ }
+ if (Json.Data.ConveyerConfigs.Count == 0)
+ {
+ InitConveyerConfig();
+ Json.Save();
+ }
+
#region 实例初始化配料机
batchers.TryAdd(1, new Batcher());
batchers.TryAdd(2, new Batcher());
batchers.TryAdd(4, new Batcher());
batchers.TryAdd(5, new Batcher());
- //SetBatcherComm(1, "192.168.6.100");
- //SetBatcherComm(2, "192.168.6.101");
- //SetBatcherComm(4, "192.168.6.102");
- //SetBatcherComm(5, "192.168.6.103");
+ SetBatcherComm(1, "192.168.6.100");
+ SetBatcherComm(2, "192.168.6.101");
+ SetBatcherComm(4, "192.168.6.102");
+ SetBatcherComm(5, "192.168.6.103");
- SetBatcherComm(1, "127.0.0.1", 503);
- SetBatcherComm(2, "127.0.0.1", 504);
- SetBatcherComm(4, "127.0.0.1", 505);
- SetBatcherComm(5, "127.0.0.1", 506);
+ //SetBatcherComm(1, "127.0.0.1", 503);
+ //SetBatcherComm(2, "127.0.0.1", 504);
+ //SetBatcherComm(4, "127.0.0.1", 505);
+ //SetBatcherComm(5, "127.0.0.1", 506);
foreach (var batcher in batchers.Values)
{
await batcher.Initial();
}
#endregion
- //conveyer.SetCommParam(1, "192.168.6.104");
- conveyer.SetCommParam(1, "127.0.0.1",510);
+ conveyer.SetCommParam(1, "192.168.6.104",508);
+ //conveyer.SetCommParam(1, "127.0.0.1",510);
await conveyer.Initial();
- //currentTask.Clear();
+ currentTask.Clear();
ActionRegister();
-
-
TaskManage.GetInstance.StartLong(() =>
{
- if (global.RecipeQueue.Count>0 && currentRecipe is null )
+ InterActive();
+
+ for (int i = 0; i < currentTask.Count; i++)
+ {
+ if (currentTask[i].CurrentRecipe.IsMakeComplete.All(b=>b==true))
+ {
+ currentTask.RemoveAt(i);
+ break;
+ }
+ }
+ if (global.RecipeQueue.Count>0/* && currentRecipe is null*/ )
{
//多配方情况下,必须在工位1没有碗位置,才能进行下发,否则会与之前的配方冲突。
- if (/*!conveyer.HaveVessel[0] &&*/ global.RecipeQueue.ElementAt(0) is not null && global.RecipeQueue.ElementAt(0) is RecipeData)
+ if (/*!conveyer.HaveVessel[0] &&*/ global.RecipeQueue.ElementAt(0) is not null && global.RecipeQueue.ElementAt(0) is RecipeData && currentTask.Count <5 )
{
- global.RecipeQueue.TryDequeue(out currentRecipe);
- //currentTask.Add(new TaskServer() {RunTask=Task.Run(() => { Batching(recipe); }) ,TaskName=$"{recipe.Name}"});
+ //global.RecipeQueue.TryDequeue(out currentRecipe);
+ //cts = new();
+ //Task.Run(() => { Batching(currentRecipe); }, cts.Token);
+ //logService.LogRunInfo($"配方【{currentRecipe.Name}】-- 开始执行配料。");
- cts = new();
- Task.Run(() => { Batching(currentRecipe); }, cts.Token);
- logService.LogRunInfo($"配方【{currentRecipe.Name}】-- 开始执行配料。");
+ global.RecipeQueue.TryDequeue(out RecipeData recipe);
+ if (recipe !=null)
+ {
+ currentTask.Add(new TaskServer() { RunTask = Task.Run(() => { Batching(recipe); }),
+ ID = recipe.IssueTime.Ticks,CurrentRecipe=recipe });
+ logService.LogRunInfo($"配方【{recipe.Name}】-- 开始执行配料。");
+ }
}
}
}, "MonitorRecipeIssue", true);
@@ -102,9 +131,6 @@ namespace BPA.SingleDevice.Business
{
await StationBatching(recipe, 1);
}
-
-
-
for (int stationNum = 2; stationNum <= 5; stationNum++)
{
await MoveOnceAndBatach(recipe, stationNum);
@@ -112,7 +138,7 @@ namespace BPA.SingleDevice.Business
//ToDo:如果最后需要移动一次才能出餐,在这里添加一次移动传送带。
logService.LogRunInfo($"配方【{recipe.Name}】配料完成。");
logService.LogRecipeCompleteInfo($"【{recipe.Name}】");
- currentRecipe = null;
+ //currentRecipe = null;
}
///
@@ -136,7 +162,7 @@ namespace BPA.SingleDevice.Business
recipe.IsMakeComplete[stationNum - 1] = true;
logService.LogRunInfo($"参数值为[{stationNum}],目前该工位无配料机或连接配料机失败。");
//工位3无到位检测。
- recipe.CurrentStation = stationNum;
+ //recipe.CurrentStation = stationNum;
return;
}
#endregion
@@ -231,6 +257,8 @@ namespace BPA.SingleDevice.Business
switch (global.MoveConveyerStep)
{
case MoveConveyer.WaitMove:
+ conveyer.InitalMoveParam();
+ await Task.Delay(500);
if (conveyer.MoveOnce())
{
logService.LogRunInfo($"配方【{recipe.Name}】控制传送带去下个工位,等待动作完成信号上升沿。");
@@ -238,7 +266,7 @@ namespace BPA.SingleDevice.Business
}
else
{
- logService.LogRunInfo($"配方【{recipe.Name}】控制传送带去下个工位失败,3S后重试。");
+ logService.LogRunInfo($"配方【{recipe.Name}】控制传送带去下个工位失败,可能连接异常或不允许移动,3S后重试。");
await Task.Delay(3000);
}
break;
@@ -246,6 +274,7 @@ namespace BPA.SingleDevice.Business
if (moveCompleteTrig)
{
logService.LogRunInfo($"配方【{recipe.Name}】控制传送带移动结束。");
+ conveyer.InitalMoveParam();
while (recipe.IsMakeComplete[stationNum - 1] == false)
{
await StationBatching(recipe, stationNum);
@@ -284,8 +313,16 @@ namespace BPA.SingleDevice.Business
ActionManage.GetInstance.Register(new Func(() =>
{
//目前如果工位1 没有碗或者当前没配方就可以下配方。
- bool result =! (conveyer.HaveVessel[0]) || (currentRecipe==null);
- return result;
+ //bool result =(currentTask.Count > 0 && !conveyer.HaveVessel[0]) || (currentTask.Count==0);
+ foreach (var item in currentTask)
+ {
+ //起始工位没完成的不允许下配方。
+ if (!item.CurrentRecipe.IsMakeComplete[0])
+ {
+ return false;
+ }
+ }
+ return true;
}), "CanIssueRecipe", true);
}
///
@@ -294,18 +331,77 @@ namespace BPA.SingleDevice.Business
private void InterActive()
{
#region 配料机
-
+ foreach (var batcher in batchers.Values)
+ {
+ batcher.AllowBatching = conveyer.HaveVessel[batcher.ID - 1];
+ }
#endregion
#region 传送带
- conveyer.AllowMove = conveyer.MoveComplete;
+ conveyer.AllowMove = /*conveyer.MoveComplete &&*/ GetBatcherAllowMove();
#endregion
}
-
+ ///
+ /// 获取传送带的运行许可,仅通过配方的完成状态来判断。
+ ///
+ ///
+ private bool GetBatcherAllowMove()
+ {
+
+ foreach (var task in currentTask)
+ {
+ foreach (var item in task.CurrentRecipe.BatchStatus.Values)
+ {
+ switch (item)
+ {
+ case BatchStep.WaitBatch:
+ case BatchStep.BatchCompleted:
+ break;
+ default:
+ return false;
+ }
+ }
+ }
+ return true;
+ }
private void SingleDetect()
{
//TODO:上升沿信号检测。
}
+ ///
+ /// 初始化传送带配置。
+ ///
+ private void InitConveyerConfig()
+ {
+ ConveyerConfig conveyerConfig = new() { IP = "192.168.6.104", Port = 502, ID = 1, IsConnect = true };
+ Json.Data.ConveyerConfigs.Add(conveyerConfig);
+
+
+ }
+ ///
+ /// 初始化配料机配置。
+ ///
+ private void InitBatcherConfig()
+ {
+ for (int i = 1; i < 6; i++)
+ {
+ BatcherConfig batcherConfig = new() { StationID = i, IP = $"192.168.6.10{i - 1}", Port = 502, IsConnect = (i==3?false:true) };
+ Json.Data.BatcherConfigs.Add(batcherConfig);
+ }
+ }
+
+ private void InitalBatcher(IList configs)
+ {
+ foreach (var item in configs)
+ {
+ if (item.IsConnect)
+ {
+ batchers.TryAdd(item.StationID, new Batcher());
+ SetBatcherComm(item.StationID, item.IP, item.Port);
+ batchers[item.StationID].Initial();
+ }
+ }
+ }
}
}
diff --git a/BPA.SingleDevice/Interface/IConveyer.cs b/BPA.SingleDevice/Interface/IConveyer.cs
index 6c44f1f..23ef561 100644
--- a/BPA.SingleDevice/Interface/IConveyer.cs
+++ b/BPA.SingleDevice/Interface/IConveyer.cs
@@ -80,5 +80,6 @@ namespace BPA.SingleDevice.Interface
/// 移动一次。
///
bool MoveOnce();
+ bool InitalMoveParam();
}
}
diff --git a/BPA.SingleDevice/Json/ConnectConfig.cs b/BPA.SingleDevice/Json/ConnectConfig.cs
index 48f4fba..7e49caa 100644
--- a/BPA.SingleDevice/Json/ConnectConfig.cs
+++ b/BPA.SingleDevice/Json/ConnectConfig.cs
@@ -6,11 +6,17 @@ using System.Threading.Tasks;
namespace BPA.SingleDevice.Json
{
+ ///
+ /// 设备连接设置。
+ ///
public class ConnectConfig
{
-
+ public List BatcherConfigs { get; set; } = new();
+ public List ConveyerConfigs { get; set; } = new();
}
-
+ ///
+ /// 配料机设置
+ ///
public class BatcherConfig
{
///
@@ -25,6 +31,27 @@ namespace BPA.SingleDevice.Json
/// 端口号
///
public int Port { get; set; }
-
+ public bool IsConnect { get; set; }
+
+ }
+ ///
+ /// 传送带设置
+ ///
+ public class ConveyerConfig
+ {
+ ///
+ /// 对应ID
+ ///
+ public int ID { get; set; }
+ ///
+ /// IP地址
+ ///
+ public string IP { get; set; }
+ ///
+ /// 端口号
+ ///
+ public int Port { get; set; }
+ public bool IsConnect { get; set; }
+
}
}