Browse Source

合并MORKIC

样式分支
NXX 2 years ago
parent
commit
fe38705932
19 changed files with 2055 additions and 37 deletions
  1. +85
    -0
      BPASmartClient.DRCoffee/CommandHandler.cs
  2. +76
    -0
      BPASmartClient.DRCoffee/MorkCStatus.cs
  3. +118
    -0
      BPASmartClient.GSIceCream/CommandHandler.cs
  4. +131
    -0
      BPASmartClient.GSIceCream/MorkIStatus.cs
  5. +135
    -0
      BPASmartClient.Lebai/LebaiRobot.cs
  6. +21
    -0
      BPASmartClient.Model/BatchingInfoPar.cs
  7. +14
    -0
      BPASmartClient.Model/单片机/SCChipEvent.cs
  8. +1
    -0
      BPASmartClient.MorkT/BPASmartClient.MorkT.csproj
  9. +164
    -0
      BPASmartClient.MorkT/Control_MorkT.cs
  10. +0
    -36
      BPASmartClient.MorkT/Device_MorkT.cs
  11. +37
    -0
      BPASmartClient.MorkT/GLV_MorkT.cs
  12. +22
    -0
      BPASmartClient.MorkT/OrderLocInfo.cs
  13. +122
    -0
      BPASmartClient.MorkT/PolymerBatching.cs
  14. +132
    -0
      BPASmartClient.SCChip/ChipStatus.cs
  15. +197
    -0
      BPASmartClient.SCChip/CommandHandler.cs
  16. +23
    -0
      HBLConsole.MORKIC/BPASmartClient.MORKIC.csproj
  17. +647
    -0
      HBLConsole.MORKIC/Control_MORKIC.cs
  18. +122
    -0
      HBLConsole.MORKIC/PolymerBatching.cs
  19. +8
    -1
      SmartClient.sln

+ 85
- 0
BPASmartClient.DRCoffee/CommandHandler.cs View File

@@ -0,0 +1,85 @@

using BPASmartClient.EventBus;
using BPASmartClient.Model;
using BPASmartClient.Model.咖啡机.Enum;
using BPASmartClient.SerialPort;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static BPASmartClient.EventBus.EventBus;

namespace BPASmartClient.DRCoffee
{
/// <summary>
/// 指令封装
/// </summary>
internal class CommandHandler
{
byte[] cmdAsk;
private SerialPortClient commProxy;
private DrCoffeePackage drinksOrder = new DrCoffeePackage();

public Action<bool> PauseAsk { get; set; }
/// <summary>
/// 初始化
/// </summary>
internal void Init(SerialPortClient commProxy)
{
this.commProxy = commProxy;

DrCoffeePackage package = new DrCoffeePackage();
package.CommCmd = DrCoffeeCommCmd.饮品制作指令;
cmdAsk = DrCoffee.Packe(package);
drinksOrder.CommCmd = DrCoffeeCommCmd.饮品制作指令;

EventBus.EventBus.GetInstance().Subscribe<DRCoffee_MakeCoffeeEvent>(0,MakeCoffeeEventHandle);
EventBus.EventBus.GetInstance().Subscribe<DRCoffee_CancelMakeCoffeeEvent>(0, CancelMakeCoffeeEventHandle);
EventBus.EventBus.GetInstance().Subscribe<DRCoffee_CoffeeCommCmdEvent>(0, CoffeeCommCmdEventHandle);

}

private void CoffeeCommCmdEventHandle(IEvent @event, EventCallBackHandle callBack)
{
PauseAsk?.Invoke(true);
Thread.Sleep(200);
drinksOrder.CommCmd = ((DRCoffee_CoffeeCommCmdEvent)@event).CommCmd;
commProxy.SendData(DrCoffee.Packe(drinksOrder));
Thread.Sleep(200);
PauseAsk?.Invoke(false);
}

private void CancelMakeCoffeeEventHandle(IEvent @event, EventCallBackHandle callBack)
{
PauseAsk?.Invoke(true);
Thread.Sleep(200);
drinksOrder.CommCmd = DrCoffeeCommCmd.取消应用指令;
drinksOrder.DrinksCode = 0;
commProxy.SendData(DrCoffee.Packe(drinksOrder));
Thread.Sleep(200);
PauseAsk?.Invoke(false);
}

private void MakeCoffeeEventHandle(IEvent @event, EventCallBackHandle callBack)
{
PauseAsk?.Invoke(true);
Thread.Sleep(200);
drinksOrder.CommCmd = DrCoffeeCommCmd.饮品制作指令;
drinksOrder.DrinksCode = ((DRCoffee_MakeCoffeeEvent)@event).DrinkCode;
commProxy.SendData(DrCoffee.Packe(drinksOrder));

Thread.Sleep(200);
PauseAsk?.Invoke(false);
}

/// <summary>
/// 发送状态询问
/// </summary>
internal byte[] GetStatusAsk()
{
return cmdAsk;
}
}
}

+ 76
- 0
BPASmartClient.DRCoffee/MorkCStatus.cs View File

@@ -0,0 +1,76 @@
using BPASmartClient.DRCoffee;
using BPASmartClient.EventBus;
using BPASmartClient.Helper;
using BPASmartClient.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.DRCoffee
{
public class MorkCStatus : Singleton<MorkCStatus>
{
private DRCoffee_CoffeEndCookEvent coffeEndCook = new DRCoffee_CoffeEndCookEvent();
private DateTime lastRefreshTime = DateTime.MinValue;
/// <summary>
/// 是否在线
/// </summary>
public bool OnLine { get { return DateTime.Now.Subtract(lastRefreshTime).TotalSeconds <= 3; } }
/// <summary>
/// 咖啡机状态
/// </summary>
public DrCoffeeStatus CoffeeStatus { get; set; }
/// <summary>
/// 应用状态
/// </summary>
public DrCoffeeAppStatus AppStatus { get; set; }
/// <summary>
/// 警告信息
/// </summary>
public DrCoffeeWarning Warning { get; set; }
/// <summary>
/// 故障信息
/// </summary>
public DrCoffeeFault Fault { get; set; }

public bool CanDo
{
get

{
if (!OnLine)
return false;
if (Warning != DrCoffeeWarning.无警告)
return false;
if (Fault != DrCoffeeFault.无故障)
return false;
return true;
}
}

/// <summary>
/// 咖啡机状态解析
/// </summary>
/// <param name="package"></param>
public void ProcessPackage(DrCoffeePackage package)
{
if (CoffeeStatus == DrCoffeeStatus.Running && package.Status != DrCoffeeStatus.Running)
{
CoffeeStatus = package.Status;
coffeEndCook.Publish();
}
else
{
CoffeeStatus = package.Status;
}

AppStatus = package.ApplicationStatus;
Warning = package.Warning;
Fault = package.Fault;

lastRefreshTime = DateTime.Now;
}
}
}

+ 118
- 0
BPASmartClient.GSIceCream/CommandHandler.cs View File

@@ -0,0 +1,118 @@

using BPASmartClient.EventBus;
using BPASmartClient.GSIceCream;
using BPASmartClient.Message;
using BPASmartClient.Model;
using BPASmartClient.Model.冰淇淋.Enum;
using BPASmartClient.SerialPort;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static BPASmartClient.EventBus.EventBus;

namespace BPASmartClient.DRCoffee
{
/// <summary>
/// 指令封装
/// </summary>
internal class CommandHandler
{
byte[] cmdHeartDW;

private SerialPortClient commProxy;
private GSIceCream_EndCookEvent iceCreamEndCook = new GSIceCream_EndCookEvent();
public Action<bool> PauseAsk { get; set; }

/// <summary>
/// 初始化
/// </summary>
internal void Init(SerialPortClient commProxy)
{
this.commProxy = commProxy;
ICMSG_Heart_DW heartDW = new ICMSG_Heart_DW();
cmdHeartDW = IcPack.StructureToByte(heartDW);
EventBus.EventBus.GetInstance().Subscribe<GSIceCream_ModeSetEvent>(0, ModeSetEventHandle);
EventBus.EventBus.GetInstance().Subscribe<GSIceCream_DischargeEvent>(0,DischargeEventHandle);
}
/// <summary>
/// 发送心跳
/// </summary>
internal byte[] GetHeartDW()
{
return cmdHeartDW;
}


public void ModeSetEventHandle(IEvent @event, EventCallBackHandle callBack = null)
{
PauseAsk?.Invoke(true);
Thread.Sleep(200);
var data = IcPack.StructureToByte(ICMSG_MODE_DW.Build(((GSIceCream_ModeSetEvent)@event).Mode));
commProxy.SendData(data);
Thread.Sleep(200);
PauseAsk?.Invoke(false);
MessageLog.GetInstance.Show(string.Format("设置模式[{0}]", ((GSIceCream_ModeSetEvent)@event).Mode));
}

public void DischargeEventHandle(IEvent @event, EventCallBackHandle callBack = null)
{
if (MorkIStatus.GetInstance().Fault != MORKI_FAULT.未发生故障)
{
MessageLog.GetInstance.Show(string.Format("当前存在故障[{0}%],不允许制作", MorkIStatus.GetInstance().Fault));
callBack?.Invoke(false);
return;
}
if (MorkIStatus.GetInstance().CXB <= 86)
{
MessageLog.GetInstance.Show(string.Format("当前成型比[{0}%],低于86%,不允许制作", MorkIStatus.GetInstance().CXB));
callBack?.Invoke(false);
return;
}

bool modeRight = MorkIStatus.GetInstance().CurrentMode == MORKI_MODE.制冷模式;

if (!modeRight)
{
PauseAsk?.Invoke(true);
Thread.Sleep(200);

var temp = IcPack.StructureToByte(ICMSG_MODE_DW.Build(MORKI_MODE.制冷模式));
commProxy.SendData(temp);

Thread.Sleep(200);
PauseAsk?.Invoke(false);
MessageLog.GetInstance.Show(string.Format("出料操作->设置模式[{0}]", MORKI_MODE.制冷模式));

DateTime freeTime = DateTime.Now.AddSeconds(5);
while (DateTime.Now < freeTime)
{
Thread.Sleep(10);
modeRight = MorkIStatus.GetInstance().CurrentMode == MORKI_MODE.制冷模式;
if (modeRight)
break;
}
}

if (modeRight)
{
PauseAsk?.Invoke(true);
Thread.Sleep(200);
var data = IcPack.StructureToByte(ICMSG_MODE_DW.Build(MORKI_MODE.打料));
commProxy.SendData(data);
Thread.Sleep(200);
PauseAsk?.Invoke(false);
iceCreamEndCook.Publish();
MessageLog.GetInstance.Show(string.Format("出料操作->设置模式[{0}]", MORKI_MODE.打料));
callBack?.Invoke(true);
}
else
{
MessageLog.GetInstance.Show(string.Format("出料操作->模式切换失败,当前模式[{0}],不允许出料", MorkIStatus.GetInstance().CurrentMode));
callBack?.Invoke(false);
}
}
}
}

+ 131
- 0
BPASmartClient.GSIceCream/MorkIStatus.cs View File

@@ -0,0 +1,131 @@
using BPASmartClient.GSIceCream;
using BPASmartClient.Helper;
using BPASmartClient.Message;
using BPASmartClient.Model.冰淇淋.Enum;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static BPASmartClient.GSIceCream.MessageDefine;

namespace BPASmartClient.GSIceCream
{
public class MorkIStatus : Singleton<MorkIStatus>
{
private DateTime lastRefreshTime = DateTime.MinValue;
/// <summary>
/// 是否在线
/// </summary>
public bool OnLine { get { return DateTime.Now.Subtract(lastRefreshTime).TotalSeconds <= 3; } }
/// <summary>
/// 预冷温度
/// </summary>
public short YLWD { get; set; }
/// <summary>
/// 回气温度
/// </summary>
public short HQWD { get; set; }
/// <summary>
/// 环境温度
/// </summary>
public short HJWD { get; set; }
/// <summary>
/// 电流
/// </summary>
public short DL { get; set; }
/// <summary>
/// 电压
/// </summary>
public short DY { get; set; }
/// <summary>
/// 当前模式
/// </summary>
public MORKI_MODE CurrentMode { get; set; }
/// <summary>
/// 故障
/// </summary>
public MORKI_FAULT Fault { get; set; }
/// <summary>
/// 成型比
/// </summary>
public byte CXB { get; set; }
/// <summary>
/// 成型比(门限)
/// </summary>
public byte CXB_Threshold { get; set; }
/// <summary>
/// 打料完成(完成为true,正在打料为false)
/// </summary>
public bool DLCompleted { get; set; }


public bool CanDo
{
get
{
if (!OnLine)
return false;
if (Fault != MORKI_FAULT.未发生故障)
return false;
if (CXB < CXB_Threshold)
return false;
return true;
}
}

private void ProcessHeart(ICMSG_Heart_UP heartUpMsg)
{
CurrentMode = heartUpMsg.MS;
YLWD = BitConverter.ToInt16(new byte[] { heartUpMsg.YLWD_L, heartUpMsg.YLWD_H }, 0);
HQWD = BitConverter.ToInt16(new byte[] { heartUpMsg.HQWD_L, heartUpMsg.HQWD_H }, 0);
HJWD = BitConverter.ToInt16(new byte[] { heartUpMsg.HJWD_L, heartUpMsg.HJWD_H }, 0);
DL = BitConverter.ToInt16(new byte[] { heartUpMsg.DL_L, heartUpMsg.DL_H }, 0);
Fault = (MORKI_FAULT)BitConverter.ToInt16(new byte[] { heartUpMsg.GZ_L, heartUpMsg.GZ_H }, 0);
CXB = heartUpMsg.CXB;
DLCompleted = (heartUpMsg.DLTJ >> 4 & 1) == 1;

if (RTrig.GetInstance("打料完成检测").Start(DLCompleted))
{
MessageLog.GetInstance.Show("打料完成");
}

if (RTrig.GetInstance("打料中检测").Start(!DLCompleted))
{
MessageLog.GetInstance.Show("打料中");
}
//MessageLog.GetInstance.Show(string.Format("当前模式为:{0}", CurrentMode));

}

private void ProcessModeUp(ICMSG_MODE_UP modeUpMsg)
{
MessageLog.GetInstance.Show(string.Format("模式返回为:{0}", modeUpMsg.Mode));
}

public void ProcessMsg(byte[] data)
{
lastRefreshTime = DateTime.Now;
try
{
if (data.Length < 5)
return;
switch (data[2])
{
case (byte)IC_CMD.HEART:
var msg = IcPack.ByteToStructure<ICMSG_Heart_UP>(data.ToArray());
ProcessHeart(msg);
break;
case (byte)IC_CMD.MODE:
var modeUp = IcPack.ByteToStructure<ICMSG_MODE_UP>(data.ToArray());
ProcessModeUp(modeUp);
break;
}
}
catch (Exception ex)
{

}
}
}
}

+ 135
- 0
BPASmartClient.Lebai/LebaiRobot.cs View File

@@ -67,6 +67,12 @@ namespace BPASmartClient.Lebai
public const int SENCE_接3号冰淇淋 = 10041; public const int SENCE_接3号冰淇淋 = 10041;
public const int SENCE_放咖啡位置 = 10042; public const int SENCE_放咖啡位置 = 10042;
public const int SENCE_放冰淇淋位置 = 10043; public const int SENCE_放冰淇淋位置 = 10043;

//add 新加场景
public const int SENCE_接咖啡_新 = 10051;
public const int SENCE_咖啡杯回原点 = 10050;
public const int SENCE_冰淇淋杯回原点 = 10049;
public const int SENCE_取咖啡出餐 = 10052;
#endregion #endregion


/// <summary> /// <summary>
@@ -82,6 +88,10 @@ namespace BPASmartClient.Lebai
/// </summary> /// </summary>
public int OutputSingalValue { get; set; } public int OutputSingalValue { get; set; }



private volatile static LebaiRobot _Instance;
public static LebaiRobot GetInstance => _Instance ?? (_Instance = new LebaiRobot());
private LebaiRobot() { }
private LebaiRobotClient client; private LebaiRobotClient client;
private RobotData robotData; private RobotData robotData;
public bool IsIdle { get; set; } = false; public bool IsIdle { get; set; } = false;
@@ -110,6 +120,74 @@ namespace BPASmartClient.Lebai
StartRobot(); StartRobot();
MessageLog.GetInstance.Show("乐百机器人连接成功!"); MessageLog.GetInstance.Show("乐百机器人连接成功!");
} }
/// <summary>
/// 机器人重连检测
/// </summary>
/// <param name="ip"></param>
public void Reconnect(string ip)
{
if (client == null)
{
try
{
client = new LebaiRobotClient(ip);
}
catch (Exception)
{

// throw;
}
}
check:
while (robotData != null)
{

try
{
robotData = client.GetRobotData().Result;
}
catch (Exception)
{
robotData = null;
// throw;
}
}
MessageLog.GetInstance.Show("乐白机器人断开连接,准备重连");
int num = 0;
while (num < 6 && robotData == null)
{
try
{

robotData = client.GetRobotData().Result;
}
catch (Exception ex)
{
if (num == 5)
{
MessageLog.GetInstance.ShowEx(ex.ToString());
}
}

if (num < 5 && robotData == null)
{
Thread.Sleep(1000);
MessageLog.GetInstance.Show($"乐白机器人正在尝试第{num + 1}次重连....");
}
else if (num >= 5 && robotData == null)
{
MessageLog.GetInstance.Show("乐白机器人重连失败,请检查硬件连接");
//return;
}
num++;
}
if (robotData != null)
{
StartRobot();
MessageLog.GetInstance.Show("乐白机器人重连成功");
}
goto check;
}


public void GetRobotModeStatus() public void GetRobotModeStatus()
{ {
@@ -143,6 +221,63 @@ namespace BPASmartClient.Lebai
} }
} }


/// <summary>
/// 启动示教
/// </summary>
public async void StartTeachMode()
{
try
{
if (robotData != null)
{
await client.TeachMode();
MessageLog.GetInstance.Show("机器人切换为示教模式.");
}
}
catch (Exception ex)
{
MessageLog.GetInstance.ShowEx(ex.ToString());
}
}

/// <summary>
/// 结束示教
/// </summary>
public async void EndtTeachMode()
{
try
{
if (robotData != null)
{
await client.EndTeachMode();
MessageLog.GetInstance.Show("机器人切换为停止示教模式.");
}
}
catch (Exception ex)
{
MessageLog.GetInstance.ShowEx(ex.ToString());
}
}

/// <summary>
/// 机器人急停
/// </summary>
public async void EStopRobot()
{
try
{
if (robotData != null)
{
await client.EStop();
MessageLog.GetInstance.Show("机器人急停");
}
}
catch (Exception ex)
{
MessageLog.GetInstance.ShowEx(ex.ToString());
}
}

/// <summary> /// <summary>
/// 获取抓手重量 /// 获取抓手重量
/// </summary> /// </summary>


+ 21
- 0
BPASmartClient.Model/BatchingInfoPar.cs View File

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

namespace BPASmartClient.Model
{
public class BatchingInfoPar
{
/// <summary>
/// 订单物料信息
/// </summary>
public OrderMaterialDelivery orderMaterialDelivery { get; set; } = new OrderMaterialDelivery();
/// <summary>
/// 配方数据信息
/// </summary>
public RecipeBoms recipeBoms { get; set; } = new RecipeBoms();
}
}

+ 14
- 0
BPASmartClient.Model/单片机/SCChipEvent.cs View File

@@ -48,4 +48,18 @@ namespace BPASmartClient.Model.单片机
{ {
public bool TurnOn { get; set; } public bool TurnOn { get; set; }
} }
/// <summary>
/// 检测有无杯子
/// </summary>
public class ArticleExitsEvent : BaseEvent
{

}
/// <summary>
/// 检测物品距离
/// </summary>
public class ArticleDistEvent : BaseEvent
{

}
} }

+ 1
- 0
BPASmartClient.MorkT/BPASmartClient.MorkT.csproj View File

@@ -6,6 +6,7 @@


<ItemGroup> <ItemGroup>
<ProjectReference Include="..\BPASmartClient.Device\BPASmartClient.Device.csproj" /> <ProjectReference Include="..\BPASmartClient.Device\BPASmartClient.Device.csproj" />
<ProjectReference Include="..\BPASmartClient.Lebai\BPASmartClient.Lebai.csproj" />
<ProjectReference Include="..\BPASmartClient.Model\BPASmartClient.Model.csproj" /> <ProjectReference Include="..\BPASmartClient.Model\BPASmartClient.Model.csproj" />
</ItemGroup> </ItemGroup>




+ 164
- 0
BPASmartClient.MorkT/Control_MorkT.cs View File

@@ -0,0 +1,164 @@
using BPASmartClient.Device;
using BPASmartClient.EventBus;
using BPASmartClient.Lebai;
using BPASmartClient.Message;
using BPASmartClient.Model;
using BPASmartClient.Peripheral;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static BPASmartClient.EventBus.EventBus;

namespace BPASmartClient.MorkT
{
public class Control_MorkT : BaseDevice
{
public override global::BPA.Message.Enum.DeviceClientType DeviceType { get { return BPA.Message.Enum.DeviceClientType.MORKIC; } }

GLV_MorkT morkT = new GLV_MorkT();



public override void DoMain()
{
ServerInit();
DataParse();
EventBus.EventBus.GetInstance().Subscribe<DRCoffee_CoffeEndCookEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
{
if (morkT.MakeCoffeeOrder != null)
morkT.MakeCoffeeOrder.OrderStatus = 1;
});
MessageLog.GetInstance.Show("MORKF 设备初始化完成");
}

public override void ResetProgram()
{
morkT = null;
morkT = new GLV_MorkT();
}

public override void MainTask()
{
}

public override void ReadData()
{
morkT.lebai = LebaiRobot.GetInstance.GetValueAsync();
LebaiRobot.GetInstance.GetRobotModeStatus();
}


public override void Stop()
{
}


private void ServerInit()
{
//物料信息
EventBus.EventBus.GetInstance().Subscribe<MaterialDeliveryEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
{
if (@event == null) return;
if (@event is MaterialDeliveryEvent material)
{
orderMaterialDelivery = material.orderMaterialDelivery;
}
});

//配方数据信息
EventBus.EventBus.GetInstance().Subscribe<RecipeBomEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
{
if (@event == null) return;
if (@event is RecipeBomEvent recipe)
{
recipeBoms = recipe.recipeBoms;
}
});
}

/// <summary>
/// 数据解析
/// </summary>
private void DataParse()
{
EventBus.EventBus.GetInstance().Subscribe<DoOrderEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBackHandle)
{
if (@event == null) return;
if (@event is DoOrderEvent order)
{
if (order.MorkOrder.GoodBatchings == null) return;
OrderCount++;
DeviceProcessLogShow($"接收到{OrderCount}次订单");
//构建所有商品物料信息
morkT.batchings = PolymerBatching.BuildAll();
//商品类型
GOODS_TYPE currentGoodsType = GOODS_TYPE.NEITHER;
string loc_Goods = string.Empty;
foreach (var item in order.MorkOrder.GoodBatchings)
{
var res = orderMaterialDelivery?.BatchingInfo?.FirstOrDefault(p => p.BatchingId == item.BatchingId);
if (res != null)
{
//验证商品是咖啡还是冰淇淋
if (ValidateGoodsByBatching(res.BatchingLoc) != GOODS_TYPE.NEITHER)
{
//获取当前物料所属商品类型
currentGoodsType = ValidateGoodsByBatching(res.BatchingLoc);
}
//获取主料和容器位置
if (morkT.batchings[res.BatchingLoc].BatchingClass == BATCHING_CLASS.MAIN_MATERIAL) loc_Goods = res.BatchingLoc;

switch (currentGoodsType)
{
case GOODS_TYPE.COFFEE:
if (morkT.morkOrderPushesCoffee.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null)
{
morkT.morkOrderPushesCoffee.Enqueue(new OrderLocInfo()
{
SuborderId = order.MorkOrder.SuborderId,
BatchingId = res.BatchingId,
Loc = loc_Goods
});
}
break;
case GOODS_TYPE.ICECREAM:
if (morkT.morkOrderPushesIceCream.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null)
{
morkT.morkOrderPushesIceCream.Enqueue(new OrderLocInfo()
{
SuborderId = order.MorkOrder.SuborderId,
BatchingId = res.BatchingId,
Loc = loc_Goods
});
}
break;
case GOODS_TYPE.NEITHER:
DeviceProcessLogShow("未知的商品类型");
break;
}
}
}

}
});
}

/// <summary>
/// 验证当前是做咖啡还是做冰淇淋
/// </summary>
/// <param name="batchingLoc">物料位置</param>
private GOODS_TYPE ValidateGoodsByBatching(string batchingLoc)
{
if (morkT.batchings.ContainsKey(batchingLoc))
return morkT.batchings[batchingLoc].GoodsType;
return GOODS_TYPE.NEITHER;
}


}
}

+ 0
- 36
BPASmartClient.MorkT/Device_MorkT.cs View File

@@ -1,36 +0,0 @@
using BPASmartClient.Device;
using BPASmartClient.Peripheral;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.MorkT
{
public class Device_MorkT : BaseDevice
{
public override global::BPA.Message.Enum.DeviceClientType DeviceType { get { return BPA.Message.Enum.DeviceClientType.MORKIC; } }

public override void DoMain()
{

}

public override void MainTask()
{
}

public override void ReadData()
{
}

public override void ResetProgram()
{
}

public override void Stop()
{
}
}
}

+ 37
- 0
BPASmartClient.MorkT/GLV_MorkT.cs View File

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

namespace BPASmartClient.MorkT
{
public class GLV_MorkT
{
/// <summary>
/// 咖啡订单队列
/// </summary>
public ConcurrentQueue<OrderLocInfo> morkOrderPushesCoffee = new ConcurrentQueue<OrderLocInfo>();

/// <summary>
/// 冰淇淋订单队列
/// </summary>
public ConcurrentQueue<OrderLocInfo> morkOrderPushesIceCream = new ConcurrentQueue<OrderLocInfo>();
/// <summary>
/// 物料存放位置
/// </summary>
public Dictionary<string, PolymerBatching> batchings = new Dictionary<string, PolymerBatching>();

/// <summary>
/// 当前正在制作咖啡
/// </summary>
public OrderLocInfo MakeCoffeeOrder = new OrderLocInfo();

/// <summary>
/// 获取乐百机器人的数据
/// </summary>
public SignalResult lebai = new SignalResult();
}
}

+ 22
- 0
BPASmartClient.MorkT/OrderLocInfo.cs View File

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

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

public int OrderStatus { get; set; }
public OrderLocInfo()
{
OrderStatus = 0;
}
}
}

+ 122
- 0
BPASmartClient.MorkT/PolymerBatching.cs View File

@@ -0,0 +1,122 @@

using BPASmartClient.Lebai;
using BPASmartClient.Model.单片机.Enum;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.MorkT
{
public enum GOODS_TYPE
{
NEITHER,
COFFEE,
ICECREAM,
}

public enum BATCHING_CLASS
{
HOLDER,
MAIN_MATERIAL,
}

public class PolymerBatching
{
internal const string ICE_MAIN_BATCHIN1_LOC = "52";
internal const string ICE_MAIN_BATCHIN2_LOC = "53";
internal const string ICE_MAIN_BATCHIN3_LOC = "54";
internal const string COFFEE_HOLDER_LOC = "30";
internal const string ICE_HOLDER_LOC = "51";
public static Dictionary<string, GOODS_TYPE> GOODS_TYPES = new Dictionary<string, GOODS_TYPE>() {
{"1", GOODS_TYPE.COFFEE},
{"2", GOODS_TYPE.COFFEE},
{"3", GOODS_TYPE.COFFEE},
{"4", GOODS_TYPE.COFFEE},
{"5", GOODS_TYPE.COFFEE},
{"6", GOODS_TYPE.COFFEE},
{"7", GOODS_TYPE.COFFEE},
{"8", GOODS_TYPE.COFFEE},
{"9", GOODS_TYPE.COFFEE},
{"10",GOODS_TYPE.COFFEE},
{"11",GOODS_TYPE.COFFEE},
{"12",GOODS_TYPE.COFFEE},
{"13",GOODS_TYPE.COFFEE},
{"14",GOODS_TYPE.COFFEE},
{"15",GOODS_TYPE.COFFEE},
{"16",GOODS_TYPE.COFFEE},
{"17",GOODS_TYPE.COFFEE},
{"18",GOODS_TYPE.COFFEE},
{"19",GOODS_TYPE.COFFEE},
{"20",GOODS_TYPE.COFFEE},
{"21",GOODS_TYPE.COFFEE},
{"22",GOODS_TYPE.COFFEE},
{"23",GOODS_TYPE.COFFEE},
{"24",GOODS_TYPE.COFFEE},
{"25",GOODS_TYPE.COFFEE},
{"30",GOODS_TYPE.COFFEE},
{"51",GOODS_TYPE.ICECREAM},
{ICE_MAIN_BATCHIN1_LOC,GOODS_TYPE.ICECREAM},
{ICE_MAIN_BATCHIN2_LOC,GOODS_TYPE.ICECREAM},
{ICE_MAIN_BATCHIN3_LOC,GOODS_TYPE.ICECREAM},
};

public GOODS_TYPE GoodsType { get; set; }
public BATCHING_CLASS BatchingClass { get; set; }
private string loc;

public string Loc
{
get { return loc; }
set
{
loc = value;
if (GOODS_TYPES.ContainsKey(loc))
GoodsType = GOODS_TYPES[loc];
switch (loc)
{
case COFFEE_HOLDER_LOC:
case ICE_HOLDER_LOC:
BatchingClass = BATCHING_CLASS.HOLDER;
break;
default:
BatchingClass = BATCHING_CLASS.MAIN_MATERIAL;
break;
}
}
}

internal static Dictionary<string, PolymerBatching> BuildAll()
{
Dictionary<string, PolymerBatching> temp = new Dictionary<string, PolymerBatching>();
foreach (var item in GOODS_TYPES)
{
temp.Add(item.Key, new PolymerBatching() { Loc = item.Key });
}
return temp;
}

internal static IC_SE GetIceCreamSE(string loc, out int sence)
{
switch (loc)
{
case ICE_MAIN_BATCHIN1_LOC:
sence = LebaiRobot.SENCE_接1号冰淇淋;
return IC_SE.SE_1;

case ICE_MAIN_BATCHIN2_LOC:
sence = LebaiRobot.SENCE_接2号冰淇淋;
return IC_SE.SE_2;

case ICE_MAIN_BATCHIN3_LOC:
sence = LebaiRobot.SENCE_接3号冰淇淋;
return IC_SE.SE_3;

default:
sence = LebaiRobot.SENCE_接1号冰淇淋;
return IC_SE.SE_1;
}
}
}
}

+ 132
- 0
BPASmartClient.SCChip/ChipStatus.cs View File

@@ -0,0 +1,132 @@
using BPASmartClient.Helper;
using BPASmartClient.Model.单片机.Enum;
using BPASmartClient.SCChip;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.SCChip
{
public class ChipStatus : Singleton<ChipStatus>
{
private DateTime lastRefreshTime = DateTime.MinValue;
/// <summary>
/// 是否在线
/// </summary>
public bool OnLine { get { return DateTime.Now.Subtract(lastRefreshTime).TotalSeconds <= 3; } }
/// <summary>
/// 取冰淇淋杯完成
/// </summary>
public bool CompletedTake_CPU_CUP_ICECREAM { get; set; }
/// <summary>
/// 取咖啡杯完成
/// </summary>
public bool CompletedTake_CPU_CUP_COFFEE { get; set; }
/// <summary>
/// 1号舵机打开完成
/// </summary>
public bool CompletedOpen_SE_1 { get; set; }
/// <summary>
/// 2号舵机打开完成
/// </summary>
public bool CompletedOpen_SE_2 { get; set; }
/// <summary>
/// 3号舵机打开完成
/// </summary>
public bool CompletedOpen_SE_3 { get; set; }
/// <summary>
/// 1号舵机关闭完成
/// </summary>
public bool CompletedClose_SE_1 { get; set; }
/// <summary>
/// 2号舵机关闭完成
/// </summary>
public bool CompletedClose_SE_2 { get; set; }
/// <summary>
/// 3号舵机关闭完成
/// </summary>
public bool CompletedClose_SE_3 { get; set; }
/// <summary>
/// 是否存在物品
/// </summary>
public bool ArticleExits { get; set; }
/// <summary>
/// 物品距离
/// </summary>
public byte ArticleDist { get; set; }

public bool CanDo
{
get
{
if (!OnLine)
return false;
return true;
}
}

public void ProcessMsg(ICChipPackage data)
{
try
{
switch (data.Cmd)
{
case IC_CMD.HEART_BEAT:
lastRefreshTime = DateTime.Now;
break;
case IC_CMD.TAKE_CUP:
switch ((IC_CUP)data.Value)
{
case IC_CUP.CUP_COFFEE:
CompletedTake_CPU_CUP_COFFEE = true;
break;
case IC_CUP.CUP_ICECREAM:
CompletedTake_CPU_CUP_ICECREAM = true;
break;
}
break;
case IC_CMD.OPEN_SE:
switch ((IC_SE)data.Value)
{
case IC_SE.SE_1:
CompletedOpen_SE_1 = true;
break;
case IC_SE.SE_2:
CompletedOpen_SE_2 = true;
break;
case IC_SE.SE_3:
CompletedOpen_SE_3 = true;
break;
}
break;
case IC_CMD.CLOSE_SE:
switch ((IC_SE)data.Value)
{
case IC_SE.SE_1:
CompletedClose_SE_1 = true;
break;
case IC_SE.SE_2:
CompletedClose_SE_2 = true;
break;
case IC_SE.SE_3:
CompletedClose_SE_3 = true;
break;
}
break;
case IC_CMD.ARTICLE_EXITS:
ArticleExits = data.Value > 0;
break;
case IC_CMD.ARTICLE_DIST:
ArticleDist = data.Value;
break;
}
}
catch (Exception ex)
{

}
}
}
}

+ 197
- 0
BPASmartClient.SCChip/CommandHandler.cs View File

@@ -0,0 +1,197 @@

using BPASmartClient.EventBus;
using BPASmartClient.Model.单片机;
using BPASmartClient.Model.单片机.Enum;
using BPASmartClient.SCChip;
using BPASmartClient.SerialPort;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static BPASmartClient.EventBus.EventBus;

namespace BPASmartClient.SCChip
{
/// <summary>
/// 指令封装
/// </summary>
internal class CommandHandler
{
private SerialPortClient commProxy;
private ICChipPackage package = new ICChipPackage();

/// <summary>
/// 初始化
/// </summary>
internal void Init(SerialPortClient commProxy)
{
this.commProxy = commProxy;
EventBus.EventBus.GetInstance().Subscribe<SCChip_TakeCupEvent>(0,TakeCupEventHandle);
EventBus.EventBus.GetInstance().Subscribe<SCChip_MakeIceCreamEvent>(0, MakeIceCreamEventHandle);
EventBus.EventBus.GetInstance().Subscribe<SCChip_SESwitchCreamEvent>(0, StopMakeIceCreamEventHandle);
EventBus.EventBus.GetInstance().Subscribe<SCChip_RotorSwitchEvent>(0, RotorSwitchEventHandle);
EventBus.EventBus.GetInstance().Subscribe<ArticleExitsEvent>(0, ArticleExitsEventHandle);
EventBus.EventBus.GetInstance().Subscribe<ArticleDistEvent>(0, ArticleDistEventHandle);
}

private void ArticleDistEventHandle(IEvent @event, EventCallBackHandle callBack)
{
package.Cmd = IC_CMD.ARTICLE_DIST;
commProxy.SendData(StructureToByte(package));
}

private void ArticleExitsEventHandle(IEvent @event, EventCallBackHandle callBack)
{
ChipStatus.GetInstance().ArticleExits = false;
package.Cmd = IC_CMD.ARTICLE_EXITS;
commProxy.SendData(StructureToByte(package));
}

private void StopMakeIceCreamEventHandle(IEvent @event, EventCallBackHandle callBack)
{
ChipStatus.GetInstance().ArticleDist = 0;
package.Cmd = (@event as SCChip_SESwitchCreamEvent).IsOpen ? IC_CMD.OPEN_SE : IC_CMD.CLOSE_SE;
package.Value = (byte)(@event as SCChip_SESwitchCreamEvent).SteeringEngine;
commProxy.SendData(StructureToByte(package));
}

private void RotorSwitchEventHandle(IEvent @event, EventCallBackHandle callBack)
{
package.Cmd = IC_CMD.ROTOR;
package.Value = (@event as SCChip_RotorSwitchEvent).TurnOn ? (byte)IC_ROTOR.OPEN_ROTOR : (byte)IC_ROTOR.CLOSE_ROTOR;
commProxy.SendData(StructureToByte(package));
}

private void MakeIceCreamEventHandle(IEvent @event, EventCallBackHandle callBack)
{
switch ((@event as SCChip_MakeIceCreamEvent).SteeringEngine)
{
case IC_SE.SE_1:
ChipStatus.GetInstance().CompletedOpen_SE_1 = false;
break;
case IC_SE.SE_2:
ChipStatus.GetInstance().CompletedOpen_SE_2 = false;
break;
case IC_SE.SE_3:
ChipStatus.GetInstance().CompletedOpen_SE_3 = false;
break;
}
package.Cmd = IC_CMD.OPEN_SE;
package.Value = (byte)(@event as SCChip_MakeIceCreamEvent).SteeringEngine;
commProxy.SendData(StructureToByte(package));

bool wait = true;
DateTime waitTimeout = DateTime.Now.AddSeconds(3);
while (wait)
{
wait = DateTime.Now < waitTimeout;
if (wait)
{
switch ((@event as SCChip_MakeIceCreamEvent).SteeringEngine)
{
case IC_SE.SE_1:
wait = !ChipStatus.GetInstance().CompletedOpen_SE_1;
break;
case IC_SE.SE_2:
wait = !ChipStatus.GetInstance().CompletedOpen_SE_2;
break;
case IC_SE.SE_3:
wait = !ChipStatus.GetInstance().CompletedOpen_SE_3;
break;
}
}
Thread.Sleep(10);
}
Thread.Sleep(2000);
package.Cmd = IC_CMD.CLOSE_SE;
package.Value = (byte)(@event as SCChip_MakeIceCreamEvent).SteeringEngine;
commProxy.SendData(StructureToByte(package));

wait = true;
waitTimeout = DateTime.Now.AddSeconds(3);
while (wait)
{
wait = DateTime.Now < waitTimeout;
if (wait)
{
switch ((@event as SCChip_MakeIceCreamEvent).SteeringEngine)
{
case IC_SE.SE_1:
wait = !ChipStatus.GetInstance().CompletedClose_SE_1;
break;
case IC_SE.SE_2:
wait = !ChipStatus.GetInstance().CompletedClose_SE_2;
break;
case IC_SE.SE_3:
wait = !ChipStatus.GetInstance().CompletedClose_SE_3;
break;
}
}
Thread.Sleep(10);
}
}

private void TakeCupEventHandle(IEvent @event, EventCallBackHandle callBack)
{
switch ((@event as SCChip_TakeCupEvent).Cup)
{
case IC_CUP.CUP_ICECREAM:
ChipStatus.GetInstance().CompletedTake_CPU_CUP_ICECREAM = false;
break;
case IC_CUP.CUP_COFFEE:
ChipStatus.GetInstance().CompletedTake_CPU_CUP_COFFEE = false;
break;
}
package.Cmd = IC_CMD.TAKE_CUP;
package.Value = (byte)(@event as SCChip_TakeCupEvent).Cup;
commProxy.SendData(StructureToByte(package));

bool wait = true;
var waitTimeout = DateTime.Now.AddSeconds(3);
while (wait)
{
wait = DateTime.Now < waitTimeout;
if (wait)
{
switch ((@event as SCChip_TakeCupEvent).Cup)
{
case IC_CUP.CUP_ICECREAM:
wait = !ChipStatus.GetInstance().CompletedTake_CPU_CUP_ICECREAM;
break;
case IC_CUP.CUP_COFFEE:
wait = !ChipStatus.GetInstance().CompletedTake_CPU_CUP_COFFEE;
break;
}
}
Thread.Sleep(10);
}
}


private byte[] StructureToByte(ICChipPackage structure)
{
structure.Header = 0xAA;
structure.Sender = IC_SENDER.CONSOLE;
structure.End = 0xBB;

int size = Marshal.SizeOf(typeof(ICChipPackage));
byte[] buffer = new byte[size];
IntPtr bufferIntPtr = Marshal.AllocHGlobal(size);
try
{
Marshal.StructureToPtr(structure, bufferIntPtr, true);
Marshal.Copy(bufferIntPtr, buffer, 0, size);
}
finally
{
Marshal.FreeHGlobal(bufferIntPtr);
}
return buffer;
}


}
}

+ 23
- 0
HBLConsole.MORKIC/BPASmartClient.MORKIC.csproj View File

@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BPA.Message" Version="1.0.24" />
<PackageReference Include="BPA.Models" Version="1.0.10" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\BPASmartClient.Device\BPASmartClient.Device.csproj" />
<ProjectReference Include="..\BPASmartClient.DRCoffee\BPASmartClient.DRCoffee.csproj" />
<ProjectReference Include="..\BPASmartClient.GSIceCream\BPASmartClient.GSIceCream.csproj" />
<ProjectReference Include="..\BPASmartClient.Lebai\BPASmartClient.Lebai.csproj" />
<ProjectReference Include="..\BPASmartClient.SCChip\BPASmartClient.SCChip.csproj" />
<ProjectReference Include="..\BPASmartClient.SCChip\BPASmartClient.SCChip.csproj" />
<ProjectReference Include="..\Lebai.SDK\Lebai.SDK.csproj" />
</ItemGroup>

</Project>

+ 647
- 0
HBLConsole.MORKIC/Control_MORKIC.cs View File

@@ -0,0 +1,647 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Threading;
using BPA.Message;
using Robotc;
using System.Collections.Concurrent;
using System.Diagnostics;
using BPA.Message.IOT;
using System.Threading.Tasks;
using BPASmartClient.Device;
using BPA.Message.Enum;
using BPASmartClient.DRCoffee;
using BPASmartClient.GSIceCream;
using BPASmartClient.Helper;
using BPASmartClient.Lebai;
using BPASmartClient.EventBus;
using BPASmartClient.Model.咖啡机.Enum;
using BPASmartClient.Message;
using BPASmartClient.Model.冰淇淋.Enum;
using BPASmartClient.Model.单片机.Enum;
using BPASmartClient.SCChip;
using BPASmartClient.Model;
using BPASmartClient.Model.单片机;
using static BPASmartClient.EventBus.EventBus;

namespace BPASmartClient.MORKIC
{
/*
* 冰淇淋咖啡机组合套装
* 物料位置:
* 1:冰淇料
* 2:冰淇淋杯
* 5:咖啡
* 6:咖啡杯
*/
public class Control_MORKIC : BaseDevice
{

//咖啡机主控程序
private CoffeeMachine coffeeMachine;
//单片机主控程序
private ICChipMachine icchipMachine;
//广绅单口冰淇淋机
private IceCreamMachine iceCreamMachine;
//物料存放位置
private Dictionary<string, PolymerBatching> batchings = new Dictionary<string, PolymerBatching>();
/// <summary>
/// 获取乐百机器人的数据
/// </summary>
SignalResult lebai = new SignalResult();
/// <summary>
/// 咖啡位置是否有东西
/// </summary>
private bool IsCoffeeMake=false;

private bool enableFunny = false;
private DateTime lastRecvdOrder = DateTime.Now;
private bool working = false;
private bool IceIsOK = true;

public void ConnectOk()
{

}
/// <summary>
/// 当前正在制作咖啡
/// </summary>
SimOrderData MakeCoffeeOrder = new SimOrderData();
/// <summary>
/// 咖啡订单队列
/// </summary>
ConcurrentQueue<SimOrderData> morkOrderPushesCoffee = new ConcurrentQueue<SimOrderData>();
/// <summary>
/// 冰淇淋订单队列
/// </summary>
ConcurrentQueue<SimOrderData> morkOrderPushesIceCream = new ConcurrentQueue<SimOrderData>();
/// <summary>
/// 等待取餐的订单,只有一个
/// </summary>
ConcurrentQueue<SimOrderData> WaitTakeMealOrder= new ConcurrentQueue<SimOrderData>();

public void Init()
{

ActionManage.GetInstance.Register(new Action<object>((s) =>
{
if (s is DrCoffeeDrinksCode cf)
{
DoCoffee(new SimOrderData { Loc = ((int)cf).ToString() });
}
else if (s is Dictionary<string, string> ms)
{
if (ms.ContainsKey("Button"))
{
switch (ms["Button"])
{
case "启动示教":
LebaiRobot.GetInstance.StartTeachMode();
break;
case "停止示教":
LebaiRobot.GetInstance.EndtTeachMode();
break;
case "启动机器人":
LebaiRobot.GetInstance.StartRobot();
break;
case "急停":
LebaiRobot.GetInstance.EStopRobot();
break;
default:
break;
}
}
}
}),"SimCoffee");

//构建所有商品物料信息
batchings = PolymerBatching.BuildAll();

EventBus.EventBus.GetInstance().Subscribe<DRCoffee_CoffeEndCookEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
{
if (MakeCoffeeOrder != null)
MakeCoffeeOrder.OrderStatus = 1;
});

System.Configuration.Configuration config = System.Configuration.ConfigurationManager.OpenExeConfiguration(System.Configuration.ConfigurationUserLevel.None);
//一系列外围基础配置
var com_Coffee = config.AppSettings.Settings["COM_Coffee"].Value;
var baud_Coffee = config.AppSettings.Settings["BAUD_Coffee"].Value;
var com_IceCream = config.AppSettings.Settings["COM_IceCream"].Value;
var baud_IceCream = config.AppSettings.Settings["BAUD_IceCream"].Value;
var iceCreamCXBThreshold = int.Parse(config.AppSettings.Settings["IceCream_CXB_Threshold"].Value);

var com_ICChip = config.AppSettings.Settings["COM_ICChip"].Value;
var baud_ICChip = config.AppSettings.Settings["BAUD_IChip"].Value;


if (iceCreamCXBThreshold > 0)
{
//设置冰淇淋成型比
MorkIStatus.GetInstance().CXB_Threshold = (byte)iceCreamCXBThreshold;
}
//咖啡机创建
coffeeMachine = new CoffeeMachine();
//单片机机创建
icchipMachine = new ICChipMachine();
//冰淇淋机创建
iceCreamMachine = new IceCreamMachine();

Main();
ReadRobotData();
OrderMake();
}

private int NoOrderTime = 0;

public override DeviceClientType DeviceType => throw new NotImplementedException();

//订单制作
public void OrderMake()
{
ThreadManage.GetInstance().StartLong(new Action(() =>
{
while (IsHealth &&(morkOrderPushesCoffee.Count > 0 || morkOrderPushesIceCream.Count>0 || IsCoffeeMake))
{
working = true; NoOrderTime = 0;
//1.有咖啡订单 取杯去制作
if (!IsCoffeeMake)//位置无杯子
{
if (morkOrderPushesCoffee.Count>0 && morkOrderPushesCoffee.TryDequeue(out SimOrderData simOrder))
{
IsCoffeeMake = true; MakeCoffeeOrder = simOrder;
MessageLog.GetInstance.Show($"开始制作 [咖啡] 订单[{simOrder.morkOrder.SortNum}]");
DoCoffee(simOrder);
}
}

if (!LebaiRobot.GetInstance.GetInput())//取餐口是否有餐饮
{
//取餐位的订单完成
if (WaitTakeMealOrder.TryDequeue(out SimOrderData waitOrder)) OrderChange(waitOrder.morkOrder.SuborderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_TAKE);

//1.制作冰淇淋
if (morkOrderPushesIceCream.Count>0 && MorkIStatus.GetInstance().CurrentMode!= MORKI_MODE.制冷模式) new GSIceCream_ModeSetEvent() { Mode = MORKI_MODE.制冷模式 }.Publish();

if (MorkIStatus.GetInstance().CXB >= 86 && morkOrderPushesIceCream.Count > 0)//成型比大于80 我才会制作
{
if (LebaiRobot.GetInstance.GetInput(3))
{
if(IceIsOK) MessageLog.GetInstance.Show("请擦拭冰淇淋机出口");
IceIsOK = false;

}
else if(morkOrderPushesIceCream.TryDequeue(out SimOrderData order))
{
IceIsOK = true;
MessageLog.GetInstance.Show($"开始制作 [冰淇淋] 订单[{order.morkOrder.SortNum}]");
DoIceCream(order);
}
}

//2.取咖啡到取餐口
if (IsCoffeeMake)
{
if (MakeCoffeeOrder != null && MakeCoffeeOrder.OrderStatus == 1)
{
MessageLog.GetInstance.Show($"将咖啡移动到取餐位 [咖啡] 订单[{MakeCoffeeOrder.morkOrder.SortNum}]");
DoCoffeeQC(MakeCoffeeOrder);
MakeCoffeeOrder = null;
IsCoffeeMake = false;
}
}
}
working = false;
lastRecvdOrder = DateTime.Now;
}
if (IsHealth == false && (morkOrderPushesCoffee.Count > 0 || morkOrderPushesIceCream.Count > 0 || IsCoffeeMake))
{
MessageLog.GetInstance.Show($"机器连接问题 订单,不允许制作,请检查设备连接后尝试," +
$"乐白:{LebaiRobot.GetInstance.IsConnected}咖啡机:{MorkIStatus.GetInstance().CanDo}单片机:{ChipStatus.GetInstance().CanDo}");

if (LebaiRobot.GetInstance.IsConnected && IsCoffeeMake && !LebaiRobot.GetInstance.GetInput())//乐白有订单
{
MessageLog.GetInstance.Show($"将咖啡移动到取餐位 [咖啡] 订单[{MakeCoffeeOrder.morkOrder.SortNum}]");
DoCoffeeQC(MakeCoffeeOrder);
MakeCoffeeOrder = null;
IsCoffeeMake = false;
}
}

if (!LebaiRobot.GetInstance.GetInput())
{
if (WaitTakeMealOrder.TryDequeue(out SimOrderData waitOrder)) OrderChange(waitOrder.morkOrder.SuborderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_TAKE);
}


Thread.Sleep(1000);
}),"订单制作");
}

private void OrderChange(string subid, ORDER_STATUS oRDER_STATUS)
{
EventBus.EventBus.GetInstance().Publish(new OrderStatusChangedEvent() { Status = oRDER_STATUS, SubOrderId = subid, deviceClientType = DeviceType });
}

public void Main()
{
//咖啡机开启主线程
coffeeMachine.Start();
//单片机开启主线程
icchipMachine.Start();
//冰淇淋机开启主线程
iceCreamMachine.Start();
new GSIceCream_ModeSetEvent() { Mode = MORKI_MODE.制冷模式 }.Publish();
//开始心跳刷新,根据咖啡机及冰淇淋机来判断
//ThreadManage.GetInstance().StartLong(new Action(() =>
//{
// GeneralConfig.Healthy =
// LebaiRobot.GetInstance.IsConnected &&
// MorkCStatus.GetInstance().CanDo &&
// ChipStatus.GetInstance().CanDo;
// //GeneralConfig.Healthy = true;
// Thread.Sleep(100);
//}), "MORK-IC心跳刷新");
ThreadManage.GetInstance().Start(new Action(() =>
{
while (!LebaiRobot.GetInstance.IsConnected)
{
Thread.Sleep(10);
}
//LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_欢迎);
}), "MORK-IC欢迎");
}

public void DataParse<T>(T order)
{
if (order is MorkOrderPush morkOrderPush)
{
//商品类型
GOODS_TYPE currentGoodsType = GOODS_TYPE.NEITHER;
string loc_coffe = string.Empty;
string loc_cup = string.Empty;
#region 订单分类
//遍历物料
foreach (var item in morkOrderPush.GoodBatchings)
{
var res = Json<BatchingInfoPar>.Data.orderMaterialDelivery.BatchingInfo.FirstOrDefault(p => p.BatchingId == item.BatchingId);
if (res != null)
{
//验证商品是咖啡还是冰淇淋
if (ValidateGoodsByBatching(res.BatchingLoc) != GOODS_TYPE.NEITHER)
{
//获取当前物料所属商品类型
currentGoodsType = ValidateGoodsByBatching(res.BatchingLoc);
}
//获取主料和容器位置
switch (batchings[res.BatchingLoc].BatchingClass)
{
case BATCHING_CLASS.HOLDER:
loc_cup = res.BatchingLoc;
break;
case BATCHING_CLASS.MAIN_MATERIAL:
loc_coffe = res.BatchingLoc;
break;
}
}
}
//根据商品类型执行具体制作流程
switch (currentGoodsType)
{
case GOODS_TYPE.COFFEE:
morkOrderPushesCoffee.Enqueue(new SimOrderData { Loc = loc_coffe,morkOrder = morkOrderPush });
break;
case GOODS_TYPE.ICECREAM:
morkOrderPushesIceCream.Enqueue(new SimOrderData { Loc = loc_coffe,morkOrder = morkOrderPush });
break;
case GOODS_TYPE.NEITHER:
MessageLog.GetInstance.Show("未知的商品类型");
break;
}
#endregion


}
}

/// <summary>
/// 验证当前是做咖啡还是做冰淇淋
/// </summary>
/// <param name="batchingLoc">物料位置</param>
private GOODS_TYPE ValidateGoodsByBatching(string batchingLoc)
{
if (batchings.ContainsKey(batchingLoc))
return batchings[batchingLoc].GoodsType;
return GOODS_TYPE.NEITHER;
}

private void Wait(int value = 101)
{
while (!(lebai.Ok && lebai.Value == value))
{
Thread.Sleep(5);
}
}

/// <summary>
/// 做咖啡-接杯子 并且 回到 安全位置
/// </summary>
private void DoCoffee(SimOrderData order)
{
#region 且时且多入场设备程序
int checkeNum = 0;
// are.Reset();
LebaiRobot.GetInstance.SetValue(0);
OrderChange(order.morkOrder.SuborderId, BPA.Message.Enum.ORDER_STATUS.COOKING);
//SimpleFactory.GetInstance.OrderChanged(order.morkOrder.SuborderId, BPA.Message.Enum.ORDER_STATUS.COOKING);
LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_取咖啡杯);
Wait();
new SCChip_TakeCupEvent() { Cup = IC_CUP.CUP_COFFEE }.Publish();//落碗控制
Thread.Sleep(500);
MessageLog.GetInstance.Show("尝试取咖啡杯!");
LebaiRobot.GetInstance.SetValue(1);

int count = 2;
p:
LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_咖啡杯检测);
Wait();
LebaiRobot.GetInstance.SetValue(1);
if (!LebaiRobot.GetInstance.GetInput())
{
if (count >= 3)
{
//退出循环回到初始位置
MessageLog.GetInstance.Show($"执行{count}次取咖啡杯,仍为成功,订单默认废弃,机器人回到初始位置!");
LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_咖啡杯回原点);
Wait();
LebaiRobot.GetInstance.SetValue(1);
return;
}
MessageLog.GetInstance.Show("执行二次取咖啡杯");
LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_二次取咖啡杯);
Wait();
new SCChip_TakeCupEvent() { Cup = IC_CUP.CUP_COFFEE }.Publish();//落碗控制
LebaiRobot.GetInstance.SetValue(1);
count++;
goto p;
}

MessageLog.GetInstance.Show("咖啡杯取杯完成");
LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_接咖啡_新);
Wait();
LebaiRobot.GetInstance.SetValue(1);
//加场景 回初始位置
new DRCoffee_MakeCoffeeEvent() { DrinkCode = (Model.咖啡机.Enum.DrCoffeeDrinksCode)int.Parse(order.Loc) }.Publish(); //接咖啡控制
MessageLog.GetInstance.Show($"发送咖啡机制作{order.Loc}!");
#endregion

}

/// <summary>
/// 将咖啡杯子 取走到 取餐口
/// </summary>
private void DoCoffeeQC(SimOrderData order)
{
LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_取咖啡出餐);
Wait();
LebaiRobot.GetInstance.SetValue(1);
//订单状态改变:完成
OrderChange(order.morkOrder.SuborderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_COOK);
//SimpleFactory.GetInstance.OrderChanged(order.morkOrder.SuborderId,BPA.Message.Enum.ORDER_STATUS.COMPLETED_COOK);
MessageLog.GetInstance.Show($"{order.morkOrder.GoodsName}等待取餐");
WaitTakeMealOrder.Enqueue(order);
}

/// <summary>
/// 做冰淇淋
/// </summary>
private void DoIceCream(SimOrderData order)
{
//if (LebaiRobot.GetInstance.GetInput(3))
//{
// MessageLog.GetInstance.Show("请擦拭冰淇淋机出口");
// return;
//}
#region 且时且多入场设备程序
int checkeNum = 0;
//are.Reset();
LebaiRobot.GetInstance.SetValue(0);
LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_取冰淇淋杯);
Wait();
new SCChip_TakeCupEvent() { Cup = IC_CUP.CUP_ICECREAM }.Publish();//落碗控制
Thread.Sleep(500);
MessageLog.GetInstance.Show("尝试取冰淇淋杯!");
LebaiRobot.GetInstance.SetValue(1);

int count = 2;
p:
LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_冰淇淋杯检测);
Wait();
LebaiRobot.GetInstance.SetValue(1);
if (!LebaiRobot.GetInstance.GetInput())
{
if (count >= 3)
{
//退出循环回到初始位置
MessageLog.GetInstance.Show($"执行{count}次取冰淇淋杯,仍未成功,订单默认废弃,机器人回到初始位置!");
LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_冰淇淋杯回原点);
Wait();
LebaiRobot.GetInstance.SetValue(1);
return;
}
MessageLog.GetInstance.Show($"执行{count}次取冰淇淋杯!");
LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_二次取冰淇淋杯);
new SCChip_TakeCupEvent() { Cup = IC_CUP.CUP_ICECREAM }.Publish();//落碗控制
Wait();
LebaiRobot.GetInstance.SetValue(1);
count++;
goto p;
}
MessageLog.GetInstance.Show("冰淇淋杯检测完成");

#region 通讯冰淇淋机

//制冷模式
new GSIceCream_ModeSetEvent() { Mode = MORKI_MODE.制冷模式 }.Publish();
LebaiRobot.GetInstance.SetValue(0);
OrderChange(order.morkOrder.SuborderId, BPA.Message.Enum.ORDER_STATUS.COOKING);
//SimpleFactory.GetInstance.OrderChanged(order.morkOrder.SuborderId, BPA.Message.Enum.ORDER_STATUS.COOKING);
LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_接1号冰淇淋);
Wait();
bool doItResult = true;
//出料
new GSIceCream_DischargeEvent().Publish(delegate (object[] args)
{
doItResult = (bool)args[0];
});
if (doItResult)
{
IceCreamCookCheck();
}
else
{
int count_1 = 0;
while (MorkIStatus.GetInstance().CXB <= 86)
{
Thread.Sleep(5);
count_1++;
if (count_1 >= 2000)
break;
}
IceCreamCookCheck();
}
LebaiRobot.GetInstance.SetValue(1);
#endregion
while (LebaiRobot.GetInstance.GetInput())
{
Thread.Sleep(500);
}
LebaiRobot.GetInstance.Scene(LebaiRobot.SENCE_放冰淇淋位置);
Wait();
LebaiRobot.GetInstance.SetValue(1);
//订单状态改变:完成
OrderChange(order.morkOrder.SuborderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_COOK);
//SimpleFactory.GetInstance.OrderChanged(order.morkOrder.SuborderId, BPA.Message.Enum.ORDER_STATUS.COMPLETED_COOK);
MessageLog.GetInstance.Show($"{order.morkOrder.GoodsName}等待取餐");
WaitTakeMealOrder.Enqueue(order);
#endregion
}

/// <summary>
/// 冰淇淋制作
/// </summary>
public void IceCreamCookCheck()
{

int retry = 3;
DateTime beginTime = DateTime.Now;
while (!LebaiRobot.GetInstance.GetInput(3))
{
if (retry <= 0 && DateTime.Now.Subtract(beginTime).TotalSeconds >= 10)
{
MessageLog.GetInstance.Show("超时未出料,重试次数用尽");
break;
}
if (DateTime.Now.Subtract(beginTime).TotalSeconds > 5)
{
MessageLog.GetInstance.Show("超时未出料,重新发送打料指令");
new GSIceCream_ModeSetEvent() { Mode = MORKI_MODE.打料 }.Publish();
beginTime = DateTime.Now;
retry--;
}
Thread.Sleep(10);
}
MessageLog.GetInstance.Show("开始等待6s");
Thread.Sleep(5000);

}

//private void CoffeEndCookHandle(IEvent @event, EventBus.EventCallBackHandle callBack)
//{
// //are.Set();
// if(MakeCoffeeOrder!=null)
// MakeCoffeeOrder.OrderStatus = 1;
//}

public void ReadRobotData()
{
ThreadManage.GetInstance().StartLong(new Action(() =>
{
lebai = LebaiRobot.GetInstance.GetValueAsync();
LebaiRobot.GetInstance.GetRobotModeStatus();
//LebaiRobot.GetInstance.GetInput();


Thread.Sleep(100);
}), "乐百机器人数据读取", true);
}

public void SimOrder<T>(T simOrder)
{
}

/// <summary>
/// IOT 广播消息命令
/// </summary>
public void IotBroadcast<T>(T broadcast)
{
if (broadcast != null && broadcast is IOTCommandModel iOTCommand)
{
switch (iOTCommand.CommandName)
{
case 0://控制类
if (iOTCommand.CommandValue != null)
{
if (iOTCommand.CommandValue.ContainsKey("SimOrder"))
{
//SimOrder(new SimOrderData { NoodleLoc = 1, BowlLoc = 10 });
}
}
break;
case 1://设置属性

break;
case 2://通知消息

break;
default:
break;
}
}
}

public override void DoMain()
{
}

public override void Stop()
{
throw new NotImplementedException();
}

public override void ReadData()
{
throw new NotImplementedException();
}

public override void MainTask()
{
throw new NotImplementedException();
}

public override void ResetProgram()
{
throw new NotImplementedException();
}
}


public class SimOrderData
{
public string id { get; set; }

public int OrderStatus { get; set; }

public string Loc { get; set; }

public MorkOrderPush morkOrder { get; set; }

public SimOrderData()
{
id = Guid.NewGuid().ToString();
OrderStatus=0;
}
}
}

+ 122
- 0
HBLConsole.MORKIC/PolymerBatching.cs View File

@@ -0,0 +1,122 @@

using BPASmartClient.Lebai;
using BPASmartClient.Model.单片机.Enum;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.MORKIC
{
internal enum GOODS_TYPE
{
NEITHER,
COFFEE,
ICECREAM,
}

internal enum BATCHING_CLASS
{
HOLDER,
MAIN_MATERIAL,
}

internal class PolymerBatching
{
internal const string ICE_MAIN_BATCHIN1_LOC = "52";
internal const string ICE_MAIN_BATCHIN2_LOC = "53";
internal const string ICE_MAIN_BATCHIN3_LOC = "54";
internal const string COFFEE_HOLDER_LOC = "30";
internal const string ICE_HOLDER_LOC = "51";
public static Dictionary<string, GOODS_TYPE> GOODS_TYPES = new Dictionary<string, GOODS_TYPE>() {
{"1", GOODS_TYPE.COFFEE},
{"2", GOODS_TYPE.COFFEE},
{"3", GOODS_TYPE.COFFEE},
{"4", GOODS_TYPE.COFFEE},
{"5", GOODS_TYPE.COFFEE},
{"6", GOODS_TYPE.COFFEE},
{"7", GOODS_TYPE.COFFEE},
{"8", GOODS_TYPE.COFFEE},
{"9", GOODS_TYPE.COFFEE},
{"10",GOODS_TYPE.COFFEE},
{"11",GOODS_TYPE.COFFEE},
{"12",GOODS_TYPE.COFFEE},
{"13",GOODS_TYPE.COFFEE},
{"14",GOODS_TYPE.COFFEE},
{"15",GOODS_TYPE.COFFEE},
{"16",GOODS_TYPE.COFFEE},
{"17",GOODS_TYPE.COFFEE},
{"18",GOODS_TYPE.COFFEE},
{"19",GOODS_TYPE.COFFEE},
{"20",GOODS_TYPE.COFFEE},
{"21",GOODS_TYPE.COFFEE},
{"22",GOODS_TYPE.COFFEE},
{"23",GOODS_TYPE.COFFEE},
{"24",GOODS_TYPE.COFFEE},
{"25",GOODS_TYPE.COFFEE},
{"30",GOODS_TYPE.COFFEE},
{"51",GOODS_TYPE.ICECREAM},
{ICE_MAIN_BATCHIN1_LOC,GOODS_TYPE.ICECREAM},
{ICE_MAIN_BATCHIN2_LOC,GOODS_TYPE.ICECREAM},
{ICE_MAIN_BATCHIN3_LOC,GOODS_TYPE.ICECREAM},
};

public GOODS_TYPE GoodsType { get; set; }
public BATCHING_CLASS BatchingClass { get; set; }
private string loc;

public string Loc
{
get { return loc; }
set
{
loc = value;
if (GOODS_TYPES.ContainsKey(loc))
GoodsType = GOODS_TYPES[loc];
switch (loc)
{
case COFFEE_HOLDER_LOC:
case ICE_HOLDER_LOC:
BatchingClass = BATCHING_CLASS.HOLDER;
break;
default:
BatchingClass = BATCHING_CLASS.MAIN_MATERIAL;
break;
}
}
}

internal static Dictionary<string, PolymerBatching> BuildAll()
{
Dictionary<string, PolymerBatching> temp = new Dictionary<string, PolymerBatching>();
foreach (var item in GOODS_TYPES)
{
temp.Add(item.Key, new PolymerBatching() { Loc = item.Key });
}
return temp;
}

internal static IC_SE GetIceCreamSE(string loc, out int sence)
{
switch (loc)
{
case ICE_MAIN_BATCHIN1_LOC:
sence = LebaiRobot.SENCE_接1号冰淇淋;
return IC_SE.SE_1;

case ICE_MAIN_BATCHIN2_LOC:
sence = LebaiRobot.SENCE_接2号冰淇淋;
return IC_SE.SE_2;

case ICE_MAIN_BATCHIN3_LOC:
sence = LebaiRobot.SENCE_接3号冰淇淋;
return IC_SE.SE_3;

default:
sence = LebaiRobot.SENCE_接1号冰淇淋;
return IC_SE.SE_1;
}
}
}
}

+ 8
- 1
SmartClient.sln View File

@@ -74,7 +74,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lebai.SDK", "Lebai.SDK\Leba
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.PLC", "BPASmartClient.MORKSM.BK.PLC\BPASmartClient.PLC.csproj", "{7F04A788-38B5-42CB-B601-70C657C953B8}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.PLC", "BPASmartClient.MORKSM.BK.PLC\BPASmartClient.PLC.csproj", "{7F04A788-38B5-42CB-B601-70C657C953B8}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.MorkF", "BPASmartClient.MorkF\BPASmartClient.MorkF.csproj", "{15FD3FF1-80F1-4274-945A-BA5EBA35999E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.MorkF", "BPASmartClient.MorkF\BPASmartClient.MorkF.csproj", "{15FD3FF1-80F1-4274-945A-BA5EBA35999E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.MORKIC", "HBLConsole.MORKIC\BPASmartClient.MORKIC.csproj", "{31A3B51C-A4BB-4FEB-B712-38482F6D1667}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -194,6 +196,10 @@ Global
{15FD3FF1-80F1-4274-945A-BA5EBA35999E}.Debug|Any CPU.Build.0 = Debug|Any CPU {15FD3FF1-80F1-4274-945A-BA5EBA35999E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{15FD3FF1-80F1-4274-945A-BA5EBA35999E}.Release|Any CPU.ActiveCfg = Release|Any CPU {15FD3FF1-80F1-4274-945A-BA5EBA35999E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{15FD3FF1-80F1-4274-945A-BA5EBA35999E}.Release|Any CPU.Build.0 = Release|Any CPU {15FD3FF1-80F1-4274-945A-BA5EBA35999E}.Release|Any CPU.Build.0 = Release|Any CPU
{31A3B51C-A4BB-4FEB-B712-38482F6D1667}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{31A3B51C-A4BB-4FEB-B712-38482F6D1667}.Debug|Any CPU.Build.0 = Debug|Any CPU
{31A3B51C-A4BB-4FEB-B712-38482F6D1667}.Release|Any CPU.ActiveCfg = Release|Any CPU
{31A3B51C-A4BB-4FEB-B712-38482F6D1667}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@@ -227,6 +233,7 @@ Global
{3A55F68A-D526-4CFC-A5A6-B69FB76716C2} = {666CB1A9-562E-453A-A2C7-FD9D77CFDFDD} {3A55F68A-D526-4CFC-A5A6-B69FB76716C2} = {666CB1A9-562E-453A-A2C7-FD9D77CFDFDD}
{7F04A788-38B5-42CB-B601-70C657C953B8} = {666CB1A9-562E-453A-A2C7-FD9D77CFDFDD} {7F04A788-38B5-42CB-B601-70C657C953B8} = {666CB1A9-562E-453A-A2C7-FD9D77CFDFDD}
{15FD3FF1-80F1-4274-945A-BA5EBA35999E} = {9FB27073-61A0-4FE3-94DB-5FDDE062332F} {15FD3FF1-80F1-4274-945A-BA5EBA35999E} = {9FB27073-61A0-4FE3-94DB-5FDDE062332F}
{31A3B51C-A4BB-4FEB-B712-38482F6D1667} = {9FB27073-61A0-4FE3-94DB-5FDDE062332F}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9AEC9B81-0222-4DE9-B642-D915C29222AC} SolutionGuid = {9AEC9B81-0222-4DE9-B642-D915C29222AC}


Loading…
Cancel
Save