Kaynağa Gözat

1. 单配方修改,添加配置文件。

master
Nah 1 yıl önce
ebeveyn
işleme
c85b4e01b7
8 değiştirilmiş dosya ile 212 ekleme ve 51 silme
  1. +5
    -2
      BPA.Model/Recipe/RecipeData.cs
  2. +10
    -2
      BPA.Model/TaskServer.cs
  3. +1
    -0
      BPA.SingleDevice/App.xaml.cs
  4. +2
    -0
      BPA.SingleDevice/Business/Batcher.cs
  5. +31
    -8
      BPA.SingleDevice/Business/Conveyer.cs
  6. +132
    -36
      BPA.SingleDevice/Business/ProcessControl.cs
  7. +1
    -0
      BPA.SingleDevice/Interface/IConveyer.cs
  8. +30
    -3
      BPA.SingleDevice/Json/ConnectConfig.cs

+ 5
- 2
BPA.Model/Recipe/RecipeData.cs Dosyayı Görüntüle

@@ -26,7 +26,10 @@ namespace BPA.Model.Recipe
/// 各个设备是否下料完成。
/// </summary>
public bool[] IsMakeComplete { get; set; }

/// <summary>
/// 下发时间
/// </summary>
public DateTime IssueTime { get; set; }
public Dictionary<int,BatchStep> BatchStatus { get; set; }
public RecipeData(string id,string name, Dictionary<int, ushort[]> 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++)
{


+ 10
- 2
BPA.Model/TaskServer.cs Dosyayı Görüntüle

@@ -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
/// </summary>
public class TaskServer
{
public int ID { get; set; }
/// <summary>
/// 任务ID,本程序中直接使用配方的下发时间Ticks做标识。
/// </summary>
public long ID { get; set; }
/// <summary>
/// 任务名称
/// </summary>
@@ -26,5 +30,9 @@ namespace BPA.Model
/// 任务取消标识
/// </summary>
public CancellationTokenSource Cts { get; set; } = new CancellationTokenSource();
/// <summary>
/// 当前线程执行的配方。
/// </summary>
public RecipeData CurrentRecipe { get; set; }
}
}

+ 1
- 0
BPA.SingleDevice/App.xaml.cs Dosyayı Görüntüle

@@ -61,6 +61,7 @@ namespace BPA.SingleDevice
protected override void OnExit(ExitEventArgs e)
{
base.OnExit(e);
//MainControl.GetInstance.Stop();
}



+ 2
- 0
BPA.SingleDevice/Business/Batcher.cs Dosyayı Görüntüle

@@ -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;
}
}


+ 31
- 8
BPA.SingleDevice/Business/Conveyer.cs Dosyayı Görüntüle

@@ -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<bool>("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<ushort>("VW0".ToModbusAdd(), 2).IsSuccess;
lock (mocelock)
{
return modbus.Write<ushort>("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<ushort>("VW0".ToModbusAdd(), 0).IsSuccess;
}
catch (Exception ex)
{
MessageLog.GetInstance.Show(ex.Message);
}
}
return false;


+ 132
- 36
BPA.SingleDevice/Business/ProcessControl.cs Dosyayı Görüntüle

@@ -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
/// </summary>
ConcurrentDictionary<int, IBatchcer> batchers = new();

//List<TaskServer> currentTask = new();
List<TaskServer> currentTask = new();
//ConcurrentDictionary<int, TaskServer> 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<ConnectConfig>.Read();
if (Json<ConnectConfig>.Data.BatcherConfigs.Count==0)
{
InitBatcherConfig();
Json<ConnectConfig>.Save();
}
if (Json<ConnectConfig>.Data.ConveyerConfigs.Count == 0)
{
InitConveyerConfig();
Json<ConnectConfig>.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;
}

/// <summary>
@@ -136,7 +162,7 @@ namespace BPA.SingleDevice.Business
recipe.IsMakeComplete[stationNum - 1] = true;
logService.LogRunInfo($"参数<stationNum>值为[{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<bool>(new Func<bool>(() =>
{
//目前如果工位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);
}
/// <summary>
@@ -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
}

/// <summary>
/// 获取传送带的运行许可,仅通过配方的完成状态来判断。
/// </summary>
/// <returns></returns>
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:上升沿信号检测。
}
/// <summary>
/// 初始化传送带配置。
/// </summary>
private void InitConveyerConfig()
{
ConveyerConfig conveyerConfig = new() { IP = "192.168.6.104", Port = 502, ID = 1, IsConnect = true };
Json<ConnectConfig>.Data.ConveyerConfigs.Add(conveyerConfig);

}
/// <summary>
/// 初始化配料机配置。
/// </summary>
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<ConnectConfig>.Data.BatcherConfigs.Add(batcherConfig);
}
}

private void InitalBatcher(IList<BatcherConfig> 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();
}
}
}
}

}

+ 1
- 0
BPA.SingleDevice/Interface/IConveyer.cs Dosyayı Görüntüle

@@ -80,5 +80,6 @@ namespace BPA.SingleDevice.Interface
/// 移动一次。
/// </summary>
bool MoveOnce();
bool InitalMoveParam();
}
}

+ 30
- 3
BPA.SingleDevice/Json/ConnectConfig.cs Dosyayı Görüntüle

@@ -6,11 +6,17 @@ using System.Threading.Tasks;

namespace BPA.SingleDevice.Json
{
/// <summary>
/// 设备连接设置。
/// </summary>
public class ConnectConfig
{

public List<BatcherConfig> BatcherConfigs { get; set; } = new();
public List<ConveyerConfig> ConveyerConfigs { get; set; } = new();
}

/// <summary>
/// 配料机设置
/// </summary>
public class BatcherConfig
{
/// <summary>
@@ -25,6 +31,27 @@ namespace BPA.SingleDevice.Json
/// 端口号
/// </summary>
public int Port { get; set; }
public bool IsConnect { get; set; }

}
/// <summary>
/// 传送带设置
/// </summary>
public class ConveyerConfig
{
/// <summary>
/// 对应ID
/// </summary>
public int ID { get; set; }
/// <summary>
/// IP地址
/// </summary>
public string IP { get; set; }
/// <summary>
/// 端口号
/// </summary>
public int Port { get; set; }
public bool IsConnect { get; set; }

}
}

Yükleniyor…
İptal
Kaydet