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;
}
}
}
}