using System.ComponentModel; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using PlcSiemens.Core.Extension; using ServiceCenter; using ServiceCenter.Extensions; using ServiceCenter.Redis; using ServiceCenter.SqlSugars; using System.Net.NetworkInformation; using System.Text; using SqlSugar; using WCS.Core; using WCS.Entity; using WCS.Entity.Protocol.DataStructure; using WCS.Entity.Protocol.HUB; using WCS.Entity.Protocol.Protocol.Robot; using WCS.Entity.Protocol.SRM; using WCS.WorkEngineering.Extensions; using WCS.WorkEngineering.Systems; using WCS.WorkEngineering.WebApi.Models.WCS.Request; using WCS.WorkEngineering.WebApi.Models.WCS.Response; using WCS.WorkEngineering.WebApi.Models.WMS.Response; using TaskStatus = WCS.Entity.TaskStatus; using static Dm.net.buffer.ByteArrayBuffer; using System.Security.Claims; using WCS.Entity.Protocol.Truss; // ReSharper disable PossibleLossOfFraction namespace WCS.WorkEngineering.WebApi.Controllers { /// /// 设备Ip通讯检测结构 /// public class DeviceIpTestResults { public string Ip { get; set; } public bool Result { get; set; } } /// /// WCS相关接口控制器 /// [ApiController] [Route("api/[controller]/[action]")] public class WcsController : ControllerBase { /// /// 获取设备配置信息接口 /// /// [HttpGet] public List GetDeviceList() { return Device.All.ToList(); } /// /// 获取设备运行状态 /// /// /// [HttpPost] public List GetDevRunInfo([FromBody] DevRunInfoViewMode req) { var runInfos = new List(); var db = new SqlSugarHelper().Default; var plcEx = new SqlSugarHelper().PLCEX; var type = ""; switch (req.Type) { case DevType.Robot: //机械臂 type = DevType.Robot.ToString(); //获取时段内设备的运行状态 var runInfoList = plcEx.Queryable().Where(x => x.Type == type && x.Frame >= req.StateTime && x.Frame < req.EndTime).ToList().GroupBy(x => x.Code); foreach (var runInfo in runInfoList) { var info = new RunInfo() { Code = runInfo.Key, EnterDepot = db.Queryable().With(SqlWith.NoLock) .Where(x => x.Status == TaskStatus.Finish && x.Type == TaskType.SetPlate && x.Device == runInfo.Key && x.EndTime >= req.StateTime && x.EndTime < req.EndTime) .SplitTable(x => x.Take(2)) .Count(), OutDepot = db.Queryable().With(SqlWith.NoLock) .Where(x => x.Status == TaskStatus.Finish && x.Type == TaskType.OutDepot && x.Device == runInfo.Key && x.EndTime >= req.StateTime && x.EndTime < req.EndTime) .SplitTable(x => x.Take(2)) .Count(), Free = runInfo.Where(x => x.RunMode == RobotMode.Automatic.GetDescription() && x.RunStatus == RobotRunStatus.Idle.GetDescription()).Sum(x => x.Duration) / 1000 / 60, Alarm = runInfo.Where(x => x.RunMode == RobotMode.Alarm.GetDescription()) .Sum(x => x.Duration) / 1000 / 60, Manual = runInfo.Where(x => x.RunMode == RobotMode.Manua.GetDescription()) .Sum(x => x.Duration) / 1000 / 60, Automatic = runInfo.Where(x => x.RunMode == RobotMode.Automatic.GetDescription() && x.RunStatus != RobotRunStatus.Idle.GetDescription() && x.RunStatus != RobotRunStatus.Maintain.GetDescription()) .Sum(x => x.Duration) / 1000 / 60, }; #region 开始分析设备动作,不计算停止时间 var devActions = new List(); double totalTime = 0; //总耗时 double totalCount = 0; //总次数 //入库 var infos = runInfo.Where(x => x.RunMode == RobotMode.Automatic.GetDescription()).OrderBy(x => x.Frame).ToList(); totalTime = infos.Where(x => x.RunStatus == RobotRunStatus.InboundCrawling.GetDescription() || x.RunStatus == RobotRunStatus.InStorage.GetDescription()).Sum(x => x.Duration); totalCount = infos.Count(x => x.RunStatus == RobotRunStatus.InboundCrawling.GetDescription()); devActions.Add(new DevActionViewMode() { Type = DevActionType.In.GetDescription(), ActionAmount = totalCount, ActionTime = totalTime == 0 ? 0 : Math.Round(totalTime / totalCount, 2), }); //出库 infos = runInfo.Where(x => x.RunMode == RobotMode.Automatic.GetDescription()).ToList(); totalTime = infos.Where(x => x.RunStatus == RobotRunStatus.OutBoundCrawling.GetDescription() || x.RunStatus == RobotRunStatus.OutStorage.GetDescription()).Sum(x => x.Duration); totalCount = infos.Count(x => x.RunStatus == RobotRunStatus.OutBoundCrawling.GetDescription()); devActions.Add(new DevActionViewMode() { Type = DevActionType.Out.GetDescription(), ActionAmount = totalCount, ActionTime = totalTime == 0 ? 0 : Math.Round(totalTime / totalCount, 2), }); info.DevAction = devActions; #endregion 开始分析设备动作,不计算停止时间 #region 计算任务的工位使用数量 var stationCounts = new List(); type = DevType.RobotTaskSum.ToString(); var taskSum = plcEx.Queryable().Where(x => x.Code == runInfo.Key && x.Type == type && x.Frame >= req.StateTime && x.Frame < req.EndTime) .ToList().Select(x => { var item = x; item.Duration = long.Parse(item.RunStatus.Split("--")[2]); return item; }).ToList(); //入库 stationCounts.Add(new StationCount() { Type = DevActionType.In.GetDescription(), StationNum = taskSum.Count(x => x is { Duration: 3, RunMode: "1" }), StationIndex = 1 }); stationCounts.Add(new StationCount() { Type = DevActionType.In.GetDescription(), StationNum = taskSum.Count(x => x is { Duration: 3, RunMode: "2" }), StationIndex = 2 }); //出库 stationCounts.Add(new StationCount() { Type = DevActionType.Out.GetDescription(), StationNum = taskSum.Count(x => x is { Duration: 4, RunMode: "1" }), StationIndex = 1 }); stationCounts.Add(new StationCount() { Type = DevActionType.Out.GetDescription(), StationNum = taskSum.Count(x => x is { Duration: 4, RunMode: "2" }), StationIndex = 2 }); info.StationCount = stationCounts; #endregion 计算任务的工位使用数量 runInfos.Add(info); } break; case DevType.Truss: type = DevType.Truss.ToString(); //获取时段内设备的运行状态 var trussInfoList = plcEx.Queryable().Where(x => x.Type == type && x.Frame >= req.StateTime && x.Frame < req.EndTime).ToList().GroupBy(x => x.Code); foreach (var runInfo in trussInfoList) { var info = new RunInfo() { Code = runInfo.Key, EnterDepot = db.Queryable().With(SqlWith.NoLock) .Where(x => x.Status == TaskStatus.Finish && x.Type == TaskType.SetPlate && x.Device == runInfo.Key && x.EndTime >= req.StateTime && x.EndTime < req.EndTime) .SplitTable(x => x.Take(2)) .Count(), Free = runInfo.Where(x => x.RunMode == TrussStatus.Idle.GetDescription()).Sum(x => x.Duration) / 1000 / 60, Alarm = runInfo.Where(x => x.RunMode == TrussStatus.Alarm.GetDescription()).Sum(x => x.Duration) / 1000 / 60, Manual = runInfo.Where(x => x.RunMode == TrussStatus.Manual.GetDescription() || x.RunMode == TrussStatus.KeepInRepair.GetDescription()).Sum(x => x.Duration) / 1000 / 60, Automatic = runInfo.Where(x => x.RunMode == TrussStatus.Execute.GetDescription()).Sum(x => x.Duration) / 1000 / 60, }; #region 开始分析设备动作,不计算停止时间 var devActions = new List(); double totalTime = 0; //总耗时 double totalCount = 0; //总次数 //入库 var infos = runInfo.Where(x => x.RunMode == TrussStatus.Execute.GetDescription()).ToList(); totalTime = infos.Where(x => x.RunMode == TrussStatus.Execute.GetDescription()).Sum(x => x.Duration); totalCount = infos.Count(x => x.RunMode == TrussStatus.Execute.GetDescription()); devActions.Add(new DevActionViewMode() { Type = DevActionType.In.GetDescription(), ActionAmount = totalCount, ActionTime = totalTime == 0 ? 0 : Math.Round(totalTime / totalCount, 2), }); info.DevAction = devActions; #endregion 开始分析设备动作,不计算停止时间 #region 计算任务的工位使用数量 var stationCounts = new List(); type = DevType.TrussTaskSum.ToString(); var taskSum = plcEx.Queryable().Where(x => x.Code == runInfo.Key && x.Type == type && x.Frame >= req.StateTime && x.Frame < req.EndTime) .ToList(); //入库 stationCounts.Add(new StationCount() { Type = DevActionType.In.GetDescription(), StationNum = taskSum.Count(x => x is { RunMode: "1" }), StationIndex = 1 }); stationCounts.Add(new StationCount() { Type = DevActionType.In.GetDescription(), StationNum = taskSum.Count(x => x is { RunMode: "2" }), StationIndex = 2 }); stationCounts.Add(new StationCount() { Type = DevActionType.In.GetDescription(), StationNum = taskSum.Count(x => x is { RunMode: "3" }), StationIndex = 3 }); stationCounts.Add(new StationCount() { Type = DevActionType.In.GetDescription(), StationNum = taskSum.Count(x => x is { RunMode: "4" }), StationIndex = 4 }); stationCounts.Add(new StationCount() { Type = DevActionType.In.GetDescription(), StationNum = taskSum.Count(x => x is { RunMode: "5" }), StationIndex = 5 }); stationCounts.Add(new StationCount() { Type = DevActionType.In.GetDescription(), StationNum = taskSum.Count(x => x is { RunMode: "6" }), StationIndex = 6 }); stationCounts.Add(new StationCount() { Type = DevActionType.In.GetDescription(), StationNum = taskSum.Count(x => x is { RunMode: "7" }), StationIndex = 7 }); stationCounts.Add(new StationCount() { Type = DevActionType.In.GetDescription(), StationNum = taskSum.Count(x => x is { RunMode: "8" }), StationIndex = 8 }); stationCounts.Add(new StationCount() { Type = DevActionType.In.GetDescription(), StationNum = taskSum.Count(x => x is { RunMode: "9" }), StationIndex = 9 }); stationCounts.Add(new StationCount() { Type = DevActionType.In.GetDescription(), StationNum = taskSum.Count(x => x is { RunMode: "10" }), StationIndex = 10 }); info.StationCount = stationCounts; #endregion 计算任务的工位使用数量 runInfos.Add(info); } break; } return runInfos; } #region 设备IP相关 /// /// 检查Ip是否正常联通 /// /// 输入参数,表示IP地址或域名 /// [HttpGet] public static bool PingIpOrDomainName(string strIpOrDName) { try { var objPingSender = new Ping(); var objPinOptions = new PingOptions { DontFragment = true }; const string data = ""; var buffer = Encoding.UTF8.GetBytes(data); const int intTimeout = 120; var objPinReply = objPingSender.Send(strIpOrDName, intTimeout, buffer, objPinOptions); var strInfo = objPinReply.Status.ToString(); return strInfo == "Success"; } catch (Exception) { return false; } } /// /// 获取设备IP检测结果 /// /// 设备IP检测结果 [HttpGet] public List DeviceIpTest() { if (!ServiceHub.DeviceIPList.Any()) throw new Exception("未配置任何Ip"); var deviceIpTestResults = new List(); ServiceHub.DeviceIPList.ForEach(ip => { deviceIpTestResults.Add(new DeviceIpTestResults { Ip = ip, Result = PingIpOrDomainName(ip) }); }); return deviceIpTestResults; } /// /// 获取设备Ip集合 /// /// 设备Ip集合 [HttpGet] public List GetDeviceIpList() { if (!ServiceHub.DeviceIPList.Any()) throw new Exception("未配置任何Ip"); return ServiceHub.DeviceIPList; } #endregion 设备IP相关 } /// /// 设备运行状态 /// public class DevRunInfoViewMode { /// /// 类型 /// public DevType Type { get; set; } /// /// 开始时间 /// public DateTime StateTime { get; set; } /// /// 结束时间 /// public DateTime EndTime { get; set; } } /// /// 分页参数 /// public class PagedInfo { /// /// 每页行数 /// public int PageSize { get; set; } = 10; /// /// 当前页 /// public int PageIndex { get; set; } = 1; /// /// 总记录数 /// public int TotalNum { get; set; } /// /// 总页数 /// public int TotalPage { get { if (TotalNum > 0) { return TotalNum % this.PageSize == 0 ? TotalNum / this.PageSize : TotalNum / this.PageSize + 1; } else { return 0; } } set { } } public List Result { get; set; } public Dictionary Extra { get; set; } = new Dictionary(); public PagedInfo() { } } public class RunInfo { public string Code { get; set; } /// /// 出库任务 /// public int OutDepot { get; set; } /// /// 入库任务 /// public int EnterDepot { get; set; } /// /// 移库任务 /// public int MoveDepot { get; set; } /// /// 空闲 /// public double Free { get; set; } /// /// 手动 /// public double Manual { get; set; } /// /// 自动 /// public double Automatic { get; set; } /// /// 报警 /// public double Alarm { get; set; } /// /// 运行 /// public double Working { get; set; } /// /// 交互总耗时 /// public double InteractTotal { get; set; } /// /// 设备执行分析 /// public List DevAction { get; set; } /// /// 任务执行工位使用数量 /// public List StationCount { get; set; } } /// /// 设备动作分析 /// public class DevActionViewMode { /// /// 动作次数 /// public double ActionAmount { get; set; } /// /// 动作平均耗时 /// public double ActionTime { get; set; } /// /// 动作类型 /// public string Type { get; set; } } /// /// 设备动作类型 /// public enum DevActionType { /// /// 入库 /// [Description("入库")] In = 0, /// /// 出库 /// [Description("出库")] Out = 1, /// /// 移库 /// [Description("移库")] Move = 2, } /// /// 任务执行工位数量 /// public class StationCount { /// /// 执行数量 /// public double StationNum { get; set; } /// /// 工位数 /// public double StationIndex { get; set; } /// /// 任务类型 /// public string Type { get; set; } } }