#region MyRegion #region << 版 本 注 释 >> /*---------------------------------------------------------------- * 命名空间:WIDESEAWCS_Tasks.ConveyorLineJob * 创建者:胡童庆 * 创建时间:2024/8/2 16:13:36 * 版本:V1.0.0 * 描述: * * ---------------------------------------------------------------- * 修改人: * 修改时间: * 版本:V1.0.1 * 修改说明: * *----------------------------------------------------------------*/ #endregion << 版 本 注 释 >> using AutoMapper; using HslCommunication; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Quartz; using SqlSugar; using System.Reflection; using WIDESEAWCS_BasicInfoRepository; using WIDESEAWCS_Common; using WIDESEAWCS_Common.TaskEnum; using WIDESEAWCS_Core; using WIDESEAWCS_Core.Helper; using WIDESEAWCS_Core.HttpContextUser; using WIDESEAWCS_DTO.MOM; using WIDESEAWCS_DTO.TaskInfo; using WIDESEAWCS_IProcessRepository; using WIDESEAWCS_ISystemServices; using WIDESEAWCS_ITaskInfoRepository; using WIDESEAWCS_ITaskInfoService; using WIDESEAWCS_Model.Models; using WIDESEAWCS_QuartzJob; using WIDESEAWCS_QuartzJob.DTO; using WIDESEAWCS_QuartzJob.Repository; using WIDESEAWCS_QuartzJob.Service; using WIDESEAWCS_SignalR; using WIDESEAWCS_Tasks.ConveyorLineJob; using ICacheService = WIDESEAWCS_Core.Caches.ICacheService; using Platform = WIDESEAWCS_Model.Models.Platform; namespace WIDESEAWCS_Tasks { [DisallowConcurrentExecution] public partial class CommonConveyorLine_GWJob : JobBase, IJob { public readonly ITaskService _taskService; private readonly ITaskRepository _taskRepository; private readonly ITaskExecuteDetailService _taskExecuteDetailService; private readonly IRouterService _routerService; private readonly IPlatFormRepository _platFormRepository; private readonly ISys_ConfigService _sys_ConfigService; private readonly IMapper _mapper; private readonly IDt_StationManagerRepository _stationManagerRepository; private readonly ICacheService _cacheService; private readonly INoticeService _noticeService; private readonly IDt_needBarcodeRepository _needBarcodeRepository; private readonly IDeviceInfoRepository _deviceInfoRepository; private static List? userTokenIds; private static List? userIds; public CommonConveyorLine_GWJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, IRouterService routerService, IMapper mapper, ITaskRepository taskRepository, IPlatFormRepository platFormRepository, ISys_ConfigService sys_ConfigService, IDt_StationManagerRepository stationManagerRepository, ICacheService cacheService, INoticeService noticeService, IDt_needBarcodeRepository needBarcodeRepository, IDeviceInfoRepository deviceInfoRepository) { _taskService = taskService; _taskExecuteDetailService = taskExecuteDetailService; _routerService = routerService; _mapper = mapper; _taskRepository = taskRepository; _platFormRepository = platFormRepository; _sys_ConfigService = sys_ConfigService; _stationManagerRepository = stationManagerRepository; _cacheService = cacheService; _noticeService = noticeService; _needBarcodeRepository = needBarcodeRepository; _deviceInfoRepository = deviceInfoRepository; } public Task Execute(IJobExecutionContext context) { try { CommonConveyorLine_GW conveyorLine = (CommonConveyorLine_GW)context.JobDetail.JobDataMap.Get("JobParams"); if (conveyorLine != null) { #region 站台方式 //List stationManagers = _stationManagerService.GetAllStationByDeviceCode(conveyorLine.DeviceCode); //foreach (var station in stationManagers) //{ // ConveyorLineTaskCommand_After command = conveyorLine.ReadCustomer(station.stationChildCode); // DeviceProtocolDetailDTO? deviceProtocolDetails = conveyorLine.DeviceProtocolDetailDTOs.FirstOrDefault(x => x.DeviceProParamName == nameof(ConveyorLineTaskCommand_After.InteractiveSignal) && x.ProtocalDetailValue == command.InteractiveSignal.ToString()); // if (deviceProtocolDetails != null) // { // MethodInfo? method = GetType().GetMethod(deviceProtocolDetails.ProtocolDetailType); // if (method != null) // { // method.Invoke(this, new object[] { conveyorLine, command, station }); // } // } //} #endregion 站台方式 #region 路由方式 List childDeviceCodes = _routerService.QueryAllPositions(conveyorLine.DeviceCode); foreach (string childDeviceCode in childDeviceCodes) { ConveyorLineTaskCommand_After command = conveyorLine.ReadCustomer(childDeviceCode); if (command == null) continue; if (command.ConveyorLineBarcode.Trim().Contains("\0")) command.ConveyorLineBarcode = ""; DeviceProtocolDetailDTO? deviceProtocolDetails = conveyorLine.DeviceProtocolDetailDTOs.FirstOrDefault(x => x.DeviceProParamName == nameof(ConveyorLineTaskCommand_After.InteractiveSignal) && x.ProtocalDetailValue == command.InteractiveSignal.ToString()); if (deviceProtocolDetails != null) { MethodInfo? method = GetType().GetMethod(deviceProtocolDetails.ProtocolDetailType); if (method != null) { method.Invoke(this, new object[] { conveyorLine, command, childDeviceCode }); } } if (childDeviceCode == "1670"||childDeviceCode=="1666"||childDeviceCode=="1548"||childDeviceCode=="1448") { Platform platform = _platFormRepository.QueryFirst(x => x.DeviceCode == conveyorLine.DeviceCode && x.PlatCode == childDeviceCode && x.Status == "Active"); if (platform != null) { if (command.HasPallet != 1) { MethodInfo? method = GetType().GetMethod(platform.ExecutionMethod); if (method != null) { //var strings = platform.Location.Split(',').ToList(); int count = 1; method.Invoke(this, new object[] { conveyorLine, command, childDeviceCode, count, platform }); } } } } #region 调用事件总线通知前端 var tokenInfos = _cacheService.Get>("Cache_UserToken"); if (tokenInfos == null || !tokenInfos.Any()) { //throw new Exception(conveyorLine.DeviceName + "缓存中未找到Token缓存"); continue; } var userTokenIds = tokenInfos?.Select(x => x.Token_ID).ToList(); var userIds = tokenInfos?.Select(x => x.UserId).ToList(); object obj = new { childDeviceCode, commandAfter = command, }; _noticeService.LineData(userIds?.FirstOrDefault(), userTokenIds, new { conveyorLine.DeviceName, data = obj }); #endregion 调用事件总线通知前端 } #endregion 路由方式 } } catch (Exception ex) { Console.Out.WriteLine(nameof(CommonConveyorLine_GWJob) + ":" + ex.ToString()); } finally { //WriteDebug("CommonConveyorLineJob", "test"); //Console.Out.WriteLine(DateTime.Now); } return Task.CompletedTask; } /// /// 输送线请求入库 /// /// 输送线实例对象 /// 读取的请求信息 /// 子设备编号 /// 线体当前bool读取偏移地址 public void RequestInbound(CommonConveyorLine_GW conveyorLine, ConveyorLineTaskCommand_After command, string childDeviceCode) { try { var task = _taskService.QueryBarCodeConveyorLineTask(command.ConveyorLineBarcode, childDeviceCode); //HandleTaskOut(conveyorLine, command, childDeviceCode, task); // && command.ConveyorLineBarcode != "NoRead" && !command.ConveyorLineBarcode.IsNotEmptyOrNull() var log = $"【{conveyorLine.DeviceName}】托盘号:【{command.ConveyorLineBarcode}】任务号:【{command.ConveyorLineTaskNum}】设备编码:【{childDeviceCode}】"; ConsoleHelper.WriteSuccessLine(log); _noticeService.Logs(userTokenIds, new { conveyorLine.DeviceName, log = log, time = DateTime.Now.ToString("G"), color = "red" }); WriteInfo(conveyorLine.DeviceName, log); if (task == null) { HandleNewTask(conveyorLine, command, childDeviceCode); } else { ConveyorLineTaskCommand_After taskCommand = _mapper.Map(task); conveyorLine.SendCommand(taskCommand, childDeviceCode); conveyorLine.SetValue(ConveyorLineDBName_After.ResponState, 1, childDeviceCode); _taskService.UpdateTaskStatusToNext(task); } } catch (Exception ex) { Console.Out.WriteLine(ex.ToString()); } } /// /// 输送线请求入库下一地址 /// /// 输送线实例对象 /// 读取的请求信息 /// 子设备编号 public void RequestInNextAddress(CommonConveyorLine_GW conveyorLine, ConveyorLineTaskCommand_After command, string childDeviceCode) { Dt_Task task = _taskService.QueryExecutingConveyorLineTask(command.ConveyorLineTaskNum, childDeviceCode); if (task != null) { if (command.ConveyorLineBarcode != task.PalletCode) { conveyorLine.SetValue(ConveyorLineDBName_After.ResponState, 2, childDeviceCode); return; } Dt_Task? newTask = _taskService.UpdatePosition(task.TaskNum, task.CurrentAddress); if (newTask != null) { //conveyorLine.SetValue(ConveyorLineDBName_After.ConveyorLineTaskNum, newTask.TaskNum, childDeviceCode); //conveyorLine.SetValue(ConveyorLineDBName_After.ConveyorLineTargetAddress, newTask.NextAddress, childDeviceCode); //conveyorLine.SetValue(ConveyorLineDBName_After.ConveyorLineBarcode, command.ConveyorLineBarcode, childDeviceCode); ConveyorLineTaskCommand_After taskCommand = _mapper.Map(newTask); //taskCommand.InteractiveSignal = command.InteractiveSignal; conveyorLine.SendCommand(taskCommand, childDeviceCode); conveyorLine.SetValue(ConveyorLineDBName_After.ResponState, 1, childDeviceCode); } } } /// /// 输送线入库完成 /// /// 输送线实例对象 /// 读取的请求信息 /// 子设备编号 /// 线体当前bool读取偏移地址 public void ConveyorLineInFinish(CommonConveyorLine_GW conveyorLine, ConveyorLineTaskCommand_After command, string childDeviceCode) { var task = _taskService.QueryExecutingTaskByBarcode(command.ConveyorLineBarcode, childDeviceCode); if (task != null && task.TaskState != (int)TaskInStatusEnum.Line_InFinish) { //ConveyorLineSendFinish(conveyorLine, childDeviceCode, ProtocalDetailValue, true); WebResponseContent content = _taskService.UpdateTaskStatusToNext(task); if (content.Status) { conveyorLine.SetValue(ConveyorLineDBName_After.ResponState, 1, childDeviceCode); } Console.Out.WriteLine(content.Serialize()); } } /// /// 输送线请求出信息 /// /// 输送线实例对象 /// 读取的请求信息 /// 子设备编号 /// 线体当前bool读取偏移地址 public void RequestOutbound(CommonConveyorLine_GW conveyorLine, ConveyorLineTaskCommand_After command, string childDeviceCode) { var task = _taskService.QueryConveyorLineTask(conveyorLine.DeviceCode, childDeviceCode); if (task != null) { ConveyorLineTaskCommand_After taskCommand = _mapper.Map(task); conveyorLine.SendCommand(taskCommand, childDeviceCode); conveyorLine.SetValue(ConveyorLineDBName_After.ResponState, 1, childDeviceCode); //ConveyorLineSendFinish(conveyorLine, childDeviceCode, ProtocalDetailValue, true); _taskService.UpdateTaskStatusToNext(task); if (task.TaskType == (int)TaskOutboundTypeEnum.OutTray) { _taskService.UpdateTaskStatusToNext(task); } } } /// /// 输送线请求出库下一地址 /// /// 输送线实例对象 /// 读取的请求信息 /// 子设备编号 public void RequestOutNextAddress(CommonConveyorLine_GW conveyorLine, ConveyorLineTaskCommand_After command, string childDeviceCode) { Dt_Task task = _taskService.QueryExecutingConveyorLineTask(command.ConveyorLineTaskNum, childDeviceCode); if (task != null) { var config = _sys_ConfigService.GetConfigsByCategory(CateGoryConst.CONFIG_SYS_IPAddress); var wmsBase = config.FirstOrDefault(x => x.ConfigKey == SysConfigKeyConst.MOMIP_BASE)?.ConfigValue; var ipAddress = config.FirstOrDefault(x => x.ConfigKey == SysConfigKeyConst.TrayCellsStatus)?.ConfigValue; if (wmsBase == null || ipAddress == null) { throw new InvalidOperationException("MOM IP 未配置"); } Dt_StationManager stationManager = _stationManagerRepository.QueryFirst(x => x.stationPLC == conveyorLine.DeviceCode && x.stationChildCode == childDeviceCode); TrayCellsStatusDto trayCells = new TrayCellsStatusDto() { Software = "WMS", TrayBarcode = command.ConveyorLineBarcode, EquipmentCode = stationManager.stationEquipMOM, SessionId = Guid.NewGuid().ToString(), EmployeeNo = "MITest", SceneType = "1", RequestTime = TimeZoneInfo.ConvertTimeToUtc(DateTime.Now).ToString("yyyy-MM-ddTHH:mm:ss.fffZ") }; var MOMIpAddress = wmsBase + ipAddress; var result = HttpHelper.PostAsync(MOMIpAddress, trayCells.ToJsonString()).Result; WriteInfo("入站校验", $"【{childDeviceCode}】入站校验请求参数【{trayCells.ToJsonString()}】"); WriteInfo("入站校验", ""); WriteInfo("入站校验", $"【{childDeviceCode}】入站校验返回参数【{result}】"); ResultTrayCellsStatus result1 = JsonConvert.DeserializeObject(result); if (result1.Success || task.Remark != "NG") { Dt_Task? newTask = _taskService.UpdatePosition(task.TaskNum, task.CurrentAddress); if (newTask != null) { ConveyorLineTaskCommand_After taskCommand = _mapper.Map(newTask); conveyorLine.SendCommand(taskCommand, childDeviceCode); conveyorLine.SetValue(ConveyorLineDBName_After.ResponState, 1, childDeviceCode); } } else { ConveyorLineTaskCommand_After taskCommand = _mapper.Map(task); taskCommand.ConveyorLineTargetAddress = Convert.ToInt16(stationManager.stationNGChildCode); conveyorLine.SendCommand(taskCommand, childDeviceCode); conveyorLine.SetValue(ConveyorLineDBName_After.ResponState, 1, childDeviceCode); _taskService.UpdateTaskStatusToNext(task); } } } /// /// 输送线出库完成 /// /// 输送线实例对象 /// 读取的请求信息 /// 子设备编号 public void ConveyorLineOutFinish(CommonConveyorLine_GW conveyorLine, ConveyorLineTaskCommand_After command, string childDeviceCode) { var task = _taskService.QueryExecutingConveyorLineTask(command.ConveyorLineTaskNum, childDeviceCode); if (task != null) { WebResponseContent content = new WebResponseContent(); ConveyorLineTaskCommand_After taskCommand = _mapper.Map(task); taskCommand.InteractiveSignal = command.InteractiveSignal; Dt_StationManager stationManager = _stationManagerRepository.QueryFirst(x => x.stationPLC == conveyorLine.DeviceCode && x.stationChildCode == childDeviceCode); if (task.PalletCode != command.ConveyorLineBarcode) { //var NGAddress = _platFormRepository.QueryFirst(x => x.PlatCode == task.TargetAddress).Capacity; //taskCommand.ConveyorLineTargetAddress = (short)NGAddress; taskCommand.ConveyorLineTargetAddress = Convert.ToInt16(stationManager.stationNGChildCode); } else { //Dt_StationManager stationManager = _stationManagerRepository.QueryFirst(x => x.stationPLC == conveyorLine.DeviceCode && x.stationChildCode == childDeviceCode); taskCommand.ConveyorLineTargetAddress = Convert.ToInt16(stationManager.stationLocation); } if (stationManager.stationPLC == "1018" && stationManager.stationArea == "Cache") //更新在途数据 { dt_needBarcode needBarcode = _needBarcodeRepository.QueryFirst(x => x.productLine == stationManager.productLine && x.toArea == stationManager.stationChildCode); if (needBarcode != null) { needBarcode.inLineNum--; _needBarcodeRepository.UpdateData(needBarcode); } } conveyorLine.SendCommand(taskCommand, childDeviceCode); conveyorLine.SetValue(ConveyorLineDBName_After.ResponState, 1, childDeviceCode); //ConveyorLineSendFinish(conveyorLine, childDeviceCode, ProtocalDetailValue, true); content = _taskService.UpdateTaskStatusToNext(task); } //else //{ // Dt_StationManager stationManager = _stationManagerRepository.QueryFirst(x => x.stationPLC == conveyorLine.DeviceCode && x.stationChildCode == childDeviceCode && x.stationArea == "Cache"); // ////查询对应产线的在途数据 // //dt_needBarcode needBarcode = _needBarcodeRepository.QueryFirst(x => x.productLine == station.productLine); // //needBarcode.inLineNum = _taskRepository.QueryData(x => x.TargetAddress == station.stationChildCode).Count(); // //若在途数量小于目标位置的缓存数量 则寻找对应常温库存中常温3工序的可出库数据 并建立出库任务 // //if (needBarcode.inLineNum <= needBarcode.cacheNum) // //{ // //} // //如果包装缓存站台存在 且有请求 则 // if (stationManager != null) // { // _taskService.RequestOutTaskToBZAsync(stationManager); // } //} } /// /// 输送线交互完成 /// /// 输送线实例对象 /// 子设备编号 /// 线体当前bool读取偏移地址 /// 值 //public void ConveyorLineSendFinish(CommonConveyorLine conveyorLine, string childDeviceCode, int ProtocalDeValue, bool value) //{ // DeviceProDTO? devicePro = conveyorLine.DeviceProDTOs.Where(x => x.DeviceProParamType == nameof(DeviceCommand) && x.DeviceChildCode == childDeviceCode).OrderBy(x => x.DeviceProOffset).FirstOrDefault(); // string[] x = devicePro.DeviceProAddress.Split('.'); // x[x.Length - 1] = (ProtocalDetailValue + 1).ToString(); // string DeviceProAddress = string.Join(".", x); // conveyorLine.Communicator.Write(DeviceProAddress, value); //} /// /// 监测空托盘实盘出库 /// /// 输送线实例对象 /// 读取的请求信息 /// 子设备编号 /// 线体当前bool读取偏移地址 public async void EmptyTrayReturn(CommonConveyorLine_GW conveyorLine, ConveyorLineTaskCommand_After command, string childDeviceCode, int index, WIDESEAWCS_Model.Models.Platform platform) { try { TaskOutboundTypeEnum taskOutboundTypeEnum; if (platform.PlatformType.Contains("OutTray")) taskOutboundTypeEnum = TaskOutboundTypeEnum.OutTray; else taskOutboundTypeEnum = TaskOutboundTypeEnum.Outbound; await CheckAndCreateTask(taskOutboundTypeEnum, childDeviceCode, index, platform); } catch (Exception) { } } /// /// 检查任务并创建新任务 /// private async Task CheckAndCreateTask(TaskOutboundTypeEnum taskType, string childDeviceCode, int index, Platform platform) { var tasks = _taskRepository.QueryData(x => x.TaskType == (int)taskType && x.TargetAddress == childDeviceCode); if (tasks.Count < platform.Capacity) { #region 调用WMS获取出库任务 WMSTaskDTO taskDTO = new WMSTaskDTO(); // 获取WMSip地址 var config = _sys_ConfigService.GetConfigsByCategory(CateGoryConst.CONFIG_SYS_IPAddress); var wmsBase = config.FirstOrDefault(x => x.ConfigKey == SysConfigKeyConst.WMSIP_BASE)?.ConfigValue; var requestTrayOutTask = config.FirstOrDefault(x => x.ConfigKey == SysConfigKeyConst.RequestTrayOutTask)?.ConfigValue; if (wmsBase == null || requestTrayOutTask == null) { throw new InvalidOperationException("WMS IP 未配置"); } var wmsIpAddress = wmsBase + requestTrayOutTask; var device = _deviceInfoRepository.QueryData(x => x.DeviceStatus == "1" && x.DeviceRemark == platform.Id.ToString()); var deviceCode = device.Select(x => x.DeviceCode).ToList(); List strings = platform.Location.Split(',').ToList(); var result = await HttpHelper.PostAsync(wmsIpAddress, new { Position = childDeviceCode, Tag = (int)taskType, AreaCdoe = platform.Stacker, AreaCdoes = strings, platform.ProductionLine }.ToJsonString()); //var result = await HttpHelper.PostAsync("http://localhost:5000/api/Task/RequestTrayOutTaskAsync", dynamic.ToJsonString()); WebResponseContent content = JsonConvert.DeserializeObject(result); // 检查状态并返回 if (!content.Status) return; taskDTO = JsonConvert.DeserializeObject(content.Data.ToString()); #endregion 调用WMS获取出库任务 CreateAndSendTask(taskDTO); } } /// /// 创建任务 /// public WebResponseContent CreateAndSendTask(WMSTaskDTO taskDTO) { var content = _taskService.ReceiveWMSTask(new List { taskDTO }); if (content.Status) { Console.WriteLine($"{taskDTO.TaskType}呼叫成功"); } return content; } } } #endregion