using Autofac.Core; using Microsoft.AspNetCore.Components.Routing; using Microsoft.AspNetCore.Hosting; using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime; using OfficeOpenXml.FormulaParsing.Excel.Functions.RefAndLookup; using Quartz; using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel.Design; using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Eventing.Reader; using System.Linq; using System.Reflection.Metadata; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using WIDESEA_Common.Log; using WIDESEAWCS_Common.TaskEnum; using WIDESEAWCS_Core; using WIDESEAWCS_Core.Enums; using WIDESEAWCS_DTO.Enum; using WIDESEAWCS_ISystemServices; using WIDESEAWCS_ITaskInfoRepository; using WIDESEAWCS_ITaskInfoService; using WIDESEAWCS_Model.Models; using WIDESEAWCS_Model.Models.System; using WIDESEAWCS_QuartzJob; using WIDESEAWCS_QuartzJob.DeviceBase; using WIDESEAWCS_QuartzJob.DTO; using WIDESEAWCS_QuartzJob.Models; using WIDESEAWCS_QuartzJob.Service; using WIDESEAWCS_QuartzJob.StackerCrane; using WIDESEAWCS_QuartzJob.StackerCrane.Enum; using WIDESEAWCS_TaskInfoService; using WIDESEAWCS_Tasks.ConveyorLineJob; using WIDESEAWCS_Tasks.StackerCraneJob; namespace WIDESEAWCS_Tasks { [DisallowConcurrentExecution] public class SpeStackerCraneJob : IJob { private readonly ITaskService _taskService; private readonly ITaskExecuteDetailService _taskExecuteDetailService; private readonly ITaskRepository _taskRepository; private readonly IRouterService _routerService; private readonly IAgvStationService _agvStationService; public SpeStackerCraneJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository, IRouterService routerService, IAgvStationService agvStationService) { _taskService = taskService; _taskExecuteDetailService = taskExecuteDetailService; _taskRepository = taskRepository; _routerService = routerService; _agvStationService = agvStationService; } public Task Execute(IJobExecutionContext context) { try { SpeStackerCrane speStackerCrane = (SpeStackerCrane)context.JobDetail.JobDataMap.Get("JobParams"); if (speStackerCrane != null) { GetStackerObject getStackerObject = new GetStackerObject(speStackerCrane); //读取设备完成信息 if (getStackerObject.StaclerkJobJobStatusValue == RgvJobCraneStatus.Completed && getStackerObject.CurrentRgvtaskid != 0) { _taskService.UpdateTaskStatus(getStackerObject.CurrentRgvtaskid,2); } if (getStackerObject.RgvCraneAutoStatusValue == RgvCraneAutoStatus.Automatic && getStackerObject.StaclerkJobJobStatusValue == RgvJobCraneStatus.Ready && getStackerObject.RgvCraneWorkStatusValue == RGVStepprocess.NoAction) { //下发RGV任务之前,先读取一下安全门状态 //查找RGV进行下发任务 Dt_Task task = GetTask(speStackerCrane.DeviceCode); if (task != null) { //调取写入RGV小车任务 RgvCraneTaskCommand? stackerCraneTaskCommand = ConvertToStackerCraneTaskCommand(task); bool sendFlag = getStackerObject.SendCommand(stackerCraneTaskCommand); if (sendFlag) { //修改任务状态 _taskService.UpdateTaskStatusToNext(task); } } else { int HCJGoodsplatform = 1170; //定义的放货站台 //判断母车是否需要进行移动 AGVStation GdZiche = _agvStationService.Corridorequipment(speStackerCrane.DeviceCode); if(GdZiche.Station_Area == 1) { switch (getStackerObject.RGVCurrentlocation) { case int Whcjaddress when Whcjaddress == GdZiche.MotherCarDeviceCode: //在第一个母车上 RGVMovetask(HCJGoodsplatform, GdZiche.ChildPosiDeviceCode); break; case int Waddress when Waddress == GdZiche.MotherCardeputy: //在第二个母车上 OutNMotherCar(GdZiche.MotherCarDeviceCode); break; case int HCJaddress when HCJaddress == GdZiche.HCJStorageaddress: //在HCJ站台上 OutHCJMotherCar(GdZiche); break; default: return null; } } else { switch (getStackerObject.RGVCurrentlocation) { case int Whcjaddress when Whcjaddress == GdZiche.MotherCarDeviceCode: //在第一个母车上,需要判断外侧子车是否在HCJ上 OutinnerSideNMotherCar(GdZiche); break; case int Waddress when Waddress == GdZiche.MotherCardeputy: //在第二个母车上,需要判断子车与外侧母车是否在过道上 OutNMotherCar(GdZiche.MotherCarDeviceCode); break; default: return null; } } } } } } catch (Exception ex) { //Console.WriteLine(nameof(CommonStackerCraneJob) + ":" + ex.ToString()); } return Task.CompletedTask; } private Dt_Task? GetTask(string DeviceCode) { Dt_Task task = _taskService.QueryStackerCraneTask(DeviceCode); if (task == null) return null; return task.TaskType switch { (int)TaskInboundTypeEnum.Inbound => HandleInboundTask(task), (int)TaskOutboundTypeEnum.Outbound => HandleOutboundTask(task), _ => null }; } private Dt_Task? HandleInboundTask(Dt_Task task) { return task.TaskState switch { (int)TaskInStatusEnum.RGV_InNew => task, (int)TaskInStatusEnum.RGV_InPickupFinish => HandlePickupFinish(task), (int)TaskInStatusEnum.RGV_InReleaseFinish => HandInneRouterSides(task), (int)TaskInStatusEnum.RGV_InZicheFinish => HandleZicheFinish(task), (int)TaskInStatusEnum.RGV_InZicheReleaseFinish => task, (int)TaskInStatusEnum.RGV_InZichemoveFinish => HandleZicheMoveFinish(task), _ => null }; } private Dt_Task? HandleOutboundTask(Dt_Task task) { // 出库任务的状态判断相对简单,可以直接返回 int[] validStates = { (int)TaskOutStatusEnum.OutNew, (int)TaskOutStatusEnum.RGV_OutMothercarFinish, (int)TaskOutStatusEnum.RGV_OutZicheFinish, (int)TaskOutStatusEnum.RGV_OutZicheReleaseFinish, (int)TaskOutStatusEnum.RGV_OutPickupFinish }; return validStates.Contains(task.TaskState) ? task : null; } #region 入库方法 #region 入库口取货完成后,进行放货(HCJ,异常出库口) private Dt_Task? HandlePickupFinish(Dt_Task task) { try { //获取需要区分是否去入库与去不合格载货台任务 IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == "HCJ2000"); CommonStackerCrane Commonstacker = (CommonStackerCrane)device; DeviceProDTO? deviceProDTO = GetDeviceAddress.GetDeviceProDTO(Commonstacker, task.NextAddress, "HCJ_GoodsStatus"); int HCJGStatus = GetDeviceAddress.GetLine(Commonstacker, deviceProDTO.DeviceProAddress); if (HCJGStatus == 0) //为无货 { return task; } } catch (Exception ex) { //记录异常情况 _taskService.UpdateTaskExceptionMessage(task.TaskNum, $"判断HCJ站台是否有货信息出错,出错信息:{ex.Message}"); throw; } return null; } #endregion #region 入库口放货完成后,进行取货内容 private Dt_Task? HandInneRouterSides(Dt_Task task) { // 根据设备名称,获取到设备相关数据 AGVStation currentStation = _agvStationService.Corridorequipment(task.Roadway); // 获取子车位置 int zicheAddress = GetDeviceAddress.GetEquipmentlocation(currentStation.ChildPosiDeviceCode); if (currentStation.Station_Area == 1) { // 根据子车位置处理不同情况 switch (zicheAddress) { case int Whcjaddress when Whcjaddress == int.Parse(task.CurrentAddress): return task; case int Waddress when Waddress == currentStation.MotherCarDeviceCode: return task; case int Naddress when Naddress == currentStation.MotherCardeputy: return HandleMedialCase(task, currentStation.MotherCarDeviceCode); case int HCJaddress when HCJaddress == currentStation.HCJStorageaddress: return HandleMedialCase2(task, currentStation); default: return null; } } else { //取HCJ位的料判断 switch (zicheAddress) { case int Whcjaddress when Whcjaddress == int.Parse(task.CurrentAddress): return task; case int Waddress when Waddress == currentStation.MotherCarDeviceCode: return task; case int Naddress when Naddress == currentStation.MotherCardeputy: return HandleMedialCase(task, currentStation.MotherCarDeviceCode); default: return null; } } } /// /// 判断外侧母车是否在入口口 /// /// /// /// private Dt_Task? HandleMedialCase(Dt_Task task, int currentStation) { AGVStation Muche = _agvStationService.GetMothervehicle(currentStation); int motherCarAddress = GetDeviceAddress.GetEquipmentlocation(Muche.ChildPosiDeviceCode); if (motherCarAddress == Muche.Motherinlaw) return task; RGVMovetask(Muche.Motherinlaw, Muche.ChildPosiDeviceCode); return null; } /// /// 判断内外侧母车是否在入库口 /// /// /// /// private Dt_Task? HandleMedialCase2(Dt_Task task, AGVStation currentStation) { AGVStation Muche = _agvStationService.GetMothervehicle(currentStation.MotherCarDeviceCode); //外侧母车 AGVStation Muche2 = _agvStationService.GetMothervehicle(currentStation.MotherCardeputy); //内侧母车 int motherCarAddress = GetDeviceAddress.GetEquipmentlocation(Muche.ChildPosiDeviceCode); int motherCarAddress2 = GetDeviceAddress.GetEquipmentlocation(Muche2.ChildPosiDeviceCode); if (motherCarAddress == 0 || motherCarAddress2 == 0) return null; // 如果母车不在预期位置,下发移动任务 if (motherCarAddress != Muche.Motherinlaw) { RGVMovetask(Muche.Motherinlaw, Muche.ChildPosiDeviceCode); } if (motherCarAddress2 != Muche2.Motherinlaw) { RGVMovetask(Muche2.Motherinlaw, Muche2.ChildPosiDeviceCode); } if (motherCarAddress == Muche.Motherinlaw && motherCarAddress2 == Muche2.Motherinlaw) return task; // 母车已在正确位置 return null; } #endregion #region 取货完成后,进行放货操作 private Dt_Task? HandleZicheFinish(Dt_Task task) { // 根据设备名称,获取到设备相关数据 AGVStation GdaoRgvStation = _agvStationService.Corridorequipment(task.Roadway); int nexaddres = int.Parse(task.NextAddress); switch (nexaddres) { case int Whcjaddress when Whcjaddress == GdaoRgvStation.MotherCarDeviceCode: //放货点在第一个过道点 return MotherCarMoves(task, GdaoRgvStation); case int Waddress when Waddress == GdaoRgvStation.MotherCardeputy: //放货点在第二个过道点 return MotherCarMovesinside(task, GdaoRgvStation); case int HCJaddress when HCJaddress == GdaoRgvStation.HCJStorageaddress: //放货点在HCJ上 return HCJMotherCarMovesinside(task, GdaoRgvStation); default: return null; } } //区域一判断母车是否到位,可立即放货 private Dt_Task? MotherCarMoves(Dt_Task _Task, AGVStation aGVStation) { AGVStation Muche = _agvStationService.GetMothervehicle(aGVStation.ZicheMotherinlaw); int motherCarAddress = GetDeviceAddress.GetEquipmentlocation(Muche.ChildPosiDeviceCode); if (motherCarAddress == Muche.ZicheMotherinlaw) return _Task; RGVMovetask(Muche.ZicheMotherinlaw, aGVStation.ChildPosiDeviceCode); return null; } /// /// 判断放第二个母车位置 /// /// /// /// private Dt_Task? MotherCarMovesinside(Dt_Task _Task, AGVStation aGVStation) { AGVStation Muche = _agvStationService.GetMothervehicle(aGVStation.MotherCarDeviceCode); //外侧母车 AGVStation Muche2 = _agvStationService.GetMothervehicle(aGVStation.MotherCardeputy); //内侧母车 int motherCarAddress = GetDeviceAddress.GetEquipmentlocation(Muche.ChildPosiDeviceCode); int motherCarAddress2 = GetDeviceAddress.GetEquipmentlocation(Muche2.ChildPosiDeviceCode); // 如果母车不在预期位置,下发移动任务 if (motherCarAddress != Muche.Motherinlaw) { RGVMovetask(Muche.Motherinlaw, Muche.ChildPosiDeviceCode); } if (motherCarAddress2 != Muche2.ZicheMotherinlaw) { RGVMovetask(Muche2.ZicheMotherinlaw, Muche2.ChildPosiDeviceCode); } if (motherCarAddress == Muche.Motherinlaw && motherCarAddress2 == Muche2.ZicheMotherinlaw) return _Task; // 母车已在正确位置 return null; } private Dt_Task? HCJMotherCarMovesinside(Dt_Task _Task, AGVStation aGVStation) { AGVStation Muche = _agvStationService.GetMothervehicle(aGVStation.MotherCarDeviceCode); //外侧母车 AGVStation Muche2 = _agvStationService.GetMothervehicle(aGVStation.MotherCardeputy); //内侧母车 AGVStation Ziche3 = _agvStationService.GetZicheDeep(aGVStation.HCJStorageaddress); //内侧子车 int motherCarAddress = GetDeviceAddress.GetEquipmentlocation(Muche.ChildPosiDeviceCode); int motherCarAddress2 = GetDeviceAddress.GetEquipmentlocation(Muche2.ChildPosiDeviceCode); int ZiCarAddress3 = GetDeviceAddress.GetEquipmentlocation(Ziche3.ChildPosiDeviceCode); // 如果母车不在预期位置,下发移动任务 if (motherCarAddress != Muche.Motherinlaw) { RGVMovetask(Muche.Motherinlaw, Muche.ChildPosiDeviceCode); } if (motherCarAddress2 != Muche2.Motherinlaw) { RGVMovetask(Muche2.Motherinlaw, Muche2.ChildPosiDeviceCode); } if(ZiCarAddress3== Ziche3.HCJStorageaddress) { //判断目标站台是入库到几号堆垛机 if (_Task.TargetAddress == "3") //入库至3号堆垛机 { //判断外侧母车位置(2区域) AGVStation MucheN = _agvStationService.GetMothervehicle(Ziche3.MotherCarDeviceCode); //外侧母车 int motNCarAddress = GetDeviceAddress.GetEquipmentlocation(MucheN.ChildPosiDeviceCode); //获取到母车当前位置 if(MucheN.ZicheMotherinlaw== motNCarAddress) { RGVMovetask(Ziche3.MotherCarDeviceCode, Ziche3.ChildPosiDeviceCode); } else { RGVMovetask(MucheN.ZicheMotherinlaw, MucheN.ChildPosiDeviceCode); } } else if (_Task.TargetAddress == "4") //入库至4号堆垛机 { //判断外侧母车位置(2区域) AGVStation MucheN = _agvStationService.GetMothervehicle(Ziche3.MotherCarDeviceCode); //外侧母车 int motNCarAddress = GetDeviceAddress.GetEquipmentlocation(MucheN.ChildPosiDeviceCode); //获取到母车当前位置 if (MucheN.Motherinlaw != motNCarAddress) { RGVMovetask(MucheN.Motherinlaw, MucheN.ChildPosiDeviceCode); } AGVStation MucheN2 = _agvStationService.GetMothervehicle(Ziche3.MotherCardeputy); //外侧母车 int motNCarAddress2 = GetDeviceAddress.GetEquipmentlocation(MucheN2.ChildPosiDeviceCode); //获取到母车当前位置 if (MucheN2.ZicheMotherinlaw != motNCarAddress2) { RGVMovetask(MucheN2.ZicheMotherinlaw, MucheN2.ChildPosiDeviceCode); } if(MucheN.Motherinlaw == motNCarAddress && MucheN2.ZicheMotherinlaw == motNCarAddress2) { RGVMovetask(Ziche3.MotherCardeputy, Ziche3.ChildPosiDeviceCode); } } } if (motherCarAddress == Muche.Motherinlaw && motherCarAddress2 == Muche2.Motherinlaw && ZiCarAddress3 != Ziche3.HCJStorageaddress) return _Task; // 母车已在正确位置 return null; } #endregion #region 母车移动至入库口 private Dt_Task? HandleZicheMoveFinish(Dt_Task task) { int curradder = int.Parse(task.CurrentAddress); AGVStation GdZiche = _agvStationService.GetMotheaisle(curradder); int motherCarAddress = GetDeviceAddress.GetEquipmentlocation(GdZiche.ChildPosiDeviceCode); if (motherCarAddress != curradder) return task; RGVMovetask(GdZiche.Motherinlaw, GdZiche.ChildPosiDeviceCode); return null; } #endregion #endregion #region 出库方法 #region 外侧小车回归到起始点位 /// /// 判断放第二个母车位置 /// /// /// /// private void OutNMotherCar(int MotherCarDeviceCode) { AGVStation Muche = _agvStationService.GetMothervehicle(MotherCarDeviceCode); //外侧母车 int motherCarAddress = GetDeviceAddress.GetEquipmentlocation(Muche.ChildPosiDeviceCode); if (motherCarAddress != Muche.Motherinlaw) { RGVMovetask(Muche.Motherinlaw, Muche.ChildPosiDeviceCode); } } private void OutHCJMotherCar(AGVStation aGVStation) { AGVStation Muche = _agvStationService.GetMothervehicle(aGVStation.MotherCarDeviceCode); //外侧母车 AGVStation Muche2 = _agvStationService.GetMothervehicle(aGVStation.MotherCardeputy); //内侧母车 int motherCarAddress = GetDeviceAddress.GetEquipmentlocation(Muche.ChildPosiDeviceCode); int motherCarAddress2 = GetDeviceAddress.GetEquipmentlocation(Muche2.ChildPosiDeviceCode); // 如果母车不在预期位置,下发移动任务 if (motherCarAddress != Muche.Motherinlaw) { RGVMovetask(Muche.Motherinlaw, Muche.ChildPosiDeviceCode); } if (motherCarAddress2 != Muche2.Motherinlaw) { RGVMovetask(Muche2.Motherinlaw, Muche2.ChildPosiDeviceCode); } } #endregion #region 外侧小车回归到起始点位 /// /// 在第一个位置,则判断外侧子车是否在HCJ站台下面 /// /// /// /// private void OutinnerSideNMotherCar(AGVStation aGVStation) { AGVStation Ziche3 = _agvStationService.GetZicheDeep(aGVStation.HCJStorageaddress); //内侧子车 int ZiCarAddress3 = GetDeviceAddress.GetEquipmentlocation(Ziche3.ChildPosiDeviceCode); if (ZiCarAddress3 == Ziche3.HCJStorageaddress) { } else { //RGVMovetask(Muche.Motherinlaw, Muche.ChildPosiDeviceCode); } } private void OutinnerSideMotherCar(AGVStation aGVStation) { AGVStation Muche = _agvStationService.GetMothervehicle(aGVStation.MotherCarDeviceCode); //外侧母车 AGVStation Muche2 = _agvStationService.GetMothervehicle(aGVStation.MotherCardeputy); //内侧母车 int motherCarAddress = GetDeviceAddress.GetEquipmentlocation(Muche.ChildPosiDeviceCode); int motherCarAddress2 = GetDeviceAddress.GetEquipmentlocation(Muche2.ChildPosiDeviceCode); // 如果母车不在预期位置,下发移动任务 if (motherCarAddress != Muche.Motherinlaw) { RGVMovetask(Muche.Motherinlaw, Muche.ChildPosiDeviceCode); } if (motherCarAddress2 != Muche2.Motherinlaw) { RGVMovetask(Muche2.Motherinlaw, Muche2.ChildPosiDeviceCode); } } #endregion #endregion /// /// 子母车移动任务 /// /// 目标地址 /// 设备编号 /// private bool RGVMovetask(int RGVAdders, string ChildPosiDeviceCode) { RgvCraneTaskCommand standardCommands = ConvertMotherCarTaskCommand(RGVAdders); bool sendFlag = SendCommand2(standardCommands, ChildPosiDeviceCode); return sendFlag; } /// /// 任务实体转换成命令Model /// /// 任务实体 /// /// public RgvCraneTaskCommand? ConvertToStackerCraneTaskCommand([NotNull] Dt_Task task) { RgvCraneTaskCommand stackerCraneTaskCommand = new RgvCraneTaskCommand(); short locaticurr = task.RGVTaskType switch { _ when task.RGVTaskType == (short)RGVTaskTypeEnum.PickingUp || (task.RGVTaskType == (short)RGVTaskTypeEnum.TravelingOnly && task.TaskType != (int)TaskInStatusEnum.RGV_InZichemoveFinish) => short.Parse(task.CurrentAddress), _ when task.RGVTaskType == (short)RGVTaskTypeEnum.Placing || (task.RGVTaskType == (short)RGVTaskTypeEnum.TravelingOnly && task.TaskType== (int)TaskInStatusEnum.RGV_InZichemoveFinish) => short.Parse(task.NextAddress), _ => (short)0 }; stackerCraneTaskCommand.RGV_RGVTasklocation = locaticurr; stackerCraneTaskCommand.RGV_RGVtasktype = (short)task.RGVTaskType; stackerCraneTaskCommand.RGV_Rgvtaskid = (short)task.TaskNum; stackerCraneTaskCommand.RGV_Lanjiantaskid = (short)task.TaskNum; return stackerCraneTaskCommand; } /// /// 下发移动任务 /// /// 任务实体 /// /// public RgvCraneTaskCommand? ConvertMotherCarTaskCommand(int RGVAddress) { RgvCraneTaskCommand stackerCraneTaskCommand = new RgvCraneTaskCommand(); stackerCraneTaskCommand.RGV_RGVTasklocation = (short)RGVAddress; stackerCraneTaskCommand.RGV_RGVtasktype = 3; stackerCraneTaskCommand.RGV_Rgvtaskid = 999; //rgv任务号 stackerCraneTaskCommand.RGV_Lanjiantaskid = 999; //兰剑任务id return stackerCraneTaskCommand; } public bool SendCommand2(RgvCraneTaskCommand command, string DeviceCode) { try { IDevice? device = Storage.Devices.FirstOrDefault(x => x.DeviceCode == DeviceCode); CommonStackerCrane Commonstacker = (CommonStackerCrane)device; DeviceProDTO? deviceProDTO = GetDeviceAddress.GetDeviceProDTO(Commonstacker, DeviceCode, "RGV_Rgvtaskstutas"); int MCGStatus = GetDeviceAddress.GetLine(Commonstacker, deviceProDTO.DeviceProAddress); if (Commonstacker.IsConnected) { if (MCGStatus == (int)RgvJobCraneStatus.Ready) { Commonstacker.SetValue(RgvCraneDBName.RGV_RGVTasklocation, command.RGV_RGVTasklocation); Commonstacker.SetValue(RgvCraneDBName.RGV_RGVtasktype, command.RGV_RGVtasktype); Commonstacker.SetValue(RgvCraneDBName.RGV_Rgvtaskid, command.RGV_Rgvtaskid); Commonstacker.SetValue(RgvCraneDBName.RGV_Lanjiantaskid, command.RGV_Lanjiantaskid); return true; } } return false; } catch (Exception ex) { return false; } } } }