using Khd.Core.Application; using Khd.Core.Application.Interface; using Khd.Core.Domain.Models; using Khd.Core.EntityFramework; 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 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 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; 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.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(); 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 { 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 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.ud1 == "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 = "F01", currPointId = F01, currPointNo = "F01", nextPointId = T01, nextPointNo = "T01", endPointId = warehouseId, fromFloorNo = 1, floorNo = TargetFloor.warehouseFloor, useFlag = 1, createBy = "一楼接驳位", createTime = DateTime.Now, remark = "一楼创建入库任务" }; dbContext.Add(newTask); } } } } } else if (Itpyes.Contains(task.taskType))//按照正常任务下发 { if (task.nextPointId != T01) { task.currPointId = F01; task.currPointNo = "F01"; task.nextPointId = T01; task.nextPointNo = "T01"; task.taskStatus = 0; task.updateBy = "一楼接驳位线程"; task.updateTime = DateTime.Now; task.remark = "一楼创建入库任务"; dbContext.WcsTask.Update(task); dbContext.SaveChanges(); } } //出库 else { //清空托盘绑定 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 = "SYS"; material.updateTime = DateTime.Now; dbContext.Update(material); //dbContext.MesBasePalletInfo.Where(t => t.palletInfoCode == RFID001Value).Delete(); dbContext.SaveChanges(); } } } } } catch (Exception ex) { if (ex is PlcException) { try { this._plc = new Plc.S7.Plc(this._plc.CPU, this._plc.IP, this._plc.Port, this._plc.Rack, this._plc.Slot); this._plc.Open(); } catch { } } 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 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); //反馈流水号 //正常读到plc值 if (targetfloor06Value != null && serialno06Value != null && equipstate06Value != null && currentfloor06Value != null && reserialno06 != null && hoisterTrayIn06Value != null) { //提升机空闲 if (Convert.ToInt32(equipstate06Value) == 0) { var wcsTask = dbContext.WcsTask.Where(t => t.nextPointId == T01).OrderBy(t => t.createTime).FirstOrDefault(); if (wcsTask != null) { if (wcsTask.taskStatus == 0 && Convert.ToInt32(hoisterTrayIn06Value) == 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.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.SaveChanges(); } } if (wcsTask.taskStatus == 1 && Convert.ToInt32(reserialno06) == wcsTask.serialNo) { 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()); dbContext.Update(wcsTask); 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.SaveChanges(); } } if (wcsTask.taskStatus == 3 && Convert.ToInt32(currentfloor06Value) == wcsTask.floorNo && Convert.ToInt32(reserialno06) == wcsTask.serialNo)//任务状态为3,且当前楼层为任务的目的楼层 { 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.SaveChanges(); } } } } } catch (Exception ex) { if (ex is PlcException) { try { this._plc = new Plc.S7.Plc(this._plc.CPU, this._plc.IP, this._plc.Port, this._plc.Rack, this._plc.Slot); this._plc.Open(); } catch { } } LogManager.Error(ex); } Thread.Sleep(1000); } } } }