using iWareCommon;
using iWareCommon.Utils;
using iWareSql;
using System;
using System.Collections.Generic;
using System.Threading;
using iWareCC.SrmService;
using System.Linq;
using iWareSql.Orm;
using System.Threading.Tasks;
using iWareSql.Entity.ParamModel;
using Newtonsoft.Json;
using iWareCC.BLL;
using iWareCC.Common;
using iWareModel;
using iWareCommon.Common.Globle;
using XiGang.Core.Model;
using iWareCC.Common.Helper;
using iWareModel.EnumType.AoSinPublicCommon;
using Admin.NET.Core.TaskModule.Enum;
using iWareSql.DbOrm;
using iWareSql.DataAccess;
using static WZ.Useful.Commons.DGVPrinter;
using System.Runtime.Remoting.Contexts;
namespace iWareCC
{
///
/// 堆垛机任务服务线程类
///
public class SrmTaskThreadService : DeviceThreadServiceHandle
{
private static string _namespace = "iWareCC.SrmTaskThreadService";
private SrmTaskThreadService() { }
public SrmTaskThreadService(iWareCommon.Utils.LogType logType)
{
base.currentLogType = logType;
}
public override void StartService()
{
Task.Run(() =>
{
try
{
//自动执行堆垛机任务线程
Log4NetHelper.WriteInfoLog(base.currentLogType, "自动执行堆垛机任务线程启动了");
//var srmList = new SrmService.SrmServiceClient().GetSrm_CacheEntity();
var srmList = FormCC.SrmDeviceList;
foreach (var x in srmList)
{
IssueTaskThread(x);
ConfirmFinishTaskThread(x);
}
}
catch (Exception ex)
{
Log4NetHelper.WriteErrorLog(base.currentLogType, "SrmTaskThreadService线程启动出现异常", ex);
}
});
}
#region 线程处理
#region 自动执行堆垛机任务线程
///
/// 自动执行堆垛机任务
///
///
public override void IssueTask(object deviceId)
{
string errMsg1 = "", errMsg2 = "", errMsg3 = "", errMsg4 = "";
int i_deviceId = (int)deviceId;
while (true)
{
if ((int)deviceId == (int)EDevice.堆垛机 && SystemValue.isStartedModel)
{
IssueTaskHandle(i_deviceId, out errMsg1);
}
//else if ((int)deviceId == (int)EDevice.二号堆垛机 && SystemValue.isAllowRuning_SrmTaskThreadService_2 && SystemValue.isStartedModel)
//{
// IssueTaskHandle(i_deviceId, out errMsg2);
//}
SystemWarningMsg._lbl_Alert_Srm1Release = errMsg1;
SystemWarningMsg._lbl_Alert_Srm2Release = errMsg2;
Thread.Sleep(500);//2秒一次
}
}
///
/// 自动执行堆垛机任务(线程)
///
///
public override void IssueTaskHandle(int deviceId, out string errMsg)
{
errMsg = "";
try
{
int int_deviceId = (int)deviceId;
var vs = new SrmServiceClient();
//2、判断堆垛机是否可以下发新任务
SdaResEntity sdaResult = vs.IsAllowSendTask(int_deviceId, out errMsg);
if (sdaResult.result == false)
{
errMsg = $"非自动、有任务未确认或有报警,{errMsg}";
return;
}
//bool isOk = ValidateDeviceIsAllowSendTask(int_deviceId, out errMsg);
//if (!isOk)
//{
// errMsg = "不允许下发新任务," + errMsg;
// return;
//}
using (DbOrm dbOrm = new DbOrm())
{
var srmTaskList = ValidateIsExistTaskToDisposeForIssued(dbOrm, int_deviceId, out errMsg);
if (srmTaskList == null || srmTaskList.Count == 0)
{
//表示DB中没有任务要发送给堆垛机
errMsg = $"没有要执行的堆垛机任务";
return;
}
foreach (var item in srmTaskList)
{
SingleIssueTaskHandle(item, dbOrm, int_deviceId, vs, out errMsg);
if (!string.IsNullOrEmpty(errMsg))
{//说明报错了,继续走下一个循环
continue;
}
else
{//说明执行成功了,跳出循环
//修改下发的堆垛机任务状态,0->1
item.TaskState = (int)SubTaskStateEnum.已下发;
dbOrm.SaveChanges();
break;
}
}
}
vs.Close();
}
catch (Exception ex)
{
errMsg = "异常,请联系管理员:" + ex.Message;
//SysExceptionInfoHandler.GetExceptionInfoForError("自动执行堆垛机任务(线程)出现异常,deviceId:" + deviceId + ",异常:" + ex.Message, ex, ref exception);
//SysExceptionInfoHandler.InsertExceptionInfo(exception, true);
}
}
private string GetRealLocatiomCodeOut(string sourcePlace)
{
switch (sourcePlace)
{
case "102":
return "1-00-901-00";
//case "202":
// return "1-00-902-00";
//case "203":
// return "2-00-901-00";
//case "204":
// return "2-00-902-00";
default:
return "ERROR";
}
}
private string GetRealLocatiomCodeIn(string sourcePlace)
{
switch (sourcePlace)
{
case "102":
return "1-00-801-00";
//case "202":
// return "1-00-802-00";
//case "203":
// return "2-00-801-00";
//case "204":
// return "2-00-802-00";
default:
return "ERROR";
}
}
///
/// 单个堆垛机任务下发处理
///
///
///
///
///
///
private void SingleIssueTaskHandle(ware_task_sub srmTask, DbOrm dbOrm, int int_deviceId, SrmServiceClient vs, out string errMsg)
{
#region //3、判断数据库中是否有可要下发的任务,如果有就下发
DeviceTaskTypeEnum _DeviceTaskTypeEnum = (DeviceTaskTypeEnum)Enum.Parse(typeof(DeviceTaskTypeEnum), srmTask.TaskType.ToString());
EDevice device = (EDevice)Enum.Parse(typeof(EDevice), int_deviceId.ToString());
string realSourcePlace = "";
string realToPlace = "";
bool isOk;
if (srmTask.TaskType == (int)TaskCategoryEnum.InStock)
{
realSourcePlace = GetRealLocatiomCodeIn(srmTask.SourcePlace);
realToPlace = srmTask.ToPlace;
if (realToPlace.Substring(2).StartsWith("02"))
{
//查看该1排是否有货
var arr = realToPlace.Split('-');
string newstr = arr[0] + "-" + "01" + "-" + arr[2] + "-" + arr[3];
//看1排是否有货,无货放1排
var lvc = dbOrm.ware_location_vs_container.AsNoTracking().Any(u => u.WareLocationCode == newstr);
if (!lvc)
{
var container1 = dbOrm.wms_container.Where(u => u.RealLocationCode == newstr).FirstOrDefault();
if (container1 != null)
{
container1.RealLocationCode = realToPlace;
}
//查看是否有指向1排原绑定库位的任务
var newtask = dbOrm.ware_task.Where(u => u.ToLocationCode == newstr).FirstOrDefault();
if (newtask != null)
{
newtask.ToLocationCode = realToPlace;
var newtasksub = dbOrm.ware_task_sub.Where(u => u.TaskId == newtask.Id && u.DeviceId == int_deviceId && u.ToPlace == newstr).FirstOrDefault();
if (newtasksub != null)
{
newtasksub.ToPlace = realToPlace;
}
}
//目标库位修改为1排
realToPlace = newstr;
var container = dbOrm.wms_container.Where(u => u.ContainerCode == srmTask.ContainerCode).FirstOrDefault();
container.RealLocationCode = newstr;
srmTask.ToPlace = realToPlace;
//主任务也修改
var maintask = dbOrm.ware_task.Where(u => u.Id == srmTask.TaskId).FirstOrDefault();
maintask.ToLocationCode = realToPlace;
}
}
//else if (realToPlace.Substring(2).StartsWith("01"))
//{
// //查看该1排是否有货
// var arr = realToPlace.Split('-');
// string newstr = arr[0] + "-" + "02" + "-" + arr[2] + "-" + arr[3];
// var lvc = dbOrm.ware_location_vs_container.AsNoTracking().Any(u => u.WareLocationCode == realToPlace);
// if (lvc)//有货就换到2排
// {
// //目标库位修改为1排
// realToPlace = newstr;
// var container = dbOrm.wms_container.Where(u => u.ContainerCode == srmTask.ContainerCode).FirstOrDefault();
// container.RealLocationCode = realToPlace;
// srmTask.ToPlace = realToPlace;
// //主任务也修改
// var maintask = dbOrm.ware_task.Where(u => u.Id == srmTask.TaskId).FirstOrDefault();
// maintask.ToLocationCode = realToPlace;
// }
//}
isOk = dbOrm.ware_location_vs_container.Any(x => x.WareLocationCode == realToPlace && x.WareContainerCode != srmTask.ContainerCode && x.IsDeleted == false);
if (isOk)
{
errMsg = device.ToString() + "不允许下发新任务,目标库位" + realToPlace + "系统显示有库存";
return;
}
}
else if (srmTask.TaskType == (int)TaskCategoryEnum.OutStock)
{
realSourcePlace = srmTask.SourcePlace;
realToPlace = GetRealLocatiomCodeOut(srmTask.ToPlace);
//判断是否存在指向放货站台的执行中的任务
isOk = dbOrm.ware_task_sub.Any(x => x.ToPlace == srmTask.ToPlace && x.TaskState == (int)SubTaskStateEnum.已下发);
if (isOk)
{
errMsg = "存在指向目标点" + srmTask.ToPlace + "的任务,不能下发同一目标点的任务";
return;
}
}
else
{
realSourcePlace = srmTask.SourcePlace;
realToPlace = srmTask.ToPlace;
if (realToPlace.Substring(2).StartsWith("02") && realToPlace != "1-02-06-04")
{
//查看该1排是否有货
var arr = realToPlace.Split('-');
string newstr = arr[0] + "-" + "01" + "-" + arr[2] + "-" + arr[3];
//看1排是否有货,无货放1排
var lvc = dbOrm.ware_location_vs_container.AsNoTracking().Any(u => u.WareLocationCode == newstr);
if (!lvc)
{
var container1 = dbOrm.wms_container.Where(u => u.RealLocationCode == newstr).FirstOrDefault();
if (container1 != null)
{
container1.RealLocationCode = realToPlace;
}
//查看是否有指向1排原绑定库位的任务
var newtask = dbOrm.ware_task.Where(u => u.ToLocationCode == newstr).FirstOrDefault();
if (newtask != null)
{
newtask.ToLocationCode = realToPlace;
var newtasksub = dbOrm.ware_task_sub.Where(u => u.TaskId == newtask.Id && u.DeviceId == int_deviceId && u.ToPlace == newstr).FirstOrDefault();
if (newtasksub != null)
{
newtasksub.ToPlace = realToPlace;
}
}
//目标库位修改为1排
realToPlace = newstr;
var container = dbOrm.wms_container.Where(u => u.ContainerCode == srmTask.ContainerCode).FirstOrDefault();
container.RealLocationCode = newstr;
srmTask.ToPlace = realToPlace;
//主任务也修改
var maintask = dbOrm.ware_task.Where(u => u.Id == srmTask.TaskId).FirstOrDefault();
maintask.ToLocationCode = realToPlace;
}
}
//判断是否存在指向放货站台的执行中的任务
isOk = dbOrm.ware_task_sub.Any(x => x.ToPlace == srmTask.ToPlace && x.TaskState == (int)SubTaskStateEnum.已下发);
if (isOk)
{
errMsg = "存在指向目标点" + srmTask.SourcePlace + "的任务,不能下发同一目标点的任务";
return;
}
}
//判断堆垛机是否有执行中的任务任务 【EditBy kejj,2022-09-22】
isOk = dbOrm.ware_task_sub.Any(u => u.DeviceId == int_deviceId && u.TaskState == (int)SubTaskStateEnum.执行中);
if (isOk)
{
errMsg = "不允许下发新任务,当前堆垛机存在执行中的任务";
return;
}
//同一个关联任务的其他设备任务
var relevanceTask = dbOrm.ware_task_sub.Where(x => x.TaskId == srmTask.TaskId && x.TaskSequence < srmTask.TaskSequence && x.TaskState == (int)SubTaskStateEnum.未开始).FirstOrDefault();
if (relevanceTask != null)
{
errMsg = string.Format("关联{0}任务未开始,所以堆垛机任务不允许下发!关联任务号:{1}", Enum.Parse(typeof(EDevice), relevanceTask.DeviceId.ToString()).ToString(), relevanceTask.TaskNo);
return;
}
ESrmCmd eSrmCmd;
if (srmTask.TaskType == (int)TaskCategoryEnum.InStock)
{
eSrmCmd = ESrmCmd.入库;
}
else if (srmTask.TaskType == (int)TaskCategoryEnum.OutStock)
{
eSrmCmd = ESrmCmd.出库;
}
else
{
eSrmCmd = ESrmCmd.库内搬运;
}
SdaResEntity sdaResult = new SdaResEntity();
try
{
if (WCSConfigHelper.GetConfig_IsSimulationPLC())
{
sdaResult.result = true;
}
else
{
if (Convert.ToInt32(srmTask.TaskNo) <= 0)
{
throw new Exception("任务号不能小于等于0,PlcTaskId:" + srmTask.TaskNo);
}
//short pallettype = GetSrmContainerType(srmTask.ContainerType);
short pallettype = Convert.ToInt16(srmTask.ContainerType);
if (pallettype == 0)
{
throw new Exception("托盘类型不能等于0,PlcTaskId:" + srmTask.TaskNo);
}
sdaResult = vs.SendSrmTask(int_deviceId, Convert.ToInt32(srmTask.TaskNo), realSourcePlace, realToPlace, (short)eSrmCmd, /*GetSrmContainerType(*/Convert.ToInt16(srmTask.ContainerType)/*)*/);
}
if (sdaResult.result == false)
{//给堆垛机下发指令失败
//exception.exceptionMsg = string.Format("发送指令给堆垛机失败,设备号{0},任务ID{1},起始位{2},目标位{3},ContainerId{4}", int_deviceId,
// Convert.ToInt32(srmTask.TaskNo), realSourcePlace, realToPlace, srmTask.ContainerCode);
//SysExceptionInfoHandler.InsertExceptionInfo(exception, true);
errMsg = string.Format("发送指令给堆垛机失败,设备号{0},任务ID{1},起始位{2},目标位{3},ContainerId{4}", int_deviceId,
Convert.ToInt32(srmTask.TaskNo), realSourcePlace, realToPlace, srmTask.ContainerCode);
return;
}
else
{
//SystemValueUtil.DelayExcuteForSrmTaskThreadService(int_deviceId, ThreadDirectionEnum.任务开始下发线程);
errMsg = "";
}
}
catch (Exception ex)
{
throw ex;
}
#endregion
}
public short GetSrmContainerType(int? conveyorContainerType)
{
if (conveyorContainerType == 1)
{
return 2;
}
else if (conveyorContainerType == 3)
{
return 1;
}
else
{
return 0;
}
}
#endregion
#region 自动结束堆垛机任务线程
///
/// 自动结束堆垛机任务线程
///
///
public override void ConfirmFinishTask(object deviceId)
{
string errMsg1 = "", errMsg2 = "", errMsg3 = "", errMsg4 = "";
int i_deviceId = (int)deviceId;
while (true)
{
if ((int)deviceId == (int)EDevice.堆垛机 && SystemValue.isStartedModel)
{
ConfirmFinishTaskHandle(i_deviceId, out errMsg1);
}
//else if ((int)deviceId == (int)EDevice.二号堆垛机 && SystemValue.isAllowRuning_SrmTaskThreadService_2_Finish && SystemValue.isStartedModel)
//{
// ConfirmFinishTaskHandle(i_deviceId, out errMsg2);
//}
SystemWarningMsg._lbl_Alert_Srm1ReleaseFinish = errMsg1;
SystemWarningMsg._lbl_Alert_Srm2ReleaseFinish = errMsg2;
Thread.Sleep(500);//设置2秒一次
}
}
///
/// 自动结束堆垛机任务线程(线程)
///
///
public override void ConfirmFinishTaskHandle(int deviceId, out string errMsg)
{
errMsg = "";
try
{
/*
* 执行发送给堆垛机的指令任务
* 1、验证根据设备号是否找到堆垛机
* 2、判断设备是否属于任务完成,如果属于任务完成,就继续走3
* 3、判断数据库中是否有可要完成的任务,如果有判断是否跟堆垛机中的完成任务相符,如果相符就处理
* 4、更新任务状态
*/
int int_deviceId = (int)deviceId;
var vs = new SrmService.SrmServiceClient();
using (DbOrm dbOrm = new DbOrm())
{
#region //3、判断数据库中是否有可要完成的任务,如果有判断是否跟堆垛机中的完成任务相符,如果相符就处理
var currentTask = ValidateIsExistTaskToDispose(dbOrm, int_deviceId, out errMsg, SubTaskStateEnum.已完成);
if (currentTask == null)
{//表示DB中没有任务要发送给堆垛机
errMsg = "没有堆垛机任务数据要处理";
return;
}
#endregion
//2、判断设备是否任务完成
//var isFinished = ValidateDeviceTaskIsFinsished(int_deviceId, currentTask, Convert.ToInt32(currentTask.TaskNo), (DeviceTaskTypeEnum)Enum.Parse(typeof(DeviceTaskTypeEnum), currentTask.TaskType.ToString()), true, out errMsg);
//if (!isFinished) return;
SdaResEntity sdaResult = vs.IsTaskFinish(int_deviceId, Convert.ToInt32(currentTask.TaskNo));
if (sdaResult.result != true)
{
errMsg = $"验证堆垛机是否任务完成 失败:{sdaResult.resMsg}";
return;
}
//同一个关联任务的其他设备任务
var relevanceTask = dbOrm.ware_task_sub.Where(x => x.TaskId == currentTask.TaskId && x.TaskSequence < currentTask.TaskSequence
&& (x.TaskState != (int)SubTaskStateEnum.已完成)).FirstOrDefault();
if (relevanceTask != null)
{
errMsg = string.Format("关联{0}任务未完成,所以堆垛机任务不允许完成!关联任务号:{1}", Enum.Parse(typeof(EDevice), relevanceTask.DeviceId.ToString()).ToString(), relevanceTask.TaskNo);
return;
}
//4、处理任务完成状态
//var isOk = ConfirmTaskFinishToSrm(currentTask, "堆垛机任务完成");
sdaResult = vs.ConfirmTaskFinish((int)currentTask.DeviceId, Convert.ToInt32(currentTask.TaskNo));
if (sdaResult.result)
{
//using (var tran = dbOrm.Database.BeginTransaction())
//{
//try
//{
//堆垛机完成了当前任务后进行任务状态的修改
//ChangeTaskStateWhenTaskFinish(currentTask);
currentTask.FinishedTime = DateTime.Now;//完成时间
currentTask.TaskState = (int)SubTaskStateEnum.已完成;
var isExist = dbOrm.ware_task_sub.Any(u => u.TaskId == currentTask.TaskId && u.TaskState != (int)SubTaskStateEnum.已完成 && u.Id != currentTask.Id);
if (!isExist)
{
var maintask = dbOrm.ware_task.Where(u => u.Id == currentTask.TaskId).FirstOrDefault();
if (maintask != null)
{
maintask.TaskState = (int)TaskStateEnum.已完成;
}
}
dbOrm.SaveChanges();
//tran.Commit();
//}
//catch (Exception)
//{
//tran.Rollback();
// throw;
//}
//}
}
}
vs.Close();
}
catch (Exception ex)
{
errMsg = $"堆垛机任务完成异常:{ex.Message}";
//SysExceptionInfoHandler.GetExceptionInfoForError("自动结束堆垛机任务线程(线程)出现异常,deviceId:" + deviceId + ",异常:" + ex.Message, ex, ref exception);
//SysExceptionInfoHandler.InsertExceptionInfo(exception, true);
}
}
///
/// 判断是人工发送给任务,单独给堆垛机发送任务完成信号
///
///
///
///
private bool ConfirmTaskFinishToSda(int deviceId, int taskId)
{
//任务完成处理成功,需要再给堆垛机发送任务完成确认信号
SdaResEntity sdaResult = new SdaResEntity();
try
{
sdaResult = new SrmService.SrmServiceClient().ConfirmTaskFinish(deviceId, taskId);
if (!sdaResult.result)
{
Log4NetHelper.WriteInfoLog(iWareCommon.Utils.LogType.SrmTheadService, "判断是人工发送的任务,单独给堆垛机发送任务完成信号,【失败】,设备号:" + deviceId + ",任务号:" + taskId);
return false;
}
else
{
Log4NetHelper.WriteInfoLog(iWareCommon.Utils.LogType.SrmTheadService, "判断是人工发送的任务,单独给堆垛机发送任务完成信号,【成功】,设备号:" + deviceId + ",任务号:" + taskId);
return true;
}
}
catch (Exception ex)
{
Log4NetHelper.WriteErrorLog(iWareCommon.Utils.LogType.SrmTheadService, "判断是人工发送的任务,单独给堆垛机发送任务完成信号,【异常】,设备号:" + deviceId + ",任务号:" + taskId + ",ex:" + ex.Message, ex);
throw ex;
}
}
#region 向堆垛机发送任务完成确认信号
///
/// 向堆垛机发送任务完成确认信号
///
///
///
///
///
private bool ConfirmTaskFinishToSrm(ware_task_sub currentTask, string business)
{
//任务完成处理成功,需要再给堆垛机发送任务完成确认信号
SdaResEntity sdaResult = new SdaResEntity();
string realSourcePlace = "";
string realToPlace = "";
if (currentTask.TaskType == (int)TaskCategoryEnum.InStock)
{
realSourcePlace = GetRealLocatiomCodeIn(currentTask.SourcePlace);
realToPlace = currentTask.ToPlace;
}
else if (currentTask.TaskType == (int)TaskCategoryEnum.OutStock)
{
realSourcePlace = currentTask.SourcePlace;
realToPlace = GetRealLocatiomCodeOut(currentTask.ToPlace);
}
try
{
if (WCSConfigHelper.GetConfig_IsSimulationPLC())
{
sdaResult.result = true;
}
else
{
sdaResult = new SrmService.SrmServiceClient().ConfirmTaskFinish((int)currentTask.DeviceId, Convert.ToInt32(currentTask.TaskNo));
}
if (!sdaResult.result)
{
//exception.exceptionMsg = string.Format(business + ",需要再给堆垛机发送任务完成确认信号失败,设备号{0} 任务号{1}", (int)currentTask.DeviceId, currentTask.TaskNo);
//SysExceptionInfoHandler.InsertExceptionInfo(exception, true);
return false;
}
else
{
Log4NetHelper.WriteInfoLog(base.currentLogType, string.Format(business + ",再给堆垛机发送任务完成确认信号成功,设备号{0} 任务号{1}", (int)currentTask.DeviceId, currentTask.TaskNo));
return true;
}
}
catch (Exception ex)
{
throw ex;
}
}
#endregion
#endregion
#endregion
#region 公共处理
/////
///// 验证RGV站点上是否允许下发堆垛机新任务
/////
/////
/////
/////
/////
///// true:允许,false:不允许
//private bool ValidateIsAllowNewTaskForRgvStattion(DbModel model, DeviceTaskTypeEnum _DeviceTaskTypeEnum, string realToPlace, ref string errMsg)
//{
// MainInOutFlagEnum _MainInOutFlagEnum = GetMainInOutFlagForSrm(_DeviceTaskTypeEnum);
// if (_MainInOutFlagEnum == MainInOutFlagEnum.出库)
// {
// //判断目标点是否有光电占用
// var rgv_stationCode = model.Base_Station.Where(x => x.SrmStationCode == realToPlace).First();
// var isGD_HasCatogryForRgvStattion = MyExtendHelper.IsGD_HasCatogryForRgvStattion(rgv_stationCode.RgvStationCode);
// if (isGD_HasCatogryForRgvStattion)
// {
// errMsg = "RGV出库口站点" + rgv_stationCode.RgvStationCode + "上面光电显示有货,不允许下发堆垛机的出库任务";
// return false;
// }
// }
// return true;
//}
///
/// 根据堆垛机任务类型判断出是出库还是入库
///
///
///
private MainInOutFlagEnum GetMainInOutFlagForSrm(DeviceTaskTypeEnum _DeviceTaskTypeEnum)
{
switch (_DeviceTaskTypeEnum)
{
case DeviceTaskTypeEnum.组盘入库:
case DeviceTaskTypeEnum.空托转运到立体库:
return MainInOutFlagEnum.入库;
case DeviceTaskTypeEnum.立库空托到拆盘机入口:
case DeviceTaskTypeEnum.出库:
return MainInOutFlagEnum.出库;
}
throw new Exception("堆垛机不支持的任务类型" + _DeviceTaskTypeEnum.ToString());
}
///
/// 堆垛机任务完成后修改任务状态
///
///
private void ChangeTaskStateWhenTaskFinish(ware_task_sub currentTask)
{
//堆垛机完成了当前任务后进行任务状态的修改
currentTask.FinishedTime = DateTime.Now;//完成时间
//currentTask.IsFinished = true;
currentTask.TaskState = (int)SubTaskStateEnum.已完成;
//currentTask.TaskStateName = DeviceTaskStatusEnum.已完成.ToString();
//currentTask.OperationRemark = "已完成";
//currentTask.ModifyTime = DateTime.Now;
//currentTask.ModifyBy = SysGloble.WCSSystem;
//currentTask.IsLastTask = (int)EYesOrNo.否;//设置不是最新的任务
}
///
/// 堆垛机任务完成后,根据堆垛机的任务类型去判断Base_Salver_V_Station 的State
///
/// 堆垛机任务类型
/// 原先的Base_Salver_V_Station 的State
///
private Salver_V_Station_StateEnum DeviceTaskTypeEnumToC_V_P_StateEnumWhenTaskFinish(DeviceTaskTypeEnum _DeviceTaskTypeEnum, int old_int_C_V_P_StateEnum)
{
Salver_V_Station_StateEnum old_C_V_P_StateEnum = (Salver_V_Station_StateEnum)Enum.Parse(typeof(Salver_V_Station_StateEnum), old_int_C_V_P_StateEnum.ToString());
Salver_V_Station_StateEnum _C_V_P_StateEnum = old_C_V_P_StateEnum;
switch (_DeviceTaskTypeEnum)
{
case DeviceTaskTypeEnum.组盘入库:
_C_V_P_StateEnum = Salver_V_Station_StateEnum.在库物料;
break;
//case DeviceTaskTypeEnum22.线下其他垛入库:
// _C_V_P_StateEnum = C_V_P_StateEnum.在库其他料;
// break;
//case DeviceTaskTypeEnum22.线下垫板垛入库:
// _C_V_P_StateEnum = C_V_P_StateEnum.在库垫板;
// break;
//case DeviceTaskTypeEnum22.成品料配板完成回库:
// _C_V_P_StateEnum = C_V_P_StateEnum.在库成品料;
// break;
//case DeviceTaskTypeEnum22.待拆垛回库:
// _C_V_P_StateEnum = C_V_P_StateEnum.在库待拆垛;
// break;
//case DeviceTaskTypeEnum22.桁架垫板垛入立库垫板库位:
//case DeviceTaskTypeEnum22.锯切垫板垛入立体库:
// _C_V_P_StateEnum = C_V_P_StateEnum.在库垫板;
// break;
//case DeviceTaskTypeEnum22.移库://移库,状态不变
//case DeviceTaskTypeEnum22.成品料上锯切线出库://成品料出库,状态不变
//case DeviceTaskTypeEnum22.垫板上料出库://垫板出库,状态不变
// _C_V_P_StateEnum = old_C_V_P_StateEnum;
// break;
//case DeviceTaskTypeEnum22.配板原料出库:
// _C_V_P_StateEnum = C_V_P_StateEnum.原料配板中;
// break;
//case DeviceTaskTypeEnum22.人工出库://出库后会将表Base_Salver_V_Station 清掉
// break;
}
return _C_V_P_StateEnum;
}
public override bool ValidateDeviceIsAllowSendTask(int int_deviceId, out string errMsg)
{
if (FormCC.IsSimulationPLC)
{
errMsg = "模拟PLC";
return true;
}
//errMsg = "";
if (!base.ValidateDeviceIsAllowSendTask(int_deviceId, out errMsg))
{
return false;
}
using (var srmService = new SrmService.SrmServiceClient())
{
SdaResEntity sdaResult = srmService.IsAllowSendTask(int_deviceId, out errMsg);
if (sdaResult.result == false)
{
errMsg = "非自动、有任务未确认或有报警," + sdaResult.resMsg;
Log4NetHelper.WriteErrorLog(currentLogType, "验证堆垛机不可以下发新任务,int_deviceId:" + int_deviceId + ",sdaResultStr:" + JsonConvert.SerializeObject(sdaResult));
}
return sdaResult.result;
}
}
///
/// 验证堆垛机是否任务完成
///
///
///
private bool ValidateDeviceTaskIsFinsished(int int_deviceId, ware_task_sub _task, int taskId, DeviceTaskTypeEnum _DeviceTaskTypeEnum, bool? isAllowSimulateExecute, out string errMsg)
{
errMsg = "";
if (WCSConfigHelper.GetConfig_IsSimulationPLC())
{
errMsg = "模拟PLC完成或任务要求强制模拟完成";
return true;
}
SdaResEntity sdaResult = new SrmService.SrmServiceClient().IsTaskFinish(int_deviceId, taskId);
if (sdaResult.result == false)
{
errMsg = "验证堆垛机是否任务完成 失败:" + JsonConvert.SerializeObject(sdaResult);
//Log4NetHelper.WriteErrorLog(currentLogType, "验证堆垛机是否任务完成 失败:" + JsonConvert.SerializeObject(sdaResult));
}
//switch (_DeviceTaskTypeEnum)
//{
// //涉及到最后到输送线的任务,都要再加上输送线的任务是否完成
// case DeviceTaskTypeEnum.组盘入库:
// //using (var srmConveyorService = new SrmConveyorService.SrmConveyorServiceClient())
// //{
// // sdaResultStr = srmConveyorService.IsTaskFinish(taskId);
// // sdaResult = JsonConvert.DeserializeObject(sdaResultStr);
// // if (sdaResult.result == false)
// // {
// // errMsg = "验证输送线是否任务完成 失败:" + sdaResultStr;
// // Log4NetHelper.WriteErrorLog(currentLogType, "验证输送线是否任务完成 失败:" + sdaResultStr);
// // }
// //}
// break;
//}
return sdaResult.result;
}
#endregion
#region 私有方法
///
/// 验证数据库中是否有任务要处理
///
///
///
/// Rgv设备号
///
///
///
private List ValidateIsExistTaskToDisposeForIssued(DbOrm dbOrm, int int_deviceId, out string errMsg)
{
errMsg = "";
List partList = new List();
//看同一个设备,是否还有其他正在执行的任务
var partTask = dbOrm.ware_task_sub.Where(x => x.DeviceId == int_deviceId && x.TaskState == (int)SubTaskStateEnum.已下发).
OrderBy(x => x.CreatedTime).FirstOrDefault();//按照主任务的顺序升序
if (partTask != null)
{
errMsg = string.Format("deviceId={0}的正在执行任务,任务ID:" + partTask.Id + ",主任务:" + partTask.TaskId + ",PLC任务号:" + partTask.TaskNo, int_deviceId);
return null;
}
//1、查询
var currTaskList = dbOrm.ware_task_sub.Where(x => x.DeviceId == int_deviceId && (x.TaskState == (int)SubTaskStateEnum.未开始 || x.TaskState == (int)SubTaskStateEnum.等待下发)).ToList().OrderBy(x => x.CreatedTime).ToList();//按照主任务优先级的升序排序
if (currTaskList == null || currTaskList.Count == 0)
{
errMsg = "没有需要处理的任务";
return null;
}
//查找所有AGV任务
var agvTaskList = dbOrm.ware_task_sub.AsNoTracking().Where(u => u.DeviceId == 1099).ToList();
var currentAgvTask = agvTaskList.Find(u => u.TaskState == (int)SubTaskStateEnum.已完成);
if (currentAgvTask == null)
{
//查找AGV执行步骤最高的
currentAgvTask = agvTaskList.OrderByDescending(u => u.TaskState).FirstOrDefault();
}
if (currentAgvTask != null)
{
//currentAgvTask是执行步骤最高的agv,优先下这个的关联任务
var vs = currTaskList.FindAll(u => u.TaskId == currentAgvTask.TaskId).OrderBy(u => u.TaskSequence).FirstOrDefault();
if (vs != null)
{
if (vs.TaskState == (int)SubTaskStateEnum.等待下发)
{
errMsg = $"目标点{vs.ToPlace}的堆垛机任务等待下发";
return null;
}
else
{
partList.Add(vs);
return partList;
}
}
else
{
//执行步骤最高的agv没有待处理的堆垛机任务
//查找另一个agv任务
var anotherAgvTask = agvTaskList.Find(u => u.TaskId != currentAgvTask.TaskId);
if (anotherAgvTask == null)
{
var temp = currTaskList.Find(u => u.TaskType == (int)TaskCategoryEnum.MoveStock && u.TaskSequence == 1);
if (temp != null)
{
partList.Add(temp);
return partList;
}
errMsg = "没有任务要执行";
return null;
}
else
{
var anthorSrmTask = currTaskList.FindAll(u => u.TaskId == anotherAgvTask.TaskId).OrderBy(u => u.TaskSequence).FirstOrDefault(); ;
if (anthorSrmTask != null)
{
if (anthorSrmTask.TaskState == (int)SubTaskStateEnum.等待下发)
{
errMsg = $"目标点{anthorSrmTask.ToPlace}的堆垛机任务等待下发";
return null;
}
else
{
partList.Add(vs);
return partList;
}
}
else
{
errMsg = "没有任务要执行";
return null;
}
}
}
}
else
{
var temp = currTaskList.Find(u => u.TaskType == (int)TaskCategoryEnum.MoveStock && u.TaskSequence == 1);
if (temp != null)
{
partList.Add(temp);
return partList;
}
else
{
return null;
}
}
//查找AGV执行步骤最高的
//var agvTask = dbOrm.ware_task_sub.AsNoTracking().Where(u => u.TaskState > 0 && u.DeviceId == 1099).OrderByDescending(u => u.TaskState).FirstOrDefault();
//ware_task_sub temp = null;
//if (agvTask == null)
//{
// temp = currTaskList.Find(u => u.TaskType == (int)TaskCategoryEnum.MoveStock);
// if (temp == null)
// {
// errMsg = "agv没有到达,等待下发";
// return null;
// }
// else
// {
// partList.Add(temp);
// return partList;
// }
//}
//var firstTask = currTaskList.First();//第一个待执行的任务
//var firstTask = currTaskList.Find(u => u.TaskId == agvTask.TaskId);
//partList.Add(firstTask);
/*
//判断如果这个任务是出库任务的话,就再查询第一个待执行的入库任务
DeviceTaskTypeEnum _DeviceTaskTypeEnum = (DeviceTaskTypeEnum)Enum.Parse(typeof(DeviceTaskTypeEnum), firstTask.TaskType.ToString());
//查询 出库和入库的两个任务,优先执行出库任务 【EditBy shaocx,2022-05-09】
MainInOutFlagEnum _MainInOutFlagEnum = GetMainInOutFlagForSrm(_DeviceTaskTypeEnum);
if (_MainInOutFlagEnum == MainInOutFlagEnum.出库)
{
//查询第一个待执行的入库任务
var queryInOutFlag = (int)MainInOutFlagEnum.入库;
var fisrtTaskForIn = currTaskList.Where(x => x.InOutFlag == queryInOutFlag).ToList().OrderBy(x => x.CreateTime).FirstOrDefault();
if (fisrtTaskForIn != null)
{
partList.Add(fisrtTaskForIn);
}
}
*/
//return partList;
}
#endregion
}
}