123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339 |
- using PlcSiemens.Core.Extension;
- using ServiceCenter.Extensions;
- using ServiceCenter.Logs;
- using ServiceCenter.SqlSugars;
- using System.ComponentModel;
- using System.Threading.Tasks;
- using WCS.Core;
- using WCS.Entity;
- using WCS.WorkEngineering.Extensions;
- using WCS.WorkEngineering.Protocol.SRM;
- using WCS.WorkEngineering.Protocol.Station;
- using WCS.WorkEngineering.WebApi.Controllers;
- using WCS.WorkEngineering.Worlds;
- using DeviceFlags = WCS.WorkEngineering.Extensions.DeviceFlags;
- namespace WCS.WorkEngineering.Systems
- {
- /// <summary>
- /// Agv交互系统
- /// </summary>
- [BelongTo(typeof(MainWorld))]
- [Description("Agv交互系统")]
- public class AgvSystems : DeviceSystem<Station>
- {
- protected override bool ParallelDo => true;
- protected override bool SaveLogsToFile => true;
- private List<Station> devs = new List<Station>();
- private List<SRM> srms = new List<SRM>();
- public AgvSystems()
- {
- devs = Device.All.Where(v => v.HasFlag(DeviceFlags.入库, DeviceFlags.巷道口)).Select(v => new Station(v, this.World)).ToList();
- srms = Device.All.Where(v => v.HasProtocol(typeof(ISRM520))).Select(v => new SRM(v, this.World)).ToList();
- }
- public override void Do(Station obj)
- {
- if (obj.Entity.HasFlag(DeviceFlags.出库))
- {
- List<WCS_AgvTaskInfo> agvTaskInfos = new List<WCS_AgvTaskInfo>();
- //获取所有未结束的AGV叫料、搬运任务
- SqlSugarHelper.Do(db =>
- {
- agvTaskInfos = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.Status < AGVTaskStatus.MissionCompleted && (v.TaskType == AGVTaskType.CallMaterial || v.TaskType == AGVTaskType.ForkliftFilling)).SplitTable(tabs => tabs.Take(2)).OrderBy(v => v.AddTime).ToList();
- });
- //有需要处理的AGV任务
- if (agvTaskInfos.Any())
- {
- this.ExRecord(obj.Entity.Code, "可用出库AGV任务列表", agvTaskInfos.Select(v => v.ID).ToList());
- List<WCS_TaskInfo> taskInfos = new List<WCS_TaskInfo>();
- foreach (var agv in agvTaskInfos)
- {
- try
- {
- SqlSugarHelper.Do(db =>
- {
- //出库叫料任务
- if (agv.TaskType == AGVTaskType.CallMaterial)
- {
- var task = db.Default.Queryable<WCS_TaskInfo>().First(v => v.AgvTaskID == agv.ID);
- if (task == null) throw new Exception($"AGV任务{agv.ID}未找到对应WCS任务");
- //取货点安全交互
- if (agv.AgvStatus == AGVTaskStatus.RequestOrPermission2 && agv.Status != AGVTaskStatus.Complete2)
- {
- agv.Status = AGVTaskStatus.Complete2;
- db.Default.Updateable(agv).SplitTable().ExecuteCommand();
- task.AddWCS_TASK_DTL(db, "agv", $"允许AGV任务{agv.ID}在站台{agv.Station}取货");
- AgvApi.ContinueTask(agv.AgvID, agv.Station);
- }
- else if (agv.AgvStatus == AGVTaskStatus.Complete3)
- {
- agv.Status = AGVTaskStatus.Execution;
- db.Default.Updateable(agv).SplitTable().ExecuteCommand();
- //WmsApi.PinkuInfoManagement(task.ID);
- }
- else if (agv.AgvStatus == AGVTaskStatus.WalkIntoStorage && agv.Status != AGVTaskStatus.ExitStorage)
- {
- string endPos = "";
- if (agv.Position == "1021")
- {
- endPos = "2001";
- }
- else if (agv.Position == "1022")
- {
- endPos = "2002";
- }
- else if (agv.Position == "1023")
- {
- endPos = "2003";
- }
- else if (agv.Position == "1024")
- {
- endPos = "2004";
- }
- else
- {
- endPos = agv.Position;
- }
- agv.Status = AGVTaskStatus.ExitStorage;
- db.Default.Updateable(agv).SplitTable().ExecuteCommand();
- task.AddWCS_TASK_DTL(db, "agv", $"允许AGV任务{agv.ID}放货,目标站台{endPos}");
- AgvApi.ContinueTask(agv.AgvID, endPos);
- }
- //完成任务
- else if (agv.AgvStatus == AGVTaskStatus.MissionCompleted && agv.Status != AGVTaskStatus.MissionCompleted)
- {
- if (agv.TaskType is AGVTaskType.CallMaterial)
- {
- //更新AGV任务状态
- agv.Status = AGVTaskStatus.MissionCompleted;
- db.Default.Updateable(agv).SplitTable().ExecuteCommand();
- //更新WCS任务状态
- task.Status = Entity.TaskStatus.Finish;
- task.EedTime = DateTime.Now;
- db.Default.Updateable(task).ExecuteCommand();
- task.AddWCS_TASK_DTL(db, "agv", "任务完成");
- task.CompleteOrCancelTasks(db);
- taskInfos.Add(task);
- }
- }
- }
- else if (agv.TaskType == AGVTaskType.ForkliftFilling)//搬运任务,判断是WCS还是WMS创建
- { //终点安全交互
- if (agv.WorkShop == 111)
- {
- var taskInfo = db.Default.Queryable<WCS_TaskInfo>().First(v => v.AgvTaskID == agv.ID);
- if (taskInfo == null) throw new Exception($"未找到AGV任务{agv.ID}对应WCS任务");
- if (agv.AgvStatus == AGVTaskStatus.Complete3)
- {
- agv.Status = AGVTaskStatus.Execution;
- db.Default.Updateable(agv).SplitTable().ExecuteCommand();
- WmsApi.PinkuInfoManagement(taskInfo.ID);
- }
- else if (agv.AgvStatus == AGVTaskStatus.WalkIntoStorage && agv.Status != AGVTaskStatus.ExitStorage)
- {
- agv.Status = AGVTaskStatus.ExitStorage;
- db.Default.Updateable(agv).SplitTable().ExecuteCommand();
- taskInfo.AddWCS_TASK_DTL(db, "agv", $"允许AGV任务{agv.ID}放货,目标站台{agv.Position}");
- AgvApi.ContinueTask(agv.AgvID, agv.Position);
- }
- //完成任务
- else if (agv.AgvStatus == AGVTaskStatus.MissionCompleted && agv.Status != AGVTaskStatus.MissionCompleted)
- {
- //更新AGV任务状态
- agv.Status = AGVTaskStatus.MissionCompleted;
- db.Default.Updateable(agv).SplitTable().ExecuteCommand();
- //更新WCS任务状态
- taskInfo.Status = Entity.TaskStatus.Finish;
- taskInfo.EedTime = DateTime.Now;
- db.Default.Updateable(taskInfo).ExecuteCommand();
- taskInfo.AddWCS_TASK_DTL(db, "agv", "任务完成");
- taskInfo.CompleteOrCancelTasks(db);
- taskInfos.Add(taskInfo);
- }
- }
- else if(agv.WorkShop == 222)
- {
- //取货点安全交互
- if (agv.AgvStatus == AGVTaskStatus.RequestOrPermission2 && agv.Status != AGVTaskStatus.Complete2)
- {
- //var dev = devs.Find(v => v.Entity.Code == agv.Position);
- //if (dev.Data.VoucherNo != dev.Data2.VoucherNo) throw new Exception($"AGV请求取货,但{dev.Entity.Code}凭证号不一致");
- //if (!dev.Data3.Status.HasFlag(StationStatus.Auto)) throw new Exception($"AGV请求取货,但{dev.Entity.Code}不在自动状态");
- //if (!(dev.Data3.Status.HasFlag(StationStatus.PH_Status) && !dev.Data3.Status.HasFlag(StationStatus.OT_Status))) throw new Exception($"AGV请求取货,但{dev.Entity.Code}光电状态不满足");
- //if (dev.Data3.Status.HasFlag(StationStatus.Run)) throw new Exception($"AGV请求取货,但{dev.Entity.Code}在运行状态");
- agv.Status = AGVTaskStatus.Complete2;
- db.Default.Updateable(agv).SplitTable().ExecuteCommand();
- AgvApi.ContinueTask(agv.AgvID, agv.Station);
- }
- else if (agv.AgvStatus == AGVTaskStatus.WalkIntoStorage && agv.Status != AGVTaskStatus.ExitStorage)
- {
- agv.Status = AGVTaskStatus.ExitStorage;
- db.Default.Updateable(agv).SplitTable().ExecuteCommand();
- AgvApi.ContinueTask(agv.AgvID, agv.Position);
- }
- //完成任务
- else if (agv.AgvStatus == AGVTaskStatus.MissionCompleted && agv.Status != AGVTaskStatus.MissionCompleted)
- {
- //任务完成清除货架信号
- var dev = devs.Find(v => v.Entity.Code == agv.Station);
- dev.Data.GoodsStart = 0;
- //更新AGV任务状态
- agv.Status = AGVTaskStatus.MissionCompleted;
- db.Default.Updateable(agv).SplitTable().ExecuteCommand();
- }
- }
- //起点安全交互
- if (agv.WorkShop == 333)
- {
- var taskInfo = db.Default.Queryable<WCS_TaskInfo>().First(v => v.AgvTaskID == agv.ID);
- if (taskInfo == null) throw new Exception($"未找到AGV任务{agv.ID}对应WCS任务");
- //取货点安全交互
- if (agv.AgvStatus == AGVTaskStatus.RequestOrPermission2 && agv.Status != AGVTaskStatus.Complete2)
- {
- agv.Status = AGVTaskStatus.Complete2;
- db.Default.Updateable(agv).SplitTable().ExecuteCommand();
- string startPos = "";
- if (taskInfo.AddrFrom == "1021" || taskInfo.AddrFrom == "1022" || taskInfo.AddrFrom == "1023" || taskInfo.AddrFrom == "1024")
- {
- startPos = "PT" + taskInfo.AddrFrom;
- }
- //else if (taskInfo.AddrFrom == "1022")
- //{
- // startPos = "2002";
- //}
- //else if (taskInfo.AddrFrom == "1023")
- //{
- // startPos = "2003";
- //}
- //else if (taskInfo.AddrFrom == "1024")
- //{
- // startPos = "2004";
- //}
- else
- {
- startPos = taskInfo.AddrFrom;
- }
- taskInfo.AddWCS_TASK_DTL(db, "agv", $"允许AGV任务{agv.ID}在站台{startPos}取货");
- AgvApi.ContinueTask(agv.AgvID, startPos);
- }
- else if (agv.AgvStatus == AGVTaskStatus.Complete3)
- {
- agv.Status = AGVTaskStatus.Execution;
- db.Default.Updateable(agv).SplitTable().ExecuteCommand();
- //WmsApi.PinkuInfoManagement(task.ID);
- }
- //完成任务
- else if (agv.AgvStatus == AGVTaskStatus.MissionCompleted && agv.Status != AGVTaskStatus.MissionCompleted)
- {
- var dev = devs.Find(v => v.Entity.Code == agv.Station);
- if (dev != null)
- {
- dev.Data.GoodsStart = 0;
- }
-
- //更新AGV任务状态
- agv.Status = AGVTaskStatus.MissionCompleted;
- db.Default.Updateable(agv).SplitTable().ExecuteCommand();
- //更新WCS任务状态
- taskInfo.Status = Entity.TaskStatus.Finish;
- taskInfo.EedTime = DateTime.Now;
- db.Default.Updateable(taskInfo).ExecuteCommand();
- taskInfo.AddWCS_TASK_DTL(db, "agv", "任务完成");
- taskInfo.CompleteOrCancelTasks(db);
- taskInfos.Add(taskInfo);
- }
- }
- }
- });
- }
- catch (Exception ex)
- {
- World.Log(ex.Message, LogLevelEnum.Mid);
- this.ExRecord(obj.Entity.Code, ex.Message);
- continue;
- }
- }
- foreach (var item in taskInfos)
- {
- WmsApi.CompleteTask(item.ID);
- }
- }
- }
- else if (obj.Entity.HasFlag(DeviceFlags.入库))
- {
- List<WCS_AgvTaskInfo> agvTaskInfos = new List<WCS_AgvTaskInfo>();
- //获取所有未结束的入库AGV任务
- SqlSugarHelper.Do(db =>
- {
- agvTaskInfos = db.Default.Queryable<WCS_AgvTaskInfo>().Where(v => v.Status < AGVTaskStatus.MissionCompleted && v.TaskType == AGVTaskType.EnterDepot).SplitTable(tabs => tabs.Take(2)).OrderBy(v => v.EditTime).ToList();
- });
- if (agvTaskInfos.Any())
- {
- this.ExRecord(obj.Entity.Code, "可用入库AGV任务列表", agvTaskInfos.Select(v => v.ID).ToList());
- foreach (var agv in agvTaskInfos)
- {
- try
- {
- SqlSugarHelper.Do(db =>
- {
- //找到对应WCS任务
- var task = db.Default.Queryable<WCS_TaskInfo>().First(v => v.AgvTaskID == agv.ID);
- if (task == null) throw new Exception($"AGV任务{agv.ID}未找到对应WCS任务");
- #region 开始跟据AGV状态做出处理
- //agv取货完成
- if (agv.AgvStatus == AGVTaskStatus.Complete3 && agv.Status != AGVTaskStatus.Execution)
- {
- agv.Status = AGVTaskStatus.Execution;
- db.Default.Updateable(agv).SplitTable().ExecuteCommand();
- //通知WMS取货完成
- WmsApi.PinkuInfoManagement(task.ID);
- }
- else if (agv.AgvStatus == AGVTaskStatus.RequestOrPermission2 && agv.Status != AGVTaskStatus.Complete2)
- {
- agv.Status = AGVTaskStatus.Complete2;
- db.Default.Updateable(agv).SplitTable().ExecuteCommand();
- }
- //放货点安全交互
- else if (agv.AgvStatus == AGVTaskStatus.WalkIntoStorage && agv.Status != AGVTaskStatus.ExitStorage)
- {
- if (agv.Position.IsNullOrEmpty()) throw new Exception($"无有效放货地址");
- var dev = devs.Find(v => v.Entity.Code == agv.Position);
- if (dev.Data.VoucherNo != dev.Data2.VoucherNo) throw new Exception($"AGV请求放货,但{dev.Entity.Code}凭证号不一致");
- if (!dev.Data3.Status.HasFlag(StationStatus.Auto)) throw new Exception($"AGV请求放货,但{dev.Entity.Code}不在自动状态");
- if (dev.Data3.Status.HasFlag(StationStatus.PH_Status) || dev.Data3.Status.HasFlag(StationStatus.OT_Status)) throw new Exception($"AGV请求放货,{dev.Entity.Code}不满足放货条件,请检查光电状态");
- if (dev.Data3.Status.HasFlag(StationStatus.Run)) throw new Exception($"AGV请求放货,但{dev.Entity.Code}在运行状态");
- agv.Status = AGVTaskStatus.ExitStorage;
- db.Default.Updateable(agv).SplitTable().ExecuteCommand();
- //调继续执行任务接口
- AgvApi.ContinueTask(agv.AgvID, agv.Position);
- }
- //完成任务
- else if (agv.AgvStatus == AGVTaskStatus.MissionCompleted && agv.Status != AGVTaskStatus.MissionCompleted)
- {
- var dev = devs.Find(v => v.Entity.Code == agv.Position);
- dev.Data.TaskNumber = task.ID;
- dev.Data.VoucherNo++;
- agv.Status = AGVTaskStatus.MissionCompleted;
- db.Default.Updateable(agv).SplitTable().ExecuteCommand();
- }
- #endregion 开始跟据AGV状态做出处理
- });
- }
- catch (Exception ex)
- {
- World.Log(ex.Message, LogLevelEnum.Mid);
- this.ExRecord(obj.Entity.Code, ex.Message);
- continue;
- }
- }
- }
- }
- }
- public override bool Select(Device dev)
- {
- return dev.Code is "1001" or "1002";
- }
- }
- }
|