using EnumType; using iWareSda_QQJF.RGV.RgvService; using iWareSda_QQJF.RgvModel; using iWareSda_QQJF.SRM.SrmModel; using iWareSda_QQJF.SRM.SrmService; using iWareSda_QQJF.SRMTRAN.SrmTranService; using iWareSda_QQJF.WCSNEW.EDM; using iWareSda_QQJF.WCSNEW.生成主任务; using iWareSda_QQJF.WEBAPI; using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace iWareSda_QQJF.WCSNEW { public class WCS { public static bool deviceCanDo = true;//一键暂停设备任务 public static List fiveTran = new List() { 9, 10, 44, 43 };//五号出入库输送线 public static bool doInEast = false;//记录上一次做了出库还是入库,为了平衡 public static bool doInWest = false;//记录上一次做了出库还是入库,为了平衡 public static bool doEast = false;//记录上一次做了焊装还是冲压,为了平衡 public static int fullTimesMax = 20;//堵塞时间上限 public static int deleteCVPTime = 120;//删除组盘时间 static int fullTimes = 0;//堵塞时间 static int centerEastId = 52;//中转台设备号 static int centerWestId = 17; public static int safeLength = 1900 + 1900 + 1000 + 750;//RGV安全距离(RGV1长度一半+RGV2长度一半+安全距离+额外多算点) static int AgvLength = 1900;//RGV安全距离 static Thread WriteRecordThread;//记录 static Thread UpdateWillFinishTimeThread; static Thread deleteCVIThread; static Thread SendTranTaskThread; static Thread SendRgvTaskThread; static Thread SendSrmTaskThread; static Thread TranTaskFinishThread; static Thread RgvTaskFinishThread; static Thread SrmTaskFinishThread; static Thread ReturnThread; static Thread ReadMainTaskThread; static Thread ReadRgvPLCThread1; static Thread ReadRgvPLCThread2; static Thread ReadRgvPLCThread3; static Thread ReadRgvPLCThread4; static Thread ReadSrmPLCThread1; static Thread ReadSrmPLCThread2; static Thread ReadSrmPLCThread3; static Thread ReadSrmPLCThread4; static Thread ReadSrmPLCThread5; static Thread ReadSrmPLCThread6; static Thread ReadSrmPLCThread7; static Thread ReadSrmPLCThread8; static Thread ReadSrmPLCThread9; static Thread ReadTranThread; //static Thread ReadERPItemThread; //static Thread ReadERPTaskThread; //static Thread SaveDirectionThread; static Thread creatOutTask; static Thread creatInTask1; static Thread creatInTask2; static Thread creatInTask3; static Thread creatInTask4; static Thread creatInTask5; static Thread creatInTask6; static Thread creatMoveThread1; static Thread creatMoveThread2; static Thread creatMoveThread3; static Thread creatMoveThread4; static Thread creatMoveThread5; static Thread creatMoveThread6; static Thread creatMoveThread7; static Thread creatMoveThread8; static Thread creatMoveThread9; static Thread insertAlertTimeThread; static Thread updateCarTask; public static void init() { updateCarTask = new Thread(CreateMainTask.UpdateCarTask); updateCarTask.IsBackground = true; updateCarTask.Start(); creatOutTask = new Thread(CreateMainTask.CreatOutTask);//解析出库单,生成出库主任务 creatOutTask.IsBackground = true; creatOutTask.Start(); creatInTask1 = new Thread(CreateMainTask.CreatInTask);//生成入库主任务 creatInTask2 = new Thread(CreateMainTask.CreatInTask);//生成入库主任务 creatInTask3 = new Thread(CreateMainTask.CreatInTask);//生成入库主任务 creatInTask4 = new Thread(CreateMainTask.CreatInTask);//生成入库主任务 creatInTask5 = new Thread(CreateMainTask.CreatInTask);//生成入库主任务 creatInTask6 = new Thread(CreateMainTask.CreatInTask);//生成入库主任务 creatInTask1.IsBackground = true; creatInTask2.IsBackground = true; creatInTask3.IsBackground = true; creatInTask4.IsBackground = true; creatInTask5.IsBackground = true; creatInTask6.IsBackground = true; creatInTask1.Start(0); creatInTask2.Start(1); creatInTask3.Start(2); creatInTask4.Start(3); creatInTask5.Start(4); creatInTask6.Start(5); creatMoveThread1 = new Thread(CreateMainTask.CreateMove);//生成优化任务 creatMoveThread2 = new Thread(CreateMainTask.CreateMove);//生成优化任务 creatMoveThread3 = new Thread(CreateMainTask.CreateMove);//生成优化任务 creatMoveThread4 = new Thread(CreateMainTask.CreateMove);//生成优化任务 creatMoveThread5 = new Thread(CreateMainTask.CreateMove);//生成优化任务 creatMoveThread6 = new Thread(CreateMainTask.CreateMove);//生成优化任务 creatMoveThread7 = new Thread(CreateMainTask.CreateMove);//生成优化任务 creatMoveThread8 = new Thread(CreateMainTask.CreateMove);//生成优化任务 creatMoveThread9 = new Thread(CreateMainTask.CreateMove);//生成优化任务 creatMoveThread1.IsBackground = true; creatMoveThread2.IsBackground = true; creatMoveThread3.IsBackground = true; creatMoveThread4.IsBackground = true; creatMoveThread5.IsBackground = true; creatMoveThread6.IsBackground = true; creatMoveThread7.IsBackground = true; creatMoveThread8.IsBackground = true; creatMoveThread9.IsBackground = true; creatMoveThread1.Start(1); creatMoveThread2.Start(2); creatMoveThread3.Start(3); creatMoveThread4.Start(4); creatMoveThread5.Start(5); creatMoveThread6.Start(6); creatMoveThread7.Start(7); creatMoveThread8.Start(8); creatMoveThread9.Start(9); ReadRgvPLCThread1 = new Thread(new ParameterizedThreadStart(ReadRgvPLC)); ReadRgvPLCThread2 = new Thread(new ParameterizedThreadStart(ReadRgvPLC)); ReadRgvPLCThread3 = new Thread(new ParameterizedThreadStart(ReadRgvPLC)); ReadRgvPLCThread4 = new Thread(new ParameterizedThreadStart(ReadRgvPLC)); ReadRgvPLCThread1.Start(1); ReadRgvPLCThread2.Start(2); ReadRgvPLCThread3.Start(3); ReadRgvPLCThread4.Start(4); ReadSrmPLCThread1 = new Thread(new ParameterizedThreadStart(ReadSrmPLC)); ReadSrmPLCThread2 = new Thread(new ParameterizedThreadStart(ReadSrmPLC)); ReadSrmPLCThread3 = new Thread(new ParameterizedThreadStart(ReadSrmPLC)); ReadSrmPLCThread4 = new Thread(new ParameterizedThreadStart(ReadSrmPLC)); ReadSrmPLCThread5 = new Thread(new ParameterizedThreadStart(ReadSrmPLC)); ReadSrmPLCThread6 = new Thread(new ParameterizedThreadStart(ReadSrmPLC)); ReadSrmPLCThread7 = new Thread(new ParameterizedThreadStart(ReadSrmPLC)); ReadSrmPLCThread8 = new Thread(new ParameterizedThreadStart(ReadSrmPLC)); ReadSrmPLCThread9 = new Thread(new ParameterizedThreadStart(ReadSrmPLC)); ReadSrmPLCThread1.Start(1); ReadSrmPLCThread2.Start(2); ReadSrmPLCThread3.Start(3); ReadSrmPLCThread4.Start(4); ReadSrmPLCThread5.Start(5); ReadSrmPLCThread6.Start(6); ReadSrmPLCThread7.Start(7); ReadSrmPLCThread8.Start(8); ReadSrmPLCThread9.Start(9); ReadTranThread = new Thread(ReadTranPLC); ReadTranThread.Start(); insertAlertTimeThread = new Thread(insertAlertTime); insertAlertTimeThread.Start(); //等待信号读取线程开启且读到信号 Thread.Sleep(5000); WriteRecordThread = new Thread(WriteRecord); WriteRecordThread.Start(); UpdateWillFinishTimeThread = new Thread(UpdateWillFinishTime); UpdateWillFinishTimeThread.Start(); deleteCVIThread = new Thread(deleteCVI); deleteCVIThread.Start(); SendTranTaskThread = new Thread(SendTranTask); SendTranTaskThread.Start(); SendRgvTaskThread = new Thread(SendRgvTask); SendRgvTaskThread.Start(); SendSrmTaskThread = new Thread(SendSrmTask); SendSrmTaskThread.Start(); //TranTaskFinishThread = new Thread(TranTaskFinish); //TranTaskFinishThread.Start(); RgvTaskFinishThread = new Thread(RgvTaskFinish); RgvTaskFinishThread.Start(); SrmTaskFinishThread = new Thread(SrmTaskFinish); SrmTaskFinishThread.Start(); //ReturnThread = new Thread(Returnresult); //ReturnThread.Start(); ReadMainTaskThread = new Thread(ReadMainTask); ReadMainTaskThread.Start(); ////ERP接口线程 //初始化指针 try { using (Model edm = new Model()) { OracleWord.oldidOfItem = long.Parse(edm.KEYVALUE.FirstOrDefault(x => x.NAME == "oldidOfItem").VALUE.ToString()); OracleWord.oldidOfKanban = long.Parse(edm.KEYVALUE.FirstOrDefault(x => x.NAME == "oldidOfKanban").VALUE.ToString()); } } catch { } //ReadERPItemThread = new Thread(ReadERPItem); //ReadERPItemThread.Start(); //ReadERPTaskThread = new Thread(ReadERPTask); //ReadERPTaskThread.Start(); //SaveDirectionThread = new Thread(SaveDirection); //SaveDirectionThread.Start(); } private static void deleteCVI() { while (true) { Thread.Sleep(10000); using (Model edm = new Model()) { DateTime oldTime = DateTime.Now.AddMinutes(-deleteCVPTime); //找出超时器具 List cviList = edm.BASE_CONTAINER_VS_ITEM.Where(x => x.UPDATETIME < oldTime && x.BASE_CONTAINER.BASE_PLACE_VS_CONTAINER.Where(y => y.ENABLE == 1).Count() == 0 && x.BASE_CONTAINER.TASK_TASK.Where(y => (y.HASFINISHED ?? 0) == 0 && (y.ENABLE ?? 0) == 1).Count() == 0).ToList(); //foreach (var i in cviList) //{ // if (i.BASE_CONTAINER.BASE_PLACE_VS_CONTAINER.Where(x=>x.ENABLE==1).Count() == 0 && i.BASE_CONTAINER.TASK_TASK.Where(x => (x.HASFINISHED ?? 0) == 0 && (x.ENABLE ?? 0)==1).Count() == 0)//不存在库里且不存在任务中 // { // edm.BASE_CONTAINER_VS_ITEM.Remove(i); // } //} foreach (var i in cviList) { var task = edm.TASK_TASK.AsNoTracking().Any(u => u.CONTAINERID == i.CONTAINERID && u.TASKSTATUS != "完成" && u.TASKSTATUS != "异常/取消" && u.TASKSTATUS != "任务删除" && u.TASKSTATUS != "取消"); if (!task)//vy存在未完成的任务 { edm.BASE_CONTAINER_VS_ITEM.Remove(i); } } try { string msg = ""; //foreach (var i in cviList) //{ // msg = msg + "零件:" + i.BASE_ITEM.ITEMNAME + "器具:" + i.BASE_CONTAINER.CONTAINERNAME + "\n"; //} for (int i = 0; i < cviList.Count; i++) { var task = edm.TASK_TASK.AsNoTracking().Any(u => u.CONTAINERID == cviList[i].CONTAINERID && u.TASKSTATUS != "完成" && u.TASKSTATUS != "异常/取消" && u.TASKSTATUS != "任务删除" && u.TASKSTATUS != "取消"); if (task) { cviList.RemoveAt(i); msg += msg + "零件:" + cviList[i].BASE_ITEM.ITEMNAME + "器具:" + cviList[i].BASE_CONTAINER.CONTAINERNAME + "存在任务" + "\n"; } else { msg += msg + "零件:" + cviList[i].BASE_ITEM.ITEMNAME + "器具:" + cviList[i].BASE_CONTAINER.CONTAINERNAME + "\n"; } } edm.BASE_CONTAINER_VS_ITEM.RemoveRange(cviList); if (!string.IsNullOrEmpty(msg)) { WZ.Useful.Commons.LogTextHelper.WriteLine("自动删除组盘", "成功", msg); } } catch (Exception e) { WZ.Useful.Commons.LogTextHelper.WriteLine("自动删除组盘", "记录失败", e.ToString()); } edm.SaveChanges(); //记录删除托盘和物料绑定关系日志 【Editby shaoc,2023-03-07】 iWareSda_QQJF.WCSNEW.Helper.LogRemoveBASE_CONTAINER_VS_ITEM(cviList, "WCS.deleteCVI", "自动删除组盘,超过XX分钟未入库,自动删除组盘数据"); } } } /// /// 记录首页数据 /// public static void WriteRecord() { while (true) { try { using (Model edm = new Model()) { //记录前一天的 DateTime day = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd")); DateTime dayBefore = day.AddDays(-1); RECORD_WAREHOUSEINFO r = edm.RECORD_WAREHOUSEINFO.FirstOrDefault(x => x.time < day && x.time > dayBefore); if (r == null) { var overdatacoun2 = edm.View_BASE_PLACE_VS_CONTAINER.ToList(); int hasplace = overdatacoun2.Select(x => x.place).Distinct().Count(); int emptyitemplace = overdatacoun2.Where(x => string.IsNullOrEmpty(x.itemName)).Select(x => x.place).Distinct().Count(); int itemcoun = (int)overdatacoun2.Select(x => x.itemNum).Sum(); RECORD_WAREHOUSEINFO newR = new RECORD_WAREHOUSEINFO(); newR.time = day; newR.itemOver = edm.View_BASE_PLACE_VS_CONTAINER.Where(x => x.stStatus == "超期").ToList().Count; newR.placeFull = hasplace; newR.containerFull = (hasplace - emptyitemplace); newR.containerEmpty = emptyitemplace; newR.itemNum = itemcoun; edm.RECORD_WAREHOUSEINFO.AddOrUpdateExtension(newR); edm.SaveChanges(); } } Thread.Sleep(60000); } catch (Exception e) { WZ.Useful.Commons.LogTextHelper.WriteLine("", "WriteRecord", e.ToString()); } } } /// /// 自动更新预判完成时间 /// public static void UpdateWillFinishTime() { while (true) { try { using (Model edm = new Model()) { List mainTaskList = edm.TASK_TASK.Where(x => x.ENABLE == 1 && x.HASFINISHED == 0 && x.HASREADED == 1 && x.TASKSTATUS == "任务执行中").OrderBy(x => x.DOTIME).ToList();//取出所有执行中任务 List rgvTaskList = edm.RgvTask.Where(x => x.HASFINISHED == 0 && x.TASK_TASK.HASFINISHED == 0).OrderBy(x => x.ID).ToList();//取出所有未完成的RGV任务 List srmTaskList = edm.SrmTask.Where(x => x.HASFINISHED == 0 && x.TASK_TASK.HASFINISHED == 0).OrderBy(x => x.ID).ToList();//取出所有未完成的RGV任务 foreach (var i in mainTaskList) { ////计算RGV时间 //int rgvTime = 0; //RgvTask laskRgvTask = i.RgvTask.OrderByDescending(x => x.ID).FirstOrDefault(x => x.TASKTYPE == 1);//取出此任务的最后一条RGV任务(搬运) //List oneSideRgvTaskList = rgvTaskList.Where(x => Math.Abs(x.USERGVID - laskRgvTask.USERGVID) <= 1).ToList();//取出影响的任务集合 //if (oneSideRgvTaskList.Contains(laskRgvTask)) //{ // int rgvIndex = oneSideRgvTaskList.IndexOf(laskRgvTask);//计算出是第几个 // rgvTime = rgvTime + (rgvIndex + 1) * 3;//任务*3分钟,自身未完成额外+3 //} ////计算堆垛机时间 //int srmTime = 0; //SrmTask srmTask = i.SrmTask.FirstOrDefault(); //List sameSrmTask = srmTaskList.Where(x => x.USESRMID == srmTask.USESRMID).ToList(); //if (sameSrmTask.Contains(srmTask)) //{ // int srmIndex = sameSrmTask.IndexOf(srmTask); // srmTime = srmTime + (srmIndex + 1) * 2; //} //int totalTime = rgvTime + srmTime;//总时间 ////记录 if (i.TASKTYPE == 1)//入库从RGV推导 { int rgvTotalTime = 0; List rgvTaskOfMainTask = i.RgvTask.OrderBy(x => x.ID).ToList(); int needRgv1 = 0; int needRgv2 = 0; if (i.RgvTask.FirstOrDefault().USERGVID == 1 || i.RgvTask.FirstOrDefault().USERGVID == 2) { needRgv1 = 1; needRgv2 = 2; } else if (i.RgvTask.FirstOrDefault().USERGVID == 3 || i.RgvTask.FirstOrDefault().USERGVID == 4) { needRgv1 = 3; needRgv2 = 4; } List oneSideRgvTaskList = rgvTaskList.Where(x => x.USERGVID == needRgv1 || x.USERGVID == needRgv2).ToList();//取出影响的任务集合 //RGV foreach (var j in rgvTaskOfMainTask) { if (oneSideRgvTaskList.Contains(j)) { int rgvIndex = oneSideRgvTaskList.IndexOf(j);//计算出是第几个 //(入库不计算堆垛机任务前置情况) if (rgvIndex != 0) { j.NEEDTIME = oneSideRgvTaskList[rgvIndex - 1].NEEDTIME + 1;//前置任务+1分钟 } else { j.NEEDTIME = 1;//第一个任务1分钟 } } else { //已完成不记时 j.NEEDTIME = 0; } rgvTotalTime = j.NEEDTIME ?? 0;//记录RGV最终使用时间 } //堆垛机 SrmTask srmTask = i.SrmTask.FirstOrDefault(); List sameSrmTask = srmTaskList.Where(x => x.USESRMID == srmTask.USESRMID).ToList(); if (sameSrmTask.Contains(srmTask)) { int srmIndex = sameSrmTask.IndexOf(srmTask); if (srmIndex != 0) { srmTask.NEEDTIME = sameSrmTask[srmIndex - 1].NEEDTIME + 1; } else { srmTask.NEEDTIME = 1; } } else { srmTask.NEEDTIME = 0; } //看瓶颈设备 if (rgvTotalTime + 1 > srmTask.NEEDTIME)//rgv比较慢 { srmTask.NEEDTIME = rgvTotalTime + 1; } else//堆垛机比较慢 { //不处理 } i.NEEDTIME = rgvTotalTime;//以堆垛机完成时间记录 } else if (i.TASKTYPE == 2)//出库从堆垛机推导 { int rgvStartTime = 0; int needRgv1 = 0; int needRgv2 = 0; if (i.RgvTask.FirstOrDefault().USERGVID == 1 || i.RgvTask.FirstOrDefault().USERGVID == 2) { needRgv1 = 1; needRgv2 = 2; } else if (i.RgvTask.FirstOrDefault().USERGVID == 3 || i.RgvTask.FirstOrDefault().USERGVID == 4) { needRgv1 = 3; needRgv2 = 4; } List rgvTaskOfMainTask = i.RgvTask.OrderBy(x => x.ID).ToList(); List oneSideRgvTaskList = rgvTaskList.Where(x => x.USERGVID == needRgv1 || x.USERGVID == needRgv2).ToList();//取出影响的任务集合 //RGV foreach (var j in rgvTaskOfMainTask) { if (oneSideRgvTaskList.Contains(j)) { int rgvIndex = oneSideRgvTaskList.IndexOf(j);//计算出是第几个 //(出库不计算RGV任务前置情况) if (rgvIndex != 0) { j.NEEDTIME = oneSideRgvTaskList[rgvIndex - 1].NEEDTIME + 1;//前置任务+3分钟 } else { j.NEEDTIME = 1;//第一个任务3分钟 } } else { //已完成不记时 j.NEEDTIME = 0; } rgvStartTime = rgvTaskOfMainTask.FirstOrDefault().NEEDTIME ?? 0;//记录RGV开始使用时间 } //堆垛机 SrmTask srmTask = i.SrmTask.FirstOrDefault(); List sameSrmTask = srmTaskList.Where(x => x.USESRMID == srmTask.USESRMID).ToList(); if (sameSrmTask.Contains(srmTask)) { int srmIndex = sameSrmTask.IndexOf(srmTask); if (srmIndex != 0) { srmTask.NEEDTIME = sameSrmTask[srmIndex - 1].NEEDTIME + 1; } else { srmTask.NEEDTIME = 1; } } else { srmTask.NEEDTIME = 0; } //看瓶颈设备 if (rgvStartTime < srmTask.NEEDTIME + 1)//堆垛机比较慢 { rgvTaskOfMainTask.FirstOrDefault().NEEDTIME = srmTask.NEEDTIME + 1;//第一个RGV任务需要时间 foreach (var j in rgvTaskOfMainTask) { j.NEEDTIME = rgvTaskOfMainTask.FirstOrDefault().NEEDTIME + rgvTaskOfMainTask.IndexOf(j) * 1;//后续累加3分钟 } } else//RGV比较慢 { //不处理 } i.NEEDTIME = rgvTaskOfMainTask.OrderByDescending(x => x.ID).FirstOrDefault(x => x.TASKTYPE == 1).NEEDTIME;//以RGV完成时间记录(移动不计入) } } if (edm.SaveChanges() > 0) { } } Thread.Sleep(1000 * 10); } catch (Exception e) { WZ.Useful.Commons.LogTextHelper.WriteLine("", "UpdateWillFinishTime", e.ToString()); } } } /// /// 定时存储指针线程 /// public static void SaveDirection() { while (true) { //记录ERP指针 using (Model edm = new Model()) { KEYVALUE oldidOfItemkv = edm.KEYVALUE.FirstOrDefault(x => x.NAME == "oldidOfItem"); oldidOfItemkv.VALUE = int.Parse(OracleWord.oldidOfItem.ToString()); KEYVALUE oldidOfKanbankv = edm.KEYVALUE.FirstOrDefault(x => x.NAME == "oldidOfKanban"); oldidOfKanbankv.VALUE = int.Parse(OracleWord.oldidOfKanban.ToString()); if (edm.SaveChanges() == 0) { edm.SaveChanges(); } } Thread.Sleep(1000 * 60 * 60); } } /// /// 关闭此类 /// public static void Close() { try { //记录ERP指针 using (Model edm = new Model()) { KEYVALUE oldidOfItemkv = edm.KEYVALUE.FirstOrDefault(x => x.NAME == "oldidOfItem"); oldidOfItemkv.VALUE = int.Parse(OracleWord.oldidOfItem.ToString()); KEYVALUE oldidOfKanbankv = edm.KEYVALUE.FirstOrDefault(x => x.NAME == "oldidOfKanban"); oldidOfKanbankv.VALUE = int.Parse(OracleWord.oldidOfKanban.ToString()); if (edm.SaveChanges() == 0) { edm.SaveChanges(); } } WriteRecordThread.Abort(); UpdateWillFinishTimeThread.Abort(); SendTranTaskThread.Abort(); SendRgvTaskThread.Abort(); SendSrmTaskThread.Abort(); //TranTaskFinishThread.Abort(); RgvTaskFinishThread.Abort(); SrmTaskFinishThread.Abort(); //ReturnThread.Abort(); ReadMainTaskThread.Abort(); ReadRgvPLCThread1.Abort(); ReadRgvPLCThread2.Abort(); ReadRgvPLCThread3.Abort(); ReadRgvPLCThread4.Abort(); ReadSrmPLCThread1.Abort(); ReadSrmPLCThread2.Abort(); ReadSrmPLCThread3.Abort(); ReadSrmPLCThread4.Abort(); ReadSrmPLCThread5.Abort(); ReadSrmPLCThread6.Abort(); ReadSrmPLCThread7.Abort(); ReadSrmPLCThread8.Abort(); ReadSrmPLCThread9.Abort(); ReadTranThread.Abort(); //ReadERPTaskThread.Abort(); //ReadERPItemThread.Abort(); //SaveDirectionThread.Abort(); creatOutTask.Abort(); creatInTask1.Abort(); creatInTask2.Abort(); creatInTask3.Abort(); creatInTask4.Abort(); creatInTask5.Abort(); creatInTask6.Abort(); creatMoveThread1.Abort(); creatMoveThread2.Abort(); creatMoveThread3.Abort(); creatMoveThread4.Abort(); creatMoveThread5.Abort(); creatMoveThread6.Abort(); creatMoveThread7.Abort(); creatMoveThread8.Abort(); creatMoveThread9.Abort(); insertAlertTimeThread.Abort(); } catch { } } /// /// 循环读取ERP零件信息 /// public static void ReadERPItem() { while (true) { //Thread.Sleep(10); //OracleWord.oldidOfItem++; //Thread st = new Thread(OracleWord.SearchItem); //st.Start(); OracleWord.SearchItem(); } } /// /// 循环读取ERP出库单信息 /// public static void ReadERPTask() { while (true) { //Thread.Sleep(1000); OracleWord.SearchTask(); } } /// /// 循环输送线心跳 /// public static void ReadTranPLC() { SrmTranService srv = new SrmTranService(); while (true) { try { Thread.Sleep(1000); srv.GetHeart(); //srv.readHasGood(); } catch { } } } /// /// 循环更新RGV数据 /// public static void ReadRgvPLC(object id) { RgvService srv = new RgvService(); while (true) { try { Thread.Sleep(300); srv.ReadPlc(Convert.ToInt32(id)); //报警 int rgvId = int.Parse(id.ToString()); string alarm = Enum.GetName(typeof(ESrgvAlarm), Rgv_CacheEntity.Rgvs[rgvId - 1].alarmCode); if (string.IsNullOrEmpty(alarm) || alarm == "无故障") { using (Model edm = new Model()) { List alertList = edm.ALERT_ALERT.Where(x => x.FINISHTIME == null && x.ALERTDES == "RGV" && x.ALERTDEVICEID == rgvId + 9).ToList(); foreach (var i in alertList) { i.FINISHTIME = DateTime.Now; i.TOTALTIME = (int)((i.FINISHTIME ?? DateTime.Now) - (i.CREATETIME ?? DateTime.Now)).TotalMinutes; } edm.SaveChanges(); } } else { using (Model edm = new Model()) { ALERT_ALERT alert = edm.ALERT_ALERT.FirstOrDefault(x => x.FINISHTIME == null && x.ALERTNAME == alarm); if (alert != null) { //持续故障 } else { //新故障 alert = new ALERT_ALERT(); alert.CREATETIME = DateTime.Now; alert.ALERTNAME = alarm; alert.ALERTDES = "RGV"; BASE_DEVICE d = edm.BASE_DEVICE.FirstOrDefault(x => x.DEVICEID == rgvId && x.DEVICETYPE == "RGV"); if (d != null) { alert.ALERTDEVICEID = d.ID; } edm.ALERT_ALERT.Add(alert); edm.SaveChanges(); } } } } catch { } } } /// /// 循环更新堆垛机数据 /// public static void ReadSrmPLC(object id) { SrmService srv = new SrmService(); while (true) { try { Thread.Sleep(300); srv.ReadPlc(Convert.ToInt32(id)); //报警 int srmId = int.Parse(id.ToString()); string alarm = Enum.GetName(typeof(ESrmAlarm), Srm_CacheEntity.Srms[srmId - 1].RalarmNumber); if (string.IsNullOrEmpty(alarm)) { using (Model edm = new Model()) { List alertList = edm.ALERT_ALERT.Where(x => x.FINISHTIME == null && x.ALERTDES == "堆垛机" && x.ALERTDEVICEID == srmId).ToList(); foreach (var i in alertList) { i.FINISHTIME = DateTime.Now; i.TOTALTIME = (int)((i.FINISHTIME ?? DateTime.Now) - (i.CREATETIME ?? DateTime.Now)).TotalMinutes; } edm.SaveChanges(); //Thread.Sleep(5000); } } else { using (Model edm = new Model()) { ALERT_ALERT alert = edm.ALERT_ALERT.FirstOrDefault(x => x.FINISHTIME == null && x.ALERTNAME == alarm); if (alert != null) { //持续故障 } else { //新故障 alert = new ALERT_ALERT(); alert.CREATETIME = DateTime.Now; alert.ALERTNAME = alarm; alert.ALERTDES = "堆垛机"; BASE_DEVICE d = edm.BASE_DEVICE.FirstOrDefault(x => x.DEVICEID == srmId && x.DEVICETYPE == "堆垛机"); if (d != null) { alert.ALERTDEVICEID = d.ID; } edm.ALERT_ALERT.Add(alert); edm.SaveChanges(); } } } } catch { } } } /// /// 异常统计表线程 /// public static void insertAlertTime() { while (true) { try { Thread.Sleep(1000); using (Model edm = new Model()) { ALERT_ALERT alert = edm.ALERT_ALERT.FirstOrDefault(x => (x.HASDONE ?? 0) != 1); if (alert != null) { //插入统计时长表 //string deviceName = edm.BASE_DEVICE.FirstOrDefault(x => x.ID == alert.ALERTDEVICEID); DateTime dateTimeStart = alert.CREATETIME ?? DateTime.Now;//开始时间 DateTime dateTimeEnd = alert.FINISHTIME ?? DateTime.Now;//结束时间 for (DateTime date = dateTimeStart.Date; date <= dateTimeEnd.Date; date = date.AddDays(1)) { //初始化int int startTime = 0; int endTime = 1439; if (date == dateTimeStart.Date)//第一天 { startTime = dateTimeStart.Hour * 60 + dateTimeStart.Minute; } if (date == dateTimeEnd.Date)//最后一天 { endTime = dateTimeEnd.Hour * 60 + dateTimeEnd.Minute; } for (int i = startTime; i <= endTime; i++) { ALERT_ALERTTIME at = new ALERT_ALERTTIME(); at.DAY = date; at.ISERROR = 1; at.TIME = i; at.DEVICENAME = alert.BASE_DEVICE.DEVICENAME; edm.ALERT_ALERTTIME.AddOrUpdateExtension(at); } } alert.HASDONE = 1; edm.SaveChanges(); } } } catch { } } } /// /// 下发输送线线程 /// public static void SendTranTask() { SrmTranService srmService = new SrmTranService(); while (true) { try { if (!deviceCanDo) { Thread.Sleep(1000); continue; } using (Model edm = new Model()) { //读取数据库输送线任务 List tranTask = edm.TranTask.Where(x => x.ISRELEASED == 0).ToList(); foreach (var task in tranTask) { //判断设备可行性 if (srmService.TranReady(task.SOURCEPLACE) && srmService.TranReady(task.TOPLACE)) { //下发任务 if (srmService.SendGoodsType(task.SOURCEPLACE, task.PALLETTYPE ?? 0)) { if (srmService.SendGoodsReady(task.SOURCEPLACE, task.TOPLACE, (task.ID % 32767) + 1, (task.FASTHERTASKID % 32767) + 1) == 1) { WZ.Useful.Commons.LogTextHelper.WriteLine("输送线任务下发成功", "任务号:" + task.ID.ToString(), "主任务号:" + task.FASTHERTASKID.ToString()); //修改数据 task.ISRELEASED = 1; task.HASFINISHED = 1; if (task.TASK_TASK.TASKTYPE == 1) { task.TASK_TASK.LOCALDEVICE = "输送线"; } edm.SaveChanges(); Thread.Sleep(5000); break; } else { WZ.Useful.Commons.LogTextHelper.WriteLine("输送线任务下发失败", "任务号:" + task.ID.ToString(), ""); Thread.Sleep(1000); break; } } else { WZ.Useful.Commons.LogTextHelper.WriteLine("输送线规格下发失败", "任务号:" + task.ID.ToString(), ""); Thread.Sleep(1000); break; } } } } } catch (Exception e) { WZ.Useful.Commons.LogTextHelper.WriteLine("", "SendTranTask", e.ToString()); } Thread.Sleep(1000); } } /// /// 下发RGV任务 /// public static void SendRgvTask() { RgvService rgvService = new RgvService(); SrmTranService tranService = new SrmTranService(); while (true) { if (!deviceCanDo) { Thread.Sleep(1000); continue; } try { //读取数据库RGV任务 using (Model edm = new Model()) { //RgvTask rgvTask = edm.RgvTask.FirstOrDefault(x => x.ISRELEASED == 0); for (int i = 1; i < 5; i++) { //判断设备可行性 if (rgvService.IsRgvReady(i)) { RgvTask rgvTask = edm.RgvTask.FirstOrDefault(x => x.ISRELEASED == 0 && x.USERGVID == i); if (rgvTask == null) { continue; } //5号巷道特殊处理 if (fiveTran.Contains(rgvTask.SOURCEPLACE) || fiveTran.Contains(rgvTask.TOPLACE)) { RgvTask t = new RgvTask(); if (i == 2 || i == 4) { t = edm.RgvTask.FirstOrDefault(x => x.ISRELEASED == 0 && x.USERGVID == (i - 1) && (fiveTran.Contains(x.SOURCEPLACE) || fiveTran.Contains(x.TOPLACE)) && x.ID < rgvTask.ID); } else { t = edm.RgvTask.FirstOrDefault(x => x.ISRELEASED == 0 && x.USERGVID == (i + 1) && (fiveTran.Contains(x.SOURCEPLACE) || fiveTran.Contains(x.TOPLACE)) && x.ID < rgvTask.ID); } if (t != null) { //存在则跳过 continue; } } RgvTask preTask = edm.RgvTask.FirstOrDefault(x => x.ID == rgvTask.PRETASK); if (preTask != null && preTask.HASFINISHED != 1)//前置任务存在且未完成(前置任务字段现在可能没用,待考证) { continue; } if (rgvTask.TASKTYPE == 1)//搬运任务时 { TranLock centerTo = edm.TranLock.FirstOrDefault(x => x.TRANID == rgvTask.TOPLACE); TranLock centerSource = edm.TranLock.FirstOrDefault(x => x.TRANID == rgvTask.SOURCEPLACE); if (tranService.GetSrmConveyorStationHasGoods(rgvTask.TOPLACE) == 0) { continue; } if ((tranService.GetSrmConveyorStationHasGoods(rgvTask.TOPLACE) == 1 || centerTo.ISFULL == 1) && (rgvTask.TOPLACE == 17 || rgvTask.TOPLACE == 52))//避免重复放至中转台(任务目标库位有货则暂时不放) { continue; } if ((tranService.GetSrmConveyorStationHasGoods(rgvTask.SOURCEPLACE) == 2 || centerSource.ISFULL == 0) && (rgvTask.SOURCEPLACE == 17 || rgvTask.SOURCEPLACE == 52))//(取货时目标没货则暂不执行,仅限中转台) { continue; } } //判断是否干涉 if (!Helper.IsTouch(rgvTask.SOURCEPLACE, rgvTask.USERGVID) && !Helper.IsTouch(rgvTask.TOPLACE, rgvTask.USERGVID))//设备不干涉下 { int palletType = 0; try { palletType = rgvTask.TASK_TASK.BASE_CONTAINER.BASE_PALLET.PALLETCODE ?? 0; } catch { return; } //下发任务 if (rgvService.SendRgvTask(rgvTask.USERGVID, (rgvTask.ID % 32767) + 1, rgvTask.SOURCEPLACE, rgvTask.TOPLACE, rgvTask.TASKTYPE, palletType, (rgvTask.FASTHERTASKID % 32767) + 1) == 1) { WZ.Useful.Commons.LogTextHelper.WriteLine("RGV下发", "任务号:" + rgvTask.ID, "主任务号:" + rgvTask.FASTHERTASKID); //修改数据 rgvTask.ISRELEASED = 1; rgvTask.DOTIME = DateTime.Now; if (rgvTask.TASK_TASK.TASKTYPE == 1 && rgvTask.TASK_TASK.RgvTask.OrderBy(x => x.ID).ToList().IndexOf(rgvTask) == 0)//入库时第一个下发RGV认为东西在RGV上或者输送线上 { //rgvTask.TASK_TASK.LOCALDEVICE = "输送线或者RGV"; } else if (rgvTask.TASK_TASK.TASKTYPE == 1 && rgvTask.TASK_TASK.RgvTask.OrderBy(x => x.ID).ToList().IndexOf(rgvTask) == 1)//入库时第二个下发RGV(存在时)认为东西在RGV上或者输送线上 { rgvTask.TASK_TASK.LOCALDEVICE = "RGV"; } //如果不是中转任务,生成叉车任务 if (rgvTask.TOPLACE != 52 && rgvTask.TOPLACE != 17) { ORDER_OUTORDER order = edm.ORDER_OUTORDER.FirstOrDefault(x => x.ID == rgvTask.TASK_TASK.ORDERID); //创建叉车任务,[Editby kejj,20230626] //去掉验证PDA上选择目的地才能生成叉车任务的限制 【Editby shaocx,2023-06-07】 //我靠,还不能直接 去掉验证PDA上选择目的地才能生成叉车任务的限制,因为会在这一行报错 carTask.TODESTINATION = order.BASE_PRODUCTIONLINE.PRODUCTIONLINENAME; 【Editby shaocx,2023-06-11】 if (order != null)//[Editby kejj,20230621] { var isExist = edm.CAR_CARTASK.AsNoTracking().Any(u => u.OUTORDERID == order.ID && u.CONTAINERID == rgvTask.TASK_TASK.CONTAINERID); if (!isExist) { CAR_CARTASK carTask = new CAR_CARTASK(); BASE_PRODUCTIONLINE pl = edm.BASE_PRODUCTIONLINE.FirstOrDefault(x => x.PRODUCTIONLINECODE == rgvTask.TASK_TASK.TOPLACE); if (pl != null) { carTask.CARTASKNAME = IWareDataAccess.Car.CARTASK.CarTaskSqlFunc.GetCode(); carTask.FROMDESTINATION = pl.PRODUCTIONLINENAME; carTask.TODESTINATION = order.BASE_PRODUCTIONLINE?.PRODUCTIONLINENAME; carTask.CONTAINERID = rgvTask.TASK_TASK.CONTAINERID; carTask.TASKSTATUS = "新建"; carTask.ENABLE = 1; carTask.UPDATETIME = DateTime.Now; carTask.CREATORID = order.CREATORID; carTask.ORDER_OUTORDER = order; carTask.USERID = order.SYS_USER?.ID;//[Editby kejj,20230621] string detail = ""; foreach (var m in rgvTask.TASK_TASK.BASE_CONTAINER.BASE_CONTAINER_VS_ITEM) { detail = detail + m.BASE_ITEM.ITEMNAME + " " + m.BASE_ITEM.ITEMDES + ":" + m.ITEMNUM + "个;\n"; } carTask.ITEMDETAIL = detail; edm.CAR_CARTASK.Add(carTask); } } } //else //{ // if (rgvTask.TASK_TASK.BASE_CONTAINER.BASE_CONTAINER_VS_ITEM != null) // { // CAR_CARTASK carTask = new CAR_CARTASK(); // BASE_PRODUCTIONLINE pl = edm.BASE_PRODUCTIONLINE.FirstOrDefault(x => x.PRODUCTIONLINECODE == rgvTask.TASK_TASK.TOPLACE); // if (pl != null) // { // carTask.CARTASKNAME = IWareDataAccess.Car.CARTASK.CarTaskSqlFunc.GetCode(); // carTask.FROMDESTINATION = pl.PRODUCTIONLINENAME; // //carTask.TODESTINATION = order.BASE_PRODUCTIONLINE?.PRODUCTIONLINENAME; // carTask.CONTAINERID = rgvTask.TASK_TASK.CONTAINERID; // carTask.TASKSTATUS = "新建"; // carTask.ENABLE = 1; // carTask.UPDATETIME = DateTime.Now; // //carTask.CREATORID = order.CREATORID; // //carTask.ORDER_OUTORDER = order; // //carTask.USERID = order.SYS_USER?.ID;//[Editby kejj,20230621] // string detail = ""; // foreach (var m in rgvTask.TASK_TASK.BASE_CONTAINER.BASE_CONTAINER_VS_ITEM) // { // detail = detail + m.BASE_ITEM.ITEMNAME + " " + m.BASE_ITEM.ITEMDES + ":" + m.ITEMNUM + "个;\n"; // } // carTask.ITEMDETAIL = detail; // edm.CAR_CARTASK.Add(carTask); // } // } //} } if (edm.SaveChanges() > 0) { } //输送线锁定 int sourceLocal = edm.TranLock.FirstOrDefault(x => x.TRANID == rgvTask.SOURCEPLACE).LOCAL; int toLocal = edm.TranLock.FirstOrDefault(x => x.TRANID == rgvTask.TOPLACE).LOCAL; if (rgvTask.USERGVID == 2 || rgvTask.USERGVID == 4) { sourceLocal = sourceLocal + safeLength; toLocal = toLocal + safeLength; } else { sourceLocal = sourceLocal - safeLength; toLocal = toLocal - safeLength; } //锁定单侧 if (Helper.LockTran(rgvTask.USERGVID, sourceLocal, toLocal)) { } Thread.Sleep(5000); } } } } } Thread.Sleep(1000); } catch (Exception e) { WZ.Useful.Commons.LogTextHelper.WriteLine("", "SendRgvTask", e.ToString()); continue; } } } /// /// 下发堆垛机任务 /// public static void SendSrmTask() { SrmService srmService = new SrmService(); while (true) { if (!deviceCanDo) { Thread.Sleep(1000); continue; } try { using (Model edm = new Model()) { for (int i = 1; i < 10; i++) { //判断设备可行性 if (srmService.IsReady(i)) { //机智的重发?不机智 SrmTask taskRe = edm.SrmTask.OrderByDescending(x => x.ID).FirstOrDefault(x => x.ISRELEASED == 1 && x.HASFINISHED == 0 && x.USESRMID == i); if (taskRe != null) { if (taskRe.TASK_TASK.TASKTYPE == 1) { BASE_PLACE_VS_CONTAINER pvc = edm.BASE_PLACE_VS_CONTAINER.FirstOrDefault(x => x.BASE_PLACE.PLACE.Contains(taskRe.TOPLACE) && x.BASE_PLACE.SRMID == taskRe.USESRMID && x.STATUS.Contains("TEMP")); if (pvc != null)//存在机智重发 { if (srmService.SendSrmTask(i, (taskRe.ID % 32767) + 1, taskRe.SOURCEPLACE, taskRe.TOPLACE, taskRe.PALLETTYPE ?? 0, (taskRe.FASTHERTASKID % 32767) + 1) == 1) { continue; } } } else if (taskRe.TASK_TASK.TASKTYPE == 2) { BASE_PLACE_VS_CONTAINER pvc = edm.BASE_PLACE_VS_CONTAINER.FirstOrDefault(x => x.BASE_PLACE.PLACE.Contains(taskRe.SOURCEPLACE) && x.BASE_PLACE.SRMID == taskRe.USESRMID && x.STATUS.Contains("TEMP")); if (pvc != null)//存在机智重发 { if (srmService.SendSrmTask(i, (taskRe.ID % 32767) + 1, taskRe.SOURCEPLACE, taskRe.TOPLACE, taskRe.PALLETTYPE ?? 0, (taskRe.FASTHERTASKID % 32767) + 1) == 1) { continue; } } } else if (taskRe.TASK_TASK.TASKTYPE == 3) { BASE_PLACE_VS_CONTAINER pvc = edm.BASE_PLACE_VS_CONTAINER.FirstOrDefault(x => x.BASE_PLACE.PLACE.Contains(taskRe.TOPLACE) && x.BASE_PLACE.SRMID == taskRe.USESRMID && x.STATUS.Contains("TEMP")); if (pvc != null)//存在机智重发 { if (srmService.SendSrmTask(i, (taskRe.ID % 32767) + 1, taskRe.SOURCEPLACE, taskRe.TOPLACE, taskRe.PALLETTYPE ?? 0, (taskRe.FASTHERTASKID % 32767) + 1) == 1) { continue; } } } } //读取数据库堆垛机任务 SrmTask task = edm.SrmTask.FirstOrDefault(x => x.ISRELEASED == 0 && x.USESRMID == i && x.SRMTASKTYPE == 3);//移库 if (task == null) { //无移库则搜索出入库 task = edm.SrmTask.FirstOrDefault(x => x.ISRELEASED == 0 && x.USESRMID == i); if (task == null) { //无任务 continue; } } //重定向 if (task.SRMTASKTYPE == 1 || task.SRMTASKTYPE == 3)//入库和移库 { if (task.SRMTASKTYPE == 3)//移库 { BASE_PLACE place = edm.BASE_PLACE.FirstOrDefault(x => x.PLACE.Substring(2) == task.SOURCEPLACE && x.SRMID == task.USESRMID); if (place.ISFULL != 1)//移库取货点不存在,则已无需移库 { edm.SrmTask.Remove(task); edm.SaveChanges(); continue; } } //看目标位 BASE_PLACE toPlace = edm.BASE_PLACE.FirstOrDefault(x => x.PLACE.Substring(2) == task.TOPLACE && x.SRMID == task.USESRMID); //入库优先选最好的库位,[Editby kejj,20230623]注释 //List pvcList = edm.BASE_PLACE_VS_CONTAINER.Where(x => x.BASE_PLACE.SRMID == task.USESRMID && x.ENABLE == 1).ToList(); ////找同种外侧 //if(task.TASK_TASK.BASE_CONTAINER.BASE_CONTAINER_VS_ITEM.Count==0)//空器具 //{ //} //else if(task.TASK_TASK.BASE_CONTAINER.BASE_CONTAINER_VS_ITEM.Count==1)//单零件器具 //{ // BASE_CONTAINER_VS_ITEM cvi = task.TASK_TASK.BASE_CONTAINER.BASE_CONTAINER_VS_ITEM.FirstOrDefault(); // List specialPvcList = edm.View_BASE_PLACE_VS_CONTAINER.Where(x => x.itemName == cvi.BASE_ITEM.ITEMNAME && x.itemNum == cvi.ITEMNUM && (x.overDueTime ?? 0) == 0).ToList(); // foreach (var s in specialPvcList) // { // BASE_PLACE place = edm.BASE_PLACE.FirstOrDefault(x=>x.PLACE==s.place); // edm.BASE_PLACE.FirstOrDefault(x=>x.ROW) // edm.BASE_PLACE.FirstOrDefault(x=>(x.ISFULL ?? 0 ) != 1 &&x.PLACE) // } //} //找排 int row = 0; List newPlaceList = edm.BASE_PLACE.Where(x => x.SRMID == task.USESRMID && (x.ISFULL ?? 0) == 0 && (x.ISLOCK ?? 0) == 0 && x.BASE_PLACETYPE.PLACETYPE == toPlace.BASE_PLACETYPE.PLACETYPE).ToList(); if (task.TOPLACE.Substring(0, 1) != "1" && task.TOPLACE.Substring(0, 1) != "5") { if (newPlaceList.Where(x => (x.PLACELEVEL ?? 0) == 1).Count() > 0)//1、4 { if (newPlaceList.Where(x => x.ROW == 1).Count() >= newPlaceList.Where(x => x.ROW == 4).Count()) { row = 1; } else { row = 4; } } else//2、3 { if (newPlaceList.Where(x => x.ROW == 2).Count() >= newPlaceList.Where(x => x.ROW == 3).Count()) { row = 2; } else { row = 3; } } } BASE_PLACE newPlace = new BASE_PLACE(); /* var newList = newPlaceList.OrderBy(x => x.PLACELEVEL).ThenBy(x => x.LAYER).ThenBy(x => System.Math.Abs((x.COL ?? 0) - 9)).ToList();//[Editby kejj,20230623] if (row != 0) { //newPlace = newPlaceList.OrderBy(x => x.PLACELEVEL).ThenBy(x => x.LAYER).ThenBy(x => System.Math.Abs((x.COL ?? 0) - 9)).FirstOrDefault(x => x.ROW == row); newList = newList.FindAll(x => x.ROW == row); } else { //newPlace = newPlaceList.OrderBy(x => x.PLACELEVEL).ThenBy(x => x.LAYER).ThenBy(x => System.Math.Abs((x.COL ?? 0) - 9)).FirstOrDefault(); } foreach (var item in newList) { //校验目标位库存 var checkbalance = edm.BASE_PLACE_VS_CONTAINER.AsNoTracking().FirstOrDefault(u => u.BASE_PLACE.PLACE == item.PLACE); if (checkbalance != null) { continue; } newPlace = item; } */ //查询当前所有没完成任务的目标位置 //var strlist = edm.TASK_TASK.AsNoTracking().Where(u => u.TASKSTATUS != "完成" && u.TASKSTATUS != "异常/取消" && u.TASKSTATUS != "任务删除" && u.TASKSTATUS != "取消" && u.TASKTYPE == 1 && u.USESRMID == i).Select(u => u.TOPLACE).ToList(); if (row != 0) { newPlace = newPlaceList.OrderBy(x => x.PLACELEVEL).ThenBy(x => x.LAYER).ThenBy(x => System.Math.Abs((x.COL ?? 0) - 9)).FirstOrDefault(x => x.ROW == row); } else { newPlace = newPlaceList.OrderBy(x => x.PLACELEVEL).ThenBy(x => x.LAYER).ThenBy(x => System.Math.Abs((x.COL ?? 0) - 9)).FirstOrDefault(); } //BASE_PLACE newPlace = edm.BASE_PLACE.OrderBy(x => x.PLACELEVEL).ThenBy(x => x.LAYER).ThenBy(x => x.COL).FirstOrDefault(x => x.SRMID == task.USESRMID && (x.ISFULL ?? 0) == 0 && (x.ISLOCK ?? 0) == 0 && x.BASE_PLACETYPE.PLACETYPE == toPlace.BASE_PLACETYPE.PLACETYPE /*&& !pvcList.Contains(x.BASE_PLACE_VS_CONTAINER.FirstOrDefault())*/); if (newPlace != null) { WZ.Useful.Commons.LogTextHelper.WriteLine("满入记录日志:原库位" + task.TOPLACE + "重定向后库位:" + newPlace.PLACE.Substring(2) + ";器具号-" + task.TASK_TASK?.BASE_CONTAINER?.CONTAINERNAME); //查看当前未执行的任务是否有相同的目标库位 var sametask = edm.SrmTask.FirstOrDefault(x => x.ISRELEASED == 0 && x.USESRMID == i && x.TOPLACE == newPlace.PLACE.Substring(2) && x.ID != task.ID); if (sametask != null)//有,两个任务目标位互换 { WZ.Useful.Commons.LogTextHelper.WriteLine("满入记录日志:库位互换原库位" + sametask.TOPLACE + "重定向后库位:" + toPlace.PLACE.Substring(2) + ";器具号-" + sametask.TASK_TASK?.BASE_CONTAINER?.CONTAINERNAME); sametask.TOPLACE = toPlace.PLACE.Substring(2); if (sametask.SRMTASKTYPE == 1) { sametask.TASK_TASK.TOPLACE = toPlace.PLACE; } } task.TOPLACE = newPlace.PLACE.Substring(2); if (task.SRMTASKTYPE == 1) { task.TASK_TASK.TOPLACE = newPlace.PLACE; } } var arr = task.TOPLACE.Split('-'); if (arr.Length == 3) { string tempToPlace = ""; //增加执行顺序判断 if (arr[0] == "02") { //看1排那个是否满库位 tempToPlace = "01" + "-" + arr[1] + "-" + arr[2]; } else if (arr[0] == "03") { //看4排那个是否满库位 tempToPlace = "04" + "-" + arr[1] + "-" + arr[2]; } if (!string.IsNullOrEmpty(tempToPlace)) { string srmId = i.ToString(); string longToPlace = srmId + "-" + tempToPlace; string source = task.TOPLACE; string longSource = srmId + "-" + task.TOPLACE; var tempplace = edm.BASE_PLACE.FirstOrDefault(x => x.PLACE == longToPlace && x.ISFULL == 0 && x.ISLOCK == 0); if (tempplace != null) //查询远伸为空库位 { var vs = edm.BASE_PLACE_VS_CONTAINER.FirstOrDefault(u => u.PLACEID == tempplace.ID); if (vs == null) { var sametask = edm.SrmTask.FirstOrDefault(x => x.ISRELEASED == 0 && x.USESRMID == i && x.TOPLACE == tempToPlace && x.ID != task.ID); if (sametask != null)//有,两个任务目标位互换 { WZ.Useful.Commons.LogTextHelper.WriteLine("满入记录日志:库位互换原库位" + longSource + "三次重定向后库位:" + longToPlace + ";器具号-" + sametask.TASK_TASK?.BASE_CONTAINER?.CONTAINERNAME); sametask.TOPLACE = source; if (sametask.SRMTASKTYPE == 1) { sametask.TASK_TASK.TOPLACE = longSource; } } WZ.Useful.Commons.LogTextHelper.WriteLine("满入记录日志:库位互换原库位" + longSource + "三次重定向后库位2:" + longToPlace + ";器具号-" + task.TASK_TASK?.BASE_CONTAINER?.CONTAINERNAME); task.TOPLACE = tempToPlace; if (task.SRMTASKTYPE == 1) { task.TASK_TASK.TOPLACE = longToPlace; } } else { WZ.Useful.Commons.LogTextHelper.WriteLine("满入记录日志:没找到库存" + longToPlace); } } } } //else //{ // task.TASK_TASK.CANNOTDO = "该巷道已经没有空库位了"; // continue; //} var vs1 = edm.BASE_PLACE.AsNoTracking().Where(u => u.PLACE == (task.USESRMID.ToString() + "-" + task.TOPLACE)).FirstOrDefault(); if (vs1?.ISFULL == 1) { WZ.Useful.Commons.LogTextHelper.WriteLine("WCS", "必须换库位", "必须换库位"); //必须换库位 BASE_PLACE to_place = CreateMainTask.CreateIn(task.TASK_TASK.BASE_CONTAINER.CONTAINERNAME, task.USESRMID); if (to_place != null) { task.TOPLACE = to_place.PLACE.Substring(2); ; if (task.SRMTASKTYPE == 1) { task.TASK_TASK.TOPLACE = to_place.PLACE; } } else { WZ.Useful.Commons.LogTextHelper.WriteLine("WCS", "第二次调用生成入库任务寻找库位方法", task.TASK_TASK.BASE_CONTAINER.CONTAINERNAME + "没有充足的空库位"); continue; } } } if (task.SRMTASKTYPE == 2)//出库 { //因为零件数量原因,需指定器具 BASE_PLACE_VS_CONTAINER pvc = edm.BASE_PLACE_VS_CONTAINER.FirstOrDefault(x => x.BASE_CONTAINER.CONTAINERNAME == task.TASK_TASK.BASE_CONTAINER.CONTAINERNAME && x.ENABLE == 1); if (pvc != null && (pvc.STATUS == "IN" || pvc.STATUS == "TEMPOUT"))//存在且无占用(TEMPOUT暂定) { if (task.SOURCEPLACE != pvc.BASE_PLACE.PLACE.Substring(2))//库位改变 { task.SOURCEPLACE = pvc.BASE_PLACE.PLACE.Substring(2); task.TASK_TASK.SOURCEPLACE = task.USESRMID + "-" + task.SOURCEPLACE; edm.SaveChanges();//保存,用第二次循环判断是否生成移库任务 continue; } else//库位没改变、判断是否需要移库 { BASE_PLACE fromplace = edm.BASE_PLACE.FirstOrDefault(x => x.PLACE.Contains(task.SOURCEPLACE) && x.SRMID == task.USESRMID); if (task.USESRMID == 2 || task.USESRMID == 3 || task.USESRMID == 4 || task.USESRMID == 6 || task.USESRMID == 7 || task.USESRMID == 8 || task.USESRMID == 9) { if ((fromplace.ROW ?? 0) == 1 || (fromplace.ROW ?? 0) == 4) { BASE_PLACE nextPlace = edm.BASE_PLACE.FirstOrDefault(x => x.LAYER == fromplace.LAYER && x.COL == fromplace.COL && x.SRMID == fromplace.SRMID && (x.ROW == fromplace.ROW - 1 || x.ROW == fromplace.ROW + 1)); if (nextPlace != null && nextPlace.ISFULL == 1)//需要移库 { SrmTask srmTask = new SrmTask(); srmTask.SOURCEPLACE = nextPlace.PLACE.Substring(2); BASE_PLACE newPlace = edm.BASE_PLACE.OrderBy(x => x.PLACELEVEL).ThenBy(x => x.LAYER).ThenBy(x => x.COL).FirstOrDefault(x => x.SRMID == task.USESRMID && (x.ISFULL ?? 0) == 0 && (x.ISLOCK ?? 0) == 0 && x.BASE_PLACETYPE.PLACETYPE == nextPlace.BASE_PLACETYPE.PLACETYPE); if (newPlace != null) { srmTask.TOPLACE = newPlace.PLACE.Substring(2); srmTask.FASTHERTASKID = task.FASTHERTASKID; srmTask.ISRELEASED = 0; srmTask.HASFINISHED = 0; srmTask.USESRMID = task.USESRMID; srmTask.SRMTASKTYPE = 3; srmTask.TASK_TASK = task.TASK_TASK; BASE_PLACE_VS_CONTAINER nextPvc = edm.BASE_PLACE_VS_CONTAINER.FirstOrDefault(x => x.BASE_PLACE.PLACE == nextPlace.PLACE && x.ENABLE == 1); if (nextPvc == null) { nextPlace.ISFULL = 0; edm.SaveChanges(); continue;//自动校正 } srmTask.PALLETTYPE = nextPvc.BASE_CONTAINER.BASE_PALLET.PALLETCODE; edm.SrmTask.Add(srmTask); edm.SaveChanges(); continue;//下一循环下发移库任务 } else { //无库位可移库 continue; } } } } } } else if (pvc != null)//存在,占用,等会重发 { continue; } else { task.ISRELEASED = 1; task.TASK_TASK.HASFINISHED = 4;//暂定4为没做但是没法做 task.TASK_TASK.TASKSTATUS = "异常"; edm.SaveChanges(); //作为异常处理 List srmid; List rgvid; List tranid; int dir; int mainid = task.FASTHERTASKID; SrmService srmOPC = new SrmService(); List placeList = new List(); srmOPC.DeleteMainTask(mainid, out tranid, out rgvid, out srmid, out placeList, out dir); continue; } // } //下发任务 if (srmService.SendSrmTask(i, (task.ID % 32767) + 1, task.SOURCEPLACE, task.TOPLACE, task.PALLETTYPE ?? 0, (task.FASTHERTASKID % 32767) + 1) == 1) { //修改数据 task.ISRELEASED = 1; task.DOTIME = DateTime.Now; if (task.TASK_TASK.TASKTYPE == 2 || task.TASK_TASK.TASKTYPE == 3)//所在位置 { task.TASK_TASK.LOCALDEVICE = "堆垛机"; } //库存占用相关 BASE_PLACE_VS_CONTAINER pvcFrom = edm.BASE_PLACE_VS_CONTAINER.FirstOrDefault(x => x.BASE_PLACE.PLACE.Contains(task.SOURCEPLACE) && x.BASE_PLACE.SRMID == task.USESRMID && x.ENABLE == 1); if (pvcFrom != null) { pvcFrom.STATUS = "TEMPOUT"; } BASE_PLACE_VS_CONTAINER pvcTo = edm.BASE_PLACE_VS_CONTAINER.FirstOrDefault(x => x.BASE_PLACE.PLACE.Contains(task.TOPLACE) && x.BASE_PLACE.SRMID == task.USESRMID && x.ENABLE == 1); if (pvcTo != null) { pvcTo.STATUS = "TEMPIN"; } else { pvcTo = new BASE_PLACE_VS_CONTAINER(); } BASE_PLACE gotoPlace = edm.BASE_PLACE.FirstOrDefault(x => x.PLACE.Substring(2) == task.TOPLACE && x.SRMID == task.USESRMID); if (gotoPlace != null) { pvcTo.BASE_PLACE = gotoPlace; if (task.SRMTASKTYPE == 3)//移库 { BASE_PLACE_VS_CONTAINER pvc = edm.BASE_PLACE_VS_CONTAINER.FirstOrDefault(x => x.BASE_PLACE.PLACE.Substring(2) == task.SOURCEPLACE && x.BASE_PLACE.SRMID == task.USESRMID); pvcTo.BASE_CONTAINER = pvc.BASE_CONTAINER; } else { pvcTo.BASE_CONTAINER = task.TASK_TASK.BASE_CONTAINER; } pvcTo.ENABLE = 1; pvcTo.UPDATETIME = DateTime.Now; pvcTo.STATUS = "TEMPIN"; pvcTo.PVCCODE = IWareDataAccess.Base.PLACEVSCONTAINER.PlaceVsContainerSqlFunc.GetCode(); try { if (pvcTo.BASE_CONTAINER.BASE_CONTAINER_VS_ITEM.Count == 0) { pvcTo.TASKTYPE = "空器具入库"; } else { if ((pvcTo.BASE_CONTAINER.BASE_CONTAINER_VS_ITEM.FirstOrDefault().INTYPEID ?? 0) == 0) { pvcTo.TASKTYPE = "未选择"; } else { pvcTo.TASKTYPE = pvcTo.BASE_CONTAINER.BASE_CONTAINER_VS_ITEM.FirstOrDefault().BASE_INTYPE.INTYPE; } } } catch { } edm.BASE_PLACE_VS_CONTAINER.AddOrUpdateExtension(pvcTo); } //记录堆垛机任务 foreach (var j in task.TASK_TASK.BASE_CONTAINER.BASE_CONTAINER_VS_ITEM) { TASK_SRMRECORD srmRecord = new TASK_SRMRECORD(); srmRecord.srmTaskId = task.ID; srmRecord.containerId = task.TASK_TASK.CONTAINERID; srmRecord.itemId = j.ITEMID; srmRecord.itemCount = j.ITEMNUM; srmRecord.createTime = DateTime.Now; edm.TASK_SRMRECORD.AddOrUpdateExtension(srmRecord); } if (task.TASK_TASK.BASE_CONTAINER.BASE_CONTAINER_VS_ITEM.Count == 0) { TASK_SRMRECORD srmRecord = new TASK_SRMRECORD(); srmRecord.srmTaskId = task.ID; srmRecord.containerId = task.TASK_TASK.CONTAINERID; srmRecord.itemId = null; srmRecord.itemCount = 0; srmRecord.createTime = DateTime.Now; edm.TASK_SRMRECORD.AddOrUpdateExtension(srmRecord); } if (edm.SaveChanges() > 0) { Thread.Sleep(6000); } else { Thread.Sleep(1000); edm.SaveChanges(); } } } } } } catch (Exception ex) { WZ.Useful.Commons.LogTextHelper.WriteLine("任务下发异常" + ex.Message + "时间:" + DateTime.Now); } Thread.Sleep(5000); } } /// /// 输送线任务完成(超高检测) /// public static void TranTaskFinish() { SrmTranService srmtranService = new SrmTranService(); while (true) { List intList = new List { 47, 48, 61, 65, 32, 15 };//各个出入库口号,[Editby kejj,20230614] foreach (var tranid in intList) { //读取完成信号 if (srmtranService.IsPassed(tranid) == 1)//检测有误则记录 { ////查找对应数据库 //using (Model edm = new Model()) //{ // int taskid = srmtranService.FinishTask(tranid); // TranTask task = edm.TranTask.OrderByDescending(x=>x.ID).FirstOrDefault(x => (x.ID % 32767)+1 == taskid); // //修改数据 // task.MainTask.ERRORDEVICEID = tranid; // task.MainTask.ERRORMSG = 2; // task.MainTask.ISERROR = 1; // //反馈WMS同时删除对应子任务 // edm.SaveChanges(); // Thread.Sleep(1000); //} } } Thread.Sleep(1000); } } /// /// RGV任务完成 /// public static void RgvTaskFinish() { RgvService rgvService = new RgvService(); while (true) { try { //读取完成信号 for (int i = 1; i < 5; i++) { if (rgvService.IsTaskFinish(i)) { int taskId = rgvService.FinishTask(i); using (Model edm = new Model()) { //输送线更新锁定 long local = rgvService.GetRgvPosation(i); if (i == 1 | i == 3)//北侧安全,当前坐标需要额外减 { local = local - safeLength + AgvLength;//(当前坐标-AGV宽度一半=当前中心坐标)+安全距离 } else//南侧安全,当前坐标需要额外加 { local = local + safeLength - AgvLength; } //查找对应数据库 RgvTask task = edm.RgvTask.OrderByDescending(x => x.ID).FirstOrDefault(x => (x.ID % 32767) + 1 == taskId); //修改数据 if (task != null) { //去中转台占用中转台 if (task.TASKTYPE == 1) { if (task.TOPLACE == 17 || task.TOPLACE == 52) { TranLock t = edm.TranLock.FirstOrDefault(x => x.TRANID == task.TOPLACE); t.ISFULL = 1; } else if (task.SOURCEPLACE == 17 || task.SOURCEPLACE == 52) { TranLock t = edm.TranLock.FirstOrDefault(x => x.TRANID == task.SOURCEPLACE); t.ISFULL = 0; } if (edm.SaveChanges() > 0) { //edm = new Model(); } else { edm.SaveChanges(); } } //锁定单侧 if (Helper.LockTran(i, local, local)) { task.HASFINISHED = 1; task.FINISHTIME = DateTime.Now; if (task.TASK_TASK.TASKTYPE == 1 && task.TASK_TASK.RgvTask.OrderBy(x => x.ID).ToList().IndexOf(task) == task.TASK_TASK.RgvTask.Count - 1)//最后入库完成,在堆垛机上 { task.TASK_TASK.LOCALDEVICE = "堆垛机"; } else if (task.TASK_TASK.TASKTYPE == 2 && task.TASK_TASK.RgvTask.OrderBy(x => x.ID).ToList().IndexOf(task) == task.TASK_TASK.RgvTask.Count - 1)//最后出库完成,在输送线上 { task.TASK_TASK.LOCALDEVICE = "输送线"; } //反馈mainTask RgvTask nextTask = edm.RgvTask.FirstOrDefault(x => x.PRERGVTASK.ID == task.ID); if (nextTask == null && task.TASK_TASK.TASKTYPE == 2) { task.TASK_TASK.HASFINISHED = 1; task.TASK_TASK.TASKSTATUS = "完成"; task.TASK_TASK.FINISHTIME = DateTime.Now; task.TASK_TASK.NEEDTIME = 0; //叉车任务推送 /* [Editby kejj,20230621] CAR_CARTASK carTask = edm.CAR_CARTASK.FirstOrDefault(x => x.OUTORDERID == task.TASK_TASK.ORDERID && x.CONTAINERID == task.TASK_TASK.CONTAINERID);//此订单的相同器具就是叉车任务相关的 List userList = edm.View_SYS_USER.Where(x => x.roleName == "叉车司机").ToList(); List carTaskNotFinish = edm.CAR_CARTASK.Where(x => x.ENABLE == 1 && x.TASKSTATUS != "完成").ToList(); int numSmallest = 999;//最小任务数 int userId = 0; foreach (var j in userList) { int num = carTaskNotFinish.Where(x => x.USERID == j.id).Count(); if (num < numSmallest) { userId = j.id; numSmallest = num; } } if (carTask != null) { if (carTask.ORDER_OUTORDER != null && carTask.ORDER_OUTORDER.CARUSERID != null && carTask.ORDER_OUTORDER.CARUSERID != 0) { carTask.USERID = carTask.ORDER_OUTORDER.CARUSERID; } else { carTask.USERID = userId; } } */ //清空组盘数据 List cviList = edm.BASE_CONTAINER_VS_ITEM.Where(x => x.CONTAINERID == task.TASK_TASK.CONTAINERID).ToList(); edm.BASE_CONTAINER_VS_ITEM.RemoveRange(cviList); try { //记录删除托盘和物料绑定关系日志 【Editby shaoc,2023-03-07】 iWareSda_QQJF.WCSNEW.Helper.LogRemoveBASE_CONTAINER_VS_ITEM(cviList, "WCS.RgvTaskFinish", "RGV任务完成线程"); WZ.Useful.Commons.LogTextHelper.WriteLine("出库解组盘", "托盘" + task.TASK_TASK.BASE_CONTAINER.CONTAINERNAME, "零件" + task.TASK_TASK.BASE_CONTAINER.BASE_CONTAINER_VS_ITEM.FirstOrDefault().BASE_ITEM.ITEMNAME); } catch { } //出库单 ORDER_OUTORDER order = edm.ORDER_OUTORDER.FirstOrDefault(x => x.ID == task.TASK_TASK.ORDERID); if (order != null) { order.ORDERSTATUS = "完成"; } } //任务完成复位完成信号 if (edm.SaveChanges() > 0) { rgvService.SendRgvFinishConfirm(i); } } } else { WZ.Useful.Commons.LogTextHelper.WriteLine("任务完成触发,任务号" + taskId + "未找到,RGV:" + i + "时间:" + DateTime.Now, "", ""); //rgvService.SendRgvFinishConfirm(i); } } } } } catch (Exception e) { WZ.Useful.Commons.LogTextHelper.WriteLine("", "RgvTaskFinish", e.ToString()); continue; } Thread.Sleep(1000); } } /// /// 堆垛机任务完成 /// public static void SrmTaskFinish() { SrmService srmService = new SrmService(); while (true) { try { using (Model edm = new Model()) { //读取完成信号 for (int i = 0; i < 10; i++) { if (srmService.IsTaskFinish(i) == 1) { int taskId = srmService.FinishTask(i); //int taskId = 33; //查找对应数据库 SrmTask task = edm.SrmTask.OrderByDescending(x => x.ID).FirstOrDefault(x => (x.ID % 32767) + 1 == taskId); if (task == null)//任务号有误,先复位,然后继续运行 { //logtxtWrite.logtxt.txtWrite("任务完成触发,任务号"+taskId+"未找到,堆垛机:"+i+"时间:"+DateTime.Now,0); WZ.Useful.Commons.LogTextHelper.WriteLine("任务完成触发,任务号" + taskId + "未找到,堆垛机:" + i + "时间:" + DateTime.Now, "", ""); //srmService.SendSrmTaskFinishConfirm(i); continue; } //修改数据 task.HASFINISHED = 1; task.FINISHTIME = DateTime.Now; //修改库存 BASE_PLACE toplace = edm.BASE_PLACE.FirstOrDefault(x => x.PLACE.Contains(task.TOPLACE) && x.SRMID == task.USESRMID); if (toplace != null) { toplace.ISFULL = 1; WZ.Useful.Commons.LogTextHelper.WriteLine("堆垛机任务完成", "目标位", toplace.PLACE + "入库完成"); } BASE_PLACE fromplace = edm.BASE_PLACE.FirstOrDefault(x => x.PLACE.Contains(task.SOURCEPLACE) && x.SRMID == task.USESRMID); if (fromplace != null) { fromplace.ISFULL = 0; WZ.Useful.Commons.LogTextHelper.WriteLine("堆垛机任务完成", "起始位", fromplace.PLACE + "出库完成"); } try { BASE_PLACE_VS_CONTAINER toPvc = edm.BASE_PLACE_VS_CONTAINER.FirstOrDefault(x => x.BASE_PLACE.PLACE.Contains(task.TOPLACE) && x.BASE_PLACE.SRMID == task.USESRMID && x.ENABLE == 1); if (toPvc != null) { toPvc.STATUS = "IN"; WZ.Useful.Commons.LogTextHelper.WriteLine("堆垛机任务完成", "组盘", toPvc.PLACEID + "置位入库完成"); } else//防写入失败 { if (toplace != null) { toplace.ISFULL = 1; toPvc = new BASE_PLACE_VS_CONTAINER(); toPvc.BASE_PLACE = toplace; if (task.SRMTASKTYPE == 3)//移库 { BASE_PLACE_VS_CONTAINER pvc = edm.BASE_PLACE_VS_CONTAINER.FirstOrDefault(x => x.BASE_PLACE.PLACE.Substring(2) == task.SOURCEPLACE && x.BASE_PLACE.SRMID == task.USESRMID); toPvc.BASE_CONTAINER = pvc.BASE_CONTAINER; } else { toPvc.BASE_CONTAINER = task.TASK_TASK.BASE_CONTAINER; } toPvc.ENABLE = 1; toPvc.UPDATETIME = DateTime.Now; toPvc.STATUS = "IN"; toPvc.PVCCODE = IWareDataAccess.Base.PLACEVSCONTAINER.PlaceVsContainerSqlFunc.GetCode(); try { if (toPvc.BASE_CONTAINER.BASE_CONTAINER_VS_ITEM.Count == 0) { toPvc.TASKTYPE = "空器具入库"; } else { if ((toPvc.BASE_CONTAINER.BASE_CONTAINER_VS_ITEM.FirstOrDefault().INTYPEID ?? 0) == 0) { toPvc.TASKTYPE = "未选择"; } else { toPvc.TASKTYPE = toPvc.BASE_CONTAINER.BASE_CONTAINER_VS_ITEM.FirstOrDefault().BASE_INTYPE.INTYPE; } } WZ.Useful.Commons.LogTextHelper.WriteLine("堆垛机任务完成", "组盘", toPvc.PLACEID + "二次置位入库完成"); } catch (Exception e) { WZ.Useful.Commons.LogTextHelper.WriteLine("堆垛机任务完成", "二次置位入库失败", e.ToString()); } } } BASE_PLACE_VS_CONTAINER fromPvc = edm.BASE_PLACE_VS_CONTAINER.FirstOrDefault(x => x.BASE_PLACE.PLACE.Contains(task.SOURCEPLACE) && x.BASE_PLACE.SRMID == task.USESRMID && x.ENABLE == 1); if (fromPvc != null) { edm.BASE_PLACE_VS_CONTAINER.Remove(fromPvc); //fromPvc.ENABLE = 0; //fromPvc.STATUS = "OUT"; } //反馈mainTask if (task.TASK_TASK.TASKTYPE == 1 || task.TASK_TASK.TASKTYPE == 3) { task.TASK_TASK.HASFINISHED = 1; task.TASK_TASK.TASKSTATUS = "完成"; task.TASK_TASK.FINISHTIME = DateTime.Now; task.TASK_TASK.LOCALDEVICE = "库里"; task.TASK_TASK.NEEDTIME = 0; } else if (task.TASK_TASK.TASKTYPE == 2)//出库记录位置 { task.TASK_TASK.LOCALDEVICE = "RGV"; } //if (task.TASK_TASK.TASKTYPE == 2) //{ // //清空组盘数据 // List containerList = edm.BASE_CONTAINER_VS_ITEM.Where(x => x.CONTAINERID == task.TASK_TASK.CONTAINERID).ToList(); // edm.BASE_CONTAINER_VS_ITEM.RemoveRange(containerList); //} //任务完成复位完成信号 if (edm.SaveChanges() > 0) { srmService.SendSrmTaskFinishConfirm(i); } } catch (Exception e) { WZ.Useful.Commons.LogTextHelper.WriteLine("", "堆垛机线程错误", e.ToString()); continue; } } } } Thread.Sleep(1000); } catch (Exception e) { WZ.Useful.Commons.LogTextHelper.WriteLine("", "堆垛机完成线程错误", e.ToString()); continue; } } } /// /// 反馈任务结果 /// public static void Returnresult() { while (true) { //using (Model edm = new Model()) //{ // //获取完成且未推送的任务 // TASK_TASK maintask = edm.TASK_TASK.FirstOrDefault(x => x.HASPUSHED == 0 && x.HASFINISHED == 1); //} //Thread.Sleep(1000); } } /// /// 出口堵塞 /// /// /// public static bool OutFull(string tranId) { using (Model edm = new Model()) { SRMTRAN.SrmTranService.SrmTranService srm = new SRMTRAN.SrmTranService.SrmTranService(); int tranNum2 = 0; if (tranId == "19") { tranNum2 = srm.GetSrmConveyorStationHasGoods(int.Parse(tranId) + 1) == 1 ? 1 : 0; } else if (tranId != "67" && tranId != "34" && tranId != "68") { tranNum2 = srm.GetSrmConveyorStationHasGoods(int.Parse(tranId) - 1) == 1 ? 1 : 0; } else if (tranId == "67" || tranId == "34") { tranNum2 = 1;//分拣出口就一段 } else if (tranId == "68") { tranNum2 = srm.GetSrmConveyorStationHasGoods(45) == 1 ? 1 : 0; } int taskNum = edm.TASK_TASK.Where(x => x.TOPLACE == tranId && x.HASFINISHED == 0 && x.HASREADED == 1).Count(); int tranNum1 = srm.GetSrmConveyorStationHasGoods(int.Parse(tranId)) == 1 ? 1 : 0; if (taskNum + tranNum1 + tranNum2 >= 2) { //暂时不能发 return false; } return true; } } /// /// 排序未解析主任务 /// public static void OrderTask() { using (Model edm = new Model()) { List taskList = edm.TASK_TASK.OrderBy(x => x.TASKLEVEL).Where(x => x.HASREADED == 0 && x.ENABLE == 1).ToList(); foreach (var i in taskList) { i.TASKLEVEL = 999;//初始化优先级 //i.TASKLEVEL = i.TASKLEVEL+10;//初始化优先级 i.CANNOTDO = "优先其它任务"; } //强制优先 List mustTask = taskList.Where(x => x.MUST == 1).ToList(); if (mustTask.Count != 0) { taskList = mustTask; } ////罚函数 //DateTime endLineTime = DateTime.Now.AddMinutes(-30); //TASK_TASK longTimeTask = taskList.OrderBy(x => x.CREATETIME).FirstOrDefault(x => x.CREATETIME < endLineTime); //if (longTimeTask != null) //{ // int minute = (int)(DateTime.Now - (longTimeTask.CREATETIME ?? DateTime.Now)).TotalMinutes; // minute = minute - 30;//超过30分钟开始累计时间 // int maxMinute = 120-30;//假设最大上限出现在2小时 // if (minute > maxMinute) // { // minute = maxMinute; // } // if (minute > 0) // { // int waitTime = 10000;//等待时间,单位毫秒(从10秒等待开始,最多1分钟) // waitTime = waitTime + (50000 / maxMinute) * minute; // Thread.Sleep(waitTime);//等待 // } //} //罚函数结束,正常运行 //--------两侧都优先出库 //if (taskList.FirstOrDefault(x => (x.TASKTYPE == 1 && int.Parse(x.SOURCEPLACE) < 35) || (x.TASKTYPE == 2 && int.Parse(x.TOPLACE) < 35)) == null)//因之前筛选,所以当不存在西侧出库时必东侧,存在则必西侧 //{ // doIn = doInEast; //} //else //{ // doIn = doInWest; //} //出口堵塞(先取出堵塞能够做到堵塞时先入库) if (!OutFull("67")) { foreach (var i in taskList.Where(x => x.TOPLACE == "67")) { i.CANNOTDO = "出口堵塞"; } taskList = taskList.Where(x => x.TOPLACE != "67").ToList(); } if (!OutFull("34")) { foreach (var i in taskList.Where(x => x.TOPLACE == "34")) { i.CANNOTDO = "出口堵塞"; } taskList = taskList.Where(x => x.TOPLACE != "34").ToList(); } if (!OutFull("51")) { foreach (var i in taskList.Where(x => x.TOPLACE == "51")) { i.CANNOTDO = "出口堵塞"; } taskList = taskList.Where(x => x.TOPLACE != "51").ToList(); } if (!OutFull("64")) { foreach (var i in taskList.Where(x => x.TOPLACE == "64")) { i.CANNOTDO = "出口堵塞"; } taskList = taskList.Where(x => x.TOPLACE != "64").ToList(); } if (!OutFull("12")) { foreach (var i in taskList.Where(x => x.TOPLACE == "12")) { i.CANNOTDO = "出口堵塞"; } taskList = taskList.Where(x => x.TOPLACE != "12").ToList(); } if (!OutFull("30")) { foreach (var i in taskList.Where(x => x.TOPLACE == "30")) { i.CANNOTDO = "出口堵塞"; } taskList = taskList.Where(x => x.TOPLACE != "30").ToList(); } if (!OutFull("19")) { foreach (var i in taskList.Where(x => x.TOPLACE == "19")) { i.CANNOTDO = "出口堵塞"; } taskList = taskList.Where(x => x.TOPLACE != "19").ToList(); } if (!OutFull("68")) { foreach (var i in taskList.Where(x => x.TOPLACE == "68")) { i.CANNOTDO = "出口堵塞"; } taskList = taskList.Where(x => x.TOPLACE != "68").ToList(); } //轮回东西侧 List taskAnotherSideList = new List(); if (doEast) { taskAnotherSideList = taskList.Where(x => (x.TASKTYPE == 1 && int.Parse(x.SOURCEPLACE) < 35) || (x.TASKTYPE == 2 && int.Parse(x.TOPLACE) < 35) || x.TASKTYPE == 3).ToList(); } else { taskAnotherSideList = taskList.Where(x => (x.TASKTYPE == 1 && int.Parse(x.SOURCEPLACE) > 34) || (x.TASKTYPE == 2 && int.Parse(x.TOPLACE) > 34) || x.TASKTYPE == 3).ToList(); } if (taskAnotherSideList.Count > 0)//另一侧存在 { taskList = taskAnotherSideList; } bool doIn = true; if (doIn) { //优先出库 taskList = taskList.OrderByDescending(x => x.TASKTYPE).ThenBy(x => x.TASKLEVEL).ToList(); for (int num = 1; num < 10; num++) { TASK_TASK task = taskList.FirstOrDefault(x => x.TASKTYPE == 2 && (x.SOURCEPLACE.Substring(0, 1) == num.ToString())); if (task != null) { //此巷道存在出库任务时,入库等待 taskList = taskList.Where(x => (x.TASKTYPE == 1 && (x.TOPLACE.Substring(0, 1) != num.ToString())) || x.TASKTYPE != 1).ToList(); } } } else { //优先入库 taskList = taskList.OrderBy(x => x.TASKTYPE).ThenBy(x => x.TASKLEVEL).ToList(); for (int num = 1; num < 10; num++) { TASK_TASK task = taskList.FirstOrDefault(x => x.TASKTYPE == 1 && (x.TOPLACE.Substring(0, 1) == num.ToString())); if (task != null) { //此巷道存在入库任务时,出库等待 taskList = taskList.Where(x => (x.TASKTYPE == 2 && (x.SOURCEPLACE.Substring(0, 1) != num.ToString())) || x.TASKTYPE != 2).ToList(); } } } //堆垛机非空闲 SrmService srmService = new SrmService(); for (int num = 1; num < 10; num++) { if (!srmService.IsNotUse(num)) { foreach (var i in taskList.Where(x => (x.SOURCEPLACE.Substring(0, 1) == num.ToString() && x.TASKTYPE == 2) || x.TASKTYPE == 1)) { i.CANNOTDO = "堆垛机非空闲或故障"; } taskList = taskList.Where(x => (x.SOURCEPLACE.Substring(0, 1) != num.ToString() && x.TASKTYPE == 2) || x.TASKTYPE == 1).ToList(); } SrmTask srmTask = edm.SrmTask.FirstOrDefault(x => x.USESRMID == num && x.ISRELEASED == 0); if (srmTask != null) { foreach (var i in taskList.Where(x => (x.SOURCEPLACE.Substring(0, 1) == num.ToString() && x.TASKTYPE == 2) || x.TASKTYPE == 1)) { i.CANNOTDO = "堆垛机非空闲或故障"; } taskList = taskList.Where(x => (x.SOURCEPLACE.Substring(0, 1) != num.ToString() && x.TASKTYPE == 2) || x.TASKTYPE == 1).ToList(); } } ////rgv空闲判断东西侧 //RgvService rgvService=new RgvService(); //if (rgvService.IsRgvReady(1) && rgvService.IsRgvReady(2))//西侧全空闲 //{ // taskList = taskList.OrderByDescending(x => x.TASKTYPE).ToList(); //} //else if (rgvService.IsRgvReady(3) && rgvService.IsRgvReady(4))//东侧全空闲 //{ // taskList = taskList.OrderBy(x => x.TASKTYPE).ToList(); //} //else //{ // taskList = taskList.OrderByDescending(x => x.TASKTYPE).ToList(); //} //设置优先级 int Level = 0; taskList = taskList.OrderByDescending(x => (x.ISHURRY ?? 0)).ThenBy(x => x.CREATETIME).ToList();//提高强制的优先级 foreach (var i in taskList) { i.TASKLEVEL = Level; Level++; if (i.TASKLEVEL == 0) { i.CANNOTDO = ""; } } edm.SaveChanges(); } } /// /// 解析主任务 /// public static void ReadMainTask() { while (true) { try { Thread.Sleep(1000); //排序 OrderTask(); //读取数据库主任务任务 using (Model edm = new Model()) { TASK_TASK mainTask = edm.TASK_TASK.OrderBy(x => x.TASKLEVEL).FirstOrDefault(x => x.HASREADED == 0 && x.ENABLE == 1 && x.MUST == 1); //if (mainTask != null && mainTask.TASKLEVEL == 999) //{ // ///强制任务存在且无法下发,则死等 // continue; //} if (mainTask == null) { //不存在强制任务则选非强制顺序的 mainTask = edm.TASK_TASK.OrderByDescending(x => x.MUST).ThenBy(x => x.TASKLEVEL).FirstOrDefault(x => x.HASREADED == 0 && x.TASKLEVEL != 999 && x.ENABLE == 1); } //判断设备是否允许下发 int statusId = 0; int deviceId = 0; if (mainTask != null) { if (Helper.TaskCouldSend(mainTask.SOURCEPLACE, mainTask.TOPLACE, mainTask.TASKTYPE ?? 0, out statusId, out deviceId))//调试状态先屏蔽,不然太麻烦 { if (mainTask != null) { //堆垛机任务 SrmTask srmTask = new SrmTask(); srmTask.TASK_TASK = mainTask; srmTask.HASFINISHED = 0; srmTask.ISRELEASED = 0; try { srmTask.PALLETTYPE = mainTask.BASE_CONTAINER.BASE_PALLET.PALLETCODE; } catch { srmTask.PALLETTYPE = 0; } if (mainTask.TASKTYPE == 1)//入库 { srmTask.USESRMID = int.Parse(mainTask.TOPLACE.Substring(0, 1)); srmTask.SOURCEPLACE = Helper.GetSrmEnter(srmTask.USESRMID, mainTask.TASKTYPE ?? 0, Helper.GetIsEast(int.Parse(mainTask.SOURCEPLACE))); srmTask.TOPLACE = mainTask.TOPLACE.Substring(2, 8); srmTask.SRMTASKTYPE = 1; } else if (mainTask.TASKTYPE == 2)//出库 { srmTask.USESRMID = int.Parse(mainTask.SOURCEPLACE.Substring(0, 1)); srmTask.SOURCEPLACE = mainTask.SOURCEPLACE.Substring(2, 8); srmTask.TOPLACE = Helper.GetSrmEnter(srmTask.USESRMID, mainTask.TASKTYPE ?? 0, Helper.GetIsEast(int.Parse(mainTask.TOPLACE))); srmTask.SRMTASKTYPE = 2; //检测是否会造成RGV堵塞(单出口只能发2条) if (!OutFull(mainTask.TOPLACE)) { mainTask.TASKSTATUS = "出口堵塞"; edm.SaveChanges(); fullTimes++; if (fullTimes > fullTimesMax) { //换任务 //记录出入库 if (mainTask.TASKTYPE == 1) { if (int.Parse(mainTask.SOURCEPLACE) > 34) { //doInEast = true; doEast = true; } else { //doInWest = true; doEast = false; } } else if (mainTask.TASKTYPE == 2) { if (int.Parse(mainTask.TOPLACE) > 34) { //doInEast = false; doEast = true; } else { //doInWest = false; doEast = false; } } fullTimes = 0;//换口重置 } continue; } else { fullTimes = 0; //叉车任务创建时间改为RGV任务完成的时候 //创建叉车任务 //ORDER_OUTORDER order = edm.ORDER_OUTORDER.FirstOrDefault(x => x.ID == mainTask.ORDERID); //去掉验证PDA上选择目的地才能生成叉车任务的限制 【Editby shaocx,2023-06-07】 //我靠,还不能直接 去掉验证PDA上选择目的地才能生成叉车任务的限制,因为会在这一行报错 carTask.TODESTINATION = order.BASE_PRODUCTIONLINE.PRODUCTIONLINENAME; 【Editby shaocx,2023-06-11】 //if (order != null /*&& (order.TOLINEID ?? 0) != 0*/)//[Editby kejj,20230621] //{ // CAR_CARTASK carTask = new CAR_CARTASK(); // BASE_PRODUCTIONLINE pl = edm.BASE_PRODUCTIONLINE.FirstOrDefault(x => x.PRODUCTIONLINECODE == mainTask.TOPLACE); // if (pl != null) // { // carTask.CARTASKNAME = IWareDataAccess.Car.CARTASK.CarTaskSqlFunc.GetCode(); // carTask.FROMDESTINATION = pl.PRODUCTIONLINENAME; // carTask.TODESTINATION = order.BASE_PRODUCTIONLINE?.PRODUCTIONLINENAME; // carTask.CONTAINERID = mainTask.CONTAINERID; // carTask.TASKSTATUS = "新建"; // carTask.ENABLE = 1; // carTask.UPDATETIME = DateTime.Now; // carTask.CREATORID = order.CREATORID; // carTask.ORDER_OUTORDER = order; // carTask.USERID = order.SYS_USER?.ID;//[Editby kejj,20230621] // string detail = ""; // foreach (var i in mainTask.BASE_CONTAINER.BASE_CONTAINER_VS_ITEM) // { // detail = detail + i.BASE_ITEM.ITEMNAME + " " + i.BASE_ITEM.ITEMDES + ":" + i.ITEMNUM + "个;\n"; // } // carTask.ITEMDETAIL = detail; // edm.CAR_CARTASK.Add(carTask); // } //} } } else if (mainTask.TASKTYPE == 3)//移库 { srmTask.USESRMID = int.Parse(mainTask.TOPLACE.Substring(0, 1)); srmTask.SOURCEPLACE = mainTask.SOURCEPLACE.Substring(2, 8); srmTask.TOPLACE = mainTask.TOPLACE.Substring(2, 8); srmTask.SRMTASKTYPE = 3; } edm.SrmTask.Add(srmTask); if (mainTask.TASKTYPE != 3)//移库时只需动堆垛机 { int tranid = 0;//记录输送线出入库口 if (mainTask.TASKTYPE == 1) { tranid = int.Parse(mainTask.SOURCEPLACE); } else if (mainTask.TASKTYPE == 2) { tranid = int.Parse(mainTask.TOPLACE); } if (mainTask.TASKTYPE == 1) { //输送线任务 TranTask tranTask = new TranTask(); tranTask.TASK_TASK = mainTask; tranTask.ISRELEASED = 0; tranTask.HASFINISHED = 0; try { tranTask.PALLETTYPE = mainTask.BASE_CONTAINER.BASE_PALLET.PALLETCODE; } catch { tranTask.PALLETTYPE = 0; } //if (mainTask.TASKTYPE == 1) //{ tranTask.SOURCEPLACE = int.Parse(mainTask.SOURCEPLACE); tranTask.TOPLACE = Helper.GetNextTran(tranTask.SOURCEPLACE); //tranid = tranTask.SOURCEPLACE; //} //else if (mainTask.TASKTYPE == 2) //{ // tranTask.TOPLACE = int.Parse(mainTask.TOPLACE); // tranTask.SOURCEPLACE = Helper.GetNextTran(tranTask.TOPLACE); // tranid = tranTask.TOPLACE; //} edm.TranTask.Add(tranTask); } //RGV任务 int srmTranid = Helper.GetTranEnter(srmTask.USESRMID, mainTask.TASKTYPE ?? 0, Helper.GetIsEast(tranid)); int enterTranId = Helper.GetNextTran(tranid); //判断是否需中转 int useRgv = 0; if (Helper.NeedTwoRgv(srmTask.USESRMID, tranid, mainTask.TASKTYPE ?? 0)) { mainTask.ISEXCHANGE = 1; int centerId = 0; //定义东西中转台ID if (Helper.GetIsEast(tranid)) { centerId = centerEastId; } else { centerId = centerWestId; } if (mainTask.TASKTYPE == 1) { //创建三条RGV任务 RgvTask preTask = null; bool result1 = Helper.AddRGVTask(edm, mainTask, enterTranId, centerId, 1, preTask, out useRgv, out preTask);//去中转台 //int safeTran = Helper.GetSafeTranId(useRgv); //bool result2 = Helper.AddRGVTask(edm, mainTask, centerId, safeTran, 2, preTaskId, out useRgv, out preTaskId);//离开干涉 bool result3 = Helper.AddRGVTask(edm, mainTask, centerId, srmTranid, 1, preTask, out useRgv, out preTask);//拿中转台 if (!result1 || !result3) { //设备故障,不生成任务并反馈(通常不会,之前判断两RGV都是好的才会中转) Helper.SetTaskOver(mainTask, useRgv); mainTask.TASKSTATUS = "设备不可用"; edm.SaveChanges(); continue; } } else { //创建三条RGV任务 RgvTask preTask = null; bool result1 = Helper.AddRGVTask(edm, mainTask, srmTranid, centerId, 1, preTask, out useRgv, out preTask);//去中转台 //int safeTran = Helper.GetSafeTranId(useRgv); //bool result2 = Helper.AddRGVTask(edm, mainTask, centerId, safeTran, 2, preTaskId, out useRgv, out preTaskId);//离开干涉 bool result3 = Helper.AddRGVTask(edm, mainTask, centerId, enterTranId, 1, preTask, out useRgv, out preTask);//拿中转台 if (!result1 || !result3) { //设备故障,不生成任务并反馈(通常不会,之前判断两RGV都是好的才会中转) Helper.SetTaskOver(mainTask, useRgv); mainTask.TASKSTATUS = "设备不可用"; edm.SaveChanges(); continue; } } } else { RgvTask preTask = null; mainTask.ISEXCHANGE = 0; if (mainTask.TASKTYPE == 1) { if (!Helper.AddRGVTask(edm, mainTask, enterTranId, srmTranid, 1, preTask, out useRgv, out preTask)) { //设备故障,不生成任务并反馈 Helper.SetTaskOver(mainTask, useRgv); mainTask.TASKSTATUS = "设备不可用"; edm.SaveChanges(); continue; } } else { if (!Helper.AddRGVTask(edm, mainTask, srmTranid, enterTranId, 1, preTask, out useRgv, out preTask)) { //设备故障,不生成任务并反馈 Helper.SetTaskOver(mainTask, useRgv); mainTask.TASKSTATUS = "设备不可用"; edm.SaveChanges(); continue; } } } } //置位解析完成 mainTask.HASREADED = 1; mainTask.DOTIME = DateTime.Now; mainTask.TASKSTATUS = "任务执行中"; //记录出入库 if (mainTask.TASKTYPE == 1) { if (int.Parse(mainTask.SOURCEPLACE) > 34) { //doInEast = true; doEast = true; } else { //doInWest = true; doEast = false; } } else if (mainTask.TASKTYPE == 2) { if (int.Parse(mainTask.TOPLACE) > 34) { //doInEast = false; doEast = true; } else { //doInWest = false; doEast = false; } } edm.SaveChanges(); if (mainTask.TASKTYPE == 1) { //Helper.Speaking("开始入库"); } else if (mainTask.TASKTYPE == 2) { //Helper.Speaking("开始出库"); } } } } else { fullTimes++; if (fullTimes > fullTimesMax) { ////记录出入库 //if (doEast) //{ // doInEast = !doInEast; //} //else //{ // doInWest = !doInWest; //} doEast = !doEast; fullTimes = 0;//换口重置 } continue; } } } catch (Exception e) { WZ.Useful.Commons.LogTextHelper.WriteLine("", "ReadMainTask", e.ToString()); } } } } }