using NetTaste; using Newtonsoft.Json; using NPOI.SS.Formula.PTG; using Org.BouncyCastle.Bcpg; using ServiceCenter.SqlSugars; using SqlSugar; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; using WCS.Core; using WCS.Entity; using WCS.Entity.Protocol.Protocol.Robot; using WCS.Entity.Protocol.Robot; using WCS.Entity.Protocol.Station; using WCS.WorkEngineering.Extensions; using WCS.WorkEngineering.WebApi.Models.WCS.Request; using WCS.WorkEngineering.Worlds; using static ICSharpCode.SharpZipLib.Zip.ExtendedUnixData; namespace WCS.WorkEngineering.Systems { [BelongTo(typeof(RobotWorld))] [Description("机器人抓取")] public class 机器人抓取 : DeviceSystem> { protected override bool ParallelDo => false; private Device[] PalletStations; public 机器人抓取() { var arr = Device.All.Where(v => v.HasProtocol() && v.HasFlag("装箱码垛") && v.HasFlag("位置", "码垛")).ToArray(); PalletStations = arr.Select(v => new Device(v, this.World)).ToArray(); } public override void Do(Device obj) { if (obj.Data.VoucherNo != obj.Data2.VoucherNo) { MainWorld.Redis.Set($"Sx:WCSErrorInfo:{obj.Entity.Code}", JsonConvert.SerializeObject(new RedisError() { Equip = obj.Entity.Code, Con = obj.Entity.Code + "凭证号不一样,不允许做新的交互", Time = DateTime.Now })); return; } if (obj.Data2.Mode != RobotMode.自动) { MainWorld.Redis.Set($"Sx:WCSErrorInfo:{obj.Entity.Code}", JsonConvert.SerializeObject(new RedisError() { Equip = obj.Entity.Code, Con = obj.Entity.Code + "不是自动模式", Time = DateTime.Now })); return; } if (obj.Data2.Alarm != 0) { MainWorld.Redis.Set($"Sx:WCSErrorInfo:{obj.Entity.Code}", JsonConvert.SerializeObject(new RedisError() { Equip = obj.Entity.Code, Con = obj.Entity.Code + "有报警,请先解决报警", Time = DateTime.Now })); World.Log($"{obj.Data3.Alarm}"); return; } World.Log($"码垛任务下发{obj.Entity.Code}交互开始时间:一个周期" + DateTime.Now.ToString("yyyyMMddHHmmss")); if (obj.Data2.Rqst == RobotRqst.抓取完成) { var tasks = new int[] { obj.Data2.Task1, obj.Data2.Task2, obj.Data2.Task3 }.Take(obj.Data2.TaskQty).ToArray(); if (tasks.Any(v => v == 0) || tasks.Length == 0) { MainWorld.Redis.Set($"Sx:WCSErrorInfo:{obj.Entity.Code}", JsonConvert.SerializeObject(new RedisError() { Equip = obj.Entity.Code, Con = obj.Entity.Code + "抓取完成时任务号有误", Time = DateTime.Now })); throw new Exception("抓取完成时任务号有误"); } var res = WMS.抓取完成(tasks, obj.Data2.AddrTo.ToString()); if (!res.Success) { MainWorld.Redis.Set($"Sx:WCSErrorInfo:{obj.Entity.Code}", JsonConvert.SerializeObject(new RedisError() { Equip = obj.Entity.Code, Con = obj.Entity.Code + "码垛绑定失败," + res.ResMsg, Time = DateTime.Now })); throw new Exception("码垛绑定失败," + res.ResMsg); } SqlSugarHelper.Do(db => { var arr = db.Default.Queryable().Where(v => tasks.Contains(v.ID)).ToArray(); foreach (var task in arr) { if (task.Status != Entity.TaskStatus.码垛抓取中) { MainWorld.Redis.Set($"Sx:WCSErrorInfo:{obj.Entity.Code}", JsonConvert.SerializeObject(new RedisError() { Equip = obj.Entity.Code, Con = $"{obj.Entity.Code},任务{task.ID}状态有误", Time = DateTime.Now })); throw new Exception($"任务{task.ID}状态有误"); } task.Status = Entity.TaskStatus.码垛抓取完成; task.EditTime = DateTime.Now; db.Default.Updateable(task).ExecuteCommand(); task.AddWCS_TASK_DTL(db.Default, obj.Data2.AddrTo.ToString(), "码垛抓取完成"); } if (obj.Data.VoucherNo == -1) { obj.Data.Cmd = RobotCmd.抓取完成确认; obj.Data.VoucherNo = 1; } else { obj.Data.Cmd = RobotCmd.抓取完成确认; obj.Data.VoucherNo++; } }); return; } if (obj.Data2.Status != RobotRunStatus.空闲) return; var temp = PalletStations.Where(v => v.Entity.HasFlag("Robot", obj.Entity.Code)) .Where(v => v.Data.TaskNumber > 0 && v.Data.TaskNumber == v.Data2.PalletID).ToArray(); if (temp.Length == 0) { MainWorld.Redis.Set($"Sx:WCSErrorInfo:{obj.Entity.Code}", JsonConvert.SerializeObject(new RedisError() { Equip = obj.Entity.Code, Con = obj.Entity.Code + "码垛位状态未就绪", Time = DateTime.Now })); World.Log("码垛位状态未就绪"); return; } var temp2 = temp.Select(v => new { PalletStation = v, QtyLeft = v.Data2.MaxQty - v.Data2.Qty, PickStation = Device.All.Where(d => d.HasFlag("装箱码垛") && d.HasFlag("位置", "抓取") && d.HasFlag("码垛工位", v.Entity.Code)).First() }).ToArray(); var temp3 = temp2.Select(v => new { v.PalletStation, v.QtyLeft, v.PickStation, Arr = Device.All.Where(d => d.HasFlag("装箱码垛") && d.HasFlag("Parent", v.PickStation.Code)).Select(d => d.Protocol(this.World)).ToArray() }).ToArray(); var stArr = temp3.Select(v => new { v.PalletStation, v.QtyLeft, v.PickStation, Tasks = v.Arr.Select(d => d.TaskNumber).Where(d => d > 10000).ToArray() }) .Where(v => v.Tasks.Length > 0).ToArray(); if (stArr.Length == 0) { World.Log("抓取位空"); return; } SqlSugarHelper.Do(db => { foreach (var item in stArr.OrderBy(v => v.QtyLeft)) { var stCode = item.PalletStation.Entity.Code; if (!item.PickStation.Protocol(this.World).Status.HasFlag(StationStatus.自动)) { MainWorld.Redis.Set($"Sx:WCSErrorInfo:{obj.Entity.Code}", JsonConvert.SerializeObject(new RedisError() { Equip = obj.Entity.Code, Con = $"{item.PickStation.Code}不在自动模式", Time = DateTime.Now })); World.Log($"{item.PickStation.Code}不在自动模式", ServiceCenter.Logs.LogLevelEnum.High); continue; } try { var flag = db.Default.Queryable().Where(v => v.AddrTo == item.PalletStation.Entity.Code && v.Status == Entity.TaskStatus.码垛抓取中).Any(); if (flag) { World.Log($"{stCode}有正在抓取中的任务"); continue; } var p = db.Default.Queryable().Where(v => v.TaskNum == item.PalletStation.Data.TaskNumber).Where(v => v.PalletizState == 0).First(); if (p == null) { World.Log($"{stCode}托盘无码垛数据", ServiceCenter.Logs.LogLevelEnum.High); MainWorld.Redis.Set($"Sx:WCSErrorInfo:{obj.Entity.Code}", JsonConvert.SerializeObject(new RedisError() { Equip = obj.Entity.Code, Con = $"{stCode}托盘无码垛数据", Time = DateTime.Now })); continue; } if (item.Tasks.Distinct().Count() < 3) { if (p.Count >= p.Finish) continue; var qty = db.Default.Queryable().Where(v => v.Type == TaskType.OutDepot && v.BusType == "装箱码垛") .Where(v => v.Status >= Entity.TaskStatus.码垛缓存放行 && v.Status <= Entity.TaskStatus.码垛缓存扫码).Count(); if (qty > item.Tasks.Length) { World.Log($"{stCode}有额外货物已缓存放行"); } } var rc = db.Default.Updateable() .SetColumns(v => new WCS_TaskInfo { Status = Entity.TaskStatus.码垛抓取中, EditTime = SqlFunc.GetDate() }) .Where(v => item.Tasks.Contains(v.ID)) .Where(v => v.Status == Entity.TaskStatus.码垛抓取扫码) .ExecuteCommand(); if (rc != item.Tasks.Length) { if (db.Default.Updateable().SetColumns(v => new WCS_TaskInfo { Status = Entity.TaskStatus.码垛抓取中, EditTime = SqlFunc.GetDate() }) .Where(v => item.Tasks.Contains(v.ID)).ExecuteCommand() > 0) { World.Log($"{stCode}触发任务状态重复修改机制", ServiceCenter.Logs.LogLevelEnum.High); } else { World.Log($"{stCode}修改任务状态失败,", ServiceCenter.Logs.LogLevelEnum.High); continue; } } obj.Data.GoodsType = (short)p.GoodsType; obj.Data.AddrFrom = short.Parse(item.PickStation.Code); obj.Data.AddrTo = short.Parse(item.PalletStation.Entity.Code); obj.Data.TaskQty = (short)item.Tasks.Length; obj.Data.Task1 = item.Tasks[0]; if (item.Tasks.Length > 1) obj.Data.Task2 = item.Tasks[1]; else obj.Data.Task2 = 0; if (item.Tasks.Length > 2) obj.Data.Task3 = item.Tasks[2]; else obj.Data.Task3 = 0; if (obj.Data.VoucherNo == -1) { obj.Data.Cmd = RobotCmd.抓取; obj.Data.VoucherNo = 1; } else { obj.Data.Cmd = RobotCmd.抓取; obj.Data.VoucherNo++; } break; } catch (Exception ex) { World.Log($"{stCode}异常:{ex.Message}"); } } }); World.Log($"码垛任务下发{obj.Entity.Code}交互结束时间:一个周期" + DateTime.Now.ToString("yyyyMMddHHmmss")); } public override bool Select(Device dev) { return dev.Code is "Robot1" or "Robot2"; } } }