| | |
| | | |
| | | } |
| | | } |
| | | else if (data == "1121")//B口工作信号 |
| | | else if (data == "1121")//AB口工作信号 |
| | | { |
| | | if (BottlePEMInfoFullTwo(plc, plc.location[0])) |
| | | { |
| | |
| | | } |
| | | } |
| | | private static object locko = new object(); |
| | | private static object lockoIn = new object(); |
| | | private static object lockoOut = new object(); |
| | | |
| | | static bool BottlePEMInfoFullTwo(Settings.deviceInfo plc, string location) |
| | | { |
| | | |
| | | |
| | | try |
| | | { |
| | | lock (locko) |
| | |
| | | var chi = new SqlHelper<object>().GetInstance(); |
| | | var newDb = chi.CopyNew(); |
| | | Location endBit = null; |
| | | Location staBit = null; |
| | | bool SentTask = false; |
| | | if (location == "") |
| | | { |
| | | throw new Exception("货位为空"); |
| | |
| | | { |
| | | throw new Exception("没有【执行中】的工单"); |
| | | } |
| | | if (workOrder.SQL_UsingNow == "Y")//即产即用 |
| | | //先查询货位有没有货 满的下满 空的则上空 |
| | | // = newDb.Queryable<Location>().FindAll(x => x.S_LOCK_STATE == "无" && x.N_CURRENT_NUM == 0); |
| | | var hojs = newDb.Queryable<Location>().Where(e => e.S_LOC_CODE == location).First(); |
| | | if (hojs != null && hojs.S_LOCK_STATE != "无") |
| | | { |
| | | //查询 半成品区域表 BcpQyOrder |
| | | |
| | | return false; |
| | | } |
| | | else//非即产即用 |
| | | var bcpList = WCSHelper.BcpQyOrderList(plc.deviceName); |
| | | if (bcpList.Count() == 0) |
| | | { |
| | | |
| | | throw new Exception("未划分对应的区域 查看这个产线是否在半成品区域表进行配置 并启用"); |
| | | } |
| | | if (endBit != null) |
| | | if (hojs.N_CURRENT_NUM == 0)//上托盘 否则下托盘 |
| | | { |
| | | var _ctrl = LocationHelper.GetLocCntrRel(location); |
| | | int endLayer = endBit.N_CURRENT_NUM + 1; |
| | | var carryCntrs = new List<string> { _ctrl.FirstOrDefault().S_CNTR_CODE };//DateTime.Now.ToString("yyMMddHHmmss") }; |
| | | var bb = TaskProcess.CreateTransport(workOrder.SQL_WorkNo, location, endBit.S_LOC_CODE, "满瓶坯-入库", carryCntrs, 1, endLayer, carryCntrs.Count, plc.taskPri); |
| | | //上托盘 空框 |
| | | var jcjykk = bcpList.FindAll(e => e.S_CNTR_TYPE == "空托").OrderByDescending(g => g.N_PRI).ToList(); |
| | | var AreaList = jcjykk.Select(e => e.S_AREA_CODE).Distinct().ToList(); |
| | | foreach (var Area in AreaList) |
| | | { |
| | | var Row = jcjykk.FindAll(f => f.S_AREA_CODE == Area).Select(e => e.N_ROW).Distinct().ToList(); |
| | | //过算法 计算起点 |
| | | var staList = GetOutWork(Area, Row); |
| | | if (staList.Any()) |
| | | { |
| | | foreach (var item in jcjykk) |
| | | { |
| | | Location sta = null; |
| | | var staLisL = staList.FindAll(e => e.S_AREA_CODE == item.S_AREA_CODE && e.N_ROW == item.N_ROW).ToList(); |
| | | if (staLisL.Any()) |
| | | { |
| | | sta = staLisL.OrderByDescending(e => e.N_COL).First(); |
| | | } |
| | | if (sta != null) |
| | | { |
| | | staBit = sta; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | if (staBit != null) |
| | | { |
| | | var _ctrl = LocationHelper.GetLocCntrRel(staBit.S_LOC_CODE); |
| | | int StaLayer = staBit.N_CURRENT_NUM; |
| | | var carryCntrs = new List<string> { _ctrl.FirstOrDefault().S_CNTR_CODE };//DateTime.Now.ToString("yyMMddHHmmss") }; |
| | | var bb = TaskProcess.CreateTransport(workOrder.SQL_WorkNo, staBit.S_LOC_CODE, location, "注塑空拖-出库", carryCntrs, StaLayer, 1, carryCntrs.Count, plc.taskPri); |
| | | if (bb) |
| | | { |
| | | SentTask = true; |
| | | } |
| | | } |
| | | if (SentTask) |
| | | { |
| | | return SentTask; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | var time = LocationHelper.GetT_FULL_TIME(location); |
| | | LogHelper.Info(location + ":托盘放置时间:(" + time + ") 货位托盘数量(" + hojs.N_CURRENT_NUM + ")"); |
| | | if (DateTime.Now.Subtract(time ?? DateTime.Now).TotalMinutes < 1) |
| | | { |
| | | for (var i = 0; i < plc.location.Length; i++) |
| | | { |
| | | if (location == plc.location[i]) |
| | | { |
| | | PlcHelper.SendHex(plc.address, "3F00" + (i + 1) + "0" + "0d0a"); |
| | | break; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | LocCntrRel _clrel = LocationHelper.GetLocCntrRel(hojs.S_LOC_CODE).FirstOrDefault(); |
| | | //上托盘 满框 |
| | | var jcjykk = bcpList.FindAll(e => e.S_CNTR_TYPE == "满托").OrderByDescending(g => g.N_PRI).ToList(); |
| | | var AreaList = jcjykk.Select(e => e.S_AREA_CODE).Distinct().ToList(); |
| | | |
| | | //过算法 计算起点 |
| | | foreach (var Area in AreaList) |
| | | { |
| | | var Row = jcjykk.Select(e => e.N_ROW).Distinct().ToList(); |
| | | |
| | | |
| | | |
| | | var EndList = GetInWork(Area, Row, true, workOrder.SQL_ItemCode); |
| | | if (EndList.Any()) |
| | | { |
| | | foreach (var item in jcjykk) |
| | | { |
| | | Location End = null; |
| | | var EndListT = EndList.FindAll(e => e.S_AREA_CODE == item.S_AREA_CODE && e.N_ROW == item.N_ROW).ToList(); |
| | | if (EndListT.Count() > 0) |
| | | { |
| | | End = EndListT.OrderBy(e => e.N_COL).First(); |
| | | } |
| | | if (End != null) |
| | | { |
| | | endBit = End; |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | if (endBit != null) |
| | | { |
| | | var _ctrl = LocationHelper.GetLocCntrRel(location); |
| | | List<CntrItemRel> RItem = new List<CntrItemRel>(); |
| | | foreach (var item in _ctrl) |
| | | { |
| | | |
| | | var r = new CntrItemRel |
| | | { |
| | | S_CNTR_CODE = item.S_CNTR_CODE, |
| | | S_ITEM_CODE = workOrder.SQL_ItemCode, |
| | | S_ITEM_NAME = workOrder.SQL_ItemName, |
| | | F_QTY = workOrder.SQL_UsingNowTotal, |
| | | S_ORDER_NO = workOrder.SQL_WorkNo, |
| | | S_BATCH_NO = workOrder.SQL_BatchNo |
| | | }; |
| | | RItem.Add(r); |
| | | var cntrrel = ContainerHelper.GetCntrItemRel(item.S_CNTR_CODE).FirstOrDefault(); |
| | | if (cntrrel != null) |
| | | { |
| | | newDb.Deleteable<CntrItemRel>().Where(it => it.S_ID.Trim() == cntrrel.S_ID.Trim()).ExecuteCommand(); |
| | | } |
| | | } |
| | | var ggf = newDb.Insertable(RItem).ExecuteCommand(); |
| | | if (ggf > 0) |
| | | { |
| | | int endLayer = endBit.N_CURRENT_NUM + 1; |
| | | var carryCntrs = new List<string> { _ctrl.FirstOrDefault().S_CNTR_CODE };//DateTime.Now.ToString("yyMMddHHmmss") }; |
| | | var bb = TaskProcess.CreateTransport(workOrder.SQL_WorkNo, location, endBit.S_LOC_CODE, "注塑满托-入库", carryCntrs, 1, endLayer, carryCntrs.Count, plc.taskPri); |
| | | if (bb) |
| | | { |
| | | SentTask = true; |
| | | //触发自动解绑 |
| | | //var zdjb = jcjykk.FindAll(e => e.SQL_UsingNow == "Y").OrderByDescending(g => g.N_PRI).ToList(); |
| | | //foreach (var item in zdjb) |
| | | //{ |
| | | |
| | | //} |
| | | //var Jb = newDb.Queryable<Location>().Where(e => e.S_AREA_CODE == Area && Row.Contains(e.N_ROW)).ToList(); |
| | | ////查询第一排是否满 并且第二排入满三个后解绑第一排 |
| | | ////1.查询第一排是否有空货位 有 则跳过 |
| | | } |
| | | } |
| | | } |
| | | if (SentTask) |
| | | { |
| | | return SentTask; |
| | | } |
| | | |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 瓶坯算法--出库 |
| | | /// </summary> |
| | | /// <param name="AreaCode"></param> |
| | | /// <param name="Row"></param> |
| | | /// <param name="ItemCode"></param> |
| | | /// <returns></returns> |
| | | public static List<Location> GetOutWork(string AreaCode, List<int> Row, bool InOutLock = true, string ItemCode = "") |
| | | { |
| | | var lstCanOutL = new List<Location>(); |
| | | try |
| | | { |
| | | var chi = new SqlHelper<object>().GetInstance(); |
| | | var newDb = chi.CopyNew(); |
| | | var ca = Expressionable.Create<Location, LocCntrRel, CntrItemRel>(); |
| | | if (string.IsNullOrEmpty(ItemCode))//算空托 |
| | | { |
| | | ca.And((o, p, t) => o.N_CURRENT_NUM > 0 && o.S_LOCK_STATE == "无" && string.IsNullOrEmpty(t.S_ITEM_CODE) && o.S_AREA_CODE == AreaCode); |
| | | ca.AndIF(Row.Count() > 0, (o, p, t) => Row.Contains(o.N_ROW)); |
| | | lstCanOutL = newDb.Queryable<Location>().InnerJoin<LocCntrRel>((o, p) => o.S_LOC_CODE == p.S_LOC_CODE).LeftJoin<CntrItemRel>((o, p, t) => p.S_CNTR_CODE == t.S_CNTR_CODE).Where(ca.ToExpression()).ToList(); |
| | | } |
| | | else//算满托 |
| | | { |
| | | ca.And((o, p, t) => o.N_CURRENT_NUM > 0 && o.S_LOCK_STATE == "无" && t.S_ITEM_CODE == ItemCode && o.S_AREA_CODE == AreaCode); |
| | | ca.AndIF(Row.Count() > 0, (o, p, t) => Row.Contains(o.N_ROW)); |
| | | lstCanOutL = newDb.Queryable<Location>().InnerJoin<LocCntrRel>((o, p) => o.S_LOC_CODE == p.S_LOC_CODE).InnerJoin<CntrItemRel>((o, p, t) => p.S_CNTR_CODE == t.S_CNTR_CODE).Where(ca.ToExpression()).ToList(); |
| | | } |
| | | //地堆专门算法过滤 |
| | | if (lstCanOutL.Count() > 0) |
| | | { |
| | | var Inloca = Expressionable.Create<Location>(); |
| | | Inloca.And(it => it.S_AREA_CODE == AreaCode); |
| | | Inloca.AndIF(Row.Count() > 0, o => Row.Contains(o.N_ROW)); |
| | | var locationInLock = newDb.Queryable<Location>().Where(Inloca.ToExpression()).ToList(); |
| | | //空间锁 排除一整排 |
| | | var KjLick = locationInLock.FindAll(e => e.S_LOCK_STATE == "空间锁").ToList(); |
| | | if (KjLick.Count() > 0) |
| | | { |
| | | foreach (var item in KjLick) |
| | | { |
| | | lstCanOutL.RemoveAll(e => e.S_AREA_CODE == item.S_AREA_CODE && e.N_ROW == item.N_ROW); |
| | | } |
| | | } |
| | | if (InOutLock) |
| | | { |
| | | var CkLick = locationInLock.FindAll(e => e.S_LOCK_STATE == "出库锁").ToList(); |
| | | if (CkLick.Count() > 0) |
| | | { |
| | | foreach (var item in CkLick) |
| | | { |
| | | lstCanOutL.RemoveAll(e => e.S_AREA_CODE == item.S_AREA_CODE && e.N_ROW == item.N_ROW); |
| | | } |
| | | } |
| | | var OutLick = locationInLock.FindAll(e => e.S_LOCK_STATE == "入库锁").ToList(); |
| | | if (OutLick.Count() > 0) |
| | | { |
| | | foreach (var item in OutLick) |
| | | { |
| | | lstCanOutL.RemoveAll(e => e.S_AREA_CODE == item.S_AREA_CODE && e.N_ROW == item.N_ROW); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
| | | return lstCanOutL; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | LogHelper.Info("瓶坯算法" + $" 报错: {ex.Message}"); |
| | | return lstCanOutL; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 瓶坯算法--入库 |
| | | /// </summary> |
| | | /// <param name="AreaCode"></param> |
| | | /// <param name="Row"></param> |
| | | /// <param name="ItemCode"></param> |
| | | /// <returns></returns> |
| | | public static List<Location> GetInWork(string AreaCode, List<int> Row, bool InOutLock = true, string ItemCode = "") |
| | | { |
| | | var lstCanOutL = new List<Location>(); |
| | | try |
| | | { |
| | | lock (lockoIn) |
| | | { |
| | | var chi = new SqlHelper<object>().GetInstance(); |
| | | var newDb = chi.CopyNew(); |
| | | var ca = Expressionable.Create<Location, LocCntrRel, CntrItemRel>(); |
| | | ca.And((o, p, t) => o.N_CURRENT_NUM == 0 && o.S_LOCK_STATE == "无" && string.IsNullOrEmpty(p.S_CNTR_CODE) && string.IsNullOrEmpty(t.S_ITEM_CODE) && o.S_AREA_CODE == AreaCode); |
| | | ca.AndIF(Row.Count() > 0, (o, p, t) => Row.Contains(o.N_ROW)); |
| | | lstCanOutL = newDb.Queryable<Location>().LeftJoin<LocCntrRel>((o, p) => o.S_LOC_CODE == p.S_LOC_CODE).LeftJoin<CntrItemRel>((o, p, t) => p.S_CNTR_CODE == t.S_CNTR_CODE).Where(ca.ToExpression()).ToList(); |
| | | |
| | | var Inloca = Expressionable.Create<Location>(); |
| | | Inloca.And(it => it.S_AREA_CODE == AreaCode); |
| | | Inloca.AndIF(Row.Count() > 0, o => Row.Contains(o.N_ROW)); |
| | | var locationInLock = newDb.Queryable<Location>().Where(Inloca.ToExpression()).ToList(); |
| | | |
| | | //地堆专门算法过滤 |
| | | if (lstCanOutL.Count() > 0) |
| | | { |
| | | //空间锁 排除一整排 |
| | | var KjLick = locationInLock.FindAll(e => e.S_LOCK_STATE == "空间锁").ToList(); |
| | | if (KjLick.Count() > 0) |
| | | { |
| | | foreach (var item in KjLick) |
| | | { |
| | | lstCanOutL.RemoveAll(e => e.S_AREA_CODE == item.S_AREA_CODE && e.N_ROW == item.N_ROW); |
| | | } |
| | | } |
| | | |
| | | //获取指定库区 指定排 满的货位 然后排除 比最大列还小的空货位 |
| | | var Mhw = locationInLock.FindAll(e => e.N_CURRENT_NUM > 0).ToList(); |
| | | if (Mhw.Count() > 0) |
| | | { |
| | | var RowLis = Mhw.GroupBy(e => e.N_ROW).Select(f => f.First()).ToList(); |
| | | foreach (var item in RowLis) |
| | | { |
| | | var MaxCol = Mhw.FindAll(e => e.N_ROW == item.N_ROW).OrderByDescending(c => c.N_COL).FirstOrDefault(); |
| | | if (MaxCol != null) |
| | | { |
| | | lstCanOutL.RemoveAll(e => e.S_AREA_CODE == item.S_AREA_CODE && e.N_ROW == item.N_ROW && e.N_COL < MaxCol.N_COL); |
| | | } |
| | | } |
| | | |
| | | //排除别的物料所在的排 |
| | | if (!string.IsNullOrEmpty(ItemCode)) |
| | | { |
| | | var fzRow = Mhw.Select(e => e.N_ROW).Distinct().ToList(); |
| | | foreach (var item in fzRow) |
| | | { |
| | | var mtlo = Mhw.FindAll(e => e.N_ROW == item).FirstOrDefault(); |
| | | if (mtlo != null) |
| | | { |
| | | var _clrel = LocationHelper.GetLocCntrRel(mtlo.S_LOC_CODE).FirstOrDefault(); |
| | | if (_clrel != null) |
| | | { |
| | | var cntritems = ContainerHelper.GetCntrItemRel(_clrel.S_CNTR_CODE).FirstOrDefault(); |
| | | if (cntritems != null) |
| | | { |
| | | if (cntritems.S_ITEM_CODE != ItemCode) |
| | | { |
| | | lstCanOutL.RemoveAll(e => e.S_AREA_CODE == mtlo.S_AREA_CODE && e.N_ROW == mtlo.N_ROW); |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
| | | } |
| | | } |
| | | if (InOutLock) |
| | | { |
| | | var CkLick = locationInLock.FindAll(e => e.S_LOCK_STATE == "出库锁").ToList(); |
| | | if (KjLick.Count() > 0) |
| | | { |
| | | foreach (var item in KjLick) |
| | | { |
| | | lstCanOutL.RemoveAll(e => e.S_AREA_CODE == item.S_AREA_CODE && e.N_ROW == item.N_ROW); |
| | | } |
| | | } |
| | | var OutLick = locationInLock.FindAll(e => e.S_LOCK_STATE == "入库锁").ToList(); |
| | | if (KjLick.Count() > 0) |
| | | { |
| | | foreach (var item in KjLick) |
| | | { |
| | | lstCanOutL.RemoveAll(e => e.S_AREA_CODE == item.S_AREA_CODE && e.N_ROW == item.N_ROW); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return lstCanOutL; |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | LogHelper.Info("瓶坯算法" + $" 报错: {ex.Message}"); |
| | | return lstCanOutL; |
| | | } |
| | | } |
| | | |
| | | |
| | | //瓶坯满入库 |
| | | static bool BottlePEMInfoFull(Settings.deviceInfo plc, string location) |