#region << 版 本 注 释 >> /*---------------------------------------------------------------- * 命名空间:WIDESEAWCS_Tasks.ConveyorLineJob * 创建者:胡童庆 * 创建时间:2024/8/2 16:13:36 * 版本:V1.0.0 * 描述: * * ---------------------------------------------------------------- * 修改人: * 修改时间: * 版本:V1.0.1 * 修改说明: * *----------------------------------------------------------------*/ #endregion << 版 本 注 释 >> using AutoMapper; using HslCommunication; using Newtonsoft.Json; using Quartz; using System.Reflection; using WIDESEAWCS_Common; using WIDESEAWCS_Common.TaskEnum; using WIDESEAWCS_Core; using WIDESEAWCS_Core.Caches; using WIDESEAWCS_Core.Helper; using WIDESEAWCS_Core.HttpContextUser; using WIDESEAWCS_DTO.Enum; using WIDESEAWCS_IBasicInfoRepository; using WIDESEAWCS_IBasicInfoService; using WIDESEAWCS_ISystemServices; using WIDESEAWCS_ITaskInfoRepository; using WIDESEAWCS_ITaskInfoService; using WIDESEAWCS_Model.BasicInfo; using WIDESEAWCS_Model.Models; using WIDESEAWCS_QuartzJob; using WIDESEAWCS_QuartzJob.DeviceBase; using WIDESEAWCS_QuartzJob.DTO; using WIDESEAWCS_QuartzJob.Service; using WIDESEAWCS_SignalR; using WIDESEAWCS_Tasks.ConveyorLineJob; using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database; namespace WIDESEAWCS_Tasks { [DisallowConcurrentExecution] public partial class CommonConveyorLineJob : JobBase, IJob { private readonly ITaskService _taskService; private readonly IRGVTaskService _rgvtaskService; private readonly IRGVTask_HtyService _rgvtask_HtyService; private readonly ITaskRepository _taskRepository; private readonly ITaskExecuteDetailService _taskExecuteDetailService; private readonly IRouterService _routerService; private readonly ISys_ConfigService _sys_ConfigService; private readonly IDt_StationManagerService _stationManagerService; private readonly IDt_StationManagerRepository _stationManagerRepository; private readonly IMapper _mapper; private readonly ICacheService _cacheService; private readonly INoticeService _noticeService; private static List? userTokenIds; private static List? userIds; public CommonConveyorLineJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, IRouterService routerService, IDt_StationManagerService stationManagerService, IMapper mapper, ICacheService cacheService, INoticeService noticeService, ITaskRepository taskRepository, IRGVTaskService rgvtaskService, IRGVTask_HtyService rgvtask_HtyService, IDt_StationManagerRepository stationManagerRepository) { _taskService = taskService; _taskExecuteDetailService = taskExecuteDetailService; _routerService = routerService; _stationManagerService = stationManagerService; _mapper = mapper; _cacheService = cacheService; _noticeService = noticeService; _taskRepository = taskRepository; _rgvtaskService = rgvtaskService; _rgvtask_HtyService = rgvtask_HtyService; _stationManagerRepository = stationManagerRepository; } public async Task Execute(IJobExecutionContext context) { try { CommonConveyorLine conveyorLine = (CommonConveyorLine)context.JobDetail.JobDataMap.Get("JobParams"); if (conveyorLine != null) { // 获取所有站点管理器 List stationManagers = _stationManagerService.GetAllStationByDeviceCode(conveyorLine.DeviceCode); // 并行处理每个子设备 var tasks = stationManagers.Select(station => ProcessDeviceAsync(conveyorLine, station)).ToList(); await Task.WhenAll(tasks); } } catch (Exception ex) { Console.Out.WriteLine(nameof(RGVJob) + ":" + ex.ToString()); } return; } private Task ProcessDeviceAsync(CommonConveyorLine conveyorLine, Dt_StationManager station) { try { ConveyorLineTaskCommand command = conveyorLine.ReadCustomer(station.stationChildCode); //var Barcode = conveyorLine.GetValue(ConveyorLineDBName.ConveyorLineBarcode, station.stationChildCode); if (command != null) { #region 调用事件总线通知前端 // 获取缓存中的用户信息 var tokenInfos = _cacheService.Get>("Cache_UserToken"); if (tokenInfos != null && tokenInfos.Any()) { userTokenIds = tokenInfos.Select(x => x.Token_ID).ToList(); userIds = tokenInfos.Select(x => x.UserId).ToList(); } #endregion 调用事件总线通知前端 // 将交互信号转换为布尔数组 var structs = BitConverter.GetBytes(command.InteractiveSignal).ToArray().ToBoolArray(); // 获取设备协议详情 List? deviceProtocolDetails = conveyorLine.DeviceProtocolDetailDTOs.Where(x => x.DeviceProParamName == nameof(ConveyorLineTaskCommand.InteractiveSignal)).ToList(); if (deviceProtocolDetails != null) { foreach (var item in deviceProtocolDetails) { int itemValue = Convert.ToInt32(item.ProtocalDetailValue); if (structs[itemValue] == true) { MethodInfo? method = GetType().GetMethod(item.ProtocolDetailType); if (method != null) { method.Invoke(this, new object[] { command, conveyorLine, station }); } } } } } } catch (Exception ex) { WriteInfo(conveyorLine.DeviceName, ex.Message); } return Task.CompletedTask; } /// /// 生成取货任务,放至上料位 /// /// 输送线实例对象 /// 读取的请求信息Request outbound /// 子设备编号 public async Task RequestTask(ConveyorLineTaskCommand command, CommonConveyorLine conveyorLine, Dt_StationManager station) { try { // 输出信息,表示站台请求取货 var log = $"【{conveyorLine._deviceName}】站台【{station.stationChildCode}】请求取货"; await LogAndWarn(conveyorLine.DeviceName, log); var task = _taskService.QueryConveyorLineTask(station.stationChildCode); //if (task != null) //{ // RequestInOrOutbound(command, conveyorLine, station, task); //} //else //{ await HandleNewTaskAsync(conveyorLine, command, station.stationChildCode, task); //} } catch (Exception ex) { WriteInfo(conveyorLine.DeviceName, ex.Message); } } /// /// 输送线出库完成 /// /// 输送线实例对象 /// 读取的请求信息 /// 子设备编号 public async Task ConveyorLineFinish(ConveyorLineTaskCommand command, CommonConveyorLine conveyorLine, Dt_StationManager station) { try { // 输出信息,表示站台请求取货 var log = $"【{conveyorLine._deviceName}】站台【{station.stationChildCode}】,任务号:【{command.TaskNum}】完成"; await LogAndWarn(conveyorLine.DeviceName, log); var task = _taskService.QueryConveyorLineFinishTask(station.stationChildCode); //改查询方法 HandleFinishTaskAsync(conveyorLine, command, station.stationChildCode, task); } catch (Exception ex) { WriteInfo(conveyorLine.DeviceName, ex.Message); } } /// /// 输送线请求出信息 /// /// 输送线实例对象 /// 读取的请求信息 /// 子设备编号 /// 线体当前bool读取偏移地址 public void RequestInOrOutbound(ConveyorLineTaskCommand command, CommonConveyorLine conveyorLine, Dt_StationManager station,Dt_Task task) { try { // 输出成功信息,包括输送线名称、任务号、托盘条码和子设备代码,以及任务信息 var logs = $"【{conveyorLine._deviceName}】任务号:【{task.TaskNum}】,托盘条码:【{task.PalletCode}】已到达【{station.stationChildCode}】输送线,task{task.ToJsonString()}"; ConsoleHelper.WriteSuccessLine(logs); _noticeService.Logs(userTokenIds, new { conveyorLine.DeviceName, log = logs, time = DateTime.Now.ToString("G"), color = "red" }); WriteInfo(conveyorLine.DeviceName, logs); // 如果任务不为空,则执行以下操作 if (task != null) { ConveyorLineTaskCommandWrite taskCommand = new ConveyorLineTaskCommandWrite() { TaskNum = Convert.ToInt16(task.TaskNum), TargetAddress = Convert.ToInt16(task.NextAddress), WriteInteractiveSignal = task.TaskType == (int)TaskOutboundTypeEnum.Outbound ? (byte)Convert.ToSByte(2) : (byte)Convert.ToSByte(1) }; // 输出成功信息,包括输送线名称、任务号、托盘条码、子设备代码和下一目标地址 var log = $"【{conveyorLine._deviceName}】任务号:【{command.TaskNum}】,托盘条码:【{command.Barcode}】已到达【{station.stationChildCode}】输送线请求出库,下一目标地址【{taskCommand.TargetAddress}】"; ConsoleHelper.WriteSuccessLine(log); _noticeService.Logs(userTokenIds, new { conveyorLine.DeviceName, log = log, time = DateTime.Now.ToString("G"), color = "red" }); WriteInfo(conveyorLine.DeviceName, log); var result = SendCommand(taskCommand, conveyorLine, station.stationChildCode); if (result) { _taskService.UpdateTaskStatusToNext(task); } } } catch (Exception ex) { } } /// /// 输送线请求出库下一地址 /// /// 输送线实例对象 /// 读取的请求信息 /// 子设备编号 public void ConveyorLineInOrOutFinish(CommonConveyorLine conveyorLine, ConveyorLineTaskCommand command, Dt_StationManager station, Dt_Task task) { // 打印成功日志,显示当前设备名称、任务号、托盘条码以及请求出库下一地址的子设备代码 var log = $"【{conveyorLine._deviceName}】任务号:【{command.TaskNum}】,托盘条码:【{command.Barcode}】已到达【{station.stationChildCode}】输送线请求出库完成"; 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) { _taskService.UpdateTaskStatusToNext(task); } } /// /// 输送线请求出库下一地址 /// /// 输送线实例对象 /// 读取的请求信息 /// 子设备编号 public void RequestNextAddress(CommonConveyorLine conveyorLine, ConveyorLineTaskCommand command, Dt_StationManager station, Dt_Task task) { // 打印成功日志,显示当前设备名称、任务号、托盘条码以及请求出库下一地址的子设备代码 var log = $"【{conveyorLine._deviceName}】任务号:【{command.TaskNum}】,托盘条码:【{command.Barcode}】已到达【{station.stationChildCode}】输送线请求出库下一地址"; 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) { ConveyorLineTaskCommandWrite taskCommand = new ConveyorLineTaskCommandWrite() { TaskNum = Convert.ToInt16(task.TaskNum), TargetAddress = Convert.ToInt16(task.NextAddress), WriteInteractiveSignal = task.TaskType == (int)TaskOutboundTypeEnum.Outbound ? (byte)Convert.ToSByte(2) : (byte)Convert.ToSByte(1) }; // 打印成功日志,显示当前设备名称、任务号、托盘条码、子设备代码以及下一目标地址 var logs = $"【{conveyorLine._deviceName}】任务号:【{command.TaskNum}】,托盘条码:【{command.Barcode}】已到达【{station.stationChildCode}】输送线请求出库下一地址,下一目标地址【{taskCommand.TargetAddress}】"; ConsoleHelper.WriteSuccessLine(logs); _noticeService.Logs(userTokenIds, new { conveyorLine.DeviceName, log = logs, time = DateTime.Now.ToString("G"), color = "red" }); WriteInfo(conveyorLine.DeviceName, logs); var result = SendCommand(taskCommand, conveyorLine, station.stationChildCode); if (result) { _taskService.UpdateTaskStatusToNext(task); } } } /// /// 输送线出库完成 /// /// 输送线实例对象 /// 读取的请求信息 /// 子设备编号 public void ConveyorLineOutFinish(CommonConveyorLine conveyorLine, ConveyorLineTaskCommand command, Dt_StationManager station,Dt_Task task) { try { // 打印成功信息,表示托盘已到达指定输送线并完成出库 var logs = $"【{conveyorLine.DeviceName}】任务号:【{command.TaskNum}】,托盘条码:【{command.Barcode}】已到达【{station.stationChildCode}】输送线出库完成"; ConsoleHelper.WriteSuccessLine(logs); _noticeService.Logs(userTokenIds, new { conveyorLine.DeviceName, log = logs, time = DateTime.Now.ToString("G"), color = "red" }); WriteInfo(conveyorLine.DeviceName, logs); ConveyorLineTaskCommandWrite taskCommand = new ConveyorLineTaskCommandWrite() { TaskNum = 100, TargetAddress = Convert.ToInt16(station.stationNextChildCode), WriteInteractiveSignal = (byte)Convert.ToSByte(3) }; var result = SendCommand(taskCommand, conveyorLine, station.stationChildCode); } catch (Exception ex) { } } /// /// 输送线报警 /// /// 输送线实例对象 /// 读取的请求信息 /// 子设备编号 /// 线体当前bool读取偏移地址 public void ConveyorLineAlarm(ConveyorLineTaskCommand command, CommonConveyorLine conveyorLine, Dt_StationManager station) { var task = _taskRepository.QueryFirst(x => x.TaskNum == command.TaskNum); conveyorLine.SetValue(ConveyorLineDBName.WriteInteractiveSignal,Convert.ToSByte(3), station.stationChildCode); } public async Task LogAndWarn(string deviceName, string log, string color = "red") { ConsoleHelper.WriteWarningLine(log); await _noticeService.Logs(userTokenIds, new { deviceName, log = log, time = DateTime.Now.ToString("G"), color = color }); WriteInfo(deviceName, log); } public bool SendCommand(ConveyorLineTaskCommandWrite taskCommand, CommonConveyorLine conveyorLine, string childDeviceCode) { conveyorLine.SetValue(ConveyorLineDBName.ConveyorLineTargetAddress, Convert.ToInt16(taskCommand.TargetAddress), childDeviceCode); Thread.Sleep(100); conveyorLine.SetValue(ConveyorLineDBName.ConveyorLineTaskNum, Convert.ToInt16(taskCommand.TaskNum), childDeviceCode); Thread.Sleep(100); conveyorLine.SetValue(ConveyorLineDBName.WriteInteractiveSignal, Convert.ToSByte(taskCommand.WriteInteractiveSignal), childDeviceCode); for (int i = 0; i < 6; i++) { ConveyorLineTaskCommand command = conveyorLine.ReadCustomer(childDeviceCode); if (command != null) { if (command.TaskNum == taskCommand.TaskNum && command.TargetAddress == taskCommand.TargetAddress) { WriteInfo(conveyorLine.DeviceName, $"写入任务成功写入次数{i}写入任务【{JsonConvert.SerializeObject(taskCommand)}】"); return true; } if (command.TargetAddress != taskCommand.TargetAddress) { conveyorLine.SetValue(ConveyorLineDBName.ConveyorLineTargetAddress, Convert.ToInt16(taskCommand.TargetAddress), childDeviceCode); Thread.Sleep(100); } if (command.TaskNum != taskCommand.TaskNum) { conveyorLine.SetValue(ConveyorLineDBName.ConveyorLineTaskNum, taskCommand.TaskNum, childDeviceCode); Thread.Sleep(100); } } } WriteInfo(conveyorLine.DeviceName, $"写入任务失败任务号【{taskCommand.TaskNum}】托盘号【{taskCommand.Barcode}】目标地址【{taskCommand.TargetAddress}】当前节点【{childDeviceCode}】"); return false; } } }