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
|
{
|
/// <summary>
|
/// 立库输送线任务服务线程类
|
/// </summary>
|
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 自动执行立库输送线任务线程
|
|
///// <summary>
|
///// 自动执行立库输送线任务
|
///// </summary>
|
///// <param name="srmName"></param>
|
//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);
|
// }
|
|
//}
|
|
///// <summary>
|
///// 自动执行立库输送线任务(线程)
|
///// </summary>
|
///// <param name="srmName"></param>
|
//private void DoConveyorsTaskByThead(object deviceId, out string errMsg)
|
//{
|
// errMsg = "";
|
// string logHeader = "方法:DoConveyorsTaskByThead,参数deviceId:" + deviceId.ToString() + "===";
|
// #region 新增异常信息表 【EditBy shaocx,2020-01-20】
|
// IDictionary<string, object> logDict = new Dictionary<string, object>();
|
// logDict.Add("deviceId", deviceId);
|
// UDT_SYS_ExceptionInfo exception = ExceptionHandels.GetExceptionInfo<IDictionary<string, object>>(base.currentLogType, _namespace, "DoConveyorsTaskByThead", logDict);
|
// #endregion
|
// try
|
// {
|
// /*
|
// * 执行发送给立库输送线的指令任务
|
// * 1、验证根据设备号是否找到立库输送线
|
// * 2、判断设备是否属于任务完成,如果属于任务完成,就继续走3
|
// * 3、判断数据库中是否有可要下发的任务,如果有就下发+验证起始点和目标点是否正确
|
// * 4、下发成功后,更新任务状态
|
// */
|
// int int_deviceId = (int)deviceId;
|
|
// //1、验证根据设备号是否找到立库输送线
|
// SrmConveyorEntity deviceEntity = null;
|
// deviceEntity = ValidateIsExistDevice<SrmConveyorEntity>(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<Conveyor_Task>(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<SdaResEntity>(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 自动结束立库输送线任务线程
|
|
///// <summary>
|
///// 自动结束立库输送线任务线程
|
///// </summary>
|
///// <param name="srmName"></param>
|
//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);
|
// }
|
|
//}
|
|
///// <summary>
|
///// 自动结束立库输送线任务线程(线程)
|
///// </summary>
|
///// <param name="srmName"></param>
|
//public void FinishConveyorTaskByThead(object deviceId, out string errMsg)
|
//{
|
// errMsg = "";
|
// #region 新增异常信息表 【EditBy shaocx,2020-01-20】
|
// IDictionary<string, object> logDict = new Dictionary<string, object>();
|
// logDict.Add("deviceId", deviceId);
|
// UDT_SYS_ExceptionInfo exception = ExceptionHandels.GetExceptionInfo<IDictionary<string, object>>(base.currentLogType, _namespace, "FinishConveyorTaskByThead", logDict);
|
// #endregion
|
// try
|
// {
|
// /*
|
// * 执行发送给立库输送线的指令任务
|
// * 1、验证根据设备号是否找到立库输送线
|
// * 2、判断设备是否属于任务完成,如果属于任务完成,就继续走3
|
// * 3、判断数据库中是否有可要完成的任务,如果有判断是否跟立库输送线中的完成任务相符,如果相符就处理
|
// * 4、更新任务状态
|
// */
|
// int int_deviceId = (int)deviceId;
|
|
// //1、验证根据设备号是否找到立库输送线
|
// SrmConveyorEntity srmEntity = null;
|
// srmEntity = ValidateIsExistDevice<SrmConveyorEntity>(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<Conveyor_Task>(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 公共处理
|
|
|
|
///// <summary>
|
///// 验证立库输送线是否可以接受任务
|
///// </summary>
|
///// <param name="int_deviceId">设备号,不需要</param>
|
///// <param name="taskId">任务号,需要</param>
|
///// <returns></returns>
|
//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;
|
//}
|
|
///// <summary>
|
///// 验证立库输送线是否任务完成
|
///// </summary>
|
///// <param name="int_deviceId"></param>
|
///// <returns>0表示没有任务完成,其他表示任务完成,并返回任务号</returns>
|
//public override bool ValidateDeviceTaskIsFinsished(int int_deviceId, int taskId,out string errMsg)
|
//{
|
// errMsg = "";
|
// String sdaResultStr = new SrmConveyorService.SrmConveyorServiceClient().IsTaskFinish(taskId);
|
// SdaResEntity sdaResult = JsonConvert.DeserializeObject<SdaResEntity>(sdaResultStr);
|
// if (sdaResult.result == false)
|
// {
|
// errMsg = sdaResult.resMsg;
|
// }
|
// return sdaResult.result;
|
// //*/
|
//}
|
|
///// <summary>
|
///// 验证立库输送线是否允许任务完成
|
///// </summary>
|
///// <param name="int_deviceId"></param>
|
///// <returns>0表示没有任务完成,其他表示任务完成,并返回任务号</returns>
|
//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;
|
//}
|
|
///// <summary>
|
///// 验证立库输送线是否允许任务开始
|
///// </summary>
|
///// <param name="int_deviceId"></param>
|
///// <returns>0表示没有任务完成,其他表示任务完成,并返回任务号</returns>
|
//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;
|
//}
|
|
///// <summary>
|
///// 验证根据设备号是否找到立库输送线
|
///// </summary>
|
///// <param name="int_deviceId"></param>
|
///// <returns></returns>
|
//public override SrmConveyorEntity ValidateIsExistDevice<SrmConveyorEntity>(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;
|
//}
|
|
|
|
///// <summary>
|
///// 验证数据库中是否有任务要处理
|
///// </summary>
|
///// <typeparam name="Conveyor_Task"></typeparam>
|
///// <param name="dbModel"></param>
|
///// <param name="int_deviceId">立库输送线设备号</param>
|
///// <param name="errMsg"></param>
|
///// <param name="_TaskExcuteTypeEnum"></param>
|
///// <returns></returns>
|
//public override Conveyor_Task ValidateIsExistTaskToDispose<Conveyor_Task>(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
|
}
|
}
|