using Khd.Core.Application; using Khd.Core.Application.Interface; using Khd.Core.Domain.Models; using Khd.Core.EntityFramework; using Khd.Core.Library.Mapper; using Khd.Core.Plc; using Khd.Core.Plc.S7; using Khd.Core.Wcs.Global; using Masuit.Tools.Logging; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using System.Diagnostics; 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 canwritewcsrun06; 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.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")); this.canwritewcsrun06 = StaticData.BasePlcpointList.First(t => t.equipmentNo.Contains("Hoister") && t.plcpointNo.Contains("canwritewcsrun06")); } /// /// 启动上件扫描监听 /// 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(); Console.WriteLine(DateTime.Now + ":一楼提升机线程启动成功"); LogManager.Info("一楼提升机线程启动成功"); } /// /// 启动一楼接驳位线程 /// private void FirstFloorLine() { List Itpyes = new() { 1, 3, 5, 7 }; 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) { //正常托盘到位 if (Convert.ToInt32(linesignal01Value) == 1) { //判断task表里没有该rfid的未完成的入库 //信息,未下发去向 var task = dbContext.WcsTask.Where(t => t.containerNo == RFID001Value && t.taskStatus < 1).FirstOrDefault(); if (task == null) { //根据托盘号获取物料码 var material = dbContext.MesBasePalletInfo.Where(t => t.palletInfoCode == RFID001Value).FirstOrDefault(); if (material != null) { var lastTask = dbContext.WcsTaskLog.Where(t => t.containerNo == RFID001Value).OrderByDescending(t => t.createTime).FirstOrDefault(); if (lastTask != null) { if (lastTask.materialId == material.materialId && lastTask.ud3 != "10") { lastTask.ud2 = "1"; lastTask.ud3 = "1"; dbContext.Update(lastTask); dbContext.SaveChanges(); LogManager.Info("一楼接驳位线程:托盘" + RFID001Value + "绑定信息未更新,请人工确认是否再次入库"); Console.WriteLine(DateTime.Now + ":一楼接驳位线程:托盘" + RFID001Value + "绑定信息未更新,请人工确认是否再次入库"); 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, materialNo = material.materialCode, materialId = material.materialId, qty = Convert.ToInt32(material.bindAmount), startPointId = F01, startPointNo = "TSJ_01", 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 (Itpyes.Contains(task.taskType))//按照正常任务下发 { if (task.nextPointId != T01) { task.currPointId = F01; task.currPointNo = "TSJ_01"; task.nextPointId = T01; task.nextPointNo = "TSJ_01"; task.taskStatus = 0; task.updateBy = "一楼接驳位线程"; task.updateTime = DateTime.Now; task.remark = "一楼创建入库任务"; WcsTaskLog wcsTaskLog = CoreMapper.Map(task); dbContext.Update(wcsTaskLog); dbContext.Update(task); dbContext.SaveChanges(); } } //出库 else { dbContext.WcsTask.Where(t => t.objid == task.objid).Delete(); dbContext.WcsTaskLog.Where(t => t.objid == task.objid).Update(t => new WcsTaskLog { taskStatus = 4 }); //没有绑定信息 //WmsProductOutstock? wmsProductOutstock = dbContext.WmsProductOutstock.FirstOrDefault(t => t.palletInfoCode == RFID001Value&& t.executeStatus =="1"); //WmsRawOutstock? wmsRawOutstock = dbContext.WmsRawOutstock.FirstOrDefault(t => t.palletInfoCode == RFID001Value && t.executeStatus == "1"); //if (wmsProductOutstock != null || wmsRawOutstock != null) //{ // //清空托盘绑定 // var material = dbContext.MesBasePalletInfo.Where(t => t.palletInfoCode == RFID001Value).FirstOrDefault(); // if (material != null) // { // material.bindAmount = 0; // material.materialBarcode = null; // material.materialCode = null; // material.materialId = null; // material.materialName = null; // material.updateBy = "WCS"; // material.updateTime = DateTime.Now; // dbContext.Update(material); // if (wmsRawOutstock != null) // { // wmsRawOutstock.executeStatus = "2"; // dbContext.Update(wmsRawOutstock); // } // else if(wmsProductOutstock != null) // { // wmsProductOutstock.executeStatus = "2"; // dbContext.Update(wmsProductOutstock); // } // //dbContext.MesBasePalletInfo.Where(t => t.palletInfoCode == RFID001Value).Delete(); // dbContext.SaveChanges(); // } //} } } } } 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() { while (true) { try { //var automatic06Value = this._plc.Read(this.automatic.plcpointAddress);//提升机自动状态 //if (automatic06Value != null && Convert.ToInt32(automatic06Value) == 1) //{ using var scope = _host.Services.CreateScope(); using var dbContext = scope.ServiceProvider.GetRequiredService(); 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); //反馈流水号 var canwritewcsrun06value = this._plc.Read(this.canwritewcsrun06.plcpointAddress); //正常读到plc值 if (targetfloor06Value != null && canwritewcsrun06value != null && serialno06Value != null && equipstate06Value != null && currentfloor06Value != null && reserialno06 != null && hoisterTrayIn06Value != null) { //提升机空闲 if (Convert.ToInt32(equipstate06Value) == 0) { var wcsTasks = dbContext.WcsTask.Where(t => t.nextPointId == T01).OrderBy(t => t.createTime).ToList(); foreach (var wcsTask in wcsTasks) { 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) { //if (Convert.ToInt32(canwritewcsrun06value) == 0) { 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(canwritewcsrun06value) == 0) { 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 (Convert.ToInt32(canwritewcsrun06value) == 0) { wcsTask.taskStatus = 4; 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, "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 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.SaveChanges(); 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; } } } //} } 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); } } } }