using HslCommunication;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Metadata;
using System.Text;
using System.Threading;
using WIDESEA_Common;
using WIDESEA_Common.CutomerModel;
using WIDESEA_Common.LogEnum;
using WIDESEA_Common.TaskEnum;
using WIDESEA_Common.Tools;
using WIDESEA_Core.Utilities;
using WIDESEA_Entity.DomainModels;
using WIDESEA_Services;
using WIDESEA_Services.IRepositories;
using WIDESEA_Services.Repositories;
using WIDESEA_Services.Services;
using WIDESEA_WCS.WCSClient;
namespace WIDESEA_WCS.Jobs.ConveyorLine.OutboundArea
{
public partial class OutboundAreaDispatch
{
///
/// 出库的层
///
private static List OutboundStationLayerNo = new List() { "60101", "60102", "60103", "60104", "60105", "60106", "60107" };
///
/// 入库托盘申请站台
///
private static string ReInboundRequestStationNo = "90101";
//出库站台交互
//private static string OutboundStationNo = "90201";
//提升机编号
private static string hoisterResultNo = "90100";
///
/// 出库区调度
///
///
///
public static string currentModel = "Inbound";
static int flag = 0;
// 压装台缓存位字典
public static Dictionary PlatformDict = new Dictionary
{
["70101"] = "80101",
["70103"] = "80103",
["70104"] = "80104",
["70106"] = "80106"
};
public static void OutboundAreaDispathAction(IDt_TaskWCSinfoRepository taskWCSinfoRepository, IDt_TaskRGVinfoRepository taskRGVinfoRepository, PLCClient client)
{
try
{
//出库完成
OutboundCompleteAction(taskWCSinfoRepository, client); //压装出库口任务完成
//生成可下发的RGV任务,至缓存口
List executingTask = taskWCSinfoRepository.Find(r => r.wcstask_state != TaskState.TaskState_Assigned.ToString()
&& endStationNo.Contains(r.wcstask_endPoint));
// 这里要写一个逻辑,就是我获取的任务,只有对应的站台为空,我才能下发,这样改的话,空托盘入库也要改
if (executingTask.Count < 8) //小于8,则可生成去这边的任务
{
//直接将任务添加到AGV任务
Dt_TaskWCSinfo outboundTask = GetOutboundTask(taskWCSinfoRepository, client);
if (null != outboundTask)
{
//查找是否有该托盘条码任务,如果没有则进行添加RGV任务
Dt_TaskRGVinfo rgvInfo = taskRGVinfoRepository.FindFirst(r => r.rgvtask_barCode == outboundTask.wcstask_barcode
&& r.rgvtask_wcsTaskNumber == outboundTask.wcstask_taskNumber);
if (null == rgvInfo)
{
string rgvTaskType = RGVTaskType.RgvTaskType_Inbound.ToString();
if (outboundTask.wcstask_type.Equals(TaskType.TaskType_Box_Pallet_Outbound.ToString())
|| outboundTask.wcstask_type.Equals(TaskType.TaskType_Empty_Pallet_Outbound.ToString()))
rgvTaskType = RGVTaskType.RgvTaskType_Outbound.ToString();
rgvInfo = GetRGVTask(taskRGVinfoRepository, outboundTask, rgvTaskType);
taskRGVinfoRepository.Add(rgvInfo, true);
outboundTask.wcstask_state = TaskState.TaskState_RGV_Received.ToString();
taskWCSinfoRepository.Update(outboundTask, x => x.wcstask_state, true);
}
}
}
//缓存口(缓存架)至输送线
OutboundCZ_PLC(taskWCSinfoRepository, taskRGVinfoRepository, client);
//空托入库申请(生成了空托入库任务)
InboundRequestAction(taskWCSinfoRepository, taskRGVinfoRepository, client);
//空托到缓存口(缓存架)
ReInboundKTP(taskWCSinfoRepository, client);
//空托入库口,生成RGV任务,进行入库
RGV_InboundKTP(taskWCSinfoRepository, taskRGVinfoRepository, client);
}
catch (Exception ex)
{
WriteLog.Info("OutboundArea").Write($"{ DateTime.Now }出库区域调度失败:{ex.Message}", "OutboundArea");
}
}
public static bool WriteRGVState(PLCClient client, bool value)
{
client.WriteValue(CLineInfoDBName.W_System_RGVState.ToString(), value);
string rel = string.Empty;
for (int i = 0; i < 50; i++)
{
rel = client.ReadValue(CLineInfoDBName.W_System_RGVState.ToString()).ToString();
if (value == bool.Parse(rel))
break;
else
{
client.WriteValue(CLineInfoDBName.W_System_RGVState.ToString(), value);
Thread.Sleep(88);
}
}
rel = client.ReadValue(CLineInfoDBName.W_System_RGVState.ToString()).ToString();
if (value != bool.Parse(rel))
Console.Out.WriteLine($"{DateTime.Now}写入车存储中{value}失败.");
return bool.Parse(rel);
}
///
/// 查询是否有可出的出库任务
///
///
///
///
public static Dt_TaskWCSinfo GetOutboundTask(IDt_TaskWCSinfoRepository taskWCSinfoRepository, PLCClient client)
{
Dt_TaskWCSinfo wcsInfo = null;
List listTask = taskWCSinfoRepository.Find(r => r.wcstask_state == TaskState.TaskState_Assigned.ToString() &&
(r.wcstask_type == TaskType.TaskType_Box_Pallet_Outbound.ToString() || r.wcstask_type == TaskType.TaskType_Empty_Pallet_Outbound.ToString())
&& OutboundStationLayerNo.Contains(r.wcstask_startPoint)).OrderBy(r => r.wcstask_createTime).ToList();//
foreach (var item in listTask.GroupBy(r => r.wcstask_endPoint))
{
Dt_TaskWCSinfo wcsTask = item.OrderBy(r => r.wcstask_createTime).FirstOrDefault();
if (null != wcsTask)
{
//判断压装台是否有货 也就是判断80101那边
bool yzflag = bool.Parse(client.ReadValue(CLineInfoDBName.R_Line_LoadSleep.ToString(), PlatformDict[wcsTask.wcstask_endPoint]).ToString());
bool yznoflag = bool.Parse(client.ReadValue(CLineInfoDBName.R_Line_NoLoadSleep.ToString(), PlatformDict[wcsTask.wcstask_endPoint]).ToString());
if (yzflag || !yznoflag)
continue;
//判断缓存架是否有货
bool flag = bool.Parse(client.ReadValue(CLineInfoDBName.R_Line_LoadSleep.ToString(),wcsTask.wcstask_startPoint).ToString());
bool noflag = bool.Parse(client.ReadValue(CLineInfoDBName.R_Line_NoLoadSleep.ToString(), wcsTask.wcstask_startPoint).ToString());
if (flag || !noflag)
continue;
//同一层有执行中的任务不添加
Dt_TaskWCSinfo executingTask = taskWCSinfoRepository.FindFirst(r => (r.wcstask_startPoint == wcsTask.wcstask_startPoint || r.wcstask_endPoint == wcsTask.wcstask_endPoint)
&& (r.wcstask_state == TaskState.TaskState_RGV_Received.ToString() || r.wcstask_state == TaskState.TaskState_HoisterExecuting.ToString()));
if (null != executingTask)
continue;
List listTarget = taskWCSinfoRepository.Find(r => r.wcstask_endPoint == wcsTask.wcstask_endPoint &&
r.wcstask_state != TaskState.TaskState_Assigned.ToString());
if(listTarget != null && listTarget.Count >= 2)
{
continue;
}
else
{
wcsInfo = wcsTask;
}
string barcode = client.ReadValue(CLineInfoDBName.R_Line_Barcode.ToString(), wcsTask.wcstask_endPoint).ToString();
//if (string.IsNullOrEmpty(barcode) || "0".Equals(barcode))
//{
// if (null != listTarget && listTarget.Count > 2)
// continue;
// else
// {
// wcsInfo = wcsTask;
// break;
// }
//}
//else
//{
// if (null != listTarget && listTarget.Count > 1)
// continue;
// else
// {
// wcsInfo = wcsTask;
// break;
// }
//}
}
}
return wcsInfo;
}
public static Dt_TaskRGVinfo GetRGVTask(IDt_TaskRGVinfoRepository taskRGVinfoRepository, Dt_TaskWCSinfo wcsTask, string rgvTaskType)
{
Dt_TaskRGVinfo rgvInfo = new Dt_TaskRGVinfo();
rgvInfo.rgvtask_taskId = GetTaskNumber.GetRgvTaskNumber(taskRGVinfoRepository).ToString();
rgvInfo.rgvtask_taskType = rgvTaskType;
rgvInfo.rgvtask_taskStatus = RGVTaskState.RgvTaskState_Wait_Send.ToString();
rgvInfo.rgvtask_priorityCode = wcsTask.wcstask_grade.ToString();
rgvInfo.rgvtask_startNode = wcsTask.wcstask_startLocation;
rgvInfo.rgvtask_endNode = wcsTask.wcstask_endLocation;
rgvInfo.rgvtask_wcsTaskNumber = wcsTask.wcstask_taskNumber;
rgvInfo.rgvtask_barCode = wcsTask.wcstask_barcode;
rgvInfo.rgvtask_creator = wcsTask.wcstask_creator;
rgvInfo.rgvtask_msgTime = DateTime.Now;
rgvInfo.rgvtask_areaCode = "OutboundArea";
return rgvInfo;
}
public static void InboundRequestAction(IDt_TaskWCSinfoRepository taskWCSinfoRepository, IDt_TaskRGVinfoRepository taskRGVinfoRepository, PLCClient client)
{
try
{
//string barcode = "901010";
int R_Line_PLCDispatch = int.Parse(client.ReadValue(CLineInfoDBName.W_Line_PLCDispatch.ToString(), ReInboundRequestStationNo).ToString());
bool load = bool.Parse(client.ReadValue(CLineInfoDBName.R_Line_LoadSleep.ToString(), ReInboundRequestStationNo).ToString());
if (R_Line_PLCDispatch == 1 && load)
{
string barcode = client.ReadValue(CLineInfoDBName.R_Line_Barcode.ToString(), ReInboundRequestStationNo).ToString();
// 这里要加一个判断,如果拿回来的空托盘是800001,但是我有一条这个托盘的任务是800001还没有到指定的压装台,所以我要完成这个任务
Dt_TaskWCSinfo IsTask = taskWCSinfoRepository.FindFirst(x => x.wcstask_barcode == barcode && x.wcstask_state == TaskState.TaskState_Empty_Out_Line_Executing.ToString());
if (IsTask != null)
{
//在此完成该空托出库任务
WebResponseContent content = taskWCSinfoRepository.DbContextBeginTransaction(() =>
{
//上报WMS任务完成
content = WMSApi.TellWmsTaskFinished(IsTask.wcstask_barcode);
if (content.Status)
{
//移动任务到历史表
Dt_TaskWCSinfo_HtyRepository taskWCSinfo_HtyRepository = new Dt_TaskWCSinfo_HtyRepository(taskWCSinfoRepository.DbContext);
IsTask.wcstask_state = TaskState.TaskState_Finished.ToString();
CommonFunction.AddWcsTaskToHistory(IsTask, taskWCSinfoRepository, taskWCSinfo_HtyRepository);
}
else
throw new Exception($"{DateTime.Now}上报WMS任务完成出错,原因:【{content.Message}】");
return content;
});
string str = string.Empty;
if (content.Status)
str = $" {DateTime.Now}上报WMS出库完成成功,【手动干扰出库没有到达指定压装台点位,手动拿回90101】【TaskState_ConveyorLineExecuting】,托盘号:{IsTask.wcstask_barcode},任务号:{IsTask.wcstask_taskNumber}";
else
str = $" {DateTime.Now}上报WMS出库完成失败【手动干扰出库没有到达指定压装台点位,手动拿回90101】【TaskState_ConveyorLineExecuting】,托盘号:{IsTask.wcstask_barcode},任务号:{IsTask.wcstask_taskNumber}";
WriteLog.Info(IsTask.wcstask_endPoint).Write(str, IsTask.wcstask_endPoint);
}
if (!string.IsNullOrEmpty(barcode) && !"0".Equals(barcode))
{
Dt_TaskWCSinfo wcsInfo = taskWCSinfoRepository.FindFirst(r => r.wcstask_barcode == barcode && r.wcstask_type == TaskType.TaskType_Empty_Pallet_Inbound.ToString());
if (null == wcsInfo)
{
//获取车轴出库
List executingTask = taskWCSinfoRepository.Find(r => (r.wcstask_type.Equals(TaskType.TaskType_Box_Pallet_Outbound.ToString()) ||
r.wcstask_type.Equals(TaskType.TaskType_Empty_Pallet_Outbound.ToString())) && endStationNo.Contains(r.wcstask_endPoint));
//获取有多少条出库的任务
int LineExecucount = executingTask.Count(x => x.wcstask_state == TaskState.TaskState_Box_Out_Line_Executing.ToString() || x.wcstask_state == TaskState.TaskState_Empty_Out_Line_Executing.ToString());
if (LineExecucount >= 8)
{
//判断是否有对应层的出库任务,
//申请入库任务
WebResponseContent content = WMSApi.PostInboundRequstToWMS(barcode);
if (content.Status)
{
WmsTaskInfo wmsTask = JsonConvert.DeserializeObject(content.Data.ToString());
wcsInfo = CommonFunction.AddWCSEmptyInboundTask(wmsTask, taskWCSinfoRepository);
taskWCSinfoRepository.Add(wcsInfo, true);
//client.WriteValue(CLineInfoDBName.W_Line_PLCDispatch.ToString(), ReInboundRequestStationNo, 2);
}
else
{
throw new Exception("入库申请失败:" + content.Message);
}
}
else
{
//判断有多少条在缓存架的
int RGV_Finishedcount = executingTask.Count(x => x.wcstask_state != TaskState.TaskState_Box_Out_Line_Executing.ToString()
&& x.wcstask_state != TaskState.TaskState_Empty_Out_Line_Executing.ToString()
&& x.wcstask_state != TaskState.TaskState_Assigned.ToString());
if (RGV_Finishedcount == 0)
{
//申请入库任务
WebResponseContent content = WMSApi.PostInboundRequstToWMS(barcode);
if (content.Status)
{
WmsTaskInfo wmsTask = JsonConvert.DeserializeObject(content.Data.ToString());
wcsInfo = CommonFunction.AddWCSEmptyInboundTask(wmsTask, taskWCSinfoRepository);
taskWCSinfoRepository.Add(wcsInfo, true);
//client.WriteValue(CLineInfoDBName.W_Line_PLCDispatch.ToString(), ReInboundRequestStationNo, 2);
}
else
{
throw new Exception("入库申请失败:" + content.Message);
}
}
}
}
}
else
{
throw new Exception("入库申请失败:读取到的空托盘条码为空,读取内容:"+ barcode);
}
}
}
catch (Exception ex)
{
client.WriteValue(CLineInfoDBName.W_Line_PLCDispatch.ToString(), ReInboundRequestStationNo, 3);
Console.Out.WriteLine(DateTime.Now + ex.Message);
}
}
}
}