using CentralControl.BaseData; using CentralControl.DBDAO; using CommonFunc; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using XGL.Thrift; namespace CentralControl.App_Code { /// /// 出库暂存点逻辑 /// public class Logic4001_4002OutLocator { Thread InputMaterialThread; PlcHelper plcHelper; string LineNo { get; set; } NodeSetting ScanPoint { get; set; } bool outLocatorlock = true; /// /// 2号上件点 空车信号 /// NodeSetting emptyCarLocatorPoint { get; set; } public Logic4001_4002OutLocator(PlcHelper plc, string siteno) { try { this.ScanPoint = StaticData.NodeSettingList.FirstOrDefault(t => t.NodeNo == siteno); //IsRuning = true; if (this.ScanPoint != null) { this.LineNo = this.ScanPoint.LineCatchArea != null ? this.ScanPoint.LineCatchArea.LineNo : "1"; } else { Logger logger = new Logger(); logger.Log("创建线体,未找到扫描点位"); } this.LineNo = LineNo; this.plcHelper = plc; //默认启动,清理plc的库位出库位置 this.plcHelper.Write(this.ScanPoint.PlcSetting1, 0); } catch (Exception ex) { Console.WriteLine("站点" + siteno + " 初始化数据异常" + ex.Message); Logger logger = new Logger(); logger.Error("站点" + siteno + " 初始化数据异常" + ex.Message); } } /// /// 启动上件扫描监听 /// public void StartPoint() { InputMaterialThread = new Thread(MonitorInLocatorPoint); InputMaterialThread.Start(); } /// /// 出库暂存点 /// /// /// public void MonitorInLocatorPoint() { Logger logger = new Logger(); while (true) { try { //出库位置号 object outlocatorno = this.plcHelper.Read(this.ScanPoint.PlcSetting1); //出库完成状态 object outlocatorstate = this.plcHelper.Read(this.ScanPoint.PlcSetting2); //对立库区是否有空车 object locatorlock = this.plcHelper.Read(this.ScanPoint.PlcSetting3); //if (!IsRuning) //{ ///读取小车号 //查找符合条件的小车,,根据出库队列查找 OffLineMaterialList offmaterialnew = null; CarRealInfo preoffcar = null; // if (Convert.ToInt32(outlocatorno) == 0) if (Convert.ToInt32(outlocatorstate) == 0 && Convert.ToInt32(outlocatorno) == 0) { //int isoutCarNumber = StaticData.CarRealList.Where(t => t.IsProOutLocator == 1).Count(); //if (isoutCarNumber < 40) //{ //手动设置出库或者拉回 , 进入下件点 IsProOutLocator>0; 1 下件 ,2 拉回 preoffcar = StaticData.CarRealList.OrderBy(t => t.OutLocatorDt).FirstOrDefault(t => t.IsProOutLocator > 0 && t.IsOutLocator == 0 && t.IsOver == 0 && t.LocatorArea != null && t.LocatorArea.AreaType == 4 && t.LocatorArea.LineNo == this.LineNo); CarRealInfo LocatorCar = null; //重新启动之后,或者手动指定出库 if (preoffcar != null) { //preoffcar.OffMaterialId = 0; } else { lock (StaticData.offMaterialCarLock) { //调度出库指令 offmaterialnew = StaticData.OffMaterialList.FirstOrDefault(t => t.Number > 0 && t.IsOver == 0); if (offmaterialnew != null) { logger.Log("当前扫描物料码:" + offmaterialnew.MaterialNo + " " + offmaterialnew.MaterialDes + " " + offmaterialnew.ProductBarNo); CarRealInfo outcars = null; lock (StaticData.OutLocatorCarLock) { //再匹配库区内的安排出库 var Locators = StaticData.CarRealList.Where(t => t.LoadingProduct != null && t.LoadingProduct.FirstOrDefault(p => p.productNo == offmaterialnew.MaterialNo) != null && t.HadNumber > 0 && t.IsOutLocator == 0 && t.LocatorId > 0 && t.IsProOutLocator == 0 && t.LocatorArea != null && t.LocatorArea.AreaType == 4 && this.LineNo == t.LocatorArea.LineNo).GroupBy(t => t.LocatorId).Select(g => g.OrderBy(f => g.Count())).OrderBy(t => t.Count()).FirstOrDefault(); preoffcar = Locators == null ? null : Locators.OrderBy(t => t.OptDt).FirstOrDefault(); if (preoffcar != null) { offmaterialnew.Number -= 1; offmaterialnew.CarCode = preoffcar.CarNo; preoffcar.IsProOutLocator = 1; preoffcar.HadNumber -= 1; DBService.UpdateOffLineMaterialList(offmaterialnew); //记录第一个匹配到小车的物料 号, 用于判定下一个物料和上一个是否相同 ,如果相同则算同一个车出库 // StaticData.Last_scanMaterial = preoffcar.MaterialNo; // DBService.SetSystemConfigItem("last_scanmaterial", StaticData.Last_scanMaterial); } // } //出库队列如果在库位内没有找到匹配,自动算作放弃,匹配下一个 if (outcars == null && preoffcar == null) { logger.Log("[" + this.LineNo + "]号库区没有匹配到响应的库区物料信息" + offmaterialnew.MaterialNo + " " + offmaterialnew.MaterialDes + " " + offmaterialnew.ProductBarNo); if (this.LineNo == "1") { offmaterialnew.LeftNoData = 1; } else { offmaterialnew.RightNoData = 1; } if (offmaterialnew.LeftNoData == 1 && offmaterialnew.RightNoData == 1) { logger.Log("两个库区都没有找到匹配的该物料,该出库箱体作废"); offmaterialnew.IsOver = 1; } DBService.UpdateOffLineMaterialList(offmaterialnew); } } } } } if (preoffcar != null) { //取当前和找到小车同一个库位的小车队列,第一个 ,判定是否是预备出库小车, ,直到找到为止 LocatorCar = StaticData.CarRealList.OrderBy(t => t.OptDt).FirstOrDefault(t => t.LocatorId == preoffcar.LocatorId && t.IsOutLocator == 0 && t.LocatorArea != null && t.LocatorArea.AreaType == 4 && t.LocatorArea.LineNo == this.LineNo); if (LocatorCar != null) { ////是要准备出的小车,正常出库的小车 if (LocatorCar.CarNo == preoffcar.CarNo) { logger.Log(" 当前出库小车相同:" + LocatorCar.CarNo + " 预设出库小车" + preoffcar.CarNo); LocatorCar.HadNumber = preoffcar.HadNumber; LocatorCar.IsProOutLocator = preoffcar.IsProOutLocator; //LocatorCar.OffMaterialId = offmaterialnew == null ? 0 : offmaterialnew.Id; } else//挡在要出库前面的那些个小车 { logger.Log(" 当前出库小车不同:" + LocatorCar.CarNo + " 预设出库小车" + preoffcar.CarNo); LocatorCar.IsProOutLocator = 2; LocatorCar.OffMaterialId = 0; } } } //如果没有需要出库的库位小车,就出一个空车 ,如果当前是2号库区,则判定 1003的小车空车数量不足,,进行叫空车 if (LocatorCar == null) { //上件点呼叫空车预存,,2号等需要呼叫的时候,才放空车, 1号库区,有机会就放 bool isOutCar = false; //if (this.LineNo == "1") //{ // object needState1 = this.plcHelper.Read(this.otherLocatorPoint1.PlcSetting3); // object needState2 = this.plcHelper.Read(this.otherLocatorPoint2.PlcSetting3); var areaemp = StaticData.CarRealList.Count(t => t.LocatorArea != null && t.LocatorArea.LineNo == this.LineNo && t.LocatorArea.AreaType == 4 && t.LoadingMaterial.Count <= 0); if (areaemp > 0) { isOutCar = true; } if (isOutCar) { // //根据库位分组, 获取空车数量最少的库位 var Locators = StaticData.CarRealList.Where(t => t.LoadingMaterial.Count <= 0 && t.IsOutLocator == 0 && t.LocatorId > 0 && t.LocatorArea != null && t.LocatorArea.AreaType == 4 && t.LocatorArea.LineNo == this.LineNo).GroupBy(t => t.LocatorId).Select(g => g.OrderBy(f => g.Count())).OrderBy(t => t.Count()).FirstOrDefault(); var empoutCar = Locators != null ? Locators.OrderBy(t => t.OptDt).FirstOrDefault() : null; if (empoutCar != null) { LocatorCar = StaticData.CarRealList.OrderBy(t => t.OptDt).FirstOrDefault(t => t.LocatorId == empoutCar.LocatorId && t.IsOver == 0 && t.IsOutLocator == 0 && t.LocatorArea != null && t.LocatorArea.LineNo == this.LineNo); if (LocatorCar != null) { ////是要准备出的小车,正常出库的小车 if (LocatorCar.CarNo == empoutCar.CarNo) { LocatorCar.IsProOutLocator = 0; LocatorCar.OffMaterialId = 0; } else//挡在要出库前面的那些个小车 { LocatorCar.IsProOutLocator = 2; LocatorCar.OffMaterialId = 0; } } } } } //有需要出库的 库位小车 if (LocatorCar != null) { DBService.AddSystemLog(LocatorCar.LocatorArea.AreaNo, LocatorCar); //同时库区 ,同一时间,只有一个 isOutLocator 正在出库的小车 logger.Log(this.LineNo + "安排出库小车号" + LocatorCar.CarNo + "携带物料[" + LocatorCar.MaterialNo + ",状态:" + LocatorCar.IsProOutLocator + ",进行库位:" + LocatorCar.LocatorArea.AreaNo + "]"); LocatorCar.IsOutLocator = 1; LocatorCar.IsOver = 0; LocatorCar.OutLocatorDt = DateTime.Now; DBService.ModifyRealCarinfoRecord(LocatorCar); ///如果当前是最后一个小车 ,清空物料设定的规格 int locatornumber = StaticData.CarRealList.Count(t => t.LocatorId == LocatorCar.LocatorId & t.IsOutLocator == 0); if (locatornumber <= 0) { LocatorCar.LocatorArea.MaterialNo = ""; DBService.SetLocatorMaterial(LocatorCar.LocatorId, "", ""); } this.plcHelper.Write(this.ScanPoint.PlcSetting1, LocatorCar.LocatorArea.AreaNo); //IsRuning = false; DBService.AddSystemLog(LocatorCar.LocatorArea.AreaNo, LocatorCar); logger.Log("node:" + this.ScanPoint.NodeNo + " plc:" + this.ScanPoint.PlcSetting4.PlcNo + " mu:" + LocatorCar.LocatorArea.AreaNo); } //} //else //{ // logger.Log("待出库小车数量超过40台,暂停出库"); //} } else if (Convert.ToInt32(outlocatorstate) == 1 && Convert.ToInt32(outlocatorno) > 0) { this.plcHelper.Write(this.ScanPoint.PlcSetting1, 0); logger.Log("出库操作点编号清理"); //IsRuning = true; } } catch (Exception ex) { logger.Error("Logic1003OutLocator异常:" + this.ScanPoint.NodeNo + " :" + ex.Message + ex.StackTrace); } Thread.Sleep(2000); } } } }