diff --git a/BPA.Model/Attributes/VariableMonitorAttribute.cs b/BPA.Model/Attributes/VariableMonitorAttribute.cs new file mode 100644 index 0000000..6b1c71f --- /dev/null +++ b/BPA.Model/Attributes/VariableMonitorAttribute.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPA.Model.Attributes +{ + public class VariableMonitorAttribute : Attribute + { + /// + /// 变量描述 + /// + /// 描述 + /// PLC 地址 + /// Modbus TCP 地址 + public VariableMonitorAttribute(string Notes, string PLCAddress = "", string ModbusTcpAddress = "") + { + this.PLCAddress = PLCAddress; + this.ModbusTcpAddress = GetModbusTcpAdd(PLCAddress);// ModbusTcpAddress; + this.Notes = Notes; + } + + private string GetModbusTcpAdd(string address) + { + if (address == null) + return ""; + if (address.Length > 0) + { + address = address.Trim(); + if (address.ToUpper().Contains("GM") && address.Length >= 3) + { + var res = address.Remove(0, 2); + if (res != null && res.Length > 0) + return (int.Parse(res) + 4096).ToString(); + } + else if (address.ToUpper().Contains("M") && address.Length >= 4) + { + var res = address.Substring(1).Split('.'); + if (res != null && res.Length == 2) + { + if (int.TryParse(res[0], out int firstAddress) && int.TryParse(res[1], out int ExitAddress)) + { + if (ExitAddress >= 0 && ExitAddress <= 7) + { + return ((firstAddress * 8) + 320 + ExitAddress).ToString(); + } + } + } + } + else if (address.ToUpper().Contains("GI") && address.Length >= 3) + { + var res = address.Remove(0, 2); + if (res != null && res.Length > 0) + return res; + } + else if (address.ToUpper().Contains("LB") && address.Length >= 3) + { + var res = address.Substring(2); + if (res != null && res.Length > 0) + { + if (int.TryParse(res, out int firstAddress)) + return firstAddress.ToString(); + } + } + else if ((address.ToUpper().Contains("VW") || address.ToUpper().Contains("VD")) && address.Length >= 3) + { + var res = address.Substring(2); + if (res != null && int.TryParse(res, out int tempAddress)) + { + return ((tempAddress / 2) + 100).ToString(); + } + } + else if (address.ToUpper().Contains("LW") && address.Length >= 3) + { + var res = address.Substring(2); + if (res != null && int.TryParse(res, out int LwAddress)) + { + return LwAddress.ToString(); + } + } + } + return ""; + } + + /// + /// PLC 地址 + /// + public string PLCAddress { get; set; } + + /// + /// Modbus TCP 地址 + /// + public string ModbusTcpAddress { get; set; } + + /// + /// 描述 + /// + public string Notes { get; set; } + } +} diff --git a/BPA.Model/BPA.Model.csproj b/BPA.Model/BPA.Model.csproj index 3e23012..ecec0f9 100644 --- a/BPA.Model/BPA.Model.csproj +++ b/BPA.Model/BPA.Model.csproj @@ -1,4 +1,4 @@ - + net6.0-windows diff --git a/BPA.Model/GlobalData.cs b/BPA.Model/GlobalData.cs index b45b3de..21a3344 100644 --- a/BPA.Model/GlobalData.cs +++ b/BPA.Model/GlobalData.cs @@ -6,23 +6,44 @@ using System.Threading.Tasks; using System.Collections.Concurrent; using BPA.Model.Recipe; using BPA.Model.Enums; +using BPA.SingleDevice.Interface; +using BPA.Model.Attributes; namespace BPA.Model { - public class GlobalData + public class GlobalData: IStatus { - public ConcurrentQueue GoodsModels { get; set; } = new ConcurrentQueue(); /// /// 需要执行的配方队列。 /// public ConcurrentQueue RecipeQueue { get; set; } = new(); #region 配料机 + /// + /// 是否配料完成。 + /// + [VariableMonitor("配料机完成状态")] + public bool[] IsCompleted { get; set; } = new bool[4]; #endregion #region 传送带 + [VariableMonitor("传送带移动状态步")] public MoveConveyerStep MoveConveyerStep { get; set; } + + [VariableMonitor("传送带移动完成")] + public bool ConveyerMoveComplete { get; set; } + + [VariableMonitor("工站容器到位检测")] + public bool[] HaveVessel { get; set; } = new bool[5]; + #endregion + + #region 全局流程相关 + [VariableMonitor("待制作配方数量")] + public int WaitMakeRecipeCount { get=>RecipeQueue.Count; } + + [VariableMonitor("开机目前完成配方数量")] + public int CompletedCount { get; set; } #endregion } } diff --git a/BPA.Model/IStatus.cs b/BPA.Model/IStatus.cs new file mode 100644 index 0000000..c85c3b1 --- /dev/null +++ b/BPA.Model/IStatus.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPA.SingleDevice.Interface +{ + public interface IStatus + { + } +} diff --git a/BPA.Model/Recipe/RecipeData.cs b/BPA.Model/Recipe/RecipeData.cs index 8e1705f..247460d 100644 --- a/BPA.Model/Recipe/RecipeData.cs +++ b/BPA.Model/Recipe/RecipeData.cs @@ -30,6 +30,14 @@ namespace BPA.Model.Recipe /// 下发时间 /// public DateTime IssueTime { get; set; } + /// + /// 开始制作时间 + /// + public DateTime StartTime { get; set; } + /// + /// 制作完成时间。 + /// + public DateTime CompleteTime { get; set; } public Dictionary BatchStatus { get; set; } public RecipeData(string id,string name, Dictionary materialData,int stationCount=5) { diff --git a/BPA.Model/VariableMonitor.cs b/BPA.Model/VariableMonitor.cs new file mode 100644 index 0000000..7ac2f5d --- /dev/null +++ b/BPA.Model/VariableMonitor.cs @@ -0,0 +1,73 @@ +using BPA.Helper; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPA.Model +{ + public class VariableMonitor : NotifyBase + { + public int Id { get { return _mId; } set { _mId = value; OnPropertyChanged(); } } + private int _mId; + + + public string VarName { get { return _mVarName; } set { _mVarName = value; OnPropertyChanged(); } } + private string _mVarName; + + + public string PLCAddress { get { return _mPLCAddress; } set { _mPLCAddress = value; OnPropertyChanged(); } } + private string _mPLCAddress; + + + public string Notes { get { return _mNotes; } set { _mNotes = value; OnPropertyChanged(); } } + private string _mNotes; + + + public string ModbusTcpAddress { get { return _mModbusTcpAddress; } set { _mModbusTcpAddress = value; OnPropertyChanged(); } } + private string _mModbusTcpAddress; + + + public string CurrentValue + { + get { return _mCurrentValue; } + set + { + _mCurrentValue = value; + OnPropertyChanged(); + if (_mCurrentValue == "False" || _mCurrentValue == "True") + { + if (_mCurrentValue == "True") + StatusColor = new { r = 51, g = 232, b = 34, a = 1 }; + else + StatusColor = new { r = 255, g = 0, b = 0, a = 1 }; + } + else + StatusColor = new { r = 51, g = 232, b = 34, a = 1 }; + } + } + private string _mCurrentValue; + public bool SwitchValue + { + get { return _sWitchValue; } + set + { + _sWitchValue = value; + OnPropertyChanged(); + } + } + private bool _sWitchValue; + public int IntValue + { + get { return _intValue; } + set + { + _intValue = value; + OnPropertyChanged(); + } + } + private int _intValue; + public object StatusColor { get; set; } + } +} diff --git a/BPA.SingleDevice/Business/Conveyer.cs b/BPA.SingleDevice/Business/Conveyer.cs index 01fb6c6..3b5d180 100644 --- a/BPA.SingleDevice/Business/Conveyer.cs +++ b/BPA.SingleDevice/Business/Conveyer.cs @@ -15,8 +15,8 @@ namespace BPA.SingleDevice.Business public bool[] HaveVessel { get; set; } public int IsReverse { get; set ; } - public float InchSpeed { get; set; } - public float MoveSpeed { get; set; } + public int InchSpeed { get; set; } + public int MoveSpeed { get; set; } public int AccTime { get; set; } public int MoveLength { get; set; } public bool MoveComplete { get;set; } @@ -69,7 +69,7 @@ namespace BPA.SingleDevice.Business this.ID = id; } - public void InchMove() + public void StartInchMove() { if (IsConnected) { @@ -84,7 +84,21 @@ namespace BPA.SingleDevice.Business } } } + public void StopInchMove() + { + if (IsConnected) + { + try + { + modbus.Write("VW0".ToModbusAdd(), 0); + } + catch (Exception ex) + { + MessageLog.GetInstance.Show(ex.Message); + } + } + } public bool MoveOnce() { if (IsConnected && AllowMove) @@ -105,13 +119,13 @@ namespace BPA.SingleDevice.Business return false; } - public bool SetInchParam(int isReverse, float inchSpeed) + public bool SetInchParam(int isReverse, int inchSpeed) { if (IsConnected) { try { - var result1= modbus.Write("VD100".ToModbusAdd(), inchSpeed); + var result1= modbus.Write("VD100".ToModbusAdd(), inchSpeed); var result2= modbus.Write("VW200".ToModbusAdd(), isReverse); return result1.IsSuccess && result2.IsSuccess; } @@ -123,13 +137,13 @@ namespace BPA.SingleDevice.Business return false; } - public bool SetMoveParam(float moveSpeed, int accTime, int moveLength) + public bool SetMoveParam(int moveSpeed, int accTime, int moveLength) { if (IsConnected) { try { - var result1 = modbus.Write("VD104".ToModbusAdd(), moveSpeed); + 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; diff --git a/BPA.SingleDevice/Business/ProcessControl.cs b/BPA.SingleDevice/Business/ProcessControl.cs index 812ca15..bbe713d 100644 --- a/BPA.SingleDevice/Business/ProcessControl.cs +++ b/BPA.SingleDevice/Business/ProcessControl.cs @@ -28,16 +28,14 @@ namespace BPA.SingleDevice.Business /// /// 键就是配料设备对应的ID。这里分别为1,2,4,5。 /// - ConcurrentDictionary batchers = new(); + public ConcurrentDictionary Batchers { get; set; } = new(); - List currentTask = new(); - //ConcurrentDictionary test = new(); - - List currentRecipes = new(); - - IConveyer conveyer = new Conveyer(); + public List CurrentRecipes { get; set; } = new(); private readonly ILogService logService; private GlobalData global; + + public IConveyer Conveyer { get ; set ; } = new Conveyer(); + //RecipeData currentRecipe; //CancellationTokenSource cts; @@ -57,119 +55,99 @@ namespace BPA.SingleDevice.Business Json.Save(); } + + #region 实例初始化配料机 - batchers.TryAdd(1, new Batcher()); - batchers.TryAdd(2, new Batcher()); - batchers.TryAdd(4, new Batcher()); - batchers.TryAdd(5, new Batcher()); + //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(); - } + //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(); + //} + + InitalBatcher(Json.Data.BatcherConfigs); #endregion - //conveyer.SetCommParam(1, "192.168.6.104",508); - conveyer.SetCommParam(1, "127.0.0.1",510); - await conveyer.Initial(); + Conveyer.SetCommParam(1, "192.168.6.104",508); + //Conveyer.SetCommParam(1, "127.0.0.1",510); + await Conveyer.Initial(); - currentTask.Clear(); + CurrentRecipes.Clear(); ActionRegister(); TaskManage.GetInstance.StartLong(() => { InterActive(); - //for (int i = 0; i < currentTask.Count; i++) - //{ - // if (currentTask[i].CurrentRecipe.IsMakeComplete.All(b=>b==true)) - // { - // currentTask.RemoveAt(i); - // break; - // } - //} - for (int i = 0; i < currentRecipes.Count; i++) + #region 移除配方 + for (int i = 0; i < CurrentRecipes.Count; i++) { - if (currentRecipes[i].IsMakeComplete.All(b => b == true)) + if (CurrentRecipes[i].IsMakeComplete.All(b => b == true)) { - var recipeName = currentRecipes[i].Name; - var time = DateTime.Now.Subtract(currentRecipes[i].IssueTime); - currentRecipes.RemoveAt(i); - logService.LogRecipeCompleteInfo($"【{recipeName}】,耗时【{time.Seconds}】秒。"); - logService.LogRunInfo($"配方【{recipeName}】-- 整体配料完成,已从配料队列移除。"); + + var recipe = CurrentRecipes[i]; + recipe.CompleteTime = DateTime.Now; + var recipeName = recipe.Name; + var time = recipe.CompleteTime.Subtract(recipe.StartTime); + var issueTime = recipe.IssueTime.ToString("HH:mm:ss"); + + CurrentRecipes.RemoveAt(i); + global.CompletedCount++; + logService.LogRecipeCompleteInfo($"【{recipeName}】,下发时间【{issueTime}】,开始制作时间【{recipe.StartTime.ToString("HH:mm:ss")}】,耗时【{(int)time.TotalSeconds}】秒。"); + logService.LogRunInfo($"配方【{recipeName}】,下发时间【{issueTime}】,开始制作时间【{recipe.StartTime.ToString("HH:mm:ss")}】-- 整体配料完成,已从配料队列移除。"); break; } } + #endregion - if (global.RecipeQueue.Count>0/* && currentRecipe is null*/ ) + #region 配方加入队列 + if (global.RecipeQueue.Count > 0 && CanIssueRecipe()) { - //多配方情况下,必须在工位1没有碗位置,才能进行下发,否则会与之前的配方冲突。 - //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); - //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}】-- 开始执行配料。"); - //} - //} - - - if (/*!conveyer.HaveVessel[0] &&*/ global.RecipeQueue.ElementAt(0) is not null && global.RecipeQueue.ElementAt(0) is RecipeData && currentRecipes.Count <5 ) + if (global.RecipeQueue.ElementAt(0) is not null && global.RecipeQueue.ElementAt(0) is RecipeData && CurrentRecipes.Count < 5) { global.RecipeQueue.TryDequeue(out RecipeData recipe); if (recipe != null) { - currentRecipes.Add(recipe); + recipe.StartTime = DateTime.Now; + CurrentRecipes.Add(recipe); logService.LogRunInfo($"配方【{recipe.Name}】-- 开始执行配料。"); } } - } + } + #endregion Batching(); + + RefreshData(); }, "MonitorRecipeIssue", true); } /// - /// 配料。 + /// 显示数据的赋值。 /// - /// 需要配料的配方 - [Obsolete("流程有错误")] - private async void Batching(RecipeData recipe) + private void RefreshData() { - if (recipe is null) - { - logService.LogRunInfo($"参数值为null,配料流程结束。"); - return; - } - while (recipe.IsMakeComplete[0] == false) + global.IsCompleted[0] = Batchers[1].BatchComplete; + global.IsCompleted[1] = Batchers[2].BatchComplete; + global.IsCompleted[2] = Batchers[4].BatchComplete; + global.IsCompleted[3] = Batchers[5].BatchComplete; + for (int i = 0; i < Conveyer.HaveVessel.Length; i++) { - //await StationBatching(recipe, 1); + global.HaveVessel[i] = Conveyer.HaveVessel[i]; } - for (int stationNum = 2; stationNum <= 5; stationNum++) - { - await MoveOnceAndBatach(recipe, stationNum); - } - //ToDo:如果最后需要移动一次才能出餐,在这里添加一次移动传送带。 - logService.LogRunInfo($"配方【{recipe.Name}】配料完成。"); - logService.LogRecipeCompleteInfo($"【{recipe.Name}】"); - //currentRecipe = null; + global.ConveyerMoveComplete = Conveyer.MoveComplete; } /// @@ -181,13 +159,8 @@ namespace BPA.SingleDevice.Business { #region 数据验证 - //if (recipe is null) - //{ - // logService.LogRunInfo($"参数值为null,配料流程结束。"); - // return; - //} //如果配料机里没连接该工位的配料机,则直接完成。 - if (!batchers.ContainsKey(stationNum)) + if (!Batchers.ContainsKey(stationNum)) { recipe.BatchStatus[stationNum] = BatchStep.BatchCompleted; recipe.IsMakeComplete[stationNum - 1] = true; @@ -195,9 +168,9 @@ namespace BPA.SingleDevice.Business return; } #endregion - + //数组起始索引是0,工位起始ID是1。 - if (conveyer.HaveVessel[stationNum-1]) + if (Conveyer.HaveVessel[stationNum-1]) { ushort[] materialList=new ushort[14]; //获取工位需要的配料数据。 @@ -213,9 +186,10 @@ namespace BPA.SingleDevice.Business logService.LogRunInfo($"参数值为[{stationNum}],该配方无该工位配料需求。"); return; } + //配料机配料完成的上升沿检测。 - var completeTrig =RTrig.GetInstance($"Batchers[{stationNum}].BatchComplete").Start(batchers[stationNum].BatchComplete); - + var completeTrig = RTrig.GetInstance($"Batchers[{stationNum}].BatchComplete").Start(Batchers[stationNum].BatchComplete); + //配料流程。 switch (recipe.BatchStatus[stationNum]) { @@ -225,7 +199,7 @@ namespace BPA.SingleDevice.Business case BatchStep.WriteBatchParam: if (materialList is not null && materialList.Length == 14) { - if (batchers[stationNum].WriteBatchData(materialList)) + if (Batchers[stationNum].WriteBatchData(materialList)) { recipe.BatchStatus[stationNum] = BatchStep.StartBatch; logService.LogRunInfo($"配方【{recipe.Name}】写入工位【{stationNum}】的下料参数【{String.Join(',',materialList)}】成功。"); @@ -243,7 +217,7 @@ namespace BPA.SingleDevice.Business } break; case BatchStep.StartBatch: - if (batchers[stationNum].StartBatching()) + if (Batchers[stationNum].StartBatching()) { recipe.BatchStatus[stationNum] = BatchStep.WaitBatchComplete; logService.LogRunInfo($"配方【{recipe.Name}】工位【{stationNum}】开始配料,等待配料完成信号上升沿。"); @@ -272,49 +246,6 @@ namespace BPA.SingleDevice.Business Task.Delay(3000).Wait(); } } - [Obsolete("流程有错误")] - private async Task MoveOnceAndBatach(RecipeData recipe,int stationNum) - { - global.MoveConveyerStep = MoveConveyerStep.WaitMove; - while (global.MoveConveyerStep != MoveConveyerStep.MoveComplete) - { - var moveCompleteTrig = RTrig.GetInstance("MoveCompleted").Start(conveyer.MoveComplete); - switch (global.MoveConveyerStep) - { - case MoveConveyerStep.WaitMove: - conveyer.InitalMoveParam(); - await Task.Delay(500); - if (conveyer.MoveOnce()) - { - logService.LogRunInfo($"配方【{recipe.Name}】控制传送带去下个工位,等待动作完成信号上升沿。"); - global.MoveConveyerStep = MoveConveyerStep.Moveing; - } - else - { - logService.LogRunInfo($"配方【{recipe.Name}】控制传送带去下个工位失败,可能连接异常或不允许移动,3S后重试。"); - await Task.Delay(3000); - } - break; - case MoveConveyerStep.Moveing: - if (moveCompleteTrig) - { - logService.LogRunInfo($"配方【{recipe.Name}】控制传送带移动结束。"); - conveyer.InitalMoveParam(); - while (recipe.IsMakeComplete[stationNum - 1] == false) - { - //await StationBatching(recipe, stationNum); - } - global.MoveConveyerStep = MoveConveyerStep.MoveComplete; - } - break; - case MoveConveyerStep.MoveComplete: - //logService.LogRunInfo($"配方【{recipe.Name}】控制传送带移动结束。"); - //await StationBatching(recipe, stationNum); - break; - } - } - - } /// /// 移动传送带。 /// @@ -324,15 +255,16 @@ namespace BPA.SingleDevice.Business //global.MoveConveyerStep = MoveConveyerStep.WaitMove; //while (global.MoveConveyerStep != MoveConveyerStep.MoveComplete) //{ - var moveCompleteTrig = RTrig.GetInstance("MoveCompleted").Start(conveyer.MoveComplete); + var moveCompleteTrig = RTrig.GetInstance("MoveCompleted").Start(Conveyer.MoveComplete); switch (global.MoveConveyerStep) { case MoveConveyerStep.WaitMove: - conveyer.InitalMoveParam(); + Conveyer.InitalMoveParam(); Task.Delay(500).Wait(); - if (conveyer.MoveOnce()) + if (Conveyer.MoveOnce()) { logService.LogRunInfo($"控制传送带去下个工位,等待动作完成信号上升沿。"); + Task.Delay(500).Wait(); global.MoveConveyerStep = MoveConveyerStep.Moveing; } else @@ -350,7 +282,7 @@ namespace BPA.SingleDevice.Business } break; case MoveConveyerStep.MoveComplete: - conveyer.InitalMoveParam(); + Conveyer.InitalMoveParam(); UpdateRecipe(); global.MoveConveyerStep = MoveConveyerStep.WaitMove; //不会执行该步骤,会直接跳出循环。 @@ -366,9 +298,9 @@ namespace BPA.SingleDevice.Business /// 端口号,默认为502。 private void SetBatcherComm(int id,string ip,int port=502) { - if (batchers.ContainsKey(id)) + if (Batchers.ContainsKey(id)) { - batchers[id].SetCommParam(id, ip, port); + Batchers[id].SetCommParam(id, ip, port); } else { @@ -380,27 +312,24 @@ namespace BPA.SingleDevice.Business { ActionManage.GetInstance.Register(new Func(() => { - //目前如果工位1 没有碗或者当前没配方就可以下配方。 - //foreach (var item in currentTask) - //{ - // //起始工位没完成的不允许下配方。 - // if (!item.CurrentRecipe.IsMakeComplete[0]) - // { - // return false; - // } - //} - //return true; - - //2023.10.14修改:如果在配方队列里,有配方的当前工位是1,则不允许下发新的配方。 - foreach (var item in currentRecipes) + return CanIssueRecipe(); + }), "CanIssueRecipe", true); + } + /// + /// 是否允许下发配方。 + /// + /// + private bool CanIssueRecipe() + { + foreach (var item in CurrentRecipes) + { + //如果在配方队列里,有配方的当前工位是1,则不允许下发新的配方。 + if (item.CurrentStation == 1) { - if (item.CurrentStation==1) - { - return false; - } + return false; } - return true; - }), "CanIssueRecipe", true); + } + return global.MoveConveyerStep == MoveConveyerStep.WaitMove; } /// /// 传送带和配料机之间的信号交互。 @@ -408,14 +337,14 @@ namespace BPA.SingleDevice.Business private void InterActive() { #region 配料机 - foreach (var batcher in batchers.Values) + foreach (var batcher in Batchers.Values) { - batcher.AllowBatching = conveyer.HaveVessel[batcher.ID - 1]; + batcher.AllowBatching = Conveyer.HaveVessel[batcher.ID - 1]; } #endregion #region 传送带 - conveyer.AllowMove = /*conveyer.MoveComplete &&*/ GetBatcherAllowMove(); + Conveyer.AllowMove = GetBatcherAllowMove(); #endregion } /// @@ -425,9 +354,9 @@ namespace BPA.SingleDevice.Business private bool GetBatcherAllowMove() { - foreach (var task in currentTask) + foreach (var recipe in CurrentRecipes) { - foreach (var item in task.CurrentRecipe.BatchStatus.Values) + foreach (var item in recipe.BatchStatus.Values) { switch (item) { @@ -447,7 +376,7 @@ namespace BPA.SingleDevice.Business /// private bool IsAllowConveyerMove() { - foreach (var item in currentRecipes) + foreach (var item in CurrentRecipes) { if (item.IsMakeComplete[item.CurrentStation-1]==false) { @@ -483,17 +412,22 @@ namespace BPA.SingleDevice.Business /// 初始化配料机。 /// /// - private void InitalBatcher(IList configs) + private async void InitalBatcher(IList configs) { foreach (var item in configs) { if (item.IsConnect) { - batchers.TryAdd(item.StationID, new Batcher()); + Batchers.TryAdd(item.StationID, new Batcher()); SetBatcherComm(item.StationID, item.IP, item.Port); - batchers[item.StationID].Initial(); } } + foreach (var batcher in Batchers.Values) + { + + await batcher.Initial(); + + } } /// @@ -501,16 +435,11 @@ namespace BPA.SingleDevice.Business /// private void UpdateRecipe() { - foreach (var item in currentRecipes) + foreach (var item in CurrentRecipes) { - //if (item.CurrentStation<5 && conveyer.HaveVessel[item.CurrentStation]) - //{ - // item.CurrentStation++; - //} - if (item.CurrentStation<5) { - while (!conveyer.HaveVessel[item.CurrentStation]) + while (!Conveyer.HaveVessel[item.CurrentStation]) { logService.LogRunInfo($"未检测到配方【{item.Name}】在工位【{item.CurrentStation + 1}】的容器到位信号,请检查。"); Task.Delay(3000).Wait(); @@ -524,18 +453,22 @@ namespace BPA.SingleDevice.Business /// private void Batching() { - if (currentRecipes.Count>0 && IsAllowConveyerMove()) + if (CurrentRecipes.Count>0 && IsAllowConveyerMove()) { MoveConveyer(); } - foreach (var item in currentRecipes) + else if(global.MoveConveyerStep==MoveConveyerStep.WaitMove) { - if (!item.IsMakeComplete[item.CurrentStation-1]) + foreach (var item in CurrentRecipes) { - StationBatching(item, item.CurrentStation); + if (!item.IsMakeComplete[item.CurrentStation - 1]) + { + StationBatching(item, item.CurrentStation); + } } + } - + } } diff --git a/BPA.SingleDevice/Interface/IConveyer.cs b/BPA.SingleDevice/Interface/IConveyer.cs index 23ef561..6357ff7 100644 --- a/BPA.SingleDevice/Interface/IConveyer.cs +++ b/BPA.SingleDevice/Interface/IConveyer.cs @@ -24,11 +24,11 @@ namespace BPA.SingleDevice.Interface /// /// 寸动速度。 /// - float InchSpeed { get; set; } + int InchSpeed { get; set; } /// /// 传动带移动速度。 /// - float MoveSpeed { get; set; } + int MoveSpeed { get; set; } /// /// 加速时间,一般不改动。 /// @@ -58,16 +58,20 @@ namespace BPA.SingleDevice.Interface /// void SetCommParam(int id, string ip, int port = 502); /// - /// 寸动【调试状态】 + /// 开始寸动【调试状态】 /// - void InchMove(); + void StartInchMove(); + /// + /// 停止寸动。 + /// + void StopInchMove(); /// /// 设置寸动参数 /// /// 是否反转 /// 寸动速度 /// 设置是否成功 - bool SetInchParam(int isReverse,float inchSpeed); + bool SetInchParam(int isReverse,int inchSpeed); /// /// 设置移动参数 /// @@ -75,7 +79,7 @@ namespace BPA.SingleDevice.Interface /// 移动加速时间 /// 移动长度 /// 设置是否成功 - bool SetMoveParam(float moveSpeed, int accTime, int moveLength); + bool SetMoveParam(int moveSpeed, int accTime, int moveLength); /// /// 移动一次。 /// diff --git a/BPA.SingleDevice/Interface/IProcessControl.cs b/BPA.SingleDevice/Interface/IProcessControl.cs index 68b5e58..4c12bc2 100644 --- a/BPA.SingleDevice/Interface/IProcessControl.cs +++ b/BPA.SingleDevice/Interface/IProcessControl.cs @@ -1,4 +1,5 @@ -using System; +using BPA.Model.Recipe; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -12,5 +13,9 @@ namespace BPA.SingleDevice.Interface /// 初始化即开始。 /// void Inital(); + List CurrentRecipes { get; set; } + //ConcurrentBag CurrentRecipes { get; set; } + IConveyer Conveyer { get; set; } + ConcurrentDictionary Batchers { get; set; } } } diff --git a/BPA.SingleDevice/View/DebugView.xaml b/BPA.SingleDevice/View/DebugView.xaml index 18a2cf5..c4cecee 100644 --- a/BPA.SingleDevice/View/DebugView.xaml +++ b/BPA.SingleDevice/View/DebugView.xaml @@ -21,6 +21,7 @@ Margin="10" HorizontalAlignment="Right" bpa:ToggleButtonHelper.CheckedContent="调试模式" + x:Name="ModeButton" Command="{Binding SwitchSystemModeCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=IsChecked}" Content="配料模式" @@ -36,6 +37,7 @@