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 FirstFloor { private readonly IHost _host; private Plc.S7.Plc _plc; private readonly long F01 = 1; private readonly long T01 = 6; /// /// 一楼RFID 读 /// private readonly BasePlcpoint RFID001; private readonly BasePlcpoint automatic; /// /// 到位信号 读 /// private readonly BasePlcpoint linesignal01; /// /// 提升机流水号 读 /// private readonly BasePlcpoint serialno06; /// /// 提升机状态 读 /// private readonly BasePlcpoint equipstate06; /// /// 提升机任务状态 读 /// private readonly BasePlcpoint hoistertrayin06; /// /// 提升机当前楼层 写 /// private readonly BasePlcpoint currentfloor06; /// /// 提升机目的楼层 写 /// private readonly BasePlcpoint targetfloor06; /// /// 提升机反馈流水号 /// private readonly BasePlcpoint reserialno06; private readonly BasePlcpoint mesClose; public FirstFloor(IHost host, Plc.S7.Plc plc) { this._host = host; this._plc = plc; //一楼RFID 读 this.RFID001 = StaticData.BasePlcpointList.First(t => t.equipmentNo.Contains("FirstFloorLine") && t.plcpointNo.Contains("RFID001")); //到位信号 读 this.linesignal01 = StaticData.BasePlcpointList.First(t => t.equipmentNo.Contains("FirstFloorLine") && t.plcpointNo.Contains("linesignal01")); //一楼提升机流水号 读 this.serialno06 = StaticData.BasePlcpointList.First(t => t.equipmentNo.Contains("Hoister") && t.plcpointNo.Contains("serialno06")); this.mesClose = StaticData.BasePlcpointList.First(t => t.equipmentNo.Contains("Hoister") && t.plcpointNo.Contains("mesclose")); this.automatic = StaticData.BasePlcpointList.First(t => t.equipmentNo.Contains("Hoister") && t.plcpointNo.Contains("automatic")); //一楼提升机状态 读 this.equipstate06 = StaticData.BasePlcpointList.First(t => t.equipmentNo.Contains("Hoister") && t.plcpointNo.Contains("equipstate06")); //一楼提升机任务状态 读 this.hoistertrayin06 = StaticData.BasePlcpointList.First(t => t.equipmentNo.Contains("Hoister") && t.plcpointNo.Contains("hoistertrayin06")); //一楼提升机当前楼层 写 this.currentfloor06 = StaticData.BasePlcpointList.First(t => t.equipmentNo.Contains("Hoister") && t.plcpointNo.Contains("currentfloor06")); //一楼提升机目的楼层 写 this.targetfloor06 = StaticData.BasePlcpointList.First(t => t.equipmentNo.Contains("Hoister") && t.plcpointNo.Contains("targetfloor06")); //一楼提升机到位信号 读 this.reserialno06 = StaticData.BasePlcpointList.First(t => t.equipmentNo.Contains("Hoister") && t.plcpointNo.Contains("reserialno06")); } /// /// 启动上件扫描监听 /// public void StartPoint() { //Thread firstFloorLine = new(FirstFloorLine) //{ // IsBackground = true //}; //firstFloorLine.Start(); Console.WriteLine(DateTime.Now + ":一楼接驳位线程启动成功"); LogManager.Info("一楼接驳位线程启动成功"); Thread firstFloorHoister = new(FirstFloorHoister) { IsBackground = true }; firstFloorHoister.Start(); //Thread CallEmptyThread = new Thread(CallEmpty) //{ // IsBackground = true //}; //CallEmptyThread.Start(); Console.WriteLine(DateTime.Now + ":一楼提升机线程启动成功"); LogManager.Info("一楼提升机线程启动成功"); } private void CallEmpty() { using var scope = _host.Services.CreateScope(); using var dbContext = scope.ServiceProvider.GetRequiredService(); BasePlcpoint oneOutPoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "oneOut"); BasePlcpoint someOutPoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "someOut"); BaseEquip mdjEquip = StaticData.BaseEquip.First(t => t.objid == 40); while (true) { try { dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload()); var linesignal = this._plc.Read(this.linesignal01.plcpointAddress); int taskCount = dbContext.WcsTask.Where(t => t.nextPointId == 6 && t.taskStatus > 0 && t.endPointId == 1).Count(); int firstFloorCount = dbContext.WcsTask.Where(t => t.currPointId == 1).Count(); if (Convert.ToInt32(linesignal) == 0 && taskCount == 0 && firstFloorCount == 0) { bool canSend = dbContext.WcsTask.Where(t => t.floorNo == 1).Where(t => t.taskStatus > 0).Any(); if (!canSend) { WcsTaskManual? wcsTaskManual = dbContext.WcsTaskManual.Where(t => t.nextPointId == 40).FirstOrDefault(); if (wcsTaskManual != null) { if (wcsTaskManual.taskType == 53) { this._plc.WriteToPoint(someOutPoint.plcpointAddress, "1", someOutPoint.plcpointLength.ToString()); WcsTask wcsTask = CoreMapper.Map(wcsTaskManual); wcsTask.createTime = DateTime.Now; wcsTask.createBy = "一楼接驳位线程"; wcsTask.taskStatus = 0; wcsTask.useFlag = 1; wcsTask.isEmpty = "1"; wcsTask.qty = mdjEquip.emptyCount; wcsTask.remark = "一楼创建入库任务"; WcsTaskLog wcsTaskLog = CoreMapper.Map(wcsTask); mdjEquip.emptyCount = 0; dbContext.Update(mdjEquip); dbContext.Add(wcsTaskLog); dbContext.Add(wcsTask); dbContext.SaveChanges(); LogManager.Info("一楼接驳位线程:空托盘任务下发成功"); Console.WriteLine(DateTime.Now + ":一楼接驳位线程:空托盘任务下发成功"); } } } } } catch { } Thread.Sleep(1000); } } public static bool ReadEmptyLocation() { var oneOutPoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "oneOut"); var someOutPoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "someOut"); var oneInPoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "oneIn"); var someInPoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "someIn"); var oneOutValue = StaticData.PlcDic[0].Read(oneOutPoint.plcpointAddress); var someOutValue = StaticData.PlcDic[0].Read(someOutPoint.plcpointAddress); var oneInValue = StaticData.PlcDic[0].Read(oneInPoint.plcpointAddress); var someInValue = StaticData.PlcDic[0].Read(someInPoint.plcpointAddress); if (oneOutValue != null && someOutValue != null && oneInValue != null && someInValue != null) { if (Convert.ToInt32(oneOutValue) == 0 && Convert.ToInt32(someOutValue) == 0 && Convert.ToInt32(oneInValue) == 0 && Convert.ToInt32(someInValue) == 0) { return true; } } return false; } /// /// 启动一楼接驳位线程 /// private void FirstFloorLine() { List Outtpyes = new() { 2, 4, 8, 6 }; using var scope = _host.Services.CreateScope(); using var dbContext = scope.ServiceProvider.GetRequiredService(); while (true) { try { dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload()); var RFID001Value = this._plc.ReadRFID(this.RFID001.plcpointAddress); //一楼RFID 读 var linesignal01Value = this._plc.Read(this.linesignal01.plcpointAddress); //到位信号 读 //正常读到plc值 if (linesignal01Value != null && RFID001Value != null) { //正常托盘到位 BaseEquip baseEquip = dbContext.BaseEquip.First(t => t.objid == 1); if (Convert.ToInt32(linesignal01Value) == 1) { //判断task表里没有该rfid的未完成的入库 //信息,未下发去向 var task = dbContext.WcsTask.Where(t => t.nextPointId == 1).OrderBy(t => t.createTime).FirstOrDefault(); if (task == null) { //根据托盘号获取物料码 var material = dbContext.MesBasePalletInfo.Where(t => t.palletInfoCode == RFID001Value).FirstOrDefault(); WcsTaskLog? taskLog = dbContext.WcsTaskLog.Where(t => t.containerNo == RFID001Value).OrderByDescending(t => t.createTime).FirstOrDefault(); if (material != null) { if (taskLog != null) { if (taskLog.materialBarcode == material.materialBarcode) { if (baseEquip.containerNo == "0") { baseEquip.containerNo = null; dbContext.Update(baseEquip); dbContext.SaveChanges(); LogManager.Info("一楼接驳位线程:托盘" + RFID001Value + "解绑信息更新成功"); } else if (baseEquip.containerNo != RFID001Value) { baseEquip.containerNo = RFID001Value; dbContext.Update(baseEquip); dbContext.SaveChanges(); LogManager.Info("一楼接驳位线程:托盘" + RFID001Value + "绑定信息更新成功"); Console.WriteLine(DateTime.Now + ":一楼接驳位线程:托盘" + RFID001Value + "绑定信息更新成功"); Thread.Sleep(3000); continue; } else { Thread.Sleep(3000); continue; } } } var warehouseId = dbContext.WmsWarehouseMaterial.Where(t => t.storageType == "1" && t.storageId == material.materialId).FirstOrDefault()?.warehouseId; if (warehouseId != null) { var TargetFloor = dbContext.WmsBaseWarehouse.Where(t => t.warehouseId == warehouseId).FirstOrDefault(); if (TargetFloor != null) { //插入task表 var dic = StaticData.BaseDictionary.Where(t => t.dicKey == "TaskType" && t.agvType == "I" && t.dicField == TargetFloor.warehouseInstockType).FirstOrDefault(); if (dic != null) { var newTask = new WcsTask() { objid = StaticData.SnowId.NextId(), serialNo = SystemData.GetSerialNo(dbContext), equipmentNo = "F01", taskType = Convert.ToInt32(dic.dicValue), taskStatus = 0, containerNo = RFID001Value, materialBarcode = material.materialBarcode, materialId = material.materialId, qty = Convert.ToInt32(material.bindAmount), currPointId = F01, currPointNo = "TSJ_01", nextPointId = T01, nextPointNo = "TSJ_01", endPointId = warehouseId, fromFloorNo = 1, floorNo = TargetFloor.warehouseFloor, useFlag = 1, createBy = "一楼接驳位", createTime = DateTime.Now, remark = "一楼创建入库任务" }; WcsTaskLog wcsTaskLog = CoreMapper.Map(newTask); dbContext.Add(wcsTaskLog); dbContext.Add(newTask); dbContext.SaveChanges(); } } } } } else { if (string.IsNullOrEmpty(task.containerNo)) { if (task.qty > 1)//多个托盘 { if (task.useFlag == 1) { } } else if (task.qty == 1) { } } } } } } catch (Exception ex) { if (ex is PlcException) { 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(); } } } LogManager.Error(ex); } Thread.Sleep(1000); } } /// /// 提升机线程 /// private void FirstFloorHoister() { using var scope = _host.Services.CreateScope(); using var dbContext = scope.ServiceProvider.GetRequiredService(); while (true) { try { var mesCloseValue = this._plc.Read(this.mesClose.plcpointAddress); //MES关闭状态 读 var serialno06Value = this._plc.Read(this.serialno06.plcpointAddress); //提升机流水号 读 var equipstate06Value = this._plc.Read(this.equipstate06.plcpointAddress); //提升机状态 读 var hoisterTrayIn06Value = this._plc.Read(this.hoistertrayin06.plcpointAddress); //提升机货物到位状态 读 var currentfloor06Value = this._plc.Read(this.currentfloor06.plcpointAddress); //提升机当前楼层 读 var targetfloor06Value = this._plc.Read(this.targetfloor06.plcpointAddress); //提升机目的楼层 写 var reserialno06 = this._plc.Read(this.reserialno06.plcpointAddress); //反馈流水号 if (mesCloseValue != null && Convert.ToInt32(mesCloseValue) == 0) { //正常读到plc值 if (targetfloor06Value != null && serialno06Value != null && equipstate06Value != null && currentfloor06Value != null && reserialno06 != null && hoisterTrayIn06Value != null) { //提升机空闲 if (Convert.ToInt32(equipstate06Value) == 0) { dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload()); var wcsTasks = dbContext.WcsTask.Where(t => t.nextPointId == T01).OrderBy(t => t.createTime).ToList(); foreach (var wcsTask in wcsTasks) { wcsTask.serialNo ??= SystemData.GetSerialNo(dbContext); if (wcsTasks.Where(t => t.taskStatus > 0).Where(t => t.objid != wcsTask.objid).Any()) { LogManager.Info("提升机线程:有其他任务正在执行,跳过当前任务"); continue; } BaseEquip lineEquip = StaticData.BaseEquip.First(t => t.objid == wcsTask.floorNo); if (wcsTask.taskStatus == 0 && Convert.ToInt32(hoisterTrayIn06Value) == 0)//创建状态,并且里面没有货物 { if (lineEquip.equipStatus == 1) { LogManager.Info("提升机线程:" + wcsTask.floorNo + "楼接驳位有AGV任务,跳过当前任务"); continue; } BasePlcpoint floorPoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "RFID00" + wcsTask.fromFloorNo); if (wcsTask.containerNo == this._plc.ReadRFID(floorPoint.plcpointAddress)) { if (Convert.ToInt32(currentfloor06Value) == wcsTask.fromFloorNo) { wcsTask.taskStatus = 2; wcsTask.updateBy = "提升机线程"; wcsTask.updateTime = DateTime.Now; wcsTask.remark = "提升机任务执行中"; BasePlcpoint basePlcpoint = StaticData.BasePlcpointList.First(t => t.floorNo == wcsTask.fromFloorNo && t.plcpointNo.Contains("wcsrun")); this._plc.WriteToPoint(basePlcpoint.plcpointAddress, "1", basePlcpoint.plcpointLength.ToString()); this._plc.WriteToPoint(this.serialno06.plcpointAddress, wcsTask.serialNo.ToString(), this.serialno06.plcpointLength.ToString()); dbContext.Update(wcsTask); dbContext.WcsTaskLog.Where(t => t.objid == wcsTask.objid).Update(t => new WcsTaskLog { taskStatus = 2, updateBy = "提升机线程", updateTime = DateTime.Now, remark = "提升机任务执行中" }); lineEquip.equipStatus = 1; dbContext.Update(lineEquip); dbContext.SaveChanges(); } else { wcsTask.taskStatus = 1; wcsTask.updateBy = "提升机线程"; wcsTask.updateTime = DateTime.Now; wcsTask.remark = "提升机任务执行中"; this._plc.WriteToPoint(this.targetfloor06.plcpointAddress, wcsTask.fromFloorNo.ToString(), this.targetfloor06.plcpointLength.ToString());//目的地楼层 this._plc.WriteToPoint(this.serialno06.plcpointAddress, wcsTask.serialNo.ToString(), this.serialno06.plcpointLength.ToString()); dbContext.Update(wcsTask); dbContext.WcsTaskLog.Where(t => t.objid == wcsTask.objid).Update(t => new WcsTaskLog { taskStatus = 1, updateBy = "提升机线程", updateTime = DateTime.Now, remark = "提升机任务执行中" }); lineEquip.equipStatus = 1; dbContext.Update(lineEquip); dbContext.SaveChanges(); } } } if (wcsTask.taskStatus == 1 && Convert.ToInt32(reserialno06) == wcsTask.serialNo) { BasePlcpoint floorPoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "RFID00" + wcsTask.fromFloorNo); if (wcsTask.containerNo == this._plc.ReadRFID(floorPoint.plcpointAddress)) { if (Convert.ToInt32(currentfloor06Value) == wcsTask.fromFloorNo)//提升机当前楼层为初始地楼层 { wcsTask.taskStatus = 2; wcsTask.updateBy = "提升机线程"; wcsTask.updateTime = DateTime.Now; wcsTask.remark = "提升机任务执行中"; BasePlcpoint basePlcpoint = StaticData.BasePlcpointList.First(t => t.floorNo == wcsTask.fromFloorNo && t.plcpointNo.Contains("wcsrun")); this._plc.WriteToPoint(basePlcpoint.plcpointAddress, "1", basePlcpoint.plcpointLength.ToString()); this._plc.WriteToPoint(this.serialno06.plcpointAddress, wcsTask.serialNo.ToString(), this.serialno06.plcpointLength.ToString()); dbContext.Update(wcsTask); dbContext.WcsTaskLog.Where(t => t.objid == wcsTask.objid).Update(t => new WcsTaskLog { taskStatus = 2, updateBy = "提升机线程", updateTime = DateTime.Now, remark = "提升机任务执行中" }); dbContext.SaveChanges(); } } } if (wcsTask.taskStatus == 2 && Convert.ToInt32(reserialno06) == wcsTask.serialNo) { if (Convert.ToInt32(hoisterTrayIn06Value) == 1)//托盘已经进提升机 { wcsTask.taskStatus = 3; wcsTask.updateBy = "提升机线程"; wcsTask.updateTime = DateTime.Now; wcsTask.remark = "提升机任务执行完成"; this._plc.WriteToPoint(this.targetfloor06.plcpointAddress, wcsTask.floorNo.ToString(), this.targetfloor06.plcpointLength.ToString());//目的地楼层 dbContext.Update(wcsTask); dbContext.WcsTaskLog.Where(t => t.objid == wcsTask.objid).Update(t => new WcsTaskLog { taskStatus = 3, updateBy = "提升机线程", updateTime = DateTime.Now, remark = "提升机任务执行完成" }); dbContext.SaveChanges(); } } if (wcsTask.taskStatus == 3 && Convert.ToInt32(currentfloor06Value) == wcsTask.floorNo && Convert.ToInt32(reserialno06) == wcsTask.serialNo)//任务状态为3,且当前楼层为任务的目的楼层 { if (wcsTask.floorNo == 1) { if (ReadEmptyLocation()) { var linesignal = _plc.Read(StaticData.BasePlcpointList.First(t => t.plcpointNo == $"linesignal0{wcsTask.floorNo}").plcpointAddress); if (linesignal != null && Convert.ToInt32(linesignal) == 0) { wcsTask.taskStatus = 4; wcsTask.updateBy = "提升机线程"; wcsTask.updateTime = DateTime.Now; wcsTask.remark = "提升机任务执行完成"; BasePlcpoint basePlcpoint = StaticData.BasePlcpointList.First(t => t.floorNo == wcsTask.floorNo && t.plcpointNo.Contains("wcsrun")); this._plc.WriteToPoint(basePlcpoint.plcpointAddress, "2", basePlcpoint.plcpointLength.ToString());//去向为2,表示提升机已到达目的地,让货出去 dbContext.Update(wcsTask); dbContext.WcsTaskLog.Where(t => t.objid == wcsTask.objid).Update(t => new WcsTaskLog { taskStatus = 4, updateBy = "提升机线程", updateTime = DateTime.Now, remark = "提升机任务执行完成" }); dbContext.SaveChanges(); } else { BasePlcpoint basePlcpoint = StaticData.BasePlcpointList.First(t => t.equipmentNo == $"clear0{wcsTask.floorNo}"); this._plc.WriteToPoint(basePlcpoint.plcpointAddress, "1", basePlcpoint.plcpointLength.ToString()); } } } else { var linesignal = _plc.Read(StaticData.BasePlcpointList.First(t => t.plcpointNo == $"linesignal0{wcsTask.floorNo}").plcpointAddress); if (linesignal != null && Convert.ToInt32(linesignal) == 0) { wcsTask.taskStatus = 4; wcsTask.updateBy = "提升机线程"; wcsTask.updateTime = DateTime.Now; wcsTask.remark = "提升机任务执行完成"; BasePlcpoint basePlcpoint = StaticData.BasePlcpointList.First(t => t.floorNo == wcsTask.floorNo && t.plcpointNo.Contains("wcsrun")); this._plc.WriteToPoint(basePlcpoint.plcpointAddress, "2", basePlcpoint.plcpointLength.ToString());//去向为2,表示提升机已到达目的地,让货出去 dbContext.Update(wcsTask); dbContext.WcsTaskLog.Where(t => t.objid == wcsTask.objid).Update(t => new WcsTaskLog { taskStatus = 4, updateBy = "提升机线程", updateTime = DateTime.Now, remark = "提升机任务执行完成" }); dbContext.SaveChanges(); } else { BasePlcpoint basePlcpoint = StaticData.BasePlcpointList.First(t => t.equipmentNo == $"clear0{wcsTask.floorNo}"); this._plc.WriteToPoint(basePlcpoint.plcpointAddress, "1", basePlcpoint.plcpointLength.ToString()); } } } else if (wcsTask.taskStatus == 4) { BaseEquip floorEquip = StaticData.BaseEquip.First(t => t.objid == wcsTask.floorNo); wcsTask.nextPointId = floorEquip.objid; wcsTask.nextPointNo = floorEquip.equipNo; wcsTask.taskStatus = 5; wcsTask.updateBy = "提升机线程"; wcsTask.updateTime = DateTime.Now; wcsTask.remark = "提升机任务执行完成"; lineEquip.equipStatus = 0; dbContext.Update(lineEquip); dbContext.Update(wcsTask); dbContext.WcsTaskLog.Where(t => t.objid == wcsTask.objid).Update(t => new WcsTaskLog { taskStatus = 5, nextPointId = floorEquip.objid, nextPointNo = floorEquip.equipNo, updateBy = "提升机线程", updateTime = DateTime.Now, remark = "提升机任务执行完成" }); dbContext.SaveChanges(); } break; } } } } else { if (currentfloor06Value != null && targetfloor06Value != null) { this._plc.WriteToPoint(this.targetfloor06.plcpointAddress, Convert.ToString(currentfloor06Value), this.targetfloor06.plcpointLength.ToString()); continue; } } } 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); } Thread.Sleep(5000); } } } }