Bläddra i källkod

morks设备添加

样式分支
pry 2 år sedan
förälder
incheckning
76b1b2f112
5 ändrade filer med 958 tillägg och 30 borttagningar
  1. +15
    -8
      BPASmartClient.MORKSM.BK.PLC/MorksMachine.cs
  2. +581
    -11
      BPASmartClient.MorkS/Control.cs
  3. +346
    -0
      BPASmartClient.MorkS/GVL_MORKS.cs
  4. +16
    -0
      BPASmartClient.MorkS/OrderLocInfo.cs
  5. +0
    -11
      BPASmartClient/DeviceInfo.xml

+ 15
- 8
BPASmartClient.MORKSM.BK.PLC/MorksMachine.cs Visa fil

@@ -11,31 +11,34 @@ namespace BPASmartClient.MORKSM.BK.PLC
{
public class MorksMachine : BasePeripheral
{
ModbusTcp modbusTcp => modbusTcp ?? new ModbusTcp();
ModbusTcp modbusTcp = new ModbusTcp();
public string IpAddress { get; set; }
public int Port { get; set; }


public override void Init()
{
//读取布尔数据
//读取数据
EventBus.EventBus.GetInstance().Subscribe<ReadModel>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
{
if (@event == null) return;
var par = @event as ReadModel;
ushort address = (ushort)modbusTcp.GetAddress(par?.Address);
object readData = new object();
if (par.Address.ToUpper().Contains("M"))
{
modbusTcp.Read(address, CommandType.Coils, par.Length);
//modbusTcp.Read(address, CommandType.Coils, par.Length);
modbusTcp.Readbool(address, par.Length, new Action<bool[]>((s) => { readData = s; }));
}
else if (par.Address.ToUpper().Contains("VW"))
{
modbusTcp.Read(address, CommandType.HoldingRegisters, par.Length);
readData = modbusTcp.Read(address, CommandType.HoldingRegisters, par.Length);
}

callBack?.Invoke(readData);
//callBack = new EventCallBackHandle(readData);
});

//写入布尔数据
//写入数据
EventBus.EventBus.GetInstance().Subscribe<WriteModel>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
{
if (@event == null) return;
@@ -51,12 +54,16 @@ namespace BPASmartClient.MORKSM.BK.PLC
}
});

modbusTcp.ModbusTcpConnect(IpAddress, Port);
////批量读取数据
//EventBus.EventBus.GetInstance().Subscribe<>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
//{

//});
}

public override void Start()
{
modbusTcp.ModbusTcpConnect(IpAddress, Port);
}

public override void Stop()


+ 581
- 11
BPASmartClient.MorkS/Control.cs Visa fil

@@ -6,35 +6,605 @@ using BPASmartClient.EventBus;
using BPASmartClient.Model;
using BPASmartClient.Peripheral;
using static BPASmartClient.EventBus.EventBus;
using BPASmartClient.Helper;
using System.Threading;
using BPASmartClient.Message;
using BPA.Message;
using System.Linq;
using BPASmartClient.Model.PLC;
using System.Threading.Tasks;

namespace BPASmartClient.MorkS
{
public class Control : IDevice
public class Control : BaseDevice
{
public string DeviceId { get; set; }
public string Name { get; set; }
public override DeviceClientType DeviceType => DeviceClientType.MORKS;
GVL_MORKS mORKS = new GVL_MORKS();
/// <summary>
/// 订单物料信息
/// </summary>
public OrderMaterialDelivery orderMaterialDelivery { get; set; } = new OrderMaterialDelivery();
/// <summary>
/// 配方数据信息
/// </summary>
public RecipeBoms recipeBoms { get; set; } = new RecipeBoms();
int OrderCount;
bool Initing;
public override void StartMain()
{

}

public override void Stop()
{

}

private void OrderChange(string subid, ORDER_STATUS oRDER_STATUS)
{
//EventBus.EventBus.GetInstance().Publish(new);
}

private void ReadData(string address, ushort len = 1, Action<bool[]> action = null)
{
EventBus.EventBus.GetInstance().Publish(new ReadModel() { Address = address, Length = len }, (o) =>
{
if (o != null && o.Length > 0 && o[0] is bool[] bools)
{
action(bools);
}
});
}

private void ReadData()
{
ThreadManage.GetInstance().StartLong(new Action(() =>
{
ReadData("M0.3", 3, new Action<bool[]>((bools) =>
{
mORKS.RobotTakeNoodle = bools[0];
mORKS.RobotOutMeal = bools[1];
mORKS.MoveTurntable = bools[2];
}));

ReadData("M100.0", 16, new Action<bool[]>((bools) =>
{
mORKS.InitComplete = bools[0];
mORKS.TakeBowlIdle = bools[1];
mORKS.TemperatureReached = bools[2];
mORKS.AllowFallNoodle = bools[3];
mORKS.RbTakeNoodleComplete = bools[4];
mORKS.RbFallNoodleComplete = bools[5];
mORKS.RbOutMealComplete = bools[6];
mORKS.RobotIdle = bools[7];
mORKS.TakeMealDetect = bools[8];
mORKS.MissingBowl = bools[9];
Initing = bools[10];
mORKS.TurntableLowerLimit = bools[11];
mORKS.MissingBowlSignal2 = bools[12];
mORKS.TurntableUpLimit = bools[13];
mORKS.FeedComplete = bools[14];
mORKS.TurntableMoveInPlace = bools[15];
}));

ReadData("M235.0", 1, new Action<bool[]>((bools) => { mORKS.Error = bools[0]; }));
//var errorStatus = ModbusTcpHelper.GetInstance.Read((ushort)ModbusTcpHelper.GetInstance.GetBoolAddress("M235.0"), ReadType.Coils, 1);
//if (errorStatus != null && errorStatus is bool error) mORKS.Error = error;

ReadData("M102.0", 7, new Action<bool[]>((bools) =>
{
for (int i = 0; i < 6; i++)
{
mORKS.NoodleCookerStatus[i] = bools[i];
}
mORKS.Feeding = bools[6];
}));

ReadData("M103.0", 6, new Action<bool[]>((bools) =>
{
for (int i = 0; i < 6; i++)
{
mORKS.CookNoodlesComplete[i] = bools[i];
}
}));

ReadData("M550.0", 20, new Action<bool[]>((bools) =>
{
//alarm.MachineLeftLowTemperature = bools[0];
//alarm.MachineRightLowTemperature = bools[1];
//alarm.Supply1_LossBowl = bools[2];
//alarm.Supply2_LossBowl = bools[3];
//alarm.Supply1_ErrorOutBowl = bools[4];
//alarm.Supply2_ErrorOutBowl = bools[5];
//alarm.PushBowlCylinderError = bools[6];
//alarm.NoodleMacCommunicateError = bools[7];
//alarm.DosingMacCommunicateError = bools[8];
//alarm.RobotMacCommunicateError = bools[9];
//alarm.RobotInitError = bools[11];
//alarm.RobotUrgentStop = bools[12];
//alarm.RobotNotInRemoteMode = bools[13];
//alarm.RobotNotInReady = bools[14];
//alarm.RobotSelfInException = bools[15];
}));

EventBus.EventBus.GetInstance().Publish(new ReadModel() { Address = "VW372", Length = 1 }, (o) =>
{
if (o != null && o.Length > 0 && o[0] is ushort value)
{
mORKS.TurntableFeedbackloc = value;
}
});

//var ResLoc = ModbusTcpHelper.GetInstance.Read(286, ReadType.HoldingRegisters);
//if (ResLoc != null)
//{
// if (ResLoc is ushort loc)
// {
// mORKS.TurntableFeedbackloc = loc;
// }
//}

Thread.Sleep(500);
}), "ReadPLCData");
}

/// <summary>
/// 数据解析
/// </summary>
public void DataParse<T>(T order)
{
OrderCount++;
MessageLog.GetInstance.Show($"接收到{OrderCount}次订单");
if (order is MorkOrderPush morkOrderPush)
{
foreach (var item in morkOrderPush.GoodBatchings)
{
//var res = Json<BatchingInfoPar>.Data.orderMaterialDelivery?.BatchingInfo?.FirstOrDefault(p => p.BatchingId == item.BatchingId);
var res = orderMaterialDelivery?.BatchingInfo?.FirstOrDefault(p => p.BatchingId == item.BatchingId);
if (res != null)
{
if (ushort.TryParse(res.BatchingLoc, out ushort loc))
{
if (loc >= 1 && loc <= 5)
{
if (mORKS.RBTakeNoodleTask.FirstOrDefault(p => p.SuborderId == morkOrderPush.SuborderId) == null)
mORKS.RBTakeNoodleTask.Enqueue(new OrderLocInfo() { Loc = ushort.Parse(res.BatchingLoc), SuborderId = morkOrderPush.SuborderId, BatchingId = res.BatchingId });
}
else if (loc >= 10 && loc <= 11)
{
int index = 0;
if (recipeBoms != null)
{
index = Array.FindIndex(recipeBoms.RecipeIds?.ToArray(), p => p.RecipeId == morkOrderPush.RecipeId);
index++;
}
if (mORKS.TakeBowlTask.FirstOrDefault(p => p.SuborderId == morkOrderPush.SuborderId) == null)
mORKS.TakeBowlTask.Enqueue(new OrderLocInfo()
{
Loc = ushort.Parse(res.BatchingLoc),
SuborderId = morkOrderPush.SuborderId,
RecipeNumber = (index >= 1 && index <= 10) ? (ushort)index : (ushort)0
});
}
}
}
}
}

}


public void Main()
{
ThreadManage.GetInstance().StartLong(new Action(() =>
{
mORKS.AllowRun = mORKS.InitComplete;
//GeneralConfig.Healthy = mORKS.Error && mORKS.InitComplete && !GeneralConfig.EnableLocalSimOrder;

TakeBowlTask();

TakeNoodleTask();

OutNoodleTask();

SingleDetect();

TurntableControl();

Thread.Sleep(100);

}), "MainTask");
}

public DeviceClientType DeviceType { get; }

public DeviceStatus Status { get; set; }
/// <summary>
/// 取碗控制
/// </summary>
private void TakeBowlTask()
{
if (mORKS.AllowRun && mORKS.TakeBowlTask.Count > 0 && !mORKS.TakeBowlIdle && !mORKS.TakeBowlInterlock)
{
if (mORKS.TakeBowlTask.TryDequeue(out OrderLocInfo orderLocInfo))
{
mORKS.TakeBowlId = orderLocInfo.SuborderId;
TakeBowlControl(orderLocInfo.Loc);
SetRecipeNumber(orderLocInfo.RecipeNumber);
OrderChange(mORKS.TakeBowlId, ORDER_STATUS.COOKING);
MessageLog.GetInstance.Show($"订单【{ mORKS.TakeBowlId}】执行取碗控制,位置:[{orderLocInfo.Loc}]");
}
mORKS.TakeBowlInterlock = true;
}
}

public void Initliaze(List<IPeripheral> peripherals)
/// <summary>
/// 转台控制
/// </summary>
private void TurntableControl()
{
peripherals.ForEach(item => { item.Init(); });
//EventBus.EventBus.GetInstance().Subscribe<Demo_MakeCoffeeEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
//if (GeneralConfig.EnableLocalSimOrder)
//{
// //不做轮询,直接取面,模拟订单使用
// if (mORKS.TurntableMoveInPlace && !mORKS.Feeding && mORKS.InitComplete && !mORKS.AllowTakeNoodle && mORKS.RBTakeNoodleTask.Count > 0)
// {
// if (mORKS.TurntableLowerLimit)
// {
// TurntableStart(mORKS.RBTakeNoodleTask.ElementAt(0).Loc);
// mORKS.TurntableLocLists.Clear();
// mORKS.AllowTakeNoodle = true;
// MessageLog.GetInstance.Show($"控制机器人去转台【{mORKS.RBTakeNoodleTask.ElementAt(0).Loc}】号位置取面");
// }
// }
//}
//else
{
//正常轮询
if (mORKS.TurntableMoveInPlace && !mORKS.Feeding && mORKS.InitComplete && !mORKS.AllowTakeNoodle && mORKS.RBTakeNoodleTask.Count > 0)
{
//var result = Json<BatchingInfoPar>.Data.orderMaterialDelivery.BatchingInfo.Where(p => p.BatchingId == mORKS.RBTakeNoodleTask.ElementAt(0).BatchingId).ToList();
var result = orderMaterialDelivery.BatchingInfo.Where(p => p.BatchingId == mORKS.RBTakeNoodleTask.ElementAt(0).BatchingId).ToList();
if (result != null)
{
var res = result.FirstOrDefault(P => P.BatchingLoc == mORKS.TurntableFeedbackloc.ToString());
if (mORKS.TurntableLowerLimit && res != null)
{
//if (mORKS.RBTakeNoodleTask.ElementAt(0).Loc != mORKS.TurntableFeedbackloc)
TurntableStart(mORKS.TurntableFeedbackloc);
mORKS.TurntableLocLists.Clear();
mORKS.AllowTakeNoodle = true;
MessageLog.GetInstance.Show($"控制机器人去转台【{mORKS.TurntableFeedbackloc}】号位置取面");
}
else
{
if (!mORKS.TurntableInterlock)
{
foreach (var item in result)
{
if (ushort.TryParse(item.BatchingLoc, out ushort loc))
{
if (mORKS.TurntableFeedbackloc != loc && !mORKS.TurntableLocLists.Contains(loc))
{
TurntableStart(loc);
MessageLog.GetInstance.Show($"没有物料检测的启动转台控制,转台位置:[{loc}]");
break;
}
else if (mORKS.TurntableFeedbackloc == loc && !mORKS.TurntableLocLists.Contains(loc)) mORKS.TurntableLocLists.Add(loc);
}
}
}
}
}
else MessageLog.GetInstance.Show("未找到可用的物料信息");
}
}

//转台到位检测
if (RTrig.GetInstance("TurntableInPlace").Start(mORKS.TurntableMoveInPlace && mORKS.CurrentLoc == mORKS.TurntableFeedbackloc))
{
mORKS.CurrentLoc = 0;
mORKS.TurntableInterlock = false;
MessageLog.GetInstance.Show("转台到位检测");
}

//补料完成检测
if (RTrig.GetInstance("FeedComplete").Start(mORKS.FeedComplete))
{
if (!mORKS.AllowTakeNoodle && mORKS.TurntableLocLists.Count > 0)
{
mORKS.TurntableLocLists.Clear();
mORKS.TurntableInterlock = false;
MessageLog.GetInstance.Show("补料完成检测");
}
}

//});
}

public void StartMain()
/// <summary>
/// 取面任务
/// </summary>
private void TakeNoodleTask()
{
//取面控制
if (mORKS.AllowRun && mORKS.RobotIdle && !mORKS.Feeding && !mORKS.RobotTaskInterlock && mORKS.AllowTakeNoodle && mORKS.TurntableMoveInPlace && !mORKS.TakeNoodleInterlock && !mORKS.OutNoodleing && mORKS.RBTakeNoodleTask.Count > 0)
{
int loc = Array.FindIndex(mORKS.NoodleCookerStatus, p => p == false);//查找煮面炉空闲位置
if (loc >= 0 && loc <= 5)
{
if (mORKS.RBTakeNoodleTask.TryDequeue(out OrderLocInfo orderLocInfo))
{
mORKS.CookNodelId[loc] = orderLocInfo.SuborderId;
SetFallNoodleLoc((ushort)(loc + 1));
//机器人开始取面
RobotTakeNoodle();
OrderChange(orderLocInfo.SuborderId, ORDER_STATUS.COOKING);
MessageLog.GetInstance.Show($"订单【{orderLocInfo.SuborderId}】,机器人倒面至【{loc + 1}】号煮面栏");
//写入煮面时间
//List<ushort> values = new List<ushort>();
//values.Add(Json<KeepDataBase>.Data.parSets.ElementAt(loc).Minute);
//values.Add(Json<KeepDataBase>.Data.parSets.ElementAt(loc).Second);
//ModbusTcpHelper.GetInstance.Write((ushort)ModbusTcpHelper.GetInstance.GetWordAddress($"VW{116 + (loc * 6)}"), WriteType.HoldingRegisters, values.ToArray());

mORKS.TakeNoodleInterlock = true;
}
}

}
}

public void Stop()
/// <summary>
/// 出餐控制
/// </summary>
private void OutNoodleTask()
{
if (mORKS.AllowFallNoodle && mORKS.RobotTaskInterlock && !mORKS.TakeNoodleInterlock && mORKS.RobotIdle && !mORKS.TakeMealDetect)
{
int loc = Array.FindIndex(mORKS.CookNodelId, p => p == mORKS.IngredientsCompleteId && p.Length > 0);
if (loc >= 0 && loc <= 5)
{
if (mORKS.CookNoodlesComplete[loc])
{
SetTakeNoodleLoc((ushort)(loc + 1));
RobotOutMeal();
CookNoodleStatusReset((ushort)(loc + 1));
ResetAllowFallNoodle();
mORKS.OutMealId = mORKS.IngredientsCompleteId;
mORKS.IngredientsCompleteId = string.Empty;
mORKS.CookNodelId[loc] = string.Empty;
MessageLog.GetInstance.Show($"{loc + 1}号位置出餐控制");
mORKS.OutNoodleing = true;
}
}
}
}

/// <summary>
/// 信号检测
/// </summary>
private void SingleDetect()
{
//允许倒面信号检测
if (RTrig.GetInstance("AllowFallNoodle").Start(mORKS.AllowFallNoodle))
{
mORKS.IngredientsCompleteId = mORKS.TakeBowlId;
mORKS.TakeBowlId = string.Empty;
MessageLog.GetInstance.Show($"碗到位,允许到面,{mORKS.IngredientsCompleteId}");
mORKS.TakeBowlInterlock = false;
}

//出餐完成信号检测
if (RTrig.GetInstance("CompleteChange").Start(mORKS.RbOutMealComplete))
{
OrderChange(mORKS.OutMealId, ORDER_STATUS.COMPLETED_COOK);
MessageLog.GetInstance.Show($"订单【{mORKS.OutMealId}】制作完成");
mORKS.OutNoodleing = false;
}

//取餐完成逻辑处理
if (DelayRTrig.GetInstance("CompleteChange1").Start(mORKS.RbOutMealComplete && !mORKS.TakeMealDetect, 2))
{
OrderChange(mORKS.OutMealId, ORDER_STATUS.COMPLETED_TAKE);
MessageLog.GetInstance.Show($"订单【{mORKS.OutMealId}】取餐完成");
ResetCookComplete();
mORKS.OutMealId = string.Empty;
}

//机器人取面完成信号检测
if (RTrig.GetInstance("TakeNoodleComplete").Start(mORKS.RbTakeNoodleComplete))
{
mORKS.TakeNoodleInterlock = false;
mORKS.AllowTakeNoodle = false;
mORKS.TurntableInterlock = false;
MessageLog.GetInstance.Show("机器人取面完成信号检测");
TakeNoodleCompleteReset();
}

//转台到位检测
//if (RTrig.GetInstance("TurntableInPlace").Start(mORKS.TurntableMoveInPlace))
//{
// mORKS.TurntableInterlock = false;
//}

int OutMealRequstCount = mORKS.CookNoodlesComplete.Where(p => p == true).ToList().Count;
int mlCount = mORKS.NoodleCookerStatus.Where(p => p == true).ToList().Count;
mORKS.RobotTaskInterlock = OutMealRequstCount > 0 && mORKS.AllowFallNoodle && (mlCount >= 2 || mORKS.RBTakeNoodleTask.Count == 0);
}


#region PLC 控制函数

private void WriteData(string address, object value)
{
EventBus.EventBus.GetInstance().Publish(new WriteModel() { Address = address, Value = value });
}

/// <summary>
/// 写入配方数据到 PLC
/// </summary>
private void WriteRecipeBoms()
{
List<ushort> recipeBoms = new List<ushort>();
if (this.recipeBoms == null) return;
foreach (var item in this.recipeBoms.RecipeIds)
{
foreach (var rec in item.Recipes)
{
recipeBoms.Add((ushort)rec);
}
}
if (recipeBoms.Count > 0)
{
//配方数据地址范围:VW2000 - VW2278
WriteData("VW2000", recipeBoms.ToArray());
}
else { MessageLog.GetInstance.Show("配方数据为空"); }
}


/// <summary>
/// 取面完成复位
/// </summary>
private void TakeNoodleCompleteReset()
{
WriteData("M100.4", false);
//ModbusTcpHelper.GetInstance.Write(1124, WriteType.Coils, false);
}

/// <summary>
/// 指定煮面口状态复位
/// </summary>
/// <param name="num"></param>
private void CookNoodleStatusReset(int num)
{
if (num >= 1 && num <= 6)
{
//ushort addRess = (ushort)(1136 + num - 1);

WriteData($"102.{num - 1}", false);

//ModbusTcpHelper.GetInstance.Write(addRess, WriteType.Coils, false);
MessageLog.GetInstance.Show($"{num}号煮面口占用复位");
}

}

/// <summary>
/// 写配方编号
/// </summary>
/// <param name="num"></param>
private void SetRecipeNumber(ushort num)
{
WriteData("VW0", num);
//ModbusTcpHelper.GetInstance.Write(100, WriteType.HoldingRegisters, num);
}

/// <summary>
/// 启动转台
/// </summary>
/// <param name="loc"></param>
private void TurntableStart(ushort loc)
{
mORKS.CurrentLoc = loc;
mORKS.TurntableInterlock = true;
mORKS.TurntableLocLists.Add(loc);
WriteData("VW0", loc);
WriteData("M0.5", true);
//ModbusTcpHelper.GetInstance.Write(101, WriteType.HoldingRegisters, loc);
//ModbusTcpHelper.GetInstance.Write(325, WriteType.Coils, true);
}

/// <summary>
/// 设置倒面位置
/// </summary>
/// <param name="loc"></param>
private void SetFallNoodleLoc(ushort loc)
{
WriteData("VW4", loc);
//ModbusTcpHelper.GetInstance.Write(102, WriteType.HoldingRegisters, loc);
}

/// <summary>
/// 设置取面位置
/// </summary>
/// <param name="loc"></param>
private void SetTakeNoodleLoc(ushort loc)
{
WriteData("VW6", loc);
//ModbusTcpHelper.GetInstance.Write(103, WriteType.HoldingRegisters, loc);
}

/// <summary>
/// 取碗控制
/// </summary>
/// <param name="loc"></param>
private void TakeBowlControl(ushort loc)
{
if (loc == 10)//小碗
{
WriteData("M0.1", true);
//ModbusTcpHelper.GetInstance.Write(321, WriteType.Coils, true);
}
else if (loc == 11)//大碗
{
WriteData("M0.2", true);
//ModbusTcpHelper.GetInstance.Write(322, WriteType.Coils, true);
}
}

/// <summary>
/// 机器人取面
/// </summary>
private void RobotTakeNoodle()
{
WriteData("M0.3", true);
//ModbusTcpHelper.GetInstance.Write(323, WriteType.Coils, true);
}

/// <summary>
/// 机器人取餐
/// </summary>
private void RobotOutMeal()
{
WriteData("M0.4", true);
//ModbusTcpHelper.GetInstance.Write(324, WriteType.Coils, true);
//var result = ModbusTcpHelper.GetInstance.Read(324, ReadType.Coils);
//if (result is bool res)
// while (!res)
// {
// ModbusTcpHelper.GetInstance.Write(324, WriteType.Coils, true);
// }
}

/// <summary>
/// 制作完成信号复位
/// </summary>
private void ResetCookComplete()
{
WriteData("M100.6", false);
//ModbusTcpHelper.GetInstance.Write(1126, WriteType.Coils, false);
}

/// <summary>
/// 复位允许取面信号
/// </summary>
private void ResetAllowFallNoodle()
{
WriteData("M100.3", false);
//ModbusTcpHelper.GetInstance.Write(1123, WriteType.Coils, false);
}

/// <summary>
/// 设备初始化
/// </summary>
public async void DeviceInit()
{
WriteData("M0.0", true);
//ModbusTcpHelper.GetInstance.Write(320, WriteType.Coils, true);
await Task.Delay(1000);
//ModbusTcpHelper.GetInstance.Write(320, WriteType.Coils, false);
WriteData("M0.0", false);

}
#endregion


}
}

+ 346
- 0
BPASmartClient.MorkS/GVL_MORKS.cs Visa fil

@@ -0,0 +1,346 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.MorkS
{
public class GVL_MORKS
{
/// <summary>
/// 机器人取面
/// PLC -> M0.3
/// ModbusTcp -> 323
/// </summary>
public bool RobotTakeNoodle { get; set; }

/// <summary>
/// 机器人出餐
/// PLC -> M0.4
/// ModbusTcp -> 324
/// </summary>
public bool RobotOutMeal { get; set; }

/// <summary>
/// 移动转台
/// PLC -> M0.5
/// ModbusTcp -> 325
/// </summary>
public bool MoveTurntable { get; set; }


#region 临时变量
/// <summary>
/// 允许运行
/// </summary>
//[Circuit(new string[] { "机器人取面", "取碗控制" }, "允许运行")]
//[VariableMonitor("允许运行")]
public bool AllowRun { get; set; }

/// <summary>
/// //机器人任务互锁信号
/// </summary>
//[Circuit(new string[] { "机器人取面", "出面控制" }, "机器人互锁", new bool[] { true, false })]
//[VariableMonitor("机器人任务互锁信号")]
public bool RobotTaskInterlock { get; set; }

/// <summary>
/// 取碗互锁信号
/// </summary>
//[Circuit("取碗控制", "取碗互锁", true)]
//[VariableMonitor("取碗互锁信号")]
public bool TakeBowlInterlock { get; set; }

/// <summary>
/// 取面互锁信号
/// </summary>
//[Circuit(new string[] { "机器人取面", "出面控制" }, "取面互锁信号", new bool[] { true, true })]
//[VariableMonitor("取面互锁信号")]
public bool TakeNoodleInterlock { get; set; }

/// <summary>
/// 出面中
/// </summary>
//[Circuit("机器人取面", "出面中", true)]
//[VariableMonitor("出面中")]
public bool OutNoodleing { get; set; }

/// <summary>
/// 允许取面
/// </summary>
//[Circuit(new string[] { "转台控制", "机器人取面" }, "允许取面", new bool[] { true, false })]
//[VariableMonitor("允许取面")]
public bool AllowTakeNoodle { get; set; }

/// <summary>
/// 转台互锁信号
/// </summary>
//[VariableMonitor("转台互锁信号")]
public bool TurntableInterlock { get; set; }
#endregion


/// <summary>
/// 初始化完成
/// PLC -> M100.0
/// ModbusTcp -> 1120
/// </summary>
//[Circuit(new string[] { "允许运行", "转台控制", "转台控制" }, "初始化完成")]
//[VariableMonitor("初始化完成", "M100.0", "1120")]
public bool InitComplete { get; set; }

/// <summary>
/// 取碗机构空闲,True:忙碌,false:空闲
/// PLC -> M100.1
/// ModbusTcp -> 1121
/// </summary>
//[Circuit("取碗控制", "取碗机构空闲", true)]
//[VariableMonitor("取碗机构空闲", "M100.1", "1121")]
public bool TakeBowlIdle { get; set; }

/// <summary>
/// 温度到达,True:表示到达,false:未到达
/// PLC -> M100.2
/// ModbusTcp -> 1122
/// </summary>
//[Circuit("允许运行", "温度到达")]
//[VariableMonitor("温度到达", "M100.2", "1122")]
public bool TemperatureReached { get; set; }

/// <summary>
/// 允许到面,配料完成
/// PLC -> M100.3
/// ModbusTcp -> 1123
/// </summary>
//[Circuit("出面控制", "允许到面")]
//[VariableMonitor("允许到面", "M100.3", "1123")]
public bool AllowFallNoodle { get; set; }

/// <summary>
/// 机器人取面完成
/// PLC -> M100.4
/// ModbusTcp -> 1124
/// </summary>
//[VariableMonitor("机器人取面完成", "M100.4", "1124")]
public bool RbTakeNoodleComplete { get; set; }

/// <summary>
/// 机器人倒面完成
/// PLC -> M100.5
/// ModbusTcp -> 1125
/// </summary>
//[VariableMonitor("机器人倒面完成", "M100.5", "1125")]
public bool RbFallNoodleComplete { get; set; }

/// <summary>
/// 机器人出餐完成,上报取餐完成
/// PLC -> M100.6
/// ModbusTcp -> 1126
/// </summary>
//[VariableMonitor("机器人出餐完成", "M100.6", "1126")]
public bool RbOutMealComplete { get; set; }

/// <summary>
/// 机器人空闲
/// PLC -> M100.7
/// ModbusTcp -> 1127
/// </summary>
//[Circuit(new string[] { "机器人取面", "出面控制" }, "机器人空闲")]
//[VariableMonitor("机器人空闲", "M100.7", "1127")]
public bool RobotIdle { get; set; }

/// <summary>
/// 取餐口检测
/// PLC -> M101.0
/// ModbusTcp -> 1128
/// </summary>
//[Circuit("出面控制", "取餐口检测", true)]
//[VariableMonitor("取餐口检测", "M101.0", "1128")]
public bool TakeMealDetect { get; set; }

/// <summary>
/// 缺碗信号,false:缺碗,true:有碗
/// PLC -> M101.1
/// ModbusTcp -> 1129
/// </summary>
//[VariableMonitor("缺碗信号", "M101.1", "1129")]
public bool MissingBowl { get; set; }

/// <summary>
/// 设备初始化中,执行中等于1,2秒后复位
/// PLC -> M101.2
/// ModbusTcp -> 1130
/// </summary>
//[VariableMonitor("设备初始化中", "M101.2", "1130")]
public bool DeviceIniting { get; set; }

/// <summary>
/// 转台下限检测
/// PLC -> M101.3
/// ModbusTcp -> 1131
/// </summary>
//[Circuit("转台控制", "转台下限检测有物料")]
//[VariableMonitor("转台下限检测", "M101.3", "1131")]
public bool TurntableLowerLimit { get; set; }

/// <summary>
/// 缺碗信号 2
/// PLC -> M101.4
/// ModbusTcp -> 1132
/// </summary>
//[VariableMonitor("缺碗信号 2", "M101.4", "1132")]
public bool MissingBowlSignal2 { get; set; }

/// <summary>
/// 转台上限检测
/// PLC -> M101.5
/// ModbusTcp -> 1133
/// </summary>
//[VariableMonitor("转台上限检测", "M101.5", "1133")]
public bool TurntableUpLimit { get; set; }

/// <summary>
/// 补料完成
/// PLC -> M101.6
/// ModbusTcp -> 1134
/// </summary>
//[VariableMonitor("补料完成", "M101.6", "1134")]
public bool FeedComplete { get; set; }

/// <summary>
/// 转台移动到位
/// PLC -> M101.7
/// ModbusTcp -> 1135
/// </summary>
//[Circuit(new string[] { "转台控制", "机器人取面" }, "转台移动到位")]
//[VariableMonitor("转台移动到位", "M101.7", "1135")]
public bool TurntableMoveInPlace { get; set; }

/// <summary>
/// 煮面炉状态,True:忙碌,false:空闲
/// M102.0 - M102.5
/// 1136 - 1141
/// </summary>
//[VariableMonitor("煮面炉状态", "M102.0", "1136")]
public bool[] NoodleCookerStatus { get; set; } = new bool[6] { false, false, false, false, false, false };

/// <summary>
/// 补料中
/// M102.6
/// 1142
/// </summary>
//[VariableMonitor("补料中", "M102.6", "1142")]
public bool Feeding { get; set; }

/// <summary>
/// 煮面完成,上升后给信号
/// M103.0 - M103.5
/// 1144 - 1149
/// </summary>
//[VariableMonitor("煮面完成", "M103.0", "1144")]
public bool[] CookNoodlesComplete { get; set; } = new bool[6] { false, false, false, false, false, false };

/// <summary>
/// 硬件设备异常
/// PLC -> M235.0
/// True:设备正常,False:设备异常
/// </summary>
//[VariableMonitor("硬件设备异常", "M235.0", "")]
public bool Error { get; set; } = false;

/// <summary>
/// 配方编号
/// PLC -> VW0
/// ModbusTcp -> 100
/// </summary>
//[VariableMonitor("配方编号", "VW0", "100")]
public ushort RecipeNumber { get; set; }

/// <summary>
/// 转台设置位置
/// PLC -> VW2
/// ModbusTcp -> 101
/// </summary>
//[VariableMonitor("转台设置位置", "VW2", "101")]
public ushort TurntableLoc { get; set; }

/// <summary>
/// 到面至煮面炉位置
/// PLC -> VW4
/// ModbusTcp -> 102
/// </summary>
//[VariableMonitor("到面至煮面炉位置", "VW4", "102")]
public ushort FallNoodleLoc { get; set; }

/// <summary>
/// 取面位置
/// PLC -> VW6
/// ModbusTcp -> 103
/// </summary>
//[VariableMonitor("取面位置", "VW6", "103")]
public ushort TakeNoodleLoc { get; set; }

/// <summary>
/// 转台反馈位置
/// PLC -> VW372
/// ModbusTcp -> 286
/// </summary>
//[VariableMonitor("转台反馈位置", "VW372", "286")]
public ushort TurntableFeedbackloc { get; set; }

/// <summary>
/// 机器人取面位置队列
/// </summary>
//[Circuit(new string[] { "转台控制", "机器人取面" }, "有机器人取面队列")]
public ConcurrentQueue<OrderLocInfo> RBTakeNoodleTask { get; set; } = new ConcurrentQueue<OrderLocInfo>();

/// <summary>
/// 出碗队列
/// </summary>
//[Circuit("取碗控制", "有取碗队列数量")]
public ConcurrentQueue<OrderLocInfo> TakeBowlTask { get; set; } = new ConcurrentQueue<OrderLocInfo>();

/// <summary>
/// 是否有面条
/// </summary>
public bool IsNoodles { get; set; } = true;



#region 订单ID记录
/// <summary>
/// 取碗订单ID
/// </summary>
public string TakeBowlId = string.Empty;

/// <summary>
/// 配料完成订单ID
/// </summary>
public string IngredientsCompleteId = string.Empty;

/// <summary>
/// 煮面口对应的订单ID
/// </summary>
public string[] CookNodelId = new string[6] { string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, };

/// <summary>
/// 出餐订单ID
/// </summary>
public string OutMealId = string.Empty;

/// <summary>
/// 转台位置轮询
/// </summary>
public List<ushort> TurntableLocLists = new List<ushort>();

/// <summary>
/// 转台当前启动位置
/// </summary>
//[VariableMonitor("转台当前启动位置")]
public ushort CurrentLoc { get; set; } = 0;

#endregion
}
}

+ 16
- 0
BPASmartClient.MorkS/OrderLocInfo.cs Visa fil

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.MorkS
{
public class OrderLocInfo
{
public string SuborderId { get; set; }
public ushort Loc { get; set; }
public ushort RecipeNumber { get; set; }
public int BatchingId { get; set; }
}
}

+ 0
- 11
BPASmartClient/DeviceInfo.xml Visa fil

@@ -43,17 +43,6 @@
</Peripherals>
</Device>

<!--<Device Name="MorkM" Module="BPASmartClient.MorkS.Control" DeviceId="2">
<Peripherals>
<Peripheral Module="BPASmartClient.MORKSM.BK.PLC.MorksMachine">
<Parameters>
<IpAddress>127.0.0.1</IpAddress>
<Port>1</Port>
</Parameters>
</Peripheral>
</Peripherals>
</Device>-->



</BPADevices>

Laddar…
Avbryt
Spara