using Khd.Core.Domain.Dto.webapi; using Khd.Core.Domain.Models; using Khd.Core.EntityFramework; using Khd.Core.Wcs.Global; using Masuit.Tools.Logging; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Z.EntityFramework.Plus; namespace Khd.Core.Wcs.Wcs { /// /// 二楼AGV调度 /// public class SecondFloorAGV { List ScanPoint { get; set; }//点位信息 private readonly IHost _host; private readonly Plc.S7.Plc _plc; BasePlcpoint? LineRFID { get; set; } BasePlcpoint? LineWcsrun { get; set; } BasePlcpoint? LineSignal { get; set; } BasePlcpoint? LineIsPallet { get; set; } BasePlcpoint? LineSerialNO { get; set; } BasePlcpoint? LineFeedSeriaNo { get; set; } Thread FlowPointThread; int FloorNo { get; set; } string EquipNo = ""; List taskInType = new List { 1, 3, 5, 7 }; List taskOutType = new List { 2, 4, 6, 8 }; public SecondFloorAGV(IHost host, Plc.S7.Plc plc, int floor, string equipNo) { this._host = host; this._plc = plc; FloorNo = floor; EquipNo = equipNo; this.ScanPoint = StaticData.BasePlcpointList.Where(t => t.floorNo == floor).ToList();//加载当前站点所对应的点位 //this.LineRFID = this.ScanPoint.FirstOrDefault(t => t.plcpointNo.Contains("RFID")); //this.LineWcsrun = this.ScanPoint.FirstOrDefault(t => t.plcpointNo.Contains("wcsrun")); //this.LineSignal = this.ScanPoint.FirstOrDefault(t => t.plcpointNo.Contains("linesignal")); this.LineIsPallet = this.ScanPoint.FirstOrDefault(t => t.plcpointNo.Contains("ispallet")); //this.LineSerialNO = this.ScanPoint.FirstOrDefault(t => t.plcpointNo.Contains("serialno")); //this.LineFeedSeriaNo = this.ScanPoint.FirstOrDefault(t => t.plcpointNo.Contains("feedserialno")); //var IsPallet = this._plc.Read(LineIsPallet.plcpointAddress); try { //默认启动,清理plc的上位机写入点位值 this._plc.Write(LineRFID.plcpointAddress, MainCentralControl.QingKongDianWei); } catch (Exception ex) { Console.WriteLine("楼层" + floor + " 初始化数据异常" + ex.Message); LogManager.Error(ex); } } /// /// 启动上件扫描监听 /// public void StartPoint() { FlowPointThread = new Thread(MonitorInLocatorPoint); FlowPointThread.Start(); } public void MonitorInLocatorPoint() { using var scope = _host.Services.CreateScope(); using var dbContext = scope.ServiceProvider.GetRequiredService(); List taskInType = new List { 1, 3, 5, 7 }; List taskOutType = new List { 2, 4, 6, 8 }; while (true) { try { var taskList = GetTask(FloorNo, EquipNo); if (taskList.Count == 0) { LogManager.Info(FloorNo + "楼AGV无任务"); } foreach (var item in taskList) { if (taskInType.Contains(item.taskType.GetValueOrDefault()))//入库 { var loc = dbContext.WmsBaseLocation.Where(t => t.activeFlag == "1").ToList(); //2楼成品 if (item.taskType == 5|| item.taskType==11 )//成品入库||成品移库 { var stock = dbContext.WmsProductStock.Where(t => t.activeFlag == "1").ToList(); //获取有物料的库位 var locStock = from l in loc join s in stock on l.locationCode equals s.locationCode select new { LocId = l.locationId, locCode = l.locationCode, LocDeep = l.locDeep, productBatch = s.productBatch }; //获取空库位 var nullLocList = loc.Where(r => !locStock.Select(t => t.locCode).Contains(r.locationCode) && r.warehouseId == 1).ToList(); var location = nullLocList.OrderBy(t => t.locColumn).FirstOrDefault(); item.currPointId = 8; item.currPointNo = "AGV01"; item.nextPointId = location.locationId; item.nextPointNo = location.locationCode; //dbContext.Update(item); } //下发agv出库指令 SendAndUpdateTask(item); } else { var locList = dbContext.WmsBaseLocation.Where(t => t.activeFlag == "1").ToList(); //出库 if (item.taskType == 6)//成品出库 { //获取库存 var proStock = dbContext.WmsProductStock.Where(t => t.activeFlag == "1" && t.stockType == "3").ToList(); var dic = dbContext.BaseDictionary.Where(t => t.dicKey == "OutStockDate").FirstOrDefault(); var DateRange = Convert.ToInt32(dic.dicValue); var stockList = from t in proStock.Where(r => r.productId == item.materialId) join b in locList on t.locationCode equals b.locationCode into temp from newStock in temp.DefaultIfEmpty() select new { proID = t.productStockId, locID = newStock.locationId, locCode = t.locationCode, layerNum = newStock.layerNum, locColumn = newStock.locColumn, locRow = newStock.locRow, locDeep = newStock.locDeep, inStockDate = newStock.createTime, }; //先查出最早入库时间 var inStockModel = stockList.OrderBy(t => t.inStockDate).FirstOrDefault(); var inStockDate = inStockModel.inStockDate; //查出符合条件的成品 var outStockList = stockList.Where(t => t.inStockDate >= inStockDate && t.inStockDate <= inStockDate.GetValueOrDefault().AddDays(DateRange)).ToList(); var outModel = outStockList.OrderBy(t => t.locColumn).ThenByDescending(t => t.locDeep).FirstOrDefault(); if (outModel.locDeep == 1) { //自动获取id Jc.SnowId.JcSnowId id = new Jc.SnowId.JcSnowId(1, 1); var objid = id.NextId(); var isExiStock = stockList.Where(t=>t.locRow==outModel.locRow && t.locColumn==outModel.locColumn && t.locDeep ==2).FirstOrDefault(); if (isExiStock != null) { //创建成品移库任务 WcsTask newTask = new() { objid = objid, taskType = 11, containerNo = "", taskStatus = 0, materialId = isExiStock.locID, qty = 1, startPointId = isExiStock.locID, startPointNo = "", currPointId = isExiStock.locID, currPointNo = "", }; dbContext.Add(newTask); dbContext.SaveChanges(); return; } } //锁定库位 dbContext.WmsBaseLocation.Where(t => t.locationCode == outModel.locCode).Update(t => new WmsBaseLocation() { locationStatus = "1", updateTime = DateTime.Now, updateBy = "agv出库", }); //下发agv出库指令 SendAndUpdateTask(item); } } } } catch (Exception ex) { LogManager.Error(ex); } finally { Thread.Sleep(1000); } } } public List GetTask(int floorNo, string equipNo) { using var scope = _host.Services.CreateScope(); using var dbContext = scope.ServiceProvider.GetRequiredService(); List wcsTask = new List(); var wareHouseList = StaticData.WmsBaseWarehouse.ToList(); var equip = StaticData.BaseEquip.Where(t => t.floorNo == floorNo && t.equipType == 4).FirstOrDefault(); try { //获取条码号,如果该条码任务存在就继续任务,如果条码不存在,创建入库任务并调度agv var taskList = StaticData.WcsTask.Where(t => t.nextPointId == equip.objid && t.currPointId != equip.objid && (t.taskType==1|| t.taskType == 2|| t.taskType == 5 || t.taskType == 6)).ToList(); if (taskList.Count() == 0) { return null; } wcsTask = taskList; } catch (Exception ex) { LogManager.Info(floorNo + "楼AGV异常" + ex.Message); throw; } return wcsTask; } public void SendAndUpdateTask(WcsTask task) { //获取 if (task == null) return; using var scope = _host.Services.CreateScope(); using var dbContext = scope.ServiceProvider.GetRequiredService(); WcsToWms wcsToWms = new WcsToWms(); //首先判断是否已下发指令 var cmd = dbContext.WcsCmd.Where(t => t.taskId == task.objid).FirstOrDefault(); var locList = dbContext.WmsBaseLocation.Where(t => t.activeFlag == "1").ToList(); //指令表存在说明已下发 if (cmd == null) { //获取下发agv指令 string ip = ""; int port = 0; string url = ""; RequestAGVTaskDto agvtask = new RequestAGVTaskDto(); agvtask.reqCode = task.objid.ToString(); //var json = JsonConvert.SerializeObject(agvtask); //HttpHelper.SendPostMessage(ip, port, url, json); agvtask.positionCodePath = new List(); Position p = new Position(); WmsBaseLocation putPos = new WmsBaseLocation(); //放料点 WmsBaseLocation setPos = new WmsBaseLocation(); //取料点 if (task.taskType == 5) //入库 { setPos = locList.Where(t => t.locationId == task.nextPointId).FirstOrDefault(); } else { setPos = locList.Where(t => t.locationId == task.nextPointId).FirstOrDefault(); } putPos = locList.Where(t => t.locationId == task.nextPointId).FirstOrDefault(); p.podCode = setPos.agvPositionCode; p.podTyp = ""; agvtask.positionCodePath.Add(p); p.podCode = putPos.agvPositionCode; p.podTyp = ""; //取料点 agvtask.positionCodePath.Add(p); agvtask.taskTyp = ""; //给agv创建任务 wcsToWms.genAgvSchedulingTask(agvtask); //未下发给agv下发指令 WcsCmd taskCmd = new WcsCmd() { taskId = task.objid, cmdType = task.taskType, serialNo = task.serialNo, equipmentNo = task.equipmentNo, cmdStatus = 1, createBy = FloorNo + "楼AGV", createTime = DateTime.Now, }; dbContext.Add(taskCmd); dbContext.SaveChanges(); } else { //获取接驳位是否有托盘 var IsPallet = this._plc.Read(this.LineIsPallet.plcpointAddress); if (cmd.sendFlag == 0) { if (taskInType.Contains(task.taskType.GetValueOrDefault()))//入库 { //入库时有托盘继续任务 if (Convert.ToInt32(IsPallet) == 1) { continueTaskDto continueTask = new continueTaskDto(); continueTask.taskCode = task.objid.ToString(); wcsToWms.continueTask(continueTask); //未下发给agv下发指令 WcsCmd taskCmd = new WcsCmd() { taskId = task.objid, sendFlag = 1, createBy = FloorNo + "楼AGV", createTime = DateTime.Now, }; dbContext.Update(taskCmd); dbContext.SaveChanges(); } } else { //出库时没有托盘继续任务 if (Convert.ToInt32(IsPallet) == 0) { continueTaskDto continueTask = new continueTaskDto(); continueTask.taskCode = task.objid.ToString(); wcsToWms.continueTask(continueTask); //更新任务 dbContext.WcsCmd.Where(t => t.taskId == task.objid).Update(t => new WcsCmd() { sendFlag = 1, updateTime = DateTime.Now, updateBy = "agv出库", }); } } } } //更新任务表 dbContext.WcsTask.Where(t => t.objid == task.objid).Update(t => new WcsTask() { currPointId = task.currPointId, currPointNo = task.currPointNo, nextPointId = task.nextPointId, nextPointNo= task.nextPointNo, updateTime = DateTime.Now, updateBy = "agv出库", }) ; } ///// ///// 下发任务 ///// ///// //public void SendTask1(WcsTask task) //{ // using var scope = _host.Services.CreateScope(); // using var dbContext = scope.ServiceProvider.GetRequiredService(); // //入库类型 // //List taskInType = new List { 1, 3, 5, 7 }; // //List taskOutType = new List { 2, 4, 6, 8 }; // //获取 // if (task == null) return; // if (taskInType.Contains(task.taskType.GetValueOrDefault()))//入库 // { // WcsToWms wcsToWms = new WcsToWms(); // //首先判断是否已下发指令 // var cmd = StaticData.WcsCmd.Where(t => t.taskId == task.objid).FirstOrDefault(); // //指令表存在说明已下发 // if (cmd == null) // { //获取下发agv指令 // string ip = ""; int port = 0; string url = ""; // RequestAGVTaskDto agvtask = new RequestAGVTaskDto(); // agvtask.reqCode = task.serialNo.ToString(); // //var json = JsonConvert.SerializeObject(agvtask); // //HttpHelper.SendPostMessage(ip, port, url, json); // wcsToWms.genAgvSchedulingTask(agvtask); // //未下发给agv下发指令 // WcsCmd taskCmd = new WcsCmd() // { // taskId = task.objid, // cmdType = task.taskType, // serialNo = task.serialNo, // equipmentNo = task.equipmentNo, // cmdStatus = 1, // createBy = FloorNo + "楼AGV", // createTime = DateTime.Now, // }; // dbContext.Add(taskCmd); // dbContext.SaveChanges(); // } // else // { // var IsPallet = this._plc.Read(this.LineIsPallet.plcpointAddress); // if (cmd.sendFlag == 0) // { // if (Convert.ToInt32(IsPallet) == 1) // { // continueTaskDto continueTask = new continueTaskDto(); // continueTask.taskCode = task.objid.ToString(); // wcsToWms.continueTask(continueTask); // //未下发给agv下发指令 // WcsCmd taskCmd = new WcsCmd() // { // taskId = task.objid, // cmdType = task.taskType, // serialNo = task.serialNo, // equipmentNo = task.equipmentNo, // sendFlag = 1, // createBy = FloorNo + "楼AGV", // createTime = DateTime.Now, // }; // dbContext.Update(taskCmd); // dbContext.SaveChanges(); // } // } // } // } // else // { // var locList = dbContext.WmsBaseLocation.Where(t => t.activeFlag == "1").ToList(); // //出库 // if (task.taskType == 6)//成品出库 // { // //获取库存 // var proStock = dbContext.WmsProductStock.Where(t => t.activeFlag == "1" && t.stockType == "3" && t.productId == task.materialId).ToList(); // var dic = dbContext.BaseDictionary.Where(t => t.dicKey == "OutStockDate").FirstOrDefault(); // var DateRange = Convert.ToInt32(dic.dicValue); // var stockList = from t in proStock // join b in locList on t.locationCode equals b.locationCode // into temp // from newStock in temp.DefaultIfEmpty() // select new // { // proID = t.productStockId, // locID = newStock.locationId, // locCode = t.locationCode, // layerNum = newStock.layerNum, // locColumn = newStock.locColumn, // locRow = newStock.locRow, // locDeep = newStock.locDeep, // inStockDate = newStock.createTime, // }; // //先查出最早入库时间 // var inStockModel = stockList.OrderBy(t => t.inStockDate).FirstOrDefault(); // var inStockDate = inStockModel.inStockDate; // //查出符合条件的成品 // var outStockList = stockList.Where(t => t.inStockDate >= inStockDate && t.inStockDate <= inStockDate.GetValueOrDefault().AddDays(DateRange)).ToList(); // var outModel = outStockList.OrderBy(t => t.locColumn).ThenByDescending(t => t.locDeep).FirstOrDefault(); // dbContext.WmsBaseLocation.Where(t => t.locationCode == outModel.locCode).Update(t => new WmsBaseLocation() // { // locationStatus = "1", // updateTime = DateTime.Now, // updateBy = "agv出库", // }); // dbContext.WcsTask.Where(t => t.objid == task.objid).Update(t => new WcsTask() // { // currPointId = outModel.locID, // currPointNo = outModel.locCode, // updateTime = DateTime.Now, // updateBy = "agv出库", // }); // //下发agv出库指令 // } // else if (task.taskType == 2)//原材料出库 // { // } // } //} } }