using BPA.Message; using System; using BPA.Message.Enum; using BPASmartClient.Device; using BPASmartClient.EventBus; using BPASmartClient.Helper; using BPASmartClient.Message; using BPASmartClient.Model; using BPASmartClient.Model.PLC; using BPA.Models; using static BPASmartClient.EventBus.EventBus; using BPASmartClient.Model.小炒机; using BPASmartClient.MorkF.Model; using System.Text; using System.Collections.Concurrent; using System.Windows.Documents; using BPASmartClient.Business; using Microsoft.CodeAnalysis; using BPASmartClient.MorkF.ViewModel; using BPASmartClient.ViewModel; using System.Windows; namespace BPASmartClient.MorkF { public class Control_MorkF : BaseDevice { #region 常数定义 /// /// while循环最大sleep次数 /// private const int sleepCount = 20; /// /// while循环每次sleep时间 /// private const int sleepTime = 500; /// /// 菜品库while循环最大sleep次数 /// private const int materialSleepCount = 600; /// /// 菜品库while循环每次sleep时间 /// private const int materialSleepTime = 100; /// /// 初始化炒锅数量 /// private int count = 2; /// /// 菜品盒下移高度,相对于坐标系 /// //private const int materialBoxHigh = 4080; ////菜品库出餐高度 //private const int materialHigh = 33000; ////传感器到菜品库的高度(坐标系) //private const int materialLaserHigh = 34500; /// /// 菜品盒坐标系高度 /// private const int materialBoxHeight = 9700; //传感器1到菜品库的高度(厘米) //private const int materialLaserHighCM_1 = 22; ////传感器2到菜品库的高度(厘米) //private const int materialLaserHighCM_2 = 27; ////传感器3到菜品库的高度(厘米) //private const int materialLaserHighCM_3 = 31; /// /// 传感器到隔板的距离(坐标系) /// private const int clapboardLaserHigh = 10000; ////炒锅1倒菜的xy坐标 //private const int materialPutPositionXFry1 = 70000; //private const int materialPutPositionYFry1 = 40000; ////炒锅2倒菜的xy坐标 //private const int materialPutPositionXFry2 = 70000; //private const int materialPutPositionYFry2 = 40000; //菜品库机械爪放置菜品距离 private const int materialToFryDistance = 10000; //当前炒锅,默认为1号炒锅 private int fryIndex = 0; #endregion public override DeviceClientType DeviceType => DeviceClientType.MORKCS; public AutoResetEvent minorReset = new AutoResetEvent(false); public AutoResetEvent mainReset = new AutoResetEvent(false); /// /// 等待炒制数量 /// private int StagingFryCount { get; set; } /// /// 正在炒制数量 /// private int FryingCount { get; set; } /// /// 炒锅编号与炒锅实例 /// Dictionary morkFs = new Dictionary();//全局对象声明 /// /// 菜品库对象 /// ML_MorkF ml_morkf = new ML_MorkF(); /// /// 小炒菜单集合 /// f public static List LocalstirFryGoods = new List(); /// /// 待炒小炒队列 /// private ConcurrentQueue StirFryGoodsQuenes = new ConcurrentQueue(); /// /// 炒锅炒制线程名称 /// private const String striConst = "炒锅{0}炒制{1}线程"; /// /// 当前炒制菜品 /// private OrderLocInfo[] nowStirFryGood = new OrderLocInfo[2]; /// /// 待取菜队列 /// private ConcurrentQueue materialOperationQuenes = new ConcurrentQueue(); List resultorder = new List();//调试变量 /// /// 告警列表 /// private List alarmModel = new List(); /// /// /// private List statsModels = new List(); /// /// 暂存使用菜品量 /// private List stagingGoodBatchings = new List(); /// /// 是否为本地炒菜模式,默认为联网的 /// private bool isLocalFryingMode { get; set; } = true; /// /// 入口 /// public override void DoMain() { IsHealth = true; for (int i = 0; i < count; i++) { morkFs.Add(i, new GVL_MorkF()); } DataParse();//数据解析 CommandRegist();//调试 ServerInit(); DeviceProcessLogShow("MORKF 设备初始化完成"); ///初始化菜品库 //FoodLibInit(); Task2ReadMaterialData(); ScreenDataServer(); Json.Read(); //更新菜品余量 UpdateMaterialSurplus(); //读取坐标系 MaterialCoordinate materialCoordinate = ReadMaterialCoordinate(); if(materialCoordinate != null) { MaterialCoordinate.GetInstance().dicNoMaterialCoordinate = materialCoordinate.dicNoMaterialCoordinate; MaterialCoordinate.GetInstance().MLCoordinateList = materialCoordinate.MLCoordinateList; MaterialCoordinate.GetInstance().distance_1 = materialCoordinate.distance_1; MaterialCoordinate.GetInstance().distance_2 = materialCoordinate.distance_2; MaterialCoordinate.GetInstance().distance_3 = materialCoordinate.distance_3; MaterialCoordinate.GetInstance().frying1 = materialCoordinate.frying1; MaterialCoordinate.GetInstance().frying2 = materialCoordinate.frying2; MaterialCoordinate.GetInstance().materialHeight = materialCoordinate.materialHeight; MaterialCoordinate.GetInstance().MaterialOneX = materialCoordinate.MaterialOneX; MaterialCoordinate.GetInstance().MaterialTwoX = materialCoordinate.MaterialTwoX; MaterialCoordinate.GetInstance().MaterialThreeX = materialCoordinate.MaterialThreeX; } ////菜品库编号与坐标系对象存储 //SaveMaterialCoordinate(); } /// /// 主任务 /// public override void MainTask() { //炒锅炒制线程 MainProcessExcute(); //菜品库操作线程 MainProcessMaterial(); //MinorProcessExcute(); //SingleProcess(); } private static object saveMaterialLock = new object(); private void SaveMaterialData() { lock (saveMaterialLock) { Json.Data = MaterialSurplusOperation.GetInstance().materialSurplus; Json.Save(); } } private static object saveMaterialCoordinateLock = new object(); /// /// 保存当前的坐标系 /// public void SaveMaterialCoordinate() { lock (saveMaterialLock) { Json.Data = MaterialCoordinate.GetInstance(); Json.Save(); } } /// /// 读取坐标系 /// /// private MaterialCoordinate ReadMaterialCoordinate() { try { lock (saveMaterialLock) { Json.Read(); MaterialCoordinate materialCoordinate = Json.Data; return materialCoordinate; } } catch(Exception ex) { return null; } } private void Task2ReadMaterialData() { ThreadManage.GetInstance().StartLong(new Action(() => { //获取定位到达状态 GetStatus("M10.0", new Action((objects) => { if (objects is bool[] bools) { //ml_morkf.ArriveComplete = bools[i]; //小炒定点到达上升沿信号捕获 if (RTrig.GetInstance("SmartArriveComplete").Start(bools[0])) { if (isInitialArrive == false) { //MessageLog.GetInstance.Show("到达上升沿为true,isInitialArrive is false"); isInitialArrive = true; } else { //MessageLog.GetInstance.Show("到达上升沿为true"); ml_morkf.ArriveComplete = true; isInitialArrive = true; } } } }), 2); }), "ReadMaterialSmartArriveCompleteData", true); ThreadManage.GetInstance().StartLong(new Action(() => { ReadMaterialData(); Thread.Sleep(10); }), "ReadMaterialData", true); } private void ReadMaterialData() { //获取激光距离 GetStatus("VW270", new Action((objects) => { if (objects is ushort[] bools) { for (int i = 0; i < 1; i++) { ml_morkf.LaserDistance = bools[i]; } } }), 2); //获取坐标X GetStatus("VD828", new Action((objects) => { if (objects is int bools) { ml_morkf.ArmPositionX = bools; } }), 2); //获取坐标Y GetStatus("VD832", new Action((objects) => { if (objects is int bools) { ml_morkf.ArmPositionY = bools; } }), 2); //获取爪子到达位置 GetStatus("M11.0", new Action((objects) => { if (objects is bool[] bools && bools.Length > 3) { ml_morkf.PawArrivePortOne = bools[0]; ml_morkf.PawArrivePortTwo = bools[1]; ml_morkf.PawArrivePortThree = bools[2]; } }), 2); //获取爪子伸出退回到位 GetStatus("M10.6", new Action((objects) => { if (objects is bool[] bools && bools.Length == 2) { ml_morkf.PawOutComplete = bools[0]; ml_morkf.PawInComplete = bools[1]; } }), 2); //获取总初始化完成 GetStatus("M10.2", new Action((objects) => { if (objects is bool[] bools) { for (int i = 0; i < 1; i++) { ml_morkf.InitialComplete = bools[i]; } } }), 2); //抓手初始化完成 GetStatus("M10.3", new Action((objects) => { if (objects is bool[] bools) { for (int i = 0; i < 1; i++) { ml_morkf.PawInitialComplete = bools[i]; } } }), 2); //抓手初始化完成 GetStatus("I0.1", new Action((objects) => { if (objects is bool[] bools && bools.Length > 2) { ml_morkf.PawPositon_1 = bools[0]; ml_morkf.PawPositon_2 = bools[1]; ml_morkf.PawPositon_3 = bools[2]; } }), 2); } public override void Stop() { IsHealth = false; } #region 调试代码 public void CommandRegist() { #region 设备控制 ActionManage.GetInstance.Register(PLCInite, "InitCommand"); ActionManage.GetInstance.Register(StartOrder, "StartOrder"); ActionManage.GetInstance.Register(StartOrderMain, "开始下单"); ActionManage.GetInstance.Register(StopLocalOrder, "StopLocalOrder"); ActionManage.GetInstance.Register(new Action((o) => { if (o is string materialName) { NewStartLocalOrder(materialName); } }), "NewStartLocalOrder"); #endregion #region 菜品库 ActionManage.GetInstance.Register(new Action(() => { ThreadManage.GetInstance().Start(new Action(() => { FoodLibInit(); }), "FoodLibInit"); }), "FoodLibInit"); ActionManage.GetInstance.Register(new Action(() => { isLocalFryingMode = !isLocalFryingMode; }), "ModeChange"); ActionManage.GetInstance.Register(new Action(() => { ThreadManage.GetInstance().Start(new Action(() => { if(!UpdateMaterialLibraryStock()) { MessageLog.GetInstance.ShowEx("菜品库检测余量失败"); } }), "SurplusCheck"); }), "SurplusCheck"); ActionManage.GetInstance.Register(new Action((o) => { ThreadManage.GetInstance().Start(new Action(() => { Electromagnetism(o); }), "Electromagnetism"); }), "Electromagnetism"); ActionManage.GetInstance.Register(new Action(() => { ThreadManage.GetInstance().Start(new Action(() => { PawToPoint1(); }), "PawToPoint1"); }), "PawToPoint1"); ActionManage.GetInstance.Register(new Action(() => { ThreadManage.GetInstance().Start(new Action(() => { PawToPoint2(); }), "PawToPoint2"); }), "PawToPoint2"); ActionManage.GetInstance.Register(new Action(() => { ThreadManage.GetInstance().Start(new Action(() => { PawToPoint3(); }), "PawToPoint3"); }), "PawToPoint3"); ActionManage.GetInstance.Register(new Action(() => { ThreadManage.GetInstance().Start(new Action(() => { GetDistance_1(); }), "GetDistance_1"); }), "GetDistance_1"); ActionManage.GetInstance.Register(new Action(() => { ThreadManage.GetInstance().Start(new Action(() => { GetDistance_2(); }), "GetDistance_2"); }), "GetDistance_2"); ActionManage.GetInstance.Register(new Action(() => { ThreadManage.GetInstance().Start(new Action(() => { GetDistance_3(); }), "GetDistance_3"); }), "GetDistance_3"); ActionManage.GetInstance.Register(new Action(() => { ThreadManage.GetInstance().Start(new Action(() => { PawExtend(); }), "PawTurnFront"); }), "PawTurnFront"); ActionManage.GetInstance.Register(new Action(() => { ThreadManage.GetInstance().Start(new Action(() => { PawShrink(); }), "PawTurnBack"); }), "PawTurnBack"); ActionManage.GetInstance.Register(new Action((list) => { ThreadManage.GetInstance().Start(new Action(() => { if (list is List list_int) { if (list_int.Count == 2) { SetArmPosition(list_int[0], list_int[1]); } } }), "SetArmPosition"); }), "SetArmPosition"); ActionManage.GetInstance.Register(new Action((list) => { if (list is bool startOrStop) { ArmRunUp(startOrStop); } }), "ArmRunUp"); ActionManage.GetInstance.Register(new Action((list) => { if (list is bool startOrStop) { ArmRunDown(startOrStop); } }), "ArmRunDown"); ActionManage.GetInstance.Register(new Action((list) => { if (list is bool startOrStop) { ArmRunLeft(startOrStop); } }), "ArmRunLeft"); ActionManage.GetInstance.Register(new Action((list) => { if (list is bool startOrStop) { ArmRunRight(startOrStop); } }), "ArmRunRight"); ActionManage.GetInstance.Register(new Action((list) => { ThreadManage.GetInstance().Start(new Action(() => { if (list is List list_int) { if (list_int.Count == 2) { SetArmPosition(list_int[0], list_int[1]); } } }), "SetNowPosition"); }), "SetNowPosition"); ActionManage.GetInstance.Register(new Action((list) => { ThreadManage.GetInstance().Start(new Action(() => { if (list is List list_object) { if (list_object.Count != 3) { return; } if (list_object[0] is string No && list_object[1] is int x && list_object[2] is int y) { if (SetArmPosition(x, y)) { ActionManage.GetInstance.Send("CalibrationCallBack", new List { No });//设定机械臂当前位置 } } } }), "CalibrationCoordination"); }), "CalibrationCoordination"); #endregion //ActionManage.GetInstance.Register(PLCInite, "InitCommand"); #region 配料控制 ActionManage.GetInstance.Register(new Action((o) => { ThreadManage.GetInstance().Start(new Action(() => { OutSeasoning(o, fryIndex); }), "OutMaterials"); }), "OutMaterials"); //ActionManage.GetInstance.Register(OutSeasoning, "OutMaterials"); #endregion #region 炒锅 ActionManage.GetInstance.Register(new Action(() => { ThreadManage.GetInstance().Start(new Action(() => { Plc1Reset(fryIndex); }), "Plc1Reset"); }), "Plc1Reset"); ActionManage.GetInstance.Register(new Action(() => { ThreadManage.GetInstance().Start(new Action(() => { AddOil(); }), "AddOil"); }), "AddOil"); ActionManage.GetInstance.Register(new Action(() => { ThreadManage.GetInstance().Start(new Action(() => { StartFire(fryIndex); }), "StartFire"); }), "StartFire"); ActionManage.GetInstance.Register(new Action(() => { ThreadManage.GetInstance().Start(new Action(() => { StopFire(fryIndex); }), "StopFire"); }), "StopFire"); ActionManage.GetInstance.Register(new Action(() => { ThreadManage.GetInstance().Start(new Action(() => { StartStir(fryIndex); }), "StartStir"); }), "StartStir"); ActionManage.GetInstance.Register(new Action(() => { ThreadManage.GetInstance().Start(new Action(() => { StopStir(fryIndex); }), "StopStir"); }), "StopStir"); ActionManage.GetInstance.Register(new Action(() => { ThreadManage.GetInstance().Start(new Action(() => { MagnetOn(fryIndex); }), "MagnetOn"); }), "MagnetOn"); ActionManage.GetInstance.Register(new Action(() => { ThreadManage.GetInstance().Start(new Action(() => { MagnetOff(fryIndex); }), "MagnetOff"); }), "MagnetOff"); ActionManage.GetInstance.Register(new Action(() => { ThreadManage.GetInstance().Start(new Action(() => { string error; OutFood(fryIndex,out error); }), "OutFood"); }), "OutFood"); ActionManage.GetInstance.Register(new Action(() => { ThreadManage.GetInstance().Start(new Action(() => { StirArmGoOrigin(fryIndex); }), "StirArmGoOrigin"); }), "StirArmGoOrigin"); ActionManage.GetInstance.Register(new Action(() => { ThreadManage.GetInstance().Start(new Action(() => { string error; StirArmGoWork(fryIndex, out error); }), "StirArmGoWork"); }), "StirArmGoWork"); ActionManage.GetInstance.Register(new Action(() => { ThreadManage.GetInstance().Start(new Action(() => { HBOTGoWork(fryIndex); }), "HBOTGoWork"); }), "HBOTGoWork"); ActionManage.GetInstance.Register(new Action(() => { ThreadManage.GetInstance().Start(new Action(() => { OutMeal(fryIndex); }), "OutMeal"); }), "OutMeal"); ActionManage.GetInstance.Register(new Action((o) => { ThreadManage.GetInstance().Start(new Action(() => { SetFire(o, fryIndex); }), "SetFire"); }), "SetFire"); ActionManage.GetInstance.Register(new Action((o) => { ThreadManage.GetInstance().Start(new Action(() => { SetFry(o); }), "SetFry"); }), "SetFry"); ActionManage.GetInstance.Register(new Action((o) => { ThreadManage.GetInstance().Start(new Action(() => { SetStir(o, fryIndex); }), "SetStir"); }), "SetStir"); #endregion } /// /// 根据菜品ID下单 /// private void StartOrder(object o) { if (o == null) return; if (o is int goodId) { var res = LocalstirFryGoods?.FirstOrDefault(p => p.GoodsKey == goodId);//匹配订单对应制作流程 if (res != null) { /* morkF.listStirBom.Add(res.StirFryBomInfo);*///添加订单制作流程 if (StirFryGoodsQuenes.Count > 0) return; StirFryGoodsQuenes.Enqueue(new OrderLocInfo() { SuborderId = Guid.NewGuid().ToString(), StirPotActions = res.StirPotActions, GoodName = "本地菜品" }); MessageLog.GetInstance.Show($"添加本地订单{res.GoodsKey}"); } } } /// /// 主界面本地菜单下单 /// private void StartOrderMain(object o) { if (o == null) return; //if (o is FoodMenuModel good) //{ // NewStartLocalOrder(good.GoodName); //} //if (o == null) return; //if (o is string goodId) //{ // var res = LocalstirFryGoods?.FirstOrDefault(p => p.GoodsKey.ToString() == goodId);//匹配订单对应制作流程 // if (res != null) // { // /* morkF.listStirBom.Add(res.StirFryBomInfo);*///添加订单制作流程 // if (StirFryGoodsQuenes.Count > 0) return; // StirFryGoodsQuenes.Enqueue(new OrderLocInfo() // { // SuborderId = Guid.NewGuid().ToString(), // StirPotActions = res.StirPotActions, // GoodName = "本地菜品" // }); // MessageLog.GetInstance.Show($"添加本地订单{res.GoodsKey}"); // } //} } /// /// 本地配置的订单 /// /// private void NewStartLocalOrder(string materialName) { //if (StirFryGoodsQuenes.Count > 0) return;//只能一个一个做 //if (Json.Data.LocalstirFryGoods.StirPotActions.Count > 0) //{ // StirFryGoodsQuenes.Enqueue(new OrderLocInfo() // { // SuborderId = Guid.NewGuid().ToString(), // StirPotActions = Json.Data.LocalstirFryGoods.StirPotActions, // GoodName = "本地菜品" // }); // MessageLog.GetInstance.Show($"添加本地模拟的订单{Json.Data.LocalstirFryGoods.GoodsKey}"); //} if (Json.Data.materials.Count > 0) { if (!Json.Data.materials.ContainsKey(materialName)) { return; } List potActions = new List(); foreach(var item in Json.Data.materials[materialName]) { potActions.Add(item); } StirFryGoodsQuenes.Enqueue(new OrderLocInfo() { SuborderId = Guid.NewGuid().ToString(), StirPotActions = potActions, GoodName = materialName }); MessageLog.GetInstance.Show($"添加本地模拟的订单{Json.Data.LocalstirFryGoods.GoodsKey}"); MessageBox.Show("下单成功"); } } /// /// 停止本地菜单炒制 /// private void StopLocalOrder(int num = -1) { //判断当前是否有炒制菜品 if (nowStirFryGood == null) return; //根据morkFs中是否有num执行不同的停止操作 if (!morkFs.ContainsKey(num)) { //根据调试界面的当前炒锅编号停止炒制线程 ThreadManage.GetInstance().StopTask(String.Format(striConst, fryIndex.ToString(), nowStirFryGood[fryIndex].GoodName), new Action(() => { Plc1Reset(fryIndex); })); } else { //根据炒锅编号停止炒制线程 ThreadManage.GetInstance().StopTask(String.Format(striConst, fryIndex.ToString(), nowStirFryGood[num].GoodName), new Action(() => { Plc1Reset(num); })); } } /// /// 重置程序 /// public override void ResetProgram() { IsHealth = true; morkFs.Clear(); morkFs = new Dictionary(); ml_morkf = new ML_MorkF(); //根据编号new炒锅实例对象 for (int i = 0; i < count; i++) { morkFs.Add(i, new GVL_MorkF()); } } #endregion #region 公用PLC方法 /// /// 获取设备PLC的所有状态 /// /// /// /// 炒锅编号 private void GetStatus(string key, Action action, int num) { if (dicPort2peripheralStatus.ContainsKey(num)) { if (dicPort2peripheralStatus[num].ContainsKey(key)) { action((object)dicPort2peripheralStatus[num][key]);//获取PLC指定地址的状态值 } } } /// /// PLC数据读取 /// public override void ReadData() { for (int i = 0; i < morkFs.Count; i++) { GetStatus("LB50", new Action((objects) => { if (!morkFs.ContainsKey(i)) { return; } if (objects is bool[] bools) { morkFs[i].FryPot1_InitialComplete = bools[0]; morkFs[i].FryPot1_HOBTPut = bools[1]; morkFs[i].FryPot1_HOBTGet = bools[2]; morkFs[i].FryPot1_MaterialIntoPot = bools[3]; morkFs[i].OutFoodCompelete = bools[4]; morkFs[i].CanOutFood = bools[5]; morkFs[i].GetFoodCompelete = bools[6]; morkFs[i].CanOutPotWashingWater = bools[7]; morkFs[i].ArmOnOrigin = bools[8]; morkFs[i].ArmOnWorking = bools[9]; morkFs[i].PotOnOrigin = bools[10]; } }), i); } for (int j = 0; j < morkFs.Count; j++) { GetStatus("LB74", new Action((objects) => { if (!morkFs.ContainsKey(j)) { return; } if (objects is bool[] bools) { for (int i = 0; i < 14; i++) { morkFs[j].PassWay1_Compelete[i] = bools[i]; } } }), j); } for (int i = 0; i < morkFs.Count; i++) { if (!morkFs.ContainsKey(i)) { return; } GetStatus("LB90", new Action((objects) => { if (objects is bool[] bools) { morkFs[i].AutoMode = bools[0]; } }), i); } } #endregion #region 菜品库方法 #region PLC操作 /// /// 菜品库数据写入 /// /// /// private void MaterailLibrary_Write(string address, object value, int num = 2) { WriteControlExact(address, value, num); } /// /// 菜品库初始化 /// public bool FoodLibInit() { MaterailLibrary_Write("M0.2", true); Thread.Sleep(500); for (int i = 0; i < materialSleepCount && !ml_morkf.InitialComplete; i++) { Thread.Sleep(materialSleepTime); if (i >= materialSleepCount - 1) { MessageLog.GetInstance.ShowEx("菜品库初始化超时"); return false; } } return true; } /// /// 爪子伸出 /// /// 电磁阀启停:true:启动。false:停止。 public bool PawExtend() { if (!ml_morkf.InitialComplete) { MessageLog.GetInstance.ShowEx("爪子伸出错误,菜品库未初始化"); return false; } Thread.Sleep(500); MaterailLibrary_Write("M0.6", true); for (int i = 0; i < materialSleepCount && !ml_morkf.PawOutComplete; i++)//潘华小炒没有夹爪到位功能 { Thread.Sleep(materialSleepTime); if (i >= materialSleepCount - 1) { MessageLog.GetInstance.ShowEx("爪子伸出超时"); return false; } } return true; ////等待爪子伸出延时4s //Thread.Sleep(6000); } /// /// 爪子收缩 /// /// 电磁阀启停:true:启动。false:停止。 public bool PawShrink() { if (!ml_morkf.InitialComplete) { MessageLog.GetInstance.ShowEx("爪子伸出错误,菜品库未初始化"); return false; } MaterailLibrary_Write("M0.7", true); Thread.Sleep(500); for (int i = 0; i < materialSleepCount && !ml_morkf.PawInComplete; i++)//潘华小炒没有夹爪到位功能 { Thread.Sleep(materialSleepTime); if (i >= materialSleepCount - 1) { MessageLog.GetInstance.ShowEx("爪子伸出超时"); return false; } } return true; //等待爪子收缩延时4s //Thread.Sleep(6000); } /// /// 电磁阀启停 /// /// 电磁阀启停:true:启动。false:停止。 public void Electromagnetism(object o) { if (!ml_morkf.InitialComplete) { MessageLog.GetInstance.ShowEx("电磁阀启停出错,菜品库未初始化"); return; } if (o == null) return; if (o is List bs && bs.Count == 1) { MaterailLibrary_Write("M1.3", bs[0]); } } public bool PawToPoint1() { if (!ml_morkf.InitialComplete) { MessageLog.GetInstance.ShowEx("爪子去到1号位出错,菜品库未初始化"); return false; } //MessageLog.GetInstance.Show("爪子去到1号位"); MaterailLibrary_Write("M1.0", true); Thread.Sleep(500); for (int i = 0; i < materialSleepCount && !ml_morkf.PawArrivePortOne; i++) { Thread.Sleep(materialSleepTime); if (i >= materialSleepCount - 1) { if (i == 10) { MaterailLibrary_Write("M1.0", true); } MessageLog.GetInstance.ShowEx("爪子去到1号位超时"); return false; } } Thread.Sleep(300); //MessageLog.GetInstance.Show("爪子去到1号位完成"); return true; } public bool PawToPoint2() { if (!ml_morkf.InitialComplete) { MessageLog.GetInstance.ShowEx("爪子去到2号位出错,菜品库未初始化"); return false; } MaterailLibrary_Write("M1.1", true); //MessageLog.GetInstance.Show("爪子去到2号位"); Thread.Sleep(500); for (int i = 0; i < materialSleepCount && !ml_morkf.PawArrivePortTwo; i++) { Thread.Sleep(materialSleepTime); if (i >= materialSleepCount - 1) { if (i == 10) { MaterailLibrary_Write("M1.1", true); } MessageLog.GetInstance.ShowEx("爪子去到2号位超时"); return false; } } Thread.Sleep(300); //MessageLog.GetInstance.Show("爪子去到2号位完成"); return true; } public bool PawToPoint3() { if (!ml_morkf.InitialComplete) { MessageLog.GetInstance.ShowEx("爪子去到3号位出错,菜品库未初始化"); return false; } //MessageLog.GetInstance.Show("爪子去到3号位"); MaterailLibrary_Write("M1.2", true); Thread.Sleep(500); for (int i = 0; i < materialSleepCount && !ml_morkf.PawArrivePortThree; i++) { Thread.Sleep(materialSleepTime); if(i == 30) { MaterailLibrary_Write("M1.2", true); } if (i >= materialSleepCount - 1) { MessageLog.GetInstance.ShowEx("爪子去到3号位超时"); } } if (!ml_morkf.PawPositon_3) { MaterailLibrary_Write("M1.2", true); Thread.Sleep(3000); } Thread.Sleep(300); //MessageLog.GetInstance.Show("爪子去到3号位完成"); return true; } public bool GetDistance_1() { if (!ml_morkf.InitialComplete) { MessageLog.GetInstance.ShowEx("1号测距出错,菜品库未初始化"); return false; } MaterailLibrary_Write("M0.3", true); MaterailLibrary_Write("M0.3", false); Thread.Sleep(3000); //MessageLog.GetInstance.Show("1号测距开启完成"); //MessageLog.GetInstance.Show($"传感器的距离{ml_morkf.LaserDistance}"); ActionManage.GetInstance.Send("GetDistanceCallBack", new List { "1",ml_morkf.LaserDistance.ToString() });//通知获取测距界面 return true; } public bool GetDistance_2() { if (!ml_morkf.InitialComplete) { MessageLog.GetInstance.ShowEx("2号测距出错,菜品库未初始化"); return false; } MaterailLibrary_Write("M0.4", true); MaterailLibrary_Write("M0.4", false); Thread.Sleep(3000); //MessageLog.GetInstance.Show("2号测距开启完成"); //MessageLog.GetInstance.Show($"传感器的距离{ml_morkf.LaserDistance}"); ActionManage.GetInstance.Send("GetDistanceCallBack", new List { "2", ml_morkf.LaserDistance.ToString() });//通知获取测距界面 return true; } public bool GetDistance_3() { if (!ml_morkf.InitialComplete) { MessageLog.GetInstance.ShowEx("3号测距出错,菜品库未初始化"); return false; } MaterailLibrary_Write("M0.5", true); MaterailLibrary_Write("M0.5", false); Thread.Sleep(3000); //MessageLog.GetInstance.Show("3号测距开启完成"); //MessageLog.GetInstance.Show($"传感器的距离{ml_morkf.LaserDistance}"); ActionManage.GetInstance.Send("GetDistanceCallBack", new List { "3", ml_morkf.LaserDistance.ToString() });//通知获取测距界面 return true; } /// /// 写入传感器距离 /// /// public void WriteSpeed(int speed) { MaterailLibrary_Write("VD808", speed); Thread.Sleep(400); } /// /// 写入传感器距离 /// /// public void WriteDistance(int distance) { MaterailLibrary_Write("VW270", distance); } /// /// 根据x坐标获取传感器距离 /// /// /// public bool GetDistance(int x) { bool ret = true; //是否在第一层菜品库 if (x > 0 && x <= MaterialCoordinate.GetInstance().dicNoMaterialCoordinate["1"].X) { //获取传感器1的距离 ret &= GetDistance_1(); Thread.Sleep(400); ////获取传感器1的距离 ret &= GetDistance_1(); } //是否在第二层菜品库 else if (x > MaterialCoordinate.GetInstance().dicNoMaterialCoordinate["1"].X && x <= MaterialCoordinate.GetInstance().dicNoMaterialCoordinate["10"].X) { //获取传感器2的距离 ret &= GetDistance_2(); Thread.Sleep(400); ret &= GetDistance_2(); } //是否在第三层菜品库 else if (x > MaterialCoordinate.GetInstance().dicNoMaterialCoordinate["10"].X && x <= MaterialCoordinate.GetInstance().dicNoMaterialCoordinate["19"].X) { //获取传感器3的距离 ret &= GetDistance_3(); Thread.Sleep(400); ret &= GetDistance_3(); } if (!ret) { MessageLog.GetInstance.ShowEx($"错误:X轴:{x}获取传感器数据出错"); } return ret; } /// /// 设定机械臂的位置 /// /// /// public bool SetArmPosition(int x, int y) { if (!ml_morkf.InitialComplete) { MessageLog.GetInstance.ShowEx($"机械臂移动出错,菜品库未初始化"); return false; } if (x>212000|| y >240000) { MessageLog.GetInstance.ShowEx("机械臂移动超出范围"); return false; } //取反 x = 0 - Math.Abs(x); y = 0 - Math.Abs(y); if (x > 0 || y > 0) { MessageLog.GetInstance.ShowEx($"机械臂移动到[{x},{y}]非法"); return false; } MaterailLibrary_Write("VD836", x); Thread.Sleep(100); MaterailLibrary_Write("VD840", y); Thread.Sleep(200); //MessageLog.GetInstance.Show($"机械臂移动到[{x},{y}]"); //到达置为false ml_morkf.ArriveComplete = false; //定位启动 MaterailLibrary_Write("M0.0", true); Thread.Sleep(400); for (int i = 0; i < materialSleepCount && (!ml_morkf.ArriveComplete); i++) { Thread.Sleep(materialSleepTime); //若是目标点与当前坐标一致,跳出循环 if((ml_morkf.ArmPositionX == x && ml_morkf.ArmPositionY == y)) { MessageLog.GetInstance.Show($"机械臂已移动到[{ml_morkf.ArmPositionX},{ml_morkf.ArmPositionY}]"); break; } if (i >= materialSleepCount - 1) { MessageLog.GetInstance.ShowEx("机械臂移动操作超时"); return false; } } //MessageLog.GetInstance.Show("机械臂移动操作完成"); Thread.Sleep(300); return true; } /// /// 设定机械臂的当前坐标 /// /// /// public void SetNowPosition(int x, int y) { //取反 x -= 2 * x; y -= 2 * y; //MessageLog.GetInstance.Show($"设置机械臂当前坐标为[{x},{y}]"); MaterailLibrary_Write("VD828", x); Thread.Sleep(200); MaterailLibrary_Write("VD832", y); Thread.Sleep(200); } /// /// 机械臂向上移动开关 /// /// true:开启,false:关闭 public void ArmRunUp(bool startOrStop) { MaterailLibrary_Write("M5.3", startOrStop); Thread.Sleep(200); } /// /// 机械臂向下移动开关 /// /// true:开启,false:关闭 public void ArmRunDown(bool startOrStop) { MaterailLibrary_Write("M5.4", startOrStop); Thread.Sleep(200); } /// /// 机械臂向左移动开关 /// /// true:开启,false:关闭 public void ArmRunLeft(bool startOrStop) { MaterailLibrary_Write("M5.5", startOrStop); Thread.Sleep(200); } /// /// 机械臂向右移动开关 /// /// true:开启,false:关闭 public void ArmRunRight(bool startOrStop) { MaterailLibrary_Write("M5.6", startOrStop); Thread.Sleep(200); } #endregion //菜品库锁 object lock_Materail = new object(); /// /// 取菜操作 /// /// 取菜x轴坐标 /// 取菜y轴坐标 /// 炒锅编号 public bool GetMaterail(int x, int y, int fryNum) { //设置到抓菜处 if (!SetArmPosition(x, y)) { return false; } if (!GetDistance(x)) { MessageLog.GetInstance.Show("错误:获取传感器数据出错"); return false; } Thread.Sleep(1000); //获取传感器的距离,转换成坐标系的点 int laserHigh = ml_morkf.LaserDistance; //秦工要求读取后置0 WriteDistance(0); MessageLog.GetInstance.Show($"传感器的距离{laserHigh}"); int moveX = 0; if (LaserDistance2Coordinate(laserHigh, x, out moveX) != Laser2CoordinateState.MaterialNormal) { MessageLog.GetInstance.ShowEx("错误:传感器距离转坐标值失败"); return false; } if (x < moveX) { MessageLog.GetInstance.ShowEx("错误:传感器距离转坐标值大于当前x轴坐标"); return false; } //设置到传感器感应的距离处 if (!SetArmPosition(x - moveX, y)) { return false; } WriteSpeed(10000); //关闭电磁阀 Electromagnetism(new List { true }); Thread.Sleep(500); //爪子去1号位抓菜 if (!PawToPoint1()) { return false; } //伸出爪子 if (!PawExtend()) { return false; } //移动前开启电磁阀 Electromagnetism(new List { false }); Thread.Sleep(500); //根据x轴所在坐标系,计算高度差。 if( (x > 0 && x <= MaterialCoordinate.GetInstance().dicNoMaterialCoordinate["1"].X)&& (MaterialCoordinate.GetInstance().MaterialOneX > 0 && MaterialCoordinate.GetInstance().MaterialOneX < x)) { //菜品盒子出菜品库,往上移动一个盒子的距离 if (!SetArmPosition(MaterialCoordinate.GetInstance().MaterialOneX, y)) { return false; } } else if( (x <= MaterialCoordinate.GetInstance().dicNoMaterialCoordinate["10"].X && x > MaterialCoordinate.GetInstance().dicNoMaterialCoordinate["1"].X)&& (MaterialCoordinate.GetInstance().MaterialTwoX > 0 && MaterialCoordinate.GetInstance().MaterialTwoX < x)) { //菜品盒子出菜品库,往上移动一个盒子的距离 if (!SetArmPosition(MaterialCoordinate.GetInstance().MaterialTwoX, y)) { return false; } } else if ((x > MaterialCoordinate.GetInstance().dicNoMaterialCoordinate["10"].X && x <= MaterialCoordinate.GetInstance().dicNoMaterialCoordinate["20"].X) && (MaterialCoordinate.GetInstance().MaterialThreeX > 0 && MaterialCoordinate.GetInstance().MaterialThreeX < x)) { //菜品盒子出菜品库,往上移动一个盒子的距离 if (!SetArmPosition(MaterialCoordinate.GetInstance().MaterialThreeX, y)) { return false; } } else { MessageLog.GetInstance.ShowEx("错误:未设置当前菜品库出菜位置"); return false; } //爪子去2号位放菜 if (!PawToPoint2()) { return false; } WriteSpeed(50000);//移动速度 //ThreadManage.GetInstance().Start(new Action(() => //{ // //收缩爪子 // PawShrink(); //}), "GetMaterialPawShrink"); //收缩爪子 if (!PawShrink()) return false; //判断炒锅是否可以放盒 for (int i = 0; materialSleepCount > i && !morkFs[fryNum].FryPot1_HOBTPut; i++) { Thread.Sleep(materialSleepTime); if (i >= materialSleepCount - 1) { MessageLog.GetInstance.ShowEx("等待炒锅允许放盒超时"); return false; } } //关闭启磁吸 MagnetOff(fryNum); //Thread.Sleep(2000); //根据炒锅不同设置不同的出菜处 if (fryNum % 2 == 0) { x = MaterialCoordinate.GetInstance().frying1.X; y = MaterialCoordinate.GetInstance().frying1.Y; } else { x = MaterialCoordinate.GetInstance().frying2.X; y = MaterialCoordinate.GetInstance().frying2.Y; } //先设置到炒锅i出菜处上10000点 if (!SetArmPosition(x - materialToFryDistance, y)) { return false; } //爪子去3号位放菜 if (!PawToPoint3()) { return false; } //开启磁吸 MagnetOn(fryNum); Thread.Sleep(500); //设置到炒锅1出菜处 if (!SetArmPosition(x, y)) { return false; } //伸出爪子 if (!PawExtend()) { return false; } Thread.Sleep(300); //关闭电磁阀 Electromagnetism(new List { true }); Thread.Sleep(300); //收缩爪子 if (!PawShrink()) return false; //设置到炒锅i出菜处 if (!SetArmPosition(x + materialToFryDistance, y)) { return false; } //爪子回到2号位 if (!PawToPoint2()) { return false; } //开启电磁阀 Electromagnetism(new List { false }); if (morkFs.ContainsKey(fryNum)) { morkFs[fryNum].GetMaterialComplete = true; } return true; } /// /// 更新菜品库存量 /// /// public bool UpdateMaterialLibraryStock() { try { //判断是否初始化 if (!ml_morkf.InitialComplete) { MessageLog.GetInstance.Show("更新菜品库存量出错,菜品库未初始化"); return false; } if (MaterialCoordinate.GetInstance().dicNoMaterialCoordinate == null || MaterialCoordinate.GetInstance().dicNoMaterialCoordinate.Count != 27) { MessageLog.GetInstance.ShowEx("更新菜品库存量出错,菜品库坐标系数据未建立"); return false; } //关闭电磁阀 Electromagnetism(new List { true }); //爪子收回 if (!PawShrink()) { return false; } //爪子去2号点位 if (!PawToPoint2()) { return false; } //开启电磁阀 Electromagnetism(new List { false }); //遍历坐标系与位置,并根据位置更新菜品余量 foreach (var item in MaterialCoordinate.GetInstance().dicNoMaterialCoordinate) { bool ret = true; switch (item.Key) { //遇到1 9 10 18 19 27号位置跳过不检测,因为这6个位置不放菜品 case "1": case "9": case "10": case "18": case "19": case "27": ret = false; break; } if (!ret) { continue; } //设置到抓菜处 if (!SetArmPosition(item.Value.X, item.Value.Y)) { return false; } //获取该处的距离 if (!GetDistance(item.Value.X)) { MessageLog.GetInstance.ShowEx("错误:获取传感器数据出错"); return false; } Thread.Sleep(1000); //获取传感器的距离 int laserHigh = ml_morkf.LaserDistance; //秦工要求读取后置0 WriteDistance(0); int surplus = 0; //根据距离算出菜品余量 Laser2CoordinateState state = LaserDistance2MaterialCount(laserHigh, item.Value.X, out surplus); if (state != Laser2CoordinateState.MaterialNormal && state != Laser2CoordinateState.MaterialEmpty) { return false; } //更新菜品余量 if (!MaterialSurplusOperation.GetInstance().UpdateSurplus(item.Key, surplus)) { //return false; } } return true; } catch(Exception ex) { return false; } } /// /// 传感器距离转为x轴坐标系 /// /// /// /// public Laser2CoordinateState LaserDistance2Coordinate(int distance, int x, out int x_high) { x_high = 0; int boxCount = 0; try { Laser2CoordinateState laser2CoordinateState = LaserDistance2MaterialCount(distance, x, out boxCount); if (laser2CoordinateState == Laser2CoordinateState.MaterialNormal) { int compensateHeight = boxCount > 1 ? 500 : 0;//补偿高度,超过1层盒子增加补偿 //盒子高度计算除去起始位置的那个盒子 x_high = (boxCount - 1) * materialBoxHeight + compensateHeight; } return laser2CoordinateState; } catch(Exception ex) { return Laser2CoordinateState.MaterialUnkown; } } /// /// 传感器距离转为菜品数量 /// /// /// /// public Laser2CoordinateState LaserDistance2MaterialCount(int distance, int x, out int count) { count = 0; try { //传感器高度小于80mm,无法移出,菜品库满 if (distance < 80) { MessageLog.GetInstance.ShowEx("错误:传感器距离不满足出菜高度"); return Laser2CoordinateState.MaterialOverdo; } int heightDifferent = 0; //根据x轴所在坐标系,计算高度差。 if (x > 0 && x <= MaterialCoordinate.GetInstance().dicNoMaterialCoordinate["1"].X) { heightDifferent = MaterialCoordinate.GetInstance().distance_1 - distance; } else if (x <= MaterialCoordinate.GetInstance().dicNoMaterialCoordinate["10"].X && x > MaterialCoordinate.GetInstance().dicNoMaterialCoordinate["1"].X) { heightDifferent = MaterialCoordinate.GetInstance().distance_2 - distance; } else if (x > MaterialCoordinate.GetInstance().dicNoMaterialCoordinate["10"].X && x <= MaterialCoordinate.GetInstance().dicNoMaterialCoordinate["20"].X) { heightDifferent = MaterialCoordinate.GetInstance().distance_3 - distance; } else { return Laser2CoordinateState.MaterialOverdo; } if(heightDifferent < 0) { MessageLog.GetInstance.ShowEx($"菜品库检测{x}处的菜品量时,传感器获取的高度差为负数,请校准该层高度"); return Laser2CoordinateState.MaterialEmpty; ; } //盒子高度为45,但是需要考虑到误差,不足35,则认为为空 int boxCount = (heightDifferent + 5) / 35; count = boxCount; if (count == 0) { MessageLog.GetInstance.ShowEx("菜品库为空"); return Laser2CoordinateState.MaterialEmpty; } else if(count > 6) { MessageLog.GetInstance.ShowEx("菜品库数量超量"); return Laser2CoordinateState.MaterialOverdo; } else { return Laser2CoordinateState.MaterialNormal; } } catch (Exception ex) { return Laser2CoordinateState.MaterialUnkown; } } /// /// 获取菜品测试 /// /// private void GetMaterailTest(MaterialOperation materialOperation) { ThreadManage.GetInstance().Start(new Action(() => { bool ret = false; try { Coordinate myCoordinate = new Coordinate(); //获取坐标,根据菜品的位置信息 if (!NoMaterial2Coordinate(materialOperation.materialInfo.Loc, out myCoordinate)) { MessageLog.GetInstance.ShowEx($"炒锅{materialOperation.fryNum}获取菜品[{materialOperation.materialInfo.Name}]失败,找不到对应位置"); return; } //取菜操作 ret = GetMaterail(myCoordinate.X, myCoordinate.Y, materialOperation.fryNum); } catch (Exception ex) { ret = false; } finally { //本地炒制不进行菜品数量检查 if(!isLocalFryingMode) { GoodBatchings goodBatchings = stagingGoodBatchings.Find(o => o.BatchingId == materialOperation.materialInfo.Key); if (ret == true) { if (true) { if (goodBatchings != null) { //指定位置菜品减一 MaterialSurplusOperation.GetInstance().ReduceSurplus(materialOperation.materialInfo.Loc, goodBatchings.BatchingCount); } } else { //指定位置菜品减一 MaterialSurplusOperation.GetInstance().ReduceSurplus(materialOperation.materialInfo.Loc); } SaveMaterialData(); } //移出占用菜品 stagingGoodBatchings.Remove(goodBatchings); } ml_morkf.MaterailIsWorking = false; } }), $"菜品库操作"); } #endregion #region 炒锅PLC基本操作方法 /// /// 炒锅写寄存器方法,num为炒锅对应编号,从0开始 /// /// 寄存器地址 /// 值 /// 炒锅编号 private void FirePot_Write(string address, object value, int num) { WriteControlExact(address, value, num); } /// /// 出调料 /// /// public void OutSeasoning(object o, int num) { if (o == null) return; if (o is List ints && ints.Count == 2 && morkFs.ContainsKey(num)) { FirePot_Write(morkFs[num].PassWayValue[ints[0]], (ushort)ints[1], num);//写入通道值 Thread.Sleep(400); FirePot_Write(morkFs[num].StartPassWay[ints[0]], true, num);//开启通道 Thread.Sleep(400); FirePot_Write(morkFs[num].StartPassWay[ints[0]], false, num);//开启通道 } } /// /// 出多个调料 /// public void OutSeasonings(List seasoningLists, int num) { //防止越界 if (!morkFs.ContainsKey(num)) { return; } foreach (SeasoningList seasoning in seasoningLists) { FirePot_Write(morkFs[num].PassWayValue[seasoning.Loc], (ushort)seasoning.Qty, num); Thread.Sleep(300); } foreach (SeasoningList seasoning in seasoningLists) { FirePot_Write(morkFs[num].StartPassWay[seasoning.Loc], true, num); Thread.Sleep(300); } foreach (SeasoningList seasoning in seasoningLists) { FirePot_Write(morkFs[num].StartPassWay[seasoning.Loc], false, num); Thread.Sleep(300); } foreach (SeasoningList seasoning in seasoningLists) { FirePot_Write(morkFs[num].StartPassWay[seasoning.Loc], false, num); Thread.Sleep(300); } } /// /// 复位 /// public void Plc1Reset(int num) { ThreadManage.GetInstance().Start(new Action(() => { StopFire(num); Thread.Sleep(200); StopStir(num); Thread.Sleep(200); FirePot_Write("LB5", false, num); Thread.Sleep(200); FirePot_Write("LB3", false, num); Thread.Sleep(200); FirePot_Write("LB6", false, num); Thread.Sleep(200); FirePot_Write("LB7", false, num); Thread.Sleep(200); FirePot_Write("LB4", false, num); Thread.Sleep(200); FirePot_Write("LB53", false, num); if (morkFs.ContainsKey(num)) { foreach (var item in morkFs[num].StartPassWay.Values) { Thread.Sleep(200); FirePot_Write(item, false, num); } } }), $"炒锅{num}初始化"); } /// /// 炒锅初始化 /// public void PLCInite() { for (int i = 0; i < morkFs.Count; i++) { FirePot_Write("LB0", true, i); for (int j = 0; j < sleepCount && !morkFs[i].FryPot1_InitialComplete; j++) { Thread.Sleep(sleepTime); if (j >= sleepCount - 1) { MessageLog.GetInstance.ShowEx($"炒锅{j}初始化超时"); } } FirePot_Write("LB0", false, i); } } //加油 public void AddOil() { } //加热启动 public void StartFire(int num) { FirePot_Write("LB1", true, num); Thread.Sleep(200); } //加热停止 public void StopFire(int num) { FirePot_Write("LB1", false, num); Thread.Sleep(200); } //搅拌启动 public void StartStir(int num) { FirePot_Write("LB2", true, num); Thread.Sleep(200); } //搅拌启停止 public void StopStir(int num) { FirePot_Write("LB2", false, num); Thread.Sleep(200); } //倒菜 public bool OutFood(int num,out string error,bool isMaterial = false) { bool ret = true; error = string.Empty; if (!morkFs.ContainsKey(num)) { error = $"编号为{num}的炒锅无法找到"; return false; } int i = 0; MessageLog.GetInstance.Show("倒菜启动开始"); if (isMaterial) { //判断是否完成取菜 for (i = 0; i < materialSleepCount*2 && !morkFs[num].GetMaterialComplete; i++) { if (i == 10) { //停止搅拌 //StopStir(num); //搅拌设置为1档 SetStir(new List { 1 }, i); //火力设置为2档 SetFire(new List { 3 }, num); } Thread.Sleep(materialSleepTime); if (i >= materialSleepCount * 2 - 1) { error = $"炒锅{num}倒菜超时:未能等到取菜完成,请检查菜品库是否正常运行"; MessageLog.GetInstance.ShowEx($"炒锅{num}倒菜超时:未能等到取菜完成"); ret &= false; } } if (i > 9) { //开启搅拌 //StartStir(num); //搅拌设置为原本搅拌档位 SetStir(new List { morkFs[num].Stir }, i); //火力设置回原本火力 SetFire(new List { morkFs[num].Fire }, num); } } if(!ret) { return ret; } FirePot_Write("LB3", true, num); //MessageLog.GetInstance.Show("倒菜启动"); Thread.Sleep(500); for (i = 0; i < materialSleepCount && !morkFs[num].FryPot1_MaterialIntoPot; i++) { Thread.Sleep(materialSleepTime); if (i >= materialSleepCount - 1) { error = $"炒锅{num}倒菜超时,请联系相关工作人员"; MessageLog.GetInstance.ShowEx($"炒锅{num}倒菜超时"); ret &= false; } } FirePot_Write("LB3", false, num); Thread.Sleep(200); //MessageLog.GetInstance.Show("倒菜完成"); morkFs[num].GetMaterialComplete = false; return ret; } //搅拌臂去原点位 public void StirArmGoOrigin(int num) { if (!morkFs.ContainsKey(num)) { return; } FirePot_Write("LB5", true, num); //MessageLog.GetInstance.Show("搅拌臂去原点位"); for (int i = 0; i < sleepCount && !morkFs[num].ArmOnOrigin; i++) { Thread.Sleep(sleepTime); if (i >= sleepCount - 1) { MessageLog.GetInstance.ShowEx($"炒锅{num}搅拌臂去原点位超时"); } } FirePot_Write("LB5", false, num); Thread.Sleep(200); //MessageLog.GetInstance.Show("搅拌臂到达原点位"); } //搅拌臂去炒制位 public bool StirArmGoWork(int num,out string error) { error = string.Empty; bool ret = true; if (!morkFs.ContainsKey(num)) { error = $"编号为{num}的炒锅无法找到"; return false; } if (!morkFs[num].ArmOnWorking/* && morkFs[num].PotOnOrigin*/) { FirePot_Write("LB6", true, num); //MessageLog.GetInstance.Show("搅拌臂去工作位"); for (int i = 0; i < sleepCount && !morkFs[num].ArmOnWorking; i++) { Thread.Sleep(sleepTime); if (i >= sleepCount - 1) { error = $"炒锅{num}搅拌臂去炒制位超时"; MessageLog.GetInstance.ShowEx($"炒锅{num}搅拌臂去炒制位超时"); ret &= false; } } //while (!morkFs[num].ArmOnWorking) //{ // Thread.Sleep(200); //} FirePot_Write("LB6", false, num); Thread.Sleep(200); //MessageLog.GetInstance.Show("搅拌臂到达工作位"); return ret; } return true; } //HBOT放盒子到位 public void HBOTGoWork(int num) { FirePot_Write("LB7", true, num); Thread.Sleep(400); FirePot_Write("LB7", false, num); } //出餐启动 public void OutMeal(int num) { if (!morkFs[num].ArmOnOrigin /*&& morkFs[num].PotOnOrigin*/) { MessageLog.GetInstance.ShowEx("搅拌臂不在原点位,无法完成出餐"); return; } FirePot_Write("LB4", true, num); Thread.Sleep(500); FirePot_Write("LB4", false, num); } //加热挡位设定 public void SetFire(object o, int num) { if (o == null) return; if (o is List ints && ints.Count == 1) { FirePot_Write("LW14", (ushort)ints[0], num); Thread.Sleep(200); } } public void SetFry(object o) { if (o == null) return; if (o is List ints && ints.Count == 1) { fryIndex = ints[0] - 1; } } /// /// 搅拌挡位设定 /// /// public void SetStir(object o, int num) { if (o == null) return; if (o is List ints && ints.Count == 1) { FirePot_Write("LW15", (ushort)ints[0], num); Thread.Sleep(200); } } /// /// 开启磁吸 /// /// public void MagnetOn(int num) { FirePot_Write("LB8", false, num); Thread.Sleep(200); } /// /// 关闭磁吸 /// /// public void MagnetOff(int num) { FirePot_Write("LB8", true, num); Thread.Sleep(200); } #endregion bool isInitialArrive = false; bool isInitialPaw = false; #region 联网交互 private void ServerInit() { //物料信息 EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) { if (@event == null) return; if (@event is MaterialDeliveryEvent material) { orderMaterialDelivery = material.orderMaterialDelivery; } }); //配方数据信息 EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) { if (@event == null) return; if (@event is RecipeBomEvent recipe) { recipeBoms = recipe.recipeBoms; } }); //小炒流程信息 EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callback) { if (@event == null) return; if (@event is StirFryGoodsEvent stirFry) { if(stirFry.stirFrymessage != null) { if (stirFry.stirFrymessage.stirFryGoods.Count > 0) { foreach (var item in stirFry.stirFrymessage.stirFryGoods) { LocalstirFryGoods.Add(new StirFryGoods { GoodsKey = item.GoodsKey, StirPotActions = OrderSort(item.StirPotActions), }); } } MessageLog.GetInstance.Show("接收到小炒流程信息"); //流程解析 foreach (var item in LocalstirFryGoods) { MessageLog.GetInstance.Show($"添加菜谱{item.GoodsKey}"); // morkF.listStirBom.Add(item.StirFryBomInfo);//添加订单制作流程 string MenuStep = "菜单步骤:"; foreach (var items in item.StirPotActions) { switch (items.Actions) { case nameof(StirFryPotActionEnum.加热开启): MenuStep += items.Actions + ","; break; case nameof(StirFryPotActionEnum.设置加热挡位1): MenuStep += items.Actions + ","; break; case nameof(StirFryPotActionEnum.设置加热挡位2): MenuStep += items.Actions + ","; break; case nameof(StirFryPotActionEnum.设置加热挡位3): MenuStep += items.Actions + ","; break; case nameof(StirFryPotActionEnum.设置加热挡位4): MenuStep += items.Actions + ","; break; case nameof(StirFryPotActionEnum.设置加热挡位5): MenuStep += items.Actions + ","; break; case nameof(StirFryPotActionEnum.设置加热挡位6): MenuStep += items.Actions + ","; break; case nameof(StirFryPotActionEnum.设置加热挡位7): MenuStep += items.Actions + ","; break; case nameof(StirFryPotActionEnum.设置加热挡位8): MenuStep += items.Actions + ","; break; case nameof(StirFryPotActionEnum.设置加热挡位9): MenuStep += items.Actions + ","; break; case nameof(StirFryPotActionEnum.设置加热挡位10): MenuStep += items.Actions + ","; break; case nameof(StirFryPotActionEnum.停止加热): MenuStep += items.Actions + ","; break; case nameof(StirFryPotActionEnum.加调料): MenuStep += items.Actions + ","; break; case nameof(StirFryPotActionEnum.取原料): MenuStep += items.Actions + ","; break; case nameof(StirFryPotActionEnum.开启搅拌): MenuStep += items.Actions + ","; break; case nameof(StirFryPotActionEnum.设置搅拌挡位1): MenuStep += items.Actions + ","; break; case nameof(StirFryPotActionEnum.设置搅拌挡位2): MenuStep += items.Actions + ","; break; case nameof(StirFryPotActionEnum.设置搅拌挡位3): MenuStep += items.Actions + ","; break; case nameof(StirFryPotActionEnum.关闭搅拌): MenuStep += items.Actions + ","; break; case nameof(StirFryPotActionEnum.出餐启动): MenuStep += items.Actions + ","; break; case nameof(StirFryPotActionEnum.道菜启动): MenuStep += items.Actions + ","; break; case nameof(StirFryPotActionEnum.炒制菜品): MenuStep += items.Actions + ","; break; case nameof(StirFryPotActionEnum.搅拌臂原点位): MenuStep += items.Actions + ","; break; case nameof(StirFryPotActionEnum.搅拌臂炒制位): MenuStep += items.Actions + ","; break; case nameof(StirFryPotActionEnum.洗锅): MenuStep += items.Actions + ","; break; default: break; } } MessageLog.GetInstance.Show(MenuStep); } if (stirFry.stirFrymessage.materials.Count > 0) { MaterialSurplusOperation.GetInstance().UpdateSurplusAll(stirFry.stirFrymessage.materials); SaveMaterialData(); } } } }); } /// /// 订单排序 /// /// /// private List OrderSort(List potActions) { if (potActions.Count > 1) { potActions.Sort( delegate (PotActions st1, PotActions st2) { //降序排列 //return st2.FryTime.CompareTo(st1.FryTime); //升序版(颠倒 st1 和 st2 即可) return st1.FryTime.CompareTo(st2.FryTime); }); } return potActions; } /// /// 订单状态发布 /// /// /// private void OrderChange(string Id , string goodName, ORDER_STATUS oRDER_STATUS,int deviceId) { EventBus.EventBus.GetInstance().Publish(new OrderStatusChangedEvent() { Status = oRDER_STATUS, GoodName = goodName,DeviceId = deviceId, SubOrderId =Id }); } /// /// 订单数据解析 /// private void DataParse() { //if (!morkFs.ContainsKey(num)) //{ // return; //} EventBus.EventBus.GetInstance().Subscribe(DeviceId, delegate (IEvent @event, EventCallBackHandle callBackHandle) { if (@event == null) return; if (@event is DoOrderEvent order) { if (order.MorkOrder.GoodBatchings == null) return; OrderCount++; DeviceProcessLogShow($"接收到{OrderCount}次订单"); Enum.GetNames(typeof(StirFryPotActionEnum)); if(true) { var res = LocalstirFryGoods?.FirstOrDefault(p => p.GoodsKey == order.MorkOrder.GoodsKey);//匹配订单对应制作流程 if(order.MorkOrder.GoodBatchings.Count <= 0) { return; } MaterialSurplus materialSurplus = MaterialSurplusOperation.GetInstance().materialSurplus; if (order.MorkOrder.DeviceId != DeviceId) { return; } ///遍历并增加到待用菜品库 foreach(var goodBatching in order.MorkOrder.GoodBatchings) { MaterialInfo materialInfo = MaterialSurplusOperation.GetInstance().materialSurplus.dicSurplus.Find( o => o.Key == goodBatching.BatchingId); if (materialInfo != null) { //if if(System.Convert.ToInt32(materialInfo.Qty) - goodBatching.BatchingCount < 0) { MessageLog.GetInstance.ShowEx($"{materialInfo.Name}不够,请更新菜品库,并点击检测"); return; } else { //查找是否有该菜品 GoodBatchings existingGoodBatchings = stagingGoodBatchings.Find( o => o.BatchingId== goodBatching.BatchingId ); //判断是否存在 if (existingGoodBatchings != null) { existingGoodBatchings.BatchingCount += goodBatching.BatchingCount; } else { stagingGoodBatchings.Add(goodBatching); } } } else { MessageLog.GetInstance.ShowEx($"ID为{goodBatching.BatchingId}的菜品无法找到,请联系售后人员"); return; } } //var res = LocalstirFryGoods[0]; if (res != null) { /* morkF.listStirBom.Add(res.StirFryBomInfo);*///添加订单制作流程 //添加到带炒小炒队列 if (StirFryGoodsQuenes.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null) { //待炒数量+1 StagingFryCount++; lock (lock_MainProcessExcute) { StirFryGoodsQuenes.Enqueue(new OrderLocInfo() { SuborderId = order.MorkOrder.SuborderId, StirPotActions = res.StirPotActions, GoodName = order.MorkOrder.GoodsName }); } } } } else { NewStartLocalOrder("莲白回锅"); } ////暂时使用本地菜单 //StartLocalOrder(); } }); } #endregion private object lock_MainProcessExcute = new object(); /// /// 倒菜锁 /// private object lock_OutMeal = new object(); /// /// 炒锅主流程 /// private void MainProcessExcute() { //判断是否有订单信息 if(StirFryGoodsQuenes.Count > 0) { //遍历炒锅,找到合适、空闲的炒锅 for(int i = 0;i { try { //待炒数量-1 StagingFryCount--; //正在炒制数量+1 FryingCount++; int testi = 0; string error = string.Empty; //初始化大屏 morkFs[i].ScreenInit(); bool ret = true; MessageLog.GetInstance.Show($"炒锅{i}开始炒制菜品{res.GoodName}"); OrderChange(res.SuborderId, res.GoodName, ORDER_STATUS.COOKING, DeviceId = i); morkFs[i].GoodName = res.GoodName; Coordinate myCoordinate = new Coordinate(); foreach (var potActions in res.StirPotActions) { if (ThreadManage.GetInstance().IsCanncel(String.Format(striConst, i.ToString(), nowStirFryGood[i].GoodName))) { return; } if(ret == false) { MessageLog.GetInstance.ShowEx("上一步操作未成功"); break; } ////调试大屏用代码 //Thread.Sleep(5000); //更新 morkFs[i].UpdateProcess(potActions); switch (potActions.Actions) { case nameof(StirFryPotActionEnum.加热开启): StartFire(i); MessageLog.GetInstance.Show(potActions.Actions); break; case nameof(StirFryPotActionEnum.设置加热挡位1): morkFs[i].Fire = 1; SetFire(new List { 1 }, i); MessageLog.GetInstance.Show(potActions.Actions); break; case nameof(StirFryPotActionEnum.设置加热挡位2): morkFs[i].Fire = 2; SetFire(new List { 2 }, i); MessageLog.GetInstance.Show(potActions.Actions); break; case nameof(StirFryPotActionEnum.设置加热挡位3): morkFs[i].Fire = 3; SetFire(new List { 3 }, i); MessageLog.GetInstance.Show(potActions.Actions); break; case nameof(StirFryPotActionEnum.设置加热挡位4): morkFs[i].Fire = 4; SetFire(new List { 4 }, i); MessageLog.GetInstance.Show(potActions.Actions); break; case nameof(StirFryPotActionEnum.设置加热挡位5): morkFs[i].Fire = 5; SetFire(new List { 5 }, i); MessageLog.GetInstance.Show(potActions.Actions); break; case nameof(StirFryPotActionEnum.设置加热挡位6): morkFs[i].Fire = 6; SetFire(new List { 6 }, i); MessageLog.GetInstance.Show(potActions.Actions); break; case nameof(StirFryPotActionEnum.设置加热挡位7): morkFs[i].Fire = 7; SetFire(new List { 7 }, i); MessageLog.GetInstance.Show(potActions.Actions); break; case nameof(StirFryPotActionEnum.设置加热挡位8): morkFs[i].Fire = 8; SetFire(new List { 8 }, i); MessageLog.GetInstance.Show(potActions.Actions); break; case nameof(StirFryPotActionEnum.设置加热挡位9): morkFs[i].Fire = 9; SetFire(new List { 9 }, i); MessageLog.GetInstance.Show(potActions.Actions); break; case nameof(StirFryPotActionEnum.设置加热挡位10): morkFs[i].Fire = 10; SetFire(new List { 10 }, i); MessageLog.GetInstance.Show(potActions.Actions); break; case nameof(StirFryPotActionEnum.停止加热): StopFire(i); MessageLog.GetInstance.Show(potActions.Actions); break; case nameof(StirFryPotActionEnum.加调料): OutSeasonings(potActions.SeasoningLists, i); MessageLog.GetInstance.Show(potActions.Actions); break; case nameof(StirFryPotActionEnum.取原料): if(potActions.SeasoningLists[0].Loc == 1 || potActions.SeasoningLists[0].Loc == 9 || potActions.SeasoningLists[0].Loc == 10 || potActions.SeasoningLists[0].Loc == 18 || potActions.SeasoningLists[0].Loc == 19 || potActions.SeasoningLists[0].Loc == 27 ) { MessageLog.GetInstance.ShowEx("该取料位置禁止使用"); return; } //炒锅取菜状态置为未取到 morkFs[i].GetMaterialComplete = false; if (isLocalFryingMode) { MaterialInfo materialInfo = new MaterialInfo(); materialInfo.Loc = potActions.SeasoningLists[0].Loc.ToString(); materialInfo.Id = "1232131"; materialInfo.Name = "本地炒制未知菜品"; materialOperationQuenes.Enqueue(new MaterialOperation { materialInfo = materialInfo, fryNum = i }); //testi++; } else { if (potActions.MaterialLists != null) { foreach (var item in potActions.MaterialLists) { //通过ID获取有效的菜品对象 MaterialInfo materialInfo = MaterialSurplusOperation.GetInstance().GetVailedMaterial(item.MaterialId); if (materialInfo == null) { MessageLog.GetInstance.ShowEx($"炒锅{i}获取菜品[{item.MaterialId}]失败,库存不足"); continue; } materialOperationQuenes.Enqueue(new MaterialOperation { materialInfo = materialInfo, fryNum = i }); } } else { MessageLog.GetInstance.ShowEx($"炒锅{i}获取菜品失败,菜品列表为空"); } } MessageLog.GetInstance.Show(potActions.Actions); break; case nameof(StirFryPotActionEnum.开启搅拌): StartStir(i); MessageLog.GetInstance.Show(potActions.Actions); break; case nameof(StirFryPotActionEnum.设置搅拌挡位1): SetStir(new List { 1 }, i); MessageLog.GetInstance.Show(potActions.Actions); break; case nameof(StirFryPotActionEnum.设置搅拌挡位2): SetStir(new List { 2 }, i); MessageLog.GetInstance.Show(potActions.Actions); break; case nameof(StirFryPotActionEnum.设置搅拌挡位3): SetStir(new List { 3 }, i); MessageLog.GetInstance.Show(potActions.Actions); break; case nameof(StirFryPotActionEnum.关闭搅拌): StopStir(i); MessageLog.GetInstance.Show(potActions.Actions); break; case nameof(StirFryPotActionEnum.出餐启动): //停止搅拌 StopStir(i); //回原点位 StirArmGoOrigin(i); //出餐启动 OutMeal(i); MessageLog.GetInstance.Show(potActions.Actions); break; case nameof(StirFryPotActionEnum.道菜启动): ret = OutFood(i, out error, true); if(ret == false) { alarmModel.Add(new BPA.Message.AlarmModel() { AlarmTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), AlarmMs = error }); } break; case nameof(StirFryPotActionEnum.炒制菜品): Thread.Sleep(potActions.During * 1000); break; case nameof(StirFryPotActionEnum.搅拌臂原点位): StirArmGoOrigin(i); MessageLog.GetInstance.Show(potActions.Actions); break; case nameof(StirFryPotActionEnum.搅拌臂炒制位): //出餐时,不允许搅拌臂去炒制位 lock (lock_OutMeal) { ret = StirArmGoWork(i, out error); } if (ret == false) { alarmModel.Add(new BPA.Message.AlarmModel() { AlarmTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), AlarmMs = error }); } MessageLog.GetInstance.Show(potActions.Actions); break; case nameof(StirFryPotActionEnum.洗锅): MessageLog.GetInstance.Show(potActions.Actions); break; default: break; } } Plc1Reset(i);//复位 Thread.Sleep(3000); //回原点位 StirArmGoOrigin(i); OrderChange(res.SuborderId, res.GoodName, ORDER_STATUS.COMPLETED_COOK, DeviceId = i); //同时只能允许有一个出餐 lock (lock_OutMeal) { //出餐启动 OutMeal(i); //等待25s出餐完毕 Thread.Sleep(25000); } MessageLog.GetInstance.Show($"菜品{res.GoodName}完成"); //菜品统计数量+1 morkFs[i].orderCount++; StatsModel statsModel = statsModels.FirstOrDefault(p => p.Name == res.GoodName); if (statsModel != null) { statsModel.Count++; } else { statsModels.Add(new StatsModel() { Name = res.GoodName, Count = 0 }); } } catch (Exception ex) { nowStirFryGood[i] = null; //炒完后出队列 morkFs[i].StirFryGoodsQuenes.TryDequeue(out var orderQueue); morkFs[i].FryWorking = false; //初始化大屏 morkFs[i].ScreenClear(); //异常菜品统计数量+1 morkFs[i].orderAbnormalCount++; ThreadManage.GetInstance().StopTask($"炒锅{i}{res.GoodName}炒制线程"); MessageLog.GetInstance.ShowEx($"炒锅{i}炒制菜品{res.GoodName}出错,错误信息:" + ex.Message); } finally { //正在炒制数量-1 FryingCount--; nowStirFryGood[i] = null; //炒完后出队列 morkFs[i].StirFryGoodsQuenes.TryDequeue(out var orderQueue); morkFs[i].FryWorking = false; //初始化大屏 morkFs[i].ScreenClear(); } }), String.Format(striConst, i.ToString(), nowStirFryGood[i].GoodName)/*$"炒锅{i}炒制{res.GoodName}线程"*/, true); } } break; } } } } /// /// 更新菜品库的余量 /// private void UpdateMaterialSurplus() { ThreadManage.GetInstance().StartLong(new Action(() => { List listSurplus = MaterialSurplusOperation.GetInstance().materialSurplus.dicSurplus; if (listSurplus == null) { return; } foreach (var surplus in listSurplus) { //找到已有的余量表 var batchingInfo = BatchingInfos.Find(o => o.BatchingId == surplus.Key); //从当前下单 var stagingGoodBatching = stagingGoodBatchings.Find(o => o.BatchingId == surplus.Key); //暂存的数量 int stagingCount = 0; if(stagingGoodBatching != null) { stagingCount = stagingGoodBatching.BatchingCount; } if (batchingInfo == null) { //为空就新增 BatchingInfos.Add(new BatchingInfo() { BatchingCount = System.Convert.ToInt32(surplus.Qty) - stagingCount, BatchingLoc = surplus.Loc, BatchingId = surplus.Key }); } else { batchingInfo.BatchingLoc = surplus.Loc; batchingInfo.BatchingCount = System.Convert.ToInt32(surplus.Qty) - stagingCount; } } Thread.Sleep(1000); return; }), "UpdateMaterialSurplus", true); } /// /// 菜品库主流程 /// private void MainProcessMaterial() { if(materialOperationQuenes.Count > 0) { //判断是否初始化与是否在工作中 if (ml_morkf.InitialComplete && !ml_morkf.MaterailIsWorking) { //待菜品库操作列出队列 if (materialOperationQuenes.TryDequeue(out var res)) { Thread.Sleep(1000); ml_morkf.MaterailIsWorking = true; MessageLog.GetInstance.Show("开始操作菜品库"); //ThreadManage.GetInstance().Start(new Action(()=>{ // GetMaterail(res.x_high, res.y, res.fryNum); //}),"菜品库操作"); GetMaterailTest(res); } } } } /// /// 信号处理 /// private void SingleProcess() { } private void ScreenDataServer() { LocalMqtt.GetInstance.Init(ScreenDeviceType.小炒); ThreadManage.GetInstance().StartLong(new Action(() => { //statsModels.Add(new StatsModel() { Name = "帝王蟹", Count = 666 }); ScreenModelMinWok maxWok = new ScreenModelMinWok { IsRun = IsHealth ? IsRun.运行 : IsRun.停止,//new Random().Next(0, 2) == 0 ? IsRun.运行 : IsRun.停止, //设备是否运行 WorkStatus_1 = morkFs[0].FryPot1_InitialComplete ? ((morkFs[0].Task != null)? WorkStatus.工作:WorkStatus.待机) : WorkStatus.停止,// (WorkStatus)new Random().Next(0, 3), //设备运行状态 WorkStatus_2 = morkFs[1].FryPot1_InitialComplete ? ((morkFs[1].Task != null) ? WorkStatus.工作 : WorkStatus.待机) : WorkStatus.停止,//(WorkStatus)new Random().Next(0, 3), //设备运行状态 RobotStatu = (WorkStatus)new Random().Next(0, 3), //机器人状态 待机 1 正常 Alarm = alarmModel, //告警集合 FailuresCount = alarmModel.Count, //故障数 StatsCount = statsModels, //统计菜品数量 MinWok_Dishes_1 = morkFs[0].GoodName,//"满汉全席",//当前炒制菜品名 MinWok_Dishes_2 = morkFs[1].GoodName, MinWok_Task_1 = morkFs[0].Task,//当前任务 MinWok_Task_2 = morkFs[1].Task, //当前任务 //MinWok_Process_1 = new List() { new ProcessModel() { Id = 1, Name = "启动", Status = ProcessStatus.正在执行 }, new ProcessModel() { Id = 1, Name = "热油", Status = ProcessStatus.未执行 }, new ProcessModel() { Id = 1, Name = "炒制", Status = ProcessStatus.未执行 }, new ProcessModel() { Id = 1, Name = "出餐", Status = ProcessStatus.未执行 }, new ProcessModel() { Id = 1, Name = "结束", Status = ProcessStatus.未执行 } }, MinWok_Process_1 = morkFs[0].processModels, //炒锅当前任务流程 MinWok_Process_2 = morkFs[1].processModels, //炒锅当前任务流程 MinWok_HeatGear_1 = morkFs[0].FireNow, //炒锅加热档位 MinWok_HeatGear_2 = morkFs[1].FireNow, //炒锅加热档位 MinWok_Temp_1 = morkFs[0].TempNow, //炒锅1锅底温度 MinWok_Temp_2 = morkFs[1].TempNow, //炒锅1锅底温度 MinWok_StirGear_1 = morkFs[0].StirNow, //炒锅搅拌档位 MinWok_StirGear_2 = morkFs[1].StirNow, //炒锅搅拌档位 MinWok_OrderCount_1 = morkFs[0].orderCount, //订单数量 MinWok_OrderCount_2 = morkFs[1].orderCount, //订单数量 MinWok_ErrorOrderCount_1 = morkFs[0].orderAbnormalCount, //异常订单数量 MinWok_ErrorOrderCount_2 = morkFs[1].orderAbnormalCount, //异常订单数量 }; LocalMqtt.GetInstance.Publish(maxWok); Thread.Sleep(1000); }), "大屏数据上报",true); } public override void SimOrder() { } /// /// 菜品编号转换为坐标 /// /// /// /// public bool NoMaterial2Coordinate(string no,out Coordinate coordinate) { //默认返回0,0 coordinate = new Coordinate(); coordinate.X = 0; coordinate.Y = 0; try { if(MaterialCoordinate.GetInstance().dicNoMaterialCoordinate.ContainsKey(no)) { coordinate = MaterialCoordinate.GetInstance().dicNoMaterialCoordinate[no]; return true; } else { return false; } } catch (Exception ex) { return false; } finally { } } public enum Laser2CoordinateState { MaterialOverdo = 0,//菜品过量 MaterialNormal = 1,//菜品正常 MaterialEmpty = 2,//菜品为空 MaterialUnkown = 999,//菜品未知错误 } } }