添加项目文件。
This commit is contained in:
439
WPFWCSDemo/Schedules/CircleRGV/Check.cs
Normal file
439
WPFWCSDemo/Schedules/CircleRGV/Check.cs
Normal file
@@ -0,0 +1,439 @@
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using WPFWCSDemo.Common;
|
||||
using WPFWCSDemo.Data;
|
||||
using WPFWCSDemo.Models.Devices.CircleRGV;
|
||||
using WPFWCSDemo.Models.Tables;
|
||||
using WPFWCSDemo.StateCode;
|
||||
using WPFWCSDemo.Utilities;
|
||||
using WPFWCSDemo.ViewModels;
|
||||
|
||||
namespace WPFWCSDemo.Schedules.CircleRGV
|
||||
{
|
||||
/// <summary>
|
||||
/// 任务校验
|
||||
/// </summary>
|
||||
public class Check
|
||||
{
|
||||
static int deviceCount = RGVStation.RGVCount;
|
||||
|
||||
/// <summary>
|
||||
/// 生成【空托】任务条件校验
|
||||
/// </summary>
|
||||
/// <param name="sourceLocation">源站点(可表示某条输送线)</param>
|
||||
/// <param name="targetLocation">目标站点(可表示某条输送线)</param>
|
||||
/// <param name="isNotException">输送口是否正常 true-系统正常 false-系统异常</param>
|
||||
/// <returns>是否满足生成任务条件 true-可生成 false-禁止生成</returns>
|
||||
public static bool CanTaskGenerated(int sourceLocation, int targetLocation, bool isNotException)
|
||||
{
|
||||
//校验---源站点请求
|
||||
if (QueryForIsRequestReset(sourceLocation, 3)) return false;
|
||||
|
||||
//校验---目标站点请求
|
||||
if (QueryForIsRequestReset(targetLocation, 3)) return false;
|
||||
|
||||
//校验---系统异常
|
||||
if (!isNotException) return false;
|
||||
|
||||
//校验---同输送口相邻任务生成时间间隔过短
|
||||
if (!CheckSendTaskTimeInterval(targetLocation, 999)) return false;
|
||||
|
||||
//校验---如果已经存在处于【取货阶段】的某个【空托】任务
|
||||
//由于【空托任务】输送线的源站点唯一,因此必须等待该任务取货完成才能生成新的【空托】任务
|
||||
if (!IsPalletConvHasGettingTask()) return false;
|
||||
|
||||
//校验---当前输送线存在【空托】任务
|
||||
if (!GetRGVTaskForPalletsIsExist(targetLocation)) return false;
|
||||
|
||||
//校验5.当前同一【目标站点】是否已经生成任务
|
||||
if (!CheckSendTaskIsRepeat(sourceLocation, TaskType.Pallet)) return false;
|
||||
|
||||
//校验---上位是否手动禁止生成
|
||||
if (LineTaskForPermission(targetLocation) == 0) return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 生成【实垛】任务校验条件
|
||||
/// </summary>
|
||||
/// <param name="sourceLocation">源站点(可表示某条输送线)</param>
|
||||
/// <param name="isNotException">输送口是否正常 true-系统正常 false-系统异常</param>
|
||||
/// <returns>是否满足生成任务条件 true-可生成 false-禁止生成</returns>
|
||||
public static bool CanTaskGenerated(int sourceLocation, bool isNotException)
|
||||
{
|
||||
|
||||
//校验0 放货口无允许
|
||||
//2025.9新增
|
||||
//1003-1009输送口校验
|
||||
if (sourceLocation == RGVStation.LineM_Goods_In)
|
||||
{
|
||||
if (QueryForIsRequestReset(RGVStation.LineToWarehouse1_Out, 3)) return false;
|
||||
}
|
||||
//2025.9新增
|
||||
//1005-1010输送口校验
|
||||
if (sourceLocation == RGVStation.LineL_Goods_In)
|
||||
{
|
||||
if (QueryForIsRequestReset(RGVStation.LineToWarehouse2_Out, 3)) return false;
|
||||
}
|
||||
|
||||
//校验1.输送口无请求
|
||||
if (QueryForIsRequestReset(sourceLocation, 3)) return false;
|
||||
|
||||
//校验2.输送口系统异常
|
||||
if (!isNotException) return false;
|
||||
|
||||
//校验3.同输送口相邻任务生成时间间隔过短
|
||||
if (!CheckSendTaskTimeInterval(sourceLocation)) return false;
|
||||
|
||||
//校验4.当前输送线存在取货阶段的任务
|
||||
if (!GetRGVTaskForGoodsIsExist(sourceLocation)) return false;
|
||||
|
||||
//校验5.当前同一【源站点】是否已经生成【取货阶段】任务
|
||||
if (!CheckSendTaskIsRepeat(sourceLocation, TaskType.Goods)) return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 防错机制【用于避免请求延迟的重复下发】--- 检测上一条【实垛】任务放货时间与当前时间是否相差x秒以上
|
||||
/// </summary>
|
||||
/// <param name="location">站点</param>
|
||||
/// <returns> true-相差大于x秒 false-相差小于x秒</returns>
|
||||
public static bool CheckSendTaskTimeInterval(int location)
|
||||
{
|
||||
int diff = -15;
|
||||
|
||||
using var context = new AppDbContext();
|
||||
|
||||
var loadedState = context
|
||||
.Set<LoadedState>()
|
||||
.Where(t => t.Station == location)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (DateTime.Now.AddSeconds(diff) >= loadedState!.LoadingTime)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 防错机制【用于避免请求延迟的重复下发】--- 检测上一条【空托】任务放货时间(完成时间)与当前时间是否相差x秒以上
|
||||
/// </summary>
|
||||
/// <param name="location">站点</param>
|
||||
/// <returns> true-相差大于x秒 false-相差小于x秒</returns>
|
||||
public static bool CheckSendTaskTimeInterval(int location, int num)
|
||||
{
|
||||
int diff = -30;
|
||||
|
||||
using var context = new AppDbContext();
|
||||
|
||||
var loadedState = context
|
||||
.Set<LoadedState>()
|
||||
.Where(t => t.Station == location)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (DateTime.Now.AddSeconds(diff) >= loadedState!.PuttingTime)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 防错机制【重复下发】--- 检测已经生成但未下发的任务是否存在
|
||||
/// </summary>
|
||||
/// <param name="sourceLocation">源站点</param>
|
||||
/// <returns> true-同目标站点生成任务时间间隔合法 false-时间间隔过短</returns>
|
||||
public static bool CheckSendTaskIsRepeat(int location, int type)
|
||||
{
|
||||
using var context = new AppDbContext();
|
||||
|
||||
//实垛
|
||||
if (type == TaskType.Goods)
|
||||
{
|
||||
//生成的上一条【实垛】任务且同一个源站点 ---> 查找符合条件的记录
|
||||
var count = context
|
||||
.Set<TaskRT>()
|
||||
.Where(t => t.SourceLocation == location.ToString() && (t.ScheduleState==ScheduleStateCode.Trans_CircleRGV_Ready || t.ScheduleState == ScheduleStateCode.Trans_CircleRGV_Picking))
|
||||
.Count();
|
||||
|
||||
if (count < 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//空托
|
||||
if (type == TaskType.Pallet)
|
||||
{
|
||||
//生成的上一条【空托】任务且同一个目标站点 ---> 查找符合条件的记录
|
||||
var count1 = context
|
||||
.Set<TaskRT>()
|
||||
.Where(t => t.TargetLocation == location.ToString())
|
||||
.Count();
|
||||
|
||||
if (count1 < 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 计算某个输送口请求的值的和---用于确定该输送口在一定时间内请求是否已经复位
|
||||
/// 用于避免信号也许存在的不稳定(跳变)的情况
|
||||
/// </summary>
|
||||
/// <param name="Location">源站点/目标站点---表示对应列</param>
|
||||
/// <param name="count">计算的时间间隔(单位:秒)</param>
|
||||
/// <returns>true-无请求---已复位 false-请求存在-未复位</returns>
|
||||
public static bool QueryForIsRequestReset(int location, int count)
|
||||
{
|
||||
var context = new AppDbContext();
|
||||
|
||||
string s = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
|
||||
|
||||
var timeIsExist = context.ConvRequest
|
||||
.Where(a => a.Time == s)
|
||||
.Count();
|
||||
|
||||
if (timeIsExist == 0) { return false; }
|
||||
|
||||
string line = "";
|
||||
|
||||
switch (location)
|
||||
{
|
||||
case RGVStation.LineH_Goods_In:
|
||||
line = "Conv_Goods_In_1001";
|
||||
break;
|
||||
case RGVStation.LineM_Goods_In:
|
||||
line = "Conv_Goods_In_1003";
|
||||
break;
|
||||
case RGVStation.LineL_Goods_In:
|
||||
line = "Conv_Goods_In_1005";
|
||||
break;
|
||||
case RGVStation.LineG1_Goods_In:
|
||||
line = "Conv_Goods_In_1007";
|
||||
break;
|
||||
case RGVStation.LineG2_Goods_In:
|
||||
line = "Conv_Goods_In_1008";
|
||||
break;
|
||||
|
||||
|
||||
case RGVStation.LineGH_Pallets_In:
|
||||
line = "Conv_Pallets_In_1013";
|
||||
break;
|
||||
case RGVStation.LineH_Pallets_Out:
|
||||
line = "Conv_Pallets_Out_1002";
|
||||
break;
|
||||
case RGVStation.LineG_Pallets_Out:
|
||||
line = "Conv_Pallets_Out_1004";
|
||||
break;
|
||||
case RGVStation.LineLM_Pallets_Out:
|
||||
line = "Conv_Pallets_Out_1006";
|
||||
break;
|
||||
|
||||
case RGVStation.LineToWarehouse1_Out:
|
||||
line = "Conv_Goods_Out_1009";
|
||||
break;
|
||||
case RGVStation.LineToWarehouse2_Out:
|
||||
line = "Conv_Goods_Out_1010";
|
||||
break;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(line))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取当前时间节点前x行请求记录值
|
||||
using DataTable? dt = SqlHelper.ExecuteTable($"SELECT TOP {count} * FROM CONVREQUEST ORDER BY [time] DESC");
|
||||
|
||||
//无结果则返回
|
||||
if (dt is null || dt.Rows.Count == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int sum = 0;
|
||||
|
||||
//计算源站点对应某列3行请求(允许)值的和
|
||||
for (int i = 0; i < dt.Rows.Count; i++)
|
||||
{
|
||||
sum += (int)dt.Rows[i][line];
|
||||
}
|
||||
|
||||
if (sum == 0)
|
||||
{
|
||||
//为0---无请求
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//不等于0,请求存在或存在值跳变情况
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 手动禁止某条输送线下发任务(根据名称)
|
||||
/// </summary>
|
||||
/// <param name="name">输送线名称</param>
|
||||
/// <returns>0-禁止 1-允许</returns>
|
||||
public static int LineTaskForPermission(string name)
|
||||
{
|
||||
using var context = new AppDbContext();
|
||||
|
||||
var lineState = context.LineState
|
||||
.Where(p => p.Name == name)
|
||||
.Select(p => p.IsEnable)
|
||||
.FirstOrDefault();
|
||||
|
||||
return lineState;
|
||||
}
|
||||
/// <summary>
|
||||
/// 手动禁止某条输送线下发任务(根据目标站)
|
||||
/// </summary>
|
||||
/// <param name="source">源站点</param>
|
||||
/// <returns>0-禁止 1-允许</returns>
|
||||
public static int LineTaskForPermission(int target)
|
||||
{
|
||||
using var context = new AppDbContext();
|
||||
|
||||
var lineState = context.LineState
|
||||
.Where(p => p.Target == target)
|
||||
.Select(p => p.IsEnable)
|
||||
.FirstOrDefault();
|
||||
|
||||
return lineState;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 遍历环穿是否有某条输送线正在执行的(栈板)任务---即只要有该输送口的任务则不能生成新任务
|
||||
/// 判断条件 1.站点 2.执行阶段 3.允许下发
|
||||
/// (该方法会直接读取小车参数)
|
||||
/// </summary>
|
||||
/// <param name="sourceLocation">源站点(1至2位编号)</param>
|
||||
/// <returns>false-存在执行中的任务的设备 true-无在执行任务的设备</returns>
|
||||
public static bool GetRGVTaskForPalletsIsExist(int targetLocation)
|
||||
{
|
||||
List<CircleRGVState>? states = CircleRGVsViewModel.GetAllCircleRGVState();
|
||||
|
||||
if (states is null) return false;
|
||||
|
||||
//检查是否有符合条件的小车,如果有则标
|
||||
//【源站点】匹配
|
||||
// 任务处于【取货阶段】
|
||||
// 无【允许下发】---表示小车在工作中
|
||||
var count = states
|
||||
.Where(a => a.Read_TargetLocation == (targetLocation - 1000).ToString() && !a.Read_Permission)
|
||||
.Count();
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//无满足条件的小车则表示所有设备无此任务
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 遍历环穿是否有某条输送线正在执行的(实垛)任务---某站点输送线存在【取货阶段】任务时不能生成新任务
|
||||
/// 判断条件:
|
||||
/// 1.站点匹配
|
||||
/// 2.执行阶段--->取货阶段
|
||||
/// 3.允许下发
|
||||
/// (该方法会直接从地面站读取小车参数)
|
||||
/// </summary>
|
||||
/// <param name="sourceLocation">源站点(1至2位编号)</param>
|
||||
/// <returns>false-存在执行任务的设备(不能下发) true-无执行中的任务的设备(可下发)</returns>
|
||||
public static bool GetRGVTaskForGoodsIsExist(int sourceLocation)
|
||||
{
|
||||
List<CircleRGVState> states = CircleRGVsViewModel.GetAllCircleRGVState();
|
||||
|
||||
if (states is null) return false;
|
||||
|
||||
//检查是否有符合条件的小车,如果有则标
|
||||
//【源站点】匹配
|
||||
// 任务处于【取货阶段】
|
||||
// 无【允许下发】---表示小车在工作中
|
||||
var count = states
|
||||
.Where(a => a.Read_SourceLocation == (sourceLocation - 1000).ToString() && a.Read_Phase < 3 && a.Read_Phase > 0 && !a.Read_Permission)
|
||||
.Count();
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//无满足条件的小车则表示所有设备无此任务
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在已经生成的处于【取货阶段】的【栈板】任务 --- 源站点每次请求仅生成一条任务
|
||||
/// </summary>
|
||||
/// <returns>true-无符合条件的任务(即可生成新任务) false-存在符合条件的任务</returns>
|
||||
public static bool IsPalletConvHasGettingTask()
|
||||
{
|
||||
var context = new AppDbContext();
|
||||
|
||||
var count =context.Tasks
|
||||
.Where(a=>a.SourceLocation == RGVStation.LineGH_Pallets_In.ToString() &&
|
||||
(a.ScheduleState == ScheduleStateCode.Trans_CircleRGV_Ready ||
|
||||
a.ScheduleState == ScheduleStateCode.Trans_CircleRGV_PickOnTheWay ||
|
||||
a.ScheduleState == ScheduleStateCode.Trans_CircleRGV_Picking))
|
||||
.Count();
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user