using iWareCommon;
using iWareCommon.Utils;
using iWareSql;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Linq;
using iWareSql.Orm;
using System.Threading.Tasks;
using Newtonsoft.Json;
using iWareSql.DataAccess;
using iWareModel;
namespace iWareCC
{
///
/// 立库输送线任务服务线程类
///
public class ConveyorThreadService : DeviceThreadServiceHandle
{
//private static string _namespace = "iWareCC.ConveyorThreadService";
//private ConveyorThreadService() { }
//public ConveyorThreadService(LogType logType)
//{
// base.currentLogType = logType;
//}
//public void StartService()
//{
// Task.Run(() =>
// {
// try
// {
// //自动执行立库输送线任务线程
// Log4NetHelper.WriteInfoLog(base.currentLogType, "[自动执行立库输送线任务线程] 启动了");
// ThreadHelper.StartThread(new Thread(new ParameterizedThreadStart(DoConveyorsTask)), (int)EDeviceId222.立库输送线);
// //自动结束立库输送线任务线程
// ThreadHelper.StartThread(new Thread(new ParameterizedThreadStart(FinishTask)), (int)EDeviceId222.立库输送线);
// }
// catch (Exception ex)
// {
// Log4NetHelper.WriteErrorLog(base.currentLogType, "ConveyorThreadService线程启动出现异常", ex);
// }
// });
//}
//#region 线程处理
//#region 自动执行立库输送线任务线程
/////
///// 自动执行立库输送线任务
/////
/////
//private void DoConveyorsTask(object deviceId)
//{
// string errMsg = "";
// while (true)
// {
// if (SystemValue.isAllowRuning_ConveyorsTaskThreadService && SystemValue.isStartedModel)
// {
// DoConveyorsTaskByThead(deviceId, out errMsg);
// }
// SystemWarningMsg._lbl_Alert_ConveyorsRelease = errMsg;
// Thread.Sleep(cycleDelay);
// }
//}
/////
///// 自动执行立库输送线任务(线程)
/////
/////
//private void DoConveyorsTaskByThead(object deviceId, out string errMsg)
//{
// errMsg = "";
// string logHeader = "方法:DoConveyorsTaskByThead,参数deviceId:" + deviceId.ToString() + "===";
// #region 新增异常信息表 【EditBy shaocx,2020-01-20】
// IDictionary logDict = new Dictionary();
// logDict.Add("deviceId", deviceId);
// UDT_SYS_ExceptionInfo exception = ExceptionHandels.GetExceptionInfo>(base.currentLogType, _namespace, "DoConveyorsTaskByThead", logDict);
// #endregion
// try
// {
// /*
// * 执行发送给立库输送线的指令任务
// * 1、验证根据设备号是否找到立库输送线
// * 2、判断设备是否属于任务完成,如果属于任务完成,就继续走3
// * 3、判断数据库中是否有可要下发的任务,如果有就下发+验证起始点和目标点是否正确
// * 4、下发成功后,更新任务状态
// */
// int int_deviceId = (int)deviceId;
// //1、验证根据设备号是否找到立库输送线
// SrmConveyorEntity deviceEntity = null;
// deviceEntity = ValidateIsExistDevice(int_deviceId);
// if (deviceEntity == null) return;
// //暂时记录文本日志,正式环境要去掉
// TestStruct.WriteTempLog(base.currentLogType, logHeader + "执行结束ValidateIsExistDevice,根据设备号找到了输送线");
// //2、判断设备是否属于空闲,如果属于空闲,就继续走2
// bool isOk = ValidateDeviceIsOK((int)EDeviceId222.立库输送线, 0, out errMsg);
// //暂时记录文本日志,正式环境要去掉
// TestStruct.WriteTempLog(base.currentLogType, logHeader + "执行结束ValidateDeviceIsOK,输送线是否可以接受任务:" + isOk);
// if (!isOk) return;
// using (Edm dbModel = new Edm())
// {
// #region //3、判断数据库中是否有可要下发的任务,如果有就下发
// var currentTask = ValidateIsExistTaskToDispose(dbModel, int_deviceId, out errMsg, TaskExcuteTypeEnum.执行任务);
// if (currentTask == null)
// {//表示DB中没有任务要发送给立库输送线
// //暂时记录文本日志,正式环境要去掉
// TestStruct.WriteTempLog(base.currentLogType, logHeader + "执行ValidateIsExistTaskToDispose完,表示DB中没有任务要发送给立库输送线");
// return;
// }
// //判断输送线任务是否可以允许下发开始任务
// var isAllowStatrt = ValidateDeviceTaskIsAllowStart(currentTask, dbModel);
// if (!isAllowStatrt)
// {//防止过早给输送线发任务,导致输送线超时
// return;
// }
// //验证起始点和目标点是否正确
// RealPlaceEntity realPlaceEntity = null;
// if (!ValdiatePalceIsRight(dbModel, (int)currentTask.SourcePlace, (int)currentTask.ToPlace, ref realPlaceEntity)) return;
// //暂时记录文本日志,正式环境要去掉
// TestStruct.WriteTempLog(base.currentLogType, logHeader + "执行ValdiatePalceIsRight完,验证起始点和目标点正确,任务是srmTask的ID:" + currentTask.TackId);
// //下发
// //注意:第四个参数没有值
// var barcode = "1";//二维码写死位1
// var log = ConveyorTaskRequestLogHandles.GetTask(currentTask.TackId,
// currentTask.DeviceId.ToString(), currentTask.PlcTaskId, currentTask.RealSourcePlace.ToString(),
// currentTask.RealToPlace.ToString(), "给立库输送线发送任务指令", "sys");
// SdaResEntity sdaResult = new SdaResEntity();
// try
// {
// if (WCSConfigHelper.GetConfig_IsSimulationPLC())
// {
// sdaResult.result = true;
// }
// else
// {
// String sdaResultStr = new SrmConveyorService.SrmConveyorServiceClient().SendSrmTransTask(int_deviceId, Convert.ToInt32(currentTask.PlcTaskId), Convert.ToInt32(currentTask.RealSourcePlace), Convert.ToInt32(currentTask.RealToPlace), barcode);
// sdaResult = JsonConvert.DeserializeObject(sdaResultStr);
// }
// if (sdaResult.result == false)
// {//给立库输送线下发指令失败
// exception.exceptionMsg = string.Format("发送指令给立库输送线失败,设备号{0},任务ID{1},起始位{2},目标位{3},errMsg{4}", int_deviceId, currentTask.PlcTaskId, currentTask.RealSourcePlace.ToString(), currentTask.RealToPlace.ToString(), errMsg);
// ExceptionHandels.InsertExceptionInfo(exception, true);
// ConveyorTaskRequestLogHandles.InsertTask(base.currentLogType, RequestStatusEnum.请求失败, JsonConvert.SerializeObject(sdaResult), log, null);
// return;
// }
// else
// {
// ConveyorTaskRequestLogHandles.InsertTask(base.currentLogType, RequestStatusEnum.请求成功, JsonConvert.SerializeObject(sdaResult), log, null);
// }
// }
// catch (Exception ex)
// {
// ConveyorTaskRequestLogHandles.InsertTask(base.currentLogType, RequestStatusEnum.请求失败, JsonConvert.SerializeObject(sdaResult), log, ex);
// ExceptionHandels.GetExceptionInfoForError("给立库输送线发送任务指令出现异常,deviceId:" + deviceId + ",异常:" + ex.Message, ex, ref exception);
// ExceptionHandels.InsertExceptionInfo(exception, true);
// return;
// }
// #endregion
// //4、下发成功后,更新任务状态
// currentTask.IsReleased = (int)EYesOrNo.是;
// currentTask.UpdateTime = DateTime.Now;
// currentTask.TaskState = (int)ETaskStatus.已下发;
// currentTask.IssueTime = DateTime.Now;//下发时间
// //只更新着三个字段!
// //更新 进出库记录表的时间
// var srm_InOutStoreRecord = dbModel.Srm_InOutStoreRecord.Where(x => x.TaskGuid == currentTask.TaskGuid).FirstOrDefault();
// if (srm_InOutStoreRecord != null)
// {
// srm_InOutStoreRecord.TaskStartTime = DateTime.Now;
// srm_InOutStoreRecord.LastModifyTime = DateTime.Now;
// srm_InOutStoreRecord.LastModifier = "输送机任务下发";
// srm_InOutStoreRecord.Remark = "输送机任务下发";
// }
// /*
// //如果任务类型是配板原料入库,需要更新 mes的上料清单表
// ConveyorTaskTypeEnum _ConveyorTaskTypeEnum = (ConveyorTaskTypeEnum)Enum.Parse(typeof(ConveyorTaskTypeEnum), currentTask.TaskType.ToString());
// switch (_ConveyorTaskTypeEnum)
// {
// case ConveyorTaskTypeEnum.配板原料入库:
// if (!string.IsNullOrEmpty(currentTask.ToNumber))
// {
// }
// break;
// default:
// break;
// }
// //*/
// dbModel.SaveChanges();
// }
// }
// catch (Exception ex)
// {
// ExceptionHandels.GetExceptionInfoForError("自动执行立库输送线任务(线程)出现异常,deviceId:" + deviceId + ",异常:" + ex.Message, ex, ref exception);
// ExceptionHandels.InsertExceptionInfo(exception, true);
// }
//}
//#endregion
//#region 自动结束立库输送线任务线程
/////
///// 自动结束立库输送线任务线程
/////
/////
//private void FinishTask(object deviceId)
//{
// string errMsg = "";
// while (true)
// {
// if (SystemValue.isAllowRuning_ConveyorsTaskThreadService_Finish && SystemValue.isStartedModel)
// {
// FinishConveyorTaskByThead(deviceId, out errMsg);
// }
// SystemWarningMsg._lbl_Alert_ConveyorsReleaseFinish = errMsg;
// Thread.Sleep(cycleDelay);
// }
//}
/////
///// 自动结束立库输送线任务线程(线程)
/////
/////
//public void FinishConveyorTaskByThead(object deviceId, out string errMsg)
//{
// errMsg = "";
// #region 新增异常信息表 【EditBy shaocx,2020-01-20】
// IDictionary logDict = new Dictionary();
// logDict.Add("deviceId", deviceId);
// UDT_SYS_ExceptionInfo exception = ExceptionHandels.GetExceptionInfo>(base.currentLogType, _namespace, "FinishConveyorTaskByThead", logDict);
// #endregion
// try
// {
// /*
// * 执行发送给立库输送线的指令任务
// * 1、验证根据设备号是否找到立库输送线
// * 2、判断设备是否属于任务完成,如果属于任务完成,就继续走3
// * 3、判断数据库中是否有可要完成的任务,如果有判断是否跟立库输送线中的完成任务相符,如果相符就处理
// * 4、更新任务状态
// */
// int int_deviceId = (int)deviceId;
// //1、验证根据设备号是否找到立库输送线
// SrmConveyorEntity srmEntity = null;
// srmEntity = ValidateIsExistDevice(int_deviceId);
// if (srmEntity == null) return;
// //注意:这里不需要判断设备是否完成,直接就结束任务
// /*
// 2、判断设备是否属于任务完成,如果属于任务完成,就继续走2
// var isTaskFinished = ValidateSrmDeviceTaskIsFinsished(int_deviceId);
// if (!isTaskFinished) return;
// //*/
// using (Edm dbModel = new Edm())
// {
// #region //3、判断数据库中是否有可要完成的任务,如果有判断是否跟立库输送线中的完成任务相符,如果相符就处理
// var currentTask = ValidateIsExistTaskToDispose(dbModel, int_deviceId, out errMsg, TaskExcuteTypeEnum.结束任务);
// if (currentTask == null)
// {//表示DB中没有任务要发送给立库输送线
// return;
// }
// #endregion
// //输送线的完成,要判断和他绑定的堆垛机的任务是否完成
// var isAllowFinish = ValidateDeviceTaskIsAllowFinsished(currentTask, dbModel);
// if (!isAllowFinish)
// {//不允许执行结束
// return;
// }
// using (var trans = dbModel.Database.BeginTransaction())
// {
// try
// {
// //4、更新任务状态
// currentTask.FinishTime = DateTime.Now;//完成时间
// currentTask.IsFinished = (int)EYesOrNo.是;
// currentTask.TaskState = (int)ETaskStatus.已完成;
// currentTask.UpdateTime = DateTime.Now;
// //如果是出库任务,需要更改库存 [EditBy shaocx,2020-10-22]
// if (currentTask.TaskType == (int)ConveyorTaskTypeEnum.人工出库)
// {
// var cvp = CvP_Handles.GetCVPByPlaceId(dbModel, Convert.ToInt32(currentTask.SourcePlace));
// cvp.PlaceId = (int)currentTask.ToPlace;
// cvp.LastModifier = "输送线任务完成线程";
// cvp.UpdateTime = DateTime.Now;
// cvp.Remark = "输送线任务完成线程,更改CVP的库位";
// }
// //注意:输送线任务完成,不需要给输送线发完成确认指令,因为输送线由多个节点组成!!!!
// /*
// //任务完成处理成功,需要再给堆垛机发送任务完成确认信号
// bool isSendFinish = new iWareSda.ConveyorService.SrmConveyorService().SendTaskFinishConfirm(Convert.ToInt32(currentTask.PlcTaskId));
// if (!isSendFinish)
// {
// throw new Exception(string.Format("任务完成处理成功,需要再给立库输送线发送任务完成确认信号失败, 任务号{0}", currentTask.PlcTaskId));
// }
// //*/
// dbModel.SaveChanges();
// trans.Commit();
// }
// catch (Exception)
// {
// trans.Rollback();
// throw;
// }
// }
// }
// }
// catch (Exception ex)
// {
// ExceptionHandels.GetExceptionInfoForError("自动结束立库输送线任务线程(线程)出现异常,deviceId:" + deviceId + ",异常:" + ex.Message, ex, ref exception);
// ExceptionHandels.InsertExceptionInfo(exception, true);
// }
//}
//#endregion
//#endregion
//#region 公共处理
/////
///// 验证立库输送线是否可以接受任务
/////
///// 设备号,不需要
///// 任务号,需要
/////
//public override bool ValidateDeviceIsOK(int int_deviceId, int taskId, out string errMsg)
//{
// errMsg = "";
// // 立库输送线没有所谓的空闲状态,有任务直接发即可
// if (SrmEquipmentSituationHandels222.IsEquipmentBreakdown(int_deviceId).result)
// {//如果设备已经设定为 故障状态,不允许下发任务!!! [EditBy shaocx,2020-12-07]
// return false;
// }
// return true;
//}
/////
///// 验证立库输送线是否任务完成
/////
/////
///// 0表示没有任务完成,其他表示任务完成,并返回任务号
//public override bool ValidateDeviceTaskIsFinsished(int int_deviceId, int taskId,out string errMsg)
//{
// errMsg = "";
// String sdaResultStr = new SrmConveyorService.SrmConveyorServiceClient().IsTaskFinish(taskId);
// SdaResEntity sdaResult = JsonConvert.DeserializeObject(sdaResultStr);
// if (sdaResult.result == false)
// {
// errMsg = sdaResult.resMsg;
// }
// return sdaResult.result;
// //*/
//}
/////
///// 验证立库输送线是否允许任务完成
/////
/////
///// 0表示没有任务完成,其他表示任务完成,并返回任务号
//public bool ValidateDeviceTaskIsAllowFinsished(Conveyor_Task task, Edm edm)
//{
// Srm_Task srmTask = null;
// var queryTaskStatus_HasIssue = (int)ETaskStatus.已下发;
// var queryTaskStatus_Finish = (int)ETaskStatus.已完成;
// ConveyorTaskTypeEnum taskType = (ConveyorTaskTypeEnum)Enum.Parse(typeof(ConveyorTaskTypeEnum), task.TaskType.ToString());
// switch (taskType)
// {
// case ConveyorTaskTypeEnum.配板原料入库:
// case ConveyorTaskTypeEnum.线下配板原料入库:
// //要判断和他同一个任务的堆垛机任务是不是已经发送任务了,任务状态是 进行中或已完成,如果是就允许完成,如果不是,就不允许完成
// srmTask = edm.Srm_Task.Where(x => x.TaskGuid == task.TaskGuid && (
// x.TaskState == queryTaskStatus_HasIssue || x.TaskState == queryTaskStatus_Finish
// )).FirstOrDefault();
// if (srmTask != null)
// {
// return true;
// }
// break;
// case ConveyorTaskTypeEnum.人工出库:
// //要判断和他同一个任务的堆垛机任务是不是已经已完成,如果是就允许完成,如果不是,就不允许完成
// srmTask = edm.Srm_Task.Where(x => x.TaskGuid == task.TaskGuid && (
// x.TaskState == queryTaskStatus_Finish
// )).FirstOrDefault();
// if (srmTask != null)
// {
// return true;
// }
// break;
// }
// return false;
//}
/////
///// 验证立库输送线是否允许任务开始
/////
/////
///// 0表示没有任务完成,其他表示任务完成,并返回任务号
//public bool ValidateDeviceTaskIsAllowStart(Conveyor_Task task, Edm edm)
//{
// Srm_Task srmTask = null;
// var queryTaskStatus_Finish = (int)ETaskStatus.已完成;
// ConveyorTaskTypeEnum taskType = (ConveyorTaskTypeEnum)Enum.Parse(typeof(ConveyorTaskTypeEnum), task.TaskType.ToString());
// switch (taskType)
// {
// default:
// return true;
// case ConveyorTaskTypeEnum.人工出库:
// //要判断和他同一个任务的堆垛机任务是不是已经已完成,如果是就允许开始任务,如果不是,就不允许开始
// srmTask = edm.Srm_Task.Where(x => x.TaskGuid == task.TaskGuid && (
// x.TaskState == queryTaskStatus_Finish
// )).FirstOrDefault();
// if (srmTask != null)
// {
// return true;
// }
// break;
// }
// return false;
//}
/////
///// 验证根据设备号是否找到立库输送线
/////
/////
/////
//public override SrmConveyorEntity ValidateIsExistDevice(int int_deviceId)
//{
// iWareCC.SrmConveyorService.SrmConveyorEntity item = new SrmConveyorService.SrmConveyorServiceClient().GetSrmConveyorInfo(int_deviceId);
// var isExist = item.DeviceId == int_deviceId;
// if (!isExist)
// {
// Log4NetHelper.WriteErrorLog(base.currentLogType, "未找到立库输送线deviceId=" + int_deviceId);
// }
// return (SrmConveyorEntity)(object)item;
//}
/////
///// 验证数据库中是否有任务要处理
/////
/////
/////
///// 立库输送线设备号
/////
/////
/////
//public override Conveyor_Task ValidateIsExistTaskToDispose(Edm dbModel, int int_deviceId, out string errMsg, TaskExcuteTypeEnum _TaskExcuteTypeEnum)
//{
// errMsg = "";
// iWareSql.Orm.Conveyor_Task currTask = null;
// switch (_TaskExcuteTypeEnum)
// {
// case TaskExcuteTypeEnum.执行任务:
// var process_count = dbModel.Conveyor_Task.Where(x => x.DeviceId == int_deviceId && x.TaskState == (int)ETaskStatus.已下发).ToList().Count;
// if (process_count > 0)
// {
// errMsg = string.Format("deviceId={0}的正在执行任务", int_deviceId);
// return default(Conveyor_Task);
// }
// currTask = dbModel.Conveyor_Task.Where(x => x.DeviceId == int_deviceId && x.TaskState == (int)ETaskStatus.未开始).ToList().OrderBy(x => x.TackId).FirstOrDefault();
// break;
// case TaskExcuteTypeEnum.结束任务:
// currTask = dbModel.Conveyor_Task.Where(x => x.DeviceId == int_deviceId && x.TaskState == (int)ETaskStatus.已下发).ToList().OrderBy(x => x.TackId).FirstOrDefault();
// break;
// }
// return (Conveyor_Task)(object)currTask;
//}
//#endregion
}
}