using DBHelper; using System; using System.Linq; using WCS.Core; using WCS.Entity; using WCS.Entity.Protocol; using WCS.Service.Extensions; using WCS.Service.Helpers; namespace WCS.Service.Works.Stations { //[WorkTitle(typeof(ProductHandler), "AGV交互", false)] //class AGV交互 : DeviceWork> //{ // protected override bool SelectDevice(WCS_DEVICE dev) // { // return new string[] { "2122", "2131", "2143", "2088" }.Contains(dev.CODE); // } // protected override void Do(Device dev) // { // AGV(dev); // } // void AGV(Device dev) // { // Ltc.Log("AGV交互"); // var station = dev.Entity.CODE; // DB.Do(db => // { // var agvTasks = db.Default.Set().Where(v => v.Station == station).Where(v => v.Status < AGVTaskStatus.完成); // var agvtask = agvTasks.Where(v => v.TaskType == AGVTaskType.成品入库) // .OrderByDescending(v => v.Status).ThenBy(v => v.CreateTime) // .FirstOrDefault(); // if (agvtask == null) // return; // if (Ltc.Do(agvtask, agvtask => agvtask.Status == AGVTaskStatus.新建)) // { // if (station != "2088") // { // if (agvTasks.Where(v => v.TaskType == AGVTaskType.原膜出库 && v.Status > AGVTaskStatus.确认 && v.Status < AGVTaskStatus.取放完成).Any()) // { // var msg = "有正在执行的出库AGV任务"; // throw new Exception(msg); // } // } // var qtyIn = db.Default.Set().Where(v => v.TYPE == TaskType.组盘 && v.STATUS < WCS.Entity.TaskStatus.已完成 && v.ADDRFROM == station).Count(); // if (qtyIn >= 6) // { // var msg = $"{agvtask.Workshop}车间入库任务数量已达{qtyIn},暂停执行"; // throw new Exception(msg); // } // short inTemp = 0; // string devs = ""; // if (station == "2143") // { // inTemp = 2274; // devs = "2143,2140,2141,2274"; // } // if (inTemp > 0) // { // var flag = devs.Split(',').Select(v => Device.Find(v).Device()).Any(v => v.Data.GOODSEND == inTemp); // if (flag) // { // throw new Exception("交通管制,入库缓存位已被占用"); // } // } // var outStation = dev.Entity.CODE; // if (outStation == "2088") // outStation = "2086"; // var outTask = db.Default.Set().Where(v => v.TYPE == TaskType.出库 && v.STATUS < WCS.Entity.TaskStatus.已完成) // .Where(v => v.ADDRNEXT == v.ADDRTO || v.ADDRCURRENT == station).Where(v => v.ADDRTO == outStation) // .FirstOrDefault(); // if (outTask != null) // { // var msg = "交通管制,与任务" + outTask.ID + "路径冲突"; // throw new Exception(msg); // } // agvtask.Status = AGVTaskStatus.执行; // agvtask.UpdateTime = DateTime.Now; // db.Default.SaveChanges(); // } // else if (Ltc.Do(agvtask, v => v.Status < v.AGVStatus)) // { // if (Ltc.Do(dev, v => v.Data2.RES == true)) // return; // if (Ltc.Do(agvtask, v => v.AGVStatus == AGVTaskStatus.请求_允许 || v.AGVStatus == AGVTaskStatus.请求_允许2)) // { // if (Ltc.Do(dev, v => v.Data.TASKNUM > 0)) // return; // if (Ltc.Do(dev, v => v.Data.PH_STATUS == true)) // return; // agvtask.Status = agvtask.AGVStatus; // agvtask.UpdateTime = DateTime.Now; // db.Default.SaveChanges(); // } // else if (Ltc.Do(agvtask, v => v.AGVStatus == AGVTaskStatus.取放完成 || v.AGVStatus == AGVTaskStatus.取放完成2)) // { // agvtask.Status = agvtask.AGVStatus; // agvtask.UpdateTime = DateTime.Now; // db.Default.SaveChanges(); // //if (Ltc.Do(dev, v => v.Data.PH_STATUS)) // //{ // dev.Data2.RES = true; // //} // } // else if (Ltc.Do(agvtask, v => v.AGVStatus == AGVTaskStatus.完成 || v.AGVStatus == AGVTaskStatus.取消)) // { // agvtask.Status = agvtask.AGVStatus; // agvtask.UpdateTime = DateTime.Now; // db.Default.SaveChanges(); // } // } // }); // } //} [WorkTitle(typeof(ProductHandler), "AGV入库", true)] internal class AGV入库 : DeviceWork> { protected override bool SelectDevice(WCS_DEVICE dev) { return new string[] { "2122", "2131", "2143", "2088", "3001" }.Contains(dev.CODE); } protected override void Do(Device dev) { var station = dev.Entity.CODE; DB.Do(db => { var agvTasks = db.Default.Set().Where(v => v.Station == station).Where(v => v.Status < AGVTaskStatus.完成).Where(v => v.TaskType == AGVTaskType.入库).OrderBy(v => v.CreateTime).ToArray(); foreach (var agvtask in agvTasks) { var position = agvtask.Position.Replace("_In", ""); if (position.Contains("_Back_")) position = position.Substring(0, position.IndexOf("_0")); if (!ProtocolProxy.AllDatas.ContainsKey(position)) ProtocolProxy.AllDatas[position] = new ProdLineData(); var pld = ProtocolProxy.AllDatas[position] as ProdLineData; pld.Frame = LogicHandler.Frame; pld.Code = position; pld.TaskList.Add(agvtask); try { if (Ltc.Do(agvtask, agvtask => agvtask.Status == AGVTaskStatus.新建)) { //相关错误会在入库扫码位报出,此处只做拦截处理 if (!SystemConfigHelpers.GetDeviceConfig(dev.Entity.CODE)) return; if (station != "2088" && station != "3001") { if (db.Default.Set().Where(v => v.TaskType == AGVTaskType.叫料 && v.Status > AGVTaskStatus.确认 && v.Status < AGVTaskStatus.取放完成 && v.Station == station).Any()) { var msg = $"[{station}]有正在执行的出库AGV任务"; throw new Exception(msg); } if (db.Default.Set().Where(v => v.TaskType == AGVTaskType.入库 && v.Status > AGVTaskStatus.新建 && v.Status < AGVTaskStatus.完成扫码 && v.Station == station).Any()) { var msg = $"[{station}]有正在执行的入库AGV任务"; throw new Exception(msg); } var qtyIn = db.Default.Set().Where(v => v.TYPE == TaskType.组盘 && v.STATUS < WCS.Entity.TaskStatus.已完成 && v.ADDRFROM == station).Count(); var max = 6; max = 9; if (qtyIn >= max) { var msg = $"{agvtask.Workshop}车间入库任务数量已达{qtyIn},暂停执行-{station}"; throw new Exception(msg); } } if (dev.Data2.RES) throw new Exception($"[{station}]顶升下降信号未清除"); if (Ltc.Do(dev, v => v.Data.TASKNUM == dev.Entity.Code())) throw new Exception($"[{station}]待分配任务"); short inTemp = 0; Device[] arr = null; Device[] arrout = null; if (station == "2143") { inTemp = 2274; arr = Device.Find("2143", "2140", "2141", "2274").Select(v => v.Device()).ToArray(); arrout = Device.Find("2326", "2140", "2143").Select(v => v.Device()).ToArray(); } else if (station == "2131") { inTemp = 2273; arr = Device.Find("2131", "2128", "2129", "2273").Select(v => v.Device()).ToArray(); arrout = Device.Find("2327", "2128", "2131").Select(v => v.Device()).ToArray(); } else if (station == "2122") { inTemp = 2272; arr = Device.Find("2122", "2119", "2120", "2272").Select(v => v.Device()).ToArray(); arrout = Device.Find("2328", "2119", "2122").Select(v => v.Device()).ToArray(); } else if (station == "3001") { if (db.Default.Set().Count(v => v.TaskType == AGVTaskType.入库 && v.Station == "3001" && v.Status >= AGVTaskStatus.确认 && v.Status < AGVTaskStatus.完成扫码) >= 2) throw new Exception($"流量管控"); inTemp = 3005; arr = Device.Find("3001", "3005").Select(v => v.Device()).ToArray(); arrout = Device.Find("3001", "3012").Select(v => v.Device()).ToArray(); } if (inTemp > 0) { if (arr.Any(v => v.Data2.CONFIRM)) continue; if (arrout.Any(v => v.Data2.CONFIRM)) continue; var flag = arr.Any(v => v.Data.GOODSEND == inTemp); if (flag) throw new Exception($"[{station}]交通管制,入库缓存位已被占用"); flag = arrout.Any(v => v.Data.GOODSEND == dev.Entity.Code()); if (flag) throw new Exception($"交通管制,{station}被出库任务占用"); } else { var outStation = dev.Entity.CODE; if (outStation == "2088") outStation = "2086"; var outTask = db.Default.Set().Where(v => v.TYPE == TaskType.出库 && v.STATUS < WCS.Entity.TaskStatus.已完成) .Where(v => v.ADDRTO == outStation).Where(v => v.ADDRNEXT == v.ADDRTO).ToList() .Where(v => { var curr = v.AddrCurrent(db); return (curr != v.ADDRTO) && (curr != "2084"); }) .FirstOrDefault(); if (outTask != null) { var msg = $"[{station}]交通管制,与出库任务[{outTask.ID}]路径冲突"; throw new Exception(msg); } } agvtask.Status = AGVTaskStatus.执行; agvtask.UpdateTime = DateTime.Now; db.Default.SaveChanges(); } else if (Ltc.Do(agvtask, v => v.Status < v.AGVStatus || v.AGVStatus == AGVTaskStatus.确认)) { if (Ltc.Do(agvtask, v => v.AGVStatus == AGVTaskStatus.确认 && v.Status != AGVTaskStatus.确认)) { if (agvTasks.Any(v => v.Status >= AGVTaskStatus.确认 && v.Status != AGVTaskStatus.执行 && v.Status < AGVTaskStatus.完成扫码 && v.Station == "3001")) throw new Exception($"同时放货任务数量最大为1"); // 缓存位与取放货位没有光电 任务 去往缓存位任务 ,如果楼上没有出库任务,就不会有去往3006的任务 var inTemp = Device.Find("3006", "3001", "3012", "3004", "3005").Select(v => v.Device()); if (inTemp.Any(v => v.Data.PH_STATUS == true || v.Data.TASKNUM > 0 || v.Data.GOODSEND == 3006 || v.Data2.Status.HasFlag(StationStatus.运行状态位) || v.Data.GOODSTYPE == 2)) return; if (db.Default.Set().Any(v => v.STATUS < TaskStatus.已完成 && v.ADDRNEXT == "3060")) return; if (db.Default.Set().Any(v => v.AGVStatus >= AGVTaskStatus.确认 && v.TaskType == AGVTaskType.叫料 && v.Station == "3001" && v.Status < AGVTaskStatus.完成)) return; //3005没有出库任务 var con3005 = Device.Find("3005").Device(); if ((con3005.Data.PH_STATUS && con3005.Data.GOODSEND is 3001 or 0) || con3005.Data2.Status.HasFlag(StationStatus.运行状态位)) return; agvtask.Status = agvtask.AGVStatus; agvtask.UpdateTime = DateTime.Now; db.Default.SaveChanges(); } else if (Ltc.Do(agvtask, v => v.AGVStatus == AGVTaskStatus.请求_允许 || v.AGVStatus == AGVTaskStatus.请求_允许2)) { if (Ltc.Do(dev, v => v.Data2.RES)) continue; if (Ltc.Do(dev, v => v.Data.TASKNUM > 0)) continue; if (Ltc.Do(dev, v => !v.Data3.Status.Has(StationStatus.自动))) continue; if (Ltc.Do(dev, v => v.Data.PH_STATUS == true || v.Data.TASKNUM != 0)) continue; if (agvtask.AGVStatus == AGVTaskStatus.请求_允许2) { if (agvtask.Status < AGVTaskStatus.取放完成) throw new Exception($"[{station}]请求放第二卷之前必须完成第一卷放货"); } agvtask.Status = agvtask.AGVStatus; agvtask.UpdateTime = DateTime.Now; db.Default.SaveChanges(); } else if (Ltc.Do(agvtask, v => v.AGVStatus == AGVTaskStatus.取放完成 || v.AGVStatus == AGVTaskStatus.取放完成2)) { if (Ltc.Do(dev, v => v.Data2.RES)) { Configs.UploadException(dev.Entity.CODE, "顶升下降信号未清除"); continue; } if (Ltc.Do(dev, v => v.Data.PH_STATUS == false)) { Configs.UploadException(dev.Entity.CODE, "AGV放货完成后输送线无光电信号"); continue; } agvtask.Status = agvtask.AGVStatus; agvtask.UpdateTime = DateTime.Now; db.Default.SaveChanges(); dev.Data2.RES = true; } else if (Ltc.Do(agvtask, v => v.AGVStatus == AGVTaskStatus.完成)) { agvtask.Status = agvtask.AGVStatus; agvtask.UpdateTime = DateTime.Now; db.Default.SaveChanges(); } else if (Ltc.Do(agvtask, v => v.AGVStatus == AGVTaskStatus.取消)) { agvtask.Status = agvtask.AGVStatus; agvtask.UpdateTime = DateTime.Now; db.Default.SaveChanges(); } } } catch (Exception ex) { Ltc.Log("AGV任务" + agvtask.ID + ":" + ex.GetBaseException().Message); Configs.UploadException?.Invoke(position, ex.GetBaseException().Message); } } }); } } [WorkTitle(typeof(ProductHandler), "车间叫料", false)] internal class 车间叫料 : DeviceWork> { protected override bool SelectDevice(WCS_DEVICE dev) { return new string[] { "2086", "2122", "2131", "2143", "3001" }.Contains(dev.CODE); } protected override void Do(Device dev) { var station = dev.Entity.CODE; var taskId = dev.Data.TASKNUM; //if (Ltc.Do(dev, v => v.Entity.WakeupOn(10000,"叫料"))) { DB.Do(db => { var agvTasks = db.Default.Set().Where(v => v.Station == station && v.TaskType == AGVTaskType.叫料) .Where(v => v.Status < AGVTaskStatus.完成).ToArray(); foreach (var agvtask in agvTasks) { var position = agvtask.Position; if (!ProtocolProxy.AllDatas.ContainsKey(position)) ProtocolProxy.AllDatas[position] = new ProdLineData(); var pld = ProtocolProxy.AllDatas[position] as ProdLineData; pld.Frame = LogicHandler.Frame; pld.Code = position; pld.TaskList.Add(agvtask); try { if (Ltc.Do(agvtask, agvtask => agvtask.Status == AGVTaskStatus.新建)) { if (station == "2086") { var count1 = ProtocolProxy.WMS120Redis.Get("MaxLineCallTaskCount_13_14").ToInt(); var qty = db.Default.Set().Where(v => v.TaskType == AGVTaskType.叫料 && v.Status > AGVTaskStatus.新建 && v.Status < AGVTaskStatus.完成) .Where(v => v.Position == agvtask.Position).Count(); if (Ltc.Do(qty, OutTaskQty => OutTaskQty >= count1)) { throw new Exception($"{agvtask.Position}正在执行的叫料任务数量已达{qty},暂停出库"); } } else if (station == "3001") { var qty = db.Default.Set().Where(v => v.TaskType == AGVTaskType.叫料 && v.Status > AGVTaskStatus.新建 && v.Status < AGVTaskStatus.完成) .Where(v => v.Position == agvtask.Position).Count(); if (Ltc.Do(qty, OutTaskQty => OutTaskQty >= 5)) { throw new Exception($"{agvtask.Position}正在执行的叫料任务数量已达{qty},暂停出库"); } } else { var count2 = ProtocolProxy.WMS120Redis.Get("MaxLineCallTaskCount_1_2_3").ToInt(); var qty = db.Default.Set().Where(v => v.TaskType == AGVTaskType.叫料 && v.Status > AGVTaskStatus.新建 && v.Status < AGVTaskStatus.完成) .Where(v => v.Position == agvtask.Position).Count(); if (Ltc.Do(qty, OutTaskQty => OutTaskQty >= count2)) { throw new Exception($"{agvtask.Position}正在执行的叫料任务数量已达{qty},暂停出库"); } } var res = WMS.GetOutTask(agvtask.Position, dev.Entity.CODE); var sc = Device.Find(res.TunnelNum).ROUTES.Where(v => v.NEXT.IsSC()).Select(v => v.NEXT).FirstOrDefault(); var loc = string.Format("{0}-{1}-{2}", res.Row, res.Colomn, res.Layer); var addrNext = dev.Entity.CODE; if (agvtask.Workshop == 1) addrNext = "2108"; else if (agvtask.Workshop == 2) addrNext = "2366"; else if (agvtask.Workshop == 3) addrNext = "2385"; else if (agvtask.Station == "2086") addrNext = "2325"; else if (agvtask.Station == "3001") { addrNext = "3045"; } var task = new WCS_TASK { TYPE = TaskType.出库, STATUS = WCS.Entity.TaskStatus.新建, ADDRFROM = loc, ADDRTO = dev.Entity.CODE, BARCODE = res.ContainerBarCode, TUNNEL = res.TunnelNum, WMSTASK = int.Parse(res.WMSTaskNum), UPDATEUSER = "WCS", SCSTATION = res.Memo1, DEVICE = sc.CODE, //ADDRCURRENT = loc, AgvTask = agvtask.ID, ADDRNEXT = addrNext }; db.Default.Set().Add(task); agvtask.Status = AGVTaskStatus.确认; agvtask.UpdateTime = DateTime.Now; db.Default.SaveChanges(); } else if (Ltc.Do(agvtask, v => v.AGVStatus == AGVTaskStatus.完成)) { //if (Ltc.Do(agvtask, v => v.Status != AGVTaskStatus.取放完成 && v.Status != AGVTaskStatus.取放完成2)) // continue; agvtask.Status = agvtask.AGVStatus; agvtask.UpdateTime = DateTime.Now; db.Default.SaveChanges(); } else if (Ltc.Do(agvtask, v => v.AGVStatus == AGVTaskStatus.取消)) { //if (Ltc.Do(agvtask, v => v.Status != AGVTaskStatus.新建)) // continue; agvtask.Status = agvtask.AGVStatus; agvtask.UpdateTime = DateTime.Now; db.Default.SaveChanges(); } } catch (Exception ex) { if (ex.Message.Contains("库存不足")) { agvtask.Status = AGVTaskStatus.取消; agvtask.UpdateTime = DateTime.Now; db.Default.SaveChanges(); } Ltc.Log("AGV任务" + agvtask.ID + ":" + ex.GetBaseException().Message); Configs.UploadException?.Invoke(agvtask.Position, ex.GetBaseException().Message); } } }); } if (Ltc.Do(dev, v => v.Data.TASKNUM == 0)) return; if (Ltc.Do(dev, v => v.Data.GOODSEND != dev.Entity.Code())) return; if (Ltc.Do(dev, v => !v.Data3.Status.Has(StationStatus.自动))) return; DB.Do(db => { var task = db.Default.Set().Find(taskId); if (task == null) { var msg = $"WCS任务号{taskId}不存在"; throw new Exception(msg); } if (Ltc.Do(task, task => task.TYPE != TaskType.出库)) return; if (task.AgvTask == 0) { throw new Exception("人工出库任务,请手动搬走"); } var agvtask = db.Default.Set().Find(task.AgvTask); if (agvtask == null) { var msg = $"AGV任务号{task.AgvTask}不存在"; throw new Exception(msg); } if (Ltc.Do(agvtask, agvtask => agvtask.Station != station)) return; if (Ltc.Do(agvtask, agvtask => agvtask.Status == AGVTaskStatus.确认)) { if (Ltc.Do(dev, v => v.Data.PH_STATUS == false)) return; var flag = db.Default.Set().Where(v => v.Station == station && v.TaskType == AGVTaskType.叫料) .Where(v => v.Status > AGVTaskStatus.确认 && v.Status < AGVTaskStatus.取放完成) .Any(); if (flag) throw new Exception("有未完成的AGV出库任务"); task.STATUS = WCS.Entity.TaskStatus.已完成; task.UPDATETIME = DateTime.Now; task.ENDTIME = DateTime.Now; agvtask.Status = AGVTaskStatus.执行; agvtask.UpdateTime = DateTime.Now; db.Default.SaveChanges(); } else if (Ltc.Do(agvtask, agvtask => agvtask.Status < agvtask.AGVStatus)) { if (Ltc.Do(agvtask, agvtask => agvtask.AGVStatus == AGVTaskStatus.请求_允许 || agvtask.AGVStatus == AGVTaskStatus.请求_允许2)) { if (Ltc.Do(agvtask, agvtask => agvtask.Status < AGVTaskStatus.确认)) return; if (Ltc.Do(dev, v => v.Data2.RES == true)) throw new Exception("任务清零信号未清除"); agvtask.Status = agvtask.AGVStatus; agvtask.UpdateTime = DateTime.Now; db.Default.SaveChanges(); } else if (Ltc.Do(agvtask, agvtask => agvtask.AGVStatus == AGVTaskStatus.取放完成 || agvtask.AGVStatus == AGVTaskStatus.取放完成2)) { if (Ltc.Do(dev, v => v.Data2.RES == true)) throw new Exception("任务清零信号未清除"); if (Ltc.Do(dev, v => v.Data.PH_STATUS == true)) throw new Exception("AGV取货完成后依然有光电信号"); if (Ltc.Do(agvtask, agvtask => agvtask.Status < AGVTaskStatus.请求_允许)) throw new Exception("AGV任务状态有误"); agvtask.Status = agvtask.AGVStatus; agvtask.UpdateTime = DateTime.Now; db.Default.SaveChanges(); dev.Data2.RES = true; } } }); } } }