diff --git a/BPA.Model/Enums/BatchStep.cs b/BPA.Model/Enums/BatchStep.cs
new file mode 100644
index 0000000..2eaf36d
--- /dev/null
+++ b/BPA.Model/Enums/BatchStep.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BPA.Model.Enums
+{
+ public enum BatchStep:int
+ {
+ ///
+ /// 等待配料
+ ///
+ WaitBatch=0,
+ ///
+ /// 写入配料参数。
+ ///
+ WriteBatchParam=100,
+ ///
+ /// 开始配料。
+ ///
+ StartBatch=200,
+ ///
+ /// 等待配料完成。
+ ///
+ WaitBatchComplete=300,
+ ///
+ /// 配料完成。
+ ///
+ BatchCompleted=400
+ }
+}
diff --git a/BPA.Model/Enums/MoveConveyer.cs b/BPA.Model/Enums/MoveConveyer.cs
new file mode 100644
index 0000000..66fa5c9
--- /dev/null
+++ b/BPA.Model/Enums/MoveConveyer.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BPA.Model.Enums
+{
+ public enum MoveConveyer:int
+ {
+ WaitMove=0,
+ Moveing=100,
+ MoveComplete=200,
+ }
+}
diff --git a/BPA.Model/GlobalData.cs b/BPA.Model/GlobalData.cs
index bab1d60..5dc6c5d 100644
--- a/BPA.Model/GlobalData.cs
+++ b/BPA.Model/GlobalData.cs
@@ -4,11 +4,25 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Concurrent;
+using BPA.Model.Recipe;
+using BPA.Model.Enums;
namespace BPA.Model
{
- public class GlobalData
+ public class GlobalData
{
- public static ConcurrentQueue GoodsModels { get; set; } = new ConcurrentQueue();
+ public ConcurrentQueue GoodsModels { get; set; } = new ConcurrentQueue();
+ ///
+ /// 需要执行的配方队列。
+ ///
+ public ConcurrentQueue RecipeQueue { get; set; } = new();
+
+ #region 配料机
+
+ #endregion
+
+ #region 传送带
+ public MoveConveyer MoveConveyerStep { get; set; }
+ #endregion
}
}
diff --git a/BPA.Model/Recipe/RecipeData.cs b/BPA.Model/Recipe/RecipeData.cs
new file mode 100644
index 0000000..706e454
--- /dev/null
+++ b/BPA.Model/Recipe/RecipeData.cs
@@ -0,0 +1,47 @@
+using BPA.Model.Enums;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BPA.Model.Recipe
+{
+ ///
+ /// 根据设备生成的配方数据。
+ ///
+ public class RecipeData
+ {
+ public string ID { get; set; }
+ public string Name { get; set; }
+ ///
+ /// 该配方当前所在的工位。
+ ///
+ public int CurrentStation { get; set; }
+ ///
+ /// 配方对应的各设备的下料数据,键为设备编号,值为设备下各个料仓的下料重量。
+ ///
+ public Dictionary MaterialData { get; set; }
+ ///
+ /// 各个设备是否下料完成。
+ ///
+ public bool[] IsMakeComplete { get; set; }
+
+ public Dictionary BatchStatus { get; set; }
+ public RecipeData(string id,string name, Dictionary materialData,int stationCount=5)
+ {
+ ID = id;
+ Name = name;
+ MaterialData = materialData;
+ //取决于工位数量,本案例中,有五个工位,但是第三个工位没有设备。
+ IsMakeComplete = new bool[stationCount];
+
+ BatchStatus = new();
+ for (int i = 1; i <= stationCount; i++)
+ {
+ BatchStatus.Add(i, BatchStep.WaitBatch);
+ }
+ }
+
+ }
+}
diff --git a/BPA.Model/TaskServer.cs b/BPA.Model/TaskServer.cs
new file mode 100644
index 0000000..1f86f3a
--- /dev/null
+++ b/BPA.Model/TaskServer.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace BPA.Model
+{
+ ///
+ /// 配料线程服务类。
+ ///
+ public class TaskServer
+ {
+ public int ID { get; set; }
+ ///
+ /// 任务名称
+ ///
+ public string TaskName { get; set; }
+ ///
+ /// 是否结束。
+ ///
+ public bool IsCompleted { get; set; }
+ public Task RunTask { get; set; }
+ ///
+ /// 任务取消标识
+ ///
+ public CancellationTokenSource Cts { get; set; } = new CancellationTokenSource();
+ }
+}
diff --git a/BPA.SingleDevice/App.xaml.cs b/BPA.SingleDevice/App.xaml.cs
index f6731d4..339dd29 100644
--- a/BPA.SingleDevice/App.xaml.cs
+++ b/BPA.SingleDevice/App.xaml.cs
@@ -43,7 +43,17 @@ namespace BPA.SingleDevice
base.OnStartup(e);
SqlHelper.GetInstance.Init();
- MainControl.GetInstance.Start();
+ //MainControl.GetInstance.Start();
+
+ #region 注册调试日志。
+ ILogService logService = App.Current.Services.GetService();
+ MessageLog.GetInstance.NotifyShow = (string str) =>
+ {
+ logService.LogDebugInfo(str);
+ };
+ #endregion
+
+ Current.Services.GetService().Inital();
MainView mv = new MainView();
mv.Show();
}
@@ -51,7 +61,7 @@ namespace BPA.SingleDevice
protected override void OnExit(ExitEventArgs e)
{
base.OnExit(e);
- MainControl.GetInstance.Stop();
+ //MainControl.GetInstance.Stop();
}
private static IServiceProvider ConfigurServices()
@@ -61,15 +71,20 @@ namespace BPA.SingleDevice
//services.AddSingleton();
services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+
services.AddSingleton();
services.AddSingleton();
services.AddSingleton();
services.AddSingleton();
services.AddSingleton();
services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
-
-
+ services.AddSingleton();
+ services.AddSingleton();
return services.BuildServiceProvider();
}
diff --git a/BPA.SingleDevice/Business/Batcher.cs b/BPA.SingleDevice/Business/Batcher.cs
new file mode 100644
index 0000000..c572117
--- /dev/null
+++ b/BPA.SingleDevice/Business/Batcher.cs
@@ -0,0 +1,75 @@
+using BPA.SingleDevice.Interface;
+using BPA.SingleDevice.Services;
+using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BPA.SingleDevice.Business
+{
+ ///
+ /// 配料机,在这个程序中,指的是味魔方。
+ ///
+ public class Batcher : IBatchcer
+ {
+ public int ID { get; set; }
+ public bool BatchComplete { get; set; }
+ public bool AllowBatching { get; set; }
+ public bool IsConnected { get => modbus.IsConnected(); }
+
+ string iP="192.168.6.100";
+ int port=502;
+ ModbusTcp modbus = new();
+ public async Task Initial()
+ {
+ await Task.Run(() =>
+ {
+ modbus.WithModbusTcp(iP, port).UseConnected(() =>
+ {
+ TaskManage.GetInstance.StartLong(() =>
+ {
+ BatchComplete = modbus.Read("LB1000".ToModbusAdd()).Content;
+ }, $"Batcher【{ID}】:ReadData", true);
+ });
+ });
+
+ }
+
+
+ public bool StartBatching()
+ {
+ try
+ {
+ var result = modbus.Write("LB1001".ToModbusAdd(), true);
+ return result.IsSuccess;
+ }
+ catch (Exception ex)
+ {
+ return false;
+ }
+ }
+
+ public bool WriteBatchData(ushort[] value)
+ {
+ try
+ {
+ var result = modbus.Write("LW1000".ToModbusAdd(), value);
+ return result.IsSuccess;
+ }
+ catch(Exception ex)
+ {
+ return false;
+ }
+ }
+
+
+ public void SetCommParam(int id,string ip, int port = 502)
+ {
+ this.iP = ip;
+ this.port = port;
+ this.ID = id;
+ }
+ }
+}
diff --git a/BPA.SingleDevice/Business/Conveyer.cs b/BPA.SingleDevice/Business/Conveyer.cs
new file mode 100644
index 0000000..d52fb97
--- /dev/null
+++ b/BPA.SingleDevice/Business/Conveyer.cs
@@ -0,0 +1,138 @@
+using BPA.SingleDevice.Interface;
+using BPA.SingleDevice.Services;
+using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BPA.SingleDevice.Business
+{
+ public class Conveyer : IConveyer
+ {
+ public int ID { get; set; }
+
+ public bool[] HaveVessel { get; set; }
+ public int IsReverse { get; set ; }
+ public float InchSpeed { get; set; }
+ public float MoveSpeed { get; set; }
+ public int AccTime { get; set; }
+ public int MoveLength { get; set; }
+ public bool MoveComplete { get;set; }
+
+ public bool AllowMove { get; set; }
+
+ public bool IsConnected => modbus.IsConnected();
+
+ string iP = "192.168.6.104";
+ int port = 502;
+ ModbusTcp modbus = new();
+ public async Task Initial()
+ {
+ //因为设备中间有个空位。虽然是4台设备,但是需要设置5个位置。
+ HaveVessel = new bool[5];
+
+ //这里还需写入默认参数,从文件读取,如移动速度等。
+ await Task.Run(() =>
+ {
+ modbus.WithModbusTcp(iP, port).UseConnected(() =>
+ {
+ TaskManage.GetInstance.StartLong(() =>
+ {
+ modbus.Read("VW300".ToModbusAdd()).OnSuccess((haveVessel) =>
+ {
+ HaveVessel[0] = haveVessel.GetBitValue(1);
+ HaveVessel[1] = haveVessel.GetBitValue(2);
+ //HaveVessel[2] = false;
+ HaveVessel[3] = haveVessel.GetBitValue(4);
+ HaveVessel[4] = haveVessel.GetBitValue(5);
+ });
+
+ modbus.Read("M0.2".ToModbusAdd()).OnSuccess((moveComplete) =>
+ {
+ MoveComplete = moveComplete;
+ });
+ }, $"Conveyer【{ID}】:ReadData", true);
+ });
+ });
+
+ }
+
+ public void SetCommParam(int id, string ip, int port = 502)
+ {
+ this.iP = ip;
+ this.port = port;
+ this.ID = id;
+ }
+
+ public void InchMove()
+ {
+ if (IsConnected)
+ {
+ try
+ {
+ modbus.Write("VW0".ToModbusAdd(), 1);
+ }
+ catch (Exception ex)
+ {
+
+
+ }
+ }
+ }
+
+ public bool MoveOnce()
+ {
+ if (IsConnected)
+ {
+ try
+ {
+ return modbus.Write("VW0".ToModbusAdd(), 2).IsSuccess;
+ }
+ catch (Exception ex)
+ {
+
+ }
+ }
+ return false;
+ }
+
+ public bool SetInchParam(int isReverse, float inchSpeed)
+ {
+ if (IsConnected)
+ {
+ try
+ {
+ var result1= modbus.Write("VD100".ToModbusAdd(), inchSpeed);
+ var result2= modbus.Write("VW200".ToModbusAdd(), isReverse);
+ return result1.IsSuccess && result2.IsSuccess;
+ }
+ catch (Exception ex)
+ {
+
+ }
+ }
+ return false;
+ }
+
+ public bool SetMoveParam(float moveSpeed, int accTime, int moveLength)
+ {
+ if (IsConnected)
+ {
+ try
+ {
+ var result1 = modbus.Write("VD104".ToModbusAdd(), moveSpeed);
+ var result2 = modbus.Write("VW122".ToModbusAdd(), accTime);
+ var result3 = modbus.Write("VD108".ToModbusAdd(), moveLength);
+ return result1.IsSuccess && result2.IsSuccess && result3.IsSuccess;
+ }
+ catch (Exception ex)
+ {
+
+ }
+ }
+ return false;
+ }
+ }
+}
diff --git a/BPA.SingleDevice/Business/MainControl.cs b/BPA.SingleDevice/Business/MainControl.cs
index 5238e9e..4e9f1a2 100644
--- a/BPA.SingleDevice/Business/MainControl.cs
+++ b/BPA.SingleDevice/Business/MainControl.cs
@@ -27,11 +27,11 @@ namespace BPA.SingleDevice.Business
private void CommInit()
{
Enum.GetNames(typeof(EDeviceType)).ToList().ForEach(x => { Comm.TryAdd(x.ToEnum(), new DeviceControl()); });
- Comm[EDeviceType.WeimoCube1].SetPar("192.168.1.100", EDeviceType.WeimoCube1);
- Comm[EDeviceType.WeimoCube2].SetPar("192.168.1.100", EDeviceType.WeimoCube2);
- Comm[EDeviceType.WeimoCube3].SetPar("192.168.1.100", EDeviceType.WeimoCube3);
- Comm[EDeviceType.WeimoCube4].SetPar("192.168.1.100", EDeviceType.WeimoCube4);
- Comm[EDeviceType.Conveyor].SetPar("192.168.1.100", EDeviceType.Conveyor);
+ Comm[EDeviceType.WeimoCube1].SetPar("192.168.6.100", EDeviceType.WeimoCube1);
+ Comm[EDeviceType.WeimoCube2].SetPar("192.168.6.101", EDeviceType.WeimoCube2);
+ Comm[EDeviceType.WeimoCube3].SetPar("192.168.6.102", EDeviceType.WeimoCube3);
+ Comm[EDeviceType.WeimoCube4].SetPar("192.168.6.103", EDeviceType.WeimoCube4);
+ Comm[EDeviceType.Conveyor].SetPar("192.168.6.104", EDeviceType.Conveyor);
Task.Run(() =>
{
Parallel.ForEach(Comm, (s) => { s.Value.Stop(); });
@@ -40,43 +40,43 @@ namespace BPA.SingleDevice.Business
public void Start()
{
- CommInit();
- TaskManage.GetInstance.StartLong(() =>
- {
- while (GlobalData.GoodsModels.Count > 0 && !Comm[EDeviceType.Conveyor].AllowBatching)
- {
- Task.Run(() =>
- {
- if (GlobalData.GoodsModels.TryDequeue(out GoodsModel gm))
- {
- //对设备进行分组,筛选出对应设备所需要的料仓中的原料信息
- var res = gm.RawMaters.GroupBy(p => p.DeviceNum).ToDictionary(p => p.Key, p => p.ToList());
- res.ToList().ForEach(item =>
- {
- int index = item.Key - 1;
- if (index >= 0 && index < Comm[EDeviceType.Conveyor].DeviceStationDetection.Length)
- {
- if (Comm[EDeviceType.Conveyor].DeviceStationDetection[index])
- {
- Comm[EDeviceType.Conveyor].ConveyorControl(false);
- ushort[] weights = new ushort[14];
- item.Value.ForEach(s =>
- {
- int tempIndex = s.WarehouseNum - 1;
- if (tempIndex >= 0 && tempIndex < weights.Length)
- {
- weights[tempIndex] = s.Weight;
- }
- });
- Comm[(EDeviceType)item.Key].WriteControl(weights);
- }
- }
- });
- }
- });
- }
- Thread.Sleep(10);
- }, "配料任务", true);
+ //CommInit();
+ //TaskManage.GetInstance.StartLong(() =>
+ //{
+ // while (GlobalData.GoodsModels.Count > 0 && !Comm[EDeviceType.Conveyor].AllowBatching)
+ // {
+ // Task.Run(() =>
+ // {
+ // if (GlobalData.GoodsModels.TryDequeue(out GoodsModel gm))
+ // {
+ // //对设备进行分组,筛选出对应设备所需要的料仓中的原料信息
+ // var res = gm.RawMaters.GroupBy(p => p.DeviceNum).ToDictionary(p => p.Key, p => p.ToList());
+ // res.ToList().ForEach(item =>
+ // {
+ // int index = item.Key - 1;
+ // if (index >= 0 && index < Comm[EDeviceType.Conveyor].DeviceStationDetection.Length)
+ // {
+ // if (Comm[EDeviceType.Conveyor].DeviceStationDetection[index])
+ // {
+ // Comm[EDeviceType.Conveyor].ConveyorControl(false);
+ // ushort[] weights = new ushort[14];
+ // item.Value.ForEach(s =>
+ // {
+ // int tempIndex = s.WarehouseNum - 1;
+ // if (tempIndex >= 0 && tempIndex < weights.Length)
+ // {
+ // weights[tempIndex] = s.Weight;
+ // }
+ // });
+ // Comm[(EDeviceType)item.Key].WriteControl(weights);
+ // }
+ // }
+ // });
+ // }
+ // });
+ // }
+ // Thread.Sleep(10);
+ //}, "配料任务", true);
}
public void Stop()
diff --git a/BPA.SingleDevice/Business/ProcessControl.cs b/BPA.SingleDevice/Business/ProcessControl.cs
new file mode 100644
index 0000000..7321133
--- /dev/null
+++ b/BPA.SingleDevice/Business/ProcessControl.cs
@@ -0,0 +1,311 @@
+using BPA.Model.Enums;
+using BPA.Model.Recipe;
+using BPA.SingleDevice.Interface;
+using BPA.SingleDevice.Services;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace BPA.SingleDevice.Business
+{
+ ///
+ /// 配料流程控制
+ ///
+ public class ProcessControl : IProcessControl
+ {
+ public ProcessControl(ILogService logService,GlobalData global)
+ {
+ this.logService = logService;
+ this.global = global;
+ }
+ ///
+ /// 键就是配料设备对应的ID。这里分别为1,2,4,5。
+ ///
+ ConcurrentDictionary batchers = new();
+
+ //List currentTask = new();
+ //ConcurrentDictionary test = new();
+ IConveyer conveyer = new Conveyer();
+ private readonly ILogService logService;
+ private GlobalData global;
+ RecipeData currentRecipe;
+
+ CancellationTokenSource cts;
+
+ Task runTask;
+ public async void Inital()
+ {
+ #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, "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);
+ await conveyer.Initial();
+
+ //currentTask.Clear();
+ ActionRegister();
+
+
+
+ TaskManage.GetInstance.StartLong(() =>
+ {
+ 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)
+ {
+ global.RecipeQueue.TryDequeue(out currentRecipe);
+
+ //currentTask.Add(new TaskServer() {RunTask=Task.Run(() => { Batching(recipe); }) ,TaskName=$"{recipe.Name}"});
+
+ cts = new();
+ Task.Run(() => { Batching(currentRecipe); }, cts.Token);
+ logService.LogRunInfo($"配方【{currentRecipe.Name}】-- 开始执行配料。");
+ }
+ }
+ }, "MonitorRecipeIssue", true);
+ }
+ ///
+ /// 配料。
+ ///
+ /// 需要配料的配方
+ private async void Batching(RecipeData recipe)
+ {
+ if (recipe is null)
+ {
+ logService.LogRunInfo($"参数值为null,配料流程结束。");
+ return;
+ }
+ while (recipe.IsMakeComplete[0] == false)
+ {
+ await StationBatching(recipe, 1);
+ }
+
+
+
+ for (int stationNum = 2; stationNum <= 5; stationNum++)
+ {
+ await MoveOnceAndBatach(recipe, stationNum);
+ }
+ //ToDo:如果最后需要移动一次才能出餐,在这里添加一次移动传送带。
+ logService.LogRunInfo($"配方【{recipe.Name}】配料完成。");
+ logService.LogRecipeCompleteInfo($"【{recipe.Name}】");
+ currentRecipe = null;
+ }
+
+ ///
+ /// 单工位配料
+ ///
+ /// 配方
+ /// 工位数。
+ private async Task StationBatching(RecipeData recipe,int stationNum)
+ {
+
+ #region 数据验证
+ if (recipe is null)
+ {
+ logService.LogRunInfo($"参数值为null,配料流程结束。");
+ return;
+ }
+ //如果配料机里没连接该工位的配料机,则直接完成。
+ if (!batchers.ContainsKey(stationNum))
+ {
+ recipe.BatchStatus[stationNum] = BatchStep.BatchCompleted;
+ recipe.IsMakeComplete[stationNum - 1] = true;
+ logService.LogRunInfo($"参数值为[{stationNum}],目前该工位无配料机或连接配料机失败。");
+ //工位3无到位检测。
+ recipe.CurrentStation = stationNum;
+ return;
+ }
+ #endregion
+
+ //数组起始索引是0,工位起始ID是1。
+ if (conveyer.HaveVessel[stationNum-1])
+ {
+ recipe.CurrentStation = stationNum;
+ ushort[] materialList=new ushort[14];
+ //获取工位需要的配料数据。
+ if (recipe.MaterialData.ContainsKey(stationNum))
+ {
+ materialList = recipe.MaterialData[stationNum];
+ }
+ //如果该工位不需要配料,直接完成就行。
+ else
+ {
+ recipe.BatchStatus[stationNum] = BatchStep.BatchCompleted;
+ recipe.IsMakeComplete[stationNum - 1] = true;
+ logService.LogRunInfo($"参数值为[{stationNum}],该配方无该工位配料需求。");
+ return;
+ }
+ //配料完成的上升沿检测。
+ var completeTrig =RTrig.GetInstance($"Batchers[{stationNum}].BatchComplete").Start(batchers[stationNum].BatchComplete);
+
+ //配料流程。
+ switch (recipe.BatchStatus[stationNum])
+ {
+ case BatchStep.WaitBatch:
+ recipe.BatchStatus[stationNum] = BatchStep.WriteBatchParam;
+ break;
+ case BatchStep.WriteBatchParam:
+ if (materialList is not null && materialList.Length == 14)
+ {
+ if (batchers[stationNum].WriteBatchData(materialList))
+ {
+ recipe.BatchStatus[stationNum] = BatchStep.StartBatch;
+ logService.LogRunInfo($"配方【{recipe.Name}】写入工位【{stationNum}】的下料参数【{String.Join(',',materialList)}】成功。");
+ }
+ else
+ {
+ logService.LogRunInfo($"配方【{recipe.Name}】写入工位【{stationNum}】的下料参数失败,稍后重试。");
+ await Task.Delay(3000);
+ }
+ }
+ else
+ {
+ logService.LogRunInfo($"配方【{recipe.Name}】写入工位【{stationNum}】的下料参数失败,参数长度错误或为Null。");
+ return;
+ }
+ break;
+ case BatchStep.StartBatch:
+ if (batchers[stationNum].StartBatching())
+ {
+ recipe.BatchStatus[stationNum] = BatchStep.WaitBatchComplete;
+ logService.LogRunInfo($"配方【{recipe.Name}】工位【{stationNum}】的开始配料,等待配料完成信号上升沿。");
+ }
+ else
+ {
+ logService.LogRunInfo($"配方【{recipe.Name}】写入工位【{stationNum}】的开始配料失败,3S后重试。");
+ await Task.Delay(3000);
+ }
+ break;
+ case BatchStep.WaitBatchComplete:
+ //先延时,以免味魔方还没开始工作,未把配料完成写为false。
+ //await Task.Delay(500);
+ //if (batchers[stationNum].BatchComplete)
+ if (completeTrig)
+ {
+ logService.LogRunInfo($"配方【{recipe.Name}】工位【{stationNum}】的配料完成。");
+ recipe.BatchStatus[stationNum] = BatchStep.BatchCompleted;
+ }
+ break;
+ case BatchStep.BatchCompleted:
+ recipe.IsMakeComplete[stationNum - 1] = true;
+ break;
+ }
+ }
+ else
+ {
+ logService.LogRunInfo($"配方【{recipe.Name}】工位【{stationNum}】未检测到容器到位,请检查,3秒后重新检测。");
+ await Task.Delay(3000);
+ }
+ }
+
+ private async Task MoveOnceAndBatach(RecipeData recipe,int stationNum)
+ {
+ global.MoveConveyerStep = MoveConveyer.WaitMove;
+ while (global.MoveConveyerStep != MoveConveyer.MoveComplete)
+ {
+ var moveCompleteTrig = RTrig.GetInstance("MoveCompleted").Start(conveyer.MoveComplete);
+ switch (global.MoveConveyerStep)
+ {
+ case MoveConveyer.WaitMove:
+ if (conveyer.MoveOnce())
+ {
+ logService.LogRunInfo($"配方【{recipe.Name}】控制传送带去下个工位,等待动作完成信号上升沿。");
+ global.MoveConveyerStep = MoveConveyer.Moveing;
+ }
+ else
+ {
+ logService.LogRunInfo($"配方【{recipe.Name}】控制传送带去下个工位失败,3S后重试。");
+ await Task.Delay(3000);
+ }
+ break;
+ case MoveConveyer.Moveing:
+ if (moveCompleteTrig)
+ {
+ logService.LogRunInfo($"配方【{recipe.Name}】控制传送带移动结束。");
+ while (recipe.IsMakeComplete[stationNum - 1] == false)
+ {
+ await StationBatching(recipe, stationNum);
+ }
+ global.MoveConveyerStep = MoveConveyer.MoveComplete;
+ }
+ break;
+ case MoveConveyer.MoveComplete:
+ //logService.LogRunInfo($"配方【{recipe.Name}】控制传送带移动结束。");
+ //await StationBatching(recipe, stationNum);
+ break;
+ }
+ }
+
+ }
+ ///
+ /// 设置相应设备ID的配料机的通讯参数。
+ ///
+ /// 该设备对应的工位ID。
+ /// IP地址
+ /// 端口号,默认为502。
+ private void SetBatcherComm(int id,string ip,int port=502)
+ {
+ if (batchers.ContainsKey(id))
+ {
+ batchers[id].SetCommParam(id, ip, port);
+ }
+ else
+ {
+ logService.LogDebugInfo($"设置配料机设备【{id}】的通讯参数失败,未在集合中找到此ID对应的设备。");
+ }
+ }
+
+ private void ActionRegister()
+ {
+ ActionManage.GetInstance.Register(new Func(() =>
+ {
+ //目前如果工位1 没有碗或者当前没配方就可以下配方。
+ bool result =! (conveyer.HaveVessel[0]) || (currentRecipe==null);
+ return result;
+ }), "CanIssueRecipe", true);
+ }
+ ///
+ /// 传送带和配料机之间的信号交互。
+ ///
+ private void InterActive()
+ {
+ #region 配料机
+
+ #endregion
+
+ #region 传送带
+ conveyer.AllowMove = conveyer.MoveComplete;
+ #endregion
+ }
+
+ private void SingleDetect()
+ {
+ //TODO:上升沿信号检测。
+ }
+ }
+
+}
diff --git a/BPA.SingleDevice/Interface/IBatchcer.cs b/BPA.SingleDevice/Interface/IBatchcer.cs
new file mode 100644
index 0000000..6914795
--- /dev/null
+++ b/BPA.SingleDevice/Interface/IBatchcer.cs
@@ -0,0 +1,48 @@
+using MongoDB.Driver;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BPA.SingleDevice.Interface
+{
+ public interface IBatchcer
+ {
+ ///
+ /// 设备ID
+ ///
+ public int ID { get; set; }
+ ///
+ /// 配料完成
+ ///
+ public bool BatchComplete { get; set; }
+ ///
+ /// 允许下料。
+ ///
+ public bool AllowBatching { get; set; }
+ ///
+ /// 是否连接。
+ ///
+ bool IsConnected { get; }
+ ///
+ /// 设置通讯参数
+ ///
+ void SetCommParam(int id,string ip, int port = 502);
+ ///
+ /// 写入下料数据。
+ ///
+ ///
+ ///
+ bool WriteBatchData(ushort[] value);
+ ///
+ /// 开始配料
+ ///
+ ///
+ bool StartBatching();
+ ///
+ /// 设备初始化
+ ///
+ Task Initial();
+ }
+}
diff --git a/BPA.SingleDevice/Interface/IConveyer.cs b/BPA.SingleDevice/Interface/IConveyer.cs
new file mode 100644
index 0000000..6c44f1f
--- /dev/null
+++ b/BPA.SingleDevice/Interface/IConveyer.cs
@@ -0,0 +1,84 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BPA.SingleDevice.Interface
+{
+
+ public interface IConveyer
+ {
+ ///
+ /// 设备ID
+ ///
+ public int ID { get; set; }
+ ///
+ /// 位置有容器,这个程序里容器是碗。
+ ///
+ bool[] HaveVessel { get; set; }
+ ///
+ /// 寸动是否反转,值为1时是反转,为0时则为正转。
+ ///
+ int IsReverse { get;set; }
+ ///
+ /// 寸动速度。
+ ///
+ float InchSpeed { get; set; }
+ ///
+ /// 传动带移动速度。
+ ///
+ float MoveSpeed { get; set; }
+ ///
+ /// 加速时间,一般不改动。
+ ///
+ int AccTime { get; set; }
+ ///
+ /// 传动带移动一次的长度,单位:脉冲。
+ ///
+ int MoveLength { get; set; }
+ ///
+ /// 移动结束。
+ ///
+ bool MoveComplete { get; set; }
+ ///
+ /// 是否连接。
+ ///
+ bool IsConnected { get;}
+ ///
+ /// 允许移动。
+ ///
+ bool AllowMove { get; set; }
+ ///
+ /// 设备初始化
+ ///
+ Task Initial();
+ ///
+ /// 设置通讯参数
+ ///
+ void SetCommParam(int id, string ip, int port = 502);
+ ///
+ /// 寸动【调试状态】
+ ///
+ void InchMove();
+ ///
+ /// 设置寸动参数
+ ///
+ /// 是否反转
+ /// 寸动速度
+ /// 设置是否成功
+ bool SetInchParam(int isReverse,float inchSpeed);
+ ///
+ /// 设置移动参数
+ ///
+ /// 移动速度
+ /// 移动加速时间
+ /// 移动长度
+ /// 设置是否成功
+ bool SetMoveParam(float moveSpeed, int accTime, int moveLength);
+ ///
+ /// 移动一次。
+ ///
+ bool MoveOnce();
+ }
+}
diff --git a/BPA.SingleDevice/Interface/IProcessControl.cs b/BPA.SingleDevice/Interface/IProcessControl.cs
new file mode 100644
index 0000000..68b5e58
--- /dev/null
+++ b/BPA.SingleDevice/Interface/IProcessControl.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BPA.SingleDevice.Interface
+{
+ public interface IProcessControl
+ {
+ ///
+ /// 初始化即开始。
+ ///
+ void Inital();
+ }
+}
diff --git a/BPA.SingleDevice/Json/ConnectConfig.cs b/BPA.SingleDevice/Json/ConnectConfig.cs
new file mode 100644
index 0000000..48f4fba
--- /dev/null
+++ b/BPA.SingleDevice/Json/ConnectConfig.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BPA.SingleDevice.Json
+{
+ public class ConnectConfig
+ {
+
+ }
+
+ public class BatcherConfig
+ {
+ ///
+ /// 对应工位ID
+ ///
+ public int StationID { get; set; }
+ ///
+ /// IP地址
+ ///
+ public string IP { get; set; }
+ ///
+ /// 端口号
+ ///
+ public int Port { get; set; }
+
+ }
+}
diff --git a/BPA.SingleDevice/Services/ILogService.cs b/BPA.SingleDevice/Services/ILogService.cs
index 0cef42e..fcd7023 100644
--- a/BPA.SingleDevice/Services/ILogService.cs
+++ b/BPA.SingleDevice/Services/ILogService.cs
@@ -21,6 +21,6 @@ namespace BPA.SingleDevice.Services
void LogRecipeCompleteInfo(string info);
void LogDebugInfo(string info);
- Task> GetAllLog();
+ Task> GetAllLog() where T:LogBase;
}
}
diff --git a/BPA.SingleDevice/Services/LogService.cs b/BPA.SingleDevice/Services/LogService.cs
index b1f6c12..61f6b90 100644
--- a/BPA.SingleDevice/Services/LogService.cs
+++ b/BPA.SingleDevice/Services/LogService.cs
@@ -132,7 +132,7 @@ namespace BPA.SingleDevice.Services
}
}
- public async Task> GetAllLog()
+ public async Task> GetAllLog() where T:LogBase
{
var logs= await sqlHelper.GetListAsync();
if (logs.IsSuccess)
diff --git a/BPA.SingleDevice/View/AddRawMaterialDialogView.xaml b/BPA.SingleDevice/View/AddRawMaterialDialogView.xaml
index 51a1028..cb57591 100644
--- a/BPA.SingleDevice/View/AddRawMaterialDialogView.xaml
+++ b/BPA.SingleDevice/View/AddRawMaterialDialogView.xaml
@@ -48,7 +48,7 @@
HorizontalAlignment="Right"
FontSize="16"
Foreground="#ddd"
- Text="设备编号:" />
+ Text="设备对应工位:" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BPA.SingleDevice/View/DebugView.xaml.cs b/BPA.SingleDevice/View/DebugView.xaml.cs
new file mode 100644
index 0000000..ce51c53
--- /dev/null
+++ b/BPA.SingleDevice/View/DebugView.xaml.cs
@@ -0,0 +1,30 @@
+using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace BPA.SingleDevice.View
+{
+ ///
+ /// DebugView.xaml 的交互逻辑
+ ///
+ public partial class DebugView : UserControl
+ {
+ public DebugView()
+ {
+ InitializeComponent();
+ this.DataContext = App.Current.Services.GetService();
+ }
+ }
+}
diff --git a/BPA.SingleDevice/View/OrderMainView.xaml b/BPA.SingleDevice/View/OrderMainView.xaml
index e511d33..f6f5f1e 100644
--- a/BPA.SingleDevice/View/OrderMainView.xaml
+++ b/BPA.SingleDevice/View/OrderMainView.xaml
@@ -11,9 +11,9 @@
d:DesignWidth="800"
mc:Ignorable="d">
-
+
-
+ Value="{Binding Count}" />-->