using Azure.Identity; using Khd.Core.Domain.Models; using Khd.Core.EntityFramework; using Khd.Core.Library.Mapper; using Khd.Core.Plc.S7; using Khd.Core.Wcs.Global; using Masuit.Tools.Logging; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Z.EntityFramework.Plus; namespace Khd.Core.Wcs.Wcs { /// /// 二楼小包出入口 /// public class SecondFloorLine { private readonly IHost _host; int FloorNo { get; set; } public SecondFloorLine(IHost host, Plc.S7.Plc plc, int floor) { this._host = host; FloorNo = floor; } /// /// 启动上件扫描监听 /// public void StartPoint() { Thread FlowPointThread = new Thread(MonitorInLocatorPoint); FlowPointThread.Start(); Console.WriteLine(DateTime.Now + ":二楼码垛输送线调度启动成功"); LogManager.Info("二楼码垛输送线调度启动成功"); } public void MonitorInLocatorPoint() { using var scope = _host.Services.CreateScope(); using var dbContext = scope.ServiceProvider.GetRequiredService(); var rfidPoint = StaticData.BasePlcpointList.First(t => t.id == 52); var agvGetPoint = StaticData.BasePlcpointList.First(t => t.id == 53); var agvPutPoint = StaticData.BasePlcpointList.First(t => t.id == 54); BaseEquip agvEquip = StaticData.BaseEquip.First(t => t.objid == 8); BaseEquip endEquip = StaticData.BaseEquip.First(t => t.objid == 36); while (true) { try { dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload()); var agvPutValue = StaticData.PlcDic[2].Read(agvPutPoint.plcpointAddress);//小包入口叫料 var agvGetValue = StaticData.PlcDic[2].Read(agvGetPoint.plcpointAddress);//小包出口的到位 var rfidValue = StaticData.PlcDic[2].ReadRFID(rfidPoint.plcpointAddress);//小包出口的RFID if (agvGetValue != null && agvPutValue != null && rfidValue != null)//读Plc { if (Convert.ToInt32(agvPutValue) == 0)//小包入口叫料 { bool canCreate = dbContext.WcsTask.Where(t => t.nextPointId == 8 || t.endPointId == endEquip.objid).Any();//有没有生成任务 //36 是小包入口的设备信息,8是二楼Agv设备 if (!canCreate)//没有任务 { BaseEquip? baseEquip = dbContext.BaseEquip.FirstOrDefault(t => t.equipType == 20 && t.emptyCount >= 1);//二楼周转区是否存在一个空托盘以上的 if (baseEquip != null)//二楼周转区有可以去小包入口的库位 { var wcsTask = new WcsTask() { objid = StaticData.SnowId.NextId(), endPointId = endEquip.objid,//小包入口 endPointNo = endEquip.equipNo, nextPointId = agvEquip.objid,//二楼叉车 nextPointNo = agvEquip.equipNo, currPointId = baseEquip.objid,//周转区库位 currPointNo = baseEquip.equipNo, taskStatus = 0, useFlag = 1, containerNo = null, createBy = "WCS", createTime = DateTime.Now, floorNo = 2, fromFloorNo = 2, isEmpty = "1", qty = baseEquip.emptyCount,//托盘的数量 taskType = 59,//任务类型 }; dbContext.Add(wcsTask); WcsTaskLog wcsTaskLog = CoreMapper.Map(wcsTask); dbContext.Add(wcsTaskLog); dbContext.SaveChanges(); Console.WriteLine(DateTime.Now + ":二楼码垛输送线生成请求空托盘任务成功:" + wcsTask.objid); LogManager.Info("二楼码垛输送线生成请求空托盘任务成功:" + wcsTask.objid); } else//二楼周转区没有空托盘 { baseEquip = dbContext.BaseEquip.FirstOrDefault(t => t.equipType == 15 && t.emptyCount == SystemData.maxTray && t.equipStatus == 1);//三楼三个周转区是否存在空托盘 if (baseEquip != null)//如果三楼有空托盘 { BaseEquip ThirdLineEquip = dbContext.BaseEquip.First(t => t.objid == 3);//三楼接驳位 BaseEquip ThirdAgvEquip = StaticData.BaseEquip.First(t => t.objid == 9);//三楼叉车 if (ThirdLineEquip.equipStatus == 0)//三楼接驳位空闲 { //生成3楼Agv出库任务 WcsTask wcsTask = new WcsTask() { objid = StaticData.SnowId.NextId(), containerNo = null, createBy = "WCS", createTime = DateTime.Now, floorNo = 2, fromFloorNo = 3, isEmpty = "1", qty = SystemData.maxTray, taskType = 101, currPointId = baseEquip.objid, currPointNo = baseEquip.equipNo, nextPointId = ThirdAgvEquip.objid, nextPointNo = ThirdAgvEquip.equipNo, endPointId = endEquip.objid, endPointNo = endEquip.equipNo, taskStatus = 0, useFlag = 1, }; dbContext.Add(wcsTask); WcsTaskLog wcsTaskLog = CoreMapper.Map(wcsTask); dbContext.Add(wcsTaskLog); dbContext.SaveChanges(); Console.WriteLine(DateTime.Now + ":二楼码垛输送线生成3楼Agv出库任务成功:" + wcsTask.objid); LogManager.Info("二楼码垛输送线生成3楼Agv出库任务成功:" + wcsTask.objid); } } else { BaseEquip startEquip = dbContext.BaseEquip.First(t => t.objid == 40);//一楼的托盘库 if (startEquip.emptyCount > 1 && startEquip.emptyCount <= SystemData.maxTray) { BasePlcpoint basePlcpoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "someOut");//多个出 BasePlcpoint linesignal01 = StaticData.BasePlcpointList.First(t => t.plcpointNo == "linesignal01");//一楼接驳位到位 BasePlcpoint equipstate06 = StaticData.BasePlcpointList.First(t => t.plcpointNo == "equipstate06");//提升机状态 BaseEquip lineEquip = dbContext.BaseEquip.First(t => t.objid == 1);//一楼接驳位 var lineSignal01Value = StaticData.PlcDic[0].Read(linesignal01.plcpointAddress); var equipstate06Value = StaticData.PlcDic[0].Read(equipstate06.plcpointAddress); if (FirstFloor.ReadEmptyLocation() && Convert.ToInt32(lineSignal01Value) == 0 && Convert.ToInt32(equipstate06Value) == 0) { StaticData.PlcDic[0].WriteToPoint(basePlcpoint.plcpointAddress, "1", basePlcpoint.plcpointLength.ToString());//托盘库多个出 WcsTask wcsTaskManual = new WcsTask() { objid = StaticData.SnowId.NextId(), endPointId = endEquip.objid, endPointNo = endEquip.equipNo, nextPointId = lineEquip.objid, nextPointNo = lineEquip.equipNo, currPointId = lineEquip.objid, currPointNo = lineEquip.equipNo, taskStatus = 0, useFlag = 1, containerNo = null, createBy = "WCS", createTime = DateTime.Now, floorNo = endEquip.floorNo, fromFloorNo = 1, isEmpty = "1", qty = startEquip.emptyCount, taskType = 53, }; dbContext.Add(wcsTaskManual); WcsTaskLog wcsTaskLog = CoreMapper.Map(wcsTaskManual); dbContext.Add(wcsTaskLog); dbContext.SaveChanges(); Console.WriteLine(DateTime.Now + ":二楼码垛输送线生成手动托盘任务成功:" + wcsTaskManual.objid); LogManager.Info("二楼码垛输送线生成手动托盘任务成功:" + wcsTaskManual.objid); } } else if (startEquip.emptyCount > SystemData.maxTray)//如果托盘库大于五个,出一个 { BasePlcpoint basePlcpoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "oneOut");//多个出 BasePlcpoint linesignal01 = StaticData.BasePlcpointList.First(t => t.plcpointNo == "linesignal01");//一楼接驳位到位 BasePlcpoint equipstate06 = StaticData.BasePlcpointList.First(t => t.plcpointNo == "equipstate06");//提升机状态 BaseEquip lineEquip = dbContext.BaseEquip.First(t => t.objid == 1);//一楼接驳位 var lineSignal01Value = StaticData.PlcDic[0].Read(linesignal01.plcpointAddress); var equipstate06Value = StaticData.PlcDic[0].Read(equipstate06.plcpointAddress); if (FirstFloor.ReadEmptyLocation() && Convert.ToInt32(lineSignal01Value) == 0 && Convert.ToInt32(equipstate06Value) == 0) { StaticData.PlcDic[0].WriteToPoint(basePlcpoint.plcpointAddress, "1", basePlcpoint.plcpointLength.ToString());//托盘库多个出 WcsTask wcsTaskManual = new WcsTask() { objid = StaticData.SnowId.NextId(), endPointId = endEquip.objid, endPointNo = endEquip.equipNo, nextPointId = lineEquip.objid, nextPointNo = lineEquip.equipNo, currPointId = lineEquip.objid, currPointNo = lineEquip.equipNo, taskStatus = 0, useFlag = 1, containerNo = null, createBy = "WCS", createTime = DateTime.Now, floorNo = endEquip.floorNo, fromFloorNo = 1, isEmpty = "1", qty = 1, taskType = 53, }; dbContext.Add(wcsTaskManual); WcsTaskLog wcsTaskLog = CoreMapper.Map(wcsTaskManual); dbContext.Add(wcsTaskLog); dbContext.SaveChanges(); Console.WriteLine(DateTime.Now + ":二楼码垛输送线生成手动托盘任务成功:" + wcsTaskManual.objid); LogManager.Info("二楼码垛输送线生成手动托盘任务成功:" + wcsTaskManual.objid); } } else { //todo:没有空托盘 Console.WriteLine(DateTime.Now + ":二楼码垛输送线没有空托盘"); LogManager.Info("二楼码垛输送线没有空托盘"); } } } } } if (Convert.ToInt32(agvGetValue) == 1 && !string.IsNullOrEmpty(rfidValue))//小包出口成品入口 { MesBasePalletInfo? mesBasePalletInfo = dbContext.MesBasePalletInfo.FirstOrDefault(t => t.palletInfoCode == rfidValue); if (mesBasePalletInfo != null) { MesBaseBarcodeInfo? mesBaseBarcodeInfo = dbContext.MesBaseBarcodeInfo.FirstOrDefault(t => t.barcodeInfo == mesBasePalletInfo.materialBarcode); if (mesBaseBarcodeInfo != null) { var wmsBaseLocations = dbContext.WmsBaseLocation .Where(t => t.warehouseFloor == FloorNo) .Where(t => t.activeFlag == "1") .Where(t => t.delFlag == "0") .Where(t => t.locationScrapType == "1") .Where(t => t.locationStatus == "1") .Where(t => t.warehouseId == 231) .ToList();//所有可用库位 var wmsProductStocks = dbContext.WmsProductStock .Where(t => t.warehouseId == 231) .ToList();//仓库的库存 WmsBaseLocation? wmsBaseLocation = null; if (wmsBaseLocations.Count > 0) { List containerCodes = wmsBaseLocations .Where(t => t.locDeep == 1) .Select(t => t.containerCode).ToList();//深库位的有托盘 List mesBasePalletInfos = dbContext.MesBaseBarcodeInfo .Where(t => t.saleOrderId == mesBaseBarcodeInfo.saleOrderId)//销售订单 .Where(t => t.materialId == mesBasePalletInfo.materialId)//物料Id .Where(t => containerCodes.Contains(t.palletInfoCode)).ToList();//深库位的托盘的物料等于当前任务的物料 var bill = from a in mesBasePalletInfos join b in wmsBaseLocations.Where(t => t.locDeep == 1) on a.palletInfoCode equals b.containerCode select new { b };//等于当前任务的物料的托盘的库位信息 var outBill = from a in bill//深库位托盘和当前任务绑定物料一致的托盘库位 from b in wmsBaseLocations//所有库位 where a.b.layerNum == b.layerNum//层数相同 && b.locDeep == 2//浅库位 && b.locRow == (a.b.locRow % 2 == 0 ? a.b.locRow - 1 : a.b.locRow + 1) //如果是4则找3,如果是1则找2 && a.b.locColumn == b.locColumn//列数相同 && string.IsNullOrEmpty(b.containerCode) select new { a.b };//在上面的基础上获取对应托盘的外侧库位的空库位信息 wmsBaseLocation ??= outBill.FirstOrDefault()?.b;//先找相同物料的外侧库位 wmsBaseLocation ??= wmsBaseLocations.Where(t => string.IsNullOrEmpty(t.containerCode)).FirstOrDefault(t => t.locDeep == 2);//找不到再找深库位 wmsBaseLocation ??= wmsBaseLocations.Where(t => string.IsNullOrEmpty(t.containerCode)).FirstOrDefault();//找不到再找任意库位 if (wmsBaseLocation != null)//如果找到库位,生成入库任务 { BaseEquip startEquip = StaticData.BaseEquip.First(t => t.objid == 37); var wcsTask = new WcsTask() { objid = StaticData.SnowId.NextId(), currPointId = startEquip.objid, currPointNo = startEquip.equipNo, nextPointId = agvEquip.objid, nextPointNo = agvEquip.equipNo, endPointId = wmsBaseLocation.locationId, endPointNo = wmsBaseLocation.locationCode, taskStatus = 0, useFlag = 1, containerNo = rfidValue, createBy = "WCS", createTime = DateTime.Now, floorNo = 2, fromFloorNo = 2, isEmpty = "0", taskType = 49, qty = 1, }; dbContext.Add(wcsTask); WcsTaskLog wcsTaskLog = CoreMapper.Map(wcsTask); dbContext.Add(wcsTaskLog); dbContext.SaveChanges(); Console.WriteLine(DateTime.Now + ":二楼码垛输送线生成入库托盘任务成功:" + wcsTask.objid); LogManager.Info("二楼码垛输送线生成入库托盘任务成功:" + wcsTask.objid); } else { //报警 } } } } } } } catch (Exception ex) { if (ex is PlcException) { try { foreach (var item in StaticData.PlcDic) { if (item.Value.IP == ex.Message) { StaticData.PlcDic[item.Key] = new Plc.S7.Plc(item.Value.CPU, item.Value.IP, item.Value.Port, item.Value.Rack, item.Value.Slot); StaticData.PlcDic[item.Key].Open(); } } } catch { } } LogManager.Error(ex); } finally { Thread.Sleep(1000); } } } } }