using HslCommunication;
using Newtonsoft.Json;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
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 OutboundAreaJZ(IDt_TaskWCSinfoRepository taskWCSinfoRepository, IDt_TaskRGVinfoRepository taskRGVinfoRepository, PLCClient client)
{
// 出库区的出库任务 到缓存架子了 就要把任务号和托盘号写入到对应层的缓存架
List executingTasks = taskWCSinfoRepository.Find(r => (
r.wcstask_state == TaskState.TaskState_Box_Out_RGV_Finished.ToString() ||
r.wcstask_state == TaskState.TaskState_Empty_Out_RGV_Finished.ToString())
&& endStationNo.Contains(r.wcstask_endPoint)).ToList();
foreach (var item in executingTasks)
{
bool LoadSleep = bool.Parse(client.ReadValue(CLineInfoDBName.R_Line_LoadSleep.ToString(), item.wcstask_startPoint.ToString()).ToString());
int ReadNumber = int.Parse(client.ReadValue(CLineInfoDBName.R_Line_TaskNumber.ToString(), item.wcstask_startPoint.ToString()).ToString());
int ReadBarcode = int.Parse(client.ReadValue(CLineInfoDBName.R_Line_Barcode.ToString(), item.wcstask_startPoint.ToString()).ToString());
if (LoadSleep && (ReadNumber == 0 || ReadBarcode == 0))
{
//写入托盘条码
bool writeTaskNumber = client.WriteValue(CLineInfoDBName.W_Line_TaskNumber.ToString(), item.wcstask_startPoint, item.wcstask_taskNumber);
bool writeBarcode = client.WriteValue(CLineInfoDBName.W_Line_Barcode.ToString(), item.wcstask_startPoint, item.wcstask_barcode);
}
}
foreach (var item in OutboundStationLayerNo)
{
bool LoadSleep = bool.Parse(client.ReadValue(CLineInfoDBName.R_Line_LoadSleep.ToString(), item.ToString()).ToString());
int ReadNumber = int.Parse(client.ReadValue(CLineInfoDBName.R_Line_TaskNumber.ToString(), item.ToString()).ToString());
int ReadBarcode = int.Parse(client.ReadValue(CLineInfoDBName.R_Line_Barcode.ToString(), item.ToString()).ToString());
Dt_TaskWCSinfo dt_TaskWCSinfo = taskWCSinfoRepository.Find(r =>
r.wcstask_type == TaskType.TaskType_Empty_Pallet_Inbound.ToString()
&& r.wcstask_state == TaskState.TaskState_Assigned.ToString()
&& r.wcstask_startPoint == 90101.ToString()
&& r.wcstask_endPoint == item
&& r.wcstask_barcode == ReadBarcode.ToString()
&& r.wcstask_taskNumber == ReadNumber
).FirstOrDefault();
if (LoadSleep && dt_TaskWCSinfo != null)
{
// 证明货物已经到了缓存架 但任务状态没有改变 还是新建状态 就要改为 TaskState.TaskState_Empty_In_PLC_Finished.ToString()
dt_TaskWCSinfo.wcstask_state = TaskState.TaskState_Empty_In_PLC_Finished.ToString();
taskWCSinfoRepository.Update(dt_TaskWCSinfo, true);
string str = $"出库区域 空托盘回库 托盘都到缓存架子 但任务状态没变 {DateTime.Now}【{dt_TaskWCSinfo.wcstask_state}】,托盘号:{dt_TaskWCSinfo.wcstask_barcode},任务号:{dt_TaskWCSinfo.wcstask_taskNumber}";
LogRecord.WriteLog(LogEnum.Errer, str.ToString());
}
}
// 这里要写一个 有一些托盘已经出到外面去了 但状态还是提升机运行中 导致后面的发不出去
Dt_TaskWCSinfo OutTask = taskWCSinfoRepository.Find(r =>
r.wcstask_state == TaskState.TaskState_HoisterExecuting.ToString()
&& endStationNo.Contains(r.wcstask_endPoint)
).FirstOrDefault();
if (OutTask != null)
{
double secondsPassend = (DateTime.Now - OutTask.wcstask_dispatcherTime.Value).TotalSeconds;
if (secondsPassend > 38) // 如果大于38秒 还没用提升机完成 就要手动
{
string state = TaskState.TaskState_Box_Out_Line_Executing.ToString();
if (OutTask.wcstask_type == TaskType.TaskType_Empty_Pallet_Outbound.ToString())
{
state = TaskState.TaskState_Empty_Out_Line_Executing.ToString();
}
OutTask.wcstask_state = state;
OutTask.wcstask_dispatcherTime = DateTime.Now;
taskWCSinfoRepository.Update(OutTask, true);
string str = $"出库区 出库 提升机已经内的托盘已经出去 但状态还是提升机执行中... {DateTime.Now},托盘号:{OutTask.wcstask_barcode},任务号:{OutTask.wcstask_taskNumber}";
LogRecord.WriteLog(LogEnum.Errer, str.ToString());
}
}
}
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())
&& endStationNo.Contains(r.wcstask_endPoint)).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;
// 肖佼 将上面修改成下面
Dt_TaskWCSinfo executingTask = taskWCSinfoRepository.FindFirst(r =>
(r.wcstask_startPoint == wcsTask.wcstask_startPoint)
&& (r.wcstask_state == TaskState.TaskState_RGV_Received.ToString()));
if (null != executingTask)
continue;
List listTarget = taskWCSinfoRepository.Find(r => r.wcstask_endPoint == wcsTask.wcstask_endPoint &&
r.wcstask_state != TaskState.TaskState_Assigned.ToString());
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 > 1)
continue;
else
{
wcsInfo = wcsTask;
break;
}
}
else
{
if (null != listTarget && listTarget.Count > 0)
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;
}
// 只用一个字典:Key=托盘号,Value=Tuple<锁对象, 最后使用时间>
// Tuple