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; }
}
}