using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; using SlnMesnac.Business.@base; using SlnMesnac.Model.domain; using SlnMesnac.Model.dto.taskType; using SlnMesnac.Model.dto.webapi; using SlnMesnac.Plc; using SlnMesnac.Serilog; using SlnMesnac.WCS.Global; using SlnMesnac.WCS.Library; using SqlSugar; using System.Collections.Generic; using System.Threading.Tasks; namespace SlnMesnac.WCS.WCS { /// /// 背负式agv /// public class BearAgv : BaseBusiness { private readonly SerilogHelper _logger; private readonly ISqlSugarClient sqlSugarClient; private List agvEquipNos = new List() { "AGV01", "AGV02", "AGV03" }; //3#车间上料点plc private readonly PlcAbsractFactory workShop3Plc; //2#计量室相关点位 private readonly PlcAbsractFactory workShop2Plc; public readonly WcsBaseEquip baseEquip; public BearAgv(IServiceProvider serviceProvider) : base(serviceProvider) { sqlSugarClient = serviceProvider.GetRequiredService(); _logger = serviceProvider.GetRequiredService(); workShop3Plc = base.GetPlcByKey("workShop3Plc"); workShop2Plc = base.GetPlcByKey("workShop2Plc"); baseEquip = sqlSugarClient.Queryable().Where(x => x.EquipNo == "AGV01").First(); } /// /// 启动扫描监听 /// public void StartPoint() { try { //List agvList = sqlSugarClient.Queryable().Where(x => agvEquipNos.Contains(x.EquipNo)).ToList(); Task.Run(async () => { while (true) { await ExecuteTaskAsync(); await Task.Delay(1000); } }); } catch (Exception ex) { _logger.Error($"agv执行任务启动扫描监听失败:{ex.Message},{ex.StackTrace}"); } } /// /// Agv执行任务 /// private async Task ExecuteTaskAsync() { try { List taskList = sqlSugarClient.Queryable().OrderBy(x => x.CreatedTime).ToList(); foreach (WcsTask item in taskList) { item.UpdatedTime = DateTime.Now; switch (item.TaskType) { //3#车间补四宫格空箱任务 case StaticTaskType.SupplyEmptyPalletTask: SupplyEmptyPalletTaskHandler(item); break; //3#车间从下料点到1-16机台送料任务 case StaticTaskType.TransferMaterialBoxTask: TransferMaterialBoxTaskHandler(item); break; //1-12号机台之间空料箱移库任务 case StaticTaskType.MoveLocationTask: MoveLocationTaskHandler(item); break; //3#接驳位到2#计量室接驳位的送料任务 case StaticTaskType.TransferMaterialMetrologyRoomBoxTask: lock (string.Empty) { TransferMaterialMetrologyRoomBoxTaskHandler(item); } break; //3#车间从2#接驳位补充小托盘任务 case StaticTaskType.SupplySmallPalletTask: await SupplySmallPalletTaskHandlerAsync(item); break; //3#车间从色粉存放点补充小托盘任务 case StaticTaskType.SupplySmallPalletFromTonerTask: await SupplySmallPalletFromTonerTaskHandlerAsync(item); break; // 2#接驳位色粉派送至色粉存放点 case StaticTaskType.DeliverTonerTask: await DeliverTonerTaskHandlerAsync(item); break; //色粉存放点空托盘派送至2#接驳位--暂时不使用 //case StaticTaskType.EmptyReturnFromTonerTask: // await EmptyReturnFromTonerTaskHandlerAsync(item); // break; //四宫格前往异常库位任务处理 case StaticTaskType.ExceptionTask: ExceptionTaskHandler(item); break; default: break; } } } catch (Exception ex) { _logger.Error($"ExecuteTask异常{ex.StackTrace}"); Thread.Sleep(2000); } } #region 不同agv任务处理流程 /// /// 3#车间补四宫格空箱任务处理 /// private void SupplyEmptyPalletTaskHandler(WcsTask task) { try { WcsTaskLog wcsTaskLog = sqlSugarClient.Queryable().First(t => t.Id == task.Id); if (task.TaskStatus == 0) { TaskStatus0Handle(task); } else if (task.TaskStatus == 2) //取完料箱前往目的地 { //解锁起始库位 WmsBaseLocation? startLocation = sqlSugarClient.Queryable().First(t => t.AgvPositionCode == task.CurrPointNo); if (startLocation != null) { startLocation.ContainerCode = ""; startLocation.LocationStatus = 0; task.TaskStatus = 3; if (wcsTaskLog != null) { wcsTaskLog.TaskStatus = task.TaskStatus; } sqlSugarClient.AsTenant().BeginTran(); try { sqlSugarClient.Updateable(startLocation).ExecuteCommand(); sqlSugarClient.Updateable(task).ExecuteCommand(); sqlSugarClient.Updateable(wcsTaskLog).ExecuteCommand(); sqlSugarClient.AsTenant().CommitTran(); } catch (Exception ex) { sqlSugarClient.AsTenant().RollbackTran(); _logger.Error("SupplyEmptyPalletTaskHandlerAsync提交事务异常:" + ex.Message); } } } else if (task.TaskStatus == 4) { if (workShop3Plc == null || !workShop3Plc.IsConnected) { _logger.Plc(DateTime.Now + "3#PLC未连接,请检查网络!"); return; } //通知plc已经放下了料箱 workShop3Plc.writeBoolByAddress(StaticData.GetPlcAddress("3#四宫格空托盘就绪信号"), true); sqlSugarClient.Deleteable(task).ExecuteCommand(); _logger.Agv($"Agv:{task.NextPointNo};完成{task.TaskName},起点:{task.CurrPointNo},终点:{task.EndPointNo}"); } } catch (Exception ex) { _logger.Error("SupplyEmptyPalletTaskHandlerAsync方法异常:" + ex.Message); } } /// /// 3#车间从下料点到1-16机台送料任务 /// /// /// private void TransferMaterialBoxTaskHandler(WcsTask task) { try { WcsTaskLog wcsTaskLog = sqlSugarClient.Queryable().First(t => t.Id == task.Id); if (task.TaskStatus == 0) { TaskStatus0Handle(task); } else if (task.TaskStatus == 2) //取完料箱前往目的地 { //复位清空机台号等信息 if (workShop3Plc == null || !workShop3Plc.IsConnected) { _logger.Plc(DateTime.Now + "3#PLC未连接,请检查网络!"); return; } sqlSugarClient.AsTenant().BeginTran(); try { task.TaskStatus = 3; if (wcsTaskLog != null) { wcsTaskLog.TaskStatus = task.TaskStatus; } sqlSugarClient.Updateable(task).ExecuteCommand(); sqlSugarClient.Updateable(wcsTaskLog).ExecuteCommand(); sqlSugarClient.AsTenant().CommitTran(); //从下料点直接取,清空RFID及机台号,条码等信息--ok workShop3Plc.writeBoolByAddress(StaticData.GetPlcAddress("3#大料箱agv已取走反馈"), true); } catch (Exception ex) { sqlSugarClient.AsTenant().RollbackTran(); _logger.Error("SupplyEmptyPalletTaskHandlerAsync提交事务异常:" + ex.Message); } } else if (task.TaskStatus == 4) { //解锁终点库位 WmsBaseLocation? endLocation = sqlSugarClient.Queryable().First(t => t.AgvPositionCode == task.EndPointNo); if (endLocation != null) { //入库校验RFID string readEpc = ReadEpcStrByRfidKey(endLocation.EquipKey); _logger.Agv($"读到RFID:{readEpc}"); //todo:12号机台装上RFID以后删除-------------------------------- if (endLocation.MachineId == 12) { readEpc = task.PalletInfoCode; } //---------------------------------- if (string.IsNullOrEmpty(readEpc) || readEpc != task.PalletInfoCode) { // workShop3Plc.writeBoolByAddress(StaticData.GetPlcAddress("3#机台校验失败提示"), true); _logger.Error("入库校验RFID失败,当前库位RFID:" + readEpc + ",任务RFID:" + task.PalletInfoCode); return; } endLocation.LocationStatus = 0; endLocation.ContainerCode = task.PalletInfoCode; sqlSugarClient.AsTenant().BeginTran(); try { sqlSugarClient.Updateable(endLocation).ExecuteCommand(); sqlSugarClient.Deleteable(task).ExecuteCommand(); sqlSugarClient.AsTenant().CommitTran(); _logger.Agv($"Agv:{task.NextPointNo};完成{task.TaskName},起点:{task.CurrPointNo},终点:{task.EndPointNo}"); } catch (Exception ex) { sqlSugarClient.AsTenant().RollbackTran(); _logger.Error("SupplyEmptyPalletTaskHandlerAsync提交事务异常:" + ex.Message); } } } } catch (Exception ex) { _logger.Error("SupplyEmptyPalletTaskHandlerAsync方法异常:" + ex.Message); } } /// /// 1-12号机台之间空料箱移库任务 /// /// private void MoveLocationTaskHandler(WcsTask task) { try { WcsTaskLog wcsTaskLog = sqlSugarClient.Queryable().First(t => t.Id == task.Id); if (task.TaskStatus == 0) { TaskStatus0Handle(task); } else if (task.TaskStatus == 2) //取完料箱前往目的地 { //解锁起始库位 WmsBaseLocation? startLocation = sqlSugarClient.Queryable().First(t => t.AgvPositionCode == task.CurrPointNo); if (startLocation != null) { startLocation.ContainerCode = ""; startLocation.LocationStatus = 0; task.TaskStatus = 3; if (wcsTaskLog != null) { wcsTaskLog.TaskStatus = task.TaskStatus; } sqlSugarClient.AsTenant().BeginTran(); try { sqlSugarClient.Updateable(startLocation).ExecuteCommand(); sqlSugarClient.Updateable(task).ExecuteCommand(); sqlSugarClient.Updateable(wcsTaskLog).ExecuteCommand(); sqlSugarClient.AsTenant().CommitTran(); _logger.Agv($"Agv:{task.NextPointNo};完成{task.TaskName},起点:{task.CurrPointNo},终点:{task.EndPointNo}"); } catch (Exception ex) { sqlSugarClient.AsTenant().RollbackTran(); _logger.Error("SupplyEmptyPalletTaskHandlerAsync提交事务异常:" + ex.Message); } } } else if (task.TaskStatus == 4) { //解锁起始库位 WmsBaseLocation? startLocation = sqlSugarClient.Queryable().First(t => t.AgvPositionCode == task.CurrPointNo); startLocation.ContainerCode = ""; startLocation.LocationStatus = 0; //解锁终点库位 WmsBaseLocation? endLocation = sqlSugarClient.Queryable().First(t => t.AgvPositionCode == task.EndPointNo); if (endLocation != null) { endLocation.LocationStatus = 0; endLocation.ContainerCode = task.PalletInfoCode; sqlSugarClient.AsTenant().BeginTran(); try { sqlSugarClient.Updateable(startLocation).ExecuteCommand(); sqlSugarClient.Updateable(endLocation).ExecuteCommand(); sqlSugarClient.Deleteable(task).ExecuteCommand(); sqlSugarClient.AsTenant().CommitTran(); } catch (Exception ex) { sqlSugarClient.AsTenant().RollbackTran(); _logger.Error("SupplyEmptyPalletTaskHandlerAsync提交事务异常:" + ex.Message); } } } } catch (Exception ex) { _logger.Error("SupplyEmptyPalletTaskHandlerAsync方法异常:" + ex.Message); } } /// /// 四宫格前往异常库位任务处理 /// /// private void ExceptionTaskHandler(WcsTask task) { try { WcsTaskLog wcsTaskLog = sqlSugarClient.Queryable().First(t => t.Id == task.Id); if (task.TaskStatus == 0) { TaskStatus0Handle(task); } else if (task.TaskStatus == 2) //取完料箱前往目的地 { //解锁终点库位 WmsBaseLocation? start = sqlSugarClient.Queryable().Where(t => t.AgvPositionCode == task.EndPointNo).First(); if (start != null) { start.LocationStatus = 0; start.ContainerCode = ""; sqlSugarClient.Updateable(start).ExecuteCommand(); } task.TaskStatus = 3; if (wcsTaskLog != null) { wcsTaskLog.TaskStatus = task.TaskStatus; } sqlSugarClient.AsTenant().BeginTran(); try { sqlSugarClient.Updateable(task).ExecuteCommand(); sqlSugarClient.Updateable(wcsTaskLog).ExecuteCommand(); sqlSugarClient.AsTenant().CommitTran(); _logger.Agv($"Agv:{task.NextPointNo};完成{task.TaskName},起点:{task.CurrPointNo},终点:{task.EndPointNo}"); } catch (Exception ex) { sqlSugarClient.AsTenant().RollbackTran(); _logger.Error("ExceptionTaskHandler提交事务异常:" + ex.Message); } } else if (task.TaskStatus == 4) { //解锁终点库位 WmsBaseLocation? endLocation = sqlSugarClient.Queryable().First(t => t.AgvPositionCode == task.EndPointNo); if (endLocation != null) { endLocation.LocationStatus = 0; endLocation.ContainerCode = task.PalletInfoCode; sqlSugarClient.AsTenant().BeginTran(); try { sqlSugarClient.Updateable(endLocation).ExecuteCommand(); sqlSugarClient.Deleteable(task).ExecuteCommand(); sqlSugarClient.AsTenant().CommitTran(); } catch (Exception ex) { sqlSugarClient.AsTenant().RollbackTran(); _logger.Error("SupplyEmptyPalletTaskHandlerAsync提交事务异常:" + ex.Message); } } } } catch (Exception ex) { _logger.Error("SupplyEmptyPalletTaskHandlerAsync方法异常:" + ex.Message); } } /// /// 3#接驳位到2#计量室接驳位的送料任务 /// /// private void TransferMaterialMetrologyRoomBoxTaskHandler(WcsTask task) { try { WcsTaskLog wcsTaskLog = sqlSugarClient.Queryable().First(t => t.Id == task.Id); if (task.TaskStatus == 0) { TaskStatus0Handle(task); } else if (task.TaskStatus == 2) //agv到达接驳位里面,等待料箱上agv { if (workShop3Plc == null || !workShop3Plc.IsConnected) { _logger.Plc(DateTime.Now + "3#PLC未连接,请检查网络!"); return; } bool goOutFlag = workShop3Plc.readBoolByAddress(StaticData.GetPlcAddress("3#出接驳位信号")); int outFlag = workShop3Plc.readInt16ByAddress(StaticData.GetPlcAddress("3#接驳位到位信号")); if (outFlag != 1 && !goOutFlag) { workShop3Plc.writeBoolByAddress(StaticData.GetPlcAddress("3#出接驳位信号"), true); } else if (outFlag == 1) { //已经出来就绪,wcs通知agv取走托盘 bool result = ContinueTaskHandle(task).Result; if (result) { //从下料点直接取,清空RFID及机台号,条码等信息--ok workShop3Plc.writeInt16ByAddress(StaticData.GetPlcAddress("3#接驳位到位信号"), 0); workShop3Plc.writeBoolByAddress(StaticData.GetPlcAddress("3#出接驳位信号"), false); workShop3Plc.writeBoolByAddress(StaticData.GetPlcAddress("3#小料箱agv已取走反馈"), true); _logger.Agv($"agv取走料{task.PalletInfoCode},3#已取走反馈"); } } } else if (task.TaskStatus == 4) //agv已经退出接驳位,wcs把 线体忙碌状态改为0,接驳位到位信号 复位写0,出接驳位信号 0,清空RFID、机台号 { if (workShop3Plc == null || !workShop3Plc.IsConnected) { _logger.Plc(DateTime.Now + "3#PLC未连接,请检查网络!"); return; } sqlSugarClient.AsTenant().BeginTran(); try { task.TaskStatus = 5; task.UpdatedTime = DateTime.Now; if (wcsTaskLog != null) { wcsTaskLog.TaskStatus = task.TaskStatus; wcsTaskLog.UpdatedTime = DateTime.Now; } sqlSugarClient.Updateable(task).ExecuteCommand(); sqlSugarClient.Updateable(wcsTaskLog).ExecuteCommand(); sqlSugarClient.AsTenant().CommitTran(); } catch (Exception ex) { sqlSugarClient.AsTenant().RollbackTran(); _logger.Error("TransferMaterialMetrologyRoomBoxTaskHandlerAsync提交事务异常:" + ex.Message); } } else if (task.TaskStatus == 6) //agv到达终点等待点,判断 2#线体忙碌状态 ,下发agv进入接驳位 { if (workShop2Plc == null || !workShop2Plc.IsConnected) { _logger.Plc(DateTime.Now + "2#PLC未连接,请检查网络!"); return; } int busyFlag = workShop2Plc.readInt16ByAddress(StaticData.GetPlcAddress("2#线体忙碌状态")); if (busyFlag == 1) { return; } if (busyFlag == 0) { int amount = sqlSugarClient.Queryable().Where(x => x.TaskType == StaticTaskType.TransferMaterialMetrologyRoomBoxTask).Count(); int hoistFloor = workShop2Plc.readInt16ByAddress(StaticData.GetPlcAddress("2#提升机当前层")); if (hoistFloor == 2) //如果提升机正好在2楼 { Thread.Sleep(300); } else if (amount < 2) //如果只有一个agv送料任务 { Thread.Sleep(2500); } else if (amount == 2) {//如果有两个以上agv送料任务,释放掉一个agv Thread.Sleep(500); } int work2LineBusyFlag = workShop2Plc.readInt16ByAddress(StaticData.GetPlcAddress("2#缓存空箱线体状态")); busyFlag = workShop2Plc.readInt16ByAddress(StaticData.GetPlcAddress("2#线体忙碌状态")); if (busyFlag == 0 && work2LineBusyFlag == 0) { //抢占线体状态,agv进入接驳位 workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#线体忙碌状态"), 1); workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#缓存空箱线体状态"), 1); bool result = ContinueTaskHandle(task).Result; if (!result) { workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#线体忙碌状态"), 0); } else //下发agv成功以后,提前写去往计量室,预调度提升机 { workShop2Plc.writeBoolByAddress(StaticData.GetPlcAddress("2#前往计量室信号"), true); } } } } else if (task.TaskStatus == 8) //agv到达终点接驳位,等待料箱离开接驳位 { if (workShop2Plc == null || !workShop2Plc.IsConnected) { _logger.Plc(DateTime.Now + "2#PLC未连接,请检查网络!"); return; } bool goOutFlag = workShop2Plc.readBoolByAddress(StaticData.GetPlcAddress("2#放完成反馈")); // 2#已离开接驳位信号:有料箱true;无料箱false bool outFlag = workShop2Plc.readBoolByAddress(StaticData.GetPlcAddress("2#已离开接驳位信号")); if (!outFlag && !goOutFlag) { workShop2Plc.writeBoolByAddress(StaticData.GetPlcAddress("2#放完成"), true); } else if (outFlag) { //托盘已经离开,wcs通知agv离开 bool result = ContinueTaskHandle(task).Result; if (result) //已经离开 { workShop2Plc.writeBoolByAddress(StaticData.GetPlcAddress("2#放完成反馈"), false); } } } else if (task.TaskStatus == 10) //任务完成,删除任务 { //删除任务 sqlSugarClient.Deleteable(task).ExecuteCommand(); _logger.Agv($"Agv:{task.NextPointNo};完成{task.TaskName},起点:{task.CurrPointNo},终点:{task.EndPointNo}"); } } catch (Exception ex) { _logger.Error("SupplyEmptyPalletTaskHandlerAsync方法异常:" + ex.Message); } } /// /// 3#车间从2#接驳位补充小托盘任务 /// /// /// private async Task SupplySmallPalletTaskHandlerAsync(WcsTask task) { try { WcsTaskLog wcsTaskLog = await sqlSugarClient.Queryable().FirstAsync(t => t.Id == task.Id); if (task.TaskStatus == 0) { TaskStatus0Handle(task); } else if (task.TaskStatus == 2) //agv到达接驳位里面,等待料箱上agv { if (workShop2Plc == null || !workShop2Plc.IsConnected) { _logger.Plc(DateTime.Now + "2#PLC未连接,请检查网络!"); return; } bool goOutFlag = workShop2Plc.readBoolByAddress(StaticData.GetPlcAddress("2#缓存空进AGV任务反馈")); bool outFlag = workShop2Plc.readBoolByAddress(StaticData.GetPlcAddress("2#接驳位到位信号")); if (!outFlag && !goOutFlag) { workShop2Plc.writeBoolByAddress(StaticData.GetPlcAddress("2#出一个空托盘信号"), true); } else if (outFlag) { //已经出来就绪,wcs通知agv取走托盘 bool agvResult = await ContinueTaskHandle(task); if (agvResult) { workShop2Plc.writeBoolByAddress(StaticData.GetPlcAddress("2#取完成"), true); workShop2Plc.writeBoolByAddress(StaticData.GetPlcAddress("2#接驳位到位信号"), false); workShop2Plc.writeBoolByAddress(StaticData.GetPlcAddress("2#缓存空进AGV任务反馈"), false); workShop2Plc.writeBoolByAddress(StaticData.GetPlcAddress("2#出接驳位信号"), false); workShop2Plc.writeBoolByAddress(StaticData.GetPlcAddress("2#出一个空托盘信号"), false); //判断二次生成补空箱任务 Thread.Sleep(500); CreateSecondSuppleSmallPallet(); } } } else if (task.TaskStatus == 4) //agv已经退出接驳位,wcs把 线体忙碌状态改为0,接驳位到位信号 复位写0,出接驳位信号 0,清空RFID、机台号 { if (workShop2Plc == null || !workShop2Plc.IsConnected) { _logger.Plc(DateTime.Now + "2#PLC未连接,请检查网络!"); return; } sqlSugarClient.AsTenant().BeginTran(); try { task.TaskStatus = 5; task.UpdatedTime = DateTime.Now; if (wcsTaskLog != null) { wcsTaskLog.TaskStatus = task.TaskStatus; wcsTaskLog.UpdatedTime = DateTime.Now; } sqlSugarClient.Updateable(task).ExecuteCommand(); sqlSugarClient.Updateable(wcsTaskLog).ExecuteCommand(); sqlSugarClient.AsTenant().CommitTran(); } catch (Exception ex) { sqlSugarClient.AsTenant().RollbackTran(); _logger.Error("TransferMaterialMetrologyRoomBoxTaskHandlerAsync提交事务异常:" + ex.Message); } } else if (task.TaskStatus == 6) //agv到达终点等待点,判断 3#线体忙碌状态 ,下发agv进入接驳位 { if (workShop3Plc == null || !workShop3Plc.IsConnected) { _logger.Plc(DateTime.Now + "2#PLC未连接,请检查网络!"); return; } int busyFlag = workShop3Plc.readInt16ByAddress(StaticData.GetPlcAddress("3#线体忙碌状态")); if (busyFlag == 1) { return; } if (busyFlag == 0) { Thread.Sleep(1000); busyFlag = workShop3Plc.readInt16ByAddress(StaticData.GetPlcAddress("3#线体忙碌状态")); if (busyFlag == 0) { //抢占线体状态,agv进入接驳位 workShop3Plc.writeInt16ByAddress(StaticData.GetPlcAddress("3#线体忙碌状态"), 1); bool result = await ContinueTaskHandle(task); if (!result) { workShop3Plc.writeInt16ByAddress(StaticData.GetPlcAddress("3#线体忙碌状态"), 0); } } } } else if (task.TaskStatus == 8) //agv到达终点接驳位,等待料箱离开接驳位 { if (workShop3Plc == null || !workShop3Plc.IsConnected) { _logger.Plc(DateTime.Now + "3#PLC未连接,请检查网络!"); return; } bool goOutFlag = workShop3Plc.readBoolByAddress(StaticData.GetPlcAddress("3#前往缓存皮带线")); int outFlag = workShop3Plc.readInt16ByAddress(StaticData.GetPlcAddress("3#已离开接驳位信号")); if (outFlag != 1 && !goOutFlag) { workShop3Plc.writeBoolByAddress(StaticData.GetPlcAddress("3#前往缓存皮带线"), true); } else if (outFlag == 1) { //托盘已经离开,wcs通知agv离开 bool result = await ContinueTaskHandle(task); if (result) { //从下料点直接取,清空RFID及机台号,条码等信息--ok workShop3Plc.writeInt16ByAddress(StaticData.GetPlcAddress("3#接驳位到位信号"), 0); workShop3Plc.writeBoolByAddress(StaticData.GetPlcAddress("3#出接驳位信号"), false); workShop3Plc.writeBoolByAddress(StaticData.GetPlcAddress("3#小料箱agv已取走反馈"), true); } } } else if (task.TaskStatus == 10) //任务完成,wcs复位3#接驳位信号,删除任务 { if (workShop3Plc == null || !workShop3Plc.IsConnected) { _logger.Plc(DateTime.Now + "2#PLC未连接,请检查网络!"); return; } //从下料点直接取,清空RFID及机台号,条码等信息--ok workShop3Plc.writeBoolByAddress(StaticData.GetPlcAddress("3#前往缓存皮带线"), false); workShop3Plc.writeInt16ByAddress(StaticData.GetPlcAddress("3#已离开接驳位信号"), 0); //删除任务 sqlSugarClient.Deleteable(task).ExecuteCommand(); _logger.Agv($"Agv:{task.NextPointNo};完成{task.TaskName},起点:{task.CurrPointNo},终点:{task.EndPointNo}"); } } catch (Exception ex) { _logger.Error("SupplyEmptyPalletTaskHandlerAsync方法异常:" + ex.Message); } } /// ///3#车间从色粉存放点补充小托盘任务 /// /// /// private async Task SupplySmallPalletFromTonerTaskHandlerAsync(WcsTask task) { try { WcsTaskLog wcsTaskLog = await sqlSugarClient.Queryable().FirstAsync(t => t.Id == task.Id); if (task.TaskStatus == 0) { TaskStatus0Handle(task); } else if (task.TaskStatus == 2) //取完料箱前往目的地 { if (baseEquip != null) { sqlSugarClient.AsTenant().BeginTran(); try { task.TaskStatus = 3; if (wcsTaskLog != null) { wcsTaskLog.TaskStatus = task.TaskStatus; } sqlSugarClient.Updateable(task).ExecuteCommand(); sqlSugarClient.Updateable(wcsTaskLog).ExecuteCommand(); sqlSugarClient.AsTenant().CommitTran(); } catch (Exception ex) { sqlSugarClient.AsTenant().RollbackTran(); _logger.Error("SupplyEmptyPalletTaskHandlerAsync提交事务异常:" + ex.Message); } } } else if (task.TaskStatus == 4) { if (workShop3Plc == null || !workShop3Plc.IsConnected) { _logger.Plc(DateTime.Now + "2#PLC未连接,请检查网络!"); return; } int busyFlag = workShop3Plc.readInt16ByAddress(StaticData.GetPlcAddress("3#线体忙碌状态")); if (busyFlag == 1) { return; } if (busyFlag == 0) { Thread.Sleep(1000); busyFlag = workShop3Plc.readInt16ByAddress(StaticData.GetPlcAddress("3#线体忙碌状态")); if (busyFlag == 0) { //抢占线体状态,agv进入接驳位 workShop3Plc.writeInt16ByAddress(StaticData.GetPlcAddress("3#线体忙碌状态"), 1); bool result = await ContinueTaskHandle(task); if (result) { //解锁起始色粉库位 WcsBaseEquip? baseEquip = sqlSugarClient.Queryable().First(t => t.AgvPositionCode == task.CurrPointNo); if (baseEquip != null) { baseEquip.EquipStatus = 0; baseEquip.ContainerCode = null; sqlSugarClient.Updateable(baseEquip).ExecuteCommand(); } } else //下发任务继续失败 { workShop3Plc.writeInt16ByAddress(StaticData.GetPlcAddress("3#线体忙碌状态"), 0); } } } } else if (task.TaskStatus == 6) //agv到达终点接驳位,等待料箱离开接驳位 { if (workShop3Plc == null || !workShop3Plc.IsConnected) { _logger.Plc(DateTime.Now + "3#PLC未连接,请检查网络!"); return; } bool goOutFlag = workShop3Plc.readBoolByAddress(StaticData.GetPlcAddress("3#前往缓存皮带线")); int outFlag = workShop3Plc.readInt16ByAddress(StaticData.GetPlcAddress("3#已离开接驳位信号")); if (outFlag != 1 && !goOutFlag) { workShop3Plc.writeBoolByAddress(StaticData.GetPlcAddress("3#前往缓存皮带线"), true); } else if (outFlag == 1) { //托盘已经离开,wcs通知agv离开 await ContinueTaskHandle(task); } } else if (task.TaskStatus == 8) //任务完成,wcs复位3#接驳位信号,删除任务 { if (workShop3Plc == null || !workShop3Plc.IsConnected) { _logger.Plc(DateTime.Now + "2#PLC未连接,请检查网络!"); return; } //从下料点直接取,清空RFID及机台号,条码等信息--ok workShop3Plc.writeBoolByAddress(StaticData.GetPlcAddress("3#前往缓存皮带线"), false); workShop3Plc.writeInt16ByAddress(StaticData.GetPlcAddress("3#已离开接驳位信号"), 0); //plc复位 //删除任务 sqlSugarClient.Deleteable(task).ExecuteCommand(); _logger.Agv($"Agv:{task.NextPointNo};完成{task.TaskName},起点:{task.CurrPointNo},终点:{task.EndPointNo}"); } } catch (Exception ex) { _logger.Error("SupplyEmptyPalletTaskHandlerAsync方法异常:" + ex.Message); } } /// ///2#接驳位色粉派送至色粉存放点 /// /// /// private async Task DeliverTonerTaskHandlerAsync(WcsTask task) { try { WcsTaskLog wcsTaskLog = await sqlSugarClient.Queryable().FirstAsync(t => t.Id == task.Id); if (task.TaskStatus == 0) { TaskStatus0Handle(task); } else if (task.TaskStatus == 2) //agv到达接驳位里面,等待料箱上agv { if (workShop2Plc == null || !workShop2Plc.IsConnected) { _logger.Plc(DateTime.Now + "2#PLC未连接,请检查网络!"); return; } bool PalletReady = workShop2Plc.readBoolByAddress(StaticData.GetPlcAddress("2#色粉返回等待agv到位信号")); if (!PalletReady) { _logger.Plc(DateTime.Now + "等待色粉托盘到达接驳位移栽"); return; } bool goOutFlag = workShop2Plc.readBoolByAddress(StaticData.GetPlcAddress("2#出接驳位信号")); bool outFlag = workShop2Plc.readBoolByAddress(StaticData.GetPlcAddress("2#接驳位到位信号")); if (!outFlag && !goOutFlag) { workShop2Plc.writeBoolByAddress(StaticData.GetPlcAddress("2#出接驳位信号"), true); } else if (outFlag) { bool agvResult = await ContinueTaskHandle(task); if (agvResult) { workShop2Plc.writeBoolByAddress(StaticData.GetPlcAddress("2#取完成"), true); workShop2Plc.writeBoolByAddress(StaticData.GetPlcAddress("2#色粉返回等待agv到位信号"), false); workShop2Plc.writeBoolByAddress(StaticData.GetPlcAddress("2#接驳位到位信号"), false); workShop2Plc.writeBoolByAddress(StaticData.GetPlcAddress("2#出接驳位信号"), false); } } } else if (task.TaskStatus == 4) //agv已经退出接驳位,wcs把 线体忙碌状态改为0,接驳位到位信号 复位写0,出接驳位信号 0,清空RFID、机台号 { if (workShop2Plc == null || !workShop2Plc.IsConnected) { _logger.Plc(DateTime.Now + "2#PLC未连接,请检查网络!"); return; } //workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#线体忙碌状态"), 0); //解锁起始库位忙碌状态 WcsBaseEquip? startEquip = sqlSugarClient.Queryable().First(it => it.AgvPositionCode == task.CurrPointNo); sqlSugarClient.AsTenant().BeginTran(); try { if (startEquip != null) { startEquip.EquipStatus = 0; sqlSugarClient.Updateable(startEquip).ExecuteCommand(); } task.TaskStatus = 5; task.UpdatedTime = DateTime.Now; if (wcsTaskLog != null) { wcsTaskLog.TaskStatus = task.TaskStatus; wcsTaskLog.UpdatedTime = DateTime.Now; } sqlSugarClient.Updateable(task).ExecuteCommand(); sqlSugarClient.Updateable(wcsTaskLog).ExecuteCommand(); sqlSugarClient.AsTenant().CommitTran(); } catch (Exception ex) { sqlSugarClient.AsTenant().RollbackTran(); _logger.Error("DeliverTonerTaskHandlerAsync提交事务异常:" + ex.Message); } } else if (task.TaskStatus == 6) //任务结束 { //更新终点库位信息 WcsBaseEquip? baseEquip = sqlSugarClient.Queryable().First(it => it.AgvPositionCode == task.EndPointNo); sqlSugarClient.AsTenant().BeginTran(); try { if (baseEquip != null) { baseEquip.EquipStatus = 0; baseEquip.ContainerCode = task.PalletInfoCode; sqlSugarClient.Updateable(baseEquip).ExecuteCommand(); } //删除任务 sqlSugarClient.Deleteable(task).ExecuteCommand(); sqlSugarClient.AsTenant().CommitTran(); _logger.Agv($"Agv:{task.NextPointNo};完成{task.TaskName},起点:{task.CurrPointNo},终点:{task.EndPointNo}"); } catch (Exception ex) { sqlSugarClient.AsTenant().RollbackTran(); _logger.Error("DeliverTonerTaskHandlerAsync提交事务异常:" + ex.Message); } } } catch (Exception ex) { _logger.Error("DeliverTonerTaskHandlerAsync方法异常:" + ex.Message); } } /// ///色粉存放点空托盘派送至2#接驳位---暂不使用 /// /// /// private async Task EmptyReturnFromTonerTaskHandlerAsync(WcsTask task) { try { WcsTaskLog wcsTaskLog = await sqlSugarClient.Queryable().FirstAsync(t => t.Id == task.Id); if (task.TaskStatus == 0) { TaskStatus0Handle(task); } else if (task.TaskStatus == 2) //取完料箱前往目的地 { //解锁起始库位 WcsBaseEquip? baseEquip = sqlSugarClient.Queryable().First(t => t.AgvPositionCode == task.CurrPointNo); if (baseEquip != null) { sqlSugarClient.AsTenant().BeginTran(); try { baseEquip.EquipStatus = 0; baseEquip.ContainerCode = null; task.TaskStatus = 3; if (wcsTaskLog != null) { wcsTaskLog.TaskStatus = task.TaskStatus; } sqlSugarClient.Updateable(baseEquip).ExecuteCommand(); sqlSugarClient.Updateable(task).ExecuteCommand(); sqlSugarClient.Updateable(wcsTaskLog).ExecuteCommand(); sqlSugarClient.AsTenant().CommitTran(); } catch (Exception ex) { sqlSugarClient.AsTenant().RollbackTran(); _logger.Error("SupplyEmptyPalletTaskHandlerAsync提交事务异常:" + ex.Message); } } } else if (task.TaskStatus == 4) //等待点 { if (workShop2Plc == null || !workShop2Plc.IsConnected) { _logger.Plc(DateTime.Now + "2#PLC未连接,请检查网络!"); return; } int busyFlag = workShop2Plc.readInt16ByAddress(StaticData.GetPlcAddress("2#线体忙碌状态")); if (busyFlag == 1) { return; } if (busyFlag == 0) { Thread.Sleep(1000); busyFlag = workShop2Plc.readInt16ByAddress(StaticData.GetPlcAddress("2#线体忙碌状态")); if (busyFlag == 0) { //抢占线体状态,agv进入接驳位 workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#线体忙碌状态"), 1); await ContinueTaskHandle(task); } } } else if (task.TaskStatus == 6) //agv到达终点接驳位,等待料箱离开接驳位 { if (workShop2Plc == null || !workShop2Plc.IsConnected) { _logger.Plc(DateTime.Now + "2#PLC未连接,请检查网络!"); return; } int goOutFlag = workShop2Plc.readInt16ByAddress(StaticData.GetPlcAddress("2#前往缓存链条线")); bool outFlag = workShop2Plc.readBoolByAddress(StaticData.GetPlcAddress("2#已离开接驳位信号")); if (!outFlag && goOutFlag != 1) { workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#前往缓存链条线"), 1); } else if (outFlag) { //托盘已经离开,wcs通知agv离开 await ContinueTaskHandle(task); } } else if (task.TaskStatus == 8) //任务完成,wcs复位2#接驳位信号,删除任务 { if (workShop2Plc == null || !workShop2Plc.IsConnected) { _logger.Plc(DateTime.Now + "2#PLC未连接,请检查网络!"); return; } workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#前往缓存链条线"), 0); //plc复位 //workShop3Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#线体忙碌状态"), 0); //删除任务 sqlSugarClient.Deleteable(task).ExecuteCommand(); _logger.Agv($"Agv:{task.NextPointNo};完成{task.TaskName},起点:{task.CurrPointNo},终点:{task.EndPointNo}"); } } catch (Exception ex) { _logger.Error("SupplyEmptyPalletTaskHandlerAsync方法异常:" + ex.Message); } } #endregion 不同agv任务处理流程 #region 任务状态流转处理逻辑 /// /// 任务状态0-1下发处理逻辑 /// /// /// private void TaskStatus0Handle(WcsTask item) { lock (string.Empty) { try { WcsTaskLog wcsTaskLog = sqlSugarClient.Queryable().First(t => t.Id == item.Id); WcsBaseDictionary wcsBaseDictionary = sqlSugarClient.Queryable().Where(x => x.Id == item.TaskType).First(); var agvTask = new RequestAGVTaskDto { reqCode = StaticData.SnowId.NextId().ToString(), positionCodePath = GetPositionPath(item.CurrPointNo, item.EndPointNo, wcsBaseDictionary.DicValue, item.TaskType), taskTyp = wcsBaseDictionary.DicValue, ctnrTyp = "2", }; if (item.TaskType == StaticTaskType.ExceptionTask && string.IsNullOrEmpty(item.NextPointNo)) { //如果是异常任务,必须指定具体agv前往异常库位 agvTask.agvCode = item.NextPointNo; } string message = JsonConvert.SerializeObject(agvTask); string result = HttpHelper.SendPostMessage(baseEquip.ServerIp, baseEquip.ServerPort, "rcms/services/rest/hikRpcService/genAgvSchedulingTask", message); var reponseMessage = JsonConvert.DeserializeObject(result); if (reponseMessage != null && reponseMessage.code == "0") { sqlSugarClient.AsTenant().BeginTran(); try { _logger.Agv($"AGV下发任务" + item.CurrPointNo + "," + item.EndPointNo); item.TaskCode = reponseMessage.data; item.TaskStatus = 1; sqlSugarClient.Updateable(item).ExecuteCommand(); wcsTaskLog.UpdatedTime = DateTime.Now; wcsTaskLog.TaskStatus = 1; sqlSugarClient.Updateable(wcsTaskLog).ExecuteCommand(); sqlSugarClient.AsTenant().CommitTran(); } catch (Exception ex) { sqlSugarClient.AsTenant().RollbackTran(); _logger.Error($"TaskStatus0Handle提交事务异常{ex.StackTrace}"); } } else { _logger.Error($"下发小车任务失败" + result); } } catch (Exception ex) { _logger.Error($"执行任务异常{ex.StackTrace}"); } } } /// /// 根据不同任务模版获取路径 /// /// /// /// /// private List GetPositionPath(string currPointNo, string endPointNo, string dicValue, int taskType) { List PathList = new List(); if (dicValue == "DLX") //大料箱只需要起点、终点 { PathList.Add(new Position { positionCode = currPointNo, type = "00" }); PathList.Add(new Position { positionCode = endPointNo, type = "00" }); } else if (dicValue == "XLXQL" && taskType == StaticTaskType.SupplySmallPalletTask) //2#->3#小料箱空满交换取料配送流程 { PathList.Add(new Position { positionCode = "2SmallOut", type = "00" }); PathList.Add(new Position { positionCode = "2DeliverMetrologyRoomPoint", type = "00" }); PathList.Add(new Position { positionCode = "2DeliverMetrologyRoomPoint", type = "00" }); PathList.Add(new Position { positionCode = "3DeliverSmallGoodsPoint", type = "00" }); PathList.Add(new Position { positionCode = "3DeliverSmallGoodsPoint", type = "00" }); PathList.Add(new Position { positionCode = "3SmallOut", type = "00" }); } else if (dicValue == "XLXQL" && taskType == StaticTaskType.TransferMaterialMetrologyRoomBoxTask) //3#->2#小料箱空满交换取料配送流程 { PathList.Add(new Position { positionCode = "3SmallOut", type = "00" }); PathList.Add(new Position { positionCode = "3DeliverSmallGoodsPoint", type = "00" }); PathList.Add(new Position { positionCode = "3DeliverSmallGoodsPoint", type = "00" }); PathList.Add(new Position { positionCode = "2DeliverMetrologyRoomPoint", type = "00" }); PathList.Add(new Position { positionCode = "2DeliverMetrologyRoomPoint", type = "00" }); PathList.Add(new Position { positionCode = "2SmallOut", type = "00" }); } else if (dicValue == "XLXSFQL") //从2#接驳位取色粉箱运送到色粉存放点流程 { PathList.Add(new Position { positionCode = "2SmallOut", type = "00" }); PathList.Add(new Position { positionCode = "2DeliverMetrologyRoomPoint", type = "00" }); PathList.Add(new Position { positionCode = "2DeliverMetrologyRoomPoint", type = "00" }); PathList.Add(new Position { positionCode = endPointNo, type = "00" }); } else if (dicValue == "XLXKXPS") { //从色粉存放点取空料箱配送到3#接驳位 if (taskType == StaticTaskType.SupplySmallPalletFromTonerTask) { PathList.Add(new Position { positionCode = currPointNo, type = "00" }); PathList.Add(new Position { positionCode = "3SmallWait", type = "00" }); PathList.Add(new Position { positionCode = endPointNo, type = "00" }); PathList.Add(new Position { positionCode = endPointNo, type = "00" }); PathList.Add(new Position { positionCode = "3SmallOut", type = "00" }); } else if (taskType == StaticTaskType.EmptyReturnFromTonerTask) //从色粉存放点取空料箱配送到2#接驳位 { PathList.Add(new Position { positionCode = currPointNo, type = "00" }); PathList.Add(new Position { positionCode = "2SmallWait", type = "00" }); PathList.Add(new Position { positionCode = endPointNo, type = "00" }); PathList.Add(new Position { positionCode = endPointNo, type = "00" }); PathList.Add(new Position { positionCode = "2SmallOut", type = "00" }); } } return PathList; } /// ///下发agv任务继续 /// /// private async Task ContinueTaskHandle(WcsTask task) { bool continueResult = false; try { WcsTaskLog wcsTaskLog = await sqlSugarClient.Queryable().FirstAsync(t => t.Id == task.Id); #region 下发AGV信号放料箱 //条件过滤,能取托盘或能取料 ,发送agv继续信号 var agvTask = new RequestAGVTaskDto { reqCode = StaticData.SnowId.NextId().ToString(), taskCode = task.TaskCode }; string message = JsonConvert.SerializeObject(agvTask); try { string result = HttpHelper.SendPostMessage(baseEquip.ServerIp, baseEquip.ServerPort, "rcms/services/rest/hikRpcService/continueTask", message); ReponseMessage? reponseMessage = JsonConvert.DeserializeObject(result); if (reponseMessage != null && reponseMessage.message == "成功") { sqlSugarClient.AsTenant().BeginTran(); _logger.Agv($"下发agv任务继续,任务名称:{task.TaskName},任务id:{task.Id},任务状态:{task.TaskStatus}"); task.TaskStatus += 1; task.UpdatedTime = DateTime.Now; sqlSugarClient.Updateable(task).ExecuteCommand(); if (wcsTaskLog != null) { wcsTaskLog.UpdatedTime = DateTime.Now; wcsTaskLog.TaskStatus = task.TaskStatus; sqlSugarClient.Updateable(wcsTaskLog).ExecuteCommand(); } sqlSugarClient.AsTenant().CommitTran(); continueResult = true; } } catch (Exception ex) { _logger.Error($"第一次下发agv任务继续异常,任务名称:{task.TaskName},任务id:{task.Id},异常信息:{ex.StackTrace}"); _logger.Error("开始尝试第二次下发"); await Task.Delay(1000 * 2); string result = HttpHelper.SendPostMessage(baseEquip.ServerIp, baseEquip.ServerPort, "rcms/services/rest/hikRpcService/continueTask", message); ReponseMessage? reponseMessage = JsonConvert.DeserializeObject(result); if (reponseMessage != null && reponseMessage.message == "成功") { sqlSugarClient.AsTenant().BeginTran(); _logger.Agv($"下发agv任务继续,任务名称:{task.TaskName},任务id:{task.Id},任务状态:{task.TaskStatus}"); task.TaskStatus += 1; task.UpdatedTime = DateTime.Now; sqlSugarClient.Updateable(task).ExecuteCommand(); if (wcsTaskLog != null) { wcsTaskLog.UpdatedTime = DateTime.Now; wcsTaskLog.TaskStatus = task.TaskStatus; sqlSugarClient.Updateable(wcsTaskLog).ExecuteCommand(); } sqlSugarClient.AsTenant().CommitTran(); continueResult = true; } else { _logger.Error($"下发第二次agv任务继续失败,任务名称:{task.TaskName},任务id:{task.Id},异常信息:{ex.StackTrace}"); } } #endregion 下发AGV信号放料箱 } catch (Exception ex) { _logger.Error($"下发agv任务第二次继续异常,任务名称:{task.TaskName},任务id:{task.Id},异常信息:{ex.StackTrace}"); } return continueResult; } #endregion 任务状态流转处理逻辑 /// /// 在从2#接驳位补托盘退出1s以后,判断如果3#库存为0,并且补小托盘任务数只有1个,总的agv任务书小于3个,并且2#线体空闲并且库存大于0, /// 那么再次生成从2#接驳位补充空托盘任务,同时锁住2#线体 /// private void CreateSecondSuppleSmallPallet() { try { if (workShop3Plc == null || !workShop3Plc.IsConnected || workShop2Plc == null || !workShop2Plc.IsConnected) { return; } int work3EmptyAmount = workShop3Plc.readInt16ByAddress(StaticData.GetPlcAddress("3#缓存皮带线库存数")); int suppleTaskCount = sqlSugarClient.Queryable().Where(x => x.TaskType == StaticTaskType.SupplySmallPalletFromTonerTask || x.TaskType == StaticTaskType.SupplySmallPalletTask).Count(); int totalTaskCount = sqlSugarClient.Queryable().Count(); int work2EmptyAmount = workShop2Plc.readInt16ByAddress(StaticData.GetPlcAddress("2#缓存链条线库存数")); int work2LineBusyFlag = workShop2Plc.readInt16ByAddress(StaticData.GetPlcAddress("2#缓存空箱线体状态")); if (work3EmptyAmount == 0 && totalTaskCount < 3 && suppleTaskCount == 1 && work2LineBusyFlag == 0 && work2EmptyAmount > 0) { workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#缓存空箱线体状态"), 1); WcsTask task = new WcsTask(); task.TaskType = StaticTaskType.SupplySmallPalletTask; task.CurrPointNo = "2DeliverMetrologyRoomPoint"; task.EndPointNo = "3DeliverSmallGoodsPoint"; task.TaskStatus = 0; task.CreatedTime = DateTime.Now; task.CreatedBy = "wcs"; task.TaskName = " 3#车间从2#接驳位补充小托盘任务"; sqlSugarClient.AsTenant().BeginTran(); try { int id = sqlSugarClient.Insertable(task).ExecuteReturnIdentity(); WcsTaskLog wcsTaskLog = CoreMapper.Map(task); wcsTaskLog.Id = id; sqlSugarClient.Insertable(wcsTaskLog).ExecuteCommand(); sqlSugarClient.AsTenant().CommitTran(); } catch (Exception ex) { sqlSugarClient.AsTenant().RollbackTran(); workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#缓存空箱线体状态"), 0); _logger.Error($"3#车间从2#接驳位补充小托盘任务生成提交事务异常{ex.Message}"); } _logger.Agv($"生成{task.TaskName},起点:{task.CurrPointNo},终点:{task.EndPointNo}"); } } catch (Exception ex) { _logger.Error($"CreateSecondSuppleSmallPallet:{ex.Message}"); } } #region 弃用逻辑 ///// ///// ///// 任务状态3-4处理逻辑:agv取完托盘,给起点复位状态 ///// 分不同任务类型,各自根据判断条件处理 ///// ///// ///// //private async Task TaskStatus3HandleAsync(WcsTask item) //{ // try // { // sqlSugarClient.AsTenant().BeginTran(); // WcsTaskLog wcsTaskLog = sqlSugarClient.Queryable().First(t => t.Id == item.Id); // if (item.TaskType == StaticTaskType.SupplyEmptyPalletTask) // { // //不做处理--ok // } // else if (item.TaskType == StaticTaskType.MoveLocationTask) // { // // 不做处理--ok // } // else if (item.TaskType == StaticTaskType.TransferMaterialBoxTask) // { // //从下料点直接取,清空RFID及机台号,条码等信息--ok // workShop3Plc.writeInt16ByAddress(StaticData.GetPlcAddress("3#下料点机台号"), 0); // workShop3Plc.writeStringByAddress(StaticData.GetPlcAddress("3#下料点RFID号"), "", 15); // workShop3Plc.writeStringByAddress(StaticData.GetPlcAddress("3#下料点条码1"), "", 15); // workShop3Plc.writeStringByAddress(StaticData.GetPlcAddress("3#下料点条码2"), "", 15); // workShop3Plc.writeStringByAddress(StaticData.GetPlcAddress("3#下料点条码3"), "", 15); // workShop3Plc.writeStringByAddress(StaticData.GetPlcAddress("3#下料点条码4"), "", 15); // //解锁起始库位忙碌状态 // WcsBaseEquip? startEquip = sqlSugarClient.Queryable().First(it => it.AgvPositionCode == item.CurrPointNo); // if (startEquip != null) // { // startEquip.EquipStatus = 0; // sqlSugarClient.Updateable(startEquip).ExecuteCommand(); // } // } // else if (item.TaskType == StaticTaskType.SupplySmallPalletTask) // { // } // else if (item.TaskType == StaticTaskType.TransferMaterialMetrologyRoomBoxTask) // { // //从3#接驳位直接取走,清空RFID及机台号,条码等信息 // workShop3Plc.writeStringByAddress(StaticData.GetPlcAddress("3#接驳位RFID号"), "", 15); // workShop3Plc.writeStringByAddress(StaticData.GetPlcAddress("3#接驳位小料箱条码"), "", 15); // } // else if (item.TaskType == StaticTaskType.DeliverTonerTask) // { // //色粉箱直接取,无需处理,清空2#接驳位料箱方向信号 // workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#接驳位料箱方向信号"), 0); // } // #region 更新任务状态 // //解锁起始库位 // WmsBaseLocation? startLocation = sqlSugarClient.Queryable().First(it => it.AgvPositionCode == item.CurrPointNo); // if (startLocation != null) // { //起始库位料箱出库,删除RFID条码 // startLocation.ContainerCode = ""; // startLocation.UpdatedTime = DateTime.Now; // startLocation.LocationStatus = 1; // sqlSugarClient.Updateable(startLocation).ExecuteCommand(); // } // item.TaskStatus = 4; // item.UpdatedTime = DateTime.Now; // sqlSugarClient.Updateable(item).ExecuteCommand(); // wcsTaskLog.UpdatedTime = DateTime.Now; // wcsTaskLog.TaskStatus = 4; // sqlSugarClient.Updateable(wcsTaskLog).ExecuteCommand(); // sqlSugarClient.AsTenant().CommitTran(); // _logger.Agv($"AGV完成取料任务" + item.CurrPointNo + "," + item.EndPointNo); // #endregion 更新任务状态 // } // catch (Exception ex) // { // sqlSugarClient.AsTenant().RollbackTran(); // _logger.Error($"执行任务异常{ex.StackTrace}"); // } //} ///// ///// 任务状态5-6处理逻辑:agv到达放料等待点,询问能否放料 ///// 分不同任务类型,各自根据判断条件处理 ///// ///// ///// //private async Task TaskStatus5HandleAsync(WcsTask item) //{ // try // { // if (workShop2Plc == null || !workShop2Plc.IsConnected || workShop3Plc == null || !workShop3Plc.IsConnected) // { // return; // } // WcsTaskLog wcsTaskLog = sqlSugarClient.Queryable().First(t => t.Id == item.Id); // //if (item.TaskType == StaticTaskType.SupplyEmptyPalletTask) // //{ // // //判断光电信号及线体忙碌状态 // // int signal1 = workShop3Plc.readInt16ByAddress(StaticData.GetPlcAddress("3#1号光电状态")); // // int line1Status = workShop3Plc.readInt16ByAddress(StaticData.GetPlcAddress("3#输送线1系统状态")); // // if (signal1 == 1 || line1Status == 1) // // { // // //接驳位有东西或者线体忙碌,等待 // // return; // // } // //} // if (item.TaskType == StaticTaskType.SupplySmallPalletTask) // { // //判断3#接驳位3号光电及输送线2线体忙碌状态,能放的时候还需要锁住线体,防止plc往这送箱 // int signal3 = workShop3Plc.readInt16ByAddress(StaticData.GetPlcAddress("3#3号光电状态")); // int line2Status = workShop3Plc.readInt16ByAddress(StaticData.GetPlcAddress("3#输送线2系统状态")); // if (signal3 == 1 || line2Status == 1) // { // //接驳位有东西或者线体忙碌,等待 // return; // } // else // { // //锁住输送线2,plc禁止出 // workShop3Plc.writeInt16ByAddress(StaticData.GetPlcAddress("3#输送线2系统状态"), 2); // } // } // else if (item.TaskType == StaticTaskType.TransferMaterialMetrologyRoomBoxTask) // { // //判断2#接驳位PLC光电信号是否为空,不为空等待并预警 // int signal2 = workShop2Plc.readInt16ByAddress(StaticData.GetPlcAddress("2#接驳位光电信号")); // //todo 还需要判断线体状态 // if (signal2 == 1) // { // // 推送预警 // _logger.Agv($"AGV要往2#接驳位放托盘,但是目标库位光电检测有异物"); // //不满足条件的时候,优先放料信号 写1 // workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#优先放料信号"), 1); // return; // } // } // //else if (item.TaskType == StaticTaskType.TransferMaterialBoxTask) // //{ // // //判断机台库位是否为空,不为空等待并预警 // // //终点库位 // // WmsBaseLocation endBaseLocation = sqlSugarClient.Queryable().First(t => t.AgvPositionCode == item.EndPointNo); // // bool signal = await ReadSignalByRfidKeyAsync(endBaseLocation.EquipKey!); // // if (signal) // // { // // // todo推送预警,人工前往查看 // // _logger.Agv($"AGV要往目标库位放托盘,但是目标库位{endBaseLocation.LocationCode}光电检测有异物"); // // return; // // } // //} // //else if (item.TaskType == StaticTaskType.DeliverTonerTask) // //{ // // //色粉存放点色粉直接放,无需处理 // //} // //else if (item.TaskType == StaticTaskType.MoveLocationTask) // //{ // // //判断目标机台库位是否为空,不为空等待并预警 // // //终点库位 // // WmsBaseLocation endBaseLocation = sqlSugarClient.Queryable().First(t => t.AgvPositionCode == item.EndPointNo); // // bool signal = await ReadSignalByRfidKeyAsync(endBaseLocation.EquipKey!); // // if (signal) // // { // // // 推送预警,人工前往查看 // // _logger.Agv($"AGV要往目标库位放托盘,但是目标库位{endBaseLocation.LocationCode}光电检测有异物"); // // return; // // } // //} // #region 下发AGV信号放料箱 // //条件过滤,能取托盘或能取料 ,发送agv继续信号 // var agvTask = new RequestAGVTaskDto // { // reqCode = StaticData.SnowId.NextId().ToString(), // taskCode = item.TaskCode // }; // string message = JsonConvert.SerializeObject(agvTask); // string result = HttpHelper.SendPostMessage(baseEquip.ServerIp, baseEquip.ServerPort, "rcms/services/rest/hikRpcService/continueTask", message); // ReponseMessage? reponseMessage = JsonConvert.DeserializeObject(result); // if (reponseMessage != null && reponseMessage.message == "成功") // { // sqlSugarClient.AsTenant().BeginTran(); // _logger.Agv($"AGV线程允许取料任务" + item.CurrPointNo + "," + item.EndPointNo); // item.TaskStatus = 6; // sqlSugarClient.Updateable(item).ExecuteCommand(); // wcsTaskLog.UpdatedTime = DateTime.Now; // wcsTaskLog.TaskStatus = 6; // sqlSugarClient.Updateable(wcsTaskLog).ExecuteCommand(); // sqlSugarClient.AsTenant().CommitTran(); // } // #endregion 下发AGV信号放料箱 // } // catch (Exception ex) // { // sqlSugarClient.AsTenant().RollbackTran(); // _logger.Error($"执行任务异常{ex.StackTrace}"); // } //} ///// ///// 任务状态7-8完成逻辑 ///// 解锁库位,更新库存等等 ///// ///// ///// //private async Task TaskStatus7HandleAsync(WcsTask item) //{ // try // { // if (workShop2Plc == null || !workShop2Plc.IsConnected || workShop3Plc == null || !workShop3Plc.IsConnected) // { // return; // } // WcsTaskLog wcsTaskLog = sqlSugarClient.Queryable().First(t => t.Id == item.Id); // sqlSugarClient.AsTenant().BeginTran(); // if (item.TaskType == StaticTaskType.SupplyEmptyPalletTask) // { // //终点库位解锁,通知PLC可以使用--ok // WcsBaseEquip? endBaseEquip = sqlSugarClient.Queryable().First(t => t.AgvPositionCode == item.EndPointNo); // if (endBaseEquip != null) // { // //空闲 // endBaseEquip.EquipStatus = 0; // } // sqlSugarClient.Updateable(endBaseEquip).ExecuteCommand(); // } // else if (item.TaskType == StaticTaskType.TransferMaterialBoxTask) // { // //不额外处理 --ok // } // else if (item.TaskType == StaticTaskType.MoveLocationTask) // { // //不额外处理 --ok // } // else if (item.TaskType == StaticTaskType.SupplySmallPalletTask) // { // //wcs 给空箱入缓存链条线信号1,plc复位 , wcs并解锁输送线状态0 // workShop3Plc.writeInt16ByAddress(StaticData.GetPlcAddress("3#空箱入缓存链条线"), 1); // workShop3Plc.writeInt16ByAddress(StaticData.GetPlcAddress("3#输送线2系统状态"), 0); // } // else if (item.TaskType == StaticTaskType.TransferMaterialMetrologyRoomBoxTask) // { // // 料箱放到接驳位,给接驳位料箱方向信号写1,优先放料信号 写0,plc将其运送到计量室。 // workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#优先放料信号"), 0); // workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#接驳位料箱方向信号"), 1); // } // else if (item.TaskType == StaticTaskType.DeliverTonerTask) // { // //todo待确定 // } // #region 入库校验、库位解锁、任务删除、日志更新 // WmsBaseLocation? endlocation = sqlSugarClient.Queryable().First(t => t.AgvPositionCode == item.EndPointNo); // if (endlocation != null && !string.IsNullOrEmpty(endlocation.EquipKey)) // { // #region 校验RFID // string readRfid = await ReadEpcStrByRfidKeyAsync(endlocation.EquipKey!); // if (string.IsNullOrEmpty(readRfid)) // { // //todo推送失败预警 // throw new Exception($"机台{endlocation.MachineId},库位:{endlocation.LocationCode}RFID读取失败"); // } // else if (readRfid != item.PalletInfoCode) // { // //todo推送失败预警 // throw new Exception($"机台{endlocation.MachineId},库位:{endlocation.LocationCode}RFID读取结果:{readRfid}与任务记录RFID:{item.PalletInfoCode}不一致!"); // } // #endregion 校验RFID // endlocation.LocationStatus = 1; // endlocation.UpdatedTime = DateTime.Now; // endlocation.ContainerCode = item.PalletInfoCode; // sqlSugarClient.Updateable(endlocation).ExecuteCommand(); // } // //更新机台库存信息及在途数 // UpdateWmsMachineInfo(item); // //更新任务状态 // sqlSugarClient.Deleteable(item).ExecuteCommand(); // wcsTaskLog.UpdatedTime = DateTime.Now; // wcsTaskLog.TaskStatus = 8; // sqlSugarClient.Updateable(wcsTaskLog).ExecuteCommand(); // sqlSugarClient.AsTenant().CommitTran(); // _logger.Agv($"AGV线程完成 {item.TaskName}," + item.CurrPointNo + "," + item.EndPointNo); // #endregion 入库校验、库位解锁、任务删除、日志更新 // } // catch (Exception ex) // { // sqlSugarClient.AsTenant().RollbackTran(); // _logger.Error($"执行任务异常{ex.StackTrace}"); // } //} ///// ///// 任务完成,更新在途数及库存数 ///// //private void UpdateWmsMachineInfo(WcsTask wcsTask) //{ // if (!string.IsNullOrEmpty(wcsTask.PalletInfoCode) && !string.IsNullOrEmpty(wcsTask.MachineCode)) // { // WmsMachineInfo wmsMachineInfo = sqlSugarClient.Queryable().First(t => t.MachineCode == wcsTask.MachineCode); // int count = sqlSugarClient.Queryable().Where(t => t.MachineCode == wcsTask.MachineCode && t.PalletInfoCode == wcsTask.PalletInfoCode).Count(); // if (wmsMachineInfo != null) // { // wmsMachineInfo.AmountOnLocation += count; // wmsMachineInfo.AmountOnWay -= count; // if (wmsMachineInfo.AmountOnWay < 0) wmsMachineInfo.AmountOnWay = 0; // wmsMachineInfo.AmountTotal = wmsMachineInfo.AmountOnLocation + wmsMachineInfo.AmountOnWay; // sqlSugarClient.Updateable(wmsMachineInfo).ExecuteCommand(); // } // } //} ///// ///// 暂不使用 ///// 任务状态3-4处理逻辑:agv到达取料等待点,询问能否取料或托盘 ///// 分不同任务类型,各自根据判断条件处理 ///// ///// ///// //private async Task TaskStatus333HandleAsync(WcsTask item) //{ // try // { // WcsTaskLog wcsTaskLog = sqlSugarClient.Queryable().First(t => t.Id == item.Id); // if (item.TaskType == StaticTaskType.SupplyEmptyPalletTask) // { // //需要判断箱子是否为空且在1-12机台库位(1-11机台直接取,12机台需核实是否是空箱) // WmsBaseLocation wmsBaseLocation = sqlSugarClient.Queryable().First(t => t.AgvPositionCode == item.CurrPointNo); // if (wmsBaseLocation.MachineId == 12) // { // //12机台需核实是否是空箱 // bool signal = await ReadSignalByRfidKeyAsync(wmsBaseLocation.EquipKey!); // if (!signal) // { // //todo: 位置是空的,推送报警---- // _logger.Agv($"AGV到达12机台库位{wmsBaseLocation.AgvPositionCode},取空箱但是位置是空的,推送报警"); // return; // } // string rfid = await ReadEpcStrByRfidKeyAsync(wmsBaseLocation.EquipKey!); // if (string.IsNullOrEmpty(rfid)) // { // //todo: 推送报警---- // _logger.Agv($"AGV到达12机台库位{wmsBaseLocation.AgvPositionCode},取空箱但是未读取到RFID,推送报警"); // return; // } // // 通过该料箱是否绑定有物料来判断是否为空托盘 // bool hasMaterial = await sqlSugarClient.Queryable().AnyAsync(it => it.PalletInfoCode == rfid); // if (hasMaterial) // { // //todo: 推送报警---- // _logger.Agv($"AGV到达12机台库位{wmsBaseLocation.AgvPositionCode},取空箱但是该料箱有物料,推送报警"); // return; // } // } // } // else if (item.TaskType == StaticTaskType.SupplySmallPalletTask) // { // } // else if (item.TaskType == StaticTaskType.TransferMaterialBoxTask) // { // //从下料点直接取,清空RFID及机台号,条码等信息 // workShop3Plc.writeInt16ByAddress(StaticData.GetPlcAddress("3#下料点机台号"), 0); // workShop3Plc.writeStringByAddress(StaticData.GetPlcAddress("3#下料点RFID号"), "", 15); // workShop3Plc.writeStringByAddress(StaticData.GetPlcAddress("3#下料点条码1"), "", 15); // workShop3Plc.writeStringByAddress(StaticData.GetPlcAddress("3#下料点条码2"), "", 15); // workShop3Plc.writeStringByAddress(StaticData.GetPlcAddress("3#下料点条码3"), "", 15); // workShop3Plc.writeStringByAddress(StaticData.GetPlcAddress("3#下料点条码4"), "", 15); // } // else if (item.TaskType == StaticTaskType.TransferMaterialMetrologyRoomBoxTask) // { // //从3#接驳位直接取走,清空RFID及机台号,条码等信息 // workShop3Plc.writeStringByAddress(StaticData.GetPlcAddress("3#接驳位RFID号"), "", 15); // workShop3Plc.writeStringByAddress(StaticData.GetPlcAddress("3#接驳位小料箱条码"), "", 15); // } // else if (item.TaskType == StaticTaskType.DeliverTonerTask) // { // //色粉箱直接取,无需处理,清空2#接驳位料箱方向信号 // workShop2Plc.writeInt16ByAddress(StaticData.GetPlcAddress("2#接驳位料箱方向信号"), 0); // } // else if (item.TaskType == StaticTaskType.MoveLocationTask) // { // // 直接取,无需处理 // } // #region 下发AGV信号取料箱 // //条件过滤,能取托盘或能取料 ,发送agv继续信号 // var agvTask = new RequestAGVTaskDto // { // reqCode = StaticData.SnowId.NextId().ToString(), // taskCode = item.TaskCode // }; // string message = JsonConvert.SerializeObject(agvTask); // string result = HttpHelper.SendPostMessage(baseEquip.ServerIp, baseEquip.ServerPort, "rcms/services/rest/hikRpcService/continueTask", message); // ReponseMessage? reponseMessage = JsonConvert.DeserializeObject(result); // if (reponseMessage != null && reponseMessage.message == "成功") // { // WmsBaseLocation? startLocation = sqlSugarClient.Queryable().First(it => it.AgvPositionCode == item.CurrPointNo); // sqlSugarClient.AsTenant().BeginTran(); // if (startLocation != null) // { //起始库位料箱出库,删除RFID条码 // startLocation.ContainerCode = ""; // startLocation.UpdatedTime = DateTime.Now; // startLocation.LocationStatus = 1; // sqlSugarClient.Updateable(startLocation).ExecuteCommand(); // } // item.TaskStatus = 4; // sqlSugarClient.Updateable(item).ExecuteCommand(); // wcsTaskLog.UpdatedTime = DateTime.Now; // wcsTaskLog.TaskStatus = 4; // sqlSugarClient.Updateable(wcsTaskLog).ExecuteCommand(); // sqlSugarClient.AsTenant().CommitTran(); // _logger.Agv($"AGV允许取料任务" + item.CurrPointNo + "," + item.EndPointNo); // } // #endregion 下发AGV信号取料箱 // } // catch (Exception ex) // { // sqlSugarClient.AsTenant().RollbackTran(); // _logger.Error($"执行任务异常{ex.StackTrace}"); // } //} #endregion 弃用逻辑 } }